From 75ca67d2d4810d69c8d844fb403eea60ea9a8988 Mon Sep 17 00:00:00 2001 From: fruffy Date: Thu, 6 Feb 2025 19:56:57 -0500 Subject: [PATCH 01/19] Add bf-asm. Signed-off-by: fruffy --- backends/tofino/bf-asm/.gdbinit | 402 + backends/tofino/bf-asm/.gitignore | 27 + backends/tofino/bf-asm/CMakeLists.txt | 414 + backends/tofino/bf-asm/CPPLINT.cfg | 25 + backends/tofino/bf-asm/Options.md | 98 + backends/tofino/bf-asm/README.md | 379 + backends/tofino/bf-asm/SYNTAX.yaml | 1294 ++ backends/tofino/bf-asm/action_bus.cpp | 1202 ++ backends/tofino/bf-asm/action_bus.h | 244 + backends/tofino/bf-asm/action_table.cpp | 794 + backends/tofino/bf-asm/alias_array.h | 142 + backends/tofino/bf-asm/alloc.h | 229 + backends/tofino/bf-asm/asm-parse.ypp | 446 + backends/tofino/bf-asm/asm-types.cpp | 317 + backends/tofino/bf-asm/asm-types.h | 494 + backends/tofino/bf-asm/atcam_match.cpp | 558 + backends/tofino/bf-asm/attached_table.cpp | 525 + backends/tofino/bf-asm/b2j.cpp | 48 + backends/tofino/bf-asm/bfas.cpp | 627 + backends/tofino/bf-asm/bfas.h | 182 + backends/tofino/bf-asm/bfdis.cpp | 185 + backends/tofino/bf-asm/bfdumpbin.cpp | 228 + backends/tofino/bf-asm/bflink | 182 + backends/tofino/bf-asm/binary_output.h | 72 + backends/tofino/bf-asm/bson.cpp | 320 + backends/tofino/bf-asm/bson.h | 74 + backends/tofino/bf-asm/checked_array.h | 146 + backends/tofino/bf-asm/cmake/Abseil.cmake | 76 + backends/tofino/bf-asm/cmake/config.h.in | 25 + backends/tofino/bf-asm/constants.h | 242 + backends/tofino/bf-asm/counter.cpp | 406 + backends/tofino/bf-asm/crash.cpp | 280 + backends/tofino/bf-asm/data_switchbox.h | 168 + backends/tofino/bf-asm/deparser.cpp | 822 + backends/tofino/bf-asm/deparser.h | 278 + backends/tofino/bf-asm/depositfield.cpp | 39 + backends/tofino/bf-asm/depositfield.h | 34 + backends/tofino/bf-asm/disasm.cpp | 29 + backends/tofino/bf-asm/disasm.h | 50 + backends/tofino/bf-asm/dynhash.cpp | 64 + backends/tofino/bf-asm/error_mode.cpp | 201 + backends/tofino/bf-asm/error_mode.h | 73 + backends/tofino/bf-asm/escape.h | 56 + backends/tofino/bf-asm/exact_match.cpp | 528 + backends/tofino/bf-asm/exename.cpp | 69 + backends/tofino/bf-asm/exename.h | 25 + backends/tofino/bf-asm/fdstream.cpp | 85 + backends/tofino/bf-asm/fdstream.h | 61 + backends/tofino/bf-asm/flexible_headers.cpp | 48 + backends/tofino/bf-asm/gateway.cpp | 918 + backends/tofino/bf-asm/gtest/asm-types.cpp | 270 + backends/tofino/bf-asm/gtest/depositfield.cpp | 153 + backends/tofino/bf-asm/gtest/gateway.cpp | 122 + backends/tofino/bf-asm/gtest/gtestasm.cpp | 83 + backends/tofino/bf-asm/gtest/hashexpr.cpp | 117 + backends/tofino/bf-asm/gtest/mirror.cpp | 240 + backends/tofino/bf-asm/gtest/parser-test.cpp | 1054 + .../tofino/bf-asm/gtest/register-matcher.cpp | 175 + .../tofino/bf-asm/gtest/register-matcher.h | 67 + backends/tofino/bf-asm/hash_action.cpp | 231 + backends/tofino/bf-asm/hash_dist.cpp | 228 + backends/tofino/bf-asm/hash_dist.h | 61 + backends/tofino/bf-asm/hashdump.cpp | 132 + backends/tofino/bf-asm/hashexpr.cpp | 846 + backends/tofino/bf-asm/hashexpr.h | 77 + backends/tofino/bf-asm/idletime.cpp | 217 + backends/tofino/bf-asm/input_xbar.cpp | 1139 ++ backends/tofino/bf-asm/input_xbar.h | 367 + backends/tofino/bf-asm/instruction.cpp | 1745 ++ backends/tofino/bf-asm/instruction.h | 75 + backends/tofino/bf-asm/j2b.cpp | 48 + backends/tofino/bf-asm/jbay/CMakeLists.txt | 65 + backends/tofino/bf-asm/jbay/chip.schema | Bin 0 -> 2250682 bytes backends/tofino/bf-asm/jbay/counter.h | 121 + backends/tofino/bf-asm/jbay/deparser.cpp | 1092 ++ backends/tofino/bf-asm/jbay/gateway.cpp | 99 + backends/tofino/bf-asm/jbay/gateway.h | 30 + backends/tofino/bf-asm/jbay/input_xbar.cpp | 70 + backends/tofino/bf-asm/jbay/input_xbar.h | 29 + backends/tofino/bf-asm/jbay/instruction.cpp | 200 + backends/tofino/bf-asm/jbay/match_table.cpp | 130 + backends/tofino/bf-asm/jbay/meter.h | 140 + backends/tofino/bf-asm/jbay/parser.cpp | 584 + backends/tofino/bf-asm/jbay/phv.cpp | 66 + backends/tofino/bf-asm/jbay/phv.h | 56 + backends/tofino/bf-asm/jbay/salu_inst.cpp | 493 + backends/tofino/bf-asm/jbay/stage.cpp | 316 + backends/tofino/bf-asm/jbay/stateful.cpp | 393 + backends/tofino/bf-asm/jbay/stateful.h | 60 + .../tofino/bf-asm/jbay/template_objects.yaml | 121 + backends/tofino/bf-asm/json.cpp | 253 + backends/tofino/bf-asm/json.h | 639 + backends/tofino/bf-asm/json_diff.cpp | 628 + backends/tofino/bf-asm/lex-yaml.l | 283 + backends/tofino/bf-asm/map.h | 255 + backends/tofino/bf-asm/mask_counter.h | 65 + backends/tofino/bf-asm/match_source.h | 81 + backends/tofino/bf-asm/match_table.cpp | 703 + backends/tofino/bf-asm/meter.cpp | 1036 + backends/tofino/bf-asm/misc.cpp | 223 + backends/tofino/bf-asm/misc.h | 218 + backends/tofino/bf-asm/mksizes.cpp | 40 + backends/tofino/bf-asm/mktags | 23 + backends/tofino/bf-asm/p4_table.cpp | 254 + backends/tofino/bf-asm/p4_table.h | 94 + backends/tofino/bf-asm/parser-tofino-jbay.cpp | 2029 ++ backends/tofino/bf-asm/parser-tofino-jbay.h | 722 + backends/tofino/bf-asm/parser.h | 45 + backends/tofino/bf-asm/phase0.cpp | 93 + backends/tofino/bf-asm/phv.cpp | 498 + backends/tofino/bf-asm/phv.h | 329 + backends/tofino/bf-asm/power_ctl.h | 65 + backends/tofino/bf-asm/primitives.cpp | 165 + backends/tofino/bf-asm/proxy_hash.cpp | 188 + backends/tofino/bf-asm/reflow.cpp | 113 + backends/tofino/bf-asm/register_reference.h | 111 + .../tofino/bf-asm/rvalue_reference_wrapper.h | 33 + backends/tofino/bf-asm/salu_inst.cpp | 1073 + backends/tofino/bf-asm/sections.h | 104 + backends/tofino/bf-asm/selection.cpp | 453 + backends/tofino/bf-asm/slist.h | 52 + backends/tofino/bf-asm/sram_match.cpp | 1504 ++ backends/tofino/bf-asm/stage.cpp | 857 + backends/tofino/bf-asm/stage.h | 227 + backends/tofino/bf-asm/stateful.cpp | 678 + backends/tofino/bf-asm/synth2port.cpp | 177 + backends/tofino/bf-asm/tables.cpp | 3356 ++++ backends/tofino/bf-asm/tables.h | 2196 +++ backends/tofino/bf-asm/target.cpp | 324 + backends/tofino/bf-asm/target.h | 726 + backends/tofino/bf-asm/ternary_match.cpp | 1223 ++ backends/tofino/bf-asm/test/CMakeLists.txt | 112 + backends/tofino/bf-asm/test/acl1.p4 | 319 + backends/tofino/bf-asm/test/action_bus1.p4 | 40 + backends/tofino/bf-asm/test/action_chain1.p4 | 83 + backends/tofino/bf-asm/test/action_chain1.stf | 20 + backends/tofino/bf-asm/test/action_chain2.p4 | 83 + .../bf-asm/test/asm/action_bus_alignment.tfa | 422 + .../test/asm/action_default_multiple.tfa | 112 + .../tofino/bf-asm/test/asm/always_run.jba | 16 + .../tofino/bf-asm/test/asm/always_run.stf | 2 + .../tofino/bf-asm/test/asm/counter_lrt1.tfa | 10 + backends/tofino/bf-asm/test/asm/em1-clot.jba | 98 + backends/tofino/bf-asm/test/asm/em1-clot.stf | 8 + .../bf-asm/test/asm/expected_failures.txt | 14 + .../bf-asm/test/asm/hash_action_basic.tfa | 112 + .../bf-asm/test/asm/hash_action_gateway2.stf | 22 + .../bf-asm/test/asm/hash_action_gateway2.tfa | 120 + .../bf-asm/test/asm/jbay_sful_syntax.jba | 51 + .../tofino/bf-asm/test/asm/network_tap.bfa | 13304 +++++++++++++ backends/tofino/bf-asm/test/asm/p4c-2257.bfa | 16228 ++++++++++++++++ backends/tofino/bf-asm/test/asm/p4c-4021.bfa | 2381 +++ .../bf-asm/test/asm/parser_value_set.tfa | 23 + .../bf-asm/test/asm/parser_zero_write.jba | 6 + backends/tofino/bf-asm/test/asm/rng.tfa | 22 + .../asm/stateful_multiple_output_error.tfa | 348 + .../test/asm/switch_l2_profile_tofino.tfa | 5453 ++++++ .../bf-asm/test/asm/table_action_alias.tfa | 66 + .../test/asm/table_alias_fields_error.tfa | 66 + backends/tofino/bf-asm/test/asm/tor.tfa | 1587 ++ .../bf-asm/test/bfas_lookup_test/__init__.py | 0 .../bfas_lookup_test/bfas_lookup_cases.py | 25 + .../test/bfas_lookup_test/bfas_lookup_test.py | 126 + backends/tofino/bf-asm/test/checksum1.p4 | 120 + backends/tofino/bf-asm/test/counter1.p4 | 44 + backends/tofino/bf-asm/test/counter2.p4 | 44 + backends/tofino/bf-asm/test/counter3.p4 | 53 + backends/tofino/bf-asm/test/counter4.p4 | 45 + backends/tofino/bf-asm/test/counter5.p4 | 44 + backends/tofino/bf-asm/test/ctx_json | 1 + backends/tofino/bf-asm/test/ctxt_json_ignore | 94 + .../tofino/bf-asm/test/ctxt_json_ignore_new | 9 + backends/tofino/bf-asm/test/exact_match0.p4 | 35 + backends/tofino/bf-asm/test/exact_match1.p4 | 40 + backends/tofino/bf-asm/test/exact_match1.stf | 11 + backends/tofino/bf-asm/test/exact_match2.p4 | 41 + backends/tofino/bf-asm/test/exact_match3.p4 | 41 + backends/tofino/bf-asm/test/exact_match4.p4 | 42 + backends/tofino/bf-asm/test/exact_match5.p4 | 43 + backends/tofino/bf-asm/test/exact_match6.p4 | 43 + backends/tofino/bf-asm/test/exact_match7.p4 | 41 + backends/tofino/bf-asm/test/exact_match8.p4 | 54 + backends/tofino/bf-asm/test/exact_match9.p4 | 44 + .../tofino/bf-asm/test/exact_match_valid1.p4 | 44 + .../tofino/bf-asm/test/expected_failures.txt | 41 + backends/tofino/bf-asm/test/gateway1.p4 | 48 + backends/tofino/bf-asm/test/gateway2.p4 | 48 + backends/tofino/bf-asm/test/gateway3.p4 | 51 + backends/tofino/bf-asm/test/gateway4.p4 | 62 + backends/tofino/bf-asm/test/gateway5.p4 | 54 + backends/tofino/bf-asm/test/gateway6.p4 | 48 + backends/tofino/bf-asm/test/gateway7.p4 | 48 + backends/tofino/bf-asm/test/hash_index0.p4 | 36 + backends/tofino/bf-asm/test/hash_index1.p4 | 38 + backends/tofino/bf-asm/test/hash_index2.p4 | 51 + backends/tofino/bf-asm/test/hash_index3.p4 | 63 + backends/tofino/bf-asm/test/hash_index5.p4 | 37 + backends/tofino/bf-asm/test/instruct1.p4 | 61 + backends/tofino/bf-asm/test/instruct2.p4 | 39 + backends/tofino/bf-asm/test/instruct3.p4 | 34 + backends/tofino/bf-asm/test/instruct4.p4 | 35 + backends/tofino/bf-asm/test/instruct5.p4 | 56 + .../test/internal/brig/expected_failures.txt | 2 + .../internal/brig/test_config_123_meter_2.p4 | 118 + .../test_config_223_simple_set_metadata.p4 | 82 + ...ebug_issue_1_invalid_action_pack_format.p4 | 84 + .../debug_issue_2_action_data_bus.PRAGMA | 610 + .../internal/debug_issue_3_7_way_table.p4 | 82 + .../debug_issue_4_small_exact_match_key.p4 | 81 + .../tofino/bf-asm/test/internal/dileep.p4 | 290 + .../tofino/bf-asm/test/internal/dileep10.p4 | 186 + .../tofino/bf-asm/test/internal/dileep11.p4 | 183 + .../tofino/bf-asm/test/internal/dileep12.p4 | 449 + .../tofino/bf-asm/test/internal/dileep2.p4 | 329 + .../tofino/bf-asm/test/internal/dileep3.p4 | 358 + .../tofino/bf-asm/test/internal/dileep4.p4 | 412 + .../bf-asm/test/internal/dileep5.PRAGMA | 487 + .../bf-asm/test/internal/dileep6.PHV_BUG | 592 + .../tofino/bf-asm/test/internal/dileep7-b.p4 | 577 + .../bf-asm/test/internal/dileep7.PRAGMA | 573 + .../tofino/bf-asm/test/internal/dileep8.p4 | 593 + .../bf-asm/test/internal/dileep9.PRAGMA | 188 + .../bf-asm/test/internal/google-tor/lag.p4 | 48 + .../bf-asm/test/internal/google-tor/tor.p4 | 672 + .../test/internal/test_7_storm_control.p4 | 140 + .../internal/test_config_100_hash_action.p4 | 105 + .../internal/test_config_101_switch_msdc.p4 | 3838 ++++ .../internal/test_config_102_clone.NOT_READY | 97 + .../test/internal/test_config_102_clone.p4 | 97 + .../internal/test_config_103_first_phase_0.p4 | 129 + .../test_config_10_new_crossbar_allocation.p4 | 120 + .../internal/test_config_114_simple_drop.p4 | 71 + .../test_config_115_hash_parity_groups.p4 | 103 + ...t_config_116_predication_with_condition.p4 | 109 + .../test_config_117_first_tcam_range.p4 | 68 + .../internal/test_config_118_tcam_range_2.p4 | 88 + .../internal/test_config_119_tcam_range_3.p4 | 88 + .../test_config_11_simple_gateway_table.p4 | 121 + .../internal/test_config_120_tcam_range_4.p4 | 88 + .../internal/test_config_121_tcam_range_5.p4 | 88 + .../internal/test_config_122_tcam_range_6.p4 | 70 + .../test/internal/test_config_123_meter_2.p4 | 118 + .../test/internal/test_config_124_meter_3.p4 | 113 + .../test_config_125_meter_pre_color.p4 | 112 + .../test_config_126_meter_pre_color_2.p4 | 114 + .../test_config_127_meter_pre_color_3.p4 | 160 + .../test_config_128_table_placement_bug.p4 | 101 + .../internal/test_config_12_no_overhead.p4 | 72 + .../test_config_130_test_default_action.p4 | 115 + .../test_config_132_meter_pre_color_4.p4 | 172 + .../internal/test_config_134_stage_deps.p4 | 120 + .../internal/test_config_135_tcam_range_7.p4 | 71 + .../test_config_136_tcam_error_detection.p4 | 73 + .../test_config_137_tcam_error_detection_2.p4 | 131 + .../test_config_138_tcam_error_detection_3.p4 | 147 + .../test_config_139_tcam_error_detection_4.p4 | 140 + .../test_config_13_first_selection.p4 | 152 + .../internal/test_config_140_table_counter.p4 | 103 + .../internal/test_config_142_stateful_bfd.p4 | 103 + .../test_config_143_packing_constants.p4 | 80 + .../internal/test_config_144_recirculate.p4 | 56 + .../test_config_145_shift_primitives.p4 | 69 + .../internal/test_config_146_two_drops.p4 | 69 + .../test_config_147_subtract_primitive.p4 | 69 + .../test_config_148_action_profile.p4 | 67 + ...onfig_149_signed_and_saturating_add_sub.p4 | 85 + ...st_config_14_auto_immediate_action_data.p4 | 97 + .../test_config_150_action_bus_allocation.p4 | 90 + ...test_config_151_action_bus_allocation_2.p4 | 84 + .../test_config_152_stateful_simple_cntr.p4 | 72 + ...ig_153_stateful_simple_cntr_with_output.p4 | 91 + .../test_config_154_stateful_sampling.p4 | 85 + .../test_config_155_stateful_3_alus.p4 | 139 + .../test_config_156_indirect_stateful_cntr.p4 | 107 + ...test_config_157_random_number_generator.p4 | 75 + .../internal/test_config_158_share_vliw.p4 | 81 + ...est_config_159_stateful_using_phv_field.p4 | 90 + .../test/internal/test_config_15_wide_key.p4 | 93 + ...est_config_160_stateful_single_bit_mode.p4 | 127 + .../test_config_161_new_primitives.p4 | 123 + .../test_config_162_add_header_init.p4 | 80 + ...est_config_163_stateful_table_math_unit.p4 | 92 + ...fig_164_stateful_deterministic_sampling.p4 | 115 + ...nfig_165_stateful_bfd_failure_detection.p4 | 125 + ...est_config_166_stateful_generic_counter.p4 | 96 + ...t_config_167_stateful_flowlet_switching.p4 | 144 + .../internal/test_config_168_meter_bug.p4 | 89 + ...test_config_169_stateful_sflow_sequence.p4 | 195 + ..._16_action_packing_multi_entry_with_pad.p4 | 79 + ...fig_170_stateful_selection_table_update.p4 | 167 + .../test_config_171_stateful_conga.p4 | 175 + .../test_config_172_stateful_heavy_hitter.p4 | 262 + .../test_config_173_stateful_bloom_filter.p4 | 259 + ...test_config_175_match_table_with_no_key.p4 | 70 + .../internal/test_config_176_extend_crc16.p4 | 77 + .../internal/test_config_177_meter_test.p4 | 90 + .../internal/test_config_178_hash_action.p4 | 69 + ...fig_179_check_if_sequential_action_used.p4 | 79 + ..._config_17_action_packing_wide_with_pad.p4 | 82 + .../test_config_180_first_proxy_hash.p4 | 74 + .../test_config_181_first_alg_tcam.p4 | 161 + .../test_config_182_warp_primitive.p4 | 81 + .../internal/test_config_183_sample_e2e.p4 | 58 + .../internal/test_config_184_stateful_bug1.p4 | 103 + .../internal/test_config_185_first_lpf.p4 | 105 + .../internal/test_config_186_hlir_modify.p4 | 89 + .../internal/test_config_187_proxy_hash_2.p4 | 61 + .../test_config_188_action_data_overflow.p4 | 59 + .../internal/test_config_189_stat_with_lrt.p4 | 62 + .../internal/test_config_18_first_bit_xor.p4 | 100 + .../test_config_190_modify_with_expr.p4 | 69 + .../internal/test_config_191_invalidate.p4 | 64 + ...test_config_192_stateful_driven_by_hash.p4 | 300 + ...test_config_193_indirect_stats_no_reads.p4 | 64 + .../test_config_194_same_action_param.p4 | 103 + ...st_config_195_stateful_predicate_output.p4 | 96 + .../test/internal/test_config_196_hit_miss.p4 | 119 + .../test_config_197_default_next_table.p4 | 109 + .../test_config_198_shared_action_profile.p4 | 92 + ...test_config_199_stateful_constant_index.p4 | 67 + ...g_19_immediate_but_no_action_data_table.p4 | 76 + .../test_config_1_ternary_match_crossbar.p4 | 51 + .../test_config_200_counter_constant_index.p4 | 63 + .../test_config_201_meter_constant_index.p4 | 109 + .../test_config_202_write_same_byte.p4 | 67 + .../test_config_203_first_reduction_or.p4 | 144 + .../test_config_204_no_tables_in_stage0.p4 | 75 + .../test_config_205_modify_field_from_hash.p4 | 90 + .../test_config_206_stateful_logging.p4 | 70 + .../internal/test_config_207_not_gateway.p4 | 61 + .../internal/test_config_208_table_no_key.p4 | 51 + .../test_config_209_pack_hash_dist.p4 | 137 + .../test_config_20_table_dependencies.p4 | 131 + .../test/internal/test_config_21_tcam_vpns.p4 | 76 + .../test_config_22_direct_mapped_exact.p4 | 92 + .../test_config_23_same_container_modified.p4 | 95 + .../test_config_24_action_entries_pragma.p4 | 87 + .../test_config_25_no_reads_for_table.p4 | 83 + .../test_config_26_direct_add_primitive.p4 | 88 + .../test_config_2_action_data_table_sizing.p4 | 66 + .../test_config_30_action_data_imm_param.p4 | 87 + .../test_config_31_action_data_imm_imm.p4 | 87 + ...est_config_32_action_data_imm_param_imm.p4 | 44 + .../test_config_33_action_data_paramx3.p4 | 44 + ...test_config_34_action_data_1_bit_params.p4 | 114 + ...ig_35_action_data_1_bit_params_and_imms.p4 | 113 + .../test_config_36_action_data_field_param.p4 | 43 + .../test_config_37_action_data_field_field.p4 | 46 + ...fig_38_action_data_field_same_container.p4 | 46 + ...test_config_39_action_data_add_to_field.p4 | 46 + .../test_config_3_add_to_field.PHV_BUG | 74 + .../test_config_40_action_data_bit_xor.p4 | 46 + ...est_config_41_action_data_remove_header.p4 | 46 + .../test_config_42_action_data_add_header.p4 | 45 + .../test_config_43_action_data_drop.PHV_BUG | 46 + .../test_config_44_action_data_immediate.p4 | 47 + ...ction_data_immediate_param_and_constant.p4 | 49 + ...test_config_46_action_data_big_constant.p4 | 87 + ...g_47_action_data_big_constant_immediate.p4 | 87 + ...st_config_48_action_data_bit_masked_set.p4 | 44 + ...49_action_data_bit_masked_set_immediate.p4 | 50 + .../internal/test_config_4_modify_field.p4 | 65 + ...ig_50_action_data_different_size_fields.p4 | 44 + ...ction_data_same_parameter_used_multiple.p4 | 51 + .../internal/test_config_52_copy_header.p4 | 45 + .../test_config_53_ternary_swizzle.p4 | 43 + ...fig_54_modify_field_different_size.PHV_BUG | 51 + .../test_config_55_generate_digest.p4 | 42 + .../test_config_56_iterate_through_packing.p4 | 39 + ..._config_57_tcam_with_44_bits_no_version.p4 | 41 + .../test_config_58_tcam_with_40_bits.p4 | 41 + ...config_59_tcam_with_44_bits_and_version.p4 | 41 + .../internal/test_config_5_sram_allocation.p4 | 69 + ...tcam_with_44_and_no_version_high_nibble.p4 | 41 + ..._with_44_bits_and_no_version_low_nibble.p4 | 41 + ...config_62_tcam_with_48_bits_and_version.p4 | 41 + ...fig_63_tcam_with_48_bits_and_no_version.p4 | 41 + ...config_64_tcam_with_84_bits_and_version.p4 | 41 + ...am_with_84_bits_high_nibble_and_version.p4 | 45 + ...cam_with_84_bits_low_nibble_and_version.p4 | 45 + ...cam_with_84_bits_high_nibble_no_version.p4 | 45 + ...tcam_with_84_bits_low_nibble_no_version.p4 | 45 + ...config_68_tcam_with_88_bits_and_version.p4 | 45 + ..._config_69_tcam_with_88_bits_no_version.p4 | 45 + .../test_config_6_sram_and_tcam_allocation.p4 | 131 + ...onfig_70_tcam_with_128_bits_and_version.p4 | 43 + ...ig_71_tcam_with_128_bits_and_no_version.p4 | 43 + ...onfig_72_tcam_with_172_bits_and_version.p4 | 45 + ...m_with_172_bits_high_nibble_and_version.p4 | 48 + ...am_with_172_bits_low_nibble_and_version.p4 | 48 + ...cam_with_172_bits_low_nibble_no_version.p4 | 48 + ...config_75_tcam_with_176_bits_no_version.p4 | 47 + ...onfig_76_tcam_with_176_bits_and_version.p4 | 47 + ...onfig_77_tcam_with_216_bits_and_version.p4 | 51 + ...m_with_220_bits_high_nibble_and_version.p4 | 56 + ...am_with_220_bits_high_nibble_no_version.p4 | 52 + ...cam_with_220_bits_low_nibble_no_version.p4 | 52 + ..._config_81_indirect_action_data_default.p4 | 60 + .../internal/test_config_82_param_sharing.p4 | 78 + ...no_immediate_when_indirect_action_table.p4 | 53 + .../test_config_84_simple_wide_exact_match.p4 | 53 + .../internal/test_config_85_table_ordering.p4 | 126 + ...tiple_action_widths_for_indirect_action.p4 | 95 + ...hare_parameter_for_different_containers.p4 | 59 + ...fig_88_testing_action_data_allocation_3.p4 | 192 + ...tion_data_allocation_3_with_partial_ram.p4 | 121 + .../internal/test_config_8_next_table.BUG | 175 + ...ta_allocation_3_with_fields_in_overhead.p4 | 121 + ...test_config_91_gateway_with_split_table.p4 | 77 + .../test_config_92_bit_xor_10_bits.p4 | 56 + .../internal/test_config_93_push_and_pop.p4 | 71 + ...est_config_94_action_constant_alignment.p4 | 75 + ...test_config_95_first_meter_table.NOT_READY | 105 + .../test/internal/test_config_96_hash_data.p4 | 171 + .../test_config_97_unrelated_tables.p4 | 94 + .../test_config_98_multiple_control_flow.p4 | 103 + .../test_config_99_share_exact_match_key.p4 | 91 + .../test_config_9_no_ternary_indirection.p4 | 92 + .../internal/test_tp_1_one_table_spill.p4 | 104 + .../test/internal/vk_basic_ipv4.PHV_BUG | 629 + .../test/internal/vk_basic_ipv4_20150706.p4 | 707 + .../test/internal/vk_basic_ipv4_subset.p4 | 189 + backends/tofino/bf-asm/test/jdiff.sh | 84 + backends/tofino/bf-asm/test/mac_rewrite.p4 | 149 + .../tofino/bf-asm/test/mau/01-FlexCounter.p4 | 89 + .../test/mau/02-FlexCounterActionProfile.p4 | 101 + .../tofino/bf-asm/test/mau/02-FullPHV1.p4 | 766 + .../tofino/bf-asm/test/mau/04-FieldProblem.p4 | 91 + .../tofino/bf-asm/test/mau/07-MacAddrCheck.p4 | 52 + .../bf-asm/test/mau/08-MacAddrCheck1.p4 | 55 + .../bf-asm/test/mau/08-MultiProtocolIfElse.p4 | 199 + .../bf-asm/test/mau/09-MacAddrCheck2.p4 | 56 + .../bf-asm/test/mau/10-AssignChooseSource.p4 | 100 + .../tofino/bf-asm/test/mau/12-Counters.p4 | 49 + .../test/mau/12-SmallToBigFieldWithMask8.p4 | 59 + backends/tofino/bf-asm/test/mau/14-Counter.p4 | 36 + .../test/mau/15-MultiProtocolIfElseMinimal.p4 | 107 + .../tofino/bf-asm/test/mau/16-NoHeaders.p4 | 19 + .../tofino/bf-asm/test/mau/19-SimpleTrill.p4 | 94 + .../bf-asm/test/mau/20-SimpleTrillTwoStep.p4 | 115 + .../test/mau/22-BigToSmallFieldWithMask8.p4 | 58 + .../test/mau/22-SimpleTrillThreeStep.p4 | 124 + .../tofino/bf-asm/test/mau/action_params.p4 | 136 + .../bf-asm/test/mau/basic_ipv4_selection.p4 | 215 + backends/tofino/bf-asm/test/mau/do_nothing.p4 | 36 + .../bf-asm/test/mau/expected_failures.txt | 111 + backends/tofino/bf-asm/test/mau/instruct1.p4 | 61 + backends/tofino/bf-asm/test/mau/selector1.p4 | 60 + .../tofino/bf-asm/test/mau/ternary_match0.p4 | 34 + backends/tofino/bf-asm/test/meter_test1.p4 | 69 + backends/tofino/bf-asm/test/parser1.p4 | 154 + backends/tofino/bf-asm/test/parser2.p4 | 255 + backends/tofino/bf-asm/test/parser3.p4 | 63 + backends/tofino/bf-asm/test/parser_dc_full.p4 | 959 + .../tofino/bf-asm/test/port_vlan_mapping.p4 | 1415 ++ backends/tofino/bf-asm/test/proxy_hash1.p4 | 109 + .../bf-asm/test/ptf/action_spec_format.p4 | 464 + backends/tofino/bf-asm/test/ptf/alpm_test.p4 | 173 + backends/tofino/bf-asm/test/ptf/basic_ipv4.p4 | 866 + .../bf-asm/test/ptf/basic_ipv4_selector.p4 | 269 + .../tofino/bf-asm/test/ptf/basic_switching.p4 | 79 + backends/tofino/bf-asm/test/ptf/dkm.p4 | 214 + .../tofino/bf-asm/test/ptf/drivers_test.p4 | 477 + backends/tofino/bf-asm/test/ptf/easy.p4 | 32 + .../tofino/bf-asm/test/ptf/easy_ternary.p4 | 32 + backends/tofino/bf-asm/test/ptf/ecmp_pi.p4 | 221 + backends/tofino/bf-asm/test/ptf/emulation.p4 | 202 + backends/tofino/bf-asm/test/ptf/exm_direct.p4 | 723 + .../tofino/bf-asm/test/ptf/exm_direct_1.p4 | 780 + .../tofino/bf-asm/test/ptf/exm_indirect_1.p4 | 893 + .../tofino/bf-asm/test/ptf/exm_smoke_test.p4 | 766 + .../tofino/bf-asm/test/ptf/fast_reconfig.p4 | 279 + backends/tofino/bf-asm/test/ptf/fr_test.p4 | 635 + .../bf-asm/test/ptf/includes/headers.p4 | 41 + .../tofino/bf-asm/test/ptf/includes/parser.p4 | 46 + backends/tofino/bf-asm/test/ptf/iterator.p4 | 195 + .../tofino/bf-asm/test/ptf/mau_mem_test.p4 | 294 + .../tofino/bf-asm/test/ptf/mau_tcam_test.p4 | 282 + backends/tofino/bf-asm/test/ptf/mau_test.p4 | 1285 ++ backends/tofino/bf-asm/test/ptf/meters.p4 | 447 + .../tofino/bf-asm/test/ptf/multi_device.p4 | 692 + .../tofino/bf-asm/test/ptf/multicast_scale.p4 | 120 + .../tofino/bf-asm/test/ptf/multicast_test.p4 | 279 + backends/tofino/bf-asm/test/ptf/p4features.h | 8 + .../tofino/bf-asm/test/ptf/parser_intr_md.p4 | 129 + .../tofino/bf-asm/test/ptf/pcie_pkt_test.p4 | 30 + backends/tofino/bf-asm/test/ptf/pctr.p4 | 226 + backends/tofino/bf-asm/test/ptf/perf_test.p4 | 245 + .../tofino/bf-asm/test/ptf/perf_test_alpm.p4 | 217 + backends/tofino/bf-asm/test/ptf/pgrs.p4 | 309 + .../tofino/bf-asm/test/ptf/pktgen_headers.p4 | 57 + backends/tofino/bf-asm/test/ptf/pvs.p4 | 160 + backends/tofino/bf-asm/test/ptf/range.p4 | 185 + backends/tofino/bf-asm/test/ptf/resubmit.p4 | 129 + .../bf-asm/test/ptf/smoke_large_tbls.p4 | 253 + backends/tofino/bf-asm/test/ptf/stats_pi.p4 | 171 + backends/tofino/bf-asm/test/ptf/stful.p4 | 932 + backends/tofino/bf-asm/test/ptf/tofino.p4 | 145 + .../bf-asm/test/ptf/tofino/constants.p4 | 52 + .../test/ptf/tofino/intrinsic_metadata.p4 | 445 + .../bf-asm/test/ptf/tofino/lpf_blackbox.p4 | 53 + .../bf-asm/test/ptf/tofino/meter_blackbox.p4 | 83 + .../bf-asm/test/ptf/tofino/pktgen_headers.p4 | 57 + .../bf-asm/test/ptf/tofino/primitives.p4 | 26 + .../test/ptf/tofino/stateful_alu_blackbox.p4 | 276 + .../bf-asm/test/ptf/tofino/wred_blackbox.p4 | 64 + .../tofino/bf-asm/test/ptf/tofino_diag.p4 | 158 + backends/tofino/bf-asm/test/runtests | 703 + backends/tofino/bf-asm/test/selector0.p4 | 60 + backends/tofino/bf-asm/test/selector1.p4 | 62 + backends/tofino/bf-asm/test/selector2.p4 | 62 + backends/tofino/bf-asm/test/selector3.p4 | 69 + .../tofino/bf-asm/test/stf/exact_match1.p4 | 51 + .../tofino/bf-asm/test/stf/exact_match1.stf | 8 + .../bf-asm/test/stf/hash_action_basic.p4 | 64 + .../bf-asm/test/stf/hash_action_basic.stf | 20 + .../tofino/bf-asm/test/stf/max_counters.p4 | 87 + .../tofino/bf-asm/test/stf/max_counters.stf | 14 + backends/tofino/bf-asm/test/stf/p4c-5198.bfa | 6776 +++++++ backends/tofino/bf-asm/test/stf/p4c-5198.stf | 11 + .../tofino/bf-asm/test/stf/simple_counter.p4 | 73 + .../tofino/bf-asm/test/stf/simple_counter.stf | 15 + backends/tofino/bf-asm/test/ternary_match0.p4 | 34 + backends/tofino/bf-asm/test/ternary_match1.p4 | 40 + .../tofino/bf-asm/test/ternary_match1.stf | 18 + backends/tofino/bf-asm/test/ternary_match2.p4 | 41 + .../tofino/bf-asm/test/ternary_match2.stf | 84 + backends/tofino/bf-asm/test/ternary_match3.p4 | 43 + .../tofino/bf-asm/test/ternary_match3.stf | 7 + backends/tofino/bf-asm/test/ternary_match4.p4 | 44 + .../tofino/bf-asm/test/ternary_match4.stf | 84 + backends/tofino/bf-asm/test/test-bfas-bin | 144 + backends/tofino/bf-asm/test/testgw.p4 | 91 + backends/tofino/bf-asm/test/triv_eth.p4 | 36 + backends/tofino/bf-asm/test/triv_ipv4.p4 | 72 + backends/tofino/bf-asm/test/update_config.py | 70 + backends/tofino/bf-asm/test/validate.py | 25 + .../bf-asm/test/validate_outer_ethernet.p4 | 170 + backends/tofino/bf-asm/test/wide_action1.p4 | 62 + backends/tofino/bf-asm/test/wide_action2.p4 | 81 + backends/tofino/bf-asm/test/wide_action3.p4 | 63 + backends/tofino/bf-asm/tofino/CMakeLists.txt | 72 + backends/tofino/bf-asm/tofino/action_table.h | 29 + backends/tofino/bf-asm/tofino/chip.schema | Bin 0 -> 1168699 bytes backends/tofino/bf-asm/tofino/counter.h | 39 + backends/tofino/bf-asm/tofino/deparser.cpp | 926 + backends/tofino/bf-asm/tofino/exact_match.cpp | 37 + backends/tofino/bf-asm/tofino/exact_match.h | 31 + backends/tofino/bf-asm/tofino/gateway.cpp | 320 + backends/tofino/bf-asm/tofino/gateway.h | 42 + backends/tofino/bf-asm/tofino/input_xbar.cpp | 80 + backends/tofino/bf-asm/tofino/input_xbar.h | 27 + backends/tofino/bf-asm/tofino/instruction.cpp | 56 + backends/tofino/bf-asm/tofino/match_table.cpp | 75 + backends/tofino/bf-asm/tofino/meter.h | 39 + backends/tofino/bf-asm/tofino/parser.cpp | 1631 ++ backends/tofino/bf-asm/tofino/phv.cpp | 66 + backends/tofino/bf-asm/tofino/phv.h | 55 + backends/tofino/bf-asm/tofino/salu_inst.cpp | 196 + backends/tofino/bf-asm/tofino/sram_match.cpp | 95 + backends/tofino/bf-asm/tofino/stage.cpp | 140 + backends/tofino/bf-asm/tofino/stateful.cpp | 77 + backends/tofino/bf-asm/tofino/stateful.h | 33 + .../bf-asm/tofino/template_objects.yaml | 109 + .../tofino/bf-asm/tofino/ternary_match.cpp | 55 + backends/tofino/bf-asm/tofino/ternary_match.h | 40 + backends/tofino/bf-asm/top_level.cpp | 126 + backends/tofino/bf-asm/top_level.h | 61 + backends/tofino/bf-asm/ubits.cpp | 83 + backends/tofino/bf-asm/ubits.h | 178 + backends/tofino/bf-asm/vector.c | 116 + backends/tofino/bf-asm/vector.h | 229 + backends/tofino/bf-asm/version.h | 44 + backends/tofino/bf-asm/walle/README.md | 263 + backends/tofino/bf-asm/walle/chip.py | 167 + backends/tofino/bf-asm/walle/csr.py | 2709 +++ backends/tofino/bf-asm/walle/walle.py | 711 + backends/tofino/bf-asm/widereg.cpp | 29 + backends/tofino/bf-asm/widereg.h | 170 + 579 files changed, 159878 insertions(+) create mode 100644 backends/tofino/bf-asm/.gdbinit create mode 100644 backends/tofino/bf-asm/.gitignore create mode 100644 backends/tofino/bf-asm/CMakeLists.txt create mode 100644 backends/tofino/bf-asm/CPPLINT.cfg create mode 100644 backends/tofino/bf-asm/Options.md create mode 100644 backends/tofino/bf-asm/README.md create mode 100644 backends/tofino/bf-asm/SYNTAX.yaml create mode 100644 backends/tofino/bf-asm/action_bus.cpp create mode 100644 backends/tofino/bf-asm/action_bus.h create mode 100644 backends/tofino/bf-asm/action_table.cpp create mode 100644 backends/tofino/bf-asm/alias_array.h create mode 100644 backends/tofino/bf-asm/alloc.h create mode 100644 backends/tofino/bf-asm/asm-parse.ypp create mode 100644 backends/tofino/bf-asm/asm-types.cpp create mode 100644 backends/tofino/bf-asm/asm-types.h create mode 100644 backends/tofino/bf-asm/atcam_match.cpp create mode 100644 backends/tofino/bf-asm/attached_table.cpp create mode 100644 backends/tofino/bf-asm/b2j.cpp create mode 100644 backends/tofino/bf-asm/bfas.cpp create mode 100644 backends/tofino/bf-asm/bfas.h create mode 100644 backends/tofino/bf-asm/bfdis.cpp create mode 100644 backends/tofino/bf-asm/bfdumpbin.cpp create mode 100755 backends/tofino/bf-asm/bflink create mode 100644 backends/tofino/bf-asm/binary_output.h create mode 100644 backends/tofino/bf-asm/bson.cpp create mode 100644 backends/tofino/bf-asm/bson.h create mode 100644 backends/tofino/bf-asm/checked_array.h create mode 100644 backends/tofino/bf-asm/cmake/Abseil.cmake create mode 100644 backends/tofino/bf-asm/cmake/config.h.in create mode 100644 backends/tofino/bf-asm/constants.h create mode 100644 backends/tofino/bf-asm/counter.cpp create mode 100644 backends/tofino/bf-asm/crash.cpp create mode 100644 backends/tofino/bf-asm/data_switchbox.h create mode 100644 backends/tofino/bf-asm/deparser.cpp create mode 100644 backends/tofino/bf-asm/deparser.h create mode 100644 backends/tofino/bf-asm/depositfield.cpp create mode 100644 backends/tofino/bf-asm/depositfield.h create mode 100644 backends/tofino/bf-asm/disasm.cpp create mode 100644 backends/tofino/bf-asm/disasm.h create mode 100644 backends/tofino/bf-asm/dynhash.cpp create mode 100644 backends/tofino/bf-asm/error_mode.cpp create mode 100644 backends/tofino/bf-asm/error_mode.h create mode 100644 backends/tofino/bf-asm/escape.h create mode 100644 backends/tofino/bf-asm/exact_match.cpp create mode 100644 backends/tofino/bf-asm/exename.cpp create mode 100644 backends/tofino/bf-asm/exename.h create mode 100644 backends/tofino/bf-asm/fdstream.cpp create mode 100644 backends/tofino/bf-asm/fdstream.h create mode 100644 backends/tofino/bf-asm/flexible_headers.cpp create mode 100644 backends/tofino/bf-asm/gateway.cpp create mode 100644 backends/tofino/bf-asm/gtest/asm-types.cpp create mode 100644 backends/tofino/bf-asm/gtest/depositfield.cpp create mode 100644 backends/tofino/bf-asm/gtest/gateway.cpp create mode 100644 backends/tofino/bf-asm/gtest/gtestasm.cpp create mode 100644 backends/tofino/bf-asm/gtest/hashexpr.cpp create mode 100644 backends/tofino/bf-asm/gtest/mirror.cpp create mode 100644 backends/tofino/bf-asm/gtest/parser-test.cpp create mode 100644 backends/tofino/bf-asm/gtest/register-matcher.cpp create mode 100644 backends/tofino/bf-asm/gtest/register-matcher.h create mode 100644 backends/tofino/bf-asm/hash_action.cpp create mode 100644 backends/tofino/bf-asm/hash_dist.cpp create mode 100644 backends/tofino/bf-asm/hash_dist.h create mode 100644 backends/tofino/bf-asm/hashdump.cpp create mode 100644 backends/tofino/bf-asm/hashexpr.cpp create mode 100644 backends/tofino/bf-asm/hashexpr.h create mode 100644 backends/tofino/bf-asm/idletime.cpp create mode 100644 backends/tofino/bf-asm/input_xbar.cpp create mode 100644 backends/tofino/bf-asm/input_xbar.h create mode 100644 backends/tofino/bf-asm/instruction.cpp create mode 100644 backends/tofino/bf-asm/instruction.h create mode 100644 backends/tofino/bf-asm/j2b.cpp create mode 100644 backends/tofino/bf-asm/jbay/CMakeLists.txt create mode 100644 backends/tofino/bf-asm/jbay/chip.schema create mode 100644 backends/tofino/bf-asm/jbay/counter.h create mode 100644 backends/tofino/bf-asm/jbay/deparser.cpp create mode 100644 backends/tofino/bf-asm/jbay/gateway.cpp create mode 100644 backends/tofino/bf-asm/jbay/gateway.h create mode 100644 backends/tofino/bf-asm/jbay/input_xbar.cpp create mode 100644 backends/tofino/bf-asm/jbay/input_xbar.h create mode 100644 backends/tofino/bf-asm/jbay/instruction.cpp create mode 100644 backends/tofino/bf-asm/jbay/match_table.cpp create mode 100644 backends/tofino/bf-asm/jbay/meter.h create mode 100644 backends/tofino/bf-asm/jbay/parser.cpp create mode 100644 backends/tofino/bf-asm/jbay/phv.cpp create mode 100644 backends/tofino/bf-asm/jbay/phv.h create mode 100644 backends/tofino/bf-asm/jbay/salu_inst.cpp create mode 100644 backends/tofino/bf-asm/jbay/stage.cpp create mode 100644 backends/tofino/bf-asm/jbay/stateful.cpp create mode 100644 backends/tofino/bf-asm/jbay/stateful.h create mode 100644 backends/tofino/bf-asm/jbay/template_objects.yaml create mode 100644 backends/tofino/bf-asm/json.cpp create mode 100644 backends/tofino/bf-asm/json.h create mode 100644 backends/tofino/bf-asm/json_diff.cpp create mode 100644 backends/tofino/bf-asm/lex-yaml.l create mode 100644 backends/tofino/bf-asm/map.h create mode 100644 backends/tofino/bf-asm/mask_counter.h create mode 100644 backends/tofino/bf-asm/match_source.h create mode 100644 backends/tofino/bf-asm/match_table.cpp create mode 100644 backends/tofino/bf-asm/meter.cpp create mode 100644 backends/tofino/bf-asm/misc.cpp create mode 100644 backends/tofino/bf-asm/misc.h create mode 100644 backends/tofino/bf-asm/mksizes.cpp create mode 100755 backends/tofino/bf-asm/mktags create mode 100644 backends/tofino/bf-asm/p4_table.cpp create mode 100644 backends/tofino/bf-asm/p4_table.h create mode 100644 backends/tofino/bf-asm/parser-tofino-jbay.cpp create mode 100644 backends/tofino/bf-asm/parser-tofino-jbay.h create mode 100644 backends/tofino/bf-asm/parser.h create mode 100644 backends/tofino/bf-asm/phase0.cpp create mode 100644 backends/tofino/bf-asm/phv.cpp create mode 100644 backends/tofino/bf-asm/phv.h create mode 100644 backends/tofino/bf-asm/power_ctl.h create mode 100644 backends/tofino/bf-asm/primitives.cpp create mode 100644 backends/tofino/bf-asm/proxy_hash.cpp create mode 100644 backends/tofino/bf-asm/reflow.cpp create mode 100644 backends/tofino/bf-asm/register_reference.h create mode 100644 backends/tofino/bf-asm/rvalue_reference_wrapper.h create mode 100644 backends/tofino/bf-asm/salu_inst.cpp create mode 100644 backends/tofino/bf-asm/sections.h create mode 100644 backends/tofino/bf-asm/selection.cpp create mode 100644 backends/tofino/bf-asm/slist.h create mode 100644 backends/tofino/bf-asm/sram_match.cpp create mode 100644 backends/tofino/bf-asm/stage.cpp create mode 100644 backends/tofino/bf-asm/stage.h create mode 100644 backends/tofino/bf-asm/stateful.cpp create mode 100644 backends/tofino/bf-asm/synth2port.cpp create mode 100644 backends/tofino/bf-asm/tables.cpp create mode 100644 backends/tofino/bf-asm/tables.h create mode 100644 backends/tofino/bf-asm/target.cpp create mode 100644 backends/tofino/bf-asm/target.h create mode 100644 backends/tofino/bf-asm/ternary_match.cpp create mode 100644 backends/tofino/bf-asm/test/CMakeLists.txt create mode 100644 backends/tofino/bf-asm/test/acl1.p4 create mode 100644 backends/tofino/bf-asm/test/action_bus1.p4 create mode 100644 backends/tofino/bf-asm/test/action_chain1.p4 create mode 100644 backends/tofino/bf-asm/test/action_chain1.stf create mode 100644 backends/tofino/bf-asm/test/action_chain2.p4 create mode 100644 backends/tofino/bf-asm/test/asm/action_bus_alignment.tfa create mode 100644 backends/tofino/bf-asm/test/asm/action_default_multiple.tfa create mode 100644 backends/tofino/bf-asm/test/asm/always_run.jba create mode 100644 backends/tofino/bf-asm/test/asm/always_run.stf create mode 100644 backends/tofino/bf-asm/test/asm/counter_lrt1.tfa create mode 100644 backends/tofino/bf-asm/test/asm/em1-clot.jba create mode 100644 backends/tofino/bf-asm/test/asm/em1-clot.stf create mode 100644 backends/tofino/bf-asm/test/asm/expected_failures.txt create mode 100644 backends/tofino/bf-asm/test/asm/hash_action_basic.tfa create mode 100644 backends/tofino/bf-asm/test/asm/hash_action_gateway2.stf create mode 100644 backends/tofino/bf-asm/test/asm/hash_action_gateway2.tfa create mode 100644 backends/tofino/bf-asm/test/asm/jbay_sful_syntax.jba create mode 100644 backends/tofino/bf-asm/test/asm/network_tap.bfa create mode 100644 backends/tofino/bf-asm/test/asm/p4c-2257.bfa create mode 100644 backends/tofino/bf-asm/test/asm/p4c-4021.bfa create mode 100644 backends/tofino/bf-asm/test/asm/parser_value_set.tfa create mode 100644 backends/tofino/bf-asm/test/asm/parser_zero_write.jba create mode 100644 backends/tofino/bf-asm/test/asm/rng.tfa create mode 100644 backends/tofino/bf-asm/test/asm/stateful_multiple_output_error.tfa create mode 100644 backends/tofino/bf-asm/test/asm/switch_l2_profile_tofino.tfa create mode 100644 backends/tofino/bf-asm/test/asm/table_action_alias.tfa create mode 100644 backends/tofino/bf-asm/test/asm/table_alias_fields_error.tfa create mode 100644 backends/tofino/bf-asm/test/asm/tor.tfa create mode 100644 backends/tofino/bf-asm/test/bfas_lookup_test/__init__.py create mode 100644 backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_cases.py create mode 100755 backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_test.py create mode 100644 backends/tofino/bf-asm/test/checksum1.p4 create mode 100644 backends/tofino/bf-asm/test/counter1.p4 create mode 100644 backends/tofino/bf-asm/test/counter2.p4 create mode 100644 backends/tofino/bf-asm/test/counter3.p4 create mode 100644 backends/tofino/bf-asm/test/counter4.p4 create mode 100644 backends/tofino/bf-asm/test/counter5.p4 create mode 120000 backends/tofino/bf-asm/test/ctx_json create mode 100644 backends/tofino/bf-asm/test/ctxt_json_ignore create mode 100644 backends/tofino/bf-asm/test/ctxt_json_ignore_new create mode 100644 backends/tofino/bf-asm/test/exact_match0.p4 create mode 100644 backends/tofino/bf-asm/test/exact_match1.p4 create mode 100644 backends/tofino/bf-asm/test/exact_match1.stf create mode 100644 backends/tofino/bf-asm/test/exact_match2.p4 create mode 100644 backends/tofino/bf-asm/test/exact_match3.p4 create mode 100644 backends/tofino/bf-asm/test/exact_match4.p4 create mode 100644 backends/tofino/bf-asm/test/exact_match5.p4 create mode 100644 backends/tofino/bf-asm/test/exact_match6.p4 create mode 100644 backends/tofino/bf-asm/test/exact_match7.p4 create mode 100644 backends/tofino/bf-asm/test/exact_match8.p4 create mode 100644 backends/tofino/bf-asm/test/exact_match9.p4 create mode 100644 backends/tofino/bf-asm/test/exact_match_valid1.p4 create mode 100644 backends/tofino/bf-asm/test/expected_failures.txt create mode 100644 backends/tofino/bf-asm/test/gateway1.p4 create mode 100644 backends/tofino/bf-asm/test/gateway2.p4 create mode 100644 backends/tofino/bf-asm/test/gateway3.p4 create mode 100644 backends/tofino/bf-asm/test/gateway4.p4 create mode 100644 backends/tofino/bf-asm/test/gateway5.p4 create mode 100644 backends/tofino/bf-asm/test/gateway6.p4 create mode 100644 backends/tofino/bf-asm/test/gateway7.p4 create mode 100644 backends/tofino/bf-asm/test/hash_index0.p4 create mode 100644 backends/tofino/bf-asm/test/hash_index1.p4 create mode 100644 backends/tofino/bf-asm/test/hash_index2.p4 create mode 100644 backends/tofino/bf-asm/test/hash_index3.p4 create mode 100644 backends/tofino/bf-asm/test/hash_index5.p4 create mode 100644 backends/tofino/bf-asm/test/instruct1.p4 create mode 100644 backends/tofino/bf-asm/test/instruct2.p4 create mode 100644 backends/tofino/bf-asm/test/instruct3.p4 create mode 100644 backends/tofino/bf-asm/test/instruct4.p4 create mode 100644 backends/tofino/bf-asm/test/instruct5.p4 create mode 100644 backends/tofino/bf-asm/test/internal/brig/expected_failures.txt create mode 100644 backends/tofino/bf-asm/test/internal/brig/test_config_123_meter_2.p4 create mode 100644 backends/tofino/bf-asm/test/internal/brig/test_config_223_simple_set_metadata.p4 create mode 100644 backends/tofino/bf-asm/test/internal/debug_issue_1_invalid_action_pack_format.p4 create mode 100644 backends/tofino/bf-asm/test/internal/debug_issue_2_action_data_bus.PRAGMA create mode 100644 backends/tofino/bf-asm/test/internal/debug_issue_3_7_way_table.p4 create mode 100644 backends/tofino/bf-asm/test/internal/debug_issue_4_small_exact_match_key.p4 create mode 100644 backends/tofino/bf-asm/test/internal/dileep.p4 create mode 100644 backends/tofino/bf-asm/test/internal/dileep10.p4 create mode 100644 backends/tofino/bf-asm/test/internal/dileep11.p4 create mode 100644 backends/tofino/bf-asm/test/internal/dileep12.p4 create mode 100644 backends/tofino/bf-asm/test/internal/dileep2.p4 create mode 100644 backends/tofino/bf-asm/test/internal/dileep3.p4 create mode 100644 backends/tofino/bf-asm/test/internal/dileep4.p4 create mode 100644 backends/tofino/bf-asm/test/internal/dileep5.PRAGMA create mode 100644 backends/tofino/bf-asm/test/internal/dileep6.PHV_BUG create mode 100644 backends/tofino/bf-asm/test/internal/dileep7-b.p4 create mode 100644 backends/tofino/bf-asm/test/internal/dileep7.PRAGMA create mode 100644 backends/tofino/bf-asm/test/internal/dileep8.p4 create mode 100644 backends/tofino/bf-asm/test/internal/dileep9.PRAGMA create mode 100644 backends/tofino/bf-asm/test/internal/google-tor/lag.p4 create mode 100644 backends/tofino/bf-asm/test/internal/google-tor/tor.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_7_storm_control.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_100_hash_action.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_101_switch_msdc.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_102_clone.NOT_READY create mode 100644 backends/tofino/bf-asm/test/internal/test_config_102_clone.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_103_first_phase_0.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_10_new_crossbar_allocation.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_114_simple_drop.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_115_hash_parity_groups.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_116_predication_with_condition.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_117_first_tcam_range.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_118_tcam_range_2.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_119_tcam_range_3.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_11_simple_gateway_table.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_120_tcam_range_4.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_121_tcam_range_5.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_122_tcam_range_6.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_123_meter_2.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_124_meter_3.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_125_meter_pre_color.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_126_meter_pre_color_2.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_127_meter_pre_color_3.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_128_table_placement_bug.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_12_no_overhead.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_130_test_default_action.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_132_meter_pre_color_4.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_134_stage_deps.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_135_tcam_range_7.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_136_tcam_error_detection.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_137_tcam_error_detection_2.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_138_tcam_error_detection_3.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_139_tcam_error_detection_4.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_13_first_selection.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_140_table_counter.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_142_stateful_bfd.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_143_packing_constants.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_144_recirculate.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_145_shift_primitives.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_146_two_drops.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_147_subtract_primitive.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_148_action_profile.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_149_signed_and_saturating_add_sub.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_14_auto_immediate_action_data.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_150_action_bus_allocation.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_151_action_bus_allocation_2.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_152_stateful_simple_cntr.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_153_stateful_simple_cntr_with_output.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_154_stateful_sampling.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_155_stateful_3_alus.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_156_indirect_stateful_cntr.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_157_random_number_generator.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_158_share_vliw.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_159_stateful_using_phv_field.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_15_wide_key.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_160_stateful_single_bit_mode.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_161_new_primitives.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_162_add_header_init.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_163_stateful_table_math_unit.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_164_stateful_deterministic_sampling.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_165_stateful_bfd_failure_detection.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_166_stateful_generic_counter.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_167_stateful_flowlet_switching.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_168_meter_bug.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_169_stateful_sflow_sequence.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_16_action_packing_multi_entry_with_pad.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_170_stateful_selection_table_update.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_171_stateful_conga.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_172_stateful_heavy_hitter.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_173_stateful_bloom_filter.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_175_match_table_with_no_key.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_176_extend_crc16.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_177_meter_test.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_178_hash_action.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_179_check_if_sequential_action_used.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_17_action_packing_wide_with_pad.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_180_first_proxy_hash.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_181_first_alg_tcam.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_182_warp_primitive.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_183_sample_e2e.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_184_stateful_bug1.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_185_first_lpf.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_186_hlir_modify.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_187_proxy_hash_2.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_188_action_data_overflow.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_189_stat_with_lrt.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_18_first_bit_xor.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_190_modify_with_expr.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_191_invalidate.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_192_stateful_driven_by_hash.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_193_indirect_stats_no_reads.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_194_same_action_param.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_195_stateful_predicate_output.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_196_hit_miss.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_197_default_next_table.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_198_shared_action_profile.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_199_stateful_constant_index.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_19_immediate_but_no_action_data_table.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_1_ternary_match_crossbar.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_200_counter_constant_index.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_201_meter_constant_index.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_202_write_same_byte.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_203_first_reduction_or.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_204_no_tables_in_stage0.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_205_modify_field_from_hash.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_206_stateful_logging.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_207_not_gateway.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_208_table_no_key.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_209_pack_hash_dist.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_20_table_dependencies.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_21_tcam_vpns.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_22_direct_mapped_exact.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_23_same_container_modified.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_24_action_entries_pragma.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_25_no_reads_for_table.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_26_direct_add_primitive.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_2_action_data_table_sizing.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_30_action_data_imm_param.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_31_action_data_imm_imm.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_32_action_data_imm_param_imm.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_33_action_data_paramx3.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_34_action_data_1_bit_params.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_35_action_data_1_bit_params_and_imms.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_36_action_data_field_param.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_37_action_data_field_field.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_38_action_data_field_same_container.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_39_action_data_add_to_field.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_3_add_to_field.PHV_BUG create mode 100644 backends/tofino/bf-asm/test/internal/test_config_40_action_data_bit_xor.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_41_action_data_remove_header.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_42_action_data_add_header.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_43_action_data_drop.PHV_BUG create mode 100644 backends/tofino/bf-asm/test/internal/test_config_44_action_data_immediate.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_45_action_data_immediate_param_and_constant.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_46_action_data_big_constant.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_47_action_data_big_constant_immediate.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_48_action_data_bit_masked_set.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_49_action_data_bit_masked_set_immediate.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_4_modify_field.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_50_action_data_different_size_fields.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_51_action_data_same_parameter_used_multiple.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_52_copy_header.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_53_ternary_swizzle.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_54_modify_field_different_size.PHV_BUG create mode 100644 backends/tofino/bf-asm/test/internal/test_config_55_generate_digest.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_56_iterate_through_packing.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_57_tcam_with_44_bits_no_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_58_tcam_with_40_bits.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_59_tcam_with_44_bits_and_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_5_sram_allocation.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_60_tcam_with_44_and_no_version_high_nibble.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_61_tcam_with_44_bits_and_no_version_low_nibble.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_62_tcam_with_48_bits_and_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_63_tcam_with_48_bits_and_no_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_64_tcam_with_84_bits_and_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_64_tcam_with_84_bits_high_nibble_and_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_65_tcam_with_84_bits_low_nibble_and_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_66_tcam_with_84_bits_high_nibble_no_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_67_tcam_with_84_bits_low_nibble_no_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_68_tcam_with_88_bits_and_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_69_tcam_with_88_bits_no_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_6_sram_and_tcam_allocation.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_70_tcam_with_128_bits_and_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_71_tcam_with_128_bits_and_no_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_72_tcam_with_172_bits_and_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_72_tcam_with_172_bits_high_nibble_and_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_73_tcam_with_172_bits_low_nibble_and_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_74_tcam_with_172_bits_low_nibble_no_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_75_tcam_with_176_bits_no_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_76_tcam_with_176_bits_and_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_77_tcam_with_216_bits_and_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_78_tcam_with_220_bits_high_nibble_and_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_79_tcam_with_220_bits_high_nibble_no_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_80_tcam_with_220_bits_low_nibble_no_version.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_81_indirect_action_data_default.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_82_param_sharing.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_83_no_immediate_when_indirect_action_table.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_84_simple_wide_exact_match.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_85_table_ordering.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_86_multiple_action_widths_for_indirect_action.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_87_share_parameter_for_different_containers.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_88_testing_action_data_allocation_3.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_89_testing_action_data_allocation_3_with_partial_ram.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_8_next_table.BUG create mode 100644 backends/tofino/bf-asm/test/internal/test_config_90_testing_action_data_allocation_3_with_fields_in_overhead.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_91_gateway_with_split_table.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_92_bit_xor_10_bits.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_93_push_and_pop.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_94_action_constant_alignment.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_95_first_meter_table.NOT_READY create mode 100644 backends/tofino/bf-asm/test/internal/test_config_96_hash_data.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_97_unrelated_tables.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_98_multiple_control_flow.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_99_share_exact_match_key.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_config_9_no_ternary_indirection.p4 create mode 100644 backends/tofino/bf-asm/test/internal/test_tp_1_one_table_spill.p4 create mode 100644 backends/tofino/bf-asm/test/internal/vk_basic_ipv4.PHV_BUG create mode 100644 backends/tofino/bf-asm/test/internal/vk_basic_ipv4_20150706.p4 create mode 100644 backends/tofino/bf-asm/test/internal/vk_basic_ipv4_subset.p4 create mode 100755 backends/tofino/bf-asm/test/jdiff.sh create mode 100644 backends/tofino/bf-asm/test/mac_rewrite.p4 create mode 100644 backends/tofino/bf-asm/test/mau/01-FlexCounter.p4 create mode 100644 backends/tofino/bf-asm/test/mau/02-FlexCounterActionProfile.p4 create mode 100644 backends/tofino/bf-asm/test/mau/02-FullPHV1.p4 create mode 100644 backends/tofino/bf-asm/test/mau/04-FieldProblem.p4 create mode 100644 backends/tofino/bf-asm/test/mau/07-MacAddrCheck.p4 create mode 100644 backends/tofino/bf-asm/test/mau/08-MacAddrCheck1.p4 create mode 100644 backends/tofino/bf-asm/test/mau/08-MultiProtocolIfElse.p4 create mode 100644 backends/tofino/bf-asm/test/mau/09-MacAddrCheck2.p4 create mode 100644 backends/tofino/bf-asm/test/mau/10-AssignChooseSource.p4 create mode 100644 backends/tofino/bf-asm/test/mau/12-Counters.p4 create mode 100644 backends/tofino/bf-asm/test/mau/12-SmallToBigFieldWithMask8.p4 create mode 100644 backends/tofino/bf-asm/test/mau/14-Counter.p4 create mode 100644 backends/tofino/bf-asm/test/mau/15-MultiProtocolIfElseMinimal.p4 create mode 100644 backends/tofino/bf-asm/test/mau/16-NoHeaders.p4 create mode 100644 backends/tofino/bf-asm/test/mau/19-SimpleTrill.p4 create mode 100644 backends/tofino/bf-asm/test/mau/20-SimpleTrillTwoStep.p4 create mode 100644 backends/tofino/bf-asm/test/mau/22-BigToSmallFieldWithMask8.p4 create mode 100644 backends/tofino/bf-asm/test/mau/22-SimpleTrillThreeStep.p4 create mode 100644 backends/tofino/bf-asm/test/mau/action_params.p4 create mode 100644 backends/tofino/bf-asm/test/mau/basic_ipv4_selection.p4 create mode 100644 backends/tofino/bf-asm/test/mau/do_nothing.p4 create mode 100644 backends/tofino/bf-asm/test/mau/expected_failures.txt create mode 100644 backends/tofino/bf-asm/test/mau/instruct1.p4 create mode 100644 backends/tofino/bf-asm/test/mau/selector1.p4 create mode 100644 backends/tofino/bf-asm/test/mau/ternary_match0.p4 create mode 100644 backends/tofino/bf-asm/test/meter_test1.p4 create mode 100644 backends/tofino/bf-asm/test/parser1.p4 create mode 100644 backends/tofino/bf-asm/test/parser2.p4 create mode 100644 backends/tofino/bf-asm/test/parser3.p4 create mode 100644 backends/tofino/bf-asm/test/parser_dc_full.p4 create mode 100644 backends/tofino/bf-asm/test/port_vlan_mapping.p4 create mode 100644 backends/tofino/bf-asm/test/proxy_hash1.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/action_spec_format.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/alpm_test.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/basic_ipv4.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/basic_ipv4_selector.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/basic_switching.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/dkm.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/drivers_test.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/easy.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/easy_ternary.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/ecmp_pi.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/emulation.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/exm_direct.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/exm_direct_1.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/exm_indirect_1.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/exm_smoke_test.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/fast_reconfig.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/fr_test.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/includes/headers.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/includes/parser.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/iterator.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/mau_mem_test.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/mau_tcam_test.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/mau_test.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/meters.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/multi_device.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/multicast_scale.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/multicast_test.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/p4features.h create mode 100644 backends/tofino/bf-asm/test/ptf/parser_intr_md.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/pcie_pkt_test.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/pctr.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/perf_test.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/perf_test_alpm.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/pgrs.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/pktgen_headers.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/pvs.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/range.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/resubmit.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/smoke_large_tbls.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/stats_pi.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/stful.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/tofino.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/tofino/constants.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/tofino/intrinsic_metadata.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/tofino/lpf_blackbox.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/tofino/meter_blackbox.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/tofino/pktgen_headers.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/tofino/primitives.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/tofino/stateful_alu_blackbox.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/tofino/wred_blackbox.p4 create mode 100644 backends/tofino/bf-asm/test/ptf/tofino_diag.p4 create mode 100755 backends/tofino/bf-asm/test/runtests create mode 100644 backends/tofino/bf-asm/test/selector0.p4 create mode 100644 backends/tofino/bf-asm/test/selector1.p4 create mode 100644 backends/tofino/bf-asm/test/selector2.p4 create mode 100644 backends/tofino/bf-asm/test/selector3.p4 create mode 100644 backends/tofino/bf-asm/test/stf/exact_match1.p4 create mode 100644 backends/tofino/bf-asm/test/stf/exact_match1.stf create mode 100644 backends/tofino/bf-asm/test/stf/hash_action_basic.p4 create mode 100644 backends/tofino/bf-asm/test/stf/hash_action_basic.stf create mode 100644 backends/tofino/bf-asm/test/stf/max_counters.p4 create mode 100644 backends/tofino/bf-asm/test/stf/max_counters.stf create mode 100644 backends/tofino/bf-asm/test/stf/p4c-5198.bfa create mode 100644 backends/tofino/bf-asm/test/stf/p4c-5198.stf create mode 100644 backends/tofino/bf-asm/test/stf/simple_counter.p4 create mode 100644 backends/tofino/bf-asm/test/stf/simple_counter.stf create mode 100644 backends/tofino/bf-asm/test/ternary_match0.p4 create mode 100644 backends/tofino/bf-asm/test/ternary_match1.p4 create mode 100644 backends/tofino/bf-asm/test/ternary_match1.stf create mode 100644 backends/tofino/bf-asm/test/ternary_match2.p4 create mode 100644 backends/tofino/bf-asm/test/ternary_match2.stf create mode 100644 backends/tofino/bf-asm/test/ternary_match3.p4 create mode 100644 backends/tofino/bf-asm/test/ternary_match3.stf create mode 100644 backends/tofino/bf-asm/test/ternary_match4.p4 create mode 100644 backends/tofino/bf-asm/test/ternary_match4.stf create mode 100755 backends/tofino/bf-asm/test/test-bfas-bin create mode 100644 backends/tofino/bf-asm/test/testgw.p4 create mode 100644 backends/tofino/bf-asm/test/triv_eth.p4 create mode 100644 backends/tofino/bf-asm/test/triv_ipv4.p4 create mode 100644 backends/tofino/bf-asm/test/update_config.py create mode 100755 backends/tofino/bf-asm/test/validate.py create mode 100644 backends/tofino/bf-asm/test/validate_outer_ethernet.p4 create mode 100644 backends/tofino/bf-asm/test/wide_action1.p4 create mode 100644 backends/tofino/bf-asm/test/wide_action2.p4 create mode 100644 backends/tofino/bf-asm/test/wide_action3.p4 create mode 100644 backends/tofino/bf-asm/tofino/CMakeLists.txt create mode 100644 backends/tofino/bf-asm/tofino/action_table.h create mode 100644 backends/tofino/bf-asm/tofino/chip.schema create mode 100644 backends/tofino/bf-asm/tofino/counter.h create mode 100644 backends/tofino/bf-asm/tofino/deparser.cpp create mode 100644 backends/tofino/bf-asm/tofino/exact_match.cpp create mode 100644 backends/tofino/bf-asm/tofino/exact_match.h create mode 100644 backends/tofino/bf-asm/tofino/gateway.cpp create mode 100644 backends/tofino/bf-asm/tofino/gateway.h create mode 100644 backends/tofino/bf-asm/tofino/input_xbar.cpp create mode 100644 backends/tofino/bf-asm/tofino/input_xbar.h create mode 100644 backends/tofino/bf-asm/tofino/instruction.cpp create mode 100644 backends/tofino/bf-asm/tofino/match_table.cpp create mode 100644 backends/tofino/bf-asm/tofino/meter.h create mode 100644 backends/tofino/bf-asm/tofino/parser.cpp create mode 100644 backends/tofino/bf-asm/tofino/phv.cpp create mode 100644 backends/tofino/bf-asm/tofino/phv.h create mode 100644 backends/tofino/bf-asm/tofino/salu_inst.cpp create mode 100644 backends/tofino/bf-asm/tofino/sram_match.cpp create mode 100644 backends/tofino/bf-asm/tofino/stage.cpp create mode 100644 backends/tofino/bf-asm/tofino/stateful.cpp create mode 100644 backends/tofino/bf-asm/tofino/stateful.h create mode 100644 backends/tofino/bf-asm/tofino/template_objects.yaml create mode 100644 backends/tofino/bf-asm/tofino/ternary_match.cpp create mode 100644 backends/tofino/bf-asm/tofino/ternary_match.h create mode 100644 backends/tofino/bf-asm/top_level.cpp create mode 100644 backends/tofino/bf-asm/top_level.h create mode 100644 backends/tofino/bf-asm/ubits.cpp create mode 100644 backends/tofino/bf-asm/ubits.h create mode 100644 backends/tofino/bf-asm/vector.c create mode 100644 backends/tofino/bf-asm/vector.h create mode 100644 backends/tofino/bf-asm/version.h create mode 100644 backends/tofino/bf-asm/walle/README.md create mode 100644 backends/tofino/bf-asm/walle/chip.py create mode 100644 backends/tofino/bf-asm/walle/csr.py create mode 100755 backends/tofino/bf-asm/walle/walle.py create mode 100644 backends/tofino/bf-asm/widereg.cpp create mode 100644 backends/tofino/bf-asm/widereg.h diff --git a/backends/tofino/bf-asm/.gdbinit b/backends/tofino/bf-asm/.gdbinit new file mode 100644 index 00000000000..90702882411 --- /dev/null +++ b/backends/tofino/bf-asm/.gdbinit @@ -0,0 +1,402 @@ +# Copyright (C) 2024 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# +# SPDX-License-Identifier: Apache-2.0 + +# vim: ft=python +set print object +set unwindonsignal on +set unwind-on-terminating-exception on + +if $_isvoid($bpnum) + break __assert_fail + break error + break bug +end + +define d + call ::dump($arg0) +end + + +python +def template_split(s): + parts = [] + bracket_level = 0 + current = [] + for c in (s): + if c == "," and bracket_level == 1: + parts.append("".join(current)) + current = [] + else: + if c == '>': + bracket_level -= 1 + if bracket_level > 0: + current.append(c) + if c == '<': + bracket_level += 1 + parts.append("".join(current)) + return parts + +def vec_begin(vec): + return vec['_M_impl']['_M_start'] +def vec_end(vec): + return vec['_M_impl']['_M_finish'] +def vec_size(vec): + return int(vec_end(vec) - vec_begin(vec)) +def vec_at(vec, i): + return (vec_begin(vec) + i).dereference() + +class bitvecPrinter(object): + "Print a bitvec" + def __init__(self, val): + self.val = val + def to_string(self): + data = self.val['data'] + rv = "" + size = self.val['size'] + ptr = self.val['ptr'] + unitsize = ptr.type.target().sizeof * 8 + while size > 1: + data = ptr.dereference() + i = 0 + while i < unitsize: + if (rv.__len__() % 120 == 119): rv += ':' + elif (rv.__len__() % 30 == 29): rv += ' ' + elif (rv.__len__() % 6 == 5): rv += '_' + if (data & 1) == 0: + rv += "0" + else: + rv += "1" + data >>= 1 + i += 1 + ptr += 1 + size -= 1 + data = ptr.dereference() + while rv == "" or data > 0: + if (rv.__len__() % 120 == 119): rv += ':' + elif (rv.__len__() % 30 == 29): rv += ' ' + elif (rv.__len__() % 6 == 5): rv += '_' + if (data & 1) == 0: + rv += "0" + else: + rv += "1" + data >>= 1 + return rv +class value_t_Printer(object): + "Print a value_t" + def __init__(self, val): + self.val = val + def to_string(self): + typ = self.val['type'] + if typ == 0: # tINT + return str(self.val['i']) + elif typ == 1: # tBIGINT + v = self.val['bigi'] + data = v['data'] + size = v['size'] + val = 0 + while size > 0: + val <<= 64 + val += data.dereference() + size -= 1 + data += 1 + return str(val) + elif typ == 2: # tRANGE + return str(self.val['lo']) + '..' + str(self.val['hi']) + elif typ == 3: # tSTR + return self.val['s'] + elif typ == 4: # tMATCH + return self.val['m'] + elif typ == 5: # tBIGMATCH + return self.val['bigm'] + elif typ == 6: # tVEC + return "vector of %d elements" % self.val['vec']['size'] + elif typ == 7: # tMAP + return "map of %d elements" % self.val['map']['size'] + elif typ == 8: # tCMD + cmd = self.val['vec']['data'] + count = self.val['vec']['size'] + rv = str(cmd.dereference()) + rv += "(" + while count > 1: + count -= 1 + cmd += 1 + rv += str(cmd.dereference()) + if count > 1: + rv += ", " + rv += ")" + return rv; + else: + return "" + class _vec_iter: + def __init__(self, data, size): + self.data = data + self.size = size + self.counter = -1 + def __iter__(self): + return self + def __next__(self): + self.counter += 1 + if self.counter >= self.size: + raise StopIteration + item = self.data.dereference() + self.data += 1 + return ("[%d]" % self.counter, item) + def next(self): return self.__next__() + class _map_iter: + def __init__(self, data, size): + self.data = data + self.size = size + def __iter__(self): + return self + def __next__(self): + self.size -= 1 + if self.size < 0: + raise StopIteration + item = self.data.dereference() + self.data += 1 + return ("[" + str(item['key']) + "]", item['value']) + def next(self): return self.__next__() + + class _not_iter: + def __init__(self): + pass + def __iter__(self): + return self + def __next__(self): + raise StopIteration + def next(self): return self.__next__() + def children(self): + typ = self.val['type'] + if typ == 6: + vec = self.val['vec'] + return self._vec_iter(vec['data'], vec['size']) + elif typ == 7: + map = self.val['map'] + return self._map_iter(map['data'], map['size']) + else: + return self._not_iter() +class value_t_VECTOR_Printer(object): + "Print a VECTOR(value_t)" + def __init__(self, val): + self.val = val + def to_string(self): + return "vector of %d elements" % self.val['size'] + class _iter: + def __init__(self, data, size): + self.data = data + self.size = size + self.counter = -1 + def __iter__(self): + return self + def __next__(self): + self.counter += 1 + if self.counter >= self.size: + raise StopIteration + item = self.data.dereference() + self.data += 1 + return ("[%d]" % self.counter, item) + def next(self): return self.__next__() + def children(self): + return self._iter(self.val['data'], self.val['size']) +class pair_t_VECTOR_Printer(object): + "Print a VECTOR(pair_t)" + def __init__(self, val): + self.val = val + def to_string(self): + return "map of %d elements" % self.val['size'] + class _iter: + def __init__(self, data, size): + self.data = data + self.size = size + def __iter__(self): + return self + def __next__(self): + self.size -= 1 + if self.size < 0: + raise StopIteration + item = self.data.dereference() + self.data += 1 + return ("[" + str(item['key']) + "]", item['value']) + def next(self): return self.__next__() + def children(self): + return self._iter(self.val['data'], self.val['size']) +class ordered_map_Printer: + "Print an ordered_map<>" + def __init__(self, val): + self.val = val + self.args = template_split(val.type.tag) + self.eltype = gdb.lookup_type('std::pair<' + self.args[0] + ' const,' + self.args[1] + '>') + def to_string(self): + it = self.val['data']['_M_impl']['_M_node']['_M_next'] + e = self.val['data']['_M_impl']['_M_node'].address + if it == e: # empty map + return "{}" + else: + return None + class _iter: + def __init__(self, eltype, it, e): + self.eltype = eltype + self.it = it + self.e = e + def __iter__(self): + return self + def __next__(self): + if self.it == self.e: + raise StopIteration + el = (self.it + 1).cast(self.eltype.pointer()).dereference() + self.it = self.it.dereference()['_M_next'] + return ("[" + str(el['first']) + "]", el['second']); + def next(self): return self.__next__() + def children(self): + return self._iter(self.eltype, self.val['data']['_M_impl']['_M_node']['_M_next'], + self.val['data']['_M_impl']['_M_node'].address) +class InputXbar_Group_Printer: + "Print an InputXbar::Group" + def __init__(self, val): + self.val = val + def to_string(self): + types = [ 'invalid', 'exact', 'ternary', 'byte', 'gateway', 'xcmp' ] + t = int(self.val['type']) + if t >= 0 and t < len(types): + rv = types[t] + else: + rv = '' % int(self.val['type']) + rv += ' group ' + str(self.val['index']) + return rv +class ActionBusSource_Printer: + "Print an ActionBusSource" + def __init__(self, val): + self.val = val + def to_string(self): + try: + types = [ "None", "Field", "HashDist", "HashDistPair", "RandomGen", + "TableOutput", "TableColor", "TableAddress", "Ealu", "XCmp", + "NameRef", "ColorRef", "AddressRef" ] + t = int(self.val['type']) + if t >= 0 and t < len(types): + rv = types[t] + else: + rv = '' % int(self.val['type']) + if t == 9: # XCMP on one line without children + rv += "[" + str(self.val['xcmp_group']) + ":" + str(self.val['xcmp_byte']) + "]" + except Exception as e: + rv += "{crash: "+str(e)+"}" + return rv + class _iter: + def __init__(self, val, type): + self.val = val + self.type = type + self.count = 0 + def __iter__(self): + return self + def __next__(self): + self.count = self.count + 1 + if self.type == 3: + if self.count == 1: + return ("hd1", self.val['hd1']) + elif self.count == 2: + return ("hd2", self.val['hd2']) + else: + raise StopIteration + #elif self.type == 9: + # XCmp on one line without children + # if self.count == 1: + # return ("group", self.val['xcmp_group']) + # elif self.count == 2: + # return ("byte", self.val['xcmp_byte']) + elif self.count > 1: + raise StopIteration + elif self.type == 1: + return ("field", self.val['field'].dereference()) + elif self.type == 2: + return ("hd", self.val['hd']) + elif self.type == 4: + return ("rng", self.val['rng']) + elif self.type == 5 or self.type == 6 or self.type == 7: + return ("table", self.val['table']) + elif self.type == 10 or self.type == 11 or self.type == 12: + return ("name_ref", self.val['name_ref']) + raise StopIteration + def next(self): return self.__next__() + def children(self): + return self._iter(self.val, int(self.val['type'])) + +class PhvRef_Printer: + "Print a Phv::Ref" + def __init__(self, val): + self.val = val + def to_string(self): + threads = [ "ig::", "eg::", "gh::" ] + rv = threads[self.val['gress_']] + str(self.val['name_']) + if self.val['lo'] >= 0: + rv += '(' + str(self.val['lo']) + if self.val['hi'] >= 0: + rv += '..' + str(self.val['hi']) + rv += ')' + return rv + +class Mem_Printer: + "Print a MemUnit or subclass" + def __init__(self, val, big, small): + self.val = val + self.big = big + self.small = small + def to_string(self): + if self.val['stage'] > -32768: + return "%s(%d,%d,%d)" % (self.big, self.val['stage'], self.val['row'], self.val['col']) + if self.val['row'] >= 0: + return "%s(%d,%d)" % (self.big, self.val['row'], self.val['col']) + return "%s(%d)" % (self.small, self.val['col']) + +def bfas_pp(val): + if val.type.tag == 'bitvec': + return bitvecPrinter(val) + if val.type.tag == 'value_t': + return value_t_Printer(val) + if val.type.tag == 'value_t_VECTOR': + return value_t_VECTOR_Printer(val) + if val.type.tag == 'pair_t_VECTOR': + return pair_t_VECTOR_Printer(val) + if str(val.type.tag).startswith('ordered_map<'): + return ordered_map_Printer(val) + if val.type.tag == 'InputXbar::Group': + return InputXbar_Group_Printer(val) + if val.type.tag == 'ActionBusSource': + return ActionBusSource_Printer(val) + if val.type.tag == 'Phv::Ref': + return PhvRef_Printer(val) + if val.type.tag == 'SRamMatchTable::Ram': + return Mem_Printer(val, 'Ram', 'Lamb') + if val.type.tag == 'MemUnit': + return Mem_Printer(val, 'Mem', 'Mem') + return None + +try: + found = False + for i in range(len(gdb.pretty_printers)): + try: + if gdb.pretty_printers[i].__name__ == "bfas_pp": + gdb.pretty_printers[i] = bfas_pp + found = True + except: + pass + if not found: + gdb.pretty_printers.append(bfas_pp) +except: + pass + +end diff --git a/backends/tofino/bf-asm/.gitignore b/backends/tofino/bf-asm/.gitignore new file mode 100644 index 00000000000..0651a09e2dc --- /dev/null +++ b/backends/tofino/bf-asm/.gitignore @@ -0,0 +1,27 @@ +Makefile.in +aclocal.m4 +autom4te.cache +build +compile +configure +depcomp +install-sh +missing +ylwrap +*.o +*.d +*.out +*.tofino +*.pyc +gen +templates +asm-parse.c +lex-yaml.c +json2cpp +json_diff +mksizes +reflow +tags +tfas +y.output +faillog.txt diff --git a/backends/tofino/bf-asm/CMakeLists.txt b/backends/tofino/bf-asm/CMakeLists.txt new file mode 100644 index 00000000000..bfdfabdf151 --- /dev/null +++ b/backends/tofino/bf-asm/CMakeLists.txt @@ -0,0 +1,414 @@ +# Copyright (C) 2024 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# +# SPDX-License-Identifier: Apache-2.0 + +####### Tofino assembler +cmake_minimum_required (VERSION 3.16.3 FATAL_ERROR) + +find_program(CCACHE_PROGRAM ccache) +if(CCACHE_PROGRAM) + MESSAGE(STATUS "Enabling ccache") + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}") +endif() + +project (BFASM) + +MESSAGE("-- Adding bf-asm") + +OPTION(ASAN_ENABLED "Enable ASAN checks" OFF) + +set (BFASM_LIB_DEPS dynhashStatic) + +find_package (BISON REQUIRED) +find_package (FLEX REQUIRED) +find_package(absl REQUIRED) + +# other required libraries +include (CheckLibraryExists) +# check includes +include (CheckIncludeFile) +check_include_file (execinfo.h HAVE_EXECINFO_H) +check_include_file (ucontext.h HAVE_UCONTEXT_H) + +set(CMAKE_CXX_FLAGS "") # clear CXX_FLAGS +# TODO: Fix build warnings with -Wall and enable it. +# add_cxx_compiler_option ("-Wall") +# add_cxx_compiler_option ("-Wextra") +# add_cxx_compiler_option ("-Wno-unused") +# add_cxx_compiler_option ("-Wno-unused-parameter") +# add_cxx_compiler_option ("-Wno-pragmas") +# add_cxx_compiler_option ("-Wno-unknown-pragmas") +add_cxx_compiler_option ("-Wno-overloaded-virtual") +add_cxx_compiler_option ("-Wno-deprecated") +if (${CMAKE_SYSTEM_PROCESSOR} MATCHES i386|i586|i686) + # on 32-bit platforms we get a lot of warnings when using the error macros + add_cxx_compiler_option("-Wno-write-strings") +endif() +if (ENABLE_BAREFOOT_INTERNAL) + add_definitions("-DBAREFOOT_INTERNAL=1") +endif() + +message(STATUS "P4C ${P4C_SOURCE_DIR}") +macro(get_schema_version schema_file schema_var) + execute_process( + COMMAND python3 -c "from ${schema_file} import get_schema_version;print(get_schema_version(), end='', flush=True)" + OUTPUT_VARIABLE __schema_version + RESULT_VARIABLE __schema_errcode + ERROR_VARIABLE __schema_errstr + WORKING_DIRECTORY ${P4C_SOURCE_DIR}/backends/tofino/compiler_interfaces/schemas) + if (${__schema_errcode}) + MESSAGE(FATAL_ERROR "Error retrieving ${schema_file} version ${__schema_errstr}") + endif() + set(${schema_var} ${__schema_version}) +endmacro(get_schema_version) +# Now force cmake to rerun if any of the files that we depend on versions for +# change: context and manifest for now +# We generate a pair of dummy dependency files will be ignored +set(SCHEMA_FILES + ${P4C_SOURCE_DIR}/backends/tofino/compiler_interfaces/schemas/context_schema.py + ${P4C_SOURCE_DIR}/backends/tofino/compiler_interfaces/schemas/manifest_schema.py + ${P4C_SOURCE_DIR}/backends/tofino/compiler_interfaces/schemas/phv_schema.py + ${P4C_SOURCE_DIR}/backends/tofino/compiler_interfaces/schemas/power_schema.py + ${P4C_SOURCE_DIR}/backends/tofino/compiler_interfaces/schemas/resources_schema.py + ) +foreach (f ${SCHEMA_FILES}) + configure_file(${f} ${CMAKE_BINARY_DIR}/${f}.dep) +endforeach() + +get_schema_version(context_schema CONTEXT_SCHEMA_VERSION) +MESSAGE(STATUS "Found context schema version ${CONTEXT_SCHEMA_VERSION}") +add_definitions("-DCONTEXT_SCHEMA_VERSION=\"${CONTEXT_SCHEMA_VERSION}\"") +set (BFN_P4C_LIB_DIR ${P4C_SOURCE_DIR}/lib) +include_directories(${BFASM_SOURCE_DIR} ${BFASM_BINARY_DIR} ${BFN_P4C_LIB_DIR} ${P4C_SOURCE_DIR}) + +# ASAN CHECKS +if (ASAN_ENABLED) + # force this set of flags only + set (CMAKE_CXX_FLAGS "-fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -O1") +endif() + +# json_diff +set (JSONDIFF_SOURCES json_diff.cpp json.cpp fdstream.cpp) + +# bfdumpbin +set (BFDUMPBIN_SOURCES bfdumpbin.cpp fdstream.cpp json.cpp bson.cpp) + +# bfdis +set (BFDIS_SOURCES bfdis.cpp disasm.cpp fdstream.cpp) + +# reflow +set (REFLOW_SOURCES reflow.cpp) + +# b2j +set (B2J_SOURCES b2j.cpp json.cpp bson.cpp) + +# j2b +set (J2B_SOURCES j2b.cpp json.cpp bson.cpp) + +# mksizes +set (MKSIZES_SOURCES mksizes.cpp) + +set (BFAS_COMMON_SOURCES + action_bus.cpp + action_table.cpp + asm-types.cpp + atcam_match.cpp + attached_table.cpp + bfas.cpp + bson.cpp + counter.cpp + crash.cpp + deparser.cpp + depositfield.cpp + dynhash.cpp + error_mode.cpp + exact_match.cpp + exename.cpp + flexible_headers.cpp + gateway.cpp + hash_action.cpp + hash_dist.cpp + hashexpr.cpp + idletime.cpp + input_xbar.cpp + instruction.cpp + json.cpp + match_table.cpp + meter.cpp + misc.cpp + p4_table.cpp + parser-tofino-jbay.cpp + phase0.cpp + phv.cpp + primitives.cpp + proxy_hash.cpp + salu_inst.cpp + selection.cpp + sram_match.cpp + stage.cpp + stateful.cpp + synth2port.cpp + tables.cpp + target.cpp + ternary_match.cpp + top_level.cpp + ubits.cpp + vector.c + widereg.cpp + ${BFN_P4C_LIB_DIR}/bitvec.cpp + ${BFN_P4C_LIB_DIR}/hex.cpp + ${BFN_P4C_LIB_DIR}/indent.cpp + ${BFN_P4C_LIB_DIR}/log.cpp + ${BFN_P4C_LIB_DIR}/cstring.cpp + ${BFN_P4C_LIB_DIR}/hash.cpp + ) + +SET (BFAS_COMMON_HEADERS + action_bus.h + asm-types.h + bfas.h + checked_array.h + constants.h + data_switchbox.h + deparser.h + depositfield.h + error_mode.h + escape.h + exename.h + fdstream.h + hash_dist.h + hashexpr.h + input_xbar.h + instruction.h + json.h + mask_counter.h + match_source.h + misc.h + p4_table.h + parser.h + parser-tofino-jbay.h + phv.h + power_ctl.h + register_reference.h + rvalue_reference_wrapper.h + sections.h + slist.h + stage.h + tables.h + target.h + top_level.h + ubits.h + widereg.h + alloc.h + ) + +# \TODO: use the headers from p4c/lib for utilities +set (BFAS_UTIL_HEADERS + map.h + vector.h + ) + +set (BFAS_GEN_SOURCES + ${BFASM_BINARY_DIR}/asm-parse.cpp + ${BFASM_BINARY_DIR}/gen/uptr_sizes.h) + +BISON_TARGET (asm-parse asm-parse.ypp ${CMAKE_CURRENT_BINARY_DIR}/asm-parse.cpp VERBOSE) + +add_custom_command(OUTPUT lex-yaml.c + COMMAND ${FLEX_EXECUTABLE} -t ${CMAKE_CURRENT_SOURCE_DIR}/lex-yaml.l > lex-yaml.c + DEPENDS ${BFASM_SOURCE_DIR}/lex-yaml.l + COMMENT "Generating lex-yaml.cpp") + +add_custom_command(OUTPUT gen/uptr_sizes.h + COMMAND ${CMAKE_COMMAND} -E make_directory ${BFASM_BINARY_DIR}/gen + COMMAND mksizes > gen/uptr_sizes.h + DEPENDS lex-yaml.c mksizes) + +set (BFASM_WALLE ${BFASM_SOURCE_DIR}/walle/walle.py) +set (WALLE_SOURCES + ${BFASM_SOURCE_DIR}/walle/chip.py + ${BFASM_SOURCE_DIR}/walle/csr.py + ${BFASM_SOURCE_DIR}/walle/walle.py) + +add_subdirectory (tofino) +set (HAVE_TOFINO 1) +set (BFASM_LIBS regs_tofino) +add_subdirectory (jbay) +set (HAVE_JBAY 1) +set (BFASM_LIBS ${BFASM_LIBS} regs_jbay) + +# Other configuration files that need to be generated +configure_file ("${BFASM_SOURCE_DIR}/cmake/config.h.in" "${BFASM_BINARY_DIR}/config.h") + +set_source_files_properties (${BFAS_GEN_SOURCES} ${BFASM_BINARY_DIR}/lex-yaml.c + PROPERTIES GENERATED TRUE) + +set (BFAS_SOURCES ${BFAS_COMMON_SOURCES} ${BFAS_GEN_SOURCES} + ${BFAS_TOFINO_SRCS} + ${BFAS_JBAY_SRCS} +) + +set (CPPLINT_FILES + ${JSONDIFF_SOURCES} + ${BFDUMPBIN_SOURCES} + ${REFLOW_SOURCES} + ${B2J_SOURCES} + ${J2B_SOURCES} + ${MKSIZE_SOURCES} + ${BFAS_COMMON_SOURCES} + ${BFAS_TOFINO_SRCS} + ${BFAS_JBAY_SRCS} + ${BFAS_UTIL_HEADERS} + ${BFAS_COMMON_HEADERS} + ${BFAS_TOFINO_HEADERS} + ${BFAS_JBAY_HEADERS} + ) +list(REMOVE_ITEM CPPLINT_FILES vector.c) +list(REMOVE_DUPLICATES CPPLINT_FILES) + +# json_diff +add_executable (json_diff ${JSONDIFF_SOURCES}) + +# bfdumpbin +add_executable (bfdumpbin ${BFDUMPBIN_SOURCES}) + +# bfdis +if (ENABLE_GTESTS) + # FIXME -- bfdis depends on bfas_lib which is only built if GTESTS are enabled. So for + # now we only enable bfdis with ENABLE_GTESTS. Should fix to use bfas_lib for bfas + # rather than building separately, so it will always be anbled. + add_executable (bfdis ${BFDIS_SOURCES}) + target_link_libraries (bfdis bfas_lib ${BFASM_LIBS} ${BFASM_LIB_DEPS}) +endif() + +# reflow +add_executable (reflow ${REFLOW_SOURCES}) + +# b2j +add_executable (b2j ${B2J_SOURCES}) + +# j2b +add_executable (j2b ${J2B_SOURCES}) + +# mksizes +add_executable (mksizes ${MKSIZES_SOURCES}) + +set_source_files_properties(${BFAS_SOURCES} PROPERTIES COMPILE_FLAGS ${BFASM_CXX_FLAGS}) +# Remove compiler flag that is C++ only for vector.c +string(REPLACE "-Wno-overloaded-virtual" "" vector_c_flags ${BFASM_CXX_FLAGS}) +set_source_files_properties(vector.c PROPERTIES COMPILE_FLAGS ${vector_c_flags}) +add_executable (bfas ${BFAS_SOURCES}) +target_link_libraries (bfas ${BFASM_LIBS} ${BFASM_LIB_DEPS} absl::strings absl::str_format absl::base absl::flags absl::flags_parse absl::status absl::hash) + +install (TARGETS bfas + RUNTIME DESTINATION bin) +# Link bfas into the p4c binary folder. +add_custom_target(linkbfas + COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_CURRENT_BINARY_DIR}/bfas ${P4C_BINARY_DIR}/bfas + ) +add_dependencies(linkbfas bfas) +add_dependencies(p4c_driver linkbfas) + + +add_custom_target(check-asm + COMMAND export BUILDDIR=${BFASM_BINARY_DIR} && cd ${BFASM_SOURCE_DIR}/test && + ./runtests asm/*.tfa asm/*.jba asm/*.bfa asm/*.stf) + +# This is broken and it doesn't make sense to use p4 tests here anyways +# add_custom_target(check-all-asm +# COMMAND export BUILDDIR=${BFASM_BINARY_DIR} && cd ${BFASM_SOURCE_DIR}/test && +# ./runtests -f asm/*.tfa *.p4 mau/*.p4 +# COMMAND export BUILDDIR=${BFASM_BINARY_DIR} && cd ${BFASM_SOURCE_DIR}/test && +# ./runtests -f -b stf/*.stf brig/*.p4) + +add_custom_target(check-sanity + COMMAND export BUILDDIR=${BFASM_BINARY_DIR} && cd ${BFASM_SOURCE_DIR}/test && + ./runtests *.p4) + +set (CPPLINT_CMD ${BFN_P4C_SOURCE_DIR}/p4c/tools/cpplint.py) +set (CPPLINT_ARGS --root=${BFASM_SOURCE_DIR}/.. --extensions=h,hpp,cpp,ypp,l) +add_custom_target(cpplint-asm + COMMAND ${CPPLINT_CMD} ${CPPLINT_ARGS} ${CPPLINT_FILES} + WORKING_DIRECTORY ${BFASM_SOURCE_DIR} + COMMENT "cpplint") +add_custom_target(cpplint-asm-quiet + COMMAND ${CPPLINT_CMD} --quiet ${CPPLINT_ARGS} ${CPPLINT_FILES} + WORKING_DIRECTORY ${BFASM_SOURCE_DIR} + COMMENT "cpplint quietly") + +string(CONFIGURE "/^DECLARE_(ABSTRACT_)?TABLE_TYPE\(([a-zA-Z0-9_]+)/2/c/" CTAGS_CXX_REGEXP @ONLY) +add_custom_target(ctags-asm + COMMAND ctags -R -I VECTOR --exclude=test --exclude=submodules + "--regex-C++=${CTAGS_CXX_REGEXP}" + COMMENT "Generating ctags") + +# Build the bf-asm test suite +add_subdirectory(test) + +if (ENABLE_GTESTS) + # TODO Components need to be built, once, into intermediate libraries. + # These lib would then be linked to unit-tests and also linked into larger components/executable. + # The exact shape, size, hierarchy of components is to be decided. + # For now we will allow the source to be built twice, once for 'bfas', and once for + # gtest/CMakeList.txt as a single monolithic component 'bfas_lib'. + # TODO ASAP refactor bfas.cpp, moving main() into its own file. + # add_executable (bfas asm_main.cpp) + # target_link_libraries (bfas bfas_lib ${BFASM_LIBS} ${BFASM_LIB_DEPS}) + + add_library (bfas_lib ${BFAS_SOURCES}) + target_compile_definitions(bfas_lib PRIVATE BUILDING_FOR_GTEST) # removes main() + target_link_libraries (bfas_lib PRIVATE ${BFASM_LIBS} ${BFASM_LIB_DEPS} absl::strings absl::str_format absl::base absl::flags absl::flags_parse absl::status absl::hash) + + set(BFAS_GTEST_SOURCES + gtest/gtestasm.cpp + gtest/asm-types.cpp + gtest/depositfield.cpp + gtest/gateway.cpp + gtest/hashexpr.cpp + gtest/mirror.cpp + gtest/parser-test.cpp + gtest/register-matcher.h + gtest/register-matcher.cpp + ) + + set(BFP4C_SOURCES + ${BFN_P4C_LIB_DIR}/bitvec.cpp + ${BFN_P4C_LIB_DIR}/compile_context.cpp + ${BFN_P4C_LIB_DIR}/cstring.cpp + ${BFN_P4C_LIB_DIR}/error_catalog.cpp + ${BFN_P4C_LIB_DIR}/error_message.cpp + ${BFN_P4C_LIB_DIR}/error_reporter.h + ${BFN_P4C_LIB_DIR}/hash.cpp + ${BFN_P4C_LIB_DIR}/options.cpp + ${BFN_P4C_LIB_DIR}/source_file.cpp + ${BFN_P4C_LIB_DIR}/stringify.cpp +) + + # Do not use a unity build for gtestasm (for now). + set_source_files_properties (${BFAS_GTEST_SOURCES} PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE) + + add_executable (gtestasm ${BFAS_GTEST_SOURCES} ${BFP4C_SOURCES}) + include_directories( + ${BFN_P4C_SOURCE_DIR}/p4c + ) + target_link_libraries (gtestasm PRIVATE bfas_lib gtest absl::strings absl::str_format absl::base absl::flags absl::flags_parse absl::status absl::hash) + target_compile_options (gtestasm PRIVATE -Wall -Wextra -ggdb -O3 + -Wno-unused-parameter -Wno-sign-compare) + + # Add to CTests - but this is in the BFASM project viz build/bf-asm, not build/p4c + add_test (NAME gtestasm COMMAND gtestasm WORKING_DIRECTORY ${P4C_BINARY_DIR}) + set_tests_properties (gtestasm PROPERTIES LABELS "gtest") +endif () diff --git a/backends/tofino/bf-asm/CPPLINT.cfg b/backends/tofino/bf-asm/CPPLINT.cfg new file mode 100644 index 00000000000..3a79f137f4d --- /dev/null +++ b/backends/tofino/bf-asm/CPPLINT.cfg @@ -0,0 +1,25 @@ +set noparent +filter=-build/include_subdir +filter=-build/c++11 +filter=-build/include_what_you_use +filter=-build/namespaces +filter=-legal/copyright +filter=-runtime/int +filter=-runtime/references +filter=-readability/todo +filter=-readability/function +filter=-readability/casting +linelength=100 +# include bf-asm in the cpp header guard prefix. +root=.. +filematch=*.ypp +# yacc productions&actions really confuse cpplint.py, so disable a bunch of things +filter=-readability/braces +filter=-whitespace/braces +filter=-whitespace/semicolon +filter=-readability/namespace + +filematch=*.l +filter=-whitespace/semicolon,-whitespace/braces,-whitespace/comma +filter=-whitespace/operators +filter=-readability/multiline_string, diff --git a/backends/tofino/bf-asm/Options.md b/backends/tofino/bf-asm/Options.md new file mode 100644 index 00000000000..05dba981d2a --- /dev/null +++ b/backends/tofino/bf-asm/Options.md @@ -0,0 +1,98 @@ +# bfas command line options + +usage: bfas [ options ] file.bfa + +### general options + +* -h + help + +* --target *target* + + specify the target (obsolete as target is generally specified in the .bfa file) + +* -Werror + + treat warnings as errors + +### options for controlling output + +* -a +* --allpipes + + Generate a binary that has explicit writes for all pipes, rather than just one + +* -s +* --singlepipe +* --pipe*N* + +* -G +* --gen\_json + + Generate .cfg.json files instead of binary + +* --no-bin +* --num-stages-override*N* + +* -M + + Attempt to match glass bit-for-bit + +* -o *directory* + + Generate output in the specified directory rather than in the current working dir + +### options for controling cfg details + +* -C + condense json by stripping out unset subtrees (default) + +* --disable-egress-latency-padding + + Disable the padding of egress latency to avoid tofino1 TM overrun bus + +* --disable-longbranch +* --enable-longbranch + + Disable or enable support for long branches + +* --disable-tof2lab44-workaround + +* --high\_availability\_disabled +* --multi-parsers +* --no-condense +* --noop-fill-instruction *opcode* + + Insert instructions (of the form *opcode* R, R, R) for noop slots in VLIW instructions + where the slot is not used by any action in the stage. *opcode* must be one that is an + identity function when applied to two copies of the same value (and, or, alu\_a, alu\_b, + mins, maxs, minu, or maxu) + +* -p + Disable power gating + +* --singlewrite +* --stage\_dependency\_pattern *pattern* +* --table-handle-offset*N* + +### options for logging/debugging + +* -l *file* + + redirect logging output to file + +* --log-hashes + +* -q + + disable all logging output + +* --no-warn + +* -T *debug spec* + + enable logging of specific source files and specific levels + +* -v + + increase logging verbosity diff --git a/backends/tofino/bf-asm/README.md b/backends/tofino/bf-asm/README.md new file mode 100644 index 00000000000..5e4008a8a0c --- /dev/null +++ b/backends/tofino/bf-asm/README.md @@ -0,0 +1,379 @@ +# Tofino Assembler + +## Documentation + +Documentation on using the assembler, notes on file formats, and internals are +in [Google Drive > Barefoot shared > documents > Software > Assembler] +(https://drive.google.com/drive/folders/0Byf8esgFy8YacmNzMmZiSkN4OFU) + +## Setup + +The repository contains code for the Barefoot assembler (bfas) and linker (walle). +More info on walle can be found in walle/README.md. + +Assembler takes assembly files (.bfa or .tfa) as input to generate output json which is +then fed to walle to produce binary for tofino. + +## Dependencies + +- GNU make +- A C++ compiler supporting C++11 (the Makefile uses g++ by defalt) +- bison +- flex + +Running the test suite requires access to the Glass p4c\_tofino compiler. +Running stf tests requires access to the simple test harness. The +`tests/runtests` script will look in various places for these tools (see the top +of the script) + +## Building Assembler + +The assenbler is built automatically as part of the full bf-p4c-tofino build; there +is currently no supported standalone method of building the assembler by itself. + +## Address Sanitizer checks + +(obsolete) +To enable address sanitizer checks in the assembler use, + +``` +user@box$ ./bootstrap.sh --enable-asan-checks +``` + +Or alternatively, + +``` +user@box$ ./configure --enable-asan-checks +``` + +This configures the Makefile to add -fsanitizer=address & -fsanitizer=undefined. +By default the leak sanitizer is also enabled along with the address santizier. +You can disable it by setting environment variable ASAN\_OPTIONS with +"detect\_leaks=0". + +## Testing + +### Make Targets + +``` +user@box$ make check +``` + +Runs tests/runtests script on all .p4 files in the tests and tests/mau +directories and .bfa files in tests/asm directory. This script can run one or +more tests specified on the command line, or will run all .p4 files in the +current directory if run with no arguments. Stf tests can be run if specified +explicitly on the command line; they will not run by default. + +``` +user@box$ make check-sanity +``` + +This is similar to `make check` but will only run on .p4 files in the tests +directory which is a small subset for a quick sanity check. + +### Runtests Script + +The ./tests/runtests script will first run glass compiler (p4c-tofino) on +input .p4 file and then run the assembler (bfas) on generated assembly (.tfa) +file. Glass also generates output json which is then compared (by the script) +to the json generated from assembler. + +To skip running glass use -f option on the runtests script + +Use -j to run parallel threads. If invoking through Make targets set +MAKEFLAGS to "-j " + +### Expected Failures + +expected\_failures.txt files are under tests & tests/mau directory which outline +failing tests with cause (compile, bfas, mismatch). These files must be updated +to reflect any new or fixed fails. + +| FAIL | TYPE | CAUSE | +|----------|--------------|---------------------------------------------------------| +| compile | Glass | Glass cannot compile input .p4 file | +| bfas | Assembler | Assembler error while running input assembly file (.bfa)| +| mismatch | Json output | Difference in json outputs for glass and assembler | + +### Context Json Ignore +Context Json output from Glass compiler is verbose and may or may not be +consumed entirely by the drivers unlike the assembler Json output. The +tests/runtests script ignores the keys placed in the tests/ctxt\_json\_ignore file +while creating json diff to only display relevant mismatches + +### Json Diff +Each test after running will have its own .out dir with following +items: +E.g. TEST = exact\_match0.p4 +exact\_match0.p4.out +##### Glass Json output +``` +├── cfg +│   ├── memories.all.parser.egress.cfg.json.gz +│   ├── memories.all.parser.ingress.cfg.json.gz +│   ├── memories.pipe.cfg.json.gz +│   ├── memories.top.cfg.json.gz +│   ├── regs.all.deparser.header_phase.cfg.json.gz +│   ├── regs.all.deparser.input_phase.cfg.json.gz +│   ├── regs.all.parse_merge.cfg.json.gz +│   ├── regs.all.parser.egress.cfg.json.gz +│   ├── regs.all.parser.ingress.cfg.json.gz +│   ├── regs.match_action_stage.00.cfg.json.gz +│   ├── regs.match_action_stage.01.cfg.json.gz +│   ├── regs.match_action_stage.02.cfg.json.gz +│   ├── regs.match_action_stage.03.cfg.json.gz +│   ├── regs.match_action_stage.04.cfg.json.gz +│   ├── regs.match_action_stage.05.cfg.json.gz +│   ├── regs.match_action_stage.06.cfg.json.gz +│   ├── regs.match_action_stage.07.cfg.json.gz +│   ├── regs.match_action_stage.08.cfg.json.gz +│   ├── regs.match_action_stage.09.cfg.json.gz +│   ├── regs.match_action_stage.0a.cfg.json.gz +│   ├── regs.match_action_stage.0b.cfg.json.gz +│   ├── regs.pipe.cfg.json.gz +│   └── regs.top.cfg.json.gz +├── context +│   ├── deparser.context.json +│   ├── mau.context.json +│   ├── parser.context.json +│   └── phv.context.json +``` +##### Assembler Output Directory +``` +├── exact_match0.out +``` +##### Assembler Json Output +``` +│   ├── memories.all.parser.egress.cfg.json.gz +│   ├── memories.all.parser.ingress.cfg.json.gz +│   ├── memories.pipe.cfg.json.gz +│   ├── memories.top.cfg.json.gz +│   ├── regs.all.deparser.header_phase.cfg.json.gz +│   ├── regs.all.deparser.input_phase.cfg.json.gz +│   ├── regs.all.parse_merge.cfg.json.gz +│   ├── regs.all.parser.egress.cfg.json.gz +│   ├── regs.all.parser.ingress.cfg.json.gz +│   ├── regs.match_action_stage.00.cfg.json.gz +│   ├── regs.match_action_stage.01.cfg.json.gz +│   ├── regs.match_action_stage.02.cfg.json.gz +│   ├── regs.match_action_stage.03.cfg.json.gz +│   ├── regs.match_action_stage.04.cfg.json.gz +│   ├── regs.match_action_stage.05.cfg.json.gz +│   ├── regs.match_action_stage.06.cfg.json.gz +│   ├── regs.match_action_stage.07.cfg.json.gz +│   ├── regs.match_action_stage.08.cfg.json.gz +│   ├── regs.match_action_stage.09.cfg.json.gz +│   ├── regs.match_action_stage.0a.cfg.json.gz +│   ├── regs.match_action_stage.0b.cfg.json.gz +│   ├── regs.pipe.cfg.json.gz +│   ├── regs.top.cfg.json.gz +``` +##### Context Json +``` +│   └── context.json +``` +##### Symlink to Glass Assembly File +``` +├── exact_match0.tfa -> out.tfa +``` +##### Glass Run Log +``` +├── glsc.log +``` +##### Json Diff File +``` +├── json_diff.txt +``` +##### Glass Output Logs +``` +├── logs +│   ├── asm.log +│   ├── mau.characterize.log +│   ├── mau.config.log +│   ├── mau.gateway.log +│   ├── mau.gw.log +│   ├── mau.log +│   ├── mau.power.log +│   ├── mau.resources.log +│   ├── mau.rf.log +│   ├── mau.sram.log +│   ├── mau.tcam.log +│   ├── mau.tp.log +│   ├── pa.characterize.log +│   ├── pa.liveness.log +│   ├── pa.log +│   ├── parde.calcfields.log +│   ├── parde.config.log +│   ├── parde.error.log +│   ├── parde.log +│   ├── pa.results.log +│   ├── parser.characterize.log +│   └── transform.log +├── name_lookup.c +``` +##### Glass output assembly file +``` +├── out.tfa +``` +##### Assembler Run Log +``` +├── bfas.config.log +├── bfas.log +``` +##### Test visualization htmls +``` +└── visualization + ├── deparser.html + ├── jquery.js + ├── mau.html + ├── parser.egress.html + ├── parser.ingress.html + ├── phv_allocation.html + └── table_placement.html +``` + +## Backends (Tofino/JBay) +Assembler currently supports Tofino backend but code is generic enough to be +ported to a different backend like JBay. Architecture specific constants must be +parameterized and placed in the constants.h file + +"tofino" and "jbay" directories hold the chip schema to be used by the +assembler. The chip schema contains register information and is a binary +(python pickle file) generated from csv file in bfnregs repository. + +### Extracting information from hardware bfnregs info + +To the greatest extent possible, we automatically generate assembler support code +directly from the information provided to use by the hardware team. The main 'source' +we get from hardware are the Semfore .csr files and the associated .csv files generated +by Semafore from the .csr files. We use walle (walle subdirectory) to read the .csv +files and distill them into a chip.schema -- a python pickle file containing the +datastructures defined in walle/csr.py that encapsulate the information and structure +of all the hardware registers. + +We then use walle to generate C++ code embodying the register structure, defining C++ +classes containing the structure of all the registers. The template.yaml file defines +various options for the structure of the resulting C++ code -- which registers to use +as the 'roots' of class hierarchies, what files to write the code in, which methods to +define in each class. Within the templates.yaml file, there's a `global:` section giving +global options for all files, a `generate:` section listing the files to generate, and +an `ignore:` section listing register subtrees to ignore (no code will be generated for +them -- its as if they don't exist). + +Options that can be used include: + +| option | description | +| ----------- | ---------------- | +| decl | generate just declarations (suitable for a header file) | +| defn | generate definitions for those declarations. With neither `decl` or `defn` will generate complete classes with inline methods | +| checked\_array | Use the checked\_array class (`checked_array.h`) for arrays (default) | +| delete\_copy | Delete copy constructors for generated classes | +| dump\_unread | generate a `dump_unread` method which dumps all unread registers to an ostream (default False) | +| emit\_binary | generate an `emit_binary` method that outputs binary code for the driver/model | +| emit\_fieldname | generate `emit_fieldname` method used to print logging messages | +| emit\_json | generate `emit_json` method to generate config json | +| enable\_disable | generate `enable`, `disable`, and `modified` methods | +| global | generate the specified register types once as global names rather than as nested in the containing object(s) | +| include | generate a `#include` of the specified file | +| name | Change the name of the top-level object | +| namespace | Put all declarations in the specified namesapce | +| unpack\_json | generate `unpack_json` method | +| widereg | Use `widereg` for registers wider than 64 bits | +| write\_dma | Generate `'B'` block writes for the specified registers instead of `'R'` single register writes in `emit_binary` methods | + +This results in C++ code that can either generate .cfg.json files or binary files for use by +the driver/model. When cfg.json files are produced, walle can be used to link them into a +binary file. There are also options for generating C++ code to read .cfg.json files for +future support of binary disassembly. + +### Config JSON +The config json files (with .cfg.json extension) are generated by the +assembler which are fed into walle to generate the binary +(also called `tofino.bin`) + +The config json is nothing but json files with a map of all the registers for +a backend. In order to limit the json file size assembler disables registers +which are not set (with the -C or condense json flag). Some registers are also +explicitly disabled or enabled based on what the drive expects to see in the +tofino.bin. Below is the status of regs and whether they will appear in the +config json. +``` +--------------------------------- +Disabled - (unconditionally) +--------------------------------- +mem_pipe.mau +regs.input.icr.inp_cfg +regs.input.icr.intr +regs.header.hem.he_edf_cfg +regs.header.him.hi_edf_cfg +regs.glb_group +regs.chan0_group.chnl_drop +regs.chan0_group.chnl_metadata_fix +regs.chan1_group.chnl_drop +regs.chan1_group.chnl_metadata_fix +regs.chan2_group.chnl_drop +regs.chan2_group.chnl_metadata_fix +regs.chan3_group.chnl_drop +regs.chan3_group.chnl_metadata_fix +--------------------------------- +Disabled - (if Zero) +--------------------------------- +regs (In all regs) +mem_top (mau) +mem_pipe (mau/dummy_reg) +reg_top (ethgpiobr, ethgpiotl, pipes) +reg_pipe (mau, pmarb, deparser) +--------------------------------- +Enabled - (always) +--------------------------------- +regs.dp.imem.imem_subword8 +regs.dp.imem.imem_subword16 +regs.dp.imem.imem_subword32 +regs.rams.map_alu.row[row].adrmux.mapram_config[col] +``` +Once JBay support is added for all regs, above will be different for both +backends. + +Driver dictates which regs are disabled or enabled unconditionally. Other +regs which are disabled if zero are to limit file size and driver should +automatically fill in the zero values. + +#### Generating and using chip.schema + +chip.schema files are generated by walle from the csv files in the +bfnregs repo. To generate a new chip.schema file, use + + walle/walle.py --generate-schema ${BFNREGS_REPO}/modules/${CHIP}_regs + +where `${BFNREGS_REPO}` is the root of the bfnregs repo, and `${CHIP}` +is the chip to target (`tofino`, `trestles`, or `jbay` at the moment). +The newly created chip.schema file should then be moved into the jbay +or tofino subdirectory where the build system expects to find it. + +chip.schema is a binary (python pickle) file; you can use +`walle.py --dump-schema` to dump it as (vaguely human readble) +yaml. It is basically a DAG of python objects (csr.address\_map, +csr.address\_map\_instance, and csr.reg) describing the register tree. +The build uses walle to turn this into json files describing various +subtrees of the dag. The `template_objectss.yaml` file describes which +subtrees to generate json files for as well as list of subtrees to +ignore (elide from the json files). Names in this file are the names of +csr.address\_map objects (NOT instances), and where the generated files +are nested, the containing json will contain a reference to the contained +json rather than a copy of the tree. In this way, the generated json +files as a group describe the DAG even though json can only describe +trees, not DAGs. + +If, when running make, you get a KeyError from walle, that generally +means that the template\_objects.yaml file contains a refernce to +some csr.address\_map that does not exist in the chip.schema file -- +the register tree has changed in a way that invalidates the json files +it is trying to generate. If you have your python setup to drop into pydb +automatically on an uncaught exception (highly recommended), at that point +you can use `pp section` to list all the csr.address\_map objects that +*are* in the chip.schema. Generally you'll find that it is the 'ignore' +names that have changed, so fixing them is trivial. + +## Assembly Syntax +The assembly syntax is documented in `SYNTAX.md` file diff --git a/backends/tofino/bf-asm/SYNTAX.yaml b/backends/tofino/bf-asm/SYNTAX.yaml new file mode 100644 index 00000000000..e11a476f63a --- /dev/null +++ b/backends/tofino/bf-asm/SYNTAX.yaml @@ -0,0 +1,1294 @@ +# Copyright (C) 2024 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# +# SPDX-License-Identifier: Apache-2.0 + +# yaml format tags for tofino assembler +# +# symbols used below: +# ::= a string of 1 or more letters, digits, '_', '-', '.', +# '$', or '@' not starting with a digit. Cannot start or +# end with '-' or '.' or have two consecutive '-' or '.' +# ::= "ingress" | "egress" | "ghost" +# ghost is only availble in jbay mau and phv sections +# ghost only has 'ghost_md' and 'pipe_mask' sections used to +# configure 'tm_status_phv' register +# ::= that matches a predefined register name +# ::= (..) | () +# no spaces between parts of the +# ::= unsigned integer constant +# 0x/0b/0o prefix for hex/binary/octal +# ::= constant where one or more digits may be replaced +# by '*' to denote don't-care for ternary matches. +# ::= .. +# no spaces between parts of the +# ::= | | '[' | , ... ']' +# can be a single constant or range or multiple constants +# or ranges in a yaml list +# ::= | +# Must be a register name or a name defined in the phv section +# ::= +# Denotes a single bit +# ::= half | byte0 | byte1 +# denotes one of the parser match units +# ::= { , } +# ::= | | +# | hash_dist [ .. ] +# | rng [ .. ] +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +phv []: + # Defines PHV alias names for registers. is 'ingress', 'ghost' or + # 'egress' and is optional. If present, aliases are defined only for + # that thread. If not present, aliases are for all threads + : | + # Makes an alias for a register or piece of a register. + # register B0 through B63 for byte registers, H0-H95 for half + # (16-bit) registers, or W0-W63 for word (32-bit) registers. + # May also use R0-R224 for all registers in W/B/H order. + # TW0-TW31, TB0-TB21, TH0-TH47, R256-R367 for tagalong + : + stage ..: | + stage : | + # makes name an alias that varies over stages. In the first form, the map + # applies just for those stages; in the second form it applies from that stage + # up until the next stage specified by another stage key. Stage numbers + # apply to iPHV (input), so uses for VLIW destinations use the mapping for the + # next stage. Parser uses stage 0 and deparser uses the end-of-pipe stage + context_json: + : + # any keys/vector/values here are converted to json and output into + # the context.json phv_allocation.records info for field + # verbatim +hdr: + # Information related to hdr_ids (header names and compressed + # header sequence and length encoding in bridge metadata) + map: + # Mapping of hdr_ids to header names + : + # constant is hdr_id, name can be used as substitution for hdr_id + # e.g. md32: 0, ethernet: 1, ipv4: 2, ... + seq: + # Compressed header sequence encoding in bridge metadata + : [ , ... ] + # constant is 8b sequence number; 255 is reserved for + # escape value to specify explicit list of all headers + # e.g. 0: ethernet, ipv4 + len: + # Compressed header length encoding in bridge metadata + : { base_len: , num_comp_bits: , scale: } + # base_len is 8b, num_comp_bits 3b, scale 2b + # e.g. ipv4: { base_len: 20, num_comp_bits: 4, scale: 2 } # (20B + N * 4B; N < 10) + # e.g. ipv6: { base_len: 40, num_comp_bits: 7, scale: 3 } # (40B + N * 8B) +parser [] [, ...]: + # Defines a parser. must be 'ingress' or 'egress' + # can have numerical values, such as range, int, vector of range and int. + # can also have symbolic values, such as "ALL", "CPU", "PCIE", "UNUSED" + # "CPU" and "PCIE" are symbolic names that the corresponding numeric values are device-specific. + # "UNUSED" represents the parser program that is not configured to any physical + # parser during device initialization, but may be used by driver during runtime. + name: # parser name defined in the arch file, used by bfrt to find the parser + # config in context.json + start: + start: '[' , ... ']' + # define up to 4 distinct initial start states for the four channels + priority: | '[' , ... ']' + priority_threshold: | '[' , ... ']' + # define initial parser priority and threshold for the 4 channels + states: + # Parser states can be defined with or without the 'states' key but this + # is preferred as it avoids name collisions with other assembly + # directives, + []: + # Defines a parser state. The state 'start' is the implicit initial state + # if there is no explicit initial state defined by a separate 'start' entry. + # The state 'end' cannot exist (used for exit) + # The optional constant is the 8-bit value used to denote the state; + # overlapping state values will be flagged as an error + match: | { : } + # specifies up to 4 bytes to match against in the input buffer + # may also specify 'ctr_zero' and 'ctr_neg' to match those + # special bits, or the specific matchers 'byte0', 'byte1' or 'half' + # to match against values explicitly loaded by a 'save' in a previous + # state. May additionally specify specific matchers to use. + option: + # enable an optional feature for this state. Currently the only option + # is "ignore_max_depth" which means the state (and subsequent states) are + # ignore for calculating the max parser bytes. Used for min parser padding + # states + : + # actions to perform when the match matches this match constant + # this is a tcam priority match, so only the first match triggers + buf_req: + # number bytes that must be in the input buffer to not stall + counter: inc | dec | load | + # modification of the counter + src: # matcher to load counter from + max: # max value of the counter + rotate: # number of bits to circular right rotate + mask: # mask of rotated value + add: # immediate to add to masked value + checksum : + # modification of checksum unit + type: VERIFY | RESIDUAL | CLOT + mask: # vector of byte ranges of input buffer + swap: + dest: | clot # write destination + start: 0 | 1 + end: 0 | 1 + next: | + # next state -- match-constant takes don't care bits + # from current state + offset: [set] | inc + # modificate to the offset + priority: | @ [ >> ] [ & ] + # update the packet priority + load: { : , ... } | + # specifies one or more values from the input stream to be + # loaded into specific matchers or specific matchers to have + # their values preserved for use by later states + save: [ , ... ] + # specifies on more more values from the matchers to be + # saved into the scratch pad registers + shift: + # number of bytes to shift out + intr_md: + # number of bits of intrinsic metadata being shifted out + [rotate] : [offset] + [rotate] : [offset] + # write the specifed byte (or range) to named phv slot + [offset] : [rotate] + # write the specified constant to the phv location + clot : + # output a CLOT (jbay only) + start: + length: | + # expression is generally '@' [ '>>' ] [ '&' ] + # with variations (unary is highest precedence, followed by shift, + # mask(&), +/- lowest) + max_length: + stack_depth: + stack_inc: + hdr_len_inc_stop: + # stop the header length counter, and use value as final increment amount (jbay only) + disable_partial_hdr_err: + # specifies whether the partial header error is enabled or not for + # the current state. Specific to: + # - JBay + partial_hdr_err_proc: + # specifies whether or not the best effort extraction (a.k.a. greedy extract) + # is performed when insufficient data is available in the input buffer. + value_set : + handle: # pvs handle + field_mapping: + (range) : (range) + # actions to perform for a value set of the given and integer + default: + # actions to perform regardless of the match + # if there is no 'default' tag in a state, anything that is not + # recognized as a valid state tag is treated as part of an implicit + # default + hdr_len_adj: + # value for the hdr_len_adj register + init_zero: [ ,... ] + # list of phv slots that should be initialized to (valid) zero + meta_opt: + # value for the meta_opt register + multi_write: [ ,... ] + # list of phv slots that the parser may write multiple times + # values OR'd with previous values + parser_error: + # define a phv location to receive parser error codes + bubble: + # configure rate limit registers for pipe + inc: + dec: + max: + interval: # tofino2+ only + ghost_md: + # container(s) allocated to store ghost intrinsic metadata + # tofino2+ only (set tm_status_phv reg) + pipe_mask: + # pipe_mask to be set for ghost packets + # (tm_status_phv.pipe_mask in tofino2) + parse_depth_checks_disabled: true | false + # Parse depth checks disabled + states: + : + # specifies match values for states (64b) + # e.g. parse_ipv4: 0x********_******02 + # e.g. parse_tcp: 0x********_******04 + port_metadata: + # specifies port metadata for each logical port number + : + # constant is logical port number, vector is port metadata (14B) + profile : + # specifies a parser profile, constant represents the TCAM&SRAM index + match_port: + match_inband_metadata: + # if the logical port number (2'b0 ++ 6b) or inband metadata (8B) match is omitted, + # it is treated as * + initial_pktlen: + # specifies the value to adjust the length for AdjustedPacketLength (6b) + initial_seglen: + # specifies the value to adjust the length for AdjustedSegLength (6b) + initial_state: | + # specifies initial state (80b) + # if a state name is used, all-match bits are initialized to 0 + # and upper-most two bytes are set to 0 + initial_flags: + # specifies initial flags (64b) + initial_ptr: + # specifies initial pointer (8b) + initial_w0_offset: + # specifies initial W0 offset (8b) + initial_w1_offset: + # specifies initial W1 offset (8b) + initial_w2_offset: + # specifies initial W2 offset (8b) + initial_alu0_instruction: + # specifies initial instruction for ALU0 (15b) + initial_alu1_instruction: + # specifies initial instruction for ALU1 (19b) + metadata_select: '[' , ... ']' + # specifies source of each of 32B of MD32 metadata + analyzer_stage []: + # constant is stage number + # if name is present, it is looked up in state_map and all rules match the state + # only one of stage name and rule state match can be present + # e.g. stage 0 parse_ipv4 + rule : + # constant is explicit rule index; it also specifies the rule priority + # when more rules match (higher value is higher priority) + # each rule supports up to 4 instructions for modifying flags, one for up to 16 bits + # (modify_flags16), one for up to 4 bits (modify_flags4), and two for 1 bit + # (modify_flag0 and modify_flag1). All of these can be set simultaneously. If the + # affected flags overlap, the instructions take effect in the following order of + # precedence: + # modify_flags16, modify_flag4, modify_flag0, modify_flag1. + match_state: | + # if state match constant is ommited, it is derived from the state name at stage + # if it is missing, it is treated as * + match_w0: + match_w1: + # if w0 or w1 match constant is ommited, it is treated as * + # e.g. rule 0 w0 17 # state is matched based on `stage 0 parse_ipv4' above + # e.g. rule 0 w0 17 state 0x************02 # 17 is for TCP; 02 is for parse_ipv4 (see state_map) + next_state: | + # specifies state for the next stage (80b) + # e.g. next_state: 0x**************04 + # e.g. next_state: parse_tcp + next_skip_extractions: + # skips Wx extractions in the next stage (bool) + next_w0_offset: + # specifies W0 offset for the next stage (8b) + # e.g. next_w0_offset: 2 # TCP destination port + next_w1_offset: + # specifies W1 offset for the next stage (8b) + next_w2_offset: + # specifies W2 offset for the next stage (8b) + next_alu0_instruction: + # specifies instruction for ALU0 for the next stage (15b) + next_alu1_instruction: + # specifies instruction for ALU1 for the next stage (19b) + push_hdr_id: { hdr: , offset: } + # specifies header ID (8b) or name, and offset (8b) to be pushed to ana_hdr_ptrs + # if name is specified, it is looked up in hdr -> map + # 0xff for header ID is reserved for invalid + # offset is relative to pointer + # e.g. push_hdr_id: ipv4 0 + modify_flags16: + # specifies src (2b), imm (16b), mask (16b), and shift (6b) to set/clear + # multiple flags at once. + src: + imm: + # whether to set or clear the corresponding flags, only used if src == 3 + mask: + # modify a flag if the corresponding mask bit is set + shift: + # index into flags at which to start the operation + modify_flags4: + # same as modify_flag16, but with 4b imm and mask + src: + imm: + mask: + shift: + modify_flag0: { set: | clear: }, + # set or clear the flag at the index given by the 6-bit + modify_flag1: { set: | clear: }, + # same as modify_flag0 + modify_checksum: { idx: , enabled: }, + # changes the enabled state of the checksum unit at the 1-bit index idx + phv_builder_group : + # specifies extract groups + pov_select: + # specifies which POV bytes are used to address the TCAM & SRAM + extract : + # specifies extracts + match: + # match constant is 4B + source: + # specifies a PHE source pair + initial_predication_vector: + # specifies the initial predication information + pov_select: + # specifies which POV bytes are used to address the TCAM + next_tbl_config: + # a mapping for the IPV TCAM, from match constants to next table identifiers + : + # match constant is 4B, constant is 1B + ghost_initial_predication_vector: + # specifies the initial predication information for the ghost thread + pov_select: + # specifies which POV bytes are used to address the TCAM + next_tbl_config: + # a mapping for the IPV TCAM, from match constants to next table identifiers + : + # match constant is 4B, constant is 1B + checksum_checkers: + mask : + # There can be up to 4 masks. + # Each mask is specified as an up to 224b wide constant. + # A mask specifies which bytes of the header are used for the checksum computation. + # 1 -> used, 0 -> not used + unit : + # Each unit is able to verify 1 checksum. + # The checksum is computed according to the selected 'config' + # which specifies a header ('hdr') and a mask ('mask_sel'). + # A config is selected using the 'match_pov' key. + # There are 2 units. + # Both units operate independently and allow verification of overlapping bytes. + pov_select: + # Specifies which POV bytes are used to address the TCAM + config : + # There are up to 16 checksum configurations for each unit. + match_pov: + # 32b match key + mask_sel: + # Selects one of the 4 masks (2b). + # Both csum units can select the same mask. + hdr: + # Specifies which header is used for the checksum computation. + # The concrete header bytes which are used for the checksum + # are specified using a mask. + # One of the 4 masks is selected using the 'mask_sel' field. + pov_flags_pos: + # specifies start position of POV flags in bridge metadata (6b) + pov_state_pos: + # specifies start position of POV state in bridge metadata (6b) +stage : + # Defines a single stage of the MAU. The order of the tables within the + # stage is the logical table ordering, so order matters + []: + # common keys available in (almost) all tables types + row: + # one or more ram rows the table uses + # whether these are physical or logical rows depends on the table type + column: | '[' , ... ']' + # May be a single vector or a list of vectors. If a list, length + # must match the number of rows specified + # Denotes the rams used on each row. RAM type (sram, tcam or mapram) + # depends on the table type + stage : | '[' , ... ']' + - stage : + stages: | '[' , ... ']' + bus: 0 | 1 | '[' 0 | 1, ... ']' + # bus(es) to use. If a list, must match the number of rows + lhbus: 0 | 1 | + rhbus: 0 | 1 | + word: + # for wide tables, specify which word of the wide word is in each row of the table + vpns: + # vpn values to use for rams + dyanamic_config: + : + : { : } + # defines the match for one specific dconfig bit. Match may be a single + # match for the entire width or matches against specific + # named slices of those PHVs. Other bits are implicitly don't-care + input_xbar [ | ]: + # Input xbar config for this table + : | '[' , ... ']' | + { : | ..: ,... } + [] group : ... # tofino 1/2 + # One or more registers to be mapped into the specified ixbar group + # in order or at the locations specified. Locations are bit offsets in + # the group (even for groups that are not bit-addressable + hash [table] : + # hash table config + : + # specify one column of the table -- hash is a 64-bit constant + | : + # specify one or more columns according to expression. Phv refs + # must be in the corresponding input group of this input_xbar + + # identity copy of phv (must match width of range) + random(, ...) + # random hash of the given phv locations. We generate + # with random(3) and we do NOT call srand, so the hash + # for a given program is repeatable. + crc(, [,] , ...) + # Deprecated. + # crc hash of the given phv locations -- first arg is integer + # constant denoting polynomial (Koopman notation). Second arg + # is an initial constant prefixed to the input. + crc(, [,] '{' : , ... '}' [, '{' : '}' ]) + # crc hash of the given phv locations, at the specified offsets + # from the lsb of the crc input as a whole. + # arguments are polynomial (Koopman Notation) + # init shift register + # final xor + # total number of bits in the crc + # -- + # hash calculation could have a list of constants as inputs. + # : represents the constant value in hash calculation, + # the key encodes the offset and length of the constant + # the value encodes the value of the constant + crc_rev(...) + # bit-reversed (little endian instead of the defaul big endian) crc + xor(, '{' : , ... '}') + # XOR of a data block (message) + # + # Fields specified in the second parameter are joined into one + # big bit stream, cut into blocks of width specified in the first + # parameter and the blocks are bitwise XORed together. If the + # field list is not continuous (there are gaps in bit offsets), + # zeros are padded in. + # + # Constants are not supported by this directive - they are computed + # into the seed value by the backend. + ^ + # xor of other expressions. + & + & + # mask expression, including just some bits in the result + stripe(, ...) + # stripe other expressions across the width required, + # repeating as necessary + sextend() + sign_extend() + # sign extend expression (replicating the sign bit to the needed width + : parity + # Keyword parity indicates this bit is reserved for parity + # calculation + valid : + # specifies the 16-bit valid hash for one column of the table + hash group : + # hash group config + table: + # one or more hash tables to xor together for this group + seed: + # 52-bit hash seed value + seed_parity: + # optional parameter to indicate if seed must be parity + # encoded, must be true when hash parity is enabled on the + # group. + + # a single table to use for the group + : '[]' + - + # use an xbar group configured elsewhere + random_seed: + # random seed from pragma for the table + exact unit: + output unit: + gateway: + # gateway table on this table -- see below + format: { : , : ... } + # format of data in the table, mapping names to ranges of bits. + # fields with sizes instead of explicit ranges will be laid out + # by the assembler following preceeding fields + hash_dist: { : , ... } + : # hash distribution unit to config + hash: + mask: + shift: + expand: + # hash distribution config params + output: | '[' ,... ']' + # outputs to enable for this hast_dist unit + # 'lo' | 'hi' | 'meter' | 'stats' | 'action' | 'hashmod' + instruction: (, ) + # specifies where to get the action index and pfe for the instruction + # to run in a given table + action: ( [, ]) + # Action table to use -- action is a named field from the format + # that determines which action to do. Index is optional (for + # indirect action), named field from format. If not present use + # direct action (index is match address). + action_enable: + enable_action_data_enable: true | false + enable_action_instruction_enable: true | false + default_action: + default_action_handle: + # Specifies a unique integer for action handle, used to match glass + # If not present assembler generate handles + default_action_parameters: { : , ... } + # Specifies list of params and values + action_bus: { : | .. : , ... } + # immediate actions data + # meter output data + actions: + # defines actions that can be used in the table + []: + # the optional index is the index to use in the 8-entry + # instruction indirection map of the table. + [-
] # constant imem address to use for this action + [- ] # map of aliases for data operands + : [ () ] + # defines a name as an alias for (a slice of) something else + [- p4_param_order: '{' param_name : , ... '}' ] + # Param order specifying param name and width for context json (p4_parameters) + [- hit_allowed: '{' allowed: true|false, reason: '}' ] + [- default_action: '{' allowed: true|false, reason: '}' ] + # the next table to be run when the entry hits with this action, could be + # an index into the hit_next + [- next_table: | ] + # the next table to run when the entry misses with this action + [- next_table_miss: ] + [- context_json: ... ] + # any keys/vector/values here are converted to json and output + # into the context.json info for this action verbatim + - + selector: ( [ , [ , ] ] ) + # selection table to use + stats: [ () ] + # statistics table to use + meter: [ () ] + # meter table to use + stateful: [ ( [, ]) ] + stateful: [ (, counter [ hit | miss | gateway ]) ] + # stateful table to use + idletime: + # idletime table + row: + column: | '[' , ... ']' + bus: + precision: 1 | 2 | 3 | 6 + sweep_interval: + notification: enable | disable | two_way + per_flow_enable: true | false + table_counter: disable | table_miss | table_hit | gateway_miss | + gateway_hit | gateway_inhibit + # event type to count in per-table event counter + hit: | '[' , ... ']' + # next table on table hit. If a list, 'format' must contain a + # 'next' field that determines which next table to use + miss: + # next table on table miss + next: + # default (unconditional) next table. Exclusive with hit/miss + p4: # information about P4 level tables and control plane API + name: + # P4 table name + handle: + # runtime API handle for the table + size: + # table size specified in P4 -- may be smaller than the actual + # table size, as table is rounded up to fill memories + match_type: exact | ternary | lpm | ... + action_profile: + how_referenced: direct | indirect + p4_param_order: + # order of match params as seen in p4 program + # PD generated has same order and needs to match context + # json output + : + # param names with their types and size info + type: + size: + ... + context_json: + # any keys/vector/values here are converted to json and + # output into the context.json info for this match param + # verbatim + context_json: + # any keys/vector/values here are converted to json and output into + # the context.json info for this table verbatim + static_entries: + # List of static entries as described in the p4 program. These are + # passed on directly to the driver through context json. The + # match_key_fields_values and action_parameters_values follow the + # same order as the p4_param_order list in the table and action + # sections. + # Match Key Fields Values based on match type: + # Exact - field_name, value + # Ternary - field_name, value, mask + # Range - field_name, range_start, range_end + # Lpm - field_name, value, prefix_length // TODO + - priority: + match_key_fields_values: + - field_name: + value: + mask: # Only for ternary match + range_start: # Only for range match + range_end: # Only for range match + prefix_length: # Only for lpm match // TODO + action_handle: + is_default_entry: + action_parameters_values: + - parameter_name: + value: + exact_match []: + # Exact match table + row: + column: | '[' , ... ']' + # physical rows and srams used by the table + stash: # Stash Allocation for exact match tables only + row: + col: + # Row and col are indexed in sync to give RAM used to determine word + # in entry + unit: + # Unit value can be (0,1) as there are 2 units per row and is indexed + # in sync with row/col values to give stash unit + input_xbar: + # specifies exact match groups, hash tables, and groups (see above) + # If there are multiple groups, the must match the total width of the + # format, which must in turn match the rows and the ways. + format: { : , : ... } + # names may have `()` suffix denoting up to 5 match groups + # all match groups must contain the same keys + # some names have predefined meanings: + match: ... # exact match groups to match against + action: ... # field that selects which action to run + next: ... # next table + match: | '[' , ... ']' + # value(s) to match against the 'match' field(s) in the format + ways: + - '{' < way description '}' + # description of one way of the table + xme: + # 0 - 7 (lambs) , 8 - 15 (stms) + group: + # hash group or XME used for this way + index: | + # hash bits used to index the way rams/lambs (including subword bits) + select: [ '&' ] + # hash bits used to select enable rams/lambs in the way + rams: '[' , ... ']' + # rams or lambs in the way. Each is a vector of 1, 2, or 3 integers + '[' , ']' # tofino1/2 + - '[' ,,, '[' , ']',... ']' + # DEPRECATED description of one way of the table + # initial 3 values are hash group, 10-bit slice from group, and + # mask of upper 12 bits from the group. + match_group_map: '[' '[' ,... ']',... ']' + # map from per-word match groups to overall match groups + # one row for each word in the width of the table with up to + # 5 values for up to 5 match groups in that word. Values are + # match groups in the format + # common keys described above + action: + actions: + action_bus: + default_action: + default_action_handle: + default_action_parameters: + context_json: + gateway: + hash_dist: + hit: + idletime: + meter: + miss: + next: + p4: + selector: + stateful: + stats: + ternary_match []: + # Ternary match table + row: + column: | '[' , ... ']' + # tcam rows and columns to use + input_xbar: + # specifies ternary match groups + group : | '[' , ... ']' + # odd groups are 5 bytes wide, even groups 6 -- the extra byte + # is the byte group n/2 + # TBD -- Need a way to explicitly set byte swizzler? + match: + # Input xbar group(s) to match against -- may be a vector of maps for wide + # matches using multiple groups + group: + # Match group to match against (placed on tcam bus) + byte_group: + # byte group to use for top 4 bits of tcam bus + byte_config: + # value for tcams.vh_data_xbar.tcam_vh_xbar.tcam_row_halfbyte_mux_ctl + # .tcam_row_halfbyte_mux_ctl_select + dirtcam: + # dirtcam control bits for the group; used to set + # tcams.col.tcam_mode.tcam_data_dirtcam_mode (bits 0..9) + # and tcams.col.tcam_mode.tcam_vbit_dirtcam_mode (bits 10..11) + indirect: + # ternary indirection table to use with this table + # if there's an indirection table, it should contain all the table refs + indirect: | + indirect_bus: + # which indirect bus to use for ternary tables with no indirection table + # common keys described above + action: + actions: + action_bus: + default_action: + default_action_handle: + default_action_parameters: + context_json: + gateway: + hash_dist: + hit: + idletime: + meter: + miss: + next: + p4: + selector: + stateful: + stats: + ternary_indirect : + # Ternary indirection table + row: + column: | '[' , ... ']' + # physical rows and srams to use + bus: 0 | 1 | '[' 0 | 1, ... ']' + # ternary indirection bus to use. List must match rows + format: { : , ... } + # fields in the ram record, sized in bits + # common keys described above + action: + actions: + action_bus: + default_action: + default_action_handle: + default_action_parameters: + context_json: + gateway: + hash_dist: + hit: + idletime: + meter: + miss: + next: + p4: + selector: + stateful: + stats: + hash_action []: + # hash-action table + row: + bus: + # specify which physical row and exact match bus to use + input_xbar: + # input xbar config (as exact match table) + # common keys described above + action: + actions: + action_bus: + default_action: + default_action_handle: + default_action_parameters: + context_json: + gateway: + hash_dist: + hit: + idletime: + meter: + miss: + next: + p4: + selector: + stateful: + stats: + phase0_match + # special phase 0 match table before stage 0 (only in stage 0 ingress) + p4: # information about P4 level tables and control plane API + width: + # other common keys are NOT available in this table type + proxy_hash []: + # Proxy hash Table + row: + column: | '[' , ... ']' + # see exact_match + input_xbar: + # see exact_match + format: { : , : ... } + # see exact_match + match: ... # exact match groups to match against + action: ... # field that selects which action to run + next: ... # next table + match: hash_group(..) | '[' hash_group(..), ... ']' + # hash groups + ways: + - '[' ,,, '[' , ']',... ']' + # see exact_match + proxy_hash_group: + # hash group of the 8 possible hash groups to use + proxy_hash_algorithm: + # for the context JSON, proxy_hash_algorithm key + # common keys described above + action: + actions: + action_bus: + default_action: + default_action_handle: + default_action_parameters: + context_json: + gateway: + hash_dist: + hit: + idletime: + meter: + miss: + next: + p4: + selector: + stateful: + stats: + action : + # Action table + logical_row: + column: | '[' , ... ']' + # srams to use -- in logical (16x6) coords, not physical (8x12) + home_row: | '[' , ... ']' + # row(s) to use as home rows for the table + format []: { : , ... } + # fields in the ram record. Different actions may have + # different formats (and different sizes)... + action_bus: { : | .. : , ... } + # mapping from action bus bytes to values in the table. Names + # must be present in the 'format' for the table. + # Can be optional -- if not present, assembler will attempt to + # lay out fields in the action bus based on usage in actions. + actions: + # defines actions that can be used in the table + []: + # the optional index is the index to use in the 8-entry + # instruction indirection map of the table. + [-
] # constant imem address to use for this action + [- ] # map of aliases for data operands + : [ () ] + # defines a name as an alias for (a slice of) something else + [- p4_param_order: '{' param_name : , ... '}' ] + # Param order specifying param name and width for context json (p4_parameters) + [- p4_param_order: + param_name: + width: + context_json: #anything + ... ] + # Alternative syntax for specifying param order when attaching context_json + [- default_action: '{' allowed: true|false, reason: '}' ] + - + p4: # information about P4 level tables and control plane API + # same as exact_match p4 info + context_json: #anything + gateway []: + # 'bare' Gateway table -- no corresponding match table, so must + # always specify next table + name: + # Only output when gateway associated with a match table i.e. not + # 'bare' + row: + # physical match row to use + bus: 0 | 1 + # match bus to use + payload_row: + payload_bus: + # row/bus to use for payload -- can only be specified on a + # standalone gateway, as an attached gateway uses the row(s) + # specified by the table it is attached to + input_xbar: + # as for exact_match, but can only specify one group + match: | '[' , ... ']' + # value(s) to match against the match constants + xor: | '[' , ... ']' + # value(s) to xor against the match value + range: 2 | 4 + # do 2 or 4 bit range matches in the upper 12 bits of the gateway + : + # match row for gateway. Value may be (for next table) + # or "run_table" or a map with some or all of these keys. + next: + # next table for this match + run_table: | + # disable the gateway (run the logical match normally) + # not applicable to bare gateways + action: + # run the specified action when the line hits + ? [ , ..., ] : + # Range match row for gateway. Each value except the ladt is a + # 2**n bit lookup table for a range match unit (so 4 bit values + # for range:2 and 16 bit values for range:4). The last value is + # the normal tcam match for the bottm 32 bits of the gateway + # Same value options as normal match rows. Big-endian order + # for units (last int is bottom 2 or 4 bits of upper 12 bits) + miss: + # behavior if no row matches (same options as match row above) + condition: + # condition output used for model logging + expression : + # condition string as specified in p4 + true : + # next table name when condition is true + false : + # next table name when condition is false + payload: + # payload data to use if gateway is not disabled (run_table is false) + match_address: + # gateway match address to use if the gateway is not disabled + context_json: #anything + selection []: + row: + logical_bus: + # must match the number of rows specified. Indicate the logical bus + # used for each rows. Value can be: 'A' => Action Bus, 'S' => Synth + # Bus, 'O' => Overflow Bus, 'X' => Undefined. + column: | '[' , ... ']' + # srams to use -- in logical (16x6) coords, not physical (8x12) + maprams: | '[' , ... ']' + # map rams to use + home_row: + # represent the row ultimately connected to the ALU + input_xbar: + # hash match groups on input xbar + mode: resilient | fair + non_linear: true | false + per_flow_enable: true | false + pool_sizes: + selection_hash: + hash_dist: + # see hash_action hash_dist + p4: # information about P4 level tables and control plane API + # same as exact_match p4 info + context_json: #anything + counter []: + row: + logical_bus: + # must match the number of rows specified. Indicate the logical bus + # used for each rows. Value can be: 'A' => Action Bus, 'S' => Synth + # Bus, 'O' => Overflow Bus, 'X' => Undefined. + column: | '[' , ... ']' + # srams to use -- in logical (16x6) coords, not physical (8x12) + maprams: | '[' , ... ']' + # map rams to use + vpns: + home_row: + # represent the row ultimately connected to the ALU + format: + count: bytes | packets | both | packets_and_bytes + lrt: '{' : , ... '}' + - '{' threshold: , interval: '}' ... + # largest recent with threshold params + global_binding: true | false + per_flow_enable: true | false + bytecount_adjust: + # add value to counted bytes + meter []: + row: + logical_bus: + # must match the number of rows specified. Indicate the logical bus + # used for each rows. Value can be: 'A' => Action Bus, 'S' => Synth + # Bus, 'O' => Overflow Bus, 'X' => Undefined. + column: | '[' , ... ']' + # srams to use -- in logical (16x6) coords, not physical (8x12) + maprams: | '[' , ... ']' + # map rams to use + vpns: + home_row: + # represent the row ultimately connected to the ALU + input_xbar: + # hash match groups on input xbar + color_aware: true | false | per_flow + color_maprams: + row: + # logical rows + column: | '[' , ... ']' + bus: + vpns: + hash_dist: + # see hash_action hash_dist + type: standard | lpf | red + count: bytes | packets + bytecount_adjust: + # add value to counted bytes + sweep_interval: + global_binding: true | false + per_flow_enable: true | false + context_json: #anything + stateful []: + row: + logical_bus: + # must match the number of rows specified. Indicate the logical bus + # used for each rows. Value can be: 'A' => Action Bus, 'S' => Synth + # Bus, 'O' => Overflow Bus, 'X' => Undefined. + column: | '[' , ... ']' + # srams to use -- in logical (16x6) coords, not physical (8x12) + maprams: | '[' , ... ']' + # map rams to use + vpns: + home_row: + # represent the row ultimately connected to the ALU + hash_dist: + # see hash_action hash_dist + input_xbar: + # exact match group and hash to use for phv input + data_bytemask: + hash_bytemask: + # masks specifying which byte of the phv input come from data and hash + initial_value: { lo : , hi : } + # Specify initial value for register, assumed 0 otherwise + const_table: | '{' : '}' + math_table: + data: | '{' : '}' + invert: true | false + shift: + scale: + log_vpn: | + # vpns to use in stateful logging mode + pred_shift: + pred_comb_shift: + # set the salu_output_pred_shift and _comb_shift csr regs explicitly + # FIXME -- should have a better way of doing this? + actions: + : + - + # SALU instructions to run for this table + context_json: #anything + # jbay additional features: + sbus: + # jbay only -- shared bus use + learn: | '['
, ... ']' + match:
| '['
, ... ']' + combine: "and" | "or" + fifo: { push: , pop: } + stack: { push: , pop: } + bloom filter clear: + # fifo or stack or bloom filter fast clear mode (mutually exclusive) + # is hit | miss | gateway | active | control_plane + # controls when the stack/fifo is pushed or popped + watermark: push | pop + # watermark interrupts sent every pushes or pops + offset_vpn: true | false + # adjust immediate data by vpn offset to compute vpns for multistage + # fifo/stack (jbay only) + address_shift: + # shift up the incoming meter address before vpn/index/subword extract (jbay only) + stage_alu_id: + # stage + alu id to be preprended to output addresses + dependency: concurrent | action | match + # set the interstage dependency between this stage and the + # previous stage. Ignored in stage 0 + error_mode: no_config | propagate | map_to_immediate | disable + always_run_action: + # action that runs automatcially in the stage independent of tables + - + # configuration setting for mpr_stage_id + mpr_stage_id: + # configuration setting for mpr_bus_dep_glob_exec + # A bit that is 0 means treat that global execute bit as pass-through (action dependent), + # because the next stage is action dependent, while a 1 means update it in the current stage. + mpr_bus_dep_glob_exec: + # configuration setting for mpr_bus_dep_long_brch + # A bit that is 0 means treat that long branch tag ID bit as pass-through (action dependent), + # because the next stage is action dependent, while a 1 means update it in the current stage. + mpr_bus_dep_long_brch: + # configuration setting for mpr_always_run + mpr_always_run: + # Note that unspecified values are assumed to be 0. + mpr_next_table_lut: + : # Resolved incoming logical ID to activation bit map + mpr_glob_exec_lut: + : # Resolved incoming global execute bit to activation bit map + mpr_long_brch_lut: + : # Resolved incoming long branch tag ID to activation bit map +deparser : + # Defines a deparser. must be 'ingress' or 'egress' + dictionary: + # ordered list of phv locations to write out as the output deparser + - : + # single value to write iff the referred bit is set + - full_checksum : + # checksum result to write iff the referred bit is set + - : + # constant to write iff the referred bit is set (jbay only) + - clot : + # clot to output (jbay only) + pov: + length: + # maximum length of the clot + : | checksum + # offset in clot to replace with a PHV or checksum value + pov: | '[' , ... ']' + # optional explicit use/ordering of phvs for POV. All phvs used for POV bits + # in the dictionary will be added to the end of this, if not already present + partial_checksum : + : { swap: [, pov: ] } + # checksum unit programming -- pov bits for jbay only + full_checksum : + partial_checksum | clot : { pov: , invert: } + : [ ':' + # more generally, any deparser param that comes from the phv is + # specified this way. Only jbay has pov bits here + # are as follows + select: [ ':' ] + # controls which digest group is output + shift: + : | '[' , ... ']' + # values for a single digest group; specifies the sequence of + # phv containers in the appropriate table entry. this is usually + # data that is included in the digest, but it may also contain + # control metadata; for example, when configuring mirroring on + # Tofino, the first phv container specifies the mirror session id. + context_json: # anything + # ingress or egress params: + mirror: + egress_unicast_port: [ ':' ] + # specifies the port to write to + # FIXME: should this be squashed into the port? + egress_unicast_pipe: [ ':' ] + # specifies the port to write to + drop_ctl: [ ':' ] + # jbay only, ingress or egress + afc: '{' location> ':' '}' + mirr_epipe_port: '{' location> ':' '}' + mirr_c2c_ctrl: '{' location> ':' '}' + mirr_coal_smpl_len: '{' location> ':' '}' + mirr_dond_ctrl: '{' location> ':' '}' + mirr_hash: '{' location> ':' '}' + mirr_icos: '{' location> ':' '}' + mirr_io_sel: '{' location> ':' '}' + mirr_mc_ctrl: '{' location> ':' '}' + mirr_qid: '{' location> ':' '}' + mtu_trunc_err_f: '{' location> ':' '}' + mtu_trunc_len: '{' location> ':' '}' + # ingress only deparser params: + learning: [ ':' ] + resubmit: [ ':' ] + copy_to_cpu: [ ':' ] + egress_multicast_group_: [ ':' ] + hash_lag_ecmp_mcast_: [ ':' ] + copy_to_cpu_cos: [ ':' ] + ingress_port_source: [ ':' ] + deflect_on_drop: [ ':' ] + meter_color: [ ':' ] + icos: [ ':' ] + qid: [ ':' ] + xid: [ ':' ] + yid: [ ':' ] + rid: [ ':' ] + warp: [ ':' ] + ct_disable: [ ':' ] + ct_mcast: [ ':' ] + # jbay ingress only + bypass_egr: '{' location> ':' '}' + # egress only deparser params: [ ':' ] + force_tx_err: [ ':' ] + tx_pkt_has_offsets: [ ':' ] + capture_tx_ts: [ ':' ] + coal: [ ':' ] + ecos: [ ':' ] + copy_to_cpu_cos: [ ':' ] # or c2c_cos + copy_to_cpu_qid: [ ':' ] # or c2c_qid + mirr_bitmap: [ ':' ] + valid_vec: [ ':' ] + # Ingress pipe -> TM fields + # - tableid (1b) -- ??? + # - mcid1 - Multicast Group ID 1 + # - mcid2 - Multicast Group ID 2 + # - hash1 - Hash for L1 (is the the same as hash_lag_ecmp_mcast_?) + # - hash2 - Hash for L2 (is the the same as hash_lag_ecmp_mcast_?) + packet_body_offset: + # TODO: Needed? Maybe just use a fixed header type for PBO? + # Packet body offset + # Payload body offset is: + # base_offset (unsigned) + const_offset (signed) + var_offset (unsigned). + hdr: | + # Header name or ID to use for base offset location + offset: + # Constant (signed) offset to add to the base offset + # Default: 0 + var_off_pos: + # Variable offset: start bit position in POV + # Default: 0 + var_off_len: + # Variable offset: length in POV + # Default: 0 + zero: , + # list of phv slots that should be initialized to (valid) zero + remaining_bridge_metadata: + # packing of remaining bridge metadata + pov_select: + # POV bytes used to address the TCAM & SRAM + config : + # TCAM & SRAM configuration + match: + # POV match (4B) + start: + # start position of the remaining bridge metadata in bridge metadata (6b) + # register: rem_brm_ext_ram.rem_brm_ext[*].rem_brm_start + bytes: '[' | , ... ']' | '{' ':' | , ... '}' + # source PHEs of the remaining bridge metadata + # if a list is used, the items are implicitly addressed (from 0 up) bytes of remaining bridge metadata + # if a map is used, the items are explicitly addressed bytes of remaining bridge metadata + # up to 62 items depending on the remaining bridge metadata start position and the number of POV bytes (8B flags + 8B state) + # if an 8b constant is used as the PHE byte source, its value is directly written to the configuration registers + # if a PHE (slice) name is used as the PHE byte source, it is first mapped to the PHE byte number + # registers: rem_brm_ext_ram.rem_brm_ext[*].b*_phv_sel +flexible_headers: + # Lists the headers that were re-packed by the compiler because + # they were marked flexible. See context.json schema 'flexible_headers' node + # for more information. This section is optional. It exists only if there are + # flexible headers defined in the program (e.g., bridged metadata) + # It consists of the json snippet that is part of context.json verbatim. +primitives: + # Defines the name of the json file that has information on primitives used + # within table actions. These are placed in the respective actions as + # primitives node. This node is mainly used by model for logging + # instructions as specified in original p4 program +dynhash: + # Defines the name of the json file that has the dynamic hash calculation + # node. This node is directly merged into the context json at the top level +# version 1.0.0 +version: + # semantic versioning number +# version 1.0.1 +version: + version: + # semantic versioning number + run_id: + # defines an id that ties together all the files produced by the compiler + # part of the Version section + target: + # specify the target architecture diff --git a/backends/tofino/bf-asm/action_bus.cpp b/backends/tofino/bf-asm/action_bus.cpp new file mode 100644 index 00000000000..299743a607b --- /dev/null +++ b/backends/tofino/bf-asm/action_bus.cpp @@ -0,0 +1,1202 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "action_bus.h" + +#include + +#include "hex.h" +#include "misc.h" +#include "stage.h" + +static MeterBus_t MeterBus; + +std::ostream &operator<<(std::ostream &out, const ActionBusSource &src) { + const char *sep = ""; + switch (src.type) { + case ActionBusSource::None: + out << "None"; + break; + case ActionBusSource::Field: + out << "Field("; + for (auto &range : src.field->bits) { + out << sep << range.lo << ".." << range.hi; + sep = ", "; + } + out << ")"; + if (src.field->fmt && src.field->fmt->tbl) + out << " " << src.field->fmt->tbl->find_field(src.field); + break; + case ActionBusSource::HashDist: + out << "HashDist(" << src.hd->hash_group << ", " << src.hd->id << ")"; + break; + case ActionBusSource::HashDistPair: + out << "HashDistPair([" << src.hd1->hash_group << ", " << src.hd1->id << "]," << "[" + << src.hd2->hash_group << ", " << src.hd2->id << "])"; + break; + case ActionBusSource::RandomGen: + out << "rng " << src.rng.unit; + break; + case ActionBusSource::TableOutput: + out << "TableOutput(" << (src.table ? src.table->name() : "0") << ")"; + break; + case ActionBusSource::TableColor: + out << "TableColor(" << (src.table ? src.table->name() : "0") << ")"; + break; + case ActionBusSource::TableAddress: + out << "TableAddress(" << (src.table ? src.table->name() : "0") << ")"; + break; + case ActionBusSource::Ealu: + out << "EALU"; + break; + case ActionBusSource::XcmpData: + out << "XCMP(" << src.xcmp_group << ":" << src.xcmp_byte << ")"; + break; + case ActionBusSource::NameRef: + out << "NameRef(" << (src.name_ref ? src.name_ref->name : "0") << ")"; + break; + case ActionBusSource::ColorRef: + out << "ColorRef(" << (src.name_ref ? src.name_ref->name : "0") << ")"; + break; + case ActionBusSource::AddressRef: + out << "AddressRef(" << (src.name_ref ? src.name_ref->name : "0") << ")"; + break; + default: + out << ""; + break; + } + return out; +} + +/* identifes which bytes on the action bus are tied together in the hv_xbar input, + * so must be routed together. The second table here is basically just bitcount of + * masks in the first table. */ +static std::array, ACTION_HV_XBAR_SLICES> action_hv_slice_byte_groups = {{ + {0x3, 0x3, 0xc, 0xc, 0xf0, 0xf0, 0xf0, 0xf0, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, + 0xff00, 0xff00}, + {0xf, 0xf, 0xf, 0xf, 0xf0, 0xf0, 0xf0, 0xf0, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, + 0xff00, 0xff00}, + {0xf, 0xf, 0xf, 0xf, 0xf0, 0xf0, 0xf0, 0xf0, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, + 0xff00, 0xff00}, + {0xf, 0xf, 0xf, 0xf, 0xf0, 0xf0, 0xf0, 0xf0, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, + 0xff00, 0xff00}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, + 0xff00, 0xff00}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, + 0xff00, 0xff00}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, + 0xff00, 0xff00}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, + 0xff00, 0xff00}, +}}; + +static std::array, ACTION_HV_XBAR_SLICES> action_hv_slice_group_align = { + {{2, 2, 2, 2, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8}, + {4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8}, + {4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8}, + {4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}, + {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}}}; + +ActionBus::ActionBus(Table *tbl, VECTOR(pair_t) & data) { + lineno = data.size ? data[0].key.lineno : -1; + for (auto &kv : data) { + if (!CHECKTYPE2(kv.key, tINT, tRANGE)) continue; + unsigned idx = kv.key.type == tRANGE ? kv.key.lo : kv.key.i; + if (!CHECKTYPE2M(kv.value, tSTR, tCMD, "field name or slice")) continue; + const char *name = kv.value.s; + value_t *name_ref = &kv.value; + unsigned off = 0, sz = 0; + if (kv.value.type == tCMD) { + BUG_CHECK(kv.value.vec.size > 0 && kv.value[0].type == tSTR); + if (kv.value == "hash_dist" || kv.value == "rng") { + if (!PCHECKTYPE(kv.value.vec.size > 1, kv.value[1], tINT)) continue; + name = kv.value[0].s; + name_ref = nullptr; + } else { + if (!PCHECKTYPE2M(kv.value.vec.size == 2, kv.value[1], tRANGE, tSTR, + "field name or slice")) + continue; + // if ((kv.value[1].lo & 7) != 0 || (kv.value[1].hi & 7) != 7) { + // error(kv.value.lineno, "Slice must be byte slice"); + // continue; } + name = kv.value[0].s; + name_ref = &kv.value[0]; + if (kv.value[1].type == tRANGE) { + off = kv.value[1].lo; + sz = kv.value[1].hi - kv.value[1].lo + 1; + } else if (kv.value[1] != "color") { + error(kv.value[1].lineno, "unexpected %s", kv.value[1].s); + } + } + } + Table::Format::Field *f = tbl->lookup_field(name, "*"); + ActionBusSource src; + const char *p = name - 1; + while (!f && (p = strchr(p + 1, '.'))) + f = tbl->lookup_field(p + 1, std::string(name, p - name)); + if (!f) { + if (tbl->table_type() == Table::ACTION) { + error(kv.value.lineno, "No field %s in format", name); + continue; + } else if (kv.value == "meter") { + src = ActionBusSource(MeterBus); + if (kv.value.type == tCMD) { + if (kv.value[1] == "color") { + src.type = ActionBusSource::ColorRef; + if (!sz) off = 24, sz = 8; + } else if (kv.value[1] == "address") { + src.type = ActionBusSource::AddressRef; + } + } + } else if (kv.value.type == tCMD && kv.value == "hash_dist") { + if (auto hd = tbl->find_hash_dist(kv.value[1].i)) { + src = ActionBusSource(hd); + } else { + error(kv.value.lineno, "No hash_dist %" PRId64 " in table %s", kv.value[1].i, + tbl->name()); + continue; + } + sz = 16; + for (int i = 2; i < kv.value.vec.size; ++i) { + if (kv.value[i] == "lo" || kv.value[i] == "low") { + src.hd->xbar_use |= HashDistribution::IMMEDIATE_LOW; + } else if (kv.value[i] == "hi" || kv.value[i] == "high") { + src.hd->xbar_use |= HashDistribution::IMMEDIATE_HIGH; + off += 16; + } else if (kv.value[i].type == tINT) { + if (auto hd_hi = tbl->find_hash_dist(kv.value[i].i)) { + src.hd->xbar_use |= HashDistribution::IMMEDIATE_LOW; + hd_hi->xbar_use |= HashDistribution::IMMEDIATE_HIGH; + setup_slot(kv.value.lineno, tbl, name, idx + 2, ActionBusSource(hd_hi), + 16, 16); + setup_slot(kv.value.lineno, tbl, name, idx, + ActionBusSource(src.hd, hd_hi), 32, 0); + } + } else if (kv.value[i].type == tRANGE) { + if ((kv.value[i].lo & 7) != 0 || (kv.value[i].hi & 7) != 7) + error(kv.value.lineno, "Slice must be byte slice"); + off += kv.value[i].lo; + sz = kv.value[i].hi - kv.value[i].lo + 1; + } else { + error(kv.value[i].lineno, "Unexpected hash_dist %s", + value_desc(kv.value[i])); + break; + } + } + } else if (kv.value.type == tCMD && kv.value == "rng") { + src = ActionBusSource(RandomNumberGen(kv.value[1].i)); + if (kv.value.vec.size > 2 && CHECKTYPE(kv.value[2], tRANGE)) { + off = kv.value[2].lo; + sz = kv.value[2].hi + 1 - off; + } + } else if (name_ref) { + src = ActionBusSource(new Table::Ref(*name_ref)); + if (kv.value.type == tCMD) { + if (kv.value[1] == "color") { + src.type = ActionBusSource::ColorRef; + if (!sz) off = 24, sz = 8; + } else if (kv.value[1] == "address") { + src.type = ActionBusSource::AddressRef; + } + } + } else if (tbl->format) { + error(kv.value.lineno, "No field %s in format", name); + continue; + } + } else { + src = ActionBusSource(f); + if (!sz) sz = f->size; + if (off + sz > f->size) + error(kv.value.lineno, "Invalid slice of %d bit field %s", f->size, name); + } + if (kv.key.type == tRANGE) { + unsigned size = (kv.key.hi - idx + 1) * 8; + // Make slot size (sz) same as no. of bytes allocated on action bus. + if (size > sz) sz = size; + } else if (!sz) { + sz = idx < ACTION_DATA_8B_SLOTS ? 8 + : idx < ACTION_DATA_8B_SLOTS + 2 * ACTION_DATA_16B_SLOTS ? 16 + : 32; + } + setup_slot(kv.key.lineno, tbl, name, idx, src, sz, off); + tbl->apply_to_field( + name, [](Table::Format::Field *f) { f->flags |= Table::Format::Field::USED_IMMED; }); + if (f) { + auto &slot = by_byte.at(idx); + tbl->apply_to_field(name, [&slot, tbl, off](Table::Format::Field *f) { + ActionBusSource src(f); + if (slot.data.emplace(src, off).second) { + LOG4(" data += " << src.toString(tbl) << " off=" << off); + } + }); + } + } +} + +std::unique_ptr ActionBus::create() { + return std::unique_ptr(new ActionBus()); +} + +std::unique_ptr ActionBus::create(Table *tbl, VECTOR(pair_t) & data) { + return std::unique_ptr(new ActionBus(tbl, data)); +} + +void ActionBus::setup_slot(int lineno, Table *tbl, const char *name, unsigned idx, + ActionBusSource src, unsigned sz, unsigned off) { + if (idx >= ACTION_DATA_BUS_BYTES) { + error(lineno, "Action bus index out of range"); + return; + } + if (by_byte.count(idx)) { + auto &slot = by_byte.at(idx); + if (sz > slot.size) { + slot.name = name; + slot.size = sz; + } + slot.data.emplace(src, off); + LOG4("ActionBus::ActionBus: " << idx << ": " << name << " sz=" << sz + << " data += " << src.toString(tbl) << " off=" << off); + } else { + by_byte.emplace(idx, Slot(name, idx, sz, src, off)); + LOG4("ActionBus::ActionBus: " << idx << ": " << name << " sz=" << sz + << " data = " << src.toString(tbl) << " off=" << off); + } +} + +unsigned ActionBus::Slot::lo(Table *tbl) const { + int rv = -1; + for (auto &src : data) { + int off = src.second; + if (src.first.type == ActionBusSource::Field) off += src.first.field->immed_bit(0); + BUG_CHECK(rv < 0 || rv == off); + rv = off; + } + BUG_CHECK(rv >= 0); + return rv; +} + +bool ActionBus::compatible(const ActionBusSource &a, unsigned a_off, const ActionBusSource &b, + unsigned b_off) { + if ((a.type == ActionBusSource::HashDist) && (b.type == ActionBusSource::HashDistPair)) { + return ((compatible(a, a_off, ActionBusSource(b.hd1), b_off)) || + (compatible(a, a_off, ActionBusSource(b.hd2), b_off + 16))); + } else if ((a.type == ActionBusSource::HashDistPair) && (b.type == ActionBusSource::HashDist)) { + return ((compatible(ActionBusSource(a.hd1), a_off, b, b_off)) || + (compatible(ActionBusSource(a.hd2), a_off + 16, b, b_off))); + } + if (a.type != b.type) return false; + switch (a.type) { + case ActionBusSource::Field: + // corresponding fields in different groups are compatible even though they + // are at different locations. Table::Format::pass1 checks that + if (a.field->by_group == b.field->by_group) return true; + return a.field->bit(a_off) == b.field->bit(b_off); + case ActionBusSource::HashDist: + return a.hd->hash_group == b.hd->hash_group && a.hd->id == b.hd->id && a_off == b_off; + case ActionBusSource::HashDistPair: + return ((a.hd1->hash_group == b.hd1->hash_group && a.hd1->id == b.hd1->id) && + (a_off == b_off) && + (a.hd2->hash_group == b.hd2->hash_group && a.hd2->id == b.hd2->id)); + case ActionBusSource::TableOutput: + return a.table == b.table; + default: + return false; + } +} + +void ActionBus::pass1(Table *tbl) { + bool is_immed_data = dynamic_cast(tbl) != nullptr; + LOG1("ActionBus::pass1(" << tbl->name() << ")" << (is_immed_data ? " [immed]" : "")); + if (lineno < 0) + lineno = tbl->format && tbl->format->lineno >= 0 ? tbl->format->lineno : tbl->lineno; + Slot *use[ACTION_DATA_BUS_SLOTS] = {0}; + for (auto &slot : Values(by_byte)) { + for (auto it = slot.data.begin(); it != slot.data.end();) { + if (it->first.type >= ActionBusSource::NameRef && + it->first.type <= ActionBusSource::AddressRef) { + // Remove all NameRef and replace with TableOutputs or Fields + // ColorRef turns into TableColor, AddressRef into TableAddress + if (it->first.name_ref) { + bool ok = false; + if (*it->first.name_ref) { + ActionBusSource src(*it->first.name_ref); + switch (it->first.type) { + case ActionBusSource::NameRef: + src.table->set_output_used(); + break; + case ActionBusSource::ColorRef: + src.type = ActionBusSource::TableColor; + src.table->set_color_used(); + break; + case ActionBusSource::AddressRef: + src.type = ActionBusSource::TableAddress; + src.table->set_address_used(); + break; + default: + BUG(); + } + slot.data[src] = it->second; + ok = true; + } else if (tbl->actions) { + Table::Format::Field *found_field = nullptr; + Table::Actions::Action *found_act = nullptr; + for (auto &act : *tbl->actions) { + int lo = -1, hi = -1; + auto name = act.alias_lookup(it->first.name_ref->lineno, + it->first.name_ref->name, lo, hi); + if (auto *field = tbl->lookup_field(name, act.name)) { + if (found_field) { + if (field != found_field || + slot.data.at(ActionBusSource(field)) != it->second + lo) + error(it->first.name_ref->lineno, + "%s has incompatible " + "aliases in actions %s and %s", + it->first.name_ref->name.c_str(), + found_act->name.c_str(), act.name.c_str()); + } else { + found_act = &act; + found_field = field; + slot.data[ActionBusSource(field)] = it->second + lo; + ok = true; + } + } + } + } + if (!ok) + error(it->first.name_ref->lineno, "No format field or table named %s", + it->first.name_ref->name.c_str()); + } else { + auto att = tbl->get_attached(); + if (!att || att->meters.empty()) { + error(lineno, "No meter table attached to %s", tbl->name()); + } else if (att->meters.size() > 1) { + error(lineno, "Multiple meter tables attached to %s", tbl->name()); + } else { + ActionBusSource src(att->meters.at(0)); + switch (it->first.type) { + case ActionBusSource::NameRef: + src.table->set_output_used(); + break; + case ActionBusSource::ColorRef: + src.type = ActionBusSource::TableColor; + src.table->set_color_used(); + break; + case ActionBusSource::AddressRef: + src.type = ActionBusSource::TableAddress; + src.table->set_address_used(); + break; + default: + BUG(); + } + slot.data[src] = it->second; + } + } + it = slot.data.erase(it); + } else { + if (it->first.type == ActionBusSource::TableColor) + it->first.table->set_color_used(); + if (it->first.type == ActionBusSource::TableOutput) + it->first.table->set_output_used(); + ++it; + } + } + if (error_count > 0) continue; + auto first = slot.data.begin(); + if (first != slot.data.end()) { + for (auto it = next(first); it != slot.data.end(); ++it) { + if (!compatible(first->first, first->second, it->first, it->second)) + error(lineno, "Incompatible action bus entries at offset %d", slot.byte); + } + } + int slotno = Stage::action_bus_slot_map[slot.byte]; + for (unsigned byte = slot.byte; byte < slot.byte + slot.size / 8U; + byte += Stage::action_bus_slot_size[slotno++] / 8U) { + if (slotno >= ACTION_DATA_BUS_SLOTS) { + error(lineno, "%s extends past the end of the actions bus", slot.name.c_str()); + break; + } + if (auto tbl_in_slot = tbl->stage->action_bus_use[slotno]) { + if (tbl_in_slot != tbl) { + if (!(check_atcam_sharing(tbl, tbl_in_slot) || + check_slot_sharing(slot, tbl->stage->action_bus_use_bit_mask))) + warning(lineno, "Action bus byte %d set in table %s and table %s", byte, + tbl->name(), tbl->stage->action_bus_use[slotno]->name()); + } + } else { + tbl->stage->action_bus_use[slotno] = tbl; + // Set a per-byte mask on the action bus bytes to indicate which + // bits in bytes are being used. A slot can be shared among + // tables which dont overlap any bits. The code assumes the + // action bus allocation is byte aligned (and sets the mask to + // 0xF), while this could ideally be not the case. In that + // event, the mask must be set accordingly. This will require + // additional logic to determine which bits in the byte are used + // or additional syntax in the action bus assembly output. + tbl->stage->action_bus_use_bit_mask.setrange(slot.byte * 8U, slot.size); + } + if (use[slotno]) { + BUG_CHECK(!slot.data.empty() && !use[slotno]->data.empty()); + auto nsrc = slot.data.begin()->first; + unsigned noff = slot.data.begin()->second; + unsigned nstart = 8 * (byte - slot.byte) + noff; + if (nsrc.type == ActionBusSource::Field) nstart = nsrc.field->immed_bit(nstart); + auto osrc = use[slotno]->data.begin()->first; + unsigned ooff = use[slotno]->data.begin()->second; + unsigned ostart = 8 * (byte - use[slotno]->byte) + ooff; + if (osrc.type == ActionBusSource::Field) { + if (ostart < osrc.field->size) + ostart = osrc.field->immed_bit(ostart); + else + ostart += osrc.field->immed_bit(0); + } + if (ostart != nstart) + error(lineno, + "Action bus byte %d used inconsistently for fields %s and " + "%s in table %s", + byte, use[slotno]->name.c_str(), slot.name.c_str(), tbl->name()); + } else { + use[slotno] = &slot; + } + unsigned hi = slot.lo(tbl) + slot.size - 1; + if (action_hv_slice_use.size() <= hi / 128U) action_hv_slice_use.resize(hi / 128U + 1); + auto &hv_groups = action_hv_slice_byte_groups.at(slot.byte / 16); + for (unsigned byte = slot.lo(tbl) / 8U; byte <= hi / 8U; ++byte) { + byte_use[byte] = 1; + action_hv_slice_use.at(byte / 16).at(slot.byte / 16) |= hv_groups.at(byte % 16); + } + } + } +} + +bool ActionBus::check_slot_sharing(Slot &slot, bitvec &action_bus) { + return (action_bus.getrange(slot.byte * 8U, slot.size) == 0); +} + +bool ActionBus::check_atcam_sharing(Table *tbl1, Table *tbl2) { + bool atcam_share_bytes = false; + bool atcam_action_share_bytes = false; + // Check tables are not same atcam's sharing bytes on action bus + if (tbl1->to() && tbl2->to() && + tbl1->p4_table->p4_name() == tbl2->p4_table->p4_name()) + atcam_share_bytes = true; + // Check tables are not same atcam action tables sharing bytes on action bus + if (auto tbl1_at = tbl1->to()) { + if (auto tbl2_at = tbl2->to()) { + auto tbl1_mt = tbl1_at->get_match_table(); + auto tbl2_mt = tbl2_at->get_match_table(); + if (tbl1_mt->p4_table->p4_name() == tbl2_mt->p4_table->p4_name()) + atcam_action_share_bytes = true; + } + } + return (atcam_share_bytes || atcam_action_share_bytes); +} + +void ActionBus::need_alloc(Table *tbl, const ActionBusSource &src, unsigned lo, unsigned hi, + unsigned size) { + LOG3("need_alloc(" << tbl->name() << ") " << src << " lo=" << lo << " hi=" << hi << " size=0x" + << hex(size)); + need_place[src][lo] |= size; + switch (src.type) { + case ActionBusSource::Field: + lo += src.field->immed_bit(0); + break; + case ActionBusSource::TableOutput: + src.table->set_output_used(); + break; + case ActionBusSource::TableColor: + src.table->set_color_used(); + break; + case ActionBusSource::TableAddress: + src.table->set_address_used(); + break; + case ActionBusSource::XcmpData: + break; + default: + break; + } + byte_use.setrange(lo / 8U, size); +} + +/** + * find_free -- find a free slot on the action output bus for some data. Looks through bytes + * in the range min..max for a free space where we can put 'bytes' bytes from an action + * input bus starting at 'lobyte'. 'step' is an optimization to only check every step bytes + * as we know alignment restrictions mean those are the only possible aligned spots + */ +int ActionBus::find_free(Table *tbl, unsigned min, unsigned max, unsigned step, unsigned lobyte, + unsigned bytes) { + unsigned avail; + LOG4("find_free(" << min << ", " << max << ", " << step << ", " << lobyte << ", " << bytes + << ")"); + for (unsigned i = min; i + bytes - 1 <= max; i += step) { + unsigned hv_slice = i / ACTION_HV_XBAR_SLICE_SIZE; + auto &hv_groups = action_hv_slice_byte_groups.at(hv_slice); + int mask1 = action_hv_slice_group_align.at(hv_slice).at(lobyte % 16U) - 1; + int mask2 = action_hv_slice_group_align.at(hv_slice).at((lobyte + bytes - 1) % 16U) - 1; + if ((i ^ lobyte) & mask1) continue; // misaligned + bool inuse = false; + for (unsigned byte = lobyte & ~mask1; byte <= ((lobyte + bytes - 1) | mask2); ++byte) { + if (!byte_use[byte]) continue; + if (action_hv_slice_use.size() <= byte / 16U) + action_hv_slice_use.resize(byte / 16U + 1); + if (action_hv_slice_use.at(byte / 16U).at(hv_slice) & hv_groups.at(byte % 16U)) { + LOG5(" input byte " << byte << " in use for hv_slice " << hv_slice); + inuse = true; + break; + } + } + if (inuse) { + // skip up to next hv_slice + while ((i + step) / ACTION_HV_XBAR_SLICE_SIZE == hv_slice) i += step; + continue; + } + for (unsigned byte = i & ~mask1; byte <= ((i + bytes - 1) | mask2); ++byte) + if (tbl->stage->action_bus_use[Stage::action_bus_slot_map[byte]]) { + LOG5(" output byte " + << byte << " in use by " + << tbl->stage->action_bus_use[Stage::action_bus_slot_map[byte]]->name()); + inuse = true; + break; + } + if (inuse) continue; + for (avail = 1; avail < bytes; avail++) + if (tbl->stage->action_bus_use[Stage::action_bus_slot_map[i + avail]]) break; + if (avail >= bytes) return i; + } + return -1; +} + +/** + * find_merge -- find any adjacent/overlapping data on the action input bus that means the + * data at 'offset' actually already on the action output bus + * offset offset (in bits) on the action input bus of the data we're interested in + * bytes how many bytes of data on the action input bus + * use bitmask of the sizes of phv that need to access this on the action output bus + */ +int ActionBus::find_merge(Table *tbl, int offset, int bytes, int use) { + LOG4("find_merge(" << offset << ", " << bytes << ", " << use << ")"); + bool is_action_data = dynamic_cast(tbl) != nullptr; + for (auto &alloc : by_byte) { + if (use & 1) { + if (alloc.first >= 32) break; + } else if (use & 2) { + if (alloc.first < 32) continue; + if (alloc.first >= 96) break; + } + if (alloc.second.is_table_output()) continue; // can't merge table output with immediate + int inbyte = alloc.second.lo(tbl) / 8U; + int align = 4; + if (is_action_data) + align = action_hv_slice_group_align.at(alloc.first / 16U).at(inbyte % 16U); + int outbyte = alloc.first & ~(align - 1); + inbyte &= ~(align - 1); + if (offset >= inbyte * 8 && offset + bytes * 8 <= (inbyte + align) * 8) + return outbyte + offset / 8 - inbyte; + } + return -1; +} + +void ActionBus::do_alloc(Table *tbl, ActionBusSource src, unsigned use, int lobyte, int bytes, + unsigned offset) { + LOG2("putting " << src << '(' << offset << ".." << (offset + bytes * 8 - 1) << ")[" + << (lobyte * 8) << ".." << ((lobyte + bytes) * 8 - 1) << "] at action_bus " + << use); + unsigned hv_slice = use / ACTION_HV_XBAR_SLICE_SIZE; + auto &hv_groups = action_hv_slice_byte_groups.at(hv_slice); + for (unsigned byte = lobyte; byte < unsigned(lobyte + bytes); ++byte) { + if (action_hv_slice_use.size() <= byte / 16) action_hv_slice_use.resize(byte / 16 + 1); + action_hv_slice_use.at(byte / 16).at(hv_slice) |= hv_groups.at(byte % 16); + } + while (bytes > 0) { + int slot = Stage::action_bus_slot_map[use]; + int slotsize = Stage::action_bus_slot_size[slot]; + auto slot_tbl = tbl->stage->action_bus_use[slot]; + // Atcam tables are mutually exclusive and should be allowed to share + // bytes on action bus + if (slot_tbl && !Table::allow_bus_sharing(tbl, slot_tbl)) + BUG_CHECK(slot_tbl == tbl || slot_tbl->action_bus->by_byte.at(use).data.count(src)); + tbl->stage->action_bus_use[slot] = tbl; + Slot &sl = by_byte.emplace(use, Slot(src.name(tbl), use, bytes * 8U)).first->second; + if (sl.size < bytes * 8U) sl.size = bytes * 8U; + sl.data.emplace(src, offset); + LOG4(" slot " << sl.byte << "(" << sl.name << ") data += " << src.toString(tbl) + << " off=" << offset); + offset += slotsize; + bytes -= slotsize / 8U; + use += slotsize / 8U; + } +} + +const unsigned ActionBus::size_masks[8] = {7, 7, 15, 15, 31, 31, 31, 31}; + +void ActionBus::alloc_field(Table *tbl, ActionBusSource src, unsigned offset, + unsigned sizes_needed) { + LOG4("alloc_field(" << src << ", " << offset << ", " << sizes_needed << ")"); + int lineno = this->lineno; + bool is_action_data = dynamic_cast(tbl) != nullptr; + int lo, hi, use; + bool can_merge = true; + if (src.type == ActionBusSource::Field) { + lo = src.field->immed_bit(offset); + hi = src.field->immed_bit(src.field->size) - 1; + lineno = tbl->find_field_lineno(src.field); + } else { + lo = offset; + if (src.type == ActionBusSource::TableOutput || src.type == ActionBusSource::TableColor || + src.type == ActionBusSource::TableAddress || src.type == ActionBusSource::RandomGen) + can_merge = false; + if (src.type == ActionBusSource::HashDist && + !(src.hd->xbar_use & HashDistribution::IMMEDIATE_LOW)) + lo += 16; + hi = lo | size_masks[sizes_needed]; + } + if (lo / 32U != hi / 32U) { + /* Can't go across 32-bit boundary so chop it down as needed */ + hi = lo | 31U; + } + int bytes = hi / 8U - lo / 8U + 1; + int step = 4; + if (is_action_data) step = (lo % 128U) < 32 ? 2 : (lo % 128U) < 64 ? 4 : 8; + if (sizes_needed & 1) { + /* need 8-bit */ + if ((lo % 8U) && (lo / 8U != hi / 8U)) { + error(lineno, + "%s not correctly aligned for 8-bit use on " + "action bus", + src.toString(tbl).c_str()); + return; + } + unsigned start = (lo / 8U) % step; + int bytes_needed = (sizes_needed & 4) ? bytes : 1; + if ((use = find(tbl->stage, src, lo, hi, 1)) >= 0 || + (can_merge && (use = find_merge(tbl, lo, bytes_needed, 1)) >= 0) || + (use = find_free(tbl, start, 31, step, lo / 8U, bytes_needed)) >= 0) + do_alloc(tbl, src, use, lo / 8U, bytes_needed, offset); + else + error(lineno, "Can't allocate space on 8-bit part of action bus for %s", + src.toString(tbl).c_str()); + } + step = (lo % 128U) < 64 ? 4 : 8; + if (sizes_needed & 2) { + /* need 16-bit */ + if (lo % 16U) { + if (lo / 16U != hi / 16U) { + error(lineno, + "%s not correctly aligned for 16-bit use " + "on action bus", + src.toString(tbl).c_str()); + return; + } + if (can_merge && (use = find_merge(tbl, lo, bytes, 2)) >= 0) { + do_alloc(tbl, src, use, lo / 8U, bytes, offset); + return; + } + } + if (!(sizes_needed & 4) && bytes > 2) bytes = 2; + unsigned start = 32 + (lo / 8U) % step; + if ((use = find(tbl->stage, src, lo, hi, 2)) >= 0 || + (can_merge && (use = find_merge(tbl, lo, bytes, 2)) >= 0) || + (use = find_free(tbl, start, 63, step, lo / 8U, bytes)) >= 0 || + (use = find_free(tbl, start + 32, 95, 8, lo / 8U, bytes)) >= 0) + do_alloc(tbl, src, use, lo / 8U, bytes, offset); + else + error(lineno, "Can't allocate space on 16-bit part of action bus for %s", + src.toString(tbl).c_str()); + } + if (sizes_needed == 4) { + /* need only 32-bit */ + unsigned odd = (lo / 8U) & (4 & step); + unsigned start = (lo / 8U) % step; + if (lo % 32U) { + if (can_merge && (use = find_merge(tbl, lo, bytes, 4)) >= 0) { + do_alloc(tbl, src, use, lo / 8U, bytes, offset); + return; + } + } + if ((use = find(tbl->stage, src, lo, hi, 4)) >= 0 || + (can_merge && (use = find_merge(tbl, lo, bytes, 4)) >= 0) || + (use = find_free(tbl, 96 + start + odd, 127, 8, lo / 8U, bytes)) >= 0 || + (use = find_free(tbl, 64 + start + odd, 95, 8, lo / 8U, bytes)) >= 0 || + (use = find_free(tbl, 32 + start, 63, step, lo / 8U, bytes)) >= 0 || + (use = find_free(tbl, 0 + start, 31, step, lo / 8U, bytes)) >= 0) + do_alloc(tbl, src, use, lo / 8U, bytes, offset); + else + error(lineno, "Can't allocate space on action bus for %s", src.toString(tbl).c_str()); + } +} + +void ActionBus::pass3(Table *tbl) { + bool is_action_data = dynamic_cast(tbl) != nullptr; + LOG1("ActionBus::pass3(" << tbl->name() << ") " << (is_action_data ? "[action]" : "[immed]")); + for (auto &d : need_place) + for (auto &bits : d.second) alloc_field(tbl, d.first, bits.first, bits.second); + int rnguse = -1; + for (auto &slot : by_byte) { + for (auto &d : slot.second.data) { + if (d.first.type == ActionBusSource::RandomGen) { + if (rnguse >= 0 && rnguse != d.first.rng.unit) + error(lineno, "Can't use both rng units in a single table"); + rnguse = d.first.rng.unit; + } + } + } +} + +static int slot_sizes[] = { + 5, /* 8-bit or 32-bit */ + 6, /* 16-bit or 32-bit */ + 6, /* 16-bit or 32-bit */ + 4 /* 32-bit only */ +}; + +/** + * ActionBus::find + * @brief find an action bus slot that contains the requested thing. + * + * Overloads allow looking for different kinds of things -- a Format::Field, + * a HashDistribution, a RandomNumberGen, or something by name (generally a table output). + * @param f a Format::Field to look for + * @param name named slot to look for -- generally a table output, but may be a field + * @param hd a HashDistribution to look for + * @param rng a RandomNumberGen to look for + * @param lo, hi range of bits in the thing specified by the first arg + * @param size bitmask of needed size classes -- 3 bits that denote need for a 8/16/32 bit + * actionbus slot. Generally will only have 1 bit set, but might be 0. + */ +int ActionBus::find(const char *name, TableOutputModifier mod, int lo, int hi, int size, int *len) { + if (auto *tbl = ::get(Table::all, name)) + return find(ActionBusSource(tbl, mod), lo, hi, size, -1, len); + if (mod != TableOutputModifier::NONE) return -1; + for (auto &slot : by_byte) { + int offset = lo; + if (slot.second.name != name) continue; + if (size && !(size & static_cast(slot_sizes[slot.first / 32U]))) continue; + if (offset >= static_cast(slot.second.size)) continue; + if (len) *len = slot.second.size; + return slot.first + offset / 8; + } + return -1; +} + +int ActionBus::find(const ActionBusSource &src, int lo, int hi, int size, int pos, int *len) { + bool hd1Found = true; + int hd1Pos = -1; + for (auto &slot : by_byte) { + if (!slot.second.data.count(src)) continue; + int offset = slot.second.data[src]; + // FIXME -- HashDist is 16 bits in either half of the 32-bit immediate path; we call + // the high half (16..31), but we address it directly (as if it was 16 bits) for + // non-32 bit accesses. So we ignore the top bit of the offset bit index when + // accessing it for 8- or 16- bit slots. + // There should be a better way of doing this. + if ((src.type == ActionBusSource::HashDist || src.type == ActionBusSource::HashDistPair) && + size < 4) + offset &= 15; + // Table Color is 8 bits which is ORed into the top of the immediate; The offset is + // thus >= 24, but we want to ignore that here and just use the offset within the byte + if (src.type == ActionBusSource::TableColor) offset &= 7; + if (offset > lo) continue; + if (offset + static_cast(slot.second.size) <= hi) continue; + if (size && !(size & slot_sizes[slot.first / 32U])) continue; + if (len) *len = slot.second.size; + auto bus_pos = slot.first + (lo - offset) / 8; + if (pos >= 0 && bus_pos != pos) continue; + return bus_pos; + } + return -1; +} + +int ActionBus::find(Stage *stage, ActionBusSource src, int lo, int hi, int size, int *len) { + int rv = -1; + for (auto tbl : stage->tables) + if (tbl->action_bus && (rv = tbl->action_bus->find(src, lo, hi, size, -1, len)) >= 0) + return rv; + return rv; +} + +template +void ActionBus::write_action_regs(REGS ®s, Table *tbl, int home_row, unsigned action_slice) { + LOG2("--- ActionBus write_action_regs(" << tbl->name() << ", " << home_row << ", " + << action_slice << ")"); + bool is_action_data = dynamic_cast(tbl) != nullptr; + auto &action_hv_xbar = regs.rams.array.row[home_row / 2].action_hv_xbar; + unsigned side = home_row % 2; /* 0 == left, 1 == right */ + for (auto &el : by_byte) { + if (!is_action_data && !el.second.is_table_output()) { + // Nasty hack -- meter/stateful output uses the action bus on the meter row, + // so we need this routine to set it up, but we only want to do it for the + // meter bus output; the rest of this ActionBus is for immediate data (set + // up by write_immed_regs below) + continue; + } + LOG5(" " << el.first << ": " << el.second); + unsigned byte = el.first; + BUG_CHECK(byte == el.second.byte); + unsigned slot = Stage::action_bus_slot_map[byte]; + unsigned bit = 0, size = 0; + std::string srcname; + for (auto &data : el.second.data) { + // FIXME -- this loop feels like a hack -- the size SHOULD already be set in + // el.second.size (the max of the sizes of everything in the data we're looping + // over), so should not need recomputing. We do need to figure out the source + // bit location, and ignore things in other wide words, but that should be stored + // in the Slot object? What about wired-ors, writing two inputs to the same + // slot -- it is possible but is it useful? + unsigned data_bit = 0, data_size = 0; + if (data.first.type == ActionBusSource::Field) { + auto f = data.first.field; + if ((f->bit(data.second) >> 7) != action_slice) continue; + data_bit = f->bit(data.second) & 0x7f; + data_size = std::min(el.second.size, f->size - data.second); + srcname = "field " + tbl->find_field(f); + } else if (data.first.type == ActionBusSource::TableOutput) { + if (data.first.table->home_row() != home_row) { + // skip tables not on this home row + continue; + } + data_bit = data.second; + data_size = el.second.size; + srcname = "table " + data.first.table->name_; + } else { + // HashDist and RandomGen only work in write_immed_regs + BUG(); + } + LOG3(" byte " << byte << " (slot " << slot << "): " << srcname << " (" << data.second + << ".." << (data.second + data_size - 1) << ")" << " [" << data_bit + << ".." << (data_bit + data_size - 1) << "]"); + if (size) { + BUG_CHECK(bit == data_bit); // checked in pass1; maintained by pass3 + size = std::max(size, data_size); + } else { + bit = data_bit; + size = data_size; + } + } + if (size == 0) continue; + if (bit + size > 128) { + error(lineno, + "Action bus setup can't deal with field %s split across " + "SRAM rows", + el.second.name.c_str()); + continue; + } + unsigned bytemask = (1U << ((size + 7) / 8U)) - 1; + switch (Stage::action_bus_slot_size[slot]) { + case 8: + for (unsigned sbyte = bit / 8; sbyte <= (bit + size - 1) / 8; + sbyte++, byte++, slot++) { + unsigned code = 0, mask = 0; + switch (sbyte >> 2) { + case 0: + code = sbyte >> 1; + mask = 1; + break; + case 1: + code = 2; + mask = 3; + break; + case 2: + case 3: + code = 3; + mask = 7; + break; + default: + BUG(); + } + if ((sbyte ^ byte) & mask) { + error(lineno, "Can't put field %s into byte %d on action xbar", + el.second.name.c_str(), byte); + break; + } + auto &ctl = action_hv_xbar.action_hv_ixbar_ctl_byte[side]; + switch (code) { + case 0: + ctl.action_hv_ixbar_ctl_byte_1to0_ctl = slot / 2; + ctl.action_hv_ixbar_ctl_byte_1to0_enable = 1; + break; + case 1: + ctl.action_hv_ixbar_ctl_byte_3to2_ctl = slot / 2; + ctl.action_hv_ixbar_ctl_byte_3to2_enable = 1; + break; + case 2: + ctl.action_hv_ixbar_ctl_byte_7to4_ctl = slot / 4; + ctl.action_hv_ixbar_ctl_byte_7to4_enable = 1; + break; + case 3: + ctl.action_hv_ixbar_ctl_byte_15to8_ctl = slot / 8; + ctl.action_hv_ixbar_ctl_byte_15to8_enable = 1; + break; + } + if (!(bytemask & 1)) + LOG1("WARNING: " << SrcInfo(lineno) << ": putting " << el.second.name + << " on action bus byte " << byte + << " even though bit in bytemask is " + "not set"); + action_hv_xbar.action_hv_ixbar_input_bytemask[side] |= 1 << sbyte; + bytemask >>= 1; + } + break; + case 16: + byte &= ~1; + slot -= ACTION_DATA_8B_SLOTS; + bytemask <<= ((bit / 8) & 1); + for (unsigned word = bit / 16; word <= (bit + size - 1) / 16; + word++, byte += 2, slot++) { + unsigned code = 0, mask = 0; + switch (word >> 1) { + case 0: + code = 1; + mask = 3; + break; + case 1: + code = 2; + mask = 3; + break; + case 2: + case 3: + code = 3; + mask = 7; + break; + default: + BUG(); + } + if (((word << 1) ^ byte) & mask) { + error(lineno, "Can't put field %s into byte %d on action xbar", + el.second.name.c_str(), byte); + break; + } + auto &ctl = action_hv_xbar.action_hv_ixbar_ctl_halfword[slot / 8][side]; + unsigned subslot = slot % 8U; + switch (code) { + case 1: + ctl.action_hv_ixbar_ctl_halfword_3to0_ctl = subslot / 2; + ctl.action_hv_ixbar_ctl_halfword_3to0_enable = 1; + break; + case 2: + ctl.action_hv_ixbar_ctl_halfword_7to4_ctl = subslot / 2; + ctl.action_hv_ixbar_ctl_halfword_7to4_enable = 1; + break; + case 3: + ctl.action_hv_ixbar_ctl_halfword_15to8_ctl = subslot / 4; + ctl.action_hv_ixbar_ctl_halfword_15to8_enable = 1; + break; + } + action_hv_xbar.action_hv_ixbar_input_bytemask[side] |= (bytemask & 3) + << (word * 2); + bytemask >>= 2; + } + break; + case 32: { + byte &= ~3; + slot -= ACTION_DATA_8B_SLOTS + ACTION_DATA_16B_SLOTS; + unsigned word = bit / 32; + unsigned code = 1 + word / 2; + bit %= 32; + bytemask <<= bit / 8; + if (((word << 2) ^ byte) & 7) { + error(lineno, "Can't put field %s into byte %d on action xbar", + el.second.name.c_str(), byte); + break; + } + auto &ctl = action_hv_xbar.action_hv_ixbar_ctl_word[slot / 4][side]; + slot %= 4U; + switch (code) { + case 1: + ctl.action_hv_ixbar_ctl_word_7to0_ctl = slot / 2; + ctl.action_hv_ixbar_ctl_word_7to0_enable = 1; + break; + case 2: + ctl.action_hv_ixbar_ctl_word_15to8_ctl = slot / 2; + ctl.action_hv_ixbar_ctl_word_15to8_enable = 1; + break; + } + action_hv_xbar.action_hv_ixbar_input_bytemask[side] |= (bytemask & 15) + << (word * 4); + bytemask >>= 4; + break; + } + default: + BUG(); + } + if (bytemask) + LOG1("WARNING: " << SrcInfo(lineno) << ": excess bits " << hex(bytemask) + << " set in bytemask for " << el.second.name); + } +} +FOR_ALL_REGISTER_SETS(INSTANTIATE_TARGET_TEMPLATE, void ActionBus::write_action_regs, mau_regs &, + Table *, int, unsigned) + +template +void ActionBus::write_immed_regs(REGS ®s, Table *tbl) { + LOG2("--- ActionBus write_immed_regs(" << tbl->name() << ")"); + auto &adrdist = regs.rams.match.adrdist; + int tid = tbl->logical_id; + unsigned rngmask = 0; + for (auto &f : by_byte) { + if (f.second.is_table_output()) continue; + LOG5(" " << f.first << ": " << f.second); + int slot = Stage::action_bus_slot_map[f.first]; + unsigned off = 0; + unsigned size = f.second.size; + if (!f.second.data.empty()) { + off = f.second.data.begin()->second; + if (f.second.data.begin()->first.type == ActionBusSource::Field) + off -= f.second.data.begin()->first.field->immed_bit(0); + for (auto &d : f.second.data) { + if (d.first.type == ActionBusSource::RandomGen) { + rngmask |= d.first.rng.unit << 4; + rngmask |= ((1 << (size / 8)) - 1) << d.second / 8; + } + } + } + switch (Stage::action_bus_slot_size[slot]) { + case 8: + for (unsigned b = off / 8; b <= (off + size - 1) / 8; b++) { + BUG_CHECK((b & 3) == (slot & 3)); + adrdist.immediate_data_8b_enable[tid / 8] |= 1U << ((tid & 7) * 4 + b); + // we write these ctl regs twice if we use both bytes in a pair. That will + // cause a WARNING in the log file if both uses are the same -- it should be + // impossible to get an ERROR for conflicting uses, as that should have caused + // an error in pass1 above, and never made it to this point. + setup_muxctl(adrdist.immediate_data_8b_ixbar_ctl[tid * 2 + b / 2], slot++ / 4); + } + break; + case 16: + slot -= ACTION_DATA_8B_SLOTS; + for (unsigned w = off / 16; w <= (off + size - 1) / 16; w++) { + BUG_CHECK((w & 1) == (slot & 1)); + setup_muxctl(adrdist.immediate_data_16b_ixbar_ctl[tid * 2 + w], slot++ / 2); + } + break; + case 32: + slot -= ACTION_DATA_8B_SLOTS + ACTION_DATA_16B_SLOTS; + setup_muxctl(adrdist.immediate_data_32b_ixbar_ctl[tid], slot); + break; + default: + BUG(); + } + } + if (rngmask) { + regs.rams.match.adrdist.immediate_data_rng_enable = 1; + regs.rams.match.adrdist.immediate_data_rng_logical_map_ctl[tbl->logical_id / 4] + .set_subfield(rngmask, 5 * (tbl->logical_id % 4U), 5); + } +} +FOR_ALL_REGISTER_SETS(INSTANTIATE_TARGET_TEMPLATE, void ActionBus::write_immed_regs, mau_regs &, + Table *) + +std::string ActionBusSource::name(Table *tbl) const { + switch (type) { + case Field: + return tbl->find_field(field); + case TableOutput: + case TableColor: + case TableAddress: + return table->name(); + case NameRef: + case ColorRef: + case AddressRef: + return name_ref->name; + default: + return ""; + } +} + +std::string ActionBusSource::toString(Table *tbl) const { + std::stringstream tmp; + switch (type) { + case None: + return ""; + case Field: + return tbl->find_field(field); + case HashDist: + tmp << "hash_dist " << hd->id; + return tmp.str(); + case RandomGen: + tmp << "rng " << rng.unit; + return tmp.str(); + case TableOutput: + return table->name(); + case TableColor: + return table->name_ + " color"; + case TableAddress: + return table->name_ + " address"; + case Ealu: + return "ealu"; + case XcmpData: + tmp << "xcmp(" << xcmp_group << ":" << xcmp_byte << ")"; + return tmp.str(); + case NameRef: + case ColorRef: + case AddressRef: + tmp << "name "; + if (name_ref) + tmp << name_ref->name; + else + tmp << "(meter)"; + if (type == ColorRef) tmp << " color"; + if (type == AddressRef) tmp << " address"; + return tmp.str(); + default: + tmp << ""; + return tmp.str(); + } +} + +std::ostream &operator<<(std::ostream &out, TableOutputModifier mod) { + switch (mod) { + case TableOutputModifier::Color: + out << " color"; + break; + case TableOutputModifier::Address: + out << " address"; + break; + default: + break; + } + return out; +} + +std::ostream &operator<<(std::ostream &out, const ActionBus::Slot &sl) { + out << sl.name << " byte=" << sl.byte << " size=" << sl.size; + for (auto &d : sl.data) out << "\n\t" << d.first << ": " << d.second; + return out; +} + +std::ostream &operator<<(std::ostream &out, const ActionBus &a) { + for (auto &slot : a.by_byte) out << slot.first << ": " << slot.second << std::endl; + for (auto &np : a.need_place) { + out << np.first << " {"; + const char *sep = " "; + for (auto &el : np.second) { + out << sep << el.first << ":" << el.second; + sep = ", "; + } + out << (sep + 1) << "}" << std::endl; + } + out << "byte_use: " << a.byte_use << std::endl; + for (auto &hvslice : a.action_hv_slice_use) { + for (auto v : hvslice) out << " " << hex(v, 4, '0'); + out << std::endl; + } + return out; +} + +void dump(const ActionBus *a) { std::cout << *a; } diff --git a/backends/tofino/bf-asm/action_bus.h b/backends/tofino/bf-asm/action_bus.h new file mode 100644 index 00000000000..ea798429b7f --- /dev/null +++ b/backends/tofino/bf-asm/action_bus.h @@ -0,0 +1,244 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_ACTION_BUS_H_ +#define BF_ASM_ACTION_BUS_H_ + +#include + +#include "tables.h" + +// static struct MeterBus_t {} MeterBus; +struct MeterBus_t {}; + +struct ActionBusSource { + enum { + None, + Field, + HashDist, + HashDistPair, + RandomGen, + TableOutput, + TableColor, + TableAddress, + Ealu, + XcmpData, + NameRef, + ColorRef, + AddressRef + } type; + union { + Table::Format::Field *field; + HashDistribution *hd; + struct { + HashDistribution *hd1, *hd2; + }; + Table *table; + Table::Ref *name_ref; + RandomNumberGen rng; + struct { + short xcmp_group, xcmp_byte; + }; + }; + ActionBusSource() : type(None) { field = nullptr; } + ActionBusSource(Table::Format::Field *f) : type(Field) { // NOLINT(runtime/explicit) + field = f; + } + ActionBusSource(HashDistribution *h) : type(HashDist) { hd = h; } // NOLINT(runtime/explicit) + ActionBusSource(HashDistribution *h1, HashDistribution *h2) : type(HashDistPair) { + hd1 = h1; + hd2 = h2; + } + ActionBusSource(Table *t, + TableOutputModifier m = TableOutputModifier::NONE) // NOLINT(runtime/explicit) + : type(TableOutput) { + switch (m) { + case TableOutputModifier::Color: + type = TableColor; + break; + case TableOutputModifier::Address: + type = TableAddress; + break; + default: + break; + } + table = t; + } + ActionBusSource(Table::Ref *t, + TableOutputModifier m = TableOutputModifier::NONE) // NOLINT(runtime/explicit) + : type(NameRef) { + switch (m) { + case TableOutputModifier::Color: + type = ColorRef; + break; + case TableOutputModifier::Address: + type = AddressRef; + break; + default: + break; + } + name_ref = t; + } + ActionBusSource(MeterBus_t, + TableOutputModifier m = TableOutputModifier::NONE) // NOLINT(runtime/explicit) + : type(NameRef) { + switch (m) { + case TableOutputModifier::Color: + type = ColorRef; + break; + case TableOutputModifier::Address: + type = AddressRef; + break; + default: + break; + } + name_ref = nullptr; + } + ActionBusSource(RandomNumberGen r) : type(RandomGen) { // NOLINT(runtime/explicit) + field = nullptr; + rng = r; + } + ActionBusSource(InputXbar::Group grp, int byte) : type(XcmpData) { + BUG_CHECK(grp.type == InputXbar::Group::XCMP, "Not xcmp ixbar"); + field = nullptr; + xcmp_group = grp.index; + xcmp_byte = byte; + } + bool operator==(const ActionBusSource &a) const { + if (type == XcmpData) + return a.type == XcmpData && xcmp_group == a.xcmp_group && xcmp_byte == a.xcmp_byte; + if (type == HashDistPair && hd2 != a.hd2) return false; + return type == a.type && field == a.field; + } + bool operator<(const ActionBusSource &a) const { + if (type != a.type) return type < a.type; + switch (type) { + case HashDistPair: + return hd1 == a.hd1 ? hd2 < a.hd2 : hd1 < a.hd1; + case XcmpData: + return xcmp_group == a.xcmp_group ? xcmp_byte < a.xcmp_byte + : xcmp_group < a.xcmp_group; + default: + return field < a.field; + } + } + std::string name(Table *tbl) const; + std::string toString(Table *tbl) const; + friend std::ostream &operator<<(std::ostream &, const ActionBusSource &); +}; + +class ActionBus { + protected: + // Check two ActionBusSource refs to ensure that they are compatible (can be at the same + // location on the aciton bus -- basically the same data) + static bool compatible(const ActionBusSource &a, unsigned a_off, const ActionBusSource &b, + unsigned b_off); + struct Slot { + std::string name; + unsigned byte, size; // size in bits + ordered_map data; + // offset in the specified source is in this slot -- corresponding bytes for different + // action data formats will go into the same slot. + Slot(std::string n, unsigned b, unsigned s) : name(n), byte(b), size(s) {} + Slot(std::string n, unsigned b, unsigned s, ActionBusSource src, unsigned off) + : name(n), byte(b), size(s) { + data.emplace(src, off); + } + unsigned lo(Table *tbl) const; // low bit on the action data bus + bool is_table_output() const { + for (auto &d : data) { + BUG_CHECK(d.first.type != ActionBusSource::NameRef); + if (d.first.type == ActionBusSource::TableOutput) return true; + } + return false; + } + }; + friend std::ostream &operator<<(std::ostream &, const Slot &); + friend std::ostream &operator<<(std::ostream &, const ActionBus &); + ordered_map by_byte; + ordered_map> need_place; + // bytes from the given sources are needed on the action bus -- the pairs in the map + // are (offset,use) where offset is offset in bits, and use is a bitset of the needed + // uses (bit index == log2 of the access size in bytes) + + std::vector> action_hv_slice_use; + // which bytes of input to the ixbar are used in each action_hv_xbar slice, for each + // 128-bit slice of the action bus. + bitvec byte_use; // bytes on the action data (input) bus or immediate bus in use + // for wide action tables, this may be >16 bytes... + + void setup_slot(int lineno, Table *tbl, const char *name, unsigned idx, ActionBusSource src, + unsigned sz, unsigned off); + + int find_free(Table *tbl, unsigned min, unsigned max, unsigned step, unsigned lobyte, + unsigned bytes); + int find_merge(Table *tbl, int offset, int bytes, int use); + bool check_atcam_sharing(Table *tbl1, Table *tbl2); + bool check_slot_sharing(ActionBus::Slot &slot, bitvec &action_bus); + + ActionBus() : lineno(-1) {} + ActionBus(Table *, VECTOR(pair_t) &); + + public: + int lineno; + static std::unique_ptr create(); + static std::unique_ptr create(Table *, VECTOR(pair_t) &); + + void pass1(Table *tbl); + void pass2(Table *tbl) {} + void pass3(Table *tbl); + template + void write_immed_regs(REGS ®s, Table *tbl); + template + void write_action_regs(REGS ®s, Table *tbl, int homerow, unsigned action_slice); + + void do_alloc(Table *tbl, ActionBusSource src, unsigned use, int lobyte, int bytes, + unsigned offset); + static const unsigned size_masks[8]; + virtual void alloc_field(Table *, ActionBusSource src, unsigned offset, unsigned sizes_needed); + void need_alloc(Table *tbl, const ActionBusSource &src, unsigned lo, unsigned hi, + unsigned size); + void need_alloc(Table *tbl, Table *attached, TableOutputModifier mod, unsigned lo, unsigned hi, + unsigned size) { + need_alloc(tbl, ActionBusSource(attached, mod), lo, hi, size); + } + + int find(const char *name, TableOutputModifier mod, int lo, int hi, int size, int *len = 0); + int find(const char *name, int lo, int hi, int size, int *len = 0) { + return find(name, TableOutputModifier::NONE, lo, hi, size, len); + } + int find(const std::string &name, TableOutputModifier mod, int lo, int hi, int size, + int *len = 0) { + return find(name.c_str(), mod, lo, hi, size, len); + } + int find(const std::string &name, int lo, int hi, int size, int *len = 0) { + return find(name.c_str(), lo, hi, size, len); + } + int find(const ActionBusSource &src, int lo, int hi, int size, int pos = -1, int *len = 0); + int find(Table *attached, TableOutputModifier mod, int lo, int hi, int size, int *len = 0) { + return find(ActionBusSource(attached, mod), lo, hi, size, -1, len); + } + static int find(Stage *stage, ActionBusSource src, int lo, int hi, int size, int *len = 0); + unsigned size() { + unsigned rv = 0; + for (auto &slot : by_byte) rv += slot.second.size; + return rv; + } + auto slots() const { return Values(by_byte); } +}; + +#endif /* BF_ASM_ACTION_BUS_H_ */ diff --git a/backends/tofino/bf-asm/action_table.cpp b/backends/tofino/bf-asm/action_table.cpp new file mode 100644 index 00000000000..24e532528cd --- /dev/null +++ b/backends/tofino/bf-asm/action_table.cpp @@ -0,0 +1,794 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "action_bus.h" +#include "algorithm.h" +#include "input_xbar.h" +#include "instruction.h" +#include "stage.h" +#include "tables.h" + +// template specialization declarations +#include "tofino/action_table.h" + +/// See 6.2.8.4.3 of the MAU Micro-Architecture document. +const unsigned MAX_AD_SHIFT = 5U; + +std::string ActionTable::find_field(Table::Format::Field *field) { + for (auto &af : action_formats) { + auto name = af.second->find_field(field); + if (!name.empty() && name[0] != '<') return af.first + ":" + name; + } + return Table::find_field(field); +} + +int ActionTable::find_field_lineno(Table::Format::Field *field) { + int rv = -1; + for (auto &af : action_formats) + if ((rv = af.second->find_field_lineno(field)) >= 0) return rv; + return Table::find_field_lineno(field); +} + +Table::Format::Field *ActionTable::lookup_field(const std::string &name, + const std::string &action) const { + if (action == "*" || action == "") { + if (auto *rv = format ? format->field(name) : 0) return rv; + if (action == "*") + for (auto &fmt : action_formats) + if (auto *rv = fmt.second->field(name)) return rv; + } else { + if (action_formats.count(action)) { + if (auto *rv = action_formats.at(action)->field(name)) return rv; + } else if (auto *rv = format ? format->field(name) : 0) { + return rv; + } + } + for (auto *match_table : match_tables) { + BUG_CHECK((Table *)match_table != (Table *)this); + if (auto *rv = match_table->lookup_field(name)) return rv; + } + return 0; +} +void ActionTable::pad_format_fields() { + format->size = get_size(); + format->log2size = get_log2size(); + for (auto &fmt : action_formats) { + if (fmt.second->size < format->size) { + fmt.second->size = format->size; + fmt.second->log2size = format->log2size; + } + } +} + +void ActionTable::apply_to_field(const std::string &n, std::function fn) { + for (auto &fmt : action_formats) fmt.second->apply_to_field(n, fn); + if (format) format->apply_to_field(n, fn); +} +int ActionTable::find_on_actionbus(const ActionBusSource &src, int lo, int hi, int size, int pos) { + int rv; + if (action_bus && (rv = action_bus->find(src, lo, hi, size, pos)) >= 0) return rv; + for (auto *match_table : match_tables) { + BUG_CHECK((Table *)match_table != (Table *)this); + if ((rv = match_table->find_on_actionbus(src, lo, hi, size, pos)) >= 0) return rv; + } + return -1; +} + +int ActionTable::find_on_actionbus(const char *name, TableOutputModifier mod, int lo, int hi, + int size, int *len) { + int rv; + if (action_bus && (rv = action_bus->find(name, mod, lo, hi, size, len)) >= 0) return rv; + for (auto *match_table : match_tables) { + BUG_CHECK((Table *)match_table != (Table *)this); + if ((rv = match_table->find_on_actionbus(name, mod, lo, hi, size, len)) >= 0) return rv; + } + return -1; +} + +void ActionTable::need_on_actionbus(const ActionBusSource &src, int lo, int hi, int size) { + if (src.type == ActionBusSource::Field) { + auto f = src.field; + if (f->fmt == format.get()) { + Table::need_on_actionbus(src, lo, hi, size); + return; + } + for (auto &af : Values(action_formats)) { + if (f->fmt == af.get()) { + Table::need_on_actionbus(f, lo, hi, size); + return; + } + } + for (auto *match_table : match_tables) { + BUG_CHECK((Table *)match_table != (Table *)this); + if (f->fmt == match_table->get_format()) { + match_table->need_on_actionbus(f, lo, hi, size); + return; + } + } + BUG_CHECK(!"Can't find table associated with field"); + // TBD - Add allocation for ActionBusSource::HashDistPair. Compiler does + // action bus allocation so this path is never used. + } else if (src.type == ActionBusSource::HashDist) { + auto hd = src.hd; + for (auto &hash_dist : this->hash_dist) { + if (&hash_dist == hd) { + Table::need_on_actionbus(hd, lo, hi, size); + return; + } + } + for (auto *match_table : match_tables) { + if (match_table->find_hash_dist(hd->id) == hd) { + match_table->need_on_actionbus(hd, lo, hi, size); + return; + } + } + BUG_CHECK(!"Can't find table associated with hash_dist"); + } else if (src.type == ActionBusSource::RandomGen) { + auto rng = src.rng; + int attached_count = 0; + for (auto *match_table : match_tables) { + match_table->need_on_actionbus(rng, lo, hi, size); + ++attached_count; + } + if (attached_count > 1) { + error(-1, + "Assembler cannot allocate action bus space for rng %d as it " + "used by mulitple tables", + rng.unit); + } + } else { + error(-1, "Assembler cannot allocate action bus space for %s", src.toString(this).c_str()); + } +} + +void ActionTable::need_on_actionbus(Table *att, TableOutputModifier mod, int lo, int hi, int size) { + int attached_count = 0; + for (auto *match_table : match_tables) { + if (match_table->is_attached(att)) { + match_table->need_on_actionbus(att, mod, lo, hi, size); + ++attached_count; + } + } + if (attached_count > 1) { + error(att->lineno, + "Assembler cannot allocate action bus space for table %s as it " + "used by mulitple tables", + att->name()); + } +} + +/** + * Necessary for determining the actiondata_adr_exact/tcam_shiftcount register value. + */ +unsigned ActionTable::determine_shiftcount(Table::Call &call, int group, unsigned word, + int tcam_shift) const { + int lo_huffman_bits = + std::min(get_log2size() - 2, static_cast(ACTION_ADDRESS_ZERO_PAD)); + int extra_shift = ACTION_ADDRESS_ZERO_PAD - lo_huffman_bits; + if (call.args[0] == "$DIRECT") { + return 64 + extra_shift + tcam_shift; + } else if (call.args[0].field()) { + BUG_CHECK(call.args[0].field()->by_group[group]->bit(0) / 128U == word); + return call.args[0].field()->by_group[group]->bit(0) % 128U + extra_shift; + } else if (call.args[1].field()) { + return call.args[1].field()->bit(0) + ACTION_ADDRESS_ZERO_PAD; + } + return 0; +} + +/** + * Calculates the actiondata_adr_default value. Will default in the required huffman bits + * described in section 6.2.8.4.3 Action RAM Addressing of the uArch, as well as the + * per flow enable bit if indicated + */ +unsigned ActionTable::determine_default(Table::Call &call) const { + int huffman_ones = std::max(static_cast(get_log2size()) - 3, 0); + BUG_CHECK(huffman_ones <= ACTION_DATA_HUFFMAN_BITS); + unsigned huffman_mask = (1 << huffman_ones) - 1; + // lower_huffman_mask == 0x1f, upper_huffman_mask = 0x60 + unsigned lower_huffman_mask = (1U << ACTION_DATA_LOWER_HUFFMAN_BITS) - 1; + unsigned upper_huffman_mask = ((1U << ACTION_DATA_HUFFMAN_BITS) - 1) & ~lower_huffman_mask; + unsigned rv = (huffman_mask & upper_huffman_mask) << ACTION_DATA_HUFFMAN_DIFFERENCE; + rv |= huffman_mask & lower_huffman_mask; + if (call.args[1].name() && call.args[1] == "$DEFAULT") { + rv |= 1 << ACTION_DATA_PER_FLOW_ENABLE_START_BIT; + } + return rv; +} + +/** + * Calculates the actiondata_adr_mask value for a given table. + */ +unsigned ActionTable::determine_mask(Table::Call &call) const { + int lo_huffman_bits = + std::min(get_log2size() - 2, static_cast(ACTION_DATA_LOWER_HUFFMAN_BITS)); + unsigned rv = 0; + if (call.args[0] == "$DIRECT") { + rv |= ((1U << ACTION_ADDRESS_BITS) - 1) & (~0U << lo_huffman_bits); + } else if (call.args[0].field()) { + rv = ((1U << call.args[0].size()) - 1) << lo_huffman_bits; + } + return rv; +} + +/** + * Calculates the actiondata_adr_vpn_shiftcount register. As described in section 6.2.8.4.3 + * for action data tables sized at 256, 512 and 1024, the Huffman bits for these addresses are + * no longer at the bottom of the address, but rather near the top. For direct action data + * addresses, a hole in the address needs to be created. + */ +unsigned ActionTable::determine_vpn_shiftcount(Table::Call &call) const { + if (call.args[0].name() && call.args[0] == "$DIRECT") { + return std::max(0, static_cast(get_log2size()) - 2 - ACTION_DATA_LOWER_HUFFMAN_BITS); + } + return 0; +} + +int ActionTable::get_start_vpn() { + // Based on the format width, the starting vpn is determined as follows (See + // Section 6.2.8.4.3 in MAU MicroArchitecture Doc) + // WIDTH LOG2SIZE START_VPN + // <= 128 bits - 7 - 0 + // = 256 bits - 8 - 0 + // = 512 bits - 9 - 1 + // = 1024 bits - 10 - 3 + int size = get_log2size(); + if (size <= 8) return 0; + if (size == 9) return 1; + if (size == 10) return 3; + return 0; +} + +void ActionTable::vpn_params(int &width, int &depth, int &period, const char *&period_name) const { + width = 1; + depth = layout_size(); + period = format ? 1 << std::max(static_cast(format->log2size) - 7, 0) : 0; + // Based on the format width, the vpn are numbered as follows (See Section + // 6.2.8.4.3 in MAU MicroArchitecture Doc) + // WIDTH PERIOD VPN'S + // <= 128 bits - +1 - 0, 1, 2, 3, ... + // = 256 bits - +2 - 2, 4, 6, 8, ... + // = 512 bits - +4 - 1, 5, 9, 13, ... + // = 1024 bits - +8 - 3, 11, 19, 27, ... + for (auto &fmt : Values(action_formats)) + period = std::max(period, 1 << std::max(static_cast(fmt->log2size) - 7, 0)); + period_name = "action data width"; +} + +void ActionTable::setup(VECTOR(pair_t) & data) { + action_id = -1; + setup_layout(layout, data); + for (auto &kv : MapIterChecked(data, true)) { + if (kv.key == "format") { + const char *action = nullptr; + if (kv.key.type == tCMD) { + if (!PCHECKTYPE(kv.key.vec.size > 1, kv.key[1], tSTR)) continue; + if (action_formats.count((action = kv.key[1].s))) { + error(kv.key.lineno, "Multiple formats for action %s", kv.key[1].s); + continue; + } + } + if (CHECKTYPEPM(kv.value, tMAP, kv.value.map.size > 0, "non-empty map")) { + auto *fmt = new Format(this, kv.value.map, true); + if (fmt->size < 8) { // pad out to minimum size + fmt->size = 8; + fmt->log2size = 3; + } + if (action) + action_formats[action].reset(fmt); + else + format.reset(fmt); + } + } + } + if (!format && action_formats.empty()) error(lineno, "No format in action table %s", name()); + for (auto &kv : MapIterChecked(data, true)) { + if (kv.key == "format") { + /* done above to be done before action_bus and vpns */ + } else if (kv.key.type == tCMD && kv.key[0] == "format") { + /* done above to be done before action_bus */ + } else if (kv.key == "actions") { + if (CHECKTYPE(kv.value, tMAP)) actions.reset(new Actions(this, kv.value.map)); + } else if (kv.key == "action_bus") { + if (CHECKTYPE(kv.value, tMAP)) action_bus = ActionBus::create(this, kv.value.map); + } else if (kv.key == "action_id") { + if (CHECKTYPE(kv.value, tINT)) action_id = kv.value.i; + } else if (kv.key == "vpns") { + if (kv.value == "null") + no_vpns = true; + else if (CHECKTYPE(kv.value, tVEC)) + setup_vpns(layout, &kv.value.vec); + } else if (kv.key == "home_row") { + home_lineno = kv.value.lineno; + // Builds the map of home rows possible per word, as different words of the + // action row is on different home rows + if (CHECKTYPE2(kv.value, tINT, tVEC)) { + int word = 0; + if (kv.value.type == tINT) { + if (kv.value.i >= 0 || kv.value.i < LOGICAL_SRAM_ROWS) + home_rows_per_word[word].setbit(kv.value.i); + else + error(kv.value.lineno, "Invalid home row %" PRId64 "", kv.value.i); + } else { + for (auto &v : kv.value.vec) { + if (CHECKTYPE2(v, tINT, tVEC)) { + if (v.type == tINT) { + if (v.i >= 0 || v.i < LOGICAL_SRAM_ROWS) + home_rows_per_word[word].setbit(v.i); + else + error(v.lineno, "Invalid home row %" PRId64 "", v.i); + } else if (v.type == tVEC) { + for (auto &v2 : v.vec) { + if (CHECKTYPE(v2, tINT)) { + if (v2.i >= 0 || v2.i < LOGICAL_SRAM_ROWS) + home_rows_per_word[word].setbit(v2.i); + else + error(v.lineno, "Invalid home row %" PRId64 "", v2.i); + } + } + } + } + word++; + } + } + } + } else if (kv.key == "p4") { + if (CHECKTYPE(kv.value, tMAP)) + p4_table = P4Table::get(P4Table::ActionData, kv.value.map); + } else if (kv.key == "context_json") { + setup_context_json(kv.value); + } else if (kv.key == "row" || kv.key == "logical_row" || kv.key == "column" || + kv.key == "word") { + /* already done in setup_layout */ + } else if (kv.key == "logical_bus") { + if (CHECKTYPE2(kv.value, tSTR, tVEC)) { + if (kv.value.type == tSTR) { + if (*kv.value.s != 'A' && *kv.value.s != 'O' && *kv.value.s != 'S') + error(kv.value.lineno, "Invalid logical bus %s", kv.value.s); + } else { + for (auto &v : kv.value.vec) { + if (CHECKTYPE(v, tSTR)) { + if (*v.s != 'A' && *v.s != 'O' && *v.s != 'S') + error(v.lineno, "Invalid logical bus %s", v.s); + } + } + } + } + } else { + warning(kv.key.lineno, "ignoring unknown item %s in table %s", value_desc(kv.key), + name()); + } + } + if (Target::SRAM_GLOBAL_ACCESS()) + alloc_global_srams(); + else + alloc_rams(true, stage->sram_use, 0); + if (!action_bus) action_bus = ActionBus::create(); +} + +void ActionTable::pass1() { + LOG1("### Action table " << name() << " pass1 " << loc()); + if (default_action.empty()) default_action = get_default_action(); + if (!p4_table) + p4_table = P4Table::alloc(P4Table::ActionData, this); + else + p4_table->check(this); + alloc_vpns(); + std::sort(layout.begin(), layout.end(), [](const Layout &a, const Layout &b) -> bool { + if (a.word != b.word) return a.word < b.word; + return a.row > b.row; + }); + int width = format ? (format->size - 1) / 128 + 1 : 1; + for (auto &fmt : action_formats) { +#if 0 + for (auto &fld : *fmt.second) { + if (auto *f = format ? format->field(fld.first) : 0) { + if (fld.second.bits != f->bits || fld.second.size != f->size) { + error(fmt.second->lineno, "Action %s format for field %s incompatible " + "with default format", fmt.first.c_str(), fld.first.c_str()); + continue; } } + for (auto &fmt2 : action_formats) { + if (fmt.second == fmt2.second) break; + if (auto *f = fmt2.second->field(fld.first)) { + if (fld.second.bits != f->bits || fld.second.size != f->size) { + error(fmt.second->lineno, "Action %s format for field %s incompatible " + "with action %s format", fmt.first.c_str(), fld.first.c_str(), + fmt2.first.c_str()); + break; } } } } +#endif + width = std::max(width, int((fmt.second->size - 1) / 128U + 1)); + } + unsigned depth = layout_size() / width; + std::vector slice_size(width, 0); + unsigned idx = 0; // ram index within depth + int word = 0; // word within wide table; + int home_row = -1; + std::map final_home_rows; + Layout *prev = nullptr; + for (auto row = layout.begin(); row != layout.end(); ++row) { + if (row->word > 0) word = row->word; + if (!prev || prev->word != word || home_rows_per_word[word].getbit(row->row) || + home_row / 2 - row->row / 2 > 5 /* can't go over 5 physical rows for timing */ + || (!Target::SUPPORT_OVERFLOW_BUS() && home_row >= 8 && row->row < 8) + /* can't flow between logical row 7 and 8 in JBay*/ + ) { + if (prev && prev->row == row->row) prev->home_row = false; + home_row = row->row; + row->home_row = true; + final_home_rows[word].setbit(row->row); + need_bus(row->lineno, stage->action_data_use, row->row, "action data"); + } + if (row->word >= 0) { + if (row->word > width) { + error(row->lineno, "Invalid word %u for row %d", row->word, row->row); + continue; + } + slice_size[row->word] += row->memunits.size(); + } else { + if (slice_size[word] + row->memunits.size() > depth) { + int split = depth - slice_size[word]; + row = layout.insert(row, Layout(*row)); + row->memunits.erase(row->memunits.begin() + split, row->memunits.end()); + row->vpns.erase(row->vpns.begin() + split, row->vpns.end()); + auto next = row + 1; + next->memunits.erase(next->memunits.begin(), next->memunits.begin() + split); + next->vpns.erase(next->vpns.begin(), next->vpns.begin() + split); + } + row->word = word; + if ((slice_size[word] += row->memunits.size()) == int(depth)) ++word; + } + prev = &*row; + } + if (!home_rows_per_word.empty()) { + for (word = 0; word < width; ++word) { + for (unsigned row : home_rows_per_word[word] - final_home_rows[word]) { + error(home_lineno, "home row %u not present in table %s", row, name()); + break; + } + } + } + home_rows_per_word = final_home_rows; + for (word = 0; word < width; ++word) + if (slice_size[word] != int(depth)) { + error(layout.front().lineno, "Incorrect size for word %u in layout of table %s", word, + name()); + break; + } + for (auto &r : layout) LOG4(" " << r); + action_bus->pass1(this); + if (actions) actions->pass1(this); + AttachedTable::pass1(); + SelectionTable *selector = nullptr; + for (auto mtab : match_tables) { + auto *s = mtab->get_selector(); + if (s && selector && s != selector) + error(lineno, "Inconsistent selectors %s and %s for table %s", s->name(), + selector->name(), name()); + if (s) selector = s; + } +} + +void ActionTable::pass2() { + LOG1("### Action table " << name() << " pass2 " << loc()); + if (match_tables.empty()) error(lineno, "No match table for action table %s", name()); + if (!format) format.reset(new Format(this)); + /* Driver does not support formats with different widths. Need all formats + * to be the same size, so pad them out */ + pad_format_fields(); + if (actions) actions->pass2(this); + if (action_bus) action_bus->pass2(this); +} + +/** + * FIXME: Due to get_match_tables function not being a const function (which itself should be + * a separate PR), in order to get all potentialy pack formats from all of the actions in all + * associated match tables, an initial pass is required to perform this lookup. + * + * Thus a map is saved in this pass containing a copy of an action, with a listing of all of + * the possible aliases. This will only currently work if the aliases are identical across + * actions, which at the moment, they are. We will need to change this functionality when + * actions could potentially be different across action profiles, either by gathering a union + * of the aliases across actions with the same action handle, or perhaps de-alias the pack + * formats before context JSON generation + */ +void ActionTable::pass3() { + LOG1("### Action table " << name() << " pass3 " << loc()); + action_bus->pass3(this); + + if (!actions) { + Actions *tbl_actions = nullptr; + for (auto mt : get_match_tables()) { + if (mt->actions) { + tbl_actions = mt->actions.get(); + } else if (auto tern = mt->to()) { + if (tern->indirect && tern->indirect->actions) { + tbl_actions = tern->indirect->actions.get(); + } + } + BUG_CHECK(tbl_actions); + for (auto &act : *tbl_actions) { + if (pack_actions.count(act.name) == 0) pack_actions[act.name] = &act; + } + } + } else { + for (auto &act : *actions) { + if (pack_actions.count(act.name) == 0) pack_actions[act.name] = &act; + } + } + + for (auto &fmt : action_formats) { + if (pack_actions.count(fmt.first) == 0) { + error(fmt.second->lineno, "Format for non-existant action %s", fmt.first.c_str()); + continue; + } + } +} + +template +static void flow_selector_addr(REGS ®s, int from, int to) { + BUG_CHECK(from > to); + BUG_CHECK((from & 3) == 3); + if (from / 2 == to / 2) { + /* R to L */ + regs.rams.map_alu.selector_adr_switchbox.row[from / 4] + .ctl.l_oflo_adr_o_mux_select.l_oflo_adr_o_sel_selector_adr_r_i = 1; + return; + } + if (from & 1) /* R down */ + regs.rams.map_alu.selector_adr_switchbox.row[from / 4] + .ctl.b_oflo_adr_o_mux_select.b_oflo_adr_o_sel_selector_adr_r_i = 1; + // else + // /* L down */ + // regs.rams.map_alu.selector_adr_switchbox.row[from/4].ctl + // .b_oflo_adr_o_mux_select.b_oflo_adr_o_sel_selector_adr_l_i = 1; + + /* Include all selection address switchboxes needed when the action RAMs + * reside on overflow rows */ + for (int row = from / 4 - 1; row >= to / 4; row--) + if (row != to / 4 || (to % 4) < 2) /* top to bottom */ + regs.rams.map_alu.selector_adr_switchbox.row[row] + .ctl.b_oflo_adr_o_mux_select.b_oflo_adr_o_sel_oflo_adr_t_i = 1; + + switch (to & 3) { + case 3: + /* flow down to R */ + regs.rams.map_alu.selector_adr_switchbox.row[to / 4].ctl.r_oflo_adr_o_mux_select = 1; + break; + case 2: + /* flow down to L */ + regs.rams.map_alu.selector_adr_switchbox.row[to / 4] + .ctl.l_oflo_adr_o_mux_select.l_oflo_adr_o_sel_oflo_adr_t_i = 1; + break; + default: + /* even physical rows are hardwired to flow down to both L and R */ + break; + } +} + +template +void ActionTable::write_regs_vt(REGS ®s) { + LOG1("### Action table " << name() << " write_regs " << loc()); + unsigned fmt_log2size = format ? format->log2size : 0; + unsigned width = format ? (format->size - 1) / 128 + 1 : 1; + for (auto &fmt : Values(action_formats)) { + fmt_log2size = std::max(fmt_log2size, fmt->log2size); + width = std::max(width, (fmt->size - 1) / 128U + 1); + } + unsigned depth = layout_size() / width; + bool push_on_overflow = false; // true if we overflow from bottom to top + unsigned idx = 0; + int word = 0; + Layout *home = nullptr; + int prev_logical_row = -1; + decltype(regs.rams.array.switchbox.row[0].ctl) *home_switch_ctl = 0, *prev_switch_ctl = 0; + auto &adrdist = regs.rams.match.adrdist; + auto &icxbar = adrdist.adr_dist_action_data_adr_icxbar_ctl; + for (Layout &logical_row : layout) { + unsigned row = logical_row.row / 2; + unsigned side = logical_row.row & 1; /* 0 == left 1 == right */ + unsigned top = logical_row.row >= 8; /* 0 == bottom 1 == top */ + auto vpn = logical_row.vpns.begin(); + auto &switch_ctl = regs.rams.array.switchbox.row[row].ctl; + auto &map_alu_row = regs.rams.map_alu.row[row]; + if (logical_row.home_row) { + home = &logical_row; + home_switch_ctl = &switch_ctl; + action_bus->write_action_regs(regs, this, logical_row.row, word); + if (side) + switch_ctl.r_action_o_mux_select.r_action_o_sel_action_rd_r_i = 1; + else + switch_ctl.r_l_action_o_mux_select.r_l_action_o_sel_action_rd_l_i = 1; + for (auto mtab : match_tables) + icxbar[mtab->logical_id].address_distr_to_logical_rows |= 1U << logical_row.row; + } else { + BUG_CHECK(home); + // FIXME use DataSwitchboxSetup for this somehow? + if (&switch_ctl == home_switch_ctl) { + /* overflow from L to R action */ + switch_ctl.r_action_o_mux_select.r_action_o_sel_oflo_rd_l_i = 1; + } else { + if (side) { + /* overflow R up */ + switch_ctl.t_oflo_rd_o_mux_select.t_oflo_rd_o_sel_oflo_rd_r_i = 1; + } else { + /* overflow L up */ + switch_ctl.t_oflo_rd_o_mux_select.t_oflo_rd_o_sel_oflo_rd_l_i = 1; + } + if (prev_switch_ctl != &switch_ctl) { + if (prev_switch_ctl != home_switch_ctl) + prev_switch_ctl->t_oflo_rd_o_mux_select.t_oflo_rd_o_sel_oflo_rd_b_i = 1; + else if (home->row & 1) + home_switch_ctl->r_action_o_mux_select.r_action_o_sel_oflo_rd_b_i = 1; + else + home_switch_ctl->r_l_action_o_mux_select.r_l_action_o_sel_oflo_rd_b_i = 1; + } + } + /* if we're skipping over full rows and overflowing over those rows, need to + * propagate overflow from bottom to top. This effectively uses only the + * odd (right side) overflow busses. L ovfl can still go to R action */ + for (int r = prev_logical_row / 2 - 1; r > static_cast(row); r--) { + prev_switch_ctl = ®s.rams.array.switchbox.row[r].ctl; + prev_switch_ctl->t_oflo_rd_o_mux_select.t_oflo_rd_o_sel_oflo_rd_b_i = 1; + } + + auto &oflo_adr_xbar = map_alu_row.vh_xbars.adr_dist_oflo_adr_xbar_ctl[side]; + if ((home->row >= 8) == top) { + oflo_adr_xbar.adr_dist_oflo_adr_xbar_source_index = home->row % 8; + oflo_adr_xbar.adr_dist_oflo_adr_xbar_source_sel = 0; + } else { + BUG_CHECK(home->row >= 8); + BUG_CHECK(options.target == TOFINO); + oflo_adr_xbar.adr_dist_oflo_adr_xbar_source_index = 0; + oflo_adr_xbar.adr_dist_oflo_adr_xbar_source_sel = 3; + push_on_overflow = true; + for (auto mtab : match_tables) + if (!icxbar[mtab->logical_id].address_distr_to_overflow) + icxbar[mtab->logical_id].address_distr_to_overflow = 1; + } + oflo_adr_xbar.adr_dist_oflo_adr_xbar_enable = 1; + } + SelectionTable *selector = get_selector(); + if (selector) { + if (logical_row.row != selector->home_row()) { + if (logical_row.row > selector->home_row()) + error(lineno, "Selector data from %s on row %d cannot flow up to %s on row %d", + selector->name(), selector->home_row(), name(), logical_row.row); + else + flow_selector_addr(regs, selector->home_row(), logical_row.row); + } + } + for (auto &memunit : logical_row.memunits) { + int logical_col = memunit.col; + unsigned col = logical_col + 6 * side; + auto &ram = regs.rams.array.row[row].ram[col]; + auto &unitram_config = map_alu_row.adrmux.unitram_config[side][logical_col]; + if (logical_row.home_row) unitram_config.unitram_action_subword_out_en = 1; + ram.unit_ram_ctl.match_ram_write_data_mux_select = UnitRam::DataMux::NONE; + ram.unit_ram_ctl.match_ram_read_data_mux_select = + home == &logical_row ? UnitRam::DataMux::ACTION : UnitRam::DataMux::OVERFLOW; + unitram_config.unitram_type = UnitRam::ACTION; + if (!no_vpns) unitram_config.unitram_vpn = *vpn++; + unitram_config.unitram_logical_table = action_id >= 0 ? action_id : logical_id; + if (gress == INGRESS || gress == GHOST) + unitram_config.unitram_ingress = 1; + else + unitram_config.unitram_egress = 1; + unitram_config.unitram_enable = 1; + auto &ram_mux = map_alu_row.adrmux.ram_address_mux_ctl[side][logical_col]; + auto &adr_mux_sel = ram_mux.ram_unitram_adr_mux_select; + if (selector) { + int shift = std::min(fmt_log2size - 2, MAX_AD_SHIFT); + auto &shift_ctl = regs.rams.map_alu.mau_selector_action_adr_shift[row]; + if (logical_row.row == selector->layout[0].row) { + /* we're on the home row of the selector, so use it directly */ + if (home == &logical_row) + adr_mux_sel = UnitRam::AdrMux::SELECTOR_ALU; + else + adr_mux_sel = UnitRam::AdrMux::SELECTOR_ACTION_OVERFLOW; + if (side) + shift_ctl.mau_selector_action_adr_shift_right = shift; + else + shift_ctl.mau_selector_action_adr_shift_left = shift; + } else { + /* not on the home row -- use overflows */ + if (home == &logical_row) + adr_mux_sel = UnitRam::AdrMux::SELECTOR_OVERFLOW; + else + adr_mux_sel = UnitRam::AdrMux::SELECTOR_ACTION_OVERFLOW; + if (side) + shift_ctl.mau_selector_action_adr_shift_right_oflo = shift; + else + shift_ctl.mau_selector_action_adr_shift_left_oflo = shift; + } + } else { + if (home == &logical_row) { + adr_mux_sel = UnitRam::AdrMux::ACTION; + } else { + adr_mux_sel = UnitRam::AdrMux::OVERFLOW; + ram_mux.ram_oflo_adr_mux_select_oflo = 1; + } + } + if (gress == EGRESS) + regs.cfg_regs.mau_cfg_uram_thread[col / 4U] |= 1U << (col % 4U * 8U + row); + regs.rams.array.row[row].actiondata_error_uram_ctl[timing_thread(gress)] |= + 1 << (col - 2); + if (++idx == depth) { + idx = 0; + home = nullptr; + ++word; + } + } + prev_switch_ctl = &switch_ctl; + prev_logical_row = logical_row.row; + } + if (push_on_overflow) adrdist.oflo_adr_user[0] = adrdist.oflo_adr_user[1] = AdrDist::ACTION; + if (actions) actions->write_regs(regs, this); +} + +// Action data address huffman encoding +// { 0, {"xxx", "xxxxx"} }, +// { 8, {"xxx", "xxxx0"} }, +// { 16, {"xxx", "xxx01"} }, +// { 32, {"xxx", "xx011"} }, +// { 64, {"xxx", "x0111"} }, +// { 128, {"xxx", "01111"} }, +// { 256, {"xx0", "11111"} }, +// { 512, {"x01", "11111"} }, +// { 1024, {"011", "11111"} }; + +// Track the actions added to json per action table. gen_tbl_cfg can be called +// multiple times for the same action for each stage table in case of an action +// table split across multiple stages, but must be added to json only once. +static std::map> actions_in_json; +void ActionTable::gen_tbl_cfg(json::vector &out) const { + // FIXME -- this is wrong if actions have different format sizes + unsigned number_entries = (layout_size() * 128 * 1024) / (1 << format->log2size); + json::map &tbl = *base_tbl_cfg(out, "action_data", number_entries); + json::map &stage_tbl = *add_stage_tbl_cfg(tbl, "action_data", number_entries); + for (auto &act : pack_actions) { + auto *fmt = format.get(); + if (action_formats.count(act.first)) fmt = action_formats.at(act.first).get(); + add_pack_format(stage_tbl, fmt, true, true, act.second); + auto p4Name = p4_name(); + if (!p4Name) { + error(lineno, "No p4 table name found for table : %s", name()); + continue; + } + std::string tbl_name = p4Name; + std::string act_name = act.second->name; + if (actions_in_json.count(tbl_name) == 0) { + actions_in_json[tbl_name].insert(act_name); + act.second->gen_simple_tbl_cfg(tbl["actions"]); + } else { + auto acts_added = actions_in_json[tbl_name]; + if (acts_added.count(act_name) == 0) { + actions_in_json[tbl_name].emplace(act_name); + act.second->gen_simple_tbl_cfg(tbl["actions"]); + } + } + } + stage_tbl["memory_resource_allocation"] = + gen_memory_resource_allocation_tbl_cfg("sram", layout); + // FIXME: what is the check for static entries? + tbl["static_entries"] = json::vector(); + std::string hr = how_referenced(); + if (hr.empty()) hr = indirect ? "indirect" : "direct"; + tbl["how_referenced"] = hr; + merge_context_json(tbl, stage_tbl); +} + +DEFINE_TABLE_TYPE_WITH_SPECIALIZATION(ActionTable, TARGET_CLASS) // NOLINT(readability/fn_size) diff --git a/backends/tofino/bf-asm/alias_array.h b/backends/tofino/bf-asm/alias_array.h new file mode 100644 index 00000000000..5551776e446 --- /dev/null +++ b/backends/tofino/bf-asm/alias_array.h @@ -0,0 +1,142 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_ALIAS_ARRAY_H_ +#define BF_ASM_ALIAS_ARRAY_H_ + +#include + +#include "bfas.h" // for BUG_CHECK + +template +class alias_array; + +template +class alias_array_base { + protected: + class iterator { + T **ptr; + + public: + explicit iterator(T **p) : ptr(p) {} + iterator &operator++() { + ++ptr; + return *this; + } + iterator &operator--() { + --ptr; + return *this; + } + iterator &operator++(int) { + auto copy = *this; + ++ptr; + return copy; + } + iterator &operator--(int) { + auto copy = *this; + --ptr; + return copy; + } + bool operator==(const iterator &i) const { return ptr == i.ptr; } + bool operator!=(const iterator &i) const { return ptr != i.ptr; } + T &operator*() const { return **ptr; } + T *operator->() const { return *ptr; } + }; + + public: + virtual T &operator[](size_t) = 0; + virtual const T &operator[](size_t) const = 0; + virtual size_t size() const = 0; + virtual iterator begin() = 0; + virtual iterator end() = 0; + virtual bool modified() const = 0; + virtual void set_modified(bool v = true) = 0; + virtual bool disabled() const = 0; + virtual bool disable() = 0; + virtual bool disable_if_zero() = 0; + virtual void enable() = 0; +}; + +template +class alias_array : public alias_array_base { + T *data[S]; + using typename alias_array_base::iterator; + + public: + alias_array(const std::initializer_list &v) { + auto it = v.begin(); + for (auto &e : data) { + BUG_CHECK(it != v.end(), "Not enough initializers for alias array"); + e = *it++; + } + BUG_CHECK(it == v.end(), "Too many initializers for alias array"); + } + T &operator[](size_t idx) { + BUG_CHECK(idx < S, "alias array index %zd out of bounds %zd", idx, S); + return *data[idx]; + } + const T &operator[](size_t idx) const { + BUG_CHECK(idx < S, "alias array index %zd out of bounds %zd", idx, S); + return *data[idx]; + } + size_t size() const { return S; } + iterator begin() { return iterator(data); } + iterator end() { return iterator(data + S); } + bool modified() const { + for (size_t i = 0; i < S; i++) + if (data[i]->modified()) return true; + return false; + } + void set_modified(bool v = true) { + for (size_t i = 0; i < S; i++) data[i]->set_modified(v); + } + bool disabled() const { + bool rv = true; + for (size_t i = 0; i < S; i++) + if (!data[i]->disabled()) rv = false; + return rv; + } + bool disable() { + bool rv = true; + for (size_t i = 0; i < S; i++) + if (!data[i]->disable()) rv = false; + return rv; + } + void enable() { + for (size_t i = 0; i < S; i++) data[i]->enable(); + } + bool disable_if_unmodified() { + bool rv = true; + for (size_t i = 0; i < S; i++) + if (!data[i]->disable_if_unmodified()) rv = false; + return rv; + } + bool disable_if_zero() { + bool rv = true; + for (size_t i = 0; i < S; i++) + if (!data[i]->disable_if_zero()) rv = false; + return rv; + } + bool disable_if_reset_value() { + bool rv = true; + for (size_t i = 0; i < S; i++) + if (!data[i]->disable_if_reset_value()) rv = false; + return rv; + } +}; + +#endif /* BF_ASM_ALIAS_ARRAY_H_ */ diff --git a/backends/tofino/bf-asm/alloc.h b/backends/tofino/bf-asm/alloc.h new file mode 100644 index 00000000000..11683595f05 --- /dev/null +++ b/backends/tofino/bf-asm/alloc.h @@ -0,0 +1,229 @@ +#ifndef EXTENSIONS_BF_P4C_COMMON_ALLOC_H_ +#define EXTENSIONS_BF_P4C_COMMON_ALLOC_H_ + +#include + +#include +#include + +namespace BFN { + +template +class Alloc1Dbase { + int size_; + T *data; + Alloc1Dbase() = delete; + Alloc1Dbase(const Alloc1Dbase &) = delete; + Alloc1Dbase &operator=(const Alloc1Dbase &) = delete; + Alloc1Dbase &operator=(Alloc1Dbase &&) = delete; + + public: + explicit Alloc1Dbase(int sz) : size_(sz) { data = sz ? new T[sz]{} : nullptr; } + Alloc1Dbase(Alloc1Dbase &&a) noexcept : size_(a.size_), data(a.data) { a.data = 0; } + virtual ~Alloc1Dbase() { delete[] data; } + + typedef T *iterator; + typedef T *const_iterator; + T &operator[](int i) { + if (i < 0 || i >= size_) throw std::out_of_range("Alloc1D"); + return data[i]; + } + const T &operator[](int i) const { + if (i < 0 || i >= size_) throw std::out_of_range("Alloc1D"); + return data[i]; + } + bool operator==(const Alloc1Dbase &t) const { + return std::equal(data, data + size_, t.data, t.data + t.size_); + } + bool operator!=(const Alloc1Dbase &t) const { return !(*this == t); } + + int size() const { return size_; } + void clear() { std::fill(data, data + size_, T()); } + T *begin() { return data; } + T *end() { return data + size_; } +}; + +template +class Alloc1D : public Alloc1Dbase { + public: + Alloc1D() : Alloc1Dbase(S) {} + Alloc1Dbase &base() { return *this; } + bool operator!=(const Alloc1D &t) const { return Alloc1Dbase::operator!=(t); } +}; + +template +class Alloc3Dbase; + +template +class Alloc2Dbase { + int nrows, ncols; + T *data; + template + class rowref { + U *row; + int ncols; + friend class Alloc2Dbase; + friend class Alloc3Dbase; + rowref(U *r, int c) : row(r), ncols(c) {} + + public: + typedef U *iterator; + typedef const U *const_iterator; + U &operator[](int i) const { + if (i < 0 || i >= ncols) throw std::out_of_range("Alloc2D"); + return row[i]; + } + U *begin() const { return row; } + U *end() const { return row + ncols; } + }; + Alloc2Dbase() = delete; + Alloc2Dbase(const Alloc2Dbase &) = delete; + Alloc2Dbase &operator=(const Alloc2Dbase &) = delete; + Alloc2Dbase &operator=(Alloc2Dbase &&) = delete; + friend class Alloc3Dbase; + + public: + Alloc2Dbase(int r, int c) : nrows(r), ncols(c) { + size_t sz = r * c; + data = sz ? new T[sz]{} : nullptr; + } + Alloc2Dbase(Alloc2Dbase &&a) noexcept : nrows(a.nrows), ncols(a.ncols), data(a.data) { + a.data = 0; + } + virtual ~Alloc2Dbase() { delete[] data; } + + rowref operator[](int i) { + if (i < 0 || i >= nrows) throw std::out_of_range("Alloc2D"); + return {data + i * ncols, ncols}; + } + rowref operator[](int i) const { + if (i < 0 || i >= nrows) throw std::out_of_range("Alloc2D"); + return {data + i * ncols, ncols}; + } + T &at(int i, int j) { + if (i < 0 || i >= nrows || j < 0 || j >= ncols) throw std::out_of_range("Alloc2D"); + return data[i * ncols + j]; + } + const T &at(int i, int j) const { + if (i < 0 || i >= nrows || j < 0 || j >= ncols) throw std::out_of_range("Alloc2D"); + return data[i * ncols + j]; + } + T &operator[](std::pair i) { + if (i.first < 0 || i.first >= nrows || i.second < 0 || i.second >= ncols) + throw std::out_of_range("Alloc2D"); + return data[i.first * ncols + i.second]; + } + const T &operator[](std::pair i) const { + if (i.first < 0 || i.first >= nrows || i.second < 0 || i.second >= ncols) + throw std::out_of_range("Alloc2D"); + return data[i.first * ncols + i.second]; + } + bool operator==(const Alloc2Dbase &t) const { + int sz = nrows * ncols; + if (nrows != t.nrows || ncols != t.ncols) return false; + return std::equal(data, data + sz, t.data); + } + bool operator!=(const Alloc2Dbase &t) const { return !(*this == t); } + + int rows() const { return nrows; } + int cols() const { return ncols; } + void clear() { std::fill(data, data + nrows * ncols, T()); } +}; + +template +class Alloc2D : public Alloc2Dbase { + public: + Alloc2D() : Alloc2Dbase(R, C) {} + Alloc2Dbase &base() { return *this; } +}; + +template +class Alloc3Dbase { + int nmats, nrows, ncols; + T *data; + template + class matref { + U *matrix; + int nrows, ncols; + friend class Alloc3Dbase; + + public: + typename Alloc2Dbase::template rowref operator[](int i) const { + if (i < 0 || i >= nrows) throw std::out_of_range("Alloc3D"); + return {matrix + i * ncols, ncols}; + } + U &operator[](std::pair i) const { + if (i.first < 0 || i.first >= nrows || i.second < 0 || i.second >= ncols) + throw std::out_of_range("Alloc3D"); + return matrix[i.first * ncols + i.second]; + } + }; + Alloc3Dbase() = delete; + Alloc3Dbase(const Alloc3Dbase &) = delete; + Alloc3Dbase &operator=(const Alloc3Dbase &) = delete; + Alloc3Dbase &operator=(Alloc3Dbase &&) = delete; + + public: + Alloc3Dbase(int m, int r, int c) : nmats(m), nrows(r), ncols(c) { + size_t sz = m * r * c; + data = sz ? new T[sz]{} : nullptr; + } + Alloc3Dbase(Alloc3Dbase &&a) noexcept + : nmats(a.nmats), nrows(a.nrows), ncols(a.ncols), data(a.data) { + a.data = 0; + } + virtual ~Alloc3Dbase() { delete[] data; } + + matref operator[](int i) { + if (i < 0 || i >= nmats) throw std::out_of_range("Alloc3D"); + return {data + i * nrows * ncols, nrows, ncols}; + } + matref operator[](int i) const { + if (i < 0 || i >= nmats) throw std::out_of_range("Alloc3D"); + return {data + i * nrows * ncols, nrows, ncols}; + } + T &at(int i, int j, int k) { + if (i < 0 || i >= nmats || j < 0 || j >= nrows || k < 0 || k >= ncols) + throw std::out_of_range("Alloc3D"); + return data[i * nrows * ncols + j * ncols + k]; + } + const T &at(int i, int j, int k) const { + if (i < 0 || i >= nmats || j < 0 || j >= nrows || k < 0 || k >= ncols) + throw std::out_of_range("Alloc3D"); + return data[i * nrows * ncols + j * ncols + k]; + } + T &operator[](std::tuple i) { + if (std::get<0>(i) < 0 || std::get<0>(i) >= nmats || std::get<1>(i) < 0 || + std::get<1>(i) >= nrows || std::get<2>(i) < 0 || std::get<2>(i) >= ncols) + throw std::out_of_range("Alloc3D"); + return data[std::get<0>(i) * nrows * ncols + std::get<1>(i) * ncols + std::get<2>(i)]; + } + const T &operator[](std::tuple i) const { + if (std::get<0>(i) < 0 || std::get<0>(i) >= nmats || std::get<1>(i) < 0 || + std::get<1>(i) >= nrows || std::get<2>(i) < 0 || std::get<2>(i) >= ncols) + throw std::out_of_range("Alloc3D"); + return data[std::get<0>(i) * nrows * ncols + std::get<1>(i) * ncols + std::get<2>(i)]; + } + bool operator==(const Alloc3Dbase &t) const { + int sz = nmats * nrows * ncols; + if (nmats != t.nmats || nrows != t.nrows || ncols != t.ncols) return false; + return std::equal(data, data + sz, t.data); + } + bool operator!=(const Alloc3Dbase &t) const { return !(*this == t); } + + int matrixes() const { return nmats; } + int rows() const { return nrows; } + int cols() const { return ncols; } + void clear() { std::fill(data, data + nmats * nrows * ncols, T()); } +}; + +template +class Alloc3D : public Alloc3Dbase { + public: + Alloc3D() : Alloc3Dbase(B, R, C) {} + Alloc3Dbase &base() { return *this; } +}; + +} // namespace BFN + +#endif /* EXTENSIONS_BF_P4C_COMMON_ALLOC_H_ */ diff --git a/backends/tofino/bf-asm/asm-parse.ypp b/backends/tofino/bf-asm/asm-parse.ypp new file mode 100644 index 00000000000..11a0bb15d72 --- /dev/null +++ b/backends/tofino/bf-asm/asm-parse.ypp @@ -0,0 +1,446 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +%{ +#define YYDEBUG 1 +#include "asm-types.h" +#include +#include +#include "sections.h" +#include +#include +static int yylex(); +static void yyerror(const char *, ...); +static int lineno; +static std::map> line_file_map; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +/* DANGER -- The value/command functions take non-const references to + * value_t and MOVE them, so the source should not be used or cleaned + * up afterwards. This matches up with how bison actions work -- in + * the normal case it does NOT try to destroy stuff on the value stack, + * but rather just pops it and lets it go. Do not try to use them + * outside of bison action code */ +static value_t value(int64_t v, int lineno_adj) { + value_t rv = {tINT, lineno - lineno_adj}; + rv.i = v; + return rv; } +static value_t value(VECTOR(uintptr_t) &v, int lineno_adj) { + value_t rv{tBIGINT, lineno - lineno_adj}; + rv.bigi = v; + return rv; } +static value_t value(int lo, int hi, int lineno_adj) { + value_t rv{tRANGE, lineno - lineno_adj}; + rv.lo = lo; + rv.hi = hi; + return rv; } +static value_t value(char *v, int lineno_adj) { + value_t rv{tSTR, lineno - lineno_adj}; + rv.s = v; + return rv; } +static value_t value(match_t v, int lineno_adj) { + value_t rv{tMATCH, lineno - lineno_adj}; + rv.m = v; + return rv; } +static value_t value(VECTOR(match_t) v, int lineno_adj) { + value_t rv{tBIGMATCH, lineno - lineno_adj}; + rv.bigm = v; + return rv; } +static value_t value(VECTOR(value_t) &v, int lineno_adj) { + value_t rv{tVEC, lineno - lineno_adj}; + if (v.size > 0) rv.lineno = v.data[0].lineno; + rv.vec = v; + return rv; } +static value_t value(VECTOR(pair_t) &v, int lineno_adj) { + value_t rv{tMAP, lineno - lineno_adj}; + if (v.size > 0) rv.lineno = v.data[0].key.lineno; + rv.map = v; + return rv; } +static value_t empty_vector(int lineno_adj) { + value_t rv{tVEC, lineno - lineno_adj}; + memset(&rv.vec, 0, sizeof(rv.vec)); + return rv; } +static value_t empty_map(int lineno_adj) { + value_t rv{tMAP, lineno - lineno_adj}; + memset(&rv.vec, 0, sizeof(rv.vec)); + return rv; } +static value_t singleton_map(const value_t &k, const value_t &v) { + value_t rv{tMAP, k.lineno}; + VECTOR_init1(rv.map, pair_t(k, v)); + return rv; } +static value_t command(char *cmd, const VECTOR(value_t) &args, int lineno_adj) { + value_t rv{tCMD, lineno - lineno_adj}; + if (args.size && args.data[0].lineno < rv.lineno) + rv.lineno = args.data[0].lineno; + rv.vec = args; + VECTOR_insert(rv.vec, 0, 1); + rv[0] = value(cmd, 0); + rv[0].lineno = rv.lineno; + return rv; } +static value_t command(char *cmd, value_t &arg, int lineno_adj) { + value_t rv{tCMD, lineno - lineno_adj}; + if (arg.lineno < rv.lineno) + rv.lineno = arg.lineno; + VECTOR_init2(rv.vec, value(cmd, 0), arg); + rv[0].lineno = rv.lineno; + return rv; } +static value_t command(char *cmd, value_t &&arg, int lineno_adj) { + return command(cmd, arg, lineno_adj); } +static value_t command(char *cmd, bool merge, value_t &a1, value_t &a2, int lineno_adj) { + if (merge && a1.type == tCMD && a1 == cmd && a1.vec.size > 2) { + free(cmd); + VECTOR_add(a1.vec, a2); + return a1; } + if (merge && a2.type == tCMD && a2 == cmd && a2.vec.size > 2) { + free(cmd); + VECTOR_insert(a2.vec, 1); + a2.vec[1] = a1; + return a2; } + value_t rv{tCMD, lineno - lineno_adj}; + if (a1.lineno < rv.lineno) + rv.lineno = a1.lineno; + VECTOR_init3(rv.vec, value(cmd, 0), a1, a2); + rv[0].lineno = rv.lineno; + return rv; } + +#define VAL(...) value(__VA_ARGS__, yychar == '\n' ? 1 : 0) +#define CMD(...) command(__VA_ARGS__, yychar == '\n' ? 1 : 0) + +#pragma GCC diagnostic pop +%} + +%define parse.error verbose +%define lr.default-reduction accepting + +%nonassoc LOW_PREC +%left '|' '^' +%left '&' +%left '<' '>' +%nonassoc UNARY + +%union { + int64_t i; + VECTOR(uintptr_t) bigi; + char *str; + match_t match; + VECTOR(match_t) bigm; + value_t value; + VECTOR(value_t) vec; + pair_t pair; + VECTOR(pair_t) map; +} + +%token INDENT UNINDENT DOTDOT +%token INT +%token BIGINT +%token ID +%token STR +%token MATCH +%token BIGMATCH + +%type param param_expr list_element key value elements opt_indent_elements + indent_elements flow_value +%type opt_params params comma_params linewrapped_value_list list_elements value_list dotvals +%type map_element pair +%type map_elements pair_list + +%destructor { free($$); } +%destructor { VECTOR_fini($$); } +%destructor { free_value(&$$); } +%destructor { VECTOR_foreach($$, free_value); VECTOR_fini($$); } +%destructor { free_pair(&$$); } +%destructor { VECTOR_foreach($$, free_pair); VECTOR_fini($$); } + +%printer { fprintf(yyoutput, "%" PRId64, $$); } +%printer { fprintf(yyoutput, "0x%" PRIuPTR, $$.data[$$.size-1]); + for (int i = $$.size-2; i >= 0; i--) + fprintf(yyoutput, "%016" PRIuPTR, $$.data[i]); } +%printer { if ($$) fprintf(yyoutput, "'%s'", $$); else fprintf(yyoutput, "null"); } +%printer { print_match(yyoutput, $$); } +%printer { fprintf(yyoutput, "%s", value_desc(&$$)); } +%printer { fprintf(yyoutput, "vec of size %d", $$.size); } +%printer { fprintf(yyoutput, "map of size %d", $$.size); } + +%% + +start: INDENT sections UNINDENT | sections | /* epsilon */; + +sections: sections section | section ; + +section : ID opt_params ':' + { $$ = Section::start_section(lineno, $1, $2); } + '\n' opt_indent_elements + { if (!$4) Section::asm_section($1, $2, $6); + VECTOR_foreach($2, free_value); + VECTOR_fini($2); + free_value(&$6); + free($1); } + | ID opt_params ':' + { $$ = Section::start_section(lineno, $1, $2); } + value '\n' + { if (!$4) Section::asm_section($1, $2, $5); + VECTOR_foreach($2, free_value); + VECTOR_fini($2); + free_value(&$5); + free($1); } +; + +opt_params: /* empty */ { memset(&$$, 0, sizeof($$)); } + | params + ; +params : param %prec LOW_PREC { VECTOR_init1($$, $1); } + | params param { $$ = $1; VECTOR_add($$, $2); } + ; +comma_params + : param ',' value { VECTOR_init2($$, $1, $3); } + | comma_params ',' value { $$ = $1; VECTOR_add($$, $3); } + | param_expr ',' value { VECTOR_init2($$, $1, $3); } + | '(' value ')' ',' value { VECTOR_init2($$, $2, $5); } + ; +param : INT { $$ = VAL($1); } + | ID { $$ = VAL($1); } + | '-' INT { $$ = VAL(-$2); } + | '!' ID { $$ = CMD(strdup("!"), VAL($2)); } + | INT DOTDOT INT { $$ = VAL($1, $3); } + | ID '(' value ')' { $$ = CMD($1, $3); } + | ID '(' value_list ')' { $$ = CMD($1, $3); } + | flow_value { $$ = $1; } + ; +param_expr + : param '^' value { $$ = CMD(strdup("^"), true, $1, $3); } + | param '|' value { $$ = CMD(strdup("|"), true, $1, $3); } + | param '&' value { $$ = CMD(strdup("&"), true, $1, $3); } + /* rule duplication to get precedence correct */ + | param_expr '^' value { $$ = CMD(strdup("^"), true, $1, $3); } + | param_expr '|' value { $$ = CMD(strdup("|"), true, $1, $3); } + | param_expr '&' value { $$ = CMD(strdup("&"), true, $1, $3); } + ; + +opt_indent_elements: { $$ = empty_map(1); } + | indent_elements + ; + +indent_elements + : INDENT elements UNINDENT { $$ = $2; } + | INDENT error { $$ = lineno; } error_resync UNINDENT { $$ = empty_map(lineno-$3); } + ; +elements: list_elements { $$ = VAL($1); } + | list_elements error error_resync { $$ = VAL($1); } + | map_elements { $$ = VAL($1); } + | map_elements error error_resync { $$ = VAL($1); } + ; +map_elements: map_elements map_element { $$ = $1; VECTOR_add($$, $2); } + | map_element { VECTOR_init1($$, $1); } + ; +list_elements: list_elements list_element { $$ = $1; VECTOR_add($$, $2); } + | list_element { VECTOR_init1($$, $1); } + ; + +map_element + : key ':' value '\n' { $$ = pair_t($1, $3); } + | key ':' '\n' indent_elements { $$ = pair_t($1, $4); } + | key ':' '\n' list_elements { $$ = pair_t($1, VAL($4)); } + | key ':' '\n' { $$ = pair_t($1, empty_map(1)); } + | '?' value ':' value '\n' { $$ = pair_t($2, $4); } + | '?' value ':' '\n' indent_elements { $$ = pair_t($2, $5); } + | '?' value ':' '\n' list_elements { $$ = pair_t($2, VAL($5)); } + | '?' value '\n' ':' value '\n' { $$ = pair_t($2, $5); } + ; + +list_element + : '-' key ':' value '\n' { $$ = singleton_map($2, $4); } + | '-' key ':' value '\n' INDENT map_elements UNINDENT { + VECTOR_insert($7, 0); + $7.data[0] = pair_t($2, $4); + $$ = VAL($7); } + | '-' '?' value ':' value '\n' { $$ = singleton_map($3, $5); } + | '-' '?' value ':' value '\n' INDENT map_elements UNINDENT { + VECTOR_insert($8, 0); + $8.data[0] = pair_t($3, $5); + $$ = VAL($8); } + | '-' value '\n' { $$ = $2; } + | '-' ID comma_params '\n' { $$ = command($2, $3, yychar == '\n' ? 2 : 1); } + | '-' ID comma_params ',' '\n' linewrapped_value_list + { VECTOR_addcopy($3, $6.data, $6.size); + $$ = command($2, $3, yychar == '\n' ? 2 : 1); + VECTOR_fini($6); } + | '-' ID param ',' '\n' linewrapped_value_list + { VECTOR_insert($6, 0); $6.data[0] = $3; + $$ = command($2, $6, yychar == '\n' ? 2 : 1); } + | '-' key ':' '\n' indent_elements { $$ = singleton_map($2, $5); } + | '-' '?' value ':' '\n' indent_elements { $$ = singleton_map($3, $6); } + | '-' '\n' { $$ = value(strdup(""), yychar == '\n' ? 2 : 1); } + ; + +key : ID { $$ = VAL($1); } + | ID params { $$ = CMD($1, $2); } + | INT { $$ = VAL($1); } + | BIGINT { $$ = VAL($1); } + | MATCH { $$ = VAL($1); } + | BIGMATCH { $$ = VAL($1); } + | INT DOTDOT INT { $$ = VAL($1, $3); } + | ID '(' value_list ')' { $$ = CMD($1, $3); } + | ID '(' value ')' { $$ = CMD($1, $3); } + | ID '(' ')' { $$ = VAL($1); } + | flow_value + ; + +value: key + | '-' value %prec UNARY { if (($$=$2).type == tINT) $$.i = -$$.i; else $$ = CMD(strdup("-"), $2); } + | '!' value %prec UNARY { $$ = CMD(strdup("!"), $2); } + | dotvals INT { VECTOR_add($1, VAL($2)); $$ = VAL($1); } + | value '^' value { $$ = CMD(strdup("^"), true, $1, $3); } + | value '|' value { $$ = CMD(strdup("|"), true, $1, $3); } + | value '&' value { $$ = CMD(strdup("&"), true, $1, $3); } + | value '<' '<' value { $$ = CMD(strdup("<<"), false, $1, $4); } + | value '>' '>' value { $$ = CMD(strdup(">>"), false, $1, $4); } + | '(' value ')' { $$ = $2; } + | STR { $$ = VAL($1); } + ; + +flow_value + : '[' value_list ']' { $$ = VAL($2); } + | '[' value ']' { VECTOR(value_t) tmp; VECTOR_init1(tmp, $2); $$ = VAL(tmp); } + | '[' value_list error error_resync ']' { $$ = VAL($2); } + | '[' value error error_resync ']' { + VECTOR(value_t) tmp; VECTOR_init1(tmp, $2); $$ = VAL(tmp); } + | '{' pair_list '}' { $$ = VAL($2); } + | '{' pair_list error error_resync '}' { $$ = VAL($2); } + | '[' ']' { $$ = empty_vector(yychar == '\n' ? 1 : 0); } + | '[' error error_resync ']' { $$ = empty_vector(yychar == '\n' ? 1 : 0); } + | '{' '}' { $$ = empty_map(yychar == '\n' ? 1 : 0); } + | '{' error error_resync '}' { $$ = empty_map(yychar == '\n' ? 1 : 0); } + ; + +value_list + : value_list ',' value { $$ = $1; VECTOR_add($$, $3); } + | value ',' value { VECTOR_init2($$, $1, $3); } + ; +linewrapped_value_list + : value_list '\n' { $$ = $1; } + | value '\n' { VECTOR_init1($$, $1); } + | value_list ',' '\n' linewrapped_value_list + { $$ = $1; VECTOR_addcopy($$, $4.data, $4.size); VECTOR_fini($4); } + | value ',' '\n' linewrapped_value_list + { VECTOR_init1($$, $1); VECTOR_addcopy($$, $4.data, $4.size); VECTOR_fini($4); } + | INDENT value_list '\n' UNINDENT { $$ = $2; } + | INDENT value '\n' UNINDENT { VECTOR_init1($$, $2); } + | INDENT value_list ',' '\n' linewrapped_value_list UNINDENT + { $$ = $2; VECTOR_addcopy($$, $5.data, $5.size); VECTOR_fini($5); } + | INDENT value ',' '\n' linewrapped_value_list UNINDENT + { VECTOR_init1($$, $2); VECTOR_addcopy($$, $5.data, $5.size); VECTOR_fini($5); } + ; + +pair_list + : pair_list ',' pair { $$ = $1; VECTOR_add($$, $3); } + | pair { VECTOR_init1($$, $1); } + ; +pair: value ':' value { $$ = pair_t($1, $3); } + ; + +dotvals : dotvals INT '.' { $$ = $1; VECTOR_add($$, VAL($2)); } + | INT '.' { VECTOR_init1($$, VAL($1)); } + +error_resync: /* epsilon */ | error_resync indent_elements { free_value(&$2); } + | error_resync INT | error_resync ID { free($2); } | error_resync MATCH + | error_resync BIGMATCH { VECTOR_fini($2); } + | error_resync BIGINT { VECTOR_fini($2); } | error_resync ':' | error_resync '-' + | error_resync ',' | error_resync '(' | error_resync ')' | error_resync DOTDOT + | error_resync '\n' | error_resync flow_value { free_value(&$2); } + ; + +%% + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpragmas" +#pragma GCC diagnostic ignored "-Wdeprecated-register" +#pragma GCC diagnostic ignored "-Wsign-compare" +#include "lex-yaml.c" +#pragma GCC diagnostic pop + +int error_count = 0; +int warn_count = 0; + +std::ostream &operator<<(std::ostream &out, const SrcInfo &s) { + auto it = line_file_map.upper_bound(s.lineno); + it--; + out << it->second.first << ':' << (s.lineno - it->first + it->second.second); + return out; +} + +void warning(int lineno, const char *fmt, va_list args) { + auto it = line_file_map.upper_bound(lineno); + if (it == line_file_map.begin()) { + fprintf(stderr, ": warning: "); + } else { + --it; + fprintf(stderr, "%s:%d: warning: ", it->second.first.c_str(), + lineno - it->first + it->second.second); } + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + fflush(stderr); + warn_count++; } + +void error(int lineno, const char *fmt, va_list args) { + auto it = line_file_map.upper_bound(lineno); + if (it == line_file_map.begin()) { + fprintf(stderr, ": error: "); + } else { + --it; + fprintf(stderr, "%s:%d: error: ", it->second.first.c_str(), + lineno - it->first + it->second.second); } + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + fflush(stderr); + error_count++; } + +static void yyerror(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + error(lineno, fmt, args); + va_end(args); +} + +int asm_parse_file(const char *name, FILE *in) { +#ifdef YYDEBUG + if (const char *p = getenv("YYDEBUG")) + yydebug = atoi(p); +#endif /* YYDEBUG */ + yyrestart(in); + line_file_map[lineno++] = std::make_pair(name, 0); + if (yyparse()) + error_count++; + return error_count; +} + +int asm_parse_string(const char* in) { + YY_BUFFER_STATE buf; +#ifdef YYDEBUG + if (const char *p = getenv("YYDEBUG")) + yydebug = atoi(p); +#endif /* YYDEBUG */ + // Reset state in case func is called multiple times + BEGIN(INITIAL); + buf = yy_scan_string(in); + if (yyparse()) + error_count++; + yy_delete_buffer(buf); + return error_count; +} + +std::map *Section::sections = 0; diff --git a/backends/tofino/bf-asm/asm-types.cpp b/backends/tofino/bf-asm/asm-types.cpp new file mode 100644 index 00000000000..7325da5cc55 --- /dev/null +++ b/backends/tofino/bf-asm/asm-types.cpp @@ -0,0 +1,317 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "asm-types.h" + +#include +#include + +#include "misc.h" + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +void VECTOR(pair_t)::push_back(const char *s, value_t &&v) { // NOLINT(whitespace/operators) + pair_t entry{{tSTR, v.lineno}, v}; + entry.key.s = strdup(s); + VECTOR_push(*this, entry); + memset(&v, 0, sizeof(v)); +} + +void push_back(VECTOR(pair_t) & m, const char *s, value_t &&v) { // NOLINT(whitespace/operators) + m.push_back(s, std::move(v)); +} + +VECTOR(value_t) & VECTOR(value_t)::add(value_t &&v) { + VECTOR_add(*this, std::move(v)); + return *this; +} +VECTOR(value_t) & VECTOR(value_t)::add(int v) { + value_t tmp{tINT, v}; + VECTOR_add(*this, tmp); + return *this; +} +VECTOR(value_t) & VECTOR(value_t)::add(const char *v) { + value_t tmp{tSTR, -1}; + tmp.s = const_cast(v); + VECTOR_add(*this, tmp); + return *this; +} + +/** check a value and see if it is a list of maps -- if so, concatenate the + * maps into a single map and replace the list with that */ +void collapse_list_of_maps(value_t &v, bool singleton_only) { + if (v.type != tVEC || v.vec.size == 0) return; + for (int i = 0; i < v.vec.size; i++) { + if (v[i].type != tMAP) return; + if (singleton_only && v[i].map.size != 1) return; + } + VECTOR(pair_t) map = v[0].map; + for (int i = 1; i < v.vec.size; i++) { + VECTOR_addcopy(map, v[i].map.data, v[i].map.size); + VECTOR_fini(v[i].map); + } + VECTOR_fini(v.vec); + v.type = tMAP; + v.map = map; +} + +std::unique_ptr toJson(value_t &v) { + switch (v.type) { + case tINT: + return json::mkuniq(v.i); + case tBIGINT: + if (v.bigi.size == 1 && v.bigi.data[0] < INT64_MAX) + return json::mkuniq(v.bigi.data[0]); + // fall through + case tRANGE: + case tMATCH: + return json::mkuniq(value_desc(v)); + case tSTR: + if (v == "true") return json::mkuniq(); + if (v == "false") return json::mkuniq(); + if (v == "null") return std::unique_ptr(); + return json::mkuniq(v.s); + case tVEC: + return toJson(v.vec); + case tMAP: + return toJson(v.map); + case tCMD: + return toJson(v.vec); + default: + assert(0); + } + return std::unique_ptr(); +} + +std::unique_ptr toJson(VECTOR(value_t) & v) { + auto rv = json::mkuniq(); + auto &vec = *rv; + for (auto &el : v) vec.push_back(toJson(el)); + return rv; +} + +std::unique_ptr toJson(pair_t &kv) { + auto rv = json::mkuniq(); + auto &map = *rv; + map[toJson(kv.key)] = toJson(kv.value); + return rv; +} + +std::unique_ptr toJson(VECTOR(pair_t) & m) { + auto rv = json::mkuniq(); + auto &map = *rv; + for (auto &kv : m) map[toJson(kv.key)] = toJson(kv.value); + return rv; +} + +bool get_bool(const value_t &v) { + if (v == "true") + return true; + else if (v == "false") + return false; + else if (CHECKTYPE(v, tINT)) + return v.i != 0; + return false; +} + +bitvec get_bitvec(const value_t &v, unsigned max_bits, const char *error_message) { + bitvec bv; + if (CHECKTYPE2(v, tINT, tBIGINT)) { + if (v.type == tINT) { + bv.setraw(v.i); + } else { + if (!v.bigi.size) return bv; + bv.setraw(v.bigi.data, v.bigi.size); + } + } + if (!max_bits) return bv; + int bits = bv.max().index() + 1; + if (error_message && bits > max_bits) error(v.lineno, "%s", error_message); + bv.clrrange(max_bits, bits); + return bv; +} + +uint64_t get_int64(const value_t &v, unsigned max_bits, const char *error_message) { + BUG_CHECK(max_bits <= 64); + bool too_large = false; + uint64_t value = 0; + if (CHECKTYPE2(v, tINT, tBIGINT)) { + if (v.type == tINT) { + value = (uint64_t)v.i; + } else { + if (!v.bigi.size) return 0; + if (sizeof(uintptr_t) == sizeof(uint32_t)) { + value = ((uint64_t)v.bigi.data[1] << 32) + v.bigi.data[0]; + too_large = v.bigi.size > 2; + } else { + BUG_CHECK(sizeof(uintptr_t) == sizeof(uint64_t)); + value = v.bigi.data[0]; + too_large = v.bigi.size > 1; + } + } + } + if (!max_bits) return value; + uint64_t masked = value; + if (max_bits < 64) masked &= (1ULL << max_bits) - 1; + if (error_message && (too_large || masked != value)) error(v.lineno, "%s", error_message); + return masked; +} + +static int chkmask(const match_t &m, int maskbits) { + uint64_t mask = bitMask(maskbits); + int shift = 0; + while (mask && ((m.word0 | m.word1) >> shift)) { + if ((mask & m.word0 & m.word1) && (mask & m.word0 & m.word1) != mask) return -1; + mask <<= maskbits; + shift += maskbits; + } + return shift - maskbits; +} + +std::ostream &operator<<(std::ostream &out, match_t m) { + int shift, bits; + if ((shift = chkmask(m, (bits = 4))) >= 0) + out << "0x"; + else if ((shift = chkmask(m, (bits = 3))) >= 0) + out << "0o"; + else if ((shift = chkmask(m, (bits = 1))) >= 0) + out << "0b"; + else if ((shift = chkmask(m, (bits = 0))) == 0) + out << "0b*"; + else + assert(0); + uint64_t mask = bitMask(bits) << shift; + for (; mask; shift -= bits, mask >>= bits) + if (mask & m.word0 & m.word1) + out << '*'; + else + out << "0123456789abcdef"[(m.word1 & mask) >> shift]; + return out; +} + +void print_match(FILE *fp, match_t m) { + std::stringstream tmp; + tmp << m; + fputs(tmp.str().c_str(), fp); +} + +const char *value_type_desc[] = {"integer", "bigint", "range", + "identifier", "match pattern", "big match", + "list", "key: value pairs", "operation"}; + +const char *value_desc(const value_t *p) { + static char buffer[32]; + switch (p->type) { + case tINT: + snprintf(buffer, sizeof(buffer), "%" PRId64 "", p->i); + return buffer; + case tBIGINT: + return ""; + case tRANGE: + snprintf(buffer, sizeof(buffer), "%d..%d", p->lo, p->hi); + return buffer; + case tMATCH: + return ""; + case tBIGMATCH: + return ""; + case tSTR: + return p->s; + case tVEC: + return ""; + case tMAP: + return ""; + case tCMD: + if (p->vec.size > 0 && p->vec.data[0].type == tSTR) return p->vec.data[0].s; + return ""; + } + assert(false && "unknown value type"); + return ""; +} + +void free_value(value_t *p) { + switch (p->type) { + case tBIGINT: + VECTOR_fini(p->bigi); + break; + case tSTR: + free(p->s); + break; + case tVEC: + case tCMD: + VECTOR_foreach(p->vec, free_value); + VECTOR_fini(p->vec); + break; + case tMAP: + VECTOR_foreach(p->map, free_pair); + VECTOR_fini(p->map); + break; + default: + break; + } +} + +bool operator==(const struct value_t &a, const struct value_t &b) { + int i; + if (a.type != b.type) { + if (a.type == tINT && b.type == tBIGINT) { + if (a.i < 0 || (size_t)a.i != b.bigi.data[0]) return false; + for (i = 1; i < b.bigi.size; i++) + if (b.bigi.data[i]) return false; + return true; + } else if (a.type == tBIGINT && b.type == tINT) { + if (b.i < 0 || (size_t)b.i != a.bigi.data[0]) return false; + for (i = 1; i < a.bigi.size; i++) + if (a.bigi.data[i]) return false; + return true; + } + return false; + } + switch (a.type) { + case tINT: + return a.i == b.i; + case tBIGINT: + for (i = 0; i < a.bigi.size && i < b.bigi.size; i++) + if (a.bigi.data[i] != b.bigi.data[i]) return false; + for (; i < a.bigi.size; i++) + if (a.bigi.data[i]) return false; + for (; i < b.bigi.size; i++) + if (b.bigi.data[i]) return false; + return true; + case tRANGE: + return a.lo == b.lo && a.hi == b.hi; + case tSTR: + return !strcmp(a.s, b.s); + case tMATCH: + return a.m.word0 == b.m.word0 && a.m.word1 == b.m.word1; + case tVEC: + case tCMD: + if (a.vec.size != b.vec.size) return false; + for (int i = 0; i < a.vec.size; i++) + if (a.vec.data[i] != b.vec.data[i]) return false; + return true; + case tMAP: + if (a.map.size != b.map.size) return false; + for (int i = 0; i < a.map.size; i++) { + if (a.map.data[i].key != b.map.data[i].key) return false; + if (a.map.data[i].value != b.map.data[i].value) return false; + } + return true; + } + assert(false && "unknown value type"); + return ""; +} +#pragma GCC diagnostic pop diff --git a/backends/tofino/bf-asm/asm-types.h b/backends/tofino/bf-asm/asm-types.h new file mode 100644 index 00000000000..32dccfb91d8 --- /dev/null +++ b/backends/tofino/bf-asm/asm-types.h @@ -0,0 +1,494 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_ASM_TYPES_H_ +#define BF_ASM_ASM_TYPES_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "bfas.h" +#include "json.h" +#include "map.h" +#include "mask_counter.h" +#include "vector.h" + +enum gress_t { INGRESS, EGRESS, GHOST, NUM_GRESS_T }; + +/* All timing related uses combine the INGRESS and GHOST threads (they run in lockstep), so + * we remap GHOST->INGRESS when dealing with timing */ +inline gress_t timing_thread(gress_t gress) { return gress == GHOST ? INGRESS : gress; } +/* imem similarly shares color between INGRESS and GHOST */ +inline gress_t imem_thread(gress_t gress) { return gress == GHOST ? INGRESS : gress; } + +struct match_t { + uint64_t word0, word1; +#ifdef __cplusplus + operator bool() const { return (word0 | word1) != 0; } + bool operator==(const match_t &a) const { return word0 == a.word0 && word1 == a.word1; } + bool matches(uint64_t v) const { + return (v | word1) == word1 && ((~v & word1) | word0) == word0; + } + bool matches(const match_t &v) const { + assert(0); + return false; + } + unsigned dirtcam(unsigned width, unsigned bit); +#endif /* __cplusplus */ +}; + +DECLARE_VECTOR(match_t); + +struct wmatch_t { + bitvec word0, word1; +#ifdef __cplusplus + wmatch_t() = default; + wmatch_t(const wmatch_t &) = default; + wmatch_t(wmatch_t &&) = default; + wmatch_t &operator=(const wmatch_t &) = default; + wmatch_t &operator=(wmatch_t &&) = default; + wmatch_t(const match_t &v) : word0(v.word0), word1(v.word1) {} // NOLINT(runtime/explicit) + wmatch_t(const VECTOR(match_t) & v) { // NOLINT(runtime/explicit) + for (int i = 0; i < v.size; ++i) { + word0.putrange(i * 64, 64, v.data[i].word0); + word1.putrange(i * 64, 64, v.data[i].word1); + } + } + operator bool() const { return word0 || word1; } + bool operator==(const wmatch_t &a) const { return word0 == a.word0 && word1 == a.word1; } + bool matches(bitvec v) const { return (v | word1) == word1 && ((word1 - v) | word0) == word0; } + bool matches(const wmatch_t &v) const { + assert(0); + return false; + } + unsigned dirtcam(unsigned width, unsigned bit); +#endif /* __cplusplus */ +}; + +enum value_type { tINT, tBIGINT, tRANGE, tSTR, tMATCH, tBIGMATCH, tVEC, tMAP, tCMD }; +extern const char *value_type_desc[]; + +struct value_t; +struct pair_t; +#ifdef __cplusplus +DECLARE_VECTOR( + value_t, value_t &operator[](int) const; value_t & back() const; + value_t * begin() const { return data; } value_t * end() const; value_t & front() const; + VECTOR(value_t) & add(value_t &&); VECTOR(value_t) & add(int); + VECTOR(value_t) & add(const char *);) +DECLARE_VECTOR( + pair_t, void push_back(const char *, value_t &&); // NOLINT(whitespace/operators) + pair_t & operator[](int) const; pair_t * operator[](const char *) const; pair_t & back() const; + pair_t * begin() const { return data; } pair_t * end() const; pair_t & front() const;) +#else +DECLARE_VECTOR(value_t) +DECLARE_VECTOR(pair_t) +#endif /* __cplusplus */ +DECLARE_VECTOR(uintptr_t); + +struct value_t { + enum value_type type; + int lineno; + union { + int64_t i; + VECTOR(uintptr_t) bigi; + struct { + int lo; + int hi; + }; + char *s; + match_t m; + VECTOR(match_t) bigm; + VECTOR(value_t) vec; + VECTOR(pair_t) map; + }; +#ifdef __cplusplus + value_t &operator[](int i) const { + assert(type == tVEC || type == tCMD); + return vec[i]; + } + bool startsWith(const char *pfx) const { + if (type == tSTR) return strncmp(s, pfx, strlen(pfx)) == 0; + if (type == tCMD && vec.size > 0 && vec[0].type == tSTR) + return strncmp(vec[0].s, pfx, strlen(pfx)) == 0; + return false; + } + bool checkSize() const { + if (type == tVEC) return (vec.size > 0); + if (type == tMAP) return (map.size > 0); + if (type == tCMD) return (vec.size > 0); + return true; + } +#endif /* __cplusplus */ +}; + +struct pair_t { + struct value_t key, value; +#ifdef __cplusplus + pair_t() = default; + pair_t(const value_t &k, const value_t &v) : key(k), value(v) {} +#endif /* __cplusplus */ +}; + +void free_value(value_t *p); +const char *value_desc(const value_t *v); +static inline void free_pair(pair_t *p) { + free_value(&p->key); + free_value(&p->value); +} +bool get_bool(const value_t &v); + +// If max_bits is zero, no testing or masking is carried out. +// If error_message is set, values larger than max_bits will error, otherwise the value is masked. +bitvec get_bitvec(const value_t &v, unsigned max_bits = 0, const char *error_message = nullptr); +uint64_t get_int64(const value_t &v, unsigned max_bits = 0, const char *error_message = nullptr); + +#ifdef __cplusplus +bool operator==(const struct value_t &, const struct value_t &); +inline bool operator==(const struct value_t &a, const char *b) { + if (a.type == tCMD && a.vec.size > 0 && a[0].type == tSTR) return !strcmp(a[0].s, b); + return a.type == tSTR && !strcmp(a.s, b); +} +inline bool operator==(const char *a, const struct value_t &b) { + if (b.type == tCMD && b.vec.size > 0 && b[0].type == tSTR) return !strcmp(a, b[0].s); + return b.type == tSTR && !strcmp(a, b.s); +} +inline bool operator==(const struct value_t &a, int b) { return a.type == tINT && a.i == b; } +inline bool operator==(int a, const struct value_t &b) { return b.type == tINT && a == b.i; } + +inline const char *value_desc(const value_t &v) { return value_desc(&v); } + +template +inline bool operator!=(A a, B b) { + return !(a == b); +} + +inline value_t &VECTOR(value_t)::operator[](int i) const { + assert(i >= 0 && i < size); + return data[i]; +} +inline pair_t &VECTOR(pair_t)::operator[](int i) const { + assert(i >= 0 && i < size); + return data[i]; +} +inline pair_t *VECTOR(pair_t)::operator[](const char *k) const { + for (int i = 0; i < size; i++) + if (data[i].key == k) return &data[i]; + return 0; +} +inline value_t *VECTOR(value_t)::end() const { return data + size; } +inline value_t &VECTOR(value_t)::front() const { + assert(0 < size); + return data[0]; +} +inline value_t &VECTOR(value_t)::back() const { + assert(0 < size); + return data[size - 1]; +} +inline pair_t *VECTOR(pair_t)::end() const { return data + size; } +inline pair_t &VECTOR(pair_t)::front() const { + assert(0 < size); + return data[0]; +} +inline pair_t &VECTOR(pair_t)::back() const { + assert(0 < size); + return data[size - 1]; +} + +/* can't call VECTOR(pair_t)::push_back directly except from the compilation unit where + * it is defined, due to gcc bug. Workaround via global function */ +extern void push_back(VECTOR(pair_t) & m, const char *s, + value_t &&v); // NOLINT(whitespace/operators) + +inline void fini(value_t &v) { free_value(&v); } +inline void fini(pair_t &p) { free_pair(&p); } +inline void fini(VECTOR(value_t) & v) { + VECTOR_foreach(v, free_value); + VECTOR_fini(v); +} +inline void fini(VECTOR(pair_t) & v) { + VECTOR_foreach(v, free_pair); + VECTOR_fini(v); +} +void collapse_list_of_maps(value_t &, bool singleton_only = false); + +std::unique_ptr toJson(value_t &); +std::unique_ptr toJson(VECTOR(value_t) &); +std::unique_ptr toJson(pair_t &); +std::unique_ptr toJson(VECTOR(pair_t) &); + +#endif /* __cplusplus */ + +#define CHECKTYPE(V, T) \ + ((V).type == (T) || (error((V).lineno, "Syntax error, expecting %s", value_type_desc[T]), 0)) +#define CHECKTYPESIZE(V, T) \ + (CHECKTYPE(V, T) && \ + ((V).checkSize() || (error((V).lineno, "Syntax error, empty %s", value_type_desc[T]), 0))) +#define PCHECKTYPE(P, V, T) \ + (((P) && (V).type == (T)) || \ + (error((V).lineno, "Syntax error, expecting %s", value_type_desc[T]), 0)) +#define CHECKTYPEM(V, T, M) \ + ((V).type == (T) || (error((V).lineno, "Syntax error, expecting %s", M), 0)) +#define CHECKTYPEPM(V, T, P, M) \ + (((V).type == (T) && (P)) || (error((V).lineno, "Syntax error, expecting %s", M), 0)) +#define PCHECKTYPEM(P, V, T, M) \ + (((P) && (V).type == (T)) || (error((V).lineno, "Syntax error, expecting %s", M), 0)) +#define CHECKTYPE2(V, T1, T2) \ + ((V).type == (T1) || (V).type == (T2) || \ + (error((V).lineno, "Syntax error, expecting %s or %s but got %s", value_type_desc[T1], \ + value_type_desc[T2], value_desc(V)), \ + 0)) +#define CHECKTYPE3(V, T1, T2, T3) \ + ((V).type == (T1) || (V).type == (T2) || (V).type == (T3) || \ + (error((V).lineno, "Syntax error, expecting %s or %s or %s", value_type_desc[T1], \ + value_type_desc[T2], value_type_desc[T3]), \ + 0)) +#define PCHECKTYPE2(P, V, T1, T2) \ + (((P) && ((V).type == (T1) || (V).type == (T2))) || \ + (error((V).lineno, "Syntax error, expecting %s or %s", value_type_desc[T1], \ + value_type_desc[T2]), \ + 0)) +#define CHECKTYPE2M(V, T1, T2, M) \ + ((V).type == (T1) || (V).type == (T2) || \ + (error((V).lineno, "Syntax error, expecting %s but got %s", M, value_desc(V)), 0)) +#define PCHECKTYPE2M(P, V, T1, T2, M) \ + (((P) && ((V).type == (T1) || (V).type == (T2))) || \ + (error((V).lineno, "Syntax error, expecting %s", M), 0)) +#define VALIDATE_RANGE(V) \ + ((V).type != tRANGE || (V).lo <= (V).hi || \ + (error((V).lineno, "Invalid range %d..%d", (V).lo, (V).hi), 0)) + +inline value_t *get(VECTOR(pair_t) & map, const char *key) { + for (auto &kv : map) + if (kv.key == key) return &kv.value; + return 0; +} +inline const value_t *get(const VECTOR(pair_t) & map, const char *key) { + for (auto &kv : map) + if (kv.key == key) return &kv.value; + return 0; +} + +#ifdef __cplusplus + +template +inline void parse_vector(std::vector &vec, const VECTOR(value_t) & data) { + for (auto &v : data) vec.emplace_back(v); +} +template <> +inline void parse_vector(std::vector &vec, const VECTOR(value_t) & data) { + for (auto &v : data) + if (CHECKTYPE(v, tINT)) vec.push_back(v.i); +} +template <> +inline void parse_vector(std::vector &vec, const VECTOR(value_t) & data) { + for (auto &v : data) + if (CHECKTYPE(v, tINT)) vec.push_back(v.i); +} +template <> +inline void parse_vector(std::vector &vec, const VECTOR(value_t) & data) { + for (auto &v : data) + if (CHECKTYPE(v, tSTR)) vec.emplace_back(v.s); +} +template +inline void parse_vector(std::vector &vec, const value_t &data) { + if (data.type == tVEC) + parse_vector(vec, data.vec); + else + vec.emplace_back(data); +} +template <> +inline void parse_vector(std::vector &vec, const value_t &data) { + if (CHECKTYPE2(data, tINT, tVEC)) { + if (data.type == tVEC) + parse_vector(vec, data.vec); + else + vec.push_back(data.i); + } +} +template <> +inline void parse_vector(std::vector &vec, const value_t &data) { + if (CHECKTYPE2(data, tINT, tVEC)) { + if (data.type == tVEC) + parse_vector(vec, data.vec); + else + vec.push_back(data.i); + } +} +template <> +inline void parse_vector(std::vector &vec, const value_t &data) { + if (CHECKTYPE2(data, tSTR, tVEC)) { + if (data.type == tVEC) + parse_vector(vec, data.vec); + else + vec.push_back(data.s); + } +} + +std::ostream &operator<<(std::ostream &out, match_t m); +void print_match(FILE *fp, match_t m); + +inline std::ostream &operator<<(std::ostream &out, gress_t gress) { + switch (gress) { + case INGRESS: + out << "ingress"; + break; + case EGRESS: + out << "egress"; + break; + case GHOST: + out << "ghost"; + break; + default: + out << "(invalid gress " << static_cast(gress) << ")"; + } + return out; +} + +template +inline std::string to_string(T val) { + std::stringstream tmp; + tmp << val; + return tmp.str(); +} + +class MapIterChecked { + /* Iterate through a map (VECTOR(pair_t)), giving errors for non-string and + * duplicate keys (and skipping them) */ + const VECTOR(pair_t) & map; + bool allow; // allow non-string keys + std::set duplicates_allowed; + std::map keys_seen; + class iter { + MapIterChecked *self; + pair_t *p; + void check() { + while (p != self->map.end()) { + if (self->allow && p->key.type != tSTR) break; + if (!CHECKTYPE(p->key, tSTR)) { + p++; + continue; + } + if (self->duplicates_allowed.count(p->key.s)) break; + if (self->keys_seen.count(p->key.s)) { + error(p->key.lineno, "Duplicate element %s", p->key.s); + warning(self->keys_seen[p->key.s], "previous element %s", p->key.s); + p++; + continue; + } + self->keys_seen[p->key.s] = p->key.lineno; + break; + } + } + + public: + iter(MapIterChecked *s, pair_t *p_) : self(s), p(p_) { check(); } + pair_t &operator*() const { return *p; } + pair_t *operator->() const { return p; } + bool operator==(iter &a) const { return p == a.p; } + iter &operator++() { + p++; + check(); + return *this; + } + }; + + public: + explicit MapIterChecked(const VECTOR(pair_t) & map_, bool o = false, + const std::set &dup = {}) + : map(map_), allow(o), duplicates_allowed(dup) {} + MapIterChecked(const VECTOR(pair_t) & map_, const std::set &dup) + : map(map_), allow(false), duplicates_allowed(dup) {} + iter begin() { return iter(this, map.begin()); } + iter end() { return iter(this, map.end()); } +}; + +class MatchIter { + /* Iterate through the integers that match a match_t */ + match_t m; + class iter : public MaskCounter { + MatchIter *self; + + public: + explicit iter(MatchIter *s) : MaskCounter(s->m.word0 & s->m.word1), self(s) { + if (!(self->m.word1 | self->m.word0)) overflow(); + } + unsigned operator*() const { + return this->operator unsigned() | (self->m.word1 & ~self->m.word0); + } + iter &end() { + overflow(); + return *this; + } + }; + + public: + explicit MatchIter(match_t m_) : m(m_) {} + iter begin() { return iter(this); } + iter end() { return iter(this).end(); } +}; + +class SrcInfo { + int lineno; + friend std::ostream &operator<<(std::ostream &, const SrcInfo &); + + public: + explicit SrcInfo(int l) : lineno(l) {} +}; + +struct RegisterSetBase { + virtual ~RegisterSetBase() = default; +}; + +struct ParserRegisterSet : public RegisterSetBase {}; + +/// An interface for parsing a section of a .bfa file +class Parsable { + public: + /// @param data entire map/sequence of elements + virtual void input(VECTOR(value_t) args, value_t data) = 0; + virtual ~Parsable() = default; +}; + +/// An interface for writing into registers +class Configurable { + public: + virtual void write_config(RegisterSetBase ®s, json::map &json, bool legacy = true) = 0; + virtual ~Configurable() = default; +}; + +/// An interface for generating context.json +class Contextable { + public: + virtual void output(json::map &ctxtJson) = 0; + virtual ~Contextable() = default; +}; + +#endif /* __cplusplus */ + +#endif /* BF_ASM_ASM_TYPES_H_ */ diff --git a/backends/tofino/bf-asm/atcam_match.cpp b/backends/tofino/bf-asm/atcam_match.cpp new file mode 100644 index 00000000000..533487772e3 --- /dev/null +++ b/backends/tofino/bf-asm/atcam_match.cpp @@ -0,0 +1,558 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "action_bus.h" +#include "algorithm.h" +#include "hex.h" +#include "input_xbar.h" +#include "instruction.h" +#include "misc.h" +#include "stage.h" +#include "tables.h" + +void AlgTcamMatchTable::setup(VECTOR(pair_t) & data) { + common_init_setup(data, false, P4Table::MatchEntry); + for (auto &kv : MapIterChecked(data, {"meter", "stats", "stateful"})) { + if (common_setup(kv, data, P4Table::MatchEntry)) { + } else if (kv.key == "number_partitions") { + if (CHECKTYPE(kv.value, tINT)) number_partitions = kv.value.i; + } else if (kv.key == "partition_field_name") { + if (CHECKTYPE(kv.value, tSTR)) { + partition_field_name = kv.value.s; + if (auto *p = find_p4_param(partition_field_name)) + if (!p->key_name.empty()) partition_field_name = p->key_name; + } + } else if (kv.key == "subtrees_per_partition") { + if (CHECKTYPE(kv.value, tINT)) max_subtrees_per_partition = kv.value.i; + } else if (kv.key == "bins_per_partition") { + if (CHECKTYPE(kv.value, tINT)) bins_per_partition = kv.value.i; + } else if (kv.key == "atcam_subset_width") { + if (CHECKTYPE(kv.value, tINT)) atcam_subset_width = kv.value.i; + } else if (kv.key == "shift_granularity") { + if (CHECKTYPE(kv.value, tINT)) shift_granularity = kv.value.i; + } else if (kv.key == "search_bus" || kv.key == "result_bus") { + // already dealt with in Table::setup_layout via common_init_setup + } else { + common_sram_setup(kv, data); + } + } + common_sram_checks(); +} + +// TODO: This could probably be rewritten in a simpler way. Below +// function checks the ways extracted from assembly for atcam and assumes the +// way no's are not sorted with column priority. Therefore the code sorts the +// first ram column and sets the column priority based on this column. Then this +// ordering is used to check if column priority is maintained if the ways are +// traversed in this column priority order for all other columns +void AlgTcamMatchTable::setup_column_priority() { + int no_ways = ways.size(); + int no_entries_per_way = ways[0].rams.size(); + // FIXME-P4C: Ideally RAM's 6 & 7 can be on both left and right RAM Units. + // Brig currently does not support this behavior and RAM 6 is always on + // left, while RAM 7 on right. Once this supported is added below function + // must be modified accordingly to accommodate these rams in lrams and rrams + // and the traversal mechanism must be changed to determine column priority + std::set lrams = {2, 3, 4, 5, 6}; + std::set rrams = {7, 8, 9, 10, 11}; + // Check if column is on left(0) or right(1) RAMs + + std::vector> first_entry_priority; + // Determine the side and which way corresponds to which column + int side = -1; + for (int w = 0; w < no_ways; w++) { + int col = ways[w].rams[0].col; + int row = ways[w].rams[0].row; + if (side == 0) { + if (lrams.find(col) == lrams.end()) { + error(lineno, + "ram(%d, %d) is not on correct side compared to rest in column " + "priority", + row, col); + } + } else if (side == 1) { + if (rrams.find(col) == rrams.end()) { + error(lineno, + "ram(%d, %d) is not on correct side compare to rest of column " + "priority", + row, col); + } + } else if (lrams.find(col) != lrams.end()) { + side = 0; + } else if (rrams.find(col) != rrams.end()) { + side = 1; + } else { + error(lineno, "ram(%d, %d) invalid for ATCAM", row, col); + } + first_entry_priority.push_back(std::make_pair(w, col)); + } + + // Sort ways based on column priority for first column + std::sort(first_entry_priority.begin(), first_entry_priority.end(), + [side](const std::pair &a, const std::pair &b) { + return side == 0 ? a.second < b.second : a.second > b.second; + }); + + int index = 0; + for (auto &entry : first_entry_priority) { + col_priority_way[index] = entry.first; + index++; + } + + // Ensure that the remaining columns match up with the first column ram + for (int i = 1; i < no_entries_per_way; i++) { + auto way_it = col_priority_way.begin(); + side = -1; + int prev_col = -1; + int prev_row = -1; + while (way_it != col_priority_way.end()) { + int row = ways[way_it->second].rams[i].row; + int col = ways[way_it->second].rams[i].col; + if (way_it != col_priority_way.begin()) { + if (!(((side == 0 && prev_col < col && lrams.find(col) != lrams.end()) || + (side == 1 && prev_col > col && rrams.find(col) != rrams.end())) && + prev_row == row)) { + error(lineno, + "ram(%d, %d) and ram(%d, %d) column priority is not " + "compatible", + prev_row, prev_col, row, col); + } + } + way_it++; + prev_col = col; + prev_row = row; + if (lrams.find(col) != lrams.end()) + side = 0; + else if (rrams.find(col) != rrams.end()) + side = 1; + else + error(lineno, "ram(%d, %d) invalid for ATCAM", row, col); + } + } +} + +/** + * Guarantees that the order of the entries provided in the ATCAM table format are order + * in HW priority 0-4, (where in HW entry 4 will be favored). This is required to guarantee that + * the entries in the ATCAM pack format are in priority order for the driver. + * + * @seealso bf-p4c/mau/table_format.cpp - no_overhead_atcam_result_bus_words + */ +void AlgTcamMatchTable::verify_entry_priority() { + int result_bus_word = -1; + for (int i = 0; i < static_cast(group_info.size()); i++) { + BUG_CHECK(group_info[i].result_bus_word >= 0); + if (result_bus_word == -1) { + result_bus_word = group_info[i].result_bus_word; + } else if (result_bus_word != group_info[i].result_bus_word) { + error(format->lineno, "ATCAM tables can at most have only one overhead word"); + return; + } + auto mg_it = group_info[i].match_group.find(result_bus_word); + if (mg_it == group_info[i].match_group.end() || mg_it->second != i) { + error(format->lineno, + "Each ATCAM entry must coordinate its entry with the " + "correct priority"); + return; + } + } + + if (word_info[result_bus_word].size() != group_info.size()) { + error(format->lineno, "ATCAM tables do not chain to the same overhead word"); + return; + } + + for (int i = 0; i < static_cast(word_info[result_bus_word].size()); i++) { + if (i != word_info[result_bus_word][i]) { + error(format->lineno, "ATCAM priority not correctly formatted in the compiler"); + return; + } + } +} + +/** + * @seealso bf-p4c/mau/table_format.cpp - no_overhead_atcam_result_bus_words. This matches + * this function exactly + */ +void AlgTcamMatchTable::no_overhead_determine_result_bus_usage() { + int result_bus_word = -1; + int shared_groups = 0; + for (int i = group_info.size() - 1; i >= 0; i--) { + if (result_bus_word == -1) { + result_bus_word = group_info[i].match_group.begin()->first; + } + bool is_shared_group = false; + + if (group_info[i].match_group.size() > 1) + is_shared_group = true; + else if (group_info[i].match_group.begin()->first != result_bus_word) + is_shared_group = true; + + if (is_shared_group) { + if (i > 1) error(format->lineno, "ATCAM chaining of shared groups is not correct"); + shared_groups++; + } + + group_info[i].result_bus_word = result_bus_word; + group_info[i].match_group[result_bus_word] = i; + } + + word_info[result_bus_word].clear(); + for (int i = 0; i < static_cast(group_info.size()); i++) { + word_info[result_bus_word].push_back(i); + } + + if (shared_groups > 2) + error(format->lineno, "ATCAM cannot safely send hit signals to same result bus"); +} + +void AlgTcamMatchTable::verify_format(Target::Tofino targ) { + SRamMatchTable::verify_format(targ); + if (!error_count) verify_entry_priority(); +} + +void AlgTcamMatchTable::pass1() { + LOG1("### ATCAM match table " << name() << " pass1 " << loc()); + SRamMatchTable::pass1(); + if (format) { + setup_column_priority(); + find_tcam_match(); + } +} + +void AlgTcamMatchTable::setup_nibble_mask(Table::Format::Field *match, int group, + std::map &elems, bitvec &mask) { + for (auto &el : Values(elems)) { + int bit = match->bit(el.offset); + if (match->hi(bit) < bit + el.width - 1) + error(el.field->lineno, "match bits for %s not contiguous in match(%d)", + el.field->desc().c_str(), group); + // Determining the nibbles dedicated to s0q1 or s1q0 + int start_bit = bit; + int end_bit = start_bit + el.width - 1; + int start_nibble = start_bit / 4U; + int end_nibble = end_bit / 4U; + mask.setrange(start_nibble, end_nibble - start_nibble + 1); + } +} + +void AlgTcamMatchTable::find_tcam_match() { + std::map exact; + std::map> tcam; + unsigned off = 0; + /* go through the match fields and find duplicates -- those are the tcam matches */ + for (auto match_field : match) { + auto phv_p = dynamic_cast(match_field); + if (phv_p == nullptr) { + BUG(); + continue; + } + auto phv_ref = *phv_p; + auto sl = *phv_ref; + if (!sl) continue; + if (exact.count(sl)) { + if (tcam.count(sl)) + error(phv_ref.lineno, "%s appears more than twice in atcam match", + phv_ref.desc().c_str()); + if ((sl.size() % 4U) != 0) { + if ((sl.size() == 1) && (phv_ref.desc().find("$valid") != std::string::npos)) { + } else + warning(phv_ref.lineno, "tcam match field %s not a multiple of 4 bits", + phv_ref.desc().c_str()); + } + tcam.emplace(sl, std::make_pair(exact.at(sl), + match_element{new Phv::Ref(phv_ref), off, sl->size()})); + exact.erase(sl); + } else { + exact.emplace(sl, match_element{new Phv::Ref(phv_ref), off, sl->size()}); + } + off += sl.size(); + } + for (auto e : exact) + for (auto t : tcam) + if (e.first.overlaps(t.first)) + error(e.second.field->lineno, "%s overlaps %s in atcam match", + e.second.field->desc().c_str(), t.second.first.field->desc().c_str()); + if (error_count > 0) return; + + /* for the tcam pairs, treat first as s0q1 and second as s1q0 */ + for (auto &el : Values(tcam)) { + s0q1[el.first.offset] = el.first; + s1q0[el.second.offset] = el.second; + } + /* now find the bits in each group that match with the tcam pairs, ensure that they + * are nibble-aligned, and setup the nibble masks */ + for (unsigned i = 0; i < format->groups(); i++) { + if (Format::Field *match = format->field("match", i)) { + setup_nibble_mask(match, i, s0q1, s0q1_nibbles); + setup_nibble_mask(match, i, s1q0, s1q0_nibbles); + if (!(s0q1_nibbles & s1q0_nibbles).empty()) + error(format->lineno, "Cannot determine if a ternary nibble is s0q1 or s1q0"); + } else { + error(format->lineno, "no 'match' field in format group %d", i); + } + } +} + +void AlgTcamMatchTable::pass2() { + LOG1("### ATCAM match table " << name() << " pass2 " << loc()); + if (logical_id < 0) choose_logical_id(); + for (auto &ixb : input_xbar) ixb->pass2(); + setup_word_ixbar_group(); + ixbar_subgroup.resize(word_ixbar_group.size()); + ixbar_mask.resize(word_ixbar_group.size()); + // FIXME -- need a method of specifying these things in the asm code? + // FIXME -- should at least check that these are sane + for (unsigned i = 0; i < word_ixbar_group.size(); ++i) { + if (word_ixbar_group[i] < 0) { + // Word with no match data, only version/valid; used for direct lookup + // tables -- can it happen with an atcam table? + continue; + } + BUG_CHECK(input_xbar.size() == 1, "%s does not have one input xbar", name()); + bitvec ixbar_use = input_xbar[0]->hash_group_bituse(word_ixbar_group[i]); + // Which 10-bit address group to use for this word -- use the lowest one with + // a bit set in the hash group. Can it be different for different words? + ixbar_subgroup[i] = ixbar_use.min().index() / EXACT_HASH_ADR_BITS; + // Assume that any hash bits usuable for select are used for select + ixbar_mask[i] = ixbar_use.getrange(EXACT_HASH_FIRST_SELECT_BIT, EXACT_HASH_SELECT_BITS); + } + if (actions) actions->pass2(this); + if (action_bus) action_bus->pass2(this); + if (gateway) gateway->pass2(); + if (idletime) idletime->pass2(); + if (format) format->pass2(this); + for (auto &hd : hash_dist) hd.pass2(this); +} + +void AlgTcamMatchTable::pass3() { + LOG1("### ATCAM match table " << name() << " pass3 " << loc()); + SRamMatchTable::pass3(); + if (action_bus) action_bus->pass3(this); +} + +template +void AlgTcamMatchTable::write_regs_vt(REGS ®s) { + LOG1("### ATCAM match table " << name() << " write_regs " << loc()); + SRamMatchTable::write_regs(regs); + + for (auto &row : layout) { + auto &rams_row = regs.rams.array.row[row.row]; + for (auto &ram : row.memunits) { + auto &way = way_map[ram]; + BUG_CHECK(ram.stage == INT_MIN && ram.row == row.row, "bogus %s in row %d", ram.desc(), + row.row); + auto &ram_cfg = rams_row.ram[ram.col]; + ram_cfg.match_nibble_s0q1_enable = version_nibble_mask.getrange(way.word * 32U, 32) & + ~s1q0_nibbles.getrange(way.word * 32U, 32); + ram_cfg.match_nibble_s1q0_enable = + 0xffffffffUL & ~s0q1_nibbles.getrange(way.word * 32U, 32); + } + } +} + +std::unique_ptr AlgTcamMatchTable::gen_memory_resource_allocation_tbl_cfg() const { + if (col_priority_way.size() == 0) + error(lineno, "No column priority determined for table %s", name()); + unsigned fmt_width = format ? (format->size + 127) / 128 : 0; + json::vector mras; + for (auto &entry : col_priority_way) { + json::map mra; + mra["column_priority"] = entry.first; + json::vector mem_units; + json::vector &mem_units_and_vpns = mra["memory_units_and_vpns"] = json::vector(); + auto &way = ways[entry.second]; + unsigned vpn_ctr = 0; + for (auto &ram : way.rams) { + if (mem_units.empty()) + vpn_ctr = layout_get_vpn(ram); + else + BUG_CHECK(vpn_ctr == layout_get_vpn(ram)); + mem_units.push_back(json_memunit(ram)); + if (mem_units.size() == fmt_width) { + json::map tmp; + tmp["memory_units"] = std::move(mem_units); + mem_units = json::vector(); + json::vector vpns; + // Because the entries in the context JSON are reversed, the VPNs have to + // be reversed as well + for (unsigned i = 0; i < format->groups(); i++) { + vpns.push_back(vpn_ctr + format->groups() - 1 - i); + } + vpn_ctr += format->groups(); + tmp["vpns"] = std::move(vpns); + mem_units_and_vpns.push_back(std::move(tmp)); + } + } + BUG_CHECK(mem_units.empty()); + mras.push_back(std::move(mra)); + } + return json::mkuniq(std::move(mras)); +} + +std::string AlgTcamMatchTable::get_match_mode(const Phv::Ref &pref, int offset) const { + for (auto &p : s0q1) { + if ((p.first == offset) && (*p.second.field == pref)) return "s0q1"; + } + for (auto &p : s1q0) { + if ((p.first == offset) && (*p.second.field == pref)) return "s1q0"; + } + return "unused"; +} + +void AlgTcamMatchTable::gen_unit_cfg(json::vector &units, int size) const { + json::map tbl; + tbl["direction"] = P4Table::direction_name(gress); + tbl["handle"] = + p4_table ? is_alpm() ? p4_table->get_alpm_atcam_table_handle() : p4_table->get_handle() : 0; + tbl["name"] = name(); + tbl["size"] = size; + tbl["table_type"] = "match"; + json::map &stage_tbl = + *add_common_sram_tbl_cfgs(tbl, "algorithmic_tcam_unit", "algorithmic_tcam_match"); + // Assuming atcam next hit table cannot be multiple tables + stage_tbl["default_next_table"] = + !hit_next.empty() ? hit_next[0].next_table_id() : Target::END_OF_PIPE(); + stage_tbl["memory_resource_allocation"] = gen_memory_resource_allocation_tbl_cfg(); + // Hash functions not necessary currently for ATCAM matches, as the result comes from + // the partition_field_name + stage_tbl["hash_functions"] = json::vector(); + add_pack_format(stage_tbl, format.get(), false); + units.push_back(std::move(tbl)); +} + +bool AlgTcamMatchTable::has_directly_attached_synth2port() const { + auto mt = this; + if (auto a = mt->get_attached()) { + if (a->selector && is_directly_referenced(a->selector)) return true; + for (auto &m : a->meters) { + if (is_directly_referenced(m)) return true; + } + for (auto &s : a->stats) { + if (is_directly_referenced(s)) return true; + } + for (auto &s : a->statefuls) { + if (is_directly_referenced(s)) return true; + } + } + return false; +} + +void AlgTcamMatchTable::gen_alpm_cfg(json::map &tbl) const { + tbl["default_action_handle"] = get_default_action_handle(); + tbl["action_profile"] = action_profile(); + // FIXME -- setting next_table_mask unconditionally only works because we process the + // stage table in stage order (so we'll end up with the value from the last stage table, + // which is what we want.) Should we check in case the ordering ever changes? + tbl["default_next_table_mask"] = next_table_adr_mask; + // FIXME -- the driver currently always assumes this is 0, so we arrange for it to be + // when choosing the action encoding. But we should be able to choose something else + tbl["default_next_table_default"] = 0; + // FIXME-JSON: PD related, check glass examples for false (ALPM) + tbl["is_resource_controllable"] = true; + tbl["uses_range"] = false; + if (p4_table && p4_table->disable_atomic_modify) tbl["disable_atomic_modify"] = true; + tbl["ap_bind_indirect_res_to_match"] = json::vector(); + tbl["static_entries"] = json::vector(); + if (context_json) { + add_json_node_to_table(tbl, "ap_bind_indirect_res_to_match"); + } + LOG1("populate alpm " << name()); + // FIXME-DRIVER + // 'actions' and 'table_refs' on the alpm are redundant as they are + // already present in the atcam table. These should probably be cleaned + // up from the context json and driver parsing. + if (actions) { + actions->gen_tbl_cfg(tbl["actions"]); + } else if (action && action->actions) { + action->actions->gen_tbl_cfg(tbl["actions"]); + } + add_all_reference_tables(tbl); + json::map &alpm_match_attributes = tbl["match_attributes"]; + alpm_match_attributes["max_subtrees_per_partition"] = max_subtrees_per_partition; + alpm_match_attributes["partition_field_name"] = get_partition_field_name(); + alpm_match_attributes["lpm_field_name"] = get_lpm_field_name(); + alpm_match_attributes["bins_per_partition"] = bins_per_partition; + alpm_match_attributes["atcam_subset_width"] = atcam_subset_width; + alpm_match_attributes["shift_granularity"] = shift_granularity; + if (context_json) { + add_json_node_to_table(alpm_match_attributes, "excluded_field_msb_bits"); + } + auto pa_hdl = get_partition_action_handle(); + // Throw an error if partition action handle is not set. The alpm + // pre-classifier should have a single action which sets the partition + // handle. If no handle is present, it is either not generated by the + // compiler or assembler is not able to find it within actions. In + // either case this is a problem as driver will error out + if (pa_hdl.empty()) + error(lineno, "Cannot find partition action handle for ALPM table %s", name()); + // backward-compatible mode + if (pa_hdl.size() == 1) { + alpm_match_attributes["set_partition_action_handle"] = *pa_hdl.begin(); + } else { + json::vector &action_handles = alpm_match_attributes["set_partition_action_handle"] = + json::vector(); + for (auto hdl : pa_hdl) action_handles.push_back(hdl); + } + alpm_match_attributes["stage_tables"] = json::vector(); +} + +void AlgTcamMatchTable::gen_tbl_cfg(json::vector &out) const { + json::map *atcam_tbl_ptr; + unsigned number_entries = get_number_entries(); + if (is_alpm()) { + // Add ALPM ATCAM config to ALPM table (generated by pre-classifier in + // previous ostage) + json::map *alpm_tbl_ptr = base_tbl_cfg(out, "match", number_entries); + if (!alpm_tbl_ptr) { + error(lineno, "No alpm table generated by alpm pre-classifier"); + return; + } + json::map &alpm_tbl = *alpm_tbl_ptr; + gen_alpm_cfg(alpm_tbl); + json::map &alpm_match_attributes = alpm_tbl["match_attributes"]; + json::map &atcam_tbl = alpm_match_attributes["atcam_table"]; + base_alpm_atcam_tbl_cfg(atcam_tbl, "match", number_entries); + atcam_tbl_ptr = &atcam_tbl; + } else { + atcam_tbl_ptr = base_tbl_cfg(out, "match", number_entries); + } + json::map &tbl = *atcam_tbl_ptr; + common_tbl_cfg(tbl); + json::map &match_attributes = tbl["match_attributes"]; + match_attributes["match_type"] = "algorithmic_tcam"; + if (actions) { + actions->gen_tbl_cfg(tbl["actions"]); + } else if (action && action->actions) { + action->actions->gen_tbl_cfg(tbl["actions"]); + } + json::vector &units = match_attributes["units"]; + gen_unit_cfg(units, number_entries); + match_attributes["number_partitions"] = number_partitions; + match_attributes["partition_field_name"] = partition_field_name; + add_all_reference_tables(tbl); + if (units.size() > 1 && has_directly_attached_synth2port()) + error(lineno, + "The ability to split directly addressed counters/meters/stateful " + "resources across multiple logical tables of an algorithmic tcam match table " + "is not currently supported."); + // Empty stage table node in atcam. These are moved inside the + // units->MatchTable->stage_table node + match_attributes["stage_tables"] = json::vector(); +} + +DEFINE_TABLE_TYPE(AlgTcamMatchTable) diff --git a/backends/tofino/bf-asm/attached_table.cpp b/backends/tofino/bf-asm/attached_table.cpp new file mode 100644 index 00000000000..049c1d88b0e --- /dev/null +++ b/backends/tofino/bf-asm/attached_table.cpp @@ -0,0 +1,525 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include + +#include "action_bus.h" +#include "algorithm.h" +#include "input_xbar.h" +#include "instruction.h" +#include "misc.h" +#include "stage.h" +#include "tables.h" + +void AttachedTable::pass1() { + if (default_action.empty()) default_action = get_default_action(); + // Per Flow Enable - Validate and Set pfe and address bits + if (per_flow_enable_param == "false") per_flow_enable = false; + + if (!Target::SUPPORT_OVERFLOW_BUS() && stage->overflow_bus_use[7]) + error(layout[0].lineno, "table %s, %s has no overflow bus between logical row 7 and 8", + name(), Target::name()); +} + +unsigned AttachedTable::per_flow_enable_bit(MatchTable *m) const { + if (!per_flow_enable || per_flow_enable_param.empty()) return 0; + unsigned pfe_bit = 0; + if (m) { + auto addr = m->find_address_field(this); + auto address_bits = addr ? addr->size : 0; + if (auto f = m->lookup_field(per_flow_enable_param)) { + // Get pfe bit position from format entry + // This value is then adjusted based on address + if (f->size == 1) + pfe_bit = f->bit(0); + else + error(lineno, "pfe bit %s is not a 1 bit in table %s format", + per_flow_enable_param.c_str(), m->name()); + if (addr) + pfe_bit -= addr->bit(0); + else + pfe_bit = 0; // we use the primary shift to get at the pfe bit + } else if (per_flow_enable_param == "true" && addr) { + pfe_bit = addr->bit(addr->size - 1) - addr->bit(0) + default_pfe_adjust(); + } else { + // FIXME -- should be an error, but the compiler can hit this for a shared attached + // table that is defaulted in one match table and in the overhead in another. We + // should no longer be generating code that tries to set per_flow_enable: in the + // attached table (it should be in the call in the match table) at all, but we still + // have issues? Comments in the compiler indicate those should go away + // and this can be an error again. + warning(lineno, "can't find per_flow_enable param %s in format for %s", + per_flow_enable_param.c_str(), m->name()); + } + } else { + for (auto mt : match_tables) { + auto bit = per_flow_enable_bit(mt); + if (bit && pfe_bit && bit != pfe_bit) { + // this should be ok, but the driver can't handle it currently + warning(lineno, + "pfe_bit %s at different locations in different match tables," + " which will cause driver problems", + per_flow_enable_param.c_str()); + } else { + pfe_bit = bit; + } + } + } + return pfe_bit; +} + +// --------------- +// Meter ALU | Row +// Used | +// --------------- +// 0 | 1 +// 1 | 3 +// 2 | 5 +// 3 | 7 +// --------------- +void AttachedTable::add_alu_index(json::map &stage_tbl, std::string alu_index) const { + if (layout.size() <= 0) + error(lineno, "Invalid meter alu setup. A meter ALU should be allocated for table %s", + name()); + stage_tbl[alu_index] = get_alu_index(); +} + +SelectionTable *AttachedTable::get_selector() const { + SelectionTable *rv = nullptr; + for (auto *mtab : match_tables) { + auto *sel = mtab->get_selector(); + if (sel && rv && rv != sel) return nullptr; // inconsistent + if (sel) rv = sel; + } + return rv; +} + +SelectionTable *AttachedTables::get_selector() const { + if (selector) return dynamic_cast(static_cast
(selector)); + return nullptr; +} + +StatefulTable *AttachedTable::get_stateful() const { + StatefulTable *rv = nullptr; + for (auto *mtab : match_tables) { + auto *s = mtab->get_stateful(); + if (s && rv && rv != s) return nullptr; // inconsistent + if (s) rv = s; + } + return rv; +} + +StatefulTable *AttachedTables::get_stateful(std::string name) const { + for (auto &s : statefuls) { + if (name == s->name() || name.empty()) + return dynamic_cast(static_cast
(s)); + } + return nullptr; +} + +MeterTable *AttachedTable::get_meter() const { + MeterTable *rv = nullptr; + for (auto *mtab : match_tables) { + auto *m = mtab->get_meter(); + if (m && rv && rv != m) return nullptr; // inconsistent + if (m) rv = m; + } + return rv; +} + +MeterTable *AttachedTables::get_meter(std::string name) const { + for (auto &s : meters) { + if (name == s->name() || name.empty()) + return dynamic_cast(static_cast
(s)); + } + return nullptr; +} + +Table::Format::Field *AttachedTables::find_address_field(const AttachedTable *tbl) const { + if (selector == tbl && selector.args.size() > 0) return selector.args.at(0).field(); + for (auto &s : stats) + if (s == tbl && s.args.size() > 0) return s.args.at(0).field(); + for (auto &m : meters) + if (m == tbl && m.args.size() > 0) return m.args.at(0).field(); + for (auto &s : statefuls) + if (s == tbl) { + if (s.args.size() > 1) { + return s.args.at(1).field(); + } else if (s.args.size() > 0) { + // this special case is a hack in case we're calling this before + // pass1 has run on the match table with these attached tables + auto *f = s.args.at(0).field(); + if (f && f->size > 3) return f; + } + } + return nullptr; +} + +bool AttachedTables::run_at_eop() { + if (meters.size() > 0) return true; + for (auto &s : stats) + if (s->run_at_eop()) return true; + return false; +} + +bitvec AttachedTables::compute_reachable_tables() const { + bitvec rv; + if (selector) rv |= selector->reachable_tables(); + if (selector_length) rv |= selector->reachable_tables(); + for (auto &t : stats) rv |= t->reachable_tables(); + for (auto &t : meters) rv |= t->reachable_tables(); + for (auto &t : statefuls) rv |= t->reachable_tables(); + return rv; +} + +unsigned AttachedTable::determine_meter_shiftcount(Table::Call &call, int group, int word, + int tcam_shift) const { + if (call.args[0].name() && strcmp(call.args[0].name(), "$DIRECT") == 0) { + return direct_shiftcount() + tcam_shift; + } else if (auto f = call.args[0].field()) { + BUG_CHECK(int(f->by_group[group]->bit(0) / 128U) == word); + return f->by_group[group]->bit(0) % 128U + indirect_shiftcount(); + } else if (auto f = call.args[1].field()) { + return f->by_group[group]->bit(0) % 128U + METER_ADDRESS_ZERO_PAD; + } else if (auto f = call.args[2].field()) { + return f->by_group[group]->bit(0) % 128U + METER_ADDRESS_ZERO_PAD; + } else { + return 0; + } +} + +/** + * In match merge, addresses are generated from result buses containing match overhead. + * These buses (83 bits = 64 bits of RAM line + 19 bits of direct address) are sent through + * format and merge to potentially generate addresses for meters, counters, action data, + * etc. + * + * The addresses for meter/selector/stateful alu, counter, idletime, and action data + * have very similar setups, and will described in the section below. But generally + * the address can be formulated in 3 steps. + * + * 1. The 83 bit bus is right shifted to get the bits corresponding to the address. + * 2. This value is ANDed with a mask to pull only the relevant bits + * 3. The value is ORed with a default register to enable certain bits + * + * This is commonly referred to as shift-mask-default, and will happen for all of + * these addresses if necessary. + * + * The addresses are built up of 2 or 3 general pieces. + * + * 1. The RAM line location - which RAM/RAM line to look up the address. This will + * potentially contain a RAM line, a VPN, and Huffman bits. + * 2. A per flow enable bit - a bit to enable the associated table to run or not + * 3. A meter type - Specifically only for the meter_adr users (selectors, stateful, + * meter). Will indicate to the meter alu what particular instruction to run. + * + * The following portion will describe the registers required to build these addresses: + * + * 1. *_payload_shifter_en - will enable the address to be generated if set to true, i.e. + * if a match table does not have a counter, then the associated stats_payload_shifter_en + * will not be enabled. + * + * 2. *_exact/_tcam_shiftcount - the right shift per tind/exact match result bus. + * Addresses themselves can have a certain number of bits appended to the lsb, so + * the number of appended bits has to appear in the shiftcount + * + * 3. *_mask - the post shift AND mask of the relevant address bits from match overhead + * + * 4. *_default - the post mask OR value. Potentially useful for per flow enable bits/ + * meter types that are identical for every action + * + * 5. *_per_entry_mux_ctl - the post shift position of the per flow enable bit, if that + * bit is contained in overhead. This is always ORed in, separate from default + * + * 6. _type_position - only relevant for meter address users. This is the lsb of the + * meter type position if the meter position is in overhead. Note that if this register + * is used, then the meter type must be included in the mask. + * + * The purpose of the function of the determine_merge_regs is to look at the arguments of the + * call for an attached table, and use those to determine the values of these registers. + */ +void AttachedTable::determine_meter_merge_regs(MatchTable *match, int type, int bus, + const std::vector &args, + METER_ACCESS_TYPE default_type, unsigned &adr_mask, + unsigned &per_entry_en_mux_ctl, + unsigned &adr_default, + unsigned &meter_type_position) { + adr_mask = 0; + per_entry_en_mux_ctl = 0; + adr_default = 0; + meter_type_position = 0; + + int max_ptr_bits = EXACT_VPN_BITS + EXACT_WORD_BITS; + if (match->to()) max_ptr_bits = TCAM_VPN_BITS + TCAM_WORD_BITS; + + unsigned max_address = (1U << METER_ADDRESS_BITS) - 1; + BUG_CHECK((args.size() == 2 && default_type == METER_COLOR_ACCESS) || args.size() == 3, + "wrong size for meter args"); + if (args[0] == "$DIRECT") { + adr_mask |= (((1U << max_ptr_bits) - 1) << address_shift()) & max_address; + } else if (auto addr = args[0].field()) { + adr_mask |= (((1U << addr->size) - 1) << address_shift()) & max_address; + } + + if (args[1].name() && strcmp(args[1].name(), "$DEFAULT") == 0) { + adr_default |= (1 << METER_PER_FLOW_ENABLE_START_BIT); + } else if (auto pfe_field = args[1].field()) { + if (auto addr_field = args[0].field()) { + per_entry_en_mux_ctl = pfe_field->bit(0) - addr_field->bit(0) + address_shift(); + } else if (args[0].hash_dist() || args[0].count_mode()) { + per_entry_en_mux_ctl = 0; + } + } + + if (default_type == METER_COLOR_ACCESS) { + // meter color access -- has no meter type + } else if (args[2].name() && strcmp(args[2].name(), "$DEFAULT") == 0) { + adr_default |= default_type << METER_TYPE_START_BIT; + } else if (auto type_field = args[2].field()) { + if (auto addr_field = args[0].field()) { + meter_type_position = type_field->bit(0) - addr_field->bit(0) + address_shift(); + } else if (args[0].hash_dist() || args[0].count_mode()) { + if (auto pfe_field = args[1].field()) { + meter_type_position = type_field->bit(0) - pfe_field->bit(0); + } + } else { + meter_type_position = 0; + } + adr_mask |= ((1 << METER_TYPE_BITS) - 1) << METER_TYPE_START_BIT; + } +} + +const Table::Call *AttachedTables::get_call(const Table *tbl) const { + if (selector == tbl) return &selector; + for (auto &s : stats) + if (s == tbl) return &s; + for (auto &m : meters) + if (m == tbl) return &m; + for (auto &s : statefuls) + if (s == tbl) return &s; + return nullptr; +} + +/** + * Currently a call for an attached table (currently for counters/meters/stateful alus/selectors) + * is built up of a 2 part address/3 part address consisting of 3 parameters: + * + * 1. The location of the address + * 2. The location of the per flow enable bit + * 3. The location of the meter type (if necessary) + * + * Currently these locations can be: + * - Names that appear in the format of the table + * - For address location, a hash distribution unit + * - For address a $DIRECT keyword for a directly addressed table + * - For pfe and meter type, a $DEFAULT keyword indicating that the value is ORed in through + * the default register + * + * This function is responsible for validating this. Perhaps, in the future, we can have arguments + * both contain potential SHIFTs and ORs that can be interpreted by the registers + */ +bool AttachedTable::validate_call(Table::Call &call, MatchTable *self, size_t required_args, + int hash_dist_type, Table::Call &first_call) { + if (!self) return false; + if (call->stage != self->stage) { + error(call.lineno, "%s not in same stage as %s", call->name(), self->name()); + return false; + } else if (call->gress != self->gress) { + if (!(call->to() && + timing_thread(call->gress) == timing_thread(self->gress))) { + error(call.lineno, "%s not in same thread as %s", call->name(), self->name()); + return false; + } + } else if (call.args != first_call.args) { + error(call.lineno, + "All calls for the same address type must be identical, and " + "are not for %s and %s", + call->name(), first_call->name()); + } + + if (call.args.size() != required_args) { + error(call.lineno, "%s requires exactly %zu arguments", call->name(), required_args); + return false; + } + + if (call.args.size() == 0) return true; + if (call.args[0].name()) { + if (strcmp(call.args[0].name(), "$DIRECT") != 0) { + error(call.lineno, "Index %s for %s cannot be found", call.args[0].name(), + call->name()); + return false; + } + } else if (call.args[0].hash_dist()) { + call.args[0].hash_dist()->xbar_use |= hash_dist_type; + } else if (call.args[0].type == Table::Call::Arg::Counter) { + auto *salu = call->to(); + if (salu == nullptr) { + error(call.lineno, + "Index for %s cannot be a stateful counter, as it is not a " + "stateful alu", + call->name()); + return false; + } + salu->set_counter_mode(call.args[0].count_mode()); + + } else if (!call.args[0].field()) { + error(call.lineno, "Index for %s cannot be understood", call->name()); + } + + if (call.args.size() == 1) return true; + + if (call.args[1].name()) { + if (strcmp(call.args[1].name(), "$DEFAULT") != 0) { + error(call.lineno, "Per flow enable %s for %s cannot be found", call.args[1].name(), + call->name()); + return false; + } + } else if (!call.args[1].field()) { + error(call.lineno, "Per flow enable for %s cannot be understood", call->name()); + return false; + } + + if (call.args.size() == 2) return true; + + if (call.args[2].name()) { + if (strcmp(call.args[2].name(), "$DEFAULT") != 0) { + error(call.lineno, "Meter type %s for %s cannot be found", call.args[2].name(), + call->name()); + return false; + } + } else if (!call.args[2].field()) { + error(call.lineno, "Meter type for %s cannot be understood", call->name()); + return false; + } + return true; +} + +void AttachedTables::pass0(MatchTable *self) { + if (selector.check() && selector->set_match_table(self, true) != Table::SELECTION) + error(selector.lineno, "%s is not a selection table", selector->name()); + for (auto &s : stats) { + bool direct = false; + if (s.check() && s->set_match_table(self, !s.is_direct_call()) != Table::COUNTER) + error(s.lineno, "%s is not a counter table", s->name()); + } + for (auto &m : meters) + if (m.check()) { + auto type = m->set_match_table(self, !m.is_direct_call() > 0); + if (type != Table::METER && type != Table::STATEFUL) + error(m.lineno, "%s is not a meter table", m->name()); + } + for (auto &s : statefuls) { + if (!s.check()) continue; + if (s->set_match_table(self, !s.is_direct_call()) != Table::STATEFUL) + error(s.lineno, "%s is not a stateful table", s->name()); + } +} + +void AttachedTables::pass1(MatchTable *self) { + if (selector) { + selector->validate_call(selector, self, 3, HashDistribution::METER_ADDRESS, selector); + if (selector_length && selector_length->name() == selector->name()) { + selector_length->to()->validate_length_call(selector_length); + } else { + error(selector.lineno, + "Must provide selector length information when a selector " + "is called"); + } + } + for (auto &s : stats) { + if (s) { + s->validate_call(s, self, 2, HashDistribution::STATISTICS_ADDRESS, stats[0]); + } + } + + bool color_mapram_req = false; + for (auto &m : meters) { + if (m) { + m->validate_call(m, self, 3, HashDistribution::METER_ADDRESS, meters[0]); + if (m->uses_colormaprams()) color_mapram_req = true; + } + } + + if (color_mapram_req) { + if (meter_color) { + meter_color->validate_call(meter_color, self, 2, HashDistribution::STATISTICS_ADDRESS, + meter_color); + } else { + error(meters[0].lineno, + "Must provide a meter color mapram call when a meter " + "required color maprams is called"); + } + } + + for (auto &s : statefuls) { + if (s) { + s->validate_call(s, self, 3, HashDistribution::METER_ADDRESS, statefuls[0]); + } + } +} + +int AttachedTable::json_memunit(const MemUnit &r) const { + if (r.stage >= 0) { + return r.stage * Target::SRAM_STRIDE_STAGE() + r.row * Target::SRAM_STRIDE_ROW() + + r.col * Target::SRAM_STRIDE_COLUMN(); + } else if (r.row >= 0) { + // per-stage logical sram + return r.row * Target::SRAM_LOGICAL_UNITS_PER_ROW() + r.col; + } else { + // lamb + return r.col; + } +} + +template +void AttachedTables::write_merge_regs(REGS ®s, MatchTable *self, int type, int bus) { + for (auto &s : stats) s->write_merge_regs(regs, self, type, bus, s.args); + for (auto &m : meters) { + m->write_merge_regs(regs, self, type, bus, m.args); + if (m->uses_colormaprams()) { + if (meter_color) + m->to()->write_color_regs(regs, self, type, bus, meter_color.args); + else + m->to()->write_color_regs(regs, self, type, bus, m.args); + } + } + for (auto &s : statefuls) s->write_merge_regs(regs, self, type, bus, s.args); + if (auto s = get_selector()) s->write_merge_regs(regs, self, type, bus, selector.args); +} +FOR_ALL_REGISTER_SETS(INSTANTIATE_TARGET_TEMPLATE, void AttachedTables::write_merge_regs, + mau_regs &, MatchTable *, int, int) + +template +void AttachedTables::write_tcam_merge_regs(REGS ®s, MatchTable *self, int bus, int tcam_shift) { + auto &merge = regs.rams.match.merge; + for (auto &st : stats) { + merge.mau_stats_adr_tcam_shiftcount[bus] = st->determine_shiftcount(st, 0, 0, tcam_shift); + break; + } + for (auto &m : meters) { + m->to()->setup_tcam_shift(regs, bus, tcam_shift, m, meter_color); + break; /* all must be the same, only config once */ + } + for (auto &s : statefuls) { + merge.mau_meter_adr_tcam_shiftcount[bus] = s->determine_shiftcount(s, 0, 0, tcam_shift); + break; /* all must be the same, only config once */ + } +} +FOR_ALL_REGISTER_SETS(INSTANTIATE_TARGET_TEMPLATE, void AttachedTables::write_tcam_merge_regs, + mau_regs &, MatchTable *, int, int) diff --git a/backends/tofino/bf-asm/b2j.cpp b/backends/tofino/bf-asm/b2j.cpp new file mode 100644 index 00000000000..b6b345aa107 --- /dev/null +++ b/backends/tofino/bf-asm/b2j.cpp @@ -0,0 +1,48 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "bson.h" + +int main(int ac, char **av) { + if (ac != 3) { + std::cerr << "usage " << av[0] << " " << std::endl; + return 1; + } + std::ifstream in(av[1]); + if (!in) { + std::cerr << "failed to open " << av[1] << std::endl; + return 1; + } + json::obj *data = nullptr; + if (!(in >> json::binary(data))) { + std::cerr << "failed to read bson" << std::endl; + return 1; + } + std::ofstream out(av[2]); + if (!out) { + std::cerr << "failed to open " << av[2] << std::endl; + return 1; + } + if (!(out << data)) { + std::cerr << "failed to write json" << std::endl; + return 1; + } + return 0; +} diff --git a/backends/tofino/bf-asm/bfas.cpp b/backends/tofino/bf-asm/bfas.cpp new file mode 100644 index 00000000000..8a282498a2d --- /dev/null +++ b/backends/tofino/bf-asm/bfas.cpp @@ -0,0 +1,627 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "bfas.h" + +#include + +#include + +#include +#include +#include +#include + +#include "../p4c/backends/tofino/bf-p4c/git_sha_version.h" // for BF_P4C_GIT_SHA +#include "../p4c/backends/tofino/bf-p4c/version.h" +#include "constants.h" +#include "indent.h" +#include "misc.h" +#include "parser-tofino-jbay.h" +#include "sections.h" +#include "target.h" +#include "top_level.h" + +#define MAJOR_VERSION 1 +#define MINOR_VERSION 0 + +const std::string SCHEMA_VERSION = CONTEXT_SCHEMA_VERSION; // NOLINT(runtime/string) + +option_t options = { + .binary = PIPE0, + .condense_json = true, + .debug_info = false, + .disable_egress_latency_padding = false, + .disable_gfm_parity = true, + .disable_long_branch = false, + .disable_power_gating = false, + .gen_json = false, + .high_availability_enabled = true, + .match_compiler = false, + .multi_parsers = true, // TODO Remove option after testing + .partial_input = false, +#if HAVE_JBAY + .singlewrite = true, +#else + .singlewrite = false, +#endif /* !HAVE_JBAY && ! */ + .stage_dependency_pattern = "", + .target = NO_TARGET, + .tof2lab44_workaround = false, + .version = CONFIG_OLD, + .werror = false, + .nowarn = false, + .log_hashes = false, + .output_dir = ".", + .num_stages_override = 0, + .tof1_egr_parse_depth_checks_disabled = false, +}; + +std::string asmfile_name; // NOLINT(runtime/string) +std::string asmfile_dir; // NOLINT(runtime/string) +std::string gfm_log_file_name = "mau.gfm.log"; // NOLINT(runtime/string) + +std::unique_ptr gfm_out; + +int log_error = 0; +extern char *program_name; + +/** + * @brief Maximum handle offset which can be used for table and parser handles. + * + * Selected bits in parser and table handles are dedicated to distinguish handles + * for different pipes. + * See comments in bf-asm/parser.h and bf-asm/p4_table.cpp to get more information + * about format of parser and table handles. + * Currently 4 bits are dedicated for pipe id. + */ +#define MAX_HANDLE_OFFSET 16 + +/** + * @brief Value OR-ed with table and parser handles to create unique handles. + * + * See comments in bf-asm/parser.h and bf-asm/p4_table.cpp to get more information + * about format of parser and table handles. + */ +unsigned unique_table_offset = 0; + +BaseAsmParser *asm_parser = nullptr; + +// Create target-specific section for parser +void createSingleAsmParser() { + if (asm_parser != nullptr) { + return; + } + asm_parser = new AsmParser; +} + +std::unique_ptr open_output(const char *name, ...) { + char namebuf[1024], *p = namebuf, *end = namebuf + sizeof(namebuf); + va_list args; + if (!options.output_dir.empty()) p += snprintf(p, end - p, "%s/", options.output_dir.c_str()); + va_start(args, name); + if (p < end) p += vsnprintf(p, end - p, name, args); + va_end(args); + if (p >= end) { + std::cerr << "File name too long: " << namebuf << "..." << std::endl; + snprintf(namebuf, sizeof(namebuf), "/dev/null"); + } + auto rv = std::unique_ptr(new std::ofstream(namebuf)); + if (!*rv) { + std::cerr << "Failed to open " << namebuf << " for writing: " << strerror(errno) + << std::endl; + } + return rv; +} + +std::string usage(std::string tfas) { + std::string u = "usage: "; + u.append(tfas); + u.append(" [-l:Mo:gqtvh] file..."); + return u; +} + +void output_all() { + auto targetName = "unknown"; + switch (options.target) { +#define SET_TOP_LEVEL(TARGET) \ + case Target::TARGET::tag: \ + new TopLevelRegs; \ + targetName = Target::TARGET::name; \ + break; + FOR_ALL_TARGETS(SET_TOP_LEVEL) + default: + std::cerr << "No target set" << std::endl; + error_count++; + return; + } + json::map ctxtJson; + const time_t now = time(NULL); + char build_date[1024]; + struct tm lt; + localtime_r(&now, <); + BUG_CHECK(<); + strftime(build_date, 1024, "%c", <); + ctxtJson["build_date"] = build_date; + ctxtJson["schema_version"] = SCHEMA_VERSION; + ctxtJson["compiler_version"] = BF_P4C_VERSION " (" BF_P4C_GIT_SHA ")"; + ctxtJson["target"] = targetName; + ctxtJson["program_name"] = asmfile_name; + ctxtJson["learn_quanta"] = json::vector(); + ctxtJson["parser"] = json::map(); + ctxtJson["phv_allocation"] = json::vector(); + ctxtJson["tables"] = json::vector(); + ctxtJson["mau_stage_characteristics"] = json::vector(); + ctxtJson["configuration_cache"] = json::vector(); + + Section::output_all(ctxtJson); + TopLevel::output_all(ctxtJson); + + json::map driver_options; + driver_options["hash_parity_enabled"] = !options.disable_gfm_parity; + driver_options["high_availability_enabled"] = options.high_availability_enabled; + if (options.target == TOFINO) + driver_options["tof1_egr_parse_depth_checks_disabled"] = + options.tof1_egr_parse_depth_checks_disabled; + ctxtJson["driver_options"] = std::move(driver_options); + + auto json_out = open_output("context.json"); + *json_out << &ctxtJson; + + delete TopLevel::all; +} + +void check_target_pipes(int pipe_id) { + if (pipe_id >= 0) { + if (pipe_id >= MAX_PIPE_COUNT) { + std::cerr << "Pipe number (" << pipe_id << ") exceeds implementation limit of pipes (" + << MAX_PIPE_COUNT << ")." << std::endl; + error_count++; + } else if (pipe_id < Target::NUM_PIPES()) { + options.binary = static_cast(PIPE0 + pipe_id); + } else { + std::cerr << "Pipe number (" << pipe_id << ") exceeds maximum number of pipes (" + << Target::NUM_PIPES() << ") for target " << Target::name() << "." + << std::endl; + error_count++; + } + } +} + +#define MATCH_TARGET_OPTION(TARGET, OPT) \ + if (!strcasecmp(OPT, Target::TARGET::name)) /* NOLINT(readability/braces) */ \ + options.target = Target::TARGET::tag; \ + else +#define OUTPUT_TARGET(TARGET) << " " << Target::TARGET::name + +// Do not build main() when BUILDING_FOR_GTEST. +#ifndef BUILDING_FOR_GTEST +int main(int ac, char **av) { + int srcfiles = 0; + const char *firstsrc = 0; + struct stat st; + bool asmfile = false; + bool disable_clog = true; + int pipe_id = -1; + extern void register_exit_signals(); + register_exit_signals(); + program_name = av[0]; + std::vector arguments(av, av + ac); + static std::set valid_noop_fill = {"and", "or", "alu_a", "alu_b", + "minu", "mins", "maxu", "maxs"}; + if (auto opt = getenv("BFAS_OPTIONS")) { + int add_at = 1; + while (auto p = strsep(&opt, " \t\r\n")) { + if (!*p) continue; + arguments.insert(arguments.begin() + add_at++, p); + } + av = &arguments[0]; + ac = arguments.size(); + } + for (int i = 1; i < ac; i++) { + int val, len; + if (av[i][0] == '-' && av[i][1] == 0) { + asm_parse_file("", stdin); + } else if (!strcmp(av[i], "--allpipes")) { + options.binary = FOUR_PIPE; + } else if (!strcmp(av[i], "--disable-egress-latency-padding")) { + options.disable_egress_latency_padding = true; + } else if (!strcmp(av[i], "--log-hashes")) { + options.log_hashes = true; + } else if (!strcmp(av[i], "--disable-longbranch")) { + options.disable_long_branch = true; + } else if (!strcmp(av[i], "--enable-longbranch")) { + if (options.target && Target::LONG_BRANCH_TAGS() == 0) { + error(-1, "target %s does not support --enable-longbranch", Target::name()); + options.disable_long_branch = true; + } else { + options.disable_long_branch = false; + } + } else if (!strcmp(av[i], "--gen_json")) { + options.gen_json = true; + options.binary = NO_BINARY; + } else if (!strcmp(av[i], "--high_availability_disabled")) { + options.high_availability_enabled = false; + } else if (!strcmp(av[i], "--no-condense")) { + options.condense_json = false; + } else if (!strcmp(av[i], "--no-bin")) { + options.binary = NO_BINARY; + } else if (!strcmp(av[i], "--no-warn")) { + options.nowarn = true; + } else if (!strcmp(av[i], "--old_json")) { + std::cerr << "Old context json is no longer supported" << std::endl; + error_count++; + } else if (!strcmp(av[i], "--partial")) { + options.partial_input = true; + } else if (sscanf(av[i], "--pipe%d%n", &val, &len) > 0 && !av[i][len] && val >= 0) { + pipe_id = val; + } else if (!strcmp(av[i], "--singlepipe")) { + options.binary = ONE_PIPE; + } else if (!strcmp(av[i], "--singlewrite")) { + options.singlewrite = true; + } else if (!strcmp(av[i], "--multi-parsers")) { + options.multi_parsers = true; + } else if (!strcmp(av[i], "--disable-tof2lab44-workaround")) { + options.tof2lab44_workaround = false; + } else if (!strcmp(av[i], "--tof2lab44-workaround")) { + options.tof2lab44_workaround = true; + } else if (!strcmp(av[i], "--stage_dependency_pattern")) { + ++i; + if (!av[i]) { + std::cerr << "No stage dependency pattern specified " << std::endl; + error_count++; + break; + } + options.stage_dependency_pattern = av[i]; + } else if (!strcmp(av[i], "--noop-fill-instruction")) { + ++i; + if (!av[i] || !valid_noop_fill.count(av[i])) { + std::cerr << "invalid fill instruction " << av[i] << std::endl; + } else { + options.fill_noop_slot = av[i]; + } + } else if (val = 0, sscanf(av[i], "--noop-fill-instruction=%n", &val), val > 0) { + if (!valid_noop_fill.count(av[i] + val)) { + std::cerr << "invalid fill instruction " << (av[i] + val) << std::endl; + } else { + options.fill_noop_slot = av[i] + val; + } + } else if (sscanf(av[i], "--table-handle-offset%d", &val) > 0 && val >= 0 && + val < MAX_HANDLE_OFFSET) { + unique_table_offset = val; + } else if (sscanf(av[i], "--num-stages-override%d", &val) > 0 && val >= 0) { + options.num_stages_override = val; + } else if (!strcmp(av[i], "--target")) { + ++i; + if (!av[i]) { + std::cerr << "No target specified '--target '" << std::endl; + error_count++; + break; + } + if (options.target != NO_TARGET) { + std::cerr << "Multiple target options" << std::endl; + error_count++; + break; + } + FOR_ALL_TARGETS(MATCH_TARGET_OPTION, av[i]) { + std::cerr << "Unknown target " << av[i] << std::endl; + error_count++; + std::cerr << "Supported targets:" FOR_ALL_TARGETS(OUTPUT_TARGET) << std::endl; + } + } else if (av[i][0] == '-' && av[i][1] == '-') { + FOR_ALL_TARGETS(MATCH_TARGET_OPTION, av[i] + 2) { + std::cerr << "Unrecognized option " << av[i] << std::endl; + error_count++; + } + } else if (av[i][0] == '-' || av[i][0] == '+') { + bool flag = av[i][0] == '+'; + for (char *arg = av[i] + 1; *arg;) switch (*arg++) { + case 'a': + options.binary = FOUR_PIPE; + break; + case 'C': + options.condense_json = true; + break; + case 'G': + options.gen_json = true; + options.binary = NO_BINARY; + break; + case 'g': + options.debug_info = true; + break; + case 'h': + std::cout << usage(av[0]) << std::endl; + return 0; + break; + case 'l': + ++i; + if (!av[i]) { + std::cerr << "No log file specified '-l '" << std::endl; + error_count++; + break; + } + disable_clog = false; + if (auto *tmp = new std::ofstream(av[i])) { + if (*tmp) { + /* FIXME -- tmp leaks, but if we delete it, the log + * redirect fails, and we crash on exit */ + std::clog.rdbuf(tmp->rdbuf()); + } else { + std::cerr << "Can't open " << av[i] << " for writing" << std::endl; + delete tmp; + } + } + break; + case 'M': + options.match_compiler = true; + options.condense_json = false; + break; + case 'o': + ++i; + if (!av[i]) { + std::cerr << "No output directory specified '-o '" + << std::endl; + error_count++; + break; + } + if (stat(av[i], &st)) { + if (mkdir(av[i], 0777) < 0) { + std::cerr << "Can't create output dir " << av[i] << ": " + << strerror(errno) << std::endl; + error_count++; + } + } else if (!S_ISDIR(st.st_mode)) { + std::cerr << av[i] << " exists and is not a directory" << std::endl; + error_count++; + } + options.output_dir = av[i]; + break; + case 'p': + options.disable_power_gating = true; + break; + case 'q': + std::clog.setstate(std::ios::failbit); + break; + case 's': + options.binary = ONE_PIPE; + break; + case 'T': + disable_clog = false; + if (*arg) { + Log::addDebugSpec(arg); + arg += strlen(arg); + } else if (++i < ac) { + Log::addDebugSpec(av[i]); + } + break; + case 't': + ++i; + if (!av[i]) { + std::cerr << "No target specified '-t '" << std::endl; + error_count++; + break; + } + if (options.target != NO_TARGET) { + std::cerr << "Multiple target options" << std::endl; + error_count++; + break; + } + FOR_ALL_TARGETS(MATCH_TARGET_OPTION, av[i]) { + std::cerr << "Unknown target " << av[i]; + error_count++; + } + break; + case 'v': + disable_clog = false; + Log::increaseVerbosity(); + break; + case 'W': + if (strcmp(arg, "error")) + options.werror = true; + else + std::cout << "Unknown warning option -W" << arg << std::endl; + arg += strlen(arg); + break; + default: + std::cerr << "Unknown option " << (flag ? '+' : '-') << arg[-1] + << std::endl; + error_count++; + } + } else if (FILE *fp = fopen(av[i], "r")) { + // asm_parse_file needs to know correct number of stages + if (options.num_stages_override) { + Target::OVERRIDE_NUM_MAU_STAGES(options.num_stages_override); + } + + createSingleAsmParser(); + + if (!srcfiles++) firstsrc = av[i]; + error_count += asm_parse_file(av[i], fp); + if (error_count > 0) return 1; + fclose(fp); + asmfile = true; + asmfile_name = get_filename(av[i]); + asmfile_dir = get_directory(av[i]); + } else { + std::cerr << "Can't read " << av[i] << ": " << strerror(errno) << std::endl; + error_count++; + } + } + + check_target_pipes(pipe_id); + + if (disable_clog) std::clog.setstate(std::ios_base::failbit); + if (!asmfile) { + std::cerr << "No assembly file specified" << std::endl; + error_count++; + } + if (error_count > 0) std::cerr << usage(av[0]) << std::endl; + + if (Log::verbosity() > 0) { + gfm_out = open_output("mau.gfm.log"); + } + + if (error_count == 0 && !options.partial_input) { + // Check if file has no sections + no_sections_error_exit(); + // Check if mandatory sections are present in assembly + bool no_section = false; + no_section |= no_section_error("deparser"); + no_section |= no_section_error("parser"); + no_section |= no_section_error("phv"); + no_section |= no_section_error("stage"); + if (no_section) exit(1); + } + if (error_count == 0) { + Section::process_all(); + } + if (error_count == 0) { + if (srcfiles == 1 && options.output_dir.empty()) { + if (const char *p = strrchr(firstsrc, '/')) + options.output_dir = p + 1; + else if (const char *p = strrchr(firstsrc, '\\')) + options.output_dir = p + 1; + else + options.output_dir = firstsrc; + if (const char *e = strrchr(&options.output_dir[0], '.')) + options.output_dir.resize(e - &options.output_dir[0]); + options.output_dir += ".out"; + if (stat(options.output_dir.c_str(), &st) ? mkdir(options.output_dir.c_str(), 0777) + : !S_ISDIR(st.st_mode)) + options.output_dir.clear(); + } + output_all(); + } + if (log_error > 0) warning(0, "%d config errors in log file", log_error); + return error_count > 0 || (options.werror && warn_count > 0) ? 1 : 0; +} +#endif /* !BUILDING_FOR_GTEST */ + +std::string toString(target_t target) { + switch (target) { + case TOFINO: + return "Tofino"; + case TOFINO2: + return "Tofino2"; + case TOFINO2H: + return "Tofino2H"; + case TOFINO2U: + return "Tofino2U"; + case TOFINO2M: + return "Tofino2M"; + case TOFINO2A0: + return "Tofino2A0"; + default: + BUG("Unexpected target value: 0x%x", target); + return ""; + } +} + +std::ostream &operator<<(std::ostream &out, target_t target) { return out << toString(target); } + +void no_sections_error_exit() { + if (Section::no_sections_in_assembly()) { + std::cerr << "No valid sections found in assembly file" << std::endl; + exit(1); + } +} + +bool no_section_error(const char *name) { + if (!Section::section_in_assembly(name)) { + std::cerr << "No '" << name << "' section found in assembly file" << std::endl; + return true; + } + return false; +} + +class Version : public Section { + Version() : Section("version") {} + + void input(VECTOR(value_t) args, value_t data) { + if (data.type == tINT || data.type == tVEC) { // version 1.0.0 + parse_version(data); + } else if (data.type == tMAP) { // version 1.0.1 + for (auto &kv : MapIterChecked(data.map, true)) { + if (kv.key == "version" && (kv.value.type == tVEC || kv.value.type == tINT)) { + parse_version(kv.value); + } else if (kv.key == "run_id" && kv.value.type == tSTR) { + _run_id = kv.value.s; + } else if (kv.key == "compiler") { + if (kv.value.type == tSTR) { + _compiler = kv.value.s; + } else if (kv.value.type == tINT) { + _compiler = std::to_string(kv.value.i); + } else if (kv.value.type == tVEC) { + const char *sep = ""; + for (auto &el : kv.value.vec) { + _compiler += sep; + if (el.type == tSTR) + _compiler += el.s; + else if (el.type == tINT) + _compiler += std::to_string(el.i); + else + error(el.lineno, "can't understand compiler version"); + sep = "."; + } + } + } else if (kv.key == "target") { + if (kv.value.type == tSTR) { + auto old = options.target; + FOR_ALL_TARGETS(MATCH_TARGET_OPTION, kv.value.s) { + error(kv.value.lineno, "Unknown target %s", kv.value.s); + } + if (old != NO_TARGET && old != options.target) { + options.target = old; + error(kv.value.lineno, "Inconsistent target %s (previously set to %s)", + kv.value.s, Target::name()); + } + createSingleAsmParser(); + } else { + error(kv.value.lineno, "Invalid target %s", value_desc(kv.value)); + } + } else { + warning(kv.key.lineno, "ignoring unknown item %s in version", + value_desc(kv.key)); + } + } + } else { + error(data.lineno, "Invalid version section"); + } + } + + void output(json::map &ctx_json) { + if (!_compiler.empty()) ctx_json["compiler_version"] = _compiler; + ctx_json["run_id"] = _run_id; + } + + private: + void parse_version(value_t data) { + if (data.type == tINT) { + if (data.i != MAJOR_VERSION) + error(data.lineno, "Version %" PRId64 " not supported", data.i); + } else if (data.vec.size >= 2) { + if (CHECKTYPE(data[0], tINT) && CHECKTYPE(data[1], tINT) && + (data[0].i != MAJOR_VERSION || data[1].i > MINOR_VERSION)) + error(data.lineno, "Version %" PRId64 ".%" PRId64 " not supported", data[0].i, + data[1].i); + } else { + error(data.lineno, "Version not understood"); + } + } + + std::string _run_id, _compiler; + static Version singleton_version; +} Version::singleton_version; diff --git a/backends/tofino/bf-asm/bfas.h b/backends/tofino/bf-asm/bfas.h new file mode 100644 index 00000000000..f2662dc39f3 --- /dev/null +++ b/backends/tofino/bf-asm/bfas.h @@ -0,0 +1,182 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_BFAS_H_ +#define BF_ASM_BFAS_H_ + +#include +#include +#include + +#include +#include +#include + +enum config_version_t { CONFIG_OLD = 1, CONFIG_NEW = 2, CONFIG_BOTH = 3 }; +enum target_t { + NO_TARGET = 0, + TOFINO, + TOFINO2, + JBAY = TOFINO2, + TOFINO2H, + TOFINO2U, + TOFINO2M, + TOFINO2A0, + TARGET_INDEX_LIMIT +}; +enum binary_type_t { + NO_BINARY = -3, + FOUR_PIPE = -2, // binary replicating to all 4 pipes + ONE_PIPE = -1, // binary for one pipe with pipe offset addresses + PIPE0 = 0, // binary with data just in pipe 0 + PIPE1, // binary with data just in pipe 1 + PIPE2, // binary with data just in pipe 2 + PIPE3, // binary with data just in pipe 3 + MAX_PIPE_COUNT, // Maximum number of pipes which bfas can create binary for +}; + +extern struct option_t { + binary_type_t binary; + bool condense_json; + bool debug_info; + bool disable_egress_latency_padding; + bool disable_gfm_parity; + bool disable_long_branch; + bool disable_power_gating; + bool gen_json; + bool high_availability_enabled; + bool match_compiler; + bool multi_parsers; + bool partial_input; + bool singlewrite; + std::string stage_dependency_pattern; + target_t target; + bool tof2lab44_workaround; + config_version_t version; + bool werror; + bool nowarn; + bool log_hashes; + std::string output_dir; + int num_stages_override; + bool tof1_egr_parse_depth_checks_disabled; + const char *fill_noop_slot; +} options; + +extern unsigned unique_action_handle; +struct value_t; + +extern std::string asmfile_name; +extern std::string asmfile_dir; +extern std::unique_ptr gfm_out; + +class BaseAsmParser; +extern BaseAsmParser *asm_parser; +void createSingleAsmParser(); + +std::string toString(target_t target); +std::ostream &operator<<(std::ostream &out, target_t target); + +int asm_parse_file(const char *name, FILE *in); +int asm_parse_string(const char *in); + +void no_sections_error_exit(); +bool no_section_error(const char *name); + +extern int error_count, warn_count; +extern void error(int lineno, const char *fmt, va_list); +void error(int lineno, const char *fmt, ...) __attribute__((format(printf, 2, 3))); +inline void error(int lineno, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + error(lineno, fmt, args); + va_end(args); +} +extern void warning(int lineno, const char *fmt, va_list); +void warning(int lineno, const char *fmt, ...) __attribute__((format(printf, 2, 3))); +inline void warning(int lineno, const char *fmt, ...) { +#ifdef BAREFOOT_INTERNAL + if (!options.nowarn) { + va_list args; + va_start(args, fmt); + warning(lineno, fmt, args); + va_end(args); + } +#endif /* BAREFOOT_INTERNAL */ +} + +inline const char *strip_prefix(const char *str, const char *pfx) { + if (const char *p = strstr(str, pfx)) return p + strlen(pfx); + return str; +} +void bug(const char *, int, const char * = 0, ...) __attribute__((format(printf, 3, 4))) +__attribute__((noreturn)); +inline void bug(const char *fname, int lineno, const char *fmt, ...) { +#ifdef NDEBUG + fprintf(stderr, "Assembler BUG"); +#else + fprintf(stderr, "%s:%d: Assembler BUG: ", fname, lineno); + if (fmt) { + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + } +#endif /* !NDEBUG */ + fprintf(stderr, "\n"); + fflush(stderr); + std::terminate(); +} + +extern std::unique_ptr open_output(const char *, ...) + __attribute__((format(printf, 1, 2))); + +#define SRCFILE strip_prefix(__FILE__, "bf-asm/") +#define BUG(...) \ + do { \ + bug(SRCFILE, __LINE__, ##__VA_ARGS__); \ + } while (0) +#define BUG_CHECK(e, ...) \ + do { \ + if (!(e)) BUG(__VA_ARGS__); \ + } while (0) + +class VersionIter { + unsigned left, bit; + void check() { + while (left && !(left & 1)) { + ++bit; + left >>= 1; + } + } + VersionIter() : left(0), bit(0) {} + + public: + explicit VersionIter(config_version_t v) : left(v), bit(0) { check(); } + VersionIter begin() { return *this; } + VersionIter end() { return VersionIter(); } + int operator*() const { return bit; } + bool operator==(VersionIter &a) { return (left << bit) == (a.left << a.bit); } + VersionIter &operator++() { + left &= ~1; + check(); + return *this; + } +}; + +extern unsigned unique_table_offset; + +#endif /* BF_ASM_BFAS_H_ */ diff --git a/backends/tofino/bf-asm/bfdis.cpp b/backends/tofino/bf-asm/bfdis.cpp new file mode 100644 index 00000000000..bb675fb0d65 --- /dev/null +++ b/backends/tofino/bf-asm/bfdis.cpp @@ -0,0 +1,185 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include +#include + +#include "bson.h" +#include "disasm.h" +#include "fdstream.h" + +Disasm *disasm = nullptr; + +int read_bin(std::istream &in) { + uint32_t atom_typ = 0; + while (in.read((char *)&atom_typ, 4)) { + if ((atom_typ >> 24) == 'H') { + json::map hdr; + if (!(in >> json::binary(hdr))) return -1; + if (auto target = hdr["target"]) { + disasm = Disasm::create(target.to()); + } else { + std::cerr << "no target specified in the binary" << std::endl; + delete disasm; + disasm = nullptr; + } + } else if ((atom_typ >> 24) == 'C') { + // future context json embedding in binary + std::unique_ptr ctxt_json; + if (!(in >> json::binary(ctxt_json))) return -1; + } else if ((atom_typ >> 24) == 'P') { + uint32_t prsr_hdl = 0; + if (!in.read((char *)&prsr_hdl, 4)) return -1; + } else if ((atom_typ >> 24) == 'R') { + // R block -- writing a single 32-bit register via 32-bit PCIe address + uint32_t reg_addr = 0, reg_data = 0; + if (!in.read((char *)®_addr, 4)) return -1; + if (!in.read((char *)®_data, 4)) return -1; + if (disasm) disasm->input_binary(reg_addr, 'R', ®_data, 1); + } else if ((atom_typ >> 24) == 'B') { + // B block -- write a range of 32-bit registers via 64-bit PCIe address + // size of the range is specified as count * width (in bits), which must + // always be a multiple of 32 + + uint64_t addr = 0; + uint32_t count = 0; + uint32_t width = 0; + + if (!in.read((char *)&addr, 8)) return -1; + if (!in.read((char *)&width, 4)) return -1; + if (!in.read((char *)&count, 4)) return -1; + // printf("B%08" PRIx64 ": %xx%x", addr, width, count); + count = (uint64_t)count * width / 32; + std::vector data(count); + if (!in.read((char *)&data[0], count * 4)) return -1; + if (disasm) disasm->input_binary(addr, 'B', &data[0], count); + } else if ((atom_typ >> 24) == 'D') { + // D block -- write a range of 128-bit memory via 64-bit chip address + // size of the range is specified as count * width (in bits), which must + // always be a multiple of 64 + + uint64_t addr = 0; + uint32_t count = 0; + uint32_t width = 0; + + if (!in.read((char *)&addr, 8)) return -1; + if (!in.read((char *)&width, 4)) return -1; + if (!in.read((char *)&count, 4)) return -1; + // printf("D%011" PRIx64 ": %xx%x", addr, width, count); + width /= 8; + std::vector data(count * width / 4); + if (!in.read((char *)&data[0], count * width)) return -1; + if (disasm) disasm->input_binary(addr, 'D', &data[0], count * width / 4); + } else if ((atom_typ >> 24) == 'S') { + // S block -- 'scanset' writing multiple data to a single 32-bit PCIE address + uint64_t sel_addr = 0, reg_addr = 0; + uint32_t sel_data = 0, width = 0, count = 0; + + if (!in.read((char *)&sel_addr, 8)) return -1; + if (!in.read((char *)&sel_data, 4)) return -1; + if (!in.read((char *)®_addr, 8)) return -1; + if (!in.read((char *)&width, 4)) return -1; + if (!in.read((char *)&count, 4)) return -1; + count = (uint64_t)count * width / 32; + std::vector data(count); + if (!in.read((char *)&data[0], count * 4)) return -1; + if (disasm) disasm->input_binary(reg_addr, 'S', &data[0], count); + } else { + fprintf(stderr, "\n"); + fprintf(stderr, "Parse error: atom_typ=%x (%c)\n", atom_typ, atom_typ >> 24); + fprintf(stderr, "fpos=%" PRIu64 " <%" PRIx64 "h>\n", (uint64_t)in.tellg(), + (uint64_t)in.tellg()); + fprintf(stderr, "\n"); + + return -1; + } + } + + return in.eof() ? 0 : -1; +} + +int main(int ac, char **av) { + int error = 0; + for (int i = 1; i < ac; ++i) { + if (*av[i] == '-') { + for (char *arg = av[i] + 1; *arg;) switch (*arg++) { + case 'l': + ++i; + if (!av[i]) { + std::cerr << "No log file specified '-l '" << std::endl; + error_count++; + break; + } + if (auto *tmp = new std::ofstream(av[i])) { + if (*tmp) { + /* FIXME -- tmp leaks, but if we delete it, the log + * redirect fails, and we crash on exit */ + std::clog.rdbuf(tmp->rdbuf()); + } else { + std::cerr << "Can't open " << av[i] << " for writing" << std::endl; + delete tmp; + } + } + break; + case 'v': + Log::increaseVerbosity(); + break; + case 'T': + if (*arg) { + Log::addDebugSpec(arg); + arg += strlen(arg); + } else if (++i < ac) { + Log::addDebugSpec(av[i]); + } + break; + default: + fprintf(stderr, "ignoring argument -%c\n", *arg); + error = 1; + } + } else { + std::ifstream in(av[i], std::ios::binary); + if (!in) { + fprintf(stderr, "failed to open %s\n", av[i]); + error = 1; + continue; + } + unsigned char magic[4] = {}; + in.read((char *)magic, 4); + if (magic[0] == 0 && magic[3] && strchr("RDBH", magic[3])) { + in.seekg(0); + error |= read_bin(in); + } else if (magic[0] == 0x1f && magic[1] == 0x8b) { + if (auto *pipe = popen((std::string("zcat < ") + av[i]).c_str(), "r")) { + fdstream in(fileno(pipe)); + error |= read_bin(in); + pclose(pipe); + } else { + fprintf(stderr, "%s: Cannot open pipe to read\n", av[i]); + } + } else { + fprintf(stderr, "%s: Unknown file format\n", av[i]); + } + } + } + if (error == 1) fprintf(stderr, "usage: %s \n", av[0]); + return error; +} diff --git a/backends/tofino/bf-asm/bfdumpbin.cpp b/backends/tofino/bf-asm/bfdumpbin.cpp new file mode 100644 index 00000000000..078b9288758 --- /dev/null +++ b/backends/tofino/bf-asm/bfdumpbin.cpp @@ -0,0 +1,228 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include +#include + +#include "bson.h" +#include "fdstream.h" + +struct { + bool oneLine; + bool noHeader; + bool noCtxtJson; +} options; + +int dump_bin(std::istream &in) { + uint32_t atom_typ = 0; + while (in.read((char *)&atom_typ, 4)) { + if ((atom_typ >> 24) == 'H') { + json::map hdr; + if (!(in >> json::binary(hdr))) return -1; + if (!options.noHeader) + for (auto &el : hdr) std::cout << el.first << " = " << el.second << std::endl; + } else if ((atom_typ >> 24) == 'C') { + // future context json embedding in binary + std::unique_ptr ctxt_json; + if (!(in >> json::binary(ctxt_json))) return -1; + if (!options.noCtxtJson) std::cout << ctxt_json; + } else if ((atom_typ >> 24) == 'P') { + uint32_t prsr_hdl = 0; + if (!in.read((char *)&prsr_hdl, 4)) return -1; + printf("P: %08x (parser handle)\n", prsr_hdl); + } else if ((atom_typ >> 24) == 'R') { + // R block -- writing a single 32-bit register via 32-bit PCIe address + uint32_t reg_addr = 0, reg_data = 0; + if (!in.read((char *)®_addr, 4)) return -1; + if (!in.read((char *)®_data, 4)) return -1; + printf("R%08x: %08x\n", reg_addr, reg_data); + } else if ((atom_typ >> 24) == 'B') { + // B block -- write a range of 32-bit registers via 64-bit PCIe address + // size of the range is specified as count * width (in bits), which must + // always be a multiple of 32 + + uint64_t addr = 0; + uint32_t count = 0; + uint32_t width = 0; + + if (!in.read((char *)&addr, 8)) return -1; + if (!in.read((char *)&width, 4)) return -1; + if (!in.read((char *)&count, 4)) return -1; + printf("B%08" PRIx64 ": %xx%x", addr, width, count); + if ((uint64_t)count * width % 32 != 0) printf(" (not a multiple of 32 bits!)"); + count = (uint64_t)count * width / 32; + uint32_t data, prev; + int repeat = 0, col = 0; + for (unsigned i = 0; i < count; ++i) { + if (!in.read((char *)&data, 4)) return -1; + if (i != 0 && data == prev) { + repeat++; + continue; + } + if (repeat > 0) { + printf(" x%-7d", repeat + 1); + if (++col > 8) col = 0; + } + repeat = 0; + if (!options.oneLine && col++ % 8 == 0) printf("\n "); + printf(" %08x", prev = data); + } + if (repeat > 0) printf(" x%d", repeat + 1); + printf("\n"); + } else if ((atom_typ >> 24) == 'D') { + // D block -- write a range of 128-bit memory via 64-bit chip address + // size of the range is specified as count * width (in bits), which must + // always be a multiple of 64 + + uint64_t addr = 0; + uint32_t count = 0; + uint32_t width = 0; + + if (!in.read((char *)&addr, 8)) return -1; + if (!in.read((char *)&width, 4)) return -1; + if (!in.read((char *)&count, 4)) return -1; + printf("D%011" PRIx64 ": %xx%x", addr, width, count); + if ((uint64_t)count * width % 64 != 0) printf(" (not a multiple of 64 bits!)"); + + width /= 8; + + uint64_t chunk[2], prev_chunk[2]; + int repeat = 0, col = 0; + for (unsigned i = 0; i < count * width; i += 16) { + if (!in.read((char *)chunk, 16)) return -1; + if (i != 0 && chunk[0] == prev_chunk[0] && chunk[1] == prev_chunk[1]) { + repeat++; + continue; + } + if (repeat > 0) { + printf(" x%d", repeat + 1); + col = 0; + } + repeat = 0; + if (!options.oneLine && col++ % 2 == 0) printf("\n "); + printf(" %016" PRIx64 "%016" PRIx64, prev_chunk[1] = chunk[1], + prev_chunk[0] = chunk[0]); + } + + if (repeat > 0) { + printf(" x%d", repeat + 1); + col = 0; + } + + if (count * width % 16 == 8) { + if (!in.read((char *)chunk, 8)) return -1; + if (!options.oneLine && col % 2 == 0) printf("\n "); + printf(" %016" PRIx64, chunk[0]); + } + printf("\n"); + } else if ((atom_typ >> 24) == 'S') { + // S block -- 'scanset' writing multiple data to a single 32-bit PCIE address + uint64_t sel_addr = 0, reg_addr = 0; + uint32_t sel_data = 0, width = 0, count = 0; + + if (!in.read((char *)&sel_addr, 8)) return -1; + if (!in.read((char *)&sel_data, 4)) return -1; + if (!in.read((char *)®_addr, 8)) return -1; + if (!in.read((char *)&width, 4)) return -1; + if (!in.read((char *)&count, 4)) return -1; + printf("S%011" PRIx64 ": %x, %011" PRIx64 ": %xx%x", sel_addr, sel_data, reg_addr, + width, count); + if (width % 32 != 0) printf(" (not a multiple of 32 bits!)"); + count = (uint64_t)count * width / 32; + uint32_t data, prev; + int repeat = 0, col = 0; + for (unsigned i = 0; i < count; ++i) { + if (!in.read((char *)&data, 4)) return -1; + if (i != 0 && data == prev) { + repeat++; + continue; + } + if (repeat > 0) { + printf(" x%-7d", repeat + 1); + if (++col > 8) col = 0; + } + repeat = 0; + if (!options.oneLine && col++ % 8 == 0) printf("\n "); + printf(" %08x", prev = data); + } + if (repeat > 0) printf(" x%d", repeat + 1); + printf("\n"); + } else { + fprintf(stderr, "\n"); + fprintf(stderr, "Parse error: atom_typ=%x (%c)\n", atom_typ, atom_typ >> 24); + fprintf(stderr, "fpos=%" PRIu64 " <%" PRIx64 "h>\n", (uint64_t)in.tellg(), + (uint64_t)in.tellg()); + fprintf(stderr, "\n"); + + return -1; + } + } + + return in.eof() ? 0 : -1; +} + +int main(int ac, char **av) { + int error = 0; + for (int i = 1; i < ac; ++i) { + if (*av[i] == '-') { + for (char *arg = av[i] + 1; *arg;) switch (*arg++) { + case 'C': + options.noCtxtJson = true; + break; + case 'H': + options.noHeader = true; + break; + case 'L': + options.oneLine = true; + break; + default: + fprintf(stderr, "ignoring argument -%c\n", *arg); + error = 1; + } + } else { + std::ifstream in(av[i], std::ios::binary); + if (!in) { + fprintf(stderr, "failed to open %s\n", av[i]); + error = 1; + continue; + } + unsigned char magic[4] = {}; + in.read((char *)magic, 4); + if (magic[0] == 0 && magic[3] && strchr("RDBH", magic[3])) { + in.seekg(0); + error |= dump_bin(in); + } else if (magic[0] == 0x1f && magic[1] == 0x8b) { + if (auto *pipe = popen((std::string("zcat < ") + av[i]).c_str(), "r")) { + fdstream in(fileno(pipe)); + error |= dump_bin(in); + pclose(pipe); + } else { + fprintf(stderr, "%s: Cannot open pipe to read\n", av[i]); + } + } else { + fprintf(stderr, "%s: Unknown file format\n", av[i]); + } + } + } + if (error == 1) fprintf(stderr, "usage: %s \n", av[0]); + return error; +} diff --git a/backends/tofino/bf-asm/bflink b/backends/tofino/bf-asm/bflink new file mode 100755 index 00000000000..3195414ba5c --- /dev/null +++ b/backends/tofino/bf-asm/bflink @@ -0,0 +1,182 @@ +#!/bin/sh + +# Copyright (C) 2024 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# +# SPDX-License-Identifier: Apache-2.0 + +WALLE="" +CHIP="" +OUT="" +objs="" +object_files="" +base_program="" +debug_info=false +tmpdir="" +pipe_args="" +READLINK_COMMAND=$(which greadlink || which readlink) +execdir=$(dirname $($READLINK_COMMAND -f $0)) + +if [ x"$BFAS_OPTIONS" = x"-g" ]; then + debug_info=true +fi + +tempfile() { + file=$(basename $1 $2) + orig=file + ctr=1 + while [ -r $tmpdir/$file ]; do + file=$ctr-$file + ctr=$((ctr + 1)) + done + echo $file +} + +while [ $# -gt 0 ]; do + case $1 in + -b) + base_program="$2" + shift ; shift;; + -g) + debug_info=true + shift;; + -o) + OUT="$2" + shift ; shift ;; + --walle|-w) + WALLE="$2" + shift ; shift ;; + --target|-t) + CHIP="$2" + OUT="$2.bin" + shift ; shift ;; + --singlepipe|-s) + pipe_args="--top memories.pipe --top regs.pipe" + shift ;; + --allpipes|-a) + pipe_args="" + shift ;; + *.json.Z) + if [ -z "$tmpdir" ]; then + tmpdir=$(mktemp -d) + fi + file=$(tempfile $1 .Z) + gunzip -c $1 >$tmpdir/$file + objs="$objs $tmpdir/$file" + object_files="$object_files $1" + shift ;; + *.json.gz) + if [ -z "$tmpdir" ]; then + tmpdir=$(mktemp -d) + fi + file=$(tempfile $1 .gz) + gunzip -c $1 >$tmpdir/$file + objs="$objs $tmpdir/$file" + object_files="$object_files $1" + shift ;; + *.json.bz) + if [ -z "$tmpdir" ]; then + tmpdir=$(mktemp -d) + fi + file=$(tempfile $1 .bz) + bzcat $1 >$tmpdir/$file + objs="$objs $tmpdir/$file" + object_files="$object_files $1" + shift ;; + *.json.bz2) + if [ -z "$tmpdir" ]; then + tmpdir=$(mktemp -d) + fi + file=$(tempfile $1 .bz2) + bzcat $1 >$tmpdir/$file + objs="$objs $tmpdir/$file" + object_files="$object_files $1" + shift ;; + *.json) + objs="$objs $1" + object_files="$object_files $1" + shift ;; + *) + echo >&2 "Unknown argument $1" + shift ;; + esac +done + +if [ ! -x "$WALLE" ]; then + if [ -f $execdir/walle -a -x $execdir/walle ]; then + WALLE=$execdir/walle + elif [ -x $execdir/walle.py ]; then + WALLE=$execdir/walle.py + elif [ -x $execdir/walle/walle.py ]; then + WALLE=$execdir/walle/walle.py + elif [ -e "$WALLE" ]; then + echo "$WALLE must be executable" + exit 1 + else + echo "4: $WALLE" + echo >&2 "Can't find walle" + exit 1 + fi +fi + +if [ -z "$CHIP" ]; then + for jf in $objs; do + if [ $(basename $jf) = regs.top.cfg.json ]; then + CHIP=$(grep '"_type"' $jf | sed -e 's/.*"regs\.//' -e 's/[_"].*//') + break + fi + done + if [ -z "$CHIP" ]; then + echo >&2 "Can't find target, assuming tofino" + CHIP=tofino + fi + if [ -z "$OUT" ]; then + OUT=$CHIP.bin + fi +fi + +schema_arg="" +if [ -r $CHIP/chip.schema ]; then + schema_arg="--schema $CHIP/chip.schema" +elif [ -r $execdir/$CHIP/chip.schema ]; then + schema_arg="--schema $execdir/$CHIP/chip.schema" +fi + +#echo "$WALLE --target $CHIP $schema_arg -o $OUT $objs $pipe_args" +$WALLE --target $CHIP $schema_arg -o $OUT $objs $pipe_args +rc=$? + +# cleanup +output_dir=$(dirname $OUT) +if [ -z "$output_dir" ]; then + output_dir="./" +fi +if ! $debug_info; then + rm -f $object_files +fi +if [ ! -z "$base_program" ] ; then + pp=$output_dir/${base_program}.p4i + if ! $debug_info && test -e $pp ; then rm -f $pp; fi +fi +if ! $debug_info && test -e $output_dir/bfas.config.log ; then + rm -f $output_dir/bfas.config.log +fi +# if we uncompressed, remove the directory +if [ -d "$tmpdir" ]; then + rm -rf $tmpdir +fi + +# exit with a return code if walle failed +exit $rc diff --git a/backends/tofino/bf-asm/binary_output.h b/backends/tofino/bf-asm/binary_output.h new file mode 100644 index 00000000000..ad137482315 --- /dev/null +++ b/backends/tofino/bf-asm/binary_output.h @@ -0,0 +1,72 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _binary_output_h_ +#define _binary_output_h_ + +#include +#include + +namespace binout { + +class tag { + char data[4] = {0, 0, 0, 0}; + + public: + tag(char ch) { data[3] = ch; } + friend std::ostream &operator<<(std::ostream &out, const tag &e) { + return out.write(e.data, 4); + } +}; + +class byte4 { + char data[4]; + + public: + byte4(uint32_t v) { + data[0] = v & 0xff; + data[1] = (v >> 8) & 0xff; + data[2] = (v >> 16) & 0xff; + data[3] = (v >> 24) & 0xff; + } + friend std::ostream &operator<<(std::ostream &out, const byte4 &e) { + return out.write(e.data, 4); + } +}; + +class byte8 { + char data[8]; + + public: + byte8(uint64_t v) { + data[0] = v & 0xff; + data[1] = (v >> 8) & 0xff; + data[2] = (v >> 16) & 0xff; + data[3] = (v >> 24) & 0xff; + data[4] = (v >> 32) & 0xff; + data[5] = (v >> 40) & 0xff; + data[6] = (v >> 48) & 0xff; + data[7] = (v >> 56) & 0xff; + } + friend std::ostream &operator<<(std::ostream &out, const byte8 &e) { + return out.write(e.data, 8); + } +}; + +} // end namespace binout + +#endif /* _binary_output_h_ */ diff --git a/backends/tofino/bf-asm/bson.cpp b/backends/tofino/bf-asm/bson.cpp new file mode 100644 index 00000000000..15cdcb4b545 --- /dev/null +++ b/backends/tofino/bf-asm/bson.cpp @@ -0,0 +1,320 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bson.h" + +#include + +#include "hex.h" + +namespace { +uint8_t get8(std::istream &in) { + char data; + in.read(&data, sizeof(data)); + return data & 0xffU; +} + +int32_t get32(std::istream &in) { + char data[4]; + in.read(data, sizeof(data)); + return (data[0] & 0xffU) | ((data[1] & 0xffU) << 8) | ((data[2] & 0xffU) << 16) | + ((data[3] & 0xffU) << 24); +} +int64_t get64(std::istream &in) { + char data[8]; + in.read(data, sizeof(data)); + return (data[0] & 0xffULL) | ((data[1] & 0xffULL) << 8) | ((data[2] & 0xffULL) << 16) | + ((data[3] & 0xffULL) << 24) | ((data[4] & 0xffULL) << 32) | ((data[5] & 0xffULL) << 40) | + ((data[6] & 0xffULL) << 48) | ((data[7] & 0xffULL) << 56); +} + +std::string out32(int32_t val) { + char data[4]; + data[0] = val & 0xff; + data[1] = (val >> 8) & 0xff; + data[2] = (val >> 16) & 0xff; + data[3] = (val >> 24) & 0xff; + return std::string(data, sizeof(data)); +} + +std::string out64(int64_t val) { + char data[8]; + data[0] = val & 0xff; + data[1] = (val >> 8) & 0xff; + data[2] = (val >> 16) & 0xff; + data[3] = (val >> 24) & 0xff; + data[4] = (val >> 32) & 0xff; + data[5] = (val >> 40) & 0xff; + data[6] = (val >> 48) & 0xff; + data[7] = (val >> 56) & 0xff; + return std::string(data, sizeof(data)); +} + +} // end anonymous namespace + +namespace json { + +std::istream &operator>>(std::istream &in, bson_wrap o) { + json::vector &out = o.o; + std::streamoff start = in.tellg(); + std::streamoff end = start + get32(in); + out.clear(); + while (uint8_t type = get8(in)) { + if (!in) break; + if (in.tellg() >= end) { + std::cerr << "truncated array" << std::endl; + in.setstate(std::ios::failbit); + break; + } + std::string key; + getline(in, key, '\0'); + if (key != std::to_string(out.size())) std::cerr << "incorrect key in array" << std::endl; + switch (type) { + case 0x02: { + uint32_t len = get32(in) - 1; + std::string val; + val.resize(len); + in.read(&val[0], len); + out.push_back(val.c_str()); + if (in.get() != 0) { + std::cerr << "missing NUL in bson string" << std::endl; + in.setstate(std::ios::failbit); + } + break; + } + case 0x03: { + json::map obj; + in >> binary(obj); + out.push_back(std::move(obj)); + break; + } + case 0x04: { + json::vector obj; + in >> binary(obj); + out.push_back(std::move(obj)); + break; + } + case 0x08: + switch (get8(in)) { + case 0: + out.push_back(false); + break; + case 1: + out.push_back(true); + break; + default: + std::cerr << "invalid boolean value" << std::endl; + in.setstate(std::ios::failbit); + break; + } + break; + case 0x0a: + out.push_back(nullptr); + break; + case 0x10: + out.push_back(get32(in)); + break; + case 0x12: + out.push_back(get64(in)); + break; + case 0x7f: + case 0xff: + break; + default: + std::cerr << "unhandled bson tag " << hex(type) << std::endl; + break; + } + } + if (start != -1 && in && in.tellg() != end) { + std::cerr << "incorrect length for object" << std::endl; + } + return in; +} + +std::istream &operator>>(std::istream &in, bson_wrap o) { + json::map &out = o.o; + std::streamoff start = in.tellg(); + std::streamoff end = start + get32(in); + out.clear(); + while (uint8_t type = get8(in)) { + if (!in) break; + if (in.tellg() >= end) { + std::cerr << "truncated object" << std::endl; + in.setstate(std::ios::failbit); + break; + } + std::string key; + getline(in, key, '\0'); + if (out.count(key.c_str())) std::cerr << "duplicate key in map" << std::endl; + switch (type) { + case 0x02: { + uint32_t len = get32(in) - 1; + std::string val; + val.resize(len); + in.read(&val[0], len); + out[key] = val; + if (in.get() != 0) { + std::cerr << "missing NUL in bson string" << std::endl; + in.setstate(std::ios::failbit); + } + break; + } + case 0x03: { + json::map obj; + in >> binary(obj); + out[key] = mkuniq(std::move(obj)); + break; + } + case 0x04: { + json::vector obj; + in >> binary(obj); + out[key] = mkuniq(std::move(obj)); + break; + } + case 0x08: + switch (get8(in)) { + case 0: + out[key] = mkuniq(False()); + break; + case 1: + out[key] = mkuniq(True()); + break; + default: + std::cerr << "invalid boolean value" << std::endl; + in.setstate(std::ios::failbit); + break; + } + break; + case 0x0a: + out[key] = std::unique_ptr(); + break; + case 0x10: + out[key] = get32(in); + break; + case 0x12: + out[key] = get64(in); + break; + case 0x7f: + case 0xff: + break; + default: + std::cerr << "unhandled bson tag " << hex(type) << std::endl; + break; + } + } + if (start != -1 && in && in.tellg() != end) { + std::cerr << "incorrect length for object" << std::endl; + } + return in; +} + +static std::unique_ptr map_is_vector(json::map &m) { + int idx = 0; + for (auto &el : m) { + if (*el.first != std::to_string(idx).c_str()) return nullptr; + ++idx; + } + if (idx == 0) return nullptr; + auto rv = mkuniq(); + for (auto &el : m) rv->push_back(std::move(el.second)); + // return std::move(rv); + return rv; +} + +std::istream &operator>>(std::istream &in, bson_wrap> json) { + json::map rv; + in >> binary(rv); + if (auto asvec = map_is_vector(rv)) + json.o = std::move(asvec); + else + json.o = mkuniq(std::move(rv)); + return in; +} + +std::string bson_encode(const json::vector &v); +std::string bson_encode(const json::map &m); + +std::string bson_encode_element(const std::string &key, const json::obj *o) { + if (!o) return '\x0A' + key + '\0'; + if (o->is()) return '\x08' + key + '\0' + '\1'; + if (o->is()) return '\x08' + key + '\0' + '\0'; + if (o->is()) { + auto &n = o->to(); + if (static_cast(n.val) == n.val) + return '\x10' + key + '\0' + out32(n.val); + else + return '\x12' + key + '\0' + out64(n.val); + } + if (o->is()) { + auto &s = o->to(); + return '\x02' + key + '\0' + out32(s.size() + 1) + s + '\0'; + } + if (o->is()) { + auto doc = bson_encode(o->to()); + return '\x04' + key + '\0' + out32(doc.size() + 4) + doc; + } + if (o->is()) { + auto doc = bson_encode(o->to()); + return '\x03' + key + '\0' + out32(doc.size() + 4) + doc; + } + assert(0); + return ""; // quiet warning +} + +std::string bson_encode(const json::vector &v) { + std::string rv; + int idx = 0; + for (auto &el : v) { + rv += bson_encode_element(std::to_string(idx), el.get()); + ++idx; + } + rv += '\0'; + return rv; +} +std::string bson_encode(const json::map &m) { + std::string rv; + for (auto &el : m) { + if (auto key = el.first->as_string()) + rv += bson_encode_element(*key, el.second.get()); + else + std::cerr << "Can't encode non-string key in bson object" << std::endl; + } + rv += '\0'; + return rv; +} + +std::ostream &operator<<(std::ostream &out, bson_wrap v) { + auto data = bson_encode(v.o); + out.write(out32(data.size() + 4).c_str(), 4); + out.write(data.data(), data.size()); + return out; +} +std::ostream &operator<<(std::ostream &out, bson_wrap m) { + auto data = bson_encode(m.o); + out.write(out32(data.size() + 4).c_str(), 4); + out.write(data.data(), data.size()); + return out; +} + +std::ostream &operator<<(std::ostream &out, bson_wrap json) { + if (auto m = json.o.as_map()) return out << binary(*m); + if (auto v = json.o.as_vector()) return out << binary(*v); + std::cerr << "object not map or vector can't be output as bson" << std::endl; + return out; +} + +} // end namespace json diff --git a/backends/tofino/bf-asm/bson.h b/backends/tofino/bf-asm/bson.h new file mode 100644 index 00000000000..6f3f850e0fd --- /dev/null +++ b/backends/tofino/bf-asm/bson.h @@ -0,0 +1,74 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _bson_h_ +#define _bson_h_ + +#include + +#include "json.h" + +namespace json { + +template +struct bson_wrap { + T &o; + bson_wrap(T &o) : o(o) {} + template + bson_wrap(U &o) : o(o) {} +}; + +template +bson_wrap binary(T &o) { + return bson_wrap(o); +} + +std::istream &operator>>(std::istream &in, bson_wrap> json); +std::istream &operator>>(std::istream &in, bson_wrap json); +std::istream &operator>>(std::istream &in, bson_wrap json); +inline std::istream &operator>>(std::istream &in, bson_wrap json) { + std::unique_ptr p; + in >> binary(p); + if (in) json.o = p.release(); + return in; +} + +std::ostream &operator<<(std::ostream &out, bson_wrap); +std::ostream &operator<<(std::ostream &out, bson_wrap); +std::ostream &operator<<(std::ostream &out, bson_wrap json); +inline std::ostream &operator<<(std::ostream &out, bson_wrap json) { + return operator<<(out, bson_wrap(json.o)); +} +inline std::ostream &operator<<(std::ostream &out, bson_wrap json) { + return operator<<(out, bson_wrap(json.o)); +} +inline std::ostream &operator<<(std::ostream &out, bson_wrap json) { + return operator<<(out, bson_wrap(json.o)); +} +inline std::ostream &operator<<(std::ostream &out, bson_wrap json) { + return out << binary(*json.o); +} +inline std::ostream &operator<<(std::ostream &out, bson_wrap json) { + return out << binary(*json.o); +} +inline std::ostream &operator<<(std::ostream &out, bson_wrap> json) { + return out << binary(*json.o.get()); +} + +} // end namespace json + +#endif /* _bson_h_ */ diff --git a/backends/tofino/bf-asm/checked_array.h b/backends/tofino/bf-asm/checked_array.h new file mode 100644 index 00000000000..cda1b1f2ba7 --- /dev/null +++ b/backends/tofino/bf-asm/checked_array.h @@ -0,0 +1,146 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_CHECKED_ARRAY_H_ +#define BF_ASM_CHECKED_ARRAY_H_ + +#include + +#include "bfas.h" // to get at the options +#include "log.h" + +void print_regname(std::ostream &out, const void *addr, const void *end); + +template +class checked_array; +template +std::ostream &operator<<(std::ostream &out, checked_array *arr); + +template +class checked_array_base { + public: + virtual T &operator[](size_t) = 0; + virtual const T &operator[](size_t) const = 0; + virtual size_t size() const = 0; + virtual T *begin() = 0; + virtual T *end() = 0; + virtual bool modified() const = 0; + virtual void set_modified(bool v = true) = 0; + virtual bool disabled() const = 0; + virtual bool disable() = 0; + virtual bool disable_if_zero() = 0; + virtual void enable() = 0; +}; + +template +class checked_array : public checked_array_base { + bool disabled_; + T data[S]; + + public: + checked_array() : disabled_(false) {} + template + explicit checked_array(U v) : disabled_(false) { + for (auto &e : data) new (&e) T(v); + } + template + checked_array(const std::initializer_list &v) : disabled_(false) { + auto it = v.begin(); + for (auto &e : data) { + if (it == v.end()) break; + new (&e) T(*it++); + } + } + T &operator[](size_t idx) { + if (idx >= S) { + LOG1("ERROR: array index " << idx << " out of bounds " << this); + BUG("array index %zu out of bounds (%zu)", idx, S); + } + return data[idx]; + } + const T &operator[](size_t idx) const { + if (idx >= S) { + LOG1("ERROR: array index " << idx << " out of bounds " << this); + BUG("array index %zu out of bounds (%zu)", idx, S); + } + return data[idx]; + } + size_t size() const { return S; } + T *begin() { return data; } + T *end() { return data + S; } + bool modified() const { + for (size_t i = 0; i < S; i++) + if (data[i].modified()) return true; + return false; + } + void set_modified(bool v = true) { + for (size_t i = 0; i < S; i++) data[i].set_modified(v); + } + bool disabled() const { return disabled_; } + bool disable() { + bool rv = true; + for (size_t i = 0; i < S; i++) + if (!data[i].disable()) rv = false; + if (rv) disabled_ = true; + return rv; + } + void enable() { + disabled_ = false; + for (size_t i = 0; i < S; i++) data[i].enable(); + } + bool disable_if_unmodified() { + bool rv = true; + for (size_t i = 0; i < S; i++) + if (!data[i].disable_if_unmodified()) rv = false; + if (rv && !options.gen_json) { + /* Can't actually disable arrays when generating json, as walle doesn't like it, + * but allow containing object to be disabled */ + disabled_ = true; + } + return rv; + } + bool disable_if_zero() { + bool rv = true; + for (size_t i = 0; i < S; i++) + if (!data[i].disable_if_zero()) rv = false; + if (rv && !options.gen_json) { + /* Can't actually disable arrays when generating json, as walle doesn't like it, + * but allow containing object to be disabled */ + disabled_ = true; + } + return rv; + } + bool disable_if_reset_value() { + bool rv = true; + for (size_t i = 0; i < S; i++) + if (!data[i].disable_if_reset_value()) rv = false; + if (rv && !options.gen_json) { + /* Can't actually disable arrays when generating json, as walle doesn't like it, + * but allow containing object to be disabled */ + disabled_ = true; + } + return rv; + } +}; + +template +inline std::ostream &operator<<(std::ostream &out, checked_array *arr) { + print_regname(out, arr, arr + 1); + return out; +} + +#endif /* BF_ASM_CHECKED_ARRAY_H_ */ diff --git a/backends/tofino/bf-asm/cmake/Abseil.cmake b/backends/tofino/bf-asm/cmake/Abseil.cmake new file mode 100644 index 00000000000..1e32d333e2a --- /dev/null +++ b/backends/tofino/bf-asm/cmake/Abseil.cmake @@ -0,0 +1,76 @@ +macro(p4c_obtain_abseil) + option( + P4C_USE_PREINSTALLED_ABSEIL + "Look for a preinstalled version of Abseil in the system instead of installing the library using FetchContent." + OFF + ) + + # If P4C_USE_PREINSTALLED_ABSEIL is ON just try to find a preinstalled version of Abseil. + if(P4C_USE_PREINSTALLED_ABSEIL) + if(ENABLE_ABSEIL_STATIC) + set(SAVED_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + set(CMAKE_FIND_LIBRARY_SUFFIXES .a) + endif() + + set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) + find_package(absl REQUIRED) + + if(ENABLE_ABSEIL_STATIC) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${SAVED_CMAKE_FIND_LIBRARY_SUFFIXES}) + endif() + else() + set(P4C_ABSEIL_VERSION "20240116.1") + message(STATUS "Fetching Abseil version ${P4C_ABSEIL_VERSION} for P4C...") + + # Unity builds do not work for Abseil... + set(CMAKE_UNITY_BUILD_PREV ${CMAKE_UNITY_BUILD}) + set(CMAKE_UNITY_BUILD OFF) + + # Print out download state while setting up Abseil. + set(FETCHCONTENT_QUIET_PREV ${FETCHCONTENT_QUIET}) + set(FETCHCONTENT_QUIET OFF) + + set(ABSL_USE_EXTERNAL_GOOGLETEST ON) + set(ABSL_FIND_GOOGLETEST OFF) + set(ABSL_BUILD_TESTING OFF) + set(ABSL_ENABLE_INSTALL OFF) + set(ABSL_USE_SYSTEM_INCLUDES ON) + set(ABSL_PROPAGATE_CXX_STD ON) + + FetchContent_Declare( + abseil + URL https://github.com/abseil/abseil-cpp/releases/download/${P4C_ABSEIL_VERSION}/abseil-cpp-${P4C_ABSEIL_VERSION}.tar.gz + URL_HASH SHA256=3c743204df78366ad2eaf236d6631d83f6bc928d1705dd0000b872e53b73dc6a + USES_TERMINAL_DOWNLOAD TRUE + GIT_PROGRESS TRUE + ) + fetchcontent_makeavailable_but_exclude_install(abseil) + + # Suppress warnings for all Abseil targets. + get_all_targets(ABSL_BUILD_TARGETS ${absl_SOURCE_DIR}) + foreach(target ${ABSL_BUILD_TARGETS}) + if(target MATCHES "absl_*") + # Do not suppress warnings for Abseil library targets that are aliased. + get_target_property(target_type ${target} TYPE) + if (NOT ${target_type} STREQUAL "INTERFACE_LIBRARY") + # We need this workaround because of https://github.com/abseil/abseil-cpp/issues/1664. + # TODO: Remove once the Abseil compilation issue is fixed. + if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 14) + target_compile_options(${target} PUBLIC "-mbmi") + endif() + target_compile_options(${target} PRIVATE "-Wno-error" "-w") + endif() + endif() + endforeach() + # TODO: Remove once the Abseil compilation issue is fixed. + if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 14) + message(WARNING "Compiling with GCC > 14. Adding -mbmi to Abseil targets, this may cause incompatibility with old CPUs.") + endif() + + # Reset temporary variable modifications. + set(CMAKE_UNITY_BUILD ${CMAKE_UNITY_BUILD_PREV}) + set(FETCHCONTENT_QUIET ${FETCHCONTENT_QUIET_PREV}) + endif() + + message(STATUS "Done with setting up Abseil for P4C.") +endmacro(p4c_obtain_abseil) diff --git a/backends/tofino/bf-asm/cmake/config.h.in b/backends/tofino/bf-asm/cmake/config.h.in new file mode 100644 index 00000000000..acbd002ead2 --- /dev/null +++ b/backends/tofino/bf-asm/cmake/config.h.in @@ -0,0 +1,25 @@ +#ifndef __BFASM_CONFIG_H__ +#define __BFASM_CONFIG_H__ + +/* Define to 1 if you have the execinfo.h header */ +#cmakedefine HAVE_EXECINFO_H @HAVE_EXECINFO_H@ + +/* Define to 1 if you have the ucontext.h header */ +#cmakedefine HAVE_UCONTEXT_H @HAVE_UCONTEXT_H@ + + + +/* Define to 1 if we include JBay */ +#cmakedefine HAVE_JBAY @HAVE_JBAY@ + +/* Define to 1 if we include Tofino */ +#cmakedefine HAVE_TOFINO @HAVE_TOFINO@ + +/* Schema version */ +#cmakedefine CONTEXT_SCHEMA_VERSION "@CONTEXT_SCHEMA_VERSION@" + +/* define the version */ +#define TFAS_VERSION "${BFN_P4C_VERSION}" + + +#endif // __BFASM_CONFIG_H__ diff --git a/backends/tofino/bf-asm/constants.h b/backends/tofino/bf-asm/constants.h new file mode 100644 index 00000000000..374ef837287 --- /dev/null +++ b/backends/tofino/bf-asm/constants.h @@ -0,0 +1,242 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef CONSTANTS_H_ +#define CONSTANTS_H_ + +enum { + /* global constants related to MAU stage */ + LOGICAL_TABLES_PER_STAGE = 16, + PHYSICAL_TABLES_PER_STAGE = 16, + TCAM_TABLES_PER_STAGE = 8, + SRAM_ROWS = 8, + LOGICAL_SRAM_ROWS = 16, + SRAM_UNITS_PER_ROW = 12, + MAPRAM_UNITS_PER_ROW = 6, + MEM_WORD_WIDTH = 128, + SRAM_DEPTH_BITS = 10, + SRAM_DEPTH = 1 << SRAM_DEPTH_BITS, + LAMB_DEPTH_BITS = 6, + LAMB_DEPTH = 1 << LAMB_DEPTH_BITS, + TCAM_ROWS = 12, + TCAM_UNITS_PER_ROW = 2, + TCAM_XBAR_GROUPS = 12, + TCAM_XBAR_GROUP_SIZE = 44, + TCAM_XBAR_INPUT_BYTES = 68, + TCAM_VPN_BITS = 6, + TCAM_WORD_BITS = 9, + TCAM_FORMAT_WIDTH = 47, + TCAM_PAYLOAD_BITS = 1, + TCAM_PAYLOAD_BITS_START = 0, + TCAM_MATCH_BITS_START = TCAM_PAYLOAD_BITS_START + TCAM_PAYLOAD_BITS, + TCAM_PARITY_BITS = 2, + TCAM_PARITY_BITS_START = 45, + TCAM_VERSION_BITS = 2, + TCAM_VERSION_BITS_START = 43, + EXACT_XBAR_GROUPS = 8, + EXACT_XBAR_GROUP_SIZE = 128, + BYTE_XBAR_GROUPS = 8, + BYTE_XBAR_GROUP_SIZE = 8, + GALOIS_FIELD_MATRIX_COLUMNS = 52, + EXACT_HASH_GROUP_SIZE = 52, + EXACT_HASH_ADR_BITS = 10, + EXACT_HASH_ADR_GROUPS = 5, + EXACT_HASH_SELECT_BITS = 12, + EXACT_HASH_FIRST_SELECT_BIT = EXACT_HASH_GROUP_SIZE - EXACT_HASH_SELECT_BITS, + EXACT_VPN_BITS = 9, + EXACT_WORD_BITS = 10, + NEXT_TABLE_MAX_RAM_EXTRACT_BITS = 8, + MAX_LONGBRANCH_TAGS = 8, + MAX_IMMED_ACTION_DATA = 32, + ACTION_DATA_8B_SLOTS = 16, + ACTION_DATA_16B_SLOTS = 24, + ACTION_DATA_32B_SLOTS = 16, + ACTION_DATA_BUS_SLOTS = ACTION_DATA_8B_SLOTS + ACTION_DATA_16B_SLOTS + ACTION_DATA_32B_SLOTS, + ACTION_DATA_BUS_BYTES = + ACTION_DATA_8B_SLOTS + 2 * ACTION_DATA_16B_SLOTS + 4 * ACTION_DATA_32B_SLOTS, + ACTION_HV_XBAR_SLICES = 8, + ACTION_HV_XBAR_SLICE_SIZE = 16, + ACTION_INSTRUCTION_SUCCESSOR_TABLE_DEPTH = 8, + ACTION_INSTRUCTION_ADR_ENABLE = 0x40, + ACTION_IMEM_SLOTS = 32, + ACTION_IMEM_COLORS = 2, + ACTION_IMEM_ADDR_MAX = ACTION_IMEM_SLOTS * ACTION_IMEM_COLORS, + ACTION_ALWAYS_RUN_IMEM_ADDR = 63, + SELECTOR_PORTS_PER_WORD = 120, + STATEFUL_PREDICATION_ENCODE_NOOP = 0, + STATEFUL_PREDICATION_ENCODE_NOTCMPHI = 3, + STATEFUL_PREDICATION_ENCODE_NOTCMPLO = 5, + STATEFUL_PREDICATION_ENCODE_CMPLO = 0xaaaa, + STATEFUL_PREDICATION_ENCODE_CMPHI = 0xcccc, + STATEFUL_PREDICATION_ENCODE_CMP0 = 0xaaaa, + STATEFUL_PREDICATION_ENCODE_CMP1 = 0xcccc, + STATEFUL_PREDICATION_ENCODE_CMP2 = 0xf0f0, + STATEFUL_PREDICATION_ENCODE_CMP3 = 0xff00, + STATEFUL_PREDICATION_ENCODE_UNCOND = 0xffff, + STATEFUL_PREDICATION_OUTPUT = 6, + // See bf-drivers/include/pipe_mgr/pipe_mgr_intf.h for the definitions + TYPE_ENUM_SHIFT = 24, + PIPE_ID_SHIFT = 28, + REGISTER_PARAM_HANDLE_START = (0x08 << TYPE_ENUM_SHIFT), + ACTION_HANDLE_START = (0x20 << TYPE_ENUM_SHIFT), + FIELD_HANDLE_START = (0x9 << TYPE_ENUM_SHIFT), + PER_FLOW_ENABLE_BITS = 1, + METER_TYPE_BITS = 3, + // Order is METER_TYPE, METER_PFE, METER_ADDRESS + METER_TYPE_START_BIT = 24, + METER_LOWER_HUFFMAN_BITS = 7, + METER_ADDRESS_BITS = 23, + METER_FULL_ADDRESS_BITS = METER_ADDRESS_BITS + PER_FLOW_ENABLE_BITS + METER_TYPE_BITS, + METER_ADDRESS_ZERO_PAD = 23, + METER_PER_FLOW_ENABLE_START_BIT = 23, + IDLETIME_BUSSES = 20, + IDLETIME_BUSSES_PER_HALF = IDLETIME_BUSSES / 2, + IDLETIME_ADDRESS_PER_FLOW_ENABLE_START_BIT = 20, + IDLETIME_ADDRESS_BITS = 20, + IDLETIME_FULL_ADDRESS_BITS = IDLETIME_ADDRESS_BITS + PER_FLOW_ENABLE_BITS, + IDLETIME_ADDRESS_ZERO_PAD = 4, + IDLETIME_HUFFMAN_BITS = 4, + SELECTOR_METER_TYPE_START_BIT = METER_TYPE_START_BIT, + SELECTOR_LOWER_HUFFMAN_BITS = METER_LOWER_HUFFMAN_BITS, + SELECTOR_METER_ADDRESS_BITS = METER_ADDRESS_BITS, + SELECTOR_PER_FLOW_ENABLE_START_BIT = METER_PER_FLOW_ENABLE_START_BIT, + SELECTOR_VHXBAR_HASH_BUS_INDEX = 3, + SELECTOR_LENGTH_MOD_BITS = 5, + STAT_ADDRESS_BITS = 19, + STAT_FULL_ADDRESS_BITS = STAT_ADDRESS_BITS + PER_FLOW_ENABLE_BITS, + STAT_ADDRESS_ZERO_PAD = 7, + STAT_METER_COLOR_LOWER_HUFFMAN_BITS = 3, + STATISTICS_PER_FLOW_ENABLE_START_BIT = 19, + STATISTICS_PER_FLOW_SHIFT_COUNT = 7, + ACTION_ADDRESS_ZERO_PAD = 5, + ACTION_ADDRESS_BITS = 22, + ACTION_FULL_ADDRESS_BITS = 23, + ACTION_DATA_PER_FLOW_ENABLE_START_BIT = ACTION_ADDRESS_BITS, + ACTION_DATA_LOWER_HUFFMAN_BITS = 5, + ACTION_DATA_UPPER_HUFFMAN_BITS = 2, + ACTION_DATA_HUFFMAN_BITS = ACTION_DATA_LOWER_HUFFMAN_BITS + ACTION_DATA_UPPER_HUFFMAN_BITS, + ACTION_DATA_HUFFMAN_DIFFERENCE = 10, + MAX_PORTS = 288, + MAX_LRT_ENTRIES = 3, + UPPER_MATCH_CENTRAL_FIRST_ROW = SRAM_ROWS / 2, + UPPER_MATCH_CENTRAL_FIRST_LOGICAL_ROW = UPPER_MATCH_CENTRAL_FIRST_ROW * 2, + CHECKSUM_ENGINE_PHVID_TOFINO_LOW = 224, + CHECKSUM_ENGINE_PHVID_TOFINO_HIGH = 235, + CHECKSUM_ENGINE_PHVID_TOFINO_PER_GRESS = 6, + CONSTANTS_PHVID_JBAY_LOW = 224, + CONSTANTS_PHVID_JBAY_HIGH = 232, +}; + +enum METER_ACCESS_TYPE { + NOP = 0, + METER_LPF_COLOR_BLIND = 2, + METER_SELECTOR = 4, + METER_COLOR_AWARE = 6, + STATEFUL_INSTRUCTION_0 = 1, + STATEFUL_INSTRUCTION_1 = 3, + STATEFUL_INSTRUCTION_2 = 5, + STATEFUL_INSTRUCTION_3 = 7, + METER_COLOR_ACCESS = -1 // special for color mapram access +}; + +/* constants for various config params */ +#include +#undef OVERFLOW /* get rid of global preproc define from math.h */ +namespace UnitRam { +enum { + MATCH = 1, + ACTION = 2, + STATISTICS = 3, + METER = 4, + STATEFUL = 5, + TERNARY_INDIRECTION = 6, + SELECTOR = 7, + HASH_ACTION = 8, +}; +namespace DataMux { +enum { + STATISTICS = 0, + METER = 1, + OVERFLOW = 2, + OVERFLOW2 = 3, + ACTION = 4, + NONE = 7, +}; +} // namespace DataMux +namespace AdrMux { +enum { + ACTION = 1, + TERNARY_INDIRECTION = 2, + OVERFLOW = 4, + STATS_METERS = 5, + SELECTOR_ALU = 6, + SELECTOR_OVERFLOW = 7, + SELECTOR_ACTION_OVERFLOW = 8, +}; +} // namespace AdrMux +} // namespace UnitRam +namespace AdrDist { +enum { + ACTION = 0, + STATISTICS = 1, + METER = 2, + OVERFLOW = 3, +}; +} // namespace AdrDist +namespace MapRam { +enum { + STATISTICS = 1, + METER = 2, + STATEFUL = 3, + IDLETIME = 4, + COLOR = 5, + SELECTOR_SIZE = 6, +}; +namespace Mux { +enum { + SYSTEM = 0, + SYNTHETIC_TWO_PORT = 1, + IDLETIME = 2, + COLOR = 3, +}; +} // namespace Mux +namespace ColorBus { +enum { + NONE = 0, + COLOR = 1, + OVERFLOW = 2, + OVERFLOW_2 = 3, +}; +} // namespace ColorBus +} // namespace MapRam +namespace BusHashGroup { +enum { + SELECTOR_MOD = 0, + METER_ADDRESS = 1, + STATISTICS_ADDRESS = 2, + ACTION_DATA_ADDRESS = 3, + IMMEDIATE_DATA = 4, +}; +} // namespace BusHashGroup +namespace MoveReg { +enum { + STATS = 0, + METER = 1, + IDLE = 2, +}; +} // namespace MoveReg +#endif /* CONSTANTS_H_ */ diff --git a/backends/tofino/bf-asm/counter.cpp b/backends/tofino/bf-asm/counter.cpp new file mode 100644 index 00000000000..ca9d310f956 --- /dev/null +++ b/backends/tofino/bf-asm/counter.cpp @@ -0,0 +1,406 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "algorithm.h" +#include "data_switchbox.h" +#include "input_xbar.h" +#include "misc.h" +#include "stage.h" +#include "tables.h" + +// target specific template specializations +#include "tofino/counter.h" +#if HAVE_JBAY +#include "jbay/counter.h" +#endif /* HAVE_JBAY */ + +void CounterTable::setup(VECTOR(pair_t) & data) { + common_init_setup(data, false, P4Table::Statistics); + if (!format) error(lineno, "No format specified in table %s", name()); + for (auto &kv : MapIterChecked(data, true)) { + if (common_setup(kv, data, P4Table::Statistics)) { + } else if (kv.key == "count") { + if (kv.value == "bytes") + type = BYTES; + else if (kv.value == "packets") + type = PACKETS; + else if (kv.value == "both" || kv.value == "packets_and_bytes") + type = BOTH; + else + error(kv.value.lineno, "Unknown counter type %s", value_desc(kv.value)); + } else if (kv.key == "teop") { + if (gress != EGRESS) error(kv.value.lineno, "tEOP can only be used in EGRESS"); + if (!Target::SUPPORT_TRUE_EOP()) + error(kv.value.lineno, "tEOP is not available on device"); + if (CHECKTYPE(kv.value, tINT)) { + teop = kv.value.i; + if (teop < 0 || teop > 3) + error(kv.value.lineno, "Invalid tEOP bus %d, valid values are 0-3", teop); + BUG_CHECK(!stage->teop[teop].first, + "previously used tEOP bus %d used again in stage %d", teop, + stage->stageno); + stage->teop[teop] = {true, stage->stageno}; + } + } else if (kv.key == "lrt") { + if (!CHECKTYPE2(kv.value, tVEC, tMAP)) continue; + collapse_list_of_maps(kv.value, true); + if (kv.value.type == tVEC) { + for (auto &el : kv.value.vec) lrt.emplace_back(el); + } else if (kv.value.map.size >= 1 && kv.value.map[0].key.type == tSTR) { + lrt.emplace_back(kv.value); + } else { + for (auto &el : kv.value.map) { + if (CHECKTYPE2(el.key, tINT, tBIGINT) && CHECKTYPE(el.value, tINT)) { + lrt.emplace_back(el.key.lineno, + get_int64(el.key, 64, "Threshold too large"), el.value.i); + } + } + } + } else if (kv.key == "bytecount_adjust") { + if (CHECKTYPE(kv.value, tINT)) { + bytecount_adjust = kv.value.i; + } + } else { + warning(kv.key.lineno, "ignoring unknown item %s in table %s", value_desc(kv.key), + name()); + } + } + if (teop >= 0 && type != BYTES && type != BOTH) + error(lineno, "tEOP bus can only used when counting bytes"); + if (Target::SRAM_GLOBAL_ACCESS()) + alloc_global_srams(); + else + alloc_rams(true, stage->sram_use); +} + +CounterTable::lrt_params::lrt_params(const value_t &m) + : lineno(m.lineno), threshold(-1), interval(-1) { + if (CHECKTYPE(m, tMAP)) { + for (auto &kv : MapIterChecked(m.map, true)) { + if (kv.key == "threshold") { + if (CHECKTYPE2(kv.value, tINT, tBIGINT)) + threshold = get_int64(kv.value, 64, "Threshold too large"); + } else if (kv.key == "interval") { + if (CHECKTYPE(kv.value, tINT)) interval = kv.value.i; + } else { + warning(kv.key.lineno, "ignoring unknown item %s in lrt params", + value_desc(kv.key)); + } + } + if (threshold < 0) error(m.lineno, "No threshold in lrt params"); + if (interval < 0) error(m.lineno, "No interval in lrt params"); + } +} + +void CounterTable::pass1() { + LOG1("### Counter table " << name() << " pass1 " << loc()); + if (!p4_table) + p4_table = P4Table::alloc(P4Table::Statistics, this); + else + p4_table->check(this); + alloc_vpns(); + alloc_maprams(); + std::sort(layout.begin(), layout.end(), + [](const Layout &a, const Layout &b) -> bool { return a.row > b.row; }); + // stage->table_use[timing_thread(gress)] |= Stage::USE_SELECTOR; + int prev_row = -1; + for (auto &row : layout) { + if (home_rows.count(row.row)) prev_row = -1; + + if (prev_row >= 0) + need_bus(lineno, stage->overflow_bus_use, row.row, "Overflow"); + else + need_bus(lineno, stage->stats_bus_use, row.row, "Statistics data"); + for (int r = (row.row + 1) | 1; r < prev_row; r += 2) + need_bus(lineno, stage->overflow_bus_use, r, "Overflow"); + prev_row = row.row; + } + Synth2Port::pass1(); + int update_interval_bits = 29; + // Tofino didn't have enough bits to cover all possible values of + // the update interval. The compiler should have saturated it to + // the max value. Check that has been done here. + if (options.target == TOFINO) update_interval_bits = 28; + for (auto &l : lrt) { + if (l.interval >= (1 << update_interval_bits)) + error(l.lineno, "lrt update interval too large"); + } + if (lrt.size() > MAX_LRT_ENTRIES) + error(lrt[0].lineno, "Too many lrt entries (max %d)", MAX_LRT_ENTRIES); +} + +void CounterTable::pass2() { + LOG1("### Counter table " << name() << " pass2 " << loc()); + if (logical_id < 0) warning(lineno, "counter %s appears unused by any table", name()); +} + +void CounterTable::pass3() { LOG1("### Counter table " << name() << " pass3 " << loc()); } + +static int counter_size[] = {0, 0, 1, 2, 3, 0, 4}; +static int counter_masks[] = {0, 7, 3, 4, 1, 0, 0}; +static int counter_shifts[] = {0, 3, 2, 3, 1, 0, 2}; +static int counter_hole_swizzle[] = {0, 0, 0, 1, 0, 0, 2}; + +int CounterTable::direct_shiftcount() const { + return 64 + STAT_ADDRESS_ZERO_PAD - counter_shifts[format->groups()]; +} + +int CounterTable::indirect_shiftcount() const { + return STAT_ADDRESS_ZERO_PAD - counter_shifts[format->groups()]; +} + +int CounterTable::address_shift() const { return counter_shifts[format->groups()]; } + +unsigned CounterTable::determine_shiftcount(Table::Call &call, int group, unsigned word, + int tcam_shift) const { + if (call.args[0].name() && strcmp(call.args[0].name(), "$DIRECT") == 0) { + return direct_shiftcount() + tcam_shift; + } else if (call.args[0].field()) { + BUG_CHECK(unsigned(call.args[0].field()->by_group[group]->bit(0) / 128) == word); + return call.args[0].field()->by_group[group]->bit(0) % 128 + indirect_shiftcount(); + } else if (call.args[1].field()) { + return call.args[1].field()->by_group[group]->bit(0) % 128 + STAT_ADDRESS_ZERO_PAD; + } + return 0; +} + +template +void CounterTable::write_merge_regs_vt(REGS ®s, MatchTable *match, int type, int bus, + const std::vector &args) { + auto &merge = regs.rams.match.merge; + unsigned adr_mask = 0; + unsigned per_entry_en_mux_ctl = 0; + unsigned adr_default = 0; + + if (args[0].type == Table::Call::Arg::Name && args[0].name() != nullptr && + strcmp(args[0].name(), "$DIRECT") == 0) { + adr_mask |= ((1U << STAT_ADDRESS_BITS) - 1) & ~counter_masks[format->groups()]; + } else if (args[0].type == Table::Call::Arg::Field && args[0].field() != nullptr) { + auto addr = args[0].field(); + auto address_bits = addr->size; + adr_mask |= ((1U << address_bits) - 1) << (counter_shifts[format->groups()]); + } + + if (args[1].type == Table::Call::Arg::Name && args[1].name() != nullptr && + strcmp(args[1].name(), "$DEFAULT") == 0) { + adr_default = (1U << STATISTICS_PER_FLOW_ENABLE_START_BIT); + } else if (args[1].type == Table::Call::Arg::Field) { + if (args[0].type == Table::Call::Arg::Field) { + per_entry_en_mux_ctl = args[1].field()->bit(0) - args[0].field()->bit(0); + per_entry_en_mux_ctl += counter_shifts[format->groups()]; + } else if (args[0].type == Table::Call::Arg::HashDist) { + per_entry_en_mux_ctl = 0; + } + } + + merge.mau_stats_adr_mask[type][bus] = adr_mask; + merge.mau_stats_adr_default[type][bus] = adr_default; + merge.mau_stats_adr_per_entry_en_mux_ctl[type][bus] = per_entry_en_mux_ctl; + merge.mau_stats_adr_hole_swizzle_mode[type][bus] = counter_hole_swizzle[format->groups()]; +} + +template +void CounterTable::write_regs_vt(REGS ®s) { + LOG1("### Counter table " << name() << " write_regs " << loc()); + // FIXME -- factor common AttachedTable::write_regs + // FIXME -- factor common Synth2Port::write_regs + // FIXME -- factor common MeterTable::write_regs + Layout *home = nullptr; + bool push_on_overflow = false; + auto &map_alu = regs.rams.map_alu; + auto &adrdist = regs.rams.match.adrdist; + DataSwitchboxSetup *swbox = nullptr; + std::vector stats_groups; + int minvpn, maxvpn; + + layout_vpn_bounds(minvpn, maxvpn, true); + for (Layout &logical_row : layout) { + unsigned row = logical_row.row / 2U; + unsigned side = logical_row.row & 1; /* 0 == left 1 == right */ + BUG_CHECK(side == 1); /* no map rams or alus on left side anymore */ + /* FIXME factor vpn/mapram stuff with selection.cpp */ + auto vpn = logical_row.vpns.begin(); + auto mapram = logical_row.maprams.begin(); + auto &map_alu_row = map_alu.row[row]; + auto home_it = home_rows.find(logical_row.row); + if (home_it != home_rows.end()) { + home = &logical_row; + swbox = new DataSwitchboxSetup(regs, this, logical_row.row, + (++home_it == home_rows.end()) ? -1 : *home_it); + + stats_groups.push_back(swbox->get_home_row() / 2); + + if (swbox->get_home_row() != row) swbox->setup_row(swbox->get_home_row()); + } + BUG_CHECK(home != nullptr); + LOG2("# DataSwitchbox.setup(" << row << ") home=" << home->row / 2U); + swbox->setup_row(row); + for (auto &memunit : logical_row.memunits) { + int logical_col = memunit.col; + unsigned col = logical_col + 6 * side; + swbox->setup_row_col(row, col, *vpn); + write_mapram_regs(regs, row, *mapram, *vpn, MapRam::STATISTICS); + if (gress) regs.cfg_regs.mau_cfg_uram_thread[col / 4U] |= 1U << (col % 4U * 8U + row); + ++mapram, ++vpn; + } + if (&logical_row == home) { + int stats_group_index = swbox->get_home_row() / 2; + auto &stats = map_alu.stats_wrap[stats_group_index].stats; + auto &stat_ctl = stats.statistics_ctl; + stat_ctl.stats_entries_per_word = format->groups(); + if (type & BYTES) stat_ctl.stats_process_bytes = 1; + if (type & PACKETS) stat_ctl.stats_process_packets = 1; + // The configuration values for threshold and interval are passed + // in directly to the assembler. Any adjustment required based + // on the counter type has already been done. + if (lrt.size() > 0) { + stat_ctl.lrt_enable = 1; + int idx = 0; + for (auto &l : lrt) { + stats.lrt_threshold[idx] = l.threshold; + stats.lrt_update_interval[idx] = l.interval; + ++idx; + } + } + stat_ctl.stats_alu_egress = timing_thread(gress); + if (type == BYTES || type == BOTH) { + auto stats_bytecount_adjust_size = stat_ctl.stats_bytecount_adjust.size(); + auto stats_bytecount_adjust_mask = ((1U << stats_bytecount_adjust_size) - 1); + int bytecount_adjust_max = (1U << (stats_bytecount_adjust_size - 1)) - 1; + int bytecount_adjust_min = -1 * (1U << (stats_bytecount_adjust_size - 1)); + if (bytecount_adjust > bytecount_adjust_max || + bytecount_adjust < bytecount_adjust_min) { + error(lineno, + "The bytecount adjust value of %d on counter %s " + "does not fit within allowed range for %d bits - { %d, %d }", + bytecount_adjust, name(), stats_bytecount_adjust_size, + bytecount_adjust_min, bytecount_adjust_max); + } + stat_ctl.stats_bytecount_adjust = bytecount_adjust & stats_bytecount_adjust_mask; + } + stat_ctl.stats_alu_error_enable = 0; // TODO + if (logical_id >= 0) regs.cfg_regs.mau_cfg_stats_alu_lt[stats_group_index] = logical_id; + // setup_muxctl(adrdist.stats_alu_phys_to_logical_ixbar_ctl[row/2], logical_id); + map_alu_row.i2portctl.synth2port_vpn_ctl.synth2port_vpn_base = minvpn; + map_alu_row.i2portctl.synth2port_vpn_ctl.synth2port_vpn_limit = maxvpn; + } else { + auto &adr_ctl = map_alu_row.vh_xbars.adr_dist_oflo_adr_xbar_ctl[side]; + if (swbox->get_home_row_logical() >= 8 && logical_row.row < 8) { + adr_ctl.adr_dist_oflo_adr_xbar_source_index = 0; + adr_ctl.adr_dist_oflo_adr_xbar_source_sel = AdrDist::OVERFLOW; + push_on_overflow = true; + BUG_CHECK(options.target == TOFINO); + } else { + adr_ctl.adr_dist_oflo_adr_xbar_source_index = swbox->get_home_row_logical() % 8; + adr_ctl.adr_dist_oflo_adr_xbar_source_sel = AdrDist::STATISTICS; + } + adr_ctl.adr_dist_oflo_adr_xbar_enable = 1; + } + } + bool run_at_eop = this->run_at_eop(); + if (home_rows.size() > 1) write_alu_vpn_range(regs); + + BUG_CHECK(stats_groups.size() == home_rows.size()); + bool first_stats_group = true; + for (int &idx : stats_groups) { + auto &movereg_stats_ctl = adrdist.movereg_stats_ctl[idx]; + for (MatchTable *m : match_tables) { + run_at_eop = run_at_eop || m->run_at_eop(); + adrdist.adr_dist_stats_adr_icxbar_ctl[m->logical_id] |= 1U << idx; + auto &dump_ctl = regs.cfg_regs.stats_dump_ctl[m->logical_id]; + dump_ctl.stats_dump_entries_per_word = format->groups(); + if (type == BYTES || type == BOTH) dump_ctl.stats_dump_has_bytes = 1; + if (type == PACKETS || type == BOTH) dump_ctl.stats_dump_has_packets = 1; + dump_ctl.stats_dump_offset = minvpn; + dump_ctl.stats_dump_size = maxvpn; + if (direct) { + adrdist.movereg_ad_direct[MoveReg::STATS] |= 1U << m->logical_id; + if (m->is_ternary()) movereg_stats_ctl.movereg_stats_ctl_tcam = 1; + } + movereg_stats_ctl.movereg_stats_ctl_lt = m->logical_id; + // The first ALU will drive this xbar register + if (first_stats_group) { + adrdist.movereg_ad_stats_alu_to_logical_xbar_ctl[m->logical_id / 8U].set_subfield( + 4 + idx, 3 * (m->logical_id % 8U), 3); + } + adrdist.mau_ad_stats_virt_lt[idx] |= 1U << m->logical_id; + } + movereg_stats_ctl.movereg_stats_ctl_size = counter_size[format->groups()]; + movereg_stats_ctl.movereg_stats_ctl_direct = direct; + if (run_at_eop) { + if (teop >= 0) { + setup_teop_regs(regs, idx); + } else { + adrdist.deferred_ram_ctl[MoveReg::STATS][idx].deferred_ram_en = 1; + adrdist.deferred_ram_ctl[MoveReg::STATS][idx].deferred_ram_thread = gress; + if (gress) regs.cfg_regs.mau_cfg_dram_thread |= 1 << idx; + movereg_stats_ctl.movereg_stats_ctl_deferred = 1; + } + adrdist.stats_bubble_req[timing_thread(gress)].bubble_req_1x_class_en |= 1 << (4 + idx); + } else { + adrdist.packet_action_at_headertime[0][idx] = 1; + adrdist.stats_bubble_req[timing_thread(gress)].bubble_req_1x_class_en |= 1 << idx; + } + if (push_on_overflow) { + adrdist.deferred_oflo_ctl = 1 << ((home->row - 8) / 2U); + adrdist.oflo_adr_user[0] = adrdist.oflo_adr_user[1] = AdrDist::STATISTICS; + } + first_stats_group = false; + } +} + +void CounterTable::gen_tbl_cfg(json::vector &out) const { + // FIXME -- factor common Synth2Port stuff + auto spare_mems = determine_spare_bank_memory_units(); + int size = (layout_size() - spare_mems.size()) * SRAM_DEPTH * format->groups(); + json::map &tbl = *base_tbl_cfg(out, "statistics", size); + json::map &stage_tbl = *add_stage_tbl_cfg(tbl, "statistics", size); + if (home_rows.size() > 1) + add_alu_indexes(stage_tbl, "stats_alu_index"); + else + add_alu_index(stage_tbl, "stats_alu_index"); + tbl["enable_pfe"] = per_flow_enable; + tbl["pfe_bit_position"] = per_flow_enable_bit(); + if (auto *f = lookup_field("bytes")) + tbl["byte_counter_resolution"] = f->size; + else + tbl["byte_counter_resolution"] = INT64_C(0); + if (auto *f = lookup_field("packets")) + tbl["packet_counter_resolution"] = f->size; + else + tbl["packet_counter_resolution"] = INT64_C(0); + switch (type) { + case PACKETS: + tbl["statistics_type"] = "packets"; + break; + case BYTES: + tbl["statistics_type"] = "bytes"; + break; + case BOTH: + tbl["statistics_type"] = "packets_and_bytes"; + break; + default: + break; + } + if (context_json) stage_tbl.merge(*context_json); +} + +DEFINE_TABLE_TYPE_WITH_SPECIALIZATION(CounterTable, TARGET_CLASS) +FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void CounterTable::write_merge_regs, + (mau_regs & regs, MatchTable *match, int type, int bus, + const std::vector &args), + { write_merge_regs_vt(regs, match, type, bus, args); }) diff --git a/backends/tofino/bf-asm/crash.cpp b/backends/tofino/bf-asm/crash.cpp new file mode 100644 index 00000000000..bccab36eb3a --- /dev/null +++ b/backends/tofino/bf-asm/crash.cpp @@ -0,0 +1,280 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#if HAVE_EXECINFO_H +#include +#endif +#include +#include +#include +#include + +#include +#if HAVE_UCONTEXT_H +#include +#endif +#include + +#include + +#include "bfas.h" +#include "exename.h" +#include "hex.h" +#include "log.h" + +using namespace P4; + +static const char *signames[] = { + "NONE", "HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", "BUS", "FPE", "KILL", "USR1", + "SEGV", "USR2", "PIPE", "ALRM", "TERM", "STKFLT", "CHLD", "CONT", "STOP", "TSTP", "TTIN", + "TTOU", "URG", "XCPU", "XFSZ", "VTALRM", "PROF", "WINCH", "POLL", "PWR", "SYS"}; + +char *program_name = nullptr; + +#ifdef MULTITHREAD +#include + +#include +std::vector thread_ids; +__thread int my_id; + +void register_thread() { + static std::mutex lock; + std::lock_guard acquire(lock); + my_id = thread_ids.size(); + thread_ids.push_back(pthread_self()); +} +#define MTONLY(...) __VA_ARGS__ +#else +#define MTONLY(...) +#endif // MULTITHREAD + +static MTONLY(__thread) int shutdown_loop = 0; // avoid infinite loop if shutdown crashes + +static void sigint_shutdown(int sig, siginfo_t *, void *) { + if (shutdown_loop++) _exit(-1); + LOG1("Exiting with SIG" << signames[sig]); + _exit(sig + 0x80); +} + +/* + * call external program addr2line WITHOUT using malloc or stdio or anything + * else that might be problematic if there's memory corruption or exhaustion + */ +const char *addr2line(void *addr, const char *text) { + MTONLY(static std::mutex lock; std::lock_guard acquire(lock);) + static pid_t child = 0; + static int to_child, from_child; + static char binary[PATH_MAX]; + static char buffer[PATH_MAX]; + const char *t; + + if (!text || !(t = strchr(text, '('))) { + text = exename(program_name); + t = text + strlen(text); + } + memcpy(buffer, text, t - text); + buffer[t - text] = 0; + if (child && strcmp(binary, buffer)) { + child = 0; + close(to_child); + close(from_child); + } + memcpy(binary, buffer, (t - text) + 1); + text = binary; + if (!child) { + int pfd1[2], pfd2[2]; + char *p = buffer; + const char *argv[4] = {"/bin/sh", "-c", buffer, 0}; + strcpy(p, "addr2line "); + p += strlen(p); // NOLINT + strcpy(p, " -Cfspe "); + p += strlen(p); // NOLINT + t = text + strlen(text); + if (!memchr(text, '/', t - text)) { + strcpy(p, "$(which "); + p += strlen(p); + } // NOLINT + memcpy(p, text, t - text); + p += t - text; + if (!memchr(text, '/', t - text)) *p++ = ')'; + *p = 0; + child = -1; +#if HAVE_PIPE2 + if (pipe2(pfd1, O_CLOEXEC) < 0) return 0; + if (pipe2(pfd2, O_CLOEXEC) < 0) return 0; +#else + if (pipe(pfd1) < 0) return 0; + if (pipe(pfd2) < 0) return 0; + fcntl(pfd1[0], F_SETFD, FD_CLOEXEC | fcntl(pfd1[0], F_GETFL)); + fcntl(pfd1[1], F_SETFD, FD_CLOEXEC | fcntl(pfd1[1], F_GETFL)); + fcntl(pfd2[0], F_SETFD, FD_CLOEXEC | fcntl(pfd2[0], F_GETFL)); + fcntl(pfd2[1], F_SETFD, FD_CLOEXEC | fcntl(pfd2[1], F_GETFL)); +#endif + while ((child = fork()) == -1 && errno == EAGAIN) { + } + if (child == -1) return 0; + if (child == 0) { + dup2(pfd1[1], 1); + dup2(pfd1[1], 2); + dup2(pfd2[0], 0); + execvp(argv[0], (char *const *)argv); + _exit(-1); + } + close(pfd1[1]); + from_child = pfd1[0]; + close(pfd2[0]); + to_child = pfd2[1]; + } + if (child == -1) return 0; + char *p = buffer; + uintptr_t a = (uintptr_t)addr; + int shift = (CHAR_BIT * sizeof(uintptr_t) - 1) & ~3; + while (shift > 0 && (a >> shift) == 0) shift -= 4; + while (shift >= 0) { + *p++ = "0123456789abcdef"[(a >> shift) & 0xf]; + shift -= 4; + } + *p++ = '\n'; + auto _unused = write(to_child, buffer, p - buffer); + (void)_unused; + p = buffer; + int len; + while (p < buffer + sizeof(buffer) - 1 && + (len = read(from_child, p, buffer + sizeof(buffer) - p - 1)) > 0 && (p += len) && + !memchr(p - len, '\n', len)) { + } + *p = 0; + if ((p = strchr(buffer, '\n'))) *p = 0; + if (buffer[0] == 0 || buffer[0] == '?') return 0; + return buffer; +} + +#if HAVE_UCONTEXT_H +static void dumpregs(mcontext_t *mctxt) { +#if defined(REG_EAX) + LOG1(" eax=" << P4::hex(mctxt->gregs[REG_EAX], 8, '0') + << " ebx=" << P4::hex(mctxt->gregs[REG_EBX], 8, '0') + << " ecx=" << P4::hex(mctxt->gregs[REG_ECX], 8, '0') + << " edx=" << P4::hex(mctxt->gregs[REG_EDX], 8, '0')); + LOG1(" edi=" << P4::hex(mctxt->gregs[REG_EDI], 8, '0') + << " esi=" << P4::hex(mctxt->gregs[REG_ESI], 8, '0') + << " ebp=" << P4::hex(mctxt->gregs[REG_EBP], 8, '0') + << " esp=" << P4::hex(mctxt->gregs[REG_ESP], 8, '0')); +#elif defined(REG_RAX) + LOG1(" rax=" << P4::hex(mctxt->gregs[REG_RAX], 16, '0') + << " rbx=" << P4::hex(mctxt->gregs[REG_RBX], 16, '0') + << " rcx=" << P4::hex(mctxt->gregs[REG_RCX], 16, '0')); + LOG1(" rdx=" << P4::hex(mctxt->gregs[REG_RDX], 16, '0') + << " rdi=" << P4::hex(mctxt->gregs[REG_RDI], 16, '0') + << " rsi=" << P4::hex(mctxt->gregs[REG_RSI], 16, '0')); + LOG1(" rbp=" << P4::hex(mctxt->gregs[REG_RBP], 16, '0') + << " rsp=" << P4::hex(mctxt->gregs[REG_RSP], 16, '0') + << " r8=" << P4::hex(mctxt->gregs[REG_R8], 16, '0')); + LOG1(" r9=" << P4::hex(mctxt->gregs[REG_R9], 16, '0') + << " r10=" << P4::hex(mctxt->gregs[REG_R10], 16, '0') + << " r11=" << P4::hex(mctxt->gregs[REG_R11], 16, '0')); + LOG1(" r12=" << P4::hex(mctxt->gregs[REG_R12], 16, '0') + << " r13=" << P4::hex(mctxt->gregs[REG_R13], 16, '0') + << " r14=" << P4::hex(mctxt->gregs[REG_R14], 16, '0')); + LOG1(" r15=" << P4::hex(mctxt->gregs[REG_R15], 16, '0')); +#elif defined(__i386__) + LOG1(" eax=" << P4::hex(mctxt->mc_eax, 8, '0') << " ebx=" << P4::hex(mctxt->mc_ebx, 8, '0') + << " ecx=" << P4::hex(mctxt->mc_ecx, 8, '0') + << " edx=" << P4::hex(mctxt->mc_edx, 8, '0')); + LOG1(" edi=" << P4::hex(mctxt->mc_edi, 8, '0') << " esi=" << P4::hex(mctxt->mc_esi, 8, '0') + << " ebp=" << P4::hex(mctxt->mc_ebp, 8, '0') + << " esp=" << P4::hex(mctxt->mc_esp, 8, '0')); +#elif defined(__amd64__) + LOG1(" rax=" << P4::hex(mctxt->mc_rax, 16, '0') << " rbx=" << P4::hex(mctxt->mc_rbx, 16, '0') + << " rcx=" << P4::hex(mctxt->mc_rcx, 16, '0')); + LOG1(" rdx=" << P4::hex(mctxt->mc_rdx, 16, '0') << " rdi=" << P4::hex(mctxt->mc_rdi, 16, '0') + << " rsi=" << P4::hex(mctxt->mc_rsi, 16, '0')); + LOG1(" rbp=" << P4::hex(mctxt->mc_rbp, 16, '0') << " rsp=" << P4::hex(mctxt->mc_rsp, 16, '0') + << " r8=" << P4::hex(mctxt->mc_r8, 16, '0')); + LOG1(" r9=" << P4::hex(mctxt->mc_r9, 16, '0') << " r10=" << P4::hex(mctxt->mc_r10, 16, '0') + << " r11=" << P4::hex(mctxt->mc_r11, 16, '0')); + LOG1(" r12=" << P4::hex(mctxt->mc_r12, 16, '0') << " r13=" << P4::hex(mctxt->mc_r13, 16, '0') + << " r14=" << P4::hex(mctxt->mc_r14, 16, '0')); + LOG1(" r15=" << P4::hex(mctxt->mc_r15, 16, '0')); +#else +#warning "unknown machine type" +#endif +} +#endif + +static void crash_shutdown(int sig, siginfo_t *info, void *uctxt) { + if (shutdown_loop++) _exit(-1); + MTONLY(static std::recursive_mutex lock; static int threads_dumped = 0; + static bool killed_all_threads = false; lock.lock(); if (!killed_all_threads) { + killed_all_threads = true; + for (int i = 0; i < int(thread_ids.size()); i++) + if (i != my_id - 1) { + pthread_kill(thread_ids[i], SIGABRT); + } + }) + LOG1(MTONLY("Thread #" << my_id << " " <<) "exiting with SIG" << signames[sig] << ", trace:"); + if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS || sig == SIGTRAP) + LOG1(" address = " << hex(info->si_addr)); +#if HAVE_UCONTEXT_H + dumpregs(&(static_cast(uctxt)->uc_mcontext)); +#else + (void)uctxt; // Suppress unused parameter warning. +#endif +#if HAVE_EXECINFO_H + if (LOGGING(1)) { + static void *buffer[64]; + int size = backtrace(buffer, 64); + char **strings = backtrace_symbols(buffer, size); + for (int i = 1; i < size; i++) { + if (strings) LOG1(" " << strings[i]); + if (const char *line = addr2line(buffer[i], strings ? strings[i] : 0)) + LOG1(" " << line); + } + if (size < 1) LOG1("backtrace failed"); + free(strings); + } +#endif + MTONLY( + if (++threads_dumped < int(thread_ids.size())) { + lock.unlock(); + pthread_exit(0); + } else { lock.unlock(); }) + if (sig != SIGABRT) BUG("Exiting with SIG%s", signames[sig]); + _exit(sig + 0x80); +} + +void register_exit_signals() { + struct sigaction sigact; + sigact.sa_sigaction = sigint_shutdown; + sigact.sa_flags = SA_SIGINFO; + sigemptyset(&sigact.sa_mask); + sigaction(SIGHUP, &sigact, 0); + sigaction(SIGINT, &sigact, 0); + sigaction(SIGQUIT, &sigact, 0); + sigaction(SIGTERM, &sigact, 0); + sigact.sa_sigaction = crash_shutdown; + sigaction(SIGILL, &sigact, 0); + sigaction(SIGABRT, &sigact, 0); + sigaction(SIGFPE, &sigact, 0); + sigaction(SIGSEGV, &sigact, 0); + sigaction(SIGBUS, &sigact, 0); + sigaction(SIGTRAP, &sigact, 0); + signal(SIGPIPE, SIG_IGN); +} diff --git a/backends/tofino/bf-asm/data_switchbox.h b/backends/tofino/bf-asm/data_switchbox.h new file mode 100644 index 00000000000..f54c06b4740 --- /dev/null +++ b/backends/tofino/bf-asm/data_switchbox.h @@ -0,0 +1,168 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_DATA_SWITCHBOX_H_ +#define BF_ASM_DATA_SWITCHBOX_H_ + +#include "stage.h" +#include "tables.h" + +/* + * Code to handle programming of the Ram Data Bus Horizontal/Vertical Switchbox + * see section 6.2.4.4 of the MAU uArch docs + */ + +template +class DataSwitchboxSetup { + REGS ®s; + Table *tbl; + unsigned home_row, home_row_logical, prev_row, top_ram_row, bottom_ram_row; + + public: + unsigned get_home_row() { return home_row; } + unsigned get_home_row_logical() { return home_row_logical; } + DataSwitchboxSetup(REGS ®s, Table *t, int home = -1, int next_home = -1) + : regs(regs), tbl(t) { + if (home >= 0) + top_ram_row = prev_row = home_row = home / 2U; + else + top_ram_row = prev_row = home_row = tbl->layout[0].row / 2U; + bottom_ram_row = tbl->layout.back().row / 2U; + if (next_home >= 0) { + for (auto it = tbl->layout.rbegin(); it != tbl->layout.rend(); ++it) { + if (it->row > next_home) { + bottom_ram_row = it->row / 2U; + break; + } + } + } + + // Counter ALU's are on even rows on right side of RAM array. Set + // home_row to the correct ALU + if (tbl->table_type() == Table::COUNTER) + prev_row = home_row = prev_row % 2 ? prev_row + 1 : prev_row; + // Stateful/Selection/Meter ALU's are on odd rows on right side of RAM + // array. Set home_row to the correct ALU + else if (tbl->table_type() == Table::STATEFUL || tbl->table_type() == Table::SELECTION || + tbl->table_type() == Table::METER) + prev_row = home_row = prev_row % 2 ? prev_row : prev_row + 1; + home_row_logical = home_row * 2 + 1; + } + /** + * Responsible for the data hv switch box per row, as well as the fabric_ctl. At a high + * level, the fabric ctl is an optimized version of the fabric_ctl in order to manage + * some of the timing issues. + * + * Operates under the assumption that all rows in the layout are numerically highest to lowest. + * Information has to flow up to the home row, and flow down to the lowest row. Should not + * flow above the homerow and below the lowest row + */ + void setup_row(unsigned row) { + auto &map_alu = regs.rams.map_alu; + auto &swbox = regs.rams.array.switchbox.row; + auto &map_alu_row = map_alu.row[row]; + int side = 1; // always -- currently no maprams on left side + auto &syn2port_ctl = map_alu_row.i2portctl.synth2port_fabric_ctl[0][side]; + map_alu_row.i2portctl.synth2port_ctl.synth2port_enable = 1; + while (prev_row != row) { + auto &prev_syn2port_ctl = map_alu.row[prev_row].i2portctl.synth2port_fabric_ctl[0]; + if (prev_row == home_row) { + swbox[prev_row].ctl.r_stats_alu_o_mux_select.r_stats_alu_o_sel_oflo_rd_b_i = 1; + swbox[prev_row].ctl.b_oflo_wr_o_mux_select.b_oflo_wr_o_sel_stats_wr_r_i = 1; + prev_syn2port_ctl[side].stats_to_vbus_below = 1; + } else { + // If a row is in the middle of possible rows, must program the switchbox + // to have data pass through the bottom of the switch box to the top of + // the switchbox + swbox[prev_row].ctl.t_oflo_rd_o_mux_select.t_oflo_rd_o_sel_oflo_rd_b_i = 1; + swbox[prev_row].ctl.b_oflo_wr_o_mux_select.b_oflo_wr_o_sel_oflo_wr_t_i = 1; + // below2above only means that there is no synth2port RAMs on this row, but + // the signal needs to pass between the rows + prev_syn2port_ctl[side].synth2port_connect_below2above = 1; + /* need to also program left side below2above connections + * see ram_bus_path.py:254 -- 'Mike F.' comment */ + prev_syn2port_ctl[0].synth2port_connect_below2above = 1; + prev_syn2port_ctl[side].oflo_to_vbus_below = 1; + } + auto &next_syn2port_ctl = + map_alu.row[prev_row - 1].i2portctl.synth2port_fabric_ctl[0][side]; + // From RTL, it only appears that oflo_to_vbus_below/above should be programmed + // when RAMs appear on the RAM line, but the model asserts if these are not enabled. + // Keeping this, as it is what is DV'ed against + next_syn2port_ctl.oflo_to_vbus_above = 1; + prev_row--; + } + // FIXME: Should this be top_ram_row? + if (row == home_row) { + swbox[row].ctl.r_stats_alu_o_mux_select.r_stats_alu_o_sel_stats_rd_r_i = 1; + } else { + // The oflo signal of this row must go through the overflow bus + swbox[row].ctl.t_oflo_rd_o_mux_select.t_oflo_rd_o_sel_oflo_rd_r_i = 1; + swbox[row].ctl.r_oflo_wr_o_mux_select = 1; + syn2port_ctl.synth2port_connect_above = 1; + } + + if (row != bottom_ram_row) { + // To determine whether data flows back down. Doesn't flow down on the lowest row + syn2port_ctl.synth2port_connect_below = 1; + } + } + void setup_row_col(unsigned row, unsigned col, int vpn) { + int side = col >= 6; + unsigned logical_col = col % 6U; + auto &ram = regs.rams.array.row[row].ram[col]; + auto &map_alu = regs.rams.map_alu; + auto &map_alu_row = map_alu.row[prev_row]; + auto &unitram_config = map_alu_row.adrmux.unitram_config[side][logical_col]; + unitram_config.unitram_type = tbl->unitram_type(); + unitram_config.unitram_logical_table = tbl->logical_id; + if (!options.match_compiler) // FIXME -- compiler doesn't set this? + unitram_config.unitram_vpn = vpn; + if (tbl->gress == INGRESS || tbl->gress == GHOST) + unitram_config.unitram_ingress = 1; + else + unitram_config.unitram_egress = 1; + unitram_config.unitram_enable = 1; + + auto &ram_address_mux_ctl = map_alu_row.adrmux.ram_address_mux_ctl[side][logical_col]; + ram_address_mux_ctl.ram_unitram_adr_mux_select = UnitRam::AdrMux::STATS_METERS; + if (row == home_row) { + ram.unit_ram_ctl.match_ram_write_data_mux_select = UnitRam::DataMux::STATISTICS; + ram.unit_ram_ctl.match_ram_read_data_mux_select = UnitRam::DataMux::STATISTICS; + if (tbl->adr_mux_select_stats()) + ram_address_mux_ctl.ram_stats_meter_adr_mux_select_stats = 1; + else + ram_address_mux_ctl.ram_stats_meter_adr_mux_select_meter = 1; + ram_address_mux_ctl.ram_ofo_stats_mux_select_statsmeter = 1; + ram_address_mux_ctl.synth2port_radr_mux_select_home_row = 1; + } else { + ram.unit_ram_ctl.match_ram_write_data_mux_select = UnitRam::DataMux::OVERFLOW; + ram.unit_ram_ctl.match_ram_read_data_mux_select = UnitRam::DataMux::OVERFLOW; + ram_address_mux_ctl.ram_oflo_adr_mux_select_oflo = 1; + ram_address_mux_ctl.ram_ofo_stats_mux_select_oflo = 1; + ram_address_mux_ctl.synth2port_radr_mux_select_oflo = 1; + } + ram_address_mux_ctl.map_ram_wadr_mux_select = MapRam::Mux::SYNTHETIC_TWO_PORT; + ram_address_mux_ctl.map_ram_wadr_mux_enable = 1; + ram_address_mux_ctl.map_ram_radr_mux_select_smoflo = 1; + int syn2port_bus = prev_row == top_ram_row ? 0 : 1; + auto &syn2port_members = map_alu_row.i2portctl.synth2port_hbus_members[syn2port_bus][side]; + syn2port_members |= 1U << logical_col; + } +}; + +#endif /* BF_ASM_DATA_SWITCHBOX_H_ */ diff --git a/backends/tofino/bf-asm/deparser.cpp b/backends/tofino/bf-asm/deparser.cpp new file mode 100644 index 00000000000..c3c2280f29a --- /dev/null +++ b/backends/tofino/bf-asm/deparser.cpp @@ -0,0 +1,822 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "deparser.h" + +#include + +#include "constants.h" +#include "misc.h" +#include "parser-tofino-jbay.h" +#include "phv.h" +#include "range.h" +#include "target.h" +#include "top_level.h" +#include "ubits.h" + +unsigned Deparser::unique_field_list_handle; +Deparser Deparser::singleton_object; + +Deparser::Deparser() : Section("deparser") {} +Deparser::~Deparser() {} + +struct Deparser::FDEntry { + struct Base { + virtual ~Base() {} + virtual void check(bitvec &phv_use) = 0; + virtual unsigned encode() = 0; + virtual unsigned size() = 0; // size in bytes; + virtual void dbprint(std::ostream &) const = 0; + template + bool is() const { + return dynamic_cast(this) != nullptr; + } + template + T *to() { + return dynamic_cast(this); + } + friend std::ostream &operator<<(std::ostream &out, const Base &b) { + b.dbprint(out); + return out; + } + }; + struct Phv : Base { + ::Phv::Ref val; + Phv(gress_t g, const value_t &v) : val(g, DEPARSER_STAGE, v) {} + void check(bitvec &phv_use) override { + if (val.check()) { + phv_use[val->reg.uid] = 1; + if (val->lo != 0 || val->hi != val->reg.size - 1) + error(val.lineno, + "Can only output full phv registers, not slices, " + "in deparser"); + } + } + unsigned encode() override { return val->reg.deparser_id(); } + unsigned size() override { return val->reg.size / 8; } + const ::Phv::Register *reg() { return &val->reg; } + void dbprint(std::ostream &out) const override { out << val.desc(); } + }; + struct Checksum : Base { + gress_t gress; + int unit; + Checksum(gress_t gr, const value_t &v) : gress(gr) { + if (CHECKTYPE(v, tINT)) { + if ((unit = v.i) < 0 || v.i >= Target::DEPARSER_CHECKSUM_UNITS()) + error(v.lineno, "Invalid deparser checksum unit %" PRId64 "", v.i); + } + } + void check(bitvec &phv_use) override {} + template + unsigned encode(); + unsigned encode() override; + unsigned size() override { return 2; } + void dbprint(std::ostream &out) const override { out << gress << " checksum " << unit; } + }; + struct Constant : Base { + int lineno; + gress_t gress; + int val; + Constant(gress_t g, const value_t &v) : gress(g), val(v.i) { + lineno = v.lineno; + if (v.i < 0 || v.i >> 8) + error(lineno, + "Invalid deparser constant %" PRId64 ", valid constant range is 0-255", v.i); + bool ok = Deparser::add_constant(gress, val); + if (!ok) error(lineno, "Ran out of deparser constants"); + } + void check(bitvec &phv_use) override {} + template + unsigned encode(); + unsigned encode() override; + unsigned size() override { return 1; } + void dbprint(std::ostream &out) const override { out << val; } + }; + struct Clot : Base { + int lineno; + gress_t gress; + std::string tag; + int length = -1; + std::map phv_replace; + std::map csum_replace; + Clot(gress_t gr, const value_t &tag, const value_t &data, ordered_set<::Phv::Ref> &pov) + : lineno(tag.lineno), gress(gr) { + if (CHECKTYPE2(tag, tINT, tSTR)) { + if (tag.type == tSTR) + this->tag = tag.s; + else + this->tag = std::to_string(tag.i); + } + if (data.type == tMAP) { + for (auto &kv : data.map) { + if (kv.key == "pov") { + pov.emplace(gress, DEPARSER_STAGE, kv.value); + } else if (kv.key == "max_length" || kv.key == "length") { + if (length >= 0) error(kv.value.lineno, "Duplicate length"); + if (CHECKTYPE(kv.value, tINT) && ((length = kv.value.i) < 0 || length > 64)) + error(kv.value.lineno, "Invalid clot length"); + } else if (kv.key.type == tINT) { + if (phv_replace.count(kv.key.i) || csum_replace.count(kv.key.i)) + error(kv.value.lineno, "Duplicate value at offset %" PRId64 "", + kv.key.i); + if (kv.value.type == tCMD && kv.value.vec.size == 2 && + kv.value == "full_checksum") + csum_replace.emplace(kv.key.i, Checksum(gress, kv.value.vec[1])); + else + phv_replace.emplace(kv.key.i, + ::Phv::Ref(gress, DEPARSER_STAGE, kv.value)); + } else { + error(kv.value.lineno, "Unknown key for clot: %s", value_desc(kv.key)); + } + } + } else { + pov.emplace(gress, DEPARSER_STAGE, data); + } + if (pov.size() > Target::DEPARSER_MAX_POV_PER_USE()) + error(data.lineno, "Too many POV bits for CLOT"); + } + void check(bitvec &phv_use) override { + if (length < 0) length = Parser::clot_maxlen(gress, tag); + if (length < 0) error(lineno, "No length for clot %s", tag.c_str()); + if (Parser::clot_tag(gress, tag) < 0) error(lineno, "No tag for clot %s", tag.c_str()); + unsigned next = 0; + ::Phv::Ref *prev = nullptr; + for (auto &r : phv_replace) { + if (r.first < next) { + error(r.second.lineno, "Overlapping phvs in clot"); + error(prev->lineno, "%s and %s", prev->name(), r.second.name()); + } + if (r.second.check()) { + phv_use[r.second->reg.uid] = 1; + if (r.second->lo != 0 || r.second->hi != r.second->reg.size - 1) + error(r.second.lineno, + "Can only output full phv registers, not slices," + " in deparser"); + next = r.first + r.second->reg.size / 8U; + prev = &r.second; + } + } + } + unsigned size() override { return length; } + unsigned encode() override { + BUG(); + return -1; + } + void dbprint(std::ostream &out) const override { + out << "clot " << tag; + if (length > 0) out << " [len " << length << "]"; + } + }; + + int lineno; + std::unique_ptr what; + ordered_set<::Phv::Ref> pov; + FDEntry(gress_t gress, const value_t &v, const value_t &p) { + lineno = v.lineno; + if (v.type == tCMD && v.vec.size == 2 && v == "clot") { + what.reset(new Clot(gress, v.vec[1], p, pov)); + } else if (v.type == tCMD && v.vec.size == 2 && v == "full_checksum") { + what.reset(new Checksum(gress, v.vec[1])); + pov.emplace(gress, DEPARSER_STAGE, p); + } else if (v.type == tINT) { + what.reset(new Constant(gress, v)); + pov.emplace(gress, DEPARSER_STAGE, p); + } else { + what.reset(new Phv(gress, v)); + pov.emplace(gress, DEPARSER_STAGE, p); + } + } + void check(bitvec &phv_use) { what->check(phv_use); } +}; + +struct Deparser::Intrinsic::Type { + target_t target; + gress_t gress; + std::string name; + int max; + static std::map all[TARGET_INDEX_LIMIT][2]; + + protected: + Type(target_t t, gress_t gr, const char *n, int m) : target(t), gress(gr), name(n), max(m) { + BUG_CHECK(!all[t][gr].count(name)); + all[target][gress][name] = this; + } + ~Type() { all[target][gress].erase(name); } + + public: +#define VIRTUAL_TARGET_METHODS(TARGET) \ + virtual void setregs(Target::TARGET::deparser_regs ®s, Deparser &deparser, \ + Intrinsic &vals) { \ + BUG_CHECK(!"target mismatch"); \ + } + FOR_ALL_REGISTER_SETS(VIRTUAL_TARGET_METHODS) +#undef VIRTUAL_TARGET_METHODS +}; + +#define DEPARSER_INTRINSIC(TARGET, GR, NAME, MAX) \ + static struct TARGET##INTRIN##GR##NAME : public Deparser::Intrinsic::Type { \ + TARGET##INTRIN##GR##NAME() \ + : Deparser::Intrinsic::Type(Target::TARGET::tag, GR, #NAME, MAX) {} \ + void setregs(Target::TARGET::deparser_regs &, Deparser &, Deparser::Intrinsic &) override; \ + } TARGET##INTRIN##GR##NAME##_singleton; \ + void TARGET##INTRIN##GR##NAME::setregs(Target::TARGET::deparser_regs ®s, \ + Deparser &deparser, Deparser::Intrinsic &intrin) + +std::map + Deparser::Intrinsic::Type::all[TARGET_INDEX_LIMIT][2]; + +Deparser::Digest::Digest(Deparser::Digest::Type *t, int l, VECTOR(pair_t) & data) { + type = t; + lineno = l; + for (auto &l : data) { + if (l.key == "select") { + if (l.value.type == tMAP && l.value.map.size == 1) { + select = Val(t->gress, l.value.map[0].key, l.value.map[0].value); + } else { + select = Val(t->gress, l.value); + } + } else if (t->can_shift && l.key == "shift") { + if (CHECKTYPE(l.value, tINT)) shift = l.value.i; + } else if (l.key == "context_json") { + if (CHECKTYPE(l.value, tMAP)) context_json = toJson(l.value.map); + } else if (!CHECKTYPE(l.key, tINT)) { + continue; + } else if (l.key.i < 0 || l.key.i >= t->count) { + error(l.key.lineno, "%s index %" PRId64 " out of range", t->name.c_str(), l.key.i); + } else if (l.value.type != tVEC) { + layout[l.key.i].emplace_back(t->gress, DEPARSER_STAGE, l.value); + } else { + // TODO : Need an empty layout entry if no values are present to + // set the config registers correctly + layout.emplace(l.key.i, std::vector()); + for (auto &v : l.value.vec) layout[l.key.i].emplace_back(t->gress, DEPARSER_STAGE, v); + } + } + if (!select && t->name != "pktgen") error(lineno, "No select key in %s spec", t->name.c_str()); +} + +#define DEPARSER_DIGEST(TARGET, GRESS, NAME, CNT, ...) \ + static struct TARGET##GRESS##NAME##Digest : public Deparser::Digest::Type { \ + TARGET##GRESS##NAME##Digest() \ + : Deparser::Digest::Type(Target::TARGET::tag, GRESS, #NAME, CNT) { \ + __VA_ARGS__ \ + } \ + void setregs(Target::TARGET::deparser_regs &, Deparser &, Deparser::Digest &) override; \ + } TARGET##GRESS##NAME##Digest##_singleton; \ + void TARGET##GRESS##NAME##Digest::setregs(Target::TARGET::deparser_regs ®s, \ + Deparser &deparser, Deparser::Digest &data) + +std::map Deparser::Digest::Type::all[TARGET_INDEX_LIMIT][2]; + +void Deparser::start(int lineno, VECTOR(value_t) args) { + if (args.size == 0) { + this->lineno[INGRESS] = this->lineno[EGRESS] = lineno; + return; + } + if (args.size != 1 || (args[0] != "ingress" && args[0] != "egress")) + error(lineno, "deparser must specify ingress or egress"); + gress_t gress = args[0] == "egress" ? EGRESS : INGRESS; + if (!this->lineno[gress]) this->lineno[gress] = lineno; +} + +void Deparser::input(VECTOR(value_t) args, value_t data) { + if (!CHECKTYPE(data, tMAP)) return; + for (gress_t gress : Range(INGRESS, EGRESS)) { + if (args.size > 0) { + if (args[0] == "ingress" && gress != INGRESS) continue; + if (args[0] == "egress" && gress != EGRESS) continue; + } else if (error_count > 0) { + break; + } + for (auto &kv : MapIterChecked(data.map, true)) { + if (kv.key == "dictionary") { + if (kv.value.type == tVEC && kv.value.vec.size == 0) continue; + collapse_list_of_maps(kv.value); + if (!CHECKTYPE(kv.value, tMAP)) continue; + for (auto &ent : kv.value.map) + dictionary[gress].emplace_back(gress, ent.key, ent.value); + } else if (kv.key == "pov") { + if (kv.value.type != tVEC) { + /// The check for correct type is done in Phv::Ref constructor + pov_order[gress].emplace_back(gress, DEPARSER_STAGE, kv.value); + } else { + for (auto &ent : kv.value.vec) + pov_order[gress].emplace_back(gress, DEPARSER_STAGE, ent); + } + } else if (kv.key == "partial_checksum") { + if (kv.key.type != tCMD || kv.key.vec.size != 2 || kv.key[1].type != tINT || + kv.key[1].i < 0 || kv.key[1].i >= Target::DEPARSER_CHECKSUM_UNITS()) { + error(kv.key.lineno, "Invalid deparser checksum unit number"); + } else if (CHECKTYPE2(kv.value, tVEC, tMAP)) { + collapse_list_of_maps(kv.value); + int unit = kv.key[1].i; + if (unit < 0) error(kv.key.lineno, "Invalid checksum unit %d", unit); + for (auto &ent : kv.value.map) { + checksum_entries[gress][unit].emplace_back(gress, ent.key, ent.value); + } + } + } else if (kv.key == "full_checksum") { + if (kv.key.type != tCMD || kv.key.vec.size != 2 || kv.key[1].type != tINT || + kv.key[1].i < 0 || kv.key[1].i >= Target::DEPARSER_CHECKSUM_UNITS()) { + error(kv.key.lineno, "Invalid deparser checksum unit number"); + } else if (CHECKTYPE2(kv.value, tVEC, tMAP)) { + collapse_list_of_maps(kv.value); + int unit = kv.key[1].i; + if (unit < 0) error(kv.key.lineno, "Invalid checksum unit %d", unit); + for (auto &ent : kv.value.map) { + if (ent.key == "partial_checksum") { + full_checksum_unit[gress][unit].entries[ent.key[1].i] = + checksum_entries[gress][ent.key[1].i]; + collapse_list_of_maps(ent.value); + for (auto &a : ent.value.map) { + if (a.key == "pov") { + full_checksum_unit[gress][unit].pov[ent.key[1].i] = + ::Phv::Ref(gress, DEPARSER_STAGE, a.value); + } else if (a.key == "invert") { + full_checksum_unit[gress][unit].checksum_unit_invert.insert( + ent.key[1].i); + } + } + } else if (ent.key == "clot") { + collapse_list_of_maps(ent.value); + for (auto &a : ent.value.map) { + if (a.key == "pov") { + full_checksum_unit[gress][unit].clot_entries.emplace_back( + gress, ent.key[1].i, a.value); + } else if (a.key == "invert") { + full_checksum_unit[gress][unit].clot_tag_invert.insert( + a.value.i); + } + } + } else if (ent.key == "zeros_as_ones") { + full_checksum_unit[gress][unit].zeros_as_ones_en = ent.value.i; + } + } + } + } else if (auto *itype = ::get(Intrinsic::Type::all[Target::register_set()][gress], + value_desc(&kv.key))) { + intrinsics.emplace_back(itype, kv.key.lineno); + auto &intrin = intrinsics.back(); + collapse_list_of_maps(kv.value); + if (kv.value.type == tVEC) { + for (auto &val : kv.value.vec) intrin.vals.emplace_back(gress, val); + } else if (kv.value.type == tMAP) { + for (auto &el : kv.value.map) intrin.vals.emplace_back(gress, el.key, el.value); + } else { + intrin.vals.emplace_back(gress, kv.value); + } + } else if (auto *digest = ::get(Digest::Type::all[Target::register_set()][gress], + value_desc(&kv.key))) { + if (CHECKTYPE(kv.value, tMAP)) + digests.emplace_back(digest, kv.value.lineno, kv.value.map); + } else { + error(kv.key.lineno, "Unknown deparser tag %s", value_desc(&kv.key)); + } + } + } +} + +template +static void write_checksum_entry(ENTRIES &entry, unsigned mask, int swap, int id, + const char *name = "entry") { + BUG_CHECK(swap == 0 || swap == 1); + BUG_CHECK(mask == 0 || mask & 3); + if (entry.modified()) error(1, "%s appears multiple times in checksum %d", name, id); + entry.swap = swap; + // CSR: The order of operation: data is swapped or not and then zeroed or not + if (swap) mask = (mask & 0x2) >> 1 | (mask & 0x1) << 1; + switch (mask) { + case 0: + entry.zero_m_s_b = 1; + entry.zero_l_s_b = 1; + break; + case 1: + entry.zero_m_s_b = 1; + entry.zero_l_s_b = 0; + break; + case 2: + entry.zero_m_s_b = 0; + entry.zero_l_s_b = 1; + break; + case 3: + entry.zero_m_s_b = 0; + entry.zero_l_s_b = 0; + break; + default: + break; + } +} + +// Used for field dictionary logging and deparser resoureces. +// Using fd entry and pov, a json::map is filled with appropriate field names +void write_field_name_in_json(const Phv::Register *phv, const Phv::Register *pov, int povBit, + json::map &chunk_byte, json::map &fd_entry_chunk_byte, int stageno, + gress_t gress) { + auto povName_ = Phv::get_pov_name(pov->mau_id(), povBit); + std::string povName = povName_; + std::string headerName; + size_t pos = 0; + if ((pos = povName.find("$valid")) != std::string::npos) { + headerName = povName.substr(0, pos); + } + std::string fieldNames; + auto allFields = Phv::aliases(phv, stageno); + for (auto fieldName : allFields) { + if (fieldName.find(headerName) != std::string::npos) fieldNames += (fieldName + ", "); + } + fd_entry_chunk_byte["phv_container"] = phv->uid; + chunk_byte["PHV"] = phv->uid; + chunk_byte["Field"] = fieldNames; + return; +} + +void write_pov_resources_in_json(ordered_map &pov, + json::map &pov_resources) { + unsigned pov_size = 0; + json::vector pov_bits; + // ent will be tuple of (register ref, pov position start) + for (auto const &ent : pov) { + // Go through all the bits + unsigned used_bits = 0; + for (unsigned i = 0; i < ent.first->size; i++) { + json::map pov_bit; + std::string pov_name = Phv::get_pov_name(ent.first->uid, i); + // Check if this POV bit is used + if (pov_name.compare(" ") != 0) { + pov_bit["pov_bit"] = ent.second + i; + pov_bit["phv_container"] = ent.first->uid; + pov_bit["phv_container_bit"] = i; + pov_bit["pov_name"] = pov_name; + pov_bits.push_back(std::move(pov_bit)); + used_bits++; + } + } + if (pov_size < (ent.second + used_bits)) pov_size = ent.second + used_bits; + } + pov_resources["size"] = pov_size; + pov_resources["pov_bits"] = std::move(pov_bits); +} + +// Used for field dictionary logging. Using fd entry and pov, a json::map +// is filled with appropriate checksum or constant +void write_csum_const_in_json(int deparserPhvIdx, json::map &chunk_byte, + json::map &fd_entry_chunk_byte, gress_t gress) { + if (options.target == Target::Tofino::tag) { + if (deparserPhvIdx >= CHECKSUM_ENGINE_PHVID_TOFINO_LOW && + deparserPhvIdx <= CHECKSUM_ENGINE_PHVID_TOFINO_HIGH) { + auto csum_id = deparserPhvIdx - CHECKSUM_ENGINE_PHVID_TOFINO_LOW - + (gress * CHECKSUM_ENGINE_PHVID_TOFINO_PER_GRESS); + chunk_byte["Checksum"] = csum_id; + fd_entry_chunk_byte["csum_engine"] = csum_id; + } + } else if (options.target == Target::JBay::tag) { + if (deparserPhvIdx > CONSTANTS_PHVID_JBAY_LOW && + deparserPhvIdx < CONSTANTS_PHVID_JBAY_HIGH) { + chunk_byte["Constant"] = + Deparser::get_constant(gress, deparserPhvIdx - CONSTANTS_PHVID_JBAY_LOW); + fd_entry_chunk_byte["phv_container"] = deparserPhvIdx; + } else { + auto csum_id = deparserPhvIdx - CONSTANTS_PHVID_JBAY_HIGH; + chunk_byte["Checksum"] = csum_id; + fd_entry_chunk_byte["csum_engine"] = csum_id; + } + } + return; +} + +/// Get JSON for deparser resources from digest of deparser table +/// @param tab_digest Digest for the deparser table, nullptr if the table does not exist +/// @return JSON node representation of the table for deparser resources +json::map deparser_table_digest_to_json(Deparser::Digest *tab_digest) { + json::map dep_table; + json::vector table_phv; + + // nullptr means the table is not used, create JSON node for empty table + // and return it + if (tab_digest == nullptr) { + dep_table["nTables"] = 0; + dep_table["maxBytes"] = 0; + dep_table["table_phv"] = std::move(table_phv); + return dep_table; + } + + unsigned int max_bytes = 0; + // Prepare tables of the deparser table type + for (auto &set : tab_digest->layout) { + json::map table; + table["table_id"] = set.first; + // TODO: field_list_name? + json::vector bytes; + unsigned byte_n = 0; + for (auto ® : set.second) { + json::map byte; + byte["byte_number"] = byte_n++; + byte["phv_container"] = reg->reg.uid; + bytes.push_back(std::move(byte)); + } + if (byte_n > max_bytes) max_bytes = byte_n; + table["bytes"] = std::move(bytes); + table_phv.push_back(std::move(table)); + } + dep_table["nTables"] = tab_digest->layout.size(); + dep_table["maxBytes"] = max_bytes; + dep_table["index_phv"] = tab_digest->select->reg.uid; + dep_table["table_phv"] = std::move(table_phv); + // Now we have a digest + return dep_table; +} + +/// Create resources_deparser.json with the deparser node +/// for resources.json +/// @param fde_entries_i JSON vector of field dictionary entries from Ingress +/// @param fde_entries_e JSON vector of field dictionary entries from Egress +void Deparser::report_resources_deparser_json(json::vector &fde_entries_i, + json::vector &fde_entries_e) { + json::map resources_deparser_ingress; + json::map resources_deparser_egress; + // Set gress property + resources_deparser_ingress["gress"] = "ingress"; + resources_deparser_egress["gress"] = "egress"; + // Fill out POV resource information for ingress + json::map pov_resources; + write_pov_resources_in_json(pov[INGRESS], pov_resources); + resources_deparser_ingress["pov"] = std::move(pov_resources); + // Fill out POV resoure information for egress + write_pov_resources_in_json(pov[EGRESS], pov_resources); + resources_deparser_egress["pov"] = std::move(pov_resources); + // Fill out field dictionaries + unsigned n_fde_entries = Target::DEPARSER_MAX_FD_ENTRIES(); + resources_deparser_ingress["nFdeEntries"] = n_fde_entries; + resources_deparser_ingress["fde_entries"] = std::move(fde_entries_i); + resources_deparser_egress["nFdeEntries"] = n_fde_entries; + resources_deparser_egress["fde_entries"] = std::move(fde_entries_e); + // Fill deparser tables + Digest *learning_table[2] = {nullptr, nullptr}; + Digest *resubmit_table[2] = {nullptr, nullptr}; + Digest *mirror_table[2] = {nullptr, nullptr}; + for (auto &digest : digests) { + // Check if this is egress/ingress + if (digest.type->gress != INGRESS && digest.type->gress != EGRESS) continue; + if (digest.type->name == "learning") + learning_table[digest.type->gress] = &digest; + else if (digest.type->name == "resubmit" || + digest.type->name == "resubmit_preserving_field_list") + resubmit_table[digest.type->gress] = &digest; + else if (digest.type->name == "mirror") + mirror_table[digest.type->gress] = &digest; + } + resources_deparser_ingress["mirror_table"] = + deparser_table_digest_to_json(mirror_table[INGRESS]); + resources_deparser_egress["mirror_table"] = deparser_table_digest_to_json(mirror_table[EGRESS]); + resources_deparser_ingress["resubmit_table"] = + deparser_table_digest_to_json(resubmit_table[INGRESS]); + resources_deparser_egress["resubmit_table"] = + deparser_table_digest_to_json(resubmit_table[EGRESS]); + resources_deparser_ingress["learning_table"] = + deparser_table_digest_to_json(learning_table[INGRESS]); + resources_deparser_egress["learning_table"] = + deparser_table_digest_to_json(learning_table[EGRESS]); + + // Create the main deparser resources node + json::vector resources_deparser; + resources_deparser.push_back(std::move(resources_deparser_ingress)); + resources_deparser.push_back(std::move(resources_deparser_egress)); + // Dump resources to file + auto deparser_json_dump = open_output("logs/resources_deparser.json"); + *deparser_json_dump << &resources_deparser; +} + +#include "tofino/deparser.cpp" // NOLINT(build/include) +#if HAVE_JBAY +#include "jbay/deparser.cpp" // NOLINT(build/include) +#endif /* HAVE_JBAY */ + +std::vector Deparser::merge_csum_entries( + const std::vector &entries, int id) { + std::vector rv; + ordered_map merged_entries; + + for (auto &entry : entries) { + if (entry.is_clot()) { + rv.push_back(entry); + continue; + } + auto name = entry.val.name(); + int hi = entry.val.hibit(); + int lo = entry.val.lobit(); + bool is_hi = hi >= 16; + bool is_lo = lo < 16; + + if (!merged_entries.count(name)) { + auto reg = Phv::reg(name); + auto new_entry(entry); + if (lo != 0 && hi != reg->size - 1) { + new_entry.val = Phv::Ref(*reg, entry.val.gress(), 0, reg->size - 1); + } + merged_entries.emplace(name, new_entry); + } else { + auto &rv_entry = merged_entries[name]; + if (rv_entry.mask & entry.mask) + error(entry.lineno, "bytes within %s appear multiple times in checksum %d", name, + id); + if (is_hi) { + if ((rv_entry.mask & 0xc) && (rv_entry.swap & 2) != (entry.swap & 2)) + error(entry.lineno, "incompatible swap values for %s in checksum %d", name, id); + rv_entry.mask |= entry.mask & 0xc; + rv_entry.swap |= entry.swap & 2; + } + if (is_lo) { + if ((rv_entry.mask & 0x3) && (rv_entry.swap & 1) != (entry.swap & 1)) + error(entry.lineno, "incompatible swap values for %s in checksum %d", name, id); + rv_entry.mask |= entry.mask & 0x3; + rv_entry.swap |= entry.swap & 1; + } + } + } + + for (auto &[_, entry] : merged_entries) rv.push_back(entry); + + return rv; +} + +/* The following uses of specialized templates must be after the specialization... */ +void Deparser::process() { + bitvec pov_use[2]; + for (gress_t gress : Range(INGRESS, EGRESS)) { + for (auto &ent : pov_order[gress]) + if (ent.check()) { + pov_use[gress][ent->reg.uid] = 1; + phv_use[gress][ent->reg.uid] = 1; + } + for (auto &ent : dictionary[gress]) { + ent.check(phv_use[gress]); + for (auto &pov : ent.pov) { + if (!pov.check()) continue; + phv_use[gress][pov->reg.uid] = 1; + if (pov->lo != pov->hi) error(pov.lineno, "POV bits should be single bits"); + if (!pov_use[gress][pov->reg.uid]) { + pov_order[gress].emplace_back(pov->reg, gress); + pov_use[gress][pov->reg.uid] = 1; + } + } + } + for (int i = 0; i < MAX_DEPARSER_CHECKSUM_UNITS; i++) + for (auto &ent : full_checksum_unit[gress][i].entries) { + for (auto entry : ent.second) { + if (!entry.check()) error(entry.lineno, "Invalid checksum entry"); + } + ent.second = merge_csum_entries(ent.second, i); + } + } + for (auto &intrin : intrinsics) { + for (auto &el : intrin.vals) { + if (el.check()) phv_use[intrin.type->gress][el->reg.uid] = 1; + for (auto &pov : el.pov) { + if (pov.check()) { + phv_use[intrin.type->gress][pov->reg.uid] = 1; + if (pov->lo != pov->hi) error(pov.lineno, "POV bits should be single bits"); + if (!pov_use[intrin.type->gress][pov->reg.uid]) { + pov_order[intrin.type->gress].emplace_back(pov->reg, intrin.type->gress); + pov_use[intrin.type->gress][pov->reg.uid] = 1; + } + } + } + } + if (intrin.vals.size() > (size_t)intrin.type->max) + error(intrin.lineno, "Too many values for %s", intrin.type->name.c_str()); + } + if (phv_use[INGRESS].intersects(phv_use[EGRESS])) + error(lineno[INGRESS], "Registers used in both ingress and egress in deparser: %s", + Phv::db_regset(phv_use[INGRESS] & phv_use[EGRESS]).c_str()); + for (auto &digest : digests) { + if (digest.select.check()) { + phv_use[digest.type->gress][digest.select->reg.uid] = 1; + if (digest.select->lo > 0 && !digest.type->can_shift) + error(digest.select.lineno, "%s digest selector must be in bottom bits of phv", + digest.type->name.c_str()); + } + for (auto &pov : digest.select.pov) { + if (pov.check()) { + phv_use[digest.type->gress][pov->reg.uid] = 1; + if (pov->lo != pov->hi) error(pov.lineno, "POV bits should be single bits"); + if (!pov_use[digest.type->gress][pov->reg.uid]) { + pov_order[digest.type->gress].emplace_back(pov->reg, digest.type->gress); + pov_use[digest.type->gress][pov->reg.uid] = 1; + } + } + } + for (auto &set : digest.layout) + for (auto ® : set.second) + if (reg.check()) phv_use[digest.type->gress][reg->reg.uid] = 1; + } + SWITCH_FOREACH_REGISTER_SET(Target::register_set(), TARGET *t = nullptr; + // process(t); + process((TARGET *)nullptr);) + + if (options.match_compiler || 1) { /* FIXME -- need proper liveness analysis */ + Phv::setuse(INGRESS, phv_use[INGRESS]); + Phv::setuse(EGRESS, phv_use[EGRESS]); + } + for (gress_t gress : Range(INGRESS, EGRESS)) { + int pov_byte = 0, pov_size = 0; + for (auto &ent : pov_order[gress]) + if (pov[gress].count(&ent->reg) == 0) { + pov[gress][&ent->reg] = pov_size; + pov_size += ent->reg.size; + } + if (pov_size > 8 * Target::DEPARSER_MAX_POV_BYTES()) + error(lineno[gress], "Ran out of space in POV in deparser"); + } +} + +/* The following uses of specialized templates must be after the specialization... */ +void Deparser::output(json::map &map) { + SWITCH_FOREACH_TARGET(options.target, auto *regs = new TARGET::deparser_regs; + declare_registers(regs); write_config(*regs); + gen_learn_quanta(*regs, map["learn_quanta"]); return;) + error(__LINE__, "Unsupported target %d", options.target); +} + +/* this is a bit complicated since the output from compiler digest is as follows: + context_json: + 0: [ [ ipv4.ihl, 0, 4, 0], [ ipv4.protocol, 0, 8, 1], [ ipv4.srcAddr, 0, 32, 2], [ + ethernet.srcAddr, 0, 48, 6], [ ethernet.dstAddr, 0, 48, 12], [ ipv4.fragOffset, 0, 13, 18 ], [ + ipv4.identification, 0, 16, 20], [ routing_metadata.learn_meta_1, 0, 20, 22], [ + routing_metadata.learn_meta_4, 0, 10, 26] ] 1: [ [ ipv4.ihl, 0, 4, 0], [ ipv4.identification, 0, + 16, 1], [ ipv4.protocol, 0, 8, 3], [ ipv4.srcAddr, 0, 32, 4], [ ethernet.srcAddr, 0, 48, 8], [ + ethernet.dstAddr, 0, 48, 14], [ ipv4.fragOffset, 0, 13, 20], [ routing_metadata.learn_meta_2, + 0, 24, 22], [ routing_metadata.learn_meta_3, 0, 25, 26] ] name: [ learn_1, learn_2 ] +*/ +template +void Deparser::gen_learn_quanta(REGS ®s, json::vector &learn_quanta) { + for (auto &digest : digests) { + if (digest.type->name != "learning") continue; + BUG_CHECK(digest.context_json); + auto namevec = (*(digest.context_json))["name"]; + auto &names = *(namevec->as_vector()); + auto digentry = digest.context_json->begin(); + // Iterate on names. for each name, get the corresponding digest entry and fill in + for (auto &tname : names) { + BUG_CHECK(digentry != digest.context_json->end()); + json::map quanta; + quanta["name"] = (*tname).c_str(); + quanta["lq_cfg_type"] = digentry->first->as_number()->val; + quanta["handle"] = next_handle(); + auto *digfields = digentry->second->as_vector(); + if (digfields) { + auto &digfields_vec = *digfields; + json::vector &fields = quanta["fields"]; + for (auto &tup : digfields_vec) { + auto &one = *(tup->as_vector()); + BUG_CHECK(one.size() == 5); + json::map anon; + anon["field_name"] = (*(one[0])).clone(); + anon["start_byte"] = (*(one[1])).clone(); + anon["field_width"] = (*(one[2])).clone(); + anon["start_bit"] = (*(one[3])).clone(); + anon["phv_offset"] = (*(one[4])).clone(); + fields.push_back(std::move(anon)); + } + } + digentry++; + learn_quanta.push_back(std::move(quanta)); + } + } +} + +unsigned Deparser::FDEntry::Checksum::encode() { + SWITCH_FOREACH_TARGET(options.target, return encode();); + return -1; +} + +unsigned Deparser::FDEntry::Constant::encode() { + SWITCH_FOREACH_TARGET(options.target, return encode();); + return -1; +} + +void Deparser::gtest_clear() { + for (int i = 0; i < 2; i++) { + for (int j = 0; j < MAX_DEPARSER_CHECKSUM_UNITS; j++) checksum_entries[i][j].clear(); + dictionary[i].clear(); + pov_order[i].clear(); + pov[i].clear(); + phv_use[i].clear(); + constants[i].clear(); + } + intrinsics.clear(); + digests.clear(); +} diff --git a/backends/tofino/bf-asm/deparser.h b/backends/tofino/bf-asm/deparser.h new file mode 100644 index 00000000000..5136dd91fb5 --- /dev/null +++ b/backends/tofino/bf-asm/deparser.h @@ -0,0 +1,278 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef DEPARSER_H_ +#define DEPARSER_H_ + +#include + +#include + +#include "bitops.h" +#include "constants.h" +#include "ordered_set.h" +#include "phv.h" +#include "sections.h" + +enum { + // limits over all targets + MAX_DEPARSER_CHECKSUM_UNITS = 8, + DEPARSER_STAGE = INT_MAX, // greater than the number of stages +}; + +/** + * \ingroup parde + */ +class Deparser : public Section { + static Deparser singleton_object; + + public: + struct Val { + /* a phv or clot reference with optional associated POV phv reference */ + Phv::Ref val; + int tag = -1; + ordered_set pov; + const int &lineno = val.lineno; + Val() {} + virtual ~Val() {} + Val(gress_t gr, const value_t &v) : val(gr, DEPARSER_STAGE, v) {} + Val(gress_t gr, const value_t &v, const value_t &p) : val(gr, DEPARSER_STAGE, v) { + pov.emplace(gr, DEPARSER_STAGE, p); + } + Val(gress_t gr, int tag, const value_t &p) : tag(tag) { + pov.emplace(gr, DEPARSER_STAGE, p); + } + Val &operator=(const Val &a) { + val = a.val; + tag = a.tag; + pov = a.pov; + return *this; + } + explicit operator bool() const { return is_phv() || is_clot(); } + Phv::Slice operator*() const { return *val; } + Phv::Slice operator->() const { return *val; } + bool is_phv() const { return bool(val); } + bool is_clot() const { return tag >= 0; } + virtual bool check() const { + if (is_phv() && is_clot()) { + error(lineno, "Reference cannot be phv and clot at the same time"); + return false; + } + if (is_phv()) { + return val.check(); + } else if (is_clot()) { + if (pov.empty()) { + error(lineno, "Clot requires a pov bit"); + return false; + } + } else { + error(lineno, "Unknown val"); + return false; + } + return true; + } + }; + + struct ChecksumVal : public Val { + int mask = 0; + int swap = 0; + ChecksumVal(gress_t gr, const value_t &v, const value_t &m) : Val(gr, v) { + if ((val->lo % 8 != 0) || (val->hi % 8 != 7)) + error(lineno, "Can only do checksums on byte-aligned container slices"); + mask = ((1 << (val->hi + 1) / 8) - 1) ^ ((1 << val->lo / 8) - 1); + + if (CHECKTYPE(m, tMAP)) { + for (auto &kv : m.map) { + if (kv.key == "pov") { + if (!pov.empty()) error(kv.value.lineno, "Duplicate POV"); + pov.emplace_back(gr, DEPARSER_STAGE, kv.value); + } else if (kv.key == "swap" && CHECKTYPE(kv.value, tINT)) { + swap = kv.value.i; + } else { + error(m.lineno, "Unknown key for checksum: %s", value_desc(kv.key)); + } + } + } + } + ChecksumVal(gress_t gr, int tag, const value_t &p) : Val(gr, tag, p) {} + ChecksumVal &operator=(const ChecksumVal &a) { + Val::operator=(a); + mask = a.mask; + swap = a.swap; + return *this; + } + ChecksumVal() : Val() {} + + bool check() const override { + if (is_phv()) { + if (mask == 0) error(lineno, "mask is 0 for phv checkum value?"); + if (swap < 0 || swap > 3) error(lineno, "Invalid swap for phv checksum"); + } + return Val::check(); + } + }; + + struct FullChecksumUnit { + std::map> entries; + std::map pov; + std::set checksum_unit_invert; + std::set clot_tag_invert; + std::vector clot_entries; + bool zeros_as_ones_en = false; + }; + + struct FDEntry; + std::vector checksum_entries[2][MAX_DEPARSER_CHECKSUM_UNITS]; + FullChecksumUnit full_checksum_unit[2][MAX_DEPARSER_CHECKSUM_UNITS]; + int lineno[2]; + std::vector dictionary[2]; + std::vector pov_order[2]; + ordered_map pov[2]; + bitvec phv_use[2]; + std::set constants[2]; + + struct Intrinsic { + struct Type; + Type *type; + int lineno; + std::vector vals; + Intrinsic(Type *t, int l) : type(t), lineno(l) {} + }; + std::vector intrinsics; + struct Digest { + struct Type { + target_t target; + gress_t gress; + std::string name; + int count; + bool can_shift = false; + static std::map all[TARGET_INDEX_LIMIT][2]; + + protected: + Type(target_t t, gress_t gr, const char *n, int cnt) + : target(t), gress(gr), name(n), count(cnt) { + BUG_CHECK(!all[target][gress].count(name)); + all[target][gress][name] = this; + } + ~Type() { all[target][gress].erase(name); } + + public: +#define VIRTUAL_TARGET_METHODS(TARGET) \ + virtual void setregs(Target::TARGET::deparser_regs ®s, Deparser &deparser, \ + Deparser::Digest &data) { \ + BUG_CHECK(!"target mismatch"); \ + } + FOR_ALL_REGISTER_SETS(VIRTUAL_TARGET_METHODS) +#undef VIRTUAL_TARGET_METHODS + }; + + Type *type; + int lineno; + Val select; + int shift = 0; + std::map> layout; + std::unique_ptr context_json; + Digest(Type *t, int lineno, VECTOR(pair_t) & data); + }; + std::vector digests; + Deparser(); + ~Deparser(); + void start(int lineno, VECTOR(value_t) args); + void input(VECTOR(value_t) args, value_t data); + void process(); + std::vector merge_csum_entries(const std::vector &, int); + template + void process(TARGET *); + void output(json::map &); + template + void gen_learn_quanta(REGS &, json::vector &); + template + void write_config(REGS &); + + static const bitvec &PhvUse(gress_t gr) { return singleton_object.phv_use[gr]; } + + static bool add_constant(gress_t gr, int c) { + if (!singleton_object.constants[gr].count(c)) { + singleton_object.constants[gr].insert(c); + if (int(singleton_object.constants[gr].size()) > Target::DEPARSER_CONSTANTS()) + return false; + } + return true; + } + + static int constant_idx(gress_t gr, int c) { + if (singleton_object.constants[gr].count(c)) + return std::distance(singleton_object.constants[gr].begin(), + singleton_object.constants[gr].find(c)); + return -1; + } + + // @return constant value that will be deparsed + static int get_constant(gress_t gr, int phv_idx) { + int i = 0; + for (auto constant : singleton_object.constants[gr]) { + if ((phv_idx - 224) == i) { + return constant; + } else { + i++; + } + } + return -1; + } + + // Writes POV information in json used for field dictionary logging + // and deparser resources + static void write_pov_in_json(json::map &fd, json::map &fd_entry, const Phv::Register *phv, + int bit, int offset) { + auto povName = Phv::get_pov_name(phv->uid, offset); + // Field dictionary logging + fd["POV PHV"] = phv->uid; + fd["POV Field bit"] = bit; + fd["POV Field Name"] = povName; + // Deparser resources + fd_entry["pov_bit"] = bit; + fd_entry["pov_name"] = povName; + return; + } + + // Digest Handle Setup + // ------------------------------------------------------ + // | Pipe ID | Field Type | Field List Handle | + // 31 ... 28 24 0 + // Field List Handle = 24 bits + // Field List Type = 4 bits (Field list is 0x9) + // Pipe ID = 4 bits + static unsigned unique_field_list_handle; + static unsigned next_handle() { + return unique_table_offset << PIPE_ID_SHIFT | FIELD_HANDLE_START | + unique_field_list_handle++; + } + + // gtest methods + + /// @brief Get the singleton object for use in gtest + static Deparser *gtest_get_deparser() { return &singleton_object; } + + /// @brief Clear/reset the deparser object + void gtest_clear(); + + private: + // Report deparser resources to JSON file + void report_resources_deparser_json(json::vector &fde_entries_i, json::vector &fde_entries_e); +}; + +#endif /* DEPARSER_H_ */ diff --git a/backends/tofino/bf-asm/depositfield.cpp b/backends/tofino/bf-asm/depositfield.cpp new file mode 100644 index 00000000000..15f2b991bb4 --- /dev/null +++ b/backends/tofino/bf-asm/depositfield.cpp @@ -0,0 +1,39 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "depositfield.h" + +namespace DepositField { + +RotateConstant discoverRotation(int32_t val, int containerSize, int32_t tooLarge, + int32_t tooSmall) { + int32_t containerMask = ~(UINT64_MAX << containerSize); + int32_t signBit = 1U << (containerSize - 1); + unsigned rotate = 0; + for (/*rotate*/; rotate < containerSize; ++rotate) { + if (val > tooSmall && val < tooLarge) break; + // Reverse the rotate-right to discover encoding. + int32_t rotBit = (val >> (containerSize - 1)) & 1; + val = ((val << 1) | rotBit) & containerMask; + val |= (val & signBit) ? ~containerMask : 0; + } + // If a solution has not been found, val is back to where it started. + rotate %= containerSize; + return RotateConstant{rotate, val}; +} + +} // namespace DepositField diff --git a/backends/tofino/bf-asm/depositfield.h b/backends/tofino/bf-asm/depositfield.h new file mode 100644 index 00000000000..b7519eb2fcb --- /dev/null +++ b/backends/tofino/bf-asm/depositfield.h @@ -0,0 +1,34 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _DEPOSITFIELD_H_ +#define _DEPOSITFIELD_H_ + +#include + +namespace DepositField { + +struct RotateConstant { + unsigned rotate; + int32_t value; +}; + +RotateConstant discoverRotation(int32_t val, int containerSize, int32_t tooLarge, int32_t tooSmall); + +} // namespace DepositField + +#endif /* _DEPOSITFIELD_H_ */ diff --git a/backends/tofino/bf-asm/disasm.cpp b/backends/tofino/bf-asm/disasm.cpp new file mode 100644 index 00000000000..0a58816fc47 --- /dev/null +++ b/backends/tofino/bf-asm/disasm.cpp @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "disasm.h" + +#include + +Disasm *Disasm::create(std::string target) { +#define CREATE_TARGET(TARGET, ...) \ + if (target == Target::TARGET::name) return new Disasm::TARGET; + FOR_ALL_TARGETS(CREATE_TARGET); +#undef CREATE_TARGET + std::cerr << "Unsupported target " << target << std::endl; + return nullptr; +} diff --git a/backends/tofino/bf-asm/disasm.h b/backends/tofino/bf-asm/disasm.h new file mode 100644 index 00000000000..a59514a27be --- /dev/null +++ b/backends/tofino/bf-asm/disasm.h @@ -0,0 +1,50 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef DISASM_H_ +#define DISASM_H_ + +#include "target.h" + +class Disasm { + public: + FOR_ALL_TARGETS(DECLARE_TARGET_CLASS) + virtual void input_binary(uint64_t addr, char tag, uint32_t *data, size_t len) = 0; + static Disasm *create(std::string target); +}; + +#define DECLARE_DISASM_TARGET(TARGET, ...) \ + class Disasm::TARGET : public Disasm { \ + public: \ + typedef ::Target::TARGET Target; \ + Target::top_level_regs regs; \ + TARGET() { declare_registers(®s); } \ + ~TARGET() { undeclare_registers(®s); } \ + TARGET(const TARGET &) = delete; \ + __VA_ARGS__ \ + }; + +FOR_ALL_TARGETS( + DECLARE_DISASM_TARGET, void input_binary(uint64_t addr, char tag, uint32_t *data, size_t len) { + if (tag == 'D') { + regs.mem_top.input_binary(addr, tag, data, len); + } else { + regs.reg_top.input_binary(addr, tag, data, len); + } + }) + +#endif /* DISASM_H_ */ diff --git a/backends/tofino/bf-asm/dynhash.cpp b/backends/tofino/bf-asm/dynhash.cpp new file mode 100644 index 00000000000..c77779686d4 --- /dev/null +++ b/backends/tofino/bf-asm/dynhash.cpp @@ -0,0 +1,64 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include "bfas.h" +#include "json.h" +#include "sections.h" + +class DynHash : public Section { + int lineno = -1; + std::unique_ptr _dynhash = nullptr; + std::string _dynhashFileName; + + DynHash() : Section("dynhash") {} + + void input(VECTOR(value_t) args, value_t data) { + lineno = data.lineno; + if (!CHECKTYPE(data, tSTR)) return; + _dynhashFileName = data.s; + } + + void process() { + if (_dynhashFileName.empty()) return; + std::ifstream inputFile(_dynhashFileName); + if (!inputFile && _dynhashFileName[0] != '/') + inputFile.open(asmfile_dir + "/" + _dynhashFileName); + if (!inputFile) { + warning(lineno, "%s: can't read file", _dynhashFileName.c_str()); + } else { + inputFile >> _dynhash; + if (!inputFile) { + warning(lineno, "%s: not valid dynhash json representation", + _dynhashFileName.c_str()); + _dynhash.reset(new json::map()); + } + } + } + + void output(json::map &ctxtJson) { + ctxtJson["dynamic_hash_calculations"] = json::vector(); // this key required by schema + if (_dynhash) { + ctxtJson.merge(_dynhash->to()); + } + } + + static DynHash singleton_dynhash; +} DynHash::singleton_dynhash; diff --git a/backends/tofino/bf-asm/error_mode.cpp b/backends/tofino/bf-asm/error_mode.cpp new file mode 100644 index 00000000000..93f1d3c6793 --- /dev/null +++ b/backends/tofino/bf-asm/error_mode.cpp @@ -0,0 +1,201 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "error_mode.h" + +#include "stage.h" + +DefaultErrorMode DefaultErrorMode::singleton; + +ErrorMode::mode_t ErrorMode::str2mode(const value_t &v) { + if (CHECKTYPE(v, tSTR)) { + if (v == "propagate") return PROPAGATE; + if (v == "map_to_immediate") return MAP_TO_IMMEDIATE; + if (v == "disable") return DISABLE_ALL_TABLES; + if (v == "propagate_and_map") return PROPAGATE_AND_MAP; + if (v == "propagate_and_disable") return PROPAGATE_AND_DISABLE; + if (v != "no_config") error(v.lineno, "Not a valid error mode: %s", v.s); + } + return NO_CONFIG; +} + +const char *ErrorMode::mode2str(ErrorMode::mode_t m) { + switch (m) { + case NO_CONFIG: + return "no_config"; + case PROPAGATE: + return "propagate"; + case MAP_TO_IMMEDIATE: + return "map_to_immediate"; + case DISABLE_ALL_TABLES: + return "disable"; + case PROPAGATE_AND_MAP: + return "propagate_and_map"; + case PROPAGATE_AND_DISABLE: + return "propagate_and_disable"; + default: + return ""; + } +} + +ErrorMode::type_t ErrorMode::str2type(const value_t &v) { + if (CHECKTYPE(v, tSTR)) { + if (v == "tcam_match") return TCAM_MATCH; + if (v == "tind_ecc") return TIND_ECC; + if (v == "gfm_parity") return GFM_PARITY; + if (v == "emm_ecc") return EMM_ECC; + if (v == "prev_err") return PREV_ERROR; + if (v == "actiondata") return ACTIONDATA_ERROR; + if (v == "imem_parity") return IMEM_PARITY_ERROR; + error(v.lineno, "Not a valid error type: %s", v.s); + } + return TCAM_MATCH; // avoid invalid type here, error message has been output already +} + +const char *ErrorMode::type2str(ErrorMode::type_t t) { + switch (t) { + case TCAM_MATCH: + return "tcam_match"; + case TIND_ECC: + return "tind_ecc"; + case GFM_PARITY: + return "gfm_parity"; + case EMM_ECC: + return "emm_ecc"; + case PREV_ERROR: + return "prev_err"; + case ACTIONDATA_ERROR: + return "actiondata"; + case IMEM_PARITY_ERROR: + return "imem_parity"; + default: + return ""; + } +} + +void ErrorMode::input(value_t data) { + if (!CHECKTYPE2(data, tSTR, tMAP)) return; + if (data.type == tSTR) { + mode_t m = str2mode(data); + for (int i = 0; i < NUM_TYPE_T; ++i) { + if (i == LATE_ERROR && m != NO_CONFIG) m = PROPAGATE; + mode[i] = m; + } + } else { + for (auto &kv : MapIterChecked(data.map)) { + type_t t = str2type(kv.key); + mode_t m = str2mode(kv.value); + if (t >= LATE_ERROR && m > PROPAGATE) + error(kv.value.lineno, "%s error mode can only propagate, not %s", type2str(t), + mode2str(m)); + mode[t] = m; + } + } +} + +template +void ErrorMode::write_regs(REGS ®s, const Stage *stage, gress_t gress) { + auto &merge = regs.rams.match.merge; + int tcam_err_delay = stage->tcam_delay(gress) ? 1 : 0; + int fifo_err_delay = + stage->pipelength(gress) - stage->pred_cycle(gress) - Target::MAU_ERROR_DELAY_ADJUST(); + bool map_to_immed = false; + bool propagate = false; +#define YES(X) X +#define NO(X) +#define HANDLE_ERROR_CASES(REG, HAVE_O_ERR_EN) \ + case NO_CONFIG: \ + break; \ + case PROPAGATE: \ + HAVE_O_ERR_EN(merge.REG[gress].REG##_o_err_en = 1;) \ + propagate = true; \ + break; \ + case PROPAGATE_AND_MAP: \ + HAVE_O_ERR_EN(merge.REG[gress].REG##_o_err_en = 1;) \ + propagate = true; \ + /* fall through */ \ + case MAP_TO_IMMEDIATE: \ + merge.REG[gress].REG##_idata_ovr = 1; \ + map_to_immed = true; \ + break; \ + case PROPAGATE_AND_DISABLE: \ + HAVE_O_ERR_EN(merge.REG[gress].REG##_o_err_en = 1;) \ + propagate = true; \ + /* fall through */ \ + case DISABLE_ALL_TABLES: \ + merge.REG[gress].REG##_dis_pred = 1; \ + break; \ + default: \ + BUG(); + + switch (mode[PREV_ERROR]) { HANDLE_ERROR_CASES(prev_error_ctl, NO) } + merge.prev_error_ctl[gress].prev_error_ctl_delay = tcam_err_delay; + if (propagate) { + switch (stage->stage_dep[gress]) { + case Stage::CONCURRENT: + merge.prev_error_ctl[gress].prev_error_ctl_conc = 1; + break; + case Stage::ACTION_DEP: + merge.prev_error_ctl[gress].prev_error_ctl_action = 1; + break; + case Stage::NONE: + if (stage->stageno == 0) { + // stage 0 does not have stage_dep set, but counts as if it was match + // dependent (on the parser). FIXME -- should just always set stage_dep to + // MATCH_DEP for stage 0? fall through + case Stage::MATCH_DEP: + merge.prev_error_ctl[gress].prev_error_ctl_match = 1; + break; + } + default: + BUG(); + } + } + + switch (mode[TCAM_MATCH]) { HANDLE_ERROR_CASES(tcam_match_error_ctl, YES) } + switch (mode[TIND_ECC]) { HANDLE_ERROR_CASES(tind_ecc_error_ctl, YES) } + switch (mode[GFM_PARITY]) { HANDLE_ERROR_CASES(gfm_parity_error_ctl, YES) } + merge.gfm_parity_error_ctl[gress].gfm_parity_error_ctl_delay = tcam_err_delay; + switch (mode[EMM_ECC]) { HANDLE_ERROR_CASES(emm_ecc_error_ctl, YES) } + merge.emm_ecc_error_ctl[gress].emm_ecc_error_ctl_delay = tcam_err_delay; + + if (map_to_immed) { + merge.err_idata_ovr_fifo_ctl[gress].err_idata_ovr_fifo_ctl_en = 1; + merge.err_idata_ovr_fifo_ctl[gress].err_idata_ovr_fifo_ctl_delay = fifo_err_delay - 2; + } + if (propagate) { + merge.o_error_fifo_ctl[gress].o_error_fifo_ctl_en = 1; + merge.o_error_fifo_ctl[gress].o_error_fifo_ctl_delay = fifo_err_delay; + } + + // action error sources can only propagate (too late for disable or map_to_immed + if (mode[ACTIONDATA_ERROR]) merge.actiondata_error_ctl |= 1 << gress; + if (mode[IMEM_PARITY_ERROR]) merge.imem_parity_error_ctl |= 1 << gress; + + /* TODO -- additional error cfg regs: + * rams.match.merge.err_idata_ovr_ctl[gress] + * rams.match.merge.s2p_meter_error_ctl[gress] + * rams.match.merge.s2p_stats_error_ctl[gress] + * rams.map_alu.stats_wrap[alu].stats.statistics.ctl.stats_alu_error_enable; + * rams.map_alu.meter_alu_group_error_ctl[alu] + * rams.array.row[r].actiondata_error_uram_ctl[gress] + * rams.array.row[r].emm_ecc_error_uram_ctl[gress] + * rams.array.row[r].tind_ecc_error_uram_ctl[gress] + */ +} +FOR_ALL_REGISTER_SETS(INSTANTIATE_TARGET_TEMPLATE, void ErrorMode::write_regs, mau_regs &, + const Stage *, gress_t); diff --git a/backends/tofino/bf-asm/error_mode.h b/backends/tofino/bf-asm/error_mode.h new file mode 100644 index 00000000000..b5a6739cbac --- /dev/null +++ b/backends/tofino/bf-asm/error_mode.h @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_ERROR_MODE_H_ +#define BF_ASM_ERROR_MODE_H_ + +#include "sections.h" + +class Stage; + +class ErrorMode { + public: + typedef enum { + NO_CONFIG = 0, + PROPAGATE, + MAP_TO_IMMEDIATE, + DISABLE_ALL_TABLES, + PROPAGATE_AND_MAP, + PROPAGATE_AND_DISABLE + } mode_t; + typedef enum { + TCAM_MATCH, + TIND_ECC, + GFM_PARITY, + EMM_ECC, + PREV_ERROR, + ACTIONDATA_ERROR, + IMEM_PARITY_ERROR, + NUM_TYPE_T, + LATE_ERROR = ACTIONDATA_ERROR, // this (and after) is limited + } type_t; + + mode_t mode[NUM_TYPE_T] = {NO_CONFIG}; + mode_t &operator[](type_t t) { return mode[t]; } + static mode_t str2mode(const value_t &); + static const char *mode2str(mode_t m); + static type_t str2type(const value_t &); + static const char *type2str(type_t t); + + void input(value_t data); + template + void write_regs(REGS &, const Stage *, gress_t); +}; + +class DefaultErrorMode : public Section, public ErrorMode { + DefaultErrorMode() : Section("error_mode") { + // This code sets the default error mode when the assembler is used with an older + // compiler. Current compiler should always set or override this in the .bfa file + for (auto &m : mode) m = PROPAGATE_AND_DISABLE; + } + static DefaultErrorMode singleton; + + public: + void input(VECTOR(value_t) args, value_t data) override { ErrorMode::input(data); } + void output(json::map &) override {} + static ErrorMode get() { return singleton; } +}; + +#endif /* BF_ASM_ERROR_MODE_H_ */ diff --git a/backends/tofino/bf-asm/escape.h b/backends/tofino/bf-asm/escape.h new file mode 100644 index 00000000000..cc76afa5ffd --- /dev/null +++ b/backends/tofino/bf-asm/escape.h @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_ESCAPE_H_ +#define BF_ASM_ESCAPE_H_ + +#include +#include + +#include "hex.h" + +class escape { + std::string str; + + public: + explicit escape(const std::string &s) : str(s) {} + friend std::ostream &operator<<(std::ostream &os, escape e); +}; + +inline std::ostream &operator<<(std::ostream &os, escape e) { + for (char ch : e.str) { + switch (ch) { + case '\n': + os << "\\n"; + break; + case '\t': + os << "\\t"; + break; + case '\\': + os << "\\\\"; + break; + default: + if (ch < 32 || ch >= 127) + os << "\\x" << hex(ch & 0xff, 2, '0'); + else + os << ch; + } + } + return os; +} + +#endif /* BF_ASM_ESCAPE_H_ */ diff --git a/backends/tofino/bf-asm/exact_match.cpp b/backends/tofino/bf-asm/exact_match.cpp new file mode 100644 index 00000000000..a92d49c7297 --- /dev/null +++ b/backends/tofino/bf-asm/exact_match.cpp @@ -0,0 +1,528 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "tofino/exact_match.h" + +#include "action_bus.h" +#include "algorithm.h" +#include "hashexpr.h" +#include "hex.h" +#include "input_xbar.h" +#include "instruction.h" +#include "misc.h" +#include "stage.h" +#include "tables.h" + +void ExactMatchTable::setup(VECTOR(pair_t) & data) { + common_init_setup(data, false, P4Table::MatchEntry); + for (auto &kv : MapIterChecked(data, {"meter", "stats", "stateful"})) { + if (common_setup(kv, data, P4Table::MatchEntry)) { + // Dynamic key masks are only on exact match tables + } else if (kv.key == "dynamic_key_masks") { + if (CHECKTYPE(kv.value, tSTR)) + dynamic_key_masks = (strncmp(kv.value.s, "true", 4) == 0); + } else if (kv.key == "stash") { + CHECKTYPE(kv.value, tMAP); + for (auto &m : kv.value.map) { + if (m.key == "row") { + if (CHECKTYPE(m.value, tVEC)) { + auto rows = m.value.vec; + for (value_t &r : rows) { + if (CHECKTYPE(r, tINT)) stash_rows.push_back(r.i); + } + } + } + if (m.key == "col") { + if (CHECKTYPE(m.value, tVEC)) { + auto cols = m.value.vec; + for (value_t &c : cols) { + if (CHECKTYPE(c, tINT)) stash_cols.push_back(c.i); + } + } + } + if (m.key == "unit") { + if (CHECKTYPE(m.value, tVEC)) { + auto units = m.value.vec; + for (value_t &u : units) { + if (CHECKTYPE(u, tINT)) stash_units.push_back(u.i); + } + } + } + } + if (stash_rows.size() == 0) { + error(kv.value.lineno, "No 'row' attribute for stash info in exact match table %s", + name()); + return; + } + if (stash_cols.size() == 0) { + error(kv.value.lineno, "No 'col' attribute for stash info in exact match table %s", + name()); + return; + } + if (stash_units.size() == 0) { + error(kv.value.lineno, "No 'unit' attribute for stash info in exact match table %s", + name()); + return; + } + if (stash_units.size() != stash_rows.size()) { + error(kv.value.lineno, + "Stash units not specified correctly for each row entry " + "in exact match table %s", + name()); + return; + } + } else if (kv.key == "search_bus" || kv.key == "result_bus") { + // already dealt with in Table::setup_layout via common_init_setup + } else { + common_sram_setup(kv, data); + } + } + common_sram_checks(); +} + +void ExactMatchTable::pass1() { + LOG1("### Exact match table " << name() << " pass1 " << loc()); + SRamMatchTable::pass1(); + // Check if stashes are allocated (only for exact match tables). Note + // stashes are disabled on JBAY + if (stash_rows.size() == 0 && options.target == TOFINO && layout_size() > 0) + error(lineno, "No stashes allocated for exact match table %s in stage %d", name(), + stage->stageno); +} + +/** + * Any bits that are not matched directly against, but appear in the key of the p4 table, + * are ghost bits. The rules for ghost bits on exact match tables are: + * + * 1. Any field that does not appear in the match key must appear in the hash function. This + * is considered a ghost bit + * 2. A hash column can have at most one ghost bit, in order to maintain the linear + * independence of the impact of each ghost bit. + * + * The following function verifies these two properties, and saves them in a map to be output + * in the gen_ghost_bits function call + */ +void ExactMatchTable::determine_ghost_bits() { + std::set> ghost_bits; + // Determine ghost bits by determine what is not in the match + for (auto &p4_param : p4_params_list) { + for (int bit = p4_param.start_bit; bit < p4_param.start_bit + p4_param.bit_width; bit++) { + if (!p4_param.mask.empty() && !p4_param.mask[bit]) continue; // Skip non-masked bits. + bool found = false; + for (auto ms : match) { + std::string field_name = ms->name(); + int field_bit_lo = remove_name_tail_range(field_name) + ms->fieldlobit(); + int field_bit_hi = field_bit_lo + ms->size() - 1; + if (field_name == p4_param.name && field_bit_lo <= bit && field_bit_hi >= bit) { + found = true; + break; + } + } + if (found) continue; + ghost_bits.emplace(p4_param.name, bit); + } + } + + BUG_CHECK(!input_xbar.empty(), "%s does not have an input xbar", name()); + for (const auto &ixb : input_xbar) { + int way_index = 0; + for (auto way : ways) { + bitvec hash_tables; + if (auto *hash_group = ixb->get_hash_group(way.group_xme)) { + hash_tables = bitvec(hash_group->tables); + } else { + for (auto &ht : ixb->get_hash_tables()) { + BUG_CHECK(ht.first.type == InputXbar::HashTable::EXACT); + hash_tables[ht.first.index] = 1; + } + } + + // key is the field name/field bit that is the ghost bit + // value is the bits that the ghost bit appears in within this way + std::map, bitvec> ghost_bit_impact; + + // Check a phv ref against the ghost bits for sanity + auto check_ref = [this, way_index, &ghost_bits, &ghost_bit_impact, &ixb](Phv::Ref &ref, + int hash_bit) { + std::string field_name = ref.name(); + int field_bit = remove_name_tail_range(field_name) + ref.fieldlobit(); + for (int i = 0; i < ref.size(); ++i) { + auto key = std::make_pair(field_name, field_bit + i); + auto ghost_bit_it = ghost_bits.find(key); + if (ghost_bit_it == ghost_bits.end()) continue; + + // This is a check to make sure that the ghost bit appears only once + // in the hash column, as an even number of appearances would + // xor each other out, and cancel the hash out. This check + // should be done on all hash bits + if (ghost_bit_impact[key].getbit(hash_bit)) { + error(ixb->lineno, + "Ghost bit %s:%d appears multiple times " + "in the same hash col %d", + key.first.c_str(), key.second, way_index); + return; + } + ghost_bit_impact[key].setbit(hash_bit); + } + }; + + // Calculate the ghost bit per hash way + for (unsigned hash_table_id : hash_tables) { + auto &hash_table = ixb->get_hash_table(hash_table_id); + for (auto hash_bit : way.select_bits()) { + if (hash_table.count(hash_bit) == 0) continue; + const HashCol &hash_col = hash_table.at(hash_bit); + if (hash_col.fn) { + for (auto &ref : hash_col.fn->get_sources(hash_col.bit)) + check_ref(ref, hash_bit); + } else { + for (const auto &input_bit : hash_col.data) + if (auto ref = ixb->get_hashtable_bit(hash_table_id, input_bit)) + check_ref(ref, hash_bit); + } + } + } + + // Verify that each ghost bit appears in the hash function + for (auto gb : ghost_bits) { + if (ghost_bit_impact.find(gb) == ghost_bit_impact.end()) { + error(ixb->lineno, + "Ghost bit %s:%d does not appear on the hash function " + "for way %d", + gb.first.c_str(), gb.second, way_index); + return; + } + } + + // Verify that the ghost bits are linearly independent, that only one ghost bit + // exists per column + bitvec total_use; + for (auto gbi : ghost_bit_impact) { + if (!(total_use & gbi.second).empty()) + error(ixb->lineno, "The ghost bits are not linear independent on way %d", + way_index); + total_use |= gbi.second; + } + + auto &ghost_bit_position = ghost_bit_positions[way.group_xme]; + for (auto gbi : ghost_bit_impact) { + ghost_bit_position[gbi.first] |= gbi.second; + } + way_index++; + } + } +} + +void ExactMatchTable::pass2() { + LOG1("### Exact match table " << name() << " pass2 " << loc()); + // FIXME -- does some of this common stuff belong in SRamMatch::pass2 + if (logical_id < 0) choose_logical_id(); + for (auto &ixb : input_xbar) ixb->pass2(); + setup_word_ixbar_group(); + if (actions) actions->pass2(this); + if (action_bus) action_bus->pass2(this); + if (gateway) gateway->pass2(); + if (idletime) idletime->pass2(); + if (format) format->pass2(this); + unsigned usable = -1; + for (auto &ixb : input_xbar) usable &= ixb->exact_physical_ids(); + allocate_physical_ids(usable); + determine_ghost_bits(); + // Derive a stash format from current table format with a single entry (we + // use group 0 entry) and all fields except 'version' and 'action' (match + // overhead). The version bits are set by the driver. + if (format) { + stash_format.reset(new Format(this)); + stash_format->size = MEM_WORD_WIDTH; + stash_format->log2size = ceil_log2(MEM_WORD_WIDTH); + auto group = 0; + for (auto f = format->begin(group); f != format->end(group); f++) { + if (f->first == "action" || f->first == "version") continue; + stash_format->add_field(f->second, f->first, group); + } + } + for (auto &hd : hash_dist) hd.pass2(this); + if (format) verify_format_pass2(); +} + +void ExactMatchTable::pass3() { + LOG1("### Exact match table " << name() << " pass3 " << loc()); + SRamMatchTable::pass3(); + if (action_bus) action_bus->pass3(this); +} + +// Check way_map for each stash row/col pair to determine which word the ram is +// assigned to and verify if it is the match overhead word. Allocate stash +// overhead row for each stash row/col pair. +void ExactMatchTable::generate_stash_overhead_rows() { + auto mem_units_per_word = format ? format->get_mem_units_per_table_word() : 1; + for (int i = 0; i < stash_rows.size(); i++) { + auto idx = (i + mem_units_per_word) / mem_units_per_word; + if (stash_overhead_rows.size() >= idx) continue; + auto stash_row = stash_rows[i]; + auto stash_col = stash_cols[i]; + for (auto &row : layout) { + if (row.row == stash_row) { + Ram stash_ram(stash_row, stash_col); + if (way_map.count(stash_ram) > 0) { + auto way_word = way_map[stash_ram].word; + BUG_CHECK(format); + if (way_word == format->overhead_word) { + stash_overhead_rows.push_back(stash_row); + break; + } + } + } + } + } +} + +/* FIXME -- should have ExactMatchTable::write_merge_regs write some of the merge stuff + * from write_regs? */ +template +void ExactMatchTable::write_regs_vt(REGS ®s) { + LOG1("### Exact match table " << name() << " write_regs " << loc()); + SRamMatchTable::write_regs(regs); + + for (auto &row : layout) { + auto &rams_row = regs.rams.array.row[row.row]; + for (auto &ram : row.memunits) { + auto &way = way_map[ram]; + BUG_CHECK(ram.stage == INT_MIN && ram.row == row.row, "bogus %s in row %d", ram.desc(), + row.row); + auto &ram_cfg = rams_row.ram[ram.col]; + ram_cfg.match_nibble_s0q1_enable = version_nibble_mask.getrange(way.word * 32U, 32); + ram_cfg.match_nibble_s1q0_enable = UINT64_C(0xffffffff); + } + } + + // Write stash regs if stashes are allocated + if (stash_rows.size() == 0) return; + auto &merge = regs.rams.match.merge; + auto &stash_hitmap_output_map = merge.stash_hitmap_output_map; + generate_stash_overhead_rows(); + auto mem_units_per_word = format ? format->get_mem_units_per_table_word() : 1; + for (int i = 0; i < stash_rows.size(); i++) { + auto stash_row = stash_rows[i]; + auto stash_col = stash_cols[i]; + auto stash_unit_id = stash_units[i]; + MemUnit stash_memunit(stash_row, stash_col); + auto idx = i / mem_units_per_word; + auto physical_row_with_overhead = + stash_overhead_rows.size() > idx ? stash_overhead_rows[idx] : ways[0].rams[0].row; + LOG5("Setting cfg for stash Row: " << stash_row << ", stash Unit: " << stash_unit_id + << " with overhead word row: " + << physical_row_with_overhead); + auto &stash_map_entry = stash_hitmap_output_map[stash_unit_id][stash_row]; + stash_map_entry.enabled_3bit_muxctl_select = physical_row_with_overhead; + stash_map_entry.enabled_3bit_muxctl_enable = 1; + auto &stash_reg = regs.rams.array.row[stash_row].stash; + auto &input_data_ctl = stash_reg.stash_match_input_data_ctl[stash_unit_id]; + input_data_ctl.stash_hash_adr_select = ways[0].index / EXACT_HASH_ADR_BITS; + input_data_ctl.stash_enable = 1; + input_data_ctl.stash_logical_table = logical_id; + input_data_ctl.stash_thread = (gress == EGRESS); + auto &stash_row_nxtable_bus_drive = + merge.stash_row_nxtable_bus_drive[stash_unit_id][stash_row]; + for (auto &row : layout) { + if (row.row != stash_row) continue; + if (contains(row.memunits, stash_memunit)) { + // Assumption is that the search or match and result buses are + // always generated on the same index + auto &stash_match_mask = stash_reg.stash_match_mask[stash_unit_id]; + if (stash_row == physical_row_with_overhead) { + // FIXME -- the overhead row should always have a result bus allocated, but + // sometimes it does not. This hack has been here for awhile and is needed + // for p4_16/compile_only/meters_0.p4 at least, but seems wrong and unsafe + int result_bus = row.bus.count(Layout::RESULT_BUS) + ? row.bus.at(Layout::RESULT_BUS) + : row.bus.at(Layout::SEARCH_BUS); + stash_row_nxtable_bus_drive = 1 << result_bus; + stash_reg.stash_match_result_bus_select[stash_unit_id] = 1 << result_bus; + + // Set default next table only when there is a single next table + auto &nxt_table_lut = merge.stash_next_table_lut[stash_unit_id][stash_row]; + std::set nxt_tables; + for (auto &n : hit_next) { + for (auto &n1 : n) { + nxt_tables.emplace(n1); + } + } + if (nxt_tables.size() == 0) { + nxt_table_lut = Stage::end_of_pipe(); + } else if (nxt_tables.size() == 1) { + nxt_table_lut = miss_next.next_table_id(); + } else { + nxt_table_lut = 0; + } + + // 2 entries per stash unit + nxt_table_lut |= (nxt_table_lut << 8); + + bitvec match_mask; + match_mask.setrange(0, 128); + // Since stash format can only have one entry (and no version bits) we + // generate the stash mask on exact match format with group 0 + if (Format::Field *match = format->field("match", 0)) { + for (auto &piece : match->bits) + match_mask.clrrange(piece.lo, piece.hi + 1 - piece.lo); + } + for (int word = 0; word < 4; word++) { + stash_match_mask[word] = match_mask.getrange(word * 32, 32); + } + } else { + stash_row_nxtable_bus_drive = 0; + stash_reg.stash_match_result_bus_select[stash_unit_id] = 0; + for (int word = 0; word < 4; word++) { + stash_match_mask[word] = 0; + } + } + input_data_ctl.stash_match_data_select = row.bus.at(Layout::SEARCH_BUS); + input_data_ctl.stash_hashbank_select = row.bus.at(Layout::SEARCH_BUS); + break; + } + } + } +} + +void ExactMatchTable::gen_tbl_cfg(json::vector &out) const { + LOG3("### Exact match table " << name() << " gen_tbl_cfg " << loc()); + unsigned size = get_number_entries(); + json::map &tbl = *base_tbl_cfg(out, "match", size); + add_all_reference_tables(tbl); + json::map &stage_tbl = *add_common_sram_tbl_cfgs(tbl, "exact", "hash_match"); + add_pack_format(stage_tbl, format.get(), true, false); + stage_tbl["memory_resource_allocation"] = nullptr; + if (stash_rows.size() > 0) { + json::map &stash_allocation = stage_tbl["stash_allocation"] = json::map(); + // Add 'action' field if present + if (format && stash_format) { + int group = 0; + for (auto f = format->begin(group); f != format->end(group); f++) { + if (f->first == "action") stash_format->add_field(f->second, f->first, group); + } + } + add_pack_format(stash_allocation, stash_format.get(), false, true); + auto mem_units_per_word = format ? format->get_mem_units_per_table_word() : 1; + auto &stash_pack_formats = stash_allocation["pack_format"]->to(); + for (auto &stash_pack_format : stash_pack_formats) { + json::map &pack = stash_pack_format->to(); + pack["number_memory_units_per_table_word"] = mem_units_per_word; + pack["table_word_width"] = MEM_WORD_WIDTH * mem_units_per_word; + } + auto num_stash_entries = stash_rows.size() / mem_units_per_word * 2; + stash_allocation["num_stash_entries"] = num_stash_entries; + json::vector &stash_entries = stash_allocation["stash_entries"] = json::vector(); + for (int k = 0; k < stash_rows.size() / mem_units_per_word; k++) { + for (int i = 0; i < 2; i++) { + json::vector stash_entry; + for (int j = 0; j < mem_units_per_word; j++) { + auto stash_row = stash_rows[k * mem_units_per_word + j]; + auto stash_col = stash_cols[k * mem_units_per_word + j]; + auto stash_unit = stash_units[k * mem_units_per_word + j]; + MemUnit stash_memunit(stash_row, stash_col); + json::map stash_entry_per_unit; + stash_entry_per_unit["stash_entry_id"] = (4 * stash_row) + (2 * stash_unit) + i; + for (auto &row : layout) { + if (row.row != stash_row) continue; + if (contains(row.memunits, stash_memunit)) { + int bus = row.bus.at(Layout::SEARCH_BUS); + stash_entry_per_unit["stash_match_data_select"] = bus; + stash_entry_per_unit["stash_hashbank_select"] = bus; + stash_entry_per_unit["hash_function_id"] = k; + break; + } + } + stash_entry.push_back(std::move(stash_entry_per_unit)); + } + stash_entries.push_back(std::move(stash_entry)); + } + } + } else { + stage_tbl["stash_allocation"] = nullptr; + } + json::map &match_attributes = tbl["match_attributes"]; + match_attributes["uses_dynamic_key_masks"] = dynamic_key_masks; + if (ways.size() > 0) { + json::vector &way_stage_tables = stage_tbl["ways"] = json::vector(); + unsigned way_number = 0; + for (auto &way : ways) { + json::map way_tbl; + way_tbl["stage_number"] = stage->stageno; + way_tbl["way_number"] = way_number++; + way_tbl["stage_table_type"] = "hash_way"; + auto fmt_width = get_format_width(); + BUG_CHECK(fmt_width); + unsigned ram_depth = way.rams.at(0).isLamb() ? LAMB_DEPTH : SRAM_DEPTH; + way_tbl["size"] = way.rams.size() / fmt_width * format->groups() * ram_depth; + add_pack_format(way_tbl, format.get(), false); + way_tbl["memory_resource_allocation"] = gen_memory_resource_allocation_tbl_cfg(way); + way_stage_tables.push_back(std::move(way_tbl)); + } + } + if (size == 0) { + if (!match_attributes.count("match_type")) + match_attributes["match_type"] = "match_with_no_key"; + if (!stage_tbl["stage_table_type"]) stage_tbl["stage_table_type"] = "match_with_no_key"; + stage_tbl["size"] = 1; + } + if (stage_tbl["stage_table_type"] == "hash_match") { + // hash_match table schema requires 'hash_functions' and 'ways' so add (empty) if + // they are not present + if (!stage_tbl["hash_functions"]) stage_tbl["hash_functions"] = json::vector(); + if (!stage_tbl["ways"]) stage_tbl["ways"] = json::vector(); + } +} + +/** + * The ghost_bits information is required by the driver to correctly run an entry read from + * hardware. Ghost bits are bits that do not appear in the key, and must be calculated + * from the hash matrix. + * + * The ghost_bits information is broken into two vectors: + * + * - ghost_bit_info: a vector of information on ghost bits, maps of 2 fields + * 1. field_name - name of the field being ghosted + * 2. bit_in_match_spec - awfully named for the field bit (not the bit in the entire key) + * + * - ghost_bit_to_hash_bit: a vector per each entry in the ghost_bit_info describing which + * hash bits coordinate to which ghost bits + */ +void ExactMatchTable::gen_ghost_bits(int hash_function_number, + json::vector &ghost_bits_to_hash_bits, + json::vector &ghost_bits_info) const { + if (ghost_bit_positions.count(hash_function_number) == 0) return; + auto ghost_bit_pos = ghost_bit_positions.at(hash_function_number); + + for (auto kv : ghost_bit_pos) { + json::map ghost_bit_info; + auto field_name = kv.first.first; + auto global_name = field_name; + auto p4_param = find_p4_param(field_name); + if (p4_param && !p4_param->key_name.empty()) field_name = p4_param->key_name; + ghost_bit_info["field_name"] = field_name; + ghost_bit_info["global_name"] = global_name; + ghost_bit_info["bit_in_match_spec"] = kv.first.second; + ghost_bits_info.push_back(std::move(ghost_bit_info)); + + json::vector ghost_bit_to_hash_bits; + for (auto hash_bit : kv.second) ghost_bit_to_hash_bits.push_back(hash_bit); + ghost_bits_to_hash_bits.push_back(std::move(ghost_bit_to_hash_bits)); + } +} + +DEFINE_TABLE_TYPE_WITH_SPECIALIZATION(ExactMatchTable, TARGET_CLASS) diff --git a/backends/tofino/bf-asm/exename.cpp b/backends/tofino/bf-asm/exename.cpp new file mode 100644 index 00000000000..5fe2e6a162c --- /dev/null +++ b/backends/tofino/bf-asm/exename.cpp @@ -0,0 +1,69 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "exename.h" + +#include +#include +#include +#include + +#include +#include + +#include "bfas.h" + +template +static void convertToAbsPath(const char *const relPath, char (&output)[N]) { + output[0] = '\0'; // Default to the empty string, indicating failure. + + char cwd[PATH_MAX]; + if (!getcwd(cwd, sizeof(cwd))) return; + const size_t cwdLen = strlen(cwd); + if (cwdLen == 0) return; + const char *separator = cwd[cwdLen - 1] == '/' ? "" : "/"; + + // Construct an absolute path. We're assuming that @relPath is relative to + // the current working directory. + int n = snprintf(output, N, "%s%s%s", cwd, separator, relPath); + BUG_CHECK(n >= 0, "Pathname too long"); +} + +const char *exename(const char *argv0) { + static char buffer[PATH_MAX]; + if (buffer[0]) return buffer; // done already + int len; + /* find the path of the executable. We use a number of techniques that may fail + * or work on different systems, and take the first working one we find. Fall + * back to not overriding the compiled-in installation path */ + if ((len = readlink("/proc/self/exe", buffer, sizeof(buffer) - 1)) > 0 || + (len = readlink("/proc/curproc/exe", buffer, sizeof(buffer) - 1)) > 0 || + (len = readlink("/proc/curproc/file", buffer, sizeof(buffer) - 1)) > 0 || + (len = readlink("/proc/self/path/a.out", buffer, sizeof(buffer) - 1)) > 0) { + buffer[len] = 0; + } else if (argv0 && argv0[0] == '/') { + snprintf(buffer, sizeof(buffer), "%s", argv0); + } else if (argv0 && strchr(argv0, '/')) { + convertToAbsPath(argv0, buffer); + } else if (getenv("_")) { + strncpy(buffer, getenv("_"), sizeof(buffer)); + buffer[sizeof(buffer) - 1] = 0; + } else { + buffer[0] = 0; + } + return buffer; +} diff --git a/backends/tofino/bf-asm/exename.h b/backends/tofino/bf-asm/exename.h new file mode 100644 index 00000000000..957775dc58f --- /dev/null +++ b/backends/tofino/bf-asm/exename.h @@ -0,0 +1,25 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_EXENAME_H_ +#define BF_ASM_EXENAME_H_ + +/** Attempt to determine the executable name and return a static path to it. Will use + * argv0 if provided and nothing better can be found */ +const char *exename(const char *argv0 = nullptr); + +#endif /* BF_ASM_EXENAME_H_ */ diff --git a/backends/tofino/bf-asm/fdstream.cpp b/backends/tofino/bf-asm/fdstream.cpp new file mode 100644 index 00000000000..0e49aee298b --- /dev/null +++ b/backends/tofino/bf-asm/fdstream.cpp @@ -0,0 +1,85 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "fdstream.h" + +#include + +#include + +#define BUFSIZE 1024 + +fdstream::buffer_t::int_type fdstream::buffer_t::underflow() { + if (!gptr()) { + char_type *n = new char_type[BUFSIZE]; + setg(n, n, n); + } else if (gptr() != egptr()) { + size_t len = egptr() - gptr(); + if (len > 0) std::memmove(eback(), gptr(), len * sizeof(char_type)); + setg(eback(), eback(), eback() + len); + } else { + setg(eback(), eback(), eback()); + } + int rv = ::read(fd, egptr(), eback() + BUFSIZE - egptr()); + if (rv > 0) + setg(eback(), eback(), egptr() + rv); + else if (gptr() == egptr()) + return traits_type::eof(); + return traits_type::to_int_type(*gptr()); +} + +fdstream::buffer_t::int_type fdstream::buffer_t::overflow(fdstream::buffer_t::int_type c) { + if (!pptr()) { + char_type *n = new char_type[BUFSIZE]; + setp(n, n + BUFSIZE); + } + if (pptr() != pbase()) { + int rv = ::write(fd, pbase(), pptr() - pbase()); + if (rv <= 0) return traits_type::eof(); + if (pbase() + rv == pptr()) + setp(pbase(), epptr()); + else { + size_t len = pptr() - pbase() + rv; + std::memmove(pbase(), pbase() + rv, len); + setp(pbase(), epptr()); + pbump(len); + } + } + if (!traits_type::eq_int_type(c, traits_type::eof())) { + *pptr() = c; + pbump(1); + return c; + } else { + return traits_type::not_eof(c); + } +} + +int fdstream::buffer_t::sync() { + char *p = pbase(), *e = pptr(); + while (p != e) { + int rv = ::write(fd, p, e - p); + if (rv <= 0) { + if (p != pbase()) std::memmove(pbase(), p, e - p); + setp(pbase(), epptr()); + pbump(e - p); + return -1; + } + p += rv; + } + setp(pbase(), epptr()); + return 0; +} diff --git a/backends/tofino/bf-asm/fdstream.h b/backends/tofino/bf-asm/fdstream.h new file mode 100644 index 00000000000..524414374ed --- /dev/null +++ b/backends/tofino/bf-asm/fdstream.h @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_FDSTREAM_H_ +#define BF_ASM_FDSTREAM_H_ + +#include +#include + +#include +#include +#include + +class fdstream : public std::iostream { + struct buffer_t : public std::basic_streambuf { + int fd; + + public: + explicit buffer_t(int _fd) : fd(_fd) {} + ~buffer_t() { + delete[] eback(); + delete[] pbase(); + } + int sync(); + int_type underflow(); + int_type overflow(int_type c = traits_type::eof()); + void reset() { + setg(eback(), eback(), eback()); + setp(pbase(), epptr()); + } + } buffer; + std::function closefn; + + public: + explicit fdstream(int fd = -1) : std::iostream(&buffer), buffer(fd) { init(&buffer); } + ~fdstream() { + if (closefn) closefn(); + } + void connect(int fd) { + flush(); + buffer.reset(); + buffer.fd = fd; + } + void setclose(std::function fn) { closefn = fn; } +}; + +#endif /* BF_ASM_FDSTREAM_H_ */ diff --git a/backends/tofino/bf-asm/flexible_headers.cpp b/backends/tofino/bf-asm/flexible_headers.cpp new file mode 100644 index 00000000000..e485b834e28 --- /dev/null +++ b/backends/tofino/bf-asm/flexible_headers.cpp @@ -0,0 +1,48 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include + +namespace BFASM { + +// Singleton class representing the assembler flexible_headers +class FlexibleHeaders : public Section { + private: + std::unique_ptr flexHeaders; + + FlexibleHeaders() : Section("flexible_headers") {} + + void input(VECTOR(value_t) args, value_t data) { + if (!CHECKTYPE(data, tVEC)) return; + flexHeaders = std::move(toJson(data.vec)); + } + + void output(json::map &ctxtJson) { + if (flexHeaders != nullptr) ctxtJson["flexible_headers"] = std::move(flexHeaders); + } + + public: + // disable any other constructors + FlexibleHeaders(FlexibleHeaders const &) = delete; + void operator=(FlexibleHeaders const &) = delete; + + static FlexibleHeaders singleton_flexHeaders; +} FlexibleHeaders::singleton_flexHeaders; + +}; // namespace BFASM diff --git a/backends/tofino/bf-asm/gateway.cpp b/backends/tofino/bf-asm/gateway.cpp new file mode 100644 index 00000000000..f669f9b9d9b --- /dev/null +++ b/backends/tofino/bf-asm/gateway.cpp @@ -0,0 +1,918 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "algorithm.h" +#include "hashexpr.h" +#include "hex.h" +#include "input_xbar.h" +#include "instruction.h" +#include "misc.h" +#include "stage.h" +#include "tables.h" + +// template specialization declarations +#include "jbay/gateway.h" +#include "tofino/gateway.h" + +static struct { + unsigned units, bits, half_shift, mask, half_mask; +} range_match_info[] = {{0, 0, 0, 0, 0}, {6, 4, 2, 0xf, 0x3}, {3, 8, 8, 0xffff, 0xff}}; + +// Dummy value used to start gateway handles. For future use by driver, +// Incremented from inside the gateway table +static uint gateway_handle = 0x70000000; + +GatewayTable::Match::Match(value_t *v, value_t &data, range_match_t range_match) { + if (range_match) { + for (unsigned i = 0; i < range_match_info[range_match].units; i++) + range[i] = range_match_info[range_match].mask; + } + if (v) { + lineno = v->lineno; + if (v->type == tVEC) { + int last = v->vec.size - 1; + if (last > static_cast(range_match_info[range_match].units)) + error(lineno, "Too many set values for range match"); + for (int i = 0; i < last; i++) + if (CHECKTYPE((*v)[last - i - 1], tINT)) { + if ((unsigned)(*v)[last - i - 1].i > range_match_info[range_match].mask) + error(lineno, "range match set too large"); + range[i] = (*v)[last - i - 1].i; + } + v = &(*v)[last]; + } + if (v->type == tINT) { + val.word1 = bitvec(v->i); + val.word0.setrange(0, 64); + val.word0 -= val.word1; + } else if (v->type == tBIGINT) { + val.word1.setraw(v->bigi.data, v->bigi.size); + val.word0.setrange(0, v->bigi.size * 64); + val.word0 -= val.word1; + } else if (v->type == tMATCH) { + val = v->m; + } else if (v->type == tBIGMATCH) { + val = v->bigm; + } + } + if (data == "run_table") { + run_table = true; + } else if (data.type == tSTR || data.type == tVEC) { + next = data; + } else if (data.type == tMAP) { + for (auto &kv : MapIterChecked(data.map)) { + if (kv.key == "next") { + next = kv.value; + } else if (kv.key == "run_table") { + if (kv.value == "true") + run_table = true; + else if (kv.value == "false") + run_table = false; + else + error(kv.value.lineno, "Syntax error, expecting boolean"); + } else if (kv.key == "action") { + if (CHECKTYPE(kv.value, tSTR)) action = kv.value.s; + } else { + error(kv.key.lineno, "Syntax error, expecting gateway action description"); + } + } + if (run_table && next.set()) + error(data.lineno, "Can't run table and override next in the same gateway row"); + } else { + error(data.lineno, "Syntax error, expecting gateway action description"); + } +} + +void GatewayTable::setup(VECTOR(pair_t) & data) { + setup_logical_id(); + if (auto *v = get(data, "range")) { + if (CHECKTYPE(*v, tINT)) { + if (v->i == 2) range_match = DC_2BIT; + if (v->i == 4) + range_match = DC_4BIT; + else + error(v->lineno, "Unknown range match size %" PRId64 " bits", v->i); + } + } + for (auto &kv : MapIterChecked(data, true)) { + if (kv.key == "name") { + if (CHECKTYPE(kv.value, tSTR)) gateway_name = kv.value.s; + } else if (kv.key == "row") { + if (!CHECKTYPE(kv.value, tINT)) continue; + if (kv.value.i < 0 || kv.value.i > Target::GATEWAY_ROWS()) + error(kv.value.lineno, "row %" PRId64 " out of range", kv.value.i); + if (layout.empty()) layout.resize(1); + layout[0].row = kv.value.i; + layout[0].lineno = kv.value.lineno; + } else if (kv.key == "bus") { + if (!CHECKTYPE(kv.value, tINT)) continue; + if (kv.value.i < 0 || kv.value.i > 1) + error(kv.value.lineno, "bus %" PRId64 " out of range", kv.value.i); + if (layout.empty()) layout.resize(1); + layout[0].bus[Layout::SEARCH_BUS] = kv.value.i; + if (layout[0].lineno < 0) layout[0].lineno = kv.value.lineno; + } else if (kv.key == "payload_row") { + if (!CHECKTYPE(kv.value, tINT)) continue; + if (kv.value.i < 0 || kv.value.i > 7) + error(kv.value.lineno, "row %" PRId64 " out of range", kv.value.i); + if (layout.size() < 2) layout.resize(2); + layout[1].row = kv.value.i; + layout[1].lineno = kv.value.lineno; + } else if (kv.key == "payload_bus") { + if (!CHECKTYPE(kv.value, tINT)) continue; + if (kv.value.i < 0 || kv.value.i > 3) + error(kv.value.lineno, "bus %" PRId64 " out of range", kv.value.i); + if (layout.size() < 2) layout.resize(2); + layout[1].bus[Layout::RESULT_BUS] = kv.value.i; + if (layout[1].lineno < 0) layout[1].lineno = kv.value.lineno; + } else if (kv.key == "payload_unit") { + if (!CHECKTYPE(kv.value, tINT)) continue; + if (kv.value.i < 0 || kv.value.i > 1) + error(kv.value.lineno, "payload unit %" PRId64 " out of range", kv.value.i); + payload_unit = kv.value.i; + } else if (kv.key == "gateway_unit" || kv.key == "unit") { + if (!CHECKTYPE(kv.value, tINT)) continue; + if (kv.value.i < 0 || kv.value.i > 1) + error(kv.value.lineno, "gateway unit %" PRId64 " out of range", kv.value.i); + gw_unit = kv.value.i; + } else if (kv.key == "input_xbar") { + if (CHECKTYPE(kv.value, tMAP)) + input_xbar.emplace_back(InputXbar::create(this, false, kv.key, kv.value.map)); + } else if (kv.key == "format") { + if (CHECKTYPEPM(kv.value, tMAP, kv.value.map.size > 0, "non-empty map")) + format.reset(new Format(this, kv.value.map)); + } else if (kv.key == "always_run") { + if ((always_run = get_bool(kv.value)) && !Target::SUPPORT_ALWAYS_RUN()) + error(kv.key.lineno, "always_run not supported on %s", Target::name()); + } else if (kv.key == "miss") { + miss = Match(0, kv.value, range_match); + } else if (kv.key == "condition") { + if (CHECKTYPE(kv.value, tMAP)) { + for (auto &v : kv.value.map) { + if (v.key == "expression" && CHECKTYPE(v.value, tSTR)) + gateway_cond = v.value.s; + else if (v.key == "true") + cond_true = Match(0, v.value, range_match); + else if (v.key == "false") + cond_false = Match(0, v.value, range_match); + } + } + } else if (kv.key == "payload") { + if (CHECKTYPE2(kv.value, tINT, tBIGINT)) payload = get_int64(kv.value); + /* FIXME -- should also be able to specify payload as () */ + have_payload = kv.key.lineno; + } else if (kv.key == "payload_map") { + if (kv.value.type == tVEC) { + if (kv.value.vec.size > Target::GATEWAY_PAYLOAD_GROUPS()) + error(kv.value.lineno, "payload_map too large (limit %d)", + Target::GATEWAY_PAYLOAD_GROUPS()); + for (auto &v : kv.value.vec) { + if (v == "_") + payload_map.push_back(-1); + else if (CHECKTYPE(v, tINT)) + payload_map.push_back(v.i); + } + } + } else if (kv.key == "match_address") { + if (CHECKTYPE(kv.value, tINT)) match_address = kv.value.i; + } else if (kv.key == "match") { + if (kv.value.type == tVEC) { + for (auto &v : kv.value.vec) match.emplace_back(gress, stage->stageno, v); + } else if (kv.value.type == tMAP) { + for (auto &v : kv.value.map) { + if (CHECKTYPE(v.key, tINT)) { + if (v.value.type == tCMD && v.value.vec.size == 2 && + v.value.vec[0] == "$valid") { + match.emplace_back(v.key.i, gress, stage->stageno, v.value.vec[1], + true); + } else { + match.emplace_back(v.key.i, gress, stage->stageno, v.value); + } + } + } + } else { + match.emplace_back(gress, stage->stageno, kv.value); + } + } else if (kv.key == "range") { + /* done above, to be before match parsing */ + } else if (kv.key == "xor") { + if (kv.value.type == tVEC) { + for (auto &v : kv.value.vec) xor_match.emplace_back(gress, stage->stageno, v); + } else if (kv.value.type == tMAP) { + for (auto &v : kv.value.map) + if (CHECKTYPE(v.key, tINT)) + xor_match.emplace_back(v.key.i, gress, stage->stageno, v.value); + } else { + xor_match.emplace_back(gress, stage->stageno, kv.value); + } + } else if (kv.key == "long_branch" && Target::LONG_BRANCH_TAGS() > 0) { + if (options.disable_long_branch) error(kv.key.lineno, "long branches disabled"); + if (CHECKTYPE(kv.value, tMAP)) { + for (auto &lb : kv.value.map) { + if (lb.key.type != tINT || lb.key.i < 0 || + lb.key.i >= Target::LONG_BRANCH_TAGS()) + error(lb.key.lineno, "Invalid long branch tag %s", value_desc(lb.key)); + else if (long_branch.count(lb.key.i)) + error(lb.key.lineno, "Duplicate long branch tag %" PRIi64, lb.key.i); + else + long_branch.emplace(lb.key.i, lb.value); + } + } + } else if (kv.key == "context_json") { + setup_context_json(kv.value); + } else if (kv.key.type == tINT || kv.key.type == tBIGINT || kv.key.type == tMATCH || + (kv.key.type == tVEC && range_match != NONE)) { + table.emplace_back(&kv.key, kv.value, range_match); + } else { + warning(kv.key.lineno, "ignoring unknown item %s in table %s", value_desc(kv.key), + name()); + } + } +} + +bool GatewayTable::check_match_key(MatchKey &key, const std::vector &vec, bool is_xor) { + if (!key.val.check()) return false; + if (key.val->reg.mau_id() < 0) + error(key.val.lineno, "%s not accessable in mau", key.val->reg.name); + if (key.offset >= 0) { + for (auto &okey : vec) { + if (&okey == &key) break; + if (key.offset < okey.offset + static_cast(okey.val->size()) && + okey.offset < key.offset + static_cast(key.val->size())) + error(key.val.lineno, + "Gateway %s key at offset %d overlaps previous " + "value at offset %d", + is_xor ? "xor" : "match", key.offset, okey.offset); + } + } else if (&key == &vec[0]) { + key.offset = 0; + } else { + auto *prev = &key - 1; + key.offset = prev->offset + prev->val->size(); + } + return true; +} + +void GatewayTable::verify_format() { + if (format->log2size > 6) + error(format->lineno, "Gateway payload format too large (max 64 bits)"); + format->log2size = 6; + format->pass1(this); + if (format->groups() > Target::GATEWAY_PAYLOAD_GROUPS()) + error(format->lineno, "Too many groups for gateway payload"); + if (payload_map.empty()) { + if (format->groups() == 1) { + payload_map.push_back(0); + } else { + payload_map = std::vector(Target::GATEWAY_PAYLOAD_GROUPS(), -1); + int i = Target::GATEWAY_PAYLOAD_GROUPS() - 2; + int grp = 0; + for (auto &row : table) { + if (!row.run_table && i >= 0) { + if (grp >= format->groups() && format->groups() > 1) { + error(format->lineno, "Not enough groups in format for payload"); + grp = 0; + } + payload_map[i--] = grp++; + } + } + if (!miss.run_table) payload_map.back() = format->groups() - 1; + } + } + for (auto pme : payload_map) { + if (pme < -1 || pme >= int(format->groups())) + error(format->lineno, "Invalid format group %d in payload_map", pme); + } + if (match_table) { + if (match_table->table_type() == TERNARY) { + if (format->groups() > 1) + error(format->lineno, + "Can't have mulitple payload format groups when attached " + "to a ternary table"); + } else if (!match_table->format) { + // ok + } else if (auto *srm = match_table->to()) { + int groups = std::min(format->groups(), match_table->format->groups()); + bool err = false; + for (auto &field : *format) { + if (auto match_field = match_table->format->field(field.first)) { + int match_group = -1; + for (auto gw_group : payload_map) { + ++match_group; + if (gw_group < 0) continue; + int em_group = match_group; + if (!srm->word_info.empty()) { + if (match_group < srm->word_info[0].size()) + em_group = srm->word_info[0][match_group]; + else + em_group = -1; + } + if (em_group < 0) continue; + if (field.second.by_group[gw_group]->bits != + match_field->by_group[em_group]->bits) { + if (!err) { + error(format->lineno, + "Gateway format inconsistent with table " + "%s it is attached to", + match_table->name()); + error(match_table->format->lineno, "field %s inconsistent", + field.first.c_str()); + err = true; + break; + } + } + } + } else { + if (!err) + error(format->lineno, + "Gateway format inconsistent with table %s it is " + "attached to", + match_table->name()); + error(match_table->format->lineno, "No field %s in match table format", + field.first.c_str()); + err = true; + } + } + } + } else if (layout.size() > 1) { + if (!layout[1].bus.count(Layout::RESULT_BUS)) { + error(layout[1].lineno, "No result bus for gateway payload"); + } else { + int result_bus = layout[1].bus.at(Layout::RESULT_BUS); + if (result_bus > 3) + error(layout[1].lineno, "Invalid bus %d for gateway payload", result_bus); + if ((result_bus & 2) && format->groups() > 1) + error(format->lineno, + "Can't have mulitple payload format groups when using " + "ternary indirect bus"); + } + } +} + +void GatewayTable::pass1() { + LOG1("### Gateway table " << name() << " pass1 " << loc()); + if (!match_table) { + // needs to happen before Actions::pass1, but will have been called from the + // match table if this gateway is attached to one. + setup_map_indexing(this); + } + Table::pass1(); +#if 0 + // redundant with (and supercedes) choose_logical_id in pass2. That function is much + // better, taking dependencies into account, so logical_id should not be allocated here + alloc_id("logical", logical_id, stage->pass1_logical_id, + LOGICAL_TABLES_PER_STAGE, true, stage->logical_id_use); +#endif + if (always_run && match_table) + error(lineno, "always_run set on non-standalone gateway for %s", match_table->name()); + if (gw_unit >= 0) { + if (auto *old = stage->gw_unit_use[layout[0].row][gw_unit]) + error(layout[0].lineno, "gateway %d.%d already in use by table %s", layout[0].row, + gw_unit, old->name()); + else + stage->gw_unit_use[layout[0].row][gw_unit] = this; + } + for (auto &ixb : input_xbar) { + ixb->pass1(); + if (Target::GATEWAY_SINGLE_XBAR_GROUP() && ixb->match_group() < 0) + error(ixb->lineno, "Gateway match keys must be in a single ixbar group"); + } + for (auto &k : match) + if (!check_match_key(k, match, false)) break; + for (auto &k : xor_match) + if (!check_match_key(k, xor_match, true)) break; + std::sort(match.begin(), match.end()); + std::sort(xor_match.begin(), xor_match.end()); + if (table.size() > 4) error(lineno, "Gateway can only have 4 match entries max"); + for (auto &line : table) check_next(line.next); + check_next(miss.next); + check_next(cond_false.next); + check_next(cond_true.next); + if (format) verify_format(); + + if (error_count > 0) return; + /* FIXME -- the rest of this function is a hack -- sometimes the compiler wants to + * generate matches just covering the bits it names in the match and other times it wants + * to create the whole tcam value. Need to fix the asm syntax to be sensible and fix the + * compiler's output. + * Part of the issue is that in tofino1/2 we copy the word0/word1 bits directly to + * the tcam, so we need to treat unspecified bits as don't care. Another part is that + * integer constants used as matches get padded with 0 out to a mulitple of 64 bits, + * and those should also be don't care where they don't get matched. + */ + bitvec ignore(0, Target::GATEWAY_MATCH_BITS()); + int shift = -1; + int maxbit = 0; + for (auto &r : match) { + if (range_match && r.offset >= 32) { + continue; + } + ignore.clrrange(r.offset, r.val->size()); + if (shift < 0 || shift > r.offset) shift = r.offset; + if (maxbit < r.offset + r.val->size()) maxbit = r.offset + r.val->size(); + } + if (shift < 0) shift = 0; + LOG3("shift=" << shift << " ignore=0x" << ignore); + for (auto &line : table) { + bitvec matching = (line.val.word0 ^ line.val.word1) << shift; + matching -= (line.val.word0 << shift) - bitvec(0, maxbit); // ignore leading 0s + if (matching & ignore) + warning(line.lineno, "Trying to match on bits not in match of gateway"); + line.val.word0 = (line.val.word0 << shift) | ignore; + line.val.word1 = (line.val.word1 << shift) | ignore; + } +} + +int GatewayTable::find_next_lut_entry(Table *tbl, const Match &match) { + int rv = 0; + for (auto &e : tbl->hit_next) { + if (e == match.next) return rv; + ++rv; + } + for (auto &e : tbl->extra_next_lut) { + if (e == match.next) return rv; + ++rv; + } + tbl->extra_next_lut.push_back(match.next); + if (rv == Target::NEXT_TABLE_SUCCESSOR_TABLE_DEPTH()) + error(tbl->lineno, "Too many next table map entries in table %s", tbl->name()); + return rv; +} + +void GatewayTable::pass2() { + LOG1("### Gateway table " << name() << " pass2 " << loc()); + if (logical_id < 0) { + if (match_table) + logical_id = match_table->logical_id; + else + choose_logical_id(); + } + for (auto &ixb : input_xbar) ixb->pass2(); + need_next_map_lut = miss.next.need_next_map_lut(); + for (auto &e : table) need_next_map_lut |= e.next.need_next_map_lut(); + if (need_next_map_lut) { + Table *tbl = match_table; + if (!tbl) tbl = this; + for (auto &e : table) + if (!e.run_table && e.next_map_lut < 0) e.next_map_lut = find_next_lut_entry(tbl, e); + if (!miss.run_table && miss.next_map_lut < 0) + miss.next_map_lut = find_next_lut_entry(tbl, miss); + } +} + +void GatewayTable::pass3() { + LOG1("### Gateway table " << name() << " pass3 " << loc()); + if (match_table) + physical_ids = match_table->physical_ids; + else + allocate_physical_ids(); +} + +static unsigned match_input_use(const std::vector &match) { + unsigned rv = 0; + for (auto &r : match) { + unsigned lo = r.offset; + unsigned hi = lo + r.val->size() - 1; + if (lo < 32) { + rv |= (((UINT32_C(1) << (hi / 8 - lo / 8 + 1)) - 1) << lo / 8) & 0xf; + lo = 32; + } + if (lo <= hi) rv |= ((UINT32_C(1) << (hi - lo + 1)) - 1) << (lo - 24); + } + return rv; +} + +/* caluclate match_bus byte use (8 bytes/bits) + hash output use (12 bits) */ +unsigned GatewayTable::input_use() const { + unsigned rv = match_input_use(match) | match_input_use(xor_match); + if (!xor_match.empty()) rv |= (rv & 0xf) << 4; + return rv; +} + +bool GatewayTable::is_branch() const { + for (auto &line : table) + if (line.next.next_table() != nullptr) return true; + if (!miss.run_table && miss.next.next_table() != nullptr) return true; + return false; +} + +/* FIXME -- how to deal with (or even specify) matches in the upper 24 bits coming from + * the hash bus? Currently we assume that the input_xbar is declared to set up the + * hash signals correctly so that we can just match them. Should at least check it + * somewhere, somehow. We do some checking in check_match_key above, but is that enough? + */ +template +static bool setup_vh_xbar(REGS ®s, Table *table, Table::Layout &row, int base, + std::vector &match, int group) { + auto &rams_row = regs.rams.array.row[row.row]; + auto &byteswizzle_ctl = + rams_row.exactmatch_row_vh_xbar_byteswizzle_ctl[row.bus.at(Table::Layout::SEARCH_BUS)]; + for (auto &r : match) { + if (r.offset >= 32) break; /* skip hash matches */ + for (int bit = 0; bit < r.val->size(); ++bit) { + int ibyte = table->find_on_ixbar(*Phv::Ref(r.val, bit, bit), group); + if (ibyte < 0) { + error(r.val.lineno, "Can't find %s(%d) on ixbar", r.val.desc().c_str(), bit); + return false; + } + unsigned byte = base + (r.offset + bit) / 8; + byteswizzle_ctl[byte][(r.val->lo + bit) & 7] = 0x10 + ibyte; + } + } + return true; +} + +template +void enable_gateway_payload_exact_shift_ovr(REGS ®s, int bus) { + regs.rams.match.merge.gateway_payload_exact_shift_ovr[bus / 8] |= 1U << bus % 8; +} + +template +void GatewayTable::payload_write_regs(REGS ®s, int row, int type, int bus) { + auto &merge = regs.rams.match.merge; + auto &xbar_ctl = merge.gateway_to_pbus_xbar_ctl[row * 2 + bus]; + if (type) { + xbar_ctl.tind_logical_select = logical_id; + xbar_ctl.tind_inhibit_enable = 1; + } else { + xbar_ctl.exact_logical_select = logical_id; + xbar_ctl.exact_inhibit_enable = 1; + } + if (have_payload >= 0 || match_address >= 0) { + BUG_CHECK(payload_unit == bus); + if (type) + merge.gateway_payload_tind_pbus[row] |= 1 << bus; + else + merge.gateway_payload_exact_pbus[row] |= 1 << bus; + } + if (have_payload >= 0) { + merge.gateway_payload_data[row][bus][0][type] = payload & 0xffffffff; + merge.gateway_payload_data[row][bus][1][type] = payload >> 32; + merge.gateway_payload_data[row][bus][0][type ^ 1] = payload & 0xffffffff; + merge.gateway_payload_data[row][bus][1][type ^ 1] = payload >> 32; + } + if (match_address >= 0) { + merge.gateway_payload_match_adr[row][bus][type] = match_address; + merge.gateway_payload_match_adr[row][bus][type ^ 1] = match_address; + } else if (options.target == TOFINO) { + // For Tofino A0, there is a bug in snapshot that cannot distinguish if a + // gateway is inhibiting a table To work around this, configure the + // gateway_payload_match_adr to an invalid value. Add a command line flag + // if this is only a tofino A0 issue?. + merge.gateway_payload_match_adr[row][bus][type] = 0x7ffff; + merge.gateway_payload_match_adr[row][bus][type ^ 1] = 0x7ffff; + } + + int groups = format ? format->groups() : 1; + if (groups > 1 || payload_map.size() > 1) { + BUG_CHECK(type == 0); // only supported on exact result busses + enable_gateway_payload_exact_shift_ovr(regs, row * 2 + bus); + } + + int tcam_shift = 0; + if (type != 0 && format) { + auto match_table = get_match_table(); + if (match_table) { + auto ternary_table = match_table->to(); + if (ternary_table && ternary_table->has_indirect()) { + tcam_shift = format->log2size - 2; + } + } + } + + if (format) { + if (auto *attached = get_attached()) { + for (auto &st : attached->stats) { + if (type == 0) { + for (unsigned i = 0; i < payload_map.size(); ++i) { + auto grp = payload_map.at(i); + if (grp < 0) continue; + merge.mau_stats_adr_exact_shiftcount[row * 2 + bus][i] = + st->determine_shiftcount(st, grp, 0, 0); + } + } else { + merge.mau_stats_adr_tcam_shiftcount[row * 2 + bus] = + st->determine_shiftcount(st, 0, 0, tcam_shift); + } + break; + } + + for (auto &m : attached->meters) { + if (type == 0) { + for (unsigned i = 0; i < payload_map.size(); ++i) { + auto grp = payload_map.at(i); + if (grp < 0) continue; + m->to()->setup_exact_shift(regs, row * 2 + bus, grp, 0, i, m, + attached->meter_color); + } + } else { + m->to()->setup_tcam_shift(regs, row * 2 + bus, tcam_shift, m, + attached->meter_color); + } + break; + } + for (auto &s : attached->statefuls) { + if (type == 0) { + for (unsigned i = 0; i < payload_map.size(); ++i) { + auto grp = payload_map.at(i); + if (grp < 0) continue; + merge.mau_meter_adr_exact_shiftcount[row * 2 + bus][i] = + s->determine_shiftcount(s, grp, 0, 0); + } + } else { + merge.mau_meter_adr_tcam_shiftcount[row * 2 + bus] = + s->determine_shiftcount(s, 0, 0, tcam_shift); + } + break; + } + } + } + + if (match_table && match_table->instruction) { + if (auto field = match_table->instruction.args[0].field()) { + if (type == 0) { + for (unsigned i = 0; i < payload_map.size(); ++i) { + auto grp = payload_map.at(i); + if (grp < 0) continue; + merge.mau_action_instruction_adr_exact_shiftcount[row * 2 + bus][i] = + field->by_group[grp]->bit(0); + } + } else { + merge.mau_action_instruction_adr_tcam_shiftcount[row * 2 + bus] = + field->bit(0) + tcam_shift; + } + } + } else if (auto *action = format ? format->field("action") : nullptr) { + if (type == 0) { + for (unsigned i = 0; i < payload_map.size(); ++i) { + auto grp = payload_map.at(i); + if (grp < 0) continue; + merge.mau_action_instruction_adr_exact_shiftcount[row * 2 + bus][i] = + action->by_group[grp]->bit(0); + } + } else { + merge.mau_action_instruction_adr_tcam_shiftcount[row * 2 + bus] = + action->bit(0) + tcam_shift; + } + } + + if (format && format->immed) { + if (type == 0) { + for (unsigned i = 0; i < payload_map.size(); ++i) { + auto grp = payload_map.at(i); + if (grp < 0) continue; + merge.mau_immediate_data_exact_shiftcount[row * 2 + bus][i] = + format->immed->by_group[grp]->bit(0); + } + } else { + merge.mau_immediate_data_tcam_shiftcount[row * 2 + bus] = + format->immed->bit(0) + tcam_shift; + } + // FIXME -- may be redundant witehr writing this for the match table, + // but should always be consistent + merge.mau_immediate_data_mask[type][row * 2 + bus] = bitMask(format->immed_size); + merge.mau_payload_shifter_enable[type][row * 2 + bus].immediate_data_payload_shifter_en = 1; + } + + if (type) { + merge.tind_bus_prop[row * 2 + bus].tcam_piped = 1; + merge.tind_bus_prop[row * 2 + bus].thread = gress; + merge.tind_bus_prop[row * 2 + bus].enabled = 1; + } else { + merge.exact_match_phys_result_en[row / 4U] |= 1U << (row % 4U * 2 + bus); + merge.exact_match_phys_result_thread[row / 4U] |= gress << (row % 4U * 2 + bus); + if (stage->tcam_delay(gress)) + merge.exact_match_phys_result_delay[row / 4U] |= 1U << (row % 4U * 2 + bus); + } +} + +template +void GatewayTable::standalone_write_regs(REGS ®s) {} + +template +void GatewayTable::write_regs_vt(REGS ®s) { + LOG1("### Gateway table " << name() << " write_regs " << loc()); + auto &row = layout[0]; + for (auto &ixb : input_xbar) { + // FIXME -- if there's no ixbar in the gateway, we should look for a group with + // all the match/xor values across all the exact match groups in the stage and use + // that. + ixb->write_regs(regs); + if (!setup_vh_xbar(regs, this, row, 0, match, ixb->match_group()) || + !setup_vh_xbar(regs, this, row, 4, xor_match, ixb->match_group())) + return; + } + auto &row_reg = regs.rams.array.row[row.row]; + auto &gw_reg = row_reg.gateway_table[gw_unit]; + auto &merge = regs.rams.match.merge; + int search_bus = row.bus.at(Layout::SEARCH_BUS); + if (search_bus == 0) { + gw_reg.gateway_table_ctl.gateway_table_input_data0_select = 1; + gw_reg.gateway_table_ctl.gateway_table_input_hash0_select = 1; + } else { + BUG_CHECK(search_bus == 1); + gw_reg.gateway_table_ctl.gateway_table_input_data1_select = 1; + gw_reg.gateway_table_ctl.gateway_table_input_hash1_select = 1; + } + for (auto &ixb : input_xbar) { + if (ixb->hash_group() >= 0) + setup_muxctl(row_reg.vh_adr_xbar.exactmatch_row_hashadr_xbar_ctl[search_bus], + ixb->hash_group()); + if (ixb->match_group() >= 0 && gateway_needs_ixbar_group()) { + auto &vh_xbar_ctl = row_reg.vh_xbar[search_bus].exactmatch_row_vh_xbar_ctl; + setup_muxctl(vh_xbar_ctl, ixb->match_group()); + /* vh_xbar_ctl.exactmatch_row_vh_xbar_thread = gress; */ } + } + gw_reg.gateway_table_ctl.gateway_table_logical_table = logical_id; + gw_reg.gateway_table_ctl.gateway_table_thread = timing_thread(gress); + for (auto &r : xor_match) + gw_reg.gateway_table_matchdata_xor_en |= bitMask(r.val->size()) << r.offset; + int idx = 3; + gw_reg.gateway_table_ctl.gateway_table_mode = range_match; + for (auto &line : table) { + BUG_CHECK(idx >= 0); + /* FIXME -- hardcoding version/valid to always */ + gw_reg.gateway_table_vv_entry[idx].gateway_table_entry_versionvalid0 = 0x3; + gw_reg.gateway_table_vv_entry[idx].gateway_table_entry_versionvalid1 = 0x3; + gw_reg.gateway_table_entry_matchdata[idx][0] = line.val.word0.getrange(0, 32); + gw_reg.gateway_table_entry_matchdata[idx][1] = line.val.word1.getrange(0, 32); + if (range_match) { + auto &info = range_match_info[range_match]; + for (unsigned i = 0; i < range_match_info[range_match].units; i++) { + gw_reg.gateway_table_data_entry[idx][0] |= (line.range[i] & info.half_mask) + << (i * info.bits); + gw_reg.gateway_table_data_entry[idx][1] |= + ((line.range[i] >> info.half_shift) & info.half_mask) << (i * info.bits); + } + } else { + gw_reg.gateway_table_data_entry[idx][0] = line.val.word0.getrange(32, 24); + gw_reg.gateway_table_data_entry[idx][1] = line.val.word1.getrange(32, 24); + } + if (!line.run_table) { + merge.gateway_inhibit_lut[logical_id] |= 1 << idx; + } + idx--; + } + if (!miss.run_table) { + merge.gateway_inhibit_lut[logical_id] |= 1 << 4; + } + write_next_table_regs(regs); + merge.gateway_en |= 1 << logical_id; + setup_muxctl(merge.gateway_to_logicaltable_xbar_ctl[logical_id], row.row * 2 + gw_unit); + if (layout.size() > 1) { + int result_bus = layout[1].bus.at(Layout::RESULT_BUS); + payload_write_regs(regs, layout[1].row, result_bus >> 1, result_bus & 1); + } + if (Table *tbl = match_table) { + bool tind_bus = false; + auto bus_type = Layout::RESULT_BUS; + auto *tmatch = dynamic_cast(tbl); + if (tmatch) { + tind_bus = true; + bus_type = Layout::TIND_BUS; + tbl = tmatch->indirect; + } else if (auto *hashaction = dynamic_cast(tbl)) { + tind_bus = hashaction->layout[0].bus.at(bus_type) >= 2; + } + if (tbl) { + for (auto &row : tbl->layout) { + if (row.bus.count(bus_type)) { + int bus = row.bus.at(bus_type); + auto &xbar_ctl = merge.gateway_to_pbus_xbar_ctl[row.row * 2 + (bus & 1)]; + if (tind_bus) { + xbar_ctl.tind_logical_select = logical_id; + xbar_ctl.tind_inhibit_enable = 1; + } else { + xbar_ctl.exact_logical_select = logical_id; + xbar_ctl.exact_inhibit_enable = 1; + } + } + } + } else { + BUG_CHECK(tmatch); + auto &xbar_ctl = merge.gateway_to_pbus_xbar_ctl[tmatch->indirect_bus]; + xbar_ctl.tind_logical_select = logical_id; + xbar_ctl.tind_inhibit_enable = 1; + } + } else { + if (gress != GHOST) merge.predication_ctl[gress].table_thread |= 1 << logical_id; + if (gress == INGRESS || gress == GHOST) { + merge.logical_table_thread[0].logical_table_thread_ingress |= 1 << logical_id; + merge.logical_table_thread[1].logical_table_thread_ingress |= 1 << logical_id; + merge.logical_table_thread[2].logical_table_thread_ingress |= 1 << logical_id; + } else if (gress == EGRESS) { + regs.dp.imem_table_addr_egress |= 1 << logical_id; + merge.logical_table_thread[0].logical_table_thread_egress |= 1 << logical_id; + merge.logical_table_thread[1].logical_table_thread_egress |= 1 << logical_id; + merge.logical_table_thread[2].logical_table_thread_egress |= 1 << logical_id; + } + auto &adrdist = regs.rams.match.adrdist; + adrdist.adr_dist_table_thread[timing_thread(gress)][0] |= 1 << logical_id; + adrdist.adr_dist_table_thread[timing_thread(gress)][1] |= 1 << logical_id; + // FIXME -- allow table_counter on standalone gateay? What can it count? + if (options.match_compiler) + merge.mau_table_counter_ctl[logical_id / 8U].set_subfield(4, 3 * (logical_id % 8U), 3); + standalone_write_regs(regs); + } + if (stage->tcam_delay(gress) > 0) merge.exact_match_logical_result_delay |= 1 << logical_id; +} + +std::set gateways_in_json; +void GatewayTable::gen_tbl_cfg(json::vector &out) const { + // Avoid adding gateway table multiple times to the json. The gateway table + // gets called multiple times in some cases based on how it is attached or + // associated with a match table, we should only output it to json once. + auto gwName = gateway_name.empty() ? name() : gateway_name; + if (gateways_in_json.count(gwName)) return; + LOG3("### Gateway table " << gwName << " gen_tbl_cfg " << loc()); + json::map gTable; + gTable["direction"] = P4Table::direction_name(gress); + gTable["attached_to"] = match_table ? match_table->p4_name() : "-"; + gTable["handle"] = gateway_handle++; + gTable["name"] = gwName; + gTable["table_type"] = "condition"; + + json::vector gStageTables; + json::map gStageTable; + + json::map &next_table_ids = gStageTable["next_tables"]; + json::map &next_table_names = gStageTable["next_table_names"]; + + auto &condTNext = cond_true.next; + auto &condFNext = cond_false.next; + if (Target::LONG_BRANCH_TAGS() > 0) { + json::vector &next_table_names_true = next_table_names["true"]; + json::vector &next_table_names_false = next_table_names["false"]; + json::vector &next_table_ids_true = next_table_ids["true"]; + json::vector &next_table_ids_false = next_table_ids["false"]; + if (condTNext.size() == 0) { + next_table_names_true.push_back(condTNext.next_table_name()); + next_table_ids_true.push_back(condTNext.next_table_id()); + } else { + for (auto t : condTNext) { + next_table_names_true.push_back(t.name); + next_table_ids_true.push_back(t->table_id()); + } + } + if (condFNext.size() == 0) { + next_table_names_false.push_back(condFNext.next_table_name()); + next_table_ids_false.push_back(condFNext.next_table_id()); + } else { + for (auto t : condFNext) { + next_table_names_false.push_back(t.name); + next_table_ids_false.push_back(t->table_id()); + } + } + } else { + next_table_ids["false"] = json::string(condFNext.next_table_id()); + next_table_ids["true"] = json::string(condTNext.next_table_id()); + next_table_names["false"] = json::string(condFNext.next_table_name()); + next_table_names["true"] = json::string(condTNext.next_table_name()); + } + + json::map mra; + mra["memory_unit"] = gw_memory_unit(); + mra["memory_type"] = "gateway"; + mra["payload_buses"] = json::vector(); + gStageTable["memory_resource_allocation"] = std::move(mra); + json::vector pack_format; // For future use + gStageTable["pack_format"] = std::move(pack_format); + + gStageTable["logical_table_id"] = logical_id; + gStageTable["stage_number"] = stage->stageno; + gStageTable["stage_table_type"] = "gateway"; + gStageTable["size"] = 0; + gStageTables.push_back(std::move(gStageTable)); + + json::vector condition_fields; + for (auto m : match) { + json::map condition_field; + condition_field["name"] = m.val.name(); + condition_field["start_bit"] = m.offset; + condition_field["bit_width"] = m.val.size(); + condition_fields.push_back(std::move(condition_field)); + } + + gTable["stage_tables"] = std::move(gStageTables); + gTable["condition_fields"] = std::move(condition_fields); + gTable["condition"] = gateway_cond; + gTable["size"] = 0; + out.push_back(std::move(gTable)); + gateways_in_json.insert(gwName); +} + +DEFINE_TABLE_TYPE_WITH_SPECIALIZATION(GatewayTable, TARGET_CLASS) diff --git a/backends/tofino/bf-asm/gtest/asm-types.cpp b/backends/tofino/bf-asm/gtest/asm-types.cpp new file mode 100644 index 00000000000..d723334de09 --- /dev/null +++ b/backends/tofino/bf-asm/gtest/asm-types.cpp @@ -0,0 +1,270 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "asm-types.h" + +#include "gtest/gtest.h" + +namespace { + +auto CaptureStderr = ::testing::internal::CaptureStderr; +auto Stderr = ::testing::internal::GetCapturedStderr; +auto terminate = ::testing::KilledBySignal(SIGABRT); + +TEST(asm_types, get_int64_0) { + uint32_t i = 0; + value_t v{tINT, 0, 0}; + v.i = i; + CaptureStderr(); + EXPECT_EQ(get_int64(v), i); + EXPECT_EQ(get_int64(v, 0), i); + EXPECT_EQ(get_int64(v, 0, "no error check"), i); + EXPECT_EQ(get_int64(v, 1), i); + EXPECT_EQ(get_int64(v, 1, "no error"), i); + EXPECT_EQ(get_int64(v, 64), i); + EXPECT_EQ(get_int64(v, 64, "no error"), i); + EXPECT_TRUE(Stderr().find("error") == std::string::npos); + // Slow tests... + EXPECT_EXIT(get_int64(v, 128), terminate, "Assembler BUG"); + EXPECT_EXIT(get_int64(v, 128, "terminates"), terminate, "Assembler BUG"); +} + +TEST(asm_types, get_int64_32bit) { + uint32_t i = 0xAAAAAAAA; + value_t v{tINT, 0, 0}; + v.i = i; + CaptureStderr(); + EXPECT_EQ(get_int64(v), i); + EXPECT_EQ(get_int64(v, 0), i); + EXPECT_EQ(get_int64(v, 0, "no error check"), i); + EXPECT_EQ(get_int64(v, 32), i); + EXPECT_EQ(get_int64(v, 32, "no error"), i); + EXPECT_EQ(get_int64(v, 16), 0xAAAA); + EXPECT_TRUE(Stderr().find("error") == std::string::npos); + CaptureStderr(); + get_int64(v, 16, "my error"); + EXPECT_TRUE(Stderr().find("error: my error") != std::string::npos); +} + +TEST(asm_types, get_int64_64bit) { + uint64_t i = 0xAAAAAAAAAAAAAAAA; + value_t v{tINT, 0, 0}; + v.i = i; + CaptureStderr(); + EXPECT_EQ(get_int64(v), i); + EXPECT_EQ(get_int64(v, 0), i); + EXPECT_EQ(get_int64(v, 0, "no error check"), i); + EXPECT_EQ(get_int64(v, 64), i); + EXPECT_EQ(get_int64(v, 64, "no error"), i); + EXPECT_EQ(get_int64(v, 48), 0xAAAAAAAAAAAA); + EXPECT_TRUE(Stderr().find("error") == std::string::npos); + CaptureStderr(); + get_int64(v, 48, "my error"); + EXPECT_TRUE(Stderr().find("error: my error") != std::string::npos); +} + +TEST(asm_types, get_bigi_empty) { + value_t v{tBIGINT, 0, 0}; + v.bigi = EMPTY_VECTOR_INIT; + EXPECT_EQ(get_int64(v), 0); + EXPECT_EQ(get_bitvec(v), bitvec()); +} + +TEST(asm_types, get_int64_bigi_0) { + uint32_t i = 0; + value_t v{tBIGINT, 0, 0}; + VECTOR_init1(v.bigi, i); + CaptureStderr(); + EXPECT_EQ(get_int64(v), i); + EXPECT_EQ(get_int64(v, 0), i); + EXPECT_EQ(get_int64(v, 0, "no error check"), i); + EXPECT_EQ(get_int64(v, 1), i); + EXPECT_EQ(get_int64(v, 1, "no error"), i); + EXPECT_EQ(get_int64(v, 64), i); + EXPECT_EQ(get_int64(v, 64, "no error"), i); + EXPECT_TRUE(Stderr().find("error") == std::string::npos); + // Slow tests... + EXPECT_EXIT(get_int64(v, 128), terminate, "Assembler BUG"); + EXPECT_EXIT(get_int64(v, 128, "terminates"), terminate, "Assembler BUG"); +} + +TEST(asm_types, get_int64_bigi_32bit) { + uint32_t i = 0xAAAAAAAA; + value_t v{tBIGINT, 0, 0}; + VECTOR_init1(v.bigi, i); + CaptureStderr(); + EXPECT_EQ(get_int64(v), i); + EXPECT_EQ(get_int64(v, 0), i); + EXPECT_EQ(get_int64(v, 0, "no error check"), i); + EXPECT_EQ(get_int64(v, 32), i); + EXPECT_EQ(get_int64(v, 32, "no error"), i); + EXPECT_EQ(get_int64(v, 16), 0xAAAA); + EXPECT_TRUE(Stderr().find("error") == std::string::npos); + CaptureStderr(); + get_int64(v, 16, "my error"); + EXPECT_TRUE(Stderr().find("error: my error") != std::string::npos); +} + +TEST(asm_types, get_int64_bigi_64bit) { + uint64_t i = 0xAAAAAAAAAAAAAAAA; + value_t v{tBIGINT, 0, 0}; + if (sizeof(uintptr_t) == sizeof(uint32_t)) + VECTOR_init2(v.bigi, 0xAAAAAAAA, 0xAAAAAAAA); + else + VECTOR_init1(v.bigi, i); + CaptureStderr(); + EXPECT_EQ(get_int64(v), i); + EXPECT_EQ(get_int64(v, 0), i); + EXPECT_EQ(get_int64(v, 0, "no error check"), i); + EXPECT_EQ(get_int64(v, 64), i); + EXPECT_EQ(get_int64(v, 64, "no error"), i); + EXPECT_EQ(get_int64(v, 48), 0xAAAAAAAAAAAA); + EXPECT_TRUE(Stderr().find("error") == std::string::npos); + CaptureStderr(); + get_int64(v, 48, "my error"); + EXPECT_TRUE(Stderr().find("error: my error") != std::string::npos); +} + +TEST(asm_types, get_bitvec_0) { + value_t v{tINT, 0, 0}; + v.i = 0; + auto i = bitvec(0); + CaptureStderr(); + EXPECT_EQ(get_bitvec(v), i); + EXPECT_EQ(get_bitvec(v, 0), i); + EXPECT_EQ(get_bitvec(v, 0, "no error check"), i); + EXPECT_EQ(get_bitvec(v, 1), i); + EXPECT_EQ(get_bitvec(v, 1, "no error"), i); + EXPECT_EQ(get_bitvec(v, 64), i); + EXPECT_EQ(get_bitvec(v, 64, "no error"), i); + EXPECT_EQ(get_bitvec(v, 128), i); + EXPECT_EQ(get_bitvec(v, 128, "no error"), i); + EXPECT_TRUE(Stderr().find("error") == std::string::npos); +} + +TEST(asm_types, get_bitvec_32bit) { + value_t v{tINT, 0, 0}; + v.i = 0xAAAAAAAA; + auto i = bitvec(0xAAAAAAAA); + CaptureStderr(); + EXPECT_EQ(get_bitvec(v), i); + EXPECT_EQ(get_bitvec(v, 0), i); + EXPECT_EQ(get_bitvec(v, 0, "no error check"), i); + EXPECT_EQ(get_bitvec(v, 32), i); + EXPECT_EQ(get_bitvec(v, 32, "no error"), i); + EXPECT_EQ(get_bitvec(v, 16), bitvec(0xAAAA)); + EXPECT_TRUE(Stderr().find("error") == std::string::npos); + CaptureStderr(); + get_bitvec(v, 16, "my error"); + EXPECT_TRUE(Stderr().find("error: my error") != std::string::npos); +} + +TEST(asm_types, get_bitvec_64bit) { + value_t v{tINT, 0, 0}; + v.i = 0xAAAAAAAAAAAAAAAA; + auto i = bitvec(0xAAAAAAAAAAAAAAAA); + CaptureStderr(); + EXPECT_EQ(get_bitvec(v), i); + EXPECT_EQ(get_bitvec(v, 0), i); + EXPECT_EQ(get_bitvec(v, 0, "no error check"), i); + EXPECT_EQ(get_bitvec(v, 64), i); + EXPECT_EQ(get_bitvec(v, 64, "no error"), i); + EXPECT_EQ(get_bitvec(v, 48), bitvec(0xAAAAAAAAAAAA)); + EXPECT_TRUE(Stderr().find("error") == std::string::npos); + CaptureStderr(); + get_bitvec(v, 48, "my error"); + EXPECT_TRUE(Stderr().find("error: my error") != std::string::npos); +} + +TEST(asm_types, get_bitvec_bigi_0) { + value_t v{tBIGINT, 0, 0}; + VECTOR_init1(v.bigi, 0); + auto i = bitvec(0); + CaptureStderr(); + EXPECT_EQ(get_bitvec(v), i); + EXPECT_EQ(get_bitvec(v, 0), i); + EXPECT_EQ(get_bitvec(v, 0, "no error check"), i); + EXPECT_EQ(get_bitvec(v, 1), i); + EXPECT_EQ(get_bitvec(v, 1, "no error"), i); + EXPECT_EQ(get_bitvec(v, 64), i); + EXPECT_EQ(get_bitvec(v, 64, "no error"), i); + EXPECT_EQ(get_bitvec(v, 128), i); + EXPECT_EQ(get_bitvec(v, 128, "no error"), i); + EXPECT_TRUE(Stderr().find("error") == std::string::npos); +} + +TEST(asm_types, get_bitvec_bigi_32bit) { + value_t v{tBIGINT, 0, 0}; + VECTOR_init1(v.bigi, 0xAAAAAAAA); + auto i = bitvec(0xAAAAAAAA); + CaptureStderr(); + EXPECT_EQ(get_bitvec(v), i); + EXPECT_EQ(get_bitvec(v, 0), i); + EXPECT_EQ(get_bitvec(v, 0, "no error check"), i); + EXPECT_EQ(get_bitvec(v, 32), i); + EXPECT_EQ(get_bitvec(v, 32, "no error"), i); + EXPECT_EQ(get_bitvec(v, 16), bitvec(0xAAAA)); + EXPECT_TRUE(Stderr().find("error") == std::string::npos); + CaptureStderr(); + get_bitvec(v, 16, "my error"); + EXPECT_TRUE(Stderr().find("error: my error") != std::string::npos); +} + +TEST(asm_types, get_bitvec_bigi_64bit) { + value_t v{tBIGINT, 0, 0}; + if (sizeof(uintptr_t) == sizeof(uint32_t)) + VECTOR_init2(v.bigi, 0xAAAAAAAA, 0xAAAAAAAA); + else + VECTOR_init1(v.bigi, 0xAAAAAAAAAAAAAAAA); + auto i = bitvec(0xAAAAAAAAAAAAAAAA); + CaptureStderr(); + EXPECT_EQ(get_bitvec(v), i); + EXPECT_EQ(get_bitvec(v, 0), i); + EXPECT_EQ(get_bitvec(v, 0, "no error check"), i); + EXPECT_EQ(get_bitvec(v, 64), i); + EXPECT_EQ(get_bitvec(v, 64, "no error"), i); + EXPECT_EQ(get_bitvec(v, 48), bitvec(0xAAAAAAAAAAAA)); + EXPECT_TRUE(Stderr().find("error") == std::string::npos); + CaptureStderr(); + get_bitvec(v, 48, "my error"); + EXPECT_TRUE(Stderr().find("error: my error") != std::string::npos); +} + +TEST(asm_types, get_bitvec_bigi_128bit) { + value_t v{tBIGINT, 0, 0}; + if (sizeof(uintptr_t) == sizeof(uint32_t)) + VECTOR_init4(v.bigi, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA); + else + VECTOR_init2(v.bigi, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA); + bitvec i; + for (int j = 0; j < 4; ++j) i.putrange(j * 32, 32, 0xAAAAAAAA); + CaptureStderr(); + EXPECT_EQ(get_bitvec(v), i); + EXPECT_EQ(get_bitvec(v, 0), i); + EXPECT_EQ(get_bitvec(v, 0, "no error check"), i); + EXPECT_EQ(get_bitvec(v, 128), i); + EXPECT_EQ(get_bitvec(v, 128, "no error"), i); + EXPECT_EQ(get_bitvec(v, 192), i); + EXPECT_EQ(get_bitvec(v, 192, "no error"), i); + EXPECT_EQ(get_bitvec(v, 48), bitvec(0xAAAAAAAAAAAA)); + EXPECT_TRUE(Stderr().find("error") == std::string::npos); + CaptureStderr(); + get_bitvec(v, 48, "my error"); + EXPECT_TRUE(Stderr().find("error: my error") != std::string::npos); +} + +} // namespace diff --git a/backends/tofino/bf-asm/gtest/depositfield.cpp b/backends/tofino/bf-asm/gtest/depositfield.cpp new file mode 100644 index 00000000000..e60e1f0a8ab --- /dev/null +++ b/backends/tofino/bf-asm/gtest/depositfield.cpp @@ -0,0 +1,153 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "depositfield.h" + +#include "gtest/gtest.h" + +#if __cplusplus < 201402L && __cpp_binary_literals < 201304 +#error "Binary literals are required" +// We could fall back on boost/utility/binary.hpp +#endif + +namespace { + +constexpr int conSize8 = 8; +constexpr int conSize32 = 32; +constexpr int tooLarge = 8; +constexpr int tooSmall = -9; +constexpr int tooSmall2 = -5; + +TEST(depositfield, 0) { + int32_t zero = 0; + auto res = DepositField::discoverRotation(zero, conSize8, tooLarge, tooSmall); + EXPECT_EQ(res.rotate, 0U); + EXPECT_EQ(res.value, zero); + res = DepositField::discoverRotation(zero, conSize32, tooLarge, tooSmall); + EXPECT_EQ(res.rotate, 0U); + EXPECT_EQ(res.value, zero); + res = DepositField::discoverRotation(zero, conSize8, tooLarge, tooSmall2); + EXPECT_EQ(res.rotate, 0U); + EXPECT_EQ(res.value, zero); +} + +TEST(depositfield, large) { + int32_t value = tooLarge - 1; + auto res = DepositField::discoverRotation(value, conSize8, tooLarge, tooSmall); + EXPECT_EQ(res.rotate, 0U); + EXPECT_EQ(res.value, value); + res = DepositField::discoverRotation(value, conSize32, tooLarge, tooSmall); + EXPECT_EQ(res.rotate, 0U); + EXPECT_EQ(res.value, value); + res = DepositField::discoverRotation(value, conSize8, tooLarge, tooSmall2); + EXPECT_EQ(res.rotate, 0U); + EXPECT_EQ(res.value, value); +} + +TEST(depositfield, small) { + int32_t value = tooSmall + 1; + int32_t value2 = tooSmall2 + 1; + auto res = DepositField::discoverRotation(value, conSize8, tooLarge, tooSmall); + EXPECT_EQ(res.rotate, 0U); + EXPECT_EQ(res.value, value); + res = DepositField::discoverRotation(value, conSize32, tooLarge, tooSmall); + EXPECT_EQ(res.rotate, 0U); + EXPECT_EQ(res.value, value); + ASSERT_TRUE(value < tooSmall2); + res = DepositField::discoverRotation(value, conSize8, tooLarge, tooSmall2); + EXPECT_EQ(res.rotate, 0U); // Not possible '0b11111000' + EXPECT_EQ(res.value, value); + res = DepositField::discoverRotation(value2, conSize8, tooLarge, tooSmall2); + EXPECT_EQ(res.rotate, 0U); + EXPECT_EQ(res.value, value2); +} + +TEST(depositfield, numTooLarge) { // 0b00001000 + // N.B. other solutions are valid, these are the ones we expect. + auto res = DepositField::discoverRotation(8, conSize8, tooLarge, tooSmall); + EXPECT_EQ(res.rotate, 5U); + EXPECT_EQ(res.value, 1); + res = DepositField::discoverRotation(8, conSize32, tooLarge, tooSmall); + EXPECT_EQ(res.rotate, 29U); + EXPECT_EQ(res.value, 1); + res = DepositField::discoverRotation(8, conSize8, tooLarge, tooSmall2); + EXPECT_EQ(res.rotate, 5U); + EXPECT_EQ(res.value, 1); +} + +TEST(depositfield, numTooSmall) { // 0b11110111 + auto res = DepositField::discoverRotation(-9, conSize8, tooLarge, tooSmall); + EXPECT_EQ(res.rotate, 5U); + EXPECT_EQ(res.value, -2); + res = DepositField::discoverRotation(-9, conSize32, tooLarge, tooSmall); + EXPECT_EQ(res.rotate, 29U); + EXPECT_EQ(res.value, -2); + res = DepositField::discoverRotation(-9, conSize8, tooLarge, tooSmall2); + EXPECT_EQ(res.rotate, 5U); + EXPECT_EQ(res.value, -2); +} + +TEST(depositfield, 0b00110000) { + auto res = DepositField::discoverRotation(0b00110000, conSize8, tooLarge, tooSmall); + EXPECT_EQ(res.rotate, 4U); + EXPECT_EQ(res.value, 0b00000011); + res = DepositField::discoverRotation(0b00110000, conSize32, tooLarge, tooSmall); + EXPECT_EQ(res.rotate, 28U); + EXPECT_EQ(res.value, 0b00000011); + res = DepositField::discoverRotation(0b00110000, conSize8, tooLarge, tooSmall2); + EXPECT_EQ(res.rotate, 4U); + EXPECT_EQ(res.value, 0b00000011); +} + +TEST(depositfield, 0b00100001) { + // Failures are sent back with zero rotation and the value unchanged. + auto res = DepositField::discoverRotation(0b00100001, conSize8, tooLarge, tooSmall); + EXPECT_EQ(res.rotate, 0U); + EXPECT_EQ(res.value, 0b00100001); + res = DepositField::discoverRotation(0b00100001, conSize32, tooLarge, tooSmall); + EXPECT_EQ(res.rotate, 0U); + EXPECT_EQ(res.value, 0b00100001); + res = DepositField::discoverRotation(0b00100001, conSize8, tooLarge, tooSmall2); + EXPECT_EQ(res.rotate, 0U); + EXPECT_EQ(res.value, 0b00100001); +} + +TEST(depositfield, 0b01111111) { // 127 + auto res = DepositField::discoverRotation(0b01111111, conSize8, tooLarge, tooSmall); + EXPECT_EQ(res.rotate, 1U); + EXPECT_EQ(res.value, -2); + res = DepositField::discoverRotation(0b01111111, conSize32, tooLarge, tooSmall); + EXPECT_EQ(res.rotate, 0U); + EXPECT_EQ(res.value, 0b01111111); // Can't do. + res = DepositField::discoverRotation(0b01111111, conSize8, tooLarge, tooSmall2); + EXPECT_EQ(res.rotate, 1U); + EXPECT_EQ(res.value, -2); +} + +TEST(depositfield, 0b10011111) { // -97 + auto res = DepositField::discoverRotation(-97, conSize8, tooLarge, tooSmall); + EXPECT_EQ(res.rotate, 3U); + EXPECT_EQ(res.value, -4); + res = DepositField::discoverRotation(-97, conSize32, tooLarge, tooSmall); + EXPECT_EQ(res.rotate, 27U); + EXPECT_EQ(res.value, -4); + res = DepositField::discoverRotation(-97, conSize8, tooLarge, tooSmall2); + EXPECT_EQ(res.rotate, 3U); + EXPECT_EQ(res.value, -4); +} + +} // namespace diff --git a/backends/tofino/bf-asm/gtest/gateway.cpp b/backends/tofino/bf-asm/gtest/gateway.cpp new file mode 100644 index 00000000000..e6a8e7ed060 --- /dev/null +++ b/backends/tofino/bf-asm/gtest/gateway.cpp @@ -0,0 +1,122 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bfas.h" +#include "gtest/gtest.h" +#include "stage.h" + +namespace { + +// Verify that the next table registers are correctly configured for a standalone gateway with a +// miss next table and no hit next table +TEST(gateway, standalone_miss_next_table) { + const char *gateway_str = R"GATEWAY_CFG( +version: + target: Tofino2 +phv ingress: + ig_intr_md_for_dprsr.mirror_type.$valid: B1(0) + ig_intr_md.ingress_port: { stage 0: W0(16..24) } + hdr.data.h1: MH4 + hdr.data.b1: MB1 + ig_intr_md_for_tm.ucast_egress_port: { stage 1..20: W0(0..8) } + ig_intr_md_for_tm.ucast_egress_port.$valid: { stage 1..20: B1(1) } + ig_intr_md_for_dprsr.mirror_type: { stage 20: MB0(0..3) } + hdr.data.$valid: B1(2) +stage 0 ingress: + gateway cond-1 0: + name: cond-1 + input_xbar: + exact group 0: { 16: hdr.data.b1 } + row: 7 + bus: 0 + unit: 0 + match: { 0: hdr.data.b1 } + 0x12: + next: END + miss: + next: test_0 + condition: + expression: "(hdr.data.b1 != 18)" + true: test_0 + false: END +stage 2 ingress: + dependency: match + mpr_stage_id: 1 + mpr_bus_dep_glob_exec: 0x0 + mpr_bus_dep_long_brch: 0x0 + mpr_always_run: 0x0 + mpr_next_table_lut: + 0: 0xff + ternary_match test_0 0: + always_run: true + p4: { name: ingress.test, size: 512 } + p4_param_order: + hdr.data.h1: { type: ternary, size: 16, full_size: 16 } + row: 0 + bus: 0 + column: 0 + input_xbar: + ternary group 0: { 0: hdr.data.h1 } + match: + - { group: 0, byte_config: 3, dirtcam: 0x5 } + hit: [ END ] + miss: END + indirect: test_0$tind + ternary_indirect test_0$tind: + row: 0 + bus: 0 + column: 2 + input_xbar: + ternary group 0: { 0: hdr.data.h1 } + format: { action: 0..1, immediate: 2..9 } + action_bus: { 0 : immediate(0..7) } + instruction: test_0$tind(action, $DEFAULT) + actions: + ingress.setb1(1, 1): + - p4_param_order: { val: 8 } + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000002 + - next_table: 0 + - { val_1: immediate(0..7), val: val_1 } + - set MB1, val + ingress.noop(2, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000003 + - next_table: 0 + - { } + default_action: ingress.setb1 + default_action_parameters: + val: "0xAA" +)GATEWAY_CFG"; + + asm_parse_string(gateway_str); + + Section::process_all(); + + Target::JBay::mau_regs regs; + auto &stages = AsmStage::stages(INGRESS); + stages[0].write_regs(regs, false); + for (auto table : stages[0].tables) { + table->write_regs(regs); + } + + EXPECT_EQ(regs.rams.match.merge.pred_is_a_brch, 0x01); +} + +} // namespace diff --git a/backends/tofino/bf-asm/gtest/gtestasm.cpp b/backends/tofino/bf-asm/gtest/gtestasm.cpp new file mode 100644 index 00000000000..68a6eb753cd --- /dev/null +++ b/backends/tofino/bf-asm/gtest/gtestasm.cpp @@ -0,0 +1,83 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "gtest/gtest.h" +#include "lib/compile_context.h" +#include "lib/log.h" +#include "lib/options.h" + +using namespace P4; + +template +class CompileContext : public virtual BaseCompileContext { + public: + /// @return the current compilation context, which must be of type + /// CompileContext. + static CompileContext &get() { return CompileContextStack::top(); } + + CompileContext() {} + + template + CompileContext(CompileContext &context) + : optionsInstance(context.options()) {} + + /// @return the compiler options for this compilation context. + OptionsType &options() { return optionsInstance; } + + private: + /// The compiler options for this compilation context. + OptionsType optionsInstance; +}; + +class GTestOptions : public Util::Options { + static const char *defaultMessage; + + public: + GTestOptions() : Util::Options(defaultMessage) { + registerOption( + "-T", "loglevel", + [](const char *arg) { + Log::addDebugSpec(arg); + return true; + }, + "[Compiler debugging] Adjust logging level per file (see below)"); + } + std::vector *process(int argc, char *const argv[]) { + auto remainingOptions = Util::Options::process(argc, argv); + return remainingOptions; + } + const char *getIncludePath() const override { return ""; } +}; + +const char *GTestOptions::defaultMessage = "bf-asm gtest"; + +using GTestContext = CompileContext; + +GTEST_API_ int main(int argc, char **argv) { + printf("running gtestasm\n"); + + // process gtest flags + ::testing::InitGoogleTest(&argc, argv); + + // process debug flags + AutoCompileContext autoGTestContext(new GTestContext); + GTestContext::get().options().process(argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/backends/tofino/bf-asm/gtest/hashexpr.cpp b/backends/tofino/bf-asm/gtest/hashexpr.cpp new file mode 100644 index 00000000000..24410349b95 --- /dev/null +++ b/backends/tofino/bf-asm/gtest/hashexpr.cpp @@ -0,0 +1,117 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "hashexpr.h" + +#include "bfas.h" +#include "gtest/gtest.h" +#include "stage.h" + +namespace { + +// TEST(hashexpr, slice_with_rand_alg) +// +// Verify that a slice with a random algorithm doesn't loop forever +// +// Warning: If it does loop forever, then the test will hang :( Running through ctest should +// result in an eventual timeout, but running from the command line will hang until Ctrl-C. +TEST(hashexpr, slice_with_rand_alg) { + const char *hash_str = R"HASH_CFG( +version: + target: Tofino2 +phv ingress: + Field1: MW0 + Field2: MW1 + Field3: MH8(0..8) + Field4: MB9 + Hdr.$valid: B3(4) +stage 0 ingress: + hash_action _HashTable 0: + always_run: true + p4: { name: HashTable, size: 1, disable_atomic_modify : true } + row: 0 + result_bus: 1 + hash_dist: + 1: { hash: 1, mask: 0xffff, shift: 0 } + input_xbar: + exact group 2: { 0: Field1, 32: Field2, 64: Field3, 80: Field4 } + hash 4: + 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 81, { 9: Field2, 41: Field1 }, { })), 0..15) + hash 5: + 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 81, { 0: Field3, 73: Field4 }, { })), 0..15) + hash group 1: + table: [4, 5] + seed: 0x0 + gateway: + name: cond-81 + input_xbar: + exact group 1: { 36: Hdr.$valid } + row: 1 + bus: 0 + unit: 0 + payload_row: 0 + payload_unit: 1 + payload: 0x1 + format: { action(0): 0..0 } + match: { 4: Hdr.$valid } + 0b***1: END + miss: run_table + condition: + expression: "(Hdr.$valid == 1)" + true: END + false: END + next: END + action_bus: { 108..111 : hash_dist(1) } + instruction: _HashTable(action, $DEFAULT) + actions: + MyAction(1, 7): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000063 + - next_table: 0 + - set W15(0..15), hash_dist(1, 0..15) + default_action: MyAction +)HASH_CFG"; + + asm_parse_string(hash_str); + + Stage *stage = Stage::stage(INGRESS, 0); + Table *table = stage->tables[0]; + InputXbar &ixbar = *table->input_xbar[0]; + for (auto &kv1 : ixbar.get_hash_tables()) { + // Grab the hash table map + auto &htmap = kv1.second; + for (auto &kv2 : htmap) { + // Get the hash column/hash expression and change the hash algorithm + auto &hc = kv2.second; + auto *he = hc.fn; + he->hash_algorithm.hash_alg = RANDOM_DYN; + } + } + + std::cerr << std::endl + << "If this test hangs then there is a problem with handling of RANDOM_DYN at the " + "hash slice level. Terminate the hang with Ctrl-C." + << std::endl + << std::endl; + Section::process_all(); + + // Reset the target type for future tests + options.target = NO_TARGET; +} + +} // namespace diff --git a/backends/tofino/bf-asm/gtest/mirror.cpp b/backends/tofino/bf-asm/gtest/mirror.cpp new file mode 100644 index 00000000000..5486b74fd7f --- /dev/null +++ b/backends/tofino/bf-asm/gtest/mirror.cpp @@ -0,0 +1,240 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "deparser.h" +#include "gtest/gtest.h" +#include "sections.h" + +namespace { + +/* Tests for mirror + * + * Currently we cannot run tests for multiple targets (e.g., Tofino and JBay) + * in a single run. As a result, all tests except Tofino are disabled. + */ + +#define TOF_MIRR_CFG regs.header.hir.main_i.mirror_cfg +#define TOF_MIRR_TBL regs.header.hir.main_i.mirror_tbl + +#define JBAY_MIRR_BASE regs.dprsrreg.ho_i +#define JBAY_MIRR_ENTRY him.mirr_hdr_tbl.entry +#define JBAY_MIRR_SEL regs.dprsrreg.inp.ipp.ingr.m_mirr_sel + +#define FTR_MDP_MIRR_BASE regs.mdp_mem.tmm_ext_ram.tmm_ext[0] +#define FTR_DPRSR_MIRR_BASE regs.dprsr.dprsr_phvxb_rspec.ehm_xb + +/// Mirror configuration for Tofino +struct TofinoMirrorCfg { + std::string sel_phv_; + int sel_phv_lo_; + + std::map entry_id_phv; + std::map> entry_phvs; + + TofinoMirrorCfg(std::string sel_phv, int sel_phv_lo) + : sel_phv_(sel_phv), sel_phv_lo_(sel_phv_lo) {} +}; + +/// Mirror configuration for JBay +struct JBayMirrorCfg { + std::string sel_phv_; + int sel_phv_lo_; + + std::string sel_pov_; + int sel_pov_lo_; + + std::map entry_id_phv; + std::map> entry_phvs; + + JBayMirrorCfg(std::string sel_phv, int sel_phv_lo, std::string sel_pov, int sel_pov_lo) + : sel_phv_(sel_phv), sel_phv_lo_(sel_phv_lo), sel_pov_(sel_pov), sel_pov_lo_(sel_pov_lo) {} +}; + +/// Map from register name to Phv::Register* +std::map phvRegs; + +/// Populate register name -> register map +void populateRegIds() { + if (!phvRegs.size()) { + // Initialize the PHVs. + // Triggered by requesting a slice for a field. The field does not need to exist. + Phv::get(INGRESS, 0, "jbay_dummy$"); + + // Walk through the registers and record them + for (int i = 0; i < Phv::num_regs(); ++i) { + if (const auto *reg = Phv::reg(i)) phvRegs[reg->name] = reg; + } + } +} + +/// Get the MAU ID of a given register name +int mau_id(std::string name) { return phvRegs.count(name) ? phvRegs.at(name)->mau_id() : -1; } + +/// Get the deparser ID of a given register name +int deparser_id(std::string name) { + return phvRegs.count(name) ? phvRegs.at(name)->deparser_id() : -1; +} + +/// Find a Digest for a given target +Deparser::Digest *findDigest(Deparser *dprsr, target_t target) { + for (auto &digest : dprsr->digests) { + if (digest.type->target == target) return &digest; + } + + BUG("Could not find the Digest for %s", toString(target).c_str()); + return nullptr; +} + +/** Reset all target information + * + * This function should be called when switching from one target to another + * (e.g., Tofino to JBay) in tests to reset state. + */ +void resetTarget() { + options.target = NO_TARGET; + Phv::test_clear(); + phvRegs.clear(); + Deparser *dprsr = dynamic_cast(Section::test_get("deparser")); + dprsr->gtest_clear(); +} + +/// Verify that registers match a mirror configuration (Tofino) +void tofinoCheckMirrorRegs(Target::Tofino::deparser_regs ®s, TofinoMirrorCfg &cfg) { + populateRegIds(); + + Deparser *dprsr = dynamic_cast(Section::test_get("deparser")); + auto *digest = findDigest(dprsr, TOFINO); + + // Tell the digest code to set the registers + digest->type->setregs(regs, *dprsr, *digest); + + // Verify the registers: + // 1. Verify common registers + EXPECT_EQ(TOF_MIRR_CFG.phv, deparser_id(cfg.sel_phv_)); + EXPECT_EQ(TOF_MIRR_CFG.shft, cfg.sel_phv_lo_); + EXPECT_EQ(TOF_MIRR_CFG.valid, 1); + + // 2. Verify the entries + for (auto &kv : cfg.entry_id_phv) { + int id = kv.first; + EXPECT_EQ(TOF_MIRR_TBL[id].id_phv, deparser_id(cfg.entry_id_phv[id])); + int idx = 0; + for (auto &phv : cfg.entry_phvs[id]) { + EXPECT_EQ(TOF_MIRR_TBL[id].phvs[idx], deparser_id(phv)); + idx++; + } + EXPECT_EQ(TOF_MIRR_TBL[id].len, cfg.entry_phvs[id].size()); + } +} + +/// Verify that registers match a mirror configuration (JBay) +void jbayCheckMirrorRegs(Target::JBay::deparser_regs ®s, JBayMirrorCfg &cfg) { + // Base index for POV PHV. Want this to be non-zero. + const int povBase = 64; + + populateRegIds(); + + Deparser *dprsr = dynamic_cast(Section::test_get("deparser")); + auto *digest = findDigest(dprsr, JBAY); + + // Ensure the POV register in the config is actually recorded as a POV in + // the deparser object + int povReg = mau_id(cfg.sel_pov_); + dprsr->pov[INGRESS][Phv::reg(povReg)] = povBase; + + // Tell the digest code to set the registers + digest->type->setregs(regs, *dprsr, *digest); + + // Verify the registers: + // 1. Verify common registers + EXPECT_EQ(JBAY_MIRR_SEL.phv, deparser_id(cfg.sel_phv_)); + EXPECT_EQ(JBAY_MIRR_SEL.pov, povBase + cfg.sel_pov_lo_); + EXPECT_EQ(JBAY_MIRR_SEL.shft, cfg.sel_phv_lo_); + EXPECT_EQ(JBAY_MIRR_SEL.disable_, 0); + + // 2. Verify the entries + for (auto &base : JBAY_MIRR_BASE) { + for (auto &kv : cfg.entry_id_phv) { + int id = kv.first; + EXPECT_EQ(base.JBAY_MIRR_ENTRY[id].id_phv, deparser_id(cfg.entry_id_phv[id])); + int idx = 0; + for (auto &phv : cfg.entry_phvs[id]) { + EXPECT_EQ(base.JBAY_MIRR_ENTRY[id].phvs[idx], deparser_id(phv)); + idx++; + } + EXPECT_EQ(base.JBAY_MIRR_ENTRY[id].len, cfg.entry_phvs[id].size()); + } + } +} + +TEST(mirror, digest_tofino) { + const char *mirror_str = R"MIRR_CFG( +version: + target: Tofino +deparser ingress: + mirror: + select: B9(0..3) # bit[3..0]: ingress::ig_intr_md_for_dprsr.mirror_type + 1: + - H19(0..7) # bit[7..0]: ingress::Thurmond.Circle.LaUnion[7:0].0-7 + - B9 # ingress::Thurmond.Longwood.Matheson + - B9 # ingress::Thurmond.Longwood.Matheson + - H56(0..8) # bit[8..0]: ingress::Thurmond.Armagh.Moorcroft +)MIRR_CFG"; + + resetTarget(); + + auto *digest = ::get(Deparser::Digest::Type::all[TOFINO][INGRESS], "mirror"); + ASSERT_NE(digest, nullptr) << "Unable to find the mirror digest"; + + Target::Tofino::deparser_regs regs; + asm_parse_string(mirror_str); + + TofinoMirrorCfg mirrorCfg("B9", 0); + mirrorCfg.entry_id_phv[1] = "H19"; + mirrorCfg.entry_phvs[1] = {"B9", "B9", "H56", "H56"}; + tofinoCheckMirrorRegs(regs, mirrorCfg); +} + +TEST(mirror, digest_jbay) { + const char *mirror_str = R"MIRR_CFG( +version: + target: Tofino2 +deparser ingress: + mirror: + select: { B9(0..3): B8(1) } # bit[3..0]: ingress::ig_intr_md_for_dprsr.mirror_type + 1: + - H19(0..7) # bit[7..0]: ingress::Thurmond.Circle.LaUnion[7:0].0-7 + - B9 # ingress::Thurmond.Longwood.Matheson + - B9 # ingress::Thurmond.Longwood.Matheson + - H56(0..8) # bit[8..0]: ingress::Thurmond.Armagh.Moorcroft +)MIRR_CFG"; + + resetTarget(); + + auto *digest = ::get(Deparser::Digest::Type::all[JBAY][INGRESS], "mirror"); + ASSERT_NE(digest, nullptr) << "Unable to find the mirror digest"; + + Target::JBay::deparser_regs regs; + asm_parse_string(mirror_str); + + JBayMirrorCfg mirrorCfg("B9", 0, "B8", 1); + mirrorCfg.entry_id_phv[1] = "H19"; + mirrorCfg.entry_phvs[1] = {"B9", "B9", "H56", "H56"}; + jbayCheckMirrorRegs(regs, mirrorCfg); +} + +} // namespace diff --git a/backends/tofino/bf-asm/gtest/parser-test.cpp b/backends/tofino/bf-asm/gtest/parser-test.cpp new file mode 100644 index 00000000000..c666cbc1a93 --- /dev/null +++ b/backends/tofino/bf-asm/gtest/parser-test.cpp @@ -0,0 +1,1054 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bfas.h" +#include "gtest/gtest.h" +#include "parser-tofino-jbay.h" + +namespace { + +// TEST(parser_test, get_parser_deepest_depth) +// +// +// While calculating the maximum depth, the assembler goes through the parser tree +// and visits every state recursively. The parser depth for a state is taken into account +// and included in the calculation at the time it is visited. +// +// Every state used to be visited at most one time, which was the source of the problem: +// +// In cases where parsing trees contained states that were called from more than one +// parent state, the depth calculation would be wrong unless the depth was at its maximum +// value the first time that state was visited. +// +// Made a change in the parse depth calculation to keep track of the largest parser depth +// "seen" for each state. When a state has already been visited, the recursion continues +// when the current parser depth is larger than the largest parser depth seen up to that +// point for that state. + +// The parser code provided in parser_str below contains that behavior as parse_udp and +// parse_tcp are called from both parse_ipv4 and parse_ipv6, two states with different depths, +// the longest one being parse_ipv6 that is visited after parse_ipv4. Without the fix, +// parser->get_prsr_max_dph() returns 6 instead of 7. +// +TEST(parser_test, get_parser_deepest_depth) { + const char *parser_str = R"PARSER_CFG( +version: + target: Tofino +parser egress: + start: $entry_point + init_zero: [ B19, B18, B16 ] + bitwise_or: [ B16, B18 ] + hdr_len_adj: 27 + meta_opt: 8191 + states: + $entry_point: + *: + load: { byte1 : 27 } + buf_req: 28 + next: start + start: + match: [ byte1 ] + 0x0a: + counter: + imm: 38 + 0..1: H16 # bit[7..15] -> H16 bit[8..0]: egress::eg_intr_md.egress_port + intr_md: 9 + shift: 27 + buf_req: 27 + next: parse_mirror_tagging_state + 0x**: + counter: + imm: 38 + 0..1: H16 # bit[7..15] -> H16 bit[8..0]: egress::eg_intr_md.egress_port + intr_md: 9 + shift: 27 + buf_req: 27 + next: parse_normal_tagging_state + parse_mirror_tagging_state: + *: + counter: dec 1 + B19: 10 # value 10 -> B19 bit[7..0]: egress::eg_md.packet_state + load: { half : 13..14 } + shift: 1 + buf_req: 15 + next: parse_ethernet + parse_ethernet: + match: [ half ] + 0x0800: + counter: dec 14 + 0..1: TH32 # egress::hdr.ethernet.dst_addr[47:32].32-47 + 2..5: TW19 # egress::hdr.ethernet.dst_addr[31:0].0-31 + 6..7: TH31 # egress::hdr.ethernet.src_addr[47:32].32-47 + 8..11: TW18 # egress::hdr.ethernet.src_addr[31:0].0-31 + 12..13: TH30 # egress::hdr.ethernet.ether_type + B18: 1 # value 1 -> B18 bit[0]: egress::hdr.ethernet.$valid + load: { byte1 : 23 } + shift: 14 + buf_req: 24 + next: parse_ipv4 + 0x86dd: + counter: dec 14 + 0..1: TH32 # egress::hdr.ethernet.dst_addr[47:32].32-47 + 2..5: TW19 # egress::hdr.ethernet.dst_addr[31:0].0-31 + 6..7: TH31 # egress::hdr.ethernet.src_addr[47:32].32-47 + 8..11: TW18 # egress::hdr.ethernet.src_addr[31:0].0-31 + 12..13: TH30 # egress::hdr.ethernet.ether_type + B18: 1 # value 1 -> B18 bit[0]: egress::hdr.ethernet.$valid + shift: 14 + buf_req: 14 + next: parse_ipv6 + 0x****: + counter: dec 14 + 0..1: TH32 # egress::hdr.ethernet.dst_addr[47:32].32-47 + 2..5: TW19 # egress::hdr.ethernet.dst_addr[31:0].0-31 + 6..7: TH31 # egress::hdr.ethernet.src_addr[47:32].32-47 + 8..11: TW18 # egress::hdr.ethernet.src_addr[31:0].0-31 + 12..13: TH30 # egress::hdr.ethernet.ether_type + B18: 1 # value 1 -> B18 bit[0]: egress::hdr.ethernet.$valid + shift: 14 + buf_req: 14 + next: min_parse_depth_accept_initial + parse_ipv4: + match: [ byte1 ] + 0x06: + counter: dec 20 + 0..3: TW4 + # - bit[0..3] -> TW4 bit[31..28]: egress::hdr.ipv4.version + # - bit[4..7] -> TW4 bit[27..24]: egress::hdr.ipv4.ihl + # - bit[8..15] -> TW4 bit[23..16]: egress::hdr.ipv4.diffserv + # - bit[16..31] -> TW4 bit[15..0]: egress::hdr.ipv4.total_len + 4..7: TW6 + # - bit[32..47] -> TW6 bit[31..16]: egress::hdr.ipv4.identification + # - bit[48..50] -> TW6 bit[15..13]: egress::hdr.ipv4.flags + # - bit[51..63] -> TW6 bit[12..0]: egress::hdr.ipv4.frag_offset + 8..11: TW5 + # - bit[64..71] -> TW5 bit[31..24]: egress::hdr.ipv4.ttl + # - bit[72..79] -> TW5 bit[23..16]: egress::hdr.ipv4.protocol + # - bit[80..95] -> TW5 bit[15..0]: egress::hdr.ipv4.hdr_checksum + 12..13: TH27 # egress::hdr.ipv4.src_addr[31:16].16-31 + 14..15: TH26 # egress::hdr.ipv4.src_addr[15:0].0-15 + 16..17: TH25 # egress::hdr.ipv4.dst_addr[31:16].16-31 + 18..19: TH24 # egress::hdr.ipv4.dst_addr[15:0].0-15 + B18: 2 # value 1 -> B18 bit[1]: egress::hdr.ipv4.$valid + load: { half : 22..23 } + shift: 20 + buf_req: 24 + next: parse_tcp + 0x11: + counter: dec 20 + 0..3: TW4 + # - bit[0..3] -> TW4 bit[31..28]: egress::hdr.ipv4.version + # - bit[4..7] -> TW4 bit[27..24]: egress::hdr.ipv4.ihl + # - bit[8..15] -> TW4 bit[23..16]: egress::hdr.ipv4.diffserv + # - bit[16..31] -> TW4 bit[15..0]: egress::hdr.ipv4.total_len + 4..7: TW6 + # - bit[32..47] -> TW6 bit[31..16]: egress::hdr.ipv4.identification + # - bit[48..50] -> TW6 bit[15..13]: egress::hdr.ipv4.flags + # - bit[51..63] -> TW6 bit[12..0]: egress::hdr.ipv4.frag_offset + 8..11: TW5 + # - bit[64..71] -> TW5 bit[31..24]: egress::hdr.ipv4.ttl + # - bit[72..79] -> TW5 bit[23..16]: egress::hdr.ipv4.protocol + # - bit[80..95] -> TW5 bit[15..0]: egress::hdr.ipv4.hdr_checksum + 12..13: TH27 # egress::hdr.ipv4.src_addr[31:16].16-31 + 14..15: TH26 # egress::hdr.ipv4.src_addr[15:0].0-15 + 16..17: TH25 # egress::hdr.ipv4.dst_addr[31:16].16-31 + 18..19: TH24 # egress::hdr.ipv4.dst_addr[15:0].0-15 + B18: 2 # value 1 -> B18 bit[1]: egress::hdr.ipv4.$valid + load: { half : 20..21 } + shift: 20 + buf_req: 22 + next: parse_udp + 0x**: + counter: dec 20 + 0..3: TW4 + # - bit[0..3] -> TW4 bit[31..28]: egress::hdr.ipv4.version + # - bit[4..7] -> TW4 bit[27..24]: egress::hdr.ipv4.ihl + # - bit[8..15] -> TW4 bit[23..16]: egress::hdr.ipv4.diffserv + # - bit[16..31] -> TW4 bit[15..0]: egress::hdr.ipv4.total_len + 4..7: TW6 + # - bit[32..47] -> TW6 bit[31..16]: egress::hdr.ipv4.identification + # - bit[48..50] -> TW6 bit[15..13]: egress::hdr.ipv4.flags + # - bit[51..63] -> TW6 bit[12..0]: egress::hdr.ipv4.frag_offset + 8..11: TW5 + # - bit[64..71] -> TW5 bit[31..24]: egress::hdr.ipv4.ttl + # - bit[72..79] -> TW5 bit[23..16]: egress::hdr.ipv4.protocol + # - bit[80..95] -> TW5 bit[15..0]: egress::hdr.ipv4.hdr_checksum + 12..13: TH27 # egress::hdr.ipv4.src_addr[31:16].16-31 + 14..15: TH26 # egress::hdr.ipv4.src_addr[15:0].0-15 + 16..17: TH25 # egress::hdr.ipv4.dst_addr[31:16].16-31 + 18..19: TH24 # egress::hdr.ipv4.dst_addr[15:0].0-15 + B18: 2 # value 1 -> B18 bit[1]: egress::hdr.ipv4.$valid + shift: 20 + buf_req: 20 + next: min_parse_depth_accept_initial + parse_tcp: + match: [ half ] + 0x0050: + counter: dec 20 + 0..1: TH8 # egress::hdr.tcp.src_port + 2..3: TH7 # egress::hdr.tcp.dst_port + 4..7: TW17 # egress::hdr.tcp.seq_no + 8..11: TW16 # egress::hdr.tcp.ack_no + 12: TB5 + # - bit[96..99] -> TB5 bit[7..4]: egress::hdr.tcp.data_offset + # - bit[100..103] -> TB5 bit[3..0]: egress::hdr.tcp.res + 13: TB6 # egress::hdr.tcp.flags + 14..15: TH6 # egress::hdr.tcp.window + 16..19: TW7 + # - bit[128..143] -> TW7 bit[31..16]: egress::hdr.tcp.checksum + # - bit[144..159] -> TW7 bit[15..0]: egress::hdr.tcp.urgent_ptr + B18: 4 # value 1 -> B18 bit[2]: egress::hdr.tcp.$valid + shift: 20 + buf_req: 20 + next: parse_app + 0x01bb: + counter: dec 20 + 0..1: TH8 # egress::hdr.tcp.src_port + 2..3: TH7 # egress::hdr.tcp.dst_port + 4..7: TW17 # egress::hdr.tcp.seq_no + 8..11: TW16 # egress::hdr.tcp.ack_no + 12: TB5 + # - bit[96..99] -> TB5 bit[7..4]: egress::hdr.tcp.data_offset + # - bit[100..103] -> TB5 bit[3..0]: egress::hdr.tcp.res + 13: TB6 # egress::hdr.tcp.flags + 14..15: TH6 # egress::hdr.tcp.window + 16..19: TW7 + # - bit[128..143] -> TW7 bit[31..16]: egress::hdr.tcp.checksum + # - bit[144..159] -> TW7 bit[15..0]: egress::hdr.tcp.urgent_ptr + B18: 4 # value 1 -> B18 bit[2]: egress::hdr.tcp.$valid + shift: 20 + buf_req: 20 + next: parse_app + 0x15b3: + counter: dec 20 + 0..1: TH8 # egress::hdr.tcp.src_port + 2..3: TH7 # egress::hdr.tcp.dst_port + 4..7: TW17 # egress::hdr.tcp.seq_no + 8..11: TW16 # egress::hdr.tcp.ack_no + 12: TB5 + # - bit[96..99] -> TB5 bit[7..4]: egress::hdr.tcp.data_offset + # - bit[100..103] -> TB5 bit[3..0]: egress::hdr.tcp.res + 13: TB6 # egress::hdr.tcp.flags + 14..15: TH6 # egress::hdr.tcp.window + 16..19: TW7 + # - bit[128..143] -> TW7 bit[31..16]: egress::hdr.tcp.checksum + # - bit[144..159] -> TW7 bit[15..0]: egress::hdr.tcp.urgent_ptr + B18: 4 # value 1 -> B18 bit[2]: egress::hdr.tcp.$valid + shift: 20 + buf_req: 20 + next: parse_recirculation + 0x****: + counter: dec 20 + 0..1: TH8 # egress::hdr.tcp.src_port + 2..3: TH7 # egress::hdr.tcp.dst_port + 4..7: TW17 # egress::hdr.tcp.seq_no + 8..11: TW16 # egress::hdr.tcp.ack_no + 12: TB5 + # - bit[96..99] -> TB5 bit[7..4]: egress::hdr.tcp.data_offset + # - bit[100..103] -> TB5 bit[3..0]: egress::hdr.tcp.res + 13: TB6 # egress::hdr.tcp.flags + 14..15: TH6 # egress::hdr.tcp.window + 16..19: TW7 + # - bit[128..143] -> TW7 bit[31..16]: egress::hdr.tcp.checksum + # - bit[144..159] -> TW7 bit[15..0]: egress::hdr.tcp.urgent_ptr + B18: 4 # value 1 -> B18 bit[2]: egress::hdr.tcp.$valid + shift: 20 + buf_req: 20 + next: end + parse_app: + *: + counter: dec 1 + 0: TB4 # egress::hdr.app.byte + B18: 8 # value 1 -> B18 bit[3]: egress::hdr.app.$valid + shift: 1 + buf_req: 1 + next: end + parse_recirculation: + *: + counter: dec 3 + 0: B17 # egress::hdr.recir.packet_state + 1..2: TH33 # egress::hdr.recir.pattern_state_machine_state + B18: 16 # value 1 -> B18 bit[4]: egress::hdr.recir.$valid + shift: 3 + buf_req: 3 + next: parse_app + parse_udp: + match: [ half ] + 0x0035: + counter: dec 8 + 0..1: TH7 # egress::hdr.udp.src_port + 2..3: TH6 # egress::hdr.udp.dst_port + 4..7: TW7 + # - bit[32..47] -> TW7 bit[31..16]: egress::hdr.udp.hdr_length + # - bit[48..63] -> TW7 bit[15..0]: egress::hdr.udp.checksum + B18: 32 # value 1 -> B18 bit[5]: egress::hdr.udp.$valid + shift: 8 + buf_req: 8 + next: parse_app + 0x15b3: + counter: dec 8 + 0..1: TH7 # egress::hdr.udp.src_port + 2..3: TH6 # egress::hdr.udp.dst_port + 4..7: TW7 + # - bit[32..47] -> TW7 bit[31..16]: egress::hdr.udp.hdr_length + # - bit[48..63] -> TW7 bit[15..0]: egress::hdr.udp.checksum + B18: 32 # value 1 -> B18 bit[5]: egress::hdr.udp.$valid + shift: 8 + buf_req: 8 + next: parse_recirculation + 0x****: + counter: dec 8 + 0..1: TH7 # egress::hdr.udp.src_port + 2..3: TH6 # egress::hdr.udp.dst_port + 4..7: TW7 + # - bit[32..47] -> TW7 bit[31..16]: egress::hdr.udp.hdr_length + # - bit[48..63] -> TW7 bit[15..0]: egress::hdr.udp.checksum + B18: 32 # value 1 -> B18 bit[5]: egress::hdr.udp.$valid + shift: 8 + buf_req: 8 + next: end + min_parse_depth_accept_initial: + match: [ ctr_neg, ctr_zero ] + 0x0: + counter: dec 11 + 0: TB4 # egress::hdr.prsr_pad_0[0].blob[87:80].80-87 + 1..2: TH28 # egress::hdr.prsr_pad_0[0].blob[79:64].64-79 + 3..4: TH7 # egress::hdr.prsr_pad_0[0].blob[63:48].48-63 + 5..6: TH6 # egress::hdr.prsr_pad_0[0].blob[47:32].32-47 + 7..10: TW7 # egress::hdr.prsr_pad_0[0].blob[31:0].0-31 + B16: 4 # value 4 -> B16 bit[2..0]: egress::hdr.prsr_pad_0.$stkvalid + shift: 11 + buf_req: 11 + next: min_parse_depth_accept_loop.$split_0 + 0b**: + buf_req: 0 + next: end + min_parse_depth_accept_loop.$split_0: + match: [ ctr_neg, ctr_zero ] + 0x0: + counter: dec 11 + 0: TB5 # egress::hdr.prsr_pad_0[1].blob[87:80].80-87 + 1..2: TH29 # egress::hdr.prsr_pad_0[1].blob[79:64].64-79 + 3..4: TH11 # egress::hdr.prsr_pad_0[1].blob[63:48].48-63 + 5..6: TH10 # egress::hdr.prsr_pad_0[1].blob[47:32].32-47 + 7..8: TH9 # egress::hdr.prsr_pad_0[1].blob[31:16].16-31 + B16: 2 # value 2 -> B16 bit[2..0]: egress::hdr.prsr_pad_0.$stkvalid + shift: 9 + buf_req: 9 + next: min_parse_depth_accept_loop.$it1.$split_0 + 0b**: + buf_req: 0 + next: end + min_parse_depth_accept_loop.$it1.$split_0: + match: [ ctr_neg, ctr_zero ] + 0x0: + 0..1: TH8 # egress::hdr.prsr_pad_0[1].blob[15:0].0-15 + shift: 2 + buf_req: 2 + next: min_parse_depth_accept_loop.$it2 + 0b**: + 0..1: TH8 # egress::hdr.prsr_pad_0[1].blob[15:0].0-15 + shift: 2 + buf_req: 2 + next: end + min_parse_depth_accept_loop.$it2: + *: + counter: dec 11 + 0: TB6 # egress::hdr.prsr_pad_0[2].blob[87:80].80-87 + 1: TB16 # egress::hdr.prsr_pad_0[2].blob[79:72].72-79 + 2: TB7 # egress::hdr.prsr_pad_0[2].blob[71:64].64-71 + 3..6: TW17 # egress::hdr.prsr_pad_0[2].blob[63:32].32-63 + 7..10: TW16 # egress::hdr.prsr_pad_0[2].blob[31:0].0-31 + B16: 1 # value 1 -> B16 bit[2..0]: egress::hdr.prsr_pad_0.$stkvalid + shift: 11 + buf_req: 11 + next: min_parse_depth_accept_loop.$it2.$split_0 + min_parse_depth_accept_loop.$it2.$split_0: + match: [ ctr_neg, ctr_zero ] + 0x0: + buf_req: 0 + next: end + 0b**: + buf_req: 0 + next: end + parse_ipv6: + *: + counter: dec 40 + 0..3: TW5 + # - bit[0..3] -> TW5 bit[31..28]: egress::hdr.ipv6.version + # - bit[4..11] -> TW5 bit[27..20]: egress::hdr.ipv6.traffic_class + # - bit[12..31] -> TW5 bit[19..0]: egress::hdr.ipv6.flow_label + 4..7: TW4 + # - bit[32..47] -> TW4 bit[31..16]: egress::hdr.ipv6.payload_len + # - bit[48..55] -> TW4 bit[15..8]: egress::hdr.ipv6.next_hdr + # - bit[56..63] -> TW4 bit[7..0]: egress::hdr.ipv6.hop_limit + 8..11: TW21 # egress::hdr.ipv6.src_addr[127:96].96-127 + 12..15: TW20 # egress::hdr.ipv6.src_addr[95:64].64-95 + 16: TB16 # egress::hdr.ipv6.src_addr[63:56].56-63 + 17: TB7 # egress::hdr.ipv6.src_addr[55:48].48-55 + 18..19: TH29 # egress::hdr.ipv6.src_addr[47:32].32-47 + 20..21: TH28 # egress::hdr.ipv6.src_addr[31:16].16-31 + 22..23: TH27 # egress::hdr.ipv6.src_addr[15:0].0-15 + 24..25: TH26 # egress::hdr.ipv6.dst_addr[127:112].112-127 + B18: 64 # value 1 -> B18 bit[6]: egress::hdr.ipv6.$valid + load: { byte1 : 6 } + shift: 26 + buf_req: 26 + next: parse_ipv6.$split_0 + parse_ipv6.$split_0: + *: + 0..1: TH25 # egress::hdr.ipv6.dst_addr[111:96].96-111 + 2..3: TH24 # egress::hdr.ipv6.dst_addr[95:80].80-95 + 4..5: TH11 # egress::hdr.ipv6.dst_addr[79:64].64-79 + 6..7: TH10 # egress::hdr.ipv6.dst_addr[63:48].48-63 + 10..13: TW6 # egress::hdr.ipv6.dst_addr[31:0].0-31 + shift: 8 + buf_req: 14 + next: parse_ipv6.$split_1 + parse_ipv6.$split_1: + match: [ byte1 ] + 0x06: + 0..1: TH9 # egress::hdr.ipv6.dst_addr[47:32].32-47 + load: { half : 8..9 } + shift: 6 + buf_req: 10 + next: parse_tcp + 0x11: + 0..1: TH9 # egress::hdr.ipv6.dst_addr[47:32].32-47 + load: { half : 6..7 } + shift: 6 + buf_req: 8 + next: parse_udp + 0x**: + 0..1: TH9 # egress::hdr.ipv6.dst_addr[47:32].32-47 + shift: 6 + buf_req: 6 + next: end + parse_normal_tagging_state: + *: + B19: 1 # value 1 -> B19 bit[7..0]: egress::eg_md.packet_state + load: { half : 12..13 } + buf_req: 14 + next: parse_ethernet +)PARSER_CFG"; + + options.target = NO_TARGET; + Phv::test_clear(); + + createSingleAsmParser(); + AsmParser *asm_parser = dynamic_cast(::asm_parser); + asm_parse_string(parser_str); + std::vector parser_vector = asm_parser->test_get_parser(EGRESS); + EXPECT_GT(parser_vector.size(), 0); + Parser *parser = parser_vector.back(); + parser->process(); + EXPECT_EQ(parser->get_prsr_max_dph(), 4); +} + +// TEST(parser_test, get_parser_deepest_depth_loop_no_stack) +// +// verify that parser with loops that do not store into +// header stacks are supported and that the parser max +// depth is set to the maximum supported by the target. +// +TEST(parser_test, get_parser_depth_loop_no_stack) { + const char *parser_str = R"PARSER_CFG( +version: + target: Tofino +parser egress: + start: $entry_point.start + init_zero: [ B17, B16 ] + bitwise_or: [ B16, B17 ] + hdr_len_adj: 27 + meta_opt: 8191 + states: + $entry_point.start: + *: + counter: + imm: 65 + 0..1: H16 # bit[7..15] -> H16 bit[8..0]: egress::eg_intr_md.egress_port + 27..28: TH14 # egress::hdr.ether.dstAddr[47:32].32-47 + B17: 1 # value 1 -> B17 bit[0]: egress::hdr.ether.$valid + intr_md: 9 + shift: 29 + buf_req: 29 + next: $entry_point.start.$split_0 + $entry_point.start.$split_0: + *: + counter: dec 27 + 0..3: TW5 # egress::hdr.ether.dstAddr[31:0].0-31 + 4..5: TH13 # egress::hdr.ether.srcAddr[47:32].32-47 + 6..9: TW4 # egress::hdr.ether.srcAddr[31:0].0-31 + 10..11: TH12 # egress::hdr.ether.etherType + load: { half : 10..11 } + shift: 12 + buf_req: 12 + next: $entry_point.start.$split_1 + $entry_point.start.$split_1: + *: + counter: dec 14 + buf_req: 0 + next: L3_start_0 + L3_start_0: + match: [ half ] + 0x0800: + counter: dec 1 + 0: TB4 # egress::hdr.h.a + B17: 2 # value 1 -> B17 bit[1]: egress::hdr.h.$valid + shift: 1 + buf_req: 1 + next: min_parse_depth_accept_initial + 0x8100: + counter: dec 2 + 0: TB9 # egress::hdr.i.etherType[15:8].8-15 + 1: TB8 # egress::hdr.i.etherType[7:0].0-7 + B17: 4 # value 1 -> B17 bit[2]: egress::hdr.i.$valid + shift: 2 + buf_req: 2 + next: L3_start_0 + 0x****: + buf_req: 0 + next: min_parse_depth_accept_initial + min_parse_depth_accept_initial: + match: [ ctr_neg, ctr_zero ] + 0x0: + counter: dec 11 + 0: TB5 # egress::hdr.prsr_pad_0[0].blob[87:80].80-87 + 1..2: TH15 # egress::hdr.prsr_pad_0[0].blob[79:64].64-79 + 3..6: TW7 # egress::hdr.prsr_pad_0[0].blob[63:32].32-63 + 7..10: TW6 # egress::hdr.prsr_pad_0[0].blob[31:0].0-31 + B16: 4 # value 4 -> B16 bit[2..0]: egress::hdr.prsr_pad_0.$stkvalid + shift: 11 + buf_req: 11 + next: min_parse_depth_accept_loop.$split_0 + 0b**: + buf_req: 0 + next: end + min_parse_depth_accept_loop.$split_0: + match: [ ctr_neg, ctr_zero ] + 0x0: + counter: dec 11 + 0: TB6 # egress::hdr.prsr_pad_0[1].blob[87:80].80-87 + 1..2: TH16 # egress::hdr.prsr_pad_0[1].blob[79:64].64-79 + 3..4: TH9 # egress::hdr.prsr_pad_0[1].blob[63:48].48-63 + 5..6: TH8 # egress::hdr.prsr_pad_0[1].blob[47:32].32-47 + 7..8: TH7 # egress::hdr.prsr_pad_0[1].blob[31:16].16-31 + B16: 2 # value 2 -> B16 bit[2..0]: egress::hdr.prsr_pad_0.$stkvalid + shift: 9 + buf_req: 9 + next: min_parse_depth_accept_loop.$it1.$split_0 + 0b**: + buf_req: 0 + next: end + min_parse_depth_accept_loop.$it1.$split_0: + match: [ ctr_neg, ctr_zero ] + 0x0: + 0..1: TH6 # egress::hdr.prsr_pad_0[1].blob[15:0].0-15 + shift: 2 + buf_req: 2 + next: min_parse_depth_accept_loop.$it2 + 0b**: + 0..1: TH6 # egress::hdr.prsr_pad_0[1].blob[15:0].0-15 + shift: 2 + buf_req: 2 + next: end + min_parse_depth_accept_loop.$it2: + *: + counter: dec 11 + 0: TB7 # egress::hdr.prsr_pad_0[2].blob[87:80].80-87 + 1..2: TH17 # egress::hdr.prsr_pad_0[2].blob[79:64].64-79 + 3..6: TW8 # egress::hdr.prsr_pad_0[2].blob[63:32].32-63 + 7..8: TH11 # egress::hdr.prsr_pad_0[2].blob[31:16].16-31 + 9..10: TH10 # egress::hdr.prsr_pad_0[2].blob[15:0].0-15 + B16: 1 # value 1 -> B16 bit[2..0]: egress::hdr.prsr_pad_0.$stkvalid + shift: 11 + buf_req: 11 + next: min_parse_depth_accept_loop.$it2.$split_0 + min_parse_depth_accept_loop.$it2.$split_0: + match: [ ctr_neg, ctr_zero ] + 0x0: + buf_req: 0 + next: end + 0b**: + buf_req: 0 + next: end +)PARSER_CFG"; + + options.target = NO_TARGET; + Phv::test_clear(); + + createSingleAsmParser(); + AsmParser *asm_parser = dynamic_cast(::asm_parser); + asm_parse_string(parser_str); + std::vector parser_vector = asm_parser->test_get_parser(EGRESS); + EXPECT_GT(parser_vector.size(), 0); + Parser *parser = parser_vector.back(); + parser->process(); + EXPECT_EQ(parser->get_prsr_max_dph(), 0x3ff - 1); +} + +// TEST(parser_test, get_parser_depth_loop_with_stack) +// +// verify that when a parser has loops that store into header +// stacks, that the max parser depth is set according to the +// number of entries in the stack. +// +TEST(parser_test, get_parser_depth_loop_with_stack) { + const char *parser_str = R"PARSER_CFG( +version: + target: Tofino +phv egress: + eg_intr_md.egress_port: H17(0..8) + hdr.vlan$0.pcp: TW0(29..31) + hdr.vlan$0.dei: TW0(28) + hdr.vlan$0.vid: TW0(16..27) + hdr.vlan$0.ether_type: TW0(0..15) + hdr.vlan$1.pcp: TW1(29..31) + hdr.vlan$1.dei: TW1(28) + hdr.vlan$1.vid: TW1(16..27) + hdr.vlan$1.ether_type: TW1(0..15) + hdr.vlan$2.pcp: TW2(29..31) + hdr.vlan$2.dei: TW2(28) + hdr.vlan$2.vid: TW2(16..27) + hdr.vlan$2.ether_type: TW2(0..15) + hdr.vlan$3.pcp: TW3(29..31) + hdr.vlan$3.dei: TW3(28) + hdr.vlan$3.vid: TW3(16..27) + hdr.vlan$3.ether_type: TW3(0..15) + hdr.vlan$4.pcp: TH1(13..15) + hdr.vlan$4.dei: TH1(12) + hdr.vlan$4.vid: TH1(0..11) + hdr.vlan$4.ether_type: TH0 + hdr.vlan$5.pcp: TH3(13..15) + hdr.vlan$5.dei: TH3(12) + hdr.vlan$5.vid: TH3(0..11) + hdr.vlan$5.ether_type: TH2 + hdr.vlan$6.pcp: TH5(13..15) + hdr.vlan$6.dei: TH5(12) + hdr.vlan$6.vid: TH5(0..11) + hdr.vlan$6.ether_type: TH4 + hdr.vlan$7.pcp: TW12(29..31) + hdr.vlan$7.dei: TW12(28) + hdr.vlan$7.vid: TW12(16..27) + hdr.vlan$7.ether_type: TW12(0..15) + hdr.vlan$8.pcp: TW13(29..31) + hdr.vlan$8.dei: TW13(28) + hdr.vlan$8.vid: TW13(16..27) + hdr.vlan$8.ether_type: TW13(0..15) + hdr.vlan$9.pcp: TW14(29..31) + hdr.vlan$9.dei: TW14(28) + hdr.vlan$9.vid: TW14(16..27) + hdr.vlan$9.ether_type: TW14(0..15) + hdr.vlan$10.pcp: TW15(29..31) + hdr.vlan$10.dei: TW15(28) + hdr.vlan$10.vid: TW15(16..27) + hdr.vlan$10.ether_type: TW15(0..15) + hdr.vlan$11.pcp: TH19(13..15) + hdr.vlan$11.dei: TH19(12) + hdr.vlan$11.vid: TH19(0..11) + hdr.vlan$11.ether_type: TH18 + hdr.vlan$12.pcp: TH21(13..15) + hdr.vlan$12.dei: TH21(12) + hdr.vlan$12.vid: TH21(0..11) + hdr.vlan$12.ether_type: TH20 + hdr.vlan$13.pcp: TH23(13..15) + hdr.vlan$13.dei: TH23(12) + hdr.vlan$13.vid: TH23(0..11) + hdr.vlan$13.ether_type: TH22 + hdr.vlan$14.pcp: TB13(5..7) + hdr.vlan$14.dei: TB13(4) + hdr.vlan$14.vid.0-7: TB14 + hdr.vlan$14.vid.8-11: TB13(0..3) + hdr.vlan$14.ether_type.0-7: TB3 + hdr.vlan$14.ether_type.8-15: TB12 + hdr.prsr_pad_0$0.blob.0-31: TW20 + hdr.prsr_pad_0$0.blob.32-63: TW21 + hdr.prsr_pad_0$0.blob.64-79: TH36 + hdr.prsr_pad_0$0.blob.80-87: TB0 + hdr.prsr_pad_0$1.blob.0-31: TW22 + hdr.prsr_pad_0$1.blob.32-63: TW23 + hdr.prsr_pad_0$1.blob.64-79: TH37 + hdr.prsr_pad_0$1.blob.80-87: TB1 + hdr.prsr_pad_0$2.blob.0-15: TH30 + hdr.prsr_pad_0$2.blob.16-31: TH31 + hdr.prsr_pad_0$2.blob.32-47: TH32 + hdr.prsr_pad_0$2.blob.48-63: TH33 + hdr.prsr_pad_0$2.blob.64-79: TH38 + hdr.prsr_pad_0$2.blob.80-87: TB2 + hdr.eth.dst_addr.0-7: TB15 + hdr.eth.dst_addr.8-15: TB20 + hdr.eth.dst_addr.16-23: TB21 + hdr.eth.dst_addr.24-31: TB22 + hdr.eth.dst_addr.32-47: TH41 + hdr.eth.src_addr.0-15: TH34 + hdr.eth.src_addr.16-31: TH35 + hdr.eth.src_addr.32-47: TH40 + hdr.eth.ethertype: TH39 + hdr.eth.$valid: B17(0) + hdr.vlan.$stkvalid: H16(0..14) + hdr.vlan$0.$valid: H16(14) + hdr.vlan$1.$valid: H16(13) + hdr.vlan$2.$valid: H16(12) + hdr.vlan$3.$valid: H16(11) + hdr.vlan$4.$valid: H16(10) + hdr.vlan$5.$valid: H16(9) + hdr.vlan$6.$valid: H16(8) + hdr.vlan$7.$valid: H16(7) + hdr.vlan$8.$valid: H16(6) + hdr.vlan$9.$valid: H16(5) + hdr.vlan$10.$valid: H16(4) + hdr.vlan$11.$valid: H16(3) + hdr.vlan$12.$valid: H16(2) + hdr.vlan$13.$valid: H16(1) + hdr.vlan$14.$valid: H16(0) + hdr.prsr_pad_0.$stkvalid: B16(0..2) + hdr.prsr_pad_0$0.$valid: B16(2) + hdr.prsr_pad_0$1.$valid: B16(1) + hdr.prsr_pad_0$2.$valid: B16(0) + context_json: + B16: + - { name : hdr.prsr_pad_0$0.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.prsr_pad_0.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.prsr_pad_0$1.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.prsr_pad_0$2.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B17: + - { name : hdr.eth.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H16: + - { name : hdr.vlan$0.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan$1.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan$2.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan$3.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan$4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan$5.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan$6.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan$7.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan$8.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan$9.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan$10.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan$11.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan$12.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan$13.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan$14.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H17: + - { name : eg_intr_md.egress_port, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } +parser egress: + start: $entry_point + init_zero: [ B17, H16, B16 ] + bitwise_or: [ TH39, B16, H16 ] + hdr_len_adj: 27 + meta_opt: 8191 + states: + $entry_point: + *: + counter: + imm: 24 + 0..1: H17 # bit[7..15] -> H17 bit[8..0]: egress::eg_intr_md.egress_port + 27..28: TH41 # egress::hdr.eth.dst_addr[47:32].32-47 + 29: TB22 # egress::hdr.eth.dst_addr[31:24].24-31 + 30: TB21 # egress::hdr.eth.dst_addr[23:16].16-23 + 31: TB20 # egress::hdr.eth.dst_addr[15:8].8-15 + B17: 1 # value 1 -> B17 bit[0]: egress::hdr.eth.$valid + intr_md: 9 + shift: 32 + buf_req: 32 + next: start.$oob_stall_0 + start.$oob_stall_0: + *: + load: { half : 7..8 } + buf_req: 9 + next: start.$split_0 + start.$split_0: + match: [ half ] + 0x8100: + 0: TB15 # egress::hdr.eth.dst_addr[7:0].0-7 + 1..2: TH40 # egress::hdr.eth.src_addr[47:32].32-47 + 3..4: TH35 # egress::hdr.eth.src_addr[31:16].16-31 + 5..6: TH34 # egress::hdr.eth.src_addr[15:0].0-15 + 7..8: TH39 # egress::hdr.eth.ethertype + load: { half : 11..12 } + shift: 9 + buf_req: 13 + next: CommonParser_parse_vlan_0 + 0x****: + 0: TB15 # egress::hdr.eth.dst_addr[7:0].0-7 + 1..2: TH40 # egress::hdr.eth.src_addr[47:32].32-47 + 3..4: TH35 # egress::hdr.eth.src_addr[31:16].16-31 + 5..6: TH34 # egress::hdr.eth.src_addr[15:0].0-15 + 7..8: TH39 # egress::hdr.eth.ethertype + shift: 9 + buf_req: 9 + next: min_parse_depth_accept_initial + CommonParser_parse_vlan_0: + match: [ half ] + 0x8100: + counter: dec 4 + 0..3: TW0 + # - bit[0..2] -> TW0 bit[31..29]: egress::hdr.vlan[0].pcp + # - bit[3] -> TW0 bit[28]: egress::hdr.vlan[0].dei + # - bit[4..15] -> TW0 bit[27..16]: egress::hdr.vlan[0].vid + # - bit[16..31] -> TW0 bit[15..0]: egress::hdr.vlan[0].ether_type + H16: 16384 # value 16384 -> H16 bit[14..0]: egress::hdr.vlan.$stkvalid + TH39: 2 # value 2 -> TH39 bit[15..0]: egress::hdr.eth.ethertype + load: { half : 2..3 } + shift: 4 + buf_req: 4 + offset_inc: 1 + next: CommonParser_parse_vlan_0 + 0x****: + counter: dec 4 + 0..3: TW0 + # - bit[0..2] -> TW0 bit[31..29]: egress::hdr.vlan[0].pcp + # - bit[3] -> TW0 bit[28]: egress::hdr.vlan[0].dei + # - bit[4..15] -> TW0 bit[27..16]: egress::hdr.vlan[0].vid + # - bit[16..31] -> TW0 bit[15..0]: egress::hdr.vlan[0].ether_type + H16: 16384 # value 16384 -> H16 bit[14..0]: egress::hdr.vlan.$stkvalid + TH39: 2 # value 2 -> TH39 bit[15..0]: egress::hdr.eth.ethertype + shift: 4 + buf_req: 4 + offset_inc: 1 + next: min_parse_depth_accept_initial + min_parse_depth_accept_initial: + match: [ ctr_neg, ctr_zero ] + 0x0: + counter: dec 11 + 0: TB0 # egress::hdr.prsr_pad_0[0].blob[87:80].80-87 + 1..2: TH36 # egress::hdr.prsr_pad_0[0].blob[79:64].64-79 + 3..6: TW21 # egress::hdr.prsr_pad_0[0].blob[63:32].32-63 + 7..10: TW20 # egress::hdr.prsr_pad_0[0].blob[31:0].0-31 + B16: 4 # value 4 -> B16 bit[2..0]: egress::hdr.prsr_pad_0.$stkvalid + shift: 11 + buf_req: 11 + next: min_parse_depth_accept_loop.$split_0 + 0b**: + buf_req: 0 + next: end + min_parse_depth_accept_loop.$split_0: + match: [ ctr_neg, ctr_zero ] + 0x0: + counter: dec 11 + 0: TB1 # egress::hdr.prsr_pad_0[1].blob[87:80].80-87 + 1..2: TH37 # egress::hdr.prsr_pad_0[1].blob[79:64].64-79 + 3..6: TW23 # egress::hdr.prsr_pad_0[1].blob[63:32].32-63 + 7..10: TW22 # egress::hdr.prsr_pad_0[1].blob[31:0].0-31 + B16: 2 # value 2 -> B16 bit[2..0]: egress::hdr.prsr_pad_0.$stkvalid + shift: 11 + buf_req: 11 + next: min_parse_depth_accept_loop.$it1.$split_0 + 0b**: + buf_req: 0 + next: end + min_parse_depth_accept_loop.$it1.$split_0: + match: [ ctr_neg, ctr_zero ] + 0x0: + counter: dec 11 + 0: TB2 # egress::hdr.prsr_pad_0[2].blob[87:80].80-87 + 1..2: TH38 # egress::hdr.prsr_pad_0[2].blob[79:64].64-79 + 3..4: TH33 # egress::hdr.prsr_pad_0[2].blob[63:48].48-63 + 5..6: TH32 # egress::hdr.prsr_pad_0[2].blob[47:32].32-47 + 7..8: TH31 # egress::hdr.prsr_pad_0[2].blob[31:16].16-31 + B16: 1 # value 1 -> B16 bit[2..0]: egress::hdr.prsr_pad_0.$stkvalid + shift: 9 + buf_req: 9 + next: min_parse_depth_accept_loop.$it2.$split_0 + 0b**: + buf_req: 0 + next: end + min_parse_depth_accept_loop.$it2.$split_0: + match: [ ctr_neg, ctr_zero ] + 0x0: + 0..1: TH30 # egress::hdr.prsr_pad_0[2].blob[15:0].0-15 + shift: 2 + buf_req: 2 + next: end + 0b**: + 0..1: TH30 # egress::hdr.prsr_pad_0[2].blob[15:0].0-15 + shift: 2 + buf_req: 2 + next: end +)PARSER_CFG"; + + options.target = NO_TARGET; + Phv::test_clear(); + + createSingleAsmParser(); + AsmParser *asm_parser = dynamic_cast(::asm_parser); + asm_parse_string(parser_str); + std::vector parser_vector = asm_parser->test_get_parser(EGRESS); + EXPECT_GT(parser_vector.size(), 0); + Parser *parser = parser_vector.back(); + parser->process(); + EXPECT_EQ(parser->get_prsr_max_dph(), 6); +} + +// TEST(parser_test, get_parser_depth_untaken_path) +// +// verify that untaken paths are not considered +// in the parser depth calculation. +// +TEST(parser_test, get_parser_depth_untaken_path) { + const char *parser_str = R"PARSER_CFG( +version: + target: Tofino +parser egress: + start: $entry_point.start + init_zero: [ B17, B16 ] + bitwise_or: [ TH15, B16, B17 ] + hdr_len_adj: 27 + meta_opt: 8191 + states: + $entry_point.start: + *: + counter: + imm: 38 + 0..1: H16 # bit[7..15] -> H16 bit[8..0]: egress::eg_intr_md.egress_port + intr_md: 9 + shift: 27 + buf_req: 27 + next: $entry_point.start.$oob_stall_0 + $entry_point.start.$oob_stall_0: + *: + load: { half : 12..13 } + buf_req: 14 + next: CommonParser_start_0 + CommonParser_start_0: + match: [ half ] + 0x****: + counter: dec 14 + 0..1: TH17 # egress::hdr.eth.dst_addr[47:32].32-47 + 2..5: TW9 # egress::hdr.eth.dst_addr[31:0].0-31 + 6..7: TH16 # egress::hdr.eth.src_addr[47:32].32-47 + 8..11: TW8 # egress::hdr.eth.src_addr[31:0].0-31 + 12..13: TH15 # egress::hdr.eth.ethertype + B17: 1 # value 1 -> B17 bit[0]: egress::hdr.eth.$valid + shift: 14 + buf_req: 14 + next: min_parse_depth_accept_initial + 0x8100: + counter: dec 14 + 0..1: TH17 # egress::hdr.eth.dst_addr[47:32].32-47 + 2..5: TW9 # egress::hdr.eth.dst_addr[31:0].0-31 + 6..7: TH16 # egress::hdr.eth.src_addr[47:32].32-47 + 8..11: TW8 # egress::hdr.eth.src_addr[31:0].0-31 + 12..13: TH15 # egress::hdr.eth.ethertype + B17: 1 # value 1 -> B17 bit[0]: egress::hdr.eth.$valid + load: { half : 16..17 } + shift: 14 + buf_req: 18 + next: CommonParser_parse_vlan_0 + min_parse_depth_accept_initial: + match: [ ctr_neg, ctr_zero ] + 0x0: + counter: dec 11 + 0: TB0 # egress::hdr.prsr_pad_0[0].blob[87:80].80-87 + 1..2: TH12 # egress::hdr.prsr_pad_0[0].blob[79:64].64-79 + 3..6: TW2 # egress::hdr.prsr_pad_0[0].blob[63:32].32-63 + 7..10: TW1 # egress::hdr.prsr_pad_0[0].blob[31:0].0-31 + B16: 4 # value 4 -> B16 bit[2..0]: egress::hdr.prsr_pad_0.$stkvalid + shift: 11 + buf_req: 11 + next: min_parse_depth_accept_loop.$split_0 + 0b**: + buf_req: 0 + next: end + min_parse_depth_accept_loop.$split_0: + match: [ ctr_neg, ctr_zero ] + 0x0: + counter: dec 11 + 0: TB1 # egress::hdr.prsr_pad_0[1].blob[87:80].80-87 + 1..2: TH13 # egress::hdr.prsr_pad_0[1].blob[79:64].64-79 + 3..4: TH1 # egress::hdr.prsr_pad_0[1].blob[63:48].48-63 + 5..6: TH0 # egress::hdr.prsr_pad_0[1].blob[47:32].32-47 + 7..10: TW3 # egress::hdr.prsr_pad_0[1].blob[31:0].0-31 + B16: 2 # value 2 -> B16 bit[2..0]: egress::hdr.prsr_pad_0.$stkvalid + shift: 11 + buf_req: 11 + next: min_parse_depth_accept_loop.$it1.$split_0 + 0b**: + buf_req: 0 + next: end + min_parse_depth_accept_loop.$it1.$split_0: + match: [ ctr_neg, ctr_zero ] + 0x0: + counter: dec 11 + 0: TB2 # egress::hdr.prsr_pad_0[2].blob[87:80].80-87 + 1..2: TH14 # egress::hdr.prsr_pad_0[2].blob[79:64].64-79 + 3..4: TH5 # egress::hdr.prsr_pad_0[2].blob[63:48].48-63 + 5..6: TH4 # egress::hdr.prsr_pad_0[2].blob[47:32].32-47 + 7..8: TH3 # egress::hdr.prsr_pad_0[2].blob[31:16].16-31 + B16: 1 # value 1 -> B16 bit[2..0]: egress::hdr.prsr_pad_0.$stkvalid + shift: 9 + buf_req: 9 + next: min_parse_depth_accept_loop.$it2.$split_0 + 0b**: + buf_req: 0 + next: end + min_parse_depth_accept_loop.$it2.$split_0: + match: [ ctr_neg, ctr_zero ] + 0x0: + 0..1: TH2 # egress::hdr.prsr_pad_0[2].blob[15:0].0-15 + shift: 2 + buf_req: 2 + next: end + 0b**: + 0..1: TH2 # egress::hdr.prsr_pad_0[2].blob[15:0].0-15 + shift: 2 + buf_req: 2 + next: end + CommonParser_parse_vlan_0: + match: [ half ] + 0x8100: + counter: dec 4 + 0..3: TW0 + # - bit[0..2] -> TW0 bit[31..29]: egress::hdr.vlan.pcp + # - bit[3] -> TW0 bit[28]: egress::hdr.vlan.dei + # - bit[4..15] -> TW0 bit[27..16]: egress::hdr.vlan.vid + # - bit[16..31] -> TW0 bit[15..0]: egress::hdr.vlan.ether_type + B17: 2 # value 1 -> B17 bit[1]: egress::hdr.vlan.$valid + TH15: 2 # value 2 -> TH15 bit[15..0]: egress::hdr.eth.ethertype + load: { half : 16..17 } + shift: 4 + buf_req: 18 + next: CommonParser_start_0 + 0x****: + counter: dec 4 + 0..3: TW0 + # - bit[0..2] -> TW0 bit[31..29]: egress::hdr.vlan.pcp + # - bit[3] -> TW0 bit[28]: egress::hdr.vlan.dei + # - bit[4..15] -> TW0 bit[27..16]: egress::hdr.vlan.vid + # - bit[16..31] -> TW0 bit[15..0]: egress::hdr.vlan.ether_type + B17: 2 # value 1 -> B17 bit[1]: egress::hdr.vlan.$valid + TH15: 2 # value 2 -> TH15 bit[15..0]: egress::hdr.eth.ethertype + shift: 4 + buf_req: 4 + next: min_parse_depth_accept_initial +)PARSER_CFG"; + + options.target = NO_TARGET; + Phv::test_clear(); + + createSingleAsmParser(); + AsmParser *asm_parser = dynamic_cast(::asm_parser); + asm_parse_string(parser_str); + std::vector parser_vector = asm_parser->test_get_parser(EGRESS); + EXPECT_GT(parser_vector.size(), 0); + Parser *parser = parser_vector.back(); + parser->process(); + EXPECT_EQ(parser->get_prsr_max_dph(), 4); +} + +} // namespace diff --git a/backends/tofino/bf-asm/gtest/register-matcher.cpp b/backends/tofino/bf-asm/gtest/register-matcher.cpp new file mode 100644 index 00000000000..74b58d9aa51 --- /dev/null +++ b/backends/tofino/bf-asm/gtest/register-matcher.cpp @@ -0,0 +1,175 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "register-matcher.h" + +#include +#include + +namespace BfAsm { + +namespace Test { + +RegisterMatcher::RegisterMatcher(const char *spec) : bitsize(0) { + enum State { + INIT, + IDENT, + WIDTH, + BIN_VALUE, + OCT_VALUE, + HEX_VALUE, + } state(INIT); + uint32_t width(0); + bitvec value; + uint8_t digit(0); + bool negate(false); + + while (true) { + switch (state) { + case INIT: + if (std::isdigit(*spec)) { + width = *spec - '0'; + state = WIDTH; + } else if (*spec == '~') { + negate = !negate; + } else if (std::isalpha(*spec) || *spec == '_') { + /* -- ignore identifiers in the spec */ + state = IDENT; + } + break; + + case IDENT: + if (*spec == '~') { + state = INIT; + negate = true; + } else if (!std::isalpha(*spec) && !std::isdigit(*spec) && *spec != '_') { + state = INIT; + negate = false; + } + break; + + case WIDTH: + if (std::isdigit(*spec)) { + width = 10 * width + *spec - '0'; + } else if (*spec == 'b') { + state = BIN_VALUE; + value = bitvec(); + } else if (*spec == 'x') { + state = HEX_VALUE; + value = bitvec(); + } else if (*spec == 'o') { + state = OCT_VALUE; + value = bitvec(); + } + break; + + case BIN_VALUE: + if (*spec == '0' || *spec == '1') { + digit = *spec - '0'; + if (negate) digit = ~digit; + value <<= 1; + value |= bitvec(digit & 0x01); + } else if (*spec == '|' || *spec == 0) { + pushBits(value, width); + state = INIT; + negate = false; + } + break; + + case HEX_VALUE: + if (std::isxdigit(*spec)) { + if (*spec >= '0' && *spec <= '9') { + digit = *spec - '0'; + } else if (*spec >= 'a' && *spec <= 'f') { + digit = *spec - 'a' + 10; + } else if (*spec >= 'A' && *spec <= 'F') { + digit = *spec - 'A' + 10; + } + if (negate) digit = ~digit; + value <<= 4; + value |= bitvec(digit & 0x0f); + } else if (*spec == '|' || *spec == 0) { + pushBits(value, width); + state = INIT; + negate = false; + } + break; + + case OCT_VALUE: + if (*spec >= '0' && *spec <= '7') { + digit = *spec - '0'; + if (negate) digit = ~digit; + value <<= 3; + value |= bitvec(digit & 0x07); + } else if (*spec == '|' || *spec == 0) { + pushBits(value, width); + state = INIT; + negate = false; + } + break; + } + + if (*spec == 0) break; + ++spec; + } +} + +void RegisterMatcher::pushBits(const bitvec &bits, uint32_t width) { + expected <<= width; + bitvec mask; + mask.setrange(0, width); + expected |= bits & mask; + bitsize += width; +} + +bool RegisterMatcher::checkRegister(std::ostream &os, const uint8_t reg[], uint32_t rsize) const { + const uint32_t bytesize((bitsize + 7) / 8); + if (rsize < bytesize) { + os << "checked register is shorter than the expected value"; + return false; + } + + uint32_t bitindex(0); + bool fail(false); + for (int i(0); i < rsize; ++i) { + const uint8_t byte(expected.getrange(bitindex, 8)); + fail = (byte != reg[i]) || fail; + bitindex += 8; + } + + if (fail) { + os << std::hex << std::setfill('0'); + os << " expected: "; + for (auto i(rsize); i > 0; --i) { + uint8_t byte(expected.getrange((i - 1) * 8, 8)); + os << ' ' << std::setw(2) << static_cast(byte); + bitindex += 8; + } + os << '\n'; + os << " actual: "; + for (auto i(rsize); i > 0; --i) { + os << ' ' << std::setw(2) << static_cast(reg[i - 1]); + } + os << '\n'; + } + + return !fail; +} + +} // namespace Test + +} // namespace BfAsm diff --git a/backends/tofino/bf-asm/gtest/register-matcher.h b/backends/tofino/bf-asm/gtest/register-matcher.h new file mode 100644 index 00000000000..7cfed4482a3 --- /dev/null +++ b/backends/tofino/bf-asm/gtest/register-matcher.h @@ -0,0 +1,67 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_GTEST_REGISTER_MATCHER_H_ +#define BF_ASM_GTEST_REGISTER_MATCHER_H_ + +#include +#include +#include + +#include "bf-asm/ubits.h" +#include "gtest/gtest.h" +#include "p4c/lib/bitvec.h" + +namespace BfAsm { + +namespace Test { + +class RegisterMatcher { + private: + bitvec expected; + uint32_t bitsize; + + public: + explicit RegisterMatcher(const char *spec); + + bool checkRegister(std::ostream &os, const uint8_t reg[], uint32_t size) const; + + template + bool checkRegister(std::ostream &os, const ubits &bits) const { + static_assert(N > 0 && N <= 64); + const uint64_t value(bits); + return checkRegister(os, reinterpret_cast(&value), (N + 7) / 8); + } + + private: + void pushBits(const bitvec &bits, uint32_t width); +}; + +} // namespace Test + +} // namespace BfAsm + +#define EXPECT_REGISTER(reg, expected) \ + do { \ + RegisterMatcher matcher(expected); \ + std::ostringstream oss; \ + if (!matcher.checkRegister(oss, reg)) { \ + ADD_FAILURE() << "check of the register " << #reg << " has failed:\n" << oss.str(); \ + } \ + } while (false) + +#endif /* BF_ASM_GTEST_REGISTER_MATCHER_H_ */ diff --git a/backends/tofino/bf-asm/hash_action.cpp b/backends/tofino/bf-asm/hash_action.cpp new file mode 100644 index 00000000000..2095fe0fe01 --- /dev/null +++ b/backends/tofino/bf-asm/hash_action.cpp @@ -0,0 +1,231 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "action_bus.h" +#include "input_xbar.h" +#include "misc.h" +#include "stage.h" +#include "tables.h" + +// target specific instantiatitions + +Table::Format::Field *HashActionTable::lookup_field(const std::string &n, + const std::string &act) const { + auto *rv = format ? format->field(n) : nullptr; + if (!rv && gateway) rv = gateway->lookup_field(n, act); + if (!rv && !act.empty()) { + if (auto call = get_action()) { + rv = call->lookup_field(n, act); + } + } + return rv; +} + +void HashActionTable::setup(VECTOR(pair_t) & data) { + common_init_setup(data, false, P4Table::MatchEntry); + for (auto &kv : MapIterChecked(data, {"meter", "stats", "stateful"})) { + if (kv.key == "search_bus" || kv.key == "result_bus") { + // already dealt with in Table::setup_layout via common_init_setup + } else if (!common_setup(kv, data, P4Table::MatchEntry)) { + warning(kv.key.lineno, "ignoring unknown item %s in table %s", value_desc(kv.key), + name()); + } + } + if (!action.set() && !actions) + error(lineno, "Table %s has neither action table nor immediate actions", name()); + if (action.args.size() > 2) + error(lineno, "Unexpected number of action table arguments %zu", action.args.size()); + if (actions && !action_bus) action_bus = ActionBus::create(); +} + +void HashActionTable::pass1() { + LOG1("### Hash Action " << name() << " pass1 " << loc()); + MatchTable::pass1(); + for (auto &hd : hash_dist) { + if (hd.xbar_use == 0) hd.xbar_use |= HashDistribution::ACTION_DATA_ADDRESS; + hd.pass1(this, HashDistribution::OTHER, false); + } + if (!gateway && !hash_dist.empty()) + warning(hash_dist[0].lineno, "No gateway in hash_action means hash_dist can't be used"); +} + +void HashActionTable::pass2() { + LOG1("### Hash Action " << name() << " pass2 " << loc()); + if (logical_id < 0) choose_logical_id(); + if (Target::GATEWAY_NEEDS_SEARCH_BUS()) { // FIXME -- misnamed param? + if (layout.size() != 1 || layout[0].bus.empty()) { + error(lineno, "Need explicit row/bus in hash_action table"); + } else if (layout[0].bus.size() > 1) { + error(lineno, "Can't have both bus and result_bus in hash_action table"); + } else { + BUG_CHECK(layout[0].bus.count(Layout::RESULT_BUS), "should have result bus (only)"); + } + } + allocate_physical_ids(); + determine_word_and_result_bus(); + for (auto &ixb : input_xbar) ixb->pass2(); + if (actions) actions->pass2(this); + if (action_bus) action_bus->pass2(this); + if (gateway) gateway->pass2(); + if (idletime) idletime->pass2(); + for (auto &hd : hash_dist) hd.pass2(this); +} + +/** + * Again by definition, the bus of the hash action table by definition is the result bus + */ +void HashActionTable::determine_word_and_result_bus() { + for (auto &row : layout) { + row.word = 0; + } +} + +void HashActionTable::pass3() { + LOG1("### Hash Action " << name() << " pass3 " << loc()); + MatchTable::pass3(); + if (action_bus) action_bus->pass3(this); +} + +template +void HashActionTable::write_merge_regs_vt(REGS ®s, int type, int bus) { + attached.write_merge_regs(regs, this, type, bus); +} + +template +void HashActionTable::write_regs_vt(REGS ®s) { + LOG1("### Hash Action " << name() << " write_regs " << loc()); + /* FIXME -- setup layout with no rams so other functions can write registers properly */ + int bus_type = layout[0].bus[Layout::RESULT_BUS] >> 1; + MatchTable::write_regs(regs, bus_type, this); + auto &merge = regs.rams.match.merge; + merge.exact_match_logical_result_en |= 1 << logical_id; + if (stage->tcam_delay(gress)) merge.exact_match_logical_result_delay |= 1 << logical_id; + if (actions) actions->write_regs(regs, this); + if (idletime) idletime->write_regs(regs); + if (gateway) gateway->write_regs(regs); + for (auto &hd : hash_dist) hd.write_regs(regs, this); + if (options.match_compiler && !enable_action_data_enable && + (!gateway || gateway->empty_match())) { + /* this seems unneeded? (won't actually be used...) */ + merge.next_table_format_data[logical_id].match_next_table_adr_default = + merge.next_table_format_data[logical_id].match_next_table_adr_miss_value.value; + } +} + +/** + * Unlike the hash functions for exact match tables, the hash action table does not require + * the Galois position. On the contrary, the hash action just requires an identity matrix + * of what the address that is to be generated, as they simply use this address as a baseline + * for generating the corresponding address. + * + * Thus, the hash function that is provided starts at bit 0, and is in reverse p4 param order. + * This is under the guarantee that the compiler will allocate the hash in reverse p4 param + * order as well. + * + * FIXME: Possibly this should be validated before this is the output, but currently the + * compiler will set up the hash in that order + */ +void HashActionTable::add_hash_functions(json::map &stage_tbl) const { + json::vector &hash_functions = stage_tbl["hash_functions"] = json::vector(); + + if (input_xbar.empty()) return; + BUG_CHECK(input_xbar.size() == 1, "%s does not have one input xbar", name()); + auto &ht = input_xbar[0]->get_hash_tables(); + if (ht.size() == 0) return; + + int hash_bit_index = 0; + json::map hash_function; + json::vector &hash_bits = hash_function["hash_bits"] = json::vector(); + for (auto it = p4_params_list.rbegin(); it != p4_params_list.rend(); it++) { + auto &p4_param = *it; + for (size_t i = p4_param.start_bit; i < p4_param.start_bit + p4_param.bit_width; i++) { + // Check if the param bit is used in hash function before adding to + // json. E.g. The param can have a mask which will exclude some bits + // to not be a part of the hash function + if (!input_xbar[0]->is_p4_param_bit_in_hash(p4_param.name, i)) continue; + + json::map hash_bit; + hash_bit["hash_bit"] = hash_bit_index; + hash_bit["seed"] = 0; + json::vector &bits_to_xor = hash_bit["bits_to_xor"] = json::vector(); + json::map field; + std::string field_name, global_name; + field_name = p4_param.key_name.empty() ? p4_param.name : p4_param.key_name; + global_name = p4_param.name; + field["field_bit"] = i; + field["field_name"] = field_name; + field["global_name"] = global_name; + field["hash_match_group"] = 0; + field["hash_match_group_bit"] = 0; + bits_to_xor.push_back(std::move(field)); + hash_bits.push_back(std::move(hash_bit)); + + hash_bit_index++; + } + } + hash_function["hash_function_number"] = 0; + hash_functions.push_back(std::move(hash_function)); +} + +void HashActionTable::gen_tbl_cfg(json::vector &out) const { + // FIXME: Support multiple hash_dist's + int size = hash_dist.empty() ? 1 : 1 + hash_dist[0].mask; + json::map &tbl = *base_tbl_cfg(out, "match_entry", size); + std::string_view stage_tbl_type = "match_with_no_key"; + size = 1; + if (p4_table && p4_table->p4_stage_table_type() == "gateway_with_entries") { + stage_tbl_type = "gateway_with_entries"; + size = p4_size(); + } else if (!p4_params_list.empty()) { + stage_tbl_type = "hash_action"; + size = p4_size(); + } + json::map &match_attributes = tbl["match_attributes"]; + json::vector &stage_tables = match_attributes["stage_tables"]; + json::map &stage_tbl = *add_stage_tbl_cfg(match_attributes, stage_tbl_type.data(), size); + stage_tbl["memory_resource_allocation"] = nullptr; + if (!match_attributes.count("match_type")) + match_attributes["match_type"] = stage_tbl_type.data(); + // This is a only a glass required field, as it is only required when no default action + // is specified, which is impossible for Brig through p4-16 + stage_tbl["default_next_table"] = Stage::end_of_pipe(); + add_pack_format(stage_tbl, 0, 0, hash_dist.empty() ? 1 : 0); + add_result_physical_buses(stage_tbl); + if (actions) { + actions->gen_tbl_cfg(tbl["actions"]); + actions->add_action_format(this, stage_tbl); + } else if (action && action->actions) { + action->actions->gen_tbl_cfg(tbl["actions"]); + action->actions->add_action_format(this, stage_tbl); + } + common_tbl_cfg(tbl); + if (stage_tbl_type == "hash_action" && !p4_params_list.empty()) add_hash_functions(stage_tbl); + if (idletime) + idletime->gen_stage_tbl_cfg(stage_tbl); + else if (options.match_compiler) + stage_tbl["stage_idletime_table"] = nullptr; + add_all_reference_tables(tbl); + gen_idletime_tbl_cfg(stage_tbl); + merge_context_json(tbl, stage_tbl); +} + +DEFINE_TABLE_TYPE(HashActionTable) +FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void HashActionTable::write_merge_regs, + (mau_regs & regs, int type, int bus), + { write_merge_regs_vt(regs, type, bus); }) diff --git a/backends/tofino/bf-asm/hash_dist.cpp b/backends/tofino/bf-asm/hash_dist.cpp new file mode 100644 index 00000000000..1a61eeb3ddf --- /dev/null +++ b/backends/tofino/bf-asm/hash_dist.cpp @@ -0,0 +1,228 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "hash_dist.h" + +#include + +#include "range.h" +#include "stage.h" + +static void set_output_bit(unsigned &xbar_use, value_t &v) { + if (CHECKTYPE(v, tSTR)) { + if (v == "immediate_lo" || v == "lo") + xbar_use |= HashDistribution::IMMEDIATE_LOW; + else if (v == "immediate_hi" || v == "hi") + xbar_use |= HashDistribution::IMMEDIATE_HIGH; + else if (v == "meter" || v == "meter_address") + xbar_use |= HashDistribution::METER_ADDRESS; + else if (v == "stats" || v == "stats_address") + xbar_use |= HashDistribution::STATISTICS_ADDRESS; + else if (v == "action" || v == "action_address") + xbar_use |= HashDistribution::ACTION_DATA_ADDRESS; + else if (v == "hashmod") + xbar_use |= HashDistribution::HASHMOD_DIVIDEND; + else + error(v.lineno, "Unrecognized hash_dist output %s", v.s); + } +} + +static const char *xbar_use_string(unsigned xbar_use) { + static char buffer[256]; + static const char *bits[] = {"immed hi", "immed lo", "meter addr", + "stats addr", "action addr", "hashmod-div"}; + char *p = buffer, *e = buffer + sizeof(buffer); + for (int bit = 0; bit < sizeof(bits) / sizeof(bits[0]); ++bit) { + if (!(xbar_use & (1U << bit))) continue; + xbar_use &= ~(1U << bit); + if (p != buffer) p += snprintf(p, p < e ? e - p : 0, xbar_use ? ", " : " and "); + p += snprintf(p, p < e ? e - p : 0, "%s", bits[bit]); + } + if (xbar_use) { + if (p != buffer) p += snprintf(p, p < e ? e - p : 0, " and "); + p += snprintf(p, p < e ? e - p : 0, "<0x%x>", xbar_use); + } + return buffer; +} + +HashDistribution::HashDistribution(int id_, value_t &data, unsigned u) + : lineno(data.lineno), id(id_), xbar_use(u) { + if (id < 0 || id >= 6) error(data.lineno, "Invalid hash_dist unit id %d", id); + if (CHECKTYPE(data, tMAP)) { + for (auto &kv : MapIterChecked(data.map)) { + if (kv.key == "hash") { + if (CHECKTYPE(kv.value, tINT) && (unsigned)(hash_group = kv.value.i) >= 8U) + error(kv.value.lineno, "Invalid hash group"); + } else if (kv.key == "mask") { + if (CHECKTYPE(kv.value, tINT)) mask = kv.value.i; + } else if (kv.key == "shift") { + if (CHECKTYPE(kv.value, tINT)) shift = kv.value.i; + } else if (kv.key == "expand") { + if (CHECKTYPE(kv.value, tINT)) expand = kv.value.i; + } else if (kv.key == "output") { + if (kv.value.type == tVEC) + for (auto &s : kv.value.vec) set_output_bit(xbar_use, s); + else + set_output_bit(xbar_use, kv.value); + } else { + warning(kv.key.lineno, "ignoring unknown item %s in hash_dist", value_desc(kv.key)); + } + } + } +} + +void HashDistribution::parse(std::vector &out, const value_t &data, + unsigned xbar_use) { + if (CHECKTYPE(data, tMAP)) + for (auto &kv : data.map) + if (CHECKTYPE(kv.key, tINT)) out.emplace_back(kv.key.i, kv.value, xbar_use); +} + +bool HashDistribution::compatible(HashDistribution *a) { + if (hash_group != a->hash_group) return false; + if (id != a->id) return false; + if (shift != a->shift) return false; + if (expand != a->expand) return false; + if (delay_type != a->delay_type) return false; + if (non_linear != a->non_linear) return false; + if (meter_pre_color && !a->meter_pre_color && (mask & ~a->mask)) return false; + if (!meter_pre_color && a->meter_pre_color && (~mask & a->mask)) return false; + return true; +} + +void HashDistribution::pass1(Table *tbl, delay_type_t delay_type, bool non_linear) { + LOG1("Hash dist pass1"); + this->tbl = tbl; + this->delay_type = delay_type; + this->non_linear = non_linear; + bool err = false; + for (auto *use : tbl->stage->hash_dist_use[id]) { + if (!compatible(use)) { + err = true; + error(lineno, "hash_dist unit %d in table %s not compatible with", id, tbl->name()); + warning(use->lineno, "previous use in table %s", use->tbl->name()); + } + } + if (expand >= 0) { + int min_shift = 7, diff = 7, other = id - 1; + switch (id % 3) { + case 0: + min_shift = 0; + diff = -7; + other = id + 1; + // fall through + case 1: + if (expand < min_shift || expand >= min_shift + 16) { + error(lineno, "hash_dist unit %d expand can't pull from bit %d", id, expand); + err = true; + } + break; + case 2: + error(lineno, "hash_dist unit %d cannot be expanded", id); + err = true; + break; + default: + error(lineno, + "a mod 3 check should only hit these particular cases, of 0, 1, and 2"); + BUG(); + } + if (!err) { + for (auto *use : tbl->stage->hash_dist_use[other]) + if (use->expand != -1 && use->expand != expand - diff) { + error(lineno, "hash_dist unit %d int table %s expand not compatible with", id, + tbl->name()); + warning(use->lineno, "previous use in table %s", use->tbl->name()); + } + } + } + if (err) return; + tbl->stage->hash_dist_use[id].push_back(this); + for (int i = 0; i < 3; i++) { + if (id % 3 == i) continue; + int m = 3 * (id / 3) + i; + for (auto *use : tbl->stage->hash_dist_use[id]) { + if (use->hash_group != hash_group) { + error(lineno, "hash_dist %d and %d use different hash groups", id, m); + warning(use->lineno, "previous use here"); + } + } + } +} + +void HashDistribution::pass2(Table *tbl) { + for (auto &hd : tbl->hash_dist) { + if (&hd == this) return; + if (id == hd.id) { + error(lineno, "mulitple definitions for hash_dist %d in table %s", id, tbl->name()); + error(hd.lineno, "previous definition"); + break; + } + if (xbar_use & hd.xbar_use) + error(lineno, "confliction output use between hash_dist %d and %d in table %s %s", id, + hd.id, tbl->name(), xbar_use_string(xbar_use & hd.xbar_use)); + } +} + +template +void HashDistribution::write_regs(REGS ®s, Table *tbl) { + /* from HashDistributionResourceAllocation.write_config: */ + auto &merge = regs.rams.match.merge; + if (non_linear) merge.mau_selector_hash_sps_enable |= 1 << id; + if (tbl->gress == EGRESS) merge.mau_hash_group_config.hash_group_egress |= 1 << id; + merge.mau_hash_group_config.hash_group_enable |= 1 << id; + merge.mau_hash_group_config.hash_group_sel.set_subfield(hash_group | 8U, 4 * (id / 3), 4); + merge.mau_hash_group_config.hash_group_ctl.set_subfield(delay_type, 2 * id, 2); + merge.mau_hash_group_shiftcount.set_subfield(shift, 3 * id, 3); + merge.mau_hash_group_mask[id] |= mask; + if (expand >= 0) { + switch (id % 3) { + case 0: + merge.mau_hash_group_expand[id / 3].hash_slice_group0_expand = 1; + merge.mau_hash_group_expand[id / 3].hash_slice_group2_expand = expand; + merge.mau_hash_group_config.hash_group_enable |= 1 << (id + 2); + merge.mau_hash_group_config.hash_group_ctl.set_subfield(delay_type, 2 * (id + 2), + 2); + break; + case 1: + merge.mau_hash_group_expand[id / 3].hash_slice_group1_expand = 1; + merge.mau_hash_group_expand[id / 3].hash_slice_group2_expand = expand - 7; + merge.mau_hash_group_config.hash_group_enable |= 1 << (id + 1); + merge.mau_hash_group_config.hash_group_ctl.set_subfield(delay_type, 2 * (id + 1), + 2); + break; + default: + BUG(); + } + } + for (int oxbar : Range(0, 4)) + if ((xbar_use >> oxbar) & 1) + merge.mau_hash_group_xbar_ctl[oxbar][tbl->logical_id / 8U].set_subfield( + 8 | id, 4 * (tbl->logical_id % 8U), 4); + if (xbar_use & HASHMOD_DIVIDEND) { + int mgroup = tbl->get_selector()->meter_group(); + merge.mau_hash_group_xbar_ctl[5][mgroup / 8U].set_subfield(8 | id, 4 * (mgroup % 8U), 4); + } + if (meter_pre_color) { + merge.mau_meter_precolor_hash_sel.set_subfield(8 | id, 4 * (id / 3), 4); + int ctl = 16 | meter_mask_index; + if (id >= 3) ctl |= 8; + merge.mau_meter_precolor_hash_map_to_logical_ctl[tbl->logical_id / 4U].set_subfield( + ctl, 5 * (tbl->logical_id % 4U), 5); + } +} +FOR_ALL_REGISTER_SETS(INSTANTIATE_TARGET_TEMPLATE, void HashDistribution::write_regs, mau_regs &, + Table *) diff --git a/backends/tofino/bf-asm/hash_dist.h b/backends/tofino/bf-asm/hash_dist.h new file mode 100644 index 00000000000..f673c032b3a --- /dev/null +++ b/backends/tofino/bf-asm/hash_dist.h @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_HASH_DIST_H_ +#define BF_ASM_HASH_DIST_H_ + +#include + +#include "asm-types.h" + +class Stage; +class Table; + +/* config for a hash distribution unit in match central. + * FIXME -- need to abstract this away rather than have it be explicit + * FIXME -- in the asm code */ + +struct HashDistribution { + // FIXME -- need less 'raw' data for this */ + Table *tbl = 0; + int lineno = -1; + int hash_group = -1, id = -1; + int shift = 0, mask = 0, expand = -1; + bool meter_pre_color = false; + int meter_mask_index = 0; + enum { + IMMEDIATE_HIGH = 1 << 0, + IMMEDIATE_LOW = 1 << 1, + METER_ADDRESS = 1 << 2, + STATISTICS_ADDRESS = 1 << 3, + ACTION_DATA_ADDRESS = 1 << 4, + HASHMOD_DIVIDEND = 1 << 5 + }; + unsigned xbar_use = 0; + enum delay_type_t { SELECTOR = 0, OTHER = 1 }; + delay_type_t delay_type = SELECTOR; + bool non_linear = false; + HashDistribution(int id, value_t &data, unsigned u = 0); + static void parse(std::vector &out, const value_t &v, unsigned u = 0); + bool compatible(HashDistribution *a); + void pass1(Table *tbl, delay_type_t dt, bool nl); + void pass2(Table *tbl); + template + void write_regs(REGS ®s, Table *); +}; + +#endif /* BF_ASM_HASH_DIST_H_ */ diff --git a/backends/tofino/bf-asm/hashdump.cpp b/backends/tofino/bf-asm/hashdump.cpp new file mode 100644 index 00000000000..462bc613b6f --- /dev/null +++ b/backends/tofino/bf-asm/hashdump.cpp @@ -0,0 +1,132 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "gen/tofino/disas.regs.mau_addrmap.h" +#include "hex.h" +#include "json.h" + +static Tofino::regs_mau_addrmap regs; + +static void dump_hashtables(std::ostream &out); + +int verbose = 0; +int get_file_log_level(const char *file, int *level) { return *level = verbose; } + +int main(int ac, char **av) { + for (int i = 1; i < ac; i++) { + if (av[i][0] == '-' || av[i][0] == '+') { + bool flag = av[i][0] == '+'; + for (char *arg = av[i] + 1; *arg;) switch (*arg++) { + case 'v': + verbose++; + break; + default: + std::cerr << "Unknown option " << (flag ? '+' : '-') << arg[-1] + << std::endl; + std::cerr << "usage: " << av[0] << " file" << std::endl; + } + } else { + std::ifstream in(av[i]); + if (!in) { + std::cerr << "Can't open " << av[i] << std::endl; + continue; + } + std::unique_ptr data; + in >> data; + if (!in || regs.unpack_json(data.get())) { + std::cerr << "Can't read/unpack json from " << av[i] << std::endl; + continue; + } + dump_hashtables(std::cout); + } + } +} + +static bool col_nonzero(int i, int col) { + for (int word = i * 8; word < i * 8 + 8; word++) { + auto &x = regs.dp.xbar_hash.hash.galois_field_matrix[word][col]; + if (x.byte0 || x.byte1) return true; + } + return false; +} + +static bool col_valid_nonzero(int i, int col) { + for (int word = i * 8; word < i * 8 + 8; word++) { + auto &x = regs.dp.xbar_hash.hash.galois_field_matrix[word][col]; + if (x.valid0 || x.valid1) return true; + } + return false; +} + +static bool ht_nonzero(int i) { + for (int col = 0; col < 52; col++) { + if ((regs.dp.xbar_hash.hash.hash_seed[col] >> i) & 1) return true; + if (col_nonzero(i, col)) return true; + if (col_valid_nonzero(i, col)) return true; + } + return false; +} + +static void dump_ht(std::ostream &out, int i) { + for (int col = 0; col < 52; col++) { + if (col_nonzero(i, col)) { + out << " " << col << ": 0x"; + bool pfx = true; + for (int word = 8 * i + 7; word >= 8 * i; word--) { + auto &w = regs.dp.xbar_hash.hash.galois_field_matrix[word][col]; + if (!pfx || w.byte1) { + out << hex(w.byte1, pfx ? 0 : 2, '0'); + pfx = false; + } + if (!pfx || w.byte0) { + out << hex(w.byte0, pfx ? 0 : 2, '0'); + pfx = false; + } + } + out << '\n'; + } + if (col_valid_nonzero(i, col)) { + out << " valid " << col << ": 0b"; + bool pfx = true; + for (int word = 8 * i + 7; word >= 8 * i; word--) { + auto &w = regs.dp.xbar_hash.hash.galois_field_matrix[word][col]; + if (!pfx || w.valid1) { + out << (w.valid1 ? '1' : '0'); + pfx = false; + } + if (!pfx || w.valid0) { + out << (w.valid0 ? '1' : '0'); + pfx = false; + } + } + out << '\n'; + } + if ((regs.dp.xbar_hash.hash.hash_seed[col] >> i) & 1) out << " seed " << col << ": 1\n"; + } +} + +static void dump_hashtables(std::ostream &out) { + for (int i = 0; i < 8; i++) { + if (ht_nonzero(i)) { + out << "hash " << i << ":\n"; + dump_ht(out, i); + } + } +} diff --git a/backends/tofino/bf-asm/hashexpr.cpp b/backends/tofino/bf-asm/hashexpr.cpp new file mode 100644 index 00000000000..1e951aec5bc --- /dev/null +++ b/backends/tofino/bf-asm/hashexpr.cpp @@ -0,0 +1,846 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "hashexpr.h" + +#include "bitops.h" +#include "bitvec.h" +#include "input_xbar.h" + +static bitvec crc(bitvec poly, bitvec val) { + int poly_size = poly.max().index() + 1; + if (!poly_size) return bitvec(0); + val <<= poly_size - 1; + for (auto i = val.max(); i.index() >= (poly_size - 1); --i) { + BUG_CHECK(*i); + val ^= poly << (i.index() - (poly_size - 1)); + } + return val; +} + +static bool check_ixbar(Phv::Ref &ref, InputXbar *ix, InputXbar::HashTable hash_table) { + if (!ref.check()) return false; + if (ref->reg.mau_id() < 0) { + error(ref.lineno, "%s not accessable in mau", ref->reg.name); + return false; + } + if (!hash_table) return true; + for (auto in : ix->find_hash_inputs(*ref, hash_table)) { + BUG_CHECK(in->lo >= 0, "invalid lo in IXBar::Input"); + return true; + } + error(ref.lineno, "%s not in %s input", ref.name(), hash_table.toString().c_str()); + return false; +} + +/** + * Generating a list of ixbar_input_t and hash_matrix_output_t to be sent to the + * dynamic_hash library. The vectors are part of the function call as they + * must be on the stack to avoid using new and delete + */ +void HashExpr::gen_ixbar_init(ixbar_init_t *ixbar_init, std::vector &inputs, + std::vector &outputs, int logical_hash_bit, + InputXbar *ix, InputXbar::HashTable hash_table) { + inputs.clear(); + outputs.clear(); + + gen_ixbar_inputs(inputs, ix, hash_table); + hash_matrix_output_t hmo; + hmo.p4_hash_output_bit = logical_hash_bit; + hmo.gfm_start_bit = 0; + hmo.bit_size = 1; + outputs.push_back(hmo); + + ixbar_init->ixbar_inputs = inputs.data(); + ixbar_init->inputs_sz = inputs.size(); + ixbar_init->hash_matrix_outputs = outputs.data(); + ixbar_init->outputs_sz = outputs.size(); +} + +/** + * The function call for PhvRef, Random, Identity, and Crc functions. The input xbar is + * initialized, and the data returned writes out a vector of inputs. For Stripe, + * Slice, and others, they recursively will call this function + */ +void HashExpr::gen_data(bitvec &data, int logical_hash_bit, InputXbar *ix, + InputXbar::HashTable hash_table) { + ixbar_init_t ixbar_init; + hash_column_t hash_matrix[PARITY_GROUPS_DYN][HASH_MATRIX_WIDTH_DYN] = {}; + std::vector inputs; + std::vector outputs; + + gen_ixbar_init(&ixbar_init, inputs, outputs, logical_hash_bit, ix, hash_table); + + bool non_zero = false; + int loops = 0; + // It is possible that a hash column can be genereated as all 0s if using RANDOM_DYN algo, so + // regeneration is required if a hash column is all 0s and using RANDOM_DYN. + while (!non_zero) { + determine_hash_matrix(&ixbar_init, ixbar_init.ixbar_inputs, ixbar_init.inputs_sz, + &hash_algorithm, hash_matrix); + if (hash_algorithm.hash_alg != RANDOM_DYN || + ix->global_column0_extract(hash_table, hash_matrix)) { + non_zero = true; + } + BUG_CHECK(loops++ < 1000, "Looping trying to get a valid RANDOM_DYN matrix"); + } + data |= ix->global_column0_extract(hash_table, hash_matrix); +} + +class HashExpr::PhvRef : HashExpr { + Phv::Ref what; + PhvRef(gress_t gr, int stg, const value_t &v) : HashExpr(v.lineno), what(gr, stg, v) {} + friend class HashExpr; + bool check_ixbar(InputXbar *ix, InputXbar::HashTable hash_table) override { + return ::check_ixbar(what, ix, hash_table); + } + int width() override { return what.size(); } + int input_size() override { return what.size(); } + bool match_phvref(const Phv::Ref &ref) override { + if (what->reg != ref->reg || what->lo != ref->lo) return false; + return true; + } + bool operator==(const HashExpr &a_) const override { + if (typeid(*this) != typeid(a_)) return false; + auto &a = static_cast(a_); + return *what == *a.what; + } + void build_algorithm() override { + hash_algorithm.hash_alg = IDENTITY_DYN; + hash_algorithm.msb = false; + hash_algorithm.extend = false; + hash_algorithm.final_xor = 0ULL; + hash_algorithm.poly = 0ULL; + hash_algorithm.init = 0ULL; + hash_algorithm.reverse = false; + } + + void gen_ixbar_inputs(std::vector &inputs, InputXbar *ix, + InputXbar::HashTable hash_table) override; + void get_sources(int bit, std::vector &rv) const override { + if (bit >= 0) + rv.emplace_back(what, bit, bit); + else + rv.emplace_back(what); + } + Phv::Ref *get_ghost_slice() override { return &what; } + void dbprint(std::ostream &out) const override { + out << "HashExpr: PhvRef" << std::endl; + out << "hash algorithm: [ algo : " << hash_algorithm.hash_alg + << ", msb : " << hash_algorithm.msb << ", extend : " << hash_algorithm.extend + << ", final_xor : " << hash_algorithm.final_xor << ", poly : " << hash_algorithm.poly + << ", init : " << hash_algorithm.init << ", reverse : " << hash_algorithm.reverse + << std::endl; + if (what) out << "Phv: " << what << std::endl; + } +}; + +class HashExpr::Random : HashExpr { + std::vector what; + explicit Random(int lineno) : HashExpr(lineno) {} + friend class HashExpr; + bool check_ixbar(InputXbar *ix, InputXbar::HashTable hash_table) override { + bool rv = true; + for (auto &ref : what) rv &= ::check_ixbar(ref, ix, hash_table); + return rv; + } + int width() override { return 0; } + int input_size() override { + int rv = 0; + for (auto &ref : what) rv += ref->size(); + return rv; + } + bool operator==(const HashExpr &a_) const override { + if (typeid(*this) != typeid(a_)) return false; + auto &a = static_cast(a_); + if (what.size() != a.what.size()) return false; + auto it = a.what.begin(); + for (auto &el : what) + if (*el != **it++) return false; + return true; + } + void build_algorithm() override { + hash_algorithm.hash_alg = RANDOM_DYN; + hash_algorithm.msb = false; + hash_algorithm.extend = false; + hash_algorithm.final_xor = 0ULL; + hash_algorithm.poly = 0ULL; + hash_algorithm.init = 0ULL; + hash_algorithm.reverse = false; + } + void gen_ixbar_inputs(std::vector &inputs, InputXbar *ix, + InputXbar::HashTable hash_table) override; + void get_sources(int, std::vector &rv) const override { + rv.insert(rv.end(), what.begin(), what.end()); + } + void dbprint(std::ostream &out) const override { + out << "HashExpr: Random" << std::endl; + out << "hash algorithm: [ algo : " << hash_algorithm.hash_alg + << ", msb : " << hash_algorithm.msb << ", extend : " << hash_algorithm.extend + << ", final_xor : " << hash_algorithm.final_xor << ", poly : " << hash_algorithm.poly + << ", init : " << hash_algorithm.init << ", reverse : " << hash_algorithm.reverse + << std::endl; + for (auto &e : what) { + out << "Phv: " << e << std::endl; + } + } +}; + +class HashExpr::Crc : HashExpr { + bitvec poly; + bitvec init; + bitvec final_xor; + ///> It is a multimap to allow two fields to have the exact same hash matrix requirements + std::multimap what; + std::map constants; + std::vector vec_what; + bool reverse = false; + int total_input_bits = -1; + explicit Crc(int lineno) : HashExpr(lineno) {} + friend class HashExpr; + bool check_ixbar(InputXbar *ix, InputXbar::HashTable hash_table) override; + int width() override { return poly.max().index(); } + int input_size() override { + if (total_input_bits >= 0) return total_input_bits; + if (what.empty()) { + int rv = 0; + for (auto &ref : vec_what) rv += ref->size(); + return rv; + } else { + return what.rbegin()->first + what.rbegin()->second->size(); + } + } + bool operator==(const HashExpr &a_) const override { + if (typeid(*this) != typeid(a_)) return false; + auto &a = static_cast(a_); + if (what.size() != a.what.size()) return false; + if (vec_what.size() != a.vec_what.size()) return false; + auto it = a.what.begin(); + for (auto &el : what) + if (el.first != it->first || *el.second != *(it++)->second) return false; + auto it2 = a.vec_what.begin(); + for (auto &el : vec_what) + if (*el != **it2++) return false; + return true; + } + void build_algorithm() override { + hash_algorithm.hash_bit_width = poly.max().index(); + hash_algorithm.hash_alg = CRC_DYN; + hash_algorithm.reverse = reverse; + hash_algorithm.poly = poly.getrange(32, 32) << 32; + hash_algorithm.poly |= poly.getrange(0, 32); + hash_algorithm.init = init.getrange(32, 32) << 32; + hash_algorithm.init |= init.getrange(0, 32); + hash_algorithm.final_xor = final_xor.getrange(0, 32); + hash_algorithm.final_xor |= final_xor.getrange(32, 32) << 32; + hash_algorithm.extend = false; + hash_algorithm.msb = false; + } + + void gen_ixbar_inputs(std::vector &inputs, InputXbar *ix, + InputXbar::HashTable hash_table) override; + void get_sources(int, std::vector &rv) const override { + rv.insert(rv.end(), vec_what.begin(), vec_what.end()); + } +}; + +/** + * @brief XOR hashing algorithm implemented on the hashing matrix + * + * This expression implements XOR over the hasing matrix. The input + * message is handled as a big integer number - the highest bit is + * the begining, the zero-th bit is the end. The message is split + * from the begining into blocks of length bit_width and these blocks + * are bitwise XORed together. + */ +class HashExpr::XorHash : public HashExpr { + private: + std::multimap what; + int bit_width; + friend class HashExpr; + + public: + explicit XorHash(int lineno, int bit_width_); + + /* -- avoid copying */ + XorHash &operator=(XorHash &&) = delete; + + bool check_ixbar(InputXbar *ix, InputXbar::HashTable hash_table) override; + int width() override; + int input_size() override; + bool operator==(const HashExpr &a_) const override; + void build_algorithm() override; + void gen_ixbar_inputs(std::vector &inputs, InputXbar *ix, + InputXbar::HashTable hash_table) override; + void get_sources(int, std::vector &rv) const override; +}; + +class HashExpr::Xor : HashExpr { + std::vector what; + explicit Xor(int lineno) : HashExpr(lineno) {} + friend class HashExpr; + bool check_ixbar(InputXbar *ix, InputXbar::HashTable hash_table) override { + bool rv = true; + for (auto *e : what) rv |= e->check_ixbar(ix, hash_table); + return rv; + } + void gen_data(bitvec &data, int logical_hash_bit, InputXbar *ix, + InputXbar::HashTable hash_table) override; + int width() override { + int rv = 0; + for (auto *e : what) { + int w = e->width(); + if (w > rv) rv = w; + } + return rv; + } + int input_size() override { + int rv = 0; + for (auto *e : what) rv += e->input_size(); + return rv; + } + bool operator==(const HashExpr &a_) const override { + if (typeid(*this) != typeid(a_)) return false; + auto &a = static_cast(a_); + if (what.size() != a.what.size()) return false; + auto it = a.what.begin(); + for (auto &el : what) + if (*el != **it++) return false; + return true; + } + void build_algorithm() override { + for (auto *e : what) { + if (e) e->build_algorithm(); + } + } + + void gen_ixbar_inputs(std::vector &inputs, InputXbar *ix, + InputXbar::HashTable hash_table) override {} + void get_sources(int bit, std::vector &rv) const override { + for (auto *e : what) e->get_sources(bit, rv); + } + Phv::Ref *get_ghost_slice() override { + for (auto *e : what) { + auto g = e->get_ghost_slice(); + if (g) return g; + } + return nullptr; + } + void dbprint(std::ostream &out) const override { + out << "HashExpr: Xor" << std::endl; + for (auto *e : what) { + e->dbprint(out); + } + } +}; + +class HashExpr::Mask : HashExpr { + HashExpr *what; + bitvec mask; + Mask(int lineno, HashExpr *w, bitvec m) : HashExpr(lineno), what(w), mask(m) {} + friend class HashExpr; + bool check_ixbar(InputXbar *ix, InputXbar::HashTable hash_table) override { + return what->check_ixbar(ix, hash_table); + } + void gen_data(bitvec &data, int bit, InputXbar *ix, InputXbar::HashTable hash_table) override { + if (mask[bit]) what->gen_data(data, bit, ix, hash_table); + } + int width() override { return what->width(); } + int input_size() override { return what->input_size(); } + bool operator==(const HashExpr &a_) const override { + if (typeid(*this) != typeid(a_)) return false; + auto &a = static_cast(a_); + return mask == a.mask && *what == *a.what; + } + void build_algorithm() override { what->build_algorithm(); } + + void gen_ixbar_inputs(std::vector &inputs, InputXbar *ix, + InputXbar::HashTable hash_table) override {} + void get_sources(int bit, std::vector &rv) const override { + if (mask[bit]) what->get_sources(bit, rv); + } + Phv::Ref *get_ghost_slice() override { return what->get_ghost_slice(); } + void dbprint(std::ostream &out) const override { + out << "HashExpr: Mask " << mask << std::endl; + what->dbprint(out); + } +}; + +class HashExpr::Stripe : HashExpr { + std::vector what; + bool supress_error_cascade = false; + explicit Stripe(int lineno) : HashExpr(lineno) {} + friend class HashExpr; + bool check_ixbar(InputXbar *ix, InputXbar::HashTable hash_table) override { + bool rv = true; + for (auto *e : what) rv |= e->check_ixbar(ix, hash_table); + return rv; + } + void gen_data(bitvec &data, int logical_hash_bit, InputXbar *ix, + InputXbar::HashTable hash_table) override; + int width() override { return 0; } + int input_size() override { + int rv = 0; + for (auto *e : what) rv += e->input_size(); + return rv; + } + bool operator==(const HashExpr &a_) const override { + if (typeid(*this) != typeid(a_)) return false; + auto &a = static_cast(a_); + if (what.size() != a.what.size()) return false; + auto it = a.what.begin(); + for (auto &el : what) + if (*el != **it++) return false; + return true; + } + void build_algorithm() override { + for (auto *e : what) { + e->build_algorithm(); + } + // Does not set the extend algorithm, as the gen_data for extend does this + // in the source + } + + void gen_ixbar_inputs(std::vector &inputs, InputXbar *ix, + InputXbar::HashTable hash_table) override {} + void get_sources(int bit, std::vector &rv) const override { + for (auto *e : what) { + if (bit >= 0) { + int width = e->width(); + if (bit < width) { + e->get_sources(bit, rv); + break; + } + bit -= width; + } else { + e->get_sources(bit, rv); + } + } + } + void dbprint(std::ostream &out) const override { + out << "HashExpr: Stripe" << std::endl; + for (auto *e : what) { + e->dbprint(out); + } + } +}; + +class HashExpr::Slice : HashExpr { + HashExpr *what = nullptr; + int start = 0, _width = 0; + explicit Slice(int lineno) : HashExpr(lineno) {} + friend class HashExpr; + bool check_ixbar(InputXbar *ix, InputXbar::HashTable hash_table) override { + return what->check_ixbar(ix, hash_table); + } + void gen_data(bitvec &data, int logical_hash_bit, InputXbar *ix, + InputXbar::HashTable hash_table) override { + what->gen_data(data, logical_hash_bit + start, ix, hash_table); + } + int width() override { + if (_width == 0) { + _width = what->width(); + if (_width > 0) { + _width -= start; + if (_width <= 0) _width = -1; + } + } + return _width; + } + int input_size() override { return what->input_size(); } + bool operator==(const HashExpr &a_) const override { + if (typeid(*this) != typeid(a_)) return false; + auto &a = static_cast(a_); + if (start != a.start || _width != a._width) return false; + return *what == *a.what; + } + void build_algorithm() override { what->build_algorithm(); } + void gen_ixbar_inputs(std::vector &inputs, InputXbar *ix, + InputXbar::HashTable hash_table) override {} + void get_sources(int bit, std::vector &rv) const override { + if (bit >= start) + what->get_sources(bit - start, rv); + else if (bit < 0) + what->get_sources(bit, rv); + } + void dbprint(std::ostream &out) const override { + out << "HashExpr: Slice" << std::endl; + if (what) out << what << std::endl; + out << "start: " << start << " ,width: " << _width << std::endl; + } +}; + +class HashExpr::SExtend : HashExpr { + HashExpr *what; + SExtend(int lineno, HashExpr *w) : HashExpr(lineno), what(w) {} + friend class HashExpr; + bool check_ixbar(InputXbar *ix, InputXbar::HashTable hash_table) override { + return what->check_ixbar(ix, hash_table); + } + void gen_data(bitvec &data, int bit, InputXbar *ix, InputXbar::HashTable hash_table) override { + int width = what->width(); + if (width > 0 && bit >= width) bit = width - 1; + what->gen_data(data, bit, ix, hash_table); + } + int width() override { return 0; } + int input_size() override { return what->input_size(); } + bool operator==(const HashExpr &a_) const override { + if (typeid(*this) != typeid(a_)) return false; + auto &a = static_cast(a_); + return *what == *a.what; + } + void build_algorithm() override { what->build_algorithm(); } + void gen_ixbar_inputs(std::vector &inputs, InputXbar *ix, + InputXbar::HashTable hash_table) override {} + void get_sources(int bit, std::vector &rv) const override { + int width = what->width(); + if (width > 0 && bit >= width) bit = width - 1; + what->get_sources(bit, rv); + } + void dbprint(std::ostream &out) const override { + out << "HashExpr: SExtend" << std::endl; + if (what) out << what << std::endl; + } +}; + +// The ordering for crc expression is: +// crc(poly, @optional init, @optional input_bits, map) +HashExpr *HashExpr::create(gress_t gress, int stage, const value_t &what) { + if (what.type == tCMD) { + if (what[0] == "random") { + Random *rv = new Random(what.lineno); + for (int i = 1; i < what.vec.size; i++) rv->what.emplace_back(gress, stage, what[i]); + return rv; + } else if (what[0] == "xor") { + if (what.vec.size != 3) { + error(what[1].lineno, + "Syntax error, invalid number of parameters for 'xor' hash expression"); + return nullptr; + } + if (!CHECKTYPE(what[1], tINT)) { + return nullptr; + } + if (!CHECKTYPE(what[2], tMAP)) { + return nullptr; + } + std::unique_ptr rv(new XorHash(what.lineno, what[1].i)); + for (auto &kv : what[2].map) { + if (CHECKTYPE(kv.key, tINT)) { + rv->what.emplace(kv.key.i, Phv::Ref(gress, stage, kv.value)); + } else { + return nullptr; + } + } + + return rv.release(); + } else if ((what[0] == "crc" || what[0] == "crc_rev" || what[0] == "crc_reverse") && + CHECKTYPE2(what[1], tBIGINT, tINT)) { + Crc *rv = new Crc(what.lineno); + if (what[0] != "crc") rv->reverse = true; + rv->poly = get_bitvec(what[1]); + // Shift and set LSB to 1 to generate polynomial from Koopman number + // provided in assembly + rv->poly <<= 1; + rv->poly[0] = 1; + int i = 2; + + if (what.vec.size > i && (what[i].type == tINT || what[i].type == tBIGINT)) + rv->init = get_bitvec(what[i++]); + if (what.vec.size > i && (what[i].type == tINT || what[i].type == tBIGINT)) + rv->final_xor = get_bitvec(what[i++]); + if (what.vec.size > i && what[i].type == tINT) rv->total_input_bits = what[i++].i; + + if (what.vec.size > i && what[i].type == tMAP) { + for (auto &kv : what[i].map) { + if (CHECKTYPE(kv.key, tINT)) { + rv->what.emplace(kv.key.i, Phv::Ref(gress, stage, kv.value)); + } + } + } else { + for (; i < what.vec.size; i++) { + rv->vec_what.emplace_back(gress, stage, what[i]); + } + } + return rv; + } else if (what[0] == "^") { + Xor *rv = new Xor(what.lineno); + for (int i = 1; i < what.vec.size; i++) + rv->what.push_back(create(gress, stage, what[i])); + return rv; + } else if (what[0] == "&") { + HashExpr *op = nullptr; + bitvec mask; + bool have_mask = false; + for (int i = 1; i < what.vec.size; i++) { + if (what[i].type == tINT || what[i].type == tBIGINT) { + if (have_mask) { + mask &= get_bitvec(what[i]); + } else { + mask = get_bitvec(what[i]); + have_mask = true; + } + } else if (op) { + error(what.lineno, "Invalid mask operation"); + return nullptr; + } else { + op = create(gress, stage, what[i]); + } + } + if (!op) { + error(what.lineno, "Invalid mask operation"); + return nullptr; + } else if (have_mask) { + return new Mask(what.lineno, op, mask); + } else { + return op; + } + } else if (what[0] == "stripe") { + Stripe *rv = new Stripe(what.lineno); + for (int i = 1; i < what.vec.size; i++) + rv->what.push_back(create(gress, stage, what[i])); + return rv; + } else if (what[0] == "slice") { + if (what.vec.size < 3 || what[2].type == tRANGE + ? what.vec.size > 3 || what[2].hi < what[2].lo + : what[2].type != tINT || what.vec.size > 4 || + (what.vec.size == 4 && what[3].type != tINT)) { + error(what.lineno, "Invalid slice operation"); + return nullptr; + } + Slice *rv = new Slice(what.lineno); + rv->what = create(gress, stage, what[1]); + if (what[2].type == tRANGE) { + rv->start = what[2].lo; + rv->_width = what[2].hi - what[2].lo + 1; + } else { + rv->start = what[2].i; + if (what.vec.size > 3) rv->_width = what[3].i; + } + return rv; + } else if (what[0] == "sextend" || what[0] == "sign_extend") { + if (what.vec.size != 2) { + error(what.lineno, "Invalid sign extension"); + return nullptr; + } + return new SExtend(what.lineno, create(gress, stage, what[1])); + } else if (what.vec.size == 2) { + return new PhvRef(gress, stage, what); + } else { + error(what.lineno, "Unsupported hash operation '%s'", what[0].s); + } + } else if (what.type == tSTR) { + return new PhvRef(gress, stage, what); + } else { + error(what.lineno, "Syntax error, expecting hash expression"); + } + return nullptr; +} + +void HashExpr::find_input(Phv::Ref what, std::vector &inputs, InputXbar *ix, + InputXbar::HashTable hash_table) { + bool found = false; + auto vec = ix->find_hash_inputs(*what, hash_table); + for (auto *in : vec) { + int group_bit_position = in->lo + (what->lo - in->what->lo); + ixbar_input_t input; + input.type = ixbar_input_type::tPHV; + input.ixbar_bit_position = group_bit_position + ix->global_bit_position_adjust(hash_table); + input.bit_size = what->size(); + input.u.valid = true; + input.symmetric_info.is_symmetric = false; + inputs.push_back(input); + found = true; + break; + } + if (!found) { + error(ix->lineno, "Cannot find associated field %s[%d:%d] in %s", what->reg.name, what->hi, + what->lo, hash_table.toString().c_str()); + } +} + +void HashExpr::generate_ixbar_inputs_with_gaps(const std::multimap &what, + std::vector &inputs, InputXbar *ix, + InputXbar::HashTable hash_table) { + unsigned previous_range_hi = 0; + for (auto &entry : what) { + if (previous_range_hi != entry.first) { + ixbar_input_t invalid_input = { + ixbar_input_type::tPHV, // type + 0, // ixbar_bit_position + entry.first - previous_range_hi, // bit_size + false // u.valid + }; + inputs.push_back(invalid_input); + } + + auto &ref = entry.second; + find_input(ref, inputs, ix, hash_table); + previous_range_hi = entry.first + ref->size(); + } + if (previous_range_hi != input_size()) { + ixbar_input_t invalid_input = { + ixbar_input_type::tPHV, // type + 0, // ixbar_bit_position + input_size() - previous_range_hi, // bit_size + false // u.valid + }; + inputs.push_back(invalid_input); + } +} + +/** + * Creates a vector with a single entry corresponding to the identity input + */ +void HashExpr::PhvRef::gen_ixbar_inputs(std::vector &inputs, InputXbar *ix, + InputXbar::HashTable hash_table) { + find_input(what, inputs, ix, hash_table); +} + +/** + * Iterates through the list of references to build a corresponding vector for the + * dynamic hash library + */ +void HashExpr::Random::gen_ixbar_inputs(std::vector &inputs, InputXbar *ix, + InputXbar::HashTable hash_table) { + for (auto &ref : what) { + find_input(ref, inputs, ix, hash_table); + } +} + +/** + * Iterates through the crc map, and will generate ixbar_input_t inputs for the holes. + * These are marked as invalid, so that the hash calculation will be correct + */ +void HashExpr::Crc::gen_ixbar_inputs(std::vector &inputs, InputXbar *ix, + InputXbar::HashTable hash_table) { + generate_ixbar_inputs_with_gaps(what, inputs, ix, hash_table); +} + +bool HashExpr::Crc::check_ixbar(InputXbar *ix, InputXbar::HashTable hash_table) { + bool rv = true; + if (!vec_what.empty()) { + int off = 0; + for (auto &ref : vec_what) { + rv &= ::check_ixbar(ref, ix, InputXbar::HashTable()); + if (ref) { + for (auto *in : ix->find_hash_inputs(*ref, hash_table)) { + if (in->lo >= 0) { + what.emplace(off, ref); + break; + } + } + off += ref.size(); + } + } + vec_what.clear(); + } else { + int max = -1; + for (auto &ref : what) { + rv &= ::check_ixbar(ref.second, ix, hash_table); + } + } + return rv; +} + +HashExpr::XorHash::XorHash(int lineno, int bit_width_) : HashExpr(lineno), bit_width(bit_width_) {} + +bool HashExpr::XorHash::check_ixbar(InputXbar *ix, InputXbar::HashTable hash_table) { + bool rv(true); + for (auto &ref : what) { + rv = ::check_ixbar(ref.second, ix, hash_table) && rv; + } + return rv; +} + +int HashExpr::XorHash::width() { return bit_width; } + +int HashExpr::XorHash::input_size() { + if (what.empty()) return 0; + return what.rbegin()->first + what.rbegin()->second->size(); +} + +bool HashExpr::XorHash::operator==(const HashExpr &a_) const { + if (typeid(*this) != typeid(a_)) return false; + auto &a = static_cast(a_); + + if (what.size() != a.what.size()) return false; + if (bit_width != a.bit_width) return false; + + auto iter1(what.begin()); + auto iter2(a.what.begin()); + while (iter1 != what.end()) { + if (*iter1 != *iter2) return false; + ++iter1; + ++iter2; + } + return true; +} + +void HashExpr::XorHash::build_algorithm() { + memset(&hash_algorithm, 0, sizeof(hash_algorithm)); + hash_algorithm.hash_alg = XOR_DYN; + hash_algorithm.extend = false; + hash_algorithm.msb = false; + hash_algorithm.hash_bit_width = bit_width; +} + +void HashExpr::XorHash::gen_ixbar_inputs(std::vector &inputs, InputXbar *ix, + InputXbar::HashTable hash_table) { + generate_ixbar_inputs_with_gaps(what, inputs, ix, hash_table); +} + +void HashExpr::XorHash::get_sources(int, std::vector &rv) const {} + +void HashExpr::Xor::gen_data(bitvec &data, int bit, InputXbar *ix, + InputXbar::HashTable hash_table) { + for (auto *e : what) e->gen_data(data, bit, ix, hash_table); +} + +void HashExpr::Stripe::gen_data(bitvec &data, int bit, InputXbar *ix, + InputXbar::HashTable hash_table) { + while (1) { + int total_size = 0; + for (auto *e : what) { + int sz = e->width(); + if (bit < total_size + sz) { + e->gen_data(data, bit - total_size, ix, hash_table); + return; + } + total_size += sz; + } + if (total_size == 0) { + if (!supress_error_cascade) { + error(lineno, "Can't stripe unsized data"); + supress_error_cascade = true; + } + break; + } + bit %= total_size; + } +} + +void dump(const HashExpr *h) { + if (h) + h->dbprint(std::cout); + else + std::cout << "(null)"; + std::cout << std::endl; +} +void dump(const HashExpr &h) { + h.dbprint(std::cout); + std::cout << std::endl; +} diff --git a/backends/tofino/bf-asm/hashexpr.h b/backends/tofino/bf-asm/hashexpr.h new file mode 100644 index 00000000000..1764d3e6000 --- /dev/null +++ b/backends/tofino/bf-asm/hashexpr.h @@ -0,0 +1,77 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_HASHEXPR_H_ +#define BF_ASM_HASHEXPR_H_ + +#include "dynamic_hash/dynamic_hash.h" +#include "input_xbar.h" +#include "phv.h" + +class HashExpr : public IHasDbPrint { + class PhvRef; + class Random; + class Crc; + class XorHash; + class Xor; + class Mask; + class Stripe; + class Slice; + class SExtend; + + protected: + explicit HashExpr(int l) : lineno(l) {} + + public: + int lineno; + bfn_hash_algorithm_t hash_algorithm = {}; // Zero-init to make Klockwork happy + static HashExpr *create(gress_t, int stage, const value_t &); + virtual void build_algorithm() = 0; + virtual bool check_ixbar(InputXbar *ix, InputXbar::HashTable ht) = 0; + virtual void gen_data(bitvec &data, int bit, InputXbar *ix, InputXbar::HashTable hash_table); + void gen_ixbar_init(ixbar_init_t *ixbar_init, std::vector &inputs, + std::vector &outputs, int logical_hash_bit, + InputXbar *ix, InputXbar::HashTable hash_table); + virtual void gen_ixbar_inputs(std::vector &inputs, InputXbar *ix, + InputXbar::HashTable hash_table) = 0; + virtual void get_sources(int bit, std::vector &) const = 0; + std::vector get_sources(int bit) const { + std::vector rv; + get_sources(bit, rv); + return rv; + } + virtual int width() = 0; + virtual int input_size() = 0; + virtual bool match_phvref(const Phv::Ref &ref) { return false; } + virtual bool operator==(const HashExpr &) const = 0; + void find_input(Phv::Ref what, std::vector &inputs, InputXbar *ix, + InputXbar::HashTable hash_table); + bool operator!=(const HashExpr &a) const { return !operator==(a); } + virtual void dbprint(std::ostream &out) const {} + virtual Phv::Ref *get_ghost_slice() { return nullptr; } + virtual ~HashExpr() {} + + private: + void generate_ixbar_inputs_with_gaps(const std::multimap &what, + std::vector &inputs, InputXbar *ix, + InputXbar::HashTable hash_table); +}; + +extern void dump(const HashExpr *); +extern void dump(const HashExpr &); + +#endif /* BF_ASM_HASHEXPR_H_ */ diff --git a/backends/tofino/bf-asm/idletime.cpp b/backends/tofino/bf-asm/idletime.cpp new file mode 100644 index 00000000000..55e0fff0f86 --- /dev/null +++ b/backends/tofino/bf-asm/idletime.cpp @@ -0,0 +1,217 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "misc.h" +#include "stage.h" +#include "tables.h" + +void IdletimeTable::setup(VECTOR(pair_t) & data) { + setup_layout(layout, data); + for (auto &kv : MapIterChecked(data, true)) { + if (kv.key == "precision") { + if (CHECKTYPE(kv.value, tINT)) { + precision = kv.value.i; + if (precision != 1 && precision != 2 && precision != 3 && precision != 6) + error(kv.value.lineno, "Invalid idletime precision %d", precision); + } + } else if (kv.key == "sweep_interval") { + if (CHECKTYPE(kv.value, tINT)) sweep_interval = kv.value.i; + } else if (kv.key == "notification") { + if (kv.value == "disable") + disable_notification = true; + else if (kv.value == "two_way") + two_way_notification = true; + else if (kv.value != "enable") + error(kv.value.lineno, "Unknown notification style '%s'", value_desc(kv.value)); + } else if (kv.key == "per_flow_enable") { + per_flow_enable = get_bool(kv.value); + } else if (kv.key == "context_json") { + setup_context_json(kv.value); + } else if (kv.key == "row" || kv.key == "column" || kv.key == "bus") { + /* already done in setup_layout */ + } else { + warning(kv.key.lineno, "ignoring unknown item %s in table %s", value_desc(kv.key), + name()); + } + } + alloc_rams(false, stage->mapram_use); + for (auto &r : layout) { + if (!r.bus.count(Layout::IDLE_BUS)) continue; + int &idle_bus = r.bus.at(Layout::IDLE_BUS); + if (idle_bus >= IDLETIME_BUSSES) { + error(r.lineno, "bus %d invalid", idle_bus); + continue; + } + if (r.row >= 4 && idle_bus < 10) + idle_bus += 10; + else if (r.row < 4 && idle_bus >= 10) + error(r.lineno, "idletime bus %d not accessable on row %d", idle_bus, r.row); + if (Table *old = stage->idletime_bus_use[idle_bus]) { + if (old != this) + error(r.lineno, + "Table %s trying to use idletime bus %d which is already in " + "use by table %s", + name(), idle_bus, old->name()); + } else { + stage->idletime_bus_use[idle_bus] = this; + } + } +} + +void IdletimeTable::pass1() { + LOG1("### Idletime table " << name() << " pass1 " << loc()); + alloc_vpns(); +} + +void IdletimeTable::pass2() { LOG1("### Idletime table " << name() << " pass2 " << loc()); } + +void IdletimeTable::pass3() { LOG1("### Idletime table " << name() << " pass3 " << loc()); } + +// This is the same as AttachedTable::json_memunit, but IdletimeTable is not a derived class +// of AttachedTable, so we duplicate it +int IdletimeTable::json_memunit(const MemUnit &r) const { + if (r.stage >= 0) { + return r.stage * Target::SRAM_STRIDE_STAGE() + r.row * Target::SRAM_STRIDE_ROW() + + r.col * Target::SRAM_STRIDE_COLUMN(); + } else if (r.row >= 0) { + // per-stage logical sram + return r.row * Target::SRAM_LOGICAL_UNITS_PER_ROW() + r.col; + } else { + // lamb + return r.col; + } +} + +static int precision_bits[] = {0, 0, 1, 2, 0, 0, 3}; + +template +void IdletimeTable::write_merge_regs_vt(REGS ®s, int type, int bus) { + auto &merge = regs.rams.match.merge; + merge.mau_payload_shifter_enable[type][bus].idletime_adr_payload_shifter_en = 1; + merge.mau_idletime_adr_mask[type][bus] = + (~1U << precision_bits[precision]) & ((1U << IDLETIME_ADDRESS_BITS) - 1); + merge.mau_idletime_adr_default[type][bus] = + (1U << IDLETIME_ADDRESS_PER_FLOW_ENABLE_START_BIT) | ((1 << precision_bits[precision]) - 1); +} + +FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void IdletimeTable::write_merge_regs, + (mau_regs & regs, int type, int bus), + { write_merge_regs_vt(regs, type, bus); }) + +int IdletimeTable::precision_shift() const { return precision_bits[precision] + 1; } +int IdletimeTable::direct_shiftcount() const { return 67 - precision_bits[precision]; } + +template +void IdletimeTable::write_regs_vt(REGS ®s) { + LOG1("### Idletime table " << name() << " write_regs " << loc()); + auto &map_alu = regs.rams.map_alu; + auto &adrdist = regs.rams.match.adrdist; + int minvpn = 1000000, maxvpn = -1; + for (Layout &logical_row : layout) + for (auto v : logical_row.vpns) { + if (v < minvpn) minvpn = v; + if (v > maxvpn) maxvpn = v; + } + // regs.cfg_regs.mau_cfg_lt_has_idle |= 1 << logical_id; + for (Layout &row : layout) { + int idle_bus = row.bus.at(Layout::IDLE_BUS); + auto &map_alu_row = map_alu.row[row.row]; + auto &adrmux = map_alu_row.adrmux; + auto vpn = row.vpns.begin(); + for (auto &memunit : row.memunits) { + int col = memunit.col; + BUG_CHECK(memunit.stage == INT_MIN && memunit.row == row.row, "bogus %s in row %d", + memunit.desc(), row.row); + setup_muxctl(map_alu_row.vh_xbars.adr_dist_idletime_adr_xbar_ctl[col], idle_bus % 10); + auto &mapram_cfg = adrmux.mapram_config[col]; + // auto &mapram_ctl = adrmux.mapram_ctl[col]; + if (disable_notification) mapram_cfg.idletime_disable_notification = 1; + if (two_way_notification) mapram_cfg.two_way_idletime_notification = 1; + if (per_flow_enable) mapram_cfg.per_flow_idletime = 1; + mapram_cfg.idletime_bitwidth = precision_bits[precision]; + mapram_cfg.mapram_type = MapRam::IDLETIME; + mapram_cfg.mapram_logical_table = logical_id; + mapram_cfg.mapram_vpn_members = 0; // FIXME + mapram_cfg.mapram_vpn = *vpn++; + if (gress == INGRESS) + mapram_cfg.mapram_ingress = 1; + else + mapram_cfg.mapram_egress = 1; + mapram_cfg.mapram_enable = 1; + if ((precision == 1) || (precision == 2)) { + mapram_cfg.mapram_parity_generate = 1; + mapram_cfg.mapram_parity_check = 1; + } else { + if ((precision != 3) && (precision != 6)) + error(lineno, "Unknown idletime precision = %d", precision); + mapram_cfg.mapram_ecc_generate = 1; + mapram_cfg.mapram_ecc_check = 1; + } + auto &adrmux_ctl = adrmux.ram_address_mux_ctl[1][col]; + adrmux_ctl.map_ram_wadr_mux_select = MapRam::Mux::IDLETIME; + adrmux_ctl.map_ram_wadr_mux_enable = 1; + adrmux_ctl.map_ram_radr_mux_select_smoflo = 1; + adrmux_ctl.ram_ofo_stats_mux_select_statsmeter = 1; + adrmux_ctl.ram_stats_meter_adr_mux_select_idlet = 1; + setup_muxctl(adrmux.idletime_logical_to_physical_sweep_grant_ctl[col], logical_id); + setup_muxctl(adrmux.idletime_physical_to_logical_req_inc_ctl[col], logical_id); + unsigned clear_val = ~(~0U << precision); + if (per_flow_enable || precision == 1) clear_val &= ~1U; + for (unsigned i = 0; i < 8U / precision; i++) + adrmux.idletime_cfg_rd_clear_val[col].set_subfield(clear_val, i * precision, + precision); + if (gress) + regs.cfg_regs.mau_cfg_mram_thread[col / 3U] |= 1U << (col % 3U * 8U + row.row); + } + adrdist.adr_dist_idletime_adr_oxbar_ctl[idle_bus / 4].set_subfield(logical_id | 0x10, + 5 * (idle_bus % 4), 5); + } + // don't enable initially -- runtime will enable + // adrdist.idletime_sweep_ctl[logical_id].idletime_en = 1; + adrdist.idletime_sweep_ctl[logical_id].idletime_sweep_offset = minvpn; + adrdist.idletime_sweep_ctl[logical_id].idletime_sweep_size = layout_size() - 1; + adrdist.idletime_sweep_ctl[logical_id].idletime_sweep_remove_hole_pos = 0; // TODO + adrdist.idletime_sweep_ctl[logical_id].idletime_sweep_remove_hole_en = 0; // TODO + adrdist.idletime_sweep_ctl[logical_id].idletime_sweep_interval = sweep_interval; + auto &idle_dump_ctl = regs.cfg_regs.idle_dump_ctl[logical_id]; + idle_dump_ctl.idletime_dump_offset = minvpn; + idle_dump_ctl.idletime_dump_size = maxvpn; + idle_dump_ctl.idletime_dump_remove_hole_pos = 0; // TODO + idle_dump_ctl.idletime_dump_remove_hole_en = 0; // TODO + adrdist.movereg_idle_ctl[logical_id].movereg_idle_ctl_size = precision_bits[precision]; + adrdist.movereg_idle_ctl[logical_id].movereg_idle_ctl_direct = 1; + adrdist.movereg_ad_direct[MoveReg::IDLE] |= 1 << logical_id; + adrdist.idle_bubble_req[timing_thread(gress)].bubble_req_1x_class_en |= 1 << logical_id; +} +FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void IdletimeTable::write_regs, (mau_regs & regs), + { write_regs_vt(regs); }) + +void IdletimeTable::gen_stage_tbl_cfg(json::map &out) const { + unsigned number_entries = layout_size() * (8U / precision) * SRAM_DEPTH; + json::map &tbl = out["idletime_stage_table"] = json::map(); + tbl["stage_number"] = stage->stageno; + tbl["size"] = number_entries; + tbl["stage_table_type"] = "idletime"; + tbl["precision"] = precision; + tbl["disable_notification"] = disable_notification; + tbl["two_way_notification"] = two_way_notification; + // ?? + tbl["logical_table_id"] = match_table->logical_id; + tbl["enable_pfe"] = per_flow_enable; + add_pack_format(tbl, 11, 1, 8U / precision); + tbl["memory_resource_allocation"] = gen_memory_resource_allocation_tbl_cfg("map_ram", layout); +} diff --git a/backends/tofino/bf-asm/input_xbar.cpp b/backends/tofino/bf-asm/input_xbar.cpp new file mode 100644 index 00000000000..28696802be5 --- /dev/null +++ b/backends/tofino/bf-asm/input_xbar.cpp @@ -0,0 +1,1139 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "input_xbar.h" + +#include +#include + +#include + +#include "hashexpr.h" +#include "log.h" +#include "misc.h" +#include "power_ctl.h" +#include "range.h" +#include "stage.h" +#include "tables.h" + +// template specialization declarations +#include "jbay/input_xbar.h" +#include "tofino/input_xbar.h" + +void HashCol::dbprint(std::ostream &out) const { + out << "HashCol: " << " lineno: " << lineno << " bit: " << bit << " data: " << data + << " valid: " << valid; + if (fn) out << " fn: " << *fn << std::endl; +} + +DynamicIXbar::DynamicIXbar(const Table *tbl, const pair_t &data) { + if (CHECKTYPE(data.key, tINT)) { + bit = data.key.i; + if (bit < 0 || bit >= Target::DYNAMIC_CONFIG_INPUT_BITS()) + error(data.key.lineno, "Invalid dynamic config bit %d", bit); + } + if (CHECKTYPE2(data.value, tMAP, tMATCH)) { + if (data.value.type == tMAP) { + for (auto &kv : data.value.map) + if (CHECKTYPE(kv.value, tMATCH)) + match_phv.emplace_back(Phv::Ref(tbl->gress, tbl->stage->stageno, data.key), + data.value.m); + } else { + match = data.value.m; + } + } +} + +int InputXbar::group_max_index(Group::type_t t) const { + switch (t) { + case Group::EXACT: + return EXACT_XBAR_GROUPS; + case Group::TERNARY: + return TCAM_XBAR_GROUPS; + case Group::BYTE: + return BYTE_XBAR_GROUPS; + default: + BUG("invalid group type for %s: %s", Target::name(), group_type(t)); + } + return 0; +} + +InputXbar::Group InputXbar::group_name(bool tern, const value_t &key) const { + if (CHECKTYPE(key, tCMD)) { + int index = 1; + if (key[0] != "group" && (key[1] == "group" || key[1] == "table")) ++index; + if (PCHECKTYPE(key.vec.size == index + 1, key[index], tINT)) { + index = key[index].i; + if (key[0] == "group") return Group(tern ? Group::TERNARY : Group::EXACT, index); + if (key[0] == "exact" && key[1] == "group") return Group(Group::EXACT, index); + if (key[0] == "ternary" && key[1] == "group") return Group(Group::TERNARY, index); + if (key[0] == "byte" && key[1] == "group") return Group(Group::BYTE, index); + } + } + return Group(Group::INVALID, 0); +} + +int InputXbar::group_size(Group::type_t t) const { + switch (t) { + case Group::EXACT: + return EXACT_XBAR_GROUP_SIZE; + case Group::TERNARY: + return TCAM_XBAR_GROUP_SIZE; + case Group::BYTE: + return BYTE_XBAR_GROUP_SIZE; + default: + BUG("invalid group type for %s: %s", Target::name(), group_type(t)); + } + return 0; +} + +const char *InputXbar::group_type(Group::type_t t) const { + switch (t) { + case Group::EXACT: + return "exact"; + case Group::TERNARY: + return "ternary"; + case Group::BYTE: + return "byte"; + case Group::GATEWAY: + return "gateway"; + case Group::XCMP: + return "xcmp"; + default: + return ""; + } +} + +void InputXbar::parse_group(Table *t, Group gr, const value_t &value) { + BUG_CHECK(gr.index >= 0, "invalid group"); + auto &group = groups[gr]; + if (value.type == tVEC) { + for (auto ® : value.vec) group.emplace_back(Phv::Ref(t->gress, t->stage->stageno, reg)); + } else if (value.type == tMAP) { + for (auto ® : value.map) { + if (!CHECKTYPE2(reg.key, tINT, tRANGE)) continue; + int lo = -1, hi = -1; + if (reg.key.type == tINT) { + lo = reg.key.i; + } else { + lo = reg.key.lo; + hi = reg.key.hi; + } + if (lo < 0 || lo >= group_size(gr.type)) { + error(reg.key.lineno, "Invalid offset for %s group", group_type(gr.type)); + } else if (gr.type == Group::TERNARY && lo >= 40) { + if (hi >= lo) hi -= 40; + groups[Group(Group::BYTE, gr.index / 2)].emplace_back( + Phv::Ref(t->gress, t->stage->stageno, reg.value), lo - 40, hi); + } else { + group.emplace_back(Phv::Ref(t->gress, t->stage->stageno, reg.value), lo, hi); + } + } + } else { + group.emplace_back(Phv::Ref(t->gress, t->stage->stageno, value)); + } +} + +void InputXbar::parse_hash_group(HashGrp &hash_group, const value_t &value) { + if (value.type == tINT && (unsigned)value.i < Target::EXACT_HASH_TABLES()) { + hash_group.tables |= 1U << value.i; + return; + } + if (!CHECKTYPE2(value, tVEC, tMAP)) return; + const VECTOR(value_t) *tbl = 0; + if (value.type == tMAP) { + for (auto &el : MapIterChecked(value.map)) { + if (el.key == "seed") { + if (!CHECKTYPE2(el.value, tINT, tBIGINT)) continue; + if (el.value.type == tBIGINT) { + int shift = 0; + for (int i = 0; i < el.value.bigi.size; ++i) { + if (shift >= 64) { + error(el.key.lineno, "Invalid seed %s too large", + value_desc(&el.value)); + break; + } + hash_group.seed |= el.value.bigi.data[i] << shift; + shift += CHAR_BIT * sizeof(el.value.bigi.data[i]); + } + } else { + hash_group.seed |= el.value.i & 0xFFFFFFFF; + } + } else if (el.key == "table") { + if (el.value.type == tINT) { + if (el.value.i < 0 || el.value.i >= Target::EXACT_HASH_TABLES()) + error(el.value.lineno, "invalid hash group descriptor"); + else + hash_group.tables |= 1U << el.value.i; + } else if (CHECKTYPE(el.value, tVEC)) { + tbl = &el.value.vec; + } + } else if (el.key == "seed_parity") { + if (el.value.type == tSTR && el.value == "true") hash_group.seed_parity = true; + } else { + error(el.key.lineno, "invalid hash group descriptor"); + } + } + } else { + tbl = &value.vec; + } + if (tbl) { + for (auto &v : *tbl) { + if (!CHECKTYPE(v, tINT)) continue; + if (v.i < 0 || v.i >= Target::EXACT_HASH_TABLES()) { + error(v.lineno, "invalid hash group descriptor"); + } else { + hash_group.tables |= 1U << v.i; + } + } + } +} + +void InputXbar::parse_hash_table(Table *t, HashTable ht, const value_t &value) { + if (!CHECKTYPE(value, tMAP)) return; + for (auto &c : value.map) { + if (c.key.type == tINT) { + setup_hash(hash_tables[ht], ht, t->gress, t->stage->stageno, c.value, c.key.lineno, + c.key.i, c.key.i); + } else if (c.key.type == tRANGE) { + setup_hash(hash_tables[ht], ht, t->gress, t->stage->stageno, c.value, c.key.lineno, + c.key.lo, c.key.hi); + } else if (CHECKTYPEM(c.key, tCMD, "hash column decriptor")) { + if (c.key.vec.size != 2 || c.key[0] != "valid" || c.key[1].type != tINT || + options.target != TOFINO) { + error(c.key.lineno, "Invalid hash column descriptor"); + continue; + } + int col = c.key[1].i; + if (col < 0 || col >= 52) { + error(c.key.lineno, "Hash column out of range"); + continue; + } + if (!CHECKTYPE(c.value, tINT)) continue; + if (hash_tables[ht][col].valid) + error(c.key.lineno, "Hash table %d column %d valid duplicated", ht.index, col); + else if (c.value.i >= 0x10000) + error(c.value.lineno, "Hash valid value out of range"); + else + hash_tables[ht][col].valid = c.value.i; + } + } +} + +void InputXbar::setup_hash(std::map &hash_table, HashTable ht, gress_t gress, + int stage, value_t &what, int lineno, int lo, int hi) { + if (lo < 0 || lo >= hash_num_columns(ht) || hi < 0 || hi >= hash_num_columns(ht)) { + error(lineno, "Hash column out of range"); + return; + } + if (lo == hi) { + if (what.type == tINT || what.type == tBIGINT) { + hash_table[lo].data = get_bitvec(what, 64, "Hash column value out of range"); + return; + } else if ((what.type == tSTR) && (what == "parity")) { + options.disable_gfm_parity = false; + hash_table_parity[ht] = lo; + return; + } + } else if (what.type == tINT && what.i == 0) { + for (int i = lo; i <= hi; ++i) { + hash_table[i].data.setraw(what.i); + } + return; + } + HashExpr *fn = HashExpr::create(gress, stage, what); // TODO Set the crcSize. + if (!fn) return; + fn->build_algorithm(); + int width = fn->width(); + if (width && width != abs(hi - lo) + 1) + error(what.lineno, "hash expression width mismatch (%d != %d)", width, abs(hi - lo) + 1); + int bit = 0; + int errlo = -1; + bool fn_assigned = false; + for (int col : Range(lo, hi)) { + if (hash_table[col].data || hash_table[col].fn) { + if (errlo < 0) errlo = col; + } else { + if (errlo >= 0) { + if (errlo == col - 1) { + error(lineno, "%s column %d duplicated", ht.toString().c_str(), errlo); + } else { + error(lineno, "%s column %d..%d duplicated", ht.toString().c_str(), errlo, + col - 1); + } + errlo = -1; + } + hash_table[col].lineno = what.lineno; + hash_table[col].fn = fn; + hash_table[col].bit = bit++; + fn_assigned = true; + } + } + + if (!fn_assigned) delete fn; + + if (errlo >= 0) { + error(lineno, "%s column %d..%d duplicated", ht.toString().c_str(), errlo, hi); + } +} + +void InputXbar::input(Table *t, bool tern, const VECTOR(pair_t) & data) { + for (auto &kv : data) { + if ((kv.key.type == tSTR) && (kv.key == "random_seed")) { + random_seed = kv.value.i; + continue; + } + if (kv.key.type == tCMD && kv.key.vec.size == 2 && kv.key[1] == "unit" && + parse_unit(t, kv)) { + continue; + } + if (auto grp = group_name(tern, kv.key)) { + if (grp.index >= group_max_index(grp.type)) { + error(kv.key.lineno, "invalid group descriptor"); + continue; + } + parse_group(t, grp, kv.value); + } else if (kv.key.type == tCMD && kv.key[0] == "hash") { + if (!CHECKTYPE(kv.key.vec.back(), tINT)) continue; + int index = kv.key.vec.back().i; + if (kv.key[1] == "group") { + if (index >= Target::EXACT_HASH_GROUPS()) { + error(kv.key.lineno, "invalid hash group descriptor"); + continue; + } + if (hash_groups[index].lineno >= 0) { + // FIXME -- should be an error? but the compiler generates it this way + warning(kv.key.lineno, "duplicate hash group %d, will merge with", index); + warning(hash_groups[index].lineno, "previous definition here"); + } + hash_groups[index].lineno = kv.key.lineno; + parse_hash_group(hash_groups[index], kv.value); + } else if (index >= Target::EXACT_HASH_TABLES()) { + error(kv.key.lineno, "invalid hash descriptor"); + } else { + parse_hash_table(t, HashTable(HashTable::EXACT, index), kv.value); + } + } else if (kv.key.type == tCMD && kv.key[1] == "hash" && parse_hash(t, kv)) { + continue; + } else { + error(kv.key.lineno, "expecting a group or hash descriptor"); + } + } +} + +std::unique_ptr InputXbar::create(Table *table, const value_t *key) { + if (key && key->type != tSTR) + error(key->lineno, "%s does not support dynamic key mux", Target::name()); + return std::unique_ptr(new InputXbar(table, key ? key->lineno : -1)); +} + +std::unique_ptr InputXbar::create(Table *table, bool tern, const value_t &key, + const VECTOR(pair_t) & data) { + auto rv = create(table, &key); + rv->input(table, tern, data); + return rv; +} + +unsigned InputXbar::tcam_width() { + unsigned words = 0, bytes = 0; + for (auto &group : groups) { + if (group.first.type != Group::TERNARY) { + if (group.first.type == Group::BYTE) ++bytes; + continue; + } + unsigned in_word = 0, in_byte = 0; + for (auto &input : group.second) { + if (input.lo < 40) in_word = 1; + if (input.lo >= 40 || input.hi >= 40) in_byte = 1; + } + words += in_word; + bytes += in_byte; + } + if (bytes * 2 > words) error(lineno, "Too many byte groups in tcam input xbar"); + return words; +} + +int InputXbar::tcam_byte_group(int idx) { + for (auto &group : groups) { + if (group.first.type != Group::TERNARY) continue; + for (auto &input : group.second) + if (input.lo >= 40 || input.hi >= 40) { + if (--idx < 0) return group.first.index / 2; + break; + } + } + return -1; +} + +int InputXbar::tcam_word_group(int idx) { + for (auto &group : groups) { + if (group.first.type != Group::TERNARY) continue; + for (auto &input : group.second) + if (input.lo < 40) { + if (--idx < 0) return group.first.index; + break; + } + } + return -1; +} + +const std::map &InputXbar::get_hash_table(HashTable id) { + for (auto &ht : hash_tables) + if (ht.first == id) return ht.second; + warning(lineno, "%s does not exist in table %s", id.toString().c_str(), table->name()); + static const std::map empty_hash_table = {}; + return empty_hash_table; +} + +bool InputXbar::conflict(const std::vector &a, const std::vector &b) { + for (auto &i1 : a) { + if (i1.lo < 0) continue; + for (auto &i2 : b) { + if (i2.lo < 0) continue; + if (i2.lo > i1.hi || i1.lo > i2.hi) continue; + if (i1.what->reg != i2.what->reg) return true; + if (i1.lo - i1.what->lo != i2.lo - i2.what->lo) return true; + } + } + return false; +} + +bool InputXbar::conflict(const std::map &a, const std::map &b, + int *col) { + for (auto &acol : a) { + if (auto bcol = ::getref(b, acol.first)) { + if (acol.second.data != bcol->data || acol.second.valid != bcol->valid) { + if (col) *col = acol.first; + return true; + } + } + } + return false; +} + +bool InputXbar::conflict(const HashGrp &a, const HashGrp &b) { + if (a.tables != b.tables) return true; + if (a.seed && b.seed && a.seed != b.seed) return true; + return false; +} + +uint64_t InputXbar::hash_columns_used(HashTable hash) { + uint64_t rv = 0; + if (hash_tables.count(hash)) + for (auto &col : hash_tables[hash]) rv |= UINT64_C(1) << col.first; + return rv; +} + +/* FIXME -- this is questionable, but the compiler produces hash groups that conflict + * FIXME -- so we try to tag ones that may be ok as merely warnings */ +bool InputXbar::can_merge(HashGrp &a, HashGrp &b) { + unsigned both = a.tables & b.tables; + uint64_t both_cols = 0, a_cols = 0, b_cols = 0; + for (unsigned i = 0; i < 16; i++) { + unsigned mask = 1U << i; + if (!((a.tables | b.tables) & mask)) continue; + for (InputXbar *other : table->stage->hash_table_use[i]) { + if (both & mask) both_cols |= other->hash_columns_used(i); + if (a.tables & mask) a_cols |= other->hash_columns_used(i); + if (b.tables & mask) b_cols |= other->hash_columns_used(i); + for (auto htp : hash_table_parity) { + if (other->hash_table_parity.count(htp.first) && + other->hash_table_parity.at(htp.first) != htp.second) + return false; + } + } + } + a_cols &= ~both_cols; + b_cols &= ~both_cols; + if (a_cols & b_cols) return false; + if ((a_cols & b.seed & ~a.seed) || (b_cols & a.seed & ~b.seed)) return false; + if (a.tables && b.tables) { + a.tables |= b.tables; + b.tables |= a.tables; + } + if (a.seed && b.seed) { + a.seed |= b.seed; + b.seed |= a.seed; + } + return true; +} + +static int tcam_swizzle_offset[4][4] = { + {0, +1, -2, -1}, + {+3, 0, +1, -2}, + {+2, -1, 0, -3}, + {+1, +2, -1, 0}, +}; + +// FIXME -- when swizlling 16 bit PHVs, there are 2 places we could copy from, but +// FIXME -- we only consider the closest/easiest +static int tcam_swizzle_16[2][2]{{0, -1}, {+1, 0}}; + +int InputXbar::tcam_input_use(int out_byte, int phv_byte, int phv_size) { + int rv = out_byte; + BUG_CHECK(phv_byte >= 0 && phv_byte < phv_size / 8); + switch (phv_size) { + case 8: + break; + case 32: + rv += tcam_swizzle_offset[out_byte & 3][phv_byte]; + break; + case 16: + rv += tcam_swizzle_16[out_byte & 1][phv_byte]; + break; + default: + BUG(); + } + return rv; +} + +void InputXbar::tcam_update_use(TcamUseCache &use) { + if (use.ixbars_added.count(this)) return; + use.ixbars_added.insert(this); + for (auto &group : groups) { + if (group.first.type == Group::EXACT) continue; + for (auto &input : group.second) { + if (input.lo < 0) continue; + int group_base = (group.first.index * 11 + 1) / 2U; + int half_byte = 5 + 11 * (group.first.index / 2U); + if (group.first.type == Group::BYTE) { + group_base = 5 + 11 * group.first.index; + half_byte = -1; + } + int group_byte = input.lo / 8; + for (int phv_byte = input.what->lo / 8; phv_byte <= input.what->hi / 8; + phv_byte++, group_byte++) { + BUG_CHECK(group_byte <= 5); + int out_byte = group_byte == 5 ? half_byte : group_base + group_byte; + int in_byte = tcam_input_use(out_byte, phv_byte, input.what->reg.size); + use.tcam_use.emplace(in_byte, std::pair(input, phv_byte)); + } + } + } +} + +void InputXbar::check_input(InputXbar::Group group, Input &input, TcamUseCache &use) { + if (group.type == Group::EXACT) { + if (input.lo % input.what->reg.size != input.what->lo) + error(input.what.lineno, "%s misaligned on input_xbar", input.what.name()); + return; + } + unsigned bit_align_mask = input.lo >= 40 ? 3 : 7; + unsigned byte_align_mask = (input.what->reg.size - 1) >> 3; + int group_base = (group.index * 11 + 1) / 2U; + int half_byte = 5 + 11 * (group.index / 2U); + if (group.type == Group::BYTE) { + bit_align_mask = 3; + group_base = 5 + 11 * group.index; + half_byte = -1; + } + int group_byte = input.lo / 8; + if ((input.lo ^ input.what->lo) & bit_align_mask) { + error(input.what.lineno, "%s misaligned on input_xbar", input.what.name()); + return; + } + for (int phv_byte = input.what->lo / 8; phv_byte <= input.what->hi / 8; + phv_byte++, group_byte++) { + BUG_CHECK(group_byte <= 5); + int out_byte = group_byte == 5 ? half_byte : group_base + group_byte; + int in_byte = tcam_input_use(out_byte, phv_byte, input.what->reg.size); + if (in_byte < 0 || in_byte >= TCAM_XBAR_INPUT_BYTES) { + error(input.what.lineno, "%s misaligned on input_xbar", input.what.name()); + break; + } + auto *tbl = table->stage->tcam_ixbar_input[in_byte]; + if (tbl) { + BUG_CHECK(tbl->input_xbar.size() == 1, "%s does not have one input xbar", tbl->name()); + tbl->input_xbar[0]->tcam_update_use(use); + } + if (use.tcam_use.count(in_byte)) { + if (use.tcam_use.at(in_byte).first.what->reg != input.what->reg || + use.tcam_use.at(in_byte).second != phv_byte) { + error(input.what.lineno, "Use of tcam ixbar for %s", input.what.name()); + error(use.tcam_use.at(in_byte).first.what.lineno, "...conflicts with %s", + use.tcam_use.at(in_byte).first.what.name()); + break; + } + } else { + use.tcam_use.emplace(in_byte, std::pair(input, phv_byte)); + table->stage->tcam_ixbar_input[in_byte] = tbl; + } + } +} + +bool InputXbar::copy_existing_hash(HashTable ht, std::pair &col) { + for (InputXbar *other : table->stage->hash_table_use[ht.index]) { + if (other == this) continue; + if (other->hash_tables.count(ht)) { + auto &o = other->hash_tables.at(ht); + if (o.count(col.first)) { + auto ocol = o.at(col.first); + if (ocol.fn && *ocol.fn == *col.second.fn) { + col.second.data = ocol.data; + return true; + } + } + } + } + return false; +} + +void InputXbar::gen_hash_column(std::pair &col, + std::pair> &hash) { + col.second.fn->gen_data(col.second.data, col.second.bit, this, hash.first); +} + +void InputXbar::pass1() { + TcamUseCache tcam_use; + tcam_use.ixbars_added.insert(this); + if (random_seed >= 0) srandom(random_seed); + for (auto &group : groups) { + for (auto &input : group.second) { + if (!input.what.check()) continue; + if (input.what->reg.ixbar_id() < 0) + error(input.what.lineno, "%s not accessable in input xbar", input.what->reg.name); + table->stage->match_use[table->gress][input.what->reg.uid] = 1; + if (input.lo < 0 && group.first.type == Group::BYTE) input.lo = input.what->lo % 8U; + if (input.lo >= 0) { + if (input.hi >= 0) { + if (input.size() != input.what->size()) + error(input.what.lineno, "Input xbar size doesn't match register size"); + } else { + input.hi = input.lo + input.what->size() - 1; + } + if (input.lo >= group_size(group.first.type)) + error(input.what.lineno, "placing %s off the top of the input xbar", + input.what.name()); + } + check_input(group.first, input, tcam_use); + } + auto &use = table->stage->ixbar_use; + for (InputXbar *other : use[group.first]) { + if (other->groups.count(group.first) && + conflict(other->groups.at(group.first), group.second)) { + error(lineno, "Input xbar group %d conflict in stage %d", group.first.index, + table->stage->stageno); + warning(other->lineno, "conflicting group definition here"); + } + } + use[group.first].push_back(this); + } + for (auto &hash : hash_tables) { + bool ok = true; + HashExpr *prev = 0; + for (auto &col : hash.second) { + if (col.second.fn && col.second.fn != prev) + ok = (prev = col.second.fn)->check_ixbar(this, hash.first); + if (ok && col.second.fn && !copy_existing_hash(hash.first, col)) { + gen_hash_column(col, hash); + } + } + bool add_to_use = true; + for (InputXbar *other : table->stage->hash_table_use[hash.first.uid()]) { + if (other == this) { + add_to_use = false; + continue; + } + int column; + if (other->hash_tables.count(hash.first) && + conflict(other->hash_tables[hash.first], hash.second, &column)) { + error(hash.second.at(column).lineno, "%s column %d conflict in stage %d", + hash.first.toString().c_str(), column, table->stage->stageno); + error(other->hash_tables[hash.first].at(column).lineno, + "conflicting hash definition here"); + } + } + if (add_to_use) table->stage->hash_table_use[hash.first.uid()].push_back(this); + } + for (auto &group : hash_groups) { + bool add_to_use = true; + for (InputXbar *other : table->stage->hash_group_use[group.first]) { + if (other == this) { + add_to_use = false; + break; + } + if (other->hash_groups.count(group.first) && + conflict(other->hash_groups[group.first], group.second)) { + if (can_merge(other->hash_groups[group.first], group.second)) + warning(group.second.lineno, + "Input xbar hash group %d mergeable conflict " + "in stage %d", + group.first, table->stage->stageno); + else + error(group.second.lineno, "Input xbar hash group %d conflict in stage %d", + group.first, table->stage->stageno); + warning(other->hash_groups[group.first].lineno, + "conflicting hash group definition here"); + } + } + if (add_to_use) table->stage->hash_group_use[group.first].push_back(this); + } +} + +void InputXbar::add_use(unsigned &byte_use, std::vector &inputs) { + for (auto &i : inputs) { + if (i.lo < 0) continue; + for (int byte = i.lo / 8; byte <= i.hi / 8; byte++) byte_use |= 1 << byte; + ; + } +} + +const InputXbar::Input *InputXbar::GroupSet::find(Phv::Slice sl) const { + for (InputXbar *i : use) + if (auto rv = i->find(sl, group)) return rv; + return 0; +} + +std::vector InputXbar::GroupSet::find_all(Phv::Slice sl) const { + std::vector rv; + for (const InputXbar *i : use) { + auto vec = i->find_all(sl, group); + rv.insert(rv.end(), vec.begin(), vec.end()); + } + return rv; +} + +void InputXbar::GroupSet::dbprint(std::ostream &out) const { + std::map byte_use; + for (const InputXbar *ixbar : use) { + if (ixbar->groups.count(group)) { + for (auto &i : ixbar->groups.at(group)) { + if (i.lo < 0) continue; + for (int byte = i.lo / 8; byte <= i.hi / 8; byte++) byte_use[byte] = &i; + } + } + } + const InputXbar::Input *prev = 0; + for (auto &in : byte_use) { + if (prev == in.second) continue; + if (prev) out << ", "; + prev = in.second; + out << prev->what << ':' << prev->lo << ".." << prev->hi; + } +} + +void InputXbar::pass2() { + auto &use = table->stage->ixbar_use; + for (auto &group : groups) { + unsigned bytes_in_use = 0; + for (auto &input : group.second) { + if (input.lo >= 0) continue; + if (auto *at = GroupSet(use, group.first).find(*input.what)) { + input.lo = at->lo; + input.hi = at->hi; + LOG1(input.what << " found in bytes " << at->lo / 8 << ".." << at->hi / 8 << " of " + << group.first << " in stage " << table->stage->stageno); + continue; + } + if (bytes_in_use == 0) + for (InputXbar *other : table->stage->ixbar_use[group.first]) + if (other->groups.count(group.first)) + add_use(bytes_in_use, other->groups.at(group.first)); + int need = input.what->hi / 8U - input.what->lo / 8U + 1; + unsigned mask = (1U << need) - 1; + int max = (group_size(group.first.type) + 7) / 8 - need; + for (int i = 0; i <= max; i++, mask <<= 1) + if (!(bytes_in_use & mask)) { + input.lo = i * 8 + input.what->lo % 8U; + input.hi = (i + need - 1) * 8 + input.what->hi % 8U; + bytes_in_use |= mask; + LOG1("Putting " << input.what << " in bytes " << i << ".." << i + need - 1 + << " of " << group.first << " in stage " + << table->stage->stageno); + break; + } + if (input.lo < 0) { + error(input.what.lineno, "No space in input xbar %s group %d for %s", + group_type(group.first.type), group.first.index, input.what.name()); + LOG1("Failed to put " << input.what << " into " << group.first << " in stage " + << table->stage->stageno); + LOG1(" inuse: " << GroupSet(use, group.first)); + } + } + } + for (auto &hash : hash_tables) { + for (auto &col : hash.second) { + if (!col.second.data && col.second.fn) { + gen_hash_column(col, hash); + } + } + } +} + +template +void InputXbar::write_regs(REGS ®s) { + LOG1("### Input xbar " << table->name() << " write_regs " << table->loc()); + auto &xbar = regs.dp.xbar_hash.xbar; + auto gress = timing_thread(table->gress); + for (auto &group : groups) { + if (group.second.empty()) continue; + LOG1(" # Input xbar group " << group.first); + unsigned group_base = 0; + unsigned half_byte = 0; + unsigned bytes_used = 0; + switch (group.first.type) { + case Group::EXACT: + group_base = group.first.index * 16U; + break; + case Group::TERNARY: + group_base = 128 + (group.first.index * 11 + 1) / 2U; + half_byte = 133 + 11 * (group.first.index / 2U); + xbar.mau_match_input_xbar_ternary_match_enable[gress] |= + 1 << (group.first.index) / 2U; + break; + case Group::BYTE: + group_base = 133 + 11 * group.first.index; + xbar.mau_match_input_xbar_ternary_match_enable[gress] |= 1 << (group.first.index); + break; + default: + BUG(); + } + for (auto &input : group.second) { + BUG_CHECK(input.lo >= 0); + unsigned word_group = 0, word_index = 0, swizzle_mask = 0; + bool hi_enable = false; + switch (input.what->reg.size) { + case 8: + word_group = (input.what->reg.ixbar_id() - 64) / 8U; + word_index = (input.what->reg.ixbar_id() - 64) % 8U + (word_group & 4) * 2; + swizzle_mask = 0; + break; + case 16: + word_group = (input.what->reg.ixbar_id() - 128) / 12U; + word_index = + (input.what->reg.ixbar_id() - 128) % 12U + 16 + (word_group & 4) * 3; + swizzle_mask = 1; + break; + case 32: + word_group = input.what->reg.ixbar_id() / 8U; + word_index = input.what->reg.ixbar_id() % 8U; + hi_enable = word_group & 4; + swizzle_mask = 3; + break; + default: + BUG(); + } + word_group &= 3; + unsigned phv_byte = input.what->lo / 8U; + unsigned phv_size = input.what->reg.size / 8U; + for (unsigned byte = input.lo / 8U; byte <= input.hi / 8U; byte++, phv_byte++) { + bytes_used |= 1U << byte; + unsigned i = group_base + byte; + if (half_byte && byte == 5) i = half_byte; + if (i % phv_size != phv_byte) { + if (group.first.type != Group::EXACT) { + int off; + if (phv_size == 2) + off = (i & 2) ? -1 : 1; + else + off = tcam_swizzle_offset[i & 3][phv_byte]; + xbar.tswizzle.tcam_byte_swizzle_ctl[(i & 0x7f) / 4U].set_subfield( + off & 3U, 2 * (i % 4U), 2); + i += off; + } else { + error(input.what.lineno, "misaligned phv access on input_xbar"); + } + } + if (input.what->reg.ixbar_id() < 64) { + BUG_CHECK(input.what->reg.size == 32); + xbar.match_input_xbar_32b_ctl[word_group][i].match_input_xbar_32b_ctl_address = + word_index; + if (hi_enable) + xbar.match_input_xbar_32b_ctl[word_group][i] + .match_input_xbar_32b_ctl_hi_enable = 1; + else + xbar.match_input_xbar_32b_ctl[word_group][i] + .match_input_xbar_32b_ctl_lo_enable = 1; + } else { + xbar.match_input_xbar_816b_ctl[word_group][i] + .match_input_xbar_816b_ctl_address = word_index; + xbar.match_input_xbar_816b_ctl[word_group][i].match_input_xbar_816b_ctl_enable = + 1; + } + if ((i ^ phv_byte) & swizzle_mask) + error(input.what.lineno, "Need tcam swizzle for %s", + input.what.toString().c_str()); + } + auto &power_ctl = regs.dp.match_input_xbar_din_power_ctl; + // we do in fact want mau_id, not ixbar_id here! + set_power_ctl_reg(power_ctl, input.what->reg.mau_id()); + } + if (group.first.type == Group::EXACT) { + unsigned enable = 0; + if (bytes_used & 0xff) enable |= 1; + if (bytes_used & 0xff00) enable |= 2; + enable <<= group.first.index * 2; + regs.dp.mau_match_input_xbar_exact_match_enable[gress].rewrite(); + regs.dp.mau_match_input_xbar_exact_match_enable[gress] |= enable; + } + } + auto &hash = regs.dp.xbar_hash.hash; + for (auto &ht : hash_tables) { + if (ht.second.empty()) continue; + LOG1(" # Input xbar hash table " << ht.first); + write_galois_matrix(regs, ht.first, ht.second); + } + for (auto &hg : hash_groups) { + LOG1(" # Input xbar hash group " << hg.first); + int grp = hg.first; + if (hg.second.tables) { + hash.parity_group_mask[grp][0] = hg.second.tables & 0xff; + hash.parity_group_mask[grp][1] = (hg.second.tables >> 8) & 0xff; + regs.dp.mau_match_input_xbar_exact_match_enable[gress].rewrite(); + regs.dp.mau_match_input_xbar_exact_match_enable[gress] |= hg.second.tables; + } + if (hg.second.seed) { + for (int bit = 0; bit < 52; ++bit) { + if ((hg.second.seed >> bit) & 1) { + hash.hash_seed[bit] |= UINT64_C(1) << grp; + } + } + } + if (gress == INGRESS) + regs.dp.hashout_ctl.hash_group_ingress_enable |= 1 << grp; + else + regs.dp.hashout_ctl.hash_group_egress_enable |= 1 << grp; + // Set hash parity check if enabled. The hash parity column data is set + // in pass2 + if (hg.second.tables && !options.disable_gfm_parity) { + // Enable check if parity bit is set on all tables in hash group + int parity_bit = -1; + for (int index : bitvec(hg.second.tables)) { + HashTable ht(HashTable::EXACT, index); + if (!hash_table_parity.count(ht)) { + continue; + } else { + if (parity_bit == -1) { + parity_bit = hash_table_parity[ht]; + } else { + if (hash_table_parity[ht] != parity_bit) + error(hg.second.lineno, + "Hash tables within a hash group " + "do not have the same parity bit - %d", + grp); + } + } + } + if (parity_bit >= 0) { + regs.dp.hashout_ctl.hash_parity_check_enable |= 1 << grp; + // Hash seed must have even parity for the group. Loop through + // all bits set on the group for hash seed to determine if the + // parity bit must be set + int seed_parity = 0; + for (int bit = 0; bit < 52; ++bit) { + auto seed_bit = (hash.hash_seed[bit] >> grp) & 0x1; + seed_parity ^= seed_bit; + } + if (seed_parity) { // flip parity bit setup on group for even parity + if (!hg.second.seed_parity) + warning(hg.second.lineno, + "hash group %d has parity enabled, but setting seed_parity" + " is disabled, changing seed to even parity", + grp); + hash.hash_seed[parity_bit] ^= (1 << grp); + } + } + } + } +} + +template void InputXbar::write_regs(Target::Tofino::mau_regs &); +#if HAVE_JBAY +template void InputXbar::write_regs(Target::JBay::mau_regs &); +#endif /* HAVE_JBAY */ + +template +void InputXbar::write_xmu_regs(REGS ®s) { + BUG("no XMU regs for %s", Target::name()); +} +FOR_ALL_REGISTER_SETS(INSTANTIATE_TARGET_TEMPLATE, void InputXbar::write_xmu_regs, mau_regs &) + +const InputXbar::Input *InputXbar::find(Phv::Slice sl, Group grp, Group *found) const { + const InputXbar::Input *rv = nullptr; + if (groups.count(grp)) { + for (auto &in : groups.at(grp)) { + if (in.lo < 0) continue; + if (in.what->reg.uid != sl.reg.uid) continue; + if (in.what->lo / 8U > sl.lo / 8U) continue; + if (in.what->hi / 8U < sl.hi / 8U) continue; + rv = ∈ + if (in.what->lo > sl.lo) continue; + if (in.what->hi < sl.hi) continue; + if (found) *found = grp; + return ∈ + } + } else if (grp.index == -1) { + for (auto &g : Keys(groups)) { + if (g.type != grp.type) continue; + if ((rv = find(sl, g))) { + if (found) *found = g; + return rv; + } + } + } + return rv; +} + +int InputXbar::find_offset(const MatchSource *, Group, int) const { + BUG("find_offset should not be needed on %s", Target::name()); +} + +std::vector InputXbar::find_all(Phv::Slice sl, Group grp) const { + std::vector rv; + if (groups.count(grp)) { + for (auto &in : groups.at(grp)) { + if (in.lo < 0) continue; + if (in.what->reg.uid != sl.reg.uid) continue; + if (in.what->lo / 8U > sl.lo / 8U) continue; + if (in.what->hi / 8U < sl.hi / 8U) continue; + rv.push_back(&in); + } + } else if (grp.index == -1) { + for (auto &g : Keys(groups)) { + if (g.type != grp.type) continue; + auto tmp = find_all(sl, g); + rv.insert(rv.end(), tmp.begin(), tmp.end()); + } + } + return rv; +} + +/** + * InputXbar::find_hash_inputs: find all of the ixbar inputs that feed a particular phv slice + * to a hash table + * @param sl the PHV container slice we're interested in + * @param hash_table which hash table we want the input for (-1 for all hash tables) + */ +std::vector InputXbar::find_hash_inputs(Phv::Slice sl, + HashTable ht) const { + /* code for tofino1/2 -- all hash tables take input from exact ixbar groups, with + * two hash tables per group (even in lower bits and odd in upper bits) + */ + BUG_CHECK(ht.type == HashTable::EXACT, "not an exact hash table: %s", ht.toString().c_str()); + auto rv = find_all(sl, Group(Group::EXACT, ht.index >= 0 ? ht.index / 2 : -1)); + if (ht.index >= 0) { + unsigned upper = ht.index % 2; + for (auto it = rv.begin(); it != rv.end();) { + unsigned bit = (*it)->lo + (sl.lo - (*it)->what->lo); + if (bit / 64 != upper || (bit + sl.size() - 1) / 64 != upper) + it = rv.erase(it); + else + ++it; + } + } + return rv; +} + +bitvec InputXbar::hash_group_bituse(int grp) const { + bitvec rv; + unsigned tables = 0; + for (auto &g : hash_groups) { + if (grp == -1 || static_cast(g.first) == grp) { + tables |= g.second.tables; + rv |= g.second.seed; + } + } + for (auto &tbl : hash_tables) { + if (tbl.first.type != HashTable::EXACT) continue; + if (!((tables >> tbl.first.index) & 1)) continue; + // Skip parity bit if set on hash table + auto hash_parity_bit = -1; + if (hash_table_parity.count(tbl.first)) { + hash_parity_bit = hash_table_parity.at(tbl.first); + } + for (auto &col : tbl.second) { + if (col.first == hash_parity_bit) continue; + rv[col.first] = 1; + } + } + return rv; +} + +// Used by LPF/WRED meters to determine the bytemask input +bitvec InputXbar::bytemask() { + bitvec bytemask; + // Only one ixbar group allowed for a meter input + if (match_group() == -1) return bytemask; + for (auto group : groups) { + auto &inputs = group.second; + for (auto &input : inputs) { + int byte_lo = input.lo / 8; + int byte_hi = input.hi / 8; + int byte_size = byte_hi - byte_lo + 1; + bytemask.setrange(byte_lo, byte_size); + } + } + return bytemask; +} + +std::vector InputXbar::hash_column(int col, int grp) const { + unsigned tables = 0; + std::vector rv; + for (auto &g : hash_groups) + if (grp == -1 || static_cast(g.first) == grp) tables |= g.second.tables; + for (auto &tbl : hash_tables) { + if (tbl.first.type != HashTable::EXACT) continue; + if (!((tables >> tbl.first.index) & 1)) continue; + if (const HashCol *c = getref(tbl.second, col)) rv.push_back(c); + } + return rv; +} + +bool InputXbar::log_hashes(std::ofstream &out) const { + bool logged = false; + for (auto &ht : hash_tables) { + // ht.first is HashTable + // ht.second is std::map, key is col + if (ht.second.empty()) continue; + out << std::endl << ht.first << std::endl; + logged = true; + for (auto &col : ht.second) { + // col.first is hash result bit + // col.second is bits XOR'd in + out << "result[" << col.first << "] = "; + out << get_seed_bit(ht.first.index / 2, col.first); + for (const auto &bit : col.second.data) { + if (auto ref = get_hashtable_bit(ht.first, bit)) { + std::string field_name = ref.name(); + auto field_bit = remove_name_tail_range(field_name) + ref.lobit(); + out << " ^ " << field_name << "[" << field_bit << "]"; + } + } + out << std::endl; + } + } + return logged; +} + +std::string InputXbar::HashTable::toString() const { + std::stringstream tmp; + tmp << *this; + return tmp.str(); +} + +unsigned InputXbar::HashTable::uid() const { + switch (type) { + case EXACT: + BUG_CHECK(index < Target::EXACT_HASH_TABLES(), "index too large: %s", + toString().c_str()); + return index; + case XCMP: + return index + Target::EXACT_HASH_TABLES(); + default: + BUG("invalid type: %s", toString().c_str()); + } +} diff --git a/backends/tofino/bf-asm/input_xbar.h b/backends/tofino/bf-asm/input_xbar.h new file mode 100644 index 00000000000..70a5b1780b0 --- /dev/null +++ b/backends/tofino/bf-asm/input_xbar.h @@ -0,0 +1,367 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_INPUT_XBAR_H_ +#define BF_ASM_INPUT_XBAR_H_ + +#include + +#include "constants.h" +#include "dynamic_hash/dynamic_hash.h" +#include "ordered_map.h" +#include "phv.h" + +class Table; +class HashExpr; + +struct HashCol { + int lineno = -1; + HashExpr *fn = 0; + int bit = 0; + bitvec data; + unsigned valid = 0; // Used only in Tofino + void dbprint(std::ostream &out) const; +}; + +inline std::ostream &operator<<(std::ostream &out, HashCol &col) { + col.dbprint(out); + return out; +} + +struct DynamicIXbar { + int bit = -1; + std::vector> match_phv; + match_t match; + + DynamicIXbar() = default; + DynamicIXbar(const DynamicIXbar &) = default; + DynamicIXbar(DynamicIXbar &&) = default; + DynamicIXbar &operator=(const DynamicIXbar &) = default; + DynamicIXbar &operator=(DynamicIXbar &&) = default; + DynamicIXbar(const Table *, const pair_t &); +}; + +class InputXbar { + public: + struct Group { + short index; + enum type_t { INVALID, EXACT, TERNARY, BYTE, GATEWAY, XCMP } type; + Group() : index(-1), type(INVALID) {} + Group(Group::type_t t, int i) : index(i), type(t) {} + explicit operator bool() const { return type != INVALID; } + bool operator==(const Group &a) const { return type == a.type && index == a.index; } + bool operator<(const Group &a) const { + return (type << 16) + index < (a.type << 16) + a.index; + } + }; + struct HashTable { + short index; + enum type_t { INVALID, EXACT, XCMP } type; + HashTable() : index(-1), type(INVALID) {} + HashTable(type_t t, int i) : index(i), type(t) {} + explicit operator bool() const { return type != INVALID; } + bool operator==(const HashTable &a) const { return type == a.type && index == a.index; } + bool operator<(const HashTable &a) const { + return (type << 16) + index < (a.type << 16) + a.index; + } + std::string toString() const; + unsigned uid() const; + }; + + protected: + struct Input { + Phv::Ref what; + int lo, hi; + explicit Input(const Phv::Ref &a) : what(a), lo(-1), hi(-1) {} + Input(const Phv::Ref &a, int s) : what(a), lo(s), hi(-1) {} + Input(const Phv::Ref &a, int l, int h) : what(a), lo(l), hi(h) {} + unsigned size() const { return hi - lo + 1; } + }; + struct HashGrp { + int lineno = -1; + unsigned tables = 0; // Bit set for table index + uint64_t seed = 0; + bool seed_parity = false; // Parity to be set on the seed value + }; + Table *table; + ordered_map> groups; + std::map> hash_tables; + // Map of hash table index to parity bit set on the table + std::map hash_table_parity; + std::map hash_groups; + static bool conflict(const std::vector &a, const std::vector &b); + static bool conflict(const std::map &, const std::map &, int * = 0); + static bool conflict(const HashGrp &a, const HashGrp &b); + bool copy_existing_hash(HashTable ht, std::pair &col); + uint64_t hash_columns_used(HashTable hash); + uint64_t hash_columns_used(unsigned id) { + BUG_CHECK(id < Target::EXACT_HASH_TABLES(), "%d out of range for exact hash", id); + return hash_columns_used(HashTable(HashTable::EXACT, id)); + } + bool can_merge(HashGrp &a, HashGrp &b); + void add_use(unsigned &byte_use, std::vector &a); + virtual int hash_num_columns(HashTable ht) const { return 52; } + virtual int group_max_index(Group::type_t t) const; + virtual Group group_name(bool ternary, const value_t &value) const; + virtual int group_size(Group::type_t t) const; + const char *group_type(Group::type_t t) const; + void parse_group(Table *t, Group gr, const value_t &value); + virtual bool parse_hash(Table *t, const pair_t &kv) { return false; } + void parse_hash_group(HashGrp &hash_group, const value_t &value); + void parse_hash_table(Table *t, HashTable ht, const value_t &value); + virtual bool parse_unit(Table *t, const pair_t &kv) { return false; } + void setup_hash(std::map &, HashTable ht, gress_t, int stage, value_t &, + int lineno, int lo, int hi); + struct TcamUseCache { + std::map> tcam_use; + std::set ixbars_added; + }; + virtual void check_input(Group group, Input &input, TcamUseCache &tcam_use); + int tcam_input_use(int out_byte, int phv_byte, int phv_size); + void tcam_update_use(TcamUseCache &use); + void gen_hash_column(std::pair &col, + std::pair> &hash); + + struct GroupSet : public IHasDbPrint { + Group group; + const std::vector &use; + GroupSet(const std::vector &u, Group g) : group(g), use(u) {} + GroupSet(ordered_map> &u, Group g) : group(g), use(u[g]) {} + void dbprint(std::ostream &) const; + const Input *find(Phv::Slice sl) const; + std::vector find_all(Phv::Slice sl) const; + }; + + InputXbar() = delete; + InputXbar(const InputXbar &) = delete; + void input(Table *table, bool ternary, const VECTOR(pair_t) & data); + InputXbar(Table *table, int lineno) : table(table), lineno(lineno) {} + + public: + const int lineno; + int random_seed = -1; + static std::unique_ptr create(Table *table, const value_t *key = nullptr); + static std::unique_ptr create(Table *table, bool tern, const value_t &key, + const VECTOR(pair_t) & data); + void pass1(); + virtual void pass2(); + template + void write_regs(REGS ®s); + template + void write_xmu_regs(REGS ®s); + template + void write_galois_matrix(REGS ®s, HashTable id, const std::map &mat); + bool have_exact() const { + for (auto &grp : groups) + if (grp.first.type == Group::EXACT) return true; + return false; + } + bool have_ternary() const { + for (auto &grp : groups) + if (grp.first.type != Group::EXACT) return true; + return false; + } + int hash_group() const { + /* used by gateways to get the associated hash group */ + if (hash_groups.size() != 1) return -1; + return hash_groups.begin()->first; + } + bitvec hash_group_bituse(int grp = -1) const; + std::vector hash_column(int col, int grp = -1) const; + int match_group() { + /* used by gateways and stateful to get the associated match group */ + if (groups.size() != 1 || groups.begin()->first.type != Group::EXACT) return -1; + return groups.begin()->first.index; + } + bitvec bytemask(); + /* functions for tcam ixbar that take into account funny byte/word group stuff */ + unsigned tcam_width(); + int tcam_byte_group(int n); + int tcam_word_group(int n); + std::map> &get_hash_tables() { return hash_tables; } + const std::map &get_hash_table(HashTable id); + const std::map &get_hash_table(unsigned id = 0) { + return get_hash_table(HashTable(HashTable::EXACT, id)); + } + + // which Group provides the input for a given HashTable + virtual Group hashtable_input_group(HashTable ht) const { + BUG_CHECK(ht.type == HashTable::EXACT, "not an exact hash table"); + return Group(Group::EXACT, ht.index / 2); + } + virtual Phv::Ref get_hashtable_bit(HashTable id, unsigned bit) const { + BUG_CHECK(id.type == HashTable::EXACT, "not an exact hash table"); + return get_group_bit(Group(Group::EXACT, id.index / 2), bit + 64 * (id.index & 0x1)); + } + Phv::Ref get_hashtable_bit(unsigned id, unsigned bit) const { + return get_hashtable_bit(HashTable(HashTable::EXACT, id), bit); + } + Phv::Ref get_group_bit(Group grp, unsigned bit) const { + if (groups.count(grp)) + for (auto &in : groups.at(grp)) + if (bit >= unsigned(in.lo) && bit <= unsigned(in.hi)) + return Phv::Ref(in.what, bit - in.lo, bit - in.lo); + return Phv::Ref(); + } + std::string get_field_name(int bit) { + for (auto &g : groups) { + for (auto &p : g.second) { + if (bit <= p.hi && bit >= p.lo) return p.what.name(); + } + } + return ""; + } + bool is_p4_param_bit_in_hash(std::string p4_param_name, int bit) { + for (auto &g : groups) { + for (auto &p : g.second) { + std::string phv_field_name = p.what.name(); + auto phv_field_lobit = remove_name_tail_range(phv_field_name); + phv_field_lobit += p.what.fieldlobit(); + auto phv_field_hibit = phv_field_lobit + p.size() - 1; + if (p4_param_name == phv_field_name && bit <= phv_field_hibit && + bit >= phv_field_lobit) + return true; + } + } + return false; + } + unsigned get_seed_bit(unsigned group, unsigned bit) const { + if (hash_groups.count(group)) return ((hash_groups.at(group).seed >> bit) & 0x1); + return 0; + } + HashGrp *get_hash_group(unsigned group = -1) { return ::getref(hash_groups, group); } + HashGrp *get_hash_group_from_hash_table(int hash_table) { + if (hash_table < 0 || hash_table >= Target::EXACT_HASH_TABLES()) return nullptr; + for (auto &hg : hash_groups) { + if (hg.second.tables & (1U << hash_table)) return &hg.second; + } + return nullptr; + } + bool log_hashes(std::ofstream &out) const; + virtual unsigned exact_physical_ids() const { return -1; } + + class all_iter { + decltype(groups)::const_iterator outer, outer_end; + bool inner_valid; + std::vector::const_iterator inner; + void mk_inner_valid() { + if (!inner_valid) { + if (outer == outer_end) return; + inner = outer->second.begin(); + } + while (inner == outer->second.end()) { + if (++outer == outer_end) return; + inner = outer->second.begin(); + } + inner_valid = true; + } + struct iter_deref : public std::pair { + explicit iter_deref(const std::pair &a) + : std::pair(a) {} + iter_deref *operator->() { return this; } + }; + + public: + all_iter(decltype(groups)::const_iterator o, decltype(groups)::const_iterator oend) + : outer(o), outer_end(oend), inner_valid(false) { + mk_inner_valid(); + } + bool operator==(const all_iter &a) { + if (outer != a.outer) return false; + if (inner_valid != a.inner_valid) return false; + return inner_valid ? inner == a.inner : true; + } + all_iter &operator++() { + if (inner_valid && ++inner == outer->second.end()) { + ++outer; + inner_valid = false; + mk_inner_valid(); + } + return *this; + } + std::pair operator*() { + return std::pair(outer->first, *inner); + } + iter_deref operator->() { return iter_deref(**this); } + }; + all_iter begin() const { return all_iter(groups.begin(), groups.end()); } + all_iter end() const { return all_iter(groups.end(), groups.end()); } + + const Input *find(Phv::Slice sl, Group grp, Group *found = nullptr) const; + const Input *find_exact(Phv::Slice sl, int group) const { + return find(sl, Group(Group::EXACT, group)); + } + virtual int find_offset(const MatchSource *, Group grp, int offset) const; + int find_gateway_offset(const MatchSource *ms, int offset) const { + return find_offset(ms, Group(Group::GATEWAY, 0), offset); + } + int find_match_offset(const MatchSource *ms, int offset = -1) const { + return find_offset(ms, Group(Group::EXACT, -1), offset); + } + + std::vector find_all(Phv::Slice sl, Group grp) const; + virtual std::vector find_hash_inputs(Phv::Slice sl, HashTable ht) const; + virtual int global_bit_position_adjust(HashTable ht) const { + BUG_CHECK(ht.type == HashTable::EXACT, "not an exact hash table"); + return (ht.index / 2) * 128; + } + virtual bitvec global_column0_extract( + HashTable ht, const hash_column_t matrix[PARITY_GROUPS_DYN][HASH_MATRIX_WIDTH_DYN]) const { + BUG_CHECK(ht.type == HashTable::EXACT, "not an exact hash table"); + return bitvec(matrix[ht.index][0].column_value); + } + virtual void setup_match_key_cfg(const MatchSource *) {} // noop for tofino1/2 +}; + +inline std::ostream &operator<<(std::ostream &out, InputXbar::Group gr) { + switch (gr.type) { + case InputXbar::Group::EXACT: + out << "exact"; + break; + case InputXbar::Group::TERNARY: + out << "ternary"; + break; + case InputXbar::Group::BYTE: + out << "byte"; + break; + case InputXbar::Group::GATEWAY: + out << "gateway"; + break; + case InputXbar::Group::XCMP: + out << "xcmp"; + break; + default: + out << "(gr.type) << ">"; + } + return out << " ixbar group " << gr.index; +} + +inline std::ostream &operator<<(std::ostream &out, InputXbar::HashTable ht) { + switch (ht.type) { + case InputXbar::HashTable::EXACT: + out << "exact"; + break; + case InputXbar::HashTable::XCMP: + out << "xcmp"; + break; + default: + out << "(ht.type) << ">"; + } + return out << " hashtable " << ht.index; +} + +#endif /* BF_ASM_INPUT_XBAR_H_ */ diff --git a/backends/tofino/bf-asm/instruction.cpp b/backends/tofino/bf-asm/instruction.cpp new file mode 100644 index 00000000000..e8a086f0883 --- /dev/null +++ b/backends/tofino/bf-asm/instruction.cpp @@ -0,0 +1,1745 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "instruction.h" + +#include + +#include "action_bus.h" +#include "depositfield.h" +#include "phv.h" +#include "power_ctl.h" +#include "stage.h" +#include "tables.h" + +namespace { +constexpr int RotationBits = 16; +} + +std::multimap + Instruction::Decode::opcode[Instruction::NUM_SETS]; + +Instruction::Decode::Decode(const char *name, int set, bool ts) : type_suffix(ts) { + targets = ~0U; + for (auto d : ValuesForKey(opcode[set], name)) { + BUG_CHECK(!(d->targets & 1)); + targets &= ~d->targets; + } + BUG_CHECK(targets > 1); + opcode[set].emplace(name, this); +} +Instruction::Decode::Decode(const char *name, target_t target, int set, bool ts) : type_suffix(ts) { + targets = 1 << target; + for (auto d : ValuesForKey(opcode[set], name)) { + if (d->targets & 1) { + d->targets &= ~targets; + BUG_CHECK(d->targets > 1); + } + } + opcode[set].emplace(name, this); +} +Instruction::Decode::Decode(const char *name, std::set target, int set, bool ts) + : type_suffix(ts), targets(0) { + for (auto t : target) targets |= 1 << t; + BUG_CHECK(targets > 1); + for (auto d : ValuesForKey(opcode[set], name)) { + if (d->targets & 1) { + d->targets &= ~targets; + BUG_CHECK(d->targets > 1); + } + } + opcode[set].emplace(name, this); +} + +Instruction *Instruction::decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) { + for (auto d : ValuesForKey(Instruction::Decode::opcode[tbl->instruction_set()], op[0].s)) { + if ((d->targets >> Target::register_set()) & 1) { + auto inst = d->decode(tbl, act, op); + if (!inst) continue; + return inst; + } + } + if (auto p = strchr(op[0].s, '.')) { + std::string opname(op[0].s, p - op[0].s); + for (auto d : ValuesForKey(Instruction::Decode::opcode[tbl->instruction_set()], opname)) { + if (((d->targets >> options.target) & 1) && d->type_suffix) { + auto inst = d->decode(tbl, act, op); + if (!inst) continue; + return inst; + } + } + } + return 0; +} + +namespace VLIW { +static const int group_size[] = {32, 32, 32, 32, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16}; + +struct Operand : public IHasDbPrint { + /** A source operand to a VLIW instruction -- this can be a variety of things, so we + * have a pointer to an abstract base class and a number of derived concrete classes for + * the different kinds of operands. When we parse the operand, the type may be determined, + * or if it is just a name, we will have to wait to a later pass to resolve what the + * name refers to. At that point, the `Named' object created in parsing will be replaced + * with the actual operand type */ + static const int ACTIONBUS_OPERAND = 0x20; + struct Base { + int lineno; + explicit Base(int line) : lineno(line) {} + Base(const Base &a) : lineno(a.lineno) {} + virtual ~Base() {} + virtual Base *clone() = 0; + virtual Base *lookup(Base *&ref) { return this; } + virtual bool check() { return true; } + virtual int phvGroup() { return -1; } + virtual int bits(int group, int dest_size = -1) = 0; + virtual unsigned bitoffset(int group) const { return 0; } + virtual void dbprint(std::ostream &) const = 0; + virtual bool equiv(const Base *) const = 0; + virtual bool phvRead(std::function) { return false; } + /** pass1 called as part of pass1 processing of stage + * @param tbl table containing the action with the instruction with this operand + * @param group mau PHV group of the ALU (dest) for this instruction */ + virtual void pass1(Table *tbl, int group) {} + /** pass2 called as part of pass2 processing of stage + * @param group mau PHV group of the ALU (dest) for this instruction */ + virtual void pass2(int group) {} + } *op; + struct Const : Base { + int64_t value; + Const(int line, int64_t v) : Base(line), value(v) {} + bool equiv(const Base *a_) const override { + if (auto *a = dynamic_cast(a_)) { + return value == a->value; + } else { + return false; + } + } + Const *clone() override { return new Const(*this); } + int32_t bits(int group, int dest_size = -1) override { + // assert(value <= 0xffffffffLL); + int32_t val = value; + if (val > 0 && ((val >> (group_size[group] - 1)) & 1)) + val |= UINT64_MAX << group_size[group]; + int minconst = Target::MINIMUM_INSTR_CONSTANT(); + + if (dest_size != -1) { // DepositField::encode() calling. + auto rotConst = + DepositField::discoverRotation(val, group_size[group], 8, minconst - 1); + if (rotConst.rotate) return rotConst.value + 24 | (rotConst.rotate << RotationBits); + } + + if (val >= minconst && val < 8) return val + 24; + error(lineno, "constant value %" PRId64 " out of range for immediate", value); + return -1; + } + void dbprint(std::ostream &out) const override { out << value; } + }; + struct Phv : Base { + ::Phv::Ref reg; + Phv(int line, gress_t g, int stage, const value_t &n) : Base(line), reg(g, stage, n) {} + Phv(int line, gress_t g, int stage, const std::string &n, int l, int h) + : Base(line), reg(g, stage, line, n, l, h) {} + explicit Phv(const ::Phv::Ref &r) : Base(r.lineno), reg(r) {} + bool equiv(const Base *a_) const override { + if (auto *a = dynamic_cast(a_)) { + return reg == a->reg; + } else { + return false; + } + } + Phv *clone() override { return new Phv(*this); } + bool check() override { + if (!reg.check()) return false; + if (reg->reg.mau_id() < 0) { + error(reg.lineno, "%s not accessable in mau", reg->reg.name); + return false; + } + return true; + } + int phvGroup() override { return reg->reg.mau_id() / ::Phv::mau_groupsize(); } + int bits(int group, int dest_size = -1) override { + if (group != phvGroup()) { + error(lineno, "registers in an instruction must all be in the same phv group"); + return -1; + } + return reg->reg.mau_id() % ::Phv::mau_groupsize(); + } + unsigned bitoffset(int group) const override { return reg->lo; } + void pass1(Table *tbl, int) override { + tbl->stage->action_use[tbl->gress][reg->reg.uid] = true; + } + void dbprint(std::ostream &out) const override { out << reg; } + bool phvRead(std::function fn) override { + fn(*reg); + return true; + } + }; + struct Action : Base { + /* source referring to either an action data or immediate field OR an attached table + * output. All of these are accessed via the action data bus */ + std::string name; + std::string p4name; + TableOutputModifier mod = TableOutputModifier::NONE; + Table *table; + Table::Format::Field *field; + int lo, hi; + + Action(int line, const std::string &n, Table *tbl, Table::Format::Field *f, unsigned l, + unsigned h) + : Base(line), name(n), table(tbl), field(f), lo(l), hi(h) {} + Action(int line, const std::string &n, TableOutputModifier mod, Table *tbl, unsigned l, + unsigned h) + : Base(line), name(n), mod(mod), table(tbl), field(nullptr), lo(l), hi(h) {} + Action(int line, const std::string &n, Table *tbl, Table::Format::Field *f, unsigned l, + unsigned h, const std::string &m) + : Base(line), name(n), p4name(m), table(tbl), field(f), lo(l), hi(h) {} + Action(int line, const std::string &n, TableOutputModifier mod, Table *tbl, unsigned l, + unsigned h, const std::string &m) + : Base(line), name(n), p4name(m), mod(mod), table(tbl), field(nullptr), lo(l), hi(h) {} + bool equiv(const Base *a_) const override { + auto *a = dynamic_cast(a_); + if (!a || lo != a->lo || hi != a->hi) return false; + if (name == a->name && table == a->table && field == a->field && mod == a->mod) + return true; + if (field != a->field && (!field || !a->field)) return false; + int b1 = field ? table->find_on_actionbus(field, lo, hi, 0) + : table->find_on_actionbus(name, mod, lo, hi, 0); + int b2 = a->field ? a->table->find_on_actionbus(a->field, lo, hi, 0) + : a->table->find_on_actionbus(a->name, mod, lo, hi, 0); + return b1 == b2 && b1 >= 0; + } + Action *clone() override { return new Action(*this); } + int bits(int group, int dest_size = -1) override { + int size = group_size[group] / 8U; + BUG_CHECK(lo >= 0 && hi >= 0); + unsigned lo = this->lo, hi = this->hi; + if (dest_size > 0) { + // override size based on destination size for deposit-field + hi = lo + dest_size - 1; + unsigned mask = group_size[group] - 1; // group size is power of 2 (8, 16, or 32) + if ((hi | mask) != (lo | mask)) { + // crosses slot boundary, so is a wrap-around rotated source -- need all of it + lo &= ~mask; + hi = lo | mask; + } + } + int byte = field ? table->find_on_actionbus(field, lo, hi, size) + : table->find_on_actionbus(name, mod, lo, hi, size); + if (byte < 0) { + if (this->lo > 0 || (field && this->hi + 1 < int(field->size))) + error(lineno, "%s(%d..%d) is not on the action bus", name.c_str(), lo, hi); + else + error(lineno, "%s is not on the action bus", name.c_str()); + return -1; + } + int byte_value = byte; + if (size == 2) byte -= 32; + if (byte < 0 || byte > 32 * size) + error(lineno, "action bus entry %d(%s) out of range for %d-bit access", byte_value, + name.c_str(), size * 8); + // else if (byte % size != 0) + // error(lineno, "action bus entry %d(%s) misaligned for %d-bit access", + // byte_value, name.c_str(), size*8); + else + return ACTIONBUS_OPERAND + byte / size; + return -1; + } + void pass1(Table *tbl, int group) override { + if (field) field->flags |= Table::Format::Field::USED_IMMED; + if (lo >= 0 && hi >= 0 && lo / group_size[group] != hi / group_size[group]) { + error(lineno, + "action bus slice (%d..%d) can't fit in a single slot for %d bit " + "access", + lo, hi, group_size[group]); + // chop it down to be in range (avoid error cascade) + hi = lo | (group_size[group] - 1); + } + } + void pass2(int group) override { + int bits = group_size[group]; + unsigned bytes = bits / 8U; + if (lo < 0) lo = 0; + if (hi < 0) hi = lo + bits - 1; + if (hi > lo + bits - 1) { + warning(lineno, "%s(%d..%d) larger than %d bit access", name.c_str(), lo, hi, bits); + hi = lo + bits - 1; + } + if ((lo ^ hi) & ~(bits - 1)) + error(lineno, "%s(%d..%d) can't be accessed by %d bit PHV", name.c_str(), lo, hi, + bits); + if (field && table->find_on_actionbus(field, lo, hi, bytes) < 0) { + int immed_offset = 0; + if (table->format && table->format->immed) + immed_offset = table->format->immed->bit(0); + int l = field->bit(lo) - immed_offset, h = field->bit(hi) - immed_offset; + if (l % bits != 0 && l / bits != h / bits) + error(lineno, "%s misaligned for action bus", name.c_str()); + table->need_on_actionbus(field, lo, hi, bytes); + } else if (!field && table->find_on_actionbus(name, mod, lo, hi, bytes) < 0) { + if (auto *tbl = ::get(Table::all, name)) + table->need_on_actionbus(tbl, mod, lo, hi, bytes); + else + error(lineno, "Can't find any operand named %s", name.c_str()); + } + } + unsigned bitoffset(int group) const override { + int size = group_size[group] / 8U; + int byte = field ? table->find_on_actionbus(field, lo, hi, size) + : table->find_on_actionbus(name, lo, hi, size); + return 8 * (byte % size) + lo % 8; + } + void dbprint(std::ostream &out) const override { + out << name << mod << '(' << lo << ".." << hi << ')'; + if (field) + out << '[' << field->bits[0].lo << ':' << field->size << ", " << field->group + << ']'; + } + }; + struct RawAction : Base { + int index; + unsigned offset; + + RawAction(int line, int idx, unsigned off) : Base(line), index(idx), offset(off) {} + bool equiv(const Base *a_) const override { + if (auto *a = dynamic_cast(a_)) { + return index == a->index && offset == a->offset; + } else { + return false; + } + } + RawAction *clone() override { return new RawAction(*this); } + int bits(int group, int dest_size = -1) override { return ACTIONBUS_OPERAND + index; } + unsigned bitoffset(int group) const override { return offset; } + void dbprint(std::ostream &out) const override { out << 'A' << index; } + }; + struct HashDist : Base { + Table *table; + std::vector units; + int lo = -1, hi = -1; + + HashDist(int line, Table *t) : Base(line), table(t) {} + HashDist(int line, Table *t, int unit) : Base(line), table(t) { units.push_back(unit); } + unsigned bitoffset(int group) const override { return lo >= 0 ? lo : 0; } + static HashDist *parse(Table *tbl, const VECTOR(value_t) & v) { + if (v.size < 2 || v[0] != "hash_dist") return nullptr; + auto *rv = new HashDist(v[0].lineno, tbl); + for (int i = 1; i < v.size; ++i) { + if (v[i].type == tRANGE && rv->lo == -1) { + rv->lo = v[i].lo; + rv->hi = v[i].hi; + } else if (CHECKTYPE(v[i], tINT)) { + rv->units.push_back(v[i].i); + } else { + delete rv; + return nullptr; + } + } + return rv; + } + + HashDistribution *find_hash_dist(int unit) const { + if (auto rv = table->find_hash_dist(unit)) return rv; + for (auto *mtab : table->get_match_tables()) + if (auto rv = mtab->find_hash_dist(unit)) return rv; + return nullptr; + } + bool equiv(const Base *a_) const override { + auto *a = dynamic_cast(a_); + if (!a || units != a->units || lo != a->lo || hi != a->hi) return false; + if (table == a->table) return true; + int elo = this->lo < 0 ? 0 : lo; + int ehi = this->hi < 0 ? 15 : hi; + for (auto unit : units) { + int b1 = table->find_on_actionbus(find_hash_dist(unit), elo, ehi, 0); + int b2 = a->table->find_on_actionbus(a->find_hash_dist(unit), elo, ehi, 0); + if (b1 != b2 || b1 < 0) return false; + } + return true; + } + HashDist *clone() override { return new HashDist(*this); } + void pass2(int group) override { + if (units.size() > 2) { + error(lineno, "Can't use more than 2 hash_dist units together in an action"); + return; + } + int size = group_size[group] / 8U; + if (lo < 0) lo = 0; + if (hi < 0) hi = 8 * size - 1; + if ((lo ^ hi) & ~(8 * size - 1)) + error(lineno, "hash dist slice(%d..%d) can't be accessed by %d bit PHV", lo, hi, + 8 * size); + if (units.size() == 2) { + if (size != 4) + error(lineno, "Can't combine hash_dist units in %d bit operation", size * 8); + auto xbar_use = HashDistribution::IMMEDIATE_LOW; + for (auto u : units) { + if (auto hd = find_hash_dist(u)) + hd->xbar_use |= xbar_use; + else + error(lineno, "No hash dist %d in table %s", u, table->name()); + xbar_use = HashDistribution::IMMEDIATE_HIGH; + } + } else if (auto hd = find_hash_dist(units.at(0))) { + if (hd->xbar_use & HashDistribution::IMMEDIATE_HIGH) { + if (size == 4) { + lo += 16; + hi += 16; + } + } else { + hd->xbar_use |= HashDistribution::IMMEDIATE_LOW; + } + } else { + error(lineno, "No hash dist %d in table %s", units.at(0), table->name()); + } + int lo = this->lo; + for (auto u : units) { + if (auto hd = find_hash_dist(u)) { + if (table->find_on_actionbus(hd, lo, hi, size) < 0) + table->need_on_actionbus(hd, lo, hi, size); + lo += 16; + } + } + } + int bits(int group, int dest_size = -1) override { + int size = group_size[group] / 8U; + auto hd = find_hash_dist(units.at(0)); + if (!hd) error(lineno, "could not find hash dist"); + int byte = table->find_on_actionbus(hd, lo, hi, size); + if (byte < 0) { + error(lineno, "hash dist %d is not on the action bus", (hd ? hd->id : -1)); + return -1; + } + if (units.size() == 2) { + auto hd1 = find_hash_dist(units.at(1)); + if (!hd1) error(lineno, "could not find hash dist"); + if (table->find_on_actionbus(ActionBusSource(hd, hd1), lo + 16, hi, size) < 0) + error(lineno, "hash dists %d and %d not contiguous on the action bus", + (hd ? hd->id : -1), (hd1 ? hd1->id : -1)); + } + if (size == 2) byte -= 32; + if (byte >= 0 && byte < 32 * size) return ACTIONBUS_OPERAND + byte / size; + error(lineno, "action bus entry %d(hash_dist %d) out of range for %d-bit access", + size == 2 ? byte + 32 : byte, hd->id, size * 8); + return -1; + } + void dbprint(std::ostream &out) const override { + out << "hash_dist("; + const char *sep = ""; + for (auto u : units) { + out << sep << u; + sep = ", "; + } + out << ")"; + } + }; + struct RandomGen : Base { + Table *table; + RandomNumberGen rng; + int lo = 0, hi = -1; + RandomGen(Table *t, const VECTOR(value_t) & v) : Base(v[0].lineno), table(t), rng(0) { + if (v.size > 1 && CHECKTYPE(v[1], tINT)) rng.unit = v[1].i; + if (rng.unit < 0 || rng.unit > 1) error(v[0].lineno, "invalid random number generator"); + if (v.size > 2 && CHECKTYPE(v[2], tRANGE)) { + lo = v[2].lo; + hi = v[2].hi; + if (lo < 0 || hi > 31 || hi < lo) + error(v[2].lineno, "invalid random number generator slice"); + } + } + bool equiv(const Base *a_) const override { + if (auto *a = dynamic_cast(a_)) { + return rng == a->rng && lo == a->lo && hi == a->hi; + } else { + return false; + } + } + RandomGen *clone() override { return new RandomGen(*this); } + void pass2(int group) override { + unsigned size = group_size[group]; + if (hi < 0) hi = lo + 8 * size - 1; + if ((lo ^ hi) & ~(8 * size - 1)) + error(lineno, "invalid slice(%d..%d) of rng %d for use with %d bit PHV", lo, hi, + rng.unit, size); + if (table->find_on_actionbus(rng, lo, hi, size / 8U)) + table->need_on_actionbus(rng, lo, hi, size / 8U); + } + int bits(int group, int dest_size = -1) override { + int size = group_size[group] / 8U; + int byte = table->find_on_actionbus(rng, lo, hi, size); + if (byte < 0) { + error(lineno, "rng %d is not on the action bus", rng.unit); + return -1; + } + if (size == 2) byte -= 32; + if (byte >= 0 && byte < 32 * size) return ACTIONBUS_OPERAND + byte / size; + error(lineno, "action bus entry %d(rng %d) out of range for %d-bit access", + size == 2 ? byte + 32 : byte, rng.unit, size * 8); + return -1; + } + unsigned bitoffset(int group) const override { return lo; } + void dbprint(std::ostream &out) const override { + out << "rng " << rng.unit << '(' << lo << ".." << hi << ')'; + } + }; + struct Named : Base { + std::string name; + std::string p4name; + TableOutputModifier mod = TableOutputModifier::NONE; + int lo, hi; + Table *tbl; + std::string action; + + Named(int line, const std::string &n, int l, int h, Table *t, const std::string &act) + : Base(line), name(n), lo(l), hi(h), tbl(t), action(act) {} + Named(int line, const std::string &n, TableOutputModifier m, int l, int h, Table *t, + const std::string &act) + : Base(line), name(n), mod(m), lo(l), hi(h), tbl(t), action(act) {} + Named(int line, const std::string &n, int l, int h, Table *t, const std::string &act, + std::string &m) + : Base(line), name(n), p4name(m), lo(l), hi(h), tbl(t), action(act) {} + Named(int line, const std::string &n, TableOutputModifier mod, int l, int h, Table *t, + const std::string &act, std::string &m) + : Base(line), name(n), p4name(m), mod(mod), lo(l), hi(h), tbl(t), action(act) {} + bool equiv(const Base *a_) const override { + if (auto *a = dynamic_cast(a_)) { + return name == a->name && lo == a->lo && hi == a->hi && tbl == a->tbl && + action == a->action; + } else { + return false; + } + } + Base *lookup(Base *&ref) override; + Named *clone() override { return new Named(*this); } + bool check() override { + BUG(); + return true; + } + int phvGroup() override { + BUG(); + return -1; + } + int bits(int group, int dest_size = -1) override { + BUG(); + return 0; + } + unsigned bitoffset(int group) const override { + BUG(); + return 0; + } + void pass1(Table *, int) override { BUG(); } + void dbprint(std::ostream &out) const override { + out << name; + if (lo >= 0) { + out << '(' << lo; + if (hi >= 0 && hi != lo) out << ".. " << hi; + out << ')'; + } + out << '[' << tbl->name() << ':' << action << ']'; + } + }; + Operand() : op(0) {} + Operand(const Operand &a) : op(a.op ? a.op->clone() : 0) {} + Operand(Operand &&a) : op(a.op) { a.op = 0; } + Operand &operator=(const Operand &a) { + if (&a != this) { + delete op; + op = a.op ? a.op->clone() : 0; + } + return *this; + } + Operand &operator=(Operand &&a) { + if (&a != this) { + delete op; + op = a.op; + a.op = 0; + } + return *this; + } + ~Operand() { delete op; } + Operand(Table *tbl, const Table::Actions::Action *act, const value_t &v); + Operand(gress_t gress, int stage, const value_t &v) : op(new Phv(v.lineno, gress, stage, v)) {} + explicit Operand(const ::Phv::Ref &r) : op(new Phv(r)) {} + bool valid() const { return op != 0; } + bool operator==(Operand &a) { + return op == a.op || (op && a.op && op->lookup(op)->equiv(a.op->lookup(a.op))); + } + unsigned bitoffset(int group) { return op->lookup(op)->bitoffset(group); } + bool check() { return op && op->lookup(op) ? op->check() : false; } + int phvGroup() { return op->lookup(op)->phvGroup(); } + bool phvRead(std::function fn) { + return op->lookup(op)->phvRead(fn); + } + int bits(int group, int dest_size = -1) { return op->lookup(op)->bits(group, dest_size); } + void dbprint(std::ostream &out) const { op->dbprint(out); } + Base *operator->() { return op->lookup(op); } + template + T *to() { + return dynamic_cast(op->lookup(op)); + } +}; + +static void parse_slice(const VECTOR(value_t) & vec, int idx, int &lo, int &hi) { + if (PCHECKTYPE2(vec.size == idx + 1, vec[idx], tINT, tRANGE)) { + if (vec[idx].type == tINT) { + lo = hi = vec[idx].i; + } else { + lo = vec[idx].lo; + hi = vec[idx].hi; + } + } +} + +Operand::Operand(Table *tbl, const Table::Actions::Action *act, const value_t &v) : op(0) { + if (v.type == tINT) { + op = new Const(v.lineno, v.i); + } else if (CHECKTYPE2(v, tSTR, tCMD)) { + std::string name = v.type == tSTR ? v.s : v[0].s; + std::string p4name = name; + TableOutputModifier mod = TableOutputModifier::NONE; + int lo = -1, hi = -1; + if (v.type == tCMD) { + if (v == "hash_dist" && (op = HashDist::parse(tbl, v.vec))) return; + if (v == "rng" && (op = new RandomGen(tbl, v.vec))) return; + if (v.vec.size > 1 && (v[1] == "color" || v[1] == "address")) { + if (v[1] == "color") mod = TableOutputModifier::Color; + if (v[1] == "address") mod = TableOutputModifier::Address; + if (v[1].type == tCMD) + parse_slice(v[1].vec, 1, lo, hi); + else if (v.vec.size > 2) + parse_slice(v.vec, 2, lo, hi); + } else { + parse_slice(v.vec, 1, lo, hi); + } + } + name = act->alias_lookup(v.lineno, name, lo, hi); + if (name == "hash_dist" && lo == hi) { + auto hd = new HashDist(v.lineno, tbl, lo); + if (v.type == tCMD && v[1].type == tRANGE) { + hd->lo = v[1].lo; + hd->hi = v[1].hi; + } + op = hd; + return; + } + op = new Named(v.lineno, name, mod, lo, hi, tbl, act->name, p4name); + } +} + +auto Operand::Named::lookup(Base *&ref) -> Base * { + int slot, len = -1; + if (tbl->action) tbl = tbl->action; + int lo = this->lo >= 0 ? this->lo : 0; + if (auto *field = tbl->lookup_field(name, action)) { + if (!options.match_compiler) { + /* FIXME -- The glass compiler generates refs past the end of action table fields + * like these, and just accesses whatever bits happen to be there. So we + * supress these error checks for compatibility (ex: tests/action_bus1.p4) */ + if ((unsigned)lo >= field->size) { + error(lineno, "Bit %d out of range for field %s", lo, name.c_str()); + ref = 0; + } else if (hi >= 0 && (unsigned)hi >= field->size) { + error(lineno, "Bit %d out of range for field %s", hi, name.c_str()); + ref = 0; + } + } + if (ref) { + ref = new Action(lineno, name, tbl, field, lo, hi >= 0 ? hi : field->size - 1, p4name); + } + } else if (tbl->find_on_actionbus(name, mod, lo, hi >= 0 ? hi : 7, 0, &len) >= 0) { + ref = new Action(lineno, name, mod, tbl, lo, hi >= 0 ? hi : len - 1, p4name); + } else if (::Phv::get(tbl->gress, tbl->stage->stageno, name)) { + ref = new Phv(lineno, tbl->gress, tbl->stage->stageno, name, lo, hi); + } else if (sscanf(name.c_str(), "A%d%n", &slot, &len) >= 1 && + len == static_cast(name.size()) && slot >= 0 && slot < 32) { + ref = new RawAction(lineno, slot, lo); + } else if (name == "hash_dist" && (lo == hi || hi < 0)) { + ref = new HashDist(lineno, tbl, lo); + } else if (Table::all->count(name)) { + ref = new Action(lineno, name, mod, tbl, lo, hi, p4name); + } else { + ref = new Phv(lineno, tbl->gress, tbl->stage->stageno, name, this->lo, hi); + } + if (ref != this) delete this; + return ref; +} + +struct VLIWInstruction : Instruction { + explicit VLIWInstruction(int l) : Instruction(l) {} + virtual int encode() = 0; +#if HAVE_JBAY + template + void write_regs_2(REGS ®s, Table *tbl, Table::Actions::Action *act); +#endif /* HAVE_JBAY || */ + FOR_ALL_REGISTER_SETS(DECLARE_FORWARD_VIRTUAL_INSTRUCTION_WRITE_REGS) +}; + +// target specific template specializations +#include "tofino/instruction.cpp" // NOLINT(build/include) +#if HAVE_JBAY +#include "jbay/instruction.cpp" // NOLINT(build/include) +#endif /* HAVE_JBAY */ + +struct AluOP : VLIWInstruction { + enum special_flags { + Commutative = 1, + IgnoreSrc1 = 2, + IgnoreSrc2 = 4, + IgnoreSrcs = 6, + CanSliceWithConst = 8 + }; + const struct Decode : Instruction::Decode { + std::string name; + unsigned opcode; + const Decode *swap_args; + int flags = 0; + Decode(const char *n, unsigned opc, int flgs = 0, const char *alias_name = 0) + : Instruction::Decode(n), + name(n), + opcode(opc), + swap_args(flgs & Commutative ? this : 0), + flags(flgs) { + if (alias_name) alias(alias_name); + } + Decode(const char *n, target_t targ, unsigned opc, int flgs = 0) + : Instruction::Decode(n, targ), + name(n), + opcode(opc), + swap_args(flgs & Commutative ? this : 0), + flags(flgs) {} + Decode(const char *n, std::set targ, unsigned opc, int flgs = 0, + const char *alias_name = 0) + : Instruction::Decode(n, targ), + name(n), + opcode(opc), + swap_args(flgs & Commutative ? this : 0), + flags(flgs) { + if (alias_name) alias(alias_name); + } + Decode(const char *n, unsigned opc, int flgs, Decode *sw, const char *alias_name = 0) + : Instruction::Decode(n), name(n), opcode(opc), swap_args(sw), flags(flgs) { + if (sw && !sw->swap_args) sw->swap_args = this; + if (alias_name) alias(alias_name); + } + Decode(const char *n, unsigned opc, Decode *sw, const char *alias_name = 0) + : Instruction::Decode(n), name(n), opcode(opc), swap_args(sw) { + if (sw && !sw->swap_args) sw->swap_args = this; + if (alias_name) alias(alias_name); + } + Decode(const char *n, target_t targ, unsigned opc, Decode *sw, const char *alias_name = 0) + : Instruction::Decode(n, targ), name(n), opcode(opc), swap_args(sw) { + if (sw && !sw->swap_args) sw->swap_args = this; + if (alias_name) alias(alias_name); + } + Decode(const char *n, std::set targ, unsigned opc, Decode *sw, + const char *alias_name = 0) + : Instruction::Decode(n, targ), name(n), opcode(opc), swap_args(sw) { + if (sw && !sw->swap_args) sw->swap_args = this; + if (alias_name) alias(alias_name); + } + Decode(const char *n, std::set targ, unsigned opc, int flgs, Decode *sw, + const char *alias_name = 0) + : Instruction::Decode(n, targ), name(n), opcode(opc), swap_args(sw), flags(flgs) { + if (sw && !sw->swap_args) sw->swap_args = this; + if (alias_name) alias(alias_name); + } + Instruction *decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const override; + } *opc; + Phv::Ref dest; + Operand src1, src2; + bool ignoreSrc1 = false, ignoreSrc2 = false; + AluOP(const Decode *op, Table *tbl, const Table::Actions::Action *act, const value_t &d, + const value_t &s1, const value_t &s2) + : VLIWInstruction(d.lineno), + opc(op), + dest(tbl->gress, tbl->stage->stageno + 1, d), + src1(tbl, act, s1), + src2(tbl, act, s2) {} + std::string name() override { return opc->name; } + Instruction *pass1(Table *tbl, Table::Actions::Action *) override; + void pass2(Table *tbl, Table::Actions::Action *) override { + if (!ignoreSrc1) src1->pass2(slot / Phv::mau_groupsize()); + if (!ignoreSrc2) src2->pass2(slot / Phv::mau_groupsize()); + } + int encode() override; + bool equiv(Instruction *a_) override; + bool phvRead(std::function fn) override { + bool rv = false; + if (!ignoreSrc1) rv |= src1.phvRead(fn); + if (!ignoreSrc2) rv |= src2.phvRead(fn); + return rv; + } + void dbprint(std::ostream &out) const override { + out << "INSTR: " << opc->name << ' ' << dest << ", " << src1 << ", " << src2; + } +}; + +struct AluOP3Src : AluOP { + struct Decode : AluOP::Decode { + Decode(const char *n, unsigned opc) : AluOP::Decode(n, opc) {} + Decode(const char *n, target_t t, unsigned opc) : AluOP::Decode(n, t, opc) {} + Decode(const char *n, std::set t, unsigned opc) : AluOP::Decode(n, t, opc) {} + Instruction *decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const override; + }; + Operand src3; + AluOP3Src(const Decode *op, Table *tbl, const Table::Actions::Action *act, const value_t &d, + const value_t &s1, const value_t &s2, const value_t &s3) + : AluOP(op, tbl, act, d, s1, s2), src3(tbl, act, s3) {} + Instruction *pass1(Table *tbl, Table::Actions::Action *); + void pass2(Table *tbl, Table::Actions::Action *); +}; + +Instruction *AluOP::Decode::decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const { + AluOP *rv; + if (op.size == 4) { + rv = new AluOP(this, tbl, act, op.data[1], op.data[2], op.data[3]); + } else if (op.size == 3) { + if (!(flags & IgnoreSrc1) && (flags & IgnoreSrc2)) { + rv = new AluOP(this, tbl, act, op.data[1], op.data[2], op.data[2]); + rv->ignoreSrc2 = true; + } else { + rv = new AluOP(this, tbl, act, op.data[1], op.data[1], op.data[2]); + rv->ignoreSrc1 = (flags & IgnoreSrc1) != 0; + } + } else if (op.size == 3 && (flags & IgnoreSrc1) && (flags & IgnoreSrc2)) { + rv = new AluOP(this, tbl, act, op.data[1], op.data[1], op.data[1]); + rv->ignoreSrc1 = rv->ignoreSrc2 = true; + } else { + error(op[0].lineno, "%s requires 2 or 3 operands", op[0].s); + return 0; + } + if (!rv->src1.valid()) + error(op[2].lineno, "invalid src1"); + else if (!rv->src2.valid()) + error(op[3].lineno, "invalid src2"); + else + return rv; + delete rv; + return 0; +} +Instruction *AluOP3Src::Decode::decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const { + if (op.size != 5) { + if (op.size < 3 || op.size > 5) { + error(op[0].lineno, "%s requires 2, 3 or 4 operands", op[0].s); + return 0; + } else { + } + return AluOP::Decode::decode(tbl, act, op); + } + auto rv = new AluOP3Src(this, tbl, act, op.data[1], op.data[2], op.data[3], op.data[4]); + if (!rv->src1.valid()) + error(op[2].lineno, "invalid src1"); + else if (!rv->src2.valid()) + error(op[3].lineno, "invalid src2"); + else if (!rv->src3.valid()) + error(op[3].lineno, "invalid src3"); + else + return rv; + delete rv; + return 0; +} + +static bool will_pad_with_zeros(const Phv::Slice &dest, Table::Actions::Action *, + Operand::Action *ad) { + if (ad->lo != dest.lo || ad->hi != dest.hi) { + // need to line up with the destination, if it doesn't reject + // FIXME could we rotate the data in the field if everything else was ok? The + // compiler should have done that already + return false; + } + if (ad->field->bits.size() != 1) { + // punt for split fields. Not sure this can ever happen + return false; + } + // If Operand::Action is for immediate, check if the immediate is at the top end of the + // immediate overhead. The immediate extract mask in these cases will set the additional bits to + // zero (zero extend). Hence we dont need to check if the size is the same as destination + // register size. + // This check will be false for cases when Operand::Action is not immediate as immed_size will + // be zero + if (ad->field->immed_bit(ad->field->size) == ad->field->fmt->immed_size) return true; + if (ad->field->size < dest.reg.size) { + // field not big enough + return false; + } + // FIXME -- should check that the action has no other uses of this AD operand that uses + // other bits? Not trivial to do + return true; +} + +Instruction *AluOP::pass1(Table *tbl, Table::Actions::Action *act) { + if (!dest.check()) return this; + if (!ignoreSrc1 && !src1.check()) return this; + if (!ignoreSrc2 && !src2.check()) return this; + if (dest->reg.mau_id() < 0) { + error(dest.lineno, "%s not accessable in mau", dest->reg.name); + return this; + } + if (dest->reg.type != Phv::Register::NORMAL) { + error(dest.lineno, "%s dest can't be dark or mocha phv", opc->name.c_str()); + return this; + } + slot = dest->reg.mau_id(); + tbl->stage->action_set[tbl->gress][dest->reg.uid] = true; + if (!ignoreSrc1) src1->pass1(tbl, slot / Phv::mau_groupsize()); + if (!ignoreSrc2) src2->pass1(tbl, slot / Phv::mau_groupsize()); + if (!ignoreSrc2 && src2.phvGroup() < 0 && opc->swap_args) { + std::swap(src1, src2); + std::swap(ignoreSrc1, ignoreSrc2); + opc = opc->swap_args; + } + if (!ignoreSrc2 && src2.phvGroup() < 0) error(lineno, "src2 must be phv register"); + if (dest->lo || dest->hi != dest->reg.size - 1) { + if ((opc->flags & CanSliceWithConst) && Operand(dest) == src2) { + // special case -- bitwise op wih dest==src2 and src1 is a constant or action + // data that is padded with 0s can just operate on the whole container to get + // the right result + auto *k = src1.to(); + if (k && k->value >= 0 && (k->value << dest->lo) < 8) { + k->value <<= dest->lo; + // FIXME -- should rewrite dest and src2 to refer to the whole container for + // strict correctness? We don't actually look at the slice after this so maybe ok + return this; + } + auto *ad = src1.to(); + if (ad && will_pad_with_zeros(*dest, act, ad)) return this; + } + error(lineno, "ALU ops cannot operate on slices"); + } + return this; +} +Instruction *AluOP3Src::pass1(Table *tbl, Table::Actions::Action *act) { + AluOP::pass1(tbl, act); + src3->pass1(tbl, slot / Phv::mau_groupsize()); + if (!src3.to()) error(lineno, "src3 must be on the action bus"); + return this; +} +void AluOP3Src::pass2(Table *tbl, Table::Actions::Action *act) { + AluOP::pass2(tbl, act); + src3->pass2(slot / Phv::mau_groupsize()); + if (auto s1 = src1.to()) { + auto s3 = src3.to(); + if (s1->bits(slot / Phv::mau_groupsize()) + 1 != s3->bits(slot / Phv::mau_groupsize())) + error(lineno, "src1 and src3 must be adjacent on the action bus"); + } else { + error(lineno, "src1 must be on the action bus"); + } +} + +int AluOP::encode() { + int rv = (opc->opcode << 6); + if (!ignoreSrc1) rv |= src1.bits(slot / Phv::mau_groupsize()); + rv <<= Target::INSTR_SRC2_BITS(); + if (!ignoreSrc2) rv |= src2.bits(slot / Phv::mau_groupsize()); + return rv; +} +bool AluOP::equiv(Instruction *a_) { + if (auto *a = dynamic_cast(a_)) { + return opc == a->opc && dest == a->dest && src1 == a->src1 && src2 == a->src2 && + ignoreSrc1 == a->ignoreSrc1 && ignoreSrc2 == a->ignoreSrc2; + } else { + return false; + } +} + +struct LoadConst : VLIWInstruction { + struct Decode : Instruction::Decode { + Decode(const char *n, std::set targ) : Instruction::Decode(n, targ) {} + Instruction *decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const override; + }; + Phv::Ref dest; + int src; + LoadConst(Table *tbl, const Table::Actions::Action *act, const value_t &d, int s) + : VLIWInstruction(d.lineno), dest(tbl->gress, tbl->stage->stageno + 1, d), src(s) {} + LoadConst(int line, Phv::Ref &d, int v) : VLIWInstruction(line), dest(d), src(v) {} + std::string name() override { return ""; } + Instruction *pass1(Table *tbl, Table::Actions::Action *) override; + void pass2(Table *, Table::Actions::Action *) override {} + int encode() override { return Target::encodeConst(src); } + bool equiv(Instruction *a_) override; + bool phvRead(std::function fn) override { return false; } + void dbprint(std::ostream &out) const override { out << "INSTR: set " << dest << ", " << src; } +}; + +Instruction *LoadConst::Decode::decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const { + if (op.size != 3) { + error(op[0].lineno, "%s requires 2 operands", op[0].s); + return 0; + } + if (!CHECKTYPE(op[2], tINT)) return 0; + return new LoadConst(tbl, act, op[1], op[2].i); +} + +Instruction *LoadConst::pass1(Table *tbl, Table::Actions::Action *) { + if (!dest.check()) return this; + if (dest->reg.mau_id() < 0) { + error(dest.lineno, "%s not accessable in mau", dest->reg.name); + return this; + } + if (dest->reg.type != Phv::Register::NORMAL) { + error(dest.lineno, "load-const dest can't be dark or mocha phv"); + return this; + } + if (dest->lo || dest->hi != dest->reg.size - 1) { + error(lineno, "load-const cannot operate on slices"); + return this; + } + slot = dest->reg.mau_id(); + int size = Phv::reg(slot)->size; + int minval = -1 << (size - 1); + if (size > 21) { + size = 21; + minval = 0; + } + // For an 8 or 16 bit PHV, the constant to load is 8 (or 16) bits, so + // there's no need for sign extension to deal with a negative value. For + // 32 bit PHVs, the constant is 21 bits and zero-extended to 32 bits, so + // must be positive. + if (src >= (1 << size) || src < minval) error(lineno, "Constant value %d out of range", src); + src &= (1 << size) - 1; + tbl->stage->action_set[tbl->gress][dest->reg.uid] = true; + return this; +} + +bool LoadConst::equiv(Instruction *a_) { + if (auto *a = dynamic_cast(a_)) { + return dest == a->dest && src == a->src; + } else { + return false; + } +} + +struct CondMoveMux : VLIWInstruction { + const struct Decode : Instruction::Decode { + std::string name; + unsigned opcode, cond_size; + bool src2opt; + Decode(const char *name, unsigned opc, unsigned csize, bool s2opt, const char *alias_name) + : Instruction::Decode(name), name(name), opcode(opc), cond_size(csize), src2opt(s2opt) { + alias(alias_name); + } + Decode(const char *name, target_t targ, unsigned opc, unsigned csize, bool s2opt, + const char *alias_name) + : Instruction::Decode(name, targ), + name(name), + opcode(opc), + cond_size(csize), + src2opt(s2opt) { + alias(alias_name); + } + Decode(const char *name, std::set targ, unsigned opc, unsigned csize, bool s2opt, + const char *alias_name) + : Instruction::Decode(name, targ), + name(name), + opcode(opc), + cond_size(csize), + src2opt(s2opt) { + alias(alias_name); + } + Instruction *decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const override; + } *opc; + Phv::Ref dest; + Operand src1, src2; + unsigned cond = 0; + CondMoveMux(Table *tbl, const Decode *op, const Table::Actions::Action *act, const value_t &d, + const value_t &s) + : VLIWInstruction(d.lineno), + opc(op), + dest(tbl->gress, tbl->stage->stageno + 1, d), + src1(tbl, act, s), + src2(tbl->gress, tbl->stage->stageno, d) {} + CondMoveMux(Table *tbl, const Decode *op, const Table::Actions::Action *act, const value_t &d, + const value_t &s1, const value_t &s2) + : VLIWInstruction(d.lineno), + opc(op), + dest(tbl->gress, tbl->stage->stageno + 1, d), + src1(tbl, act, s1), + src2(tbl, act, s2) {} + std::string name() { return opc->name; } + Instruction *pass1(Table *tbl, Table::Actions::Action *); + void pass2(Table *tbl, Table::Actions::Action *) { + src1->pass2(slot / Phv::mau_groupsize()); + src2->pass2(slot / Phv::mau_groupsize()); + } + int encode(); + bool equiv(Instruction *a_); + bool phvRead(std::function fn) { + bool rv = false; + if (cond & 1) { + fn(*dest); + rv = true; + } + rv |= src1.phvRead(fn); + if (!opc->src2opt || (cond & 4)) rv |= src2.phvRead(fn); + return rv; + } + void dbprint(std::ostream &out) const { + out << "INSTR: cmov " << dest << ", " << src1 << ", " << src2; + } +}; + +Instruction *CondMoveMux::Decode::decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const { + if (op.size != 5 && (op.size != 4 || !src2opt)) { + error(op[0].lineno, "%s requires %s4 operands", op[0].s, src2opt ? "3 or " : ""); + return 0; + } + if (!CHECKTYPE(op[op.size - 1], tINT)) { + if (op[op.size - 1].i < 0 || op[op.size - 1].i >= (1 << cond_size)) { + error(op[op.size - 1].lineno, "%s condition must be %d-bit constant", op[0].s, + cond_size); + return 0; + } + } + CondMoveMux *rv; + if (op.size == 5) + rv = new CondMoveMux(tbl, this, act, op[1], op[2], op[3]); + else + rv = new CondMoveMux(tbl, this, act, op[1], op[2]); + rv->cond = op[op.size - 1].i; + if (!rv->src1.valid()) + error(op[2].lineno, "invalid src1"); + else if (!rv->src2.valid()) + error(op[3].lineno, "invalid src2"); + else + return rv; + delete rv; + return 0; +} + +Instruction *CondMoveMux::pass1(Table *tbl, Table::Actions::Action *) { + if (!dest.check() || !src1.check() || !src2.check()) return this; + if (dest->reg.mau_id() < 0) { + error(dest.lineno, "%s not accessable in mau", dest->reg.name); + return this; + } + if (dest->reg.type != Phv::Register::NORMAL) { + error(dest.lineno, "%s dest can't be dark or mocha phv", opc->name.c_str()); + return this; + } + slot = dest->reg.mau_id(); + tbl->stage->action_set[tbl->gress][dest->reg.uid] = true; + src1->pass1(tbl, slot / Phv::mau_groupsize()); + src2->pass1(tbl, slot / Phv::mau_groupsize()); + return this; +} +int CondMoveMux::encode() { + int rv = (cond << 11) | (opc->opcode << 6) | src1.bits(slot / Phv::mau_groupsize()); + rv <<= Target::INSTR_SRC2_BITS(); + /* funny cond test on src2 is to match the compiler output -- if we're not testing + * src2 validity, what we specify as src2 is irrelevant */ + return rv | (cond & 0x40 ? src2.bits(slot / Phv::mau_groupsize()) : 0); +} +bool CondMoveMux::equiv(Instruction *a_) { + if (auto *a = dynamic_cast(a_)) { + return opc == a->opc && dest == a->dest && src1 == a->src1 && src2 == a->src2 && + cond == a->cond; + } else { + return false; + } +} + +/** + * This instruction represents the Byte-Rotate-Merge instruction described in the + * uArch section 14.1.6.5 Byte-rotate-merge section. + */ +struct ByteRotateMerge : VLIWInstruction { + struct Decode : Instruction::Decode { + Decode() : Instruction::Decode("byte_rotate_merge") { alias("byte-rotate-merge"); } + Instruction *decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const; + }; + Phv::Ref dest; + Operand src1, src2; + bitvec byte_mask; + int src1_shift, src2_shift; + ByteRotateMerge(Table *tbl, const Table::Actions::Action *act, const value_t &d, + const value_t &s1, const value_t &s2, int s1s, int s2s, int bm) + : VLIWInstruction(d.lineno), + dest(tbl->gress, tbl->stage->stageno + 1, d), + src1(tbl, act, s1), + src2(tbl, act, s2), + src1_shift(s1s), + src2_shift(s2s), + byte_mask(bm) {} + + std::string name() { return "byte_rotate_merge"; } + Instruction *pass1(Table *tbl, Table::Actions::Action *); + void pass2(Table *tbl, Table::Actions::Action *) { + src1->pass2(slot / Phv::mau_groupsize()); + src2->pass2(slot / Phv::mau_groupsize()); + } + int encode(); + bool equiv(Instruction *a_); + bool phvRead(std::function fn) { + return src1.phvRead(fn) | src2.phvRead(fn); + } + void dbprint(std::ostream &out) const { + out << "INSTR: byte_rotate_merge " << dest << ", " << src1 << ", " << src2 << " " + << byte_mask; + } +}; + +/** + * Unlike deposit-field, because of the non-contiguity of both sources possibly, the + * full instruction with both sources, shifts and byte mask are required + */ +Instruction *ByteRotateMerge::Decode::decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const { + if (op.size != 7) { + error(op[0].lineno, "%s requires 6 operands", op[0].s); + return 0; + } + if (!CHECKTYPE(op[4], tINT) || !CHECKTYPE(op[5], tINT) || !CHECKTYPE(op[6], tINT)) { + error(op[0].lineno, "%s requires operands 3-5 to be ints", op[0].s); + return 0; + } + + ByteRotateMerge *rv = + new ByteRotateMerge(tbl, act, op[1], op[2], op[3], op[4].i, op[5].i, op[6].i); + if (!rv->src1.valid()) + error(op[2].lineno, "invalid src1"); + else if (!rv->src2.valid()) + error(op[3].lineno, "invalid src2"); + else + return rv; + delete rv; + return 0; +} + +/** + * The shifts at most can be container.size / 8 and the byte mask bit count can be at most + * container.size / 8. + */ +Instruction *ByteRotateMerge::pass1(Table *tbl, Table::Actions::Action *) { + if (!dest.check() || !src1.check() || !src2.check()) return this; + if (dest->reg.mau_id() < 0) { + error(dest.lineno, "%s not accessable in mau", dest->reg.name); + return this; + } + if (dest->reg.type != Phv::Register::NORMAL) { + error(dest.lineno, "byte-rotate-merge dest can't be dark or mocha phv"); + return this; + } + if (dest->reg.size == 8) { + error(dest.lineno, "byte-rotate-merge invalid on 8 bit containers"); + return this; + } + if (byte_mask.max().index() > dest->reg.size / 8) { + error(dest.lineno, "byte-rotate-merge mask beyond container size bounds"); + return this; + } + if (src1_shift > dest->reg.size / 8) { + error(dest.lineno, "byte-rotate-merge src1_shift beyond container size bounds"); + return this; + } + if (src2_shift > dest->reg.size / 8) { + error(dest.lineno, "byte-rotate-merge src2_shift beyond container size bounds"); + return this; + } + slot = dest->reg.mau_id(); + tbl->stage->action_set[tbl->gress][dest->reg.uid] = true; + src1->pass1(tbl, slot / Phv::mau_groupsize()); + src2->pass1(tbl, slot / Phv::mau_groupsize()); + src2->pass1(tbl, slot / Phv::mau_groupsize()); + if (src2.phvGroup() < 0) { + std::swap(src1, src2); + std::swap(src1_shift, src2_shift); + byte_mask = bitvec(0, dest->reg.size / 8) - byte_mask; + } + if (src2.phvGroup() < 0) error(lineno, "src2 must be phv register"); + return this; +} + +int ByteRotateMerge::encode() { + int bits = (0xa << 6) | src1.bits(slot / Phv::mau_groupsize()); + bits |= (byte_mask.getrange(0, 4)) << 10; + bits |= (src1_shift << 17); + bits |= (src2_shift << 15); + bits <<= Target::INSTR_SRC2_BITS(); + return bits | src2.bits(slot / Phv::mau_groupsize()); +} + +bool ByteRotateMerge::equiv(Instruction *a_) { + if (auto *a = dynamic_cast(a_)) { + return dest == a->dest && src1 == a->src1 && src2 == a->src2 && byte_mask == a->byte_mask && + src1_shift == a->src1_shift && src2_shift == a->src2_shift; + } else { + return false; + } +} + +struct Set; + +struct DepositField : VLIWInstruction { + struct Decode : Instruction::Decode { + Decode() : Instruction::Decode("deposit_field") { alias("deposit-field"); } + Instruction *decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const override; + }; + Phv::Ref dest; + Operand src1, src2; + DepositField(Table *tbl, const Table::Actions::Action *act, const value_t &d, const value_t &s) + : VLIWInstruction(d.lineno), + dest(tbl->gress, tbl->stage->stageno + 1, d), + src1(tbl, act, s), + src2(tbl->gress, tbl->stage->stageno, d) {} + DepositField(Table *tbl, const Table::Actions::Action *act, const value_t &d, const value_t &s1, + const value_t &s2) + : VLIWInstruction(d.lineno), + dest(tbl->gress, tbl->stage->stageno + 1, d), + src1(tbl, act, s1), + src2(tbl, act, s2) {} + DepositField(Table *tbl, const Set &); + std::string name() { return "deposit_field"; } + Instruction *pass1(Table *tbl, Table::Actions::Action *); + void pass2(Table *tbl, Table::Actions::Action *) { + src1->pass2(slot / Phv::mau_groupsize()); + src2->pass2(slot / Phv::mau_groupsize()); + } + int encode(); + bool equiv(Instruction *a_); + bool phvRead(std::function fn) { + return src1.phvRead(fn) | src2.phvRead(fn); + } + void dbprint(std::ostream &out) const { + out << "INSTR: deposit_field " << dest << ", " << src1 << ", " << src2; + } +}; + +Instruction *DepositField::Decode::decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const { + if (op.size != 4 && op.size != 3) { + error(op[0].lineno, "%s requires 2 or 3 operands", op[0].s); + return 0; + } + DepositField *rv; + if (op.size == 4) + rv = new DepositField(tbl, act, op[1], op[2], op[3]); + else + rv = new DepositField(tbl, act, op[1], op[2]); + if (!rv->src1.valid()) + error(op[2].lineno, "invalid src1"); + else if (!rv->src2.valid()) + error(op[3].lineno, "invalid src2"); + else + return rv; + delete rv; + return 0; +} + +Instruction *DepositField::pass1(Table *tbl, Table::Actions::Action *act) { + if (!dest.check() || !src1.check() || !src2.check()) return this; + if (dest->reg.mau_id() < 0) { + error(dest.lineno, "%s not accessable in mau", dest->reg.name); + return this; + } + if (dest->reg.type != Phv::Register::NORMAL) { + error(dest.lineno, "deposit-field dest can't be dark or mocha phv"); + return this; + } + slot = dest->reg.mau_id(); + tbl->stage->action_set[tbl->gress][dest->reg.uid] = true; + src1->pass1(tbl, slot / Phv::mau_groupsize()); + src2->pass1(tbl, slot / Phv::mau_groupsize()); + return this; +} +int DepositField::encode() { + // If src1 is an Operand::Const (and we pass a valid dest_size), + // we will recieve the combined rotation + bits from DepositField::discoverRotation(). + // Otherwise the top 'RotationBits' will be zero. + int rotConst = src1.bits(slot / Phv::mau_groupsize(), dest.size()); + unsigned rot = rotConst >> RotationBits; + rot += dest->reg.size - dest->lo + src1.bitoffset(slot / Phv::mau_groupsize()); + rot %= dest->reg.size; + int bits = rotConst & ((1U << RotationBits) - 1); + bits |= (1 << 6); + bits |= dest->hi << 7; + bits |= rot << 12; + switch (Phv::reg(slot)->size) { + case 8: + bits |= (dest->lo & 3) << 10; + bits |= (dest->lo & ~3) << 13; + break; + case 16: + bits |= (dest->lo & 1) << 11; + bits |= (dest->lo & ~1) << 15; + break; + case 32: + bits |= dest->lo << 17; + break; + default: + BUG(); + } + bits <<= Target::INSTR_SRC2_BITS(); + return bits | src2.bits(slot / Phv::mau_groupsize()); +} +bool DepositField::equiv(Instruction *a_) { + if (auto *a = dynamic_cast(a_)) { + return dest == a->dest && src1 == a->src1 && src2 == a->src2; + } else { + return false; + } +} + +struct Set : VLIWInstruction { + struct Decode : Instruction::Decode { + std::string name; + Decode(const char *n, std::set targ) : Instruction::Decode(n, targ), name(n) {} + Instruction *decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const override; + }; + Phv::Ref dest; + Operand src; + static AluOP::Decode *opA; + Set(Table *tbl, const Table::Actions::Action *act, const value_t &d, const value_t &s) + : VLIWInstruction(d.lineno), + dest(tbl->gress, tbl->stage->stageno + 1, d), + src(tbl, act, s) {} + std::string name() { return "set"; } + Instruction *pass1(Table *tbl, Table::Actions::Action *); + void pass2(Table *tbl, Table::Actions::Action *) { src->pass2(slot / Phv::mau_groupsize()); } + int encode(); + bool equiv(Instruction *a_); + bool phvRead(std::function fn) { return src.phvRead(fn); } + void dbprint(std::ostream &out) const { out << "INSTR: set " << dest << ", " << src; } +}; + +DepositField::DepositField(Table *tbl, const Set &s) + : VLIWInstruction(s), dest(s.dest), src1(s.src), src2(::Phv::Ref(s.dest->reg, tbl->gress)) {} + +Instruction *Set::Decode::decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const { + if (op.size != 3) { + error(op[0].lineno, "%s requires 2 operands", op[0].s); + return 0; + } + Set *rv = new Set(tbl, act, op[1], op[2]); + if (!rv->src.valid()) + error(op[2].lineno, "invalid src"); + else + return rv; + delete rv; + return 0; +} + +Instruction *Set::pass1(Table *tbl, Table::Actions::Action *act) { + if (!dest.check() || !src.check()) return this; + if (dest->reg.mau_id() < 0) { + error(dest.lineno, "%s not accessable in mau", dest->reg.name); + return this; + } + if (dest->lo || dest->hi != dest->reg.size - 1) + return (new DepositField(tbl, *this))->pass1(tbl, act); + if (auto *k = src.to()) { + if (dest->reg.type == Phv::Register::DARK) { + error(dest.lineno, "can't set dark phv to a constant"); + return this; + } + int minsignconst = Target::MINIMUM_INSTR_CONSTANT(); + // Translate large value with negative value, e.g. 0xFFFE -> -2 on 16-bit PHV + int64_t maxvalue = 1LL << dest->reg.size; + int64_t delta = k->value - maxvalue; + if (delta >= minsignconst) k->value = delta; + if (k->value < minsignconst || k->value >= 8) + return (new LoadConst(lineno, dest, k->value))->pass1(tbl, act); + } + slot = dest->reg.mau_id(); + tbl->stage->action_set[tbl->gress][dest->reg.uid] = true; + src->pass1(tbl, slot / Phv::mau_groupsize()); + return this; +} + +int Set::encode() { + int rv = src.bits(slot / Phv::mau_groupsize()); + switch (dest->reg.type) { + case Phv::Register::NORMAL: + rv |= (opA->opcode << 6); + rv <<= Target::INSTR_SRC2_BITS(); + rv |= (slot & 0xf); + break; + case Phv::Register::MOCHA: + rv |= 0x40; + break; + case Phv::Register::DARK: + rv |= 0x20; + break; + default: + BUG(); + } + return rv; +} + +bool Set::equiv(Instruction *a_) { + if (auto *a = dynamic_cast(a_)) { + return dest == a->dest && src == a->src; + } else { + return false; + } +} + +struct NulOP : VLIWInstruction { + const struct Decode : Instruction::Decode { + std::string name; + unsigned opcode; + Decode(const char *n, unsigned opc) : Instruction::Decode(n), name(n), opcode(opc) {} + Decode(const char *n, target_t targ, unsigned opc) + : Instruction::Decode(n, targ), name(n), opcode(opc) {} + Decode(const char *n, std::set targ, unsigned opc) + : Instruction::Decode(n, targ), name(n), opcode(opc) {} + Instruction *decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const override; + } *opc; + Phv::Ref dest; + NulOP(Table *tbl, const Table::Actions::Action *act, const Decode *o, const value_t &d) + : VLIWInstruction(d.lineno), opc(o), dest(tbl->gress, tbl->stage->stageno + 1, d) {} + std::string name() { return opc->name; } + Instruction *pass1(Table *tbl, Table::Actions::Action *); + void pass2(Table *, Table::Actions::Action *) {} + int encode(); + bool equiv(Instruction *a_); + bool phvRead(std::function fn) { return false; } + void dbprint(std::ostream &out) const { out << "INSTR: " << opc->name << " " << dest; } +}; + +Instruction *NulOP::Decode::decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const { + if (op.size != 2) { + error(op[0].lineno, "%s requires 1 operand", op[0].s); + return 0; + } + return new NulOP(tbl, act, this, op[1]); +} + +Instruction *NulOP::pass1(Table *tbl, Table::Actions::Action *) { + if (!dest.check()) return this; + if (dest->reg.mau_id() < 0) { + error(dest.lineno, "%s not accessable in mau", dest->reg.name); + return this; + } + slot = dest->reg.mau_id(); + if (opc->opcode || !options.match_compiler) { + tbl->stage->action_set[tbl->gress][dest->reg.uid] = true; + } + return this; +} +int NulOP::encode() { return opc->opcode; } +bool NulOP::equiv(Instruction *a_) { + if (auto *a = dynamic_cast(a_)) { + return opc == a->opc && dest == a->dest; + } else { + return false; + } +} + +struct ShiftOP : VLIWInstruction { + const struct Decode : Instruction::Decode { + std::string name; + unsigned opcode; + bool use_src1; + Decode(const char *n, std::set targ, unsigned opc, bool funnel = false) + : Instruction::Decode(n, targ), name(n), opcode(opc), use_src1(funnel) {} + Instruction *decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const override; + } *opc; + Phv::Ref dest; + Operand src1, src2; + int shift = 0; + ShiftOP(const Decode *d, Table *tbl, const Table::Actions::Action *act, const value_t *ops) + : VLIWInstruction(ops->lineno), + opc(d), + dest(tbl->gress, tbl->stage->stageno + 1, ops[0]), + src1(tbl, act, ops[1]), + src2(tbl, act, ops[2]) { + if (opc->use_src1) { + if (CHECKTYPE(ops[3], tINT)) shift = ops[3].i; + } else { + src2 = src1; + if (CHECKTYPE(ops[2], tINT)) shift = ops[2].i; + } + } + std::string name() { return opc->name; } + Instruction *pass1(Table *tbl, Table::Actions::Action *); + void pass2(Table *tbl, Table::Actions::Action *) { + src1->pass2(slot / Phv::mau_groupsize()); + src2->pass2(slot / Phv::mau_groupsize()); + } + int encode(); + bool equiv(Instruction *a_); + bool phvRead(std::function fn) { + return src1.phvRead(fn) | src2.phvRead(fn); + } + void dbprint(std::ostream &out) const { + out << "INSTR: " << opc->name << ' ' << dest << ", " << src1 << ", " << shift; + } +}; + +Instruction *ShiftOP::Decode::decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const { + if (op.size != (use_src1 ? 5 : 4)) { + error(op[0].lineno, "%s requires %d operands", op[0].s, use_src1 ? 4 : 3); + return 0; + } + ShiftOP *rv = new ShiftOP(this, tbl, act, op.data + 1); + if (!rv->src1.valid()) + error(op[2].lineno, "invalid src1"); + else if (!rv->src2.valid()) + error(op[3].lineno, "invalid src2"); + else if (rv->shift < 0 || rv->shift > 0x1f) + error(op[3].lineno, "invalid shift"); + else + return rv; + delete rv; + return 0; +} + +Instruction *ShiftOP::pass1(Table *tbl, Table::Actions::Action *) { + if (!dest.check() || !src1.check() || !src2.check()) return this; + if (dest->reg.mau_id() < 0) { + error(dest.lineno, "%s not accessable in mau", dest->reg.name); + return this; + } + if (dest->reg.type != Phv::Register::NORMAL) { + error(dest.lineno, "%s dest can't be dark or mocha phv", opc->name.c_str()); + return this; + } + if (dest->lo) { + error(lineno, "shift ops cannot operate on slices"); + return this; + } + slot = dest->reg.mau_id(); + tbl->stage->action_set[tbl->gress][dest->reg.uid] = true; + src1->pass1(tbl, slot / Phv::mau_groupsize()); + src2->pass1(tbl, slot / Phv::mau_groupsize()); + if (src2.phvGroup() < 0) error(lineno, "src%s must be phv register", opc->use_src1 ? "2" : ""); + return this; +} +int ShiftOP::encode() { + int rv = (shift << 12) | (opc->opcode << 6); + if (opc->use_src1 || options.match_compiler) rv |= src1.bits(slot / Phv::mau_groupsize()); + rv <<= Target::INSTR_SRC2_BITS(); + return rv | src2.bits(slot / Phv::mau_groupsize()); +} +bool ShiftOP::equiv(Instruction *a_) { + if (auto *a = dynamic_cast(a_)) { + return opc == a->opc && dest == a->dest && src1 == a->src1 && src2 == a->src2 && + shift == a->shift; + } else { + return false; + } +} + +static std::set tofino12 = std::set({ + TOFINO, +#if HAVE_JBAY + JBAY, +#endif +}); + +// lifted from MAU uArch 15.1.6 +// If the operation is commutative operand swap is enabled +// OPNAME OPCODE +static AluOP::Decode opADD("add", tofino12, 0x23e, AluOP::Commutative), // NOLINT + opADDC("addc", tofino12, 0x2be, AluOP::Commutative), // NOLINT + opSUB("sub", tofino12, 0x33e), // NOLINT + opSUBC("subc", tofino12, 0x3be), // NOLINT + opSADDU("saddu", tofino12, 0x03e, AluOP::Commutative), // NOLINT + opSADDS("sadds", tofino12, 0x07e, AluOP::Commutative), // NOLINT + opSSUBU("ssubu", tofino12, 0x0be), // NOLINT + opSSUBS("ssubs", tofino12, 0x0fe), // NOLINT + opMINU("minu", tofino12, 0x13e, AluOP::Commutative), // NOLINT + opMINS("mins", tofino12, 0x17e, AluOP::Commutative), // NOLINT + opMAXU("maxu", tofino12, 0x1be, AluOP::Commutative), // NOLINT + opMAXS("maxs", tofino12, 0x1fe, AluOP::Commutative), // NOLINT + opSETZ("setz", tofino12, 0x01e, AluOP::Commutative + AluOP::IgnoreSrcs), // NOLINT + opNOR("nor", tofino12, 0x05e, AluOP::Commutative), // NOLINT + opANDCA("andca", tofino12, 0x09e, AluOP::CanSliceWithConst), // NOLINT + opANDCB("andcb", tofino12, 0x11e, &opANDCA), // NOLINT + opNOTB("notb", tofino12, 0x15e, AluOP::IgnoreSrc1, "not"), // NOLINT + opNOTA("nota", tofino12, 0x0de, AluOP::IgnoreSrc2, &opNOTB), // NOLINT + opXOR("xor", tofino12, 0x19e, AluOP::Commutative + AluOP::CanSliceWithConst), // NOLINT + opNAND("nand", tofino12, 0x1de, AluOP::Commutative), // NOLINT + opAND("and", tofino12, 0x21e, AluOP::Commutative), // NOLINT + opXNOR("xnor", tofino12, 0x25e, AluOP::Commutative), // NOLINT + opB("alu_b", tofino12, 0x29e, AluOP::IgnoreSrc1), // NOLINT + opORCA("orca", tofino12, 0x2de), // NOLINT + opA("alu_a", tofino12, 0x31e, AluOP::IgnoreSrc2, &opB), // NOLINT + opORCB("orcb", tofino12, 0x35e, &opORCA), // NOLINT + opOR("or", tofino12, 0x39e, AluOP::Commutative + AluOP::CanSliceWithConst), // NOLINT + opSETHI("sethi", tofino12, 0x3de, AluOP::Commutative + AluOP::IgnoreSrcs); // NOLINT +static LoadConst::Decode opLoadConst("load-const", tofino12); // NOLINT +static Set::Decode opSet("set", tofino12); // NOLINT +static NulOP::Decode opNoop("noop", tofino12, 0x0); // NOLINT +static ShiftOP::Decode opSHL("shl", tofino12, 0x0c, false), // NOLINT + opSHRS("shrs", tofino12, 0x1c, false), // NOLINT + opSHRU("shru", tofino12, 0x14, false), // NOLINT + opFUNSHIFT("funnel-shift", tofino12, 0x4, true); // NOLINT +static DepositField::Decode opDepositField; +static ByteRotateMerge::Decode opByteRotateMerge; + +AluOP::Decode *Set::opA = &VLIW::opA; + +static AluOP3Src::Decode tf_opBMSET("bitmasked-set", TOFINO, 0x2e); // NOLINT +static CondMoveMux::Decode tf_opCondMove("cmov", TOFINO, 0x16, true, 5, + "conditional-move"); // NOLINT +static CondMoveMux::Decode tf_opCondMux("cmux", TOFINO, 0x6, false, 2, + "conditional-mux"); // NOLINT +static NulOP::Decode tf_opInvalidate("invalidate", TOFINO, 0x3800); // NOLINT + +#if HAVE_JBAY +static std::set jb_targets = std::set({ + JBAY, +}); + +static AluOP3Src::Decode jb_opBMSET("bitmasked-set", jb_targets, 0x0e); // NOLINT +static CondMoveMux::Decode jb_opCondMove("cmov", jb_targets, 0x6, true, 5, + "conditional-move"); // NOLINT +static AluOP::Decode jb_opGTEQU("gtequ", jb_targets, 0x02e), // NOLINT + jb_opGTEQS("gteqs", jb_targets, 0x06e), // NOLINT + jb_opLTU("ltu", jb_targets, 0x0ae), // NOLINT + jb_opLTS("lts", jb_targets, 0x0ee), // NOLINT + jb_opLEQU("lequ", jb_targets, 0x12e, &jb_opGTEQU), // NOLINT + jb_opLEQS("leqs", jb_targets, 0x16e, &jb_opGTEQS), // NOLINT + jb_opGTU("gtu", jb_targets, 0x1ae, &jb_opLTU), // NOLINT + jb_opGTS("gts", jb_targets, 0x1ee, &jb_opLTS), // NOLINT + jb_opEQ("eq", jb_targets, 0x22e, AluOP::Commutative), // NOLINT + jb_opNEQ("neq", jb_targets, 0x2ae, AluOP::Commutative), // NOLINT + jb_opEQ64("eq64", jb_targets, 0x26e, AluOP::Commutative), // NOLINT + jb_opNEQ64("neq64", jb_targets, 0x2ee, AluOP::Commutative); // NOLINT +#endif /* HAVE_JBAY || */ + +std::unique_ptr genNoopFill(Table *tbl, Table::Actions::Action *act, const char *op, + int slot) { + VECTOR(value_t) args; + VECTOR_init(args, 3); + args.add(op).add(Phv::reg(slot)->name).add(Phv::reg(slot)->name); + std::unique_ptr rv(Instruction::decode(tbl, act, args)); + VECTOR_fini(args); + return rv; +} + +} // end namespace VLIW + +void dump(const Instruction &inst) { std::cout << inst << std::endl; } diff --git a/backends/tofino/bf-asm/instruction.h b/backends/tofino/bf-asm/instruction.h new file mode 100644 index 00000000000..5e2c41df92d --- /dev/null +++ b/backends/tofino/bf-asm/instruction.h @@ -0,0 +1,75 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_INSTRUCTION_H_ +#define BF_ASM_INSTRUCTION_H_ + +#include + +#include + +#include "tables.h" + +struct Instruction : public IHasDbPrint { + int lineno; + int slot; + explicit Instruction(int l) : lineno(l), slot(-1) {} + virtual ~Instruction() {} + virtual Instruction *pass1(Table *, Table::Actions::Action *) = 0; + virtual std::string name() = 0; + virtual void pass2(Table *, Table::Actions::Action *) = 0; + virtual void dbprint(std::ostream &) const = 0; + virtual bool equiv(Instruction *a) = 0; + bool equiv(const std::unique_ptr &a) { return equiv(a.get()); } + virtual bool salu_output() const { return false; } + virtual bool salu_alu() const { return false; } + virtual bool phvRead(std::function) = 0; + bool phvRead() { + return phvRead([](const Phv::Slice &sl) {}); + } +#define VIRTUAL_TARGET_METHODS(TARGET) \ + virtual void write_regs(Target::TARGET::mau_regs &, Table *, Table::Actions::Action *) = 0; + FOR_ALL_REGISTER_SETS(VIRTUAL_TARGET_METHODS) +#undef VIRTUAL_TARGET_METHODS +#define DECLARE_FORWARD_VIRTUAL_INSTRUCTION_WRITE_REGS(TARGET) \ + void write_regs(Target::TARGET::mau_regs ®s, Table *tbl, Table::Actions::Action *act) \ + override; + static Instruction *decode(Table *, const Table::Actions::Action *, const VECTOR(value_t) &); + + enum instruction_set_t { VLIW_ALU = 0, STATEFUL_ALU = 1, NUM_SETS = 2 }; + struct Decode { + static std::multimap opcode[NUM_SETS]; + bool type_suffix; + unsigned targets; + explicit Decode(const char *name, int set = VLIW_ALU, bool ts = false); + Decode(const char *name, target_t target, int set = VLIW_ALU, bool ts = false); + Decode(const char *name, std::set target, int set = VLIW_ALU, bool ts = false); + const Decode &alias(const char *name, int set = VLIW_ALU, bool ts = false) { + opcode[set].emplace(name, this); + return *this; + } + virtual Instruction *decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const = 0; + }; +}; + +namespace VLIW { +std::unique_ptr genNoopFill(Table *tbl, Table::Actions::Action *act, const char *op, + int slot); +} + +#endif /* BF_ASM_INSTRUCTION_H_ */ diff --git a/backends/tofino/bf-asm/j2b.cpp b/backends/tofino/bf-asm/j2b.cpp new file mode 100644 index 00000000000..3888f460d62 --- /dev/null +++ b/backends/tofino/bf-asm/j2b.cpp @@ -0,0 +1,48 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "bson.h" + +int main(int ac, char **av) { + if (ac != 3) { + std::cerr << "usage " << av[0] << " " << std::endl; + return 1; + } + std::ifstream in(av[1]); + if (!in) { + std::cerr << "failed to open " << av[1] << std::endl; + return 1; + } + json::obj *data = nullptr; + if (!(in >> data)) { + std::cerr << "failed to read json" << std::endl; + return 1; + } + std::ofstream out(av[2]); + if (!out) { + std::cerr << "failed to open " << av[2] << std::endl; + return 1; + } + if (!(out << json::binary(data))) { + std::cerr << "failed to write bson" << std::endl; + return 1; + } + return 0; +} diff --git a/backends/tofino/bf-asm/jbay/CMakeLists.txt b/backends/tofino/bf-asm/jbay/CMakeLists.txt new file mode 100644 index 00000000000..87f256cfba4 --- /dev/null +++ b/backends/tofino/bf-asm/jbay/CMakeLists.txt @@ -0,0 +1,65 @@ +# Copyright (C) 2024 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# +# SPDX-License-Identifier: Apache-2.0 + +set (GEN_JBAY + memories.jbay_mem + memories.pipe_addrmap + memories.prsr_mem_main_rspec + regs.dprsr_reg + regs.epb_prsr4_reg + regs.ipb_prsr4_reg + regs.jbay_reg + regs.mau_addrmap + regs.pipe_addrmap + regs.pmerge_reg + regs.prsr_reg_main_rspec + ) + +foreach(f IN LISTS GEN_JBAY) + list (APPEND GEN_JBAY_SRCS ${BFASM_BINARY_DIR}/gen/jbay/${f}.cpp) + list (APPEND GEN_JBAY_HDRS ${BFASM_BINARY_DIR}/gen/jbay/${f}.h) +endforeach() + +add_custom_command(OUTPUT ${GEN_JBAY_HDRS} ${GEN_JBAY_SRCS} + COMMAND ${BFASM_WALLE} --schema chip.schema --generate-cpp template_objects.yaml -o ${BFASM_BINARY_DIR}/gen/jbay + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS template_objects.yaml chip.schema ${WALLE_SOURCES} + COMMENT "Generating cpp code for jbay from jbay/chip.schema") + +set_source_files_properties( + ${GEN_JBAY_SRCS} ${GEN_JBAY_HDRS} + PROPERTIES GENERATED TRUE) + +set (BFAS_JBAY_SRCS + jbay/gateway.cpp + jbay/input_xbar.cpp + jbay/stateful.cpp + jbay/parser.cpp + PARENT_SCOPE + ) + +set (BFAS_JBAY_HEADERS + jbay/counter.h + jbay/gateway.h + jbay/input_xbar.h + jbay/meter.h + jbay/stateful.h + PARENT_SCOPE + ) + +include_directories (${BFASM_BINARY_DIR}/gen/jbay) +add_library (regs_jbay ${GEN_JBAY_SRCS} ${GEN_JBAY_HDRS}) diff --git a/backends/tofino/bf-asm/jbay/chip.schema b/backends/tofino/bf-asm/jbay/chip.schema new file mode 100644 index 0000000000000000000000000000000000000000..5afef775e2dd881cd7521df7bda997e257a3dabc GIT binary patch literal 2250682 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 z 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

SXwJJbivKIR`r91-M{{;yf1Kj9BTdZuPEeeT zfn+*noZ>W=j;$(w4@v=wQzeJ$+c2g}D>V+9?LnzR%gK1iD2?q(ajGVa#6&8^X#)G> z6sL(aF_Dv?IH`eTB1=JW+L^8`mAs8DKyliIBQ=xEm}asTnq_h_T2AU9qfEAPLGr0k zrbvoYJwfE;G3@j93vvqk;}oY|X<{A)ijxLN=CO?wr$%}!lsf->E220xaipe>Dbm#K z2F+486)h*bLq@4%DGE@WrqPK`z4_I$KlkmyjyT0>Pw$eG-V2%&=i9{*j`pTIn_(Ws zX&?40&w%)KUi(4|r@{T8I@uqRX)cE1bO7CG#59W2fgGl<(=6~oFowVfLv?ZpBm?(A zCX1&y9ZKH{p)keiFb>kkhX&wq7z2PKpgK7ck^ovyaXO0r6+}A4>1YmAijx6321dI~ z9E+Bd;~=A@)xH#`;|Yn_6DUq6urE$=I?)5;0zCPotzHI5|)7CbOxg+qQVrXGdW1PGKT6b7_FXXqvhlr$f%wrrZ}BT z42cCSm-E;cr#PMOk+6UlKyz}TZ_gmF=px3k^5s#SE@r=0kNME*T>>ps?^38vE`wzC zW{Bc+IsIGRy883-#4&tO)%-hsS8$A$&EQ-Kqm}I{w47WG8I`Tg6sKz#EvG=?(kIul zFHUi~&c|edu7~F22H$QQ#py=6x4PtitZw1}eUZZ%YhiAN77B9w4&UJmXo_6S(J9AINeP&S~P!`l}vHEhoj;Yr+aB)_3ne> zl+#~6Pjvk`^dM58gl5L_xR^e-p`oee+*tn z%Xb_Wr#O926EpY&6emAIrf2Xc9$*dJYW|of&EGH3EPubE<>WU==I=j&;`BR_ z>T)c|I{JfS;uNPp{S=tUzo0q!+qcthL}uAF1X{U*-@yt7o0a1%?9 zoy-B5Ubs2wM+=urahi)=%F?h9bHix&g7cu|WM0UqP}5tv(Emw_QwL5+i0iG3bY!gb|HEhMw4g`6K+DC7cAoh%5MUdV-baB?9R zW|tPyLM#HK6>?FuoGbhPH|e&V`0vhg65>mx6^XIG@T^m zJU`qr9H}|y#5Ly`Xd&mzLUpnnWO~k*=fTN2Ux8hka|^K|jF$72&~nlZGP+8XlH$~z z05tI}5RQ6qWSrvElP2bVWhhR1L8fP-HxIDfw-B)pM{E9>1kL{{(EKGJqB!-1!AUtJ zWAkfo_TGWwC{6>U9|I6soZ>VfP@MX+J5ZcD1&Y%EACeTOfzX@`^6k=4oK|H#Elcxr zXupYJHFm@)POJO4EW==EPS)`4bc)lObYq2RrZ^3uU7x3OQkwF$poJyBHdH4=A(`xw zQk;e{oq2!h0+PT=O>tU}(G^=B#c6%^DaFZJqs zrr&C-%69alff6ZB+p}Na$%HuAnzI9pAXUxC<-N+;#AK8y5A{G6`#*3Fa{L6LUkgLMDagQacW>X zG+!Bf!QqD|nc~#Qfl6_*CDH_A$lGpEolJ$yT_T?1v^x*iI4x3~rg5xNoI)t>{5yor=hnThd~QjJshf&BOsa8 zqA5;C(w9c$0nrt)e)cPVWqyNO3xYy>W`u znLY{^&{@!&obB61QJl`9H=QJxj^CDv%`9WGC{E{ch`t%)q;v_L2Q8%ce5g(?fMj}G zq&Qtj9~v>4;&c%Q=w(Ucd5Y7;u!ew_Ky`8{Bm<7b$!k=}C{C9#xS}gSak`u%l;RZN zk>Yd(tXBLh(Qy>W`uwLTE*e;qU@*ZcNNiqpSBak_!^ zu}@S2#pyrGGfUoPIocB;!CDD-OT|?aS8xQak>ZA0PtR@PVR#wz?l@M_NO@A&yr}( zc!lT7ghCXj2RKwIPPU#OgfSHFA*fCshGg-0vzbhBdW3#7WIDy^Q4Um!QwRu((_=7( zfR96U@&qIU^0{vTiqn&Hq!H68PET>5Qk+6W+?+lQV~F?+R430uGGcKQr|0NXgQruR zp65WNI9c!)U<|=ugzDra$l`;)OrILO1&Y%v9H|s1i~cH%A^K}joxBd&Qgov@y+NNE zy#$#5fu$jnMo9I{kf0EeDd8 zPNLkr-{AkYU)7|_y1MFG>B3ONk#hp|+x+KaXPn~H)kowBbbe?~7Vzz2C{7E~na(&m zXOiNy5Y2kd8dSPfG-HSkVvM40eolbFDj1DveClpbf7N=RybQWR>7%iPkqUB^M z$S9p$hV4XgDkC1vc~?fsr8q6k{y4>H8Jd{&3=}8JLNXmQPH|d}j;$(w4@v=w)AAgu zZ^M`_t<(z8Y!AwcXgOI4GD>5+Qk=RGMq(nB;?$k}af(w9nwZF*P@Jp`$wZcd;?#?- zEtR~DEkJSV&5@c(W=u2L2byJa6||i6g^V)U$_2@N+Qm|w$_XMTk71v;r#SUvf1Kjf zpC;yU02C(!A(_X1(WL$UD}KJK>l!nYD|gS>Wzi$6smu8P`P{0H45GI}spGij4e+aS zq^6E3($uX6%~H2IT22N-MyX>d3Q(NZpc9>X^Q&cl?pu=`af;Ir?~;>V3!0O)eY-fq z(NMax8Rk)(hOu9H2E?!PS_fJ<4GxFuWL-$6xfqJm2)faTX%wgRI80xsS>W|y41qU* z>SQD&1NT5Ci>EkkNZ$&fFvY2YgY@yC0oVw}0ALhUCmTZ&Ki{WVE!}m*TV~ArX55#c3<{#VJmsJuoiNt)V&D#T9WViZMGnBp{sgOn>{sK&x*^{hn8$vDWU zo+YL@RS`pC0n24P`{ER*YLA2koB++qMBko4UeP4RvGV0noNCyw)nh)idOJf4)!PNC zlUhhtZ-yvNlj+~;#=D>FACww{3x(8ijF!#d)Wc|Hn}U{;T_K~gwVC21jFwZNaOsl< z_QfeqjXov|)CA4RZob_%iqllOx4Ptitaj%BeUZZ%Yhk8A3x(MOs*^n-Sr~p3X$!?^ zFS=G3g(*(>b5(>gKfb~ll)YiJqU?i~lYJpsly;>!?MF0PG=GDD}EK?`*#G`lG|3@s;zLq^$| zNpbqGqBtGF!s?py%Z008YD3ke7%SjN4vJHpj-rW6?r11Zj)6>Ha>w!jTXKbi9mj#X z>bSae)g2GbR^16`IXMwBT6O<2#pxsh)hrg`9i7Y}af;J)nwY~=pg1`dGChZ<@c_$V zp-`uDm}Zcf(hQyf%`$iqN1kI9iFjHL&>nu9fO%#Y^n8fcccYteFY9b}X@uu!ru+V&;6Jt-;&dZT%-~H>oZJkVp21sqfMqZ(+^rm{`D30mf44!i{N0Y0lRF@pzyAb^ z)15@BsVvAkx{G7t6sNoW6qv|+pgFnMx6^J!?xPb+WWiwfbDU<8+0raN04>}zJ_yyx zLy+l(dzc4nyj+UYBkWR^hJ|<(M!Oe$3@s;*Lq>&~-pYmkPg0zo;Doe@`L~nJ6sIRS zDo$~F%1@AGd>WdQXM8)YjL*`El`$pUa~!FKWHz;s&qE7^d;zMH7a`LN`4SIKF67JX z(n4B@S75Y4zKWKU*C3-pmWbl?I%DVLJfCy)21msyPH%cF%=uf;oV@MZX*qv~P7-pS zAMRa_)SPqTn)COdg`B?+)yW5t={f(92PfzJBX()dEyTw#TFyT~%gLvZ(N&_96sOM! zKoj2r;plUYj8mMxpozKv5{i?rAk#DPH4m`dw-E6gj@JA$37Y?Jq4`TdL~;5K1}EP` zGB&^VX213-j^Z>>eqaD1i&LBi28z><><$#C&Vl0elMhLX)6dYH{NmfCp*a1@cv_a` z=g@u=!*A?}Q=ESHaao2xpgH-|x6>(3f6XUwetjonD{N^PL!4!xI>|sXPAbJ|S-R3txfG}6*rgOFi?Te7A<7C+ovaASC?%jc zt;B$er4Yrb8;9s~M#Iz{#(=2@R3|+li7Aibv@#FZ2!$z5y*NlIP8!2goO;6=g7ksv zWEDsT>4!3IJ*gUhJwh^#^_fPQmf>sNx(vTJXQoc7uEXD%sM@8vF;mlk-ln>$%Es#P z(w9*bN;1W%oC9>fQ4q8rzL-HQ6IEvG{bj!%O6sHmFh*O-_^PYK&u|6~>8~AoB z2uCC7Q>V#yhDJE*D;u&)DNdY*-f~nx3t8O=s*_QW%xcjTr;X`LBXR**#B$k$T}pAX zh?~L~B5nrN$>xx)ins;cYQ&+ji2Y%H7)rezb5&O%w z>{5!8McfWXTQu9F!UZ%Inv+W3E{ftbj^1>V zTslbWSVpQr?i(^QVoU6@=b`hnUVT3FxHpgP$DlIyz& ziqoF-q9LQ*D=~`GUhLOBnHtbjoE)qn;@(i5>;uV&C8s#;%lL{fnc}n`2PnlU03^j} ze^>*+1E4xN5Rw3AQk>eK;&c#8qBY|co-Y#$QJfCuP^CE8dOifkP`pE-IynrI#pBIp zGR5g|`q7Z-6sIFNP$^C!ASg~p!WaS`1=Y#XkPOJ@z6B^w$Iy{ROs6;<%YjO93K4O0 zdK`=);_*kKMSg(QVuBmc@(GX*{5Im4bKfQ20S-Hb#fCV@sxt%bTcC=8lEzfC{DLtZ3UY^ae9bA6zx!C zHksn|Fb65c$zAR0biV@C$*Yh|cRI!CH9F7`oKQq@dYxuH(^-f&V6=3;iI$VMAft40 z8MYI}>22cCoF`J8-eG^7;`A;}%=&v!oV*Xobj&!#=>s~ps`x!91t?A*a;UxyW4g3b zA3?J{C?BKcYFwPjUKz{c(!Zk2Eol zKS6QwGbHoK_W^o33^6MtCtVETXf}+^nqeNrX?FH2&w%)KUUR@0 zPJ?qobut%Zu@UE{N6l#(#c3W6)7NPhcwQJo;0{oobcAH!9>`?z6sJz~tq=-RoH}!m zK0Y)6U0@6V=7Z{_DC)Y%;7Y%DyZA`Ot2aXwr&Z|R>Xt}x z>dP@&HiJ_Rqm`{6T2A^yMr9jdXZY+3k9`;Om&0scZDw$$L#BfafRo$;g-f3dWM7=( zG|0zffmVg)WHsMz8^vjLy0^OIf2;;`fWFA#jI}UpKnsOg6RMLTkSt7pJ2hvgphbG| zT6C>23R9fc<{&*u8TE~ zt0+#RSXfCD1)V^I8`!sPEvAsN8>moPI0QDiAfm`#Yr_}dQv9v zfP|#vgqp}_WRLg;JiqmA8n6Wx2PU<1k zGd6_>SjN%=?#jWMH|9t4CeSQz4QM%OgpBg`uTY$t2v2jE#yQ%J!{QXDsWdTzyF+m@ z4Kh80d+-3uU|P66IaKq5nmUVzK@Pg0zY=7h9}{-K?}!HaGuo6C3% zN5v^l$NCAfjK@K9a=dS+mGJ~Ru`;HFJCP%`kj$nQ@+4@XkS9ZRG95C#kf-qAmI1NTC%4tD!i#1~NSp*YW_%eG3t<<7mx4lc4#(9-6-dL=>kRU~qCH zBxCbyZ}#4S;wVmoJlhUxA>5xINb`($!)$}8j92HjHhL3 zeh%$7G2Fq9IK}BsAD3mg3!0O=eLJ1vbPwHFA(|;p_tLJ<(>W ziqqTd*LN}@4z}jJ17nEuE>tJ)K{8G%#p!*z(one+rw`br6eo-FA&eo)M^K%749O@Z zpg4WPfQqFM#pzQH(dUeY=`$Durq7`|`2v!d_$a%nuEvv#$_K5}LB8bS8lf=7=_?LW zij&6h6sNCY4MDzv>f~EU25BS3={rVID9IG3?>RvCJB6v@^Z5ge0mY9{o%{qz6#w%S zr=OV)%@;Rg@xzl$ar%V=mEvSeFN1OvKCv!sb9L&OE4I#~#^RS_4aTa7q0HphOl2)mTxWDysI zF+^Mps*}YbTNQB$y48qdV-fqylI&87lSNz#Mq4yxXgOILl8dHQ6sKkAoq-c6P8s&b zDNf7!C|p3xL36UaZx=;zT7lkll3Y4T6sHwAMBj{YQo4jzf)>)-4XTswkW6oj6sI2a zp%IfQPCYq5FH0KFQ=C?YH3aMh)k$wi1{{f#*Qk$?bw(-3;mkUVMdPAx`pT8sUudl4b_=+!?;xwECl;RWslH#;3tO4K%s7}^{B*2*zr}n2f zt*eN^uGS zL2=p`#t?85s7^M8WI#UmEkJSFjE;1Y=@h5UIZ!E1AtG*0w}3H3+!Csjtsoh(IEvF~ z`qbd*6sN5@P$^Cpd>a@;@NJ!u25*7lv;#*f#mS=Y2xEx86I3T-AX|!V z6sNKDsnJ`YI8}0_Qk+6`P@KlWXcyZmw498Gj4rkVQSt1@l*Ln=s^P^0%h{ptpAJr7 zXPn|R(MRQ#cM>!wHNM?yiqp>Ytoh(wSVVE!g=W1_aFT)IR0}oaelk=ib&$;cSWG*c z%+W3sr+NZWsJzw~#c2vV^dh5RNpad0#(-6zI%$9;*3wX%8W~f;6sHq?M4muTg68C8-!6vYG@Z_L#?d*G6o^x3)^jH3q&L^6LJR3W4XTsVA(`%U ziqjc%pdmP+h~ji6&3dM@5NE+?={y@PC+9#$>EtqOCyLX##G^S+q&S_&{y4?ye43c` z3!pf;5R&Pbaf;JLbZk}edr%5coG#{2eH+GfX{9cKW_wUBMa#)$kWm`jmEv?cVI(F} zDNa|gKTdJFk|rkdDkx5_hGZg3L2({d?sUBa`C=aqQYBc@TD9^){5 zoo0a_hcN_x0;-cIAsM&_a2HQ;dWyakLSc&2(;TFa4-LRGFa`k6LUr;SBmuOZ;`BWI zD~NQ8(+eD^6ek1nB8+yKcnK{hFGEI4t9>a>uMiTkC;W=jtL%$YoL=+5xIkZr=Hw0E zo?(j9n~bCxuQ$CWgcUmdhvXi&LCF^+;I2&!9Q^+_z_tSM&wrSowJBiBX)s zWWQFA`OxZp1uazXYp71Xfn@b&h~o4u{af7RZ|5*LO0s10` zGuFcV2`v=nFQ`ubhGb#*O(bg*Y0>oJS$1oNQJCU1D+lRG+Mvt^qZMU#w4BTV$)dC? z#c58W(V{JaSr?!<&Bal1iqqUQv3m1BaWXF?Q@1dk)Hl^NR!gS;pv<_M#s)knA79-^ zI`9CiQ2~lmM~>31dCYSPL_j=GFW~X!G>k|!l?z38BDoZ&bvPzYaT@NYz(lSK&B+MgPP-9Vk4`L+1%s{6ahgSD zOS8BEv~bTj5~`C8A=3+2!GkqkF2!jhb}384LX3jZ?gckS%gH8?QK6>C?@sN;{6B!= zv?(W~MO-8*;`ls@(`FnMr#NlyC&)5x0nN#lzMWRat?0zcxJcn}qd8Iw$!uyNw}uu9 zxeZh&+d`%nayuTJT*&R&rG>N*JHTj#+z~A&J3&T;ED^<$OGyB;-6lTs22(&N*?-`2=Vo=M$kinFN`h^BNwUob#R8r8&0{yTE8U zuSLtrWXR|$QA&za9RXV zX#NrqQJi*z!O2ue#^%@F?7aiUQJhwl-5G$$;uNP<1I1|?y932(zCdx>!-pirX-{ZQ z_VVr0P@Ej&X<3?|L;Fn(d$S`>aoWenWf}H`=43zLPNz8SPd8SGW{T4RwCnS9PD)dL zAhfXL4}$9CU`Qsrq!gz^7*8Q3P@E2BuTq>0*kLdRV249>as(uSm73yoB%>>~Jc`p% z>{E)9Av+qzfb1BkPL72nve8(d?L=`p4j}@_1d7w~>{W_WfQc;vC%_nBo(R>+Ns#Rf z^JD_iTqaVSrn6ruP6qT87z5B#p*lGYvYmmRP9O?2nc{Q?2PnnKke&%+KzbHbCuc(v zDZjZVQ=HDB9}Sd9aXOd%`c5Xq!PcDfU<`52hw9`4NXAK}I9*6r8Y-9KbP>Ch;$%@S zhA~9B1geuuAsM9v6sOA=P_Y!EI9<*m`kc`)T>)djbR|?LS3wdJA7#fVPFM4AjZm24 zbPWe7#Ytm$iqo~Qh9K8Lb#grNF1<5w zBE{)F_Qokr@B1iRKp#MJ@}X}RMREFw-gJ^&I!P3#k2yr&jB!%Bgg${5()%e?C!aww zy)9ClKBo_jm`ri{f&=ujr13n(=}TBcz^|Y>`5KY|N8;o)s$>+WZx~$B6`(kM%MnU( z3h+pA`VLkr{`Y7(`2jNeCf^#0(~pc`_0OR={lwll#p!1si1q&knv-9BdnU!{U!get z#`@SNDuLqkJ4fg)OfD4tK>YzNtnWXeI{6Ed>$?bw)8F)>A*0b%Cw1Cc z1A2VG<14;oiqo7NpcJP7kQAr6U=0B0hU#PQf;xr!zD#a-T z1jVTU;&ELf^?)2(0va)Ztn&Q-po;4r53yUaDy=m491t%FOPJN(;+^+)FNnc3jek`V) zP3CA9ic>j(C{$+2C{F#@p&S1dEGbU?VGLLYKy@+@l2}VaaT>&!3MP-@v?}}bE5G4c z4aR_Hb*N4TLlRFZC{AlIqN3p`Gl}A~CWk1+DO8jcry;NgRBJ(XvNj}94Mj!m?Ohuw zPD2?}Vf9RaMT*lf4pE9zfJKVaIXvN8|}~YiLfk@$F(LPTSI%&Nw<}avSD$H0wE&bJCmZ?V*Kq?*P@wj*v`uI>l)x zI?xcDP(*PWL$jXgEW}tCEuEEUIT;5TrIX9BohVLK#G^S+q&SUdf1Kh}O%t;|0g97} zkW9ynQ=BHzu~lW!XgQDJF6b$ZGGRh9yQGFg^=%l_rIp$ln(aZ^1uZAFkWm`jmEts+ zFcK4~6sJ1&$0<(rG%=A=pg7qTl8Gz@#YyPeQpwxc0u-kPj?_#tW17iEXqL$)w4Ce) z8D+AS3)1iDE|TIjl^}BR81{L4iqr1wk5inc(ZoFN0maFlkj!HnDNcLQTcOkuN%JCf z9I2^eiZpe5L$lQFgO-zhA*0l>6a^?w`_YL`z4_I$Klkm=jyT2X0Pm8MJ`kFdgM7O< z!qLHWXEV&BI32=%ZfIXTO>XPDx2HX~^U zdF9UMVw}SPx_Fr(UA*T)3ne@cs+02}S;7)foGxG#MO2vLbRh>RSH@6X1f$jSVziuG z0vXk_#1yAXi6OCo<#HMO;uNRLJrWl13TRHQ^z9ks6MRk)f$#syd-V9NkuBU&iTO!5j29D9P8Jrtow6fiVmXn(yqq4P`;&cn6f~NX7KYzM+Cp)< zkFFI)VT#lJ9Hb{{gYp23R+I=WoIVE>A#BN z^ehXjYtAp1M2gdM92BQGJx>#t+zU{gya<`Tjd;uNPhX<`oFg5u_muNZp3NlK{KSpu-nvgVC>5QXqI519e`j#eU>^mqR7n`QUx{LPA%li47dzyAb^)9kQae%tI%Z$b!M<}zc7*Dr6J&bfI`d$S zmrHT#!Y*ZLScv&xw0ps>XgQf5GAh*c_}!_!B>4}ZI4!^l>E|K;cCz_boEGG$IK^op zKS7ppVQ5Yk@$IxSE=ng>#*}c2aikWK+0;TV4lNXN38+q%giJ5wQam`hkY()BLRyHW zVYEUngO-yFWK_r!QJj`#?3|qEbB>nds5r%Gd5?uTUjdqv6@5D`=PS`kLeBHUb>m3Q zIVY|;?+z{Gya!Y#Jt5O`zA_I^&Ur6(Y0fP~Zx}7-eb92U3S@MZC?&7$HtLo6u-j^Z zO6V)?C~JD>oahi}PS*16<+tHGwyh^s*JbbqwO6LPu5w&$bwkGgQI&d;>V_%xb>qQm z$oLSMhNf`@Bx^H*C4sM{s_Xj7P@45oHm9Vs9R@9|wsoL784k%DbD!oG)wR`CjhPAc zlJQUW>+3=!Mp>6WGzu9*Br!Eq*Y=eWwD+!<8`HBe>%kbptPj=629ONXwi%9O42?Zc zc=1+US1udUtPe0ObOnqd^hQvfjDjp`h8xqJM&Xl+FvD`$g!bMQETDzi6vhx{GpJ5B zhiv-{w_ps7-L-j!{bWm;l_p}Lw}LT*9u3vW){sTba2vYQC?tV|8TONHY42UJXl#bt z!5G4957o&IkZqsgj*OwP7i*qjf7yxV-W7|*LXUwlgdPjkNhM@aGaN^E8f9^tVSlNj zUH83PBFDpM=f!HYoJ@d>KKI;ofDsrbBoPxm9F1jke89{iuF+!G4uppZqR(($OIRPN0VO(n5wD))hA->&vW3w%$=Xni!W zZpcH;gqm=guAfqkAqGGCn^kla7CC@dO{%P`tFFbb6AUTu zyMC`s`H+4C@n63o1K8?6WFY?=Fr=xjsiAs&ugpMac zqC=^zj1`zggkeZIj2+7CWTsI8Y~nl|npNNkwD8w|A)^X#YqC{f>ZEFXG9^=8i4Sb! zB%}_BYY5lT@tN-BJunl>&Df}@f@dwT22C!!#1xIpxNY3L<^Kq$Y^q9IC><0 zM69N=Hp6$uT9&NI$;tGkXggvs24N-mp)#FaWfh&Wz@9=A!JY~Qq)teHt-uD#)7hg% z@f-LUOwOQDFYLs|k3_{R2g{kz4fR=QfprNPq2445^_Ihjjmp&4*YDCaB~w3P0`6)W z{L;#rL!Zo+IGK*xVjT?7!s$R3u4ZCgJ^n&xA32BdJ<@Zjb=-#EPj$BHeN6B!=doYu zRMF}`pC(TG0x0l+GkMftbjq2;CWNJ`tf7ZgiX1$)PGL>P%eKN!9@G0SaZqpS1 zdv+76>o^=AAfBf@PXu@<{-F%#$S8ORPSDeA4%ce zEh_D=XMN-fPEXhKJOB>RV|bWcNqd>UNrMoNL2?~b%i8s5;m`d-Mp?VOn5rM4shWmOIRAFuZsgQ7Z`@_Vym?%56FbT( zmdZK{+)NV_cMBB!@nFcL#NEbWnmFbsB<^;ombg360^1WZN*u59(J5<+)YMB&gp5!_4Zq>TKRt-w=)vNTz^{n~if>+%>TAcNueO#y>BA@5Q?UNIzPYw>o#xq! zCk1{xoLJq!&v~EB7C2wv1BH`HeRS37lj%OPZXz5uWa{g1E$<tUytl~XJ6SMI+6fi>}LpGjdPdpn>(WDn0&N<4))6gv&&!7duCuEe3K0vVnE}i(? z)>hX|WID$0+|Q-mXKF#>*J=jKOj8JiE#&x@S$|1s{yF zco7=7pT4cH{)c)0Oc=i1HcBPGjz%ZYN!g%QnNm5ewjLMwaFTqPaR|Y3P&v6#UZGhp zVw@>*kU2~#vS!HZhqc^)xL1NjTR`OkWuRSyl&HIx%?C6w#~(t$pV@`vN&!vfWA<2<___InCS556m34)&E6u0qux0ZZ zTKE&WkP-G3fqnC8ZvAek-nFS3cemkU!2yaA;gt!42I~VouAoPRcIgJo=)=>ACVqH2L&0AxhKxQu^Rdg$+I5qs zN>`fnqr)7{{OE*lMgKoOCP}kwl=-m`?4z>)TKKcakkOTnJG=cF=LK#;&BP}C;y2iT z2J~y2EX2j+Z#5RC)^QuITzm@~!xMkigo&~U&ANpqTDgn*7+kuGLBkIS`}XqNbZ0#O z9wP$}c>1EBC|>{gngR60E%}VVe;Jh}=+~}-{F09kOk-8$WZdQ8A?z4}z(sLMj?;zD z8S*NBkSql)+|-pp#m@;t^4hynI)qK}%!E%^HW)9m4817;zT@C_JUqE$_ZZ&OhVU7V z(z_)KzbuR){Blt7yTXtRze0NW;f<2nyb|9TWCgm_;QX^^p1RYBN3QIQLa)d%`US^A zuLNTV-3=;!UKo<0$(Be-{s?>n$M+C@wAB3dyg_;}hyvlCHsizJ#+u31y!GLz2un{6 z)4y?MSXPEHVCe-FzdQ^{Ec{l{GM4P`)Y69m6bJuy8J9zZ!+*PtfULrC`ZvrBNM9HO zkaDQ_fni7j>D3Yt|E+_MaP^rw4;!M{w#S9}eEo3q^;BLD+9LLbl=fPpXu0E3|7 zhlU{upoNbFFGid2j;&!*%@kRUt~L1FVNo>SensI|=NSEtW8nwG7{ads6+e*+$?*Kk zBPoSo_))x~X0{d?LeCnV@7+9um3_E;MZwqN5Pb({!PkZ{1Rn|&zm^Nh;N*9t1RqxA zpPg^cGr~F}WF7j}@O-<%(@>@GWH1gNh&mb0ZrxaJq1S~mgdPDEzk>_O(EPg@DWTUJ zzJ;t$hZ>LD{`qx$LRCXF(+$|$yP_lR_AT5<7(=)Xq2iZYAsKGv^l-x`RafoOfCqBX zTsNY3jom5CwF>>wTt~6Hw||^#!8e961m6TIe#I4%!MP7A%yoo6>$0lh?7kU2X`n?B zXf_N*E;pxD-v9>xxMAM{#^8TTsQArRNcvwK2d&Ge9CiA#gYNl-32%mQjvS3qAwu+~ zZ+t_eY)!MiVzDV~1EYN--WDzVI4dNtS3~t8v^|egf(lQg?!b$#LOasL zi_lI`@H?xJgv*!C(f;c}1G0W%qC;kb%7)D9{`Rn@4!;KFpK*kTkz?sh6UF#^#>B9d zH0$59B3!-rjDu#E-72*3Bdd^E)2Qa)j@$6LX3h9oox%j#bn8|$g^4tA3X`DVH&P)v zh3qZlu_?&TJRl$DE;K7l!cmyD&||7MKfNg^gag;w316an3p zCIS^G_^ndNT%ZH`X60HMc|bnUCYtq6$`OzP-3^)nor)HIeH1ba=rj&Cpp6Q24_b9c zPXu&Nnh10+DEPTh$aJ84^MHJy`_QaF2}ptN3(bJ;hZcVM6EX|v0UT^UH14;7-W`#;f3iWVk2K5NE@GcE9K=m)MdDBrpWsLug z@(E3~wZ8aA(M4IsJ6Vr8j;4t~kMVAf^={&;G+zAUctAeT<7rl)1f)PufM!5XL<{f5 zAhUt;iA@YB?qUMmlj*3e;*%`6(`h2yQ@pcNy|Xm9r}2P%xTn*sa0yG{o&n9^o{1Ki zagfwF%NkM;tZ^@K}QiuOWi zhV~+~oLmfJ&$;g<)=TK6tm2m}te4V6te1IDmwQiXSg+s#`B<-{S+Nq6V!aBQ zVZ9nHyy$_<#yUSTi+xsEx5-3$Eq#>nVVJ!Izm7ISz1};z!8=NWdLs|Whk6su3YCx) z>dnv$>MdyD)e2-b)a)DB<{N3Ey^U_lM$MCr_IBEc_73msPVXxX?Oi+|AMM>VD_Wvb zwD&+WwD+QgH!G0YXt`wbZ?_5ee)=gJ)ioRL1GEwDgWlOg-dP&lhj~Cg+(&3uxP+x} zABARcA43b=D#&cOyf@9hEho??=%H-XV%b2Sq>VtI@@}5?Zqk50!vpexK1;I#B_IX* z95e&^JX%g(fXoKU1slJGC)5||qij?r8|q865$em{(JS6j8q`;LKt9yhXjZ6%q)=an zW>DWi%gLLN*-&{kh#pt@yI>-Hi!RDWb*9SEV%!E#Ah-@IU5E5pdmOkWx5_kcM6Kl`QM~WitrBmHu`gXW>G)kb*mP6Zh<6|B@ts72 z-$>~HR7|vIfp1D0v3H?cc{je$u4(KeJ&A`n!?s{-0h5(!i*LK^(5>Z^7sR}KW9iF5`iz&!&njDr1uk5>XUy|-g>VeIF+!h+UE0)0=pihns>>4lz zuxmnfG6a%fxrr}%+gR??;>;vGK^a$##iUb7Oe=TJ$y!995cycypZ{_mE6ds(qtBEL zg zR41E3GJb!=_s@@;-^gYvajuy>1zSIHE~v~j;N4Gcb#MQ&HtV6`=8U2+_^6rJoa|dq z*@FH0oY_!p31dL96;vmqA&Fuj4j&dm`OEo;;lslVsHs@5*ppKY5?cRc&XPH0|1{HyUm0m3FY zzvWdb8B_7_u{gImh5JJp$1Z&)Zg8q#3~AS7vQHm=Ta-yKhA1^qo$L(BD167THMas}sw%lF-7j`M+m36RFo9Qr`b<5xrB1-^ z0ojGVHEw6b<=dSa48w+E^!oK*%MraRI^#CNqECh~M6ZMDq#iPgzBxCZrvz`pHA$mS zp>K`eB|CakbM##~LjQi2MHd)D^aiL-8X+0Id(zzX!GC7Gk?U;|n|c#nYw+mLXGM?H zZ1%fxknRJu_)}pF@pp&nWEx}?KX>*y;cfDJ(6z?r_Bozzqxd%eJvm4jP!@kL7(;vq z)ydwFj87k1@`W-^Zrpl`^A|RI>_Z<`t+0g#Nb zDh_YOxy66j!kZpBkdYJ#|5#Y_D#x9*9K^of6$`}H*}*Ud6o)`{awsHG4Du+7J-fs} z9L7KjV!><>Jii>yKK)ykmWm@_w3jqTqUGc$NZx*vANd@!9=kWKnT*pvU#3Lt3w>P4 zSN?wQzilY@x2k?CeP!4}gVO?c5#mGIt#3En(@Ax&aBs^E=zeDouVvVWE0s0=^Ie}A zzUfxsZVpFBdw2U}HmINK_n+s4p(#$TIo2nFcf`j*b8@_IYkK+IKl%3d1Uk~&Tjo=5Z%>34ihUAPCnrPdw}+K0 z3f+ZH=iz!6YMxFpPp5iMr)7CczCk=){mh2tXMWBwKWBPBXJz>*co%oJx|%)a>Kt=* zu6K1_maD?ITj#4U(wPj_1?KBQ@9Uy0UrF~+7ps>!V_q&XFPC~Rmt}cLz8AV&{gCWx zXs$3nS9(8JW%)_GnYmiskV#~2t}!>)dNY_u;#VzLIR`24rEEl<#|J&6AUy0j1?l2E`dJlJHdC0rA->ojlQ!*F#n2US8i~F)% z6u3;^ua0<`Hb)PbqX)gChq4?MxZ*ynj=IDgJz|a?^^P9Pa#Z;0`MCNb2h>14VZNU9 zzMjhRRrpHywEF5A^Yx7Rde-}TF3VTq#qN1^Gk?s@3+CoU@8+c}H+fg8m(>NYR5q(u z%*CtT#cNqE@~$(ls|)@FiMe>gyNG!BZ+b6pc`yId*O|AOi|p%6xx7PDoND;4PXwUHKrXyH2Z5mYB1L$-9C`Gkk-b;dk>YMwsxo<7g=lzg4} zLjCYMV}8CgKVNx2UuXF#c%Au1UGX|&uD&%_-+5QxXSphTo%un1@j7F^el%Y{d0#(g z`AWLZ{GwiXoiQ)JnwQ_am*2CzBwuI#P(QrRn4dq*&tKlp-&uYVuQRjk>1)R8jJcT= z#!&s)pyGFaAfxK%U1#P{7rf4xi#g53T;9dpSuXOfGxMkmUT4h3yyl{VchND+MecQ` zlX~EF#yoU34_&;6`LaCZU1z$g3tnf;#r)=C0qV`CXUx&!=4c7;Xvr)`g|9P9sV`n<%vYKDTH5r6&{@j7F^mNj3? zd0)$C`AWRbte|dqoiR5nnwyopn{HWd@~$)8)djCJ=AwtW=;>XooaG|#I@3#C@H%5I zdV3eqb*7K^vWoYj*O@M}rhK2lcNjd&wr>Xq2Uks_;yRzsDX5(*C^IPuTg`bg|pPEQ1Kic zGCE5Y`YyCO57%pyc^Yh<*6^Oz%<`0cjT)kUc#SeYYnh+5y`Q03ehOZrhN&xFqs-Mh z=4!ZiwQiQH!q=z~>WkMX^R=G&THpKHAj?o2&Rd^1d&B#LwjH+}ZD(Gc!9oJ5@L%JWk$s)V7M@ zJIXL44KqqGqdiRO9W_P~d`B5#J41{W#5fO;dPi-q2)?5Xv4bJT3t~qPk^7FCpaj07 zjIfgts)Vq!M@YS+sujU^lp!V>qDBz49-^IhRGotOjxx|B15Fmt6c5zSJE~qmd`B5* z7X$4opau`r{yS=_viOcNR->_+gw^b^+J8swrYydrjOC2gBCJ-AmG>RhrWn4X3^UCz z(*?7;he^GoW+;O1C`0UFh&=_dmxoBbqasD{9c75U1(Cd?_7TcVq3AoR_3!q%p&u{O@%J)t z4BrWcInOZX3+4h3lX@pys0h9j3~`YmE*8Wk9wPNlxKt5*Cm7-~LtHM1D?CK*JK;(t z@SR|UtBi295U%kEsdvJ)ir_oJ5Z4*vdO_UaA=-H-+^8VF6AW~dfo>MiEgq?iSWP9;^L#!oAAkJHc4@8S8#wJ>aqOz7rl) z4BrWcdB`vi3+53IlX@pSstCRl4DpyD9v8$D9wPNlcv2C3Cm7->LExQ`ycV7o&@%$k z*TMu;$@V?4b<^ZbvQ1?snJ_FAz0j;ssP4+iY$QQwfsemo?f1ekY{t^Jc(MK zZHRXS@vetp70rDcbo$VHdOx3hyZ?Q;Kgqlg1o5FD=2Yf=M71>Y^3FzQ-hIq4#g!-f zdG`tZn022*z`h@Flf>s37dNZY-96lA45=?}8mPJVIV79E_XVynITmg*fcWp1+OMdK zmD<#_o+?`YH3Jn_p6*-z4gF~Ow-9iKJKT0G|DGY$a$2aC{{YD>{}ET1a0_?NS^hJ1 zQOonK>!97gFi3Ib*}mPsijp+^H%QovU9RnEn6I-+w z2_4`jNw**h4W~k4Pc-M|!w2Gi-JxGcl~ z#g*s#$+obl$YkpT3A29X+LBEwIn4Q5l=teSD%z$=wiu*1$rgu*4ItnqNydg!Hp!Oc zJvuAHZeL1nPpX%tg|Lhe=2Vg`OSLq~QfmiT(3a!x#g!NPDYiWQm|!bFz?s=_6O&oB za6dDdfF(s`B?i`HqkWoeD?_qpY!zH#<8ruj?ipK+x>!*Omv_+cVg@L#yxcc@b^6ip zH6UOUbhzysz9s{!;WSVUUkj2M-WgYsTO012GkhKDqK4-#z@gde^5^2pt9`S((2r(! zg%G)JaN9R~JqA{@X`Y(BJ|r`{JFc+J0Ngoeb_sQ{a-K{Olxh65yC;7yuDss2yHqr! z;boApAAwvGqPx0epY2|}S#73mYIAQ$an;ZVV&wY5P12231DhTb8+NU)b^Umg&Qi4d z`^)`F-LQcm1_)wK)eRd`t(-LDRDHDgq&D4%zZX~D?5Ekrq9N046G%7*Tdwn@*+AZ` zX-3;L%?3e=(`++{*y|i_{xloHn>5Yr{-JVzl4ipMvAH1TRGMu;wJgp2No$g3Tk`kf z%G>=k+e$QKnpHr;#9+C$G~*k{Vd7&Y@6{xuX_{oiA;n3y4MglH0M}14meT1>uGVeK zdvrdo-9A!oPf~1@5Jn4OPNmows--E$-CM$`oRVhSF+_3Y-F}*lr5}@Q9E8Yi4>vKI z?;sk@jgZ|A45v*z8mDPC9+Fi@JK_rGNyD9U)zMDWCCBLO3`#M&iXne5+`M)-Fr3;=`_%5Kkj(BzTw&@j+&O1=Gj&PZ9p?9L3{+hCxNox43>GN2IgxpSb>ppo#&t3WjDj+ z9x~?{1KF5!tYh}t<%NNI{u=LME&KEimA)`t6@g)n>;~~N8qy`ctdifm$lT$0dNPLY zxzwx?E9i2D;A6G2TVU)|UeFE^2?%u}kTVN72X(3u37j;!(OWfvQ& zPi94zb^)zJ z9FZ~N1xCD3h!=T8)+N4zWmTTN7b}iKGlsjwaF+`1G7rbjmAp9Gd%5Bk3~*N%?n=R3 z<>B~s;oDoDWAD{UCJ)Dfo4h#M zd$Zy=h-0{040o&GZu4*)g7NL`m1FPiO5}))5$`bKokG0JBXUH>SFo3F@7;=H@0a23 zG2Fd^yU)XMTqZA$_TH~Jj?NhF0mD5gxQ9F(M^xA|$Tw>4v-_~pIHqE>M~wEU&>r(> z98*c&&!xVdk1LAfDu#N(P)`c#DG$YQl@y9LKCLK@uNdkXLp>{~=R6dbUMDu@KCjO! zZMlHLK z5*u@$(YKYxQhzMH@d>)G7h$ z6GMF}sQ-AV)jS(>pUcmb#FNqle0PHulb`dwx<{CZPRnv|ohwt4CYYQ>?fDJpQJrH3QV|hWbNL ze|o63@}X#BQ6#VAwE|QJcv=Vke7M3)W4Or|!#Gqq;i9p2+HxawDPQ}|xj2B=qH`Uo zkv3~MHl?cp-2(J2u6)~X*(@k3v1PLmq{uBS*VeLOFM{;DgpHa`L}{ajrfH*Q5lC^P zW>JVZ2Nka0s9_(ez`XbS;=EnkGe%lMNJ&F@Nr5dTF#UE|1)u^a5-v@qn$Jxv^+ZAp zU^KX8_)Br+`+gEED_|zUa*!goyj=g&v-(zG43>VI5<73r-BMsqa5R)Q2K*vb$i zw+dXYZhQ=%R`F?s@$ykjS88tH(P(JBavH22frx_%OBNa5Ye4CQ0a$R`+}eiet30}J zKqlPoo+oqQP=dBP{2)j4?AfPFEl%3PQN)ed#}zvr;&iBq-NXaOMr6A7jW5{kV?SY+ z0}Y1#PrYBb8>;>i#U}vie)=t3Y>oM|rMN5~pqm``!1fr;nbNEt@fcbhV;z3e7+SIt z2R<@g`%moV!FvU?vMfy#i>IkzaifB`izD0m33p2UBy3!p7=l8P%kDiOvyGmGU|M>{ zmUWqkgu{lO@tI4Ru6>wRh4t-|Wty%Yv#(?ZPxPqGQa1<;?wbW5A>%B>ex0>AIRd#= zP7QjAV#o{buxR<@*^b|M*aW`Uy7uE8e`E z7~dODpPm3WexjQ&zVCoO@M!EY1*>$K$v8hwrW?i&==kOdarwemDE2z3ueGx&wv;n; z;wKdkC(7wwdoiEt8jkeiCsf;KPWStKXT857Gz&s;K!@7!<$-B32+L$J}Ywc z7!<+2{B#J?B-(`D*{Nc@^^ieHHRLto^i7WN%blA(y#z z>8}%OtXAv-&$w3X3K5eQ;QsRpc|FFVakKA5E97#wKD~9P6N|b#JmaW)K*WY?aOYLX z^D1Ptdgrx}=e3aMnig_T)_z(kvI{w`kjq^u{q!mRx54@PwVX82v^uk7H-nn-xEC-gK0*0*C=Oz zqmv#-qhcxrdM|N$tlNYUQ2||=gWL4f)lKPNT=}uzg*}jd?7J@WEWUshb57~&6{Y3G8yXdMy=MPSFmp&`$(}7OnxqI`(s%F>XcJIx@ z+>KhICuXsOXd({<$F2(KHOBAFO*|pJNp99|ME^GaqDNR_hvdoFnRBWf3!5Bgsp*kD zky`gn)k7{bP0jI%?Iq|h*BM(}q{SX>E<1L^>96a&s20_&C_2z>137+0 zkAR51Y2jiRreeNXZY0C4U%@F7Tv@=e0%eWj54y*w&l(Nym^B6>c9?}5v&Qn4^<`Uc zvasiHtk*dHpbZC~wLQFJ)(#M{Q!Lz=wIgp?zk+^y~r8#dh&IJHgu? zwklj<$5*&XhO7p_cIf-$M4z^1n24@Q|FB0_O|Iq*b03TDsu0diq<3-USAMS4(2to? z3jsU1!sUb21GiOHx9lnp67Kin!lP8Su`UPSFjKm5JZ$DB5oD!~)yY%<++_M|k)tKZ z!}({qDUhtl)#D1=yTVN@WRdf_isLQ2cjf(R7K=&!ZX5@}RwfPfFRuK~w`;1Ufpi=)~%_jP*T_&!YT_J4Wpe5xc6wjZu5>mh~&xUtr~9PkL&PfzR0s-c~*$Tw#M$xJW%c9=aOJ z3~s=l=u$Cpr)b>{2IWO+L+-cP(#lP2nn!-^>TFd z0sKkxgxw`I4bIJ?mkub>#CfOR&O80q9f*P;^#(`ISFJ4KR6W)-d}+IbSV~ajmcpB$ z<1BZugpC7o&IR{fuWz2nu)VR|*&QO`D^P|jI?Zy2O7JO5p?Dq!5l5%N?K)-IDGS2q z2=O^me6+-K*u8mbox{p1Z_UVN0r>FqHK zds3saZm7c$F0m&dl!rZ0ZsPe7CkfJ1a}($@?kw4LgdbX%NGMDCM40cVE=G!YGwIn@-FiA zS!PuxryaPn_=C18sk^p3&W2>Kfpc&bxpUzruYr|t`^dVOPa`dR7TbH_vNzjUiDygcM zK#J?`OCd(?GPtO{#8eLX1&}g#Iq%fhorZ4FH0!W#=Um@Ja#2^nC?LZoR>TfC)MV1%G}G!;Z$1V zykeYJh4Y%n;Z)jOPPuzsIh;dloHvZ~rf}Z!IGjV9aHQmjU2iLglV^?dj&a@<&U+q* zTbtx^%G~?P;kG8m`M@|I3g;t_!-gH(h*EwAk1ll|D}pm`4e^N~J{81&JOsN@xrXTg&$#BF47T}Q>N7+@AK z%z}bh$iuK#n(Y|ZGOgAvthcWb+}=rUPbLg5B7{YSps)Xh&=WE$+rxo2eUD^%3z`J_ zl9rA66JP1^K%YV7pus(xn_O#2rmkdiiM(X{XJ^51#!#j-gIPkE-le6RXL@AH;7;gH z?=tc3ljB=1zGbO|I%)RqB@DkHt9PV6k12mco+sVnbmm2$5SFE*m|QkTsUL$!SvAgq7Z{IAI6i zlNgEA9pA|1eekDzXye3*0NdwSJ-(0Zql;Ku;}a5Ev^-k z?ue31*Vt=7rgx9hZf+&gB^_6$q=#hHS52+1sgfHc6<6U;#aO*%skkb=n2M`Gh+HvT ze&xcZ)%lCs#Ny60b8FB~n_JW~&vzcCFyaR@XH8s1ZY{WpIe#%-wllffRAfWIn=ZRH ze<`jQ?P3b!qiKz{G1r3>*EH)xj9hoPEPtg? zdi=zuhS~|EHybh_Ge-M-WFni)ufyj&KjG!Pu#)jTC8X;?uC-5@-ZCYvg#J1u&7$rJ z&p7H*h>g|D(t6Qbr=(fbz2O;0-3KCeK7jj=t?tJtH0EI5M}PY3 zybp_d19-+!4}ciC4dMQCt2bgC8n-|1V`F-2FOEgM2|VMdH-#9vfpGt^)q@y?#vBZ; zZbp9{T(zhN!!wS02*k(@h5OH~9>zE{Zhvrfb9!qZsYSg7JmaXhgc!N4;QnK)D;R~w z9E@OWO@IB?w5TiLshws#ym2_LBDW1(eUs-L-Z+8;IlQrA=lJZ#Z6z$fy+_KuqvTp& zzT@$1g-achz1aRYXE%@iu}6Q^m(nqK-!*e$B(WVs#qv({HMU+b&!kmB6j5h8X)fXm!m2kDVS z$lk|l=c;F9TF`$k=W_M5BcgU9OrzyTw4BaW#eh{!ZB=r9R~19(hqT4KGd!&av>I2~ z-vDm%KA1}nEUIBzXgNq;B(?MkyF2P6Ay^D1L5kdDxo$sirx2le%aqi-t%nrn?Jf|p zjRM@H)!R;1HSliDDg#XwP||R16jqb4^x2t9v#ObC;b&Eu+l^j&=10=rbdnIvsuoBX zTafGav#N~<%_^p(X4N!EaaK)-hJ;N6;42HHbFNmlJCti6P#Sv7Cl{M5Gj z5!2DK8Oy%h-t^LK^OJ1eM-q|QJQEW3nUL%Dvw1%vG@F?Vn$7z|inI9uh}dWu?q6i{ zfxKI@*+2&gD9Pr7g>{IqG@DyfZ?kqzd&BVd|8(c+L#eGMCc9k1ou?1ukGk`8lB|b| z(oEJPAYm^Gxo$sMk0L^ol~!xA9t|l@)?*;zd^fm%k*vq@ZcSDL9WNjxYm%}j2<}9| zY06HJ_aZv8g3mV5s7X-MwVHP}F3yT?8p|7t3{+Z1`Aqm+)2{S*CrOY?nfc zlkGByk-Hpjl5D}a))l-*ci*(zuaw)9WV=cTR|`RtZCh_<44%{M(#m9B3l>&lDv6vi zl1yOHeS>9yxFj=*TcGgBN6ul9$GjSg;jr1t^hT_qN@ko)scx9W5Y0|E7si~Q`dSPQ zV+2{J-Czs)rm5J#g#*W}t{#Um`sZ>tVLZp-SdxZG-0%dE;eT#U-_p`nr<K z`IBq{!wp$PG2YgNCM0JKC#E$wVYe1hoWn&H2LiLY5<55oju`4|reG=$<_p!w2T#^F zR@Y*>0|&UVolC4S6M&=XCGHw#g%%aoQ1zHCREN=Som_J*e=M%p%PS$*(TfG-dI*ub z0WRCeCAc>{zZq%BX-im3N}W?SmAD&83X2v7+}%y|){l9X0WDfLL$XoQ;b>R$0d8n0 zb+<4KKN>(n;o|`1t?-K6ZE%yp&fCT34)IZ2y#dO$X7nxE0Og$s287C zBiC9Y|K0%Qy##8k{s85D^wzH(s>cD!`}vn?`v8Qzeclm$=87YBKWv1f_hvuKla}xF`9ezQ>cCe2QMo z$)_Pi?isku$vN2T`Ybh&9?It^E6YLNUe_1!gB6z-aTU3j;Ig>PghgZH z=RTf|gQ^sZvr!RXMpbz~^tjqOSXU~vcCo)a<9Y1`=?^&EcXU~u@QXM`OdvbPks5*vON8?oSpao zr+=;PEhL0x_}jRO+&gfS3~xkE{Oc33f+FPJW!`8xU<)vql~tu>;XMW^t|-NeDk%%^ z(~D){0|=4(5N=!+KH@K07Wfw7%&d>;r6qwT&npQsbUh@(yw*Pta@<(QeKD+7WcoDad<8r+`@B6B`Likp{3 z`%tqEaFgcceBv{|_^7QbGd7(|=gog>Zf=n|a2*lSYho@SH?oPjpnw*V>)B~yE=-`t z>^Ctx(Oa9CRFO^0MfjKLyC?+g_5=5CG%*+FU6z*C#9V?uXcLpVYiceD$)2>OaD{Pa zxXF{o#2M9E?PTt4D-YpHRx4Bv8snBBr&Gli7%rxyb5-g&FB+rW651`tAL5y~iDApr zkA|%P0VBh3lTS}VsIuO?5(Dap9aU46SB7LNuYxP=#}Ah(4^(YdV_=b?gkubX*%(ky{6DtfP#ja4fi&e@TE4T19Eu|kdEfYq$FiZ>Xk`>?Giy^iCXMCzhZ%Cp?_Mz5q#xmE3 zVUTMJ)28^T?hC)j^@E!{)&0e11MyL<*_RSL)%g6MqSIOjAei?^Zzy;1k={rs8_V_V zJkpyGsL}e5^rrOIN1FQaksipuOr}8)u#gDu-*}`4^DawFd!&c(2YsZeyQbw(NS3F= zaD@dmaFa)R-dCf2HEzLFlQ||^Qp)$$$hkUO@kjl9NpiA+Ud+j@Aw;ecE^~4Yel-rK z2GY#hhEl$-#u5A>Ucp2$-&~z-@q-nYk+_Q7D7Z;+$>2dM)O3`&I-^OKbR0uTn~rrk zb9J`kPug@$QgJN3n2O^dU}t=|ano@J{*u#l98W*3I;dyfrsIzILCxVn`vhD?ZYQ|< zg2@?ZuOcNJXx~}FvNouednd}Z)&~FfKzj|<(RxJY%W$B*mVRL+QYR`g)h0p02&-Io z9=AGjD*iriZ=8J!X;zbPoW0IE>0Ld4)&!>YTA%C!2^BBn+ZAHu8sM_5uWj)a9%i3P zmd2Wl-PVP}?2QZ&kKIzlQoC8M36hOxG~+6AyTMIL=3F{<>zDvq3iuMN!|sMH^wMGW z>k=+LL!{RvBn70VU%B zk+Aj_mOeRiX;$sSwD7a4%*~{i4znj&wXY-uvuZy`Sa~Mb?Pt{iL}*qqB{i#NL5j2L zK!}k$2<~5G)xo@5v&uk+2q?*_Lxpviur#aY4YQ|)*$-zrS~hc-{Rn#LFnf~CM@k|x zn~#DNxufN}{cJvl2+d~Zf@brvkm77U4r1hvhx-@Vd;;&*Y&Ot|0!p&^Bw?K_EY0Ts zW5evHP+LvR^f3FW{878-lVm+jlxDJ?4hc)aM%R)(`35^ zQk-nJLc~ZX+$7n8VfNd3j}Eij?RUuSNwVE3gu8^G$u_Sa^xx}A2rtNGSP8%>oR!)!MrY$C*>}FBt0dRr{!A9~u`ZL>m})Xg^g5+{T_zkSdV@den>@+MH|fQkd<#P4-iAAeyG-7p z2GV8nE~R{3ChzeF?J{9G$lGP|K7O#`@&T?eW(k+Yg#+!|qt?idkjtE2tFh_ z*#0>^wFyA$@^rNP|7oC|wzj%2kPw#XU*alqU%^c>y&0)Drv}@TV&uMN?r2$%SyEG` zRb}U_RVC%&8wSz=_oO_0OD~p(?;u3(d$@6V_<_G@d5{qf47mSDFD(r;dtPZkY4`~V zVWr_`Tt)5|xXBwM!_x3q1Ma^vHKi*3jZ(VTlojdk{7HLFlid4*Ud+8eAw;fdrsf_7 z+&e(b?KPc`ewuyMGf(!ly7>{t%;|`$$SnXjF=t*w^WSJ_E{GJ4pWbvsb0Pky1MW$_ zFHA4ydnX7u{2lH;Y-lb@k~NR`q_d&97`?Tj*^#1j!!8a<$_BqfY{1>QB^U(l%wW<`6x^hpxwQB!BR*PFagJo3p}AzleOUzc+M3JBoos6^4=Hjh$o1^BHCH51 zqxRdHE74oqn$(eP&6W9=3A_pfj4H$Z8*RlI-&U#09h)`m&Py4bes)}eyCo!id=8FNkJ++b)yfF zGIgUbC7rr~UJ-BVMnC?5=bIY&d{rH4z03mV%;3nM}gs|-E)Qt@pP!ou%Y36SP z$;$r5xQg5+aQ~jlo06l?F^l@-K-q!(vA8nBjfN6s2hoqpZUzD8v%}4=><|W2WvP@Z zI~0;C%aO!kxWYI(Tt(!JByPdmWF)b2;QaBL-7O_BYp$*2<_fvinrnQ~zq@94Ys3|& z6?^8mQ=zM*Us&M{rx#Ob8wfa#9WKl3ibZ}MB-?Igm+EfITdcP8DxG+-?nnmE_6F_N z#2f|5a(*h3z3kZU?x2IZY?=c;28% z%%s#L-Vu@|@dR99p2Ss506&S#+|KmUF}S2EsHPW_cp`+z)xa&B#I?LZlbA`V zNn8iXl6VrXF!~NRN#c29XQ{EXDNH=e9*&*W(@V$BlI+=qUd*0dAz+39+``#2l{aYi zFdH;`8X;NsG~p_8&2W?KX)VgFbm!30(%qm$oCtiF!=H)wLuY)y{okR&;h0fgP*fo)&mCMhzZ2n~}dGg{aNVcR5bj%3*M$V{znZboaU zgr}~_`ncF5Grk^6?CNVKOl@mv9p5v)U>mBeM{84$vYz#gT*Ow7$)Y8055yLmzAz$- z+ceE?Px=>Ej`rWzd(n?(M-Z^7EL@n)-8A>%FE$&96gQK8IzC6k^t-l0#e5a>x4M1d zVI^TdTw&N9F6|zu&7K2r88@`h!ynHPokdSHc{oQj$&3T(N39Nm5V?cl@*TNUQJy)X zhcK+Y99ierV26?QXkdxcu1z_3Al>fiEy7%_^5ywfWXFSXE zBm{t_GDkGg^kn)`(^DWs?o_ybsa~)sJ4f_1hScKB_*9S6A!UoRe1|f5(WZB2Fbr~S zCEBD-V)=}=U(bzSwYGcps~YIel}aoGW{p?+$8c7I+R!q74m>$lM{l3js~&upGz zFbF#j;hatEz}J$|&CKc>YvRqyGCWzZ9*efIj2uTtBtHX-lAR4R1FNuGx}!&iFUo4X z9e1yv+BTJYnClJj$c9y3NoE_I;MxLJ5eS_X=r&=Oh3rSva~e)hXmaSz!IE>lI$Kru z)>f=2)|uHO?0#tgD-fHSDlAS(WfG?(=F5)~Hw}FZ#Pj_?z|a3!zvY&Fex&uFK|Ar9E8iEBY=XixuU>+Kz}5MW@xhNB0!=Vu zQzznc3mIQq7awjTJvB*Xmh4!b6o!w$@SX>1z@YA9`s)UPszK$SNUcxcYX$LBTw&N4 zZc-4t6crT>&uWmwiRT_0T(FxK8(bu6xzBK)7Q@deEjn&l++1H(%f0Zccx&8e?Y`j8 zaq~MVj$hJ`@3*fYV09^6ro?td{FcK}G+7-ySsWpOgUelA zO`KecL8PGR(Lho*vC!)q#%L{^`4JNv@!!&0I|-Q_T1|Zi$zEFD;|eQP;WC*9 zLd~)wj03VdmWWK*iER_Pmd@4TFzOaml%h*E!F~imG)VTO)8JJ#B)OmXE4n(llX;R# zKhuw?^a}*6#e~aLTD}On^ClFOzP&Se_ITh=ExyZs;|*ryA_$m7f+&9HuRSU@MGUk_ zZT$n1+4?80F!s2w*;-zd-&WLxJvSRXd^CH$kq)|Ym7j3v&qoq;03tSaQ4p|TkE7UP z>3saDxU#En>HPGgr5zz)loD=XOBdt~W+@xR5(CU!h(D>BG)K)`7@lTkCtP8u4Q`U9 z|Io}u8JE6$)l3{R9-Fxse=4pl_03$Iel&9l2$5S7ZecT*;tl!DT$(?rnKVbuTn3Vv zxh$?Cw;bI6(#+)zeeVt!qJuTxYn2ZC#r;snTt%)c-2c+nZj3-}U0U)LZ^Aa5SC)NN*JA*D@%zTEPd^&l9YW-K zz%6WS32(@6Y)}5A#?mM?wiJ>XTZXI1mBalnjqSw<(#BfO_GWn52P5m)0K}_zVjJJV*?pPqn?io) zHdg+I>~3Sm(y3yZS#A?bdSnHvV!*0uCr);o(zm#Brf={-`qAJ)5U`jPE)Bj4#iO7a z)yWR;_AN8MbOJU~XQMfOBjQ}B##+45*+?woZ$q~kk^5VwE9({vo-$B*yMd&j;v-Rl z^&8NO0pW*lkGk6A!)P!~k)FmOl=KspA1TsQ#tYgFrN4fpFy*~jG_7tJJS<~2$5rIE zfSY7YcYu;s8(x9<#EcsPco%Ztt@!-E(L*XTI(WJzW6<)am1t}2)T)N+mR219h}+#( z{JpsHVLvx2=*QgH8Uhxi!ewr(inzDNooJOa;#5?_d7BkNwh9@M+lKyXFAdTXI0BLx zx-G6EHxjNI+NomTEH{dQlMfB5trm@@H(GXFGoG|r#?X%%ZwDcAW8qTc%b|jOXY`ve zAfvmC_mCzO6De-dq9udYTvH>qN=wG?>(Lm-nR~L6+qCNX2ANKvd$!fZ7_@=-Grr1M zZ2Ar;MFa$*A12`lf3^+JT;$l1#Cn zi2Q3bbp=Gb^!i>v34#g!fXB-w?2Op;w8U|0%n;Uuw$|3;EbB|Tq~H1Y>c z5?UT7NfSg%l4e|CIV{{HNgjtugW6h~xDkJi?yZR43Ow=n!r~@_!Mq{vc*vdp>YE$` z;Uls-GrhWAw)sFe2fNp}8)AY(UK*)Zp9efg0M|_6tQN4615WWPII<~4yscuqJtJ_L z7%g8r2v*;UhYRm0_PgbF50p4Z+cmrNgAwXh!5oe=G*schipj2pL5eFE_A{-Oe$2Es z2v`^kmzl<%ld*|rtOvEfY(wdv!*k>J=9IYUgjn9pkDK`oxI4WyXP5z6E6#vq8M6nj zBDW{pxi(|=qUr5s3{Di8>>>s!u3XH|n7!%8jM)c5-Tm%6dV#A&Ne7S^>biQ0lZ_O8`zvjzjkSt#=$5rI6fIHXb%at^}-Fzv- z^KunKpmW;Km#gW=e7OcfIH{T+jdr_4Cp|kd$cLGXlR?0DUKjnq?}D#YwV}kl%Cum5>E865mi-#NbXxXB zGa+Jr)a#NEe8S#<6uCF$T9cW5TMy{2`b>JxufiG8}lzbhJXuDgKMoOQ-lJg?I@`L>A&DAz_WETo)?D zOB14nnE9ZEco|4>saX~x#;oBcr6zA}x;*dILTs2746~wOR`M|U3-QXzVIeloD#lq= zIIDS_b_;Q_qF9IxwYs6!5LCuPwOfeSR1^!bq1F;qQiwYXZEc}xA#VMq3QQJwmk5&~7a>>qCkQO?QYGiH2LS(3J3AEi{JdX_!*MlzEu^ zg{E9NEHuXHWt`r^>Em(QEi`=<#X@7KeunBVs0}<+yM<BX#wHfrTQxGt0cQi*QN}FwIlvF=0N(fpbUb5!DzTi2D7au zv)wSt=LR#JZcj%0w0sPKWZ&^aaTU2?aFb^6zi;>E)J5%HPVBa?qO93lFidgfIN$6o z=|{7-f)Ke1xOvUqn&H%Jnx|%0LNc?5;|hn;!ku$wkDx9=cH8G!*6wW?sJL=R-|mt0 zqurw*L~b-(ek`qtv>TND6y#jD)+uu6D?foSU!cd7rq*t53~#ndgk=LexV58N!V#Di^+r&eQ8iWBK{AzFaD@|H;U+2<=}SBKyKq-idrI%Ca)n7Y%ijTHSsO&t5s8 z@FN$2?GLZW9RN33PBu$?4iq0v+a++nECRFr^$x<%-YT$zB{aJq50SeMm1}(mvx-ZW zXC*xvaSsUw;hQG4vYqY@BT%E`gx6#h*x~fnenjfUUXCO9m)UqE1PsH$WitQ8DzKw@ zm!=?Jubj@ItH6%o54x&>x@%@03(1P+ak#>07Tlz0E`*P&QO$KV_4xF_nTmC;M=}*h z*7#&Un-X7{#e_Cx<)Fbm`9zgu>PjY;NGkNt&N&&789W7}`U5iKGngx|d9u!`JH5-q zyHAd9x%gt3Gz{D;9hi*X;*HVnFm#`EXaw$?AKfoEaEUvCsV1wyPNbA?71&AqL05q# zxp*?Yn2V=Cz}iZ<%*8pl3hXp$AgjPmr<89M*ctpm`&(HC@~#3q6F*o{ISW@ngCMbe$&|z~Xg2q{v+$*R#J0 z>_Vcg*5F$}J{FG?H{iKyP7eoBK|6{Yv`@@r73bPJncK|I$TBWdbsl* zg8$i4$QzjM_7F_Yc?fRg&&3r}@P(W_1UE?r@FBPvQsi!t>)C$@ZY8>%hu}8;rVjyg zT_1wmA;rb=4v3Mv6Ygw11b2~@ehBWSw>|_G+dc4%W4jk(8G-~oE; zLtu(L2v2(m9>P`R9)>&bA^4v?1dlM?^&#Nr$>fO*-fG}S`D1ZKgZBtLCdto7;BiQi zdqS>f{}FhS=yo1~r}&#b0?c!L1fGTz7s_WKM($a-v-Jo(M^^d~c%I(+2v}?{z%!2R zMTj^>7w-S+5qOy~rXPV<=&g@{De@{j?GbnlS6GeUJabodT&c~%<^|2VenF}|1Vt){2mRkay1`YH;wLn`s&v*lMp2e>svp7 z6zB1W5F_^yT;}o4xXG3u)HK!BP59rh2L70OsG`AY;7{nUgY>bgSPlFsJY!Y=12J-+ z!KJGI&1&G!8IwH^(m%@8z+cc`R|BgCvKshH_*y~y3RhT(3pXi4%ar&RR|EgV7_CgrkK)0Z;6Kw_`wE#HT21`| z$v$3w#Z}~fgUe+4=c|E#C!ZSVYT&x6WTCFCk^O_e#;bvoRQi*COr@gzsX_<1Or`c$ z1J8#Lo{>4Lf#>J1x*Cl(sjVI1X|^tatH><~H?j2}E|Xn|ajCIfw4xs;x*B+4{uHkU zPAu(2KU%s7gvc!lx3Hy)@dnFIe>L#p{7KEEIcnw-kj%^_afP8vxc{Y@OEUuBOj}#H z41bDO11DxKOFx>q9E8X%54W(HEAWQ=X0FJe)J&SAX08Ou%v>2)ky{0B@_@6dDY&Rl zR@vlVTevD?k+p@ZQPQ=A$k=3UVKIHk z))to2J6>CuXxxi_)VMc<$n}9sjsKrpTiBO&Na5*6DR*sQe|l<4GR1_F4o%@|o*IG#b`wS`H>>_|Um%mfG+=Y~7`8B;|_I%9UGw`L48Kr^Nq zl4Z<9TwzyXxN~jB)Y9~JGe*`H)-g!DwlK+XUs12){J2W zXvXXc$ugz^SCN|vcdpHtMw+e}!?lGuRTR?^M&cJ`O*f-@?{#XA~zlGT$?Yu)AV-pg=-6EFhsnzFv*ua=*N876GG(nf;;>9 z5)qQlm%Zt&`NH(qeAx$*<;zT5MQ&fXb8WutN7LKQ7p^VbpCRJ4g-N~~KtJZoEC`W1 z5bo^f%Rz*s^W|WAYrZi3HD3;aWchL^t|E6B+_^Si4yWnu<_p&r9>Eat+QKAXj-(&+ zWTPm;i# z+;g(re2QG_-qOOe zNVBBWZy|3IuREIov^SpiYoeY5DemGv7a~?S!(~2phL&E8?XE05AK~L@lSKgNC$*J@ z7w~tT&uy_@2+ugyiy&gfFkHsU?rb}RNOsli%1KDxDNNb5cbAZ?1}9U%<1>chRfd-` zfX;fcs4s(O9QEZ8v1}MFqvpJ;*x-C?8m}ZwW8*~eIC*W-thBBa)s?E7{A=w>F3#ON?XuOkNx}q_u zEbo$p;B$R9q{!VP*P6`iSxY~y_Y$H{E7MY+*83pE8GAoOEChy|OjFJK_&vyb_3<;z zLxy=+Fpqec{Lj*(%HeVf<2+`Z$A$BR$I1VcJgFS6r7+G@#(7#e&v=}6i~h5U;#vwr zJ!h!r1@(f5YPUeYs3`90W~i40m8{8lS!k~aO>GWQz2bY)~xpkJ4S zV1a%E5|-%7b)f?N79m=onU-3h--Z+y=yxDulpAir0{tHE)dFpp_YL!bU_SIP`3v+% z%3*;v&d0|2L^z*%ocsm)KgwZ&HqK|p`CK?(c${_%^p}cafi~1vhWc7i-*~8Y3-q^& zVu3c)cY;a^^!GyhL11YoFS6Kc;FI{1oJPbceBJyGQ1rnC`%5|ZK z;Wt9`VPHP!!|*$#_+j`1V&wjWTkv5hIzTWTkj;ka0M8gRA4Dwgg_~gVKMWm}!-v5* z3m9iX;Vk5F@;?j9P1 zw4joQVHu$Qu={*SHHT#njmkz=bMT&cM{f7F$lN#R>TlxE>u5mMwB9e5*i;OUkF#8hibR*^-vTGpP@Ce}Cm;88y>_#`!7uwBT;0`t6im-&M{)@ruu+#Py;d3tVpq7~+MS6cn~)I|9b_ zBCapP>H03(r{%04BsuK4u7R0vsFeNk>Il8b4&W`EG{O7Cel`rERia36}he9&bdUYq%N9BT=ALv zxt&d?;S3kA_)OAi8~QPwMnH(%ws7;7kC67yW->7#LlV_MSjjQvZhCpNX=7^_Cv>bJJOdNLy}S!9?57_f*Q z2ec>81A^K(-LA1}aw9De(bdkN$U_#zHwi`$Zt0Z#DB<+SdSj?4zhOiAgrTDB?T$^P z#9vYI54AI*`23zl&>8BVo29z0C%1r_J>@6fn;3f<-QvbFu?^J&TtXz+^fzHc&5hyU<^!Cs_&H6`pYk zY=DT-S-32LJS%7R3x6Zy(72NYUUiLSu8H1Svs={7@QkD04I+j;;m#}k*a3fD;jcp~ z{G-C(!jh&1uv6UbMBy)Ut@PKWB~}94;A!pcX}H2DINandvlgC#zp<~t?qoC0q|Y{) zOv`-*X7I;&wSMx#*@J$3-|Pti!^&{|S0n0vu9S!vO5Ye%P2U)ML$Vj+KDff(-Eb3? z|9W46eaTX7xvxN7RkE+Ze*B@hvYGn|B%1CoXsUVuBy89%*X`{qa3Beq_-ynC`wASy z-?a9j)@seckm4%f5Qy0A8ZN7V|HZxnhcOz}CaH_KufXB-)_ny`kt5(KC4nDbvabN= zEy|Vv?nvH%DU=Hnro}}<$ZU0tf?(ahJ4(WARWvX-&h}{dM(!B6$^HY!iqCQ4qj^9| zOL?=LW_vvRy^RM>kYF5}JW*~tNv`!%@b7Ira58~jJn`|fr_fsm8L1FA9ypbMna`&| zh}`LLnGb)l@xU3pOOu!xZW|Ar$scq96?NC#J`0kS-Lr8OxpUwqWtXk%qzRYZL}AFV z(V4-cM!Iu}F;i+MwN_!17F(@hzDQDq;^RRIq5zeC?hwq?VPMLd5IXq>>^m*JkPYCBpkCVJx ze0|E@Q_5K+;5==dXN2>t$63_VM+%JC^_+4R4LHvm=LO-s=y4Xy!zptwDQB^O^RjVX z5zea~XYo9oa`&2Y77sYD8|Mw-yyg2oN_Y>}l?3m<0s0podurn2ylKwM?sZ3+e4^1X?UC zwD5X(cQ{FE$dE zgn(6qaM|FQgM0KWO$}s^o@FTI+oNY${-Cp!SO&PFX#VhDt6L5~SgUGzTt#jLxZ0|c zbXk%2>O;s*cz%|wM6cqCnJ9HhimXg8rpPJ~BDX4Bl>3T>XSvn*i|QADn-tSW8%>On ziggJ8wYt^ugDJKKuCR0vZmgJmFR_lSX=)+DL8;(Sl1wdh5iI?L^A%k4TP zYzU6(t#8y0F`i$W*-p-Imxd#eJzAT3V83#=4iVP+V~h-5g(KhHy8KP&XHh?G`*ne2 zdUwSYwmOBIG*dSL0rSz~-R9%I#{sepFVBS2Bdn(QhaqcF*-IZz@+l)>~fi<-ltgJ-!iNM=zv zt|He9ZekI?w#=fbO*r1Z$?;sqYV7(BOKRHC-HFqJW0Pe}2%Vuks|?1dNxd1Hw$IrP zOpI~0t`C1HuDIJXrZ2r{Og{*b>kpSjt>Y}W0e{h=mY6hvUTP9m50=$!2oJMtBV0vp zW4N?zAc$Mw2uF*uG6l|3Latr9lud4g;6<0q45)>WiM;8Ld3D zO%88%gBjL}6cy!~p&|6{QPCMxYNDlSC?wNx7_Kl}0@u@U3kKHq0;3TXx1^tZbef7= z(T^%tK)@&n+(gCR{c}{TWZ1Nd!|C0lq9;_ODyrf(kW9r9xWY&U+*n0>P+MJ9YyH$Z zHq*3WEx8wGdm$Lk3rAY;HVn#wobIo;%WydQK3+PC_sp7K9G*-Bk>!bsS?; zEp~=vT2$i-yKusV7L`Twqrg;ROSEv(FwZ)lSjV$P(lgKf-fWgl~asp(4OAP22%YQ*8_HB5ZXUp{GdH8rl5URb2= zXKbD10&{i}By2G%*Os#@GiMv>YwAj|tuD^^oFTfL$PB(^0rd zt;=436>^xWeO1fEI@dso_6QhossS4X*yI7(BhU_TDuB%jWbc3hcQc?9V2cOjhka;u zS&r4M%49ug%r;|A6XtY}$?yD7$ugV*$&K~J>fIH{Z+-*LFyI~n+|vW{o4*|(t=>z4 z{Qfs!WWc=zxQ_?qr+a91d5+aHmC4U|WA1Cr{e-!{$K+>xsARcs^#Kax_q+jT8Sp>> z9^?V}J>L$HRv)ZD7H^&e?oi3zzSXBIkYC{jJi~xz3h*os$gl8rfVBE-1@fERfae(STmhcv0r^24 zTHPnd>hqP!Pi$jeV9X1Jd6CEDCw8c0AK&VW7054c172dlO9gnD2jmxbJ3v}}xdQp^ zZNMuGc%=ZZ@__tk4z2E+WA)X_Tq$5)W6W!Xd7Z~xIi+M@-|FiXxN-oz!GJdk@Fowq zO8Y=seX{~r34pg4@Kyod<^fkrS=}$k>f4pMTEM)+n0E^EE{|E9QnH_K_1y|A4uJO< z@LmDl=K)u5A4se3SK#Ua@BsrpD8Pq2U?ydC{~W6yR%Rw(K4Q#Ah54ArTr;I)f8XlI z6}V;qe8PZF3h*fpxK{f>TK%*F*9w5o81PvEKIZ|~PFcM{j@8dAbM1inf-zqd=1U%P zos^Or_*TEHz;y!PD+YX3fUkMLb=wEh>em&xZUB74fNu)$Ef3fgKn^om+pH|NarU-C zy9UsA4EnA>-}9i|09`Q`>a|neS7Nt-_<<2W6yir7alHaW8vd~o*9(ZB81Yjf{>LMB zPaB@wKKo3e-2>?72K_>yUwY6UX*Gie+E+^K5fHyN;x|J4)+3e_Aky&flvolFzc=C! zLj2JqmZlBQZKD08(9!_`52Azp?BKw+*Vpgh4v1h3m9}kfiC1h`=r$jnrRCwu}?tkWW+^; zxTr_$TYyNz7gJ*2fVj93mk{ET98wJo}gRU;nH9Y9XX*Gk! zT1JT*2gEgvxRww*d&Er&5NY_@O57wMu4BY?h1kU-4on-K+g$6a(18K8n?ctT==vUX zP+HBPz1Cfcg92g?BbErUr$^kZ0Fj25Dsi)bSZ2g>A@=f!L(+!lw%B?rbVva0W6-_= z?dL&Df* z2N`rTfe!YdTc*_vT5Us=xMe^bYQ$ke+}tB>Re(stw@~6%0dY$sZY9JDkGOT(@Z5IW z)(YJ^fL0oGxInk@pp|JggNEA(B~}K+ZH+imh@(8>@B%~{K3a*x1L7DXZYRXC9&tp< z@bcW2+c<@e2%y^=bO(Ws_n_OR)CAOPx$UULZ3E&2Bkm-`Dvvm_0Fj38ti+K4vD%0e zg;?VeN2d+XZMoGdbaVi%Gw39NPWGT<(rN}Rw<$^-6AQEm%WW@(?ifHLgYGTReLU!dw39PW0zJ%wR;SerT5g9cu{t0gVZc!kym&=U-LqCijbpmk|AgO=OLN~{Zr zrx@{6A)e+DClw&l@Y9tzDIlI<#509>mPeeDHaxfGcD6#N1kiH~dagjv^Pu%ac#je972k8c~fWBeSHwF5Z2aVEd1}(R@l^6xYcZ~S15a08Ndlw+m@b{ItcR>8W zh#v~^Bab*UZFp|W?PG<`44|JF^izTU$Aj*hRx@b1eWt{H1LEgK{6dIddc^$-5NY^V zO586Xer?2Wg!rvTJRog&Zp-aEg&q(_JeFb@u(9pIVtU_wL>CfuY4^N_TfLCdY9 z5)TQ83m9=hAui+*4=q5X;R`GA(16&HkuQIB|d+VI?#+hPhmJb*54&?N-Aqz64B zt!B`2TS|#X1jMC{xQq~&^@v9nAky&Vlz3!7T;7N)2ysP^cr=LF5z?}Jvs_kE=FtIj zWn-=)%vC++F<@qgabu=er>~~KV*+5Y0aq8`8XoZ2_JOoIqrhVW;F<NVz*7QX9|QIkU_TFdYWqN1-Cu#H2EYvr zI6#0Kdcf0DR_E5`8!7YjfVr_THxcHh9`lTpl0j8IP=RLzz(EGwOn`$u;F;|MY4s2V zo*4j#8gQ5ZH}`;Nr>xGc$hT1D*#UD)V{RqP3XgeCO39!e-&%p^1i(rI4j14y9`M}u zfwX#r0?!SA+Zu4B07rSi^HWym*5ad;d49kgW6bS@Io4xdkWw@1fA>b1^}SK=)J@dP8DD8!RI;;jXUH2h>G-Wm{3G2*F0 zJk2BCo;EzUeRjG+Zx5hn81zhmp5;OBNUIq%(9Txk9RcwiBc3b7^E~361&B2Kd?nr) z5HB#|g+jc@Bi@}hJhzEVZ@d_heDa5Nh;=Kik zH2i8M-Ww3FG2*pCyv`%upEf+Vm3F;C?+>6i81zPg-sC|aNUIq%({5Jc0|D_CBi<^+ z+dSff1&B2Kb|pR-5brSJokG0JBR-rqJh!2Cw?ZEdp!XQ`UV+}{K_5x08MM^ySK=c9 z@c|<~D8z?6;-dwKH2h&DJ{k}oG2){_e9R+0o;EzUt@gM=9}l2U81zYjKIK85NUIq% z)}B`469MrVBR(s{=RD$*1&B2Kc_ls>5MMCji$Z+KBR-urJh!>_vO=E@psyJ8Re`?d zL7z#h8MN14SK>1P@eL!sDa5xt;k;2i8=l*8TTY?x2himWx`IGg^q?Q4)eKs0D=G1VfVi>| zR}tc>9`VBhL>j)D5mLCb9;C4Lk)q`K&0X0l=w?P+}?;g2ywhe{4H&G zZp&>)h5i;mCm3`mfmV6Y-_vRaEw`PO_GsB*e)^ ztSst~wmi4#Hbtlm>Mu*IH|#Eg-POZ(AU5oTDGwTN4a!6~pE=c-jlyj5nDZ54()wm) zBAn0M&6rM@EgrLD9`kb>aIK0(P#@c7*lB{D?qL_mqiWEE+g+Im=QC#*a}Qze=`j~9 z#H9IqDHGv*W@OC0g}IN%TsUohYRbz@#UiMW-Pf@D33h)E+bOMTIO*j8Wg?u(0b zc~lJ=b*C#6;e6&9#ynG)XL-zJ3NdN^*~&yXpLvck&lTo*9&@=o=I1u-&Q~mg`q&E$ zd!b-2^03S2Q8j4VU93!m^O=_z^HO16<}p_&#H9I`D-+>-<`u@gQkYkH%$4$(pWD2< zTCoV~W3MsnwSv9Q!>*i1)u4fQy)qHbXWn4U8-;n3$6Tclljh&7Ooa29w;1zQVczC3 zSIc95ZX@q@#UiMWy~D6~3id7!TbxJLpqY2KG7-*a-eb&rg?XRHT)hyJ=HIVOg!7pX z81q44KIAboWM-$ul;@ik^RQA8(x*OR)JKK-m`7cc)a=BVnCcC^Jg!It^N~*&@<~BH zI+7FQK&C@)OFH|29^HHibOCU z`HCT5736Cka@_(*+WxvC5zI%vVaPWH`Id+5nzlW+%70s_2FA9=|23Lt6w$BINSANh$PKNaMEJY@H@?YZ^+XG%p#pZd8`zYyw| z9<@hW(V)8jN|6ZWBfmD}H-h}uLzWak()RBZiC{kRdqe&p$R9mqY1;PO%Kj&%BBW3K z*{Ht=^;eHtmR2;V>wi-ug89hb4f%&4|MZaM1(3A8=n!^(Rw9^>>;T`S_Y)#|KjFr` zpOwASw&&LL9hHiZK6L@3E-2K6JZhh`qCrK!up$x6M|LvgB7$7hL-s9zr0t6-62W}r z;)Yy8kV|^V{%PBDzv!1zDnk0yrH#6bP?zAHtKIxZJB!c>)QPfTZnfD-ywcN-;H$p7A`#3- z_Aq3LAbWbq%?coCd#NH3%tw|PvRsh8JmiqH?YZCdy_JfPKDCcg`wF$6M;)40H29?N zuSf**ksBCtfFL*Yki!ZfY5PWsL@*z@u^~4R-WD7Gl!;ot24jKC{}G z6NOphF-PYyKevTft5^i}v2})>B-qIwc1#{sgC^b-Wg?u9&_hB=I1u`4puCJ`q)DZd#GR!^RU%k zYC6u%ibYT#dy8Rj73^&ucDJ;u;e?#qm5FdZ^A2O)Da^Y(rYppx`FAT5;e6&j#=KXU z_j%0LJm%-N`tDaOg8JA84Evy9AM&tmc~lKreGe-W;e6&J#(Y$mk9o{#g_tz|ab+T$ z&wRp|PYUxXkGXpu^K)B$Pb(Hdee5%aeO9o~dDt0wR1I2v&npw*eC7+rd{LM$dCWZu zF=_tG%0xJy`HC@L73OOmbFVz+=eGJ@S1f}1*f$LO|FL&3a5B~L|M*o1A&F914V7C~ z)}2!B(OTqE3Tdrnm$j?2yQG>zNJ0onh@uce2%#vt(M6F8p}X$)d;Q;+oqfMPXXfnm z`+pzb9>2%$(WA#>Iy3V=&v}2|XZD=Wd*+;RMA-L%4aZ2;ne`o2lj6`kX6A7*KLGRg zqD&tChiXzBnje|@v6!ELIVQ&N{jtnUjoDGtpq&HPHt zufZHwl*z;YMoo%C^IJ2&6Z3m8$Hy4Hf7bVdvJ{H!kH-Ea?9aeXh>@x@>-$AbibL~P zGk+8FcQ7XwW%BU z!k!N7)EKEcv%U&yQXHCRm|0QGGr^ozl*z-dq$b6oS=r39#5^0!=`n`ypY>HymO_y| z$Jld)JrCF!F;aDAeO1+@I5ZQ?tS099V9qScx+2_m~*3tA9eOl z17#@`*(75d3fl++xtbJ*W(zZ0ig_uR^J5I( zKkK_pSqeqAm9du#dj+ryVx;QK`dX_=acH(Nv#przz+70A$-{52CdHxI!OV_gUJ2%+ z7{m9^`Z_5~p~!YN_9|hMfn6LURcF@MMNNuBGsVoVVs-=b;i60)es?t~4$Z60>>*}P zFqgy_zJJ!&OIZp1&HiTI zAm#utm&F*qf7W-SvJ{GJs<8uwO#^m$j8vUj-yk(94$X8k2a7ob%oRnMJp2qbDGtp{ zGlz;f49t}=hVP&CWhqOc$PPC)Ti6_6SH(!xne~lOlj6|4$xKhoTrgJ`W%BUz)TB5x z^UWM7<|r`NuvvKaPNP_7@7$~^MWQ;|)LTTo71Xt?7M{IRpu%@Nw<$?sNQRBPUC29t zTvr6iV;`d=g&{fC$Z<5i_dR414^QPjIY-4LCqv(ulXB!wY)w~>>D zya&jQMUXu9DN0fpl2eVGCgi<9Zi*hef0sX9Rfs;7?QJ% zoFnA@KyE35RwY{74JKSNVMrb}@`#Y{1G%pVlE;2jNeV;qn32bY`~b+eqQ~y<=|5DJB2oRw z)Q?5|1l0Y}i8?L)r%F;7lAjrQLdeg7JWvG5WB)=)3PbWsBfk>zYakCYS$Ou2%)p|~ z-uXsZ3Ptu?W4{yjdtl#Tw(#to2n#d2AJn8cG=DVnCoz8p^WCCM9{w+CQXHDUn)#cU zzk_)w#_;`fyFZkrP-Oo!_Ag=o2KI1_RGrCPv3ukLQi?++xSAA)W(hM(ig_xSM`H}%KfNoZEQKOl+SoF}o(Al(7^yn*yRvFh9Gd0KEHCEi zU>+~Z{-H|4eUoTQgxHn6QIyHUudODD%w}MI6Jz-Psa|tsDHPcj#I)Q z>;Pc@jFGA{>AO))ibFHi%z5(bI;z%Qj_A)9ByW|m^omcT$IVfAE742p?Q;;o|w5{7LPG}|Ew=h zSqeoq-`J7Djsmtsj8vUj-_2@L9GaueyhY4g!7N#n$-}=*O^QP^Z07A^-T`K*7{m9^ z`o<_rp~#LkcAT(x0$Vyps?Mx$yqXk;<^(e*ig_29Wr{L+_>bub;3Rg>^U(~b!L6*)ucEyH<-Cm%%{LSwKDwQYf-78T+!ZuK-&;Myk%NZ;zT3hvr^0UlsE;Fl!WL z^6+0*lj6{P!_0kRz6s`qF^2D-^}VGmg(AD(*aO184eUiRQgvp12i2rFG~Y4vT`}JS zvu05y5C4#w6o=+vGmnV*KA5$mhaYwJ&QWD46xn0O9vAilVCzJu>Ylyxp_&wj=0|3J zEaoR*)-B59;eV0@=+Vf>r?f~PpVDpQV4K89)tU8`Qj_A)ENx~PF;4@tX;CH*zpR=Rhh{l5%ZqtBn9XAh-#_cCpe%(V zdxo(Ug*_A47BNzFW_^{^q&PGyn|YR)XM@?YD3ga@MNNuB^BgnJ74tkWFN-mJ|E#a7 zvJ{GJg0aD%w}MA@F(f)>YFP_K?t@mu%&>P0@yJSZ{!#mP@~zdRI5gXs*;dSUV0QK=>FnX#D@Z{Ib}+D`fL8)|RUpWt?xY|E zA=uf#s{~92u#11x{(XBFH7O3w6f?Vu*$vDTf0E9Qy}N=Ggy7W%_7JcqfL#MY9(6AT zDG0&d23{lJwE%YakJ`UW@1rKgp?RH|*NfQ~%&YxLI{Wi}3Q`b){SCZ9zySdE2n2c5 zH!4U$2&Ni1P{1?*d-+H0-;)nglj6`!H*>IDG0&Q2HqmztpN7(kJ{g@-=-$Tp&2&wb}{b&v%fz{r&S-LAO#^f*1&NB-U;9h zfgq21yn+;j-~lacHo}17D^hMWMLd#1$ew4q{f+!2R>Hm5NdzqN@yDE$9<~4v$LHnV_vv zk)lvsYvMW)p9C>GSmc4PSCOJn++gBH5uXBaMAX3jQ?yNrQXrz64c#K>(}3O-m8LUC z+o~c(p}5V&?IJz{q8BXkz@Jr-qEOsn;!Y8t12HdZ;Qm?K^NLa+qPq;;E$9n?=0~OJ zOw(Rek)lw1$;6jMdufq7;be8;0%^^i4oV zN2Te^)ZS8&qEOs#;sFug2Jx0)kq3TIMT$c49TVRb@jVc4iyF9pu69UK3Pkj67YD1K|=cOrfd;`pe6`)6!FC`y5d z{%Gh=g8mHXgs3!~Dcdh9QWT26n)sWDzk@h2Smc5Kp&~`0_@{|~iTF2&lcEOhpR^U5 zs#nFk=t=Zw{=kgdb;f!p(;|IpNw<+tE$@y>)0wpuSCOJH%@QV-6!BCLCkKl>@KP#L z6pE!yEFw49;k1w9?msZnV<6SoQ~QWT13m{?K7GeMjdEb_oB zsYp>MRyOf05zhv3x_{tN=g?G9lmZbw$Ix>HJrB?s{xsb)XsW76Q79&uSWU$9L7W*Z z^1wqXQWT2SO{^i}1t89f8n}PvcA=sai0DOz))cfBptGaWbY^a~Rir2s>zG(q#EU_k z6D;z;>#0alC?=X%U&Kp5oEtT8|IDp{q7;Z|lA#R+Z3O58QE56ex5g?`6pBquY${?i z5a$JpJn-f!QWT0UOl&FQr6A6a8n}PvcA26Sh-fQAFBkL*Ko>-%>CD_(t4L8OwlT4- zi0wdJ7%cL@+p9=XD0VQhqlj06xF~Ai{+U}RMJW)`&W2tkXfmLSqtbL{Ze3KQC=^pn z>?&e65FZW}dEnhuq$m`xHnE3@JwaR&HE{pTt(T${h-hy^uMzZGK$k|P>CD{vs7O&L zUT5O-xeZd0 zqEJjXaj=L(KwJ?l^1w4xq$m_KO&luXFc4Qp4ctF-%TkmA5gl%5wxBtHu8K<2nYoQn zk)lw%$wW`YTo6|Wi#+f=6)6hEd=p2CI10oyQ3LnS+-_Es0udc;=q-ZY3h3IXG@Y5- zZ7Na}ieVFP7x4}d*9D6_@G&Y<6pCX_94F$PAg+%ZxPRt0UQr4}bb_H11-%Q<4N+-2 zGq*`9QWT1Jn>bm-dqCV6Eb_pos7O&LPBn3wi1&iH$v^O@^I)bcN`Z*ZFm$G%_W`=u zpQd{j%q$ft3dPwb&Jpo`5Vr)2Jn*?HQWT00m^e?w2SMB#HE{pTZN8!ui0A@C7Yh0i zpxdI-bY^agRHP^r7n}I7h>w7{Jy_&{FHw=AP+V%_qar>A;qucA`g6xiWG(7S`*ia_#}wWM-ALRb6c+{1tPk^ z(2asV1?aA*G@Y5-CKV|P#my#e5%FmdcL$3+@U1FR6pGtS+%DoXAifwiaR1EhSw$%j z(H(~F6!bYjUy4f8nYlf$B1NIN%f#Ixz5wFO!6Fa*MHMLu#g|NcS;SXB+!Hl$|IBTV zq7;beUPE6M^ff^DMy2V@++J6aqELLp#C;;Z3F524A`kp66)6hE{U#m|@of-akBDjM zSy>GRG#D@_GdFc$R{DUnjP$f&-a!>93dMI!d{@NxKzxJ6iu5%~M1=294k@g7xuA7W>>H|BN=1r7 zv9yV0L_7_|W0)X|uzkxaMw>7JHxn&!kr1+hwga&+qaU6 z6oq1C6VDRyY!E+k6Lhw373C-dxpRy=SGe*0CZC09CT!yi6{H{pFEX&EfVBWT5eV|AYb!`W z2-Y#Mu7DQ<_=SJe{_R{(O^QP^(aic{UIONq{v@3(-9SMKLNLj|h5|MM@T)+ON8MOK z3PP}nflUQ$2H-dTQTwOc&DEqhG+UV2Qp`)i{MMhOGuysQK?*{!m4TNFcm;sp1%f>4 z)(TP(f^7_JD_}bSfAEjmKi6)rCdHxI!OV_gUJ2%p{v@5Lb|(cX2*J(-w%DA9UUs|zOMrLlvOCOS%n@3+sWTocOoGmvrGS$n>$Y70SyA zW#-lQdT~CbGs+a?n46cH=k?~t5|Sy;p)<$RV$J^EHIfp44|gpsg}pv<|AIbED7`kJ z+|2ADS?QsHnR%fO?b?MXog6PTDm6DWC_OJdEstJ4Gdq-a zUraA_TAxw`5jK(`{`kQDezrcz#x1 z=Kom=H?XZK@O9*cDe$Hqz|SQn^L68v!j1G`K?u2lpZWd zVHhojy)3%@pOm4YH=JKbb0}^(G?X%A^K*&G#hn~-=)r;g{!^FBLwJujg`Z1IF5{#zl^!feV;U`ny?g1F(`Y7X{F6OibQaV3 zl{AafFbm$kGx)j0j9VQ&`Qaux}c1#aKy*P6|qzE)X!tum1j>qef# z&n709bzbd$da&Tt=F(!=dw_2F)vD3T&PI-Yxp@rg%ay~I(=GiVKbx3b&Uv}{^kBiu zEuh7)w~%i6yJsuX+Z(YB^ddZ}d3dZ#@SjCRcP`bpt(^Kai)5JoDQ~_rl&&bXz+^XMX$W z#od`-=I{|&>BD)77fR3O5AS%olN%aLyO{LUw2Xq8VBtiteyB6=bO-ZfFhn!R-1I!2 z_0?)nE0mG$rPqV_QJGm;q3oQz(7^PNmztSNGd7BB*S)vkc|89dL9Xb8z zCYm0sF7r-#i9Cj~a)u1iIbSWFPv+;=DxAI6_cn1YxLBw4IfX`;p54IP%nv2V0X{O{ z+#-eG`R3EK6!x~teXViSba5N6uhT^?qfQsM(^A1keTEjp-m`RD@Zk(i>k6k@4F>RE zzz$wdr+Y^1G~ziSo(Cdowzf+No~;?N+lUv0coB%G+15)+@NCP7myLKuh&@0=O_ug5 z!ILE;UNz!1AzlX}YO?c&5YQFE33O7L98hyzBvEyO_}qUIX!D8X|L zBi=RQJs}PO5jBfAtOU;@j5uP%`$8NAB5HbYObMPI7;)T)4}|y-h^RyRM@sOa-H4Bk z_(X_LfrvUTf2IT4=*QCM8V<3oRjInf<4hGv>5h^gA@CJQ9>O)V3<=a8Ga~1+Jnde<1{G*A27<&QrIge_X7?X<#~NQU~n1rfN?r46>O#ov>5izpxeL$ zMnzsv4;V(AX+$Li?I0uNR1ID>Z@Bzb!^Ngq}L;?^|2aIY; z@Bzb!^Nk1zQ5}e=14a!c_<&)=1x8#b#6>_v9WZJt!3PW@Y8g>mh&n(-9Wd%D!3PW@ zE;gc`5Q#uU9Wd%E!3PW@E-|8k5J^Bp9WWXy!3PW@8X3`8h$cWp9Wa_I!3PW@nizN53Wc!li^_ZvlZ8lhgK6gEGR&%p4`m{Q!zIQ#>(GE5=Xs<6nlpr5dL=HCnq=+8XWH-R2(ZltAxgH0+e(kIDu8+fou5p}Q`rUV~sjL0%#xDeSuL>+8$l;DGn5hIMaNeB;!sDn+e5`3^RBF~6?Aw~ib zb+8$w1RrdSxY>x&LfisG)WPOfCHP=t#BD}|g}5DvsDsTNO7OwPh%rWt6=EC^Q3snl zmEePo5#x=RAjCuP(urX+nL5l@?7@*h(n@7~)gN->$%vmbVqu|6o*gU2VA8gE7CQjsF zvs|bZLg~RK@1K60MISt+<)}h>Mor>4^(4-9$vha{A7ZB2pQSAuacyB=f0Yj!rl{dKVav+ zhS%4fI}cfR?rUkOVCTM$7Q^0?bQ`#HU(f65&fSO&Mr;(~DIlVD?wge0ox2g6jo2c@ z(?CS++_x&hJ9i_t8L?f6XMl*>xj(A}@7#^pVZ=@$o&zFk=l;ABymL2Vml3;#cmas0 zo%@SQ@Xph*yA!+PUvhf_Lsl>^0(5AzlL_YUlpC61;Oa;teDA3GpTnQ9Jjy zl;EAa5&MleAjI21MD5%UD#1H=9v`8P^!P>mz;kDCpvb++yHvg&G+9hr6Q)TT^ zur~jx@;N~RQ?rM8rFC`w8?)8R$m)@LpC&?C5&o@um*cd2^``Gi3hP~-pHE2n1?zpf zWXScdKuh!)n%uX8XQbX0d0nkH4^8WRCM^}zyAmyiy~=bOIc{RT&*D||OM6@UY+JjE ztbGow?bQ2RU7hP~tDh&UN9tWwgai@(t$J7Ew48d&X+VYbKA)dYNcjWn9g+;W-qmR- z?A4I_(e=K7*VTIS(6rtc(o#XaFQUb;SCejI)w>q2qV=}5Yunm&WbL}Jwo~tmb#<<{ ztzJ)7kJLL+g!&@BP|uw`$}32 zd!6VuR=qp(Dq3$_`zl*IS=R0XYdiH$(bYL`TfM8S9;tUX5xR@;Z`J#1PRmzse1G@g z=Mz#&VZD1whFtGnv=sJw%l+tjU&HHay?JO_?`vtPpx%9GG3;GOx3TJdJ+Gqmwzd1( z+Wlnh{;;-F?;CV=&f8WWAgf2}eWM7eBK%wR9>{4q^_CO&3g6#p{Cq-6S*-UU$&l-v zPD^2Lu-uQX_YhuJ>&-*cdS}p5LA^6+G3*Vc+gSA;#;a((ZS5>ud$_Ef4Qo5~&e7F5 zZ(DtYtRAWNO(J+A{9EMfkVs zJ)YBY>MiF~6~4bG@bd{Nm9X9uB}1yLn|j*O|wr1)oey z1qHu{7Q@~Yx{VZ^Kf>VYLF(`4;P#qJegx&Z%H#b$6?PQ~PWu)>PX z$cg%x{^(}ik%D2*@ffe7f77=1GFyAOti1x(cK)Ux*VQ?1TYaUh9;x># z5mt-vZ`Jz=PRmzs+=s5==Mz#wSnsuxA=i5yEzzf&azDD>>v>(RHxEtgy@8er>b;Q` z>6AyhjaBbWyo%P_*4}JuZ;`d1hP9n~Z`IW~Z(DtvtRAWNb`hQt;oqwFvz(UJ8!yb` zQ-TZM<2yJeA>~4>`A*4_YyKQ9g}vwHzSX?&vxHr|vVNM(wsvY1}v}(5Y+p>0~Y6k^)M}U8;YVUGd zS~dQ)W9LNZ!Z+J{9F&k!56gClALFVWriHL~gl;3l=FiMZ5H=!nM0&3GJ_qX6K|DY$ z+fiD|ADBv&&DoNgoMHUIB_Q1}7o5X%(;F|OJVODxqm^QBwF=azSfV<_O4fO5(RyCMyEog z<#=9t?ueZ1L3FhqeXque> z`;l(>Z26-n7c16NF7l(V>PBRx%IPC?n#l0fJU(qCbzn|@UWgVrnL(MUQihgg`exB( zjs5%9?cXxgAhA(PN^C@`mrEyR==Fm1m^|0GW#noadA#o>vRX&c2}#Qtl-~bVZ_t3$ z;WTXeKTj%Ufu@J@|8%-L%G2lR|N1;F$n*67^z3loON1#y*GhWnEejJx>oLIoRDPic?K_iS>0a3Tjcy}* z1l|?WHzk>AsagE>_K1wpxw6cASK8PkM$lhs{k{Xe{&F2i!2_YbnR%)7XV!l>U2N3% zl7c&YI$oeE!X#xT9(M|gkm;|VFvahLKZKgN5M zzi1)s{Y|&D_e(B5!7Da{p3&=cdBCiAC-Gx?$mD@#)UTafEcvA5lao)$^G>GcY)^O! z-J|bL=r%I$fpp?o*L*s9dwgABT2@Zluu$4)`u0b@<s9DG{hr;r)2L_%Lf53E z-;|%8o5wq@RF5ut@pP9W7d7+lgr3c(^8)x{=*+y#)U2%0q4eP+_+k~QoSr>E57UK+ zJsWoCTBoL^<r?P|o0giJ&dKIv(}`pB ze#jd|rzy}X^!J)JES)a8?mMD?;U1%Lg9cZ&3^gwp6aCpVln0WU*&|8vNTVk9NE2SC zS&}`_*#AJoCccOyj%ZM@MyPhdPx{m;*g1M7coXTy=j+e7t^?9@2T*oHypsG}Lds?M z1~`=;<2OJlS_pfk=@t)vd{juI6En(in6{3*Y4xaZ8ZFr-FH8669BjJ%Z+hCa+BQ z!robQ``;%2S2y|Dyg{NjIlbG4cvbkhgp~HU$(R$9Ri3p@p#5lx|~f@n#&RTb#G7Zt>={WLvxi-3xmy>Gr=Z{;zKFOL>DtZ}BAh z8^4U7N=WI2Tf7xN##{VyS_per&~2T(0dtt8~-A104H zcer*|9r(F~ls>qvI`U(@t*)d6IuC_zV{NO>9H!ffw~216t7yr#RWjWRdtK=Eziq`I z7)W1LWEY&mm5kn2(h_y$=Mqx-;kN3=kMXwZP77i0YPyZJt$J{nZY$mcfxmwz`fM!rt|C8*5wjlF^%ryN67EDj_8UH`P#nj5pOVTA*L| zquW@UYB-1Krs7San<|@@Y*XdXy|6ceZvWd<|7=s;#FdQRR6OnX_^E`HEZkJN{1|Vl zJX#2Q`E(m=Q;p;>-Bi3ubW@F@CEHXt)4i}anr{EwRR3&K-NKcO-c&qazm=a#NEv~f z>Nb9iH&vJx!rtw48*5YD!C|_oc$4U+8beFAsm9X1us4owBb%xXeF|j1OEx@*z6Htg zTGH1h^xYlLy@%8HBE$2C7yMir{}dR1L!6mSU(sfz(lt5s#c+C_cPGD|4(JR5BPR^d zwE9nklV-rf9=eoMxK z&@YXO(HBR>^1R9PfQ*sPnK-X2eYsYW*2-;2eZvs%9*$19s@S5FBtwd*KrcCk9u0d_ z>9%&pnHeSNk!kYCz4C~TIA{1XD+EC%g$a&-l7Hb1OCpvwvI59rR}|8tq{r-iUL zmu~qxb3P{^@-n&fRTBMT0lh|{{{XMWzLt^Cycn69m7ng-<0lf6&!^LyICp)QJV;CS zE}2jF!rlV9jl4_vAJUGTZcy;UZt0=+9eah^_3Ys-WX6UvXmH+uv|P`7h#%J9W{V7E zk&rx=#k54{+sS>)lFwcsaX^n=Jv(%1;61{Eo0SKSg;!}_nB}Xn3*RRLded9wId%A| zS#zE@XO}p;!QrcB{Z5kif;xOXo;fd?^O86(gTvF@2kTX)0%VCoMYk~2Zt}F zPmTCYh!a5Y6|@oJTF&Bg zCHUf5Bfc==OCi1j;!KxF^1fE$Oo#Z!h;N1X4ha5zc|OWh%J93bB3O!M9sI+ZTTvm^qomoPJ zk|OBg|5W+_wC9NQv`qQ|A^PppbT2V-#t}^k^dK!ixf*#?&Jv;1Oz3o>OZfDm`l0mt zL+Z;xmQDlFbFy+8iZPg`iA%nkx*iYPT&ajug4E3$-{IGi1TPed6Z8aa2{?H z9n3~!d6>^NaiW_@^lUZ_zks#3jB<5v0E`Se4z^+HW3iXUm(iich=)QsY&1YSALpmcJn30`?# z(kWDFdi}JF>@3OMJDs1 z`zd1i?UKkTf^-s*{O&Hz8nf+;C;8Q4d0$1|9Q-M_o|G1Ow?t0iqn}OJe_laOMWd6U z^n}42{t4d5sbF+AlAQ?_nXbw?Nj=ija)#4y2J?sNGIh+g6C3q3rG||oZGoMr)DRxx z;i~iIyf8Z)-Dm5y6K+mZ2&g24?POdn?tHevE_2I9k(?<-{pI;v3d6oI$gyb>s zCOL~A;y20Jv=H{H&}~8Ua1KA?HV^0WL;CLk@K)fBb&CF%=bc9n*hZ>K_rhKR-9|Rj zT*?JDQgnwDc_$Y9pmgfU)XXgUiDml1WB%*^U)@SxH6D#r?tEVIRn8mah4^8*5}E%s zipbwrb$*OXSA!P9-UW19P`V5G8Mky7@k3fVu8q@o)uackbhYRneZx<;T)NhjR;LMG z9bQKdG9!jjUqJtkNnL)3QsOCWB&Cb_F;1x-Ezq~lbjyG86{z-&n$n5J{2S?!U+S*U zvDPz0&MmuyA5KiZfK<*zn}r6nWEm#Wy|CAiZXv@)9IOXp`I&W2u`xeJDe`nOl428n zj8kk%3v>ZC-9}Pu+}xL9bB>Kpu?0Vzn0yJToQkH{l9nvROX*(NyNqrNQk0*&=9vQJ zH6Sl@c)Hh$SEZA&cy1X2z?R^Uv#tI>60)em*crc+OoLUImiYMPw) zF2AjwkvcMxnf{O>f5*wE>DSV`wd|J)?PdAw)$|w<^zjsZ_%Mk6p!l~82g#2a3Z_H1 zUuxu0(g~~ey{=q*-M(^ee_EQ?jUP%#8G{?PyKDvCvRBhm*y|zpZOfid?=CqXy}ytsga02EzEfpx)J-05@&u75g3OJ2tc0C^UHC3#xp_BslCgISI~iDR-iu_p z4)-X_4ZX2bjGZd%G+?{mWVsIaE6c6Cv2%@mK-hV}at|J>4o!Xk^6-NyS8?R|CNB_qA;{+hB-|AL z1=EL=J;z}e8M|26hk-pe9?NxjMA>s4c8Re|g?$v*ssVLq=BvYFDpz&nWhO5dc?HM` z0SPz5Iy|myg2S#fc9pQJfvpygq>k)Jhr zhsZlYz9=B!7FdVpl)cDdpEq`wu)Be+8IR>Uyr67Nhkeo5mxO&8*xJN~V$AxI{1eJo zl&pNwK<&4^(d8$RC>gk;or|oJ6wkFjpYMd*TyilN|O_V?Pu21h5U`v0R7G zm2K#-Ul{wPuwMb&IG_&xcf{8!H+JN2O#W8n??7%6kg)TH_+Hs24*P?#KMMO3uubE! zT!){PZR)VU82hWRzX97kpbq{n<9C&tJMteU|0(icAh!re*y%F8l62jWn|@&!QW+^sWN{dVe{2WCRY~uERfp- zBj*aTs#0oy*H4*o9Ve3jcfa>(TBBG&-9 zLqNh#mvMoz9US&TV=of6Ca@jjv0R5*%64?v+Q!xqwl1)p0_x!JGA>rRlOxwNIZ@>L zAa@Q(*y%DZQMR+gHZV3x*oMGf6_4dQG*b2|hiz2w*FDx2c4ml@ki*vo+nd}$Ky8_!Qpbq{n zqnpaT9J#y6SBu;O2dI0UKWI>YEpp@#z9KPY8qQaMcB{*Iev?r?Fl!M!1_%caOs_Xfuu zVeU=hdf?tjuCL2z7^}<3Rry9o&NDe*u{^G10D7@W5dGU4(yfrA(9#MIOBQG&|smPCld{aQePM7hRvNt*GGGmtu zy8>7*9?NxjTv^XyR~oxY*ww)11=PXcWjvvBo+Ga@d9BFnK+X?H*y%E!R5ssX*BiS* z*p0xBjK^{vo>F$C!)`Kmv#?u$y*Z!`{x0Kbm2Y@5!ays^84-3{z*0d??q884`OnJM8Pmz9H;BV8;a1!QW-PsWPAOW}ia5W%7QJ4}d&2 zAYrG=cw5=A4tvnpcZ7Wx*m3b#uETrEj&s;U#vT^-2(aS=>frA(-dB0NBOf*Sn8?RL zo)D0*(`9_1>;#AX(AbZJ{TSGZ@mQ|IC(2HA*iVi9OxP2^P9oOVWyq{As>}FX=}8X# zh0$LM{T0x66Yc9VA~eh>zgG8d$Nk3KZ^iu%+{tlWF2(oiPIlZM%>7Z^pTM0GR0{u` z@@J)|IP@<@|0?uvKu--y*_l-SuI^OF{lnZp#r+H1X>naH#oy{qbKGLH?4w{>q>qB> zHu6#MbaH)NMx$6=#woN8eHuL7k&ByLLgbPl&mh^?WfaKpo;X$684g>@*wVt50d{6Q zmg{huvNIjFtg+>UEf4IhfI9f!5vQv>%aJRXe1^ysL7p9uu=9pEQ`y-LTglkU!kz`} zoOmqP;cR8+IBXST&k^=qVCM$Z!QW+^r}A7!u4;0E$kjl8ARu9<%Q#=z2OKtJY;|F4 z06Q-p%XPRw*?A6op|KYUTNBv%0d??q8MRcN@5r@Ht|M|?kQW3b>~t9yE4#p9>lvFU zY<*xC#$&k-mngf?VH+5mBy2-q7X{S8-(@sXd66SGHo1w&O+j89kg(HbG*fo5!!|dz zg|IDweK;P=b+}a7haL7ZV_OM(Ij~Ct>frA(u26Z2BeyoWjmT|5UK)_F(`B?%cB#X* zH@1VY9f5r`9?NyOQrSlxwv(})g}n;cWdU{YcNxhlFLUHBCZ~wp73Ads2|HazH)WSQ zYks(^%@E~Brq zs~onUvHgX;0oc{?SgykWWmh}wjmD-5I}q440d??q8EGo7apXZJr;9uomyx6LdPg2%@=YRpAa4jr*y%EI zmEGX5dB)}oI}+H9@mQ|IC}lS~?9IlG7WNikHxcXWGGx{l)n(kO^d^VC&FHYuw*$SI zXkV8RpS@XsmlQhKXHPcr&$ zp(g{qEhuGYQhATM+Z=a_xl_fR2JZH_E|=n7b+`M;2#@MyOt^@Yvcr4f9No8Ml*!9M45OyQ5 zdjjg+p=SuR83r#_kYy zC$O&v)WP3nJg4&Oj{LmIyF}g%@*4pOJ6*;L%D&;SFB{|hK@OK%nsr;5Bzi#pyBJTrve?Y=cm+_{u`yKWzWA_Vt0N4ZZSgym{${ujo zgT}ri?7P4o45)*@%Xm-agN}U2_@_W4D6wRI{3ScPgFkS$e)`0naC$VJ{*v+(`9_F>|uxf!q_i`{R-G4@mQ|I z*UBDo*l&#eR@m==JsMC4f0yyS%10gf2a|sk`6rN%1tjcr89ys~%wc~q_E%wl1NL}4 zmh14lvd10v4`crn_Ag*R45)*@%lKR64;{JKZ2KIT7U^?fx{Z7e{82!{PM2{Ctw0|F zf8?;mjV&Q;Nnk&Y$8sG`RrX_tEoE$JVaovfDY1oJ2F&`Rx{TA5{?wt%8eLB4@<4w^ zbYYj_(lDbuUER+dw}QE6h+7fd6LDQG#hL1!aNJ7fRu=axaK8vDg?~QU! zN50VHi$tyo^0y@Wx{T=SGHNONt;5zfwvMoMf&DHX%XPR|+3y^-p0SC-)(7^7fI9f! z5tpd^gCjREIZ5P(ApaPUu=9p!r0kCl+t}D9!Zro=r+6&ap_#HjIc#%dTL{|{*k1zb z;O{anRrwc3zRcuSB3};juK@`=UB(s4{_3!;jcp@rTVQ{S$8sIoDf^qlwl}teupNQ@ zBcKlcF5^m-|8V3^CU+M3Dvxdtv_XB=S1`}ySLcafPE6%v33zoqj9am6kHZgw&-K^!vfz9 zaQV0}SK|(aDH!1~29FhZ9KaQVs^M=x?o^xN(H?L11hFTAeMV5yP6Kk6!W4|~B!ll3 zcrw5h>* ziQv$TJft#3qrAxE#Ueip^11P4F32M)Q#8s;OkOJTqaareEQo*l`IzFg0^-XIUoQ9x zz!L(~c4nZDt4z@-uQYj;$g4rF7GLIqJfSj0qrArCwIZ(rImEKBEs1#{$CGMPJlgBc z-XQiyu&cA}n{`BA%JG!K6pZjDgEtGj1>hQSVXns03R5t`TMgbO@OFSN4626z-SLdt z6p!|^X73PtC)gJSCGEU9o>Q2D5q{p_T>|e0xMp0KtMP)u6pZkT2EQcm%K+C7s)oNs zc|~oCM|+Rid&Pbg>^eb7J59=K3R5t`uN(Y^!21BM8yDtkys0n+Bm9=Z`vpD#aJ`^v z_#2hC)uwo~51Rds*zba!7?iZrs=TK#1tWaO;KKqR0l0o#n5*%=!W4|~QG<^Od>r5g zLDlegD<7y$@o0Z&_D5oW40cjb(oVPXiNX|&@TUfUCh!S>8^(pX8lNjn!3ck0@RtIA z1#sh_YWTaAuhph_w7)U?Td}_byGc;ePPg*C!W4|~4+j4z@J|3YjSF)%epZ-*5&p&C zUj_aR;O0Tq@OLY}t4;A}|6%r@V*dqpi=d>PZsl)9*h_=9HFk zVXnq0v_?iE2P0hE;1U9t1o*O`YWTaAQ`M$;v`d*?TI@1lw+c$y=~hltn1T^5Yj8P% z%L9CQT$rnIy22EUa0P?U5V#`1t%IuJ?^e!Ko8r-~WOik-&jPzmP|{Afa<;-0jBpi$ z&k^`sfZN7}xf}M8b+K!J-61Gxr(3x|VG2h0 zLW3_7xF*0IW4HQEp&zlE@7~zAC=V1!<%*MWfu<n-8 z9_{XCUoCbIuzLq3?Yud9Donu$_cFM*z}EnLOjBp==uM_xsfcpeh!{4p+ zRh#0`?q_y?v2OtTx}c<;Ze@VN6pZkV2B!)<5a8?M!d#6sg((=}K?bJ_JQ(19LDleg zD?`+#c(gOj&J=qn*!_c&cDj{e3R5t`Sq2XmI2+&_;=){w9EB+u;SmPkB(MkYjX~A$ zcPqJSQ#{&vX6K7N671BVq@8YMl)@B@@XZE~7Wfu`2gZfD8n-G;!3f`Ga9H5m0Ui`o z4S%@*a z2&#s^Te(MVibs2j*;B=y26kpp(oVN>ufi0J@N|P`2s{(up>biZ#(fG?Fv7D8o-Obk zfU|+#xALIE6pZkEgBJ+A5a8^%FjwOtg((=}MFuYx z_+fxY1XaV|tvsSO#iPB%?4@Eq3ieGwNju%jV+vC+!pjU^F7OI~y|^$}<8g&47~z!$ zuM&7Qz)`uQ7YA*z3T~4@%nUR-ROtf)QSC@CJc50z5J<%++{GVG2fg zlfjz>-U9H=4Ews3$Q2)MxAL^&v;yK=4c{jCcECq7?(0?}ICLw|s7%o)KWp+1k#~Z8 zOMICN@|?;Pjq>v*?-F@8$hQR+#6KT>L2+6E@fQt$N${5e4+p00Oh{i*nW9nNWAa{+ zUj_O0_%avdHI*qE<=0JqL*#uRk72p6TWJ`4Vac0nQ#{&lnY~}^17MG3yRchvY5H+#6Ax8grKCI zH^&DGQ!v6G8vK#K9|JrwF3i>VL}3a>_)~*F6ZizclY*+@?^Zrno8r;_!t5`_{tE27 zgOYZ-m9G`1V1&Oh_*;R$19);=n5*%)U5p922{@U*xvSL1JmDH!2m_uEI&v`8OC({1FV=;=Y#@OLYx z&`R`aG{vJ`-0Tu!mjru8P|{Afa;m}2v;%q9D&aT zcy3TN{N2iVYEwMgRn1NiyBgRJ1SRcsE9War!3c*8t}bv5fak@9xf&NJOu-0WXz)b> z*93TeP&NGBN-ec19_`v@*Acre*b9P^cDj{|6{cW>>lvIVaD9Lm#)Y{WmnclZ2sbb| zN#KS6FAA!LzguafHpQde*z6`^HwAlfP|{Af(oA6rM!31bEd*`}@WXLouEwPbQ!v7p z8QeMZ+D&DOM!CDmSBu;O zsF#KQ5m8z z1tXkcaHhaR0bUmu=4uR6n1T_`GI+Sa*#NH(s)qmFk)t-nqdmgxo5c3O-Vl_u^XAA^ zn1T_`GdN%1kpORu3v)F_DNMl#-)!(`fo}nLQ&2Vh-O8PmU20Q2+LO$_TkOeTZwpG= z=~nJhn1T_WV(?Ufrvbb@F3i=qS78c9c)Gze1fB`-vq9DHcPsa)P4Q^YGJCezbHLsa zl(f^W+^;YNBRtpO2Lzr6@Xoj}SK~p2DH!4T1}_kJA;8ZERm0z{Jft?oqrJ%N#bQ4U z_O76$oo?k3g((=}B?d1Q_)&m&$A!5Xk10&S2rn~uxxgy`ele&T{%+-QwJ9F$m1eIJ zdo|cE1tsltD^Dm)!3eK0c&)(e0Dd_x%++{OVG2fgy}=s<-U#rXplbNLm8aCEc(gZ} zy;)U5p922{@P|Rw@V`6$R-59{E;iRbjiyEVG@5QBpGJQal(h5aIEB`r zkD@6U;o=6D5V$13AIF8c8mB5u!3dW!xU|4!0RA+n8vbtOG_@%n?XqT<6T3Xvp9LlD zbStMTOu-0OF!&6CD*}8XF3i<9Q(+25xRSw@1wISlFM_J!?^e!Mo8r-~V)i*=p9}Vv zK}kE^%6SS?Fv3+0P7t^nz+c6MxfH1s)oN?xj=1-NBcsvFA}>Z z*xv>v?Q|=(6sBN=Ya3ig;JN^R7Z>JgT&yq!BV5nmM1kuA{6kPR{N2hWYEwMg4a`mw zyCK*=1|{uuD~%MUV1yeR+(h7}0RI#h=4v!kn1T^*Zg2~MTLSz`P&NGB%B5;kJldC; z-Ae4s!TvQUX{TGcLSYI}$Y2iS1bP4X0bVR$&T8xR1ft34A@kC&z`k8hsU}V1)Y_++W}u04^R> z4S%;XKy8Xg`$n@<#U2QDiJ+vNZY51&3PyO4!RZ1I2DoHgn5!{FVG2e#!{AJThXP!R zVPCfrxwORXR)#4~DXCOwlNhF!?5tJ&?=9m$@LhDpNGd zc_!zJJQC!xfd%o;M@K16Dr3_fn0%QU$+wTx|KWCrg*f+n>|77iC~|>wr}qdecj4k3R5t`lMKFF;K=}2 zj0!7kdTR2|-Ca-OA$%Q!v6S z4PGViYJjW7g}E9}C``c!uQ7P7!0P}G1y#e}tvsnV#iPC6>o8r;lWAza#d$U?&D8 z?Q|>eDNMl#A2Rr`z()YC9~b6oyst0?BYf20V*(!sxIs`g{N2h2YEwMgADaD<*dK$P z6qK~nt$d;|1ta{a!Ji3y0^o*mVXnsK3R5t`Ul{zQz+VB}IH(%_ZslvWDIV=_%>GvF z@4#*nl(f^We6KJCBm9HGKMMR4z)j=AT#cU|GLaXo(bhvVH zlS_zP66DJQ3*w)To~k&lfN7U9ytLqD0B;qTwlg6;O=XHkxva_ML@p2VhoUJegBV5Jca|AvY z;I?sLuEu!^Q!v6+4Nefa8o=#?s^NckoUb;;qa8B4y4W?q?hur;^X9lfVG2h0LW3_7 zxF*0IqD%HpQb|&+J68>x11nC~2o#xkOO5H?=7q?e1n@Ep`vEdj}=$bSpg- zreK778QfdoYXH6`F3i=qR$&T8xR1ft34A@keS)gt?^gP%P4Q^=GrPaoH-LRzP|{Af zGC*MpM)*d9Qw1If@bz(Fu11=|6pZj7gVO~b3~;}oYWTaAA!<`R+8JhNiaiwU{y|AQ z-O4b9DH!1_gNF;84e$+dVXj7w!W4|~2!n4D*aP^+plbNLm0Yzc9_>7{^Ti$sc4|=4 zPPZ~jVG2h0W`joyd<(z>EicH1}yA>CQ+33A0Q#8ucO`ak0Opu4hm$@MKsZ7x* z&oX(o$a6r>3M`0!K6=06v;yLD4SzuJd4LZOOxu}|KBzK9qdec_1tKp5IXk}01$jti zibi>n$%{pP7~~Nw`?{5w*R4FFHpQd8#O$SFKMM9uZ2P*E=<8McurvoM)-MycL}^3;M;<#;qO*nP@Ce>e$nig#C{pJs~J*r(5|z zVG2h0LxVpO_+x-4#)Y{WpD0Yh2!CquX9Ax9cv4U`{N2juYEwMgUzq)+*k6HtcTmz! zxAL{Z6pZjU27fE?cK}b03v)HTSD1nk{=wiM1^x-(DM8incPl@uP4Q^|V)n0M{|5Hd zproB{<#&ZC7~ww*{!`$;0G<{X=4$+{Fa;xAY+m7{@g!QL52EQdGHIM1R1JT(atf`) zzs}*>#mz1uc1f^j1SRcsE2k<kl#iL!p>@&o!2=?rtq@8Z%Oob^J;YtQq7WgcH=fs7%8fPm^!3b9|_#A=H1$ZvQ zzHTLQX^H#Y%6W>@3W!%VJVEekfIq;vuUm=W(5;-WGDV{tGP%0QH9(#hU*>{bpfW|H ze4)t~iCh!p`GE!T&qr%1PAec@+weMq*9Ck*VA{@v^kS7M8s&N>CyHDjUuUl!PHpQde*z6`^HwAk!+rDlk`nr{73R5t`%?)lLa7%z6 zjtg@&E>)O<5x&geRsvrR@RFcv_}?8@s7>)`w>GX2lj@bq@8XhS78c9 zIM3jGfky(oF)qy27^N@;BYd;LqXoVN;7vi*@OLY>s!j1|-)44L?AyWK9F(-vt=yq7 z1tUDh;IRUa19(eZn5%K8!W4|~c!MVhJQ3inLDlegD|e|)@n}yn`);u(gS{;%X{TGc zM_~#^c#6SO1)c`*_P8)t<6ea+7~$y#&k%Sfz|RI%!{4pkr#8i-J6=}!d#696{cW>=Nr60;DrD`A5;y0xAKtM6p!{Ivlol~Fxb0- zl6Jb4M---DgqIk+RNzMe-W?a_YCNVe1tYx7;N=3Z0Qg0Qecejr(h|2@d0cT?0r8cF zuM&JU;4d-m>sBH-bSqD&OwlN>F?p@X>p*@vzRU%AQe}!pdA-RSMBWJUp1^|m=c7+4 zPAee3$?(mBZvlL7VA{@v^l6nT8s)7fZxeYt$gjqixggJ|OwlMmYw`|}cY^#n%f4;qO-7Q=8(^K4kV`v5$cLPEgWLxAMNi6pZjugO3S(9N>53!d#6H6sBN= zKQ#CwfjG5A}7zx)5#dk^?3im(4aRy5dqi(W+ql!V+Qbg|GBV-x`uMT{Z2A<>Y;xe186 zwy)TG@4ffld+)vX-h1!w(`+ z@Ve=sOK^iVK_eTx?{@S*}P^uQk{c_TMk>8WhU`|QPxy|}QK@YtUu86AsOmQ*l=eehBS zURuD*c;HXF1=AbLDj32(csT@Sjxjzuf0 zDj32(cr^nT33zo6{AIUbdSeX*L)ZtW47{d**Ydz$CwU_`TIr>1$ouTIjlGVr*Y()n zBpDrxR(dNK!alfeFa0<2lq2@v4BfF@b^jH$cr zeeyUXZ!P5U9=TuvKU%3ser{!gvLWxYCmMSjVQ=fP=Oeo#T8Xi}{;{2cA?$-E8F+gE z@8E&w?-opNOja<2eejM3o+99#Jn(`^-pK78)yjsv&)(VCHNu|iu@_1*I@URA6%1h? zTxZ~nfa^W*!rg-DjcE#oun%r9aHD{C@xY5Dc_TMk*;Uz)_t{Oxo-XWWkG*J;(XnWy zMZpmE!L0_~O~B3r7j_G#H?j(bun%rCaJztKc;Lm7ypbEN%v3hyefI9go+a!(Joe&A zM#rL+JrxXLAH0`=0|D>tftTnOOmFO?U0y@ zVISzRmrgP|7OfnlUJ@86N z-pGwsPE$7IefH_bK10}NdhC^xjE+SsXDJxMKKN_{pCjONJ@6{sg6WO(6bxY>e7=D% z5b%W_c(o*NXR- zA?$;%Ht;n9zSaY$lDv@{tz4&U$ouT;jeUc#Z}iw}CK(-zR&G)-gnjVM2EIkWw|d~U zx&_l4w<#FHKKOP6-yz^TJ@DE|-pGws?ou}7efHhPzDL;idhB(QjE+Ss_bC{{KKOnE zKOo=-J@C5Sg6WNi6bxY>{IG!^5%8lPxDUY{(TX=;%zJL-F@>Xo4}aX?PYC=;58jvX zj%Xzg_hzF{DH+l}`Dr6RBjjg2@_OBq>5%7?3~8VIypdlJ@{1n1U!p^D=c6wv92I={ z%Lac%;IDe{;zYA!6Vlg|3~8VIx{==y@|zyHqris-tm>PA@8%lHug8d{?=m;NHRLsIlfacgnjV$2L3_7KYHMS-Gb?j zpA-yXAN;d{e-ZGn9(Zt)H*%wu-;@n`pZ&YB{}A?{9(zcV(XnXdF9k!`2N#@fm!gry zrD&wlrRbsEg6WL~P=hb%h=Uh2@InG!*aL5n8W4{`{2b4ytsgu@W2~(3#K=gR4{~n@KOd|TENSA;Ej{KksGZnt8B>o?B$HTys%gB z*qbC79g9|0R4{~n@Ja?=S-`7!;1S(|>5Wwt3}GL9?*Yen-lZ=is9VIRDKH67ZHDcw&+_a-)^4lnr^GJfagN(A?!m1-qJ z+9&U90QsCDH8I zgmhOWL)s@d8F{*pn?3SQ-IM8%79~U4C$}1THz7NZyfeu;(MqS!tz?xAd7s^8>~>+# z@YpqEuU1e{kZo$L&1fW)|J=$<)WF0M!ajI+l(y^p9cCdLxIK_YGt#Nug6WMt6%1h? zyqAFk0q^aB>yo^Y+dKAAHspQwzQ*29*!z3zOp?*D&hZ}wL)Zr&VBpyTKF|Z#cMGOB z4pK0Leel5sK19HWdfZ z=>|SSz-M~k=5E3C##su6un#`lz~>0~To2ru>415+?M2x+-T)0WkcR)Uv2Dbgng~Y zZcj2g7Oh;TUkWK^fN%7`Gr9%S8#gH!!an$B1K%RxTRrgZN#4kfR&G-^@fIu@-wreFyB;KvR8gn*y)zZ(*}MiU=Z*b>uwV4p`z0A2i&kDzFob>Z%LaZ$z^{7X{ksLz8?PxC!an$Q z1HU2QH$CtHN#4kfR^C!J5ZNWhOiG_%)pBa zcnJ@De3CbEd&iQ>hP=;S%GgT_dl`>?LXy$3&ate5A?$;fGw|{PUcm#O*e#geSW&?c z_Q5L|cx3^v;(W-86AsO)=)5neQ?UaYYKQR4}5C3 zV0xpMf+6gK*EaAv0$$expPuB6+-Rk@vLWxY`xv{gu-Eh0XCxUNi&oZGFob<@KLZyF zxWogW*)5pf=&xW1``}Uorv+T*fzM9zMsBoHu58Hr>x`WdcD={GCduenv@%V>5ca_h25uDaE*|*WZo%}%t_p^*4{kE>bOASe;OmpT zksGbFC>!!VyVcmc3EO$>85jM=2T7KKW=PA0y;rJ@VZoFOP#*n`vq)tuC#OcZ=hc z2q~XlN{{%6Zy<@@@x4lM5b<$W8}1sxUF+c28*_U0bno0JGCpLnwoZxQ0H9`T8|fwALzo8lni<8C+H9fG^l z!#$aRV|(vX97KHF-G;kIaQAw+r~USp!#$gTV|yP{97KHFRy4TgD}q_U08)0#4=sf}%^(IZEuU`~rm&8*3$>N0Ja+BT?fY)-W`Wbmi8 zy)9MmTBfHaR=M}7hq~8?uAY+?2CHp)brz2PfP0F?0=lH3q_SYP`w+Qs%JC7hf%_O~ zANXjH7%{!QsjYFYZTN(EwSk|14{hMV{*-%)EBT#wv*9xohBkbTY~a2?N*e~uxg%ty zLTYMzeLaq5sr!<8)B--;x(GnosrcE_4_|R#aV4K)H5mxZQ;*uPpxKZXH~hkV#gz-j zZ1@$0p$)$w8@S(*&Vw7$?hmR_6BhDKpd0?=zT(P-VkZ2B!q9|*GikznNaw{3Wo~{D zLK_w~8_L8D3vgd?<-#!=7DQoa!$QagZegVJ;D$2SgKE?bJ$w`BhDErqxUxsgghf#p znox*r;CdpR7dMo<#i&PZSj2277dI@8-)sYR{8c1ovDj1%&nvrq!O)WE1 zE%m9Ils^o)6k)1pF;mn+X}2c#6<016Q?wQeLq)xi4cyvDsc2Ow+NQZKQPVo4siwtE zQ@dzdm-~t<7msP`jlxhc0~7T2Csp+>nX6ZuTS|%I$|YlZ z(DCZJdwvF72Ia$hb^DPkv@&Q&XzBr7blzlX5kUS_T>RJ0M))G}?F&PIB3rqiD7-7&8!aTW9hz14Hl z0z5*^rEUO=isZx-&4dPuBRCTpgk0bT%eFc>XBIPrwRILlC+aL_D01OJ9foY+Hb5F) zIKgBiHU$~ZS~>+Wz=j6cNB|pqfV>&RCW_z;!Vn`2F;WntJVf3MV6-AQ12DuGLu@LD z%{)Zj34E*~cmg-X=7y*g#12%dlqv85rl62v$Uk$3*wS`j>d8e+U5CJ17p zhsZnsZKDXD{|vFMA+{65BoC2y`r2L*Jbf8r2SZF2#Eu>!@ANZ85j_1EVkbjX3u0#v zk$3i}Q3TH(hL~!IT0zu#h`iB1qX>@vhNw5hG(j|Yh`e#VQ4t*14Y7+Mb`?aEhsYbS zrz?U3wjr7g(ISXe50Nkg@1`IQ!3J^$$_l8>10{^9?F!bcipJEL!rEO}|EI^) zS@eZJrl#E~F?Da&)-jb%)G>7*C^2XFd6~Qsp5QiD!a6ug5A@au5 zBNf3h)euJ+;%Gq}<010K)MFLFG1U;q8RB?BoZuny#?%uP!7WVG1U;~8RC3FT;L({#?%WH z!7p)eu)1;%Y%$<010K)N2*N zG1U;)8RB|D+~6S+#?%`X#4*)CHyP+=0o~$(62{b96~r;sK(`4f8dGl<)*ZsqF?EUg zx|pY8Zd%I=QoMM^iK$*CZER@{r=@c{cf}>OPUo(9^VS;7brB}$Jh{%By^ig$rDN9G z)qFKI5tNQ8bab6>>a0{ljho3!e>L^ITo_&R!_~NSiMx}2wDA~?c6YI;NMfsKJic3; z$np3d5P9SA zON!ulY>1Z)@roc`^$>aE@oS3Ucx;H*4e^E`-t-W81By@rfWl^$>aE@n?$Qcx;Hz4e^B_zVr}z1x?@rxjS^$-c;@ox&^ zcx<5G4fKbA{`5czMHD{GNP*A3d{^tu5e{Mr`WEoo^=HP+)M zLbh>QGlO`P*Skz+4~*Nm(x4H%-r1hj(>|H7mk00$l`)1(uDDEG1k)Y&j5=X zUhV_zoitx@y`%T8)6wjEbAfi#=qqh!ST-!%Nt?^L9FN@^2WcF6v6S&5GxyE z6+x`(A@at*)fB<;&k#k1SX~fnc!<35FQo{Me}-7o5Nipdmxst3|JGIn$3H`?V~BMH z(c44hjemUxd1{xutksc^v{2Qepj(-LkEg;NCqbcba!EGuyosv$$@MH75En23f#^>JG zt#5Q$+{%@Es5%kEMdZdNy}8R#Fq-P&o@&QP7u_8$ahuUHo#F91v))jx2Cf>DNjH{z zi>j960gXnx%~{65t`eERZGkizt9U_^x2|jI>YS^hTyfV}mCm6S!@VcG}==DW?r)!?eNM zA!iMqgss4BkM!Sb@D8*^8@v>bO?0!kqsf!Gzo=?8zsWm_g>3T_;xs0<(5)OOvZ*6}>HHwd<^QMrzl4wK-<7gH5ez z-qlUh>a^RcH%Rs97u6_)U4-y&{i1fISvmgpyI2$V7geQve@_<+>F;Lb0@otj`TlNY zUG+DcrvBayxzOJZ*}!FycINLkR#AUj?RKj@Lu$|TYRCM&yH=;&R(+OKkNmxd5cU+p zzvb_}XjaVMvI?N1e+S%ORJFG6@4dxB`gVJAY3lF&kqiC(A7le} z0MgF@r^YVJAY3lFekPH2NJhFj10cmIcK9N<_-&Xr1t9`Q6 zKEgW6WY_X93J_otL zoh#e<{yvX&)!%HI`ulw3LVsU?Y~U_L+L^yEVionb)xOwjUm~?H^=ilbeVJCL-B$f_ zsUG?J3L#u6gn!H5SJA8-fBXIWYVI$pD)s$+jaW#3UyEGeu9NM2e_zkK>Tfnp{e1&+ zp}%iLHgGo~?abddvx@rLYTshDZb>-|vfs^!EqI1@1%H&iD66 ztgHTJ)70M|BNzJn6J!JTDbmjT{TZvMzpeJ?R{IO7{iRns=I^hxI_F*zr!}?U&&iD7vtgHTJ)70O;AQ$@kS7ZbC z8`94F{X46uzpeHkR{Kw>{g+oe=I?^Dr8@1l>hqz{t{}{ht-vjS^xumw7o=G+f6E%R zj{dz6_ZL--^8LNASV({OKrV2L$hP^LF2t7O~M;f2VB4)2L<;1)v~ zIh@xj8DLJYsdbB^9JP6M&uTA$Li5;?*uv^hr2n4BmZn)TkICw~4v#Iv{Y6!q`5s$V zETqSlLk^2YWxErPt-#9aF}6)Twjy$&$5ui%a4RG2%wwytih9gyuPU{p-}Gt%C=$TG z^_yOuW~s+kD9Bw6+2OY}C{3X){B+ZZ)~CZZEfU2zpaC8 z;MPUjncsS&JoKB@?t?<>X?+E-o&f$WzpYQRI`Lb)zxAV3QPnu#Z^dFK{Z@ip;QGsU zCw?nsW%V0dsD4W$7y7LXS*!;|+L_-fSVjAr)gB?E8AFG)5M!R zxKb(E*2dOMYI;p;E1oYYnLO1^kyWQ*L27biTMb_NIAwZ!wrz6%aD(ea)5UEq#p(Wy z%~%WC)`-=pC2layQonH#HNn;3xFIYrs+#C~YADO-sA0%peI`=0v~t1OZaDYo!zvum zNO2poOz+>YVGSjHDhn#-tDL`bfi|}h3hY|p#@GtnCP<@^>6LO~uncxaO;dX&J9Kgr9xR$NdA%tWrKOt=O;v!cdQns+ zMdf8)QCf=91HGaFtY_8w3($=~OX0U=X1kHh^_9&@}9#tB} zhNbQL>z|CA_2V6}6}Tx#qkhbl{i8Bd+o$2FCfuJ0Z{3a$`<>efqG4kSAz4Ss>e@Ef zv;aan7_nMS0C@9#D53ymfc)xJ<4Ej3Oz|^)lm&vxaG}qw= zg1g1EBilZewzyi<_S(sL1lM)fu~_fgvNhVu407QZSC4GqrXi&-PcOhB%QWFhHfbA{ zx%2S_S=b(Fn^p{MLsK0;rP86Pv3L%^!6N*M(nC|@YFrkpaW-*yNDiOm!!Ii=E3U#f z=`tuNN5P0~Cdh4VEJH#`1x0Fi#p3u)GtC)vnHE+YFjO8f5OnxUYk;9)E4hN4V^cQM zRO%X8u21V&Gj~B@*vws#4O|maHuLX!csg}xPvUJ*^>ErXvsfR}G1V<73{|%x8@Sz& z{;%+`V{^2Xyi*%`IPJ15*XJj!nQbTxo7s+R;ASBG`yQT29jbe&4iA^P-C0~L>lRG) zEEI;S_dqsqdm{Z`;o-g59Bt*&=HW6Iu)Mf(MGQ#R%)L<hN&6+n>e7l`F+m{|AMk>I0As+-#)(D?EH43=LbkvU#}N9mH}S^3B5sqtK?hhhQsk zha!!J{B;Tn3Pw&CFC!dB#rno+?M|Njsc*-FHf;?Uk{ep^6tX)EwM1>tNj!hnW?ePM zu4>9vtDHNWGP))_Iu9IyB0UcriCo~0lI>oTN(%}K#*7`aRVuDWPH%OM4udo%ewu+@ z)2B8zW43WLDq||Lz-)I6b2^jYNw2ZGrg@e-mW4XyWlM27Sdjk@a>rpSJlMx0i#rua zd9YIj$yP+_-H8xZttT$H3Qg50&>t*)iD zW?D@fUZtQ*2mMzlxO-7oTBKo%t~D%m_pvxW0l#0g@CWt)a#-su+r8u$YD;~vSZBi6 zQKjx7>XDOjSAk*?33PUZ=Ba534 zNRzabyBEo@A5Wf^a`zG?^k-vQUPfW4c@NpZy^l0W%Ru)5_J&%xIww!d zK=&af^eT;M`3QxfmXDDQ+$TtrvG8REVtL$&Z6ou_4p`+*XAso%8x zh{90IPsj%DXQb4!OhG5V%2M|Wc86+s4qp;d(R8SkKmK&7`;{X4RKMx@4TUx#_#In; z`vYk-8JpX|?N2IUbN#_B?fznMJQ^=Jhgvwe&4(P8bIW$;!%nGN0DHssB@Av0QbGqe zHbV!ug-{r}abaY!-WqAr!AiSD$k2n8Ft{yB2_4)_OCbtFEj^LNO$MY%TFTtwWT+O- z5%Ri3nOlMqI=GpZB~ch^Sqj;}EsZouOSxNy4AsJ!L7tX!w=5-ea5F8-p)l04JhFjX z0cnz!3b!H|s)f^mJS`P&B}(YvW?EK8VW?#lWCOP<(j+Yd+-hW~7ES{4vmkiaCFu3)m zgbr?|r4I^2Eq##<+n zz_iQ&hmt0*(n5%?Gr(a|i8H_r1TtK<|K1F6L*m&Ue~>J78?iV(1Ke1&aFE;txxkH( z?W93+BmwHD+(9y}Gr&=l&_R;T&_QxEa^c|^gDftOBTYK!X}1|Gs+QbAQnaMqSW4(1 zX<9Z%VW_1NS*!*}nxv)7Rgs}uatBG#Qs%a#gbtFXWh)ehTE-z8xUG>UX(@N($xto1 zgQRFFcM~X~gQRJhh{90IHpm8UTck-^D%^HtsFvJ8QnXaKNtDn*(zI-k!cfZ&$OdjQ z(j+Yd+>T_ZmfS&7vE>caRh<1Km_g=pboY zYEc+!sY5n!8Kg;C2Dy4NR7>t4DOv`(X_U}G(zG<7Fx1kBY~Xf5nxtj0+m#H}k~>I> zmcg!x5;{nlmgy)AwKOA(CD=%lv;WT=*e zLFYV5=%8a-&PQRW zbprwFrrg1+OlM3tQbGqWHbV!mn~)0+#?8nE?iQp;2P5rnWkuDJJ9vqfw7ZQGI(V6u z+ff*5xdYk2-H9|wOPRZi4Aqi5c!`!WcQ++;@G>p;pfJ>OFS3EV4{4H?a(6!&swH>u z5-sKK0ZQoLWm+CYVW{OHWU-JMX_A%-_XruPC3o-=EfwxjO6cHaS{_4TsO52F1NQ{d zBrOBnlVqrt+`&t<3~*0TLI*F?@-zzV%=`?t0{1M^zk6nWj!I~T-?`K7c^1dd%rA%* zcJ3FE3*1Yxoz%HsCP15)(79isgm!K=Lp%4Y$c0XP4cWlGjx@=MY4-*zs+NS#{U#-} zbDNg8P#9`?8`;3UgEUD?nR}NE)soP;-=lyX_A%-_cT(N`q+0k(F&A>l zms^N?^;cqg7Di#Hrw6iF{fv})^cJMOVJO8r=HqemyVNa8kgDNNWl>nvaVgjpa;N@E zOiND`hFTUwHgJn0?NUqHEkTfK;ZMcal6FgSr~XPz%Tg!|wJeQn;Fdw!rIs?cEJ3P; zKNVj~nOlxK^;cqAmPert&MROma4RDHyMyyeR6+~ z4dSk%%2IEU#$Xn)Qw~8Ua6^&mIIb&I761XuGu<$XX=FpI(bX22?KVIzzSdPnMj5WK z+I2VuvD)?R*lO1eQ5v|7kVdOrHU%Gp# z+m;w=)Lyf2s5RT>w&NZhqu2x;qb4C|t9rM`R^WC(8vP7-_8OmQZEEt-+BTjb={;Q`;dbO69de`AO<@sRw-Yjft47M!ZEbk2DT;L9M@5y@S*(vPOzk!MU4&X>YYY7Ub%xYFP;!t>K6L(qXYozdsvNlFF1!E0F_d zi}r`6MmD5MQ&=#Z;-dRhaVm{;NEUGq@TY8e1-HtF!#Vv@6~o(`+wnf|eyIVFV#&baY;nKTAjqNR zZWmgxD96ZMnbTi|%uX7bo2seOHF1ZY?s(|=5J3-J{1>HdZaQ{Y4{630E+!+5ddQBk z7U4rHSd<>V_q?N1MDInfOZ7?jP2p!0ex?iCrG2GyblQoe1G!dOrf%;6UE=mkv)hfu zy4WxBxnmK1o<#;%qLKRNkp)pZ(>%4wwNp+{By5lV5@sN0?VO3N!0nDSYG+^64u?8f zb{{^pGQ9;;=bGla)U>9Ssd#=Te689na@A=52suQ^lK(weuCH5*tlm?U(CodC!|Q)# zyVs=6QEzNB9`@jy<@IS5anUuhP!iXn~ z@X3eijd(h#xV^QGzx1j23XuHLr`OElb3`nQTL~+~Mn39;N1MWWC>>Wep(ItoPYn@X z5!o4?-Ba#hI!_%O&AvE;saAwLguC?v59ZrLQ5gF6Fk}OFIMV0K6u z=$A6God2NxJQ~e>8U^kcA}8b$`I1JdzXRv#(n2Xt?_J^VC}WLmA?-$eJg7pVeu=~5 z>RZSlIV}1*10G`W_Lt!YEP4^@@0X_L#Rq=w_17S0jU{mc6g=s##!&i-_?zpQ^n z|AE5_6Kayc$tiwRiSU;-+io?*<(mYMx42f4lW}52VvGlIGe+9Uo zt5Be%TD;%Th?k(b<0w&FxkAkU$D`09(i5;1xD$~^gWoFP;8DHYZlK+>(49mkwf3B} z7$iB`=|Oi`=goaZ_zW1{o5n0Ae5dd)2fR~}!QyVDJk|}UI<~p7tr5d$*zqyp$kkaW zy`MWe&Xdz?cE|H~m@iE(A6hyEKT-7eaAzq?2Mw)=m!?zhblRYfVob}~qUv;KaF5QD z=!k}rLl-(2|1bufiA_62oQ18xosBf|5@*AhmvhP(jvtYO&LK!0#DUj$kW3xjxfCdp zhb3n1YcL7p*sR;GMd1*9#h$$;^7qVifO}mJDv}v?nPka|6XRW#fTYXvJf3x}lZki}gZq)|8h*9^Xa_Nc*pHb;V*w(92H+uV)ZQ(V~}E;gfYLZSVRZ^jnx z`yh>a=!R(UD2dnf;X(Xz8mG5UPc^sWl@g8vY(G z&^C8B_v^J}dIpC%HQU{Toc4Z(-}hn*cbAYx7n1wH>zp*pB@F4?_p`2s$Qy?t@&i(V zA@YL)cu2PO=QA0VC;kt9!ti05qsN02Tru$xmc@hYN5v!_g2#{x+~cyX-*B3Mlc9Ve z5zh~08fVCqW>=io8^d`{ORIZ=MDs1@Z8)ctR^x$YidAPI^CV?7%%&UkXY>?u;m_!4 zWCQmMQXc!YfS3ct&q6#@%&Qfl;&e>$bCl6*gQoa-6o!glKsInMBApAxFA=IO=5@kQ zaam09%aqah$rQhW!cg(6$Oi5;q;sM8bwX7!FCB)8%VUb)pp0HYG{tYCFjV{&vVnUW z>0Bs&hfr0_tBIlFikRYeDWd^`DSi)yq2l+E4crGv=R)y^gsS2wC_v{L5L5gSW%S2u zia$nSsQ43P@oFHXbD{V%LRB%>Y=kWy7*qT?WpvesDgFY5q2e!*4cu2q=R)zRBXRvDqfB<`i((TygUj+#Va6-+i*zdLh(w3 zs$#w>J5+4HV=7*mGWw9bDP9GIq2g7M#ho~$RNOoHw1_(^oVDR)|K(*PIMFI1S+(=g zcuvRUq};k|TXj=gb$OXg$5yA5J}Gbd*Fa&YKZPvr&>@{${cDk|`uWg$s6SmD*WZg$ z#g$9Peq3v#Fx0;evbb}HbZ+(cCRz0_WBSW-^!K5ZzQ@|y-xr0U{`HW>Jw2pztG^$~ zs()G2U!J4Cm{P@+%f{MYg2GULe`ImD59!?MPm`?r`IYU^{}nm<%P3VW0l2ll9EG9& z3S@By5b50NA4sz5U*7Z&$k9KDQhLG1^bba1sDB8uxao&Ir=xC zlwR;K{lifh>faDq+zdoIxB53GS@o}I`UmCc--J>cU7G$8C=B(FL^g1vkW&A8{_mex zBJo0;Rw355HQ|FtxK&h-@C+B4`HFluns7CN@gbk7v)e?JD|KTiqVI7q{hOjN)V~?B zfg6kTZ|L8gaMjPZD&*@=yGn`_SFRlE|68Ci)L(^c;I>5iH}r2sxawb}Q~hOb97T#N zSBdH08ik?$@yOyOMM(dK{)vRE{#85GU+%V{NO9$=G5y=3Fx0;tvUqb5QtFS5|D7NI zjyDHvPqHds4aynt^5A#u-+}v!D_4tYo{Yj!^Nz^kRYpjuc~oxCli-VC z(H{3ZcwHMGolUhj%ln6F+vMdJ+9!9SS~aT(X7Qv*RB1J?AfS%Cs-c=P#g#=d({@H- zXj%=jc>593IWsLiXQtIst(vyFXBtjfW?CI(iYr%-nU+CeXj(n8csml(IWw(n&P;2d zS~YDA&orFP%(O9(6n8V#T$)~&Y5ZDb7tCfs#Vico@qGInQ6_GDV8gK zW?BmhL(^K3#T$>1&Y5Wyb7q>OS~YD=&orC^&9p3KiYwQQ9ndxuhNiV6i?B1A$`n_w6*FxX3PaQOKo)N?LON%r4V*L6_M%!ft(RvS&YWgi zK$+soUNO`5Mqy~$KFH$DLrCY$v_W%b+J024rmgLnhLft9wm)TxE7y*h_8%06rX7GR z-b{p)rd8*TYjqj0cy~`$Gu89$a58WW#Zsn5d?8zw(9BBpky}HMsV|Y;slE2%J)i24 zqsH-CC`Ugn@0)T5(jv8b9azl^hIKN0Lc$%yoyC>w#LPVyg`v5JAdA-vA*H#zUf6M6 zEII-FgQgxvYt+f*s(0_;EI;|>P&5IbzOT+lbk4yp;&Qc@0dx)qA)b+IAjBN zJkq~qQutO$HR%NEQj>VuH^-!G^E5T-M2Z#5^=%vKPC{X5(#gmM?i8dniEo1$$6G?- z4d{-u^QpwBw!Y9Nm#e3GXYbRvzqqn*tmUVp&@S+wfvv!ui8Q)d^DMN*uQvam_&EJp z^aXtty<)G_oz0^7nwxXP5xmBIE^>i8Pqx*?yvY}a=XSM=SFO({N3UAboqE;!0_4J@ zc_Ffay9jBtmL%~y^u?^N*P#t{iJ>kP)MXwj@yhb$isFl+4RwW~t`yW&9xCx#@zsjr z$L$PtjiIg;)O8*z@#^pOisDD^40VH{ZWPo_9xCyA?#+tg$L)ndt$L|bvkD=}r)O{W*@ha;5isDD`4E2Da9u(9=9xCy= z=);QQ$M6jGh@l=8)MFkh@k;08isF?{Lp@=rCk6GChf2J5`Lv?=3R^=xW2k2Z^_+)F zyc+quqWI!AL%m?A7X|f_hf2J@__Ct-u{=Y)VyIUI^_quDykhveqWHNyL%m_BHwE>U zhf2H#__m_>!8}8~W2kop^`3|7;)34$3gag`4fcV-J`~tT9;}P2a~~^=SLY1&iNQV< z*k>NBi%V^vD~#XBGuRgf`%++Ed9W_7n|-Y?UN)R1)9*X{3dWw6KtRc%-E3KZ_`d*ME$(sF4bV)YBs+ zUCCKYNxYI{q{WT2gpii>NJ-aZmQoV0$rx#ABP}DOWj#`-7g&~43@@-4W_iP`Aea?B zOyUKRl@!GbB8FPoP^$=PRS%VT0b?~q@dAdSiVU^7pw{qEi5DDFisJjQ4Yj7B))G`N z50!Xg}Nt1NuISVnA=GzJ^*)Q0sfB!~ndXq8NZ1s@PB^g6i*~ z5(DN^MKNGDRN7Ewf-3h=i2-hfq8Q*BYJi~z3Tlvt%8xn+D}zy|F@_jps4#|kjJ$Ag z14S?#G{kU2Y$%A0JVaNK+{Q{{Bxkfuj5b1OBRyJILD(pzagmYHMjLI6&^GmGod#K( zDTYCoVa5t3`e4K6LaG#!F6sF{8f0xjU-&^*+EuYAzFd7vaRh^`t&qdxK(gIUkhL{A z8f4L(8f1+}E<7(yKsIm_kw)jG#2{-M*4H4*P}>@6J3&qIP>Dg-_KISVWvCqtHCa$Q zdZ@%8Yl@;6WEpBFLsbiEXAhMaWYs8&L6)JW8md-Mbsj1)$jT^+L6)KF4K+ z7-Si0hM{H(YIhHn7-Y>-6oV{7?O~`r1+|xlN({0BMKQ=S)ZT{LM^O8EsKg*^KSeRf zGSvQt`j4Ov@KA|C)@(&F$THM{hB`=42YaZ*AnOoCF~~C1p@uq4P=|Y{#31VkMKQ=S z)RBfdN>E38s4jx6V-&_9%V5VE>^OlP@4>nVvQAJKgDiucXt0w6cCrWSBFH*LVGObi zcB;Wn6WHk zU1+e21a`3p>mtayL}3iF40fr(E)&@09;}NX>k5T2$THZK2D?gNS9`FeAnO_>F~~B~ zwMM#5NY{I$q#)}CB{9e{(v3#CNk}()q@*D079}yrGSaO^x=l#8d!(cw>kcI`$THHM zM!HK#cYCBxgRFZL!ywBr_ZsFt!QAg*5`(M<6vZIRP!AgFAwfOtp%R0vM-;^%%TSLR z>M=n*?x7NctS1!3Aj?os8tN%QJ?)_qgREy1#URU2&l>7EK|SxG5`(N46vZIRP%j$l zB|*LHp%R0vR}{q{%TTWx>NP>V?x7NctTzf?jgDgvc6CngDj(cX|%6| z_O(arD#-dqX$-QA_N~#r6WaG4tOkGHK7n5)eIj4?49nN!c)tc zejZXD6rGA^9BUf!m^B}O898p7R1Kfp#4XHbu6L=!Ge?aryb}y=^kxiskVT#Y#drLs zK?cvQ^yX6;?b+UVU{YV-P?DMmirNY@@QkUxxM5ZbZ*brz&{8$^Sm2qO33wacyHS%( zrAyo|^rHo6Xtev4Me*mxeiJ7$K>HmzyeeI`y9v<#Bu4`@9tsW6{z5Jc&Ns3H%Q7@)1LCBKB zx{6|eW~knV>LaMW9x5?FTTf98&2!$~~GuTLjjS|>s57tG1Hb!9#&mooKuP_E^2Ag28i2~ckgLM(0ZL2T_Xa?KP zV3P#4y$9gY>Ed<3ea{^5(6|NRU2t%A=P-KqyTNIk{F;Fsn$q! zLdtlgqyVj6Nes}8G|fm2LTdC#Ndej}N@9R!q+N~FB&6vcsnYAD% zVG;v0rzi$!hRPbMO;GI~DltHtp(qAuhMH-p-32wvLnQ`idnk$lnxXbI)Lw!LJXB(U zwzr}fpc!f(L+vZ5{XA4+fVRJ)7@!&IKZZI$P_sQ$Vt{s_q8OkV>L5cMET}^~RAPX3 zsG=C48R{@Y9WJONJXB(UcBG;hpc(2YLme%sV?0!TfOf1h7@!&BIAa_yj1xRYUVwI@ zA{d|<;v_?yEQnJ)L{|aYsY+vjX0+3ccDm5c@Mv8HXlE*o0h-ayGTPZfJIAAS8lau4 z7zSvDIZrTAfOfu+E)bFiXl--4)DWQ)UY*kBTAEUg^;iX*ZJdTT3Cdeb>Rl$Y2Lib^ zgklmR>2v6KzQ6*vj^Ih-HN4+~)@m5UH%};|I(+fcMcf&G^TfqsGy|ebki*L@WV@Sy z=rVFNAY#)sAi5m6Fp9YXS$zBuX}1B)x=T?EhzxbNq3#jX zy&fttAi7Uc42TSMzo8xw)Po)>F(7(KQ4EL-^{}BH5!9m|Dls5>Oi>Jo4E4C7o)FZN z9x5>)dP-3Yhz#|#p`H=cvmPojAbL(w42TT%yrEtY)QcV}F(7(LQ4EL-^|GN}5!9<5 zDls5>O;HSp4E4I9-VoHA9x5>)dP`9Zhz#|%q23YHyB;brAbL+x42TT%zM(!4)Q27_ zF(CR#Q4EL-^|7Ho5!9z1s*8Z=GlelAGT7$^`$Aw}day16qOTOjfXHB98|)i_ee1!x z2#CH@7y}}MeQ&TI1ooo`>mnffNns3#4ED3Zei7KO9;}Oi=r@HiATrqR2Kz%`e|oSk z0;0bZ#(>CR1s8UlGUh`T-w;F^oie%zh!%htP8tk|47Q-b782OP9;}OisE5KB5E*O{ zgDonsLJyV{5cO0N10o|WW~9Z1w1h`W3W%0e5(6S5EoG#og|v)EN(zXURT2XtBQ0m7 z<%P6@M@kBaR#XxLA|tJ2q?LuVibv`+AX-&142TS~nqi6rv$}^#42afH6aykdr3|&E zpw{wGi2+eBMKK^U)Y^txM^Ni}sKkJ%x1tyj8LE$=`U+}250w}Yt*r~!f+=%Eq=qCtvcKxC-Fh8iNMp&lwR zAR4A921JJ1z)-^lwV{W~4~RBW1_L5vY;258gfYTn5ac z@g1;L@%XF0a}m*t!^;+@g>TiKK%BlZY~S#eVH2emUm3QIP_~tAeXI5qL^XClX^WO= zsqxWkznf~>Y8&u6G<`v(Jhm3zaKigw8}U|v8GKo+cT1_$yH9RA8l)jq$5U?nvc0@o zpi~~bn?#ZLJH)nU5#y*Gkin<^kVa>+0yKO=iH8z(>E8faT+^KLC#(?xD&SU zGHj&LtLgsd8@)4aNosUj8eKz?`1`x3vWShYMFua&M%rnkGnCUtvvJz!dgQFp)36n| z2BiO9qZ?^UQlrbH(YsJ2{v_S5EMlXZkO|y$q@6apnR41_HclJef}AzF6{jr5l7b5-l zT6_R)(H5^1wm9eU;c6L=W>YTy3fco%#Fig~3_ga4G`Hna^$^PGE6LbGZTX?dS<4T@ z7G9Z*^xtdw5wxY#mPb!1Ys-(MTzq-JQ7mH1k46SBT1MJw%a5g;wwx{0mLG?lwfuN& z1?~i-|6a>aq%GQVzDc*$dtzGNa_ml`K#{!kWDH;ZhW8Dh%px}V6l4N-D$?90OE*7_ za@x(=G;Q+f$VroKh6=`>5y}g!*kNI9ld~=D`~P=B*RDW!#5o8;eGkCLk4e3-yJUt#j+Hf4V<42aRx-P=gx92M~OtI(}Gm>ZOzm zpY&!{jJgcD(5TCi4crw-Y1Hs!qsHlrB)V~~yOK)OE?yg^UF`XER?M!eD5ozZWj9s3 zu13z@8E_4@0(ULasQa!78s4CfgM?n%f^ReEyL@VEajm|#r4FxyMOSs#kr(e?_=4j1{Se*-H1%!ZbC{gq@X7J?n4TlvjZ-_4jlRvTH|hJUF#L>$YHN=w{Vws z1hzrjb}Mo=Al-(oz}=2CY8$`evZ;QVVPfNSG;pi>dMx^4gYF7-M9z+_sho{Ys-)%HXjT$qNpK5at5o1TZt{!iK$~yNji;F5R_nh;HAnBb) zkqg{ovTb(qD>)!mkDoYU^cJP=aT4@M(j+zY3FN|G&y&ao?kS|vFwGxh43c(Fv!?z8 z4f2dZo)yS*9)!P~7^KWSuMpl(F~|!Bc~KxQc@W-Di6Gl)b6!>m@1z*y6@$Dgkk>p2 z@1(>aY4^H9cn`%OZy4lFfxP8Gcn>88DRXZtgm+I2@{U2?707!Ygm+IONR>9{eTDG8 zi9tRv$cF;?$b;~{Neq&9A1j1+ObqggK|U48XC8!iOn5u5qn}i7gRb(qa(KJMIA0j& zOW}Owad^8Vmy>p1D~I<=jPs3gz7@`Q9*6fzaye!0d*$#(iE(}~&X2Z=wNyL#3 zBklTGIlN0^oL`Ldt8jkvIJ`@e%SpT6mBU*k#`(iIe+uU>kHcFextuaraFP6)cz?t= z^Pw>ONzRWf9vnv+{UmvRB;rWVk#;Sp9Nru;&O*jnSU5dA4sVX+a?)-QTS79Nrn>%Z#M|jGS2N7E=W8hZtgULo6YPB|QZ1hj@szTS^hU3u1_+4Y72w@A&m&Ux50NB z@pz0FH(C}!;Ou`P!-%OZ8}yUm}G5LePtHtD*KLb-T1@u>u@Z1uR#X-pWZazkyiB z^I|Efdb;FmFmul8F3sIVl~+S)G!HLh5zm_C$ONteDd!X$qc%R$P}APjCf}4Pocn1- zp&LN9oq-nsliyGr$YPx(u!(x=9fVv*h{Fq;gHaH;AxLRYx!Qw|{OLy{xM&_xNf_O@ zEM{_bjkWkVhpdthKfIDEbwjCuCahZ71ov~2#hs<$MbTm0Ef++!4R9xrwOZ zkr;to;6}=JuSu=wGV*OHG`Sxh7HE>s4q+B2FTKpRw&)k6bR9pY&Ujn^Z-x`^OwY8{ z@H-kMg;ilruFA^Cp6a;RML$(Fv$3rqe3~G996+0hM;Khobj%oWDYwJXQ6<^M5V17X zM=u0N+LX~3AB^Hmo+9b8RG+3AblMz|l0tkNPZ>kuHVsU7YtOW2a5!6Gl>F;cRx!0N zrm3MUKh77)!tK-WE8sI1q3mFYnk+xr7s)Euem1E-csI4j<#+tT4`8LbvwDy{@1&uvEm(uZO0>97++KbMFw)(G?{dZd<=D%Q15U@!6I^%})BO$&V@Kf= zcLV*l4TfxvgdVd_Y#0LBt%2zDUyi+Le7h<$vL!o5viN!xza-{h9Bji61z-ATbhT19 zmy0i};F*?bjm-%EqXQ^!^u}{2+BP2KiTD-Z21jFUN*|jzrMYQV*mwEmJ?ZA@ z6rY-r-)T&{T2!Z2;`iwRwKe?^Z#6Zw%*5z5byi1%qn^NDg8m4o$(Iy=#vVGNBm3bZ z&aRR1Z7qCJbB7}k6t;q*!z7IiKRH*Esu(=AL(Glh_+%qDrvgM&x3spo(cGu6?dJfg z!}l2E!qf1k$OdjRq#U^ULGjSheCwcIfoW}Q%~UtmrQBEoR1fEJ3qzRu8tdHV+@o)- zH!YPY47F^5Y~ZSpQp;wjn8w#fho-h{No8Et6mZcD0Gqd1{sRG}j`o{(yGTXC?=?%lgVDrkFg9M_*C~Ku)Fh@mj+9 zd0Kw>v!t-RuYAH5eSdg*Sc)HDWwvY>zG$o2ieZ#y;oxC~6@8=YxVk{K(G(Z+6dgOfSM8OW^>VUNQRh8Mh%mnz|>(;PBtLk`cH)+zd*eamDG9(am-1 zr~3{I_Xnv=6Rt7snd;wvWOxa=w6m)C=Ahz&!hwBL<4B>2A$on}Xlehl;6(aF0~l|y zKXn*@kCnOU+^=tZSM^nI;WMVqC=KF$_>q^ zzrLF7_D5-G)PIl-+yO{w)QW)c9Pei6m%!`W+uAV+!*@#y-E5*%-$u~a5qlrV^5V*k zI#lp>&Os=&liR`A3fv(`qs!FWK#`uqWKxKE6kn)}7*qz!@FUuGWj&l%VMq*Td*Q2> zhhpMc9Dc_Tky3q2p*xi3&`do>-l?#Dnmdd;<9Eyt7pr(CJOa7E9Vy#-i%0Hx#Z2PI z2|F_@eE)c8CoL&)M^TwNj3-H6nHOL+!oO(YO|9cy zgSg*h)G^D>qO9I}Hp|XNq5Uk*!B*hTMH>AqcylZKEkqM)1XOs@K%qO2JnGh$(M!MP zK6gHM#MeSxAV~J<3z5USu4TK|q&0vauRpcuOS2uX&ezFuiMyCMZDTaGi_NAl;eP$V z8SU4edMR?D$1g)RaF-*EJl>5)P8?I5q&2iOVTvh}v+^?e@_E)>K^1BZFPHO*lRvS( zlDliOIK#xwdAQf&O@k zskh@LSrNal_GL8Mf7_+ruG&TT35Oi zTY`kxVvRrZ{>#$ z>CU9i#?yPK$$BOy81a$R-Af7mmL(mcee*u#!sBy4vVnU5DUT07o!f~yb2G$0NG)m- zZ{G2HRdJK#B>WJibm5Je^)L$U_&tKHz&(mII)40;?mQg7QPC$cWKQ88qX{%L?+B*d z-Av0O6{E(GPmC-a#%r zSnnbmxc89G)4_V5Y&9hI^Wyy8&a@v;N_&nO^C1fDV10zGz$uIR>+AI7R^tAkV(m3t|D~r@{qj0L(asO=xIZaVR9WiXWc*9a zVDBlom}bp~l>TAtDsdwgMU@ZaMf5B#lH;0|n;#Nh_u#yh%ab})xBz9<8*H_9k_Ay1 z9+QQT4cx*=yVlu*9Q8UMf9XM;&PkgV;jZG!P0=P(u_y}7;f2@=Tu-Et!#4rIJNk3w z@Mw}-;ufQ7bvgT`cp%za-Qo1bDOH4V!tU%YA*RsjOClGzrDVG+r!P&2I)D@DReY!C zt6YZC>UOqW-M%bxq1%^3HgL-$?b_`tuyW^aUy-}i?WSTS6q?&t##Z1~K^nQ8pM;VN z!t$fa^ZL|Ttu^{hdH&|2TQRul(1e@IDYq(Bs=GNRiMu%|FjuceiK5DJo~w&QJzc#z za#+P6+g-UjMTohYN4BGX$JMP#Np&;Zs%~BjxzNqMkPY10NV|6PI;`Beo7d$ob+f7H zjY4yCA8ZA#FVe`(BVh8}^lsek%QViwji>OYa)zHaD{<>lxB6Q~1KuKUEz9DHgNn<~ zZ+!|CVHC68-A_!R%Zrf9`Z8cQjxUT4$Q>uKadua_YkxN@Xj zd%c2{JNNnk?ozLtih(E;uSd^!4MIWS1|y}Szqbq`?S@bn&4@39NQcWHhH`hf3}Vr6 z8N@JA$z>25AQ!mdvaM5*xm*UZA@O>Qb-JkLxDL1#X0F|92Tgcn26a zNOZ}>f0se1AO5=x;=juv{>PRe{2~<6`-L}oh*acl6!R- zgc-IK3PZ!jAse`@kETRR1~H8idcPq&pt#rBfWq*AHX<9iU6AsC_QUUVyN-1&Ik&DmS=HipC0-5a zbQwew_vu<=F{$1q_T#BP+(Wf0bh z916pOm_;^lZAf_#=WrQBJE5vJ6<*|uErXcB{kjaohN77$43+MVY~W@grPAbO5POiL zdOBYQu_py|8ARAexeQ`2l!lrDWCOQ1Qfiv#Wf1#NpBj|B3}Rmj=`x7WC@zE852c|| z`y-2o-I3C$u9iU@K$Pl>ErXcNa$N=yIv7L4fhe?-+d}(mtq1+i?2632J#WUgI$OY~Q+5RV%K^#eC>M))pb8eb*nVDV6KZ>%t41&(mY2eYw zg@@@FWCM3BQXZyxT?TO+Rj6g%E`vCpvbqeyEIR>(p=Bo`8@Q8@{u7p+Ol@k}94&)5 zh4Q)#!mK+Lg`st)Ase{UkFP3>aKATH*9T?Rq>wWnT! zTlVuS1P(ts{(jnS6??o;=KKCITxciav`1}LQAReF=H7RzVHa@sNNGZMjXl6Zx zLOXsBV=HivAdQaSKYO3{QJT={5lp+sxG%m8;&CyANAL;c0{5hB&%=G%r>G z_cSHcNpyxDyJwIKkKMD#2JSheJa&J38N~Bst0C;p{taXAbo>IP^!}_F^CAlEh`ofZ zz`cw#I%5CWGKg2Gz0-qL=3eE#_%evs#0DO$*O3d{8?rqQK6;Zn@(-4`4B{O?1l+vDK#(aQ6J6IoLD{vnn<-z*rmqC0? z6FNO&CJbh-@UXYSXV zbY{gbD760bE4Bjn8&dY4e`*=T?^LY4CUF_WAC!qNgZNX-VDI@0xxf`%qW(!<1~DHb zyzbHEGKl#ptKML%wUaD>!tj_Zh-}~%Lds*3taD*<)a$v+AbN0@-m)|mi=faPz9_Z= zSBNxn_&>7@q9;|W%ez?kqz8(NV|6X@~qss+gIQ&b-Srp5ryXVm9Q1Km61knpSNWYt5Bu7`~R`` z6<~4|S-8PraMyu`07)PnM&f9cgiatNfdoPrMtYJ-#yB$*0cw%OVSz;!Tio4kad&rj zcXxRIU#D)@y)(CaCeyvkd+*B!Idg7R-E;mrC0FXd)mdl|>#{_Y2C<%X&rlabGqS!t z&K2qnXvBv)2Mr>@k{V{#Rl~d?G#BQLpkng}$lPJxm?y`Fc@t)7n7xZlk?6zR3r9wJ zLk3|k5DlUaeQUh!$c&{yY{o*x5gNqi779b&7n+fzJfXfwB-*G4G>CynFfs^|j=D#KD3ihTMHo>UM46*O z3}LpTK@>R}#8B&!G>9#s8QIDn>#fKF(jc~`d2Qom@Qi1vMfPjgZI}_IL2PT?uwA!< zW@MN>UPyyjNP}=6+%DV=qP3!a;cgKBlieVObAIxdjHNMoWoQs1n5Q%dPLO(q7zxc? zAx1$pG8&Q-cWxTQ_B5b=+R-4!Fh^++-pg1dIxjmwHIjm)moWfXFdD=-x>iszG>Gxc zRT_i`wj&Z9u$`b9nE**(9cU0c^K>lO$$xw~#0!b$eNQ2mw z))hil8pITqQ5uA+C1?;+k?8M?cEgd8-645rw4gMIX>>pku{4N1m>Z=*Ot+4BecTfo zc5%1IU8X_oMT=VL;9Yry22sg;r9rS_=+&S>R6%nQuZD_!*dZD5g*1r2msr~{!IIS7)Va?v3EPE+bHLW4M%=}Loe0mjsD z2on9p?NA&UISi5)xBo5;;&8$t%s3jv5zLIzAda-CcqKdv8h!-89v6ZJ@eexFfbk-k zlLm1N%PI|m!P48nW1+cbIu0r}`iEpQ5m#J}lH(RE6LID=)C2H}yNi9|mv z&cczAvmt|Fk%IMu7 zGzj9?o_aAf7x7D=;`do0gNWxtgSd>3X)(tr$Jmz zd+IKZ25}9ul?LJ6U5iBL?mDPOu7{+%uF)WFpiOm|jRtWeizp4kyS)jCzAN2~BO|v! z23@I;G>HEY05QhUAZ}$|lm>B|g~9H3J2WGA*yFru5O>m(Mv6T%h6ZsLOX%t>1EPKN zZfLH3?tyCLUP!i20ca5S(ThTgtkXtm5cji`EH4e(^E?uLi@ks&BQHV*EmklZ#7p!}j2(ts znY_%rC=KEji-C>xDl{Xn+2cH7^g4ZXY^)Fs;tiJ2fyOv!W4#H@HP%~Djl2z+S7W_H z+X^HyyrMLScUek%jtBD|5`AO6k0T==K(et4PlNc75Mo=bTs~r6lm_v!1;Q5l1e%dg z?QtG0_8EQn77O?45DnsUmeN2mAlhnQKy$73B~&9{LFUzJU(>dNVHeIpgZPFeb(ncT z-y+cg`VOj*?;#1OyEKR&=tc3w(jb0hzAn;v6h9%+_n)6}WaJk}_Mbx0AbzD|?KN3x z5WlfZlm_v;g~8tQ2Q(vp+T&bnmOU=bL?Cz)@tFIKiX$VvAcHU$hz8M{ zzBS(2X%Kx_C`yCa%tB$vH-~1VuRYEc@+6J;kmsgB^kZR-I;*Zx-vXM8dI?k`rI5L! zUdEH-qh8J|jkO0 zvYkC%NP}2NgIGv|;AZoQg+Gds_@DhK#xTxL{*n=)K@4Y}(jYiN>J?%HGf6%L2S<)r9pTvW02^)jD>1s2S|D;C=DV-*9t0z1~HDgN`vsg#v{=I z+YzdfogfLU0}WyVPgmpFX%IWJkkTO3howPGM5=Q#396CFkaV&ct}Wp$Cp!62j9qY= zgOHU5u`A0c4Z_tDG>9ok^mj&6ab#pSNZuJOC=FtFI$#`PX%N$x8>K<)VIA@MI31di zJ?(LqX%H2(sBsV8l}Bh0dof>W5Udz_HE0l(&|Ji;pc<)$WW*QJApT++L=D?Wn==ay zBFz%I-ryP(Yn`=7bPYNKs*#zHY|sU!LDbQ_0*IwS%woRMAk@93LCi*~^Is3uNCPDO zFQh^I1vH38wvo1B78*noODGM(ccNw_x<=d^su6)?BX*Gn(L$r@HsRhIM`#eO%vTzO zpNiU$=$y`hYGf`Xoo1&&%%dIk6HkMf&jLz=aD9|Ch<%XiJnakB$bOLYls65+(4PXz zPJ{Rx3n>l4fg%lJf22B42S7D)AS6NMqCp%)Q|d25gZMksl?LGgjH%&ZB>IcnAviK} zC?qd#|6LlyVT41NaWsg-nHi-)9AQ!MN_ZqRBS+ceLeL;xn_WG6y3auQ@Ako}9^ z6j_&O5GS*|(jYv#Q;_J;oeI^+X^;z!t|JZNbb3>Cozfuw&9X{^@W{?Uq8}D#;>gHZ zkioFXL4!D(_UOAk4dNVTL}?J`T9fS4=Rq@azCG?54dMct(>eyXb`cuHh0IqP1o3N6 zy$G6%_{C6-Tml(HJRcgwrF5Za;%E?;F^INh#Oc$X%OD+jY#xe=_VW*xfwF(N`<6B z+(H1v*kN6^ME=9PC=KFP3xnP7HfTm}x5s(YAnu?ijTC!k3=QH=meAE%21NVjUC>8&O&$5)R&w4P=Ax3N$0H+T%Q8^csD1Y^)Fs;&qnLfyOv!W4!^*HP)L@jl2b!S7W_R+X^HyyrMLS zcUVe$jtBED5`AO6ha)5JL$a|7PlNb?5Mo=bTs~x8lm_vU1;Q5l7@Cn!>~S6~_9=b% z77O?45DnrpmeN2mAlho5LvyY61ymznLgv+KU(vRL;SkF~gZP>yb(ncT-yqQe`WC8@ z?;r`NyEKUJ=|%Cx(jb0dzAn;v6h9)-_n)6|WaMW^_Mbx0Abz1^?KN3x5Wlialm_ve zg~8tQJ2WGI*yCJlmVeTS?;bgKgXnQtCK{}@c9KPq=-Omas74lpWSeBCK`c%?>a#r! zVhLvHlBIXCBockVm%@>er6GfW7lsD03|(u;bI>4)SSm_`Sk^*e(3gW|WO;j>D*!9d zh!1)vG>8>hT00@@u3=vZnhX2NP>rktnLF&O^5poiuf{A5yLYiV5`Ea$z>$$PA%n2z zM}t_4E;Za)Xb@|&M3e@xj&;vauM5q{diFS1sEcXDhdKuhVttm>Fte^2<_(~^FejiI z*$^^!m^b3d@nP=CEDf`Fu`v>Tm^Z^n+B0&VU0Sgu2Js?%|(3+s76X4b4R_DC&x#14A7qd`ojb%l_X2C)mvC=J5Z5;TZik?8M?rr^lPR7l<#Ehr6QH##7QSQ^Cc%#G3@ zrddb4KJEd{$aH($Wg5huw5XL1-jzpa5EaZ<8U!nbUJV+=UeH{`E1?>xf@H)O(jfj~ z8bmeQNSiYY4Wfo6biKhfDAqdDNOTQa3)RRBNH*vK(;#NjyaI@&LDVr{X%On((jaCb z)%l+d)kr-g{V$|J`~@_K2DXv5VHO%hBTFa^!gr!3B)UdyhH7MQNH$^@X%IrA>NbJt zkC%uD4WfnlN`vrIQ7aOi(>AC^=0MVEb{fQ7+EG98G>CaDpfm{AM@fU2k5uPrAE-w5 zg`}svX%PF-p90EGgD@E?;)q&a{s*wXA2`U#2;y{{Ge-RqQK}=T~gbOgH zhQA}xU)&DHk�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�Z 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%0An4?ETK*#LrXE~Af#YDBdJ7#(h36*B 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

YDv&1?1S@1~8F!gk*o& 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 literal 0 HcmV?d00001 diff --git a/backends/tofino/bf-asm/jbay/counter.h b/backends/tofino/bf-asm/jbay/counter.h new file mode 100644 index 00000000000..826c4e6af1f --- /dev/null +++ b/backends/tofino/bf-asm/jbay/counter.h @@ -0,0 +1,121 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_JBAY_COUNTER_H_ +#define BF_ASM_JBAY_COUNTER_H_ + +template +void CounterTable::setup_teop_regs_2(REGS ®s, int stats_group_index) { + BUG_CHECK(teop >= 0 && teop < 4); + BUG_CHECK(gress == EGRESS); + + auto &adrdist = regs.rams.match.adrdist; + + if (!teop_initialized) { + // assume this stage driving teop + auto delay = stage->pipelength(gress) - stage->pred_cycle(gress) - 7; + adrdist.teop_bus_ctl[teop].teop_bus_ctl_delay = delay; + adrdist.teop_bus_ctl[teop].teop_bus_ctl_delay_en = 1; + adrdist.teop_bus_ctl[teop].teop_bus_ctl_stats_en = 1; + + adrdist.stats_to_teop_adr_oxbar_ctl[teop].enabled_2bit_muxctl_select = stats_group_index; + adrdist.stats_to_teop_adr_oxbar_ctl[teop].enabled_2bit_muxctl_enable = 1; + teop_initialized = true; + } + + adrdist.teop_to_stats_adr_oxbar_ctl[stats_group_index].enabled_2bit_muxctl_select = teop; + adrdist.teop_to_stats_adr_oxbar_ctl[stats_group_index].enabled_2bit_muxctl_enable = 1; + + // count all tEOP events + adrdist.dp_teop_stats_ctl[stats_group_index].dp_teop_stats_ctl_err = 0; + // XXX is this always 2? + adrdist.dp_teop_stats_ctl[stats_group_index].dp_teop_stats_ctl_rx_shift = 2; + adrdist.dp_teop_stats_ctl[stats_group_index].dp_teop_stats_ctl_rx_en = 1; + + auto &stats = regs.rams.map_alu.stats_wrap[stats_group_index].stats; + stats.statistics_ctl_teop_en = 1; +} + +template +void CounterTable::write_alu_vpn_range_2(REGS ®s) { + auto &adrdist = regs.rams.match.adrdist; + int minvpn, sparevpn; + + // Used to validate the BFA VPN configuration + std::set vpn_processed; + bitvec vpn_range; + + // Get Spare VPN + layout_vpn_bounds(minvpn, sparevpn, false); + + for (int home_row : home_rows) { + bool block_start = false; + bool block_end = false; + int min = 1000000; + int max = -1; + for (Layout &logical_row : layout) { + // Block Start with the home row and End with the Spare VPN + if (logical_row.row == home_row) block_start = true; + + if (block_start) { + for (auto v : logical_row.vpns) { + if (v == sparevpn) { + block_end = true; + break; + } + if (vpn_processed.count(v)) + error(home_lineno, "Multiple instance of the VPN %d detected", v); + else + vpn_processed.insert(v); + + if (v < min) min = v; + if (v > max) max = v; + } + } + if (block_end) { + BUG_CHECK(min != 1000000 && max != -1); + + bitvec block_range(min, max - min + 1); + if (vpn_range.intersects(block_range)) + error(home_lineno, "Overlapping of VPN range detected"); + else + vpn_range |= block_range; + + adrdist.mau_stats_alu_vpn_range[home_row / 4].stats_vpn_base = min; + adrdist.mau_stats_alu_vpn_range[home_row / 4].stats_vpn_limit = max; + adrdist.mau_stats_alu_vpn_range[home_row / 4].stats_vpn_range_check_enable = 1; + break; + } + } + BUG_CHECK(block_start && block_end); + } + + if (vpn_range != bitvec(minvpn, sparevpn - minvpn)) + error(home_lineno, "VPN range not entirely covered"); +} + +template <> +void CounterTable::setup_teop_regs(Target::JBay::mau_regs ®s, int stats_group_index) { + setup_teop_regs_2(regs, stats_group_index); +} + +template <> +void CounterTable::write_alu_vpn_range(Target::JBay::mau_regs ®s) { + write_alu_vpn_range_2(regs); +} + +#endif /* BF_ASM_JBAY_COUNTER_H_ */ diff --git a/backends/tofino/bf-asm/jbay/deparser.cpp b/backends/tofino/bf-asm/jbay/deparser.cpp new file mode 100644 index 00000000000..e30402ac9b2 --- /dev/null +++ b/backends/tofino/bf-asm/jbay/deparser.cpp @@ -0,0 +1,1092 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* deparser template specializations for jbay -- #included directly in top-level deparser.cpp */ + +#define YES(X) X +#define NO(X) + +#define JBAY_POV(GRESS, VAL, REG) \ + if (VAL.pov.size() == 1) \ + REG.pov = deparser.pov[GRESS].at(&VAL.pov.front()->reg) + VAL.pov.front()->lo; \ + else \ + error(VAL.val.lineno, "POV bit required for Tofino2"); + +#define JBAY_SIMPLE_INTRINSIC(GRESS, VAL, REG, IFSHIFT) \ + REG.phv = VAL.val->reg.deparser_id(); \ + JBAY_POV(GRESS, VAL, REG) \ + IFSHIFT(REG.shft = intrin.vals[0].val->lo;) + +#define JBAY_ARRAY_INTRINSIC(GRESS, VAL, ARRAY, REG, POV, IFSHIFT) \ + for (auto &r : ARRAY) { \ + r.REG.phv = VAL.val->reg.deparser_id(); \ + IFSHIFT(r.REG.shft = intrin.vals[0].val->lo;) \ + } \ + JBAY_POV(GRESS, VAL, POV) + +#define EI_INTRINSIC(NAME, IFSHIFT) \ + DEPARSER_INTRINSIC(JBay, EGRESS, NAME, 1) { \ + JBAY_SIMPLE_INTRINSIC(EGRESS, intrin.vals[0], regs.dprsrreg.inp.ipp.egr.m_##NAME, IFSHIFT) \ + } +#define HO_E_INTRINSIC(NAME, IFSHIFT) \ + DEPARSER_INTRINSIC(JBay, EGRESS, NAME, 1) { \ + JBAY_ARRAY_INTRINSIC(EGRESS, intrin.vals[0], regs.dprsrreg.ho_e, her.meta.m_##NAME, \ + regs.dprsrreg.inp.icr.egr_meta_pov.m_##NAME, IFSHIFT) \ + } +#define II_INTRINSIC(NAME, IFSHIFT) \ + DEPARSER_INTRINSIC(JBay, INGRESS, NAME, 1) { \ + JBAY_SIMPLE_INTRINSIC(INGRESS, intrin.vals[0], regs.dprsrreg.inp.ipp.ingr.m_##NAME, \ + IFSHIFT) \ + } +#define II_INTRINSIC_RENAME(NAME, REGNAME, IFSHIFT) \ + DEPARSER_INTRINSIC(JBay, INGRESS, NAME, 1) { \ + JBAY_SIMPLE_INTRINSIC(INGRESS, intrin.vals[0], regs.dprsrreg.inp.ipp.ingr.m_##REGNAME, \ + IFSHIFT) \ + } +#define HO_I_INTRINSIC(NAME, IFSHIFT) \ + DEPARSER_INTRINSIC(JBay, INGRESS, NAME, 1) { \ + JBAY_ARRAY_INTRINSIC(INGRESS, intrin.vals[0], regs.dprsrreg.ho_i, hir.meta.m_##NAME, \ + regs.dprsrreg.inp.icr.ingr_meta_pov.m_##NAME, IFSHIFT) \ + } +#define HO_I_INTRINSIC_RENAME(NAME, REGNAME, IFSHIFT) \ + DEPARSER_INTRINSIC(JBay, INGRESS, NAME, 1) { \ + JBAY_ARRAY_INTRINSIC(INGRESS, intrin.vals[0], regs.dprsrreg.ho_i, hir.meta.m_##REGNAME, \ + regs.dprsrreg.inp.icr.ingr_meta_pov.m_##REGNAME, IFSHIFT) \ + } + +EI_INTRINSIC(drop_ctl, YES) +EI_INTRINSIC(egress_unicast_port, NO) +HO_E_INTRINSIC(afc, YES) +HO_E_INTRINSIC(capture_tx_ts, YES) +HO_E_INTRINSIC(force_tx_err, YES) +HO_E_INTRINSIC(tx_pkt_has_offsets, YES) +HO_E_INTRINSIC(mirr_c2c_ctrl, YES) +HO_E_INTRINSIC(mirr_coal_smpl_len, YES) +HO_E_INTRINSIC(mirr_dond_ctrl, YES) +HO_E_INTRINSIC(mirr_epipe_port, YES) +HO_E_INTRINSIC(mirr_hash, YES) +HO_E_INTRINSIC(mirr_icos, YES) +HO_E_INTRINSIC(mirr_io_sel, YES) +HO_E_INTRINSIC(mirr_mc_ctrl, YES) +HO_E_INTRINSIC(mirr_qid, YES) +HO_E_INTRINSIC(mtu_trunc_err_f, YES) +HO_E_INTRINSIC(mtu_trunc_len, YES) + +II_INTRINSIC(copy_to_cpu, YES) +II_INTRINSIC(drop_ctl, YES) +II_INTRINSIC(egress_unicast_port, NO) +II_INTRINSIC_RENAME(egress_multicast_group_0, mgid1, NO) +II_INTRINSIC_RENAME(egress_multicast_group_1, mgid2, NO) +II_INTRINSIC(pgen, YES) +II_INTRINSIC(pgen_len, YES) +II_INTRINSIC(pgen_addr, YES) +HO_I_INTRINSIC(afc, YES) +HO_I_INTRINSIC(bypss_egr, YES) +HO_I_INTRINSIC(copy_to_cpu_cos, YES) +HO_I_INTRINSIC(ct_disable, YES) +HO_I_INTRINSIC(ct_mcast, YES) +HO_I_INTRINSIC(deflect_on_drop, YES) +HO_I_INTRINSIC(icos, YES) +HO_I_INTRINSIC(mirr_c2c_ctrl, YES) +HO_I_INTRINSIC(mirr_coal_smpl_len, YES) +HO_I_INTRINSIC(mirr_dond_ctrl, YES) +HO_I_INTRINSIC(mirr_epipe_port, YES) +HO_I_INTRINSIC(mirr_hash, YES) +HO_I_INTRINSIC(mirr_icos, YES) +HO_I_INTRINSIC(mirr_io_sel, YES) +HO_I_INTRINSIC(mirr_mc_ctrl, YES) +HO_I_INTRINSIC(mirr_qid, YES) +HO_I_INTRINSIC(mtu_trunc_err_f, YES) +HO_I_INTRINSIC(mtu_trunc_len, YES) +HO_I_INTRINSIC(qid, YES) +HO_I_INTRINSIC(rid, YES) +HO_I_INTRINSIC_RENAME(meter_color, pkt_color, YES) +HO_I_INTRINSIC_RENAME(xid, xid_l1, YES) +HO_I_INTRINSIC_RENAME(yid, xid_l2, YES) +HO_I_INTRINSIC_RENAME(hash_lag_ecmp_mcast_0, hash1, YES) +HO_I_INTRINSIC_RENAME(hash_lag_ecmp_mcast_1, hash2, YES) + +#undef EI_INTRINSIC +#undef HO_E_INTRINSIC +#undef II_INTRINSIC +#undef II_INTRINSIC_RENAME +#undef HO_I_INTRINSIC +#undef HO_I_INTRINSIC_RENAME + +/** Macros to build Digest::Type objects for JBay -- + * JBAY_SIMPLE_DIGEST: basic digest that appears one place in the config + * JBAY_ARRAY_DIGEST: config is replicated across Header+Output slices + * GRESS: INGRESS or EGRESS + * NAME: keyword use for this digest in the assembler + * ARRAY: Header+Ouput slice array (ho_i or ho_e, matching ingress or egress) + * TBL: config register containing the table config + * SEL: config register with the selection config + * IFID: YES or NO -- if this config needs to program id_phv + * CNT: how many patterns can be specified in the array + * REVERSE: YES or NO -- if the entries in the table are reverse (0 is last byte of header) + * IFIDX: YES or NO -- if CNT > 1 (if we index by id) + */ + +#define JBAY_SIMPLE_DIGEST(GRESS, NAME, TBL, SEL, IFID, CNT, REVERSE, IFIDX) \ + JBAY_COMMON_DIGEST(GRESS, NAME, TBL, SEL, IFID, CNT, REVERSE, IFIDX) \ + JBAY_DIGEST_TABLE(GRESS, NAME, TBL, IFID, YES, CNT, REVERSE, IFIDX) \ + } +#define JBAY_ARRAY_DIGEST(GRESS, NAME, ARRAY, TBL, SEL, IFID, CNT, REVERSE, IFIDX) \ + JBAY_COMMON_DIGEST(GRESS, NAME, TBL, SEL, IFID, CNT, REVERSE, IFIDX) \ + for (auto &r : ARRAY) { \ + JBAY_DIGEST_TABLE(GRESS, NAME, r.TBL, IFID, NO, CNT, REVERSE, IFIDX) \ + } \ + } + +#define JBAY_COMMON_DIGEST(GRESS, NAME, TBL, SEL, IFID, CNT, REVERSE, IFIDX) \ + DEPARSER_DIGEST(JBay, GRESS, NAME, CNT, can_shift = true;) { \ + SEL.phv = data.select.val->reg.deparser_id(); \ + JBAY_POV(GRESS, data.select, SEL) \ + SEL.shft = data.shift + data.select->lo; \ + SEL.disable_ = 0; + +#define JBAY_DIGEST_TABLE(GRESS, NAME, REG, IFID, IFVALID, CNT, REVERSE, IFIDX) \ + for (auto &set : data.layout) { \ + int id = set.first >> data.shift; \ + int idx = 0; \ + int maxidx = REG IFIDX([id]).phvs.size() - 1; \ + bool first = true; \ + int last = -1; \ + for (auto ® : set.second) { \ + if (first) { \ + first = false; \ + IFID(REG IFIDX([id]).id_phv = reg->reg.deparser_id(); continue;) \ + } \ + /* The same 16b/32b container cannot appear consecutively, but 8b can. */ \ + if (last == reg->reg.deparser_id() && reg->reg.size != 8) { \ + error(data.lineno, "%s: %db container %s seen in consecutive locations", #NAME, \ + reg->reg.size, reg->reg.name); \ + continue; \ + } \ + for (int i = reg->reg.size / 8; i > 0; i--) { \ + if (idx > maxidx) { \ + error(data.lineno, "%s digest limited to %d bytes", #NAME, maxidx + 1); \ + break; \ + } \ + REG IFIDX([id]).phvs[REVERSE(maxidx -) idx++] = reg->reg.deparser_id(); \ + } \ + last = reg->reg.deparser_id(); \ + } \ + IFVALID(REG IFIDX([id]).valid = 1;) \ + REG IFIDX([id]).len = idx; \ + } + +JBAY_SIMPLE_DIGEST(INGRESS, learning, regs.dprsrreg.inp.ipp.ingr.learn_tbl, + regs.dprsrreg.inp.ipp.ingr.m_learn_sel, NO, 8, YES, YES) +JBAY_ARRAY_DIGEST(INGRESS, mirror, regs.dprsrreg.ho_i, him.mirr_hdr_tbl.entry, + regs.dprsrreg.inp.ipp.ingr.m_mirr_sel, YES, 16, NO, YES) +JBAY_ARRAY_DIGEST(EGRESS, mirror, regs.dprsrreg.ho_e, hem.mirr_hdr_tbl.entry, + regs.dprsrreg.inp.ipp.egr.m_mirr_sel, YES, 16, NO, YES) +JBAY_SIMPLE_DIGEST(INGRESS, resubmit, regs.dprsrreg.inp.ipp.ingr.resub_tbl, + regs.dprsrreg.inp.ipp.ingr.m_resub_sel, NO, 8, NO, YES) +JBAY_SIMPLE_DIGEST(INGRESS, pktgen, regs.dprsrreg.inp.ipp.ingr.pgen_tbl, + regs.dprsrreg.inp.ipp.ingr.m_pgen, NO, 1, NO, NO) + +// all the jbay deparser subtrees with a dis or disable_ bit +// FIXME -- should be a way of doing this with a smart template or other metaprogramming. +#define JBAY_DISABLE_REGBITS(M) \ + M(YES, regs.dprsrreg.ho_e, her.meta.m_afc, dis) \ + M(YES, regs.dprsrreg.ho_e, her.meta.m_capture_tx_ts, dis) \ + M(YES, regs.dprsrreg.ho_e, her.meta.m_force_tx_err, dis) \ + M(YES, regs.dprsrreg.ho_e, her.meta.m_mirr_c2c_ctrl, dis) \ + M(YES, regs.dprsrreg.ho_e, her.meta.m_mirr_coal_smpl_len, dis) \ + M(YES, regs.dprsrreg.ho_e, her.meta.m_mirr_dond_ctrl, dis) \ + M(YES, regs.dprsrreg.ho_e, her.meta.m_mirr_epipe_port, dis) \ + M(YES, regs.dprsrreg.ho_e, her.meta.m_mirr_hash, dis) \ + M(YES, regs.dprsrreg.ho_e, her.meta.m_mirr_icos, dis) \ + M(YES, regs.dprsrreg.ho_e, her.meta.m_mirr_io_sel, dis) \ + M(YES, regs.dprsrreg.ho_e, her.meta.m_mirr_mc_ctrl, dis) \ + M(YES, regs.dprsrreg.ho_e, her.meta.m_mirr_qid, dis) \ + M(YES, regs.dprsrreg.ho_e, her.meta.m_mtu_trunc_err_f, dis) \ + M(YES, regs.dprsrreg.ho_e, her.meta.m_mtu_trunc_len, dis) \ + M(YES, regs.dprsrreg.ho_e, her.meta.m_tx_pkt_has_offsets, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_afc, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_bypss_egr, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_copy_to_cpu_cos, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_ct_disable, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_ct_mcast, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_deflect_on_drop, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_hash1, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_hash2, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_icos, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_mirr_c2c_ctrl, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_mirr_coal_smpl_len, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_mirr_dond_ctrl, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_mirr_epipe_port, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_mirr_hash, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_mirr_icos, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_mirr_io_sel, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_mirr_mc_ctrl, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_mirr_qid, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_mtu_trunc_err_f, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_mtu_trunc_len, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_pkt_color, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_qid, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_rid, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_xid_l1, dis) \ + M(YES, regs.dprsrreg.ho_i, hir.meta.m_xid_l2, dis) \ + M(NO, , regs.dprsrreg.inp.ipp.egr.m_drop_ctl, disable_) \ + M(NO, , regs.dprsrreg.inp.ipp.egr.m_egress_unicast_port, disable_) \ + M(NO, , regs.dprsrreg.inp.ipp.egr.m_mirr_sel, disable_) \ + M(NO, , regs.dprsrreg.inp.ipp.ingr.m_copy_to_cpu, disable_) \ + M(NO, , regs.dprsrreg.inp.ipp.ingr.m_drop_ctl, disable_) \ + M(NO, , regs.dprsrreg.inp.ipp.ingr.m_egress_unicast_port, disable_) \ + M(NO, , regs.dprsrreg.inp.ipp.ingr.m_learn_sel, disable_) \ + M(NO, , regs.dprsrreg.inp.ipp.ingr.m_mgid1, disable_) \ + M(NO, , regs.dprsrreg.inp.ipp.ingr.m_mgid2, disable_) \ + M(NO, , regs.dprsrreg.inp.ipp.ingr.m_mirr_sel, disable_) \ + M(NO, , regs.dprsrreg.inp.ipp.ingr.m_pgen, disable_) \ + M(NO, , regs.dprsrreg.inp.ipp.ingr.m_pgen_addr, disable_) \ + M(NO, , regs.dprsrreg.inp.ipp.ingr.m_pgen_len, disable_) \ + M(NO, , regs.dprsrreg.inp.ipp.ingr.m_resub_sel, disable_) + +// Compiler workaround for TOF2LAB-44, skip certain chunk indices +void tof2lab44_workaround(int lineno, unsigned &chunk_index) { + if (options.tof2lab44_workaround) { + static std::set skipped_chunks = {24, 32, 40, 48, 56, 64, 72, + 80, 88, 96, 104, 112, 120}; + while (skipped_chunks.count(chunk_index)) chunk_index++; + } +} + +// INVARIANT: check_chunk is idempotent. +bool check_chunk(int lineno, unsigned &chunk) { + tof2lab44_workaround(lineno, chunk); + + const unsigned TOTAL_CHUNKS = Target::JBay::DEPARSER_TOTAL_CHUNKS; + static bool suppress_repeated = false; + if (chunk >= TOTAL_CHUNKS) { + if (!suppress_repeated) + error(lineno, "Ran out of chunks in field dictionary (%d)", TOTAL_CHUNKS); + suppress_repeated = true; + return false; + } + return true; +} + +/// A callback to write a PHV, constant, or checksum chunk to the field dictionary. +using WriteChunk = std::function; + +/// A callback to finish writing a PHV, constant, or checksum chunk to the field dictionary. +using FinishChunk = + std::function; + +/// A callback for writing a CLOT to the field dictionary. This increments the chunk index if the +/// CLOT spans multiple chunks. +using WriteClot = std::function; + +/// Implements common control functionality for outputting field dictionaries and field dictionary +/// slices. +template +void output_jbay_field_dictionary_helper(int lineno, POV &pov, DICT &dict, WriteChunk write_chunk, + FinishChunk finish_chunk, WriteClot write_clot) { + const unsigned CHUNK_SIZE = Target::JBay::DEPARSER_CHUNK_SIZE; + const unsigned CHUNK_GROUPS = Target::JBay::DEPARSER_CHUNK_GROUPS; + const unsigned CHUNKS_PER_GROUP = Target::JBay::DEPARSER_CHUNKS_PER_GROUP; + const unsigned CLOTS_PER_GROUP = Target::JBay::DEPARSER_CLOTS_PER_GROUP; + unsigned ch = 0, entry_n = 0, byte = 0, group = 0, clots_in_group = 0; + Phv::Slice prev_pov; + int prev = -1; + + // INVARIANT: check_chunk should be called immediately before doing anything with a chunk. + // Because check_chunk is idempotent, it is fine to call it on a chunk that has previously been + // checked. + + for (auto &ent : dict) { + auto *clot = dynamic_cast(ent.what.get()); + // FIXME -- why does the following give an error from gcc? + // auto *clot = ent.what->to(); + unsigned size = ent.what->size(); + + // Finish the current chunk if needed. + if (byte && + (clot || byte + size > CHUNK_SIZE || (prev_pov && *ent.pov.front() != prev_pov))) { + finish_chunk(ch++, entry_n++, prev_pov, byte); + byte = 0; + } + if (ch / CHUNKS_PER_GROUP != group) { + // into a new group + group = ch / CHUNKS_PER_GROUP; + clots_in_group = 0; + } + if (clot) { + // Start a new group if needed. Each group has a maximum number of CLOTs that can be + // deparsed, and CLOTs cannot span multiple groups. + bool out_of_clots_in_group = clots_in_group >= CLOTS_PER_GROUP; + auto chunks_in_clot = (size + CHUNK_SIZE - 1) / CHUNK_SIZE; + bool out_of_chunks_in_group = ch % CHUNKS_PER_GROUP + chunks_in_clot > CHUNKS_PER_GROUP; + if (out_of_clots_in_group || out_of_chunks_in_group) { + // go on to the next group + ch = (ch | (CHUNKS_PER_GROUP - 1)) + 1; + group = ch / CHUNKS_PER_GROUP; + clots_in_group = 0; + } + + // Write the CLOT to the next segment in the current group. + if (chunks_in_clot == CHUNKS_PER_GROUP && (ch % CHUNKS_PER_GROUP)) + error(clot->lineno, "--tof2lab44-workaround incompatible with clot >56 bytes"); + int clot_tag = Parser::clot_tag(clot->gress, clot->tag); + int seg_tag = clots_in_group++; + write_clot(ch, entry_n, seg_tag, clot_tag, ent.pov.front(), clot); + + prev = -1; + } else { + // Phv, Constant, or Checksum + write_chunk(ch, prev_pov, prev, ent.lineno, ent.pov.front(), ent.what.get(), byte, + size); + byte += size; + prev = ent.what->encode(); + } + prev_pov = *ent.pov.front(); + } + + if (byte > 0) { + finish_chunk(ch, entry_n, prev_pov, byte); + } +} + +template +void output_jbay_field_dictionary(int lineno, REGS ®s, POV_FMT &pov_layout, POV &pov, + DICT &dict) { + // Initialize pov_layout. + unsigned byte = 0; + for (auto &r : pov) { + for (int bits = 0; bits < r.first->size; bits += 8) { + if (byte > pov_layout.size()) error(lineno, "Ran out of space in POV in deparser"); + pov_layout[byte++] = r.first->deparser_id(); + } + } + while (byte < pov_layout.size()) pov_layout[byte++] = 0xff; + LOG5("jbay field dictionary:"); + + // Declare some callback functions, and then delegate to helper. + auto write_chunk = [](unsigned ch, const Phv::Slice &prev_pov, int prev, int ent_lineno, + const Phv::Ref &ent_pov, Deparser::FDEntry::Base *ent_what, unsigned byte, + unsigned size) { + // Just do an error check here. Defer actual writing to finish_chunk. + LOG5(" chunk " << ch << ": " << *ent_what << " (pov " << ent_pov << ")"); + if (dynamic_cast(ent_what) && prev_pov == *ent_pov && + int(ent_what->encode()) == prev && (size & 6)) + error(ent_lineno, "16 and 32-bit container cannot be repeatedly deparsed"); + }; + + auto finish_chunk = [&](unsigned ch, unsigned entry_n, const Phv::Slice &pov_bit, + unsigned byte) { + if (check_chunk(lineno, ch)) { + regs.chunk_info[ch].chunk_vld = 1; + regs.chunk_info[ch].pov = pov.at(&pov_bit.reg) + pov_bit.lo; + regs.chunk_info[ch].seg_vld = 0; + regs.chunk_info[ch].seg_slice = byte & 7; + regs.chunk_info[ch].seg_sel = byte >> 3; + } + }; + + auto write_clot = [&](unsigned &ch, unsigned &entry_n, int seg_tag, int clot_tag, + const Phv::Ref &pov_bit, Deparser::FDEntry::Clot *clot) { + const unsigned CHUNKS_PER_GROUP = Target::JBay::DEPARSER_CHUNKS_PER_GROUP; + const int group = ch / CHUNKS_PER_GROUP; + if (group < regs.fd_tags.size()) regs.fd_tags[group].segment_tag[seg_tag] = clot_tag; + LOG5(" chunk " << ch << ": " << *clot << " (pov " << pov_bit << ")"); + for (int i = 0; i < clot->length; i += 8, ++ch) { + // CLOTs cannot span multiple groups. + BUG_CHECK(ch / CHUNKS_PER_GROUP == group || error_count > 0, "CLOT spanning groups"); + if (check_chunk(lineno, ch)) { + regs.chunk_info[ch].chunk_vld = 1; + regs.chunk_info[ch].pov = pov.at(&pov_bit->reg) + pov_bit->lo; + regs.chunk_info[ch].seg_vld = 1; + regs.chunk_info[ch].seg_sel = seg_tag; + regs.chunk_info[ch].seg_slice = i / 8U; + } + } + }; + + output_jbay_field_dictionary_helper(lineno, pov, dict, write_chunk, finish_chunk, write_clot); +} + +template +void output_jbay_field_dictionary_slice(int lineno, CHUNKS &chunk, CLOTS &clots, POV &pov, + DICT &dict, json::vector &fd_gress, + json::vector &fd_entries, gress_t gress) { + json::map fd; + json::map fd_entry; + json::vector chunk_bytes; + json::vector fd_entry_chunk_bytes; + + auto write_chunk = [&](unsigned ch, const Phv::Slice &prev_pov, int prev, int ent_lineno, + const Phv::Ref &ent_pov, Deparser::FDEntry::Base *ent_what, + unsigned byte, unsigned size) { + while (size--) { + json::map chunk_byte; + json::map fd_entry_chunk_byte; + json::map fd_entry_chunk; + chunk_byte["Byte"] = byte; + fd_entry_chunk_byte["chunk_number"] = byte; + if (ent_what->encode() < CONSTANTS_PHVID_JBAY_LOW) { + auto *phv = dynamic_cast(ent_what); + auto phv_reg = phv->reg(); + write_field_name_in_json(phv_reg, &ent_pov->reg, ent_pov->lo, chunk_byte, + fd_entry_chunk, 19, gress); + } else { + write_csum_const_in_json(ent_what->encode(), chunk_byte, fd_entry_chunk, gress); + } + fd_entry_chunk_byte["chunk"] = std::move(fd_entry_chunk); + chunk_bytes.push_back(std::move(chunk_byte)); + fd_entry_chunk_bytes.push_back(std::move(fd_entry_chunk_byte)); + if (check_chunk(lineno, ch)) { + chunk[ch].is_phv |= 1 << byte; + chunk[ch].byte_off.phv_offset[byte++] = ent_what->encode(); + } + } + }; + + auto finish_chunk = [&](unsigned ch, unsigned entry_n, const Phv::Slice &pov_bit, + unsigned byte) { + fd["Field Dictionary Number"] = entry_n; + fd["Field Dictionary Chunk"] = ch; + fd_entry["entry"] = entry_n; + // fd_entry["fde_chunk"] = ch; -- requires compiler_interfaces change + Deparser::write_pov_in_json(fd, fd_entry, &pov_bit.reg, pov.at(&pov_bit.reg) + pov_bit.lo, + pov_bit.lo); + if (check_chunk(lineno, ch)) { + chunk[ch].cfg.seg_vld = 0; // no CLOTs yet + chunk[ch].cfg.seg_slice = byte & 7; + chunk[ch].cfg.seg_sel = byte >> 3; + } + + fd["Content"] = std::move(chunk_bytes); + fd_entry["chunks"] = std::move(fd_entry_chunk_bytes); + fd_entries.push_back(std::move(fd_entry)); + fd_gress.push_back(std::move(fd)); + }; + + auto write_clot = [&](unsigned &ch, unsigned &entry_n, int seg_tag, int clot_tag, + const Phv::Ref &pov_bit, Deparser::FDEntry::Clot *clot) { + const unsigned CHUNKS_PER_GROUP = Target::JBay::DEPARSER_CHUNKS_PER_GROUP; + const int group = ch / CHUNKS_PER_GROUP; + if (group < clots.size()) clots[group].segment_tag[seg_tag] = clot_tag; + auto phv_repl = clot->phv_replace.begin(); + auto csum_repl = clot->csum_replace.begin(); + for (int i = 0; i < clot->length; i += 8, ++ch, ++entry_n) { + // CLOTs cannot span multiple groups. + BUG_CHECK(ch / CHUNKS_PER_GROUP == group || error_count > 0, "CLOT spanning groups"); + + fd["Field Dictionary Number"] = entry_n; + fd["Field Dictionary Chunk"] = ch; + fd_entry["entry"] = entry_n; + // fd_entry["fde_chunk"] = ch; -- requires compiler_interfaces change + Deparser::write_pov_in_json(fd, fd_entry, &pov_bit->reg, + pov.at(&pov_bit->reg) + pov_bit->lo, pov_bit->lo); + + if (check_chunk(lineno, ch)) { + chunk[ch].cfg.seg_vld = 1; + chunk[ch].cfg.seg_sel = seg_tag; + chunk[ch].cfg.seg_slice = i / 8U; + } + + for (int j = 0; j < 8 && i + j < clot->length; ++j) { + json::map chunk_byte; + json::map fd_entry_chunk_byte; + json::map fd_entry_chunk; + chunk_byte["Byte"] = j; + fd_entry_chunk_byte["chunk_number"] = j; + if (phv_repl != clot->phv_replace.end() && int(phv_repl->first) <= i + j) { + // This is PHV replaced, PHV is used + chunk[ch].is_phv |= 1 << j; + chunk[ch].byte_off.phv_offset[j] = phv_repl->second->reg.deparser_id(); + auto phv_reg = &phv_repl->second->reg; + write_field_name_in_json(phv_reg, &pov_bit->reg, pov_bit->lo, chunk_byte, + fd_entry_chunk, 19, gress); + if (int(phv_repl->first + phv_repl->second->size() / 8U) <= i + j + 1) + ++phv_repl; + } else if (csum_repl != clot->csum_replace.end() && + int(csum_repl->first) <= i + j) { + if (check_chunk(lineno, ch)) { + chunk[ch].is_phv |= 1 << j; + chunk[ch].byte_off.phv_offset[j] = csum_repl->second.encode(); + } + write_csum_const_in_json(csum_repl->second.encode(), chunk_byte, fd_entry_chunk, + gress); + if (int(csum_repl->first + 2) <= i + j + 1) ++csum_repl; + } else { + if (check_chunk(lineno, ch)) chunk[ch].byte_off.phv_offset[j] = i + j; + chunk_byte["CLOT"] = clot_tag; + chunk_byte["CLOT_OFFSET"] = i + j; + fd_entry_chunk["clot_tag"] = clot_tag; + // fd_entry_chunk["clot_offset"] = i + j; requires compiler_interfaces change + } + fd_entry_chunk_byte["chunk"] = std::move(fd_entry_chunk); + chunk_bytes.push_back(std::move(chunk_byte)); + fd_entry_chunk_bytes.push_back(std::move(fd_entry_chunk_byte)); + } + fd["Content"] = std::move(chunk_bytes); + fd_entry["chunks"] = std::move(fd_entry_chunk_bytes); + fd_entries.push_back(std::move(fd_entry)); + fd_gress.push_back(std::move(fd)); + } + }; + + output_jbay_field_dictionary_helper(lineno, pov, dict, write_chunk, finish_chunk, write_clot); +} + +static void check_jbay_ownership(bitvec phv_use[2]) { + unsigned mask = 0; + int group = -1; + for (auto i : phv_use[INGRESS]) { + if ((i | mask) == (group | mask)) continue; + switch (Phv::reg(i)->size) { + case 8: + case 16: + mask = 3; + break; + case 32: + mask = 1; + break; + default: + BUG(); + } + group = i & ~mask; + if (phv_use[EGRESS].getrange(group, mask + 1)) { + error(0, "%s..%s used by both ingress and egress deparser", Phv::reg(group)->name, + Phv::reg(group | mask)->name); + } + } +} + +static void setup_jbay_ownership(bitvec phv_use, ubits_base &phv8, ubits_base &phv16, + ubits_base &phv32) { + std::set phv8_grps, phv16_grps, phv32_grps; + + for (auto i : phv_use) { + auto *reg = Phv::reg(i); + switch (reg->size) { + case 8: + phv8_grps.insert(1U << ((reg->deparser_id() - 64) / 4U)); + break; + case 16: + phv16_grps.insert(1U << ((reg->deparser_id() - 128) / 4U)); + break; + case 32: + phv32_grps.insert(1U << (reg->deparser_id() / 2U)); + break; + default: + BUG(); + } + } + + for (auto v : phv8_grps) phv8 |= v; + for (auto v : phv16_grps) phv16 |= v; + for (auto v : phv32_grps) phv32 |= v; +} + +static short jbay_phv2cksum[224][2] = { + // Entries 0-127 are for 32 bit PHV + // Each 32 bit PHV uses two 16b adders + // The even addresses are for [31:16], the odd addresses are for [15:0] + // Note: The current CSR description of these entries for 32 bit containers is incorrect. + // 128-191 are for 8 bit PHV + // 192-287 are for 16 bit PHV + {1, 0}, {3, 2}, {5, 4}, {7, 6}, {9, 8}, {11, 10}, {13, 12}, {15, 14}, + {17, 16}, {19, 18}, {21, 20}, {23, 22}, {25, 24}, {27, 26}, {29, 28}, {31, 30}, + {33, 32}, {35, 34}, {37, 36}, {39, 38}, {41, 40}, {43, 42}, {45, 44}, {47, 46}, + {49, 48}, {51, 50}, {53, 52}, {55, 54}, {57, 56}, {59, 58}, {61, 60}, {63, 62}, + {65, 64}, {67, 66}, {69, 68}, {71, 70}, {73, 72}, {75, 74}, {77, 76}, {79, 78}, + {81, 80}, {83, 82}, {85, 84}, {87, 86}, {89, 88}, {91, 90}, {93, 92}, {95, 94}, + {97, 96}, {99, 98}, {101, 100}, {103, 102}, {105, 104}, {107, 106}, {109, 108}, {111, 110}, + {113, 112}, {115, 114}, {117, 116}, {119, 118}, {121, 120}, {123, 122}, {125, 124}, {127, 126}, + {128, -1}, {129, -1}, {130, -1}, {131, -1}, {132, -1}, {133, -1}, {134, -1}, {135, -1}, + {136, -1}, {137, -1}, {138, -1}, {139, -1}, {140, -1}, {141, -1}, {142, -1}, {143, -1}, + {144, -1}, {145, -1}, {146, -1}, {147, -1}, {148, -1}, {149, -1}, {150, -1}, {151, -1}, + {152, -1}, {153, -1}, {154, -1}, {155, -1}, {156, -1}, {157, -1}, {158, -1}, {159, -1}, + {160, -1}, {161, -1}, {162, -1}, {163, -1}, {164, -1}, {165, -1}, {166, -1}, {167, -1}, + {168, -1}, {169, -1}, {170, -1}, {171, -1}, {172, -1}, {173, -1}, {174, -1}, {175, -1}, + {176, -1}, {177, -1}, {178, -1}, {179, -1}, {180, -1}, {181, -1}, {182, -1}, {183, -1}, + {184, -1}, {185, -1}, {186, -1}, {187, -1}, {188, -1}, {189, -1}, {190, -1}, {191, -1}, + {192, -1}, {193, -1}, {194, -1}, {195, -1}, {196, -1}, {197, -1}, {198, -1}, {199, -1}, + {200, -1}, {201, -1}, {202, -1}, {203, -1}, {204, -1}, {205, -1}, {206, -1}, {207, -1}, + {208, -1}, {209, -1}, {210, -1}, {211, -1}, {212, -1}, {213, -1}, {214, -1}, {215, -1}, + {216, -1}, {217, -1}, {218, -1}, {219, -1}, {220, -1}, {221, -1}, {222, -1}, {223, -1}, + {224, -1}, {225, -1}, {226, -1}, {227, -1}, {228, -1}, {229, -1}, {230, -1}, {231, -1}, + {232, -1}, {233, -1}, {234, -1}, {235, -1}, {236, -1}, {237, -1}, {238, -1}, {239, -1}, + {240, -1}, {241, -1}, {242, -1}, {243, -1}, {244, -1}, {245, -1}, {246, -1}, {247, -1}, + {248, -1}, {249, -1}, {250, -1}, {251, -1}, {252, -1}, {253, -1}, {254, -1}, {255, -1}, + {256, -1}, {257, -1}, {258, -1}, {259, -1}, {260, -1}, {261, -1}, {262, -1}, {263, -1}, + {264, -1}, {265, -1}, {266, -1}, {267, -1}, {268, -1}, {269, -1}, {270, -1}, {271, -1}, + {272, -1}, {273, -1}, {274, -1}, {275, -1}, {276, -1}, {277, -1}, {278, -1}, {279, -1}, + {280, -1}, {281, -1}, {282, -1}, {283, -1}, {284, -1}, {285, -1}, {286, -1}, {287, -1}, +}; + +template +static void write_jbay_checksum_entry(ENTRIES &entry, unsigned mask, int swap, int pov, int id, + const char *reg = nullptr) { + write_checksum_entry(entry, mask, swap, id, reg); + entry.pov = pov; +} + +// Populates pov_map which maps the bit in the main POV array [127:0] +// to bit in the checksum pov array [32:0] +// The checksum pov array is 32 bits / 4 bytes - pov_cfg.byte_set[4]. +// Each element of the pov_cfg.byte_sel array maps to the byte in the main POV array +template +void jbay_csum_pov_config(Phv::Ref povRef, POV &pov_cfg, + ordered_map &pov, + std::map &pov_map, unsigned *prev_byte, + int csum_unit) { + unsigned bit = pov.at(&povRef->reg) + povRef->lo; + if (pov_map.count(bit)) return; + for (unsigned i = 0; i < (*prev_byte); ++i) { + if (pov_cfg.byte_sel[i] == bit / 8U) { + pov_map[bit] = i * 8U + bit % 8U; + break; + } + } + if (pov_map.count(bit)) return; + if (*prev_byte >= (int)pov_cfg.byte_sel.size()) { + error(povRef.lineno, "Checksum unit %d exceeds %d bytes of POV", csum_unit, + (int)pov_cfg.byte_sel.size()); + return; + } + pov_map[bit] = (*prev_byte) * 8U + bit % 8U; + pov_cfg.byte_sel[(*prev_byte)++] = bit / 8U; + return; +} + +template +void set_jbay_pov_cfg(POV &pov_cfg, std::map &pov_map, + Deparser::FullChecksumUnit &full_csum, + ordered_map &pov, int csum_unit, + unsigned *prev_byte) { + for (auto &unit_entry : full_csum.entries) { + for (auto val : unit_entry.second) { + if (val.pov.size() != 1) { + error(val.val.lineno, "one POV bit required for Tofino2"); + continue; + } + jbay_csum_pov_config(val.pov.front(), pov_cfg, pov, pov_map, prev_byte, csum_unit); + } + } + for (auto &val : full_csum.clot_entries) { + if (val.pov.size() != 1) { + error(val.val.lineno, "one POV bit required for Tofino2"); + continue; + } + jbay_csum_pov_config(val.pov.front(), pov_cfg, pov, pov_map, prev_byte, csum_unit); + } + for (auto &checksum_pov : full_csum.pov) { + jbay_csum_pov_config(checksum_pov.second, pov_cfg, pov, pov_map, prev_byte, csum_unit); + } + return; +} + +template +void write_jbay_full_checksum_config( + CSUM &csum, ENTRIES &phv_entries, int unit, std::set &visited, + std::array, MAX_DEPARSER_CHECKSUM_UNITS> &pov_map, + Deparser::FullChecksumUnit &full_csum, ordered_map &pov) { + for (auto &unit_entry : full_csum.entries) { + // Same partial checksum unit can be used in multiple full checksum unit. + // No need to rewrite the checksum entries multiple times for the same unit + if (visited.count(unit_entry.first)) continue; + visited.insert(unit_entry.first); + for (auto val : unit_entry.second) { + if (val.pov.size() != 1) continue; + int povbit = + pov_map[unit_entry.first].at(pov.at(&val.pov.front()->reg) + val.pov.front()->lo); + int mask = val.mask; + int swap = val.swap; + auto &remap = jbay_phv2cksum[val->reg.deparser_id()]; + write_jbay_checksum_entry(phv_entries[unit_entry.first].entry[remap[0]], mask & 3, + swap & 1, povbit, unit_entry.first, val->reg.name); + if (remap[1] >= 0) + write_jbay_checksum_entry(phv_entries[unit_entry.first].entry[remap[1]], mask >> 2, + swap >> 1, povbit, unit_entry.first, val->reg.name); + else + BUG_CHECK((mask >> 2 == 0) && (swap >> 1 == 0)); + } + } + int tag_idx = 0; + for (auto &val : full_csum.clot_entries) { + if (val.pov.size() != 1) continue; + int povbit = pov_map[unit].at(pov.at(&val.pov.front()->reg) + val.pov.front()->lo); + if (tag_idx == 16) error(-1, "Ran out of clot entries in deparser checksum unit %d", unit); + csum.clot_entry[tag_idx].pov = povbit; + csum.clot_entry[tag_idx].vld = 1; + csum.tags[tag_idx].tag = val.tag; + tag_idx++; + } + for (auto &checksum_pov : full_csum.pov) { + csum.phv_entry[checksum_pov.first].pov = + pov_map[unit].at(pov.at(&checksum_pov.second->reg) + checksum_pov.second->lo); + csum.phv_entry[checksum_pov.first].vld = 1; + } + csum.zeros_as_ones.en = full_csum.zeros_as_ones_en; + + // FIXME -- use/set csum.csum_constant? +} +// Engine 0: scratch[23:0] +// Engine 1: { scratch2[15:0], scratch[31:24] } +// Engine 2: { scratch[7:0] , scratch2[31:16] } +// Engine 3: scratch[31:8] +// So each engine gets a cfg_vector[23:0] +// There are 16 CLOT csums and 8 PHV csums that can be inverted: +// CLOT csum [15:0] are controlled by cfg_vector [15:0] +// PHV csums [7:0] are controlled by cfg_vector [23:16] + +template +void write_jbay_full_checksum_invert_config(SCRATCH1 &scratch1, SCRATCH2 &scratch2, + SCRATCH3 &scratch3, int unit, + Deparser::FullChecksumUnit &full_csum) { + ubits<32> value1; + ubits<32> value2; + ubits<32> value3; + for (auto checksum_unit : full_csum.checksum_unit_invert) { + if (unit == 0) { + value1 |= (1 << (16 + checksum_unit)); + } else if (unit == 1) { + value1 |= (1 << (8 + checksum_unit)); + } else if (unit == 2) { + value3 |= (1 << checksum_unit); + } else if (unit == 3) { + value3 |= (1 << (24 + checksum_unit)); + } + } + for (auto clot_tag : full_csum.clot_tag_invert) { + if (unit == 0) { + value1 |= (1 << clot_tag); + } else if (unit == 1) { + if (clot_tag > 7) { + value1 |= (1 << (clot_tag - 8)); + } else { + value3 |= (1 << (16 + clot_tag)); + } + } else if (unit == 2) { + value2 |= (1 << (16 + clot_tag)); + } else if (unit == 3) { + value3 |= (1 << (8 + clot_tag)); + } + } + if (value1 || value2 || value3) { + scratch1.value |= value1; + scratch2.value |= value2; + scratch3.value |= value3; + } + return; +} + +template +void write_jbay_constant_config(CONS &cons, const std::set &vals) { + unsigned idx = 0; + for (auto v : vals) { + cons[idx] = v; + idx++; + } +} + +template <> +void Deparser::write_config(Target::JBay::deparser_regs ®s) { + regs.dprsrreg.inp.icr.disable(); // disable this whole tree + regs.dprsrreg.inp.icr.disabled_ = false; // then enable just certain subtrees + regs.dprsrreg.inp.icr.csum_engine.enable(); + regs.dprsrreg.inp.icr.egr.enable(); + regs.dprsrreg.inp.icr.egr_meta_pov.enable(); + regs.dprsrreg.inp.icr.ingr.enable(); + regs.dprsrreg.inp.icr.ingr_meta_pov.enable(); + regs.dprsrreg.inp.icr.scratch.enable(); + regs.dprsrreg.inp.icr.scratch2.enable(); + regs.dprsrreg.inp.ipp.scratch.enable(); + regs.dprsrreg.inp.iim.disable(); + regs.dprsrreg.inpslice.disable(); + for (auto &r : regs.dprsrreg.ho_i) r.out_ingr.disable(); + for (auto &r : regs.dprsrreg.ho_e) r.out_egr.disable(); + + for (auto &r : regs.dprsrreg.ho_i) + write_jbay_constant_config(r.hir.h.hdr_xbar_const.value, constants[INGRESS]); + for (auto &r : regs.dprsrreg.ho_e) + write_jbay_constant_config(r.her.h.hdr_xbar_const.value, constants[EGRESS]); + std::set visited_i; + std::array, MAX_DEPARSER_CHECKSUM_UNITS> pov_map_i; + for (int csum_unit = 0; csum_unit < Target::JBay::DEPARSER_CHECKSUM_UNITS; csum_unit++) { + unsigned prev_byte = 0; + if (full_checksum_unit[INGRESS][csum_unit].clot_entries.empty() && + full_checksum_unit[INGRESS][csum_unit].entries.empty()) + continue; + set_jbay_pov_cfg(regs.dprsrreg.inp.ipp.phv_csum_pov_cfg.csum_pov_cfg[csum_unit], + pov_map_i[csum_unit], full_checksum_unit[INGRESS][csum_unit], pov[INGRESS], + csum_unit, &prev_byte); + if (error_count > 0) break; + } + for (int csum_unit = 0; csum_unit < Target::JBay::DEPARSER_CHECKSUM_UNITS && error_count == 0; + csum_unit++) { + if (full_checksum_unit[INGRESS][csum_unit].clot_entries.empty() && + full_checksum_unit[INGRESS][csum_unit].entries.empty()) + continue; + regs.dprsrreg.inp.ipp.phv_csum_pov_cfg.thread.thread[csum_unit] = INGRESS; + write_jbay_full_checksum_config( + regs.dprsrreg.inp.icr.csum_engine[csum_unit], regs.dprsrreg.inp.ipp_m.i_csum.engine, + csum_unit, visited_i, pov_map_i, full_checksum_unit[INGRESS][csum_unit], pov[INGRESS]); + write_jbay_full_checksum_invert_config( + regs.dprsrreg.inp.icr.scratch, regs.dprsrreg.inp.icr.scratch2, + regs.dprsrreg.inp.ipp.scratch, csum_unit, full_checksum_unit[INGRESS][csum_unit]); + } + std::set visited_e; + std::array, MAX_DEPARSER_CHECKSUM_UNITS> pov_map_e; + for (int csum_unit = 0; csum_unit < Target::JBay::DEPARSER_CHECKSUM_UNITS; csum_unit++) { + unsigned prev_byte = 0; + if (full_checksum_unit[EGRESS][csum_unit].clot_entries.empty() && + full_checksum_unit[EGRESS][csum_unit].entries.empty()) + continue; + set_jbay_pov_cfg(regs.dprsrreg.inp.ipp.phv_csum_pov_cfg.csum_pov_cfg[csum_unit], + pov_map_e[csum_unit], full_checksum_unit[EGRESS][csum_unit], pov[EGRESS], + csum_unit, &prev_byte); + if (error_count > 0) break; + } + for (int csum_unit = 0; csum_unit < Target::JBay::DEPARSER_CHECKSUM_UNITS && error_count == 0; + csum_unit++) { + if (full_checksum_unit[EGRESS][csum_unit].clot_entries.empty() && + full_checksum_unit[EGRESS][csum_unit].entries.empty()) + continue; + regs.dprsrreg.inp.ipp.phv_csum_pov_cfg.thread.thread[csum_unit] = EGRESS; + write_jbay_full_checksum_config( + regs.dprsrreg.inp.icr.csum_engine[csum_unit], regs.dprsrreg.inp.ipp_m.i_csum.engine, + csum_unit, visited_e, pov_map_e, full_checksum_unit[EGRESS][csum_unit], pov[EGRESS]); + write_jbay_full_checksum_invert_config( + regs.dprsrreg.inp.icr.scratch, regs.dprsrreg.inp.icr.scratch2, + regs.dprsrreg.inp.ipp.scratch, csum_unit, full_checksum_unit[EGRESS][csum_unit]); + } + + output_jbay_field_dictionary(lineno[INGRESS], regs.dprsrreg.inp.icr.ingr, + regs.dprsrreg.inp.ipp.main_i.pov.phvs, pov[INGRESS], + dictionary[INGRESS]); + json::map field_dictionary_alloc; + json::vector fde_entries_i; + json::vector fde_entries_e; + json::vector fde_entries; + json::vector fd_gress; + for (auto &rslice : regs.dprsrreg.ho_i) { + output_jbay_field_dictionary_slice(lineno[INGRESS], rslice.him.fd_compress.chunk, + rslice.hir.h.compress_clot_sel, pov[INGRESS], + dictionary[INGRESS], fd_gress, fde_entries, INGRESS); + field_dictionary_alloc["ingress"] = std::move(fd_gress); + fde_entries_i = std::move(fde_entries); + } + output_jbay_field_dictionary(lineno[EGRESS], regs.dprsrreg.inp.icr.egr, + regs.dprsrreg.inp.ipp.main_e.pov.phvs, pov[EGRESS], + dictionary[EGRESS]); + for (auto &rslice : regs.dprsrreg.ho_e) { + output_jbay_field_dictionary_slice(lineno[EGRESS], rslice.hem.fd_compress.chunk, + rslice.her.h.compress_clot_sel, pov[EGRESS], + dictionary[EGRESS], fd_gress, fde_entries, EGRESS); + field_dictionary_alloc["egress"] = std::move(fd_gress); + fde_entries_e = std::move(fde_entries); + } + if (Log::verbosity() > 0) { + auto json_dump = open_output("logs/field_dictionary.log"); + *json_dump << &field_dictionary_alloc; + } + // Output deparser resources + report_resources_deparser_json(fde_entries_i, fde_entries_e); + + if (Phv::use(INGRESS).intersects(Phv::use(EGRESS))) { + if (!options.match_compiler) { + error(lineno[INGRESS], "Registers used in both ingress and egress in pipeline: %s", + Phv::db_regset(Phv::use(INGRESS) & Phv::use(EGRESS)).c_str()); + } else { + warning(lineno[INGRESS], "Registers used in both ingress and egress in pipeline: %s", + Phv::db_regset(Phv::use(INGRESS) & Phv::use(EGRESS)).c_str()); + } + /* FIXME -- this only (sort-of) works because 'deparser' comes first in the alphabet, + * FIXME -- so is the first section to have its 'output' method run. Its a hack + * FIXME -- anyways to attempt to correct broken asm that should be an error */ + Phv::unsetuse(INGRESS, phv_use[EGRESS]); + Phv::unsetuse(EGRESS, phv_use[INGRESS]); + } + + check_jbay_ownership(phv_use); + regs.dprsrreg.inp.icr.i_phv8_grp.enable(); + regs.dprsrreg.inp.icr.i_phv16_grp.enable(); + regs.dprsrreg.inp.icr.i_phv32_grp.enable(); + // regs.dprsrreg.inp.icr.scratch.enable(); + regs.dprsrreg.inp.icr.i_phv8_grp.val = 0; + regs.dprsrreg.inp.icr.i_phv16_grp.val = 0; + regs.dprsrreg.inp.icr.i_phv32_grp.val = 0; + // regs.dprsrreg.inp.icr.scratch.value = 0; + setup_jbay_ownership(phv_use[INGRESS], regs.dprsrreg.inp.icr.i_phv8_grp.val, + regs.dprsrreg.inp.icr.i_phv16_grp.val, + regs.dprsrreg.inp.icr.i_phv32_grp.val); + regs.dprsrreg.inp.icr.e_phv8_grp.enable(); + regs.dprsrreg.inp.icr.e_phv16_grp.enable(); + regs.dprsrreg.inp.icr.e_phv32_grp.enable(); + setup_jbay_ownership(phv_use[EGRESS], regs.dprsrreg.inp.icr.e_phv8_grp.val, + regs.dprsrreg.inp.icr.e_phv16_grp.val, + regs.dprsrreg.inp.icr.e_phv32_grp.val); + + for (auto &intrin : intrinsics) intrin.type->setregs(regs, *this, intrin); + + /* resubmit_mode specifies whether this pipe can perform a resubmit operation on + a packet. i.e. tell the IPB to resubmit a packet to the MAU pipeline for a second + time. If the compiler determines that no resubmit is possible, then it can set this + bit, which should lower latency in some circumstances. + 0 = Resubmit is allowed. 1 = Resubmit is not allowed */ + bool resubmit = false; + for (auto &digest : digests) { + if (digest.type->name == "resubmit" || + digest.type->name == "resubmit_preserving_field_list") { + resubmit = true; + break; + } + } + if (resubmit) + regs.dprsrreg.inp.ipp.ingr.resubmit_mode.mode = 0; + else + regs.dprsrreg.inp.ipp.ingr.resubmit_mode.mode = 1; + + for (auto &digest : digests) digest.type->setregs(regs, *this, digest); + + /* Set learning digest mask for JBay */ + for (auto &digest : digests) { + if (digest.type->name == "learning") { + regs.dprsrreg.inp.icr.lrnmask.enable(); + for (auto &set : digest.layout) { + int id = set.first; + int len = regs.dprsrreg.inp.ipp.ingr.learn_tbl[id].len; + if (len == 0) continue; // Allow empty param list + + // Fix for TF2LAB-37s: + // This fixes a hardware limitation where the container following + // the last PHV used cannot be the same non 8 bit container as the last entry. + // E.g. For len = 5, (active entries start at index 47) + // Used - PHV[47] ... PHV[43] = 0; + // Unused - PHV[42] ... PHV[0] = 0; // Defaults to 0 + // This causes issues in hardware as container 0 is used. + // We fix by setting the default as 64 an 8 - bit container. It can be any + // other 8 bit container value. + // The hardware does not cause any issues for 8 bit conatiners. + for (int i = 47 - len; i >= 0; i--) + regs.dprsrreg.inp.ipp.ingr.learn_tbl[id].phvs[i] = 64; + // Fix for TF2LAB-37 end + + // Create a bitvec of all phv masks stacked up next to each + // other in big-endian. 'setregs' above stacks the digest fields + // in a similar manner to setup the phvs per byte on learn_tbl + // regs. To illustrate with an example - tna_digest.p4 (since + // this is not clear based on reg descriptions); + // + // BFA Output: + // + // learning: + // select: { B1(0..2): B0(1) } # L[0..2]b: + // ingress::ig_intr_md_for_dprsr.digest_type 0: + // - B1(0..2) # L[0..2]b: ingress::ig_intr_md_for_dprsr.digest_type + // - MW0 # ingress::hdr.ethernet.dst_addr.16-47 + // - MH1 # ingress::hdr.ethernet.dst_addr.0-15 + // - MH0(0..8) # L[0..8]b: ingress::ig_md.port + // - MW1 # ingress::hdr.ethernet.src_addr.16-47 + // - MH2 # ingress::hdr.ethernet.src_addr.0-15 + // + // PHV packing for digest, + // + // B1(7..0) | MW0 (31..24) | MW0(23..16) | MW0(15..8) | + // MW0(7..0) | MH1 (15..8) | MH1(7..0) | MH0(16..8) | + // MH0(7..0) | MW1 (31..24) | MW1(23..16) | MW1(15..8) | + // MW1(7..0) | MH2 (15..8) | MH2(7..0) | ---------- | + // + // Learn Mask Regs for above digest + // deparser.regs.dprsrreg.inp.icr.lrnmask[0].mask[11] = 4294967047 (0x07ffffff) + // deparser.regs.dprsrreg.inp.icr.lrnmask[0].mask[10] = 4294967295 (0xffffff01) + // deparser.regs.dprsrreg.inp.icr.lrnmask[0].mask[9] = 4278321151 (0xffffffff) + // deparser.regs.dprsrreg.inp.icr.lrnmask[0].mask[8] = 4294967040 (0xffffff00) + + bitvec lrnmask; + int startBit = 0; + int size = 0; + for (auto p : set.second) { + if (size > 0) lrnmask <<= p->reg.size; + auto psliceSize = p.size(); + startBit = p.lobit(); + lrnmask.setrange(startBit, psliceSize); + size += p->reg.size; + } + // Pad to a 32 bit word + auto shift = (size % 32) ? (32 - (size % 32)) : 0; + lrnmask <<= shift; + int num_words = (size + 31) / 32; + int quanta_index = 11; + for (int index = num_words - 1; index >= 0; index--) { + BUG_CHECK(quanta_index >= 0); + unsigned word = lrnmask.getrange(index * 32, 32); + regs.dprsrreg.inp.icr.lrnmask[id].mask[quanta_index--] = word; + } + } + } + } + +#define DISBALE_IF_NOT_SET(ISARRAY, ARRAY, REGS, DISABLE) \ + ISARRAY(for (auto &r : ARRAY)) if (!ISARRAY(r.) REGS.modified()) ISARRAY(r.) REGS.DISABLE = 1; + JBAY_DISABLE_REGBITS(DISBALE_IF_NOT_SET) + + if (options.condense_json) regs.disable_if_reset_value(); + if (error_count == 0 && options.gen_json) + regs.emit_json(*open_output("regs.deparser.cfg.json")); + TopLevel::regs()->reg_pipe.pardereg.dprsrreg.set("regs.deparser", ®s); +} + +#if 0 +namespace { +static struct JbayChecksumReg : public Phv::Register { + JbayChecksumReg(int unit) : Phv::Register("", Phv::Register::CHECKSUM, unit, + unit+CONSTANTS_PHVID_JBAY_HIGH, 16) { + snprintf(name, "csum%d", unit); } + int deparser_id() const override { return uid; } +} jbay_checksum_units[8] = { {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7} }; +} + +template<> Phv::Slice Deparser::RefOrChksum::lookup() const { + if (lo != hi || lo < 0 || lo >= Target::JBay::DEPARSER_CHECKSUM_UNITS) { + error(lineno, "Invalid checksum unit number"); + return Phv::Slice(); } + return Phv::Slice(tofino_checksum_units[lo], 0, 15); +} +#endif + +template <> +unsigned Deparser::FDEntry::Checksum::encode() { + return CONSTANTS_PHVID_JBAY_HIGH + unit; +} + +template <> +unsigned Deparser::FDEntry::Constant::encode() { + return CONSTANTS_PHVID_JBAY_LOW + Deparser::constant_idx(gress, val); +} + +template <> +void Deparser::gen_learn_quanta(Target::JBay::parser_regs ®s, json::vector &learn_quanta) {} + +template <> +void Deparser::process(Target::JBay *) { + // Chip-specific code for process method + // None for JBay +} diff --git a/backends/tofino/bf-asm/jbay/gateway.cpp b/backends/tofino/bf-asm/jbay/gateway.cpp new file mode 100644 index 00000000000..1e163400737 --- /dev/null +++ b/backends/tofino/bf-asm/jbay/gateway.cpp @@ -0,0 +1,99 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "gateway.h" + +#include + +void Target::Tofino::GatewayTable::write_next_table_regs(Target::JBay::mau_regs ®s) { + auto &merge = regs.rams.match.merge; + if (need_next_map_lut) merge.next_table_map_en_gateway |= 1U << logical_id; + int idx = 3; + for (auto &line : table) { + BUG_CHECK(idx >= 0); + if (!line.run_table) { + if (need_next_map_lut) + merge.gateway_next_table_lut[logical_id][idx] = line.next_map_lut; + else + merge.gateway_next_table_lut[logical_id][idx] = line.next.next_table_id(); + } + --idx; + } + if (!miss.run_table) { + if (need_next_map_lut) + merge.gateway_next_table_lut[logical_id][4] = miss.next_map_lut; + else + merge.gateway_next_table_lut[logical_id][4] = miss.next.next_table_id(); + } + if (!match_table && need_next_map_lut) { + // Factor with common code in jbay/match_table.cpp write_next_table_regs + merge.next_table_map_en |= 1U << logical_id; + int i = 0; + for (auto &n : extra_next_lut) { + merge.pred_map_loca[logical_id][i].pred_map_loca_next_table = n.next_table_id(); + merge.pred_map_loca[logical_id][i].pred_map_loca_exec = + n.next_in_stage(stage->stageno) >> 1; + merge.pred_map_glob[logical_id][i].pred_map_glob_exec = + n.next_in_stage(stage->stageno + 1); + merge.pred_map_glob[logical_id][i].pred_map_long_brch |= n.long_branch_tags(); + ++i; + } + // is this needed? The model complains if we leave the unused slots as 0 + while (i < Target::NEXT_TABLE_SUCCESSOR_TABLE_DEPTH()) + merge.pred_map_loca[logical_id][i++].pred_map_loca_next_table = 0x1ff; + } +} + +template <> +void GatewayTable::standalone_write_regs(Target::JBay::mau_regs ®s) { + // FIXME -- factor this with JBay MatchTable::write_regs + auto &merge = regs.rams.match.merge; + if (gress == GHOST) merge.pred_ghost_thread |= 1 << logical_id; + merge.pred_glob_exec_thread[gress] |= 1 << logical_id; + if (always_run || pred.empty()) merge.pred_always_run[gress] |= 1 << logical_id; + + if (long_branch_input >= 0) + setup_muxctl(merge.pred_long_brch_lt_src[logical_id], long_branch_input); + + bool is_branch = (miss.next.next_table() != nullptr); + if (!is_branch && !need_next_map_lut) { + for (auto &line : table) { + if (line.next.next_table() != nullptr) { + is_branch = true; + break; + } + } + } + if (!is_branch) + for (auto &n : hit_next) + if (n.next_table() != nullptr) { + is_branch = true; + break; + } + if (!is_branch) + for (auto &n : extra_next_lut) + if (n.next_table() != nullptr) { + is_branch = true; + break; + } + if (is_branch) merge.pred_is_a_brch |= 1 << logical_id; + + merge.mpr_glob_exec_thread |= merge.logical_table_thread[0].logical_table_thread_egress & + ~merge.logical_table_thread[0].logical_table_thread_ingress & + ~merge.pred_ghost_thread; +} +template void GatewayTable::standalone_write_regs(Target::JBay::mau_regs ®s); diff --git a/backends/tofino/bf-asm/jbay/gateway.h b/backends/tofino/bf-asm/jbay/gateway.h new file mode 100644 index 00000000000..08e1b0e9929 --- /dev/null +++ b/backends/tofino/bf-asm/jbay/gateway.h @@ -0,0 +1,30 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_JBAY_GATEWAY_H_ +#define BF_ASM_JBAY_GATEWAY_H_ + +#include + +#include + +#if HAVE_JBAY +template <> +void GatewayTable::standalone_write_regs(Target::JBay::mau_regs ®s); +#endif /* HAVE_JBAY */ + +#endif /* BF_ASM_JBAY_GATEWAY_H_ */ diff --git a/backends/tofino/bf-asm/jbay/input_xbar.cpp b/backends/tofino/bf-asm/jbay/input_xbar.cpp new file mode 100644 index 00000000000..8a9d9d58adb --- /dev/null +++ b/backends/tofino/bf-asm/jbay/input_xbar.cpp @@ -0,0 +1,70 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "input_xbar.h" + +template <> +void InputXbar::write_galois_matrix(Target::JBay::mau_regs ®s, HashTable id, + const std::map &mat) { + int parity_col = -1; + BUG_CHECK(id.type == HashTable::EXACT, "not an exact hash table %d", id.type); + if (hash_table_parity.count(id) && !options.disable_gfm_parity) { + parity_col = hash_table_parity[id]; + } + auto &hash = regs.dp.xbar_hash.hash; + std::set gfm_rows; + for (auto &col : mat) { + int c = col.first; + // Skip parity column encoding, if parity is set overall parity is + // computed later below + if (c == parity_col) continue; + const HashCol &h = col.second; + for (int word = 0; word < 4; word++) { + unsigned data = h.data.getrange(word * 16, 16); + if (data == 0) continue; + auto &w = hash.galois_field_matrix[id.index * 4 + word][c]; + w.byte0 = data & 0xff; + w.byte1 = (data >> 8) & 0xff; + gfm_rows.insert(id.index * 4 + word); + } + } + // A GFM row can be shared by multiple tables. In most cases the columns are + // non overlapping but if they are overlapping the GFM encodings must be the + // same (e.g. ATCAM tables). The input xbar has checks to determine which + // cases are valid. + // The parity must be computed for all columns within the row and set into + // the parity column. + if (parity_col >= 0) { + for (auto r : gfm_rows) { + int hp_byte0 = 0, hp_byte1 = 0; + for (auto c = 0; c < 52; c++) { + if (c == parity_col) continue; + auto &w = hash.galois_field_matrix[r][c]; + hp_byte0 ^= w.byte0; + hp_byte1 ^= w.byte1; + } + auto &w_hp = hash.galois_field_matrix[r][parity_col]; + w_hp.byte0.rewrite(); + w_hp.byte1.rewrite(); + w_hp.byte0 = hp_byte0; + w_hp.byte1 = hp_byte1; + } + } +} + +template void InputXbar::write_galois_matrix(Target::JBay::mau_regs ®s, HashTable id, + const std::map &mat); diff --git a/backends/tofino/bf-asm/jbay/input_xbar.h b/backends/tofino/bf-asm/jbay/input_xbar.h new file mode 100644 index 00000000000..ebe850219fb --- /dev/null +++ b/backends/tofino/bf-asm/jbay/input_xbar.h @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_JBAY_INPUT_XBAR_H_ +#define BF_ASM_JBAY_INPUT_XBAR_H_ + +#include + +#if HAVE_JBAY +template <> +void InputXbar::write_galois_matrix(Target::JBay::mau_regs ®s, HashTable id, + const std::map &mat); +#endif /* HAVE_JBAY */ + +#endif /* BF_ASM_JBAY_INPUT_XBAR_H_ */ diff --git a/backends/tofino/bf-asm/jbay/instruction.cpp b/backends/tofino/bf-asm/jbay/instruction.cpp new file mode 100644 index 00000000000..1eee6043d2f --- /dev/null +++ b/backends/tofino/bf-asm/jbay/instruction.cpp @@ -0,0 +1,200 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* JBay overloads for instructions #included in instruction.cpp + * WARNING -- this is included in an anonymous namespace, as VLIWInstruction is + * in that anonymous namespace */ + +template +void VLIWInstruction::write_regs_2(REGS ®s, Table *tbl, Table::Actions::Action *act) { + if (act != tbl->stage->imem_addr_use[imem_thread(tbl->gress)][act->addr]) { + LOG3("skipping " << tbl->name() << '.' << act->name << " as its imem is used by " + << tbl->stage->imem_addr_use[imem_thread(tbl->gress)][act->addr]->name); + return; + } + LOG2(this); + auto &imem = regs.dp.imem; + int iaddr = act->addr / ACTION_IMEM_COLORS; + int color = act->addr % ACTION_IMEM_COLORS; + unsigned bits = encode(); + BUG_CHECK(slot >= 0); + unsigned off = slot % Phv::mau_groupsize(); + unsigned side = 0, group = 0; + switch (slot / Phv::mau_groupsize()) { + case 0: + side = 0; + group = 0; + break; + case 1: + side = 0; + group = 1; + break; + case 2: + side = 1; + group = 0; + break; + case 3: + side = 1; + group = 1; + break; + case 4: + side = 0; + group = 0; + break; + case 5: + side = 0; + group = 1; + break; + case 6: + side = 1; + group = 0; + break; + case 7: + side = 1; + group = 1; + break; + case 8: + side = 0; + group = 0; + break; + case 9: + side = 0; + group = 1; + break; + case 10: + side = 0; + group = 2; + break; + case 11: + side = 1; + group = 0; + break; + case 12: + side = 1; + group = 1; + break; + case 13: + side = 1; + group = 2; + break; + default: + BUG(); + } + + switch (Phv::reg(slot)->type) { + case Phv::Register::NORMAL: + switch (Phv::reg(slot)->size) { + case 8: + BUG_CHECK(group == 0 || group == 1); + imem.imem_subword8[side][group][off][iaddr].imem_subword8_instr = bits; + imem.imem_subword8[side][group][off][iaddr].imem_subword8_color = color; + imem.imem_subword8[side][group][off][iaddr].imem_subword8_parity = + parity(bits) ^ color; + break; + case 16: + imem.imem_subword16[side][group][off][iaddr].imem_subword16_instr = bits; + imem.imem_subword16[side][group][off][iaddr].imem_subword16_color = color; + imem.imem_subword16[side][group][off][iaddr].imem_subword16_parity = + parity(bits) ^ color; + break; + case 32: + BUG_CHECK(group == 0 || group == 1); + imem.imem_subword32[side][group][off][iaddr].imem_subword32_instr = bits; + imem.imem_subword32[side][group][off][iaddr].imem_subword32_color = color; + imem.imem_subword32[side][group][off][iaddr].imem_subword32_parity = + parity(bits) ^ color; + break; + default: + BUG(); + } + break; + case Phv::Register::MOCHA: + switch (Phv::reg(slot)->size) { + case 8: + BUG_CHECK(group == 0 || group == 1); + imem.imem_mocha_subword8[side][group][off - 12][iaddr] + .imem_mocha_subword_instr = bits; + imem.imem_mocha_subword8[side][group][off - 12][iaddr] + .imem_mocha_subword_color = color; + imem.imem_mocha_subword8[side][group][off - 12][iaddr] + .imem_mocha_subword_parity = parity(bits) ^ color; + break; + case 16: + imem.imem_mocha_subword16[side][group][off - 12][iaddr] + .imem_mocha_subword_instr = bits; + imem.imem_mocha_subword16[side][group][off - 12][iaddr] + .imem_mocha_subword_color = color; + imem.imem_mocha_subword16[side][group][off - 12][iaddr] + .imem_mocha_subword_parity = parity(bits) ^ color; + break; + case 32: + BUG_CHECK(group == 0 || group == 1); + imem.imem_mocha_subword32[side][group][off - 12][iaddr] + .imem_mocha_subword_instr = bits; + imem.imem_mocha_subword32[side][group][off - 12][iaddr] + .imem_mocha_subword_color = color; + imem.imem_mocha_subword32[side][group][off - 12][iaddr] + .imem_mocha_subword_parity = parity(bits) ^ color; + break; + default: + BUG(); + } + break; + case Phv::Register::DARK: + switch (Phv::reg(slot)->size) { + case 8: + BUG_CHECK(group == 0 || group == 1); + imem.imem_dark_subword8[side][group][off - 16][iaddr].imem_dark_subword_instr = + bits; + imem.imem_dark_subword8[side][group][off - 16][iaddr].imem_dark_subword_color = + color; + imem.imem_dark_subword8[side][group][off - 16][iaddr].imem_dark_subword_parity = + parity(bits) ^ color; + break; + case 16: + imem.imem_dark_subword16[side][group][off - 16][iaddr].imem_dark_subword_instr = + bits; + imem.imem_dark_subword16[side][group][off - 16][iaddr].imem_dark_subword_color = + color; + imem.imem_dark_subword16[side][group][off - 16][iaddr] + .imem_dark_subword_parity = parity(bits) ^ color; + break; + case 32: + BUG_CHECK(group == 0 || group == 1); + imem.imem_dark_subword32[side][group][off - 16][iaddr].imem_dark_subword_instr = + bits; + imem.imem_dark_subword32[side][group][off - 16][iaddr].imem_dark_subword_color = + color; + imem.imem_dark_subword32[side][group][off - 16][iaddr] + .imem_dark_subword_parity = parity(bits) ^ color; + break; + default: + BUG(); + } + break; + default: + BUG(); + } + + auto &power_ctl = regs.dp.actionmux_din_power_ctl; + phvRead([&](const Phv::Slice &sl) { set_power_ctl_reg(power_ctl, sl.reg.mau_id()); }); +} + +void VLIWInstruction::write_regs(Target::JBay::mau_regs ®s, Table *tbl, + Table::Actions::Action *act) { + write_regs_2(regs, tbl, act); +} diff --git a/backends/tofino/bf-asm/jbay/match_table.cpp b/backends/tofino/bf-asm/jbay/match_table.cpp new file mode 100644 index 00000000000..cd177a86af8 --- /dev/null +++ b/backends/tofino/bf-asm/jbay/match_table.cpp @@ -0,0 +1,130 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* mau table template specializations for jbay -- #included directly in match_tables.cpp */ + +/** Write next table setup, which is JBay-specific. `tbl` here is the ternary indirect + * table if there is one, or the match table otherwise */ +template <> +void MatchTable::write_next_table_regs(Target::JBay::mau_regs ®s, Table *tbl) { + auto &merge = regs.rams.match.merge; + if (!hit_next.empty() || !extra_next_lut.empty()) { + merge.next_table_map_en |= (1U << logical_id); + int i = 0; + for (auto &n : hit_next) { + merge.pred_map_loca[logical_id][i].pred_map_loca_next_table = n.next_table_id(); + merge.pred_map_loca[logical_id][i].pred_map_loca_exec = + n.next_in_stage(stage->stageno) >> 1; + merge.pred_map_glob[logical_id][i].pred_map_glob_exec = + n.next_in_stage(stage->stageno + 1); + merge.pred_map_glob[logical_id][i].pred_map_long_brch |= n.long_branch_tags(); + ++i; + } + for (auto &n : extra_next_lut) { + merge.pred_map_loca[logical_id][i].pred_map_loca_next_table = n.next_table_id(); + merge.pred_map_loca[logical_id][i].pred_map_loca_exec = + n.next_in_stage(stage->stageno) >> 1; + merge.pred_map_glob[logical_id][i].pred_map_glob_exec = + n.next_in_stage(stage->stageno + 1); + merge.pred_map_glob[logical_id][i].pred_map_long_brch |= n.long_branch_tags(); + ++i; + } + // is this needed? The model complains if we leave the unused slots as 0 + while (i < Target::NEXT_TABLE_SUCCESSOR_TABLE_DEPTH()) + merge.pred_map_loca[logical_id][i++].pred_map_loca_next_table = 0x1ff; + } + + merge.next_table_format_data[logical_id].match_next_table_adr_mask = next_table_adr_mask; + merge.next_table_format_data[logical_id].match_next_table_adr_miss_value = + miss_next.next_table_id(); + merge.pred_miss_exec[logical_id].pred_miss_loca_exec = + miss_next.next_in_stage(stage->stageno) >> 1; + merge.pred_miss_exec[logical_id].pred_miss_glob_exec = + miss_next.next_in_stage(stage->stageno + 1); + merge.pred_miss_long_brch[logical_id] = miss_next.long_branch_tags(); +} + +template <> +void MatchTable::write_regs(Target::JBay::mau_regs ®s, int type, Table *result) { + write_common_regs(regs, type, result); + // FIXME -- factor this with JBay GatewayTable::standalone_write_regs + auto &merge = regs.rams.match.merge; + if (gress == GHOST) merge.pred_ghost_thread |= 1 << logical_id; + merge.pred_glob_exec_thread[gress] |= 1 << logical_id; + if (always_run || pred.empty()) merge.pred_always_run[gress] |= 1 << logical_id; + + if (long_branch_input >= 0) + setup_muxctl(merge.pred_long_brch_lt_src[logical_id], long_branch_input); + + if (result == nullptr) result = this; + + bool is_branch = (miss_next.next_table() != nullptr); + if (!is_branch && gateway && gateway->is_branch()) is_branch = true; + if (!is_branch) + for (auto &n : hit_next) + if (n.next_table() != nullptr) { + is_branch = true; + break; + } + if (!is_branch) + for (auto &n : extra_next_lut) + if (n.next_table() != nullptr) { + is_branch = true; + break; + } + + if (!is_branch && result->get_format_field_size("next") > 3) is_branch = true; + + // Check if any table actions have a next table miss set up + // if yes, the pred_is_a_brch register must be set on the table to override the next table + // configuration with this value. + // + // E.g. + // switch (mc_filter.apply().action_run) { + // NoAction : { // Has @defaultonly + // ttl_thr_check.apply(); + // } + // } + // + // Generated bfa + // ... + // hit: [ END ] + // miss: END + // ... + // NoAction(-1, 1): + // - hit_allowed: { allowed: false, reason: user_indicated_default_only } + // - default_only_action: { allowed: true, is_constant: true } + // - handle: 0x20000015 + // - next_table_miss: ttl_thr_check_0 + // + // If merge.pred_is_a_brch is not set in this usecase, the default miss configuration of 'END' + // or 'End of Pipe' is executed and next table ttl_thr_check_0 will not be executed. + if (!is_branch) { + for (auto &act : *result->actions) { + if (act.next_table_miss_ref.next_table()) { + is_branch = true; + break; + } + } + } + + if (is_branch) merge.pred_is_a_brch |= 1 << logical_id; + + merge.mpr_glob_exec_thread |= merge.logical_table_thread[0].logical_table_thread_egress & + ~merge.logical_table_thread[0].logical_table_thread_ingress & + ~merge.pred_ghost_thread; +} diff --git a/backends/tofino/bf-asm/jbay/meter.h b/backends/tofino/bf-asm/jbay/meter.h new file mode 100644 index 00000000000..7071025ff2f --- /dev/null +++ b/backends/tofino/bf-asm/jbay/meter.h @@ -0,0 +1,140 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_JBAY_METER_H_ +#define BF_ASM_JBAY_METER_H_ + +template +void MeterTable::setup_teop_regs_2(REGS ®s, int meter_group_index) { + BUG_CHECK(teop >= 0 && teop < 4); + BUG_CHECK(gress == EGRESS); + + auto &adrdist = regs.rams.match.adrdist; + if (!teop_initialized) { + // assume this stage driving teop + auto delay = stage->pipelength(gress) - stage->pred_cycle(gress) - 7; + adrdist.teop_bus_ctl[teop].teop_bus_ctl_delay = delay; + adrdist.teop_bus_ctl[teop].teop_bus_ctl_delay_en = 1; + adrdist.teop_bus_ctl[teop].teop_bus_ctl_meter_en = 1; + + adrdist.meter_to_teop_adr_oxbar_ctl[teop].enabled_2bit_muxctl_select = meter_group_index; + adrdist.meter_to_teop_adr_oxbar_ctl[teop].enabled_2bit_muxctl_enable = 1; + teop_initialized = true; + } + + adrdist.teop_to_meter_adr_oxbar_ctl[meter_group_index].enabled_2bit_muxctl_select = teop; + adrdist.teop_to_meter_adr_oxbar_ctl[meter_group_index].enabled_2bit_muxctl_enable = 1; + + // count all tEOP events + adrdist.dp_teop_meter_ctl[meter_group_index].dp_teop_meter_ctl_err = 0; + // Refer to JBAY uArch Section 6.4.4.10.8 + // + // The user of the incoming tEOP address needs to consider the original + // driver. For instance, a meter address driver will be aliged with the LSB + // of the 18b incoming address, whereas a single-entry stats driver will be + // already padded with 2 zeros. + // + // For example, dp_teop_meter_ctl.dp_teop_meter_ctl_rx_shift must be + // programmed to 2 to compensate for the single-entry stats address driver: + // + // Meter (23b) = {4b CMD+Color, ((dp_teop{6b VPN, 10b addr, 2b subword + // zeros} >> 2) + 7b zero pad)} + // + // As per above, the dp_teop_meter_ctl_rx_shift is set based on the original + // driver. For a meter address driving there is no need for any shift, + // however if a stats address is driving then it needs to be shifted by 2. + // Compiler currently does not use this mechanism where a stats address is + // driving the meter, this is scope for optimization in future. + adrdist.dp_teop_meter_ctl[meter_group_index].dp_teop_meter_ctl_rx_shift = 0; + adrdist.dp_teop_meter_ctl[meter_group_index].dp_teop_meter_ctl_rx_en = 1; + + auto &meter = regs.rams.map_alu.meter_group[meter_group_index].meter; + meter.meter_ctl_teop_en = 1; +} + +template +void MeterTable::write_alu_vpn_range_2(REGS ®s) { + auto &adrdist = regs.rams.match.adrdist; + int minvpn, sparevpn; + + // Used to validate the BFA VPN configuration + std::set vpn_processed; + bitvec vpn_range; + + // Get Spare VPN + layout_vpn_bounds(minvpn, sparevpn, false); + + for (int home_row : home_rows) { + bool block_start = false; + bool block_end = false; + int min = 1000000; + int max = -1; + for (Layout &logical_row : layout) { + // Block Start with the home row and End with the Spare VPN + if (logical_row.row == home_row) block_start = true; + + if (block_start) { + for (auto v : logical_row.vpns) { + if (v == sparevpn) { + block_end = true; + break; + } + if (vpn_processed.count(v)) + error(home_lineno, "Multiple instance of the VPN %d detected", v); + else + vpn_processed.insert(v); + + if (v < min) min = v; + if (v > max) max = v; + } + } + if (block_end) { + BUG_CHECK(min != 1000000 && max != -1); + + bitvec block_range(min, max - min + 1); + if (vpn_range.intersects(block_range)) + error(home_lineno, "Overlapping of VPN range detected"); + else + vpn_range |= block_range; + + adrdist.mau_meter_alu_vpn_range[home_row / 4].meter_vpn_base = min; + adrdist.mau_meter_alu_vpn_range[home_row / 4].meter_vpn_limit = max; + adrdist.mau_meter_alu_vpn_range[home_row / 4].meter_vpn_range_check_enable = 1; + for (MatchTable *m : match_tables) + adrdist.meter_alu_adr_range_check_icxbar_map[home_row / 4] |= 1U + << m->logical_id; + break; + } + } + BUG_CHECK(block_start && block_end); + } + + if (vpn_range != bitvec(minvpn, sparevpn - minvpn)) + error(home_lineno, "VPN range not entirely covered"); +} + +template <> +void MeterTable::setup_teop_regs(Target::JBay::mau_regs ®s, int meter_group_index) { + setup_teop_regs_2(regs, meter_group_index); +} + +template <> +void MeterTable::write_alu_vpn_range(Target::JBay::mau_regs ®s) { + write_alu_vpn_range_2(regs); +} + +#endif /* BF_ASM_JBAY_METER_H_ */ diff --git a/backends/tofino/bf-asm/jbay/parser.cpp b/backends/tofino/bf-asm/jbay/parser.cpp new file mode 100644 index 00000000000..4a6a07e83ea --- /dev/null +++ b/backends/tofino/bf-asm/jbay/parser.cpp @@ -0,0 +1,584 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "parser-tofino-jbay.h" +#include "stage.h" +#include "top_level.h" + +template <> +void Parser::Checksum::write_config(Target::JBay::parser_regs ®s, Parser *parser) { + if (unit == 0) + write_row_config(regs.memory[gress].po_csum_ctrl_0_row[addr]); + else if (unit == 1) + write_row_config(regs.memory[gress].po_csum_ctrl_1_row[addr]); + else if (unit == 2) + write_row_config(regs.memory[gress].po_csum_ctrl_2_row[addr]); + else if (unit == 3) + write_row_config(regs.memory[gress].po_csum_ctrl_3_row[addr]); + else if (unit == 4) + write_row_config(regs.memory[gress].po_csum_ctrl_4_row[addr]); + else + error(lineno, "invalid unit for parser checksum"); +} + +template <> +void Parser::Checksum::write_output_config(Target::JBay::parser_regs ®s, Parser *pa, + State::Match * /*ma*/, void *_row, + unsigned &used) const { + if (type != 0 || !dest) return; + + Target::JBay::parser_regs::_memory::_po_action_row *row = + (Target::JBay::parser_regs::_memory::_po_action_row *)_row; + + // checksum verification outputs "steal" extractors, see parser uArch (6.3.6) + + for (int i = 0; i < 20; ++i) { + if (used & (1 << i)) continue; + used |= 1 << i; + row->phv_dst[i] = dest->reg.parser_id(); + row->extract_type[i] = 3; + return; + } + error(lineno, "Ran out of phv output extractor slots"); +} + +template <> +void Parser::CounterInit::write_config(Target::JBay::parser_regs ®s, gress_t gress, int idx) { + auto &ctr_init_ram = regs.memory[gress].ml_ctr_init_ram[idx]; + ctr_init_ram.add = add; + ctr_init_ram.mask_8 = mask; + ctr_init_ram.rotate = rot; + ctr_init_ram.max = max; + ctr_init_ram.src = src; +} + +template <> +void Parser::State::Match::write_lookup_config(Target::JBay::parser_regs ®s, State *state, + int r) const { + auto &row = regs.memory[state->gress].ml_tcam_row[r]; + match_t lookup = {0, 0}; + unsigned dont_care = 0; + for (int i = 0; i < 4; i++) { + lookup.word0 <<= 8; + lookup.word1 <<= 8; + dont_care <<= 8; + if (state->key.data[i].bit >= 0) { + lookup.word0 |= ((match.word0 >> state->key.data[i].bit) & 0xff); + lookup.word1 |= ((match.word1 >> state->key.data[i].bit) & 0xff); + } else { + dont_care |= 0xff; + } + } + lookup.word0 |= dont_care; + lookup.word1 |= dont_care; + for (int i = 3; i >= 0; i--) { + row.w0_lookup_8[i] = lookup.word0 & 0xff; + row.w1_lookup_8[i] = lookup.word1 & 0xff; + lookup.word0 >>= 8; + lookup.word1 >>= 8; + } + row.w0_curr_state = state->stateno.word0; + row.w1_curr_state = state->stateno.word1; + if (state->key.ctr_zero >= 0) { + row.w0_ctr_zero = (match.word0 >> state->key.ctr_zero) & 1; + row.w1_ctr_zero = (match.word1 >> state->key.ctr_zero) & 1; + } else { + row.w0_ctr_zero = row.w1_ctr_zero = 1; + } + if (state->key.ctr_neg >= 0) { + row.w0_ctr_neg = (match.word0 >> state->key.ctr_neg) & 1; + row.w1_ctr_neg = (match.word1 >> state->key.ctr_neg) & 1; + } else { + row.w0_ctr_neg = row.w1_ctr_neg = 1; + } + row.w0_ver_0 = row.w1_ver_0 = 1; + row.w0_ver_1 = row.w1_ver_1 = 1; +} + +/* FIXME -- combine these next two methods into a single method on MatchKey */ +/* FIXME -- factor Tofino/JBay variation better (most is common) */ +template <> +int Parser::State::write_lookup_config(Target::JBay::parser_regs ®s, Parser *pa, State *state, + int row, const std::vector &prev) { + LOG2("-- checking match from state " << name << " (" << stateno << ')'); + auto &ea_row = regs.memory[gress].ml_ea_row[row]; + int max_off = -1; + for (int i = 0; i < 4; i++) { + if (key.data[i].bit < 0) continue; + bool set = true; + for (State *p : prev) { + if (p->key.data[i].bit >= 0) { + set = false; + if (p->key.data[i].byte != key.data[i].byte) + error(p->lineno, + "Incompatible match fields between states " + "%s and %s, triggered from state %s", + name.c_str(), p->name.c_str(), state->name.c_str()); + } + } + if (set && key.data[i].byte != MatchKey::USE_SAVED) { + int off = key.data[i].byte + ea_row.shift_amt; + // Valid offset ranges: + // 0..31 : Input packet + // 60..63 : Scratch registers + if ((off < 0) || ((off > 31) && (off < 60)) || (off > 63)) { + error(key.lineno, + "Match offset of %d in state %s out of range " + "for previous state %s", + key.data[i].byte, name.c_str(), state->name.c_str()); + } + ea_row.lookup_offset_8[i] = off; + ea_row.ld_lookup_8[i] = 1; + max_off = std::max(max_off, off); + } + } + return max_off; +} + +template <> +int Parser::State::Match::write_load_config(Target::JBay::parser_regs ®s, Parser *pa, + State *state, int row) const { + auto &ea_row = regs.memory[state->gress].ml_ea_row[row]; + int max_off = -1; + for (int i = 0; i < 4; i++) { + if (load.data[i].bit < 0) continue; + if (load.data[i].byte != MatchKey::USE_SAVED) { + int off = load.data[i].byte; + // Valid offset ranges: + // 0..31 : Input packet + // 60..63 : Scratch registers + if ((off < 0) || ((off > 31) && (off < 60)) || (off > 63)) { + error(load.lineno, "Load offset of %d in state %s out of range", load.data[i].byte, + state->name.c_str()); + } + ea_row.lookup_offset_8[i] = off; + ea_row.ld_lookup_8[i] = 1; + max_off = std::max(max_off, off); + } + ea_row.sv_lookup_8[i] = (load.save >> i) & 1; + } + + return max_off; +} + +static void write_output_slot(int lineno, Target::JBay::parser_regs::_memory::_po_action_row *row, + unsigned &used, int src, int dest, int bytemask, bool offset) { + BUG_CHECK(bytemask > 0 && bytemask < 4); + for (int i = 0; i < 20; ++i) { + if (used & (1 << i)) continue; + row->phv_dst[i] = dest; + row->phv_src[i] = src; + if (offset) row->phv_offset_add_dst[i] = 1; + row->extract_type[i] = bytemask; + used |= 1 << i; + return; + } + error(lineno, "Ran out of phv output slots"); +} + +template <> +void Parser::State::Match::write_row_config(Target::JBay::parser_regs ®s, Parser *pa, + State *state, int row, Match *def, + json::map &ctxt_json) { + write_common_row_config(regs, pa, state, row, def, ctxt_json); + auto &action_row = regs.memory[state->gress].po_action_row[row]; + + if (disable_partial_hdr_err > 0) action_row.disable_partial_hdr_err = 1; +} + +template <> +int Parser::State::Match::Save::write_output_config(Target::JBay::parser_regs ®s, void *_row, + unsigned &used, int, int) const { + Target::JBay::parser_regs::_memory::_po_action_row *row = + (Target::JBay::parser_regs::_memory::_po_action_row *)_row; + int dest = where->reg.parser_id(); + int mask = (1 << (1 + where->hi / 8U)) - (1 << (where->lo / 8U)); + int lo = this->lo; + // 8b containers are paired in 16b chunks in the parser + // If we're extracting to the upper half of a chunk (the odd 8b register) then + // adjust the extract type to be to the upper half + if (where->reg.size == 8 && mask == 1) { + if (where->reg.index & 1) { + mask <<= 1; + } + } + if (flags & ROTATE) error(where.lineno, "no rotate support in Tofino2"); + + // All containers are 16b in the parser. 32b container extracts are implemented as + // a pair of 16b extracts. + int bytemask = (mask >> 2) & 3; + if (bytemask) { + write_output_slot(where.lineno, row, used, lo, dest + 1, bytemask, flags & OFFSET); + lo += bitcount(mask & 0xc); + } + + bytemask = mask & 3; + if (bytemask) write_output_slot(where.lineno, row, used, lo, dest, bytemask, flags & OFFSET); + return hi; +} + +#define SAVE_ONLY_USED_SLOTS 0xffc00 +static void write_output_const_slot(int lineno, + Target::JBay::parser_regs::_memory::_po_action_row *row, + unsigned &used, unsigned src, int dest, int bytemask, + int flags) { + // use bits 24..27 of 'used' to track the two constant slots + BUG_CHECK(bytemask > 0 && bytemask < 4); + BUG_CHECK((src & ~((0xffff00ff >> (8 * (bytemask - 1))) & 0xffff)) == 0); + // FIXME -- should be able to treat this as 4x8-bit rather than 2x16-bit slots, as long + // as the ROTATE flag is consistent for each half. + int cslot = -1; + // see if const already allocated and reuse + for (cslot = 0; cslot < 2; cslot++) + if (row->val_const[cslot] == src && (used & (bytemask << (2 * cslot + 24)))) break; + if (cslot >= 2) { + for (cslot = 0; cslot < 2; cslot++) + if (0 == (used & (bytemask << (2 * cslot + 24)))) break; + } + if (cslot >= 2) { + error(lineno, "Ran out of constant output slots"); + return; + } + row->val_const[cslot] |= src; + if (flags & 2 /*ROTATE*/) row->val_const_rot[cslot] = 1; + used |= bytemask << (2 * cslot + 24); + unsigned tmpused = used | SAVE_ONLY_USED_SLOTS; + write_output_slot(lineno, row, tmpused, 62 - 2 * cslot + (bytemask == 1), dest, bytemask, + flags & 1 /*OFFSET*/); + used |= tmpused & ~SAVE_ONLY_USED_SLOTS; +} + +template <> +void Parser::State::Match::Set::write_output_config(Target::JBay::parser_regs ®s, void *_row, + unsigned &used, int, int) const { + Target::JBay::parser_regs::_memory::_po_action_row *row = + (Target::JBay::parser_regs::_memory::_po_action_row *)_row; + int dest = where->reg.parser_id(); + int mask = (1 << (1 + where->hi / 8U)) - (1 << (where->lo / 8U)); + unsigned what = this->what << where->lo; + // Trim the bytes to be written, unless the value is being rotated + if (what && !(flags & ROTATE)) { + for (unsigned i = 0; i < 4; ++i) + if (((what >> (8 * i)) & 0xff) == 0) mask &= ~(1 << i); + } + if (where->reg.size == 8) { + BUG_CHECK((mask & ~1) == 0); + if (where->reg.index & 1) { + mask <<= 1; + what <<= 8; + } + } + if (mask & 3) + write_output_const_slot(where.lineno, row, used, what & 0xffff, dest, mask & 3, flags); + if (mask & 0xc) { + write_output_const_slot(where.lineno, row, used, (what >> 16) & 0xffff, dest + 1, + (mask >> 2) & 3, flags); + if ((mask & 3) && (flags & ROTATE)) row->val_const_32b_bond = 1; + } +} + +/* Tofino2 has a simple uniform array of 20 extractors, so doesn't really need an output + * map to track them. Constants 'sets' are handled by having 4 bytes of data that is set + * per row and extrated from the input buffer like a 'save', except only the first 10 + * extractors can access them. So `output_map` ends up being just a pointer to the + * register object for the row, and `used` is a 24-bit bitmap, tracking the 20 extractors + * and the 4 constant bytes. + */ +template <> +void *Parser::setup_phv_output_map(Target::JBay::parser_regs ®s, gress_t gress, int row) { + return ®s.memory[gress].po_action_row[row]; +} +template <> +void Parser::mark_unused_output_map(Target::JBay::parser_regs &, void *, unsigned) { + // unneeded on jbay +} + +template <> +void Parser::State::Match::HdrLenIncStop::write_config( + JBay::memories_parser_::_po_action_row &po_row) const { + po_row.hdr_len_inc_stop = 1; + po_row.hdr_len_inc_final_amt = final_amt; +} + +template <> +void Parser::State::Match::Clot::write_config(JBay::memories_parser_::_po_action_row &po_row, + int idx, bool offset_add) const { + po_row.clot_tag[idx] = tag; + po_row.clot_offset[idx] = start; + if (load_length) { + po_row.clot_type[idx] = 1; + po_row.clot_len_src[idx] = length; + po_row.clot_en_len_shr[idx] = length_shift; + // po_row.clot_len_mask[idx] = length_mask; -- FIXME -- CSR reg commented out + } else { + po_row.clot_len_src[idx] = length - 1; + po_row.clot_type[idx] = 0; + po_row.clot_en_len_shr[idx] = 1; + } + po_row.clot_has_csum[idx] = csum_unit > 0; + po_row.clot_tag_offset_add[idx] = offset_add; +} + +template <> +void Parser::State::Match::write_counter_config( + Target::JBay::parser_regs::_memory::_ml_ea_row &ea_row) const { + if (ctr_load) { + switch (ctr_ld_src) { + case 0: + ea_row.ctr_op = 2; + break; + case 1: + ea_row.ctr_op = 3; + break; + default: + error(lineno, "Unsupported parser counter load instruction (JBay)"); + } + } else if (ctr_stack_pop) { + ea_row.ctr_op = 1; + } else { // add + ea_row.ctr_op = 0; + } + + ea_row.ctr_amt_idx = ctr_instr ? ctr_instr->addr : ctr_imm_amt; + ea_row.ctr_stack_push = ctr_stack_push; + ea_row.ctr_stack_upd_w_top = ctr_stack_upd_w_top; +} + +// Workaround for JBAY-2717: parser counter adds RAM index or immediate value +// to the pushed value when doing push + update_w_top. To cancel this offset, +// we subtract the amount on pop. +void jbay2717_workaround(Parser *parser, Target::JBay::parser_regs ®s) { + for (auto &kv : parser->match_to_row) { + if (kv.first->ctr_stack_pop) { + for (auto p : kv.first->get_all_preds()) { + if (p->ctr_stack_push && p->ctr_stack_upd_w_top) { + auto &ea_row = regs.memory[parser->gress].ml_ea_row[kv.second]; + auto adjust = p->ctr_instr ? p->ctr_instr->addr : p->ctr_imm_amt; + ea_row.ctr_amt_idx = ea_row.ctr_amt_idx.value - adjust; + break; + } + } + } + } +} + +template <> +void Parser::write_config(Target::JBay::parser_regs ®s, json::map &ctxt_json, + bool single_parser) { + if (single_parser) { + for (auto st : all) + st->write_config(regs, this, ctxt_json[st->gress == EGRESS ? "egress" : "ingress"]); + } else { + ctxt_json["states"] = json::vector(); + for (auto st : all) st->write_config(regs, this, ctxt_json["states"]); + } + if (error_count > 0) return; + + jbay2717_workaround(this, regs); + + int i = 0; + for (auto ctr : counter_init) { + if (ctr) ctr->write_config(regs, gress, i); + ++i; + } + + for (i = 0; i < checksum_use.size(); i++) { + for (auto csum : checksum_use[i]) { + if (csum) { + csum->write_config(regs, this); + if (csum->dest) phv_use[csum->gress].setbit(csum->dest->reg.uid); + } + } + } + + if (gress == EGRESS) { + regs.egress.epbreg.chan0_group.chnl_ctrl.meta_opt = meta_opt; + regs.egress.epbreg.chan1_group.chnl_ctrl.meta_opt = meta_opt; + regs.egress.epbreg.chan2_group.chnl_ctrl.meta_opt = meta_opt; + regs.egress.epbreg.chan3_group.chnl_ctrl.meta_opt = meta_opt; + regs.egress.epbreg.chan4_group.chnl_ctrl.meta_opt = meta_opt; + regs.egress.epbreg.chan5_group.chnl_ctrl.meta_opt = meta_opt; + regs.egress.epbreg.chan6_group.chnl_ctrl.meta_opt = meta_opt; + regs.egress.epbreg.chan7_group.chnl_ctrl.meta_opt = meta_opt; + } + + // All phvs used globaly by egress and not by ingress parser should be owned by + // egress parser so they get zeroed properly in the parser + phv_use[EGRESS] |= remove_nonparser(Phv::use(EGRESS)) - expand_parser_groups(phv_use[INGRESS]); + + setup_jbay_ownership(phv_use, regs.merge.ul.phv_owner_127_0.owner, + regs.merge.ur.phv_owner_255_128.owner, regs.main[INGRESS].phv_owner.owner, + regs.main[EGRESS].phv_owner.owner); + + setup_jbay_clear_on_write(phv_allow_clear_on_write, regs.merge.ul.phv_clr_on_wr_127_0.clr, + regs.merge.ur.phv_clr_on_wr_255_128.clr, + regs.main[INGRESS].phv_clr_on_wr.clr, + regs.main[EGRESS].phv_clr_on_wr.clr); + + setup_jbay_no_multi_write(phv_allow_bitwise_or, phv_allow_clear_on_write, + regs.main[INGRESS].no_multi_wr.nmw, + regs.main[EGRESS].no_multi_wr.nmw); + + regs.main[gress].hdr_len_adj.amt = hdr_len_adj; + + if (parser_error.lineno >= 0) { + for (auto i : {0, 1}) { + regs.main[gress].err_phv_cfg[i].en = 1; + regs.main[gress].err_phv_cfg[i].dst = parser_error->reg.parser_id(); + regs.main[gress].err_phv_cfg[i].no_tcam_match_err_en = 1; + regs.main[gress].err_phv_cfg[i].partial_hdr_err_en = 1; + regs.main[gress].err_phv_cfg[i].ctr_range_err_en = 1; + regs.main[gress].err_phv_cfg[i].timeout_iter_err_en = 1; + regs.main[gress].err_phv_cfg[i].timeout_cycle_err_en = 1; + regs.main[gress].err_phv_cfg[i].src_ext_err_en = 1; + regs.main[gress].err_phv_cfg[i].phv_owner_err_en = 1; + regs.main[gress].err_phv_cfg[i].multi_wr_err_en = 1; + regs.main[gress].err_phv_cfg[i].aram_mbe_en = 1; + regs.main[gress].err_phv_cfg[i].fcs_err_en = 1; + regs.main[gress].err_phv_cfg[i].csum_mbe_en = 1; + } + } else { + // en has a reset value of 1 and that is why we have to explicitly disable it + // otherwise dst will assume default value of 0 + for (auto i : {0, 1}) regs.main[gress].err_phv_cfg[i].en = 0; + } + + int i_start = Stage::first_table(INGRESS) & 0x1ff; + for (auto ® : regs.merge.ll1.i_start_table) reg.table = i_start; + + int e_start = Stage::first_table(EGRESS) & 0x1ff; + for (auto ® : regs.merge.lr1.e_start_table) reg.table = e_start; + + regs.merge.lr1.g_start_table.table = Stage::first_table(GHOST) & 0x1ff; + if (ghost_parser.size()) { + // tm_status_phv sets the location for ghost intrinsic metadata in the + // parser + // The parser carves up the 4k of PHV it sees into 256 x 16b containers. + // (32b MAU containers map to a pair of parser 16b containers, and 2 x + // 8b MAU containers map to a single parser 16b container.) PHV + // specified here will take the two containers at address + // { PHV & 0xfe, PHV & 0xfe + 1 }. + // Hence, ghost intrinsic metadata is assumed to be allocated in a + // contiguous 32b location. + regs.merge.lr1.tm_status_phv.en = 1; + regs.merge.lr1.tm_status_phv.phv = ghost_parser[0]->reg.parser_id(); + if (ghost_pipe_mask != 0xf) // if not default set given value + regs.merge.lr1.tm_status_phv.pipe_mask = ghost_pipe_mask; + } + + if (gress == INGRESS) { + for (auto &ref : regs.ingress.prsr) + ref.set("regs.parser.main.ingress", ®s.main[INGRESS]); + } + if (gress == EGRESS) { + for (auto &ref : regs.egress.prsr) ref.set("regs.parser.main.egress", ®s.main[EGRESS]); + } + if (error_count == 0) { + if (options.condense_json) { + // FIXME -- removing the uninitialized memory causes problems? + // FIXME -- walle gets the addresses wrong. Might also require explicit + // FIXME -- zeroing in the driver on real hardware + // regs.memory[INGRESS].disable_if_reset_value(); + // regs.memory[EGRESS].disable_if_reset_value(); + // regs.ingress.disable_if_reset_value(); + // regs.egress.disable_if_reset_value(); + regs.main[INGRESS].disable_if_reset_value(); + regs.main[EGRESS].disable_if_reset_value(); + regs.merge.disable_if_reset_value(); + } + if (options.gen_json) { + if (single_parser) { + regs.memory[INGRESS].emit_json(*open_output("memories.parser.ingress.cfg.json"), + "ingress"); + regs.memory[EGRESS].emit_json(*open_output("memories.parser.egress.cfg.json"), + "egress"); + regs.ingress.emit_json(*open_output("regs.parser.ingress.cfg.json")); + regs.egress.emit_json(*open_output("regs.parser.egress.cfg.json")); + regs.main[INGRESS].emit_json(*open_output("regs.parser.main.ingress.cfg.json"), + "ingress"); + regs.main[EGRESS].emit_json(*open_output("regs.parser.main.egress.cfg.json"), + "egress"); + regs.merge.emit_json(*open_output("regs.parse_merge.cfg.json")); + } else { + regs.memory[INGRESS].emit_json( + *open_output("memories.parser.ingress.%02x.cfg.json", parser_no), "ingress"); + regs.memory[EGRESS].emit_json( + *open_output("memories.parser.egress.%02x.cfg.json", parser_no), "egress"); + regs.ingress.emit_json( + *open_output("regs.parser.ingress.%02x.cfg.json", parser_no)); + regs.egress.emit_json(*open_output("regs.parser.egress.%02x.cfg.json", parser_no)); + regs.main[INGRESS].emit_json(*open_output("regs.parser.main.ingress.cfg.json"), + "ingress"); + regs.main[EGRESS].emit_json(*open_output("regs.parser.main.egress.cfg.json"), + "egress"); + regs.merge.emit_json(*open_output("regs.parse_merge.cfg.json")); + } + } + } + + /* multiple JBay parser mem blocks can respond to same address range to allow programming + * the device with a single write operation. See: pardereg.pgstnreg.ibprsr4reg.prsr.mem_ctrl */ + if (gress == INGRESS) { + for (unsigned i = 0; i < TopLevel::regs()->mem_pipe.parde.i_prsr_mem.size(); + options.singlewrite ? i += 4 : i += 1) { + TopLevel::regs()->mem_pipe.parde.i_prsr_mem[i].set( + "memories.parser.ingress", ®s.memory[INGRESS]); + } + } + + if (gress == EGRESS) { + for (unsigned i = 0; i < TopLevel::regs()->mem_pipe.parde.e_prsr_mem.size(); + options.singlewrite ? i += 4 : i += 1) { + TopLevel::regs()->mem_pipe.parde.e_prsr_mem[i].set( + "memories.parser.egress", ®s.memory[EGRESS]); + } + } + + if (gress == INGRESS) { + for (auto &ref : TopLevel::regs()->reg_pipe.pardereg.pgstnreg.ipbprsr4reg) + ref.set("regs.parser.ingress", ®s.ingress); + } + + if (gress == EGRESS) { + for (auto &ref : TopLevel::regs()->reg_pipe.pardereg.pgstnreg.epbprsr4reg) + ref.set("regs.parser.egress", ®s.egress); + } + TopLevel::regs()->reg_pipe.pardereg.pgstnreg.pmergereg.set("regs.parse_merge", + ®s.merge); +} + +template <> +void Parser::gen_configuration_cache(Target::JBay::parser_regs ®s, json::vector &cfg_cache) { + std::string reg_fqname; + std::string reg_name; + unsigned reg_value; + std::string reg_value_str; + unsigned reg_width = 13; + + /* Publishing meta_opt field for chnl_ctrl register */ + /* Are ovr_pipeid, chnl_clean, init_dprsr_credit, init_ebuf_credit always handled by the + * driver? + */ + for (int i = 0; i < 9; i++) { + reg_fqname = "pardereg.pgstnreg.epbprsr4reg[" + std::to_string(i) + + "].epbreg.chan0_group.chnl_ctrl.meta_opt"; + reg_name = "epb" + std::to_string(i) + "parser0_chnl_ctrl_0"; + reg_value = meta_opt; + reg_value_str = int_to_hex_string(meta_opt, reg_width); + add_cfg_reg(cfg_cache, reg_fqname, reg_name, reg_value_str); + } +} diff --git a/backends/tofino/bf-asm/jbay/phv.cpp b/backends/tofino/bf-asm/jbay/phv.cpp new file mode 100644 index 00000000000..96612045a0d --- /dev/null +++ b/backends/tofino/bf-asm/jbay/phv.cpp @@ -0,0 +1,66 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "phv.h" + +void Target::JBay::Phv::init_regs(::Phv &phv) { + // Allocating JBay regs so the uids map to mau register encodings + static const struct { + char code[2]; + unsigned size, count; + } groups[] = {{"W", 32, 4}, {"B", 8, 4}, {"H", 16, 6}}; + static const struct { + char code[2]; + Register::type_t type; + unsigned count; + } types[] = {{"", Register::NORMAL, 12}, {"M", Register::MOCHA, 4}, {"D", Register::DARK, 4}}; + unsigned uid = 0; + unsigned byte = 0; + unsigned deparser_id = 0; + phv.regs.resize(280); + for (unsigned i = 0; i < sizeof groups / sizeof *groups; i++) { + unsigned idx[sizeof types / sizeof *types] = {0}; + for (unsigned j = 0; j < groups[i].count; j++) { + for (unsigned k = 0; k < sizeof types / sizeof *types; k++) { + for (unsigned l = 0; l < types[k].count; l++, idx[k]++, uid++) { + auto reg = new Register; + phv.regs[uid] = reg; + memset(reg->name, 0, sizeof(reg->name)); + snprintf(reg->name, sizeof(reg->name), "%.2s%.2s%d", types[k].code, + groups[i].code, idx[k]); + reg->type = types[k].type; + reg->index = idx[k]; + reg->uid = uid; + reg->size = groups[i].size; + if (reg->type == Register::DARK) { + reg->parser_id_ = reg->deparser_id_ = -1; + } else { + reg->parser_id_ = byte / 2U; + reg->deparser_id_ = deparser_id++; + byte += reg->size / 8U; + } + phv.names[INGRESS][reg->name][0].slice = ::Phv::Slice(*reg, 0, reg->size - 1); + phv.names[EGRESS][reg->name][0].slice = ::Phv::Slice(*reg, 0, reg->size - 1); + phv.names[GHOST][reg->name][0].slice = ::Phv::Slice(*reg, 0, reg->size - 1); + } + } + } + } + BUG_CHECK(uid == phv.regs.size()); + BUG_CHECK(deparser_id == 224); + BUG_CHECK(byte == 512); +} diff --git a/backends/tofino/bf-asm/jbay/phv.h b/backends/tofino/bf-asm/jbay/phv.h new file mode 100644 index 00000000000..965e1c899d2 --- /dev/null +++ b/backends/tofino/bf-asm/jbay/phv.h @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_JBAY_PHV_H_ +#define BF_ASM_JBAY_PHV_H_ + +#include "../phv.h" + +class Target::JBay::Phv : public Target::Phv { + friend class ::Phv; + struct Register : public ::Phv::Register { + short parser_id_, deparser_id_; + int parser_id() const override { return parser_id_; } + int mau_id() const override { return uid < 280 ? uid : -1; } + int ixbar_id() const override { + static const int ixbar_permute[16] = {0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, -6, -6, 0, 0}; + return deparser_id_ + ixbar_permute[deparser_id_ & 0xf]; + } + int deparser_id() const override { return deparser_id_; } + }; + void init_regs(::Phv &phv) override; + target_t type() const override { return JBAY; } + unsigned mau_groupsize() const override { return 20; } +}; + +class Target::Tofino2H::Phv : public Target::JBay::Phv { + target_t type() const override { return TOFINO2H; } +}; + +class Target::Tofino2M::Phv : public Target::JBay::Phv { + target_t type() const override { return TOFINO2M; } +}; + +class Target::Tofino2U::Phv : public Target::JBay::Phv { + target_t type() const override { return TOFINO2U; } +}; + +class Target::Tofino2A0::Phv : public Target::JBay::Phv { + target_t type() const override { return TOFINO2A0; } +}; + +#endif /* BF_ASM_JBAY_PHV_H_ */ diff --git a/backends/tofino/bf-asm/jbay/salu_inst.cpp b/backends/tofino/bf-asm/jbay/salu_inst.cpp new file mode 100644 index 00000000000..f6d0ce90425 --- /dev/null +++ b/backends/tofino/bf-asm/jbay/salu_inst.cpp @@ -0,0 +1,493 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* JBay template specializations for instructions #included in salu_inst.cpp + * WARNING -- this is included in an anonymous namespace, as these SaluInstruction + * subclasses are all defined in that anonymous namespace */ + +struct DivMod : public AluOP { + struct Decode : public AluOP::Decode { + Decode(const char *name, target_t targ, int opc) : AluOP::Decode(name, targ, opc) {} + Instruction *decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const override { + auto *rv = new DivMod(this, op[0].lineno); + if (op.size != 3) error(op[0].lineno, "divmod must have exactly 2 operands"); + if (op.size > 1) rv->srca = operand(tbl, act, op[1]); + if (op.size > 2) rv->srcb = operand(tbl, act, op[2]); + rv->dest = AluOP::HI; + rv->slot = ALU2HI; + return rv; + } + }; + DivMod(const Decode *op, int l) : AluOP(op, l) {} + + Instruction *pass1(Table *tbl, Table::Actions::Action *act) override { + tbl->stage->table_use[timing_thread(tbl->gress)] |= Stage::USE_STATEFUL_DIVIDE; + BUG_CHECK(tbl->to(), "stateful instruction on non-stateful table?"); + tbl->to()->divmod_used = true; + return AluOP::pass1(tbl, act); + } + FOR_ALL_REGISTER_SETS(DECLARE_FORWARD_VIRTUAL_INSTRUCTION_WRITE_REGS) +}; + +// setz op, so can OR with alu1hi to get that result +DivMod::Decode opDIVMOD("divmod", JBAY, 0x00); + +void DivMod::write_regs(Target::Tofino::mau_regs &, Table *, Table::Actions::Action *) { BUG(); } +void DivMod::write_regs(Target::JBay::mau_regs ®s, Table *tbl, Table::Actions::Action *act) { + AluOP::write_regs(regs, tbl, act); + int logical_home_row = tbl->layout[0].row; + auto &meter_group = regs.rams.map_alu.meter_group[logical_home_row / 4U]; + auto &salu_instr_common = meter_group.stateful.salu_instr_common[act->code]; + salu_instr_common.salu_divide_enable |= 1; +} + +struct MinMax : public SaluInstruction { + const struct Decode : public Instruction::Decode { + std::string name; + unsigned opcode; + Decode(const char *name, target_t targ, int op) + : Instruction::Decode(name, targ, STATEFUL_ALU), name(name), opcode(op) {} + Instruction *decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const override; + } *opc; + bool phv = false; // source is mem or phv + operand mask, postmod; + // constants for mask and postmod packed together + boost::optional constval = boost::none; + MinMax(const Decode *op, int l) : SaluInstruction(l), opc(op) {} + std::string name() override { return opc->name; }; + Instruction *pass1(Table *tbl, Table::Actions::Action *) override; + void pass2(Table *tbl, Table::Actions::Action *) override; + bool salu_alu() const override { return true; } + bool equiv(Instruction *a_) override { + if (auto *a = dynamic_cast(a_)) + return opc == a->opc && phv == a->phv && mask == a->mask && postmod == a->postmod; + return false; + } + bool phvRead(std::function) override { return phv; } + void dbprint(std::ostream &out) const override { + out << "INSTR: " << opc->name << (phv ? "phv, " : "mem, ") << mask; + if (postmod) out << ", " << postmod; + } + FOR_ALL_REGISTER_SETS(DECLARE_FORWARD_VIRTUAL_INSTRUCTION_WRITE_REGS) +}; + +MinMax::Decode opMIN8("min8", JBAY, 0), opMAX8("max8", JBAY, 1), opMIN16("min16", JBAY, 2), + opMAX16("max16", JBAY, 3); + +Instruction *MinMax::Decode::decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const { + auto *rv = new MinMax(this, op[0].lineno); + if (op.size > 2) { + if (op[1] == "phv") + rv->phv = true; + else if (op[1] != "mem") + error(op[1].lineno, "%s source must be 'mem' or 'phv'", op[0].s); + rv->mask = operand(tbl, act, op[2]); + if (!rv->mask.to() && !rv->mask.to()) + error(op[1].lineno, "%s mask must be constant or from phv or hash_dist", op[0].s); + } else { + error(op[0].lineno, "%s must have a single mask operand", op[0].s); + } + if (op.size == 4) { + rv->postmod = operand(tbl, act, op[3]); + } else if (op.size > 4) { + error(op[0].lineno, "too many operands for %s", op[0].s); + } + rv->slot = MINMAX; + return rv; +} +Instruction *MinMax::pass1(Table *tbl_, Table::Actions::Action *act) { + auto tbl = dynamic_cast(tbl_); + BUG_CHECK(tbl); + int mask_size = (opc->opcode & 2) ? 8 : 16; + constval = boost::none; + mask->pass1(tbl); + act->minmax_use = true; + if (auto k = mask.to()) { + if (k->value < 0 || k->value >= (1U << mask_size) || mask.neg) + error(k->lineno, "%s mask value out of range", name().c_str()); + constval = k->value & ((1U << mask_size) - 1); + } else if (auto p = mask.to()) { + if (p->phv_index(tbl)) + error(lineno, "%s phv mask must come from the lower half input", name().c_str()); + } else { + error(mask->lineno, "%s invalid mask", name().c_str()); + } + if (postmod) { + if (auto k = postmod.to()) { + if (k->value < 0) { + k->value = -k->value; + postmod.neg = !postmod.neg; + } + if (k->value > 255) error(lineno, "%s post mod too large", name().c_str()); + constval = constval.get_value_or(0) | (k->value & 0xff) << mask_size; + } else if (auto p = postmod.to()) { + if (!p->phv_index(tbl)) + error(lineno, "%s phv post mod must come from the upper half input", + name().c_str()); + } else { + error(postmod->lineno, "%s invalid post mod", name().c_str()); + } + } + // We allocate the value here in order to report an error in pass1 if the capacity + // of the register file is exceeded. The next call in write_regs with the same value + // will return already allocated register file row index. + if (constval) tbl->get_const(lineno, *constval); + return this; +} +void MinMax::pass2(Table *tbl, Table::Actions::Action *act) { + if (act->slot_use.intersects(bitvec(ALU2LO, 4))) + error(lineno, "min/max requires all 4 stateful alu slots be unused"); +} +void MinMax::write_regs(Target::JBay::mau_regs ®s, Table *tbl_, Table::Actions::Action *act) { + auto tbl = dynamic_cast(tbl_); + BUG_CHECK(tbl); + int logical_home_row = tbl->layout[0].row; + auto &meter_group = regs.rams.map_alu.meter_group[logical_home_row / 4U]; + auto &salu_instr_common = meter_group.stateful.salu_instr_common[act->code]; + if (auto k = mask.to()) { + salu_instr_common.salu_minmax_mask_ctl = 1; + } else { + salu_instr_common.salu_minmax_mask_ctl = 0; + } + salu_instr_common.salu_minmax_ctl = opc->opcode; + salu_instr_common.salu_minmax_enable = 1; + if (postmod) { + if (auto k = postmod.to()) { + salu_instr_common.salu_minmax_postmod_value_ctl = 0; + } else { + salu_instr_common.salu_minmax_postmod_value_ctl = 1; + } + if (postmod.neg) + salu_instr_common.salu_minmax_postdec_enable = 1; + else + salu_instr_common.salu_minmax_postinc_enable = 1; + } + if (constval) { + auto &salu_instr_cmp = meter_group.stateful.salu_instr_cmp_alu[act->code][3]; + salu_instr_cmp.salu_cmp_regfile_adr = tbl->get_const(lineno, *constval); + } + // salu_instr_common.salu_minmax_src_sel = phv; -- FIXME -- specify PHV source? + for (auto &salu : meter_group.stateful.salu_instr_state_alu[act->code]) { + salu.salu_op = 0xd; + salu.salu_arith = 1; + salu.salu_pred = 0xffff; + } +} +void MinMax::write_regs(Target::Tofino::mau_regs &, Table *, Table::Actions::Action *) { BUG(); } + +template <> +void AluOP::write_regs(Target::JBay::mau_regs ®s, Table *tbl_, Table::Actions::Action *act) { + LOG2(this); + auto tbl = dynamic_cast(tbl_); + BUG_CHECK(tbl); + int logical_home_row = tbl->layout[0].row; + auto &meter_group = regs.rams.map_alu.meter_group[logical_home_row / 4U]; + auto &salu = meter_group.stateful.salu_instr_state_alu[act->code][slot - ALU2LO]; + auto &salu_ext = meter_group.stateful.salu_instr2_state_alu[act->code][slot - ALU2LO]; + auto &salu_instr_common = meter_group.stateful.salu_instr_common[act->code]; + auto &salu_instr_output_alu = meter_group.stateful.salu_instr_output_alu[act->code]; + salu.salu_op = opc->opcode & 0xf; + salu.salu_arith = opc->opcode >> 4; + salu.salu_pred = predication_encode; + bool need_flyover = (tbl->format->size >> tbl->is_dual_mode()) > 32; + const int alu_const_min = Target::STATEFUL_ALU_CONST_MIN(); + const int alu_const_max = Target::STATEFUL_ALU_CONST_MAX(); + if (srca) { + if (auto m = srca.to()) { + salu.salu_asrc_input = m->field->bit(0) > 0 ? 1 : 0; + if (need_flyover) { + salu_ext.salu_flyover_src_sel = 1; + need_flyover = false; + } + } else if (auto f = srca.to()) { + salu.salu_asrc_input = f->phv_index(tbl) ? 3 : 2; + if (need_flyover) { + salu_ext.salu_flyover_src_sel = 1; + need_flyover = false; + } + } else if (auto k = srca.to()) { + salu.salu_asrc_input = 4; + if (k->value >= alu_const_min && k->value <= alu_const_max) { + salu.salu_const_src = k->value & Target::STATEFUL_ALU_CONST_MASK(); + salu.salu_regfile_const = 0; + } else { + salu.salu_const_src = tbl->get_const(k->lineno, k->value); + salu.salu_regfile_const = 1; + } + } else if (auto r = srca.to()) { + salu.salu_asrc_input = 4; + salu.salu_const_src = r->index; + salu.salu_regfile_const = 1; + } else { + BUG(); + } + } + if (srcb) { + if (auto m = srcb.to()) { + salu.salu_bsrc_input = m->field->bit(0) > 0 ? 3 : 2; + if (need_flyover) { + salu_ext.salu_flyover_src_sel = 0; + need_flyover = false; + } + } else if (auto f = srcb.to()) { + salu.salu_bsrc_input = f->phv_index(tbl) ? 1 : 0; + if (need_flyover) { + salu_ext.salu_flyover_src_sel = 0; + need_flyover = false; + } + } else if (auto m = srcb.to()) { + salu_instr_common.salu_alu2_lo_bsrc_math = 1; + if (auto b = m->of.to()) { + salu_instr_common.salu_alu2_lo_math_src = b->phv_index(tbl); + } else if (auto b = m->of.to()) { + salu_instr_common.salu_alu2_lo_math_src = b->field->bit(0) > 0 ? 3 : 2; + } else { + BUG(); + } + } else if (auto k = srcb.to()) { + salu.salu_bsrc_input = 4; + if (k->value >= alu_const_min && k->value <= alu_const_max) { + salu.salu_const_src = k->value & Target::STATEFUL_ALU_CONST_MASK(); + salu.salu_regfile_const = 0; + } else { + salu.salu_const_src = tbl->get_const(k->lineno, k->value); + salu.salu_regfile_const = 1; + } + } else if (auto r = srcb.to()) { + salu.salu_bsrc_input = 4; + salu.salu_const_src = r->index; + salu.salu_regfile_const = 1; + } else { + BUG(); + } + } +} +void AluOP::write_regs(Target::JBay::mau_regs ®s, Table *tbl, Table::Actions::Action *act) { + write_regs(regs, tbl, act); +} + +template <> +void BitOP::write_regs(Target::JBay::mau_regs ®s, Table *tbl, Table::Actions::Action *act) { + LOG2(this); + int logical_home_row = tbl->layout[0].row; + auto &meter_group = regs.rams.map_alu.meter_group[logical_home_row / 4U]; + auto &salu = meter_group.stateful.salu_instr_state_alu[act->code][slot - ALU2LO]; + salu.salu_op = opc->opcode & 0xf; + salu.salu_pred = predication_encode; + // 1b instructions are from mem-lo to alu1-lo + salu.salu_asrc_input = 0; +} +void BitOP::write_regs(Target::JBay::mau_regs ®s, Table *tbl, Table::Actions::Action *act) { + write_regs(regs, tbl, act); +} + +static int sbus_mask(int alu, const std::vector &tbls) { + int rv = 0; + for (auto &tbl : tbls) { + int bit = tbl->layout[0].row / 4U; + if (bit > alu) --bit; + rv |= 1 << bit; + } + return rv; +} + +template <> +void CmpOP::write_regs(Target::JBay::mau_regs ®s, Table *tbl_, Table::Actions::Action *act) { + LOG2(this); + auto tbl = dynamic_cast(tbl_); + BUG_CHECK(tbl); + int logical_home_row = tbl->layout[0].row; + auto &meter_group = regs.rams.map_alu.meter_group[logical_home_row / 4U]; + auto &salu = meter_group.stateful.salu_instr_cmp_alu[act->code][slot]; + auto &salu_instr_common = meter_group.stateful.salu_instr_common[act->code]; + if (srca) { + salu.salu_cmp_asrc_input = srca->field->bit(0) > 0; + salu.salu_cmp_asrc_sign = srca_neg; + salu.salu_cmp_asrc_enable = 1; + if (maska != uint32_t(-1)) { + salu.salu_cmp_asrc_mask_enable = 1; + auto cval = 0; + if (auto k = dynamic_cast(srcc)) + cval = k->value; + else if (auto r = dynamic_cast(srcc)) + cval = tbl->get_const_val(r->index); + int64_t min = Target::STATEFUL_CMP_CONST_MIN(); + int64_t max = Target::STATEFUL_CMP_CONST_MAX(); + bool maska_outside = (maska < uint32_t(min) && maska > max); + bool maska_equal_inside = (uint32_t(cval) != maska && cval >= min && cval <= max); + if (!maska_outside && !maska_equal_inside) { + salu.salu_cmp_const_src = maska & Target::STATEFUL_CMP_CONST_MASK(); + salu.salu_cmp_mask_input = 0; + } else { + salu.salu_cmp_regfile_adr = tbl->get_const(srca->lineno, maska); + salu.salu_cmp_mask_input = 1; + } + } + } + if (srcb) { + salu.salu_cmp_bsrc_input = srcb->phv_index(tbl); + salu.salu_cmp_bsrc_sign = srcb_neg; + salu.salu_cmp_bsrc_enable = 1; + if (maskb != uint32_t(-1)) { + // uarch 6.2.12.6.1, masks for operand a/b are sourced from the + // same regfile slot. + if (salu.salu_cmp_asrc_mask_enable && salu.salu_cmp_mask_input && maskb != maska) + error(lineno, "inconsistent operand mask %d and %d in salu compare operation", + maska, maskb); + salu.salu_cmp_bsrc_mask_enable = 1; + salu.salu_cmp_regfile_adr = tbl->get_const(srcb->lineno, maskb); + } + } + if (srcc) { + if (auto k = dynamic_cast(srcc)) { + const int cmp_const_min = Target::STATEFUL_CMP_CONST_MIN(); + const int cmp_const_max = Target::STATEFUL_CMP_CONST_MAX(); + if (k->value >= cmp_const_min && k->value <= cmp_const_max) { + salu.salu_cmp_const_src = k->value & Target::STATEFUL_CMP_CONST_MASK(); + salu.salu_cmp_regfile_const = 0; + } else { + // uarch 6.2.12.6.1, masks for operand a/b are sourced from the + // same regfile slot as operand c if c is a constant. + if (salu.salu_cmp_asrc_mask_enable && salu.salu_cmp_mask_input && + maska != uint32_t(k->value)) + error(lineno, "inconsistent operand mask %d and %d in salu compare operation", + maska, uint32_t(k->value)); + if (salu.salu_cmp_bsrc_mask_enable && salu.salu_cmp_mask_input && + maskb != uint32_t(k->value)) + error(lineno, "inconsistent operand mask %d and %d in salu compare operation", + maskb, uint32_t(k->value)); + salu.salu_cmp_regfile_adr = tbl->get_const(srcc->lineno, k->value); + salu.salu_cmp_regfile_const = 1; + } + } else if (auto r = dynamic_cast(srcc)) { + salu.salu_cmp_regfile_adr = r->index; + salu.salu_cmp_regfile_const = 1; + } + } else { + salu.salu_cmp_const_src = 0; + salu.salu_cmp_regfile_const = 0; + } + salu.salu_cmp_opcode = opc->opcode | (type << 2); + auto lmask = sbus_mask(logical_home_row / 4U, tbl->sbus_learn); + auto mmask = sbus_mask(logical_home_row / 4U, tbl->sbus_match); + salu_instr_common.salu_lmatch_sbus_listen = lmask; + salu_instr_common.salu_match_sbus_listen = mmask; + salu_instr_common.salu_sbus_in_comb = tbl->sbus_comb; + if (lmask || mmask) { + // if lmask and mmask are both zero, these registers don't matter, but the model + // will assert if they are non-zero) + salu.salu_cmp_sbus_or = 0; + salu.salu_cmp_sbus_and = learn ? 1 : 0; + salu.salu_cmp_sbus_invert = learn_not ? 1 : 0; + } +} +void CmpOP::write_regs(Target::JBay::mau_regs ®s, Table *tbl, Table::Actions::Action *act) { + write_regs(regs, tbl, act); +} + +template <> +void TMatchOP::write_regs(Target::JBay::mau_regs ®s, Table *tbl_, Table::Actions::Action *act) { + LOG2(this); + auto tbl = dynamic_cast(tbl_); + BUG_CHECK(tbl); + int logical_home_row = tbl->layout[0].row; + auto &meter_group = regs.rams.map_alu.meter_group[logical_home_row / 4U]; + auto &salu = meter_group.stateful.salu_instr_cmp_alu[act->code][slot]; + auto &salu_tmatch = meter_group.stateful.salu_instr_tmatch_alu[act->code][slot]; + auto &salu_instr_common = meter_group.stateful.salu_instr_common[act->code]; + salu.salu_cmp_tmatch_enable = 1; + salu.salu_cmp_asrc_enable = 1; + salu.salu_cmp_bsrc_enable = 1; + meter_group.stateful.tmatch_mask[slot][0] = ~mask & 0xffffffffU; + meter_group.stateful.tmatch_mask[slot][1] = ~mask >> 32; + salu.salu_cmp_opcode = 2; + salu.salu_cmp_asrc_input = srca->field->bit(0) > 0; + salu.salu_cmp_bsrc_input = srcb->phv_index(tbl); + if (auto lmask = sbus_mask(logical_home_row / 4U, tbl->sbus_learn)) + salu_instr_common.salu_lmatch_sbus_listen = lmask; + if (auto mmask = sbus_mask(logical_home_row / 4U, tbl->sbus_match)) + salu_instr_common.salu_match_sbus_listen = mmask; + salu.salu_cmp_sbus_or = 0; + salu.salu_cmp_sbus_and = learn ? 1 : 0; + salu.salu_cmp_sbus_invert = learn_not ? 1 : 0; + // we set the learn output unconditionally if there's a tmatch -- should it be controllable? + salu_tmatch.salu_tmatch_vld_ctl = 1; + // salu_tmatch.salu_tmatch_invert = 0; -- when can this be useful? +} + +void TMatchOP::write_regs(Target::JBay::mau_regs ®s, Table *tbl, Table::Actions::Action *act) { + write_regs(regs, tbl, act); +} + +void OutOP::decode_output_mux(Target::JBay, Table *tbl, value_t &op) { + static const std::map ops_mux_lookup = { + {"mem_hi", 1}, {"mem_lo", 0}, {"memory_hi", 1}, {"memory_lo", 0}, {"phv_hi", 3}, + {"phv_lo", 2}, {"alu_hi", 5}, {"alu_lo", 4}, {"minmax_index", 5}, {"minmax_post", 4}, + {"predicate", 6}, {"address", 7}, {"div", 8}, {"mod", 9}, {"minmax", 10}}; + if (op.type == tCMD && ops_mux_lookup.count(op[0].s)) + output_mux = ops_mux_lookup.at(op[0].s); + else if (op.type == tSTR && ops_mux_lookup.count(op.s)) + output_mux = ops_mux_lookup.at(op.s); + else + output_mux = -1; + if (src) { + int tmp = output_mux; + if (auto *phv = src.to()) + output_mux = 2 + phv->phv_index(tbl->to()); + else if (auto *mem = src.to()) + output_mux = mem->field->bit(0) > 0 ? 1 : 0; + BUG_CHECK(tmp < 0 || tmp == output_mux, "inconsistent output mux decode"); + } +} +int OutOP::decode_output_option(Target::JBay, value_t &op) { + if (op == "lmatch") { + lmatch = true; + if (op.type == tCMD) + lmatch_pred = decode_predicate(op[1]); + else + lmatch_pred = STATEFUL_PREDICATION_ENCODE_UNCOND; + } else { + return -1; + } + return 0; +} + +template <> +void OutOP::write_regs(Target::JBay::mau_regs ®s, Table *tbl_, Table::Actions::Action *act) { + LOG2(this); + auto tbl = dynamic_cast(tbl_); + BUG_CHECK(tbl); + int logical_home_row = tbl->layout[0].row; + auto &meter_group = regs.rams.map_alu.meter_group[logical_home_row / 4U]; + auto &salu = meter_group.stateful.salu_instr_output_alu[act->code][slot - ALUOUT0]; + if (predication_encode) { + salu.salu_output_cmpfn = predication_encode; + } else { + salu.salu_output_cmpfn = STATEFUL_PREDICATION_ENCODE_UNCOND; + } + salu.salu_output_asrc = output_mux; + if ((salu.salu_lmatch_adr_bit_enable = lmatch)) + meter_group.stateful.salu_mathtable[0] = lmatch_pred; + if (output_mux == STATEFUL_PREDICATION_OUTPUT) + meter_group.stateful.stateful_ctl.salu_output_pred_sel = slot - ALUOUT0; +} +void OutOP::write_regs(Target::JBay::mau_regs ®s, Table *tbl, Table::Actions::Action *act) { + write_regs(regs, tbl, act); +} diff --git a/backends/tofino/bf-asm/jbay/stage.cpp b/backends/tofino/bf-asm/jbay/stage.cpp new file mode 100644 index 00000000000..38f37c71b5e --- /dev/null +++ b/backends/tofino/bf-asm/jbay/stage.cpp @@ -0,0 +1,316 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* mau stage template specializations for jbay -- #included directly in top-level stage.cpp */ + +template <> +void Stage::gen_configuration_cache(Target::JBay::mau_regs ®s, json::vector &cfg_cache) { + Stage::gen_configuration_cache_common(regs, cfg_cache); + + static unsigned i_pdddelay; + static unsigned e_pdddelay; + unsigned reg_width = 8; // this means number of hex characters + std::string i_reg_value_str; + std::string e_reg_value_str; + std::string reg_fqname; + std::string reg_name; + unsigned reg_value; + std::string reg_value_str; + + if (stageno != 0) { + if (i_pdddelay > regs.cfg_regs.amod_pre_drain_delay[INGRESS]) + i_pdddelay = regs.cfg_regs.amod_pre_drain_delay[INGRESS]; + if (e_pdddelay > regs.cfg_regs.amod_pre_drain_delay[EGRESS]) + e_pdddelay = regs.cfg_regs.amod_pre_drain_delay[EGRESS]; + + if (stageno == AsmStage::numstages() - 1) { + // 64 is due to number of CSR's + i_pdddelay += (7 + 64); + i_reg_value_str = int_to_hex_string(i_pdddelay, reg_width); + e_pdddelay += (7 + 64); + e_reg_value_str = int_to_hex_string(e_pdddelay, reg_width); + + add_cfg_reg(cfg_cache, "pardereg.pgstnreg.parbreg.left.i_wb_ctrl", "left_i_wb_ctrl", + i_reg_value_str); + add_cfg_reg(cfg_cache, "pardereg.pgstnreg.parbreg.right.e_wb_ctrl", "right_e_wb_ctrl", + e_reg_value_str); + } + } + + // meter_ctl + auto &meter_ctl = regs.rams.map_alu.meter_group; + for (int i = 0; i < 4; i++) { + reg_fqname = "mau[" + std::to_string(stageno) + "].rams.map_alu.meter_group[" + + std::to_string(i) + "]" + ".meter.meter_ctl"; + reg_name = "stage_" + std::to_string(stageno) + "_meter_ctl_" + std::to_string(i); + reg_value = meter_ctl[i].meter.meter_ctl; + if ((reg_value != 0) || (options.match_compiler)) { + reg_value_str = int_to_hex_string(reg_value, reg_width); + add_cfg_reg(cfg_cache, reg_fqname, reg_name, reg_value_str); + } + } +} + +static void addvec(json::vector &vec, ubits_base &val, uint32_t extra = 0) { + vec.push_back(val | extra); +} +static void addvec(json::vector &vec, uint32_t val, uint32_t extra = 0) { + vec.push_back(val | extra); +} + +template +static void addvec(json::vector &vec, checked_array_base &array, uint32_t extra = 0) { + for (auto &el : array) addvec(vec, el, extra); +} + +template +static json::map make_reg_vec(REGS ®s, REG ®, const char *name, uint32_t mask0, + uint32_t mask1, uint32_t mask2, uint32_t extra = 0) { + json::map rv; + rv["name"] = name; + rv["offset"] = regs.binary_offset(®); + addvec(rv["value"], reg, extra); + rv["mask"] = json::vector{json::number(mask0), json::number(mask1), json::number(mask2)}; + return rv; +} + +template +void Stage::gen_mau_stage_extension(REGS ®s, json::map &extend) { + extend["last_programmed_stage"] = Target::NUM_MAU_STAGES() - 1; + json::vector ®isters = extend["registers"] = json::vector(); + registers.push_back(make_reg_vec(regs, regs.dp.phv_ingress_thread, "regs.dp.phv_ingress_thread", + 0, 0x3ff, 0x3ff)); + registers.push_back(make_reg_vec(regs, regs.dp.phv_ingress_thread_imem, + "regs.dp.phv_ingress_thread_imem", 0, 0x3ff, 0x3ff)); + registers.push_back(make_reg_vec(regs, regs.dp.phv_egress_thread, "regs.dp.phv_egress_thread", + 0, 0x3ff, 0x3ff)); + registers.push_back(make_reg_vec(regs, regs.dp.phv_egress_thread_imem, + "regs.dp.phv_egress_thread_imem", 0, 0x3ff, 0x3ff)); + registers.push_back(make_reg_vec(regs, regs.rams.match.adrdist.adr_dist_pipe_delay, + "regs.rams.match.adrdist.adr_dist_pipe_delay", 0, 0xf, 0xf)); + typename std::remove_reference< + decltype(regs.rams.match.adrdist.deferred_eop_bus_delay[0])>::type mask0, + mask1; + mask0.eop_delay_fifo_en = mask1.eop_delay_fifo_en = 1; + mask0.eop_internal_delay_fifo = mask1.eop_internal_delay_fifo = 0x1f; + mask0.eop_output_delay_fifo = 0x1; + mask1.eop_output_delay_fifo = 0x1f; + BUG_CHECK(regs.rams.match.adrdist.deferred_eop_bus_delay[0].eop_output_delay_fifo & + regs.rams.match.adrdist.deferred_eop_bus_delay[1].eop_output_delay_fifo & 1); + registers.push_back(make_reg_vec(regs, regs.rams.match.adrdist.deferred_eop_bus_delay, + "regs.rams.match.adrdist.deferred_eop_bus_delay", mask0, mask0, + mask1)); + registers.push_back(make_reg_vec(regs, regs.dp.cur_stage_dependency_on_prev, + "regs.dp.cur_stage_dependency_on_prev", 0, 0x3, 0x3, 0x1)); + registers.push_back(make_reg_vec(regs, regs.dp.next_stage_dependency_on_cur, + "regs.dp.next_stage_dependency_on_cur", 0x3, 0x3, 0, 0x1)); + registers.push_back(make_reg_vec(regs, regs.rams.match.merge.mpr_bus_dep, + "regs.rams.match.merge.mpr_bus_dep", 0x3, 0x3, 0, 0x3)); + registers.push_back(make_reg_vec(regs, regs.dp.pipelength_added_stages, + "regs.dp.pipelength_added_stages", 0, 0xf, 0xf)); + registers.push_back(make_reg_vec(regs, regs.rams.match.merge.exact_match_delay_thread, + "regs.rams.match.merge.exact_match_delay_thread", 0, 0x3, + 0x3)); + BUG_CHECK((regs.rams.match.merge.mpr_thread_delay[0] & 1) == 0); + BUG_CHECK((regs.rams.match.merge.mpr_thread_delay[1] & 1) == 0); + registers.push_back(make_reg_vec(regs, regs.rams.match.merge.mpr_thread_delay, + "regs.rams.match.merge.mpr_thread_delay", 1, 1, 0x1f)); +} + +/* disable power gating configuration for specific MAU regs to weedout delay programming + * issues. We dont expect to call this function in the normal usage of JBay - this is + * only for emulator debug/bringup + */ +template +static void disable_jbay_power_gating(REGS ®s) { + for (gress_t gress : Range(INGRESS, EGRESS)) { + regs.dp.mau_match_input_xbar_exact_match_enable[gress] |= 0x1; + regs.dp.xbar_hash.xbar.mau_match_input_xbar_ternary_match_enable[gress] |= 0x1; + } + + auto &xbar_power_ctl = regs.dp.match_input_xbar_din_power_ctl; + auto &actionmux_power_ctl = regs.dp.actionmux_din_power_ctl; + for (int side = 0; side < 2; side++) { + for (int reg = 0; reg < 16; reg++) { + xbar_power_ctl[side][reg] |= 0x3FF; + actionmux_power_ctl[side][reg] |= 0x3FF; + } + } +} + +template <> +void Stage::write_regs(Target::JBay::mau_regs ®s, bool) { + write_common_regs(regs); + auto &merge = regs.rams.match.merge; + for (gress_t gress : Range(INGRESS, EGRESS)) { + if (stageno == 0) { + merge.predication_ctl[gress].start_table_fifo_delay0 = pred_cycle(gress) - 2; + merge.predication_ctl[gress].start_table_fifo_enable = 1; + } else if (stage_dep[gress] == MATCH_DEP) { + merge.predication_ctl[gress].start_table_fifo_delay0 = + this[-1].pipelength(gress) - this[-1].pred_cycle(gress) + pred_cycle(gress) - 3; + merge.predication_ctl[gress].start_table_fifo_enable = 1; + } else { + BUG_CHECK(stage_dep[gress] == ACTION_DEP); + merge.predication_ctl[gress].start_table_fifo_delay0 = 0; + merge.predication_ctl[gress].start_table_fifo_enable = 0; + } + + if (stageno != 0) + regs.dp.cur_stage_dependency_on_prev[gress] = stage_dep[gress] != MATCH_DEP; + + /* set stage0 dependency if explicitly set by the commandline option */ + if (stageno == 0 && !options.stage_dependency_pattern.empty()) + regs.dp.cur_stage_dependency_on_prev[gress] = stage_dep[gress] != MATCH_DEP; + + if (stageno != AsmStage::numstages() - 1) + regs.dp.next_stage_dependency_on_cur[gress] = this[1].stage_dep[gress] != MATCH_DEP; + else if (AsmStage::numstages() < Target::NUM_MAU_STAGES()) + regs.dp.next_stage_dependency_on_cur[gress] = 1; + auto &deferred_eop_bus_delay = regs.rams.match.adrdist.deferred_eop_bus_delay[gress]; + deferred_eop_bus_delay.eop_internal_delay_fifo = pred_cycle(gress) + 2; + /* FIXME -- making this depend on the dependency of the next stage seems wrong */ + if (stageno == AsmStage::numstages() - 1) { + if (AsmStage::numstages() < Target::NUM_MAU_STAGES()) + deferred_eop_bus_delay.eop_output_delay_fifo = 1; + else + deferred_eop_bus_delay.eop_output_delay_fifo = pipelength(gress) - 2; + } else if (this[1].stage_dep[gress] == MATCH_DEP) { + deferred_eop_bus_delay.eop_output_delay_fifo = pipelength(gress) - 2; + } else { + deferred_eop_bus_delay.eop_output_delay_fifo = 1; + } + deferred_eop_bus_delay.eop_delay_fifo_en = 1; + if (stageno != AsmStage::numstages() - 1 && this[1].stage_dep[gress] == MATCH_DEP) { + merge.mpr_thread_delay[gress] = pipelength(gress) - pred_cycle(gress) - 4; + } else { + /* last stage in JBay must be always set as match-dependent on deparser */ + if (stageno == AsmStage::numstages() - 1) { + merge.mpr_thread_delay[gress] = pipelength(gress) - pred_cycle(gress) - 4; + } else { + merge.mpr_thread_delay[gress] = 0; + } + } + } + + for (gress_t gress : Range(INGRESS, EGRESS)) + if (table_use[gress] & USE_TCAM) + regs.tcams.tcam_piped |= options.match_compiler ? 3 : 1 << gress; + + for (gress_t gress : Range(INGRESS, EGRESS)) { + regs.cfg_regs.amod_pre_drain_delay[gress] = pipelength(gress) - 9; + if (this[1].stage_dep[gress] == MATCH_DEP) + regs.cfg_regs.amod_wide_bubble_rsp_delay[gress] = pipelength(gress) - 3; + else + regs.cfg_regs.amod_wide_bubble_rsp_delay[gress] = 0; + } + /* Max re-request limit with a long interval. Parb is going to have a large + * gap configured to minimize traffic hits during configuration this means + * that individual stages may not get their bubbles and will need to retry. */ + regs.cfg_regs.amod_req_interval = 6732; + regs.cfg_regs.amod_req_limit = 15; + + if (stageno == 0) { + /* MFerrera: "After some debug on the emulator, we've found a programming issue due to + * incorrect documentation and CSR description of match_ie_input_mux_sel in JBAY" + * MAU Stage 0 must always be configured to source iPHV from Parser-Arbiter + * Otherwise, MAU stage 0 is configured as match-dependent on Parser-Arbiter */ + regs.dp.match_ie_input_mux_sel |= 3; + } + + merge.pred_stage_id = stageno; + if (long_branch_terminate) merge.pred_long_brch_terminate = long_branch_terminate; + for (gress_t gress : Range(INGRESS, GHOST)) { + if (long_branch_thread[gress]) + merge.pred_long_brch_thread[gress] = long_branch_thread[gress]; + } + + for (gress_t gress : Range(INGRESS, GHOST)) { + merge.mpr_stage_id[gress] = mpr_stage_id[gress]; + for (int id = 0; id < LOGICAL_TABLES_PER_STAGE; ++id) { + merge.mpr_next_table_lut[gress][id] = mpr_next_table_lut[gress][id]; + } + } + for (int id = 0; id < LOGICAL_TABLES_PER_STAGE; ++id) { + merge.mpr_glob_exec_lut[id] = mpr_glob_exec_lut[id]; + } + for (int id = 0; id < MAX_LONGBRANCH_TAGS; ++id) { + merge.mpr_long_brch_lut[id] = mpr_long_brch_lut[id]; + } + merge.mpr_always_run = mpr_always_run; + + if (stageno != AsmStage::numstages() - 1) { + merge.mpr_bus_dep.mpr_bus_dep_ingress = this[1].stage_dep[INGRESS] != MATCH_DEP; + merge.mpr_bus_dep.mpr_bus_dep_egress = this[1].stage_dep[EGRESS] != MATCH_DEP; + } + + merge.mpr_bus_dep.mpr_bus_dep_glob_exec = mpr_bus_dep_glob_exec[INGRESS] | + mpr_bus_dep_glob_exec[EGRESS] | + mpr_bus_dep_glob_exec[GHOST]; + merge.mpr_bus_dep.mpr_bus_dep_long_brch = mpr_bus_dep_long_branch[INGRESS] | + mpr_bus_dep_long_branch[EGRESS] | + mpr_bus_dep_long_branch[GHOST]; + + merge.mpr_long_brch_thread = long_branch_thread[EGRESS]; + if (auto conflict = (long_branch_thread[INGRESS] | long_branch_thread[GHOST]) & + long_branch_thread[EGRESS]) { + // Should probably check this earlier, but there's not a good place to do it. + for (auto tag : bitvec(conflict)) { + error(long_branch_use[tag]->lineno, + "Need one-stage turnaround before reusing " + "long_branch tag %d in a different thread", + tag); + } + } + + bitvec in_use = match_use[INGRESS] | action_use[INGRESS] | action_set[INGRESS]; + bitvec eg_use = match_use[EGRESS] | action_use[EGRESS] | action_set[EGRESS]; + /* FIXME -- if the regs are live across a stage (even if not used in that stage) they + * need to be set in the thread registers. For now we just assume if they are used + * anywhere, they need to be marked as live */ + in_use |= Phv::use(INGRESS); + eg_use |= Phv::use(EGRESS); + static const int phv_use_transpose[2][14] = { + {0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21}, + {4, 5, 6, 7, 12, 13, 14, 15, 22, 23, 24, 25, 26, 27}}; + // FIXME -- this code depends on the Phv::Register uids matching the + // FIXME -- mau encoding of phv containers. (FIXME-PHV) + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 14; j++) { + regs.dp.phv_ingress_thread[i][j] = regs.dp.phv_ingress_thread_imem[i][j] = + in_use.getrange(10 * phv_use_transpose[i][j], 10); + regs.dp.phv_egress_thread[i][j] = regs.dp.phv_egress_thread_imem[i][j] = + eg_use.getrange(10 * phv_use_transpose[i][j], 10); + } + } + + /* Things following are for debug/bringup only : not for normal flows */ + + if (options.disable_power_gating) { + disable_jbay_power_gating(regs); + } + + write_teop_regs(regs); +} + +void AlwaysRunTable::write_regs(Target::JBay::mau_regs ®s) { + if (gress == EGRESS) + regs.dp.imem_word_read_override.imem_word_read_override_egress = 1; + else + regs.dp.imem_word_read_override.imem_word_read_override_ingress = 1; + actions->write_regs(regs, this); +} diff --git a/backends/tofino/bf-asm/jbay/stateful.cpp b/backends/tofino/bf-asm/jbay/stateful.cpp new file mode 100644 index 00000000000..9bb9737fd07 --- /dev/null +++ b/backends/tofino/bf-asm/jbay/stateful.cpp @@ -0,0 +1,393 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "stateful.h" + +static const char *function_names[] = {"none", "log", "fifo", "stack", "clear"}; + +static int decode_push_pop(const value_t &v) { + static const std::map modes = { + {"hit", PUSH_HIT}, {"miss", PUSH_MISS}, {"gateway", PUSH_GATEWAY}, {"active", PUSH_ALL}}; + if (!CHECKTYPE(v, tSTR)) return 0; + if (!modes.count(v.s)) { + error(v.lineno, "Unknown push/pop mode %s", v.s); + return 0; + } + return modes.at(v.s); +} + +bool StatefulTable::setup_jbay(const pair_t &kv) { + if (kv.key == "sbus") { + // FIXME -- this should be in the stateful action setup as it is per action? + if (!CHECKTYPE(kv.value, tMAP)) return true; + for (auto &el : kv.value.map) { + if (el.key == "match") { + parse_vector(sbus_match, el.value); + } else if (el.key == "learn") { + parse_vector(sbus_learn, el.value); + } else if (el.key == "operation" || el.key == "combine") { + if (el.value == "and") + sbus_comb = SBUS_AND; + else if (el.value == "or") + sbus_comb = SBUS_OR; + else + error(el.value.lineno, "Invalid sbus %s %s, must be 'and' or 'or'", + value_desc(el.key), value_desc(el.value)); + } else { + warning(el.key.lineno, "ignoring unknown item %s in sbus of table %s", + value_desc(el.key), name()); + } + } + } else if (kv.key == "fifo" || kv.key == "stack") { + if (stateful_counter_mode) { + error(kv.key.lineno, "Conflicting log counter functions in %s", name()); + return true; + } + if (kv.key == "fifo") + stateful_counter_mode = FUNCTION_FIFO; + else if (kv.key == "stack") + stateful_counter_mode = FUNCTION_STACK; + if (!CHECKTYPE(kv.value, tMAP)) return true; + for (auto &el : MapIterChecked(kv.value.map)) { + if (el.key == "push") + stateful_counter_mode |= decode_push_pop(el.value); + else if (el.key == "pop") + stateful_counter_mode |= decode_push_pop(el.value) << PUSHPOP_BITS; + else + error(el.key.lineno, "Syntax error, expecting push or pop"); + } + } else if (kv.key == "clear") { + if (stateful_counter_mode) { + error(kv.key.lineno, "Conflicting log counter functions in %s", name()); + return true; + } + stateful_counter_mode = FUNCTION_FAST_CLEAR; + stateful_counter_mode |= decode_push_pop(kv.value); + } else if (kv.key == "watermark") { + if (kv.value == "pop") + watermark_pop_not_push = 1; + else if (kv.value != "push") + error(kv.value.lineno, "Syntax error, expecting push or pop"); + if (kv.value.type == tSTR) + watermark_level = 1; + else if (CHECKTYPE(kv.value[1], tINT)) + watermark_level = kv.value[1].i / 128; + if (kv.value[1].i % 128 != 0) + error(kv.value[1].lineno, "watermark level must be a mulitple of 128"); + } else if (kv.key == "underflow") { + if (CHECKTYPE(kv.value, tSTR)) underflow_action = kv.value; + } else if (kv.key == "overflow") { + if (CHECKTYPE(kv.value, tSTR)) overflow_action = kv.value; + } else if (kv.key == "offset_vpn") { + offset_vpn = get_bool(kv.value); + } else if (kv.key == "address_shift") { + if (CHECKTYPE(kv.value, tINT)) meter_adr_shift = kv.value.i; + } else if (kv.key == "phv_hash_shift") { + if (CHECKTYPE(kv.value, tINT)) { + phv_hash_shift = kv.value.i / 8U; + if (kv.value.i % 8U != 0) + error(kv.value.lineno, "phv_hash_shift must be a mulitple of 8"); + else if (phv_hash_shift < 0 || phv_hash_shift > 15) + error(kv.value.lineno, "phv_hash_shift %" PRId64 " out of range", kv.value.i); + } + } else if (kv.key == "phv_hash_mask") { + if (CHECKTYPE2(kv.value, tINT, tBIGINT)) phv_hash_mask = get_bitvec(kv.value); + } else if (kv.key == "stage_alu_id") { + if (CHECKTYPE(kv.value, tINT)) { + if (kv.value.i < 0 || kv.value.i >= 128) + error(kv.value.lineno, "invalid stage_alu_id %" PRIi64, kv.value.i); + stage_alu_id = kv.value.i; + } + } else { + return false; + } + return true; +} + +int parse_jbay_counter_mode(const value_t &v) { + int rv = 0; + if (v == "counter") + rv = FUNCTION_LOG; + else if (v == "fifo") + rv = FUNCTION_FIFO; + else if (v == "stack") + rv = FUNCTION_STACK; + else if (v == "clear") + rv = FUNCTION_FAST_CLEAR; + else + return -1; + if (v.type == tSTR) return rv | PUSH_ALL; + if (v.type != tCMD) return -1; + int flag = 0; + for (int i = 1; i < v.vec.size; ++i) { + if (v[i] == "hit") { + flag |= PUSH_HIT; + } else if (v[i] == "miss") { + flag |= PUSH_MISS; + } else if (v[i] == "gateway") { + flag |= PUSH_GATEWAY; + } else if (v[i] == "gw0") { + flag |= PUSH_GW_ENTRY; + } else if (v[i] == "gw1") { + flag |= (PUSH_GW_ENTRY << 1); + } else if (v[i] == "gw2") { + flag |= (PUSH_GW_ENTRY << 2); + } else if (v[i] == "gw3") { + flag |= (PUSH_GW_ENTRY << 3); + } else if (v[i] == "push" && (rv & FUNCTION_MASK) != FUNCTION_LOG) { + rv |= flag ? flag : PUSH_ALL; + flag = 0; + } else if (v[i] == "pop" && (rv & FUNCTION_MASK) != FUNCTION_LOG) { + rv |= (flag ? flag : PUSH_ALL) << PUSHPOP_BITS; + flag = 0; + } else { + return -1; + } + } + return rv | flag; +} +int StatefulTable::parse_counter_mode(Target::JBay target, const value_t &v) { + return parse_jbay_counter_mode(v); +} + +void StatefulTable::set_counter_mode(Target::JBay target, int mode) { + int fnmode = mode & FUNCTION_MASK; + BUG_CHECK(fnmode > 0 && (fnmode >> FUNCTION_SHIFT) <= FUNCTION_FAST_CLEAR); + if (stateful_counter_mode && (stateful_counter_mode & FUNCTION_MASK) != fnmode) + error(lineno, "Incompatible uses (%s and %s) of stateful alu counters", + function_names[stateful_counter_mode >> FUNCTION_SHIFT], + function_names[mode >> FUNCTION_SHIFT]); + else + stateful_counter_mode |= fnmode; + if (mode & PUSH_MASK) stateful_counter_mode |= PUSH_ANY; + if (mode & POP_MASK) stateful_counter_mode |= POP_ANY; +} + +// DANGER -- nasty hack to set the raw bits of an SALU state alu instruction +// really need to make the csr2cpp codegen handle this automatically +template +void set_raw_instr_bits(checked_array<4, T> ®, bitvec v) { + for (int i = 0; i < 4; ++i) { + reg[i].salu_const_src = v.getrange(i * 32, 4); + reg[i].salu_regfile_const = v.getrange(i * 32 + 4, 1); + reg[i].salu_bsrc_input = v.getrange(i * 32 + 5, 3); + reg[i].salu_asrc_input = v.getrange(i * 32 + 8, 3); + reg[i].salu_op = v.getrange(i * 32 + 11, 4); + reg[i].salu_arith = v.getrange(i * 32 + 15, 1); + reg[i].salu_pred = v.getrange(i * 32 + 16, 16); + } +} + +static int counter_to_use(MatchTable *m) { + for (auto st : m->get_attached()->statefuls) return st->to()->meter_group(); + BUG("no attached stateful table?"); + return 0; +} + +template +void StatefulTable::write_tofino2_common_regs(REGS ®s) { + auto &adrdist = regs.rams.match.adrdist; + auto &merge = regs.rams.match.merge; + auto &vpn_range = adrdist.mau_meter_alu_vpn_range[meter_group()]; + auto &salu = regs.rams.map_alu.meter_group[meter_group()].stateful; + int minvpn, maxvpn; + layout_vpn_bounds(minvpn, maxvpn, true); + vpn_range.meter_vpn_base = minvpn; + vpn_range.meter_vpn_limit = maxvpn; + vpn_range.meter_vpn_range_check_enable = 1; + int counter_idx = -1; + Actions::Action *sweep_action = nullptr; + for (MatchTable *m : match_tables) { + int mode = 0; + if (auto *call = m->get_call(this)) { + if (call->args.at(0).type == Call::Arg::Counter) { + mode = call->args.at(0).count_mode(); + if (counter_idx < 0) + counter_idx = counter_to_use(m); + else + BUG_CHECK(counter_idx == counter_to_use(m), "conflicting counter use in %s", + name()); + } + if ((mode & FUNCTION_MASK) == FUNCTION_FAST_CLEAR) { + for (auto &a : *m->get_actions()) { + if (auto *sw = action_for_table_action(m, &a)) { + BUG_CHECK(!sweep_action || sw == sweep_action, + "Inconsistent sweep action for %s", name()); + sweep_action = sw; + } + } + } + } + if (address_used) { + auto &slog_map = adrdist.mau_stateful_log_counter_logical_map[m->logical_id]; + slog_map.stateful_log_counter_logical_map_ctl = meter_group(); + slog_map.stateful_log_counter_logical_map_enable = 1; + } + if (mode) { + merge.mau_stateful_log_counter_ctl[m->logical_id / 8U][0].set_subfield( + mode & PUSHPOP_MASK, 4 * (m->logical_id % 8U), 4); + merge.mau_stateful_log_counter_ctl[m->logical_id / 8U][1].set_subfield( + (mode >> PUSHPOP_BITS) & PUSHPOP_MASK, 4 * (m->logical_id % 8U), 4); + for (auto &rep : merge.mau_stateful_log_ctl_ixbar_map[m->logical_id / 8U]) { + if (mode & PUSHPOP_MASK) + rep[0].set_subfield(counter_idx | 0x4, 3 * (m->logical_id % 8U), 3); + if ((mode >> PUSHPOP_BITS) & PUSHPOP_MASK) + rep[1].set_subfield(counter_idx | 0x4, 3 * (m->logical_id % 8U), 3); + } + } + if (address_used) + adrdist.meter_alu_adr_range_check_icxbar_map[meter_group()] |= 1U << m->logical_id; + if (offset_vpn) { + if (!address_used) + warning(lineno, + "Adjusting output address of %s for next stage, but noone is " + "reading it", + name()); + adrdist.mau_stateful_log_stage_vpn_offset[m->logical_id].stateful_log_stage_vpn_offset = + maxvpn - minvpn + 1; + // state_instr_width_logical and stateful_log_stage_vpn_offset + // should be set or unset together as they are both used for the + // stateful logging fifo feature. See figure 6-73 in jbay uarch. + adrdist.stateful_instr_width_logical[m->logical_id] = format->log2size - 3; + } + } + switch (meter_group()) { + case 0: + adrdist.meter_adr_shift.meter_adr_shift0 = meter_adr_shift; + break; + case 1: + adrdist.meter_adr_shift.meter_adr_shift1 = meter_adr_shift; + break; + case 2: + adrdist.meter_adr_shift.meter_adr_shift2 = meter_adr_shift; + break; + case 3: + adrdist.meter_adr_shift.meter_adr_shift3 = meter_adr_shift; + break; + } + if (counter_idx >= 0) { + auto &oxbar_map = adrdist.mau_stateful_log_counter_oxbar_map[meter_group()]; + oxbar_map.stateful_log_counter_oxbar_ctl = counter_idx; + oxbar_map.stateful_log_counter_oxbar_enable = 1; + } + auto &ctl2 = merge.mau_stateful_log_counter_ctl2[meter_group()]; + auto &ctl3 = merge.mau_stateful_log_counter_ctl3[meter_group()]; + if (stateful_counter_mode && (stateful_counter_mode & FUNCTION_MASK) != FUNCTION_FAST_CLEAR) { + ctl2.slog_counter_function = stateful_counter_mode >> FUNCTION_SHIFT; + ctl2.slog_instruction_width = format->log2size - 3; + if ((stateful_counter_mode & PUSH_ANY) == 0) ctl2.slog_push_event_ctl = 1; + if ((stateful_counter_mode & POP_ANY) == 0) ctl2.slog_pop_event_ctl = 1; + ctl2.slog_vpn_base = logvpn_min; + ctl2.slog_vpn_limit = logvpn_max; + if (watermark_level) { + ctl2.slog_watermark_ctl = watermark_pop_not_push; + ctl2.slog_watermark_enable = 1; + merge.mau_stateful_log_watermark_threshold[meter_group()] = watermark_level; + } + if (underflow_action.set()) { + auto act = actions->action(underflow_action.name); + BUG_CHECK(act); + // 4-bit stateful addr MSB encoding for instruction, as given by table 6-67 (6.4.4.11) + ctl3.slog_underflow_instruction = act->code * 2 + 1; + } + if (overflow_action.set()) { + auto act = actions->action(overflow_action.name); + BUG_CHECK(act); + ctl3.slog_overflow_instruction = act->code * 2 + 1; + } + } else { + // we set up for fast clear from the control plane if the counter mode is unused + ctl2.slog_counter_function = FUNCTION_FAST_CLEAR >> FUNCTION_SHIFT; + ctl2.slog_instruction_width = 4; // 128 bits + ctl2.slog_vpn_base = minvpn; + ctl2.slog_vpn_limit = maxvpn; + if (busy_value) salu.stateful_clear_action_output = busy_value; + if (clear_value) { + set_raw_instr_bits(salu.salu_instr_state_alu[3], clear_value); + salu.stateful_ctl.salu_clear_value_ctl = 1; + } + if (sweep_action) { + ctl3.slog_overflow_instruction = sweep_action->code * 2 + 1; + } else { + ctl3.slog_overflow_instruction = 0x6; + } + } + regs.rams.map_alu.meter_alu_group_phv_hash_shift[meter_group()] = phv_hash_shift; + unsigned idx = 0; + for (auto &slice : regs.rams.map_alu.meter_alu_group_phv_hash_mask[meter_group()]) + slice = phv_hash_mask.getrange(32 * idx++, 32); + + for (size_t i = 0; i < const_vals.size(); ++i) { + if (const_vals[i].value > (INT64_C(1) << 33) || const_vals[i].value <= -(INT64_C(1) << 33)) + error(const_vals[i].lineno, "constant value %" PRId64 " too large for stateful alu", + const_vals[i].value); + salu.salu_const_regfile[i] = const_vals[i].value & 0xffffffffU; + salu.salu_const_regfile_msbs[i] = (const_vals[i].value >> 32) & 0x3; + } + if (stage_alu_id >= 0) { + salu.stateful_ctl.salu_stage_id = stage_alu_id; + salu.stateful_ctl.salu_stage_id_enable = 1; + } +} + +// This is called write_logging_regs, but it handles all tofino2+ target specific +// registers, as write_regs is not specialized and this is. Should rename? +template <> +void StatefulTable::write_logging_regs(Target::JBay::mau_regs ®s) { + write_tofino2_common_regs(regs); +} + +/// Compute the proper value for the register +/// map_alu.meter_alu_group_data_delay_ctl[].meter_alu_right_group_delay +/// which controls the two halves of the ixbar->meter_alu fifo, based on a bytemask of which +/// bytes are needed in the meter_alu. On JBay, the fifo is 128 bits wide, so each enable +/// bit controls 64 bits +int AttachedTable::meter_alu_fifo_enable_from_mask(Target::JBay::mau_regs &, unsigned bytemask) { + int rv = 0; + if (bytemask & 0xff) rv |= 1; + if (bytemask & 0xff00) rv |= 2; + return rv; +} + +void StatefulTable::gen_tbl_cfg(Target::JBay, json::map &tbl, json::map &stage_tbl) const { + static const char *table_type[] = {"normal", "log", "fifo", "stack", "bloom_clear"}; + if (tbl["stateful_table_type"]) { + // overall table info already set in an earlier stage; don't override it + return; + } + tbl["stateful_table_type"] = table_type[stateful_counter_mode >> FUNCTION_SHIFT]; + bool has_push = (stateful_counter_mode & PUSHPOP_MASK) != 0; + bool has_pop = (stateful_counter_mode & (PUSHPOP_MASK << PUSHPOP_BITS)) != 0; + for (MatchTable *m : match_tables) { + if (auto *call = m->get_call(this)) { + if (call->args.at(0).type == Call::Arg::Counter) { + unsigned mode = call->args.at(0).count_mode(); + has_push |= (mode & PUSHPOP_MASK) != 0; + has_pop |= (mode & (PUSHPOP_MASK << PUSHPOP_BITS)) != 0; + } + } + } + if (has_push) { + if (has_pop) + tbl["stateful_direction"] = "inout"; + else + tbl["stateful_direction"] = "in"; + } else if (has_pop) { + tbl["stateful_direction"] = "out"; + } + tbl["stateful_counter_index"] = meter_group(); +} diff --git a/backends/tofino/bf-asm/jbay/stateful.h b/backends/tofino/bf-asm/jbay/stateful.h new file mode 100644 index 00000000000..3be1ab3aaaa --- /dev/null +++ b/backends/tofino/bf-asm/jbay/stateful.h @@ -0,0 +1,60 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_JBAY_STATEFUL_H_ +#define BF_ASM_JBAY_STATEFUL_H_ + +#include +#include + +#if HAVE_JBAY + +// FIXME -- should be a namespace somwhere? Or in class StatefulTable +/* for jbay counter mode, we may need both a push and a pop mode, as well as counter_function, + * so we pack them all into an int with some shifts and masks */ +enum { + PUSHPOP_BITS = 5, + PUSHPOP_MASK = 0xf, + PUSHPOP_ANY = 0x10, + PUSH_MASK = PUSHPOP_MASK, + PUSH_ANY = PUSHPOP_ANY, + POP_MASK = PUSHPOP_MASK << PUSHPOP_BITS, + POP_ANY = PUSHPOP_ANY << PUSHPOP_BITS, + PUSH_MISS = 1, + PUSH_HIT = 2, + PUSH_GATEWAY = 3, + PUSH_ALL = 4, + PUSH_GW_ENTRY = 5, + POP_MISS = PUSH_MISS << PUSHPOP_BITS, + POP_HIT = PUSH_HIT << PUSHPOP_BITS, + POP_GATEWAY = PUSH_GATEWAY << PUSHPOP_BITS, + POP_ALL = PUSH_ALL << PUSHPOP_BITS, + POP_GW_ENTRY = PUSH_GW_ENTRY << PUSHPOP_BITS, + FUNCTION_SHIFT = 2 * PUSHPOP_BITS, + FUNCTION_LOG = 1 << FUNCTION_SHIFT, + FUNCTION_FIFO = 2 << FUNCTION_SHIFT, + FUNCTION_STACK = 3 << FUNCTION_SHIFT, + FUNCTION_FAST_CLEAR = 4 << FUNCTION_SHIFT, + FUNCTION_MASK = 0xf << FUNCTION_SHIFT, +}; + +int parse_jbay_counter_mode(const value_t &v); +template <> +void StatefulTable::write_logging_regs(Target::JBay::mau_regs ®s); + +#endif /* HAVE_JBAY || || */ +#endif /* BF_ASM_JBAY_STATEFUL_H_ */ diff --git a/backends/tofino/bf-asm/jbay/template_objects.yaml b/backends/tofino/bf-asm/jbay/template_objects.yaml new file mode 100644 index 00000000000..9dc2f8ae478 --- /dev/null +++ b/backends/tofino/bf-asm/jbay/template_objects.yaml @@ -0,0 +1,121 @@ +# Copyright (C) 2024 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# +# SPDX-License-Identifier: Apache-2.0 + +global: + - namespace=JBay + - binary_offset + - emit_binary + - emit_fieldname + - emit_json + - enable_disable + - input_binary + - write_dma=mapram_config + - write_dma=imem_dark_subword8 + - write_dma=imem_dark_subword16 + - write_dma=imem_dark_subword32 + - write_dma=imem_mocha_subword8 + - write_dma=imem_mocha_subword16 + - write_dma=imem_mocha_subword32 + - write_dma=imem_subword8 + - write_dma=imem_subword16 + - write_dma=imem_subword32 + - write_dma=galois_field_matrix +generate: + memories: + jbay_mem: + memories.jbay_mem.h: [ decl, name=memories.top ] + memories.jbay_mem.cpp: [ defn, name=memories.top, + -Imemories.jbay_mem.h, -Imemories.pipe_addrmap.h ] + pipe_addrmap: # pipes + memories.pipe_addrmap.h: [ decl, name=memories.pipe, widereg ] + memories.pipe_addrmap.cpp: [ defn, name=memories.pipe, widereg, + -Imemories.pipe_addrmap.h, -Imemories.prsr_mem_main_rspec.h ] + # parde_mem -- parde + prsr_mem_main_rspec: # i_prsr_mem e_prsr_mem + memories.prsr_mem_main_rspec.h: [ decl, name=memories.parser.%s ] + memories.prsr_mem_main_rspec.cpp: [ defn, name=memories.parser.%s, + -Imemories.prsr_mem_main_rspec.h ] + + regs: + jbay_reg: + regs.jbay_reg.h: [ decl, name=regs.top ] + regs.jbay_reg.cpp: [ defn, name=regs.top, + -Iregs.jbay_reg.h, -Iregs.pipe_addrmap.h ] + pipe_addrmap: # pipea + regs.pipe_addrmap.h: [ decl, name=regs.pipe, widereg ] + regs.pipe_addrmap.cpp: [ defn, name=regs.pipe, widereg, + -Iregs.pipe_addrmap.h, -Iregs.ipb_prsr4_reg.h, -Iregs.epb_prsr4_reg.h, + -Iregs.pmerge_reg.h, -Iregs.mau_addrmap.h, -Iregs.dprsr_reg.h ] + mau_addrmap: # mau + regs.mau_addrmap.h: [ decl, name=regs.match_action_stage.%02x ] + regs.mau_addrmap.cpp: [ defn, name=regs.match_action_stage.%02x, + -Iregs.mau_addrmap.h ] + # parde_glue_stn_reg + ipb_prsr4_reg: # ipbprsr4reg + regs.ipb_prsr4_reg.h: [ decl, name=regs.parser.ingress ] + regs.ipb_prsr4_reg.cpp: [ defn, name=regs.parser.ingress, + -Iregs.ipb_prsr4_reg.h, -Iregs.prsr_reg_main_rspec.h ] + prsr_reg_main_rspec: # prsr + regs.prsr_reg_main_rspec.h: [ decl, name=regs.parser.main.%s ] + regs.prsr_reg_main_rspec.cpp: [ defn, name=regs.parser.main.%s, + -Iregs.prsr_reg_main_rspec.h ] + pmerge_reg: # pmergereg + regs.pmerge_reg.h: [ decl, name=regs.parse_merge ] + regs.pmerge_reg.cpp: [ defn, name=regs.parse_merge, + -Iregs.pmerge_reg.h ] + epb_prsr4_reg: # epbprsr4reg + regs.epb_prsr4_reg.h: [ decl, name=regs.parser.egress ] + regs.epb_prsr4_reg.cpp: [ defn, name=regs.parser.egress, + -Iregs.epb_prsr4_reg.h, -Iregs.prsr_reg_main_rspec.h ] + # prsr_reg_main_rspec # prsr + # mirr_ebuf_reg + dprsr_reg: + regs.dprsr_reg.h: [ decl, name=regs.deparser ] + regs.dprsr_reg.cpp: [ defn, name=regs.deparser, + -Iregs.dprsr_reg.h ] + +ignore: + memories: + # jbay_mem + - tm_top_mem_rspec # tm + # pipes + - mau_addrmap # mau -- just a dummy reg + # parde + - pgr_mem_rspec + + regs: + # jbay_reg + - dvsl_addrmap + - eth100g_addrmap + - eth400g_addrmap + - gpio_regs + - serdes_addrmap + # pipes + # mau + # pardereg + # parde_glue_stn_reg + # parb_reg + - ebuf900_reg + - pbus_station_regs_rspec + - pgr_reg_rspec # pgrreg + - s2p_reg + - p2s_reg + - parde_glue_reg_rspec #pgluereg + # mirr_ebuf_reg # mirefreg + # dprsr_reg + # dprsr_reg_rspec + - parde_dprsr_reg_rspec diff --git a/backends/tofino/bf-asm/json.cpp b/backends/tofino/bf-asm/json.cpp new file mode 100644 index 00000000000..694bd424f72 --- /dev/null +++ b/backends/tofino/bf-asm/json.cpp @@ -0,0 +1,253 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "json.h" + +#include +#include + +#include "hex.h" + +namespace json { + +static int digit_value(char ch) { + if (ch >= 'a') return ch - 'a' + 10; + if (ch >= 'A') return ch - 'A' + 10; + if (ch >= '0' && ch <= '9') return ch - '0'; + return 999; +} + +// true iff the string ends in an odd number of '\' characters +static bool odd_backslash(const std::string &s) { + int cnt = 0; + for (int i = s.size() - 1; i >= 0; --i) { + if (s[i] != '\\') break; + cnt++; + } + return (cnt & 1) == 1; +} + +std::istream &operator>>(std::istream &in, std::unique_ptr &json) { + while (in) { + bool neg = false; + char ch; + int base = 10, digit; + in >> ch; + switch (ch) { + case '-': + neg = true; + in >> ch; + if (ch != '0') goto digit; + /* fall through */ + case '0': + base = 8; + in >> ch; + if (ch == 'x' || ch == 'X') { + base = 16; + in >> ch; + } else if (ch == 'b') { + base = 2; + in >> ch; + } + /* fall through */ + digit: + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': { + int64_t l = 0; + while (in && (digit = digit_value(ch)) < base) { + if ((INT64_MAX - digit) / base < l) { + std::cerr << "overflow detected" << std::endl; + } + l = l * base + digit; + in >> ch; + } + if (in) in.unget(); + if (neg) l = -l; + json.reset(new number(l)); + return in; + } + case '"': { + std::string s; + getline(in, s, '"'); + while (odd_backslash(s)) { + std::string tmp; + getline(in, tmp, '"'); + s += '\"'; + s += tmp; + } + json.reset(new string(std::move(s))); + return in; + } + case '[': { + std::unique_ptr rv(new vector()); + in >> ch; + if (ch != ']') { + in.unget(); + do { + std::unique_ptr o; + in >> o >> ch; + rv->push_back(std::move(o)); + if (ch != ',' && ch != ']') { + std::cerr << "missing ',' in vector (saw '" << ch << "')" << std::endl; + in.unget(); + } + } while (in && ch != ']'); + } + json = std::move(rv); + return in; + } + case '{': { + std::unique_ptr rv(new map()); + in >> ch; + if (ch != '}') { + in.unget(); + do { + std::unique_ptr key, val; + in >> key >> ch; + if (ch == '}') { + std::cerr << "missing value in map" << std::endl; + } else { + if (ch != ':') { + std::cerr << "missing ':' in map (saw '" << ch << "')" << std::endl; + in.unget(); + } + in >> val >> ch; + } + if (rv->count(key.get())) + std::cerr << "duplicate key in map" << std::endl; + else + (*rv)[std::move(key)] = std::move(val); + if (ch != ',' && ch != '}') { + std::cerr << "missing ',' in map (saw '" << ch << "')" << std::endl; + in.unget(); + } + } while (in && ch != '}'); + } + json = std::move(rv); + return in; + } + default: + if (isalpha(ch) || ch == '_') { + std::string s; + while (isalnum(ch) || ch == '_') { + s += ch; + if (!(in >> ch)) break; + } + in.unget(); + if (s == "true") + json.reset(new True()); + else if (s == "false") + json.reset(new False()); + else if (s == "null") + json.reset(); + else + json.reset(new string(std::move(s))); + return in; + } else { + std::cerr << "unexpected character '" << ch << "' (0x" << hex(ch) << ")" + << std::endl; + } + } + } + return in; +} + +void vector::print_on(std::ostream &out, int indent, int width, const char *pfx) const { + int twidth = width; + bool first = true; + bool oneline = test_width(twidth); + out << '['; + indent += 2; + for (auto &e : *this) { + if (!first) out << ','; + if (!oneline) out << '\n' << pfx << std::setw(indent); + out << ' ' << std::setw(0); + if (e) + e->print_on(out, indent, width - 2, pfx); + else + out << "null"; + first = false; + } + indent -= 2; + if (!first) out << (oneline ? ' ' : '\n'); + if (!oneline) out << std::setw(indent + 1); + out << ']'; +} + +void map::print_on(std::ostream &out, int indent, int width, const char *pfx) const { + int twidth = width; + bool first = true; + bool oneline = test_width(twidth); + // std::cout << "*** width=" << width << " twdith=" << twidth << std::endl; + out << '{'; + indent += 2; + for (auto &e : *this) { + if (!first) out << ','; + if (!oneline) out << '\n' << pfx << std::setw(indent); + out << ' ' << std::setw(0); + e.first->print_on(out, indent, width - 2, pfx); + out << ": "; + if (e.second) + e.second->print_on(out, indent, width - 2, pfx); + else + out << "null"; + first = false; + } + indent -= 2; + if (!first) out << (oneline ? ' ' : '\n'); + if (!oneline) out << std::setw(indent + 1); + out << '}'; +} + +std::string obj::toString() const { + std::stringstream buf; + print_on(buf); + return buf.str(); +} + +map &map::merge(const map &a) { + for (auto &el : a) { + if (!el.second) { + erase(el.first); + } else if (count(el.first)) { + auto &exist = at(el.first); + if (exist->is() && el.second->is()) { + exist->to().merge(el.second->to()); + } else if (exist->is() && el.second->is()) { + auto &vec = exist->to(); + for (auto &vel : el.second->to()) vec.push_back(vel->clone()); + } else { + exist = el.second->clone(); + } + } else { + emplace(el.first->clone().release(), el.second->clone()); + } + } + return *this; +} + +} // namespace json + +void dump(const json::obj &o) { std::cout << &o << std::endl; } +void dump(const json::obj *o) { std::cout << o << std::endl; } diff --git a/backends/tofino/bf-asm/json.h b/backends/tofino/bf-asm/json.h new file mode 100644 index 00000000000..a4ff1777b3a --- /dev/null +++ b/backends/tofino/bf-asm/json.h @@ -0,0 +1,639 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_JSON_H_ // NOLINT(build/header_guard) +#define BF_ASM_JSON_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ordered_map.h" +#include "rvalue_reference_wrapper.h" + +using namespace P4; + +namespace json { + +/* this is std::make_unique, except that is missing in some compilers/versions. We give + * it a different name as other compilers complain about ambiguities if we don't... */ +template +std::unique_ptr mkuniq(Args &&...args) { + std::unique_ptr ret(new T(std::forward(args)...)); + return ret; +} + +class number; +class string; +class vector; +class map; + +class obj { + public: + obj() {} + obj(const obj &) = default; + obj(obj &&) = default; + obj &operator=(const obj &) & = default; + obj &operator=(obj &&) & = default; + virtual ~obj() {} + virtual bool operator<(const obj &a) const = 0; + bool operator>=(const obj &a) const { return !(*this < a); } + bool operator>(const obj &a) const { return a < *this; } + bool operator<=(const obj &a) const { return !(a < *this); } + virtual bool operator==(const obj &a) const = 0; + bool operator!=(const obj &a) const { return !(*this == a); } + virtual bool operator==(const char *str) const { return false; } + virtual bool operator==(const std::string &str) const { return false; } + virtual bool operator==(const string &str) const { return false; } + bool operator!=(const char *str) const { return !(*this == str); } + virtual bool operator==(int64_t val) const { return false; } + bool operator!=(int64_t val) const { return !(*this == val); } + struct ptrless { + bool operator()(const obj *a, const obj *b) const { return b ? a ? *a < *b : true : false; } + bool operator()(const std::unique_ptr &a, const std::unique_ptr &b) const { + return b ? a ? *a < *b : true : false; + } + }; + virtual void print_on(std::ostream &out, int indent = 0, int width = 80, + const char *pfx = "") const = 0; + virtual bool test_width(int &limit) const = 0; + virtual number *as_number() { return nullptr; } + virtual const number *as_number() const { return nullptr; } + virtual string *as_string() { return nullptr; } + virtual const string *as_string() const { return nullptr; } + virtual vector *as_vector() { return nullptr; } + virtual const vector *as_vector() const { return nullptr; } + virtual map *as_map() { return nullptr; } + virtual const map *as_map() const { return nullptr; } + virtual const char *c_str() const { return nullptr; } + template + bool is() const { + return dynamic_cast(this) != nullptr; + } + template + T &to() { + return dynamic_cast(*this); + } + template + const T &to() const { + return dynamic_cast(*this); + } + virtual std::unique_ptr copy() && = 0; // Creates a shallow copy of unique_ptr + virtual std::unique_ptr clone() const = 0; // Creates a deep copy of obj + static std::unique_ptr clone_ptr(const std::unique_ptr &a) { + return a ? a->clone() : std::unique_ptr(); + } + std::string toString() const; +}; + +class True : public obj { + bool operator<(const obj &a) const { + return std::type_index(typeid(*this)) < std::type_index(typeid(a)); + } + bool operator==(const obj &a) const { return dynamic_cast(&a) != 0; } + void print_on(std::ostream &out, int indent = 0, int width = 80, const char *pfx = "") const { + out << "true"; + } + bool test_width(int &limit) const { + limit -= 4; + return limit >= 0; + } + std::unique_ptr copy() && { return mkuniq(std::move(*this)); } + std::unique_ptr clone() const { return mkuniq(); } +}; + +class False : public obj { + bool operator<(const obj &a) const { + return std::type_index(typeid(*this)) < std::type_index(typeid(a)); + } + bool operator==(const obj &a) const { return dynamic_cast(&a) != 0; } + void print_on(std::ostream &out, int indent = 0, int width = 80, const char *pfx = "") const { + out << "false"; + } + bool test_width(int &limit) const { + limit -= 5; + return limit >= 0; + } + std::unique_ptr copy() && { return mkuniq(std::move(*this)); } + std::unique_ptr clone() const { return mkuniq(); } +}; + +class number : public obj { + public: + int64_t val; + explicit number(int64_t l) : val(l) {} + ~number() {} + bool operator<(const obj &a) const override { + if (auto *b = dynamic_cast(&a)) return val < b->val; + return std::type_index(typeid(*this)) < std::type_index(typeid(a)); + } + bool operator==(const obj &a) const override { + if (auto *b = dynamic_cast(&a)) return val == b->val; + return false; + } + bool operator==(int64_t v) const override { return val == v; } + void print_on(std::ostream &out, int indent = 0, int width = 80, + const char *pfx = "") const override { + out << val; + } + bool test_width(int &limit) const override { + char buf[32]; + limit -= snprintf(buf, sizeof(buf), "%" PRId64, val); + return limit >= 0; + } + number *as_number() override { return this; } + const number *as_number() const override { return this; } + std::unique_ptr copy() && override { return mkuniq(std::move(*this)); } + std::unique_ptr clone() const override { return mkuniq(val); } +}; + +class string : public obj, public std::string { + public: + string() {} + string(const string &) = default; + string(const std::string &a) : std::string(a) {} // NOLINT(runtime/explicit) + string(const char *a) : std::string(a) {} // NOLINT(runtime/explicit) + string(string &&) = default; + string(std::string &&a) : std::string(a) {} // NOLINT + string(int64_t l) : std::string(std::to_string(l)) {} // NOLINT + string &operator=(const string &) & = default; + string &operator=(string &&) & = default; + ~string() {} + bool operator<(const obj &a) const override { + if (const string *b = dynamic_cast(&a)) + return static_cast(*this) < static_cast(*b); + return std::type_index(typeid(*this)) < std::type_index(typeid(a)); + } + bool operator==(const obj &a) const override { + if (const string *b = dynamic_cast(&a)) + return static_cast(*this) == static_cast(*b); + return false; + } + bool operator==(const string &a) const override { + return static_cast(*this) == static_cast(a); + } + bool operator==(const char *str) const override { + return static_cast(*this) == str; + } + bool operator==(const std::string &str) const override { + return static_cast(*this) == str; + } + void print_on(std::ostream &out, int indent = 0, int width = 80, + const char *pfx = "") const override { + out << '"' << *this << '"'; + } + bool test_width(int &limit) const override { + limit -= size() + 2; + return limit >= 0; + } + const char *c_str() const override { return std::string::c_str(); } + string *as_string() override { return this; } + const string *as_string() const override { return this; } + std::unique_ptr copy() && override { return mkuniq(std::move(*this)); } + std::unique_ptr clone() const override { return mkuniq(*this); } +}; + +class map; // forward decl + +typedef std::vector> vector_base; +class vector : public obj, public vector_base { + public: + vector() {} + vector(const vector &) = delete; + vector(vector &&) = default; + vector(const std::initializer_list> &init) { + for (auto o : init) push_back(o.get().copy()); + } + vector &operator=(const vector &) & = delete; + vector &operator=(vector &&) & = default; + ~vector() {} + bool operator<(const obj &a) const override { + if (const vector *b = dynamic_cast(&a)) { + auto p1 = begin(), p2 = b->begin(); + while (p1 != end() && p2 != b->end()) { + if (**p1 < **p2) return true; + if (**p1 != **p2) return false; + p1++; + p2++; + } + return p2 != b->end(); + } + return std::type_index(typeid(*this)) < std::type_index(typeid(a)); + } + using obj::operator<=; + using obj::operator>=; + using obj::operator>; + bool operator==(const obj &a) const override { + if (const vector *b = dynamic_cast(&a)) { + auto p1 = begin(), p2 = b->begin(); + while (p1 != end() && p2 != b->end()) { + if (**p1 != **p2) return false; + p1++; + p2++; + } + return (p1 == end() && p2 == b->end()); + } + return false; + } + using obj::operator!=; + void print_on(std::ostream &out, int indent = 0, int width = 80, + const char *pfx = "") const override; + bool test_width(int &limit) const override { + limit -= 2; + for (auto &e : *this) { + if (e ? !e->test_width(limit) : (limit -= 4) < 0) return false; + if ((limit -= 2) < 0) return false; + } + return true; + } + using vector_base::push_back; + void push_back(decltype(nullptr)) { push_back(std::unique_ptr()); } + void push_back(bool t) { + if (t) + push_back(mkuniq(True())); + else + push_back(mkuniq(False())); + } + void push_back(int64_t n) { push_back(mkuniq(number(n))); } + void push_back(int n) { push_back((int64_t)n); } + void push_back(unsigned int n) { push_back((int64_t)n); } + void push_back(uint64_t n) { push_back((int64_t)n); } + void push_back(const char *s) { push_back(mkuniq(string(s))); } + void push_back(std::string s) { push_back(mkuniq(string(s))); } + void push_back(string s) { push_back(mkuniq(s)); } + void push_back(vector &&v) { push_back(mkuniq(std::move(v))); } + void push_back(json::map &&); // NOLINT(whitespace/operators) + vector *as_vector() override { return this; } + const vector *as_vector() const override { return this; } + std::unique_ptr copy() && override { return mkuniq(std::move(*this)); } + std::unique_ptr clone() const override { + vector *v = new vector(); + for (auto &e : *this) v->push_back(clone_ptr(e)); + return std::unique_ptr(v); + } +}; + +typedef ordered_map, obj::ptrless> map_base; +class map : public obj, public map_base { + public: + map() {} + map(const map &) = default; + map(map &&) = default; + map(const std::initializer_list> &init) { + for (auto &pair : init) (*this)[pair.first] = std::move(pair.second).copy(); + } + map &operator=(const map &) & = default; + map &operator=(map &&) & = default; + ~map() { + for (auto &e : *this) delete e.first; + } + bool operator<(const obj &a) const override { + if (const map *b = dynamic_cast(&a)) { + auto p1 = begin(), p2 = b->begin(); + while (p1 != end() && p2 != b->end()) { + if (*p1->first < *p2->first) return true; + if (*p1->first != *p2->first) return false; + if (*p1->second < *p2->second) return true; + if (*p1->second != *p2->second) return false; + p1++; + p2++; + } + return p2 != b->end(); + } + return std::type_index(typeid(*this)) < std::type_index(typeid(a)); + } + using obj::operator<=; + using obj::operator>=; + using obj::operator>; + bool operator==(const obj &a) const override { + if (const map *b = dynamic_cast(&a)) { + auto p1 = begin(), p2 = b->begin(); + while (p1 != end() && p2 != b->end()) { + if (*p1->first != *p2->first) return false; + if (*p1->second != *p2->second) return false; + p1++; + p2++; + } + return (p1 == end() && p2 == b->end()); + } + return false; + } + using obj::operator!=; + std::unique_ptr remove(const char *key) { + string tmp(key); + auto itr = find(&tmp); + if (itr != end()) { + std::unique_ptr val = std::move(itr->second); + this->erase(itr); + return val; + } + return std::unique_ptr(); + } + void print_on(std::ostream &out, int indent = 0, int width = 80, + const char *pfx = "") const override; + bool test_width(int &limit) const override { + limit -= 2; + for (auto &e : *this) { + if (!e.first->test_width(limit)) return false; + if (e.second ? !e.second->test_width(limit) : (limit -= 4) < 0) return false; + if ((limit -= 4) < 0) return false; + } + return true; + } + using map_base::count; + map_base::size_type count(const char *str) const { + string tmp(str); + return count(&tmp); + } + map_base::size_type count(std::string &str) const { + string tmp(str); + return count(&tmp); + } + map_base::size_type count(int64_t n) const { + number tmp(n); + return count(&tmp); + } + // using map_base::operator[]; + obj *operator[](const std::unique_ptr &i) const { + auto rv = find(i.get()); + if (rv != end()) return rv->second.get(); + return 0; + } + obj *operator[](const char *str) const { + string tmp(str); + auto rv = find(&tmp); + if (rv != end()) return rv->second.get(); + return 0; + } + obj *operator[](const std::string &str) const { + string tmp(str); + auto rv = find(&tmp); + if (rv != end()) return rv->second.get(); + return 0; + } + obj *operator[](int64_t n) const { + number tmp(n); + auto rv = find(&tmp); + if (rv != end()) return rv->second.get(); + return 0; + } + + private: + class element_ref { + map &self; + std::unique_ptr key; + map_base::iterator iter; + + public: + element_ref(map &s, const char *k) : self(s) { + string tmp(k); + iter = self.find(&tmp); + if (iter == self.end()) key.reset(new string(std::move(tmp))); + } + element_ref(map &s, int64_t k) : self(s) { + number tmp(k); + iter = self.find(&tmp); + if (iter == self.end()) key.reset(new number(std::move(tmp))); + } + element_ref(map &s, std::unique_ptr &&k) : self(s) { + iter = self.find(k.get()); + if (iter == self.end()) key = std::move(k); + } + void operator=(decltype(nullptr)) { + if (key) { + iter = self.emplace(key.release(), std::unique_ptr()).first; + } else { + assert(iter != self.end()); + iter->second.reset(); + } + } + bool operator=(bool t) { + if (key) { + iter = self.emplace(key.release(), + std::unique_ptr(t ? static_cast(new True()) + : static_cast(new False()))) + .first; + } else { + assert(iter != self.end()); + iter->second.reset(t ? static_cast(new True()) + : static_cast(new False())); + } + return t; + } + bool operator=(void *); // not defined to avoid converting pointers to bool + bool operator==(string &str) { + if (key) return false; + assert(iter != self.end()); + return *iter->second == str; + } + bool operator!=(string &str) { return !(*this == str); } + bool operator==(const std::string &str) { + if (key) return false; + assert(iter != self.end()); + return *iter->second == str; + } + bool operator!=(const std::string &str) { return !(*this == str); } + bool operator==(int64_t v) { + if (key) return false; + assert(iter != self.end()); + return *iter->second == v; + } + bool operator!=(int64_t v) { return !(*this == v); } + const char *operator=(const char *v) { + if (key) { + iter = self.emplace(key.release(), std::unique_ptr(new string(v))).first; + } else { + assert(iter != self.end()); + iter->second.reset(new string(v)); + } + return v; + } + const std::string &operator=(const std::string &v) { + if (key) { + iter = self.emplace(key.release(), std::unique_ptr(new string(v))).first; + } else { + assert(iter != self.end()); + iter->second.reset(new string(v)); + } + return v; + } + int64_t operator=(int64_t v) { + if (key) { + iter = self.emplace(key.release(), std::unique_ptr(new number(v))).first; + } else { + assert(iter != self.end()); + iter->second.reset(new number(v)); + } + return v; + } + int operator=(int v) { return static_cast(*this = static_cast(v)); } + unsigned int operator=(unsigned int v) { return (unsigned int)(*this = (int64_t)v); } +#if defined(__clang__) && defined(__APPLE__) + // Clang ang gcc on Mac OS can't agree whether size_t overloads uint64_t or unsigned long + // or the overload is not defined! + size_t operator=(size_t v) { return (size_t)(*this = (int64_t)v); } +#endif + uint64_t operator=(uint64_t v) { return (uint64_t)(*this = (int64_t)v); } + vector &operator=(vector &&v) { + if (key) { + iter = self.emplace(key.release(), mkuniq(std::move(v))).first; + } else { + assert(iter != self.end()); + iter->second = mkuniq(std::move(v)); + } + return dynamic_cast(*iter->second); + } + map &operator=(map &&v) { + if (key) { + iter = self.emplace(key.release(), mkuniq(std::move(v))).first; + } else { + assert(iter != self.end()); + iter->second = mkuniq(std::move(v)); + } + return dynamic_cast(*iter->second); + } + const std::unique_ptr &operator=(std::unique_ptr &&v) { + if (key) { + iter = self.emplace(key.release(), std::move(v)).first; + } else { + assert(iter != self.end()); + iter->second = std::move(v); + } + return iter->second; + } + obj &operator*() { + assert(!key && iter != self.end()); + return *iter->second; + } + explicit operator bool() const { return !key; } + obj *get() const { return key ? 0 : iter->second.get(); } + obj *operator->() const { return key ? 0 : iter->second.get(); } + operator vector &() { + if (key) iter = self.emplace(key.release(), mkuniq()).first; + return dynamic_cast(*iter->second); + } + operator map &() { + if (key) iter = self.emplace(key.release(), mkuniq()).first; + return dynamic_cast(*iter->second); + } + element_ref operator[](const char *str) { + if (key) iter = self.emplace(key.release(), mkuniq()).first; + map *m = dynamic_cast(iter->second.get()); + if (!m) throw std::runtime_error("lookup in non-map json object"); + return element_ref(*m, str); + } + element_ref operator[](const std::string &str) { + if (key) iter = self.emplace(key.release(), mkuniq()).first; + map *m = dynamic_cast(iter->second.get()); + if (!m) throw std::runtime_error("lookup in non-map json object"); + return element_ref(*m, str.c_str()); + } + element_ref operator[](int64_t n) { + if (key) iter = self.emplace(key.release(), mkuniq()).first; + map *m = dynamic_cast(iter->second.get()); + if (!m) throw std::runtime_error("lookup in non-map json object"); + return element_ref(*m, n); + } + element_ref operator[](std::unique_ptr &&i) { + if (key) iter = self.emplace(key.release(), mkuniq()).first; + map *m = dynamic_cast(iter->second.get()); + if (!m) throw std::runtime_error("lookup in non-map json object"); + return element_ref(*m, std::move(i)); + } + template + void push_back(T &&v) { + vector &vec = *this; + vec.push_back(std::forward(v)); + } + template + bool is() const { + return !key && dynamic_cast(iter->second.get()) != nullptr; + } + template + T &to() { + if (key) iter = self.emplace(key.release(), mkuniq()).first; + return dynamic_cast(*iter->second); + } + }; + friend std::ostream &operator<<(std::ostream &out, const element_ref &el); + + public: + element_ref operator[](const char *str) { return element_ref(*this, str); } + element_ref operator[](const std::string &str) { return element_ref(*this, str.c_str()); } + element_ref operator[](int64_t n) { return element_ref(*this, n); } + element_ref operator[](std::unique_ptr &&i) { return element_ref(*this, std::move(i)); } + using map_base::erase; + map_base::size_type erase(const char *str) { + string tmp(str); + return map_base::erase(&tmp); + } + map_base::size_type erase(int64_t n) { + number tmp(n); + return map_base::erase(&tmp); + } + map *as_map() override { return this; } + const map *as_map() const override { return this; } + std::unique_ptr copy() && override { return mkuniq(std::move(*this)); } + std::unique_ptr clone() const override { + map *m = new map(); + for (auto &e : *this) + m->emplace(e.first ? e.first->clone().release() : nullptr, clone_ptr(e.second)); + return std::unique_ptr(m); + } + + /// Merges the given map into this one and returns this map. For any key collisions, if both + /// have a map, then they are merged recursively; if both have a vector, then the one in the + /// given map is appended to the one in this map; otherwise, the entry in the given map + /// replaces the entry in this one. + map &merge(const map &a); +}; + +inline void vector::push_back(map &&m) { emplace_back(mkuniq(std::move(m))); } + +std::istream &operator>>(std::istream &in, std::unique_ptr &json); +inline std::istream &operator>>(std::istream &in, obj *&json) { + std::unique_ptr p; + in >> p; + if (in) json = p.release(); + return in; +} + +inline std::ostream &operator<<(std::ostream &out, const obj *json) { + json->print_on(out); + return out; +} +inline std::ostream &operator<<(std::ostream &out, const std::unique_ptr &json) { + return out << json.get(); +} +inline std::ostream &operator<<(std::ostream &out, const map::element_ref &el) { + el->print_on(out); + return out; +} + +} // end namespace json + +extern void dump(const json::obj *); +extern void dump(const json::obj &); + +#endif /* BF_ASM_JSON_H_ */ diff --git a/backends/tofino/bf-asm/json_diff.cpp b/backends/tofino/bf-asm/json_diff.cpp new file mode 100644 index 00000000000..554dc117ca6 --- /dev/null +++ b/backends/tofino/bf-asm/json_diff.cpp @@ -0,0 +1,628 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include "fdstream.h" +#include "json.h" +#include "ordered_map.h" + +static bool show_deletion = true; +static bool show_addition = true; +static bool sort_map = true; +static std::vector list_map_keys; +static std::set ignore_keys; +static std::map> ignore_key_indexes; +static std::vector> ignore_intkeys; + +bool is_list_map(json::vector *v, const char *key) { + if (!key) return false; + for (auto &e : *v) + if (json::map *m = dynamic_cast(e.get())) { + if (!m->count(key)) return false; + } else + return false; + return true; +} + +void add_ignore(const char *a) { + while (isspace(*a)) a++; + if (*a == '#' || *a == 0) return; + if (*a == '&' || *a == '=' || *a == '|' || isdigit(*a)) { + int64_t mask, val; + int end = 0; + if (sscanf(a, "%" PRIi64 " %n", &val, &end) >= 1) + ignore_intkeys.emplace_back(-1, val); + else if (sscanf(a, "== %" PRIi64 " %n", &val, &end) >= 1) + ignore_intkeys.emplace_back(-1, val); + else if (sscanf(a, "& %" PRIi64 " == %" PRIi64 " %n", &mask, &val, &end) >= 2) + ignore_intkeys.emplace_back(mask, val); + else if (sscanf(a, "| %" PRIi64 " == %" PRIi64 " %n", &mask, &val, &end) >= 2) + ignore_intkeys.emplace_back(~mask, val ^ mask); + else { + std::cerr << "Unknown ignore expression " << a << std::endl; + return; + } + if (a[end]) std::cerr << "extra text after ignore " << (a + end) << std::endl; + return; + } + if (auto *idx = strchr(a, '[')) { + int64_t val; + int end = 0; + if (sscanf(idx, "[%" PRIi64 " ] %n", &val, &end) >= 1 && end > 0) { + end += idx - a; + while (idx > a && isspace(idx[-1])) --idx; + std::string key(a, idx - a); + ignore_key_indexes[key].insert(val); + } else { + std::cerr << "Unknown ignore expression " << a << std::endl; + return; + } + if (a[end]) std::cerr << "extra text after ignore " << (a + end) << std::endl; + return; + } + ignore_keys.insert(a); +} +bool ignore(json::obj *o) { + if (json::string *s = dynamic_cast(o)) { + if (ignore_keys.count(*s)) return true; + } else if (json::number *n = dynamic_cast(o)) { + for (auto &k : ignore_intkeys) + if ((n->val & k.first) == k.second) return true; + } + return false; +} +bool ignore(std::unique_ptr &o) { return ignore(o.get()); } + +const std::set &ignore_indexes_for_key(json::obj *key) { + if (key && key->as_string() && ignore_key_indexes.count(*key->as_string())) + return ignore_key_indexes.at(*key->as_string()); + static std::set empty; + return empty; +} + +std::map build_list_map(json::vector *v, + const char *key) { + std::map rv; + assert(key); + for (auto &e : *v) { + json::map *m = dynamic_cast(e.get()); + assert(m); + rv[(*m)[key].get()] = m; + } + return rv; +} + +void do_prefix(int indent, const char *prefix) { + std::cout << '\n' << prefix; + if (indent) std::cout << std::setw(indent) << ' ' << std::setw(0); +} + +void do_output(json::obj *o, int indent, const char *prefix, const char *suffix = "") { + do_prefix(indent, prefix); + if (o) + o->print_on(std::cout, indent, 80 - indent, prefix); + else + std::cout << "null"; + std::cout << suffix; +} + +void do_output(int index, json::vector::iterator p, int indent, const char *prefix) { + do_prefix(indent, prefix); + std::cout << '[' << index << "] "; + if (*p) + (*p)->print_on(std::cout, indent, 80 - indent, prefix); + else + std::cout << "null"; +} + +void do_output(json::map::iterator p, int indent, const char *prefix) { + do_prefix(indent, prefix); + p->first->print_on(std::cout, indent, 80 - indent, prefix); + std::cout << ": "; + if (p->second) + p->second->print_on(std::cout, indent, 80 - indent, prefix); + else + std::cout << "null"; +} + +void do_output(std::map::iterator p, int indent, + const char *prefix) { + do_prefix(indent, prefix); + p->first->print_on(std::cout, indent, 80 - indent, prefix); + std::cout << ": "; + if (p->second) + p->second->print_on(std::cout, indent, 80 - indent, prefix); + else + std::cout << "null"; +} + +void do_output(std::map::iterator p, int indent, + const char *prefix) { + do_prefix(indent, prefix); + p->first->print_on(std::cout, indent, 80 - indent, prefix); + std::cout << ": "; + if (p->second) + p->second->print_on(std::cout, indent, 80 - indent, prefix); + else + std::cout << "null"; +} + +bool equiv(json::obj *a, json::obj *b, json::obj *key = nullptr); +bool equiv(std::unique_ptr &a, json::obj *b, json::obj *key = nullptr) { + return equiv(a.get(), b, key); +} +bool equiv(std::unique_ptr &a, std::unique_ptr &b, json::obj *key = nullptr) { + return equiv(a.get(), b.get(), key); +} +void print_diff(json::obj *a, json::obj *b, int indent, json::obj *key = nullptr); +void print_diff(std::unique_ptr &a, std::unique_ptr &b, int indent, + json::obj *key = nullptr) { + print_diff(a.get(), b.get(), indent, key); +} + +json::vector::iterator find(json::vector::iterator p, json::vector::iterator end, json::obj *m) { + while (p < end && !equiv(*p, m)) ++p; + return p; +} + +bool list_map_equiv(json::vector *a, json::vector *b, const char *key) { + auto bmap = build_list_map(b, key); + for (auto &e : *a) { + json::map *m = dynamic_cast(e.get()); + json::obj *ekey = (*m)[key].get(); + if (!bmap.count(ekey)) { + if (show_deletion && !ignore(ekey)) return false; + continue; + } + if (!ignore(ekey) && !equiv(m, bmap[ekey], ekey)) return false; + bmap.erase(ekey); + } + if (show_addition) + for (auto &e : bmap) + if (!ignore(e.first)) return false; + return true; +} +void list_map_print_diff(json::vector *a, json::vector *b, int indent, const char *key) { + auto amap = build_list_map(a, key); + auto bmap = build_list_map(b, key); + auto p1 = amap.begin(), p2 = bmap.begin(); + std::cout << " ["; + indent += 2; + while (p1 != amap.end() && p2 != bmap.end()) { + if (*p1->first < *p2->first) { + if (show_deletion && !ignore(p1->first)) do_output(p1, indent, "-"); + p1++; + continue; + } + if (*p2->first < *p1->first) { + if (show_addition && !ignore(p2->first)) do_output(p2, indent, "+"); + p2++; + continue; + } + if (!ignore(p1->first) && !equiv(p1->second, p2->second, p1->first)) { + int width = 80 - indent, copy; + if (p1->first->test_width(width) && (copy = width) && p1->second && + p1->second->test_width(width) && p2->second && p2->second->test_width(copy)) { + do_output(p1->first, indent, "-", ": "); + std::cout << p1->second; + do_output(p2->first, indent, "+", ": "); + std::cout << p2->second; + } else { + do_output(p1->first, indent, " ", ":"); + print_diff(p1->second, p2->second, indent, p1->first); + } + } + p1++; + p2++; + } + if (show_deletion) + while (p1 != amap.end()) { + if (!ignore(p1->first)) do_output(p1, indent, "-"); + p1++; + } + if (show_addition) + while (p2 != bmap.end()) { + if (!ignore(p2->first)) do_output(p2, indent, "+"); + p2++; + } + indent -= 2; + do_prefix(indent, " "); + std::cout << ']'; +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpotentially-evaluated-expression" +bool equiv(json::vector *a, json::vector *b, const std::set &ignore_idx) { + for (auto key : list_map_keys) + if (is_list_map(a, key) && is_list_map(b, key)) return list_map_equiv(a, b, key); + auto p1 = a->begin(), p2 = b->begin(); + while (p1 != a->end() && p2 != b->end()) { + if (!ignore_idx.count(p1 - a->begin()) && !equiv(*p1, *p2)) { + auto s1 = find(p1, a->end(), p2->get()); + auto s2 = find(p2, b->end(), p1->get()); + if (typeid(**p1) == typeid(**p2) && p1 - a->begin() == p2 - b->begin() && + (s1 - p1 == s2 - p2 || typeid(**p1) == typeid(json::vector) || + typeid(**p1) == typeid(json::map))) + return false; + if (s1 - p1 <= s2 - p2) { + if (show_deletion) return false; + ++p1; + } else { + if (show_addition) return false; + ++p2; + } + } else { + ++p1; + ++p2; + } + } + while (p1 != a->end() && ignore_idx.count(p1 - a->begin())) ++p1; + if (p1 != a->end() && show_deletion) return false; + while (p2 != b->end() && ignore_idx.count(p2 - b->begin())) ++p2; + if (p2 != b->end() && show_addition) return false; + return true; +} +void print_diff(json::vector *a, json::vector *b, const std::set &ignore_idx, int indent) { + for (auto key : list_map_keys) + if (is_list_map(a, key) && is_list_map(b, key)) { + list_map_print_diff(a, b, indent, key); + return; + } + auto p1 = a->begin(), p2 = b->begin(); + std::cout << " ["; + indent += 2; + while (p1 != a->end() && p2 != b->end()) { + if (!ignore_idx.count(p1 - a->begin()) && !equiv(*p1, *p2)) { + auto s1 = find(p1, a->end(), p2->get()); + auto s2 = find(p2, b->end(), p1->get()); + if ((p1 + 1 != a->end() && p2 + 1 != b->end() && equiv(p1[1], p2[1])) || + (typeid(**p1) == typeid(**p2) && p1 - a->begin() == p2 - b->begin() && + (s1 - p1 == s2 - p2 || typeid(**p1) == typeid(json::vector) || + typeid(**p1) == typeid(json::map)))) { + do_prefix(indent, " "); + std::cout << '[' << p1 - a->begin() << "]"; + print_diff(p1->get(), p2->get(), indent); + } else { + if (s1 - p1 <= s2 - p2) { + if (show_deletion) do_output(p1 - a->begin(), p1, indent, "-"); + ++p1; + } else { + if (show_addition) do_output(p2 - b->begin(), p2, indent, "+"); + ++p2; + } + continue; + } + } + + ++p1; + ++p2; + } + if (show_deletion) + while (p1 != a->end()) { + if (!ignore_idx.count(p1 - a->begin())) do_output(p1 - a->begin(), p1, indent, "-"); + ++p1; + } + if (show_addition) + while (p2 != b->end()) { + if (!ignore_idx.count(p2 - b->begin())) do_output(p2 - b->begin(), p2, indent, "+"); + ++p2; + } + indent -= 2; + do_prefix(indent, " "); + std::cout << ']'; +} +#pragma clang diagnostic pop + +std::map build_sort_map(json::map *m) { + std::map rv; + for (auto &e : *m) { + rv[e.first] = e.second.get(); + } + return rv; +} +bool sort_map_equiv(json::map *a, json::map *b) { + auto bmap = build_sort_map(b); + for (auto &e : *a) { + json::obj *ekey = e.first; + if (!bmap.count(ekey)) { + if (show_deletion && !ignore(ekey)) return false; + continue; + } + if (!ignore(ekey) && !equiv(e.second.get(), bmap[ekey], ekey)) return false; + bmap.erase(ekey); + } + if (show_addition) + for (auto &e : bmap) + if (!ignore(e.first)) return false; + return true; +} +void sort_map_print_diff(json::map *a, json::map *b, int indent) { + auto amap = build_sort_map(a); + auto bmap = build_sort_map(b); + auto p1 = amap.begin(), p2 = bmap.begin(); + std::cout << " {"; + indent += 2; + while (p1 != amap.end() && p2 != bmap.end()) { + if (*p1->first < *p2->first) { + if (show_deletion && !ignore(p1->first) && p1->second) do_output(p1, indent, "-"); + p1++; + continue; + } + if (*p2->first < *p1->first) { + if (show_addition && !ignore(p2->first) && p2->second) do_output(p2, indent, "+"); + p2++; + continue; + } + if (!ignore(p1->first) && !equiv(p1->second, p2->second, p1->first)) { + int width = 80 - indent, copy; + if (p1->first->test_width(width) && (copy = width) && p1->second && + p1->second->test_width(width) && p2->second && p2->second->test_width(copy)) { + do_output(p1->first, indent, "-", ": "); + std::cout << p1->second; + do_output(p2->first, indent, "+", ": "); + std::cout << p2->second; + } else { + do_output(p1->first, indent, " ", ":"); + print_diff(p1->second, p2->second, indent, p1->first); + } + } + p1++; + p2++; + } + if (show_deletion) + while (p1 != amap.end()) { + if (!ignore(p1->first)) do_output(p1, indent, "-"); + p1++; + } + if (show_addition) + while (p2 != bmap.end()) { + if (!ignore(p2->first)) do_output(p2, indent, "+"); + p2++; + } + indent -= 2; + do_prefix(indent, " "); + std::cout << '}'; +} + +bool equiv(json::map *a, json::map *b) { + if (sort_map) return sort_map_equiv(a, b); + auto p1 = a->begin(), p2 = b->begin(); + while (p1 != a->end() && p2 != b->end()) { + if (*p1->first < *p2->first) { + if (show_deletion && !ignore(p1->first)) return false; + ++p1; + } else if (*p2->first < *p1->first) { + if (show_addition && !ignore(p2->first)) return false; + ++p2; + } else if (!ignore(p1->first) && !(equiv(p1->second, p2->second, p1->first))) { + return false; + } else { + ++p1; + ++p2; + } + } + if (show_deletion) + for (; p1 != a->end(); ++p1) + if (!ignore(p1->first)) return false; + if (show_addition) + for (; p2 != b->end(); ++p2) + if (!ignore(p2->first)) return false; + return true; +} +void print_diff(json::map *a, json::map *b, int indent) { + if (sort_map) { + sort_map_print_diff(a, b, indent); + return; + } + auto p1 = a->begin(), p2 = b->begin(); + std::cout << " {"; + indent += 2; + while (p1 != a->end() && p2 != b->end()) { + if (*p1->first < *p2->first) { + if (show_deletion && !ignore(p1->first)) do_output(p1, indent, "-"); + p1++; + continue; + } + if (*p2->first < *p1->first) { + if (show_addition && !ignore(p2->first)) do_output(p2, indent, "+"); + p2++; + continue; + } + if (!ignore(p1->first) && !equiv(p1->second, p2->second, p1->first)) { + int width = 80 - indent, copy; + if (p1->first->test_width(width) && (copy = width) && p1->second && + p1->second->test_width(width) && p2->second && p2->second->test_width(copy)) { + do_output(p1->first, indent, "-", ": "); + std::cout << p1->second; + do_output(p2->first, indent, "+", ": "); + std::cout << p2->second; + } else { + do_output(p1->first, indent, " ", ":"); + print_diff(p1->second, p2->second, indent, p1->first); + } + } + p1++; + p2++; + } + if (show_deletion) + for (; p1 != a->end(); ++p1) + if (!ignore(p1->first)) do_output(p1, indent, "-"); + if (show_addition) + for (; p2 != b->end(); ++p2) + if (!ignore(p2->first)) do_output(p2, indent, "+"); + indent -= 2; + do_prefix(indent, " "); + std::cout << '}'; +} + +bool equiv(json::obj *a, json::obj *b, json::obj *key) { + if (a == b) return true; + // Check true for map/vector with nullptr v/s with no elements "{}" + if (!a) { + if (auto m = b->as_map()) { + if (m->empty()) return true; + } + if (auto v = b->as_vector()) { + if (v->empty()) return true; + } + } + if (!b) { + if (auto m = a->as_map()) { + if (m->empty()) return true; + } + if (auto v = a->as_vector()) { + if (v->empty()) return true; + } + } + if (!a || !b) return false; + if (typeid(*a) != typeid(*b)) return false; + if (typeid(*a) == typeid(json::vector)) + return equiv(static_cast(a), static_cast(b), + ignore_indexes_for_key(key)); + if (typeid(*a) == typeid(json::map)) + return equiv(static_cast(a), static_cast(b)); + return *a == *b; +} +void print_diff(json::obj *a, json::obj *b, int indent, json::obj *key) { + if (equiv(a, b)) + return; + else if (!a) { + if (show_deletion) do_output(b, indent, "+"); + return; + } else if (!b) { + if (show_addition) do_output(a, indent, "-"); + return; + } else if (typeid(*a) == typeid(*b)) { + if (typeid(*a) == typeid(json::vector)) { + print_diff(static_cast(a), static_cast(b), + ignore_indexes_for_key(key), indent); + return; + } else if (typeid(*a) == typeid(json::map)) { + print_diff(static_cast(a), static_cast(b), indent); + return; + } + } + do_output(a, indent, "-"); + do_output(b, indent, "+"); +} + +int do_diff(const char *a_name, json::obj *a, const char *b_name, json::obj *b) { + if (equiv(a, b)) return 0; + std::cout << "--- " << a_name << std::endl; + std::cout << "+++ " << b_name << std::endl; + print_diff(a, b, 0); + std::cout << std::endl; + return 1; +} +int do_diff(const char *a_name, std::unique_ptr &a, const char *b_name, + std::unique_ptr &b) { + return do_diff(a_name, a.get(), b_name, b.get()); +} + +int main(int ac, char **av) { + int error = 0; + std::unique_ptr file1; + const char *file1_name = 0; + for (int i = 1; i < ac; i++) + if (av[i][0] == '-' && av[i][1] == 0) { + if (file1) { + std::unique_ptr file2; + if (!(std::cin >> file2) || !file2) { + std::cerr << "Failed reading json from stdin" << std::endl; + error = 2; + } else if (!(error & 2)) + error |= do_diff(file1_name, file1, "", file2); + } else if (!(std::cin >> file1) || !file1) { + std::cerr << "Failed reading json from stdin" << std::endl; + error = 2; + } else + file1_name = ""; + } else if (av[i][0] == '-' || av[i][0] == '+') { + bool flag = av[i][0] == '+'; + for (char *arg = av[i] + 1; *arg;) switch (*arg++) { + case 'a': + show_addition = flag; + break; + case 'd': + show_deletion = flag; + break; + case 'i': + if (*av[++i] == '@') { + std::ifstream file(av[i] + 1); + std::string str; + if (!file) + std::cerr << "Can't read " << av[i] + 1 << std::endl; + else + while (getline(file, str)) add_ignore(str.c_str()); + } else + add_ignore(av[i]); + break; + case 'l': + list_map_keys.push_back(av[++i]); + break; + case 's': + sort_map = flag; + break; + default: + std::cerr << "Unknown option " << (flag ? '+' : '-') << arg[-1] + << std::endl; + error = 2; + } + } else { + std::istream *in = nullptr; + if (auto ext = strrchr(av[i], '.')) { + std::string cmd; + if (!strcmp(ext, ".gz") || !strcmp(ext, ".Z")) + cmd = "zcat "; + else if (!strcmp(ext, ".bz") || !strcmp(ext, ".bz2")) + cmd = "bzcat "; + if (!cmd.empty()) { + cmd += av[i]; + cmd = "2>/dev/null; " + cmd; // ignore errors (Broken Pipe in particular) + auto *pipe = popen(cmd.c_str(), "r"); + if (pipe) { + auto *pstream = new fdstream(fileno(pipe)); + pstream->setclose([pipe]() { pclose(pipe); }); + in = pstream; + } + } + } + if (!in) in = new std::ifstream(av[i]); + if (!in || !*in) { + std::cerr << "Can't open " << av[i] << " for reading" << std::endl; + error = 2; + } else if (file1) { + std::unique_ptr file2; + if (!(*in >> file2) || !file2) { + std::cerr << "Failed reading json from " << av[i] << std::endl; + error = 2; + } else if (!(error & 2)) + error |= do_diff(file1_name, file1, av[i], file2); + } else if (!(*in >> file1) || !file1) { + std::cerr << "Failed reading json from " << av[i] << std::endl; + error = 2; + } else + file1_name = av[i]; + delete in; + } + if (error & 2) std::cerr << "usage: " << av[0] << " [-adi:l:] file1 file2" << std::endl; + return error; +} diff --git a/backends/tofino/bf-asm/lex-yaml.l b/backends/tofino/bf-asm/lex-yaml.l new file mode 100644 index 00000000000..4033978fc18 --- /dev/null +++ b/backends/tofino/bf-asm/lex-yaml.l @@ -0,0 +1,283 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +%x LINESTART LINE1 LINE2 LINE3 COMMENT +%s NORMAL + +%{ +#include +#include +#include +static std::stack indent; +static int parens=0; +static int indent_depth(const char *); +static int parse_num(YYSTYPE *, const char *s, int base); +static int parse_match(YYSTYPE *, const char *s, int bits_per_digit); + +#if YYDEBUG +#undef BEGIN +/* DANGER -- the depends on the internals of how flex sets states, but as + * DANGER -- its only for debugging, its not too bad */ +#define BEGIN(S) ((yy_start) = 1 + 2*(S), \ + yydebug ? fprintf(stderr, "Setting lexer state "#S"\n") : 0) +#define DB(...) fprintf(stderr, __VA_ARGS__) +#else +#define DB(...) +#endif + +#pragma clang diagnostic ignored "-Wnull-conversion" + +%} + +ID [A-Za-z_@$]([-.]?*[A-Za-z0-9_@$])* +STR \"(\\.|[^\n"\\])*\" +%option nounput noyywrap + +%% + +.*|\n { yyless(0); BEGIN(LINESTART); indent.push(0); } +[ \t]* { int depth = indent_depth(yytext); + if (depth < indent.top()) { + indent.pop(); + yyless(0); + return UNINDENT; } + BEGIN(NORMAL); + if (depth > indent.top()) { + indent.push(depth); + return INDENT; } } + +"#line" { BEGIN(LINE1); } +"# " { BEGIN(LINE1); } +[0-9]+ { line_file_map[lineno].second = atoi(yytext)-1; + DB("next line is %s\n", yytext); + BEGIN(LINE2); } +\"[^"]* { line_file_map[lineno].first = yytext+1; + DB("file is '%s'\n", yytext+1); + BEGIN(LINE3); } +[ \t] ; +. { BEGIN(LINE3); } +. ; +\n { lineno++; BEGIN(LINESTART); } +<> { BEGIN(LINESTART); } + +[ \t]*"#" { BEGIN(LINE3); } +. { yyless(0); + if (indent.top() > 0) { + indent.pop(); + return UNINDENT; } + BEGIN(NORMAL); } +<> { if (indent.top() > 0) { + indent.pop(); + return UNINDENT; } + BEGIN(NORMAL); } +[ \t\r]*\n { lineno++; } + +[[({] { parens++; return *yytext; } +[])}] { if (--parens < 0) parens = 0; + return *yytext; } +\n { lineno++; + if (parens == 0) { + BEGIN(LINESTART); + return '\n'; } } +[ \t\r]+ ; +".." { return DOTDOT; } +{ID} { yylval.str = strdup(yytext); return ID; } +{STR} { yylval.str = strndup(yytext+1, yyleng-2); return STR; } +[0-9_]+ { return parse_num(&yylval, yytext, 10); } +0[xX][0-9a-fA-F_]+ { return parse_num(&yylval, yytext+2, 16); } +0[oO][0-7_]+ { return parse_num(&yylval, yytext+2, 8); } +0[bB][0-1_]+ { return parse_num(&yylval, yytext+2, 2); } +0[xX][0-9a-fA-F*_]+ { return parse_match(&yylval, yytext+2, 4); } +0[oO][0-7*_]+ { return parse_match(&yylval, yytext+2, 3); } +0[bB][0-1*_]+ { return parse_match(&yylval, yytext+2, 1); } +"*" { return parse_match(&yylval, yytext, 0); } + +"#".* ; +"/*" { BEGIN(COMMENT); } +"*/" { BEGIN(NORMAL); } +. ; +\n { lineno++; } + +. { return *yytext; } + + +%% + +/* flex's #line generation is broken, so we manually resync so we can debug */ +#line 104 "lex-yaml.l" +int indent_depth(const char *pfx) { + int rv = 0; + while (*pfx) + switch(*pfx++) { + case ' ': rv++; break; + case '\t': rv &= ~7; rv += 8; break; + default: + return rv;} + return rv; +} + +#include "gen/uptr_sizes.h" + +void bigint_mul(VECTOR(uintptr_t) &val, unsigned f) { + unsigned carry = 0; + for (int i = 0; i < val.size; i++) { +#if defined(uint2ptr_t) + uint2ptr_t v = val.data[i]; + v = v * f + carry; + val.data[i] = (uintptr_t)v; + carry = v >> CHAR_BIT * sizeof(uintptr_t); +#elif defined(uinthptr_t) + uinthptr_t lo = val.data[i], + hi = val.data[i] >> CHAR_BIT * sizeof(uinthptr_t); + uintptr_t tmp = (uintptr_t)lo * f + carry; + lo = tmp; + tmp >>= CHAR_BIT * sizeof(uinthptr_t); + tmp += (uintptr_t)hi * f; + carry = tmp >> CHAR_BIT * sizeof(uinthptr_t); + val.data[i] = (tmp << (CHAR_BIT * sizeof(uinthptr_t))) + lo; +#else +#error "No appropriately sized type for bigint_mul" +#endif + } + if (carry) + VECTOR_add(val, carry); +} + +void bigint_add(VECTOR(uintptr_t) &val, unsigned a) { + for (int i = 0; i < val.size; i++) { + if ((val.data[i] += a) >= a) + return; + a = 1; } + VECTOR_add(val, a); +} + +void bigint_init(VECTOR(uintptr_t) &val, int64_t v) { + if (sizeof(int64_t)/sizeof(uintptr_t) > 1) { + VECTOR_init(val, sizeof(int64_t)/sizeof(uintptr_t)); + do { + val.data[val.size++] = v; + v >>= CHAR_BIT * sizeof(uintptr_t) / 2; + v >>= CHAR_BIT * sizeof(uintptr_t) / 2; + } while (v > 0); + } else { + VECTOR_init1(val, v); + } +} + +int parse_num(YYSTYPE *val, const char *s, int base) { + int rv = INT; + val->i = 0; + s--; + while (*++s) { + if (*s == '_') continue; + /* The comparison is intentionally against LONG_MAX, so that we put values larger than + uintptr_t size in big ints. + */ + if (rv == INT && val->i > INT64_MAX/base) { + bigint_init(val->bigi, val->i); + rv = BIGINT; } + if (rv == INT) + val->i *= base; + else + bigint_mul(val->bigi, base); + switch (*s) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if (rv == INT) + val->i += *s - '0'; + else + bigint_add(val->bigi, *s - '0'); + break; + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + if (rv == INT) + val->i += *s - 'a' + 10; + else + bigint_add(val->bigi, *s - 'a' + 10); + break; + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + if (rv == INT) + val->i += *s - 'A' + 10; + else + bigint_add(val->bigi, *s - 'A' + 10); + break; + default: + assert(0); } + if (rv == INT && val->i > 0xffffffff) { + // We limit INT tokens to what will fit in 32 bits (unsigned) even though + // we use a int64_t to hold them, as most parts of the compiler can't deal + // with larger constants. The few places that can deal with >32bit values + // handle BIGINTs + bigint_init(val->bigi, val->i); + rv = BIGINT; } } + return rv; +} + +int parse_match(YYSTYPE *val, const char *s, int bits_per_digit) { + val->match.word0 = val->match.word1 = 0; + int rv = MATCH; + VECTOR(match_t) bigm = EMPTY_VECTOR_INIT; + if (*s == '*' && bits_per_digit == 0) return rv; + unsigned digit = 0, digit_mask = (1U << bits_per_digit) - 1; + decltype(val->match.word0) overflow_mask = digit_mask; + overflow_mask <<= sizeof(val->match.word0) * 8 - bits_per_digit; + s--; + while (*++s) { + if (*s == '_') continue; + if (rv == BIGMATCH || ((val->match.word0 | val->match.word1) & overflow_mask)) { + rv = BIGMATCH; + if (bigm.size < 2) { + VECTOR_resize(bigm, 2); + bigm.data[0].word0 = bigm.data[0].word1 = + bigm.data[1].word0 = bigm.data[1].word1 = 0; } + if ((bigm.data[bigm.size-1].word0 | bigm.data[bigm.size-1].word1) & overflow_mask) { + VECTOR_resize(bigm, bigm.size+1); + bigm.data[bigm.size-1].word0 = bigm.data[bigm.size-1].word1 = 0; } + for (int i = bigm.size-1; i > 0; --i) { + bigm.data[i].word0 <<= bits_per_digit; + bigm.data[i].word0 |= bigm.data[i].word0 >> (64 - bits_per_digit); + bigm.data[i].word1 <<= bits_per_digit; + bigm.data[i].word1 |= bigm.data[i].word1 >> (64 - bits_per_digit); } + bigm.data[1].word0 |= val->match.word0 >> (64 - bits_per_digit); + bigm.data[1].word1 |= val->match.word1 >> (64 - bits_per_digit); } + val->match.word0 <<= bits_per_digit; + val->match.word1 <<= bits_per_digit; + switch (*s) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + digit = *s - '0'; + break; + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + digit = *s - 'a' + 10; + break; + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + digit = *s - 'A' + 10; + break; + case '*': + val->match.word1 |= digit_mask; + digit = 0; + break; + default: + assert(0); } + assert((digit & ~digit_mask) == 0); + val->match.word1 |= digit; + val->match.word0 |= digit_mask & ~digit; } + if (rv == BIGMATCH) { + bigm.data[0] = val->match; + val->bigm = bigm; } + return rv; +} diff --git a/backends/tofino/bf-asm/map.h b/backends/tofino/bf-asm/map.h new file mode 100644 index 00000000000..965b2e6029b --- /dev/null +++ b/backends/tofino/bf-asm/map.h @@ -0,0 +1,255 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_MAP_H_ +#define BF_ASM_MAP_H_ + +#include + +template +inline V get(const std::map &m, T key, V def = V()) { + auto it = m.find(key); + if (it != m.end()) return it->second; + return def; +} + +template +inline V *getref(std::map &m, T key) { + auto it = m.find(key); + if (it != m.end()) return &it->second; + return 0; +} + +template +inline const V *getref(const std::map &m, T key) { + auto it = m.find(key); + if (it != m.end()) return &it->second; + return 0; +} + +template +inline V get(const std::map *m, T key, V def = V()) { + return m ? get(*m, key, def) : def; +} + +template +inline V *getref(std::map *m, T key) { + return m ? getref(*m, key) : 0; +} + +template +inline const V *getref(const std::map *m, T key) { + return m ? getref(*m, key) : 0; +} + +/* iterate over the keys in a map */ +template +struct IterKeys { + class iterator + : public std::iterator::iterator_category, + typename std::iterator_traits::value_type, + typename std::iterator_traits::difference_type, + typename std::iterator_traits::pointer, + typename std::iterator_traits::reference> { + PairIter it; + + public: + iterator() {} + explicit iterator(PairIter i) : it(i) {} + iterator &operator=(PairIter i) { + it = i; + return *this; + } + iterator &operator++() { + ++it; + return *this; + } + iterator &operator--() { + --it; + return *this; + } + iterator operator++(int) { + auto copy = *this; + ++it; + return copy; + } + iterator operator--(int) { + auto copy = *this; + --it; + return copy; + } + bool operator==(const iterator &i) const { return it == i.it; } + bool operator!=(const iterator &i) const { return it != i.it; } + decltype(*&it->first) operator*() const { return it->first; } + decltype(&it->first) operator->() const { return &it->first; } + } b, e; + + template + IterKeys(U &map) : b(map.begin()), e(map.end()) {} + IterKeys(PairIter b, PairIter e) : b(b), e(e) {} + iterator begin() const { return b; } + iterator end() const { return e; } + + protected: + IterKeys() {} +}; + +template +struct IterKeysCopy : IterKeys { + Map m; + explicit IterKeysCopy(Map &&map) : m(std::move(map)) { + // move the map into this object, then setup the iterators + this->b = m.begin(); + this->e = m.end(); + } +}; + +template +IterKeys Keys(Map &m) { + return IterKeys(m); +} + +template +IterKeys Keys(const Map &m) { + return IterKeys(m); +} + +template +IterKeysCopy Keys(Map &&m) { + return IterKeysCopy(std::move(m)); +} + +template +IterKeys Keys(std::pair range) { + return IterKeys(range.first, range.second); +} + +/* iterate over the values in a map */ +template +struct IterValues { + class iterator + : public std::iterator::iterator_category, + typename std::iterator_traits::value_type, + typename std::iterator_traits::difference_type, + typename std::iterator_traits::pointer, + typename std::iterator_traits::reference> { + PairIter it; + + public: + iterator() {} + explicit iterator(PairIter i) : it(i) {} + iterator &operator=(PairIter i) { + it = i; + return *this; + } + iterator &operator++() { + ++it; + return *this; + } + iterator &operator--() { + --it; + return *this; + } + iterator operator++(int) { + auto copy = *this; + ++it; + return copy; + } + iterator operator--(int) { + auto copy = *this; + --it; + return copy; + } + bool operator==(const iterator &i) const { return it == i.it; } + bool operator!=(const iterator &i) const { return it != i.it; } + decltype(*&it->second) operator*() const { return it->second; } + decltype(&it->second) operator->() const { return &it->second; } + } b, e; + + template + IterValues(U &map) : b(map.begin()), e(map.end()) {} + IterValues(PairIter b, PairIter e) : b(b), e(e) {} + iterator begin() const { return b; } + iterator end() const { return e; } + + protected: + IterValues() {} +}; + +template +struct IterValuesCopy : IterValues { + Map m; + explicit IterValuesCopy(Map &&map) : m(std::move(map)) { + // move the map into this object, then setup the iterators + this->b = m.begin(); + this->e = m.end(); + } +}; + +template +IterValues Values(Map &m) { + return IterValues(m); +} + +template +IterValues Values(const Map &m) { + return IterValues(m); +} + +template +IterValuesCopy Values(Map &&m) { + return IterValuesCopy(std::move(m)); +} + +template +IterValues Values(std::pair range) { + return IterValues(range.first, range.second); +} + +/* iterate over the values for a single key in a multimap */ +template +class MapForKey { + M ↦ + typename M::key_type key; + class iterator { + const MapForKey &self; + decltype(map.begin()) it; + + public: + iterator(const MapForKey &s, decltype(map.begin()) i) : self(s), it(i) {} + iterator &operator++() { + if (++it != self.map.end() && it->first != self.key) it = self.map.end(); + return *this; + } + bool operator==(const iterator &i) const { return it == i.it; } + bool operator!=(const iterator &i) const { return it != i.it; } + decltype(*&it->second) operator*() const { return it->second; } + decltype(&it->second) operator->() const { return &it->second; } + }; + + public: + MapForKey(M &m, typename M::key_type k) : map(m), key(k) {} + iterator begin() const { return iterator(*this, map.find(key)); } + iterator end() const { return iterator(*this, map.end()); } +}; + +template +MapForKey ValuesForKey(M &m, typename M::key_type k) { + return MapForKey(m, k); +} + +#endif /* BF_ASM_MAP_H_ */ diff --git a/backends/tofino/bf-asm/mask_counter.h b/backends/tofino/bf-asm/mask_counter.h new file mode 100644 index 00000000000..9628563cb5b --- /dev/null +++ b/backends/tofino/bf-asm/mask_counter.h @@ -0,0 +1,65 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_MASK_COUNTER_H_ +#define BF_ASM_MASK_COUNTER_H_ + +#include + +#include "bitvec.h" + +class MaskCounter { + unsigned mask, val; + bool oflo; + + public: + explicit MaskCounter(unsigned m) : mask(m), val(0), oflo(false) {} + explicit operator bool() const { return !oflo; } + operator unsigned() const { return val; } + bool operator==(const MaskCounter &a) const { return val == a.val && oflo == a.oflo; } + MaskCounter &operator++() { + val = ((val | ~mask) + 1) & mask; + if (val == 0) oflo = true; + return *this; + } + MaskCounter operator++(int) { + MaskCounter tmp(*this); + ++*this; + return tmp; + } + MaskCounter &operator--() { + val = (val - 1) & mask; + if (val == mask) oflo = true; + return *this; + } + MaskCounter operator--(int) { + MaskCounter tmp(*this); + --*this; + return tmp; + } + MaskCounter &clear() { + val = 0; + oflo = false; + return *this; + } + MaskCounter &overflow(bool v = true) { + oflo = v; + return *this; + } +}; + +#endif /* BF_ASM_MASK_COUNTER_H_ */ diff --git a/backends/tofino/bf-asm/match_source.h b/backends/tofino/bf-asm/match_source.h new file mode 100644 index 00000000000..c58a4e8a252 --- /dev/null +++ b/backends/tofino/bf-asm/match_source.h @@ -0,0 +1,81 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#ifndef BF_ASM_MATCH_SOURCE_H_ +#define BF_ASM_MATCH_SOURCE_H_ + +/** + * A source for a match key of a table. The source can either be from the input xbar, or from the + * galois field matrix, as indicated in uArch Section Exact Match Row Vertical/Horizontal (VH) + * Xbars. This class is the parent of HashMatchSource and Phv::Ref. + */ +class MatchSource : public IHasDbPrint { + public: + virtual int fieldlobit() const = 0; + virtual int fieldhibit() const = 0; + virtual unsigned size() const = 0; + virtual int slicelobit() const = 0; + virtual int slicehibit() const = 0; + virtual const char *name() const = 0; + virtual int get_lineno() const = 0; + virtual std::string toString() const = 0; + virtual void dbprint(std::ostream &out) const = 0; +}; + +/** + * The source used by proxy hash tables for their match key. + */ +class HashMatchSource : public MatchSource { + int lo = 0; + int hi = 0; + + public: + int lineno = 0; + HashMatchSource(int line, int l, int h) : lo(l), hi(h), lineno(line) {} + explicit HashMatchSource(value_t value) { + if (CHECKTYPE(value, tCMD)) { + lineno = value.lineno; + if (value != "hash_group") + error(value.lineno, "Hash Match source must come from a hash group"); + if (value.vec.size != 2) error(value.lineno, "Hash Match source requires a range"); + if (CHECKTYPE(value.vec[1], tRANGE)) { + lo = value.vec[1].lo; + hi = value.vec[1].hi; + } + } + } + + int get_lineno() const override { return lineno; } + int fieldlobit() const override { return lo < 0 ? 0 : lo; } + int fieldhibit() const override { return hi < 0 ? 0 : hi; } + unsigned size() const override { return hi >= lo && lo >= 0 ? hi - lo + 1 : 0; } + int slicelobit() const override { return fieldlobit(); } + int slicehibit() const override { return fieldhibit(); } + const char *name() const override { return "hash_group"; } + std::string toString() const override { + std::stringstream str; + str << *this; + return str.str(); + } + + void dbprint(std::ostream &out) const { out << name() << "(" << lo << ".." << hi << ")"; } +}; + +#endif /* BF_ASM_MATCH_SOURCE_H_ */ diff --git a/backends/tofino/bf-asm/match_table.cpp b/backends/tofino/bf-asm/match_table.cpp new file mode 100644 index 00000000000..9fa48fd1a2e --- /dev/null +++ b/backends/tofino/bf-asm/match_table.cpp @@ -0,0 +1,703 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include + +#include "action_bus.h" +#include "algorithm.h" +#include "input_xbar.h" +#include "instruction.h" +#include "misc.h" +#include "stage.h" +#include "tables.h" + +Table::Format *MatchTable::get_format() const { + if (!format && gateway) return gateway->get_format(); + return format.get(); +} + +Table::Format::Field *MatchTable::lookup_field(const std::string &n, const std::string &act) const { + auto *rv = format ? format->field(n) : nullptr; + if (!rv && gateway) rv = gateway->lookup_field(n, act); + return rv; +} + +void MatchTable::common_init_setup(const VECTOR(pair_t) & data, bool ternary, + P4Table::type p4type) { + Table::common_init_setup(data, ternary, p4type); + setup_logical_id(); + if (Target::DYNAMIC_CONFIG()) + if (auto *dconfig = get(data, "dynamic_config")) + if (CHECKTYPESIZE(*dconfig, tMAP)) + for (auto &kv : dconfig->map) dynamic_config.emplace_back(this, kv); + for (auto &kv : data) + if (kv.key == "input_xbar" && CHECKTYPESIZE(kv.value, tMAP)) + input_xbar.emplace_back(InputXbar::create(this, ternary, kv.key, kv.value.map)); +} + +bool MatchTable::common_setup(pair_t &kv, const VECTOR(pair_t) & data, P4Table::type p4type) { + if (Table::common_setup(kv, data, p4type)) { + return true; + } + if (kv.key == "input_xbar" || kv.key == "hash_dist") { + /* done in common_init_setup */ + return true; + } + if (kv.key == "dynamic_config" && Target::DYNAMIC_CONFIG()) { + /* done in common_init_setup */ + return true; + } + if (kv.key == "always_run") { + if ((always_run = get_bool(kv.value)) && !Target::SUPPORT_ALWAYS_RUN()) + error(kv.key.lineno, "always_run not supported on %s", Target::name()); + return true; + } + if (kv.key == "gateway") { + if (CHECKTYPE(kv.value, tMAP)) { + gateway = GatewayTable::create(kv.key.lineno, name_ + " gateway", gress, stage, -1, + kv.value.map); + gateway->set_match_table(this, false); + } + return true; + } + if (kv.key == "idletime") { + if (CHECKTYPE(kv.value, tMAP)) { + idletime = IdletimeTable::create(kv.key.lineno, name_ + " idletime", gress, stage, -1, + kv.value.map); + idletime->set_match_table(this, false); + } + return true; + } + if (kv.key == "selector") { + attached.selector.setup(kv.value, this); + return true; + } + if (kv.key == "selector_length") { + attached.selector_length.setup(kv.value, this); + return true; + } + if (kv.key == "meter_color") { + attached.meter_color.setup(kv.value, this); + return true; + } + if (kv.key == "stats") { + if (kv.value.type == tVEC) + for (auto &v : kv.value.vec) attached.stats.emplace_back(v, this); + else + attached.stats.emplace_back(kv.value, this); + return true; + } + if (kv.key == "meter") { + if (kv.value.type == tVEC) + for (auto &v : kv.value.vec) attached.meters.emplace_back(v, this); + else + attached.meters.emplace_back(kv.value, this); + return true; + } + if (kv.key == "stateful") { + if (kv.value.type == tVEC) + for (auto &v : kv.value.vec) attached.statefuls.emplace_back(v, this); + else + attached.statefuls.emplace_back(kv.value, this); + return true; + } + if (kv.key == "table_counter") { + if (kv.value == "table_miss") + table_counter = TABLE_MISS; + else if (kv.value == "table_hit") + table_counter = TABLE_HIT; + else if (kv.value == "gateway_miss") + table_counter = GATEWAY_MISS; + else if (kv.value == "gateway_hit") + table_counter = GATEWAY_HIT; + else if (kv.value == "gateway_inhibit") + table_counter = GATEWAY_INHIBIT; + else if (kv.value == "disabled") + table_counter = DISABLED; + else + error(kv.value.lineno, "Invalid table counter %s", value_desc(kv.value)); + return true; + } + return false; +} + +bool MatchTable::is_attached(const Table *tbl) const { + return tbl && (tbl == gateway || tbl == idletime || get_attached()->is_attached(tbl)); +} + +bitvec MatchTable::compute_reachable_tables() { + Table::compute_reachable_tables(); + if (gateway) reachable_tables_ |= gateway->reachable_tables(); + if (idletime) reachable_tables_ |= idletime->reachable_tables(); + reachable_tables_ |= attached.compute_reachable_tables(); + return reachable_tables_; +} + +/** + * Return the first default found meter type of a stateful/meter call. If the meter type + * is considered to be default, then all of the meter types would be identical + */ +METER_ACCESS_TYPE MatchTable::default_meter_access_type(bool for_stateful) { + METER_ACCESS_TYPE rv = NOP; + auto actions = get_actions(); + if (actions == nullptr) return rv; + for (auto it = actions->begin(); it != actions->end(); it++) { + if (it->default_only) continue; + for (auto &call : it->attached) { + auto type = call->table_type(); + if (!((type == Table::METER && !for_stateful) || + (type == Table::STATEFUL && for_stateful))) + continue; + // Currently the first argument is the meter type + if (call.args[0].type == Table::Call::Arg::Const) { + return static_cast(call.args[0].value()); + } else if (auto n = call.args[0].name()) { + if (auto *st = call->to()) { + if (auto *act = st->actions->action(call.args[0].name())) { + return static_cast((act->code << 1) | 1); + } + } + } + } + } + return rv; +} + +std::vector MatchTable::get_calls() const { + std::vector rv = Table::get_calls(); + if (attached.selector) rv.emplace_back(attached.selector); + if (attached.selector_length) rv.emplace_back(attached.selector_length); + for (auto &c : attached.stats) + if (c) rv.emplace_back(c); + for (auto &c : attached.meters) + if (c) rv.emplace_back(c); + for (auto &c : attached.statefuls) + if (c) rv.emplace_back(c); + if (attached.meter_color) rv.emplace_back(attached.meter_color); + return rv; +} + +void MatchTable::pass0() { + LOG1("### match table " << name() << " pass0 " << loc()); +#if 0 + // redundant with (and supercedes) choose_logical_id in pass2. That function is much + // better, taking dependencies into account, so logical_id should not be allocated here + alloc_id("logical", logical_id, stage->pass1_logical_id, + LOGICAL_TABLES_PER_STAGE, true, stage->logical_id_use); +#endif + if (logical_id >= 0) { + if (stage->logical_id_use[logical_id] && stage->logical_id_use[logical_id] != this) { + error(lineno, "Duplicate logical id %d use", logical_id); + error(stage->logical_id_use[logical_id]->lineno, "previous use here"); + } + stage->logical_id_use[logical_id] = this; + } + for (auto physid : physical_ids) { + if (stage->physical_id_use[physid] && stage->physical_id_use[physid] != this) { + error(lineno, "Duplicate physical id %d use", physid); + error(stage->physical_id_use[physid]->lineno, "previous use here"); + } + stage->physical_id_use[physid] = this; + } + if (action.check() && action->set_match_table(this, !action.is_direct_call()) != ACTION) + error(action.lineno, "%s is not an action table", action->name()); + attached.pass0(this); +} + +void MatchTable::pass1() { + if (gateway) { + // needs to happen before Actions::pass1 so that extra_next_lut is setup + gateway->setup_map_indexing(this); + } + Table::pass1(); + if (!p4_table) + p4_table = P4Table::alloc(P4Table::MatchEntry, this); + else + p4_table->check(this); + // Set up default action. This will look up action and/or tind for default + // action if the match_table doesnt have one specified + if (default_action.empty()) default_action = get_default_action(); + if (table_counter >= GATEWAY_MISS && !gateway) + error(lineno, "Can't count gateway events on table %s as it doesn't have a gateway", + name()); + if (!p4_params_list.empty()) { + for (auto &p : p4_params_list) { + // bit_width_full should be generated in assembly as 'full_size' in + // the 'p4_param_order'. This is the full size of the field as used + // in p4 program. + if (!p.bit_width_full) p.bit_width_full = p.bit_width; + + std::size_t found = p.name.find(".$valid"); + if (found != std::string::npos) p.is_valid = true; + } + } + if (idletime) { + idletime->logical_id = logical_id; + idletime->pass1(); + } + for (auto &ixb : input_xbar) ixb->pass1(); + for (auto &hd : hash_dist) hd.pass1(this, HashDistribution::OTHER, false); + if (gateway) { + gateway->logical_id = logical_id; + gateway->pass1(); + } +} + +void Table::allocate_physical_ids(unsigned usable) { + if (physical_ids) { + auto unusable = physical_ids - bitvec(usable); + BUG_CHECK(unusable.empty(), "table %s using physical id %d which appears to be invalid", + name(), *unusable.begin()); + return; + } + if (!Target::MATCH_REQUIRES_PHYSID()) return; + for (int i = 0; i < PHYSICAL_TABLES_PER_STAGE; ++i) { + if (!((usable >> i) & 1)) continue; + if (stage->physical_id_use[i]) continue; + physical_ids[i] = 1; + stage->physical_id_use[i] = this; + return; + } + error(lineno, "No physical id available for table %s", name()); +} + +void MatchTable::pass3() { + if (gateway) { + gateway->pass3(); + } +} + +void MatchTable::gen_idletime_tbl_cfg(json::map &stage_tbl) const { + if (idletime) idletime->gen_stage_tbl_cfg(stage_tbl); +} + +#include "tofino/match_table.cpp" // NOLINT(build/include) +#if HAVE_JBAY +#include "jbay/match_table.cpp" // NOLINT(build/include) +#endif /* HAVE_JBAY */ + +template +void MatchTable::write_common_regs(typename TARGET::mau_regs ®s, int type, Table *result) { + /* this follows the order and behavior in stage_match_entry_table.py + * it can be reorganized to be clearer */ + + /*------------------------ + * data path + *-----------------------*/ + if (gress == EGRESS) regs.dp.imem_table_addr_egress |= 1 << logical_id; + + /*------------------------ + * Match Merge + *-----------------------*/ + auto &merge = regs.rams.match.merge; + auto &adrdist = regs.rams.match.adrdist; + if (gress != GHOST) merge.predication_ctl[gress].table_thread |= 1 << logical_id; + if (gress == INGRESS || gress == GHOST) { + merge.logical_table_thread[0].logical_table_thread_ingress |= 1 << logical_id; + merge.logical_table_thread[1].logical_table_thread_ingress |= 1 << logical_id; + merge.logical_table_thread[2].logical_table_thread_ingress |= 1 << logical_id; + } else if (gress == EGRESS) { + merge.logical_table_thread[0].logical_table_thread_egress |= 1 << logical_id; + merge.logical_table_thread[1].logical_table_thread_egress |= 1 << logical_id; + merge.logical_table_thread[2].logical_table_thread_egress |= 1 << logical_id; + } + adrdist.adr_dist_table_thread[timing_thread(gress)][0] |= 1 << logical_id; + adrdist.adr_dist_table_thread[timing_thread(gress)][1] |= 1 << logical_id; + + Actions *actions = action && action->actions ? action->actions.get() : this->actions.get(); + + std::set result_buses; + if (result) { + actions = result->action && result->action->actions ? result->action->actions.get() + : result->actions.get(); + for (auto &row : result->layout) { + int r_bus = row.row * 2; + if (row.bus.count(Layout::RESULT_BUS)) + r_bus += row.bus.at(Layout::RESULT_BUS) & 1; + else if (row.bus.count(Layout::TIND_BUS)) + r_bus += row.bus.at(Layout::TIND_BUS); + else + continue; + result_buses.insert(r_bus); + } + } else { + /* ternary match with no indirection table */ + auto tern_table = this->to(); + BUG_CHECK(tern_table != nullptr); + if (tern_table->indirect_bus >= 0) result_buses.insert(tern_table->indirect_bus); + result = this; + } + + for (auto r_bus : result_buses) { + auto &shift_en = merge.mau_payload_shifter_enable[type][r_bus]; + setup_muxctl(merge.match_to_logical_table_ixbar_outputmap[type][r_bus], logical_id); + setup_muxctl(merge.match_to_logical_table_ixbar_outputmap[type + 2][r_bus], logical_id); + + int default_action = 0; + unsigned adr_mask = 0; + unsigned adr_default = 0; + unsigned adr_per_entry_en = 0; + + /** + * This section of code determines the registers required to determine the + * instruction code to run for this particular table. This uses the information + * provided by the instruction code. + * + * The address is built of two parts, the instruction code and the per flow enable + * bit. These can either come from overhead, or from the default register. + * The keyword $DEFAULT indicates that the value comes from the default + * register + */ + auto instr_call = instruction_call(); + // FIXME: Workaround until a format is provided on the gateway to find the + // action bit section. This will be a quick add on. + if (instr_call.args[0] == "$DEFAULT") { + for (auto it = actions->begin(); it != actions->end(); it++) { + if (it->code != -1) { + adr_default |= it->addr; + break; + } + } + } else if (auto field = instr_call.args[0].field()) { + adr_mask |= (1U << field->size) - 1; + } + + if (instr_call.args[1] == "$DEFAULT") { + adr_default |= ACTION_INSTRUCTION_ADR_ENABLE; + } else if (auto field = instr_call.args[1].field()) { + if (auto addr_field = instr_call.args[0].field()) { + adr_per_entry_en = field->bit(0) - addr_field->bit(0); + } else { + adr_per_entry_en = 0; + } + } + shift_en.action_instruction_adr_payload_shifter_en = 1; + merge.mau_action_instruction_adr_mask[type][r_bus] = adr_mask; + merge.mau_action_instruction_adr_default[type][r_bus] = adr_default; + merge.mau_action_instruction_adr_per_entry_en_mux_ctl[type][r_bus] = adr_per_entry_en; + + if (idletime) idletime->write_merge_regs(regs, type, r_bus); + if (result->action) { + if (auto adt = result->action->to()) { + merge.mau_actiondata_adr_default[type][r_bus] = + adt->determine_default(result->action); + } + shift_en.actiondata_adr_payload_shifter_en = 1; + } + if (!get_attached()->stats.empty()) shift_en.stats_adr_payload_shifter_en = 1; + if (!get_attached()->meters.empty() || !get_attached()->statefuls.empty()) + shift_en.meter_adr_payload_shifter_en = 1; + + result->write_merge_regs(regs, type, r_bus); + } + + /*------------------------ + * Action instruction Address + *-----------------------*/ + int max_code = actions->max_code; + if (options.match_compiler) + if (auto *action_format = lookup_field("action")) + max_code = (1 << (action_format->size - (gateway ? 1 : 0))) - 1; + /** + * The action map can be used if the choices for the instruction are < 8. The map data + * table will be used if the number of choices are between 2 and 8, and references + * the instruction call to determine whether the instruction comes from the map + * data table or the default register. + */ + auto instr_call = instruction_call(); + bool use_action_map = + instr_call.args[0].field() && max_code < ACTION_INSTRUCTION_SUCCESSOR_TABLE_DEPTH; + // FIXME: Workaround until a format is provided on the gateway to find the + // action bit section. This will be a quick add on. + + if (use_action_map) { + merge.mau_action_instruction_adr_map_en[type] |= (1U << logical_id); + for (auto &act : *actions) + if ((act.name != result->default_action) || !result->default_only_action) { + merge.mau_action_instruction_adr_map_data[type][logical_id][act.code / 4] + .set_subfield(act.addr + ACTION_INSTRUCTION_ADR_ENABLE, + (act.code % 4) * TARGET::ACTION_INSTRUCTION_MAP_WIDTH, + TARGET::ACTION_INSTRUCTION_MAP_WIDTH); + } + } + + /** + * This register is now the responsiblity of the driver for all tables, as the driver + * will initialize this value from the initial default action. If we ever want to + * move some of this responsibility back to the compiler, then this code can be used + * for this, but it is currently incorrect for tables that have been split across + * multiple stages for non noop default actions. + if (this->to()) { + merge.mau_action_instruction_adr_miss_value[logical_id] = 0; + } else if (!default_action.empty()) { + auto *act = actions->action(default_action); + merge.mau_action_instruction_adr_miss_value[logical_id] = + ACTION_INSTRUCTION_ADR_ENABLE + act->addr; + } else if (!result->default_action.empty()) { + auto *act = actions->action(result->default_action); + merge.mau_action_instruction_adr_miss_value[logical_id] = + ACTION_INSTRUCTION_ADR_ENABLE + act->addr; } + */ + + /** + * No direct call for a next table, like instruction. The next table can be determined + * from other parameters. If there is a next parameter in the format, then this is the + * field to be used as an extractor. + * + * If there is no next field, but there is more than one possible entry in the hitmap, + * then the action instruction is being used as the index. + * + * If necessary, i.e. something becomes more complex, then perhaps a call needs to be + * added. + * + * Also, a quick note that though the match_next_table_adr_default is not necessary to set, + * the diagram in 6.4.3.3. Next Table Processing, the default register is after the mask. + * However, in hardware, the default register is before the mask. + */ + int next_field_size = result->get_format_field_size("next"); + int action_field_size = result->get_format_field_size("action"); + + if (next_field_size > 0) { + next_table_adr_mask = ((1U << next_field_size) - 1); + } else if (result->get_hit_next().size() > 1) { + next_table_adr_mask = ((1U << action_field_size) - 1); + } + write_next_table_regs(regs, result); + + /*------------------------ + * Immediate data found in overhead + *-----------------------*/ + if (result->format) { + for (auto &row : result->layout) { + int r_bus = row.row * 2; + if (row.bus.count(Layout::RESULT_BUS)) + r_bus += row.bus.at(Layout::RESULT_BUS) & 1; + else if (row.bus.count(Layout::TIND_BUS)) + r_bus += row.bus.at(Layout::TIND_BUS); + else + continue; + merge.mau_immediate_data_mask[type][r_bus] = bitMask(result->format->immed_size); + if (result->format->immed_size > 0) + merge.mau_payload_shifter_enable[type][r_bus].immediate_data_payload_shifter_en = 1; + } + } + if (result->action_bus) { + result->action_bus->write_immed_regs(regs, result); + for (auto &mtab : get_attached()->meters) { + // if the meter table outputs something on the action-bus of the meter + // home row, need to set up the action hv xbar properly + result->action_bus->write_action_regs(regs, result, mtab->home_row(), 0); + } + for (auto &stab : get_attached()->statefuls) { + // if the stateful table outputs something on the action-bus of the meter + // home row, need to set up the action hv xbar properly + result->action_bus->write_action_regs(regs, result, stab->home_row(), 0); + } + } + + // FIXME: + // The action parameters that are stored as immediates in the match + // overhead need to be properly packed into this register. We had been + // previously assuming that the compiler would do that for us, specifying + // the bits needed here as the argument to the action call; eg assembly + // code like: + // default_action: actname(0x100) + // for the default action being actname with the value 0x100 for its + // parameters stored as immediates (which might actually be several + // parameters in the P4 source code.) To get this from the + // default_action_parameters map, we need to look up those argument names + // in the match table format and action aliases and figure out which ones + // correspond to match immediates, and pack the values appropriately. + // Doable but non-trivial, probably requiring a small helper function. Need + // to deal with both exact match and ternary indirect. + // + // For now, most miss configuration registers are only written by the driver + // (since the user API says what miss behavior to perform). The compiler + // (glass) relies on the driver to write them but this could change in + // future. This particular register would only be set if the compiler chose + // to allocate action parameters in match overhead. + // + // if (default_action_parameters.size() > 0) + // merge.mau_immediate_data_miss_value[logical_id] = default_action_parameters[0]; + // else if (result->default_action_parameters.size() > 0) + // merge.mau_immediate_data_miss_value[logical_id] = result->default_action_parameters[0]; + + for (auto &ixb : input_xbar) ixb->write_regs(regs); + /* DANGER -- you might think we should call write_regs on other related things here + * (actions, hash_dist, idletime, gateway) rather than just input_xbar, but those are + * all called by the various callers of this method. Not clear why input_xbar is + * different */ + + if (gress == EGRESS) regs.cfg_regs.mau_cfg_lt_thread |= 1U << logical_id; + if (options.match_compiler && dynamic_cast(this)) return; // skip the rest + + if (table_counter) { + merge.mau_table_counter_ctl[logical_id / 8U].set_subfield(table_counter, + 3 * (logical_id % 8U), 3); + } else { // Set to TABLE_HIT by default + merge.mau_table_counter_ctl[logical_id / 8U].set_subfield(TABLE_HIT, 3 * (logical_id % 8U), + 3); + } +} + +int MatchTable::get_address_mau_actiondata_adr_default(unsigned log2size, bool per_flow_enable) { + int huffman_ones = log2size > 2 ? log2size - 3 : 0; + BUG_CHECK(huffman_ones < 7); + int rv = (1 << huffman_ones) - 1; + rv = ((rv << 10) & 0xf8000) | (rv & 0x1f); + if (!per_flow_enable) rv |= 1 << 22; + return rv; +} + +/** + * Generates the hash_bits node for a single hash_function node in the JSON. + * + * Will add the impact of a single hash_table (64 bit section of the input xbar) to the hash + * bits. If the table requires multiple hash_tables, then the previous hash table value will + * be looked up and added. FIXME: At some point refactor this function to not keep + * doing this rewrite. + * + * The JSON for each hash bit has the following: + * hash_bit - The hash bit in which this is output on the Galois matrix. (Really whatever + * this bit position is just has to coordinate across the other driver structures, but + * those are also based on the Galois matrix position). + * seed - the bit that is xored in at the end of the calcuation + * bits_to_xor - The field bits from the P4 API that will determine the value of this bit, + * and must be XORed for this bit. This is a vector of fields with 4 values. + * - field_bit - The p4 field bit to be XORed + * - field_name - The p4 field name to be XORed + * The next two parameters are only needed for dynamic_key_masks, as they indicate + * to the driver which bit to turn off + * - hash_match_group - Which 128 bit input xbar group this bit is appearing in (0-7) + * - hash_match_group_bit - The bit offset within the 128 bit input xbar group. + */ +void MatchTable::gen_hash_bits(const std::map &hash_table, + InputXbar::HashTable hash_table_id, json::vector &hash_bits, + unsigned hash_group_no, bitvec hash_bits_used) const { + for (auto &col : hash_table) { + if (!hash_bits_used.getbit(col.first)) continue; + json::map hash_bit; + bool hash_bit_added = false; + json::vector *bits_to_xor = nullptr; + // FIXME: This function has a lot of unnecessary copying and moving around. + for (auto &hb : hash_bits) { + if (hb->to()["hash_bit"]->to() == json::number(col.first)) { + bits_to_xor = &(hb->to()["bits_to_xor"]->to()); + hash_bit_added = true; + } + } + if (!hash_bit_added) bits_to_xor = &(hash_bit["bits_to_xor"] = json::vector()); + hash_bit["hash_bit"] = col.first; + BUG_CHECK(input_xbar.size() == 1, "%s does not have one input xbar", name()); + hash_bit["seed"] = input_xbar[0]->get_seed_bit(hash_group_no, col.first); + for (const auto &bit : col.second.data) { + if (auto ref = input_xbar[0]->get_hashtable_bit(hash_table_id, bit)) { + std::string field_name, global_name; + field_name = ref.name(); + + auto field_bit = remove_name_tail_range(field_name) + ref.lobit(); + global_name = field_name; + + // Look up this field in the param list to get a custom key + // name, if present. + auto p = find_p4_param(field_name); + if (!p && !p4_params_list.empty()) { + warning(col.second.lineno, + "Cannot find field name %s in p4_param_order " + "for table %s", + field_name.c_str(), name()); + } else if (p && !p->key_name.empty()) { + field_name = p->key_name; + } + auto group = input_xbar[0]->hashtable_input_group(hash_table_id); + int group_bit = bit; + // FIXME -- this adjustment is a hack for tofino1/2. Should have a virtual + // method on InputXbar? or something in Target? + if (group.index != hash_table_id.index && (hash_table_id.index & 1)) + group_bit += 64; + bits_to_xor->push_back( + json::map{{"field_bit", json::number(field_bit)}, + {"field_name", json::string(field_name)}, + {"global_name", json::string(global_name)}, + {"hash_match_group", json::number(group.index)}, + {"hash_match_group_bit", json::number(group_bit)}}); + } + } + if (!hash_bit_added) hash_bits.push_back(std::move(hash_bit)); + } +} + +void MatchTable::add_hash_functions(json::map &stage_tbl) const { + json::vector &hash_functions = stage_tbl["hash_functions"] = json::vector(); + // TODO: Hash functions are not generated for ALPM atcams as the + // partition index bits used in hash which is a compiler generated field and + // should not be in 'match_key_fields'. The tests in p4factory are written + // with match_spec to not include the partition index field. Glass also + // generates an empty 'hash_functions' node + if (is_alpm()) return; + // Emit hash info only if p4_param_order (match_key_fields) are present + // FIXME: This input_xbar is populated if its a part of the hash_action + // table or the hash_distribution which is incorrect. This should move + // inside the hash_dist so this condition does not occur in the + // hash_action table + bitvec hash_matrix_req; + hash_matrix_req.setrange(0, EXACT_HASH_GROUP_SIZE); + if (!p4_params_list.empty() && !input_xbar.empty()) { + BUG_CHECK(input_xbar.size() == 1, "%s does not have one input xbar", name()); + auto ht = input_xbar[0]->get_hash_tables(); + if (ht.size() > 0) { + // Merge all bits to xor across multiple hash ways in single + // json::vector for each hash bit + for (const auto hash_table : ht) { + json::map hash_function; + json::vector &hash_bits = hash_function["hash_bits"] = json::vector(); + hash_function["hash_function_number"] = hash_table.first.uid(); + gen_hash_bits(hash_table.second, hash_table.first, hash_bits, + hash_table.first.uid(), hash_matrix_req); + hash_functions.push_back(std::move(hash_function)); + } + } + } +} + +void MatchTable::add_all_reference_tables(json::map &tbl, Table *match_table) const { + auto mt = (!match_table) ? this : match_table; + json::vector &action_data_table_refs = tbl["action_data_table_refs"]; + json::vector &selection_table_refs = tbl["selection_table_refs"]; + json::vector &meter_table_refs = tbl["meter_table_refs"]; + json::vector &statistics_table_refs = tbl["statistics_table_refs"]; + json::vector &stateful_table_refs = tbl["stateful_table_refs"]; + add_reference_table(action_data_table_refs, mt->action); + if (auto a = mt->get_attached()) { + if (a->selector) { + unsigned sel_mask = (1U << METER_TYPE_START_BIT) - 1; + sel_mask &= ~((1U << SELECTOR_LOWER_HUFFMAN_BITS) - 1); + add_reference_table(selection_table_refs, a->selector); + } + for (auto &m : a->meters) { + add_reference_table(meter_table_refs, m); + } + for (auto &s : a->stats) { + add_reference_table(statistics_table_refs, s); + } + for (auto &s : a->statefuls) { + add_reference_table(stateful_table_refs, s); + } + } +} diff --git a/backends/tofino/bf-asm/meter.cpp b/backends/tofino/bf-asm/meter.cpp new file mode 100644 index 00000000000..e44206a6804 --- /dev/null +++ b/backends/tofino/bf-asm/meter.cpp @@ -0,0 +1,1036 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "data_switchbox.h" +#include "input_xbar.h" +#include "misc.h" +#include "stage.h" +#include "tables.h" + +// target specific template specializations +#include "tofino/meter.h" +#if HAVE_JBAY +#include "jbay/meter.h" +#endif /* HAVE_JBAY */ + +Table::Layout::bus_type_t MeterTable::default_bus_type() const { + // FIXME -- this is a bit of a hack -- if color_mapram_addr has been set, we want the + // bus_type for color maprams, not for the meter proper (which should not actually + // have a bus specified?) + if (color_mapram_addr == IDLE_MAP_ADDR) return Layout::IDLE_BUS; + warning(lineno, "meter table should not have bus:, will be ignored"); + return Layout::SEARCH_BUS; +} + +void MeterTable::setup(VECTOR(pair_t) & data) { + common_init_setup(data, false, P4Table::Stateful); + for (auto &kv : MapIterChecked(data, true)) { + if (common_setup(kv, data, P4Table::Meter)) { + } else if (kv.key == "input_xbar") { + if (CHECKTYPE(kv.value, tMAP)) + input_xbar.emplace_back(InputXbar::create(this, false, kv.key, kv.value.map)); + } else if (kv.key == "color_aware") { + if (kv.value == "per_flow") + color_aware = color_aware_per_flow_enable = true; + else + color_aware = get_bool(kv.value); + } else if (kv.key == "color_maprams") { + if (CHECKTYPE(kv.value, tMAP)) { + if (auto addr_type = get(kv.value.map, "address")) { + if (CHECKTYPE(*addr_type, tSTR)) { + if (*addr_type == "idletime") + color_mapram_addr = IDLE_MAP_ADDR; + else if (*addr_type == "stats") + color_mapram_addr = STATS_MAP_ADDR; + else + error(addr_type->lineno, "Unrecognized color mapram address type %s", + addr_type->s); + } + } + setup_layout(color_maprams, kv.value.map, " color_maprams"); + if (auto *vpn = get(kv.value.map, "vpns")) + if (CHECKTYPE(*vpn, tVEC)) setup_vpns(color_maprams, &vpn->vec, true); + } + } else if (kv.key == "pre_color") { + if (CHECKTYPE(kv.value, tCMD)) { + if (kv.value != "hash_dist") + error(kv.value.lineno, "Pre color must come from hash distribution"); + if (kv.value.vec.size != 3) + error(kv.value.lineno, + "Pre color hash distribution requires two parameters," + " but has %d", + kv.value.vec.size); + if (CHECKTYPE(kv.value.vec[1], tINT)) pre_color_hash_dist_unit = kv.value.vec[1].i; + if (CHECKTYPE(kv.value.vec[2], tRANGE)) { + auto range = kv.value.vec[2]; + int diff = range.hi - range.lo + 1; + if (diff != 2 || range.lo % 2 != 0) + error(kv.value.lineno, "Invalid hash distribution range for precolor"); + pre_color_bit_lo = range.lo; + } + } + } else if (kv.key == "type") { + if (kv.value == "standard") + type = STANDARD; + else if (kv.value == "lpf") + type = LPF; + else if (kv.value == "wred") + type = RED; + else + error(kv.value.lineno, "Unknown meter type %s", value_desc(kv.value)); + } else if (kv.key == "red_output") { + if (CHECKTYPE(kv.value, tMAP)) { + for (auto &v : kv.value.map) { + if (CHECKTYPE(v.key, tSTR) && CHECKTYPE(v.value, tINT)) { + if (v.key == "drop") + red_drop_value = v.value.i; + else if (v.key == "nodrop") + red_nodrop_value = v.value.i; + else + error(kv.value.lineno, "Unknown meter red param: %s", v.key.s); + } + } + } + } else if (kv.key == "count") { + if (kv.value == "bytes") + count = BYTES; + else if (kv.value == "packets") + count = PACKETS; + else + error(kv.value.lineno, "Unknown meter count %s", value_desc(kv.value)); + } else if (kv.key == "teop") { + if (gress != EGRESS) error(kv.value.lineno, "tEOP can only be used in EGRESS"); + if (!Target::SUPPORT_TRUE_EOP()) + error(kv.value.lineno, "tEOP is not available on device"); + if (CHECKTYPE(kv.value, tINT)) { + teop = kv.value.i; + if (teop < 0 || teop > 3) + error(kv.value.lineno, "Invalid tEOP bus %d, valid values are 0-3", teop); + } + BUG_CHECK(!stage->teop[teop].first, + "previously used tEOP bus %d used again in stage %d", teop, stage->stageno); + stage->teop[teop] = {true, stage->stageno}; + } else if (kv.key == "green") { + if (CHECKTYPE(kv.value, tINT)) { + green_value = kv.value.i; + } + } else if (kv.key == "yellow") { + if (CHECKTYPE(kv.value, tINT)) { + yellow_value = kv.value.i; + } + } else if (kv.key == "red") { + if (CHECKTYPE(kv.value, tINT)) { + red_value = kv.value.i; + } + } else if (kv.key == "profile") { + if (CHECKTYPE(kv.value, tINT)) { + profile = kv.value.i; + } + } else if (kv.key == "sweep_interval") { + if (CHECKTYPE(kv.value, tINT)) { + // sweep_interval value in assembly if present is from + // meter_sweep_interval pragma in p4 program. Allowed values for + // the meter_sweep_interval register are [0:20]. but [5:20] are + // only to be used with shifting meter time scale. We check and + // throw an error if value is present and not in range[0:4] + int intvl = kv.value.i; + if (intvl >= 0 && intvl <= 4) + sweep_interval = intvl; + else + error( + lineno, + "Invalid meter sweep interval of %d. Allowed values are in the range[0:4]", + intvl); + } + } else if (kv.key == "bytecount_adjust") { + if (CHECKTYPE(kv.value, tINT)) { + bytecount_adjust = kv.value.i; + } + } else { + warning(kv.key.lineno, "ignoring unknown item %s in table %s", value_desc(kv.key), + name()); + } + } + if (teop >= 0 && count != BYTES) error(lineno, "tEOP bus can only used when counting bytes"); + if (Target::SRAM_GLOBAL_ACCESS()) + alloc_global_srams(); + else + alloc_rams(true, stage->sram_use); +} + +void MeterTable::pass1() { + LOG1("### Meter table " << name() << " pass1 " << loc()); + if (!p4_table) + p4_table = P4Table::alloc(P4Table::Meter, this); + else + p4_table->check(this); + alloc_vpns(); + alloc_maprams(); + if (color_maprams.empty() && type != LPF && type != RED) + error(lineno, "Missing color_maprams in meter table %s", name()); + if (uses_colormaprams() && color_mapram_addr == NO_COLOR_MAP) + error(lineno, "Missing color mapram address type in table %s", name()); + for (auto &r : color_maprams) { + for (auto &memunit : r.memunits) { + BUG_CHECK(memunit.row == r.row, "memunit on wrong row"); + if (Table *old = stage->mapram_use[r.row][memunit.col]) + error(r.lineno, + "Table %s trying to use mapram %d,%d for color, which is " + "in use by table %s", + name(), r.row, memunit.col, old->name()); + stage->mapram_use[r.row][memunit.col] = this; + } + } + if (!no_vpns && !color_maprams.empty() && color_maprams[0].vpns.empty()) + setup_vpns(color_maprams, 0); + std::sort(layout.begin(), layout.end(), + [](const Layout &a, const Layout &b) -> bool { return a.row > b.row; }); + stage->table_use[timing_thread(gress)] |= Stage::USE_METER; + if (type == LPF || type == RED) + stage->table_use[timing_thread(gress)] |= Stage::USE_METER_LPF_RED; + for (auto &ixb : input_xbar) ixb->pass1(); + for (auto &hd : hash_dist) hd.pass1(this, HashDistribution::OTHER, false); + int prev_row = -1; + for (auto &row : layout) { + if (home_rows.count(row.row)) prev_row = -1; + + if (prev_row >= 0) + need_bus(lineno, stage->overflow_bus_use, row.row, "Overflow"); + else + need_bus(lineno, stage->meter_bus_use, row.row, "Meter data"); + for (int r = (row.row + 1) | 1; r < prev_row; r += 2) + need_bus(lineno, stage->overflow_bus_use, r, "Overflow"); + prev_row = row.row; + } + Synth2Port::pass1(); +} + +void MeterTable::pass2() { + LOG1("### Meter table " << name() << " pass2 " << loc()); + for (auto &ixb : input_xbar) ixb->pass2(); + + for (auto match_table : get_match_tables()) { + for (auto &hd : match_table->hash_dist) { + if (hd.id == pre_color_hash_dist_unit) { + hd.meter_pre_color = true; + hd.meter_mask_index = pre_color_bit_lo / 2; + } + } + } + if (get_match_tables().size() > 1 && color_mapram_addr == IDLE_MAP_ADDR) + error(lineno, "Shared meter cannot use idletime addressing for color maprams"); + for (auto &hd : hash_dist) hd.pass2(this); +} + +void MeterTable::pass3() { LOG1("### Meter table " << name() << " pass3 " << loc()); } + +int MeterTable::direct_shiftcount() const { + return 64 + METER_ADDRESS_ZERO_PAD - 7; // meters are always 128 bits wide +} + +int MeterTable::indirect_shiftcount() const { + return METER_ADDRESS_ZERO_PAD - 7; // meters are always 128 bits wide +} + +int MeterTable::address_shift() const { + return 7; // meters are always 128 bits wide +} + +int MeterTable::color_shiftcount(Table::Call &call, int group, int tcam_shift) const { + int extra_padding = 0; + int zero_pad = 0; + if (color_mapram_addr == IDLE_MAP_ADDR) { + extra_padding = IDLETIME_ADDRESS_ZERO_PAD - IDLETIME_HUFFMAN_BITS; + zero_pad = IDLETIME_ADDRESS_ZERO_PAD; + } else if (color_mapram_addr == STATS_MAP_ADDR) { + extra_padding = STAT_ADDRESS_ZERO_PAD - STAT_METER_COLOR_LOWER_HUFFMAN_BITS; + zero_pad = STAT_ADDRESS_ZERO_PAD; + } + + if (call.args[0].name() && strcmp(call.args[0].name(), "$DIRECT") == 0) { + return 64 + tcam_shift + extra_padding; + } else if (auto f = call.args[0].field()) { + return f->by_group[group]->bit(0) % 128U + extra_padding; + } else if (auto f = call.args[1].field()) { + return f->bit(0) + zero_pad; + } else { + return 0; + } +} + +unsigned MeterTable::determine_shiftcount(Table::Call &call, int group, unsigned word, + int tcam_shift) const { + return determine_meter_shiftcount(call, group, word, tcam_shift); +} + +template +void MeterTable::write_merge_regs_vt(REGS ®s, MatchTable *match, int type, int bus, + const std::vector &args) { + auto &merge = regs.rams.match.merge; + unsigned adr_mask = 0U; + unsigned per_entry_en_mux_ctl = 0U; + unsigned adr_default = 0U; + unsigned meter_type_position = 0U; + METER_ACCESS_TYPE default_type = match->default_meter_access_type(false); + AttachedTable::determine_meter_merge_regs(match, type, bus, args, default_type, adr_mask, + per_entry_en_mux_ctl, adr_default, + meter_type_position); + merge.mau_meter_adr_default[type][bus] = adr_default; + merge.mau_meter_adr_mask[type][bus] = adr_mask; + merge.mau_meter_adr_per_entry_en_mux_ctl[type][bus] = per_entry_en_mux_ctl; + merge.mau_meter_adr_type_position[type][bus] = meter_type_position; +} + +template +void MeterTable::write_color_regs(REGS ®s, MatchTable *match, int type, int bus, + const std::vector &args) { + BUG_CHECK(uses_colormaprams(), "meter %s does not use color maprams, but uses color?", name()); + auto &merge = regs.rams.match.merge; + unsigned adr_mask = 0U; + unsigned per_entry_en_mux_ctl = 0U; + unsigned adr_default = 0U; + unsigned meter_type_position = 0U; + AttachedTable::determine_meter_merge_regs(match, type, bus, args, METER_COLOR_ACCESS, adr_mask, + per_entry_en_mux_ctl, adr_default, + meter_type_position); + + // Based on the uArch section 6.2.8.4.9 Map RAM Addressing, color maprams can be + // addressed by either idletime or stats based addresses. Which address is used + // can be specified in the asm file, and is built according to the specification + + if (color_mapram_addr == IDLE_MAP_ADDR) { + unsigned idle_mask = (1U << IDLETIME_ADDRESS_BITS) - 1; + unsigned full_idle_mask = (1U << IDLETIME_FULL_ADDRESS_BITS) - 1; + unsigned shift_diff = METER_LOWER_HUFFMAN_BITS - IDLETIME_HUFFMAN_BITS; + merge.mau_idletime_adr_mask[type][bus] = (adr_mask >> shift_diff) & idle_mask; + merge.mau_idletime_adr_default[type][bus] = (adr_default >> shift_diff) & full_idle_mask; + if (per_entry_en_mux_ctl > shift_diff) + merge.mau_idletime_adr_per_entry_en_mux_ctl[type][bus] = + per_entry_en_mux_ctl - shift_diff; + else + merge.mau_idletime_adr_per_entry_en_mux_ctl[type][bus] = 0; + } else if (color_mapram_addr == STATS_MAP_ADDR) { + unsigned stats_mask = (1U << STAT_ADDRESS_BITS) - 1; + unsigned full_stats_mask = (1U << STAT_FULL_ADDRESS_BITS) - 1; + unsigned shift_diff = METER_LOWER_HUFFMAN_BITS - STAT_METER_COLOR_LOWER_HUFFMAN_BITS; + merge.mau_stats_adr_mask[type][bus] = (adr_mask >> shift_diff) & stats_mask; + merge.mau_stats_adr_default[type][bus] = (adr_default >> shift_diff) & full_stats_mask; + if (per_entry_en_mux_ctl > shift_diff) + merge.mau_stats_adr_per_entry_en_mux_ctl[type][bus] = per_entry_en_mux_ctl - shift_diff; + else + merge.mau_stats_adr_per_entry_en_mux_ctl[type][bus] = 0; + } else { + BUG(); + } +} +FOR_ALL_REGISTER_SETS(INSTANTIATE_TARGET_TEMPLATE, void MeterTable::write_color_regs, mau_regs &, + MatchTable *, int, int, const std::vector &); + +template +void MeterTable::setup_exact_shift(REGS ®s, int bus, int group, int word, int word_group, + Call &meter_call, Call &color_call) { + auto &merge = regs.rams.match.merge; + int shiftcount = determine_shiftcount(meter_call, group, word, 0); + merge.mau_meter_adr_exact_shiftcount[bus][word_group] = shiftcount; + if (uses_colormaprams()) { + int color_shift = color_shiftcount(color_call, group, 0); + if (color_mapram_addr == IDLE_MAP_ADDR) { + merge.mau_idletime_adr_exact_shiftcount[bus][word_group] = color_shift; + merge.mau_payload_shifter_enable[0][bus].idletime_adr_payload_shifter_en = 1; + } else if (color_mapram_addr == STATS_MAP_ADDR) { + merge.mau_stats_adr_exact_shiftcount[bus][word_group] = color_shift; + merge.mau_payload_shifter_enable[0][bus].stats_adr_payload_shifter_en = 1; + } + } +} +FOR_ALL_REGISTER_SETS(INSTANTIATE_TARGET_TEMPLATE, void MeterTable::setup_exact_shift, mau_regs &, + int, int, int, int, Call &, Call &); + +template +void MeterTable::setup_tcam_shift(REGS ®s, int bus, int tcam_shift, Call &meter_call, + Call &color_call) { + auto &merge = regs.rams.match.merge; + int shiftcount = determine_shiftcount(meter_call, 0, 0, tcam_shift); + merge.mau_meter_adr_tcam_shiftcount[bus] = shiftcount; + if (uses_colormaprams()) { + int color_shift = color_shiftcount(color_call, 0, tcam_shift); + if (color_mapram_addr == IDLE_MAP_ADDR) { + merge.mau_idletime_adr_tcam_shiftcount[bus] = color_shift; + merge.mau_payload_shifter_enable[1][bus].idletime_adr_payload_shifter_en = 1; + } else if (color_mapram_addr == STATS_MAP_ADDR) { + merge.mau_stats_adr_tcam_shiftcount[bus] = color_shift; + merge.mau_payload_shifter_enable[1][bus].stats_adr_payload_shifter_en = 1; + } + } +} +FOR_ALL_REGISTER_SETS(INSTANTIATE_TARGET_TEMPLATE, void MeterTable::setup_tcam_shift, mau_regs &, + int, int, Call &, Call &); + +template +void MeterTable::write_regs_home_row(REGS ®s, unsigned row) { + auto &map_alu = regs.rams.map_alu; + auto &map_alu_row = map_alu.row[row]; + auto &adrdist = regs.rams.match.adrdist; + unsigned side = 1; // Meter can only be on right side + int minvpn, maxvpn; + layout_vpn_bounds(minvpn, maxvpn, true); + + if (home_rows.size() > 1) { + int sparevpn; + layout_vpn_bounds(minvpn, sparevpn, false); + bool block_start = false; + bool block_end = false; + minvpn = INT_MAX; + maxvpn = INT_MIN; + for (Layout &logical_row : layout) { + // Block Start with the home row and End with the Spare VPN + if (logical_row.row / 2U == row) block_start = true; + + if (block_start) { + for (auto v : logical_row.vpns) { + if (v == sparevpn) { + block_end = true; + break; + } + + if (v < minvpn) minvpn = v; + if (v > maxvpn) maxvpn = v; + } + } + if (block_end) { + BUG_CHECK(minvpn != INT_MAX && maxvpn != INT_MIN); + break; + } + } + BUG_CHECK(block_start && block_end); + } + + int meter_group_index = row / 2U; + auto &meter = map_alu.meter_group[meter_group_index].meter; + auto &meter_ctl = meter.meter_ctl; + auto &red_value_ctl = meter.red_value_ctl; + + int first_home_row = *home_rows.begin(); + if (count == BYTES) { + auto meter_bytecount_adjust_size = meter_ctl.meter_bytecount_adjust.size(); + auto meter_bytecount_adjust_mask = ((1U << meter_bytecount_adjust_size) - 1); + int bytecount_adjust_max = (1U << (meter_bytecount_adjust_size - 1)) - 1; + int bytecount_adjust_min = -1 * (1U << (meter_bytecount_adjust_size - 1)); + if (bytecount_adjust > bytecount_adjust_max || bytecount_adjust < bytecount_adjust_min) { + error(lineno, + "The bytecount adjust value of %d on meter %s " + "does not fit within allowed range for %d bits - { %d, %d }", + bytecount_adjust, name(), meter_bytecount_adjust_size, bytecount_adjust_min, + bytecount_adjust_max); + } + meter_ctl.meter_bytecount_adjust = bytecount_adjust & meter_bytecount_adjust_mask; + } + auto &delay_ctl = map_alu.meter_alu_group_data_delay_ctl[meter_group_index]; + delay_ctl.meter_alu_right_group_delay = + Target::METER_ALU_GROUP_DATA_DELAY() + row / 4 + stage->tcam_delay(gress); + switch (type) { + case LPF: + meter_ctl.lpf_enable = 1; + delay_ctl.meter_alu_right_group_enable = 1; + break; + case RED: + meter_ctl.lpf_enable = 1; + meter_ctl.red_enable = 1; + delay_ctl.meter_alu_right_group_enable = 1; + red_value_ctl.red_nodrop_value = red_nodrop_value; + red_value_ctl.red_drop_value = red_drop_value; + break; + default: + meter_ctl.meter_enable = 1; + // RNG: + // Enables random number generator for meter probabilistic charging + // when green/yellow burst size exponent > 14. This should be set + // when any meter entry in the table has a burstsize exponent > 14 + // RNG is also enabled whenever red_enable config bit is set. + + // this should always be turned on + // for color-based meters, to handle an issue with large burst + // sizes. This applies to both packet-based and byte-based meters. + // Mike F said, "The hardware adjusts the rate under the hood to + // match the desired rate. Without enabling the RNG, the hardware + // will always overcharge the buckets thereby reducing the rate." + meter_ctl.meter_rng_enable = 1; + meter_ctl.meter_time_scale = profile; + break; + } + if (count == BYTES) meter_ctl.meter_byte = 1; + if (gress == EGRESS) meter_ctl.meter_alu_egress = 1; + auto &error_ctl = map_alu.meter_alu_group_error_ctl[meter_group_index]; + error_ctl.meter_alu_group_ecc_error_enable = 1; + error_ctl.meter_alu_group_thread = gress; + auto &meter_sweep_ctl = adrdist.meter_sweep_ctl[meter_group_index]; + // The driver will manage turning on the meter sweep enable, + // so the compiler should not configure this value (check glass + // code) + // meter_sweep_ctl.meter_sweep_en = 1; + meter_sweep_ctl.meter_sweep_offset = minvpn; + meter_sweep_ctl.meter_sweep_size = maxvpn; + meter_sweep_ctl.meter_sweep_remove_hole_pos = 0; // FIXME -- see CSR? + meter_sweep_ctl.meter_sweep_remove_hole_en = 0; // FIXME + meter_sweep_ctl.meter_sweep_interval = sweep_interval + profile; + for (auto &ixb : input_xbar) { + auto &vh_adr_xbar = regs.rams.array.row[row].vh_adr_xbar; + auto &data_ctl = regs.rams.array.row[row].vh_xbar[side].stateful_meter_alu_data_ctl; + // FIXME: Currently in the compiler, the data headed to the meter alu/stateful alu + // can only come from hash or the search bus, but not both, thus it is + // currenlty safe for them to be mutually exclusive. If the compiler was to + // allocate fields to both, this would have to interpret the information + // correctly + auto hashdata_bytemask = bitmask2bytemask(ixb->hash_group_bituse()); + if (hashdata_bytemask != 0U) { + vh_adr_xbar.alu_hashdata_bytemask.alu_hashdata_bytemask_right = hashdata_bytemask; + setup_muxctl(vh_adr_xbar.exactmatch_row_hashadr_xbar_ctl[2 + side], ixb->hash_group()); + } else { + // FIXME: Need to be some validation between Tofino and JBay if the input + // xbar is valid for these meters. + bitvec bytemask = ixb->bytemask(); + bytemask >>= bytemask.min().index(); + unsigned u_bytemask = bytemask.getrange(0, bytemask.max().index() + 1); + data_ctl.stateful_meter_alu_data_bytemask = u_bytemask; + data_ctl.stateful_meter_alu_data_xbar_ctl = 8 | ixb->match_group(); + } + } + if (output_used) { + auto &action_ctl = map_alu.meter_alu_group_action_ctl[meter_group_index]; + action_ctl.right_alu_action_enable = 1; + action_ctl.right_alu_action_delay = stage->meter_alu_delay(gress, false); + auto &switch_ctl = regs.rams.array.switchbox.row[row].ctl; + switch_ctl.r_action_o_mux_select.r_action_o_sel_action_rd_r_i = 1; + // disable action data address huffman decoding, on the assumtion we're not + // trying to combine this with an action data table on the same home row. + // Otherwise, the huffman decoding will think this is an 8-bit value and + // replicate it. + regs.rams.array.row[row] + .action_hv_xbar.action_hv_xbar_disable_ram_adr.action_hv_xbar_disable_ram_adr_right = 1; + } + map_alu_row.i2portctl.synth2port_vpn_ctl.synth2port_vpn_base = minvpn; + map_alu_row.i2portctl.synth2port_vpn_ctl.synth2port_vpn_limit = maxvpn; + auto &movereg_meter_ctl = adrdist.movereg_meter_ctl[meter_group_index]; + if (run_at_eop()) movereg_meter_ctl.movereg_meter_ctl_deferred = 1; + movereg_meter_ctl.movereg_ad_meter_shift = 7; + movereg_meter_ctl.movereg_meter_ctl_lt = logical_id; + if (direct) movereg_meter_ctl.movereg_meter_ctl_direct = 1; + movereg_meter_ctl.movereg_meter_ctl_color_en = 1; + for (MatchTable *m : match_tables) { + if (direct) adrdist.movereg_ad_direct[1] |= 1U << m->logical_id; + // The first ALU will drive this xbar register + if (first_home_row / 4U == meter_group_index) { + adrdist.movereg_ad_meter_alu_to_logical_xbar_ctl[m->logical_id / 8U].set_subfield( + 4 | meter_group_index, 3 * (m->logical_id % 8U), 3); + } + } +} + +template +void MeterTable::write_mapram_color_regs(REGS ®s, bool &push_on_overflow) { + auto &map_alu = regs.rams.map_alu; + auto &adrdist = regs.rams.match.adrdist; + auto &merge = regs.rams.match.merge; + int curr_home_row = -1; + + for (Layout &row : color_maprams) { + curr_home_row = get_home_row_for_row(row.row * 2); + // Allocating color maprams above home row is invalid + // as color writes can only be distributed to maprams + // via buses going on the home row or below + BUG_CHECK(curr_home_row / 4U >= row.row / 2U); + + int color_map_color = color_maprams.empty() ? 0 : (curr_home_row / 4U) & 1; + if (row.row == curr_home_row / 2) { /* on the home row */ + if (color_map_color) + map_alu.mapram_color_switchbox.row[row.row] + .ctl.r_color1_mux_select.r_color1_sel_color_r_i = 1; + else + map_alu.mapram_color_switchbox.row[row.row] + .ctl.r_color0_mux_select.r_color0_sel_color_r_i = 1; + } else if (row.row / 4U == curr_home_row / 8U) { /* same half as home */ + if (color_map_color) + map_alu.mapram_color_switchbox.row[row.row] + .ctl.r_color1_mux_select.r_color1_sel_oflo_color_r_i = 1; + else + map_alu.mapram_color_switchbox.row[row.row] + .ctl.r_color0_mux_select.r_color0_sel_oflo_color_r_i = 1; + } else { /* other half from home */ + map_alu.mapram_color_switchbox.row[row.row].ctl.t_oflo_color_o_mux_select = 1; + merge.mau_match_central_mapram_read_color_oflo_ctl |= 1U << color_map_color; + } + + /* + * Below diagrams show how select bits are set to + * route color data from meter alu located on the home + * row down to the color maprams + * ********************************************* + * - ROUTE FROM RIGHT TO BOTTOM + * Bus coming from Meter ALU on current home row + * .------------ + * | r_color_write_i + * v + * .---. + * | |<---- (select = 1'b1) + * | | b_oflo_color_write_o_sel_r_color_write_i + * .___. + * | + * | b_oflo_color_write_o + * v + * Bus going to color map rams below + * + * ********************************************* + * - ROUTE FROM TOP TO BOTTOM + * Bus coming from home row above + * | + * | t_oflo_color_write_i + * v + * .---. + * | |<---- (select = 1'b1) + * | | b_oflo_color_write_o_sel_t_oflo_color_write_i + * .___. + * | + * | b_oflo_color_write_o + * v + * Bus going to color map rams below + * + * ********************************************* + * - ROUTE FROM TOP TO RIGHT + * Bus coming from home row above + * | + * | t_oflo_color_write_i + * v + * .---. + * | |<---- (select = 1'b1) + * | | r_oflo_color_write_o_mux_select + * .___. + * | + * | r_oflo_color_write_o + * .----------------> + * Bus going to color map rams on right + * + * ********************************************* + * + * A - Meter 1 Map Rams + * a - Meter 1 Color Map Rams + * B - Meter 1 Map Rams + * b - Meter 1 Color Map Rams + * + * Log Phy Columns SW Mtr + * Row Row 0 1 2 3 4 5 Box ALU + * .---..---..---..---..---..---. + * 15 7 | A || A || A || A || A || A | 3 3 + * .___..___..___..___..___..___. + * .---..---..---..---..---..---. + * 13 6 | A || A || A || A || a || a | + * .___..___..___..___..___..___. + * .---..---..---..---..---..---. + * 11 5 | B || B || B || B || B || a | 2 2 + * .___..___..___..___..___..___. + * .---..---..---..---..---..---. + * 9 4 | B || B || B || B || B || b | + * .___..___..___..___..___..___. + * .---..---..---..---..---..---. + * 7 3 | b || b || - || - || - || - | 1 1 + * .___..___..___..___..___..___. + * + * Meter Color Write Switchbox is configured to + * - set b_oflo_color_write_o_sel_r_color_write_i (1'b1) + * This routes meter alu 3 data down to rows 6 & 5 where + * meter 1 color maprams are located [6,4] [6,5] [5,5] + * + * Meter ALU 2 is configured to + * - set b_oflo_color_write_o_sel_t_oflo_color_write_i (1'b1) + * This routes meter alu data from above to the + * meter 1 color mapram located at [5,5] + * - set b_oflo_color_write_o_sel_r_color_write_i (1'b1) + * This routes meter alu 2 data down to rows 4 & 3 where + * meter 2 color maprams are located [4,5] [3,0] [3,1] + */ + if (row.row != curr_home_row / 2) { /* ALU home row */ + map_alu.mapram_color_write_switchbox[curr_home_row / 4U] + .ctl.b_oflo_color_write_o_mux_select.b_oflo_color_write_o_sel_r_color_write_i = 1; + map_alu.mapram_color_write_switchbox[row.row / 2U].ctl.r_oflo_color_write_o_mux_select = + 1; + BUG_CHECK(curr_home_row / 4U >= row.row / 2U); + /* b_oflo_color_write_o_sel_t_oflo_color_write_i must be set for all + * switchboxes below the homerow and above current row + * It should never be set for a switchbox above the home row + * It should never be set on the switchbox on the current row + * as that would drive the top overflow down to any color maprams below. + * This is invalid and can cause corruption if there is another meter occupying + * color maprams on the below row. + */ + // Switch box below home row + int switchbox_upper = curr_home_row / 4U - 1; + // Switch box above current row + int switchbox_lower = row.row % 2 ? (int)row.row / 2U + 1 : (int)row.row / 2U; + for (int i = switchbox_upper; i >= switchbox_lower; i--) { + if (i == 3) continue; // Never set on top switchbox + + map_alu.mapram_color_write_switchbox[i] + .ctl.b_oflo_color_write_o_mux_select + .b_oflo_color_write_o_sel_t_oflo_color_write_i = 1; + } + } + auto &map_alu_row = map_alu.row[row.row]; + auto vpn = row.vpns.begin(); + if (color_mapram_addr == STATS_MAP_ADDR) { + BUG_CHECK((row.row % 2) == 0); + for (MatchTable *m : match_tables) + adrdist.mau_ad_stats_virt_lt[row.row / 2] |= (1U << m->logical_id); + } + // Enable the row to be used (even if only color maprams are on this row) + map_alu_row.i2portctl.synth2port_ctl.synth2port_enable = 1; + // If the color mapram is not on the same row as the meter ALU, even if no meter + // RAMs are on the same row, the address still needs to overflow to that row + if (row.row < curr_home_row / 2) { + auto &adr_ctl = map_alu_row.vh_xbars.adr_dist_oflo_adr_xbar_ctl[1]; + // Mapram rows are 0-7, not 0-15 like logical rows + if (curr_home_row >= UPPER_MATCH_CENTRAL_FIRST_LOGICAL_ROW && + row.row < UPPER_MATCH_CENTRAL_FIRST_ROW) { + adr_ctl.adr_dist_oflo_adr_xbar_source_index = 0; + adr_ctl.adr_dist_oflo_adr_xbar_source_sel = AdrDist::OVERFLOW; + push_on_overflow = true; + BUG_CHECK(options.target == TOFINO); + } else { + adr_ctl.adr_dist_oflo_adr_xbar_source_index = curr_home_row % 8; + adr_ctl.adr_dist_oflo_adr_xbar_source_sel = AdrDist::METER; + } + adr_ctl.adr_dist_oflo_adr_xbar_enable = 1; + } + + for (auto &memunit : row.memunits) { + int col = memunit.col; + BUG_CHECK(memunit.stage == INT_MIN && memunit.row == row.row, "bogus %s in row %d", + memunit.desc(), row.row); + auto &mapram_config = map_alu_row.adrmux.mapram_config[col]; + if (row.row == curr_home_row / 2) + mapram_config.mapram_color_bus_select = MapRam::ColorBus::COLOR; + else + mapram_config.mapram_color_bus_select = MapRam::ColorBus::OVERFLOW; + mapram_config.mapram_type = MapRam::COLOR; + mapram_config.mapram_logical_table = logical_id; + BUG_CHECK(vpn != row.vpns.end(), "vpn not found!"); + mapram_config.mapram_vpn = *vpn; + // These two registers must be programmed for meter-color map rams in this way as a + // work-around for hardware issue as described in TOF-1944 + // The basic problem is that software reads of the meter color map ram are only + // returning 6-bits of data instead of the necessary 8-bits. Hardware defaults to + // 6 bits, since the meter color map ram case is not explicitly called out. + // By setting these bits, all 8-bits will be returned. + mapram_config.mapram_parity_generate = 1; + mapram_config.mapram_parity_check = 0; + // glass does not set ecc for color maprams? + // mapram_config.mapram_ecc_check = 1; + // mapram_config.mapram_ecc_generate = 1; + if (gress == INGRESS) + mapram_config.mapram_ingress = 1; + else + mapram_config.mapram_egress = 1; + mapram_config.mapram_enable = 1; + if (row.row != curr_home_row / 2) { /* ALU home row */ + mapram_config.mapram_color_write_bus_select = 1; + } + auto &ram_address_mux_ctl = map_alu_row.adrmux.ram_address_mux_ctl[1][col]; + if (row.row == curr_home_row / 2) { /* ALU home row */ + ram_address_mux_ctl.synth2port_radr_mux_select_home_row = 1; + } else { + ram_address_mux_ctl.synth2port_radr_mux_select_oflo = 1; + } + map_alu_row.i2portctl.synth2port_ctl.synth2port_mapram_color |= 1U << col; + ram_address_mux_ctl.map_ram_wadr_shift = 1; + ram_address_mux_ctl.map_ram_wadr_mux_select = MapRam::Mux::COLOR; + ram_address_mux_ctl.map_ram_wadr_mux_enable = 1; + ram_address_mux_ctl.map_ram_radr_mux_select_color = 1; + ram_address_mux_ctl.ram_ofo_stats_mux_select_statsmeter = 1; + // Indicating what bus to pull from, either stats or idletime for the color mapram + if (color_mapram_addr == IDLE_MAP_ADDR) { + ram_address_mux_ctl.ram_stats_meter_adr_mux_select_idlet = 1; + setup_muxctl(map_alu_row.vh_xbars.adr_dist_idletime_adr_xbar_ctl[col], + row.bus.at(Layout::IDLE_BUS) % 10); + } else if (color_mapram_addr == STATS_MAP_ADDR) { + ram_address_mux_ctl.ram_stats_meter_adr_mux_select_stats = 1; + } + if (gress) + regs.cfg_regs.mau_cfg_mram_thread[col / 3U] |= 1U << (col % 3U * 8U + row.row); + ++vpn; + } + } + + // Additional BUG_CHECK to verify that both these regs are not set on a switchbox + // - map_alu.mapram_color_write_switchbox[x].ctl.b_oflo_color_write_o_sel_r_color_write_i + // - map_alu.mapram_color_write_switchbox[x].ctl.b_oflo_color_write_o_sel_t_oflo_color_write_i + // Both these regs should never be set on a swithbox as it implies routing from both top and + // right map alu to the bottom rows. This leads to corruption of color data. + // Additional BUG_CHECK to verify that top row switchbox does not have + // this regs set + // - map_alu.mapram_color_write_switchbox[x].ctl.b_oflo_color_write_o_sel_t_oflo_color_write_i + for (int i = 0; i <= 3; i++) { + auto t_oflo_write_i = map_alu.mapram_color_write_switchbox[i] + .ctl.b_oflo_color_write_o_mux_select + .b_oflo_color_write_o_sel_t_oflo_color_write_i == 1; + if (i == 3) { + BUG_CHECK(!t_oflo_write_i, + "Color maprams have invalid configuration" + " may cause corruption of color data from meter"); + } + auto r_oflo_write_i = + map_alu.mapram_color_write_switchbox[i] + .ctl.b_oflo_color_write_o_mux_select.b_oflo_color_write_o_sel_r_color_write_i == 1; + LOG5("i: " << i << "t_oflo: " << t_oflo_write_i << ", r_oflo: " << r_oflo_write_i); + BUG_CHECK(!(t_oflo_write_i & r_oflo_write_i), + "Color maprams have invalid configuration" + " may cause corruption of color data from meter"); + } +} + +template +void MeterTable::write_regs_vt(REGS ®s) { + LOG1("### Meter table " << name() << " write_regs " << loc()); + for (auto &ixb : input_xbar) ixb->write_regs(regs); + Layout *home = nullptr; + bool push_on_overflow = false; + auto &map_alu = regs.rams.map_alu; + auto &adrdist = regs.rams.match.adrdist; + DataSwitchboxSetup *swbox = nullptr; + for (Layout &logical_row : layout) { + unsigned row = logical_row.row / 2U; + unsigned side = logical_row.row & 1; /* 0 == left 1 == right */ + BUG_CHECK(side == 1); /* no map rams or alus on left side anymore */ + auto vpn = logical_row.vpns.begin(); + auto mapram = logical_row.maprams.begin(); + auto &map_alu_row = map_alu.row[row]; + auto home_it = home_rows.find(logical_row.row); + if (home_it != home_rows.end()) { + home = &logical_row; + swbox = new DataSwitchboxSetup(regs, this, logical_row.row, + (++home_it == home_rows.end()) ? -1 : *home_it); + } + BUG_CHECK(home != nullptr); + LOG2("# DataSwitchbox.setup_row(" << row << ") home=" << home->row / 2U); + swbox->setup_row(row); + for (auto &memunit : logical_row.memunits) { + int logical_col = memunit.col; + BUG_CHECK(memunit.stage == INT_MIN && memunit.row == logical_row.row, + "bogus %s in logical row %d", memunit.desc(), logical_row.row); + unsigned col = logical_col + 6 * side; + LOG2("# DataSwitchbox.setup_row_col(" << row << ", " << col << ", vpn=" << *vpn + << ") home=" << home->row / 2U); + swbox->setup_row_col(row, col, *vpn); + write_mapram_regs(regs, row, *mapram, *vpn, MapRam::METER); + if (gress) regs.cfg_regs.mau_cfg_uram_thread[col / 4U] |= 1U << (col % 4U * 8U + row); + ++mapram, ++vpn; + } + if (&logical_row == home) { + write_regs_home_row(regs, row); + } else { + auto &adr_ctl = map_alu_row.vh_xbars.adr_dist_oflo_adr_xbar_ctl[side]; + if (home->row >= UPPER_MATCH_CENTRAL_FIRST_LOGICAL_ROW && + logical_row.row < UPPER_MATCH_CENTRAL_FIRST_LOGICAL_ROW) { + adr_ctl.adr_dist_oflo_adr_xbar_source_index = 0; + adr_ctl.adr_dist_oflo_adr_xbar_source_sel = AdrDist::OVERFLOW; + push_on_overflow = true; + BUG_CHECK(options.target == TOFINO); + } else { + adr_ctl.adr_dist_oflo_adr_xbar_source_index = home->row % 8; + adr_ctl.adr_dist_oflo_adr_xbar_source_sel = AdrDist::METER; + } + adr_ctl.adr_dist_oflo_adr_xbar_enable = 1; + } + } + auto &merge = regs.rams.match.merge; + write_mapram_color_regs(regs, push_on_overflow); + if (home_rows.size() > 1) write_alu_vpn_range(regs); + + for (int home_row : home_rows) { + for (MatchTable *m : match_tables) { + adrdist.adr_dist_meter_adr_icxbar_ctl[m->logical_id] |= 1U << (home_row / 4U); + // auto &icxbar = adrdist.adr_dist_meter_adr_icxbar_ctl[m->logical_id]; + // icxbar.address_distr_to_logical_rows = 1U << home->row; + // icxbar.address_distr_to_overflow = push_on_overflow; + // if (direct) + // regs.cfg_regs.mau_cfg_lt_meter_are_direct |= 1 << m->logical_id; + adrdist.meter_color_output_map[m->logical_id].set_subfield(green_value, 0, 8); + adrdist.meter_color_output_map[m->logical_id].set_subfield(yellow_value, 8, 8); + adrdist.meter_color_output_map[m->logical_id].set_subfield(yellow_value, 16, 8); + adrdist.meter_color_output_map[m->logical_id].set_subfield(red_value, 24, 8); + if (type != LPF) adrdist.meter_enable |= 1U << m->logical_id; + /*auto &movereg_ad_ctl = adrdist.movereg_ad_ctl[m->logical_id]; + movereg_ad_ctl.movereg_meter_deferred = 1; + if (!color_maprams.empty()) + movereg_ad_ctl.movereg_ad_idle_as_mc = 1; + else + movereg_ad_ctl.movereg_ad_stats_as_mc = 1; + movereg_ad_ctl.movereg_ad_direct_meter = direct; + movereg_ad_ctl.movereg_ad_meter_shift = 7; */ + meter_color_logical_to_phys(regs, m->logical_id, home_row / 4U); + adrdist.mau_ad_meter_virt_lt[home_row / 4U] |= 1 << m->logical_id; + } + if (run_at_eop()) { + if (teop >= 0) { + setup_teop_regs(regs, home_row / 4U); + } else { + adrdist.deferred_ram_ctl[1][home_row / 4U].deferred_ram_en = 1; + adrdist.deferred_ram_ctl[1][home_row / 4U].deferred_ram_thread = gress; + if (gress) regs.cfg_regs.mau_cfg_dram_thread |= 0x10 << (home_row / 4U); + } + adrdist.meter_bubble_req[timing_thread(gress)].bubble_req_1x_class_en |= + 1 << ((home_row / 4U) + 4); + } else { + adrdist.meter_bubble_req[timing_thread(gress)].bubble_req_1x_class_en |= + 1 << (home_row / 4U); + adrdist.packet_action_at_headertime[1][home_row / 4U] = 1; + } + if (push_on_overflow) { + adrdist.oflo_adr_user[0] = adrdist.oflo_adr_user[1] = AdrDist::METER; + adrdist.deferred_oflo_ctl = 1 << ((home_row - 8) / 2U); + } + if (gress == INGRESS || gress == GHOST) { + merge.meter_alu_thread[0].meter_alu_thread_ingress |= 1U << home_row / 4U; + merge.meter_alu_thread[1].meter_alu_thread_ingress |= 1U << home_row / 4U; + } else if (gress == EGRESS) { + merge.meter_alu_thread[0].meter_alu_thread_egress |= 1U << home_row / 4U; + merge.meter_alu_thread[1].meter_alu_thread_egress |= 1U << home_row / 4U; + } + } + + for (auto &hd : hash_dist) hd.write_regs(regs, this); +} + +// FIXME -- refactor these specializations better +template <> +void MeterTable::meter_color_logical_to_phys(Target::Tofino::mau_regs ®s, int logical_id, + int alu) { + auto &merge = regs.rams.match.merge; + auto &adrdist = regs.rams.match.adrdist; + if (!color_maprams.empty()) { + merge.mau_mapram_color_map_to_logical_ctl[logical_id / 8].set_subfield( + 0x4 | alu, 3 * (logical_id % 8U), 3); + + // Determining which buses to send the color mapram address to + if (color_mapram_addr == IDLE_MAP_ADDR) { + adrdist.movereg_idle_ctl[logical_id].movereg_idle_ctl_mc = 1; + for (auto lo : color_maprams) { + int bus_index = lo.bus.at(Layout::IDLE_BUS); + // upper and lower idletime busses appear to be independent with + // no overflow between them + if (lo.row >= UPPER_MATCH_CENTRAL_FIRST_ROW) bus_index += IDLETIME_BUSSES_PER_HALF; + adrdist.adr_dist_idletime_adr_oxbar_ctl[bus_index / 4].set_subfield( + logical_id | 0x10, 5 * (bus_index % 4), 5); + } + + } else if (color_mapram_addr == STATS_MAP_ADDR) { + for (auto lo : color_maprams) { + adrdist.adr_dist_stats_adr_icxbar_ctl[logical_id] |= (1U << (lo.row / 2)); + adrdist.packet_action_at_headertime[0][lo.row / 2] = 1; + } + } else { + BUG(); + } + setup_muxctl(adrdist.meter_color_logical_to_phys_ixbar_ctl[logical_id], alu); + } +} + +#if HAVE_JBAY +template <> +void MeterTable::meter_color_logical_to_phys(Target::JBay::mau_regs ®s, int logical_id, + int alu) { + auto &merge = regs.rams.match.merge; + auto &adrdist = regs.rams.match.adrdist; + if (!color_maprams.empty()) { + merge.mau_mapram_color_map_to_logical_ctl[alu] |= 1 << logical_id; + // Determining which buses to send the color mapram address to + if (color_mapram_addr == IDLE_MAP_ADDR) { + adrdist.movereg_idle_ctl[logical_id].movereg_idle_ctl_mc = 1; + for (auto lo : color_maprams) { + int bus_index = lo.bus.at(Layout::IDLE_BUS); + // No overflow bus exist between upper and lower half so every color mapram have + // to use their respective bus + if (lo.row >= UPPER_MATCH_CENTRAL_FIRST_ROW) bus_index += IDLETIME_BUSSES_PER_HALF; + adrdist.adr_dist_idletime_adr_oxbar_ctl[bus_index / 4].set_subfield( + logical_id | 0x10, 5 * (bus_index % 4), 5); + } + + } else if (color_mapram_addr == STATS_MAP_ADDR) { + for (auto lo : color_maprams) { + adrdist.adr_dist_stats_adr_icxbar_ctl[logical_id] |= (1U << (lo.row / 2)); + adrdist.packet_action_at_headertime[0][lo.row / 2] = 1; + } + } else { + BUG(); + } + } + adrdist.meter_color_logical_to_phys_icxbar_ctl[logical_id] |= 1 << alu; +} +#endif /* HAVE_JBAY */ + +void MeterTable::gen_tbl_cfg(json::vector &out) const { + // FIXME -- factor common Synth2Port stuff + auto spare_mems = determine_spare_bank_memory_units(); + int size = (layout_size() - spare_mems.size()) * SRAM_DEPTH; + json::map &tbl = *base_tbl_cfg(out, "meter", size); + json::map &stage_tbl = *add_stage_tbl_cfg(tbl, "meter", size); + stage_tbl["color_memory_resource_allocation"] = + gen_memory_resource_allocation_tbl_cfg("map_ram", color_maprams); + switch (type) { + case STANDARD: + tbl["meter_type"] = "standard"; + tbl["meter_profile"] = profile; + break; + case LPF: + tbl["meter_type"] = "lpf"; + break; + case RED: + tbl["meter_type"] = "red"; + break; + default: + tbl["meter_type"] = "standard"; + break; + } + switch (count) { + case PACKETS: + tbl["meter_granularity"] = "packets"; + break; + case BYTES: + tbl["meter_granularity"] = "bytes"; + break; + default: + tbl["meter_granularity"] = "packets"; + break; + } + tbl["enable_color_aware_pfe"] = color_aware_per_flow_enable; + /* this is not needed. but the driver asserts on existence of + * this or enable_color_aware which both seem to be redundant */ + tbl["pre_color_field_name"] = ""; + tbl["enable_pfe"] = per_flow_enable; + tbl["pfe_bit_position"] = per_flow_enable_bit(); + tbl["color_aware_pfe_address_type_bit_position"] = 0; // FIXME + tbl["reference_dictionary"] = json::map(); // To be removed in future + stage_tbl["default_lower_huffman_bits_included"] = METER_LOWER_HUFFMAN_BITS; + if (home_rows.size() > 1) + add_alu_indexes(stage_tbl, "meter_alu_index"); + else + add_alu_index(stage_tbl, "meter_alu_index"); + if (context_json) stage_tbl.merge(*context_json); +} + +DEFINE_TABLE_TYPE_WITH_SPECIALIZATION(MeterTable, TARGET_CLASS) +FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void MeterTable::write_merge_regs, + (mau_regs & regs, MatchTable *match, int type, int bus, + const std::vector &args), + { write_merge_regs_vt(regs, match, type, bus, args); }) diff --git a/backends/tofino/bf-asm/misc.cpp b/backends/tofino/bf-asm/misc.cpp new file mode 100644 index 00000000000..6c2c39020b4 --- /dev/null +++ b/backends/tofino/bf-asm/misc.cpp @@ -0,0 +1,223 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "misc.h" + +#include +#include +#include + +#include "bfas.h" +#include "target.h" + +int remove_name_tail_range(std::string &name, int *size) { + auto tail = name.rfind('.'); + if (tail == std::string::npos) return 0; + unsigned lo, hi; + int len = -1; + if (sscanf(&name[tail], ".%u-%u%n", &lo, &hi, &len) >= 2 && tail + len == name.size() && + hi >= lo) { + name.erase(tail); + if (size) *size = hi - lo + 1; + return lo; + } + return 0; +} + +std::string int_to_hex_string(unsigned val, unsigned width) { + std::stringstream sval; + sval << std::setfill('0') << std::setw(width) << std::hex << val << std::setfill(' '); + return sval.str(); +} + +void add_cfg_reg(json::vector &cfg_cache, std::string full_name, std::string name, + std::string val) { + json::map cfg_cache_reg; + cfg_cache_reg["fully_qualified_name"] = full_name; + cfg_cache_reg["name"] = name; + cfg_cache_reg["value"] = val; + cfg_cache.push_back(std::move(cfg_cache_reg)); +} + +bool check_zero_string(const std::string &s) { + char zero = '0'; + return s.find_first_not_of(zero) == std::string::npos; +} + +std::string get_filename(const char *s) { + std::string fname = s; + fname = fname.substr(fname.find_last_of("/") + 1); + fname = fname.substr(0, fname.find_last_of(".")); + return fname; +} + +std::string get_directory(const char *s) { + std::string fname = s; + auto tail = fname.find_last_of("/"); + if (tail == std::string::npos) + fname = "."; + else + fname = fname.substr(0, tail); + return fname; +} + +/* Given a p4 name, split into instance and field names if possible + * - else return a copy of the original name */ +void gen_instfield_name(const std::string &fullname, std::string &instname, + std::string &field_name) { + auto dotpos = fullname.rfind('.'); + if (dotpos == std::string::npos) { + instname = fullname; + field_name = std::string(); + } else { + instname = fullname.substr(0, dotpos); + field_name = fullname.substr(dotpos + 1, fullname.size()); + } +} + +uint64_t bitMask(unsigned size) { + BUG_CHECK(size <= 64 && "bitMask(size), maximum size is 64"); + if (size == 64) return ~UINT64_C(0); + return (UINT64_C(1) << size) - 1; +} + +uint64_t bitRange(unsigned lo, unsigned hi) { + BUG_CHECK(hi >= lo && hi < 64, "bitRange(%u,%u) invalid", lo, hi); + if (lo == 0 && hi + 1 == 64) return ~UINT64_C(0); + return ((UINT64_C(1) << (hi - lo + 1)) - 1) << lo; +} + +int parity(uint32_t v) { + v ^= v >> 16; + v ^= v >> 8; + v ^= v >> 4; + v ^= v >> 2; + v ^= v >> 1; + return v & 1; +} + +int parity_2b(uint32_t v) { + v ^= v >> 16; + v ^= v >> 8; + v ^= v >> 4; + v ^= v >> 2; + return v & 3; +} + +bool check_bigint_unsigned(value_t value, uint32_t byte_width) { + BUG_CHECK(value.type == tBIGINT); + + /* -- zero is in the range */ + if (value.bigi.size == 0) return true; + + constexpr uint64_t size_bigint_item(sizeof(value.bigi.data[0])); + + bool overflow(false); + + /* -- all items above the max_index must by zero */ + const uint64_t max_index(((byte_width + size_bigint_item - 1) / size_bigint_item) - 1); + for (int i(max_index + 1); i < value.bigi.size; ++i) { + if (value.bigi.data[i] != 0) { + overflow = true; + } + } + /* -- check limit in the boundary bigint part */ + if (value.bigi.size > max_index) { + const uint64_t ext_width(byte_width % size_bigint_item); + if (ext_width > 0 && value.bigi.data[max_index] >= (1 << (ext_width * 8))) { + overflow = true; + } + } + if (overflow) { + error(value.lineno, "the integer constant is wider than the requested width %u bytes", + byte_width); + return false; + } + + return true; +} + +bool input_int_match(const value_t value, match_t &match, int width) { + BUG_CHECK(width <= sizeof(match_t::word0) * 8); + + using MatchType = decltype(match_t::word0); + MatchType mask; + if (width < sizeof(MatchType) * 8) + mask = (1ULL << width) - 1; + else + mask = std::numeric_limits::max(); + if (value.type == tINT) { + if (!check_range_strict(value, 0, mask)) return false; + convert_i2m(value.i, match); + } else if (value.type == tBIGINT) { + /* -- As the match type is uint64_t and value_t::i is int64_t, constants + * above 0x7fffffffffffffff are passed as big integers. */ + if (value.bigi.size > 1) { + error(value.lineno, "the match constant is out of the expected range <0, %lu>", mask); + return false; + } + MatchType v(0); + if (value.bigi.size > 0) v = value.bigi.data[0]; + if (v > mask) { + error(value.lineno, "the match constant is out of the expected range <0, %lu>", mask); + return false; + } + convert_i2m(v, match); + } else { + value_t fixed_value = value; + fixed_value.m = value.m; + fix_match_star(fixed_value.m, mask); + if (!check_range_match(fixed_value, mask, width)) return false; + match = fixed_value.m; + } + return true; +} + +unsigned match_t::dirtcam(unsigned width, unsigned bit) { + static unsigned masks[] = {0x5555, 0x3333, 0xf0f0, 0xffff}; + BUG_CHECK(width <= 4, "dirtcam of more than 4 bits?"); + unsigned rv = (1U << (1U << width)) - 1; + for (unsigned i = 0; i < width; ++i, ++bit) { + if (!((word0 >> bit) & 1)) rv &= ~masks[i]; + if (!((word1 >> bit) & 1)) rv &= masks[i]; + } + return rv; +} + +unsigned wmatch_t::dirtcam(unsigned width, unsigned bit) { + static unsigned masks[] = {0x5555, 0x3333, 0xf0f0, 0xffff}; + BUG_CHECK(width <= 4, "dirtcam of more than 4 bits?"); + unsigned rv = (1U << (1U << width)) - 1; + for (unsigned i = 0; i < width; ++i, ++bit) { + // treat both bits 0 as don't care rather than never match + if (!word0[bit] && !word1[bit]) continue; + if (!word0[bit]) rv &= ~masks[i]; + if (!word1[bit]) rv &= masks[i]; + } + return rv; +} + +bool require_keys(const value_t &data, std::set keys) { + for (auto key : keys) { + pair_t *kv = data.map[key]; + if (!kv) { + error(data.lineno, "missing required key '%s'", key); + return false; + } + } + return true; +} diff --git a/backends/tofino/bf-asm/misc.h b/backends/tofino/bf-asm/misc.h new file mode 100644 index 00000000000..9aa7da5e83a --- /dev/null +++ b/backends/tofino/bf-asm/misc.h @@ -0,0 +1,218 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_MISC_H_ +#define BF_ASM_MISC_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "asm-types.h" +#include "json.h" + +template +auto setup_muxctl(T ®, int val) -> decltype((void)reg.enabled_2bit_muxctl_enable) { + reg.enabled_2bit_muxctl_select = val; + reg.enabled_2bit_muxctl_enable = 1; +} +template +auto setup_muxctl(T ®, int val) -> decltype((void)reg.enabled_3bit_muxctl_enable) { + reg.enabled_3bit_muxctl_select = val; + reg.enabled_3bit_muxctl_enable = 1; +} +template +auto setup_muxctl(T ®, int val) -> decltype((void)reg.enabled_4bit_muxctl_enable) { + reg.enabled_4bit_muxctl_select = val; + reg.enabled_4bit_muxctl_enable = 1; +} +template +auto setup_muxctl(T ®, int val) -> decltype((void)reg.enabled_5bit_muxctl_enable) { + reg.enabled_5bit_muxctl_select = val; + reg.enabled_5bit_muxctl_enable = 1; +} +template +auto setup_muxctl(T ®, int val) -> decltype((void)reg.exactmatch_row_vh_xbar_enable) { + reg.exactmatch_row_vh_xbar_select = val; + reg.exactmatch_row_vh_xbar_enable = 1; +} + +template +void append(std::vector &a, const std::vector &b) { + for (auto &e : b) a.push_back(e); +} + +template +T join(const std::vector &vec, U sep) { + T rv; + bool first = true; + for (auto &el : vec) { + if (first) + first = false; + else + rv += sep; + rv += el; + } + return rv; +} + +extern int remove_name_tail_range(std::string &, int *size = nullptr); + +// Convert an integer to hex string of specified width (in bytes) +std::string int_to_hex_string(unsigned val, unsigned width); + +// Add a reg to CJSON Configuration Cache +void add_cfg_reg(json::vector &cfg_cache, std::string full_name, std::string name, std::string val); + +bool check_zero_string(const std::string &s); + +// Get filename +std::string get_filename(const char *s); +std::string get_directory(const char *s); + +/** Given a p4 name, eg. "inst.field", write "inst" to @instname and "field" to + * @fieldname. If @fullname cannot be split, writes @fullname to @instname and + * "" to @fieldname. + */ +void gen_instfield_name(const std::string &fullname, std::string &instname, std::string &fieldname); + +/// Compare pointers based on the pointed at type +/// For use as a Comparator for map/set types +template +struct ptrless { + bool operator()(const T *a, const T *b) const { return b ? a ? *a < *b : true : false; } + bool operator()(const std::unique_ptr &a, const std::unique_ptr &b) const { + return b ? a ? *a < *b : true : false; + } +}; + +/* word with size (lowest) bits set */ +uint64_t bitMask(unsigned size); +/* word with range of bits from lo to hi (inclusive) set */ +uint64_t bitRange(unsigned lo, unsigned hi); + +int parity(uint32_t v); +int parity_2b(uint32_t v); // two-bit parity (parity of pairs in the word) + +inline bool check_value(const value_t value, const decltype(value_t::i) expected) { + if (!CHECKTYPE(value, tINT)) return false; + if (value.i != expected) { + error(value.lineno, "unexpected value %ld; expected %ld", value.i, expected); + return false; + } + return true; +} + +/** + * @brief Check range of an input integer value (tINT) + * + * This method is designated mainly for checking input integer constants. The template + * parameter defines target type in which the value is going to be stored. As the + * higher limit is quite often 0xffff... we must handle signed and unsigned integers + * correctly. + * + * @tparam IntType Target type which the value will be stored in. + * @param value The checked value + * @param lo lower inclusive limit + * @param hi higher include limit + * @return False if the value is out of the specified limits + */ +template ::value>::type> +bool check_range_strict(value_t value, IntType lo, IntType hi) { + auto format_error_message([](value_t value, IntType lo, IntType hi) { + /* -- As we don't know actual type of the IntType, we cannot use the printf-like + * formatting. */ + std::ostringstream oss; + oss << "value " << value.i << " is out of allowed range <" << +lo << "; " << +hi << ">"; + error(value.lineno, "%s", oss.str().c_str()); + }); + + if (!CHECKTYPE(value, tINT)) return false; + + /* -- Handle different ranges (signed, unsigned, different size) of the value_t::i + * and IntType. */ + typedef boost::numeric::converter Converter; + if (Converter::out_of_range(value.i)) { + format_error_message(value, lo, hi); + return false; + } + + /* -- Now check requested limits */ + IntType converted(static_cast(value.i)); + if (converted < lo || converted > hi) { + format_error_message(value, lo, hi); + return false; + } + return true; +} + +inline bool check_range(const value_t value, const decltype(value_t::i) lo, + const decltype(value_t::i) hi) { + return check_range_strict(value, lo, hi); +} + +inline bool check_range_match(const value_t &match, const decltype(match_t::word0) mask, + int width) { + if (!CHECKTYPE(match, tMATCH)) return false; + if ((match.m.word0 | match.m.word1) != mask) { + error(match.lineno, "invalid match width; expected %i bits", width); + return false; + } + return true; +} + +template +void convert_i2m(IntType i, match_t &m) { + static_assert(sizeof(IntType) == sizeof(match_t::word0)); + static_assert(std::is_integral::value); + + m.word0 = ~static_cast(i); + m.word1 = static_cast(i); +} + +bool check_bigint_unsigned(value_t value, uint32_t byte_width); + +/// * is parsed as match_t::word0 == 0 && match_t::word1 == 0. +/// The function converts the match according to the specified with @p mask. +inline void fix_match_star(match_t &match, const decltype(match_t::word0) mask) { + if (match.word0 == 0 && match.word1 == 0) match.word0 = match.word1 = mask; +} + +/// The function reads a tINT or tMATCH value, performs range checks, and converts +/// the value to a new tMATCH value. +/// @param value Input value +/// @param match Output value +/// @param width Expected width of the input value used for range checks +/// @pre @p value must be a tINT or tMATCH value. +/// @return True if the value is correctly parsed +bool input_int_match(const value_t value, match_t &match, int width); + +/// Check if a tMAP value contains all the given keys. +/// @param value A tMAP value +/// @param keys A set of keys +/// @pre @p value must be a tMAP +/// @return True if the given keys are a subset of the map's keys +bool require_keys(const value_t &data, std::set keys); + +#endif /* BF_ASM_MISC_H_ */ diff --git a/backends/tofino/bf-asm/mksizes.cpp b/backends/tofino/bf-asm/mksizes.cpp new file mode 100644 index 00000000000..746d1509e66 --- /dev/null +++ b/backends/tofino/bf-asm/mksizes.cpp @@ -0,0 +1,40 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include + +int main() { + if (sizeof(unsigned long long) == 2 * sizeof(uintptr_t)) + std::cout << "#define uint2ptr_t unsigned long long" << std::endl; + else if (sizeof(unsigned long) == 2 * sizeof(uintptr_t)) + std::cout << "#define uint2ptr_t unsigned long" << std::endl; + else if (sizeof(unsigned) == 2 * sizeof(uintptr_t)) + std::cout << "#define uint2ptr_t unsigned" << std::endl; + else if (sizeof(unsigned long) * 2 == sizeof(uintptr_t)) + std::cout << "#define uinthptr_t unsigned long" << std::endl; + else if (sizeof(unsigned) * 2 == sizeof(uintptr_t)) + std::cout << "#define uinthptr_t unsigned" << std::endl; + else if (sizeof(unsigned short) * 2 == sizeof(uintptr_t)) + std::cout << "#define uinthptr_t unsigned short" << std::endl; + else { + std::cerr << "Can't find a type that is 2x or 1/2x a uinputr_t" << std::endl; + return 1; + } + return 0; +} diff --git a/backends/tofino/bf-asm/mktags b/backends/tofino/bf-asm/mktags new file mode 100755 index 00000000000..fb7fd6e555b --- /dev/null +++ b/backends/tofino/bf-asm/mktags @@ -0,0 +1,23 @@ +#!/bin/sh + +# Copyright (C) 2024 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# +# SPDX-License-Identifier: Apache-2.0 + +ctags -R -I VECTOR --exclude=test --exclude=submodules \ + --regex-C++='/^DECLARE_(ABSTRACT_)?TABLE_TYPE\(([a-zA-Z0-9_]+)/\2/c/' + +ctags -a -R $HOME/bf-utils/include/bfutils diff --git a/backends/tofino/bf-asm/p4_table.cpp b/backends/tofino/bf-asm/p4_table.cpp new file mode 100644 index 00000000000..6b8b2a185f6 --- /dev/null +++ b/backends/tofino/bf-asm/p4_table.cpp @@ -0,0 +1,254 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "p4_table.h" + +#include "tables.h" + +static std::map alpms; + +std::map P4Table::by_handle; +std::map> P4Table::by_name; +unsigned P4Table::max_handle[7]; + +// handle[29:24] is used as type field. +const char *P4Table::type_name[] = {0, "match", "action", "selection", "statistics", + "meter", "stateful"}; + +// handle[19:16] is used as handle offset field for multipipe +static unsigned apply_handle_offset(unsigned handle, unsigned offset) { + return handle | (offset & 0xff) << 16; +} + +// clear bit[19:16] which is used to encode pipe_id. +static unsigned clear_handle_offset(unsigned handle) { return handle & 0xff00ffff; } + +P4Table *P4Table::get(P4Table::type t, VECTOR(pair_t) & data) { + BUG_CHECK(t < NUM_TABLE_TYPES); + P4Table *rv; + auto *h = ::get(data, "handle"); + auto *n = ::get(data, "name"); + if (h) { + if (!CHECKTYPE(*h, tINT)) return nullptr; + unsigned handle = h->i; + handle = clear_handle_offset(handle); + if (handle >> 24 && handle >> 24 != t) { + error(h->lineno, "Incorrect handle type %d for %s table", handle >> 24, type_name[t]); + return 0; + } + handle &= 0xffffff; + if (!handle) { + error(h->lineno, "zero handle"); + return 0; + } + if (handle > max_handle[t]) max_handle[t] = handle; + handle |= t << 24; + handle = apply_handle_offset(handle, unique_table_offset); + if (!(rv = by_handle[handle])) { + if (!n || !CHECKTYPE(*n, tSTR) || !by_name[t].count(n->s) || + (rv = by_name[t][n->s])->handle != (unsigned)t << 24) + rv = by_handle[handle] = new P4Table; + rv->handle = handle; + } + } else if (n) { + if (!CHECKTYPE(*n, tSTR)) return 0; + if (!(rv = by_name[t][n->s])) { + rv = by_name[t][n->s] = new P4Table; + rv->name = n->s; + rv->handle = apply_handle_offset(++max_handle[t] | (t << 24), unique_table_offset); + } + } else { + error(data.size ? data[0].key.lineno : 0, "no handle or name in p4 info"); + return 0; + } + for (auto &kv : MapIterChecked(data)) { + if (rv->lineno <= 0 || rv->lineno > kv.key.lineno) rv->lineno = kv.key.lineno; + if (kv.key == "handle") { + } else if (kv.key == "name") { + if (CHECKTYPE(kv.value, tSTR)) { + if (!rv->name.empty() && rv->name != kv.value.s) { + error(kv.value.lineno, "Inconsistent P4 name for handle 0x%x", rv->handle); + warning(rv->lineno, "Previously set here"); + } else if (rv->name.empty()) { + rv->name = kv.value.s; + if (!by_name[t].count(rv->name)) by_name[t][rv->name] = rv; + } + } + } else if (kv.key == "size") { + if (CHECKTYPE(kv.value, tINT)) { + if (rv->explicit_size && rv->size != (unsigned)kv.value.i) { + error(kv.value.lineno, "Inconsistent size for P4 handle 0x%x", rv->handle); + warning(rv->lineno, "Previously set here"); + } else { + rv->size = kv.value.i; + rv->explicit_size = true; + } + } + } else if (kv.key == "action_profile") { + if (CHECKTYPE(kv.value, tSTR)) rv->action_profile = kv.value.s; + } else if (kv.key == "match_type") { + if (CHECKTYPE(kv.value, tSTR)) rv->match_type = kv.value.s; + } else if (kv.key == "preferred_match_type") { + if (CHECKTYPE(kv.value, tSTR)) rv->preferred_match_type = kv.value.s; + } else if (kv.key == "disable_atomic_modify") { + if (CHECKTYPE(kv.value, tSTR)) + if (strncmp(kv.value.s, "true", 4) == 0) rv->disable_atomic_modify = true; + } else if (kv.key == "stage_table_type") { + if (CHECKTYPE(kv.value, tSTR)) rv->stage_table_type = kv.value.s; + } else if (kv.key == "how_referenced") { + if (CHECKTYPE(kv.value, tSTR)) { + if (strcmp(kv.value.s, "direct") != 0 && strcmp(kv.value.s, "indirect") != 0) + error(kv.value.lineno, "how_referenced must be either direct or indirect"); + else + rv->how_referenced = kv.value.s; + } + } else if (kv.key == "hidden") { + rv->hidden = get_bool(kv.value); + } else { + warning(kv.key.lineno, "ignoring unknown item %s in p4 info", value_desc(kv.key)); + } + } + return rv; +} + +P4Table *P4Table::alloc(P4Table::type t, Table *tbl) { + unsigned handle = apply_handle_offset(++max_handle[t] | (t << 24), unique_table_offset); + P4Table *rv = by_handle[handle] = new P4Table; + rv->handle = handle; + rv->name = tbl->name(); + return rv; +} + +void P4Table::check(Table *tbl) { + if (name.empty()) name = tbl->name(); + if (!(handle & 0xffffff)) { + auto table_type = (handle >> 24) & 0x3f; + handle += ++max_handle[table_type]; + } +} + +json::map *P4Table::base_tbl_cfg(json::vector &out, int size, const Table *table) const { + json::map *tbl_ptr = nullptr; + for (auto &_table_o : out) { + auto &_table = _table_o->to(); + if (_table["name"] == name) { + if (_table["handle"] && _table["handle"] != handle) continue; + tbl_ptr = &_table; + break; + } + } + if (!tbl_ptr) { + tbl_ptr = new json::map(); + out.emplace_back(tbl_ptr); + } + json::map &tbl = *tbl_ptr; + tbl["direction"] = direction_name(table->gress); + if (handle) tbl["handle"] = handle; + auto table_type = (handle >> 24) & 0x3f; + BUG_CHECK(table_type < NUM_TABLE_TYPES); + tbl["name"] = p4_name(); + tbl["table_type"] = type_name[table_type]; + if (!explicit_size && tbl["size"]) + tbl["size"]->as_number()->val += size; + else + tbl["size"] = explicit_size ? this->size : size; + if (hidden) tbl["p4_hidden"] = true; + return &tbl; +} + +void P4Table::base_alpm_tbl_cfg(json::map &out, int size, const Table *table, + P4Table::alpm_type atype) const { + if (is_alpm()) { + json::map **alpm_cfg = nullptr; + unsigned *alpm_table_handle = nullptr; + auto *alpm = &alpms[this]; + if (alpm) { + auto p4Name = p4_name(); + if (!p4Name) { + error(table->lineno, "No p4 table found for alpm table : %s", table->name()); + return; + } + std::string name = p4Name; + if (atype == P4Table::PreClassifier) { + alpm_cfg = &alpm->alpm_pre_classifier_table_cfg; + alpm_table_handle = &alpm->alpm_pre_classifier_table_handle; + // Both alpm pre-classifier and atcam tables share the same + // table name. For driver to uniquely distinguish a + // pre-classifier from the atcam table during snapshot, we add a + // suffix to the p4 name + name += "_pre_classifier"; + } else if (atype == P4Table::Atcam) { + alpm_cfg = &alpm->alpm_atcam_table_cfg; + alpm_table_handle = &alpm->alpm_atcam_table_handle; + } + *alpm_cfg = &out; + json::map &tbl = out; + tbl["direction"] = direction_name(table->gress); + auto table_type = (handle >> 24) & 0x3f; + BUG_CHECK(table_type < NUM_TABLE_TYPES); + if (!(*alpm_table_handle & 0xffffff)) + *alpm_table_handle = apply_handle_offset( + (P4Table::MatchEntry << 24) + (++max_handle[table_type]), unique_table_offset); + if (*alpm_table_handle) tbl["handle"] = *alpm_table_handle; + tbl["name"] = name; + tbl["table_type"] = type_name[table_type]; + tbl["size"] = explicit_size ? this->size : size; + } + } +} + +void P4Table::set_partition_action_handle(unsigned handle) { + alpms[this].set_partition_action_handle.insert(handle); +} + +void P4Table::set_partition_field_name(std::string name) { + alpms[this].partition_field_name = name; +} + +std::string P4Table::get_partition_field_name() const { + if (alpms.count(this)) return alpms[this].partition_field_name; + return ""; +} + +std::set P4Table::get_partition_action_handle() const { + if (alpms.count(this)) { + return alpms[this].set_partition_action_handle; + } + return {}; +} + +unsigned P4Table::get_alpm_atcam_table_handle() const { + if (alpms.count(this)) return alpms[this].alpm_atcam_table_handle; + return 0; +} + +std::string P4Table::direction_name(gress_t gress) { + switch (gress) { + case INGRESS: + return "ingress"; + break; + case EGRESS: + return "egress"; + break; + case GHOST: + return "ghost"; + break; + default: + BUG(); + } + return ""; +} diff --git a/backends/tofino/bf-asm/p4_table.h b/backends/tofino/bf-asm/p4_table.h new file mode 100644 index 00000000000..183690764c0 --- /dev/null +++ b/backends/tofino/bf-asm/p4_table.h @@ -0,0 +1,94 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_P4_TABLE_H_ +#define BF_ASM_P4_TABLE_H_ + +#include +#include + +#include "asm-types.h" +#include "json.h" + +class Table; +class P4Table; + +struct alpm_t { + std::string partition_field_name = ""; + unsigned alpm_atcam_table_handle = 0; + unsigned alpm_pre_classifier_table_handle = 0; + std::set set_partition_action_handle; + json::map *alpm_atcam_table_cfg = 0; // handle to cjson alpm table + json::map *alpm_pre_classifier_table_cfg = 0; // handle to cjson ternary pre classifier table +}; + +class P4Table { + int lineno = -1; + std::string name, preferred_match_type; + std::string stage_table_type; + unsigned handle = 0; + bool explicit_size = false; + bool hidden = false; + json::map *config = 0; + P4Table() {} + + public: + bool disable_atomic_modify = false; + unsigned size = 0; + std::string match_type, action_profile, how_referenced; + enum type { + None = 0, + MatchEntry = 1, + ActionData = 2, + Selection = 3, + Statistics = 4, + Meter = 5, + Stateful = 6, + NUM_TABLE_TYPES = 7 + }; + enum alpm_type { PreClassifier = 1, Atcam = 2 }; + static const char *type_name[]; + + private: + static std::map by_handle; + static std::map> by_name; + static unsigned max_handle[]; + + public: + static P4Table *get(type t, VECTOR(pair_t) & d); + static P4Table *alloc(type t, Table *tbl); + void check(Table *tbl); + const char *p4_name() const { return name.empty() ? nullptr : name.c_str(); } + unsigned get_handle() { return handle; } + unsigned p4_size() { return size; } + std::string p4_stage_table_type() { return stage_table_type; } + json::map *base_tbl_cfg(json::vector &out, int size, const Table *table) const; + void base_alpm_tbl_cfg(json::map &out, int size, const Table *table, + P4Table::alpm_type atype) const; + bool is_alpm() const { + if (match_type == "alpm") return true; + return false; + } + void set_partition_action_handle(unsigned handle); + void set_partition_field_name(std::string name); + std::string get_partition_field_name() const; + std::set get_partition_action_handle() const; + unsigned get_alpm_atcam_table_handle() const; + static std::string direction_name(gress_t); +}; + +#endif /* BF_ASM_P4_TABLE_H_ */ diff --git a/backends/tofino/bf-asm/parser-tofino-jbay.cpp b/backends/tofino/bf-asm/parser-tofino-jbay.cpp new file mode 100644 index 00000000000..d5e3d17b21c --- /dev/null +++ b/backends/tofino/bf-asm/parser-tofino-jbay.cpp @@ -0,0 +1,2029 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "parser-tofino-jbay.h" + +#include + +#include "algorithm.h" +#include "constants.h" +#include "misc.h" +#include "ordered_set.h" +#include "phv.h" +#include "range.h" +#include "stage.h" +#include "target.h" +#include "top_level.h" +#include "vector.h" + +/* Dummy specializations so that all specializations are covered */ + +void AsmParser::init_port_use(bitvec &port_use, const value_t &arg) { + if (arg.type == tVEC) { + for (int i = 0; i < arg.vec.size; i++) { + init_port_use(port_use, arg[i]); + } + } else if (arg.type == tRANGE) { + if (arg.hi > arg.lo) + error(arg.lineno, "port range hi index %d cannot be smaller than lo index %d", arg.hi, + arg.lo); + port_use.setrange(arg.lo, arg.hi - arg.lo + 1); + } else if (arg.type == tINT) { + port_use.setbit(arg.i); + } +} + +void AsmParser::start(int lineno, VECTOR(value_t) args) { + if (args.size != 0 && args[0] != "ingress" && args[0] != "egress" && + (args[0] != "ghost" || options.target < JBAY)) + error(lineno, "parser must specify ingress%s or egress", + options.target >= JBAY ? ", ghost" : ""); +} + +void AsmParser::input(VECTOR(value_t) args, value_t data) { + if (args.size > 0 && args[0] == "ghost") { + // Backward compatibility for old ghost parser syntax + // ghost parser : W0 + if (data.type == tVEC) { + for (int i = 0; i < data.vec.size; i++) { + ghost_parser.push_back(Phv::Ref(GHOST, 0, data[i])); + } + // New ghost parser syntax + // parser ghost: + // ghost_md: W0 + // pipe_mask: 0 + } else if (data.type == tMAP) { + for (auto &kv : MapIterChecked(data.map, true)) { + if (kv.key == "ghost_md") { + if (kv.value.type == tVEC) { + for (int i = 0; i < kv.value.vec.size; i++) { + ghost_parser.push_back(Phv::Ref(GHOST, 0, data[i])); + } + } else { + ghost_parser.push_back(Phv::Ref(GHOST, 0, kv.value)); + } + } else if (kv.key == "pipe_mask") { + if (!CHECKTYPE(kv.value, tINT)) continue; + ghost_pipe_mask = kv.value.i; + } + } + } else { + ghost_parser.push_back(Phv::Ref(GHOST, 0, data)); + } + return; + } + + gress_t gress = (args.size > 0 && args[0] == "egress") ? EGRESS : INGRESS; + auto *p = new Parser(phv_use, gress, parser[gress].size()); + parser[gress].push_back(p); + if (args.size == 1) { + p->port_use.setrange(0, Target::NUM_PARSERS()); + } else if (args.size == 2) { + init_port_use(p->port_use, args[1]); + } + p->input(args, data); +} + +void AsmParser::process() { + for (auto gress : Range(INGRESS, EGRESS)) { + for (auto p : parser[gress]) { + p->ghost_parser = ghost_parser; + p->ghost_pipe_mask = ghost_pipe_mask; + p->process(); + } + } + + bitvec phv_allow_bitwise_or; + for (auto p : parser[INGRESS]) { + phv_allow_bitwise_or |= p->phv_allow_bitwise_or; + } + for (auto p : parser[EGRESS]) { + phv_allow_bitwise_or |= p->phv_allow_bitwise_or; + } + for (auto p : parser[INGRESS]) { + p->phv_allow_bitwise_or = phv_allow_bitwise_or; + } + for (auto p : parser[EGRESS]) { + p->phv_allow_bitwise_or = phv_allow_bitwise_or; + } + + bitvec phv_allow_clear_on_write; + for (auto p : parser[INGRESS]) { + phv_allow_clear_on_write |= p->phv_allow_clear_on_write; + } + for (auto p : parser[EGRESS]) { + phv_allow_clear_on_write |= p->phv_allow_clear_on_write; + } + for (auto p : parser[INGRESS]) { + p->phv_allow_clear_on_write = phv_allow_clear_on_write; + } + for (auto p : parser[EGRESS]) { + p->phv_allow_clear_on_write = phv_allow_clear_on_write; + } + + bitvec phv_init_valid; + for (auto p : parser[INGRESS]) { + phv_init_valid |= p->phv_init_valid; + } + for (auto p : parser[EGRESS]) { + phv_init_valid |= p->phv_init_valid; + } + for (auto p : parser[INGRESS]) { + p->phv_init_valid = phv_init_valid; + } + for (auto p : parser[EGRESS]) { + p->phv_init_valid = phv_init_valid; + } +} + +void AsmParser::output(json::map &ctxt_json) { + ctxt_json["parser"]["ingress"] = json::vector(); + ctxt_json["parser"]["egress"] = json::vector(); + + bool use_multiple_parser_impl = false; + + for (auto gress : Range(INGRESS, EGRESS)) { + if (parser[gress].size() > 1) use_multiple_parser_impl = true; + } + /// We use the 'parsers' node in ctxt json to implement + /// multiple parser instances support. + /// We use the 'parser' node for all single parser + /// instance support. + for (auto gress : Range(INGRESS, EGRESS)) { + /// remove after multi-parser support is fully-tested. + if (use_multiple_parser_impl) { + for (auto p : parser[gress]) { + p->output(ctxt_json); + } + } else { + if (!parser[gress].empty() && parser[gress][0] != nullptr) + parser[gress][0]->output_legacy(ctxt_json); + } + } +} + +std::vector AsmParser::test_get_parser(gress_t gress) { + if ((gress == INGRESS) || (gress == EGRESS)) return parser[gress]; + return std::vector(); +} + +std::map>> Parser::clots; +std::array, PARSER_MAX_CLOTS> Parser::clot_use; +unsigned Parser::max_handle = 0; + +static void collect_phv_vector(value_t value, gress_t gress, bitvec &bv) { + for (auto &el : value.vec) { + Phv::Ref reg(gress, 0, el); + if (reg.check()) { + int id = reg->reg.uid; + bv[id] = 1; + } + } +} + +void Parser::input(VECTOR(value_t) args, value_t data) { + lineno = data.lineno; + if (!CHECKTYPE(data, tMAP)) return; + for (gress_t gress : Range(INGRESS, EGRESS)) { + if (args.size > 0) { + if (args[0] == "ingress" && gress != INGRESS) continue; + if (args[0] == "egress" && gress != EGRESS) continue; + } else if (error_count > 0) { + break; + } + for (auto &kv : MapIterChecked(data.map, true)) { + if (kv.key == "name" && (kv.value.type == tSTR)) { + name = kv.value.s; + continue; + } + if (kv.key == "start" && (kv.value.type == tVEC || kv.value.type == tSTR)) { + if (kv.value.type == tVEC) { + for (int i = 0; i < 4 && i < kv.value.vec.size; i++) + start_state[i] = kv.value[i]; + } else { + for (int i = 0; i < 4; i++) start_state[i] = kv.value; + } + continue; + } + if (kv.key == "priority" && (kv.value.type == tVEC || kv.value.type == tINT)) { + if (kv.value.type == tVEC) { + for (int i = 0; i < 4 && i < kv.value.vec.size; i++) + if (CHECKTYPE(kv.value[i], tINT)) priority[i] = kv.value[i].i; + } else { + for (int i = 0; i < 4; i++) priority[i] = kv.value.i; + } + continue; + } + if (kv.key == "priority_threshold" && + (kv.value.type == tVEC || kv.value.type == tINT)) { + if (kv.value.type == tVEC) { + for (int i = 0; i < 4 && i < kv.value.vec.size; i++) + if (CHECKTYPE(kv.value[i], tINT)) pri_thresh[i] = kv.value[i].i; + } else { + for (int i = 0; i < 4; i++) pri_thresh[i] = kv.value.i; + } + continue; + } + if (kv.key == "parser_error") { + if (parser_error.lineno >= 0) { + error(kv.key.lineno, "Multiple parser_error declarations"); + warning(parser_error.lineno, "Previous was here"); + } else { + parser_error = Phv::Ref(gress, 0, kv.value); + } + continue; + } + if (kv.key == "bitwise_or") { + if (CHECKTYPE(kv.value, tVEC)) + collect_phv_vector(kv.value, gress, phv_allow_bitwise_or); + + continue; + } + if (kv.key == "clear_on_write") { + if (options.target == TOFINO) + error(kv.key.lineno, "Tofino parser does not support clear-on-write semantic"); + + if (CHECKTYPE(kv.value, tVEC)) + collect_phv_vector(kv.value, gress, phv_allow_clear_on_write); + + continue; + } + if (kv.key == "init_zero") { + if (CHECKTYPE(kv.value, tVEC)) { + collect_phv_vector(kv.value, gress, phv_init_valid); + collect_phv_vector(kv.value, gress, phv_use[gress]); + } + + continue; + } + if (kv.key == "hdr_len_adj") { + if (CHECKTYPE(kv.value, tINT)) hdr_len_adj = kv.value.i; + continue; + } + if (kv.key == "states") { + if (CHECKTYPE(kv.value, tMAP)) + for (auto &st : kv.value.map) define_state(gress, st); + continue; + } + if (kv.key == "bubble") { // obfuscated name for reverse engineering + if (CHECKTYPE(kv.value, tMAP)) { + rate_limit.lineno = kv.key.lineno; + rate_limit.parse(kv.value.map); + } + continue; + } + if (gress == EGRESS && kv.key == "meta_opt") { + if (CHECKTYPE(kv.value, tINT)) meta_opt = kv.value.i; + continue; + } + if (kv.key == "parse_depth_checks_disabled") { + if (options.target == TOFINO) + options.tof1_egr_parse_depth_checks_disabled = get_bool(kv.value); + else + warning(kv.key.lineno, + "parse_depth_checks_disabled unexpected: supported only by Tofino"); + continue; + } + define_state(gress, kv); + } + + // process the CLOTs immediately rather than in Parser::process() so that it + // happens before Deparser::process() + for (auto &map : Values(clots)) { + for (auto &vec : Values(map)) { + State::Match::Clot *maxlen = 0; + for (auto *cl : vec) { + if (cl->tag >= 0) clot_use[cl->tag].push_back(cl); + if (!maxlen || cl->max_length > maxlen->max_length) maxlen = cl; + } + for (auto *cl : vec) cl->max_length = maxlen->max_length; + } + } + + for (auto &map : Values(clots)) { + std::map clot_alloc; + unsigned free_clot_tag = 0; + while (free_clot_tag < PARSER_MAX_CLOTS && !clot_use[free_clot_tag].empty()) + ++free_clot_tag; + + for (auto &vec : Values(map)) { + for (auto *cl : vec) { + if (cl->tag >= 0) continue; + if (clot_alloc.count(cl->name)) { + cl->tag = clot_alloc.at(cl->name); + clot_use[cl->tag].push_back(cl); + } else if (free_clot_tag >= PARSER_MAX_CLOTS) { + error(cl->lineno, "Too many CLOTs (%d max)", PARSER_MAX_CLOTS); + } else { + clot_alloc[cl->name] = cl->tag = free_clot_tag++; + clot_use[cl->tag].push_back(cl); + while (free_clot_tag < PARSER_MAX_CLOTS && !clot_use[free_clot_tag].empty()) + ++free_clot_tag; + } + } + } + } + } +} + +void Parser::define_state(gress_t gress, pair_t &kv) { + if (!CHECKTYPE2M(kv.key, tSTR, tCMD, "state declaration")) return; + const char *name = kv.key.s; + match_t stateno = {0, 0}; + if (kv.key.type == tCMD) { + name = kv.key[0].s; + if (!CHECKTYPE2(kv.key[1], tINT, tMATCH)) return; + if (kv.key[1].type == tINT) { + if (kv.key[1].i > PARSER_STATE_MASK) + error(kv.key.lineno, "Explicit state out of range"); + stateno.word1 = kv.key[1].i; + stateno.word0 = (~kv.key[1].i) & PARSER_STATE_MASK; + } else { + stateno = kv.key[1].m; + if ((stateno.word0 | stateno.word1) > PARSER_STATE_MASK) + error(kv.key.lineno, "Explicit state out of range"); + stateno.word0 |= ~(stateno.word0 | stateno.word1) & PARSER_STATE_MASK; + } + } + if (!CHECKTYPE(kv.value, tMAP)) return; + auto n = states.emplace(name, new State(kv.key.lineno, name, gress, stateno, kv.value.map)); + if (n.second) { + all.push_back(n.first->second); + } else { + error(kv.key.lineno, "State %s already defined in %sgress", name, gress ? "e" : "in"); + warning(n.first->second->lineno, "previously defined here"); + } +} + +void Parser::process() { + if (all.empty()) return; + for (auto st : all) st->pass1(this); + for (gress_t gress : Range(INGRESS, EGRESS)) { + if (states.empty()) continue; + if (start_state[0].lineno < 0) { + State *start = get_start_state(); + if (!start) { + error(lineno, "No %sgress parser start state", gress ? "e" : "in"); + continue; + } else { + for (int i = 0; i < 4; i++) { + start_state[i].name = start->name; + start_state[i].lineno = start->lineno; + start_state[i].ptr.push_back(start); + } + } + } else { + for (int i = 0; i < 4; i++) start_state[i].check(gress, this, 0); + } + for (int i = 0; i < 4 && !start_state[i]; i++) + if (!start_state[i]->can_be_start()) { + std::string name = std::string("'; + LOG1("Creating new " << gress << " " << name << " state"); + auto n = states.emplace(name, new State(lineno, name.c_str(), gress, match_t{0, 0}, + VECTOR(pair_t){0, 0, 0})); + BUG_CHECK(n.second); + State *state = n.first->second; + state->def = new State::Match(lineno, gress, *start_state[i]); + for (int j = 3; j >= i; j--) + if (start_state[j] == start_state[i]) { + start_state[j].name = name; + start_state[j].ptr[0] = state; + } + all.insert(all.begin(), state); + } + if (parser_error.lineno >= 0) + if (parser_error.check() && parser_error.gress() == gress) + phv_use[gress][parser_error->reg.uid] = 1; + } + if (ghost_parser.size()) { + int total_size = 0; + int curr_parser_id = -1; + std::sort(ghost_parser.begin(), ghost_parser.end()); + for (Phv::Ref &r : ghost_parser) { + r.check(); + total_size += r.size(); + if (curr_parser_id >= 0) { + if ((curr_parser_id + 1) != r->reg.parser_id()) + error(ghost_parser[0].lineno, "ghost thread input must be 32 consecutive bits"); + } + curr_parser_id = r->reg.parser_id(); + } + if (total_size != 32) error(ghost_parser[0].lineno, "ghost thread input must be 32 bits"); + } + if (error_count > 0) return; + int all_index = 0; + for (auto st : all) st->all_idx = all_index++; + bitvec unreach(0, all_index); + for (int i = 0; i < 4; i++) + if (!states.empty()) start_state[i]->unmark_reachable(this, unreach); + for (auto u : unreach) + warning(all[u]->lineno, "%sgress state %s unreachable", all[u]->gress ? "E" : "In", + all[u]->name.c_str()); + if (phv_use[INGRESS].intersects(phv_use[EGRESS])) { + bitvec tmp = phv_use[INGRESS]; + tmp &= phv_use[EGRESS]; + for (int reg : tmp) + error(lineno, "Phv register %s(R%d) used by both ingress and egress", + Phv::reg(reg)->name, reg); + } + if (options.match_compiler || 1) { /* FIXME -- need proper liveness analysis */ + Phv::setuse(INGRESS, phv_use[INGRESS]); + Phv::setuse(EGRESS, phv_use[EGRESS]); + } +} + +int Parser::get_header_stack_size_from_valid_bits(std::vector sets) { + // Find Set operation that holds the stack valid bits, then + // find the largest value of "$.$valid". + for (const auto *set : sets) { + auto reg = Phv::reg(set->where.name()); + if (reg) { + auto aliases = Phv::aliases(reg, 0); + if (std::find_if(aliases.begin(), aliases.end(), [](const std::string &s) { + return s.find(".$stkvalid") != std::string::npos; + }) != aliases.end()) { + int stack_size = 0; + while (std::find_if( + aliases.begin(), aliases.end(), [&stack_size](const std::string &s) { + return s.find("$" + std::to_string(stack_size) + ".$valid") != + std::string::npos; + }) != aliases.end()) + stack_size++; + return stack_size; + } + } + } + return 0; +} + +/** + * @brief Returns the deepest parser depth, starting from state s. + * Returned value in bits. + */ +int Parser::state_prsr_dph_max(const State *s) { + std::map> visited; // pair: first=curr_dph_bits + // second=recurse count + return state_prsr_dph_max(s, visited, -hdr_len_adj * 8); +} + +/** + * @brief Returns the deepest parser depth for state s, considering the depth + * is already at curr_dph_bits at the time it's being called. + * Returned value in bits. + */ +int Parser::state_prsr_dph_max(const State *s, + std::map> &visited, + int curr_dph_bits) { + int parser_depth_max_bits = parser_depth_max_bytes * 8; + int parser_depth_min_bits = parser_depth_min_bytes * 8; + if (!s) return 0; + if (s->ignore_max_depth && curr_dph_bits >= parser_depth_min_bits) return curr_dph_bits; + // Keep track of states visited along with the parser depth at time of visit + // and the number of times the state was called recursively. Return 0 if current + // curr_dph_bits value is smaller or equal to the largest value seen so far, + // or if the state was called enough times to fill the header stack if one + // is used. + if (visited.count(s) && (visited.at(s).first >= curr_dph_bits)) { + LOG5(" State : " << s->name << " --> largest depth : " << visited[s].first + << " >= current depth : " << curr_dph_bits << " --> Ignore."); + return 0; + } + visited[s].first = curr_dph_bits; + visited[s].second++; + int curr_state_prsr_dph_max = 0; + for (const auto *m : s->match) { + auto local_bits_shifted = curr_dph_bits + (m->shift * 8); + std::string next_name = m->next ? m->next->name : std::string("END"); + LOG5(" State : " << s->name << " --> " << m->match << " --> " << next_name + << " | Bits: " << curr_dph_bits << ", shift : " << m->shift * 8 + << ", intr_md_bits : " << m->intr_md_bits + << ", Total Bits : " << local_bits_shifted); + // Look for non-unrolled loops that save in header stacks. In that case, use + // header stack size to limit parser depth calculation. + if (m->offset_inc) { + // One of the Set operations will set the header stack entries $valid bits. + // Get stack size information from these valid bits. + int stack_size = get_header_stack_size_from_valid_bits(m->set); + LOG5(" State : stack_size = " << stack_size + << ", visited count = " << visited[s].second); + // Do not go beyond header stack size to find parser depth. + if (visited[s].second > stack_size) { + LOG5(" State : reached end of header stack, size = " << stack_size); + continue; + } + } + + if (local_bits_shifted < parser_depth_max_bits) { + if (m->next) { + for (auto n : m->next.ptr) { + int prsr_dph = state_prsr_dph_max(n, visited, local_bits_shifted); + curr_state_prsr_dph_max = std::max(curr_state_prsr_dph_max, prsr_dph); + } + } else { + curr_state_prsr_dph_max = std::max(curr_state_prsr_dph_max, local_bits_shifted); + } + } else { + LOG5(" State : " << s->name << " --> " << m->match << " --> " << next_name + << " | Reached " << parser_depth_max_bits + << " bits, maximum supported by target."); + curr_state_prsr_dph_max = parser_depth_max_bits; + } + + // No point in going any further with the other matches + // if we reached the maximum allowed by the target. + if (curr_state_prsr_dph_max >= parser_depth_max_bits) break; + + // If the current match is a default or catch-all transition, then + // break out of the loop as any following transitions will never + // be taken. + uint64_t mask = bitMask(s->key.width); + if ((m->match.word0 & m->match.word1 & mask) == mask) { + LOG5(" State : catch-all transition, break out of loop."); + break; + } + } + visited[s].second--; + return curr_state_prsr_dph_max; +} + +int Parser::get_prsr_max_dph() { + // Look for the longest parser depth from all configured start states. + // Return the longest one found. + // + // Note: at this point start_state[] contains the start states either + // read from the bfa file, or deduced from the standard/typical + // start state names returned from get_start_state() during + // Parser::process. + // + int prsr_dph_max = 0; + std::set visited; + for (auto &state : start_state) { + if (state) { + BUG_CHECK(states[state.name], "Start state %s not found in states table.", + state.name.c_str()); + if (visited.count(state.name)) continue; + visited.insert(state.name); + int prsr_dph = state_prsr_dph_max(states[state.name]); + LOG4("state " << state.name << " dph=" << prsr_dph); + prsr_dph_max = std::max(prsr_dph_max, prsr_dph); + } + } + prsr_dph_max = (prsr_dph_max + 0x7) & ~0x7; + prsr_dph_max /= 8; + prsr_dph_max = (prsr_dph_max + 0xf) & ~0xf; + prsr_dph_max /= 16; + // P4C-5341/5342: For Tofino EPB, the one additional word is sent beyond prsr_dph_max. + if (options.target == TOFINO && gress == EGRESS) prsr_dph_max -= 1; + return std::max(prsr_dph_max, 4); +} + +void Parser::output_default_ports(json::vector &vec, bitvec port_use) { + while (!port_use.empty()) { + auto idx = port_use.ffs(0); + vec.push_back(idx); + port_use.clrbit(idx); + } +} + +std::map Parser::parser_handles; + +void Parser::write_config(RegisterSetBase ®s, json::map &json, bool legacy) { + if (auto *tofino_regs = dynamic_cast(®s)) + write_config(*tofino_regs, json, legacy); +#ifdef HAVE_JBAY + else if (auto *jbay_regs = dynamic_cast(®s)) + write_config(*jbay_regs, json, legacy); +#endif /* HAVE_JBAY */ +} + +// output context.json format with multiple parser support +void Parser::output(json::map &ctxt_json) { + json::vector &cjson = ctxt_json["parsers"][gress ? "egress" : "ingress"]; + if (all.empty()) return; + for (auto st : all) st->pass2(this); + if (error_count > 0) return; + tcam_row_use = PARSER_TCAM_DEPTH; + SWITCH_FOREACH_TARGET( + options.target, auto *regs = new TARGET::parser_regs; declare_registers(regs); + json::map parser_ctxt_json; + // Parser Handles are generated in the assembler. Since the assembler + // has no idea about multipipe program (since assembler is separately + // invoked for each pipe bfa) the parser handles generated can be same + // across multiple pipes. Here, we rely on the driver to prefix a pipe id + // (profile id) to make the handles unique. The upper 2 bits are + // reserved for this id. + parser_handle = next_handle(); + parser_handles[name] = parser_handle; // store parser handles + parser_ctxt_json["name"] = name; parser_ctxt_json["handle"] = parser_handle; + json::vector default_ports; output_default_ports(default_ports, port_use); + parser_ctxt_json["default_parser_id"] = std::move(default_ports); + write_config(dynamic_cast(*regs), parser_ctxt_json, false); + // FIXME -- rate limit config regs are per-pipe, not per parser, so if more than + // one parser wants to set different rate limits, there will be a problem + if (rate_limit) rate_limit.write_config(TopLevel::regs()->reg_pipe, gress); + cjson.push_back(std::move(parser_ctxt_json)); + gen_configuration_cache(*regs, ctxt_json["configuration_cache"]);) +} + +// output context.json format prior to multiple parser support +// TODO: remove after multi-parser support is fully-tested. +void Parser::output_legacy(json::map &ctxt_json) { + if (all.empty()) return; + for (auto st : all) st->pass2(this); + if (error_count > 0) return; + tcam_row_use = PARSER_TCAM_DEPTH; + SWITCH_FOREACH_TARGET( + options.target, auto *regs = new TARGET::parser_regs; declare_registers(regs); + parser_handle = next_handle(); + write_config(dynamic_cast(*regs), ctxt_json["parser"], true); + if (rate_limit) rate_limit.write_config(TopLevel::regs()->reg_pipe, gress); + gen_configuration_cache(*regs, ctxt_json["configuration_cache"]);) +} + +Parser::Checksum::Checksum(gress_t gress, pair_t data) : lineno(data.key.lineno), gress(gress) { + if (!CHECKTYPE2(data.key, tSTR, tCMD)) return; + if (!CHECKTYPE(data.value, tMAP)) return; + if (data.key.vec.size == 2) { + if ((unit = data.key[1].i) >= Target::PARSER_CHECKSUM_UNITS()) + error(lineno, "Ran out of %sgress parser checksum units (%d available)", + gress ? "e" : "in", Target::PARSER_CHECKSUM_UNITS()); + } else { + error(data.key.lineno, "Syntax error"); + } + for (auto &kv : MapIterChecked(data.value.map, true)) { + if (kv.key == "type") { + if (CHECKTYPE(kv.value, tSTR)) { + if (kv.value == "VERIFY") + type = 0; + else if (kv.value == "RESIDUAL") + type = 1; + else if (kv.value == "CLOT") + type = 2; + else + error(kv.value.lineno, "Unknown parser checksum type"); + } + if (kv.value == "clot") { + if (unit < 2 || unit > 4) + error(kv.value.lineno, "CLOT can only use checksum engine 2-4"); + } + } else if (kv.key == "start") { + if (CHECKTYPE(kv.value, tINT)) start = kv.value.i; + } else if (kv.key == "end") { + if (CHECKTYPE(kv.value, tINT)) end = kv.value.i; + } else if (kv.key == "addr") { + if (CHECKTYPE(kv.value, tINT)) addr = kv.value.i; + } else if (kv.key == "add") { + if (CHECKTYPE(kv.value, tINT)) add = kv.value.i; + } else if (kv.key == "dest") { + if (kv.value.type == tCMD && kv.value == "clot" && kv.value.vec.size == 2) + tag = kv.value[1].i; + else + dest = Phv::Ref(gress, 0, kv.value); + } else if (kv.key == "end_pos") { + if (CHECKTYPE(kv.value, tINT)) { + if (kv.value.i > PARSER_INPUT_BUFFER_SIZE) + error(kv.value.lineno, "Header end position is out of input buffer"); + if (kv.value.i < 0) error(kv.value.lineno, "Header end postion cannot be negative"); + dst_bit_hdr_end_pos = kv.value.i; + } + } else if (kv.key == "mask") { + if (CHECKTYPE(kv.value, tVEC)) { + for (int i = 0; i < kv.value.vec.size; i++) { + auto range = kv.value[i]; + unsigned lo = 0, hi = 0; + if (range.type == tRANGE) { + lo = range.lo; + hi = range.hi; + } else if (range.type == tINT) { + lo = hi = range.i; + } else { + error(kv.value.lineno, "Syntax error, expecting range or int"); + } + + if (lo > hi) error(kv.value.lineno, "Invalid parser checksum input"); + if ((hi + 1) > PARSER_INPUT_BUFFER_SIZE) + error(kv.value.lineno, "Parser checksum out of input buffer?"); + + for (unsigned byte = lo; byte <= hi; ++byte) { + if (kv.key == "mask") mask |= (1 << byte); + } + } + } + } else if (kv.key == "swap") { + if (CHECKTYPE(kv.value, tINT)) swap = kv.value.i; + } else if (kv.key == "mul_2") { + if (options.target == TOFINO) { + error(kv.value.lineno, "multiply by 2 feature is available for Tofino2 and higher"); + } + if (CHECKTYPE(kv.value, tINT)) mul_2 = kv.value.i; + } else if (kv.key == "shift") { + shift = get_bool(kv.value); + } else { + warning(kv.key.lineno, "ignoring unknown item %s in checksum", value_desc(kv.key)); + } + } +} + +bool Parser::Checksum::equiv(const Checksum &a) const { + if (unit != a.unit) return false; + if (tag != a.tag) return false; + if (dest && a.dest) { + if (dest != a.dest) return false; + } else if (dest || a.dest) { + return false; + } + return add == a.add && mask == a.mask && swap == a.swap && mul_2 == a.mul_2 && + dst_bit_hdr_end_pos == a.dst_bit_hdr_end_pos && start == a.start && end == a.end && + shift == a.shift && type == a.type; +} + +void Parser::Checksum::pass1(Parser *parser) { + if (parser->checksum_use.empty()) + parser->checksum_use.resize(Target::PARSER_CHECKSUM_UNITS(), {}); + if (addr >= 0) { + if (addr >= PARSER_CHECKSUM_ROWS) { + error(lineno, "invalid %sgress parser checksum address %d", gress ? "e" : "in", addr); + } else if (parser->checksum_use[unit][addr]) { + if (!equiv(*parser->checksum_use[unit][addr])) { + error(lineno, "incompatible %sgress parser checksum use at address %d", + gress ? "e" : "in", addr); + warning(parser->checksum_use[unit][addr]->lineno, "previous use"); + } + } else { + parser->checksum_use[unit][addr] = this; + } + } + if (dest.check() && dest->reg.parser_id() < 0) + error(dest.lineno, "%s is not accessable in the parser", dest->reg.name); + if (dest && dest->reg.size == 32) + error(dest.lineno, "checksum unit cannot write to 32-bit container"); + if (type == 0 && dest) { + if (dest->lo != dest->hi) + error(dest.lineno, "checksum verification destination must be single bit"); + else + dst_bit_hdr_end_pos = dest->lo; + if (options.target == JBAY && dest->reg.size == 8 && dest->reg.deparser_id() % 2) + dst_bit_hdr_end_pos += 8; + } else if (type == 1 && dest && dest.size() != dest->reg.size) { + error(dest.lineno, "residual checksum must write whole container"); + } +} + +void Parser::Checksum::pass2(Parser *parser) { + if (addr < 0) { + int avail = -1; + for (int i = 0; i < PARSER_CHECKSUM_ROWS; ++i) { + if (parser->checksum_use[unit][i]) { + if (equiv(*parser->checksum_use[unit][i])) { + addr = i; + break; + } + } else if (avail < 0) { + avail = i; + } + } + if (addr < 0) { + if (avail >= 0) { + parser->checksum_use[unit][addr = avail] = this; + } else { + error(lineno, + "Ran out of room in parser checksum control RAM of" + " %sgress unit %d (%d rows available)", + gress ? "e" : "in", unit, PARSER_CHECKSUM_ROWS); + } + } + } +} + +Parser::CounterInit::CounterInit(gress_t gress, pair_t data) + : lineno(data.key.lineno), gress(gress) { + if (!CHECKTYPE2(data.key, tSTR, tCMD)) return; + if (!CHECKTYPE(data.value, tMAP)) return; + + if (options.target == TOFINO) mask = 7; + + for (auto &kv : MapIterChecked(data.value.map, true)) { + if (kv.key == "add" && CHECKTYPE(kv.value, tINT)) { + add = kv.value.i; + if (add > 255) error(lineno, "Parser counter add value out of range (0-255)"); + } else if (kv.key == "max" && CHECKTYPE(kv.value, tINT)) { + max = kv.value.i; + if (max > 255) error(lineno, "Parser counter max value out of range (0-255)"); + } else if (kv.key == "rotate" && CHECKTYPE(kv.value, tINT)) { + rot = kv.value.i; + if (rot > 7) error(lineno, "Parser counter rotate value out of range (0-7)"); + } else if (kv.key == "mask" && CHECKTYPE(kv.value, tINT)) { + mask = kv.value.i; + if (options.target == TOFINO && mask > 7) { + error(lineno, "Parser counter mask value out of range (0-7)"); + } else if (options.target == JBAY && mask > 255) { + error(lineno, "Parser counter mask value out of range (0-255)"); + } + } else if (kv.key == "src") { + if (CHECKTYPE(kv.value, tSTR)) { + if (options.target == TOFINO) { + if (kv.value == "half_lo") + src = 0; + else if (kv.value == "half_hi") + src = 1; + else if (kv.value == "byte0") + src = 2; + else if (kv.value == "byte1") + src = 3; + else + error(lineno, "Unexpected counter load source"); + } else if (options.target != TOFINO) { + if (kv.value == "byte0") + src = 0; + else if (kv.value == "byte1") + src = 1; + else if (kv.value == "byte2") + src = 2; + else if (kv.value == "byte3") + src = 3; + else + error(lineno, "Unexpected counter load source"); + } + } + } else if (kv.key != "push" && kv.key != "update_with_top") { + error(lineno, "Syntax error in parser counter init expression"); + } + } +} + +bool Parser::CounterInit::equiv(const CounterInit &a) const { + return add == a.add && mask == a.mask && rot == a.rot && max == a.max && src == a.src; +} + +void Parser::CounterInit::pass2(Parser *parser) { + if (addr < 0) { + int avail = -1; + for (int i = 0; i < PARSER_CTRINIT_ROWS; ++i) { + if (parser->counter_init[i]) { + if (equiv(*parser->counter_init[i])) { + addr = i; + break; + } + } else if (avail < 0) { + avail = i; + } + } + if (addr < 0) { + if (avail >= 0) + parser->counter_init[addr = avail] = this; + else + error(lineno, + "Ran out of room in parser counter init RAM of" + " %sgress (%d rows available)", + gress ? "e" : "in", PARSER_CTRINIT_ROWS); + } + } +} + +Parser::PriorityUpdate::PriorityUpdate(const value_t &exp) { + lineno = exp.lineno; + if (!parse(exp)) error(lineno, "Syntax error in priority expression"); +} + +bool Parser::PriorityUpdate::parse(const value_t &exp, int what) { + enum { START, MASK, SHIFT, LOAD }; + if (exp.type == tCMD) { + if (exp[0] == ">>") { + return what < SHIFT && parse(exp[1], LOAD) && parse(exp[2], SHIFT); + } else if (exp[0] == "&") { + return what < SHIFT && parse(exp[1], MASK) && parse(exp[2], MASK); + } + } else if (exp.type == tINT) { + switch (what) { + case START: + case MASK: + if (mask >= 0) return false; + if ((mask = exp.i) < 0 || mask > 7) { + error(exp.lineno, "priority mask %d out of range", mask); + return false; + } + return true; + case SHIFT: + if (shift >= 0) return false; + if ((shift = exp.i) < 0 || shift > 15) { + error(exp.lineno, "priority shift %d out of range", shift); + return false; + } + return true; + default: + return false; + } + } else if (exp.type == tSTR && exp.s[0] == '@' && isdigit(exp.s[1])) { + char *end; + if (what == SHIFT || offset >= 0 || (offset = strtol(exp.s + 1, &end, 10)) < 0 || *end) + return false; + return true; + } + return false; +} + +void Parser::RateLimit::parse(const VECTOR(pair_t) & data) { + inc = dec = 1; + for (auto &kv : MapIterChecked(data)) { + if (kv.key == "inc") { + if (CHECKTYPE(kv.value, tINT)) inc = kv.value.i; + } else if (kv.key == "dec") { + if (CHECKTYPE(kv.value, tINT)) dec = kv.value.i; + } else if (kv.key == "max") { + if (CHECKTYPE(kv.value, tINT)) max = kv.value.i; + } else if (kv.key == "interval") { + if (CHECKTYPE(kv.value, tINT)) interval = kv.value.i; + } else { + warning(kv.key.lineno, "ignoring unknown item %s in bubble spec", value_desc(kv.key)); + } + } + if (max < 0) error(lineno, "no max limit in bubble spec"); +} + +Parser::State::Ref &Parser::State::Ref::operator=(const value_t &v) { + lineno = v.lineno; + ptr.clear(); + if (v.type == tSTR) { + name = v.s; + pattern.word0 = pattern.word1 = 0; + } else if (CHECKTYPE2M(v, tINT, tMATCH, "state reference")) { + name.clear(); + if (v.type == tINT) { + pattern.word0 = ~v.i; + pattern.word1 = v.i; + } else { + pattern = v.m; + } + if ((pattern.word0 | pattern.word1) > PARSER_STATE_MASK) { + error(lineno, "Parser state out of range"); + pattern.word0 &= PARSER_STATE_MASK; + pattern.word1 &= PARSER_STATE_MASK; + } else { + pattern.word1 |= ~(pattern.word0 | pattern.word1) & PARSER_STATE_MASK; + } + } + return *this; +} + +void Parser::State::Ref::check(gress_t gress, Parser *pa, State *state) { + if (ptr.empty()) { + if (name.size()) { + auto it = pa->states.find(name); + if (it != pa->states.end()) + ptr.push_back(it->second); + else if (name != "END" && name != "end") + error(lineno, "No state named %s in %sgress parser", name.c_str(), + gress ? "e" : "in"); + } else if (pattern) { + match_t tmp = pattern; + unsigned wc = tmp.word0 & tmp.word1; + if (wc && !state->stateno) { + warning(lineno, + "Using next state pattern in state without an explicit " + "state number"); + wc = 0; + } + tmp.word0 &= ~wc | state->stateno.word0; + tmp.word1 &= ~wc | state->stateno.word1; + for (auto *st : pa->all) { + if (st->gress != state->gress) continue; + if (st == state) continue; + if (tmp.matches(st->stateno)) ptr.push_back(st); + } + } + } +} + +const char *Parser::match_key_loc_name(int loc) { + if (options.target == TOFINO) { + if (loc == 0 || loc == 1) return "half"; + if (loc == 2) return "byte0"; + if (loc == 3) return "byte1"; + } else { + if (loc == 0) return "byte0"; + if (loc == 1) return "byte1"; + if (loc == 2) return "byte2"; + if (loc == 3) return "byte3"; + } + + error(-1, "Invalid match key loc"); + return nullptr; +} + +int Parser::match_key_loc(value_t &key, bool errchk) { + if (errchk && !CHECKTYPE(key, tSTR)) return -1; + int loc = Parser::match_key_loc(key.s); + if (loc < 0) error(key.lineno, "Invalid matcher location %s", key.s); + return loc; +} + +int Parser::match_key_loc(const char *key) { + if (options.target == TOFINO) { + if (!strcmp(key, "half") || !strcmp(key, "half0")) return 0; + if (!strcmp(key, "byte0")) return 2; + if (!strcmp(key, "byte1")) return 3; + } else { + if (!strcmp(key, "byte0")) return 0; + if (!strcmp(key, "byte1")) return 1; + if (!strcmp(key, "byte2")) return 2; + if (!strcmp(key, "byte3")) return 3; + } + + error(-1, "Invalid match key %s", key); + return -1; +} + +int Parser::match_key_size(const char *key) { + if (!strncmp(key, "half", 4)) return 16; + if (!strncmp(key, "byte", 4)) return 8; + + error(-1, "Invalid match key %s", key); + return -1; +} + +int Parser::State::MatchKey::move_down(int loc) { + int to = loc; + while (to >= 0 && ((specified >> to) & 1)) to--; + if (to < 0) return -1; + if (data[to].bit >= 0 && move_down(to) < 0) return -1; + data[to] = data[loc]; + data[loc].bit = -1; + return 0; +} + +int Parser::State::MatchKey::add_byte(int loc, int byte, bool use_saved) { + // FIXME: Parameter "byte" is an offset in the input packet buffer. + // It seems strange to specify a negative value when checking + // for the lower range (i.e. -64): when bytes are shifted + // out of the input buffer, they can't be read anymore. + // Should the lower range value be 0 instead? + if (options.target == TOFINO) { + if (byte <= -64 || byte >= 32) { + error(lineno, "Match key index out of range"); + return -1; + } + } else { + // Valid offset ranges: + // -63..31 : Input packet + // 60..63 : Scratch registers + if ((byte <= -64) || ((byte > 31) && (byte < 60)) || (byte > 63)) { + error(lineno, "Match key index out of range"); + return -1; + } + } + + if (loc >= 0) { + if ((specified >> loc) & 1) + error(lineno, "Multiple matches in %s matcher", Parser::match_key_loc_name(loc)); + specified |= (1 << loc); + if (data[loc].bit >= 0 && move_down(loc) < 0) return -1; + } else { + for (int i = 3; i >= 0; i--) + if (data[i].bit < 0) { + loc = i; + break; + } + if (loc < 0) { + error(lineno, "Too much data for parse matcher"); + return -1; + } + } + data[loc].bit = width; + data[loc].byte = use_saved ? USE_SAVED : byte; + width += 8; + return 0; +} + +int Parser::State::MatchKey::setup_match_el(int at, value_t &spec) { + switch (spec.type) { + case tINT: + return add_byte(at, spec.i); + case tRANGE: + if (spec.lo >= spec.hi) { + error(spec.lineno, "Invalid match range"); + return -1; + } + if (at >= 0) at += spec.hi - spec.lo; + for (int i = spec.hi; i >= spec.lo; i--) { + if (add_byte(at, i) < 0) return -1; + if (at >= 0) at--; + } + return 0; + case tMAP: + if (at >= 0) goto error; + for (int i = spec.map.size - 1; i >= 0; i--) + if (setup_match_el(Parser::match_key_loc(spec.map[i].key), spec.map[i].value) < 0) + return -1; + return 0; + case tSTR: + if (spec == "ctr_zero") { + if (ctr_zero >= 0) { + error(spec.lineno, "'ctr_zero' specified twice"); + return -1; + } + ctr_zero = width++; + return 0; + } else if (spec == "ctr_neg") { + if (ctr_neg >= 0) { + error(spec.lineno, "'ctr_neg' specified twice"); + return -1; + } + ctr_neg = width++; + return 0; + } else if (!strncmp(spec.s, "save_byte", 9)) { + if (options.target == TOFINO) + error(spec.lineno, "Tofino does not have scratch registers in the parser"); + + int i = spec.s[9] - '0'; + if (i < 0 || i > 4) error(spec.lineno, "Invalid parser save source %s", spec.s); + save = 1 << i; + width += 8; + return 0; + } else if (at < 0 && (at = Parser::match_key_loc(spec, false)) >= 0) { + if (options.target == TOFINO && at == 0 && add_byte(1, 0, true) < 0) return -1; + return add_byte(at, 0, true); + } + /* fall through */ + default: + error: + error(spec.lineno, "Syntax error in match spec"); + return -1; + } +} + +void Parser::State::MatchKey::setup(value_t &spec) { + lineno = spec.lineno; + if (spec.type == tVEC) { + /* allocate the keys bits for the least significant match bits first... */ + for (int i = spec.vec.size - 1; i >= 0; i--) + if (setup_match_el(-1, spec[i]) < 0) return; + } else { + setup_match_el(-1, spec); + } + + // For TOFINO, the first match byte pair must be an adjacent 16 bit pair. We + // check and re-arrange the bytes for a 16 bit extractor. In JBAY this check + // is not necessary as we can have independent byte extractors + if (Target::MATCH_BYTE_16BIT_PAIRS() && (data[0].byte & data[1].byte) != USE_SAVED) { + if (data[0].bit >= 0 && data[1].bit >= 0 && data[0].byte + 1 != data[1].byte) { + BUG_CHECK((data[0].byte | data[1].byte) != USE_SAVED); + int unused = -1; // unused slot + for (int i = 0; i < 4; i++) { + if (data[i].bit < 0) { + if (unused < 0) unused = i; + continue; + } + for (int j = 0; j < 4; j++) { + if (data[j].bit >= 0 && data[i].byte + 1 == data[j].byte) { + if (i == 1 && j == 0) { + std::swap(data[i], data[j]); + } else { + std::swap(data[0], data[i]); + std::swap(data[1], data[j]); + } + return; + } + } + } + if (unused >= 0) { + BUG_CHECK(unused > 1); + std::swap(data[1], data[unused]); + } else { + error(spec.lineno, "Must have a 16-bit pair in match bytes"); + } + } + if (data[0].bit < 0 && data[1].bit >= 0) { + /* if we're using half of the 16-bit match, use the upper (first) half */ + std::swap(data[0], data[1]); + } + } +} + +Parser::State::Match::Match(int l, gress_t gress, State *s, match_t m, VECTOR(pair_t) & data) + : lineno(l), state(s), match(m) { + for (auto &kv : data) { + if (kv.key == "counter") { + if (kv.value.type == tMAP) { + ctr_load = 1; + + bool from_ctr_init_ram = false; + + for (auto &kkv : MapIterChecked(kv.value.map, true)) { + if (kkv.key == "src") { + from_ctr_init_ram = true; + } else if (kkv.key == "push" && CHECKTYPE(kkv.value, tINT)) { + if (options.target == TOFINO) + error(kkv.key.lineno, "Tofino does not have counter stack"); + ctr_stack_push = kkv.value.i; + } else if (kkv.key == "update_with_top" && CHECKTYPE(kkv.value, tINT)) { + if (options.target == TOFINO) + error(kkv.key.lineno, "Tofino does not have counter stack"); + ctr_stack_upd_w_top = kkv.value.i; + } + } + + if (from_ctr_init_ram) { + ctr_ld_src = 1; + if (ctr_instr) { + error(kv.key.lineno, "Tofino does not allow multiple counters on a match"); + continue; + } + ctr_instr = new CounterInit(gress, kv); + } else { // load from immediate + for (auto &kkv : MapIterChecked(kv.value.map, true)) { + if (kkv.key == "imm" && CHECKTYPE(kkv.value, tINT)) + ctr_imm_amt = kkv.value.i; + else if (kkv.key != "push" && kkv.key != "update_with_top") + error(kkv.value.lineno, "Unknown parser counter init command"); + } + } + } else if (kv.value.type == tCMD) { + if (kv.value[0] == "inc" || kv.value[0] == "increment") { + if (CHECKTYPE(kv.value[1], tINT)) ctr_imm_amt = kv.value[1].i; + } else if (kv.value[0] == "dec" || kv.value[0] == "decrement") { + if (CHECKTYPE(kv.value[1], tINT)) ctr_imm_amt = ~kv.value[1].i + 1; + } else { + error(kv.value.lineno, "Unknown parser counter command"); + } + } else if (kv.value.type == tSTR) { + if (kv.value == "pop") { + if (options.target == TOFINO) + error(kv.key.lineno, "Tofino does not have counter stack"); + ctr_stack_pop = true; + } else { + error(kv.value.lineno, "Unknown parser counter command"); + } + } else { + error(kv.value.lineno, "Syntax error for parser counter"); + } + } else if (kv.key == "hdr_len_inc_stop") { + if (options.target == TOFINO) + error(kv.key.lineno, "Tofino does not support hdr_len_inc_stop"); + else if (hdr_len_inc_stop) + error(kv.key.lineno, "Mulitple hdr_len_inc_stop in match"); + hdr_len_inc_stop = HdrLenIncStop(kv.value); + } else if (kv.key == "priority") { + if (priority) + error(kv.key.lineno, "Mulitple priority updates in match"); + else + priority = PriorityUpdate(kv.value); + } else if (kv.key == "shift") { + if (shift) error(kv.key.lineno, "Multiple shift settings in match"); + if (!CHECKTYPE(kv.value, tINT)) continue; + if ((shift = kv.value.i) < 0 || shift > PARSER_INPUT_BUFFER_SIZE) + error(kv.value.lineno, "shift value %d out of range", shift); + } else if (kv.key == "intr_md") { + if (!CHECKTYPE(kv.value, tINT)) continue; + if ((intr_md_bits = kv.value.i) < 0) + error(kv.value.lineno, "intr_md value %d is -ve", intr_md_bits); + } else if (kv.key == "offset_inc") { + if (offset_inc) error(kv.key.lineno, "Multiple offset_inc settings in match"); + if (!CHECKTYPE(kv.value, tINT)) continue; + offset_inc = kv.value.i; + } else if (kv.key == "buf_req") { + if (buf_req >= 0) error(kv.key.lineno, "Multiple buf_req settings in match"); + if (!CHECKTYPE(kv.value, tINT)) continue; + if ((buf_req = kv.value.i) < 0 || shift > PARSER_INPUT_BUFFER_SIZE) + error(kv.value.lineno, "buf_req value %d out of range", shift); + } else if (kv.key == "next") { + if (next.lineno >= 0) { + error(kv.key.lineno, "Multiple next settings in match"); + error(next.lineno, "previously set here"); + } + next = kv.value; + } else if (kv.key == "load") { + if (load.lineno) { + error(kv.value.lineno, "Multiple load entries in match"); + error(load.lineno, "previous specified here"); + } else { + load.setup(kv.value); + } + } else if (kv.key == "save") { + if (options.target == TOFINO) + error(kv.key.lineno, "Tofino does not have scratch registers in the parser"); + + if (load.save) error(kv.value.lineno, "Multiple save entries in match"); + + if (CHECKTYPE(kv.value, tVEC)) { + for (int i = 0; i < kv.value.vec.size; i++) { + if (CHECKTYPE(kv.value[i], tSTR)) { + if (kv.value[i] == "byte0") + load.save |= 1 << 0; + else if (kv.value[i] == "byte1") + load.save |= 1 << 1; + else if (kv.value[i] == "byte2") + load.save |= 1 << 2; + else if (kv.value[i] == "byte3") + load.save |= 1 << 3; + else + error(lineno, "Unexpected parser save source"); + } + } + } + } else if (kv.key == "checksum") { + csum.emplace_back(gress, kv); + } else if (kv.key == "field_mapping") { + if (CHECKTYPE(kv.value, tMAP)) { + for (auto map : kv.value.map) { + auto ref = Phv::Ref(gress, 0, map.key); + auto fm = FieldMapping(ref, map.value); + field_mapping.emplace_back(fm); + } + } + } else if (kv.key == "handle") { + if (CHECKTYPE(kv.value, tINT)) value_set_handle = kv.value.i; + } else if (kv.key == "disable_partial_hdr_err") { + if (!CHECKTYPE(kv.value, tINT)) continue; + if (options.target != TOFINO2) + error(kv.key.lineno, "disable_partial_hdr_err only available for Tofino2"); + + if (disable_partial_hdr_err != -1) + error(kv.key.lineno, "Multiple disable_partial_hdr_err settings in match"); + if (kv.value.i < 0 || kv.value.i > 1) + error(kv.value.lineno, "disable_partial_hdr_err value %ld out of range", + kv.value.i); + disable_partial_hdr_err = kv.value.i; + } else if (kv.key == "partial_hdr_err_proc") { + if (!CHECKTYPE(kv.value, tINT)) continue; + error(kv.key.lineno, "partial_hdr_err_proc is unsupported"); + if (partial_hdr_err_proc != -1) + error(kv.key.lineno, "Multiple partial_hdr_err_proc settings in match"); + if (kv.value.i < 0 || kv.value.i > 1) + error(kv.value.lineno, "partial_hdr_err_proc value %ld out of range", kv.value.i); + partial_hdr_err_proc = kv.value.i; + } else if (kv.key.type == tCMD && kv.key == "clot" && kv.key.vec.size == 2) { + clots.push_back(new Clot(gress, kv.key.vec[1], kv.value)); + } else if (kv.key.type == tINT) { + save.push_back(new Save(gress, this, kv.key.i, kv.key.i, kv.value)); + } else if (kv.key.type == tRANGE) { + save.push_back(new Save(gress, this, kv.key.lo, kv.key.hi, kv.value)); + } else if (kv.value.type == tINT) { + set.push_back(new Set(gress, this, kv.key, kv.value.i)); + } else if (kv.value.type == tCMD && kv.value[0] == "rotate") { + if (CHECKTYPE(kv.value[1], tINT)) + set.push_back(new Set(gress, this, kv.key, kv.value[1].i, ROTATE)); + } else { + error(kv.key.lineno, "Syntax error"); + } + } + + for (auto c : csum) { + if (c.type == 1 && c.end) { + if (c.dst_bit_hdr_end_pos >= shift) // see MODEL-542 + error(c.lineno, "Residual checksum end_pos must be less than state shift amount"); + } + } +} + +Parser::State::Match::Match(int l, gress_t gress, State *n) : lineno(l) { + /* build a default match for a synthetic start state */ + offset_inc = shift = 0; + offset_rst = true; + next.name = n->name; + next.ptr.push_back(n); +} + +static value_t &extract_save_phv(value_t &data) { + if (data.type == tVEC) return data[0]; + if (data.type == tCMD && (data[0] == "offset" || data[0] == "rotate")) return data[1]; + return data; +} + +Parser::State::Match::Save::Save(gress_t gress, Match *m, int l, int h, value_t &data, int flgs) + : match(m), lo(l), hi(h), where(gress, 0, extract_save_phv(data)), flags(flgs) { + if (hi < lo || hi - lo > 3 || (hi - lo == 2 && !Target::PARSER_EXTRACT_BYTES())) + error(data.lineno, "Invalid parser extraction size"); + if (data.type == tVEC) { + if (data.vec.size > 2 || data.vec.size < 1) + error(data.lineno, "Can only extract into single or pair"); + if (data.vec.size == 2) second = Phv::Ref(gress, 0, data[1]); + } + if (data.type == tCMD) { + if (data[0] == "offset") + flags |= OFFSET; + else if (data[0] == "rotate") + flags |= ROTATE; + } +} + +Parser::State::Match::Set::Set(gress_t gress, Match *m, value_t &data, int v, int flgs) + : match(m), where(gress, 0, extract_save_phv(data)), what(v), flags(flgs) { + if (data.type == tCMD) { + if (data[0] == "offset") + flags |= OFFSET; + else if (data[0] == "rotate") + flags |= ROTATE; + } +} + +bool Parser::State::Match::Clot::parse_length(const value_t &exp, int what) { + enum { START, MASK, SHIFT, LOAD }; + if (exp.type == tCMD) { + if (exp[0] == ">>") { + return what < SHIFT && parse_length(exp[1], LOAD) && parse_length(exp[2], SHIFT); + } else if (exp[0] == "&") { + return what < SHIFT && parse_length(exp[1], MASK) && parse_length(exp[2], MASK); + } + } else if (exp.type == tINT) { + switch (what) { + case START: + case MASK: + if (length_mask >= 0) return false; + if ((length_mask = exp.i) < 0 || length_mask > 0x3f) { + error(exp.lineno, "length mask %d out of range", length_mask); + return false; + } + return true; + case SHIFT: + if (length_shift >= 0) return false; + if ((length_shift = exp.i) < 0 || length_shift > 15) { + error(exp.lineno, "length shift %d out of range", length_shift); + return false; + } + return true; + default: + return false; + } + } else if (exp.type == tSTR && exp.s[0] == '@' && isdigit(exp.s[1])) { + char *end; + if (what == SHIFT || length >= 0 || (length = strtol(exp.s + 1, &end, 10)) < 0 || *end) + return false; + load_length = true; + return true; + } + return false; +} + +Parser::State::Match::Clot::Clot(gress_t gress, const value_t &tag, const value_t &data) + : lineno(tag.lineno) { + if (CHECKTYPE2(tag, tINT, tSTR)) { + if (tag.type == tINT) { + this->tag = tag.i; + name = std::to_string(tag.i); + } else { + this->tag = -1; + name = tag.s; + } + } + Parser::clots[gress][name].push_back(this); + if (!CHECKTYPE3(data, tINT, tRANGE, tMAP)) return; + if (data.type == tINT) { + start = data.i; + length = 1; + } else if (data.type == tRANGE) { + start = data.lo; + length = data.hi - data.lo + 1; + } else { + for (auto &kv : data.map) { + if (kv.key == "start") { + if (CHECKTYPE(kv.value, tINT)) start = kv.value.i; + } else if (kv.key == "length") { + if (kv.value.type == tINT) { + length = kv.value.i; + } else if (!parse_length(kv.value) || !load_length) { + error(kv.value.lineno, "Syntax error"); + } + if (length_mask < 0) length_mask = 0x3f; + if (length_shift < 0) length_shift = 0; + } else if (kv.key == "max_length") { + if (CHECKTYPE(kv.value, tINT)) max_length = kv.value.i; + } else if (kv.key == "checksum") { + if (CHECKTYPE(kv.value, tINT)) csum_unit = kv.value.i; + } else if (kv.key == "stack_depth") { + if (CHECKTYPE(kv.value, tINT)) stack_depth = kv.value.i; + } else if (kv.key == "stack_inc") { + if (CHECKTYPE(kv.value, tINT)) stack_inc = kv.value.i; + } else { + error(kv.key.lineno, "Unknown CLOT key %s", value_desc(kv.key)); + } + } + } + if (start < 0) error(data.lineno, "No start in clot %s", name.c_str()); + if (length < 0) error(data.lineno, "No length in clot %s", name.c_str()); + if (max_length < 0) { + if (load_length) + max_length = 64; + else + max_length = length; + } else if (!load_length && max_length != length) { + error(data.lineno, "Inconsistent constant length and max_length in clot"); + } + // Create objects for each element in the stack. Only the first element + // creates the additional stack elements, and this should only be done + // for clot instances in parser loops. + for (int i = stack_inc; i < stack_depth; i += stack_inc) new Clot(gress, *this, i); +} + +/// Clone a clot to create a new stack instance. Should only be used +/// for clot extrcts in non-unrolled parser loops. +Parser::State::Match::Clot::Clot(gress_t gress, const Clot &src, int instance) { + if (src.tag >= 0) { + this->tag = src.tag + instance; + name = std::to_string(this->tag); + } else { + this->tag = -1; + name = src.name + "." + std::to_string(instance); + } + Parser::clots[gress][name].push_back(this); + lineno = src.lineno; + load_length = src.load_length; + start = src.start; + length = src.length; + length_shift = src.length_shift; + length_mask = src.length_mask; + max_length = src.max_length; + csum_unit = src.csum_unit; + stack_depth = src.stack_depth; +} + +Parser::State::Match::FieldMapping::FieldMapping(Phv::Ref &ref, const value_t &a) { + if (CHECKTYPE(a, tCMD)) { + where = ref; + container_id = a.vec[0].s; + lo = a.vec[1].lo; + hi = a.vec[1].hi; + } else { + error(a.lineno, "Syntax error"); + } +} + +Parser::State::Match::HdrLenIncStop::HdrLenIncStop(const value_t &data) { + if (CHECKTYPE(data, tINT)) { + if (data.i < 0 || data.i > PARSER_INPUT_BUFFER_SIZE) + error(data.lineno, "hdr_len_inc_stop %" PRId64 " out of range", data.i); + lineno = data.lineno; + final_amt = data.i; + } +} + +Parser::State::State(int l, const char *n, gress_t gr, match_t sno, const VECTOR(pair_t) & data) + : name(n), gress(gr), stateno(sno), def(0), lineno(l) { + VECTOR(pair_t) default_data = EMPTY_VECTOR_INIT; + bool have_default = data["default"] != 0; + for (auto &kv : data) { + if (kv.key.type == tINT && kv.value.type == tMAP) { + match_t m = {~(unsigned)kv.key.i, (unsigned)kv.key.i}; + match.push_back(new Match(kv.key.lineno, gress, this, m, kv.value.map)); + } else if (kv.key.type == tBIGINT && kv.value.type == tMAP) { + match_t m = {~(unsigned)kv.key.bigi.data[0], (unsigned)kv.key.bigi.data[0]}; + match.push_back(new Match(kv.key.lineno, gress, this, m, kv.value.map)); + } else if (kv.key == "value_set" && kv.value.type == tMAP) { + match_t m = {0, 0}; + match.push_back(new Match(kv.key.lineno, gress, this, m, kv.value.map)); + if (kv.key.type == tCMD) { + if (CHECKTYPE(kv.key[1], tSTR)) match.back()->value_set_name = kv.key[1].s; + if (kv.key.vec.size > 2 && CHECKTYPE(kv.key[2], tINT)) + match.back()->value_set_size = kv.key[2].i; + else + match.back()->value_set_size = 1; + } else { + match.back()->value_set_size = 1; + } + } else if (kv.key.type == tMATCH) { + if (!CHECKTYPE(kv.value, tMAP)) continue; + match.push_back(new Match(kv.key.lineno, gress, this, kv.key.m, kv.value.map)); + } else if (kv.key == "match") { + if (key.lineno) { + error(kv.value.lineno, "Multiple match entries in state %s", n); + error(key.lineno, "previous specified here"); + } else { + key.setup(kv.value); + } + } else if (kv.key == "option") { + if (kv.value == "ignore_max_depth") + ignore_max_depth = true; + else + error(kv.value.lineno, "Unknown state option %s", value_desc(kv.value)); + } else if (kv.key == "default") { + if (!CHECKTYPE(kv.value, tMAP)) continue; + if (def) { + error(kv.key.lineno, "Multiple defaults in state %s", n); + error(def->lineno, "previous specified here"); + } else { + match_t m = {0, 0}; + def = new Match(kv.key.lineno, gress, this, m, kv.value.map); + } + } else if (!have_default) { + VECTOR_add(default_data, kv); + } else { + error(kv.key.lineno, "Syntax error"); + } + } + if (default_data.size) { + BUG_CHECK(!def); + match_t m = {0, 0}; + def = new Match(default_data[0].key.lineno, gress, this, m, default_data); + } + VECTOR_fini(default_data); +} + +bool Parser::State::can_be_start() { + if (match.size()) return false; + if (!def) return true; + // if (def->counter || def->offset || def->shift) return false; + // if (def->counter_reset || def->offset_reset) return false; + // if (def->save.size() || def->set.size()) return false; + return true; +} + +void Parser::State::unmark_reachable(Parser *pa, bitvec &unreach) { + if (!unreach[all_idx]) return; + unreach[all_idx] = 0; + for (auto m : match) m->unmark_reachable(pa, this, unreach); + if (def) def->unmark_reachable(pa, this, unreach); +} + +void Parser::State::Match::unmark_reachable(Parser *pa, Parser::State *state, bitvec &unreach) { + for (auto succ : next) succ->unmark_reachable(pa, unreach); +} + +/********* pass 1 *********/ + +void Parser::State::Match::pass1(Parser *pa, State *state) { + next.check(state->gress, pa, state); + for (auto s : save) { + if (!s->where.check()) continue; + if (s->where->reg.parser_id() < 0) + error(s->where.lineno, "%s is not accessable in the parser", s->where->reg.name); + if (options.target == TOFINO && s->lo >= 32 && s->lo < 54) + error(s->where.lineno, "byte 32-53 of input buffer cannot be used for output"); + if (options.target == JBAY && s->lo >= 32 && s->lo < 48) + error(s->where.lineno, "byte 32-47 of input buffer cannot be used for output"); + pa->phv_use[state->gress][s->where->reg.uid] = 1; + int size = s->where.size(); + if (s->second) { + if (!s->second.check()) continue; + if (s->second->reg.parser_id() < 0) + error(s->second.lineno, "%s is not accessable in the parser", s->second->reg.name); + else if (s->second->lo >= 32 && s->second->lo < 54) + error(s->where.lineno, "byte 32-53 of input buffer cannot be used for output"); + else if (s->second->reg.parser_id() != s->where->reg.parser_id() + 1 || + (s->where->reg.parser_id() & 1)) + error(s->second.lineno, "Can only write into even/odd register pair"); + else if (s->second->lo || s->second->hi != size - 1) + error(s->second.lineno, "Can only write data into whole phv registers in parser"); + else + size *= 2; + } + if (!Target::PARSER_EXTRACT_BYTES() && s->where.size() != s->where->reg.size) + error(s->where.lineno, "Can only write data into whole phv registers in parser"); + else if ((s->hi - s->lo + 1) * 8 != size) + error(s->where.lineno, "Data to write doesn't match phv register size"); + } + for (auto s : set) { + if (!s->where.check()) continue; + if (s->where->reg.parser_id() < 0) + error(s->where.lineno, "%s is not accessable in the parser", s->where->reg.name); + pa->phv_use[state->gress][s->where->reg.uid] = 1; + } + if (value_set_size == 0) { + uint64_t match_mask = bitMask(state->key.width); + uint64_t not_covered = match_mask & ~(match.word0 | match.word1); + if (not_covered != 0) { + warning(lineno, + "Match pattern does not cover all bits of match key, " + "assuming the rest are don't care"); + match.word0 |= not_covered; + match.word1 |= not_covered; + } + if ((match.word1 & ~match.word0 & ~match_mask) != 0) + error(lineno, "Matching on bits not in the match of state %s", state->name.c_str()); + for (auto m : state->match) { + if (m == this) break; + if (m->match == match) { + warning(lineno, "Can't match parser state due to previous match"); + warning(m->lineno, "here"); + break; + } + } + } + for (auto &c : csum) c.pass1(pa); +} + +bool Parser::State::Match::Set::merge(gress_t gress, const Set &a) { + auto orig = where; + if (where->reg != a.where->reg) return false; + if (!(where->hi < a.where->lo || a.where->hi < where->lo)) { + warning(where.lineno, "Phv slices %s and %s overlapping", where.name(), a.where.name()); + } + what = ((what << where->lo) | (a.what << a.where->lo)) >> (std::min(where->lo, a.where->lo)); + where = Phv::Ref(where->reg, gress, std::min(where->lo, a.where->lo), + std::max(where->hi, a.where->hi)); + LOG1("Merging phv slices " << orig << " + " << a.where << " = " << where); + return true; +} + +void Parser::State::pass1(Parser *pa) { + for (auto m : match) m->pass1(pa, this); + if (def) def->pass1(pa, this); + for (auto code : MatchIter(stateno)) { + if (pa->state_use[code]) { + error(lineno, "%sgress state %s uses state code %d, already in use", gress ? "E" : "In", + name.c_str(), code); + for (auto *state : pa->all) { + if (state != this && state->gress == gress && state->stateno.matches(code)) + error(state->lineno, "also used by state %s", state->name.c_str()); + } + } + pa->state_use[code] = 1; + } + + for (auto m : match) + for (auto succ : m->next) succ->pred.insert(m); + + if (def) + for (auto succ : def->next) succ->pred.insert(def); +} + +/********* pass 2 *********/ + +void Parser::State::MatchKey::preserve_saved(unsigned saved) { + for (int i = 3; i >= 0; i--) { + if (!((saved >> i) & 1)) continue; + if (data[i].bit < 0 || data[i].byte == USE_SAVED) continue; + if ((specified >> i) & 1) { + error(lineno, + "match in %s matcher conflicts with previous state save " + "action", + Parser::match_key_loc_name(i)); + } else if (move_down(i) < 0) { + error(lineno, + "Ran out of matching space due to preserved values from " + "previous states"); + break; + } + } +} + +void Parser::State::Match::pass2(Parser *pa, State *state) { + for (auto &c : csum) c.pass2(pa); + + if (ctr_instr) ctr_instr->pass2(pa); + + if (clots.size() > 0) { + if (options.target == TOFINO) + error(clots[0]->lineno, "clots not supported on tofino"); + else if (clots.size() > 2) + error(clots[2]->lineno, "no more than two clots per state"); + } +} + +void Parser::State::pass2(Parser *pa) { + if (!stateno) { + unsigned s; + for (s = 0; pa->state_use[s]; s++) { + } + if (s > PARSER_STATE_MASK) { + error(lineno, "Can't allocate state number for %sgress state %s", gress ? "e" : "in", + name.c_str()); + } else { + stateno.word0 = s ^ PARSER_STATE_MASK; + stateno.word1 = s; + pa->state_use[s] = 1; + } + } + unsigned def_saved = 0; + if (def && def->load.lineno >= 0) { + for (int i = 0; i < 4; i++) + if (def->load.data[i].bit >= 0) def_saved |= 1 << i; + if (def_saved && def->next) def->next->key.preserve_saved(def_saved); + } + for (auto m : match) { + m->pass2(pa, this); + unsigned saved = def_saved; + if (m->load.lineno) { + for (int i = 0; i < 4; i++) + if (m->load.data[i].bit >= 0) + saved |= 1 << i; + else if (def && def->load.lineno && def->load.data[i].bit >= 0) + m->load.data[i] = def->load.data[i]; + } + if (saved) { + if (m->next) + m->next->key.preserve_saved(saved); + else if (def && def->next) + def->next->key.preserve_saved(saved); + } + } +} + +/********* output *********/ + +/// Extractor config tracking and register config code +/// Different tofino models have very different ways in which their parser extractors are +/// managed, but all are common in that there are multiple extractions that can happen in +/// parallel in a single parser match tcam row. We manage this by having a target-specific +/// 'output_map' object passed via a void * to target-sepcific write_output_config methods +/// along with an `unsigned used` mask that tracks which or how many extractors have been +/// used, so as to issue errors for conflicting uses. +/// +/// The `setup_phv_output_map` method creates the target specific output_map object that +/// will be passed to subsequent `write_output_config` calls to deal with each individual +/// extract. Finally, `mark_unused_output_map` is called to deal with any register setup +/// needed for unused extractors. They're called 'outputs' as the are concerned with +/// outputting PHV values from the parser. +/// +/// PHV outputs are split into 'saves' and 'sets' which come from different syntax in the +/// asm source. 'saves' copy data from the input buffer into PHVs, while 'sets' write +/// constants into the PHVs. Different targets have different constraints on how flexible +/// they are for saves vs sets, so some want to do saves first and other sets +/// - tofino1: do saves first (why? sets seem more constrained, but there's an issue +/// with ganging smaller extractors to write larger PHVs) +/// - tofino2: do sets first as some extractors can only do saves +/// +/// FIXME -- should probably refactor this into a more C++ style base class pointer with +/// derived classes for each target. Should move the 'used' mask into that object as well. +/// Alternately, could move the entire `setup` to `mark_unused` process into a target specific +/// method. + +std::set Parser::State::Match::get_all_preds() { + std::set visited; + return get_all_preds_impl(visited); +} + +std::set Parser::State::Match::get_all_preds_impl( + std::set &visited) { + if (visited.count(this)) return {}; + + visited.insert(this); + + std::set rv; + + for (auto p : this->state->pred) { + rv.insert(p); + auto pred = p->get_all_preds_impl(visited); + rv.insert(pred.begin(), pred.end()); + } + + return rv; +} + +/* If the bitvec contains one of a pair of 8-bit PHVs, add the other, as they need + * to be owened together in the parser ingress/egress ownership */ +bitvec expand_parser_groups(bitvec phvs) { + for (int i : phvs) + if (Phv::reg(i)->size == 8) phvs[i ^ 1] = 1; + return phvs; +} + +/* remove PHVs from the bitvec which are not accessable in the parser + * FIXME -- should just have a static const bitvec of the valid ones and & with it */ +bitvec remove_nonparser(bitvec phvs) { + for (int i : phvs) + if (Phv::reg(i)->parser_id() < 0) phvs[i] = 0; + return phvs; +} + +void setup_jbay_ownership(bitvec phv_use[2], checked_array<128, ubits<1>> &left, + checked_array<128, ubits<1>> &right, checked_array<256, ubits<1>> &main_i, + checked_array<256, ubits<1>> &main_e) { + for (int i : phv_use[EGRESS]) { + if (Phv::reg(i)->size == 8) { + if (phv_use[INGRESS][i ^ 1]) + error(0, "Can't use %s in ingress and %s in egress in Tofino2 parser", + Phv::reg(i ^ 1)->name, Phv::reg(i)->name); + } + } + + std::set left_egress_owner_ids, right_egress_owner_ids; + std::set all_egress_owner_ids; + + for (int i : phv_use[EGRESS]) { + auto id = Phv::reg(i)->parser_id(); + if (id < 0) + error(0, "Can't access %s in parser", Phv::reg(i)->name); + else if (id < 128) + left_egress_owner_ids.insert(id); + else + right_egress_owner_ids.insert(id - 128); + + all_egress_owner_ids.insert(id); + + if (Phv::reg(i)->size == 32) { + if (++id < 128) + left_egress_owner_ids.insert(id); + else + right_egress_owner_ids.insert(id - 128); + + all_egress_owner_ids.insert(id); + } + } + + for (auto id : left_egress_owner_ids) left[id] = 1; + for (auto id : right_egress_owner_ids) right[id] = 1; + for (auto id : all_egress_owner_ids) main_i[id] = main_e[id] = 1; +} + +void setup_jbay_clear_on_write(bitvec phv_allow_clear_on_write, checked_array<128, ubits<1>> &left, + checked_array<128, ubits<1>> &right, + checked_array<256, ubits<1>> &main_i, + checked_array<256, ubits<1>> &main_e) { + for (int i : phv_allow_clear_on_write) { + auto id = Phv::reg(i)->parser_id(); + + if (id < 0) + error(0, "Can't access %s in parser", Phv::reg(i)->name); + else if (id < 128) + left[id] = 1; + else + right[id - 128] = 1; + + main_i[id] = main_e[id] = 1; + + if (Phv::reg(i)->size == 32) { + if (++id < 128) + left[id] = 1; + else + right[id - 128] = 1; + + main_i[id] = main_e[id] = 1; + } + } +} + +void setup_jbay_no_multi_write(bitvec phv_allow_bitwise_or, bitvec phv_allow_clear_on_write, + checked_array<256, ubits<1>> &nmw_i, + checked_array<256, ubits<1>> &nmw_e) { + std::set allow_multi_write_ids; + + for (int i : phv_allow_bitwise_or) { + auto id = Phv::reg(i)->parser_id(); + allow_multi_write_ids.insert(id); + + if (Phv::reg(i)->size == 32) allow_multi_write_ids.insert(++id); + } + + for (int i : phv_allow_clear_on_write) { + auto id = Phv::reg(i)->parser_id(); + allow_multi_write_ids.insert(id); + + if (Phv::reg(i)->size == 32) allow_multi_write_ids.insert(++id); + } + + for (int i = 0; i < 256; i++) { + if (!allow_multi_write_ids.count(i)) nmw_i[i] = nmw_e[i] = 1; + } +} + +// WARNING: This function will print all parser paths. In some programs based on +// the complexity of parser graphs, this can result in a path explosion as it +// visits all possible paths and can lead to the function taking an unreasonably +// large amount of time to execute. +// +// The intention for this function is for DEBUG purposes only and should not be +// checked in with it being called from anywhere for logging due to above +// potential worst case issue. +// +// Function also checks for cycles in the parser graph. +// For debug, call function on a parser object and run assembler with -Tparser:1 +void Parser::print_all_paths() { + // Check for cycles in states + ordered_set vstates; + int count = 0; + std::function visit_states = [&](State *s, std::string sstr) { + count++; + // To limit execution uncomment and set variable + // if (count > COUNT_STATE_PATHS) exit(1); + if (s == nullptr) { + LOG1("State Path : " << sstr << " => END"); + return; + } + // Check for previously visited states to show cycles in parser state + // graph + if (vstates.count(s->name)) { + LOG1("****Revisiting " << s->name << " through path : " << sstr + << ". Parser graph has a cycle"); + return; + } + if (!sstr.empty()) sstr += " => "; + sstr += s->name; + vstates.insert(s->name); + + LOG1("State Path (" << count << ") : depth (" << vstates.size() << ") :" << sstr); + + for (auto m : s->match) { + std::stringstream ss; + ss << m->match; + std::string sstr2 = sstr + ("(" + ss.str() + ")"); + for (auto ns : m->next) { + visit_states(ns, sstr2); + } + } + vstates.erase(s->name); + }; + if (states.size() > 0) visit_states(states.begin()->second, ""); +} diff --git a/backends/tofino/bf-asm/parser-tofino-jbay.h b/backends/tofino/bf-asm/parser-tofino-jbay.h new file mode 100644 index 00000000000..7fe0329897b --- /dev/null +++ b/backends/tofino/bf-asm/parser-tofino-jbay.h @@ -0,0 +1,722 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef PARSER_TOFINO_JBAY_H_ +#define PARSER_TOFINO_JBAY_H_ + +#include +#include +#include + +#include "bitvec.h" +#include "parser.h" +#include "phv.h" +#include "sections.h" +#include "target.h" +#include "ubits.h" + +enum { + /* global constants related to parser */ + PARSER_STATE_MASK = 0xff, + PARSER_TCAM_DEPTH = 256, + PARSER_CHECKSUM_ROWS = 32, + PARSER_CTRINIT_ROWS = 16, + PARSER_INPUT_BUFFER_SIZE = 32, + PARSER_SRC_MAX_IDX = 63, + PARSER_MAX_CLOTS = 64, + PARSER_MAX_CLOT_LENGTH = 64, +}; + +/** + * @brief Representation of the Tofino 1/2 parser in assembler + * @ingroup parde + */ +class Parser : public BaseParser, public Contextable { + void write_config(RegisterSetBase ®s, json::map &json, bool legacy = true) override; + template + void write_config(REGS &, json::map &, bool legacy = true); + struct CounterInit { + gress_t gress; + int lineno = -1, addr = -1; + int add = 0, mask = 255, rot = 0, max = 255, src = -1; + CounterInit(gress_t, pair_t); + void pass1(Parser *) {} + void pass2(Parser *); + template + void write_config(REGS &, gress_t, int); + bool equiv(const CounterInit &) const; + }; + struct PriorityUpdate { + int lineno = -1, offset = -1, shift = -1, mask = -1; + PriorityUpdate() {} + explicit PriorityUpdate(const value_t &data); + bool parse(const value_t &exp, int what = 0); + explicit operator bool() const { return lineno >= 0; } + template + void write_config(REGS &); + }; + struct RateLimit { + int lineno = -1; + int inc = -1, dec = -1, max = -1, interval = -1; + void parse(const VECTOR(pair_t) &); + explicit operator bool() const { return lineno >= 0; } + template + void write_config(REGS &, gress_t); + }; + + public: + struct Checksum; + + struct State { + struct Ref { + int lineno; + std::string name; + match_t pattern; + std::vector ptr; + Ref() : lineno(-1) { pattern.word0 = pattern.word1 = 0; } + Ref &operator=(const value_t &); + explicit Ref(value_t &v) { *this = v; } + operator bool() const { return ptr.size() > 0; } + State *operator->() const { + BUG_CHECK(ptr.size() == 1); + return ptr[0]; + } + State *operator*() const { + BUG_CHECK(ptr.size() == 1); + return ptr[0]; + } + bool operator==(const Ref &a) const { return name == a.name && pattern == a.pattern; } + void check(gress_t, Parser *, State *); + std::vector::const_iterator begin() const { return ptr.begin(); } + std::vector::const_iterator end() const { return ptr.end(); } + }; + struct MatchKey { + int lineno; + struct { + short bit, byte; + } data[4]; + enum { USE_SAVED = 0x7fff }; /* magic number can be stored in 'byte' field */ + short specified; + short ctr_zero, ctr_neg; + short width; + short save = 0; + MatchKey() : lineno(0), specified(0), ctr_zero(-1), ctr_neg(-1), width(0) { + for (auto &a : data) a.bit = a.byte = -1; + } + void setup(value_t &); + int setup_match_el(int, value_t &); + void preserve_saved(unsigned mask); + template + void write_config(REGS &, json::vector &); + + private: + int add_byte(int, int, bool use_saved = false); + int move_down(int); + }; + struct OutputUse { + unsigned b8 = 0, b16 = 0, b32 = 0; + OutputUse &operator+=(const OutputUse &a) { + b8 += a.b8; + b16 += a.b16; + b32 += a.b32; + return *this; + } + }; + struct Match { + int lineno; + State *state = nullptr; + match_t match; + std::string value_set_name; + int value_set_size = 0; + int value_set_handle = -1; + int offset_inc = 0, shift = 0, buf_req = -1; + int disable_partial_hdr_err = -1, partial_hdr_err_proc = -1; + bool offset_rst = false; + int intr_md_bits = 0; + + int ctr_imm_amt = 0, ctr_ld_src = 0, ctr_load = 0; + bool ctr_stack_push = false, ctr_stack_upd_w_top = false, ctr_stack_pop = false; + + CounterInit *ctr_instr = nullptr; + + PriorityUpdate priority; + + Ref next; + MatchKey load; + + int row = -1; + /// Data for narrow to wide extraction analysis, flag and + /// vector of affected PHV locations + bool has_narrow_to_wide_extract = false; + // 32b narrow to wide extractions using 2x16 extractions + std::vector narrow_to_wide_32b_16; + // 32b narrow to wide extractions using 4x8 extractions + std::vector narrow_to_wide_32b_8; + // 16b narrow to wide extractions using 2x8 extractions + std::vector narrow_to_wide_16b_8; + + enum flags_t { OFFSET = 1, ROTATE = 2 }; + + struct Save { + Match *match; + int lo, hi; + Phv::Ref where, second; + int flags; + Save(gress_t, Match *m, int l, int h, value_t &data, int flgs = 0); + template + int write_output_config(REGS &, void *, unsigned &, int, int) const; + }; + std::vector save; + + struct Set { + Match *match = nullptr; + Phv::Ref where; + unsigned what; + int flags; + Set(gress_t gress, Match *m, value_t &data, int v, int flgs = 0); + template + void write_output_config(REGS &, void *, unsigned &, int, int) const; + bool merge(gress_t, const Set &a); + bool operator==(const Set &a) const { + return where == a.where && what == a.what && flags == a.flags; + } + }; + std::vector set; + + struct Clot { + int lineno, tag; + std::string name; + bool load_length = false; + int start = -1, length = -1, length_shift = -1, length_mask = -1; + int max_length = -1; + int csum_unit = -1; + int stack_depth = 1; + int stack_inc = 1; + Clot(gress_t gress, const value_t &tag, const value_t &data); + Clot(const Clot &) = delete; + Clot(Clot &&) = delete; + bool parse_length(const value_t &exp, int what = 0); + template + void write_config(PO_ROW &, int, bool) const; + + private: + Clot(gress_t, const Clot &, int); + }; + std::vector clots; + std::vector csum; + + struct FieldMapping { + Phv::Ref where; + std::string container_id; + int lo = -1; + int hi = -1; + FieldMapping(Phv::Ref &ref, const value_t &a); + }; + std::vector field_mapping; + + struct HdrLenIncStop { + int lineno = -1; + unsigned final_amt = 0; + HdrLenIncStop() {} + explicit HdrLenIncStop(const value_t &data); + explicit operator bool() const { return lineno >= 0; } + template + void write_config(PO_ROW &) const; + } hdr_len_inc_stop; + + Match(int lineno, gress_t, State *s, match_t m, VECTOR(pair_t) & data); + Match(int lineno, gress_t, State *n); + ~Match() { + if (ctr_instr) delete ctr_instr; + } + void unmark_reachable(Parser *, State *state, bitvec &unreach); + void pass1(Parser *pa, State *state); + void pass2(Parser *pa, State *state); + template + int write_load_config(REGS &, Parser *, State *, int) const; + template + void write_lookup_config(REGS &, State *, int) const; + template + void write_counter_config(EA_REGS &) const; + template + void write_common_row_config(REGS &, Parser *, State *, int, Match *, json::map &); + template + void write_row_config(REGS &, Parser *, State *, int, Match *, json::map &); + template + void write_config(REGS &, Parser *, State *, Match *, json::map &); + template + void write_config(REGS &, json::vector &); + + template + void write_saves(REGS ®s, Match *def, void *output_map, int &max_off, unsigned &used, + int csum_8b, int csum_16b); + template + void write_sets(REGS ®s, Match *def, void *output_map, unsigned &used, int csum_8b, + int csum_16b); + + std::set get_all_preds(); + std::set get_all_preds_impl(std::set &visited); + }; + + std::string name; + gress_t gress; + match_t stateno; + MatchKey key; + std::vector match; + Match *def; + std::set pred; + bool ignore_max_depth = false; + int lineno = -1; + int all_idx = -1; + + State(State &&) = default; + State(int lineno, const char *name, gress_t, match_t stateno, const VECTOR(pair_t) & data); + bool can_be_start(); + void unmark_reachable(Parser *, bitvec &); + void pass1(Parser *); + void pass2(Parser *); + template + int write_lookup_config(REGS &, Parser *, State *, int, const std::vector &); + template + void write_config(REGS &, Parser *, json::vector &); + }; + + struct Checksum { + int lineno = -1, addr = -1, unit = -1; + gress_t gress; + Phv::Ref dest; + int tag = -1; + unsigned add = 0, mask = 0, swap = 0, mul_2 = 0; + unsigned dst_bit_hdr_end_pos = 0; + bool start = false, end = false, shift = false; + unsigned type = 0; // 0 = verify, 1 = residual, 2 = clot + Checksum(gress_t, pair_t); + bool equiv(const Checksum &) const; + void pass1(Parser *); + void pass2(Parser *); + template + void write_config(REGS &, Parser *); + template + void write_output_config(REGS &, Parser *, State::Match *, void *, unsigned &) const; + + private: + template + void write_tofino_row_config(ROW &row); + template + void write_row_config(ROW &row); + }; + + public: + void input(VECTOR(value_t) args, value_t data); + void process(); + void output(json::map &) override; + void output_legacy(json::map &); + gress_t gress; + std::string name; + std::map states; + std::vector all; + std::map match_to_row; + bitvec port_use; + int parser_no; // used to print cfg.json + bitvec state_use; + State::Ref start_state[4]; + int priority[4] = {0}; + int pri_thresh[4] = {0, 0, 0, 0}; + int tcam_row_use = 0; + Phv::Ref parser_error; + // the ghost "parser" extracts 32-bit value + // this information is first extracted in AsmParser and passed to + // individual Parser, because currently parse_merge register is programmed + // in Parser class. + // FIXME -- should move all merge reg handling into AsmParser. + std::vector ghost_parser; + unsigned ghost_pipe_mask = 0xf; // only set for JBAY + bitvec (&phv_use)[2]; + bitvec phv_allow_bitwise_or, phv_allow_clear_on_write; + bitvec phv_init_valid; + int hdr_len_adj = 0, meta_opt = 0; + std::vector> checksum_use; + std::array counter_init = {}; + static std::map>> clots; + static std::array, PARSER_MAX_CLOTS> clot_use; + static unsigned max_handle; + int parser_handle = -1; + RateLimit rate_limit; + + Parser(bitvec (&phv_use)[2], gress_t gr, int idx) + : gress(gr), parser_no(idx), phv_use(phv_use) { + if (gress == INGRESS) { + parser_depth_max_bytes = Target::PARSER_DEPTH_MAX_BYTES_INGRESS(); + parser_depth_min_bytes = Target::PARSER_DEPTH_MIN_BYTES_INGRESS(); + } else { + parser_depth_max_bytes = Target::PARSER_DEPTH_MAX_BYTES_EGRESS(); + parser_depth_min_bytes = Target::PARSER_DEPTH_MIN_BYTES_EGRESS(); + } + } + + template + void gen_configuration_cache(REGS &, json::vector &cfg_cache); + static int clot_maxlen(gress_t gress, unsigned tag) { + auto &vec = clot_use[tag]; + return vec.empty() ? -1 : vec.at(0)->max_length; + } + static int clot_maxlen(gress_t gress, std::string tag) { + if (clots.count(gress) && clots.at(gress).count(tag)) + return clots.at(gress).at(tag).at(0)->max_length; + return -1; + } + static int clot_tag(gress_t gress, std::string tag) { + if (clots.count(gress) && clots.at(gress).count(tag)) + return clots.at(gress).at(tag).at(0)->tag; + return -1; + } + + static const char *match_key_loc_name(int loc); + static int match_key_loc(const char *key); + static int match_key_loc(value_t &key, bool errchk = true); + static int match_key_size(const char *key); + + // Parser Handle Setup + // ____________________________________________________ + // | Table Type | Pipe Id | Parser Handle | PVS Handle | + // 31 24 20 12 0 + // PVS Handle = 12 bits + // Parser Handle = 8 bits + // Pipe ID = 4 bits + // Table Type = 8 bits (Parser type is 15) + static unsigned next_handle() { + // unique_table_offset is to support multiple pipe. + // assume parser type is 15, table type used 0 - 6 + return max_handle++ << 12 | unique_table_offset << 20 | 15 << 24; + } + // Store parser names to their handles. Used by phase0 match tables to link + // parser handle + static std::map parser_handles; + static unsigned get_parser_handle(std::string phase0Table) { + for (auto p : Parser::parser_handles) { + auto parser_name = p.first; + if (phase0Table.find(parser_name) != std::string::npos) return p.second; + } + return 0; + } + + template + void *setup_phv_output_map(REGS &, gress_t, int); + + State *get_start_state() { + std::vector startNames = {"start", "START", "$entry_point.start", + "$entry_point"}; + for (auto n : startNames) { + if (states.count(n)) return states.at(n); + } + return nullptr; + } + + int get_prsr_max_dph(); + int get_header_stack_size_from_valid_bits(std::vector sets); + + // Debug + void print_all_paths(); + + private: + template + void mark_unused_output_map(REGS &, void *, unsigned); + void define_state(gress_t gress, pair_t &kv); + void output_default_ports(json::vector &vec, bitvec port_use); + int state_prsr_dph_max(const State *s); + int state_prsr_dph_max(const State *s, std::map> &visited, + int curr_dph_bits); + int parser_depth_max_bytes, parser_depth_min_bytes; +}; + +class AsmParser : public BaseAsmParser { + std::vector parser[2]; // INGRESS, EGRESS + bitvec phv_use[2]; // ingress/egress only + std::vector ghost_parser; // the ghost "parser" extracts 32-bit value. This 32-bit + // can be from a single 32-bit container or multiple + // smaller one. + unsigned ghost_pipe_mask = 0xf; // only set for JBAY + void start(int lineno, VECTOR(value_t) args) override; + void input(VECTOR(value_t) args, value_t data) override; + void process() override; + void output(json::map &) override; + void init_port_use(bitvec &port_use, const value_t &arg); + + public: + AsmParser() : BaseAsmParser("parser"){}; + ~AsmParser() {} + + // For gtest + std::vector test_get_parser(gress_t gress); +}; + +template +void Parser::PriorityUpdate::write_config(REGS &action_row) { + if (offset >= 0) { + action_row.pri_upd_type = 1; + action_row.pri_upd_src = offset; + action_row.pri_upd_en_shr = shift; + action_row.pri_upd_val_mask = mask; + } else { + action_row.pri_upd_type = 0; + action_row.pri_upd_en_shr = 1; + action_row.pri_upd_val_mask = mask; + } +} + +// for jbay (tofino1 is specialized) +template <> +void Parser::RateLimit::write_config(::Tofino::regs_pipe ®s, gress_t gress); +template +void Parser::RateLimit::write_config(REGS ®s, gress_t gress) { + if (gress == INGRESS) { + auto &ctrl = regs.pardereg.pgstnreg.parbreg.left.i_phv_rate_ctrl; + ctrl.inc = inc; + ctrl.interval = interval; + ctrl.max = max; + } else if (gress == EGRESS) { + auto &ctrl = regs.pardereg.pgstnreg.parbreg.right.e_phv_rate_ctrl; + ctrl.inc = inc; + ctrl.interval = interval; + ctrl.max = max; + } +} + +template +void Parser::State::MatchKey::write_config(REGS &, json::vector &) { + // FIXME -- TBD -- probably needs to be different for tofino/jbay, so there will be + // FIXME -- template specializations for this in those files +} + +template +void Parser::State::Match::write_saves(REGS ®s, Match *def, void *output_map, int &max_off, + unsigned &used, int csum_8b, int csum_16b) { + if (offset_inc) + for (auto s : save) s->flags |= OFFSET; + for (auto s : save) + max_off = + std::max(max_off, s->write_output_config(regs, output_map, used, csum_8b, csum_16b)); + if (def) + for (auto &s : def->save) + max_off = std::max(max_off, + s->write_output_config(regs, output_map, used, csum_8b, csum_16b)); +} + +template +void Parser::State::Match::write_sets(REGS ®s, Match *def, void *output_map, unsigned &used, + int csum_8b, int csum_16b) { + if (offset_inc) + for (auto s : set) s->flags |= ROTATE; + for (auto s : set) s->write_output_config(regs, output_map, used, csum_8b, csum_16b); + if (def) + for (auto s : def->set) s->write_output_config(regs, output_map, used, csum_8b, csum_16b); +} + +template +void Parser::State::Match::write_common_row_config(REGS ®s, Parser *pa, State *state, int row, + Match *def, json::map &ctxt_json) { + int max_off = -1; + write_lookup_config(regs, state, row); + + auto &ea_row = regs.memory[state->gress].ml_ea_row[row]; + if (ctr_instr || ctr_load || ctr_imm_amt || ctr_stack_pop) { + write_counter_config(ea_row); + } else if (def) { + def->write_counter_config(ea_row); + } + if (shift) + max_off = std::max(max_off, int(ea_row.shift_amt = shift) - 1); + else if (def) + max_off = std::max(max_off, int(ea_row.shift_amt = def->shift) - 1); + max_off = std::max(max_off, write_load_config(regs, pa, state, row)); + if (auto &next = (!this->next && def) ? def->next : this->next) { + std::vector prev; + for (auto n : next) { + max_off = std::max(max_off, n->write_lookup_config(regs, pa, state, row, prev)); + prev.push_back(n); + } + const match_t &n = next.pattern ? next.pattern : next->stateno; + ea_row.nxt_state = n.word1; + ea_row.nxt_state_mask = ~(n.word0 & n.word1) & PARSER_STATE_MASK; + } else { + ea_row.done = 1; + } + + auto &action_row = regs.memory[state->gress].po_action_row[row]; + for (auto &c : csum) { + action_row.csum_en[c.unit] = 1; + action_row.csum_addr[c.unit] = c.addr; + } + if (offset_inc || offset_rst) { + action_row.dst_offset_inc = offset_inc; + action_row.dst_offset_rst = offset_rst; + } else if (def) { + action_row.dst_offset_inc = def->offset_inc; + action_row.dst_offset_rst = def->offset_rst; + } + if (priority) priority.write_config(action_row); + if (hdr_len_inc_stop) hdr_len_inc_stop.write_config(action_row); + + void *output_map = pa->setup_phv_output_map(regs, state->gress, row); + unsigned used = 0; + int csum_8b = 0; + int csum_16b = 0; + for (auto &c : csum) { + c.write_output_config(regs, pa, this, output_map, used); + if (c.type == 0 && c.dest) { + if (c.dest->reg.size == 8) + ++csum_8b; + else if (c.dest->reg.size == 16) + ++csum_16b; + } + } + + if (options.target == TOFINO) { + write_sets(regs, def, output_map, used, csum_8b, csum_16b); + write_saves(regs, def, output_map, max_off, used, csum_8b, csum_16b); + } else { + write_sets(regs, def, output_map, used, 0, 0); + write_saves(regs, def, output_map, max_off, used, 0, 0); + } + + int clot_unit = 0; + for (auto *c : clots) c->write_config(action_row, clot_unit++, offset_inc > 0); + if (def) + for (auto *c : def->clots) c->write_config(action_row, clot_unit++, offset_inc > 0); + pa->mark_unused_output_map(regs, output_map, used); + + if (buf_req < 0) { + buf_req = max_off + 1; + BUG_CHECK(buf_req <= 32); + } + ea_row.buf_req = buf_req; +} + +template +void Parser::State::Match::write_row_config(REGS ®s, Parser *pa, State *state, int row, + Match *def, json::map &ctxt_json) { + write_common_row_config(regs, pa, state, row, def, ctxt_json); +} + +template +void Parser::State::Match::write_config(REGS ®s, Parser *pa, State *state, Match *def, + json::map &ctxt_json) { + int row, count = 0; + do { + if ((row = --pa->tcam_row_use) < 0) { + if (row == -1) + error(state->lineno, "Ran out of tcam space in %sgress parser", + state->gress ? "e" : "in"); + return; + } + ctxt_json["tcam_rows"].to().push_back(row); + write_row_config(regs, pa, state, row, def, ctxt_json); + pa->match_to_row[this] = row; + } while (++count < value_set_size); +} + +template +void Parser::State::Match::write_config(REGS ®s, json::vector &vec) { + int select_statement_bit = 0; + for (auto f : field_mapping) { + json::map container_cjson; + container_cjson["container_width"] = Parser::match_key_size(f.container_id.c_str()); + + int container_hardware_id = Parser::match_key_loc(f.container_id.c_str()); + container_cjson["container_hardware_id"] = container_hardware_id; + + container_cjson["mask"] = (1 << (f.hi - f.lo + 1)) - 1; + json::vector field_mapping_cjson; + for (auto i = f.lo; i <= f.hi; i++) { + json::map field_map; + field_map["register_bit"] = i; + field_map["field_name"] = f.where.name(); + field_map["start_bit"] = i; + field_map["select_statement_bit"] = select_statement_bit++; + field_mapping_cjson.push_back(field_map.clone()); + } + container_cjson["field_mapping"] = field_mapping_cjson.clone(); + vec.push_back(container_cjson.clone()); + } +} + +template +void Parser::State::write_config(REGS ®s, Parser *pa, json::vector &ctxt_json) { + LOG2(gress << " state " << name << " (" << stateno << ')'); + for (auto i : match) { + bool uses_pvs = false; + json::map state_cjson; + state_cjson["parser_name"] = name; + i->write_config(regs, state_cjson["match_registers"]); + if (i->value_set_size > 0) uses_pvs = true; + i->write_config(regs, pa, this, def, state_cjson); + state_cjson["uses_pvs"] = uses_pvs; + if (def) def->write_config(regs, pa, this, 0, state_cjson); + if (uses_pvs) { + state_cjson["pvs_name"] = i->value_set_name; + if (i->value_set_handle < 0) + error(lineno, "Invalid handle for parser value set %s", i->value_set_name.c_str()); + auto pvs_handle_full = i->value_set_handle; + state_cjson["pvs_handle"] = pvs_handle_full; + } + for (auto idx : MatchIter(stateno)) { + state_cjson["parser_state_id"] = idx; + ctxt_json.push_back(state_cjson.clone()); + } + } +} + +template +void Parser::Checksum::write_tofino_row_config(ROW &row) { + row.add = add; + if (dest) + row.dst = dest->reg.parser_id(); + else if (tag >= 0) + row.dst = tag; + row.dst_bit_hdr_end_pos = dst_bit_hdr_end_pos; + row.hdr_end = end; + int rsh = 0; + for (auto &el : row.mask) el = (mask >> rsh++) & 1; + row.shr = shift; + row.start = start; + rsh = 0; + for (auto &el : row.swap) el = (swap >> rsh++) & 1; + row.type = type; +} + +template +void Parser::Checksum::write_row_config(ROW &row) { + write_tofino_row_config(row); + int rsh = 0; + for (auto &el : row.mul_2) el = (mul_2 >> rsh++) & 1; +} + +// Used with JBay +bitvec expand_parser_groups(bitvec phvs); +bitvec remove_nonparser(bitvec phvs); +void setup_jbay_ownership(bitvec phv_use[2], checked_array<128, ubits<1>> &left, + checked_array<128, ubits<1>> &right, checked_array<256, ubits<1>> &main_i, + checked_array<256, ubits<1>> &main_e); +void setup_jbay_no_multi_write(bitvec phv_allow_bitwise_or, bitvec phv_allow_clear_on_write, + checked_array<256, ubits<1>> &nmw_i, + checked_array<256, ubits<1>> &nmw_e); +void setup_jbay_clear_on_write(bitvec phv_allow_clear_on_write, checked_array<128, ubits<1>> &left, + checked_array<128, ubits<1>> &right, + checked_array<256, ubits<1>> &main_i, + checked_array<256, ubits<1>> &main_e); + +#endif /* PARSER_TOFINO_JBAY_H_ */ diff --git a/backends/tofino/bf-asm/parser.h b/backends/tofino/bf-asm/parser.h new file mode 100644 index 00000000000..eadde8592e2 --- /dev/null +++ b/backends/tofino/bf-asm/parser.h @@ -0,0 +1,45 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_PARSER_H_ +#define BF_ASM_PARSER_H_ + +#include "asm-types.h" +#include "json.h" +#include "sections.h" +#include "target.h" +#include "vector.h" + +/** + * @brief Base class of Tofino parser in assembler + * + * For Tofino 1/2, the class Parser is derived. + */ +class BaseParser : virtual public Configurable { + protected: + int lineno = -1; +}; + +/** + * @brief Base class of parser assembly section + */ +class BaseAsmParser : public Section { + public: + explicit BaseAsmParser(const char *name_) : Section(name_) {} +}; + +#endif /* BF_ASM_PARSER_H_ */ diff --git a/backends/tofino/bf-asm/phase0.cpp b/backends/tofino/bf-asm/phase0.cpp new file mode 100644 index 00000000000..d29f908608d --- /dev/null +++ b/backends/tofino/bf-asm/phase0.cpp @@ -0,0 +1,93 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "parser-tofino-jbay.h" +#include "stage.h" +#include "tables.h" + +DEFINE_TABLE_TYPE(Phase0MatchTable) + +void Phase0MatchTable::setup(VECTOR(pair_t) & data) { + for (auto &kv : MapIterChecked(data)) { + if (common_setup(kv, data, P4Table::MatchEntry)) { + } else if (auto *fmt = get(data, "format")) { + if (CHECKTYPEPM(*fmt, tMAP, fmt->map.size > 0, "non-empty map")) + format.reset(new Format(this, fmt->map)); + } else if (kv.key == "size") { + if (CHECKTYPE(kv.value, tINT)) size = kv.value.i; + } else if (kv.key == "constant_value") { + if (CHECKTYPE(kv.value, tINT)) constant_value = kv.value.i; + } else { + warning(kv.key.lineno, "ignoring unknown item %s in table %s", value_desc(kv.key), + name()); + } + } + if (gress != INGRESS || stage->stageno != 0) + error(lineno, "Phase 0 match table can only be in stage 0 ingress"); +} + +void Phase0MatchTable::pass1() { + LOG1("### Phase 0 match table " << name() << " pass1 " << loc()); + MatchTable::pass1(); + if (actions) actions->pass1(this); +} + +void Phase0MatchTable::pass2() { LOG1("### Phase 0 match table " << name() << " pass2 " << loc()); } + +void Phase0MatchTable::pass3() { LOG1("### Phase 0 match table " << name() << " pass3 " << loc()); } + +template +void Phase0MatchTable::write_regs_vt(REGS &) { + LOG1("### Phase 0 match table " << name() << " write_regs " << loc()); +} + +void Phase0MatchTable::gen_tbl_cfg(json::vector &out) const { + json::map &tbl = *base_tbl_cfg(out, "match_entry", p4_table ? p4_table->size : size); + common_tbl_cfg(tbl); + tbl["statistics_table_refs"] = json::vector(); + tbl["meter_table_refs"] = json::vector(); + tbl["selection_table_refs"] = json::vector(); + tbl["stateful_table_refs"] = json::vector(); + tbl["action_data_table_refs"] = json::vector(); + json::map &match_attributes = tbl["match_attributes"] = json::map(); + json::map &stage_tbl = *add_stage_tbl_cfg(match_attributes, "phase_0_match", size); + match_attributes["match_type"] = "phase_0_match"; + stage_tbl["stage_number"] = -1; + // Associate the phase0 table with corresponding parser. This is used in a + // multi parser scenario which has multiple phase0 tables + // and the handle is used by the driver to link the phase0 table to the + // parser. + auto parser_handle = Parser::get_parser_handle(name()); + if (parser_handle > 0) stage_tbl["parser_handle"] = parser_handle; + stage_tbl.erase("logical_table_id"); + stage_tbl.erase("default_next_table"); + stage_tbl.erase("has_attached_gateway"); + auto &mra = stage_tbl["memory_resource_allocation"] = json::map(); + mra["memory_type"] = "ingress_buffer"; + json::map tmp; + (tmp["vpns"] = json::vector()).push_back(INT64_C(0)); + (tmp["memory_units"] = json::vector()).push_back(INT64_C(0)); + (mra["memory_units_and_vpns"] = json::vector()).push_back(std::move(tmp)); + // Driver looks at the pack format to determine the fields and their + // positions. Since phase0 is only mimicking a table, the driver expects to + // have a single entry within the pack format. + bool pad_zeros = false; + bool print_fields = true; + add_pack_format(stage_tbl, format.get(), pad_zeros, print_fields); + if (actions) actions->gen_tbl_cfg(tbl["actions"]); + if (context_json) stage_tbl.merge(*context_json); +} diff --git a/backends/tofino/bf-asm/phv.cpp b/backends/tofino/bf-asm/phv.cpp new file mode 100644 index 00000000000..370270a3a1a --- /dev/null +++ b/backends/tofino/bf-asm/phv.cpp @@ -0,0 +1,498 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "phv.h" + +#include +#include + +#include "log.h" +#include "misc.h" + +Phv Phv::phv; +const Phv::Register Phv::Slice::invalid("", Phv::Register::NORMAL, 0, ~0, 0); + +void Phv::init_phv(target_t target_type) { + if (target) { + BUG_CHECK(target->type() == target_type); // sanity check + return; + } + switch (target_type) { +#define INIT_FOR_TARGET(TARGET) \ + case Target::TARGET::tag: \ + target = new Target::TARGET::Phv; \ + break; + FOR_ALL_TARGETS(INIT_FOR_TARGET) + default: + BUG(); + } +#undef INIT_FOR_TARGET + target->init_regs(*this); +} + +void Phv::start(int lineno, VECTOR(value_t) args) { + if (options.target == NO_TARGET) { + error(lineno, "No target specified prior to PHV section"); + return; + } + init_phv(options.target); + // The only argument to phv is the thread. We allow phv section with no thread argument + // which defines aliases for all threads. Does that really make sense when threads can't + // share registers? We never use this capability in the compiler. + if (args.size > 1 || (args.size == 1 && args[0] != "ingress" && args[0] != "egress" && + (args[0] != "ghost" || options.target < JBAY))) + error(lineno, "phv can only be ingress%s or egress", + (options.target >= JBAY ? ", ghost" : 0)); +} + +int Phv::addreg(gress_t gress, const char *name, const value_t &what, int stage, int max_stage) { + std::string phv_name = name; + remove_name_tail_range(phv_name); + if (stage == -1 && what.type == tMAP) { + int rv = 0; + for (auto &kv : what.map) { + auto &key = kv.key.type == tCMD && kv.key.vec.size > 1 && kv.key == "stage" ? kv.key[1] + : kv.key; + if (CHECKTYPE2(key, tINT, tRANGE)) { + if (key.type == tINT) + rv |= addreg(gress, name, kv.value, key.i); + else + rv |= addreg(gress, name, kv.value, key.lo, key.hi); + } + } + int size = -1; + PerStageInfo *prev = 0; + for (auto &ch : names[gress].at(name)) { + if (prev) { + if (prev->max_stage >= ch.first) { + if (prev->max_stage != INT_MAX) + error(what.lineno, "Overlapping assignments in stages %d..%d for %s", + ch.first, prev->max_stage, name); + prev->max_stage = ch.first - 1; + } + } + prev = &ch.second; + if (size < 0) { + size = ch.second.slice->size(); + } else if (size != ch.second.slice->size() && size > 0) { + error(what.lineno, "Inconsitent sizes for %s", name); + size = 0; + } + } + if (prev && prev->max_stage >= Target::NUM_MAU_STAGES()) prev->max_stage = INT_MAX; + add_phv_field_sizes(gress, phv_name, size); + return rv; + } + if (!CHECKTYPE2M(what, tSTR, tCMD, "register or slice")) return -1; + auto reg = what.type == tSTR ? what.s : what[0].s; + if (const Slice *sl = get(gress, stage, reg)) { + if (sl->valid) { + phv_use[gress][sl->reg.uid] = true; + user_defined[&sl->reg].first = gress; + if (max_stage != INT_MAX) { + /* a name that spans across stages - add it to all stages */ + for (int i = stage; i <= max_stage; i++) { + user_defined[&sl->reg].second[i].insert(name); + } + } else { + for (int i = 0; i <= Target::NUM_MAU_STAGES(); i++) { + user_defined[&sl->reg].second[i].insert(name); + } + } + LOG5(" Adding " << name << " to user_defined"); + } + auto ® = names[gress][name]; + if (what.type == tSTR) { + reg[stage].slice = *sl; + } else if (what.vec.size != 2) { + error(what.lineno, "Syntax error, expecting bit or slice"); + return -1; + } else if (!CHECKTYPE2M(what[1], tINT, tRANGE, "bit or slice")) { + return -1; + } else if (what[1].type == tINT) { + reg[stage].slice = Slice(*sl, what[1].i, what[1].i); + } else { + reg[stage].slice = Slice(*sl, what[1].lo, what[1].hi); + } + reg[stage].max_stage = max_stage; + if (!reg[stage].slice.valid) { + auto slice = reg[stage].slice; + error(what.lineno, "Invalid register slice - %s[%d:%d]", slice.reg.name, slice.hi, + slice.lo); + return -1; + } + if (stage == -1) { + add_phv_field_sizes(gress, phv_name, reg[stage].slice->size()); + if (is_pov(phv_name)) { + phv_pov_names[sl->reg.mau_id()][reg[stage].slice.lo] = phv_name; + } + } + return 0; + } else { + error(what.lineno, "No register named %s", reg); + return -1; + } +} + +void Phv::input(VECTOR(value_t) args, value_t data) { + if (!CHECKTYPE(data, tMAP)) return; + gress_t gress = + args[0] == "ingress" ? INGRESS + : args[0] == "egress" ? EGRESS + : args[0] == "ghost" && options.target >= JBAY + ? GHOST + : (error(args[1].lineno, "Invalid thread %s", value_desc(args[1])), INGRESS); + for (auto &kv : data.map) { + if (!CHECKTYPE(kv.key, tSTR)) continue; + if (kv.key == "context_json") { + if (!CHECKTYPE(kv.value, tMAP)) continue; + field_context_json.merge(*toJson(kv.value.map)); + } else { + if (get(gress, INT_MAX, kv.key.s) || (!args.size && get(EGRESS, INT_MAX, kv.key.s)) || + (!args.size && get(GHOST, INT_MAX, kv.key.s))) { + error(kv.key.lineno, "Duplicate phv name '%s'", kv.key.s); + continue; + } + if (!addreg(gress, kv.key.s, kv.value) && args.size == 0) { + addreg(EGRESS, kv.key.s, kv.value); + if (options.target >= JBAY) addreg(GHOST, kv.key.s, kv.value); + } + } + } +} + +Phv::Ref::Ref(gress_t g, int stage, const value_t &n) + : gress_(g), stage(stage), lo(-1), hi(-1), lineno(n.lineno) { + if (CHECKTYPE2M(n, tSTR, tCMD, "phv or register reference or slice")) { + if (n.type == tSTR) { + name_ = n.s; + } else { + name_ = n[0].s; + if (PCHECKTYPE2M(n.vec.size == 2, n[1], tINT, tRANGE, "register slice")) { + if (n[1].type == tINT) { + lo = hi = n[1].i; + } else { + lo = n[1].lo; + hi = n[1].hi; + if (lo > hi) { + lo = n[1].hi; + hi = n[1].lo; + } + } + } + } + } +} + +Phv::Ref::Ref(const Phv::Register &r, gress_t gr, int l, int h) + : gress_(gr), stage(0), name_(r.name), lo(l), hi(h < 0 ? l : h), lineno(-1) {} + +bool Phv::Ref::merge(const Phv::Ref &r) { + if (r.name_ != name_ || r.gress_ != gress_) return false; + if (lo < 0) return true; + if (r.lo < 0) { + lo = hi = -1; + return true; + } + if (r.hi + 1 < lo || hi + 1 < r.lo) return false; + if (r.lo < lo) lo = r.lo; + if (r.hi > hi) { + lineno = r.lineno; + hi = r.hi; + } + return true; +} + +void merge_phv_vec(std::vector &vec, const Phv::Ref &r) { + int merged = -1; + for (int i = 0; (unsigned)i < vec.size(); i++) { + if (merged >= 0) { + if (vec[merged].merge(vec[i])) { + vec.erase(vec.begin() + i); + --i; + } + } else if (vec[i].merge(r)) { + merged = i; + } + } + if (merged < 0) vec.push_back(r); +} + +void merge_phv_vec(std::vector &v1, const std::vector &v2) { + for (auto &r : v2) merge_phv_vec(v1, r); +} + +std::vector split_phv_bytes(const Phv::Ref &r) { + std::vector rv; + const auto &sl = *r; + for (unsigned byte = sl.lo / 8U; byte <= sl.hi / 8U; byte++) { + int lo = byte * 8 - sl.lo; + int hi = lo + 7; + if (lo < 0) lo = 0; + if (hi >= static_cast(sl.size())) hi = sl.size() - 1; + rv.emplace_back(r, lo, hi); + } + return rv; +} + +std::vector split_phv_bytes(const std::vector &v) { + std::vector rv; + for (auto &r : v) append(rv, split_phv_bytes(r)); + return rv; +} + +std::string Phv::Ref::toString() const { + std::stringstream str; + str << *this; + return str.str(); +} + +void Phv::Ref::dbprint(std::ostream &out) const { + out << name_; + if (lo >= 0) { + out << '[' << hi; + if (hi != lo) out << ":" << lo; + out << ']'; + } + Slice sl(**this); + if (sl.valid) { + out << '['; + sl.dbprint(out); + out << ']'; + } +} + +std::string Phv::Ref::desc() const { return toString(); } + +std::string Phv::Slice::toString() const { + std::stringstream str; + str << *this; + return str.str(); +} + +void Phv::Slice::dbprint(std::ostream &out) const { + if (valid) { + out << reg.name; + if (lo != 0 || hi != reg.size - 1) { + out << '[' << hi; + if (hi != lo) out << ":" << lo; + out << ']'; + } + } else { + out << ""; + } +} + +std::string Phv::db_regset(const bitvec &s) { + std::string rv; + for (int reg : s) { + if (!rv.empty()) rv += ", "; + rv += Phv::reg(reg)->name; + } + return rv; +} + +// For snapshot, the driver (generate pd script) generates a buffer of all phv +// fields and indexes through the buffer with a position offset to determine its +// location. It assumes the phv fields are arranged with the pov fields at the +// end. To maintain this ordering while generating the position offsets for each +// phv field, we initially generate 2 separate maps for normal and pov phv +// fields. We loop through the normap phv map first and then the pov phv map +// adding field sizes. The fields are byte aligned and put into 8/16/32 bit +// containers. +int Phv::get_position_offset(gress_t gress, std::string name) { + int position_offset = 0; + for (auto f : phv_field_sizes[gress]) { + if (f.first == name) return position_offset; + auto bytes_to_add = (f.second + 7) / 8U; + if (bytes_to_add == 3) bytes_to_add++; + position_offset += bytes_to_add; + } + for (auto f : phv_pov_field_sizes[gress]) { + if (f.first == name) return position_offset; + // POV should be single bit + BUG_CHECK(f.second == 1); + position_offset += 1; + } + return 0; +} + +// Output function sets the 'phv_allocation' node in context json Contains info +// on phv containers per gress (INGRESS/EGRESS) per stage Currently the phv +// containers are assumed to be present in all stages hence are replicated in +// each stage. Support for liveness indication for each container must be added +// (in assembly syntax/compiler) to set per stage phv containers correctly. +void Phv::output(json::map &ctxt_json) { + bool warn_once = false; + json::vector &phv_alloc = ctxt_json["phv_allocation"]; + for (int i = 0; i <= Target::NUM_MAU_STAGES(); i++) { + json::map phv_alloc_stage; + json::vector &phv_alloc_stage_ingress = phv_alloc_stage["ingress"] = json::vector(); + json::vector &phv_alloc_stage_egress = phv_alloc_stage["egress"] = json::vector(); + for (auto &slot : phv.user_defined) { + unsigned phv_number = slot.first->uid; + unsigned phv_container_size = slot.first->size; + gress_t gress = slot.second.first; + auto stage_usernames = slot.second.second[i]; + json::map phv_container; + phv_container["phv_number"] = phv_number; + phv_container["container_type"] = slot.first->type_to_string(); + json::vector &phv_records = phv_container["records"] = json::vector(); + for (auto field_name : stage_usernames) { + LOG5("Output phv record for field : " << field_name); + unsigned phv_lsb = 0, phv_msb = 0; + unsigned field_lo = 0; + int field_size = 0; + json::map phv_record; + auto sl = get(gress, i, field_name); + if (!sl) continue; + phv_lsb = sl->lo; + phv_msb = sl->hi; + field_lo = remove_name_tail_range(field_name, &field_size); + auto field_width = get_phv_field_size(gress, field_name); + if (field_size == 0) field_size = field_width; + phv_record["position_offset"] = get_position_offset(gress, field_name); + phv_record["field_name"] = field_name; + phv_record["field_msb"] = field_lo + field_size - 1; + phv_record["field_lsb"] = field_lo; + auto field_width_bytes = (field_width + 7) / 8U; + phv_record["field_width"] = field_width_bytes; + phv_record["phv_msb"] = phv_msb; + phv_record["phv_lsb"] = phv_lsb; + // FIXME-P4C: 'is_compiler_generated' is set to false for all + // fields except POV as there is no sure way of knowing from + // current assembly syntax whether the field is in the header or + // generated by the compiler. This will require additional + // assembly syntax to convey the same. Driver does not use + // is_compiler_generated (other than requiring it). p4i does + // use it for display purposes. + phv_record["is_compiler_generated"] = false; + phv_record["is_pov"] = false; + if (is_pov(field_name)) { + phv_record["is_pov"] = true; + phv_record["is_compiler_generated"] = true; + phv_record["field_width"] = 0; + phv_record["position_offset"] = 0; + /* Now that we know that this record is representing a POV, overwrite the + * phv_record to call it "POV" and get rid of "$valid" */ + phv_record["field_name"] = "POV"; + json::vector &pov_headers = phv_record["pov_headers"] = json::vector(); + json::map pov_header; + pov_header["bit_index"] = phv_lsb; + pov_header["position_offset"] = get_position_offset(gress, field_name); + pov_header["header_name"] = field_name; + // FIXME: Checks for reserved POV bits, not supported? + pov_header["hidden"] = false; + ; + pov_headers.push_back(std::move(pov_header)); + } + // Pass through per-field context_json information from the compiler. + if (field_context_json.count(slot.first->name)) { + auto add_phv_record_items = [&](int live_stage, std::string live_string) { + if (live_stage == -1) { + phv_record[live_string] = "parser"; + return; + } + if (live_stage == Target::NUM_MAU_STAGES()) { + phv_record[live_string] = "deparser"; + return; + } + phv_record[live_string] = live_stage; + }; + auto container_json = field_context_json[slot.first->name]; + BUG_CHECK(container_json); + bool field_added = false; + if (!container_json->as_vector()) { + // FIXME -- should be flexible about parsing context_json -- continue + // to accept a map instead of a vector here. + if (!warn_once) { + // FIXME -- would be nice to have the bfa lineno here. + warning(-1, "Invalid/obsolete phv context_json:, ignoring"); + warn_once = true; + } + continue; + } + for (auto &field_json : *container_json->as_vector()) { + auto live_start = -1, live_end = Target::NUM_MAU_STAGES(); + auto container_field_json = field_json->as_map(); + if (container_field_json->count("name")) { + if ((*container_field_json)["name"] != field_name) continue; + } else { + continue; + } + if (container_field_json->count("live_start")) { + auto live_start_json = (*container_field_json)["live_start"]; + if (auto n = live_start_json->as_number()) live_start = n->val; + } + if (container_field_json->count("live_end")) { + auto live_end_json = (*container_field_json)["live_end"]; + if (auto n = live_end_json->as_number()) live_end = n->val; + } + if (i >= live_start && i <= live_end) { + add_phv_record_items(live_start, "live_start"); + add_phv_record_items(live_end, "live_end"); + phv_record["mutually_exclusive_with"] = json::vector(); + if (container_field_json->count("mutually_exclusive_with")) { + auto mutex_json = + (*container_field_json)["mutually_exclusive_with"]; + if (json::vector *mutex_json_vec = mutex_json->as_vector()) + phv_record["mutually_exclusive_with"] = + std::move(*mutex_json_vec); + } + field_added = true; + // Skip duplicates + if (!std::any_of(phv_records.begin(), phv_records.end(), + [&phv_record](std::unique_ptr &r) { + return *r == phv_record; + })) + phv_records.push_back(phv_record.clone()); + } + } + if (!field_added) { + auto live_start = -1, live_end = Target::NUM_MAU_STAGES(); + add_phv_record_items(live_start, "live_start"); + add_phv_record_items(live_end, "live_end"); + phv_record["mutually_exclusive_with"] = json::vector(); + phv_records.push_back(phv_record.clone()); + } + } else { + phv_records.push_back(std::move(phv_record)); + } + } + phv_container["word_bit_width"] = phv_container_size; + // Ghost phv's are considered as ingress phv's + if (phv_records.size() > 0) { + if ((gress == INGRESS) || (gress == GHOST)) { + phv_alloc_stage_ingress.push_back(std::move(phv_container)); + } else if (gress == EGRESS) { + phv_alloc_stage_egress.push_back(std::move(phv_container)); + } + } + } + phv_alloc_stage["stage_number"] = i; + phv_alloc.push_back(std::move(phv_alloc_stage)); + } + // FIXME: Fix json clone method to do above loops more efficiently + // for (int i = 0; i < Target::NUM_MAU_STAGES(); i++) { + // phv_alloc_stage["stage_number"] = i; + // phv_alloc.push_back(std::move(phv_alloc_stage.clone())); } +} + +#include "tofino/phv.cpp" // NOLINT(build/include) +#if HAVE_JBAY +#include "jbay/phv.cpp" // NOLINT(build/include) +#endif /* HAVE_JBAY */ diff --git a/backends/tofino/bf-asm/phv.h b/backends/tofino/bf-asm/phv.h new file mode 100644 index 00000000000..cf1b0fd7de2 --- /dev/null +++ b/backends/tofino/bf-asm/phv.h @@ -0,0 +1,329 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_PHV_H_ +#define BF_ASM_PHV_H_ + +#include +#include + +#include "bfas.h" +#include "bitvec.h" +#include "json.h" +#include "match_source.h" +#include "misc.h" +#include "sections.h" +#include "target.h" + +class Phv : public Section { + void start(int lineno, VECTOR(value_t) args) override; + void input(VECTOR(value_t) args, value_t data) override; + void output(json::map &) override; + Phv() : Section("phv") {} + Phv(const Phv &) = delete; + Phv &operator=(const Phv &) = delete; + ~Phv() {} + static Phv phv; // singleton class + Target::Phv *target = nullptr; + FOR_ALL_TARGETS(FRIEND_TARGET_CLASS, ::Phv) + + public: + struct Register { + char name[8]; + enum type_t { NORMAL, TAGALONG, CHECKSUM, MOCHA, DARK } type; + // uid is used for "phv_number" in the context.json, but otherwise is just + // a unique id for the register, encoded differently for different targets + unsigned short index = 0, uid = 0, size = 0; + Register() { type = NORMAL; } + Register(const Register &) = delete; + Register &operator=(const Register &) = delete; + Register(const char *n, type_t t, unsigned i, unsigned u, unsigned s) + : type(t), index(i), uid(u), size(s) { + strncpy(name, n, sizeof(name)); + name[7] = 0; + } + bool operator==(const Register &a) const { return uid == a.uid; } + bool operator!=(const Register &a) const { return uid != a.uid; } + bool operator<(const Register &a) const { return uid < a.uid; } + virtual int parser_id() const { return -1; } + virtual int mau_id() const { return -1; } + virtual int ixbar_id() const { return -1; } + virtual int deparser_id() const { return -1; } + /// return a string representation based on the container type + const char *type_to_string() const { + switch (type) { + case NORMAL: + return "normal"; + case TAGALONG: + return "tagalong"; + case CHECKSUM: + return "checksum"; + case MOCHA: + return "mocha"; + case DARK: + return "dark"; + } + return ""; + } + }; + class Slice : public IHasDbPrint { + static const Register invalid; + + public: + const Register ® + int lo = -1, hi = -1; + bool valid; + Slice() : reg(invalid), valid(false) {} + Slice(const Register &r, int l, int h) : reg(r), lo(l), hi(h) { + valid = lo >= 0 && hi >= lo && hi < reg.size; + } + Slice(const Register &r, int b) : reg(r), lo(b), hi(b) { + valid = lo >= 0 && hi >= lo && hi < reg.size; + } + Slice(const Slice &s, int l, int h) : reg(s.reg), lo(s.lo + l), hi(s.lo + h) { + valid = lo >= 0 && hi >= lo && hi <= s.hi && hi < reg.size; + } + Slice(const Slice &) = default; + explicit operator bool() const { return valid; } + Slice &operator=(const Slice &a) { + new (this) Slice(a.reg, a.lo, a.hi); + return *this; + } + const Slice *operator->() const { return this; } + bool operator==(const Slice &s) const { + return valid && s.valid && reg.uid == s.reg.uid && lo == s.lo && hi == s.hi; + } + bool operator<(const Slice &a) const { + if (reg.uid < a.reg.uid) return true; + if (reg.uid > a.reg.uid) return false; + if (lo < a.lo) return true; + if (lo > a.lo) return false; + return (hi < a.hi); + } + bool overlaps(const Slice &a) const { + return valid && a.valid && reg.uid == a.reg.uid && lo <= a.hi && a.lo <= hi; + } + unsigned size() const { return valid ? hi - lo + 1 : 0; } + std::string toString() const; + void dbprint(std::ostream &out) const; + }; + + protected: + // registers indexed according to MAU id + std::vector regs; + std::map> phv_pov_names; + struct PerStageInfo { + int max_stage = INT_MAX; + Slice slice; + }; + std::map> names[3]; + + private: + typedef std::map> user_stagenames_t; + std::map, ptrless> + user_defined; + bitvec phv_use[3]; + std::map phv_field_sizes[3]; + std::map phv_pov_field_sizes[3]; + + // Maps P4-level field names (i.e. returned by stack_asm_name_to_p4()) to a + // map to be embedded in the field's context_json "records" node. + json::map field_context_json; + + void init_phv(target_t); + bool is_pov(std::string name) { + // There are 2 types of POV bits we are interested in + // Either ending with .$valid or .$deparse... + return (name.find(".$valid") != std::string::npos || + name.find(".$deparse") != std::string::npos); + } + void gen_phv_field_size_map(); + int addreg(gress_t gress, const char *name, const value_t &what, int stage = -1, + int max_stage = INT_MAX); + int get_position_offset(gress_t gress, std::string name); + void add_phv_field_sizes(gress_t gress, std::string name, int size) { + auto &phv_field_map = is_pov(name) ? phv_pov_field_sizes : phv_field_sizes; + phv_field_map[gress][name] += size; + } + int get_phv_field_size(gress_t gress, std::string name) { + if (phv_field_sizes[gress].count(name) > 0) return phv_field_sizes[gress][name]; + if (phv_pov_field_sizes[gress].count(name) > 0) return phv_pov_field_sizes[gress][name]; + return 0; + } + + public: + static const Slice *get(gress_t gress, int stage, const std::string &name) { + phv.init_phv(options.target); + auto phvIt = phv.names[gress].find(name); + if (phvIt == phv.names[gress].end()) return 0; + auto &per_stage = phvIt->second; + auto it = per_stage.upper_bound(stage); + if (it == per_stage.begin()) { + if (it == per_stage.end() || stage != -1) return 0; + } else { + --it; + } + if (stage > it->second.max_stage) return 0; + return &it->second.slice; + } + static const Slice *get(gress_t gress, int stg, const char *name) { + return get(gress, stg, std::string(name)); + } + class Ref : public MatchSource { + protected: + gress_t gress_; + std::string name_; + int stage = -1; + int lo = -1, hi = -1; + + public: + int lineno; + Ref() : gress_(INGRESS), lineno(-1) {} + Ref(gress_t g, int stage, const value_t &n); + Ref(gress_t g, int stage, int line, const std::string &n, int l, int h) + : gress_(g), name_(n), stage(stage), lo(l), hi(h), lineno(line) {} + Ref(const Ref &r, int l, int h) + : gress_(r.gress_), + name_(r.name_), + stage(r.stage), + lo(r.lo < 0 ? l : r.lo + l), + hi(r.lo < 0 ? h : r.lo + h), + lineno(r.lineno) { + BUG_CHECK(r.hi < 0 || hi <= r.hi); + } + Ref(const Register &r, gress_t gr, int lo = -1, int hi = -1); + explicit operator bool() const { return lineno >= 0; } + Slice operator*() const { + if (auto *s = phv.get(gress_, stage, name_)) { + if (hi >= 0) return Slice(*s, lo, hi); + return *s; + } else { + error(lineno, "No phv record %s (%s, stage %d)", name_.c_str(), + gress_ == INGRESS ? "INGRESS" : "EGRESS", stage); + phv.get(gress_, stage, name_); + return Slice(); + } + } + bool operator<(const Ref &r) const { + return (**this).reg.parser_id() < (*r).reg.parser_id(); + } + Slice operator->() const { return **this; } + bool operator==(const Ref &a) const { + if (name_ == a.name_ && lo == a.lo && hi == a.hi) return true; + return **this == *a; + } + bool check(bool err = true) const { + if (auto *s = phv.get(gress_, stage, name_)) { + if (hi >= 0 && !Slice(*s, lo, hi).valid) { + error(lineno, "Invalid slice of %s", name_.c_str()); + return false; + } + return true; + } else if (lineno >= 0 && err) { + error(lineno, "No phv record %s", name_.c_str()); + } + return false; + } + gress_t gress() const { return gress_; } + const char *name() const override { return name_.c_str(); } + std::string desc() const; + int lobit() const { return lo < 0 ? 0 : lo; } + int hibit() const { return hi < 0 ? (**this).size() - 1 : hi; } + unsigned size() const override { + if (lo >= 0) return hi - lo + 1; + if (auto *s = phv.get(gress_, stage, name_)) return s->size(); + return 0; + } + bool merge(const Ref &r); + std::string toString() const override; + void dbprint(std::ostream &out) const; + + int get_lineno() const override { return lineno; } + int fieldlobit() const override { return lobit(); } + int fieldhibit() const override { return hibit(); } + int slicelobit() const override { return (**this).lo; } + int slicehibit() const override { return (**this).hi; } + }; + // Return register using mau_id as @arg index + static const Register *reg(int idx) { + BUG_CHECK(idx >= 0 && size_t(idx) < phv.regs.size()); + return phv.regs[idx]; + } + + static const Register *reg(std::string name) { + for (auto ® : phv.regs) + if (reg->name == name) return reg; + return nullptr; + } + + // Return the number registers + static int num_regs() { return phv.regs.size(); } + + // Return POV name allocated in @arg reg at @arg index + static const std::string get_pov_name(int reg, int index) { + if (phv.phv_pov_names.count(reg) && phv.phv_pov_names.at(reg).count(index)) + return phv.phv_pov_names[reg][index]; + return " "; + } + + static const bitvec &use(gress_t gress) { return phv.phv_use[gress]; } + static void setuse(gress_t gress, const bitvec &u) { phv.phv_use[gress] |= u; } + static void unsetuse(gress_t gress, const bitvec &u) { phv.phv_use[gress] -= u; } + static std::string db_regset(const bitvec &s); + static unsigned mau_groupsize(); + + // Return all field names in @arg reg at @arg stage + static const std::set &aliases(const Register *reg, int stage) { + static std::set empty; + if (!phv.user_defined.count(reg)) return empty; + auto &m = phv.user_defined.at(reg).second; + auto it = m.upper_bound(stage); + if (it == m.begin()) return empty; + return (--it)->second; + } + + // For use by gtests + static void test_clear() { + phv.target = nullptr; + phv.regs.clear(); + phv.phv_pov_names.clear(); + phv.names[INGRESS].clear(); + phv.names[EGRESS].clear(); + phv.names[GHOST].clear(); + } +}; + +extern void merge_phv_vec(std::vector &vec, const Phv::Ref &r); +extern void merge_phv_vec(std::vector &v1, const std::vector &v2); +extern std::vector split_phv_bytes(const Phv::Ref &r); +extern std::vector split_phv_bytes(const std::vector &v); + +class Target::Phv { + friend class ::Phv; + virtual void init_regs(::Phv &) = 0; + virtual target_t type() const = 0; + virtual unsigned mau_groupsize() const = 0; +}; + +inline unsigned Phv::mau_groupsize() { return phv.target->mau_groupsize(); } + +#include "tofino/phv.h" +#if HAVE_JBAY +#include "jbay/phv.h" +#endif /* HAVE_JBAY */ + +#endif /* BF_ASM_PHV_H_ */ diff --git a/backends/tofino/bf-asm/power_ctl.h b/backends/tofino/bf-asm/power_ctl.h new file mode 100644 index 00000000000..05bd315887b --- /dev/null +++ b/backends/tofino/bf-asm/power_ctl.h @@ -0,0 +1,65 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_POWER_CTL_H_ +#define BF_ASM_POWER_CTL_H_ + +#include "misc.h" + +/* power_ctl is weirdly encoded! + * As far as I can tell, it actually walks like this: + * -[1:0] dimension controls hi-lo for each 8/16/32b type. In other words, + * [0] = 8b[31~0], 16b[47~0], 32b[31~0] and [1] = 8b[63~32], 16b[95~48], 32[63~32]. + * -Within the wider dimension, [13:0] = 112b vector, where [31:0] = control for + * 32b section (array slice 3~0), [63:32] = control for 8b section (array slice 7~4), + * [111:64] = control for 16b section (array slice 13~8) + * + * Yes, Jay's decription of how the [1~0][13~0] translates to 224b is correct. + * The [1~0] index discriminates phv words going to the left side alu's [0] + * vs the right side ones [1]. Within each container size, the bottom 32 + * (or 48 for 16b) are on the left and the top half ones are on the right. + * Pat + * + * CSR DESCRIPTION IS WRONG!!! + */ + +template +void set_power_ctl_reg(checked_array<2, checked_array<16, ubits>> &power_ctl, int reg) { + int side = 0; + switch (reg / (I * 8)) { + case 1: // 8 bit + reg -= I * 8; + side = reg / (I * 4); + reg = (reg % (I * 4)) + (I * 4); + break; + case 2: + case 3: // 16 bit + reg -= I * 16; + side = reg / (I * 6); + reg = (reg % (I * 6)) + (I * 8); + break; + case 0: // 32 bit + side = reg / (I * 4); + reg = (reg % (I * 4)); + break; + default: + BUG(); + } + power_ctl[side][reg / I] |= 1U << reg % I; +} + +#endif /* BF_ASM_POWER_CTL_H_ */ diff --git a/backends/tofino/bf-asm/primitives.cpp b/backends/tofino/bf-asm/primitives.cpp new file mode 100644 index 00000000000..65689e339fe --- /dev/null +++ b/backends/tofino/bf-asm/primitives.cpp @@ -0,0 +1,165 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include "bfas.h" +#include "json.h" +#include "log.h" +#include "sections.h" + +class Primitives : public Section { + int lineno = -1; + std::unique_ptr _primitives = nullptr; + std::string _primitivesFileName; + + Primitives() : Section("primitives") {} + + void input(VECTOR(value_t) args, value_t data) { + lineno = data.lineno; + if (!CHECKTYPE(data, tSTR)) return; + _primitivesFileName = data.s; + } + + void process() { + if (_primitivesFileName.empty()) return; + std::ifstream inputFile(_primitivesFileName); + if (!inputFile && _primitivesFileName[0] != '/') + inputFile.open(asmfile_dir + "/" + _primitivesFileName); + if (!inputFile) { + warning(lineno, "%s: can't read file", _primitivesFileName.c_str()); + } else { + inputFile >> _primitives; + if (!inputFile) { + warning(lineno, "%s: not valid primitives json representation", + _primitivesFileName.c_str()); + _primitives.reset(new json::map()); + } + } + } + + bool merge_actions(json::vector &_prim_actions, json::vector &ctxt_actions) { + bool merged = false; + for (auto &_prim_action : _prim_actions) { + for (auto &ctxt_action : ctxt_actions) { + if (*ctxt_action->to()["name"] == + *_prim_action->to()["name"]) { + ctxt_action->to().merge(_prim_action->to()); + merged = true; + auto aname = ctxt_action->to()["name"]->to(); + LOG3("Merged primitive action : " << aname); + break; + } + } + } + return merged; + } + + // If primitives json is present this function will merge the primitives + // nodes in the correct table->actions->action node The 'primitives' section + // is run last so we have already populated the context json tables at this + // stage. We check for the following tree structures to merge the action + // nodes + // Structure 1 (Match Tables) + // tables + // | + // |--> table0 + // |--> name + // |--> actions + // | + // |--> action0 + // | + // |--> name + // |--> primitives (merge here) + // Structure 2 (ALPM Tables) + // tables + // | + // |--> table0 + // |--> name + // |--> match_attributes + // | + // |--> pre_classifier + // | + // |--> actions + // | + // |--> action0 + // | + // |--> name + // |--> primitives (merge here) + // We can have multiple tables with the same name but one without + // and other with actions node e.g. stateful & its associated match table. + // In this case we want to merge with match table since it has the actions + // node + void output(json::map &ctxtJson) { + if (_primitives) { + json::vector &prim_tables = _primitives->to()["tables"]; + json::vector &ctxt_tables = ctxtJson["tables"]; + for (auto &prim_table : prim_tables) { + json::string prim_table_name = + prim_table->to()["name"]->to(); + bool is_merged = false; + json::string ctxt_table_name; + for (auto &ctxt_table : ctxt_tables) { + ctxt_table_name = ctxt_table->to()["name"]->to(); + if (prim_table_name == ctxt_table_name) { + if ((ctxt_table->to().count("actions") > 0) && + (prim_table->to().count("actions") > 0)) { + json::vector &prim_table_actions = + prim_table->to()["actions"]; + json::vector &ctxt_table_actions = + ctxt_table->to()["actions"]; + is_merged = merge_actions(prim_table_actions, ctxt_table_actions); + break; + } else if ((ctxt_table->to().count("match_attributes") > 0) && + (prim_table->to().count("match_attributes") > 0)) { + json::map &prim_table_ma = + prim_table->to()["match_attributes"]; + json::map &ctxt_table_ma = + ctxt_table->to()["match_attributes"]; + if ((ctxt_table_ma.to().count("pre_classifier") > 0) && + (prim_table_ma.to().count("pre_classifier") > 0)) { + json::map &prim_table_pc = + prim_table_ma.to()["pre_classifier"]; + json::map &ctxt_table_pc = + ctxt_table_ma.to()["pre_classifier"]; + if ((ctxt_table_pc.to().count("actions") > 0) && + (prim_table_pc.to().count("actions") > 0)) { + json::vector &prim_table_actions = + prim_table_pc.to()["actions"]; + json::vector &ctxt_table_actions = + ctxt_table_pc.to()["actions"]; + LOG3("Merging primitive actions on table: " << prim_table_name); + is_merged = + merge_actions(prim_table_actions, ctxt_table_actions); + break; + } + } + } + } + } + if (!is_merged) { + warning(lineno, "No table named %s found to merge primitive info", + prim_table_name.c_str()); + } + } + } + } + + static Primitives singleton_primitives; +} Primitives::singleton_primitives; diff --git a/backends/tofino/bf-asm/proxy_hash.cpp b/backends/tofino/bf-asm/proxy_hash.cpp new file mode 100644 index 00000000000..543b0189f88 --- /dev/null +++ b/backends/tofino/bf-asm/proxy_hash.cpp @@ -0,0 +1,188 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "input_xbar.h" +#include "stage.h" +#include "tables.h" + +void ProxyHashMatchTable::setup(VECTOR(pair_t) & data) { + common_init_setup(data, false, P4Table::MatchEntry); + for (auto &kv : MapIterChecked(data, {"meter", "stats", "stateful"})) { + if (common_setup(kv, data, P4Table::MatchEntry)) { + } else if (kv.key == "proxy_hash_group") { + if (CHECKTYPE(kv.value, tINT)) { + proxy_hash_group = kv.value.i; + } + } else if (kv.key == "proxy_hash_algorithm") { + if (CHECKTYPE(kv.value, tSTR)) { + proxy_hash_alg = kv.value.s; + } + } else if (kv.key == "search_bus" || kv.key == "result_bus") { + // already dealt with in Table::setup_layout via common_init_setup + } else { + common_sram_setup(kv, data); + } + } +} + +bool ProxyHashMatchTable::verify_match_key() { + for (auto &match_key : match) { + if (!dynamic_cast(match_key)) { + error(match_key->get_lineno(), "A proxy hash table %s has a non hash key", name()); + continue; + } + } + auto match_format = format->field("match"); + if (match_format && match.empty()) BUG_CHECK("Proxy hash table has no match"); + return error_count == 0; +} + +int ProxyHashMatchTable::determine_pre_byteswizzle_loc(MatchSource *ms, int lo, int hi, int word) { + return (ms->slicelobit() + lo) / 8; +} + +void ProxyHashMatchTable::pass1() { + LOG1("### Proxy Hash match table " << name() << " pass1 " << loc()); + SRamMatchTable::pass1(); +} + +void ProxyHashMatchTable::setup_ways() { + SRamMatchTable::setup_ways(); + for (auto &row : layout) { + int first_way = -1; + for (auto &unit : row.memunits) { + int way = way_map.at(unit).way; + if (first_way < 0) { + first_way = way; + } else if (ways[way].group_xme != ways[first_way].group_xme) { + error(row.lineno, + "Ways %d and %d of table %s share address bus on row %d, " + "but use different hash groups", + first_way, way, name(), row.row); + break; + } + } + } +} + +void ProxyHashMatchTable::setup_word_ixbar_group() { + word_ixbar_group.resize(match_in_word.size()); + for (size_t i = 0; i < match_in_word.size(); i++) { + // Basically the value per row/bus of rams.row.vh_xbar.exactmatch_row_vh_xbar_ctl, + // based on the diagram in uArch section 6.2.3 Exact Match Row Vertical/Horizontal (VH) + // Xbars + word_ixbar_group[i] = BYTE_XBAR_GROUPS + proxy_hash_group; + } +} + +void ProxyHashMatchTable::pass2() { + LOG1("### Proxy Hash match table " << name() << " pass2 " << loc()); + for (auto &ixb : input_xbar) ixb->pass2(); + setup_word_ixbar_group(); + + if (actions) actions->pass2(this); + if (gateway) gateway->pass2(); + if (idletime) idletime->pass2(); + if (format) format->pass2(this); + for (auto &hd : hash_dist) hd.pass2(this); +} + +void ProxyHashMatchTable::pass3() { + LOG1("### Proxy Hash match table " << name() << " pass3 " << loc()); +} + +template +void ProxyHashMatchTable::write_regs_vt(REGS ®s) { + LOG1("### Proxy Hash match table " << name() << " write_regs " << loc()); + SRamMatchTable::write_regs(regs); + + for (auto &row : layout) { + auto &rams_row = regs.rams.array.row[row.row]; + for (auto &unit : row.memunits) { + auto &way = way_map[unit]; + auto &ram = rams_row.ram[unit.col]; + ram.match_nibble_s0q1_enable = version_nibble_mask.getrange(way.word * 32U, 32); + ram.match_nibble_s1q0_enable = UINT64_C(0xffffffff); + } + } +} + +/** + * The purpose of this function is to add the proxy_hash_function cJSON node. This is used + * by the driver in order to build the match key for the proxy hash table. + * + * By using the group from the proxy hash table, only pull the relevant bits for the proxy + * hash lookup. + */ +void ProxyHashMatchTable::add_proxy_hash_function(json::map &stage_tbl) const { + bitvec hash_matrix_use; + for (auto *match_key : match) { + hash_matrix_use.setrange(match_key->fieldlobit(), match_key->size()); + } + + json::map &proxy_hash_function = stage_tbl["proxy_hash_function"] = json::map(); + json::vector &hash_bits = proxy_hash_function["hash_bits"] = json::vector(); + BUG_CHECK(input_xbar.size() == 1, "%s does not have one input xbar", name()); + auto *hash_group = input_xbar[0]->get_hash_group(proxy_hash_group); + if (hash_group) { + for (unsigned id : bitvec(hash_group->tables)) { + auto hash_table = input_xbar[0]->get_hash_table(id); + gen_hash_bits(hash_table, InputXbar::HashTable(InputXbar::HashTable::EXACT, id), + hash_bits, proxy_hash_group, hash_matrix_use); + } + proxy_hash_function["hash_function_number"] = proxy_hash_group; + proxy_hash_function["ghost_bit_to_hash_bit"] = json::vector(); + proxy_hash_function["ghost_bit_info"] = json::vector(); + } +} + +void ProxyHashMatchTable::gen_tbl_cfg(json::vector &out) const { + unsigned size = get_number_entries(); + json::map &tbl = *base_tbl_cfg(out, "match", size); + json::map &stage_tbl = *add_common_sram_tbl_cfgs(tbl, "exact", "proxy_hash_match"); + stage_tbl["memory_resource_allocation"] = nullptr; + // FIXME: stash_allocation being null is a placeholder until implemented. + stage_tbl["stash_allocation"] = nullptr; + add_pack_format(stage_tbl, format.get(), true, false); + json::map &match_attributes = tbl["match_attributes"]; + match_attributes["uses_dynamic_key_masks"] = false; + if (ways.size() > 0) { + json::vector &way_stage_tables = stage_tbl["ways"] = json::vector(); + unsigned way_number = 0; + for (auto &way : ways) { + json::map way_tbl; + way_tbl["stage_number"] = stage->stageno; + way_tbl["way_number"] = way_number++; + way_tbl["stage_table_type"] = "hash_way"; + auto fmt_width = get_format_width(); + BUG_CHECK(fmt_width); + way_tbl["size"] = way.rams.size() / fmt_width * format->groups() * 1024; + add_pack_format(way_tbl, format.get(), false); + way_tbl["memory_resource_allocation"] = gen_memory_resource_allocation_tbl_cfg(way); + way_stage_tables.push_back(std::move(way_tbl)); + } + } + add_proxy_hash_function(stage_tbl); + stage_tbl["proxy_hash_algorithm"] = proxy_hash_alg; + int proxy_hash_width = 0; + for (auto m : match) { + proxy_hash_width += m->size(); + } + stage_tbl["proxy_hash_bit_width"] = proxy_hash_width; +} + +DEFINE_TABLE_TYPE(ProxyHashMatchTable) diff --git a/backends/tofino/bf-asm/reflow.cpp b/backends/tofino/bf-asm/reflow.cpp new file mode 100644 index 00000000000..83a7f25d9fb --- /dev/null +++ b/backends/tofino/bf-asm/reflow.cpp @@ -0,0 +1,113 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +void output_normal(std::ostream &out, std::vector &lines) { + for (auto &l : lines) out << l << '\n'; + lines.clear(); +} + +void strip_trail_ws(std::string &s) { + auto end = s.find_last_not_of(" \t\r\n"); + if (end != std::string::npos) s.resize(end + 1); +} +void strip_lead_ws(std::string &s) { + auto start = s.find_first_not_of(" \t\r\n"); + if (start != std::string::npos) s.erase(0, start); +} + +void output_1line(std::ostream &out, std::vector &lines) { + bool first = true; + for (auto &l : lines) { + if (first) { + strip_trail_ws(l); + first = false; + } else { + strip_trail_ws(l); + strip_lead_ws(l); + out << ' '; + } + out << l; + } + out << '\n'; + lines.clear(); +} + +size_t output_len(std::vector &lines) { + size_t rv = 0; + for (auto &l : lines) { + size_t len = l.find_last_not_of(" \t\r\n"), plen; + if (len == std::string::npos) len = l.size(); + if (rv == 0 && (plen = l.find_first_not_of(" \t\r\n")) != std::string::npos) + len -= plen - 1; + rv += len; + } + return rv; +} + +void reflow(std::istream &in, std::ostream &out) { + std::string line; + char looking = 0; + std::vector save; + const auto npos = std::string::npos; + while (getline(in, line)) { + if (line.find('{') != npos && line.find('}') == npos) { + output_normal(out, save); + looking = '}'; + save.push_back(line); + } else if (line.find('[') != npos && line.find(']') == npos) { + output_normal(out, save); + looking = ']'; + save.push_back(line); + } else if (looking) { + save.push_back(line); + if (line.find(looking) != std::string::npos) { + output_1line(out, save); + looking = 0; + } else if (output_len(save) > 100) { + output_normal(out, save); + looking = 0; + } + } else { + out << line << '\n'; + } + } + output_normal(out, save); + out << std::flush; +} + +int main(int ac, char **av) { + if (ac == 2) { + std::ifstream in(av[1]); + if (in) { + reflow(in, std::cout); + } else { + std::cerr << "Can't open " << av[1] << std::endl; + return 1; + } + } else if (ac == 1) { + reflow(std::cin, std::cout); + } else { + std::cerr << "usage: " << av[0] << " [file]" << std::endl; + return 1; + } + return 0; +} diff --git a/backends/tofino/bf-asm/register_reference.h b/backends/tofino/bf-asm/register_reference.h new file mode 100644 index 00000000000..6d3c3c67c4a --- /dev/null +++ b/backends/tofino/bf-asm/register_reference.h @@ -0,0 +1,111 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_REGISTER_REFERENCE_H_ +#define BF_ASM_REGISTER_REFERENCE_H_ + +#include +#include + +#include "log.h" + +/* used by `dump_unread` methods to hold a concatenation of string literals for printing. + * Allocated on the stack, the `pfx` chain prints the calling context */ +struct prefix { + const prefix *pfx; + const char *str; // should always be a string literal + prefix(const prefix *p, const char *s) : pfx(p), str(s) {} +}; + +inline std::ostream &operator<<(std::ostream &out, const prefix *p) { + if (p) { + if (p->pfx) out << p->pfx << '.'; + out << p->str; + } + return out; +} + +/* Class to link register trees together into a larger dag that will expand into a tree + * when dumped as binary (so trees that appear in mulitple places will be duplicated) + * 'name' is the json file name to use when dumping as cfg.json, and the name for logging + * 'tree' is the subtree to dump as binary at the appropriate offset + */ +template +class register_reference { + REG *tree = nullptr; + std::string name; + + public: + mutable bool read = false, write = false, disabled_ = false; + register_reference() {} + register_reference(const register_reference &) = default; + register_reference(register_reference &&) = default; + register_reference &operator=(const register_reference &) & = default; + register_reference &operator=(register_reference &&) & = default; + ~register_reference() {} + + register_reference &set(const char *a, REG *r) { + if (disabled_) LOG1("ERROR: Writing disabled register value in " << this); + if (write) LOG1("WARNING: Overwriting \"" << name << "\" with \"" << a << "\" in " << this); + name = a; + tree = r; + log(); + write = true; + return *this; + } + const char *c_str() const { return name.c_str(); } + REG *operator->() const { + read = true; + return tree; + } + explicit operator bool() const { return tree != nullptr; } + bool modified() const { return write; } + void set_modified(bool v = true) { write = v; } + void rewrite() { write = false; } + // friend std::ostream &operator<<(std::ostream &out, const register_reference &u); + void enable() { disabled_ = false; } + bool disabled() const { return disabled_; } + bool disable_if_unmodified() { return false; } + bool disable_if_zero() { return false; } + bool disable_if_reset_value() { return false; } + bool disable() { + if (!name.empty()) { + LOG1("ERROR: Disabling modified register in " << this); + return false; + } + tree = nullptr; + disabled_ = true; + return true; + } + void log() const { LOG1(this << " = \"" << name << "\""); } +}; + +template +inline std::ostream &operator<<(std::ostream &out, const register_reference *u) { + print_regname(out, u, u + 1); + return out; +} +template +inline std::ostream &operator<<(std::ostream &out, const register_reference &u) { + if (!*u.c_str()) + out << 0; + else + out << '"' << u.c_str() << '"'; + return out; +} + +#endif /* BF_ASM_REGISTER_REFERENCE_H_ */ diff --git a/backends/tofino/bf-asm/rvalue_reference_wrapper.h b/backends/tofino/bf-asm/rvalue_reference_wrapper.h new file mode 100644 index 00000000000..81b361500d1 --- /dev/null +++ b/backends/tofino/bf-asm/rvalue_reference_wrapper.h @@ -0,0 +1,33 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_RVALUE_REFERENCE_WRAPPER_H_ +#define BF_ASM_RVALUE_REFERENCE_WRAPPER_H_ + +template +class rvalue_reference_wrapper { + T *ref; + + public: + typedef T type; + rvalue_reference_wrapper(T &&r) : ref(&r) {} // NOLINT(runtime/explicit) + template + rvalue_reference_wrapper(U &&r) : ref(&r) {} // NOLINT(runtime/explicit) + T &&get() { return std::move(*ref); } +}; + +#endif /* BF_ASM_RVALUE_REFERENCE_WRAPPER_H_ */ diff --git a/backends/tofino/bf-asm/salu_inst.cpp b/backends/tofino/bf-asm/salu_inst.cpp new file mode 100644 index 00000000000..e6fef86a18f --- /dev/null +++ b/backends/tofino/bf-asm/salu_inst.cpp @@ -0,0 +1,1073 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include + +#include + +#include "hex.h" +#include "instruction.h" +#include "phv.h" +#include "stage.h" +#include "tables.h" + +namespace StatefulAlu { + +struct operand : public IHasDbPrint { + struct Base : public IHasDbPrint { + int lineno; + explicit Base(int line) : lineno(line) {} + Base(const Base &a) : lineno(a.lineno) {} + virtual ~Base() {} + virtual Base *clone() const = 0; + virtual void dbprint(std::ostream &) const = 0; + virtual bool equiv(const Base *) const = 0; + virtual const char *kind() const = 0; + virtual Base *lookup(Base *&) { return this; } + virtual bool phvRead(std::function) { return false; } + virtual void pass1(StatefulTable *) {} + } *op; + struct Const : public Base { + int64_t value; + Const *clone() const override { return new Const(*this); } + Const(int line, int64_t v) : Base(line), value(v) {} + void dbprint(std::ostream &out) const override { out << value; } + bool equiv(const Base *a_) const override { + if (auto *a = dynamic_cast(a_)) { + return value == a->value; + } else { + return false; + } + } + const char *kind() const override { return "constant"; } + }; + // Operand representing a constant stored in the register file + struct Regfile : public Base { + int index = -1; + Regfile *clone() const override { return new Regfile(*this); } + Regfile(int line, int index) : Base(line), index(index) {} + Regfile(int line, const value_t &n) : Base(line) { + if (PCHECKTYPE2M(n.vec.size == 2, n[1], tINT, tBIGINT, "SALU regfile row reference")) + index = get_int64(n[1], sizeof(index) / 8, "regfile row index out of bounds"); + } + void dbprint(std::ostream &out) const override { out << index; } + bool equiv(const Base *a_) const override { + if (auto *a = dynamic_cast(a_)) { + return index == a->index; + } else { + return false; + } + } + const char *kind() const override { return "register file constant"; } + }; + struct Phv : public Base { + virtual Phv *clone() const = 0; + explicit Phv(int lineno) : Base(lineno) {} + virtual int phv_index(StatefulTable *tbl) = 0; + }; + struct PhvReg : public Phv { + ::Phv::Ref reg; + PhvReg *clone() const override { return new PhvReg(*this); } + PhvReg(gress_t gress, int stage, const value_t &v) : Phv(v.lineno), reg(gress, stage, v) {} + void dbprint(std::ostream &out) const override { out << reg; } + bool equiv(const Base *a_) const override { + if (auto *a = dynamic_cast(a_)) { + return reg == a->reg; + } else { + return false; + } + } + const char *kind() const override { return "phv_reg"; } + void pass1(StatefulTable *tbl) override { + if (!reg.check()) return; + int size = tbl->format->begin()->second.size / 8; + if (tbl->input_xbar.empty()) { + error(lineno, "No input xbar for salu instruction operand for phv"); + return; + } + BUG_CHECK(tbl->input_xbar.size() == 1, "%s does not have one input xbar", tbl->name()); + int byte = tbl->find_on_ixbar(*reg, tbl->input_xbar[0]->match_group()); + int base = options.target == TOFINO ? 8 : 0; + if (byte < 0) + error(lineno, "Can't find %s on the input xbar", reg.name()); + else if (byte != base && byte != base + size) + error(lineno, "%s must be at %d or %d on ixbar to be used in stateful table %s", + reg.desc().c_str(), base * 8, (base + size) * 8, tbl->name()); + else if (int(reg->size()) > size * 8) + error(lineno, "%s is too big for stateful table %s", reg.desc().c_str(), + tbl->name()); + else + tbl->phv_byte_mask |= ((1U << (reg->size() + 7) / 8U) - 1) << (byte - base); + } + int phv_index(StatefulTable *tbl) override { + int base = options.target == TOFINO ? 8 : 0; + return tbl->find_on_ixbar(*reg, tbl->input_xbar[0]->match_group()) > base; + } + bool phvRead(std::function fn) override { + fn(*reg); + return true; + } + }; + // Operand which directly accesses phv(hi/lo) from Input Xbar + struct PhvRaw : public Phv { + int pi = -1; + unsigned mask = ~0U; + PhvRaw *clone() const override { return new PhvRaw(*this); } + PhvRaw(gress_t gress, const value_t &v) : Phv(v.lineno) { + if (v == "phv_lo") + pi = 0; + else if (v == "phv_hi") + pi = 1; + else + BUG(); + if (v.type == tCMD && PCHECKTYPE(v.vec.size == 2, v[1], tRANGE)) { + if ((v[1].lo & 7) || ((v[1].hi + 1) & 7)) + error(lineno, "only byte slices allowed on %s", v[0].s); + mask = (1U << (v[1].hi + 1) / 8U) - (1U << (v[1].lo / 8U)); + } + } + void dbprint(std::ostream &out) const override { out << (pi ? "phv_hi" : "phv_lo"); } + bool equiv(const Base *a_) const override { + if (auto *a = dynamic_cast(a_)) { + return pi == a->pi; + } else { + return false; + } + } + const char *kind() const override { return "phv_ixb"; } + void pass1(StatefulTable *tbl) override { + int size = tbl->format->begin()->second.size / 8U; + if (mask == ~0U) + mask = (1U << size) - 1; + else if (mask & ~((1U << size) - 1)) + error(lineno, "slice out of range for %d byte value", size); + tbl->phv_byte_mask |= mask << (size * pi); + } + int phv_index(StatefulTable *tbl) override { return pi; } + bool phvRead(std::function) override { return true; } + }; + struct Memory : public Base { + Table *tbl; + Table::Format::Field *field; + Memory *clone() const override { return new Memory(*this); } + Memory(int line, Table *t, Table::Format::Field *f) : Base(line), tbl(t), field(f) {} + void dbprint(std::ostream &out) const override { out << tbl->format->find_field(field); } + bool equiv(const Base *a_) const override { + if (auto *a = dynamic_cast(a_)) { + return field == a->field; + } else { + return false; + } + } + const char *kind() const override { return "memory"; } + }; + struct MathFn; + bool neg = false; + uint64_t mask = uint32_t(-1); + operand() : op(0) {} + operand(const operand &a) : op(a.op ? a.op->clone() : 0) {} + operand(operand &&a) : op(a.op) { a.op = 0; } + operand &operator=(const operand &a) { + if (&a != this) { + delete op; + op = a.op ? a.op->clone() : 0; + } + return *this; + } + operand &operator=(operand &&a) { + if (&a != this) { + delete op; + op = a.op; + a.op = 0; + } + return *this; + } + ~operand() { delete op; } + operand(Table *tbl, const Table::Actions::Action *act, const value_t &v, bool can_mask = false); + bool valid() const { return op != 0; } + explicit operator bool() const { return op != 0; } + bool operator==(operand &a) { + return op == a.op || (op && a.op && op->lookup(op)->equiv(a.op->lookup(a.op))); + } + bool phvRead(std::function fn) { + return op ? op->lookup(op)->phvRead(fn) : false; + } + void dbprint(std::ostream &out) const { + if (neg) out << '-'; + if (op) + op->dbprint(out); + else + out << "(null)"; + } + Base *operator->() { return op->lookup(op); } + template + T *to() { + return dynamic_cast(op); + } +}; + +struct operand::MathFn : public Base { + operand of; + MathFn *clone() const override { return new MathFn(*this); } + MathFn(int line, operand of) : Base(line), of(of) {} + void dbprint(std::ostream &out) const override { + out << "math(" << of << ")"; + ; + } + bool equiv(const Base *a_) const override { + if (auto *a = dynamic_cast(a_)) { + return of.op == a->of.op; + } else { + return false; + } + } + const char *kind() const override { return "math fn"; } + bool phvRead(std::function fn) { return of->phvRead(fn); } + void pass1(StatefulTable *tbl) override { of->pass1(tbl); } +}; + +operand::operand(Table *tbl, const Table::Actions::Action *act, const value_t &v_, bool can_mask) + : op(nullptr) { + const value_t *v = &v_; + if (options.target == TOFINO) can_mask = false; + if (can_mask && v->type == tCMD && *v == "&" && v->vec.size == 3) { + if (v->vec[2].type == tINT || v->vec[2].type == tBIGINT) { + mask = get_int64(v->vec[2], 64, "mask too large"); + v = &v->vec[1]; + } else if (v->vec[1].type == tINT || v->vec[1].type == tBIGINT) { + mask = get_int64(v->vec[1], 64, "mask too large"); + v = &v->vec[2]; + } else { + error(v->lineno, "mask must be a constant"); + } + } + if (v->type == tCMD && *v == "-") { + neg = true; + v = &v->vec[1]; + } + if (v->type == tINT || v->type == tBIGINT) { + auto i = get_int64(*v, 64, "Integer too large"); + op = new Const(v->lineno, i); + return; + } + if (v->type == tCMD && *v == "register_param") { + op = new Regfile(v->lineno, *v); + return; + } + if (v->type == tSTR) { + if (auto f = tbl->format->field(v->s)) { + op = new Memory(v->lineno, tbl, f); + return; + } + } + if (v->type == tCMD) { + BUG_CHECK(v->vec.size > 0 && v->vec[0].type == tSTR); + if (auto f = tbl->format->field(v->vec[0].s)) { + if (v->vec.size > 1 && CHECKTYPE(v->vec[1], tRANGE) && v->vec[1].lo != 0) + error(v->vec[1].lineno, "Can't slice memory field %s in stateful action", + v->vec[0].s); + op = new Memory(v->lineno, tbl, f); + return; + } + } + if ((v->type == tCMD) && (v->vec[0] == "math_table")) { + // operand *opP = new operand(tbl, act, v->vec[1]); + op = new MathFn(v->lineno, operand(tbl, act, v->vec[1])); + return; + } + if (*v == "phv_lo" || *v == "phv_hi") { + op = new PhvRaw(tbl->gress, *v); + return; + } + if (::Phv::Ref(tbl->gress, tbl->stage->stageno, *v).check(false)) + op = new PhvReg(tbl->gress, tbl->stage->stageno, *v); +} + +enum salu_slot_use { + CMP0, + CMP1, + CMP2, + CMP3, + ALU2LO, + ALU1LO, + ALU2HI, + ALU1HI, + ALUOUT0, + ALUOUT1, + ALUOUT2, + ALUOUT3, + MINMAX, + // aliases + CMPLO = CMP0, + CMPHI = CMP1, + ALUOUT = ALUOUT0, +}; + +// Abstract interface class for SALU Instructions +// SALU Instructions - AluOP, BitOP, CmpOP, OutOP +struct SaluInstruction : public Instruction { + explicit SaluInstruction(int lineno) : Instruction(lineno) {} + // Stateful ALU's dont access PHV's directly + static int decode_predicate(const value_t &exp); +}; + +int SaluInstruction::decode_predicate(const value_t &exp) { + if (exp == "cmplo") return Target::STATEFUL_PRED_MASK() & STATEFUL_PREDICATION_ENCODE_CMPLO; + if (exp == "cmphi") return Target::STATEFUL_PRED_MASK() & STATEFUL_PREDICATION_ENCODE_CMPHI; + if (exp == "cmp0") return Target::STATEFUL_PRED_MASK() & STATEFUL_PREDICATION_ENCODE_CMP0; + if (Target::STATEFUL_CMP_UNITS() > 1 && exp == "cmp1") + return Target::STATEFUL_PRED_MASK() & STATEFUL_PREDICATION_ENCODE_CMP1; + if (Target::STATEFUL_CMP_UNITS() > 2 && exp == "cmp2") + return Target::STATEFUL_PRED_MASK() & STATEFUL_PREDICATION_ENCODE_CMP2; + if (Target::STATEFUL_CMP_UNITS() > 3 && exp == "cmp3") + return Target::STATEFUL_PRED_MASK() & STATEFUL_PREDICATION_ENCODE_CMP3; + if (exp == "!") return Target::STATEFUL_PRED_MASK() ^ decode_predicate(exp[1]); + if (exp == "&") { + auto rv = decode_predicate(exp[1]); + for (int i = 2; i < exp.vec.size; ++i) rv &= decode_predicate(exp[i]); + return rv; + } + if (exp == "|") { + auto rv = decode_predicate(exp[1]); + for (int i = 2; i < exp.vec.size; ++i) rv |= decode_predicate(exp[i]); + return rv; + } + if (exp == "^") { + auto rv = decode_predicate(exp[1]); + for (int i = 2; i < exp.vec.size; ++i) rv ^= decode_predicate(exp[i]); + return rv; + } + if (exp.type == tINT && exp.i >= 0 && exp.i <= Target::STATEFUL_PRED_MASK()) return exp.i; + error(exp.lineno, "Unexpected expression %s in predicate", value_desc(&exp)); + return -1; +} + +struct AluOP : public SaluInstruction { + const struct Decode : public Instruction::Decode { + std::string name; + unsigned opcode; + enum operands_t { NONE, A, B, AandB } operands = AandB; + const Decode *swap_args; + Decode(const char *n, int opc, bool assoc = false, const char *alias_name = 0) + : Instruction::Decode(n, STATEFUL_ALU), + name(n), + opcode(opc), + swap_args(assoc ? this : 0) { + if (alias_name) alias(alias_name, STATEFUL_ALU); + } + Decode(const char *n, int opc, Decode *sw, const char *alias_name = 0, + operands_t use = AandB) + : Instruction::Decode(n, STATEFUL_ALU), + name(n), + opcode(opc), + operands(use), + swap_args(sw) { + if (sw && !sw->swap_args) sw->swap_args = this; + if (alias_name) alias(alias_name, STATEFUL_ALU); + } + Decode(const char *n, int opc, const char *alias_name) + : Instruction::Decode(n, STATEFUL_ALU), name(n), opcode(opc), swap_args(0) { + if (alias_name) alias(alias_name, STATEFUL_ALU); + } + Decode(const char *n, int opc, bool assoc, operands_t use) + : Instruction::Decode(n, STATEFUL_ALU), + name(n), + opcode(opc), + operands(use), + swap_args(assoc ? this : 0) {} + Decode(const char *n, int opc, const char *alias_name, operands_t use) + : Instruction::Decode(n, STATEFUL_ALU), + name(n), + opcode(opc), + operands(use), + swap_args(0) { + if (alias_name) alias(alias_name, STATEFUL_ALU); + } + Decode(const char *n, int opc, Decode *sw, operands_t use) + : Instruction::Decode(n, STATEFUL_ALU), + name(n), + opcode(opc), + operands(use), + swap_args(sw) { + if (sw && !sw->swap_args) sw->swap_args = this; + } + Decode(const char *n, target_t targ, int opc) + : Instruction::Decode(n, targ, STATEFUL_ALU), name(n), opcode(opc), swap_args(0) {} + + Instruction *decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const override; + } *opc; + int predication_encode = STATEFUL_PREDICATION_ENCODE_UNCOND; + enum dest_t { LO, HI }; + dest_t dest = LO; + operand srca, srcb; + AluOP(const Decode *op, int l) : SaluInstruction(l), opc(op) {} + std::string name() override { return opc->name; }; + Instruction *pass1(Table *tbl, Table::Actions::Action *) override; + void pass2(Table *tbl, Table::Actions::Action *) override {} + bool salu_alu() const override { return true; } + bool equiv(Instruction *a_) override; + bool phvRead(std::function fn) override { + return srca.phvRead(fn) | srcb.phvRead(fn); + } + void dbprint(std::ostream &out) const override { + out << "INSTR: " << opc->name << " pred=0x" << hex(predication_encode) << " " + << (dest ? "hi" : "lo") << ", " << srca << ", " << srcb; + } + template + void write_regs(REGS ®s, Table *tbl, Table::Actions::Action *act); + FOR_ALL_REGISTER_SETS(DECLARE_FORWARD_VIRTUAL_INSTRUCTION_WRITE_REGS) +}; + +static AluOP::Decode opADD("add", 0x1c, true), opSUB("sub", 0x1e), opSADDU("saddu", 0x10, true), + opSADDS("sadds", 0x11, true), opSSUBU("ssubu", 0x12), opSSUBS("ssubs", 0x13), + opMINU("minu", 0x14, true), opMINS("mins", 0x15, true), opMAXU("maxu", 0x16, true), + opMAXS("maxs", 0x17, true), opNOP("nop", 0x18, true, AluOP::Decode::NONE), + opSUBR("subr", 0x1f, &opSUB), opSSUBRU("ssubru", 0x1a, &opSSUBU), + opSSUBRS("ssubrs", 0x1b, &opSSUBS), + + opSETZ("setz", 0x00, true, AluOP::Decode::NONE), opNOR("nor", 0x01, true), + opANDCA("andca", 0x02), opNOTA("nota", 0x03, "not", AluOP::Decode::A), + opANDCB("andcb", 0x04, &opANDCA), opNOTB("notb", 0x05, &opNOTA, AluOP::Decode::B), + opXOR("xor", 0x06, true), opNAND("nand", 0x07, true), opAND("and", 0x08, true), + opXNOR("xnor", 0x09, true), opB("alu_b", 0x0a, "b", AluOP::Decode::B), opORCA("orca", 0x0b), + opA("alu_a", 0x0c, &opB, "a", AluOP::Decode::A), opORCB("orcb", 0x0d, &opORCA), + opOR("or", 0x0e, true), opSETHI("sethi", 0x0f, true, AluOP::Decode::NONE); + +Instruction *AluOP::Decode::decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const { + AluOP *rv = new AluOP(this, op[0].lineno); + auto operands = this->operands; + int idx = 1; + // Check optional predicate operand + if (idx < op.size) { + if (op[idx].type == tINT) { + // Predicate is an integer. no warning for odd values + rv->predication_encode = op[idx++].i; + } else if (op[idx].startsWith("cmp") || op[idx] == "!" || op[idx] == "&" || + op[idx] == "|" || op[idx] == "^") { + // Predicate is an expression + rv->predication_encode = decode_predicate(op[idx++]); + if (rv->predication_encode == STATEFUL_PREDICATION_ENCODE_NOOP) + warning(op[idx - 1].lineno, "Instruction predicate is always false"); + else if (rv->predication_encode == STATEFUL_PREDICATION_ENCODE_UNCOND) + warning(op[idx - 1].lineno, "Instruction predicate is always true"); + } + } + if (idx < op.size && op[idx] == "lo") { + rv->dest = LO; + idx++; + } else if (idx < op.size && op[idx] == "hi") { + rv->dest = HI; + idx++; + } else if (idx == op.size && name == "nop") { + // allow nop without even a destination -- assume lo + rv->dest = LO; + } else { + error(rv->lineno, "invalid destination for %s instruction", op[0].s); + } + if (operands == NONE) { + if (idx < op.size) error(rv->lineno, "too many operands for %s instruction", op[0].s); + return rv; + } + if (idx < op.size && operands != B) rv->srca = operand(tbl, act, op[idx++]); + if (idx < op.size && operands != A) rv->srcb = operand(tbl, act, op[idx++]); + if (swap_args && (rv->srca.to() || rv->srca.to() || + (rv->srcb.to() && + (rv->srca.to() || rv->srca.to())))) { + operands = (rv->opc = swap_args)->operands; + std::swap(rv->srca, rv->srcb); + } + if (idx < op.size) + error(rv->lineno, "too many operands for %s instruction", op[0].s); + else if ((!rv->srca && operands != B) || (!rv->srcb && operands != A)) + error(rv->lineno, "not enough operands for %s instruction", op[0].s); + if (auto mf = rv->srca.to()) { + error(rv->lineno, "Can't reference math table in %soperand of %s instruction", + operands != A ? "first " : "", op[0].s); + if (!mf->of.to() && !mf->of.to()) + error(rv->lineno, "Math table input must come from Phv or memory"); + } + if (rv->srca.to()) + error(rv->lineno, "Can't reference phv in %soperand of %s instruction", + operands != A ? "first " : "", op[0].s); + if (rv->srcb.to()) + error(rv->lineno, "Can't reference memory in %soperand of %s instruction", + operands != A ? "first " : "", op[0].s); + if (auto mf = rv->srcb.to()) { + rv->slot = ALU2LO; + if (rv->dest != LO) error(rv->lineno, "Can't reference math table in alu-hi"); + if (!mf->of.to() && !mf->of.to()) + error(rv->lineno, "Math table input must come from Phv or memory"); + } + if (rv->srca.neg) { + if (auto k = rv->srca.to()) + k->value = -k->value; + else + error(rv->lineno, "Can't negate operand of %s instruction", op[0].s); + } + if (rv->srcb.neg) { + if (auto k = rv->srcb.to()) + k->value = -k->value; + else + error(rv->lineno, "Can't negate operand of %s instruction", op[0].s); + } + return rv; +} + +bool AluOP::equiv(Instruction *a_) { + if (auto *a = dynamic_cast(a_)) + return opc == a->opc && predication_encode == a->predication_encode && dest == a->dest && + srca == a->srca && srcb == a->srcb; + return false; +} + +Instruction *AluOP::pass1(Table *tbl_, Table::Actions::Action *act) { + auto tbl = dynamic_cast(tbl_); + BUG_CHECK(tbl); + if (slot < 0 && act->slot_use[slot = (dest ? ALU1HI : ALU1LO)]) slot = dest ? ALU2HI : ALU2LO; + auto k1 = srca.to(); + auto k2 = srcb.to(); + // Check cases when both constants would be stored in the register file on different rows + // Two constants that do not fit as immediate constants + if (k1 && k2 && !k1->equiv(k2)) + error(lineno, "can only have one constant in an SALU instruction"); + if (!k1) k1 = k2; + if (k1 && (k1->value < Target::STATEFUL_ALU_CONST_MIN() || + k1->value > Target::STATEFUL_ALU_CONST_MAX())) { + if (k1->value >= (INT64_C(1) << tbl->alu_size()) || + k1->value < (INT64_C(-1) << (tbl->alu_size() - 1))) { + error(lineno, + "value %" PRIi64 + " of the constant operand" + " out of range for %d bit stateful ALU", + k1->value, tbl->alu_size()); + } else if (k1->value >= (INT64_C(1) << (Target::STATEFUL_REGFILE_CONST_WIDTH() - 1))) { + // constants have a limited width, and are always signed, so need to make + // sure they wrap properly + k1->value -= INT64_C(1) << Target::STATEFUL_REGFILE_CONST_WIDTH(); + if (k2 && k2 != k1) k2->value = k1->value; + } + } + auto r1 = srca.to(); + auto r2 = srcb.to(); + if (r1 && r2 && !r1->equiv(r2)) + error(lineno, "can only have one register file reference in an SALU instruction"); + if (!r1) r1 = r2; + if (r1) { + int64_t v1 = tbl->get_const_val(r1->index); + if (v1 >= (INT64_C(1) << tbl->alu_size()) || v1 < (INT64_C(-1) << (tbl->alu_size() - 1))) { + error(lineno, + "initial value %" PRIi64 + " of the register file operand" + " out of range for %d bit stateful ALU", + v1, tbl->alu_size()); + } + } + if (k1 && r1) + error(lineno, + "can have either a constant or a register file reference" + " in an SALU instruction"); + if (srca) srca->pass1(tbl); + if (srcb) srcb->pass1(tbl); + return this; +} + +Instruction *genNoop(StatefulTable *tbl, Table::Actions::Action *act) { + VECTOR(value_t) args = EMPTY_VECTOR_INIT; + BUG_CHECK(tbl->format->begin() != tbl->format->end(), "No tbl->format!"); + args.add("or").add("lo").add(0).add(tbl->format->begin()->first.c_str()); + auto *rv = Instruction::decode(tbl, act, args); + VECTOR_fini(args); + return rv; +} + +struct BitOP : public SaluInstruction { + const struct Decode : public Instruction::Decode { + std::string name; + unsigned opcode; + Decode(const char *n, unsigned opc) + : Instruction::Decode(n, STATEFUL_ALU), name(n), opcode(opc) {} + Instruction *decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const override; + } *opc; + int predication_encode = STATEFUL_PREDICATION_ENCODE_UNCOND; + BitOP(const Decode *op, int lineno) : SaluInstruction(lineno), opc(op) {} + std::string name() override { return opc->name; }; + Instruction *pass1(Table *, Table::Actions::Action *) override { + slot = ALU1LO; + return this; + } + void pass2(Table *, Table::Actions::Action *) override {} + bool salu_alu() const override { return true; } + bool equiv(Instruction *a_) override; + bool phvRead(std::function fn) override { return false; } + void dbprint(std::ostream &out) const override { out << "INSTR: " << opc->name; } + template + void write_regs(REGS ®s, Table *tbl, Table::Actions::Action *act); + FOR_ALL_REGISTER_SETS(DECLARE_FORWARD_VIRTUAL_INSTRUCTION_WRITE_REGS) +}; + +static BitOP::Decode opSET_BIT("set_bit", 0x0), opSET_BITC("set_bitc", 0x1), + opCLR_BIT("clr_bit", 0x2), opCLR_BITC("clr_bitc", 0x3), opREAD_BIT("read_bit", 0x4), + opREAD_BITC("read_bitc", 0x5), opSET_BIT_AT("set_bit_at", 0x6), + opSET_BITC_AT("set_bitc_at", 0x7), opCLR_BIT_AT("clr_bit_at", 0x8), + opCLR_BITC_AT("clr_bitc_at", 0x9); + +Instruction *BitOP::Decode::decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const { + BitOP *rv = new BitOP(this, op[0].lineno); + if (op.size > 1) error(rv->lineno, "too many operands for %s instruction", op[0].s); + return rv; +} + +bool BitOP::equiv(Instruction *a_) { + if (auto *a = dynamic_cast(a_)) return opc == a->opc; + return false; +} + +struct CmpOP : public SaluInstruction { + const struct Decode : public Instruction::Decode { + std::string name; + unsigned opcode; + Decode(const char *n, unsigned opc, bool type) + : Instruction::Decode(n, STATEFUL_ALU, type), name(n), opcode(opc) {} + Instruction *decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const override; + } *opc; + int type = 0; + operand::Memory *srca = 0; + uint32_t maska = 0xffffffffU; + operand::Phv *srcb = 0; + uint32_t maskb = 0xffffffffU; + operand::Base *srcc = 0; // operand::Const or operand::Regfile + bool srca_neg = false, srcb_neg = false; + bool learn = false, learn_not = false; + CmpOP(const Decode *op, int lineno) : SaluInstruction(lineno), opc(op) {} + std::string name() override { return opc->name; }; + Instruction *pass1(Table *tbl, Table::Actions::Action *) override; + void pass2(Table *tbl, Table::Actions::Action *) override {} + bool equiv(Instruction *a_) override; + bool phvRead(std::function fn) override { + bool rv = false; + if (srca) rv |= srca->phvRead(fn); + if (srcb) rv |= srcb->phvRead(fn); + if (srcc) rv |= srcc->phvRead(fn); + return rv; + } + void dbprint(std::ostream &out) const override { + out << "INSTR: " << opc->name << " cmp" << slot; + if (srca) { + out << ", " << (srca_neg ? "-" : "") << *srca; + if (maska != 0xffffffffU) out << " & 0x" << hex(maska); + } + if (srcb) { + out << ", " << (srcb_neg ? "-" : "") << *srcb; + if (maskb != 0xffffffffU) out << " & 0x" << hex(maskb); + } + if (srcc) out << ", " << *srcc; + if (learn) out << ", learn"; + if (learn_not) out << ", learn_not"; + } + template + void write_regs(REGS ®s, Table *tbl, Table::Actions::Action *act); + FOR_ALL_REGISTER_SETS(DECLARE_FORWARD_VIRTUAL_INSTRUCTION_WRITE_REGS) +}; + +static CmpOP::Decode opEQU("equ", 0, false), opNEQ("neq", 1, false), opGRT("grt", 0, true), + opLEQ("leq", 1, true), opGEQ("geq", 2, true), opLSS("lss", 3, true); + +Instruction *CmpOP::Decode::decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const { + auto rv = new CmpOP(this, op[0].lineno); + if (auto *p = strchr(op[0].s, '.')) { + if (type_suffix && !strcmp(p, ".s")) + rv->type = 1; + else if (type_suffix && !strcmp(p, ".u")) + rv->type = 2; + else if (type_suffix && !strcmp(p, ".uus")) + rv->type = 3; + else + error(rv->lineno, "Invalid type %s for %s instruction", p + 1, name.c_str()); + } else if (type_suffix) { + error(rv->lineno, "Missing type for %s instruction", name.c_str()); + } + if (op.size < 1 || op[1].type != tSTR) { + error(rv->lineno, "invalid destination for %s instruction", op[0].s); + return rv; + } + unsigned unit; + int len; + if (op[1] == "lo") { + rv->slot = CMPLO; + } else if (op[1] == "hi") { + rv->slot = CMPHI; + } else if ((sscanf(op[1].s, "p%u%n", &unit, &len) >= 1 || + sscanf(op[1].s, "cmp%u%n", &unit, &len) >= 1) && + unit < Target::STATEFUL_CMP_UNITS() && op[1].s[len] == 0) { + rv->slot = CMP0 + unit; + } else { + error(rv->lineno, "invalid destination for %s instruction", op[0].s); + } + for (int idx = 2; idx < op.size; ++idx) { + if (!rv->learn) { + if (op[idx] == "learn") { + rv->learn = true; + continue; + } + if (op[idx] == "!" && op[idx].type == tCMD && op[idx].vec.size == 2 && + op[idx][1] == "learn") { + rv->learn = rv->learn_not = true; + continue; + } + } + operand src(tbl, act, op[idx], true); + if (!rv->srca && (rv->srca = src.to())) { + rv->srca_neg = src.neg; + rv->maska = src.mask; + src.op = nullptr; + } else if (!rv->srcb && (rv->srcb = src.to())) { + rv->srcb_neg = src.neg; + rv->maskb = src.mask; + src.op = nullptr; + } else if (!rv->srcc && (rv->srcc = src.to())) { + auto *srcc = src.to(); + if (src.neg) srcc->value = -srcc->value; + if (src.mask != ~0U) srcc->value &= src.mask; + src.op = nullptr; + } else if (!rv->srcc && (rv->srcc = src.to())) { + if (src.neg || src.mask != ~0U) + error(src->lineno, "Register file operand cannot be negated or masked"); + src.op = nullptr; + } else if (src) { + error(src->lineno, "Can't have more than one %s operand to an SALU compare", + src->kind()); + } + } + return rv; +} + +bool CmpOP::equiv(Instruction *a_) { + if (auto *a = dynamic_cast(a_)) + return opc == a->opc && slot == a->slot && srca == a->srca && maska == a->maska && + srcb == a->srcb && maskb == a->maskb && srcc == a->srcc && learn == a->learn && + learn_not == a->learn_not; + return false; +} + +Instruction *CmpOP::pass1(Table *tbl_, Table::Actions::Action *act) { + auto tbl = dynamic_cast(tbl_); + BUG_CHECK(tbl); + if (srca) srca->pass1(tbl); + if (srcb) srcb->pass1(tbl); + if (srcc) srcc->pass1(tbl); + return this; +} + +#if HAVE_JBAY + +struct TMatchOP : public SaluInstruction { + const struct Decode : public Instruction::Decode { + std::string name; + Decode(const char *n, target_t target) + : Instruction::Decode(n, target, STATEFUL_ALU), name(n) {} + Decode(const char *n, std::set target) + : Instruction::Decode(n, target, STATEFUL_ALU), name(n) {} + Instruction *decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const override; + } *opc; + operand::Memory *srca = 0; + uint64_t mask = 0; + operand::Phv *srcb = 0; + bool learn = false, learn_not = false; + TMatchOP(const Decode *op, int lineno) : SaluInstruction(lineno), opc(op) {} + std::string name() override { return opc->name; }; + Instruction *pass1(Table *tbl, Table::Actions::Action *) override; + void pass2(Table *tbl, Table::Actions::Action *) override {} + bool equiv(Instruction *a_) override; + bool phvRead(std::function fn) override { + return srcb ? srcb->phvRead(fn) : false; + } + void dbprint(std::ostream &out) const override { + out << "INSTR: " << opc->name << " cmp" << slot; + if (srca) out << ", " << *srca; + if (mask) out << ", 0x" << hex(mask); + if (srcb) out << ", " << *srcb; + if (learn) out << ", learn"; + if (learn_not) out << ", learn_not"; + } + template + void write_regs(REGS ®s, Table *tbl, Table::Actions::Action *act); + FOR_ALL_REGISTER_SETS(DECLARE_FORWARD_VIRTUAL_INSTRUCTION_WRITE_REGS) +}; + +static TMatchOP::Decode opTMatch("tmatch", { +#if HAVE_JBAY + JBAY, +#endif + }); + +Instruction *TMatchOP::Decode::decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const { + auto rv = new TMatchOP(this, op[0].lineno); + if (op.size < 1 || op[1].type != tSTR) { + error(rv->lineno, "invalid destination for %s instruction", op[0].s); + return rv; + } + unsigned unit; + int len; + if ((sscanf(op[1].s, "p%u%n", &unit, &len) >= 1 || + sscanf(op[1].s, "cmp%u%n", &unit, &len) >= 1) && + unit < Target::STATEFUL_TMATCH_UNITS() && op[1].s[len] == 0) { + rv->slot = CMP0 + unit; + } else { + error(rv->lineno, "invalid destination for %s instruction", op[0].s); + } + for (int idx = 2; idx < op.size; ++idx) { + if (!rv->learn) { + if (op[idx] == "learn") { + rv->learn = true; + continue; + } + if (op[idx] == "!" && op[idx].type == tCMD && op[idx].vec.size == 2 && + op[idx][1] == "learn") { + rv->learn = rv->learn_not = true; + continue; + } + } + if (op[idx].type == tINT || op[idx].type == tBIGINT) { + if (rv->mask) + error(op[idx].lineno, "Can't have more than one mask operand to an SALU tmatch"); + rv->mask = get_int64(op[idx], 64, "Integer too large"); + } else if (op[idx].type == tSTR) { + if (auto f = tbl->format->field(op[idx].s)) { + if (rv->srca) { + error(op[idx].lineno, + "Can't have more than one memory operand to an " + "SALU tmatch"); + delete rv->srca; + } + rv->srca = new operand::Memory(op[idx].lineno, tbl, f); + } else if (rv->srcb) { + error(op[idx].lineno, "Can't have more than one phv operand to an SALU tmatch"); + } else if (op[idx] == "phv_lo" || op[idx] == "phv_hi") { + rv->srcb = new operand::PhvRaw(tbl->gress, op[idx]); + } else { + rv->srcb = new operand::PhvReg(tbl->gress, tbl->stage->stageno, op[idx]); + } + } + } + if (!rv->srca || !rv->srcb || !rv->mask) + error(rv->lineno, "Not enough operands to SALU tmatch"); + return rv; +} + +bool TMatchOP::equiv(Instruction *a_) { + if (auto *a = dynamic_cast(a_)) + return opc == a->opc && slot == a->slot && srca == a->srca && srcb == a->srcb && + mask == a->mask && learn == a->learn && learn_not == a->learn_not; + return false; +} + +Instruction *TMatchOP::pass1(Table *tbl_, Table::Actions::Action *act) { + auto tbl = dynamic_cast(tbl_); + BUG_CHECK(tbl); + if (srca) srca->pass1(tbl); + if (srcb) srcb->pass1(tbl); + if (tbl->tmatch_use[slot].op) { + if (mask != tbl->tmatch_use[slot].op->mask) { + error(lineno, "Incompatable tmatch masks in stateful actions %s and %s", + tbl->tmatch_use[slot].act->name.c_str(), act->name.c_str()); + error(tbl->tmatch_use[slot].op->lineno, "previous use"); + } + } else { + tbl->tmatch_use[slot].act = act; + tbl->tmatch_use[slot].op = this; + } + return this; +} +#endif /* HAVE_JBAY || */ + +// Output ALU instruction +struct OutOP : public SaluInstruction { + struct Decode : public Instruction::Decode { + explicit Decode(const char *n) : Instruction::Decode(n, STATEFUL_ALU) {} + Instruction *decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const override; + }; + int predication_encode = STATEFUL_PREDICATION_ENCODE_UNCOND; + operand src; + int output_mux = -1; +#if HAVE_JBAY + bool lmatch = false; + int lmatch_pred = 0; +#endif /* HAVE_JBAY */ + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void decode_output_mux, + (register_type, Table *tbl, value_t &op)) + void decode_output_mux(Table *tbl, value_t &op) { + SWITCH_FOREACH_TARGET(options.target, decode_output_mux(TARGET(), tbl, op);); + } + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, int decode_output_option, (register_type, value_t &op)) + int decode_output_option(value_t &op) { + SWITCH_FOREACH_TARGET(options.target, return decode_output_option(TARGET(), op);); + } + OutOP(const Decode *op, int lineno) : SaluInstruction(lineno) {} + std::string name() override { return "output"; }; + Instruction *pass1(Table *tbl, Table::Actions::Action *) override; + void pass2(Table *tbl, Table::Actions::Action *) override {} + bool salu_output() const override { return true; } + bool equiv(Instruction *a_) override; + bool phvRead(std::function fn) override { + return src ? src->phvRead(fn) : false; + } + void dbprint(std::ostream &out) const override { + out << "INSTR: output " << "pred=0x" << hex(predication_encode) +#if HAVE_JBAY + << " word" << (slot - ALUOUT0) +#endif /* HAVE_JBAY */ + << " mux=" << output_mux; + } + template + void write_regs(REGS ®s, Table *tbl, Table::Actions::Action *act); + FOR_ALL_REGISTER_SETS(DECLARE_FORWARD_VIRTUAL_INSTRUCTION_WRITE_REGS) +}; + +static OutOP::Decode opOUTPUT("output"); + +bool OutOP::equiv(Instruction *a_) { + if (auto *a = dynamic_cast(a_)) + return predication_encode == a->predication_encode && slot == a->slot && + output_mux == a->output_mux; + return false; +} + +Instruction *OutOP::Decode::decode(Table *tbl, const Table::Actions::Action *act, + const VECTOR(value_t) & op) const { + OutOP *rv = new OutOP(this, op[0].lineno); + int idx = 1; + // Check optional predicate operand + if (idx < op.size) { + // Predicate is an integer + if (op[idx].type == tINT) { + rv->predication_encode = op[idx++].i; + // Predicate is an expression + } else if (op[idx].startsWith("cmp") || op[idx] == "!" || op[idx] == "&" || + op[idx] == "|" || op[idx] == "^") { + rv->predication_encode = decode_predicate(op[idx++]); + if (rv->predication_encode == STATEFUL_PREDICATION_ENCODE_NOOP) + warning(op[idx - 1].lineno, "Instruction predicate is always false"); + else if (rv->predication_encode == STATEFUL_PREDICATION_ENCODE_UNCOND) + warning(op[idx - 1].lineno, "Instruction predicate is always true"); + } + } + rv->slot = ALUOUT; +#if HAVE_JBAY + // Check for destination + if (idx < op.size && op[idx].startsWith("word")) { + int unit = -1; + char *end; + if (op[idx].type == tSTR) { + if (isdigit(op[idx].s[4])) { + unit = strtol(op[idx].s + 4, &end, 10); + if (*end) unit = -1; + } + } else if (op[idx].vec.size == 2 && op[idx][1].type == tINT) { + unit = op[idx][1].i; + } + if (unit >= Target::STATEFUL_OUTPUT_UNITS()) + error(op[idx].lineno, "Invalid output dest %s", value_desc(op[idx])); + else + rv->slot = unit + ALUOUT0; + idx++; + } +#endif /* HAVE_JBAY */ + // Check mux operand + if (idx < op.size) { + rv->src = operand(tbl, act, op[idx], false); + // DANGER -- decoding the output mux here (as part of input parsing) requires that + // the phv section be before the section we're currently parsing in the .bfa file. + // That's always the case with compiler output, but do we want to require it for + // hand-written code? Could reorg stuff to do this in pass1 instead. + rv->decode_output_mux(tbl, op[idx]); + if (rv->output_mux < 0) + error(op[idx].lineno, "invalid operand '%s' for '%s' instruction", value_desc(op[idx]), + op[0].s); + idx++; + } else { + error(rv->lineno, "too few operands for %s instruction", op[0].s); + } + while (idx < op.size) { + if (rv->decode_output_option(op[idx]) < 0) break; + ++idx; + } + if (idx < op.size) error(rv->lineno, "too many operands for %s instruction", op[0].s); + + return rv; +} + +Instruction *OutOP::pass1(Table *tbl_, Table::Actions::Action *act) { + auto tbl = dynamic_cast(tbl_); + BUG_CHECK(tbl); + if (src) src->pass1(tbl); + if (output_mux == STATEFUL_PREDICATION_OUTPUT) { + if (act->pred_comb_sel >= 0 && act->pred_comb_sel != predication_encode) + error(lineno, "Only one output of predication allowed"); + act->pred_comb_sel = predication_encode; + } +#if HAVE_JBAY + if (lmatch) { + if (tbl->output_lmatch) { + auto *other = dynamic_cast(tbl->output_lmatch); + BUG_CHECK(other); + if (lmatch_pred != other->lmatch_pred) { + error(lineno, "Conflict lmatch output use in stateful %s", tbl->name()); + error(other->lineno, "conflicting use here"); + } + } + tbl->output_lmatch = this; + } +#endif /* HAVE_JBAY */ + return this; +} + +#include "tofino/salu_inst.cpp" // NOLINT(build/include) +#if HAVE_JBAY +#include "jbay/salu_inst.cpp" // NOLINT(build/include) +#endif /* HAVE_JBAY */ + +} // end namespace StatefulAlu + +bool StatefulTable::p4c_5192_workaround(const Actions::Action *act) const { + // when trying to output bits 96..127 + // of either memory or phv input in an SALU in 128-bit mode, the model asserts + // Not clear if this is a hardware limitation or a model bug. + // RMT_ASSERTS on lines 547 and 565 of model/src/shared/mau-stateful-alu.cpp + // Workaround is to use 64x2 mode instead which is otherwise equivalent, except + // for possible problems if minmax is used + using namespace StatefulAlu; + if (format->log2size != 7 || is_dual_mode()) return false; // only apply in 128-bit mode + for (auto &inst : act->instr) { + if (auto *out = dynamic_cast(inst.get())) { + if (out->slot > ALUOUT1 && (out->output_mux == 1 || out->output_mux == 3)) { + return true; + } + } + } + return false; +} diff --git a/backends/tofino/bf-asm/sections.h b/backends/tofino/bf-asm/sections.h new file mode 100644 index 00000000000..9c08b73789e --- /dev/null +++ b/backends/tofino/bf-asm/sections.h @@ -0,0 +1,104 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_SECTIONS_H_ +#define BF_ASM_SECTIONS_H_ + +#include + +#include + +#include "asm-types.h" +#include "bfas.h" +#include "json.h" +#include "map.h" + +/// A Section represents a top level section in assembly +/// Current sections include: +/// version, phv, parser, deparser, stage, dynhash, primitives +class Section : virtual public Parsable, virtual public Contextable { + static std::map *sections; + std::string name; + bool isInput = false; + static Section *get(const char *name) { return ::get(sections, name); } + + protected: + explicit Section(const char *name_) : name(name_) { + if (!sections) sections = new std::map(); + if (get(name_)) { + fprintf(stderr, "Duplicate section handler for %s\n", name_); + exit(1); + } + (*sections)[name] = this; + } + virtual ~Section() { + sections->erase(name); + if (sections->empty()) { + delete sections; + sections = 0; + } + } + /// process the arguments on the same line as the heading + virtual void start(int lineno, VECTOR(value_t) args) {} + /// optionally process the data if not done during parsing + virtual void process() {} + + public: + static int start_section(int lineno, char *name, VECTOR(value_t) args) { + if (Section *sec = get(name)) { + int prev_error_count = error_count; + sec->isInput = true; + sec->start(lineno, args); + return error_count > prev_error_count; + } else { + warning(lineno, "Unknown section %s, ignoring\n", name); + return 1; + } + } + static void asm_section(char *name, VECTOR(value_t) args, value_t data) { + if (Section *sec = get(name)) sec->input(args, data); + } + static void process_all() { + if (sections) + for (auto &it : *sections) it.second->process(); + } + static void output_all(json::map &ctxtJson) { + if (sections) { + for (auto &it : *sections) { + // Skip primitives to be called last + if (it.first == "primitives") continue; + it.second->output(ctxtJson); + } + auto &s = *sections; + if (s.count("primitives")) s["primitives"]->output(ctxtJson); + } + } + static bool no_sections_in_assembly() { + if (sections) { + for (auto &it : *sections) { + if (it.second->isInput) return false; + } + } + return true; + } + static bool section_in_assembly(const char *name) { return get(name)->isInput; } + + public: // for gtest + static Section *test_get(const char *name) { return get(name); } +}; + +#endif /* BF_ASM_SECTIONS_H_ */ diff --git a/backends/tofino/bf-asm/selection.cpp b/backends/tofino/bf-asm/selection.cpp new file mode 100644 index 00000000000..cfb923916bf --- /dev/null +++ b/backends/tofino/bf-asm/selection.cpp @@ -0,0 +1,453 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "algorithm.h" +#include "data_switchbox.h" +#include "input_xbar.h" +#include "misc.h" +#include "stage.h" +#include "tables.h" + +void SelectionTable::setup(VECTOR(pair_t) & data) { + setup_layout(layout, data); + VECTOR(pair_t) p4_info = EMPTY_VECTOR_INIT; + for (auto &kv : MapIterChecked(data, true)) { + if (kv.key == "input_xbar") { + if (CHECKTYPE(kv.value, tMAP)) + input_xbar.emplace_back(InputXbar::create(this, false, kv.key, kv.value.map)); + } else if (kv.key == "mode") { + mode_lineno = kv.value.lineno; + if (CHECKTYPEPM(kv.value, tCMD, kv.value.vec.size == 2 && kv.value[1].type == tINT, + "hash mode and int param")) { + if (kv.value[0] == "resilient") + resilient_hash = true; + else if (kv.value[0] == "fair") + resilient_hash = false; + else + error(kv.value.lineno, "Unknown hash mode %s", kv.value[0].s); + param = kv.value[1].i; + } + } else if (kv.key == "non_linear") { + non_linear_hash = get_bool(kv.value); + } else if (kv.key == "per_flow_enable") { + if (CHECKTYPE(kv.value, tSTR)) { + per_flow_enable = true; + per_flow_enable_param = kv.value.s; + } + } else if (kv.key == "pool_sizes") { + if (CHECKTYPE(kv.value, tVEC)) + for (value_t &v : kv.value.vec) + if (CHECKTYPE(v, tINT)) pool_sizes.push_back(v.i); + } else if (kv.key == "selection_hash") { + if (CHECKTYPE(kv.value, tINT)) selection_hash = kv.value.i; + } else if (kv.key == "hash_dist") { + HashDistribution::parse(hash_dist, kv.value); + if (hash_dist.size() > 1) + error(kv.key.lineno, "More than one hast_dist in a selection table not supported"); + } else if (kv.key == "maprams") { + setup_maprams(kv.value); + } else if (kv.key == "p4") { + if (CHECKTYPE(kv.value, tMAP)) + p4_table = P4Table::get(P4Table::Selection, kv.value.map); + } else if (kv.key == "p4_table") { + push_back(p4_info, "name", std::move(kv.value)); + } else if (kv.key == "p4_table_size") { + push_back(p4_info, "size", std::move(kv.value)); + } else if (kv.key == "handle") { + push_back(p4_info, "handle", std::move(kv.value)); + } else if (kv.key == "context_json") { + setup_context_json(kv.value); + } else if (kv.key == "row" || kv.key == "logical_row" || kv.key == "column" || + kv.key == "bus") { + /* already done in setup_layout */ + } else { + warning(kv.key.lineno, "ignoring unknown item %s in table %s", value_desc(kv.key), + name()); + } + } + if (p4_info.size) { + if (p4_table) + error(p4_info[0].key.lineno, "old and new p4 table info in %s", name()); + else + p4_table = P4Table::get(P4Table::Selection, p4_info); + } + fini(p4_info); + if (Target::SRAM_GLOBAL_ACCESS()) + alloc_global_srams(); + else + alloc_rams(true, stage->sram_use); +} + +void SelectionTable::pass1() { + LOG1("### Selection table " << name() << " pass1 " << loc()); + if (!p4_table) + p4_table = P4Table::alloc(P4Table::Selection, this); + else + p4_table->check(this); + alloc_vpns(); + alloc_maprams(); + std::sort(layout.begin(), layout.end(), + [](const Layout &a, const Layout &b) -> bool { return a.row > b.row; }); + for (auto &ixb : input_xbar) ixb->pass1(); + if (param < 0 || param > (resilient_hash ? 7 : 2)) + error(mode_lineno, "Invalid %s hash param %d", resilient_hash ? "resilient" : "fair", + param); + min_words = INT_MAX; + max_words = 0; + if (pool_sizes.empty()) { + min_words = max_words = 1; + } else { + for (int size : pool_sizes) { + int words = (size + SELECTOR_PORTS_PER_WORD - 1) / SELECTOR_PORTS_PER_WORD; + if (words < min_words) min_words = words; + if (words > max_words) max_words = words; + } + } + stage->table_use[timing_thread(gress)] |= Stage::USE_SELECTOR; + if (max_words > 1) { + stage->table_use[timing_thread(gress)] |= Stage::USE_WIDE_SELECTOR; + for (auto &hd : hash_dist) hd.xbar_use |= HashDistribution::HASHMOD_DIVIDEND; + } + for (auto &hd : hash_dist) hd.pass1(this, HashDistribution::SELECTOR, non_linear_hash); + bool home = true; // first layout row is home row + for (Layout &row : layout) { + if (home) + need_bus(row.lineno, stage->selector_adr_bus_use, row.row | 3, "Selector Address"); + need_bus(row.lineno, stage->selector_adr_bus_use, row.row, "Selector Address"); + if ((row.row & 2) == 0) // even phy rows wired together + need_bus(row.lineno, stage->selector_adr_bus_use, row.row ^ 1, "Selector Address"); + home = false; + } + AttachedTable::pass1(); +} + +void SelectionTable::pass2() { + LOG1("### Selection table " << name() << " pass2 " << loc()); + for (auto &ixb : input_xbar) { + ixb->pass2(); + if (selection_hash < 0 && (selection_hash = ixb->hash_group()) < 0) + error(lineno, "No selection_hash in selector table %s", name()); + } + if (input_xbar.empty()) { + error(lineno, "No input xbar in selector table %s", name()); + } + for (auto &hd : hash_dist) hd.pass2(this); +} + +void SelectionTable::pass3() { LOG1("### Selection table " << name() << " pass3 " << loc()); } + +int SelectionTable::indirect_shiftcount() const { + return METER_ADDRESS_ZERO_PAD - 7; // selectors always start at bit 7 address +} + +unsigned SelectionTable::per_flow_enable_bit(MatchTable *match) const { + if (!per_flow_enable) + return SELECTOR_PER_FLOW_ENABLE_START_BIT; + else + return AttachedTable::per_flow_enable_bit(match); +} + +unsigned SelectionTable::determine_shiftcount(Table::Call &call, int group, unsigned word, + int tcam_shift) const { + return determine_meter_shiftcount(call, group, word, tcam_shift); +} + +template +void SelectionTable::write_merge_regs_vt(REGS ®s, MatchTable *match, int type, int bus, + const std::vector &args) { + auto &merge = regs.rams.match.merge; + setup_physical_alu_map(regs, type, bus, meter_group()); + merge.mau_payload_shifter_enable[type][bus].meter_adr_payload_shifter_en = 1; + + unsigned adr_mask = 0U; + unsigned per_entry_en_mux_ctl = 0U; + unsigned adr_default = 0U; + unsigned meter_type_position = 0U; + AttachedTable::determine_meter_merge_regs(match, type, bus, args, METER_SELECTOR, adr_mask, + per_entry_en_mux_ctl, adr_default, + meter_type_position); + merge.mau_meter_adr_default[type][bus] = adr_default; + merge.mau_meter_adr_mask[type][bus] = adr_mask; + merge.mau_meter_adr_per_entry_en_mux_ctl[type][bus] = per_entry_en_mux_ctl; + merge.mau_meter_adr_type_position[type][bus] = meter_type_position; +} + +/** + * This validates the call as the value to the selection_length key. The call requires + * two arguments: + * + * 1. A selector length mod argument + * 2. A selector length shift argument + * + * This is formatted in the following way: + * (msb_side) {shift, mod} (lsb_side) + * + * These can come from match overhead, or can come from $DEFAULT + * + * In actuality, both of these arguments are extracted by the same extractor, and they must + * be contiguous to each other. The reason for the separation is that the driver requires + * them to be separated in the pack format. + */ +bool SelectionTable::validate_length_call(const Table::Call &call) { + if (call.args.size() != 2) { + error(call.lineno, "The selector length call for %s requires two arguments", name()); + return false; + } + + if (call.args[0].name()) { + if (call.args[0] != "$DEFAULT") { + error(call.lineno, "Index %s for %s length cannot be found", call.args[0].name(), + name()); + return false; + } + } else if (!call.args[0].field()) { + error(call.lineno, "Index for %s length cannot be understood", name()); + return false; + } + + if (call.args[1].name()) { + if (call.args[1] != "$DEFAULT") { + error(call.lineno, "Index %s for %s length cannot be found", call.args[0].name(), + name()); + return false; + } + } else if (!call.args[1].field()) { + error(call.lineno, "Index for %s length cannot be understood", name()); + return false; + } + + if (call.args[0].field() && call.args[1].field()) { + auto mod = call.args[0].field(); + auto shift = call.args[1].field(); + + if (mod->bit(0) + mod->size != shift->bit(0)) { + error(call.lineno, "Indexes for %s must be contiguous on the format", name()); + return false; + } + } + return true; +} + +unsigned SelectionTable::determine_length_shiftcount(const Table::Call &call, int group, + int word) const { + if (auto f = call.args[0].field()) { + BUG_CHECK(f->by_group[group]->bit(0) / 128 == word && group == 0); + BUG_CHECK(f->by_group[group]->bit(0) % 128 <= 8); + return f->by_group[group]->bit(0) % 128U; + } + return 0; +} + +unsigned SelectionTable::determine_length_mask(const Table::Call &call) const { + unsigned rv = 0; + if (auto f = call.args[0].field()) rv |= ((1U << f->size) - 1); + if (auto f = call.args[1].field()) rv |= ((1U << f->size) - 1) << SELECTOR_LENGTH_MOD_BITS; + return rv; +} + +unsigned SelectionTable::determine_length_default(const Table::Call &call) const { + unsigned rv = 0; + if (call.args[0].name() && strcmp(call.args[0].name(), "$DIRECT") == 0) rv = 1; + return rv; +} + +template <> +void SelectionTable::setup_physical_alu_map(Target::Tofino::mau_regs ®s, int type, int bus, + int alu) { + auto &merge = regs.rams.match.merge; + merge.mau_physical_to_meter_alu_ixbar_map[type][bus / 8U].set_subfield(4 | alu, 3 * (bus % 8U), + 3); +} +#if HAVE_JBAY +template <> +void SelectionTable::setup_physical_alu_map(Target::JBay::mau_regs ®s, int type, int bus, + int alu) { + auto &merge = regs.rams.match.merge; + merge.mau_physical_to_meter_alu_icxbar_map[type][bus / 8U] |= (1U << alu) << (4 * (bus % 8U)); +} +#endif /* HAVE_JBAY */ + +template +void SelectionTable::write_regs_vt(REGS ®s) { + LOG1("### Selection table " << name() << " write_regs " << loc()); + for (auto &ixb : input_xbar) ixb->write_regs(regs); + Layout *home = &layout[0]; + bool push_on_overflow = false; + auto &map_alu = regs.rams.map_alu; + DataSwitchboxSetup swbox(regs, this); + int minvpn, maxvpn; + layout_vpn_bounds(minvpn, maxvpn, true); + BUG_CHECK(input_xbar.size() == 1, "%s does not have one input xbar", name()); + for (Layout &logical_row : layout) { + unsigned row = logical_row.row / 2U; + unsigned side = logical_row.row & 1; /* 0 == left 1 == right */ + /* FIXME factor vpn/mapram stuff with counter.cpp */ + auto vpn = logical_row.vpns.begin(); + auto mapram = logical_row.maprams.begin(); + auto &map_alu_row = map_alu.row[row]; + LOG2("# DataSwitchbox.setup(" << row << ") home=" << home->row / 2U); + swbox.setup_row(row); + for (auto &memunit : logical_row.memunits) { + BUG_CHECK(memunit.stage == INT_MIN && memunit.row == logical_row.row, + "bogus %s in logical row %d", memunit.desc(), logical_row.row); + unsigned col = memunit.col + 6 * side; + swbox.setup_row_col(row, col, *vpn); + write_mapram_regs(regs, row, *mapram, *vpn, MapRam::SELECTOR_SIZE); + if (gress) regs.cfg_regs.mau_cfg_uram_thread[col / 4U] |= 1U << (col % 4U * 8U + row); + ++mapram, ++vpn; + } + if (&logical_row == home) { + auto &vh_adr_xbar = regs.rams.array.row[row].vh_adr_xbar; + setup_muxctl( + vh_adr_xbar.exactmatch_row_hashadr_xbar_ctl[SELECTOR_VHXBAR_HASH_BUS_INDEX], + selection_hash); + vh_adr_xbar.alu_hashdata_bytemask.alu_hashdata_bytemask_right = + bitmask2bytemask(input_xbar[0]->hash_group_bituse()); + map_alu_row.i2portctl.synth2port_vpn_ctl.synth2port_vpn_base = minvpn; + map_alu_row.i2portctl.synth2port_vpn_ctl.synth2port_vpn_limit = maxvpn; + } else { + auto &adr_ctl = map_alu_row.vh_xbars.adr_dist_oflo_adr_xbar_ctl[side]; + if (home->row >= 8 && logical_row.row < 8) { + adr_ctl.adr_dist_oflo_adr_xbar_source_index = 0; + adr_ctl.adr_dist_oflo_adr_xbar_source_sel = AdrDist::OVERFLOW; + push_on_overflow = true; + BUG_CHECK(options.target == TOFINO); + } else { + adr_ctl.adr_dist_oflo_adr_xbar_source_index = home->row % 8; + adr_ctl.adr_dist_oflo_adr_xbar_source_sel = AdrDist::METER; + } + adr_ctl.adr_dist_oflo_adr_xbar_enable = 1; + } + } + + unsigned meter_group = home->row / 4U; + auto &selector_ctl = map_alu.meter_group[meter_group].selector.selector_alu_ctl; + selector_ctl.sps_nonlinear_hash_enable = non_linear_hash ? 1 : 0; + if (resilient_hash) + selector_ctl.resilient_hash_enable = param; + else + selector_ctl.selector_fair_hash_select = param; + selector_ctl.resilient_hash_mode = resilient_hash ? 1 : 0; + selector_ctl.selector_enable = 1; + auto &delay_ctl = map_alu.meter_alu_group_data_delay_ctl[meter_group]; + delay_ctl.meter_alu_right_group_delay = + Target::METER_ALU_GROUP_DATA_DELAY() + meter_group / 2 + stage->tcam_delay(gress); + delay_ctl.meter_alu_right_group_enable = + meter_alu_fifo_enable_from_mask(regs, resilient_hash ? 0x7f : 0x3); + /* FIXME -- error_ctl should be configurable */ + auto &error_ctl = map_alu.meter_alu_group_error_ctl[meter_group]; + error_ctl.meter_alu_group_ecc_error_enable = 1; + error_ctl.meter_alu_group_sel_error_enable = 1; + error_ctl.meter_alu_group_thread = gress; + + auto &merge = regs.rams.match.merge; + auto &adrdist = regs.rams.match.adrdist; + for (MatchTable *m : match_tables) { + adrdist.adr_dist_meter_adr_icxbar_ctl[m->logical_id] |= 1 << meter_group; + // auto &icxbar = adrdist.adr_dist_meter_adr_icxbar_ctl[m->logical_id]; + // icxbar.address_distr_to_logical_rows = 1 << home->row; + // icxbar.address_distr_to_overflow = push_on_overflow; + if (auto &act = m->get_action()) { + /* FIXME -- can't be attached to mutliple tables ? */ + unsigned fmt = 3; + fmt = std::max(fmt, act->format->log2size); + if (auto at = dynamic_cast(&(*act))) + for (auto &f : at->get_action_formats()) fmt = std::max(fmt, f.second->log2size); + merge.mau_selector_action_entry_size[meter_group] = fmt - 3; + } // val in bytes + adrdist.mau_ad_meter_virt_lt[meter_group] |= 1U << m->logical_id; + adrdist.movereg_ad_meter_alu_to_logical_xbar_ctl[m->logical_id / 8U].set_subfield( + 4 | meter_group, 3 * (m->logical_id % 8U), 3); + setup_logical_alu_map(regs, m->logical_id, meter_group); + } + if (max_words == 1) adrdist.movereg_meter_ctl[meter_group].movereg_ad_meter_shift = 7; + if (push_on_overflow) { + adrdist.oflo_adr_user[0] = adrdist.oflo_adr_user[1] = AdrDist::METER; + adrdist.deferred_oflo_ctl = 1 << ((home->row - 8) / 2U); + } + adrdist.packet_action_at_headertime[1][meter_group] = 1; + for (auto &hd : hash_dist) hd.write_regs(regs, this); + if (gress == INGRESS || gress == GHOST) { + merge.meter_alu_thread[0].meter_alu_thread_ingress |= 1U << meter_group; + merge.meter_alu_thread[1].meter_alu_thread_ingress |= 1U << meter_group; + } else if (gress == EGRESS) { + merge.meter_alu_thread[0].meter_alu_thread_egress |= 1U << meter_group; + merge.meter_alu_thread[1].meter_alu_thread_egress |= 1U << meter_group; + } + if (gress == EGRESS) { + regs.rams.map_alu.meter_group[meter_group].meter.meter_ctl.meter_alu_egress = 1; + } +} + +template <> +void SelectionTable::setup_logical_alu_map(Target::Tofino::mau_regs ®s, int logical_id, + int alu) { + auto &merge = regs.rams.match.merge; + if (max_words > 1) merge.mau_logical_to_meter_alu_map.set_subfield(16 | logical_id, 5 * alu, 5); + merge.mau_meter_alu_to_logical_map[logical_id / 8U].set_subfield(4 | alu, 3 * (logical_id % 8U), + 3); +} +#if HAVE_JBAY +template <> +void SelectionTable::setup_logical_alu_map(Target::JBay::mau_regs ®s, int logical_id, int alu) { + auto &merge = regs.rams.match.merge; + merge.mau_logical_to_meter_alu_map[logical_id / 8U] |= (1U << alu) << ((logical_id % 8U) * 4); + merge.mau_meter_alu_to_logical_map[logical_id / 8U].set_subfield(4 | alu, 3 * (logical_id % 8U), + 3); +} +#endif /* HAVE_JBAY */ + +std::vector SelectionTable::determine_spare_bank_memory_units() const { + if (bound_stateful) return bound_stateful->determine_spare_bank_memory_units(); + return {}; +} + +void SelectionTable::gen_tbl_cfg(json::vector &out) const { + // Stage table size reflects how many RAM lines are available for the selector, according + // to henry wang. + int size = (layout_size() - 1) * 1024; + json::map &tbl = *base_tbl_cfg(out, "selection", size); + tbl["selection_type"] = resilient_hash ? "resilient" : "fair"; + tbl["selector_name"] = p4_table ? p4_table->p4_name() : "undefined"; + tbl["selection_key_name"] = "undefined"; // FIXME! + std::string hr = how_referenced(); + if (hr.empty()) hr = indirect ? "indirect" : "direct"; + tbl["how_referenced"] = hr; + if (pool_sizes.size() > 0) + tbl["max_port_pool_size"] = *std::max_element(std::begin(pool_sizes), std::end(pool_sizes)); + for (MatchTable *m : match_tables) { + if (auto &act = m->get_action()) { + if (auto at = dynamic_cast(&(*act))) { + tbl["bound_to_action_data_table_handle"] = act->handle(); + break; + } + } + } + json::map &stage_tbl = *add_stage_tbl_cfg(tbl, "selection", size); + add_pack_format(stage_tbl, 128, 1, 1); + stage_tbl["memory_resource_allocation"] = + gen_memory_resource_allocation_tbl_cfg("sram", layout, bound_stateful != nullptr); + add_alu_index(stage_tbl, "meter_alu_index"); + stage_tbl["sps_scramble_enable"] = non_linear_hash; + if (context_json) stage_tbl.merge(*context_json); +} + +DEFINE_TABLE_TYPE(SelectionTable) +FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void SelectionTable::write_merge_regs, + (mau_regs & regs, MatchTable *match, int type, int bus, + const std::vector &args), + { write_merge_regs_vt(regs, match, type, bus, args); }) diff --git a/backends/tofino/bf-asm/slist.h b/backends/tofino/bf-asm/slist.h new file mode 100644 index 00000000000..ca3948f1220 --- /dev/null +++ b/backends/tofino/bf-asm/slist.h @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_SLIST_H_ +#define BF_ASM_SLIST_H_ + +template +class slist { + const slist *next; + T value; + + public: + explicit slist(T v) : next(nullptr), value(v) {} + slist(T v, const slist *n) : next(n), value(v) {} + typedef T value_type; + class iterator : public std::iterator { + friend class slist; + const slist *ptr; + iterator() : ptr(nullptr) {} + explicit iterator(const slist *p) : ptr(p) {} + + public: + iterator &operator++() { + ptr = ptr->next; + return *this; + } + bool operator==(const iterator &a) const { return ptr == a.ptr; } + bool operator!=(const iterator &a) const { return ptr != a.ptr; } + const T &operator*() const { return ptr->value; } + const T *operator->() const { return &ptr->value; } + }; + typedef iterator const_iterator; + + iterator begin() const { return iterator(this); } + iterator end() const { return iterator(); } +}; + +#endif /* BF_ASM_SLIST_H_ */ diff --git a/backends/tofino/bf-asm/sram_match.cpp b/backends/tofino/bf-asm/sram_match.cpp new file mode 100644 index 00000000000..34be42ca43f --- /dev/null +++ b/backends/tofino/bf-asm/sram_match.cpp @@ -0,0 +1,1504 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "action_bus.h" +#include "algorithm.h" +#include "hex.h" +#include "input_xbar.h" +#include "instruction.h" +#include "mask_counter.h" +#include "misc.h" +#include "stage.h" +#include "tables.h" + +Table::Format::Field *SRamMatchTable::lookup_field(const std::string &n, + const std::string &act) const { + auto *rv = format ? format->field(n) : nullptr; + if (!rv && gateway) rv = gateway->lookup_field(n, act); + if (!rv && !act.empty()) { + if (auto call = get_action()) rv = call->lookup_field(n, act); + } + if (!rv && n == "immediate" && !::Phv::get(gress, stage->stageno, n)) { + static Format::Field default_immediate(nullptr, 32, Format::Field::USED_IMMED); + rv = &default_immediate; + } + return rv; +} + +const char *SRamMatchTable::Ram::desc() const { + static char buffer[256], *p = buffer; + char *end = buffer + sizeof(buffer), *rv; + do { + if (end - p < 7) p = buffer; + rv = p; + if (stage >= 0) + p += snprintf(p, end - p, "Ram %d,%d,%d", stage, row, col); + else if (row >= 0) + p += snprintf(p, end - p, "Ram %d,%d", row, col); + else + p += snprintf(p, end - p, "Lamb %d", col); + } while (p++ >= end); + return rv; +} + +/* calculate the 18-bit byte/nybble mask tofino uses for matching in a 128-bit word */ +static unsigned tofino_bytemask(int lo, int hi) { + unsigned rv = 0; + for (unsigned i = lo / 4U; i <= hi / 4U; i++) rv |= 1U << (i < 28 ? i / 2 : i - 14); + return rv; +} + +/** + * Determining the result bus for an entry, if that entry has no overhead. The result bus + * is still needed to get the direct address location to find action data / run an + * instruction, etc. + * + * This section maps the allocation scheme used in the TableFormat::Use in p4c, found + * in the function result_bus_words + */ +void SRamMatchTable::no_overhead_determine_result_bus_usage() { + bitvec result_bus_words; + + for (int i = 0; i < static_cast(group_info.size()); i++) { + BUG_CHECK(group_info[i].overhead_word < 0); + if (group_info[i].match_group.size() == 1) { + group_info[i].result_bus_word = group_info[i].match_group.begin()->first; + result_bus_words.setbit(group_info[i].result_bus_word); + } + } + + for (int i = 0; i < static_cast(group_info.size()); i++) { + if (group_info[i].overhead_word < 0 && group_info[i].match_group.size() > 1) { + bool result_bus_set = false; + for (auto match_group : group_info[i].match_group) { + if (result_bus_words.getbit(match_group.first)) { + group_info[i].result_bus_word = match_group.first; + result_bus_set = true; + } + } + if (!result_bus_set) + group_info[i].result_bus_word = group_info[i].match_group.begin()->first; + LOG1(" format group " << i << " no overhead multiple match groups"); + } + } +} + +void SRamMatchTable::verify_format(Target::Tofino) { + if (format->log2size < 7) format->log2size = 7; + format->pass1(this); + group_info.resize(format->groups()); + unsigned fmt_width = (format->size + 127) / 128; + if (word_info.size() > fmt_width) { + warning(format->lineno, "Match group map wider than format, padding out format"); + format->size = word_info.size() * 128; + fmt_width = word_info.size(); + while ((1U << format->log2size) < format->size) ++format->log2size; + } + for (unsigned i = 0; i < format->groups(); i++) { + auto &info = group_info[i]; + info.tofino_mask.resize(fmt_width); + if (Format::Field *match = format->field("match", i)) { + for (auto &piece : match->bits) { + unsigned word = piece.lo / 128; + if (word != piece.hi / 128) + error(format->lineno, + "'match' field must be explictly split across " + "128-bit boundary in table %s", + name()); + info.tofino_mask[word] |= tofino_bytemask(piece.lo % 128, piece.hi % 128); + info.match_group[word] = -1; + } + } + if (auto *version = format->field("version", i)) { + if (version->bits.size() != 1) error(format->lineno, "'version' field cannot be split"); + auto &piece = version->bits[0]; + unsigned word = piece.lo / 128; + if (version->size != 4 || (piece.lo % 4) != 0) + error(format->lineno, + "'version' field not 4 bits and nibble aligned " + "in table %s", + name()); + info.tofino_mask[word] |= tofino_bytemask(piece.lo % 128, piece.hi % 128); + info.match_group[word] = -1; + } + for (unsigned j = 0; j < i; j++) + for (unsigned word = 0; word < fmt_width; word++) + if (group_info[j].tofino_mask[word] & info.tofino_mask[word]) { + int bit = ffs(group_info[j].tofino_mask[word] & info.tofino_mask[word]) - 1; + if (bit >= 14) bit += 14; + error(format->lineno, "Match groups %d and %d both use %s %d in word %d", i, j, + bit > 20 ? "nibble" : "byte", bit, word); + break; + } + for (auto it = format->begin(i); it != format->end(i); it++) { + Format::Field &f = it->second; + if (it->first == "match" || it->first == "version" || it->first == "proxy_hash") + continue; + if (f.bits.size() != 1) { + error(format->lineno, "Can't deal with split field %s", it->first.c_str()); + continue; + } + unsigned limit = Target::MAX_OVERHEAD_OFFSET(); + if (it->first == "next") limit = Target::MAX_OVERHEAD_OFFSET_NEXT(); + unsigned word = f.bit(0) / 128; + if (info.overhead_word < 0) { + info.overhead_word = word; + format->overhead_word = word; + LOG5("Setting overhead word for format : " << word); + info.overhead_bit = f.bit(0) % 128; + info.match_group[word] = -1; + } else if (info.overhead_word != static_cast(word)) { + error(format->lineno, "Match overhead group %d split across words", i); + } else if (word != f.bit(f.size - 1) / 128 || f.bit(f.size - 1) % 128 >= limit) { + error(format->lineno, "Match overhead field %s(%d) not in bottom %d bits", + it->first.c_str(), i, limit); + } + if (!info.match_group.count(word)) + error(format->lineno, "Match overhead in group %d in word with no match?", i); + if ((unsigned)info.overhead_bit > f.bit(0) % 128) info.overhead_bit = f.bit(0) % 128; + } + info.vpn_offset = i; + } + if (word_info.empty()) { + word_info.resize(fmt_width); + if (format->field("next")) { + /* 'next' for match group 0 must be in bit 0, so make the format group with + * overhead in bit 0 match group 0 in its overhead word */ + for (unsigned i = 0; i < group_info.size(); i++) { + if (group_info[i].overhead_bit == 0) { + BUG_CHECK(error_count > 0 || word_info[group_info[i].overhead_word].empty()); + group_info[i].match_group[group_info[i].overhead_word] = 0; + word_info[group_info[i].overhead_word].push_back(i); + } + } + } + for (unsigned i = 0; i < group_info.size(); i++) { + if (group_info[i].match_group.size() > 1) { + for (auto &mgrp : group_info[i].match_group) { + if (mgrp.second >= 0) continue; + if ((mgrp.second = word_info[mgrp.first].size()) > 1) + error(format->lineno, "Too many multi-word groups using word %d", + mgrp.first); + word_info[mgrp.first].push_back(i); + } + } + } + } else { + if (word_info.size() != fmt_width) + error(mgm_lineno, "Match group map doesn't match format size"); + for (unsigned i = 0; i < word_info.size(); i++) { + for (unsigned j = 0; j < word_info[i].size(); j++) { + int grp = word_info[i][j]; + if (grp < 0 || (unsigned)grp >= format->groups()) { + error(mgm_lineno, "Invalid group number %d", grp); + } else if (!group_info[grp].match_group.count(i)) { + error(mgm_lineno, "Format group %d doesn't match in word %d", grp, i); + } else { + group_info[grp].match_group[i] = j; + auto *next = format->field("next", grp); + if (!next && hit_next.size() > 1) next = format->field("action", grp); + if (next) { + if (next->bit(0) / 128 != i) continue; + static unsigned limit[5] = {0, 8, 32, 32, 32}; + unsigned bit = next->bit(0) % 128U; + if (!j && bit) + error(mgm_lineno, + "Next(%d) field must start at bit %d to be in " + "match group 0", + grp, i * 128); + else if (j && (!bit || bit > limit[j])) + warning(mgm_lineno, + "Next(%d) field must start in range %d..%d " + "to be in match group %d", + grp, i * 128 + 1, i * 128 + limit[j], j); + } + } + } + } + } + if (hit_next.size() > 1 && !format->field("next") && !format->field("action")) + error(format->lineno, "No 'next' field in format"); + if (error_count > 0) return; + + for (int i = 0; i < static_cast(group_info.size()); i++) { + if (group_info[i].match_group.size() == 1) { + for (auto &mgrp : group_info[i].match_group) { + if (mgrp.second >= 0) continue; + if ((mgrp.second = word_info[mgrp.first].size()) > 4) + error(format->lineno, "Too many match groups using word %d", mgrp.first); + word_info[mgrp.first].push_back(i); + } + } + // Determining the result bus word, where the overhead is supposed to be + } + + bool has_overhead_word = false; + bool overhead_word_set = false; + for (int i = 0; i < static_cast(group_info.size()); i++) { + if (overhead_word_set) BUG_CHECK((group_info[i].overhead_word >= 0) == has_overhead_word); + if (group_info[i].overhead_word >= 0) { + has_overhead_word = true; + group_info[i].result_bus_word = group_info[i].overhead_word; + } + overhead_word_set = true; + } + + if (!has_overhead_word) no_overhead_determine_result_bus_usage(); + + /** + * Determining the result bus for an entry, if that entry has no overhead. The result bus + * is still needed to get the direct address location to find action data / run an + * instruction, etc. + * + * This section maps the allocation scheme used in the TableFormat::Use in p4c, found + * in the function result_bus_words + */ + + for (int i = 0; i < static_cast(group_info.size()); i++) { + LOG1(" masks: " << hexvec(group_info[i].tofino_mask)); + for (auto &mgrp : group_info[i].match_group) + LOG1(" match group " << mgrp.second << " in word " << mgrp.first); + } + + for (unsigned i = 0; i < word_info.size(); i++) + LOG1(" word " << i << " groups: " << word_info[i]); + if (options.match_compiler && 0) { + /* hack to match the compiler's nibble usage -- if any of the top 4 nibbles is + * unused in a word, mark it as used by any group that uses the other nibble of the + * byte, UNLESS it is used for the version. This is ok, as the unused nibble will + * end up being masked off by the match_mask anyways */ + for (unsigned word = 0; word < word_info.size(); word++) { + unsigned used_nibbles = 0; + for (auto group : word_info[word]) + used_nibbles |= group_info[group].tofino_mask[word] >> 14; + for (unsigned nibble = 0; nibble < 4; nibble++) { + if (!((used_nibbles >> nibble) & 1) && ((used_nibbles >> (nibble ^ 1)) & 1)) { + LOG1(" ** fixup nibble " << nibble << " in word " << word); + for (auto group : word_info[word]) + if ((group_info[group].tofino_mask[word] >> (14 + (nibble ^ 1))) & 1) { + if (auto *version = format->field("version", group)) { + if (version->bit(0) == word * 128 + (nibble ^ 1) * 4 + 112) { + LOG1(" skip group " << group << " (version)"); + continue; + } + } + group_info[group].tofino_mask[word] |= 1 << (14 + nibble); + LOG1(" adding to group " << group); + } + } + } + } + } + + verify_match(fmt_width); +} + +void SRamMatchTable::verify_format_pass2(Target::Tofino) {} + +/** + * Guarantees that each match field is a PHV field, which is the standard unless the table is + * a proxy hash table. + */ +bool SRamMatchTable::verify_match_key() { + for (auto *match_key : match) { + auto phv_p = dynamic_cast(match_key); + if (phv_p == nullptr) { + error(match_key->get_lineno(), "A non PHV match key in table %s", name()); + continue; + } + auto phv_ref = *phv_p; + if (phv_ref.check() && phv_ref->reg.mau_id() < 0) + error(phv_ref.lineno, "%s not accessable in mau", phv_ref->reg.name); + } + auto match_format = format->field("match"); + if (match_format && match.empty()) { + BUG_CHECK(input_xbar.size() == 1, "%s does not have one input xbar", name()); + for (auto ixbar_element : *input_xbar[0]) { + match.emplace_back(new Phv::Ref(ixbar_element.second.what)); + } + } + return error_count == 0; +} + +std::unique_ptr SRamMatchTable::gen_memory_resource_allocation_tbl_cfg( + const Way &way) const { + json::map mra; + unsigned vpn_ctr = 0; + unsigned fmt_width = format ? (format->size + 127) / 128 : 0; + unsigned ramdepth = way.isLamb() ? LAMB_DEPTH_BITS : SRAM_DEPTH_BITS; + if (hash_fn_ids.count(way.group_xme) > 0) + mra["hash_function_id"] = hash_fn_ids.at(way.group_xme); + mra["hash_entry_bit_lo"] = way.index; + mra["hash_entry_bit_hi"] = way.index + ramdepth + way.subword_bits - 1; + mra["number_entry_bits"] = ramdepth; + mra["number_subword_bits"] = way.subword_bits; + if (way.select) { + int lo = way.select.min().index(), hi = way.select.max().index(); + mra["hash_select_bit_lo"] = lo; + mra["hash_select_bit_hi"] = hi; + if (way.select.popcount() != hi - lo + 1) { + warning(way.lineno, "driver does not support discontinuous bits in a way mask"); + mra["hash_select_bit_mask"] = way.select.getrange(lo, 32); + } + } else { + mra["hash_select_bit_lo"] = mra["hash_select_bit_hi"] = 40; + } + mra["number_select_bits"] = way.select.popcount(); + mra["memory_type"] = way.isLamb() ? "lamb" : "sram"; + json::vector mem_units; + json::vector &mem_units_and_vpns = mra["memory_units_and_vpns"] = json::vector(); + int way_uses_lambs = -1; // don't know yet + for (auto &ram : way.rams) { + if (ram.isLamb()) { + BUG_CHECK(way_uses_lambs != 0, "mixed lambs and memories in a way"); + way_uses_lambs = 1; + } else { + BUG_CHECK(way_uses_lambs != 1, "mixed lambs and memories in a way"); + way_uses_lambs = 0; + if (mem_units.empty()) + vpn_ctr = layout_get_vpn(ram); + else + BUG_CHECK(vpn_ctr == layout_get_vpn(ram)); + } + mem_units.push_back(json_memunit(ram)); + if (mem_units.size() == fmt_width) { + json::map tmp; + tmp["memory_units"] = std::move(mem_units); + mem_units = json::vector(); + json::vector vpns; + for (auto &grp : group_info) vpns.push_back(vpn_ctr + grp.vpn_offset); + vpn_ctr += group_info.size(); + if (group_info.empty()) // FIXME -- can this happen? + vpns.push_back(vpn_ctr++); + tmp["vpns"] = std::move(vpns); + mem_units_and_vpns.push_back(std::move(tmp)); + } + } + BUG_CHECK(mem_units.empty()); + return json::mkuniq(std::move(mra)); +} + +/** + * The purpose of this function is to generate the hash_functions JSON node. The hash functions + * are for the driver to determine what RAM/RAM line to write the match data into during entry + * adds. + * + * The JSON nodes for the hash functions are the following: + * - hash_bits - A vector determining what each bit is calculated from. Look at the comments + * over the function gen_hash_bits + * The following two fields are required for High Availability mode and Entry Reads from HW + * - ghost_bit_to_hash_bit - A vector describing where the ghost bits are in the hash matrix + * - ghost_bit_info - A vector indicating which p4 fields are used as the ghost bits + * The following field is only necessary for dynamic_key_masks + * - hash_function_number - which of the 8 hash functions this table is using. + * + * The order of the hash functions must coordinate to the order of the hash_function_ids used + * in the Way JSON, as this is how a single way knows which hash function to use for its lookup + */ +void SRamMatchTable::add_hash_functions(json::map &stage_tbl) const { + BUG_CHECK(input_xbar.size() == 1, "%s does not have one input xbar", name()); + auto &ht = input_xbar[0]->get_hash_tables(); + if (ht.size() == 0) return; + // Output cjson node only if hash tables present + std::map hash_bits_per_group; + for (auto &way : ways) { + int depth = way.isLamb() ? LAMB_DEPTH_BITS : SRAM_DEPTH_BITS; + if (format->field("match")) { + // cuckoo or BPH + } else { + depth += ceil_log2(format->groups()); + if (format->size < 128) depth += 7 - ceil_log2(format->size); + } + bitvec way_impact; + way_impact.setrange(way.index, depth); + way_impact |= way.select; + hash_bits_per_group[way.group_xme] |= way_impact; + } + + // Order so that the order is the same of the hash_function_ids in the ways + // FIXME -- this seems pointless, as iterating over a std::map will always be + // in order. So this loop could go away and the later loop be over hash_bits_per_group + std::vector> hash_function_to_hash_bits(hash_fn_ids.size()); + for (auto entry : hash_bits_per_group) { + int hash_fn_id = hash_fn_ids.at(entry.first); + if (hash_fn_id >= hash_fn_ids.size()) BUG(); + hash_function_to_hash_bits[hash_fn_id] = entry; + } + + json::vector &hash_functions = stage_tbl["hash_functions"] = json::vector(); + for (auto entry : hash_function_to_hash_bits) { + int hash_group_no = entry.first; + + json::map hash_function; + json::vector &hash_bits = hash_function["hash_bits"] = json::vector(); + hash_function["hash_function_number"] = hash_group_no; + json::vector &ghost_bits_to_hash_bits = hash_function["ghost_bit_to_hash_bit"] = + json::vector(); + json::vector &ghost_bits_info = hash_function["ghost_bit_info"] = json::vector(); + // Get the hash group data + if (auto *hash_group = input_xbar[0]->get_hash_group(hash_group_no)) { + // Process only hash tables used per hash group + for (unsigned id : bitvec(hash_group->tables)) { + auto hash_table = input_xbar[0]->get_hash_table(id); + gen_hash_bits(hash_table, InputXbar::HashTable(InputXbar::HashTable::EXACT, id), + hash_bits, hash_group_no, entry.second); + } + } else { + for (auto &ht : input_xbar[0]->get_hash_tables()) + gen_hash_bits(ht.second, ht.first, hash_bits, hash_group_no, entry.second); + } + gen_ghost_bits(hash_group_no, ghost_bits_to_hash_bits, ghost_bits_info); + hash_functions.push_back(std::move(hash_function)); + } +} + +void SRamMatchTable::verify_match(unsigned fmt_width) { + if (!verify_match_key()) return; + // Build the match_by_bit + unsigned bit = 0; + for (auto &r : match) { + match_by_bit.emplace(bit, r); + bit += r->size(); + } + auto match_format = format->field("match"); + if ((unsigned)bit != (match_format ? match_format->size : 0)) + warning(match[0]->get_lineno(), + "Match width %d for table %s doesn't match format match " + "width %d", + bit, name(), match_format ? match_format->size : 0); + match_in_word.resize(fmt_width); + for (unsigned i = 0; i < format->groups(); i++) { + Format::Field *match = format->field("match", i); + if (!match) continue; + unsigned bit = 0; + for (auto &piece : match->bits) { + auto mw = --match_by_bit.upper_bound(bit); + int lo = bit - mw->first; + while (mw != match_by_bit.end() && mw->first < bit + piece.size()) { + if ((piece.lo + mw->first - bit) % 8U != (mw->second->slicelobit() % 8U)) + error(mw->second->get_lineno(), + "bit within byte misalignment matching %s in " + "match group %d of table %s", + mw->second->name(), i, name()); + int hi = + std::min((unsigned)mw->second->size() - 1, bit + piece.size() - mw->first - 1); + BUG_CHECK((unsigned)piece.lo / 128 < fmt_width); + // merge_phv_vec(match_in_word[piece.lo/128], Phv::Ref(mw->second, lo, hi)); + + if (auto phv_p = dynamic_cast(mw->second)) { + auto phv_ref = *phv_p; + auto vec = split_phv_bytes(Phv::Ref(phv_ref, lo, hi)); + for (auto ref : vec) { + match_in_word[piece.lo / 128].emplace_back(new Phv::Ref(ref)); + } + + } else if (auto hash_p = dynamic_cast(mw->second)) { + match_in_word[piece.lo / 128].push_back(new HashMatchSource(*hash_p)); + } else { + BUG(); + } + lo = 0; + ++mw; + } + bit += piece.size(); + } + } + for (unsigned i = 0; i < fmt_width; i++) { + std::string match_word_info = "[ "; + std::string sep = ""; + for (auto entry : match_in_word[i]) { + match_word_info += sep + entry->toString(); + sep = ", "; + } + LOG1(" match in word " << i << ": " << match_word_info); + } +} + +bool SRamMatchTable::parse_ram(const value_t &v, std::vector &res) { + if (!CHECKTYPE(v, tVEC)) return true; // supress added message + for (auto &el : v.vec) // all elements must be positive integers + if (el.type != tINT || el.i < 0) return false; + switch (v.vec.size) { + case 1: // lamb unit + if (v[0].i < Target::SRAM_LAMBS_PER_STAGE()) { + res.emplace_back(v[0].i); + return true; + } + break; + case 2: // row, col + if (Target::SRAM_GLOBAL_ACCESS()) break; // stage required + if (v[0].i < Target::SRAM_ROWS(gress) && v[1].i < Target::SRAM_UNITS_PER_ROW()) { + res.emplace_back(v[0].i, v[1].i); + return true; + } + break; + case 3: // stage, row, col + if (Target::SRAM_GLOBAL_ACCESS() && v[0].i < Target::NUM_STAGES(gress) && + v[1].i < Target::SRAM_ROWS(gress) && v[2].i < Target::SRAM_UNITS_PER_ROW()) { + res.emplace_back(v[0].i, v[1].i, v[2].i); + return true; + } + break; + default: + break; + } + return false; +} + +bool SRamMatchTable::parse_way(const value_t &v) { + Way way = {}; + way.lineno = v.lineno; + if (!CHECKTYPE2(v, tVEC, tMAP)) return true; // supress added message + if (v.type == tVEC) { + // DEPRECATED -- old style "raw" way for tofino1/2 + if (v.vec.size < 3 || v[0].type != tINT || v[1].type != tINT || v[2].type != tINT || + v[0].i < 0 || v[1].i < 0 || v[2].i < 0 || v[0].i >= Target::EXACT_HASH_GROUPS() || + v[1].i >= EXACT_HASH_ADR_GROUPS || v[2].i >= (1 << EXACT_HASH_SELECT_BITS)) { + return false; + } + way.group_xme = v[0].i; + way.index = v[1].i * EXACT_HASH_ADR_BITS; + way.select = bitvec(v[2].i) << EXACT_HASH_FIRST_SELECT_BIT; + for (int i = 3; i < v.vec.size; i++) { + if (!CHECKTYPE(v[i], tVEC)) return true; // supress added message + if (!parse_ram(v[i], way.rams)) error(v[i].lineno, "invalid ram in way"); + } + } else { + int index_size = 0; + for (auto &kv : MapIterChecked(v.map)) { + if ((kv.key == "group" || kv.key == "xme") && CHECKTYPE(kv.value, tINT)) { + if ((way.group_xme = kv.value.i) >= Target::IXBAR_HASH_GROUPS()) + error(kv.value.lineno, "%s %ld out of range", kv.key.s, kv.value.i); + } else if (kv.key == "index") { + if (!CHECKTYPE2(kv.value, tINT, tRANGE)) continue; + if (kv.value.type == tINT) { + way.index = kv.value.i; + } else { + way.index = kv.value.lo; + way.index_hi = kv.value.hi; + index_size = kv.value.hi - kv.value.lo + 1; + } + if (way.index > Target::IXBAR_HASH_INDEX_MAX() || + way.index % Target::IXBAR_HASH_INDEX_STRIDE() != 0) + error(kv.value.lineno, "invalid way index %d", way.index); + } else if (kv.key == "select") { + if (kv.value.type == tCMD && kv.value == "&") { + if (CHECKTYPE2(kv.value[1], tINT, tRANGE) && CHECKTYPE(kv.value[2], tINT)) { + way.select = bitvec(kv.value[2].i); + if (kv.value[1].type == tINT) { + way.select <<= kv.value[1].i; + } else { + way.select <<= kv.value[1].lo; + if (kv.value[1].hi < way.select.max().index()) + error(kv.value.lineno, "invalid select mask for range"); + } + } + } else if (kv.value.type == tRANGE) { + way.select.setrange(kv.value.lo, kv.value.hi - kv.value.lo + 1); + } else { + error(kv.value.lineno, "invalid select %s", value_desc(&kv.value)); + } + } else if (kv.key == "rams" && CHECKTYPE(kv.value, tVEC)) { + for (auto &ram : kv.value.vec) { + if (!CHECKTYPE(ram, tVEC)) break; + if (!parse_ram(ram, way.rams)) error(ram.lineno, "invalid ram in way"); + } + } + } + if (index_size) { + // FIXME -- currently this code is assuming the index bits cover just the ram index + // bits and the subword bits, and not any select bits. Perhaps that is wrong an it + // should include the select bits. + if (way.rams.empty()) { + error(v.lineno, "no rams in way"); + } else { + way.subword_bits = index_size - (way.isLamb() ? LAMB_DEPTH_BITS : SRAM_DEPTH_BITS); + if (way.subword_bits < 0) error(v.lineno, "index range too small for way rams"); + } + } + } + ways.push_back(way); + return true; +} + +void SRamMatchTable::common_sram_setup(pair_t &kv, const VECTOR(pair_t) & data) { + if (kv.key == "ways") { + if (!CHECKTYPE(kv.value, tVEC)) return; + for (auto &w : kv.value.vec) + if (!parse_way(w)) error(w.lineno, "invalid way descriptor"); + } else if (kv.key == "match") { + if (kv.value.type == tVEC) { + for (auto &v : kv.value.vec) { + if (v == "hash_group") + match.emplace_back(new HashMatchSource(v)); + else + match.emplace_back(new Phv::Ref(gress, stage->stageno, v)); + } + } else { + if (kv.value == "hash_group") + match.emplace_back(new HashMatchSource(kv.value)); + else + match.emplace_back(new Phv::Ref(gress, stage->stageno, kv.value)); + } + } else if (kv.key == "match_group_map") { + mgm_lineno = kv.value.lineno; + if (CHECKTYPE(kv.value, tVEC)) { + word_info.resize(kv.value.vec.size); + for (int i = 0; i < kv.value.vec.size; i++) + if (CHECKTYPE(kv.value[i], tVEC)) { + if (kv.value[i].vec.size > 5) + error(kv.value[i].lineno, "Too many groups for word %d", i); + for (auto &v : kv.value[i].vec) + if (CHECKTYPE(v, tINT)) word_info[i].push_back(v.i); + } + } + } else { + warning(kv.key.lineno, "ignoring unknown item %s in table %s", value_desc(kv.key), name()); + } +} + +void SRamMatchTable::common_sram_checks() { + if (Target::SRAM_GLOBAL_ACCESS()) + alloc_global_srams(); + else + alloc_rams(false, stage->sram_use, &stage->sram_search_bus_use); + if (layout_size() > 0 && !format) error(lineno, "No format specified in table %s", name()); + if (!action.set() && !actions) + error(lineno, "Table %s has neither action table nor immediate actions", name()); + if (actions && !action_bus) action_bus = ActionBus::create(); + if (input_xbar.empty()) input_xbar.emplace_back(InputXbar::create(this)); +} + +void SRamMatchTable::alloc_global_busses() { BUG(); } + +void SRamMatchTable::pass1() { + LOG1("### SRam match table " << name() << " pass1 " << loc()); + if (format) { + verify_format(); + setup_ways(); + determine_word_and_result_bus(); + } + if (Target::SRAM_GLOBAL_ACCESS()) + alloc_global_busses(); + else + alloc_busses(stage->sram_search_bus_use, Layout::SEARCH_BUS); + MatchTable::pass1(); + if (action_enable >= 0) + if (action.args.size() < 1 || action.args[0].size() <= (unsigned)action_enable) + error(lineno, "Action enable bit %d out of range for action selector", action_enable); + if (gateway) { + if (!gateway->layout.empty()) { + for (auto &row : layout) { + if (row.row == gateway->layout[0].row && row.bus == gateway->layout[0].bus && + !row.memunits.empty()) { + unsigned gw_use = gateway->input_use() & 0xff; + auto &way = way_map.at(row.memunits[0]); + for (auto &grp : group_info) { + if (gw_use & grp.tofino_mask[way.word]) { + error(gateway->lineno, + "match bus conflict between match and gateway" + " on table %s", + name()); + break; + } + } + break; + } + } + } + } +} + +void SRamMatchTable::setup_hash_function_ids() { + unsigned hash_fn_id = 0; + for (auto &w : ways) { + if (hash_fn_ids.count(w.group_xme) == 0) hash_fn_ids[w.group_xme] = hash_fn_id++; + } +} + +void SRamMatchTable::setup_ways() { + unsigned fmt_width = (format->size + 127) / 128; + if (ways.empty()) { + error(lineno, "No ways defined in table %s", name()); + } else if (ways[0].rams.empty()) { + for (auto &w : ways) + if (!w.rams.empty()) { + error(w.lineno, "Must specify rams for all ways in tabls %s, or none", name()); + return; + } + if (layout.size() % fmt_width != 0) { + error(lineno, "Rows is not a multiple of width in table %s", name()); + return; + } + for (unsigned i = 0; i < layout.size(); ++i) { + unsigned first = (i / fmt_width) * fmt_width; + if (layout[i].memunits.size() != layout[first].memunits.size()) + error(layout[i].lineno, "Row size mismatch within wide table %s", name()); + } + if (error_count > 0) return; + unsigned ridx = 0, cidx = 0; + for (auto &way : ways) { + if (ridx >= layout.size()) { + error(way.lineno, "Not enough rams for ways in table %s", name()); + break; + } + unsigned size = 1U << way.select.popcount(); + for (unsigned i = 0; i < size; i++) { + for (unsigned word = 0; word < fmt_width; ++word) { + BUG_CHECK(ridx + word < layout.size()); + auto &row = layout[ridx + word]; + BUG_CHECK(cidx < row.memunits.size()); + way.rams.push_back(row.memunits[cidx]); + } + if (++cidx == layout[ridx].memunits.size()) { + ridx += fmt_width; + cidx = 0; + } + } + } + if (ridx < layout.size()) + error(ways[0].lineno, "Too many rams for ways in table %s", name()); + } else { + std::set rams; + for (auto &row : layout) { + for (auto &unit : row.memunits) { + BUG_CHECK(!rams.count(unit), "%s duplicate in table", unit.desc()); + rams.insert(unit); + } + } + int way = -1; + for (auto &w : ways) { + ++way; + int index = -1; + if (table_type() != ATCAM) { + if ((w.rams.size() != (1U << w.select.popcount()) * fmt_width)) + error(w.lineno, "Depth of way doesn't match number of rams in table %s", + name()); + } else { + // Allowed to not fully match, as the partition index can be set from the + // control plane + if (!((w.rams.size() <= (1U << w.select.popcount()) * fmt_width) && + (w.rams.size() % fmt_width) == 0)) + error(w.lineno, "RAMs in ATCAM is not a legal multiple of the format width %s", + name()); + } + for (auto &ram : w.rams) { + ++index; + if (way_map.count(ram)) { + if (way == way_map.at(ram).way) + error(w.lineno, "%s used twice in way %d of table %s", ram.desc(), way, + name()); + else + error(w.lineno, "%s used ways %d and %d of table %s", ram.desc(), way, + way_map.at(ram).way, name()); + continue; + } + way_map[ram].way = way; + if (!ram.isLamb() && !rams.count(ram)) + error(w.lineno, "%s in way %d not part of table %s", ram.desc(), way, name()); + rams.erase(ram); + } + } + for (const auto &unit : rams) { + error(lineno, "%s not in any way of table %s", unit.desc(), name()); + } + } + if (error_count > 0) return; + int way = 0; + for (auto &w : ways) { + MaskCounter bank(w.select.getrange(EXACT_HASH_FIRST_SELECT_BIT, 32)); + unsigned index = 0, word = 0; + int col = -1; + for (auto &ram : w.rams) { + auto &wm = way_map[ram]; + wm.way = way; + wm.index = index; + wm.word = fmt_width - word - 1; + wm.bank = bank; + if (word && col != ram.col) + error(w.lineno, "Wide exact match split across columns %d and %d", col, ram.col); + col = ram.col; + ++index; + if (++word == fmt_width) { + word = 0; + bank++; + } + } + ++way; + } + setup_hash_function_ids(); +} + +/** + * Either fills out the word/result bus information each row, if it is not provided directly by + * the compiler, or verifies that the word/result_bus information matches directly with + * what has been calculated through the way information provided. + */ +void SRamMatchTable::determine_word_and_result_bus() { + for (auto &row : layout) { + int word = -1; + bool word_set = false; + for (auto &ram : row.memunits) { + auto &way = way_map.at(ram); + if (word_set) { + BUG_CHECK(word == way.word); + } else { + word = way.word; + word_set = true; + } + } + if (row.word_initialized()) { + if (word != row.word) + error(lineno, "Word on row %d bus %d does not align with word in RAM", row.row, + row.bus.at(Layout::SEARCH_BUS)); + } else { + row.word = word; + } + } + + for (auto &row : layout) { + bool result_bus_needed = false; + if (row.word < 0) { + // row with no rams -- assume it needs a result bus for the payload + result_bus_needed = true; + } else { + for (auto group_in_word : word_info.at(row.word)) { + if (group_info[group_in_word].result_bus_word == row.word) result_bus_needed = true; + } + } + if (!row.bus.count(Layout::RESULT_BUS) && result_bus_needed) + row.bus[Layout::RESULT_BUS] = row.bus.at(Layout::SEARCH_BUS); + if (row.bus.count(Layout::RESULT_BUS)) { + auto *old = stage->match_result_bus_use[row.row][row.bus.at(Layout::RESULT_BUS)]; + if (old && old != this) + error(row.lineno, + "inconsistent use of match result bus %d on row %d between " + "table %s and %s", + row.row, row.bus.at(Layout::RESULT_BUS), name(), old->name()); + stage->match_result_bus_use[row.row][row.bus.at(Layout::RESULT_BUS)] = this; + } + } +} + +int SRamMatchTable::determine_pre_byteswizzle_loc(MatchSource *ms, int lo, int hi, int word) { + auto phv_p = dynamic_cast(ms); + BUG_CHECK(phv_p); + auto phv_ref = *phv_p; + Phv::Slice sl(*phv_ref, lo, hi); + BUG_CHECK(word_ixbar_group[word] >= 0); + return find_on_ixbar(sl, word_ixbar_group[word]); +} + +template +void SRamMatchTable::write_attached_merge_regs(REGS ®s, int bus, int word, int word_group) { + int group = word_info[word][word_group]; + auto &merge = regs.rams.match.merge; + for (auto &st : attached.stats) { + if (group_info[group].result_bus_word == static_cast(word)) { + merge.mau_stats_adr_exact_shiftcount[bus][word_group] = + st->to()->determine_shiftcount(st, group, word, 0); + } else if (options.match_compiler) { + /* unused, so should not be set... */ + merge.mau_stats_adr_exact_shiftcount[bus][word_group] = 7; + } + break; /* all must be the same, only config once */ + } + for (auto &m : attached.meters) { + if (group_info[group].overhead_word == static_cast(word) || + group_info[group].overhead_word == -1) { + m->to()->setup_exact_shift(regs, bus, group, word, word_group, m, + attached.meter_color); + } else if (options.match_compiler) { + /* unused, so should not be set... */ + merge.mau_meter_adr_exact_shiftcount[bus][word_group] = 16; + } + break; /* all must be the same, only config once */ + } + for (auto &s : attached.statefuls) { + if (group_info[group].overhead_word == static_cast(word) || + group_info[group].overhead_word == -1) { + merge.mau_meter_adr_exact_shiftcount[bus][word_group] = + s->to()->determine_shiftcount(s, group, word, 0); + } else if (options.match_compiler) { + /* unused, so should not be set... */ + merge.mau_meter_adr_exact_shiftcount[bus][word_group] = 16; + } + break; /* all must be the same, only config once */ + } +} + +template +void SRamMatchTable::write_regs_vt(REGS ®s) { + LOG1("### SRam match table " << name() << " write_regs " << loc()); + MatchTable::write_regs(regs, 0, this); + auto &merge = regs.rams.match.merge; + unsigned fmt_width = format ? (format->size + 127) / 128 : 0; + bitvec match_mask; + match_mask.setrange(0, 128 * fmt_width); + version_nibble_mask.setrange(0, 32 * fmt_width); + for (unsigned i = 0; format && i < format->groups(); i++) { + if (Format::Field *match = format->field("match", i)) { + for (auto &piece : match->bits) match_mask.clrrange(piece.lo, piece.hi + 1 - piece.lo); + } + if (Format::Field *version = format->field("version", i)) { + match_mask.clrrange(version->bit(0), version->size); + version_nibble_mask.clrrange(version->bit(0) / 4, 1); + } + } + Format::Field *next = format ? format->field("next") : nullptr; + if (format && !next && hit_next.size() > 1) next = format->field("action"); + + /* iterating through rows in the sram array; while in this loop, 'row' is the + * row we're on, 'word' is which word in a wide full-way the row is for, and 'way' + * is which full-way of the match table the row is for. For compatibility with the + * compiler, we iterate over rows and ways in order, and words from msb to lsb (reversed) */ + int index = -1; + for (auto &row : layout) { + index++; /* index of the row in the layout */ + int search_bus = ::get(row.bus, Layout::SEARCH_BUS, -1); + /* setup match logic in rams */ + auto &rams_row = regs.rams.array.row[row.row]; + auto &vh_adr_xbar = rams_row.vh_adr_xbar; + bool first = true; + int hash_group = -1; + unsigned word = ~0; + auto vpn_iter = row.vpns.begin(); + for (auto &memunit : row.memunits) { + int col = memunit.col; + BUG_CHECK(memunit.stage == INT_MIN && memunit.row == row.row, "bogus %s in row %d", + memunit.desc(), row.row); + auto &way = way_map.at(memunit); + if (first) { + hash_group = ways[way.way].group_xme; + word = way.word; + setup_muxctl(vh_adr_xbar.exactmatch_row_hashadr_xbar_ctl[search_bus], hash_group); + first = false; + } else if (hash_group != ways[way.way].group_xme || int(word) != way.word) { + auto first_way = way_map.at(row.memunits[0]); + error(ways[way.way].lineno, + "table %s ways #%d and #%d use the same row bus " + "(%d.%d) but different %s", + name(), first_way.way, way.way, row.row, search_bus, + int(word) == way.word ? "hash groups" : "word order"); + hash_group = ways[way.way].group_xme; + word = way.word; + } + setup_muxctl(vh_adr_xbar.exactmatch_mem_hashadr_xbar_ctl[col], + ways[way.way].index / EXACT_HASH_ADR_BITS + search_bus * 5); + if (options.match_compiler || ways[way.way].select) { + // Glass always sets this. When mask == 0, bank will also be 0, and the + // comparison will always match, so the bus need not be read (inp_sel). + // CSR suggests it should NOT be set if not needed to save power. + auto &bank_enable = vh_adr_xbar.exactmatch_bank_enable[col]; + bank_enable.exactmatch_bank_enable_bank_mask = + ways[way.way].select.getrange(EXACT_HASH_FIRST_SELECT_BIT, 32); + bank_enable.exactmatch_bank_enable_bank_id = way.bank; + bank_enable.exactmatch_bank_enable_inp_sel |= 1 << search_bus; + } + auto &ram = rams_row.ram[col]; + for (unsigned i = 0; i < 4; i++) + ram.match_mask[i] = match_mask.getrange(way.word * 128U + i * 32, 32); + + if (next) { + for (int group : word_info[way.word]) { + if (group_info[group].result_bus_word != way.word) continue; + int pos = (next->by_group[group]->bit(0) % 128) - 1; + auto &n = ram.match_next_table_bitpos; + switch (group_info[group].result_bus_word_group()) { + case 0: + break; + case 1: + n.match_next_table1_bitpos = pos; + break; + case 2: + n.match_next_table2_bitpos = pos; + break; + case 3: + n.match_next_table3_bitpos = pos; + break; + case 4: + n.match_next_table4_bitpos = pos; + break; + default: + BUG(); + } + } + } + + ram.unit_ram_ctl.match_ram_logical_table = logical_id; + ram.unit_ram_ctl.match_ram_write_data_mux_select = 7; /* unused */ + ram.unit_ram_ctl.match_ram_read_data_mux_select = 7; /* unused */ + ram.unit_ram_ctl.match_ram_matchdata_bus1_sel = search_bus; + if (row.bus.count(Layout::RESULT_BUS)) + ram.unit_ram_ctl.match_result_bus_select = 1 << row.bus.at(Layout::RESULT_BUS); + if (auto cnt = word_info[way.word].size()) + ram.unit_ram_ctl.match_entry_enable = ~(~0U << cnt); + auto &unitram_config = + regs.rams.map_alu.row[row.row].adrmux.unitram_config[col / 6][col % 6]; + unitram_config.unitram_type = 1; + unitram_config.unitram_logical_table = logical_id; + switch (gress) { + case INGRESS: + case GHOST: + unitram_config.unitram_ingress = 1; + break; + case EGRESS: + unitram_config.unitram_egress = 1; + break; + default: + BUG(); + } + unitram_config.unitram_enable = 1; + + int vpn = *vpn_iter++; + std::vector vpn01; + auto groups_in_word = word_info[way.word]; + // Action format is made up of multiple groups (groups_in_format) which can be spread + // across multiple words. The match_group_map specifies which groups are within each + // word. For an N pack across M words if N > M, we have one or more words with multiple + // groups. + // Below code assigns VPN for each group(groups_in_word) within a word which are indexed + // separately from groups_in_format. + // E.g. + // format: { + // action(0): 0..0, immediate(0): 2..9, version(0): 112..115, match(0): 18..71, + // action(1): 1..1, immediate(1): 10..17, version(1): 116..119, + // match(1): [ 194..199, 72..111, 120..127 ], + // action(2): 128..128, immediate(2): 129..136, version(2): 240..243, + // match(2): 138..191, + // action(3): 256..256, immediate(3): 257..264, version(3): 368..371, + // match(3): 266..319, + // action(4): 384..384, immediate(4): 385..392, version(4): 496..499, + // match(4): 394..447 } + // match_group_map: [ [ 1, 0 ], [ 1, 2], [ 3 ], [ 4 ] ] + // ^ ^ + // } + // In the above example the "format" specifies the 5 groups packed across 4 RAMs.These + // are the groups_in_format + // The "match_group_map" specifies the groups within each word. + // Group 1 is spread across word 0 & word 1. + // Within word 0 - group 1 is group_in_word 0 and group 0 is group_in_word 1 + // Within word 1 - group 1 is group_in_word 0 and group 2 is group_in_word 1 + // This distinction is used while specifying the config register in setting the subfield + // on match_ram_vpn_lsbs. + for (auto group_in_word = 0; group_in_word < groups_in_word.size(); group_in_word++) { + auto group_in_format = groups_in_word[group_in_word]; + int overhead_word = group_info[group_in_format].overhead_word; + int group_vpn = vpn + group_info[group_in_format].vpn_offset; + bool ok = false; + for (unsigned i = 0; i < vpn01.size(); ++i) { + if (vpn01[i] == group_vpn >> 2) { + ok = true; + group_vpn = (group_vpn & 3) + (i << 2); + break; + } + } + if (!ok) { + if (vpn01.size() >= 2) { + error(mgm_lineno > 0 ? mgm_lineno : lineno, + "Too many diverse vpns in table layout for %s", name()); + break; + } + vpn01.push_back(group_vpn >> 2); + group_vpn &= 3; + if (vpn01.size() == 1) { + ram.match_ram_vpn.match_ram_vpn0 = vpn01.back(); + } else { + ram.match_ram_vpn.match_ram_vpn1 = vpn01.back(); + group_vpn |= 4; + } + } + ram.match_ram_vpn.match_ram_vpn_lsbs.set_subfield(group_vpn, group_in_word * 3, 3); + } + + int word_group = 0; + for (int group : word_info[way.word]) { + unsigned mask = group_info[group].tofino_mask[way.word]; + ram.match_bytemask[word_group].mask_bytes_0_to_13 = ~mask & 0x3fff; + ram.match_bytemask[word_group].mask_nibbles_28_to_31 = ~(mask >> 14) & 0xf; + word_group++; + } + for (; word_group < 5; word_group++) { + ram.match_bytemask[word_group].mask_bytes_0_to_13 = 0x3fff; + ram.match_bytemask[word_group].mask_nibbles_28_to_31 = 0xf; + } + if (gress == EGRESS) + regs.cfg_regs.mau_cfg_uram_thread[col / 4U] |= 1U << (col % 4U * 8U + row.row); + rams_row.emm_ecc_error_uram_ctl[timing_thread(gress)] |= 1U << (col - 2); + } + /* setup input xbars to get data to the right places on the bus(es) */ + bool using_match = false; + // Loop for determining the config to indicate which bytes from the search bus + // are compared to the bytes on the RAM line + if (!row.memunits.empty()) { + auto &byteswizzle_ctl = rams_row.exactmatch_row_vh_xbar_byteswizzle_ctl[search_bus]; + for (unsigned i = 0; format && i < format->groups(); i++) { + if (Format::Field *match = format->field("match", i)) { + unsigned bit = 0; + for (auto &piece : match->bits) { + if (piece.lo / 128U != word) { + bit += piece.size(); + continue; + } + using_match = true; + for (unsigned fmt_bit = piece.lo; fmt_bit <= piece.hi;) { + unsigned byte = (fmt_bit % 128) / 8; + unsigned bits_in_byte = (byte + 1) * 8 - (fmt_bit % 128); + if (fmt_bit + bits_in_byte > piece.hi + 1) + bits_in_byte = piece.hi + 1 - fmt_bit; + auto it = --match_by_bit.upper_bound(bit); + int lo = bit - it->first; + int hi = lo + bits_in_byte - 1; + int bus_loc = determine_pre_byteswizzle_loc(it->second, lo, hi, word); + BUG_CHECK(bus_loc >= 0 && bus_loc < 16); + for (unsigned b = 0; b < bits_in_byte; b++, fmt_bit++) + byteswizzle_ctl[byte][fmt_bit % 8U] = 0x10 + bus_loc; + bit += bits_in_byte; + } + } + BUG_CHECK(bit == match->size); + } + if (Format::Field *version = format->field("version", i)) { + if (version->bit(0) / 128U != word) continue; + ///> if no match, but a version/valid is, the vh_xbar needs to be + ///> enabled. This was preventing anything from running + using_match = true; + for (unsigned j = 0; j < version->size; ++j) { + unsigned bit = version->bit(j); + unsigned byte = (bit % 128) / 8; + byteswizzle_ctl[byte][bit % 8U] = 8; + } + } + } + if (using_match) { + auto &vh_xbar_ctl = rams_row.vh_xbar[search_bus].exactmatch_row_vh_xbar_ctl; + if (word_ixbar_group[word] >= 0) { + setup_muxctl(vh_xbar_ctl, word_ixbar_group[word]); + } else { + // Need the bus for version/valid, but don't care what other data is on it. So + // just set the enable without actually selecting an input -- if another table + // is sharing the bus, it will set it, otherwise we'll get ixbar group 0 + vh_xbar_ctl.exactmatch_row_vh_xbar_enable = 1; + } + vh_xbar_ctl.exactmatch_row_vh_xbar_thread = timing_thread(gress); + } + } + /* setup match central config to extract results of the match */ + ssize_t r_bus = -1; + if (row.bus.count(Layout::RESULT_BUS)) r_bus = row.row * 2 + row.bus.at(Layout::RESULT_BUS); + // If the result bus is not to be used, then the registers are not necessary to set up + // for shift/mask/default etc. + /* FIXME -- factor this where possible with ternary match code */ + if (action) { + if (auto adt = action->to()) { + if (r_bus >= 0) { + /* FIXME -- support for multiple sizes of action data? */ + merge.mau_actiondata_adr_mask[0][r_bus] = adt->determine_mask(action); + merge.mau_actiondata_adr_vpn_shiftcount[0][r_bus] = + adt->determine_vpn_shiftcount(action); + } + } + } + + if (format && word < word_info.size()) { + for (unsigned word_group = 0; word_group < word_info[word].size(); word_group++) { + int group = word_info[word][word_group]; + if (group_info[group].result_bus_word == static_cast(word)) { + BUG_CHECK(r_bus >= 0); + if (format->immed) { + BUG_CHECK(format->immed->by_group[group]->bit(0) / 128U == word); + merge.mau_immediate_data_exact_shiftcount[r_bus][word_group] = + format->immed->by_group[group]->bit(0) % 128; + } + if (instruction) { + int shiftcount = 0; + if (auto field = instruction.args[0].field()) { + assert(field->by_group[group]->bit(0) / 128U == word); + shiftcount = field->by_group[group]->bit(0) % 128U; + } else if (auto field = instruction.args[1].field()) { + assert(field->by_group[group]->bit(0) / 128U == word); + shiftcount = field->by_group[group]->bit(0) % 128U; + } + merge.mau_action_instruction_adr_exact_shiftcount[r_bus][word_group] = + shiftcount; + } + } + /* FIXME -- factor this where possible with ternary match code */ + if (action) { + if (group_info[group].result_bus_word == static_cast(word)) { + BUG_CHECK(r_bus >= 0); + merge.mau_actiondata_adr_exact_shiftcount[r_bus][word_group] = + action->determine_shiftcount(action, group, word, 0); + } + } + if (attached.selector) { + if (group_info[group].result_bus_word == static_cast(word)) { + BUG_CHECK(r_bus >= 0); + auto sel = get_selector(); + merge.mau_meter_adr_exact_shiftcount[r_bus][word_group] = + sel->determine_shiftcount(attached.selector, group, word, 0); + merge.mau_selectorlength_shiftcount[0][r_bus] = + sel->determine_length_shiftcount(attached.selector_length, group, word); + merge.mau_selectorlength_mask[0][r_bus] = + sel->determine_length_mask(attached.selector_length); + merge.mau_selectorlength_default[0][r_bus] = + sel->determine_length_default(attached.selector_length); + } + } + if (idletime) { + if (group_info[group].result_bus_word == static_cast(word)) { + BUG_CHECK(r_bus >= 0); + merge.mau_idletime_adr_exact_shiftcount[r_bus][word_group] = + idletime->direct_shiftcount(); + } + } + if (r_bus >= 0) write_attached_merge_regs(regs, r_bus, word, word_group); + } + } else if (format) { + // If we have a result bus without any attached memories, program + // the registers on this row because a subset of the registers have been + // programmed elsewhere and it can break things if we have a partial configuration. + // FIXME: avoid programming any registers if we don't actually use the result bus. + if (r_bus >= 0) write_attached_merge_regs(regs, r_bus, 0, 0); + } + for (auto &ram : row.memunits) { + int word_group = 0; + auto &merge_col = merge.col[ram.col]; + for (int group : word_info[word]) { + int result_bus_word = group_info[group].result_bus_word; + if (int(word) == result_bus_word) { + BUG_CHECK(r_bus >= 0); + merge_col.row_action_nxtable_bus_drive[row.row] |= 1 << (r_bus % 2); + } + if (word_group < 2) { + auto &way = way_map.at(ram); + int idx = way.index + word - result_bus_word; + int overhead_row = ways[way.way].rams[idx].row; + auto &hitmap_ixbar = merge_col.hitmap_output_map[2 * row.row + word_group]; + setup_muxctl(hitmap_ixbar, + overhead_row * 2 + group_info[group].result_bus_word_group()); + } + ++word_group; + } + // setup_muxctl(merge.col[ram.col].hitmap_output_map[bus], + // layout[index+word].row*2 + layout[index+word].bus); + } + // if (gress == EGRESS) + // merge.exact_match_delay_config.exact_match_bus_thread |= 1 << bus; + if (r_bus >= 0) { + merge.exact_match_phys_result_en[r_bus / 8U] |= 1U << (r_bus % 8U); + merge.exact_match_phys_result_thread[r_bus / 8U] |= timing_thread(gress) + << (r_bus % 8U); + if (stage->tcam_delay(gress)) + merge.exact_match_phys_result_delay[r_bus / 8U] |= 1U << (r_bus % 8U); + } + } + + merge.exact_match_logical_result_en |= 1 << logical_id; + if (stage->tcam_delay(gress) > 0) merge.exact_match_logical_result_delay |= 1 << logical_id; + if (actions) actions->write_regs(regs, this); + if (gateway) gateway->write_regs(regs); + if (idletime) idletime->write_regs(regs); + for (auto &hd : hash_dist) hd.write_regs(regs, this); +} +FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void SRamMatchTable::write_regs, (mau_regs & regs), + { write_regs_vt(regs); }) + +std::string SRamMatchTable::get_match_mode(const Phv::Ref &pref, int offset) const { + return "unused"; +} + +void SRamMatchTable::add_field_to_pack_format(json::vector &field_list, int basebit, + std::string name, const Table::Format::Field &field, + const Table::Actions::Action *act) const { + if (name != "match") { + // FIXME -- tofino always pads out the wordsize so basebit is always 0. + basebit = 0; + Table::add_field_to_pack_format(field_list, basebit, name, field, act); + return; + } + LOG3("Adding fields for " << name << " - " << field << " to pack format for SRAM table " + << this->name() << " in action : " << act); + unsigned bit = 0; + for (auto &piece : field.bits) { + auto mw = --match_by_bit.upper_bound(bit); + int lo = bit - mw->first; + int lsb_mem_word_idx = piece.lo / MEM_WORD_WIDTH; + int msb_mem_word_idx = piece.hi / MEM_WORD_WIDTH; + int offset = piece.lo % MEM_WORD_WIDTH; + while (mw != match_by_bit.end() && mw->first < bit + piece.size()) { + std::string source = ""; + std::string immediate_name = ""; + std::string mw_name = mw->second->name(); + int start_bit = 0; + + get_cjson_source(mw_name, source, start_bit); + if (source == "") + error(lineno, "Cannot determine proper source for field %s", name.c_str()); + std::string field_name, global_name = ""; + std::string match_mode; + if (auto phv_p = dynamic_cast(mw->second)) { + field_name = mw->second->name(); + // If the name has a slice in it, remove it and add the lo bit of + // the slice to field_bit. This takes the place of + // canon_field_list(), rather than extracting the slice component + // of the field name, if present, and appending it to the key name. + int slice_offset = remove_name_tail_range(field_name); + start_bit = lo + slice_offset + mw->second->fieldlobit(); + global_name = field_name; + auto p = find_p4_param(field_name, "", start_bit); + if (!p && !p4_params_list.empty()) { + warning(lineno, + "Cannot find field name %s in p4_param_order " + "for table %s", + field_name.c_str(), this->name()); + } else if (p && !p->key_name.empty()) { + field_name = p->key_name; + } + match_mode = get_match_mode(*phv_p, mw->first); + } else if (dynamic_cast(mw->second)) { + field_name = "--proxy_hash--"; + match_mode = "unused"; + start_bit = mw->second->fieldlobit(); + } else { + BUG(); + } + + field_list.push_back(json::map{{"field_name", json::string(field_name)}, + {"global_name", json::string(global_name)}, + {"source", json::string(source)}, + {"lsb_mem_word_offset", json::number(offset)}, + {"start_bit", json::number(start_bit)}, + {"immediate_name", json::string(immediate_name)}, + {"lsb_mem_word_idx", json::number(lsb_mem_word_idx)}, + {"msb_mem_word_idx", json::number(msb_mem_word_idx)}, + // FIXME-JSON + {"match_mode", json::string(match_mode)}, + {"enable_pfe", json::False()}, // FIXME-JSON + {"field_width", json::number(mw->second->size())}}); + LOG5("Adding json field " << field_list.back()); + offset += mw->second->size(); + lo = 0; + ++mw; + } + bit += piece.size(); + } +} + +void SRamMatchTable::add_action_cfgs(json::map &tbl, json::map &stage_tbl) const { + if (actions) { + actions->gen_tbl_cfg(tbl["actions"]); + actions->add_action_format(this, stage_tbl); + } else if (action && action->actions) { + action->actions->gen_tbl_cfg(tbl["actions"]); + action->actions->add_action_format(this, stage_tbl); + } +} + +unsigned SRamMatchTable::get_format_width() const { + return format ? (format->size + 127) / 128 : 0; +} + +unsigned SRamMatchTable::get_number_entries() const { + unsigned fmt_width = get_format_width(); + unsigned number_entries = 0; + if (format) number_entries = layout_size() / fmt_width * format->groups() * entry_ram_depth(); + return number_entries; +} + +json::map *SRamMatchTable::add_common_sram_tbl_cfgs(json::map &tbl, std::string match_type, + std::string stage_table_type) const { + common_tbl_cfg(tbl); + json::map &match_attributes = tbl["match_attributes"]; + json::vector &stage_tables = match_attributes["stage_tables"]; + json::map *stage_tbl_ptr = + add_stage_tbl_cfg(match_attributes, stage_table_type.c_str(), get_number_entries()); + json::map &stage_tbl = *stage_tbl_ptr; + // This is a only a glass required field, as it is only required when no default action + // is specified, which is impossible for Brig through p4-16 + stage_tbl["default_next_table"] = Stage::end_of_pipe(); + match_attributes["match_type"] = match_type; + add_hash_functions(stage_tbl); + add_action_cfgs(tbl, stage_tbl); + add_result_physical_buses(stage_tbl); + MatchTable::gen_idletime_tbl_cfg(stage_tbl); + merge_context_json(tbl, stage_tbl); + add_all_reference_tables(tbl); + return stage_tbl_ptr; +} + +int SRamMatchTable::find_problematic_vpn_offset() const { + // Any single word of a match that contains 3 or more groups whose min and max vpn_offset + // differs by more than 5 is going to be a problem. We need to permute the offsets so that + // does not happen + if (group_info.size() <= 6) return -1; // can't differ by more than 5 + for (auto &word : word_info) { + if (word.size() <= 2) continue; // can't be a problem + int minvpn = -1, maxvpn = -1, avg = 0; + for (auto group : word) { + int vpn_offset = group_info[group].vpn_offset; + if (minvpn < 0) + minvpn = maxvpn = vpn_offset; + else if (minvpn > vpn_offset) + minvpn = vpn_offset; + else if (maxvpn < vpn_offset) + maxvpn = vpn_offset; + avg += vpn_offset; + } + if (maxvpn - minvpn > 5) { + if (minvpn + maxvpn > (2 * avg) / word.size()) + minvpn = maxvpn; // look for the max to move, instead of min + for (auto group : word) { + if (group_info[group].vpn_offset == minvpn) return group; + } + BUG("failed to find the group vpn we just saw"); + } + } + return -1; // no problem found +} + +void SRamMatchTable::alloc_vpns() { + if (error_count > 0 || no_vpns || layout_size() == 0 || layout[0].vpns.size() > 0) return; + int period, width, depth; + const char *period_name; + vpn_params(width, depth, period, period_name); + std::map vpn_for; + for (auto &row : layout) { + row.vpns.resize(row.memunits.size()); + int i = 0; + for (auto &ram : row.memunits) vpn_for[ram] = &row.vpns[i++]; + } + int vpn = 0, word = 0; + for (auto &way : ways) { + for (auto unit : way.rams) { + *vpn_for[unit] = vpn; + if (++word == width) { + word = 0; + vpn += period; + } + } + } + + int fix = find_problematic_vpn_offset(); + if (fix >= 0) { + // Swap it with the middle one. That should fix all the cases we've seen + int middle = group_info.size() / 2; + BUG_CHECK(middle != fix, "vpn_offset fix doesn't work"); + std::swap(group_info[fix].vpn_offset, group_info[middle].vpn_offset); + BUG_CHECK(find_problematic_vpn_offset() < 0, "vpn_offset fix did not work"); + } +} diff --git a/backends/tofino/bf-asm/stage.cpp b/backends/tofino/bf-asm/stage.cpp new file mode 100644 index 00000000000..2cec2bc17f9 --- /dev/null +++ b/backends/tofino/bf-asm/stage.cpp @@ -0,0 +1,857 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "stage.h" + +#include +#include + +#include + +#include "deparser.h" +#include "input_xbar.h" +#include "misc.h" +#include "parser.h" +#include "phv.h" +#include "range.h" +#include "sections.h" +#include "target.h" +#include "top_level.h" + +extern std::string asmfile_name; + +unsigned char Stage::action_bus_slot_map[ACTION_DATA_BUS_BYTES]; +unsigned char Stage::action_bus_slot_size[ACTION_DATA_BUS_SLOTS]; + +AsmStage AsmStage::singleton_object; + +#include "jbay/stage.cpp" // NOLINT(build/include) +#include "tofino/stage.cpp" // NOLINT(build/include) + +AsmStage::AsmStage() : Section("stage") { + int slot = 0, byte = 0; + for (int i = 0; i < ACTION_DATA_8B_SLOTS; i++) { + Stage::action_bus_slot_map[byte++] = slot; + Stage::action_bus_slot_size[slot++] = 8; + } + for (int i = 0; i < ACTION_DATA_16B_SLOTS; i++) { + Stage::action_bus_slot_map[byte++] = slot; + Stage::action_bus_slot_map[byte++] = slot; + Stage::action_bus_slot_size[slot++] = 16; + } + for (int i = 0; i < ACTION_DATA_32B_SLOTS; i++) { + Stage::action_bus_slot_map[byte++] = slot; + Stage::action_bus_slot_map[byte++] = slot; + Stage::action_bus_slot_map[byte++] = slot; + Stage::action_bus_slot_map[byte++] = slot; + Stage::action_bus_slot_size[slot++] = 32; + } + BUG_CHECK(byte == ACTION_DATA_BUS_BYTES); + BUG_CHECK(slot == ACTION_DATA_BUS_SLOTS); +} + +void AsmStage::start(int lineno, VECTOR(value_t) args) { + while (int(pipe.size()) < Target::NUM_MAU_STAGES()) pipe.emplace_back(pipe.size(), false); + if (args.size != 2 || args[0].type != tINT || + (args[1] != "ingress" && args[1] != "egress" && + (args[1] != "ghost" || options.target < JBAY))) { + error(lineno, "stage must specify number and ingress%s or egress", + options.target >= JBAY ? ", ghost" : ""); + } else if (args[0].i < 0) { + error(lineno, "invalid stage number"); + } else if ((unsigned)args[0].i >= pipe.size()) { + while ((unsigned)args[0].i >= pipe.size()) pipe.emplace_back(pipe.size(), false); + } +} + +void AsmStage::input(VECTOR(value_t) args, value_t data) { + if (!CHECKTYPE(data, tMAP)) return; + int stageno = args[0].i; + gress_t gress = + args[1] == "ingress" ? INGRESS + : args[1] == "egress" ? EGRESS + : args[1] == "ghost" && options.target >= JBAY + ? GHOST + : (error(args[1].lineno, "Invalid thread %s", value_desc(args[1])), INGRESS); + auto &stage = stages(gress); + BUG_CHECK(stageno >= 0 && (unsigned)stageno < stage.size()); + if (stages_seen[gress][stageno]) + error(args[0].lineno, "Duplicate stage %d %s", stageno, to_string(gress).c_str()); + stages_seen[gress][stageno] = 1; + for (auto &kv : MapIterChecked(data.map, true)) { + if (kv.key == "dependency") { + if (stageno == 0) warning(kv.key.lineno, "Stage dependency in stage 0 will be ignored"); + if (gress == GHOST) { + error(kv.key.lineno, + "Can't specify dependency in ghost thread; it is " + "locked to ingress"); + } else if (kv.value == "concurrent") { + stage[stageno].stage_dep[gress] = Stage::CONCURRENT; + if (stageno == Target::NUM_MAU_STAGES() / 2 && options.target == TOFINO) + error(kv.value.lineno, "stage %d must be match dependent", stageno); + else if (!Target::SUPPORT_CONCURRENT_STAGE_DEP()) + error(kv.value.lineno, "no concurrent execution on %s", Target::name()); + } else if (kv.value == "action") { + stage[stageno].stage_dep[gress] = Stage::ACTION_DEP; + if (stageno == Target::NUM_MAU_STAGES() / 2 && options.target == TOFINO) + error(kv.value.lineno, "stage %d must be match dependent", stageno); + } else if (kv.value == "match") { + stage[stageno].stage_dep[gress] = Stage::MATCH_DEP; + } else { + error(kv.value.lineno, "Invalid stage dependency %s", value_desc(kv.value)); + } + continue; + + } else if (kv.key == "mpr_stage_id") { + stage[stageno].verify_have_mpr(kv.key.s, kv.key.lineno); + if CHECKTYPE (kv.value, tINT) { + if (kv.value.i > stageno) + error(kv.value.lineno, + "mpr_stage_id value cannot be greater than current stage."); + stage[stageno].mpr_stage_id[gress] = kv.value.i; + + /* Intermediate stage must carry the mpr glob_exec and long_branch bitmap. + * If they have been left off by the compiler, we need to propagate the bits; + * if the compiler has provided them, we assume it did so correctly + * DANGER -- this assumes the stages appear in the .bfa file in order (at + * least for each gress) + */ + if (kv.value.i != stageno) { + for (int inter_stage = kv.value.i + 1; inter_stage < stageno; inter_stage++) { + if (!stages_seen[gress][inter_stage]) { + stage[inter_stage].mpr_bus_dep_glob_exec[gress] |= + stage[kv.value.i].mpr_bus_dep_glob_exec[gress]; + stage[inter_stage].mpr_bus_dep_long_branch[gress] |= + stage[kv.value.i].mpr_bus_dep_long_branch[gress]; + } + } + } + } + continue; + } else if (kv.key == "mpr_always_run") { + stage[stageno].verify_have_mpr(kv.key.s, kv.key.lineno); + if CHECKTYPE (kv.value, tINT) { + stage[stageno].mpr_always_run |= kv.value.i; + } + continue; + } else if (kv.key == "mpr_bus_dep_glob_exec") { + stage[stageno].verify_have_mpr(kv.key.s, kv.key.lineno); + if CHECKTYPE (kv.value, tINT) { + stage[stageno].mpr_bus_dep_glob_exec[gress] = kv.value.i; + } + continue; + } else if (kv.key == "mpr_bus_dep_long_brch") { + stage[stageno].verify_have_mpr(kv.key.s, kv.key.lineno); + if CHECKTYPE (kv.value, tINT) { + stage[stageno].mpr_bus_dep_long_branch[gress] = kv.value.i; + } + continue; + } else if (kv.key == "mpr_next_table_lut") { + stage[stageno].verify_have_mpr(kv.key.s, kv.key.lineno); + if (CHECKTYPE(kv.value, tMAP)) { + for (auto &lut : kv.value.map) { + if (!CHECKTYPE(lut.key, tINT) || lut.key.i >= LOGICAL_TABLES_PER_STAGE) + error(lut.key.lineno, "Invalid mpr_next_table_lut key."); + if (!CHECKTYPE(lut.value, tINT) || + lut.value.i >= (1 << LOGICAL_TABLES_PER_STAGE)) + error(lut.value.lineno, "Invalid mpr_next_table_lut value."); + stage[stageno].mpr_next_table_lut[gress][lut.key.i] = lut.value.i; + } + } + continue; + } else if (kv.key == "mpr_glob_exec_lut") { + stage[stageno].verify_have_mpr(kv.key.s, kv.key.lineno); + if (CHECKTYPE(kv.value, tMAP)) { + for (auto &lut : kv.value.map) { + if (!CHECKTYPE(lut.key, tINT) || lut.key.i >= LOGICAL_TABLES_PER_STAGE) + error(lut.key.lineno, "Invalid mpr_glob_exec_lut key."); + if (!CHECKTYPE(lut.value, tINT) || + lut.value.i >= (1 << LOGICAL_TABLES_PER_STAGE)) + error(lut.value.lineno, "Invalid mpr_glob_exec_lut value."); + stage[stageno].mpr_glob_exec_lut[lut.key.i] |= lut.value.i; + } + } + continue; + } else if (kv.key == "mpr_long_brch_lut") { + stage[stageno].verify_have_mpr(kv.key.s, kv.key.lineno); + if (CHECKTYPE(kv.value, tMAP)) { + for (auto &lut : kv.value.map) { + if (!CHECKTYPE(lut.key, tINT) || lut.key.i >= MAX_LONGBRANCH_TAGS) + error(lut.key.lineno, "Invalid mpr_long_brch_lut key."); + if (!CHECKTYPE(lut.value, tINT) || + lut.value.i >= (1 << LOGICAL_TABLES_PER_STAGE)) + error(lut.value.lineno, "Invalid mpr_long_brch_lut value."); + stage[stageno].mpr_long_brch_lut[lut.key.i] |= lut.value.i; + } + } + continue; + } else if (kv.key == "error_mode") { + if (gress == GHOST) + error(kv.key.lineno, "Can't specify error mode in ghost thread"); + else + stage[stageno].error_mode[gress].input(kv.value); + continue; + } else if (Target::SUPPORT_ALWAYS_RUN() && kv.key == "always_run_action") { + if (gress == GHOST) + error(kv.key.lineno, "No always run action for ghost thread, must use ingress"); + else + stage[stageno].tables.push_back(new AlwaysRunTable(gress, &stage[stageno], kv)); + continue; + } + if (!CHECKTYPEM(kv.key, tCMD, "table declaration")) continue; + if (!CHECKTYPE(kv.value, tMAP)) continue; + auto tt = Table::Type::get(kv.key[0].s); + if (!tt) { + error(kv.key[0].lineno, "Unknown table type '%s'", kv.key[0].s); + continue; + } + if (kv.key.vec.size < 2) { + error(kv.key.lineno, "Need table name"); + continue; + } + if (!CHECKTYPE(kv.key[1], tSTR)) continue; + if (kv.key.vec.size > 2 && !CHECKTYPE(kv.key[2], tINT)) continue; + if (kv.key.vec.size > 3) warning(kv.key[3].lineno, "Ignoring extra stuff after table"); + if (auto old = ::get(Table::all, kv.key[1].s)) { + error(kv.key[1].lineno, "Table %s already defined", kv.key[1].s); + warning(old->lineno, "previously defined here"); + continue; + } + if (Table *table = tt->create(kv.key.lineno, kv.key[1].s, gress, &stage[stageno], + kv.key.vec.size > 2 ? kv.key[2].i : -1, kv.value.map)) { + stage[stageno].tables.push_back(table); + } + } +} + +void AsmStage::process() { + for (auto &stage : pipe) { + stage.pass1_logical_id = stage.pass1_tcam_id = -1; + for (auto table : stage.tables) table->pass0(); + } + for (auto &stage : pipe) { + for (auto table : stage.tables) table->pass1(); + if (options.target == TOFINO) { + if (&stage - &pipe[0] == Target::NUM_MAU_STAGES() / 2) { + /* to turn the corner, the middle stage must always be match dependent */ + for (gress_t gress : Range(INGRESS, EGRESS)) + stage.stage_dep[gress] = Stage::MATCH_DEP; + } + } + if (options.match_compiler || 1) { + /* FIXME -- do we really want to do this? In theory different stages could + * FIXME -- use the same PHV slots differently, but the compiler always uses them + * FIXME -- consistently, so we need this to get bit-identical results + * FIXME -- we also don't correctly determine liveness, so need this */ + for (gress_t gress : Range(INGRESS, GHOST)) { + Phv::setuse(gress, stage.match_use[gress]); + Phv::setuse(gress, stage.action_use[gress]); + Phv::setuse(gress, stage.action_set[gress]); + } + } + } + for (auto &stage : pipe) { + for (auto table : stage.tables) table->pass2(); + std::sort(stage.tables.begin(), stage.tables.end(), + [](Table *a, Table *b) { return a->logical_id < b->logical_id; }); + } + for (auto &stage : pipe) { + for (auto table : stage.tables) table->pass3(); + } +} + +void AsmStage::output(json::map &ctxt_json) { + if (int(pipe.size()) > Target::NUM_MAU_STAGES()) { + auto lineno = pipe.back().tables.empty() ? 0 : pipe.back().tables[0]->lineno; + error(lineno, "%s supports up to %d stages, using %zd", Target::name(), + Target::NUM_MAU_STAGES(), pipe.size()); + } + + // If we encounter errors, no binary is generated, however we still proceed + // to generate the context.json with whatever info is provided in the .bfa. + // This can be inspected in p4i for debugging. + if (error_count > 0) { + options.binary = NO_BINARY; + error(0, "Due to errors, no binary will be generated"); + } + if (pipe.empty()) return; + + /* Allow to set any stage as match dependent based on a pattern - Should never be used for + * normal compilation */ + if (options.target != TOFINO && !options.stage_dependency_pattern.empty()) { + for (gress_t gress : Range(INGRESS, EGRESS)) { + auto &stage = stages(gress); + unsigned i = 0; + for (auto ch : options.stage_dependency_pattern) { + if (ch == '1') { + LOG1("explicitly setting stage " << i << " " << gress + << " as match dependent on previous stage"); + stage[i].stage_dep[gress] = Stage::MATCH_DEP; + } + if (++i >= stage.size()) break; + } + } + } + + for (gress_t gress : Range(INGRESS, EGRESS)) { + auto &stage = stages(gress); + bitvec set_regs = stage[0].action_set[gress]; + for (unsigned i = 1; i < stage.size(); i++) { + if (!stage[i].stage_dep[gress]) { + if (stage[i].match_use[gress].intersects(set_regs)) { + LOG1("stage " << i << " " << gress << " is match dependent on previous stage"); + stage[i].stage_dep[gress] = Stage::MATCH_DEP; + } else if (stage[i].action_use[gress].intersects(set_regs)) { + LOG1("stage " << i << " " << gress << " is action dependent on previous stage"); + stage[i].stage_dep[gress] = Stage::ACTION_DEP; + } else { + LOG1("stage " << i << " " << gress << " is concurrent with previous stage"); + if (!Target::SUPPORT_CONCURRENT_STAGE_DEP()) + stage[i].stage_dep[gress] = Stage::ACTION_DEP; + else + stage[i].stage_dep[gress] = Stage::CONCURRENT; + } + } + if (stage[i].stage_dep[gress] == Stage::MATCH_DEP) + set_regs = stage[i].action_set[gress]; + else + set_regs |= stage[i].action_set[gress]; + } + } + + // Propagate group_table_use so we can estimate latencies. + propagate_group_table_use(); + + // In Tofino, add match-dependent stages if latency is not the minimum + // egress latency. There is no such requirement for JBAY - COMPILER-757 + if (options.target == TOFINO) { + // Compute Egress Latency + auto total_cycles = compute_latency(EGRESS); + if (!options.disable_egress_latency_padding) { + // Get non match dependent stages + bitvec non_match_dep; + for (unsigned i = 1; i < pipe.size(); i++) { + auto stage_dep = pipe[i].stage_dep[EGRESS]; + if (stage_dep != Stage::MATCH_DEP) non_match_dep.setbit(i); + } + // Add match-dependent stages and re-evaluate latency + while (total_cycles < Target::Tofino::MINIMUM_REQUIRED_EGRESS_PIPELINE_LATENCY) { + if (non_match_dep == bitvec(0)) break; + auto non_match_dep_stage = non_match_dep.min().index(); + pipe[non_match_dep_stage].stage_dep[EGRESS] = Stage::MATCH_DEP; + LOG3("Converting egress stage " + << non_match_dep_stage + << " to match dependent to meet minimum egress pipeline latency requirement"); + non_match_dep.clrbit(non_match_dep_stage); + total_cycles = compute_latency(EGRESS); + } + } else { + if (total_cycles < Target::Tofino::MINIMUM_REQUIRED_EGRESS_PIPELINE_LATENCY) { + warning(0, + "User disabled adding latency to the egress MAU pipeline " + "to meet its minimum requirements. This may result in under " + "run in certain port speed configurations."); + } + } + } + + // Re-propagate group_table_use to account for any stages that may now be match dependent. + propagate_group_table_use(); + + for (auto &stage : pipe) SWITCH_FOREACH_TARGET(options.target, stage.output(ctxt_json);) + + if (options.log_hashes) { + std::ofstream hash_out; + std::string fname = options.output_dir + "/logs/mau.hashes.log"; + hash_out.open(fname.c_str()); + if (hash_out) { + for (auto &stage : pipe) stage.log_hashes(hash_out); + hash_out.close(); + } + } +} + +void AsmStage::propagate_group_table_use() { + for (gress_t gress : Range(INGRESS, EGRESS)) { + auto &stage = stages(gress); + stage[0].group_table_use[gress] = stage[0].table_use[gress]; + for (unsigned i = 1; i < stage.size(); i++) { + stage[i].group_table_use[gress] = stage[i].table_use[gress]; + if (stage[i].stage_dep[gress] != Stage::MATCH_DEP) + stage[i].group_table_use[gress] |= stage[i - 1].group_table_use[gress]; + } + for (int i = stage.size() - 1; i > 0; i--) + if (stage[i].stage_dep[gress] != Stage::MATCH_DEP) + stage[i - 1].group_table_use[gress] |= stage[i].group_table_use[gress]; + } +} + +unsigned AsmStage::compute_latency(gress_t gress) { + // FIXME -- this is Tofino1 only, so should be in target specific code somewhere + auto total_cycles = 4; // There are 4 extra cycles between stages 5 & 6 of the MAU + for (unsigned i = 1; i < pipe.size(); i++) { + auto stage_dep = pipe[i].stage_dep[gress]; + auto contribute = 0; + if (stage_dep == Stage::MATCH_DEP) { + contribute = pipe[i].pipelength(gress); + } else if (stage_dep == Stage::ACTION_DEP) { + contribute = 2; + } else if (stage_dep == Stage::CONCURRENT) { + contribute = 1; + } + total_cycles += contribute; + } + return total_cycles; +} + +static FakeTable invalid_rams("RAMS NOT PRESENT"); + +std::map> Stage_data::teop = { + {0, {false, INT_MAX}}, {1, {false, INT_MAX}}, {2, {false, INT_MAX}}, {3, {false, INT_MAX}}}; + +Stage::Stage(int stage, bool egress_only) : Stage_data(stage, egress_only) { + static_assert(sizeof(Stage_data) == sizeof(Stage), + "All non-static Stage fields must be in Stage_data"); + table_use[0] = table_use[1] = NONE; + stage_dep[0] = stage_dep[1] = NONE; + error_mode[0] = error_mode[1] = DefaultErrorMode::get(); + for (int i = 0; i < Target::SRAM_ROWS(egress_only ? EGRESS : INGRESS); i++) + for (int j = 0; j < Target::SRAM_REMOVED_COLUMNS(); j++) sram_use[i][j] = &invalid_rams; +} + +Stage::~Stage() { + for (auto *ref : all_refs) *ref = nullptr; +} + +int Stage::first_table(gress_t gress) { + for (auto &st : AsmStage::stages(gress)) { + int min_logical_id = INT_MAX; + for (auto tbl : st.tables) { + if (tbl->gress != gress) continue; + if (tbl->logical_id < 0) continue; // ignore phase 0 + if (tbl->logical_id < min_logical_id) min_logical_id = tbl->logical_id; + } + if (min_logical_id != INT_MAX) { + BUG_CHECK((min_logical_id & ~0xf) == 0); + return (st.stageno << 4) + min_logical_id; + } + } + return -1; +} + +Stage *Stage::stage(gress_t gress, int stageno) { + if (stageno < 0 || stageno >= AsmStage::stages(gress).size()) return nullptr; + return &AsmStage::stages(gress).at(stageno); +} + +Stage::Stage(Stage &&a) : Stage_data(std::move(a)) { + for (auto *ref : all_refs) *ref = this; +} + +bitvec Stage::imem_use_all() const { + bitvec rv; + for (auto &u : imem_use) rv |= u; + return rv; +} + +int Stage::tcam_delay(gress_t gress) const { + if (group_table_use[timing_thread(gress)] & Stage::USE_TCAM) return 2; + if (group_table_use[timing_thread(gress)] & Stage::USE_WIDE_SELECTOR) return 2; + return 0; +} + +int Stage::adr_dist_delay(gress_t gress) const { + if (group_table_use[timing_thread(gress)] & Stage::USE_SELECTOR) + return 8; + else if (group_table_use[timing_thread(gress)] & Stage::USE_STATEFUL_DIVIDE) + return 6; + else if (group_table_use[timing_thread(gress)] & Stage::USE_STATEFUL) + return 4; + else if (group_table_use[timing_thread(gress)] & Stage::USE_METER_LPF_RED) + return 4; + else + return 0; +} + +/* Calculate the meter_alu delay for a meter/stateful ALU based on both things + * used globally in the current stage group, and whether this ALU uses a divmod + * (in which case it will already have an extra 2-cycle delay */ +int Stage::meter_alu_delay(gress_t gress, bool uses_divmod) const { + if (group_table_use[timing_thread(gress)] & Stage::USE_SELECTOR) + return uses_divmod ? 2 : 4; + else if (group_table_use[timing_thread(gress)] & Stage::USE_STATEFUL_DIVIDE) + return uses_divmod ? 0 : 2; + else + return 0; +} + +int Stage::cycles_contribute_to_latency(gress_t gress) { + if (stage_dep[gress] == MATCH_DEP || stageno == 0) + return pipelength(gress); + else if (stage_dep[gress] == CONCURRENT && options.target == TOFINO) + return 1; + else + return 2; // action dependency +} + +int Stage::pipelength(gress_t gress) const { + return Target::MAU_BASE_DELAY() + tcam_delay(gress) + adr_dist_delay(gress); +} + +int Stage::pred_cycle(gress_t gress) const { + return Target::MAU_BASE_PREDICATION_DELAY() + tcam_delay(gress); +} + +void Stage::verify_have_mpr(std::string key, int line_number) { + if (!Target::HAS_MPR()) + error(line_number, "%s is not available on target %s.", key.c_str(), Target::name()); +} + +template +void Stage::write_common_regs(typename TARGET::mau_regs ®s) { + /* FIXME -- most of the values set here are 'placeholder' constants copied + * from build_pipeline_output_2.py in the compiler */ + auto &merge = regs.rams.match.merge; + auto &adrdist = regs.rams.match.adrdist; + // merge.exact_match_delay_config.exact_match_delay_ingress = tcam_delay(INGRESS); + // merge.exact_match_delay_config.exact_match_delay_egress = tcam_delay(EGRESS); + for (gress_t gress : Range(INGRESS, EGRESS)) { + if (tcam_delay(gress) > 0) { + merge.exact_match_delay_thread[0] |= 1U << gress; + merge.exact_match_delay_thread[1] |= 1U << gress; + merge.exact_match_delay_thread[2] |= 1U << gress; + } + regs.rams.match.adrdist.adr_dist_pipe_delay[gress][0] = + regs.rams.match.adrdist.adr_dist_pipe_delay[gress][1] = adr_dist_delay(gress); + regs.dp.action_output_delay[gress] = pipelength(gress) - 3; + regs.dp.pipelength_added_stages[gress] = pipelength(gress) - TARGET::MAU_BASE_DELAY; + if (stageno > 0 && stage_dep[gress] == MATCH_DEP) + regs.dp.match_ie_input_mux_sel |= 1 << gress; + } + + for (gress_t gress : Range(INGRESS, EGRESS)) { + if (stageno == 0) { + /* Credit is set to 2 - Every 512 cycles the credit is reset and every + * bubble request decrements this credit. Acts like a filter to cap bubble + * requests */ + adrdist.bubble_req_ctl[gress].bubble_req_fltr_crd = 0x2; + adrdist.bubble_req_ctl[gress].bubble_req_fltr_en = 0x1; + } + adrdist.bubble_req_ctl[gress].bubble_req_interval = 0x100; + adrdist.bubble_req_ctl[gress].bubble_req_en = 0x1; + adrdist.bubble_req_ctl[gress].bubble_req_interval_eop = 0x100; + adrdist.bubble_req_ctl[gress].bubble_req_en_eop = 0x1; + adrdist.bubble_req_ctl[gress].bubble_req_ext_fltr_en = 0x1; + } + + regs.dp.phv_fifo_enable.phv_fifo_ingress_action_output_enable = + stage_dep[INGRESS] != ACTION_DEP; + regs.dp.phv_fifo_enable.phv_fifo_egress_action_output_enable = stage_dep[EGRESS] != ACTION_DEP; + if (stageno != AsmStage::numstages() - 1) { + regs.dp.phv_fifo_enable.phv_fifo_ingress_final_output_enable = + this[1].stage_dep[INGRESS] == ACTION_DEP; + regs.dp.phv_fifo_enable.phv_fifo_egress_final_output_enable = + this[1].stage_dep[EGRESS] == ACTION_DEP; + } + + /* Error handling related */ + for (gress_t gress : Range(INGRESS, EGRESS)) error_mode[gress].write_regs(regs, this, gress); + + /*-------------------- + * Since a stats ALU enable bit is missing from mau_cfg_stats_alu_lt, need to make sure that for + * unused stats ALUs, they are programmed to point to a logical table that is either unused or + * to one that does not use a stats table. */ + + bool unused_stats_alus = false; + for (auto &salu : regs.cfg_regs.mau_cfg_stats_alu_lt) + if (!salu.modified()) unused_stats_alus = true; + if (unused_stats_alus) { + unsigned avail = 0xffff; + int no_stats = -1; + /* odd pattern of tests to replicate what the old compiler does */ + for (auto tbl : tables) { + avail &= ~(1U << tbl->logical_id); + if (no_stats < 0 && (!tbl->get_attached() || tbl->get_attached()->stats.empty())) + no_stats = tbl->logical_id; + } + if (avail) { + for (int i = 15; i >= 0; --i) + if ((avail >> i) & 1) { + no_stats = i; + break; + } + } + for (auto &salu : regs.cfg_regs.mau_cfg_stats_alu_lt) + if (!salu.modified()) salu = no_stats; + } +} + +void Stage::log_hashes(std::ofstream &out) const { + out << "+-----------------------------------------------------------+" << std::endl; + out << " Stage " << stageno << std::endl; + out << "+-----------------------------------------------------------+" << std::endl; + bool logged = false; + for (auto xbar : ixbar_use) { + if (xbar.first.type == InputXbar::Group::EXACT) { + for (auto use : xbar.second) { + if (use) logged |= use->log_hashes(out); + } + } + } + if (!logged) { + out << " Unused" << std::endl; + } + // Need to use other variables? + out << std::endl; +} + +template +void Stage::gen_gfm_json_info(REGS ®s, std::ostream &out) { + auto &hash = regs.dp.xbar_hash.hash; + auto &gfm = hash.galois_field_matrix; + out << &gfm << "\n"; + out << "Col : "; + for (auto c = 0; c < GALOIS_FIELD_MATRIX_COLUMNS; c++) { + out << std::setw(3) << c; + } + out << " | Row Parity \n"; + for (auto r = 0; r < gfm.size(); r++) { + out << "Row " << std::dec << r << ": \n"; + out << " Byte 0 :"; + unsigned byte0_parity = 0; + unsigned byte1_parity = 0; + for (auto c = 0; c < GALOIS_FIELD_MATRIX_COLUMNS; c++) { + out << std::setw(3) << std::hex << gfm[r][c].byte0; + byte0_parity ^= gfm[r][c].byte0; + } + out << " | " << std::setw(3) << parity(byte0_parity) << "\n"; + out << " Byte 1 :"; + for (auto c = 0; c < GALOIS_FIELD_MATRIX_COLUMNS; c++) { + out << std::setw(3) << std::hex << gfm[r][c].byte1; + byte1_parity ^= gfm[r][c].byte1; + } + out << " | " << std::setw(3) << parity(byte1_parity) << "\n"; + } + + out << "\n"; + auto &grp_enable = regs.dp.hashout_ctl.hash_parity_check_enable; + for (int grp = 0; grp < 8; grp++) { + out << "Hash Group : " << grp << "\n"; + out << "Hash Seed : "; + int seed_parity = 0; + bitvec hash_seed; + for (int bit = 51; bit >= 0; bit--) { + auto seed_bit = (hash.hash_seed[bit] >> grp) & 0x1; + hash_seed[bit] = seed_bit; + out << seed_bit; + seed_parity ^= seed_bit; + } + out << " (" << hash_seed << ")"; + out << "\n"; + auto seed_parity_enable = ((grp_enable >> grp) & 0x1) ? "True" : "False"; + out << "Hash Seed Parity Enable : " << seed_parity_enable; + out << "\n"; + out << "Hash Seed Parity : " << (seed_parity ? "Odd" : "Even"); + out << "\n"; + out << "\n"; + } +} + +template +void Stage::fixup_regs(REGS ®s) { + if (options.condense_json) { + // if any part of the gf matrix is enabled, we can't elide any part of it when + // generating .cfg.json, as otherwise walle will generate an invalid block write + if (options.gen_json && !regs.dp.xbar_hash.hash.galois_field_matrix.disabled()) + regs.dp.xbar_hash.hash.galois_field_matrix.enable(); + } + // Enable mapram_config and imem regs - + // These are cached by the driver, so if they are disabled they wont go + // into tofino.bin as dma block writes and driver will complain + // The driver needs the regs to do parity error correction at runtime and it + // checks for the base address of the register blocks to do a block DMA + // during tofino.bin download + regs.dp.imem.enable(); + for (int row = 0; row < SRAM_ROWS; row++) + for (int col = 0; col < MAPRAM_UNITS_PER_ROW; col++) + regs.rams.map_alu.row[row].adrmux.mapram_config[col].enable(); +} + +template +void Stage::output(json::map &ctxt_json, bool egress_only) { + auto *regs = new typename TARGET::mau_regs(); + declare_registers(regs, egress_only, stageno); + json::vector &ctxt_tables = ctxt_json["tables"]; + for (auto table : tables) { + table->write_regs(*regs); + table->gen_tbl_cfg(ctxt_tables); + if (auto gw = table->get_gateway()) gw->gen_tbl_cfg(ctxt_tables); + } + write_regs(*regs, egress_only); + + // Output GFM + if (gfm_out) gen_gfm_json_info(*regs, *gfm_out); + + if (options.condense_json) regs->disable_if_reset_value(); + + fixup_regs(*regs); + char buf[64]; + snprintf(buf, sizeof(buf), "regs.match_action_stage%s.%02x", egress_only ? ".egress" : "", + stageno); + if (error_count == 0 && options.gen_json) + regs->emit_json(*open_output("%s.cfg.json", buf), stageno); + auto NUM_STAGES = egress_only ? Target::NUM_EGRESS_STAGES() : Target::NUM_MAU_STAGES(); + if (stageno < NUM_STAGES) TopLevel::all->set_mau_stage(stageno, buf, regs, egress_only); + gen_mau_stage_characteristics(*regs, ctxt_json["mau_stage_characteristics"]); + gen_configuration_cache(*regs, ctxt_json["configuration_cache"]); + if (stageno == NUM_STAGES - 1 && Target::OUTPUT_STAGE_EXTENSION()) + gen_mau_stage_extension(*regs, ctxt_json["mau_stage_extension"]); +} + +template +void Stage::gen_mau_stage_characteristics(REGS ®s, json::vector &stg_characteristics) { + for (gress_t gress : Range(INGRESS, EGRESS)) { + json::map anon; + anon["stage"] = stageno; + anon["gress"] = P4Table::direction_name(gress); + anon["match_dependent"] = (regs.dp.cur_stage_dependency_on_prev[gress] == 0) ? true : false; + anon["clock_cycles"] = pipelength(gress); + anon["predication_cycle"] = pred_cycle(gress); + anon["cycles_contribute_to_latency"] = cycles_contribute_to_latency(gress); + stg_characteristics.push_back(std::move(anon)); + } +} + +template +void Stage::gen_configuration_cache(REGS ®s, json::vector &cfg_cache) { + BUG(); // Must be specialized for target -- no generic implementation +} + +template +void Stage::gen_configuration_cache_common(REGS ®s, json::vector &cfg_cache) { + std::string reg_fqname; + std::string reg_name; + unsigned reg_value; + std::string reg_value_str; + unsigned reg_width = 8; // this means number of hex characters + + // meter_sweep_ctl + auto &meter_sweep_ctl = regs.rams.match.adrdist.meter_sweep_ctl; + for (int i = 0; i < 4; i++) { + reg_fqname = "mau[" + std::to_string(stageno) + "].rams.match.adrdist.meter_sweep_ctl[" + + std::to_string(i) + "]"; + if (options.match_compiler) { // FIXME: Temp fix to match glass typo + reg_fqname = "mau[" + std::to_string(stageno) + + "].rams.match.adrdist.meter_sweep_ctl.meter_sweep_ctl[" + + std::to_string(i) + "]"; + } + reg_name = "stage_" + std::to_string(stageno) + "_meter_sweep_ctl_" + std::to_string(i); + reg_value = (meter_sweep_ctl[i].meter_sweep_en & 0x00000001) | + ((meter_sweep_ctl[i].meter_sweep_offset & 0x0000003F) << 1) | + ((meter_sweep_ctl[i].meter_sweep_size & 0x0000003F) << 7) | + ((meter_sweep_ctl[i].meter_sweep_remove_hole_pos & 0x00000003) << 13) | + ((meter_sweep_ctl[i].meter_sweep_remove_hole_en & 0x00000001) << 16) | + ((meter_sweep_ctl[i].meter_sweep_interval & 0x0000001F) << 17); + if ((reg_value != 0) || (options.match_compiler)) { + reg_value_str = int_to_hex_string(reg_value, reg_width); + add_cfg_reg(cfg_cache, reg_fqname, reg_name, reg_value_str); + } + } + + // meter_ctl is different for Tofino and Tofino2, so it is added in + // specialized functions. + + // statistics_ctl + auto &statistics_ctl = regs.rams.map_alu.stats_wrap; + for (int i = 0; i < 4; i++) { + reg_fqname = "mau[" + std::to_string(stageno) + "].rams.map_alu.stats_wrap[" + + std::to_string(i) + "]" + ".stats.statistics_ctl"; + reg_name = "stage_" + std::to_string(stageno) + "_statistics_ctl_" + std::to_string(i); + reg_value = + (statistics_ctl[i].stats.statistics_ctl.stats_entries_per_word & 0x00000007) | + ((statistics_ctl[i].stats.statistics_ctl.stats_process_bytes & 0x00000001) << 3) | + ((statistics_ctl[i].stats.statistics_ctl.stats_process_packets & 0x00000001) << 4) | + ((statistics_ctl[i].stats.statistics_ctl.lrt_enable & 0x00000001) << 5) | + ((statistics_ctl[i].stats.statistics_ctl.stats_alu_egress & 0x00000001) << 6) | + ((statistics_ctl[i].stats.statistics_ctl.stats_bytecount_adjust & 0x00003FFF) << 7) | + ((statistics_ctl[i].stats.statistics_ctl.stats_alu_error_enable & 0x00000001) << 21); + if ((reg_value != 0) || (options.match_compiler)) { + reg_value_str = int_to_hex_string(reg_value, reg_width); + add_cfg_reg(cfg_cache, reg_fqname, reg_name, reg_value_str); + } + } + + // match_input_xbar_din_power_ctl + auto &mixdpctl = regs.dp.match_input_xbar_din_power_ctl; + reg_value_str = ""; + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 16; j++) { + reg_value = mixdpctl[i][j]; + reg_value_str = reg_value_str + int_to_hex_string(reg_value, reg_width); + } + } + if (!check_zero_string(reg_value_str) || options.match_compiler) { + reg_fqname = "mau[" + std::to_string(stageno) + "].dp.match_input_xbar_din_power_ctl"; + reg_name = "stage_" + std::to_string(stageno) + "_match_input_xbar_din_power_ctl"; + add_cfg_reg(cfg_cache, reg_fqname, reg_name, reg_value_str); + } + + // hash_seed + auto &hash_seed = regs.dp.xbar_hash.hash.hash_seed; + reg_value_str = ""; + for (int i = 0; i < 52; i++) { + reg_value = hash_seed[i]; + reg_value_str = reg_value_str + int_to_hex_string(reg_value, reg_width); + } + if (!check_zero_string(reg_value_str) || options.match_compiler) { + reg_fqname = "mau[" + std::to_string(stageno) + "].dp.xbar_hash.hash.hash_seed"; + reg_name = "stage_" + std::to_string(stageno) + "_hash_seed"; + add_cfg_reg(cfg_cache, reg_fqname, reg_name, reg_value_str); + } + + // parity_group_mask + auto &parity_group_mask = regs.dp.xbar_hash.hash.parity_group_mask; + reg_value_str = ""; + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 2; j++) { + reg_value = parity_group_mask[i][j]; + reg_value_str = reg_value_str + int_to_hex_string(reg_value, reg_width); + } + } + if (!check_zero_string(reg_value_str) || options.match_compiler) { + reg_fqname = "mau[" + std::to_string(stageno) + "].dp.xbar_hash.hash.parity_group_mask"; + reg_name = "stage_" + std::to_string(stageno) + "_parity_group_mask"; + add_cfg_reg(cfg_cache, reg_fqname, reg_name, reg_value_str); + } +} + +template +void Stage::write_teop_regs(REGS ®s) { + BUG_CHECK(Target::SUPPORT_TRUE_EOP(), "teop not supported on target"); + // Set teop bus delay regs on current stage if previous stage is driving teop + for (auto t : teop) { + if (t.second.first && t.second.second < stageno) { + auto delay_en = (stage_dep[EGRESS] != Stage::ACTION_DEP); + if (delay_en) { + auto delay = pipelength(EGRESS) - 4; + auto &adrdist = regs.rams.match.adrdist; + adrdist.teop_bus_ctl[t.first].teop_bus_ctl_delay = delay; + adrdist.teop_bus_ctl[t.first].teop_bus_ctl_delay_en = delay_en; + } + } + } +} diff --git a/backends/tofino/bf-asm/stage.h b/backends/tofino/bf-asm/stage.h new file mode 100644 index 00000000000..89baab5c9f2 --- /dev/null +++ b/backends/tofino/bf-asm/stage.h @@ -0,0 +1,227 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_STAGE_H_ +#define BF_ASM_STAGE_H_ + +#include +#include + +#include "alloc.h" +#include "bitvec.h" +#include "error_mode.h" +#include "input_xbar.h" +#include "tables.h" + +class Stage_data { + /* we encapsulate all the Stage non-static fields in a base class to automate the + * generation of the move construtor properly */ + public: + int stageno; + std::vector

tables; + std::set all_refs; + BFN::Alloc2Dbase
sram_use; + BFN::Alloc2D
sram_search_bus_use; + BFN::Alloc3Dbase
stm_hbus_use; + BFN::Alloc2D
match_result_bus_use; + BFN::Alloc2D
mapram_use; + BFN::Alloc2Dbase
tcam_use; + BFN::Alloc2Dbase
tcam_match_bus_use; + BFN::Alloc2D, TCAM_ROWS, 2> tcam_byte_group_use; + BFN::Alloc1Dbase
local_tind_use; + BFN::Alloc2D
tcam_indirect_bus_use; + BFN::Alloc2D gw_unit_use; + BFN::Alloc2D gw_payload_use; + BFN::Alloc1D
logical_id_use; + BFN::Alloc1D
physical_id_use; + BFN::Alloc1D
tcam_id_use; + ordered_map> ixbar_use; + BFN::Alloc1D
tcam_ixbar_input; + BFN::Alloc1Dbase> hash_table_use; + BFN::Alloc1Dbase> hash_group_use; + BFN::Alloc1D, 6> hash_dist_use; + BFN::Alloc1Dbase action_unit_use; + BFN::Alloc1Dbase dp_unit_use; + BFN::Alloc1D
action_bus_use; + BFN::Alloc1D
action_data_use, meter_bus_use, stats_bus_use, + selector_adr_bus_use, overflow_bus_use; + BFN::Alloc1D
idletime_bus_use; + bitvec action_bus_use_bit_mask; + BFN::Alloc2D imem_addr_use; + bitvec imem_use[ACTION_IMEM_SLOTS]; + BFN::Alloc1D long_branch_use; + unsigned long_branch_thread[3] = {0}; + unsigned long_branch_terminate = 0; + + // for timing, ghost thread is tied to ingress, so we track ghost as ingress here + enum { + USE_TCAM = 1, + USE_STATEFUL = 4, + USE_METER = 8, + USE_METER_LPF_RED = 16, + USE_SELECTOR = 32, + USE_WIDE_SELECTOR = 64, + USE_STATEFUL_DIVIDE = 128 + }; + int /* enum */ table_use[2], group_table_use[2]; + + enum { NONE = 0, CONCURRENT = 1, ACTION_DEP = 2, MATCH_DEP = 3 } stage_dep[2]; + bitvec match_use[3], action_use[3], action_set[3]; + + // there's no error mode registers for ghost thread, so we don't allow it to be set + ErrorMode error_mode[2]; + + // MPR stage config + int mpr_stage_id[3] = {0}; // per-gress + int mpr_always_run = 0; + int mpr_bus_dep_glob_exec[3] = {0}; + int mpr_bus_dep_long_branch[3] = {0}; + // per gress, per logical table + BFN::Alloc2D mpr_next_table_lut; + // per global execute bit + BFN::Alloc1D mpr_glob_exec_lut; + // per long branch tag + BFN::Alloc1D mpr_long_brch_lut; + + int pass1_logical_id = -1, pass1_tcam_id = -1; + + // True egress accounting (4 buses) Tofino2 + static std::map> teop; + + protected: + Stage_data(int stage, bool egress_only) + : stageno(stage), + sram_use(Target::SRAM_ROWS(egress_only ? EGRESS : INGRESS), Target::SRAM_UNITS_PER_ROW()), + stm_hbus_use(Target::SRAM_ROWS(egress_only ? EGRESS : INGRESS), + Target::SRAM_HBUS_SECTIONS_PER_STAGE(), Target::SRAM_HBUSSES_PER_ROW()), + tcam_use(Target::TCAM_ROWS(), Target::TCAM_UNITS_PER_ROW()), + tcam_match_bus_use(Target::TCAM_ROWS(), Target::TCAM_MATCH_BUSSES()), + local_tind_use(Target::LOCAL_TIND_UNITS()), + hash_table_use(Target::EXACT_HASH_TABLES()), + hash_group_use(Target::EXACT_HASH_GROUPS()), + action_unit_use(Target::ARAM_UNITS_PER_STAGE()), + dp_unit_use(Target::DP_UNITS_PER_STAGE()) {} + Stage_data(const Stage_data &) = delete; + Stage_data(Stage_data &&) = default; + ~Stage_data() {} +}; + +class Stage : public Stage_data { + public: + static unsigned char action_bus_slot_map[ACTION_DATA_BUS_BYTES]; + static unsigned char action_bus_slot_size[ACTION_DATA_BUS_SLOTS]; // size in bits + + explicit Stage(int stageno, bool egress_only); + Stage(const Stage &) = delete; + Stage(Stage &&); + ~Stage(); + template + void output(json::map &ctxt_json, bool egress_only = false); + template + void fixup_regs(REGS ®s); + template + void gen_configuration_cache_common(REGS ®s, json::vector &cfg_cache); + template + void gen_configuration_cache(REGS ®s, json::vector &cfg_cache); + template + void gen_gfm_json_info(REGS ®s, std::ostream &out); + template + void gen_mau_stage_characteristics(REGS ®s, json::vector &stg_characteristics); + template + void gen_mau_stage_extension(REGS ®s, json::map &extend); + template + void write_regs(REGS ®s, bool egress_only); + template + void write_common_regs(typename TARGET::mau_regs ®s); + template + void write_teop_regs(REGS ®s); + int adr_dist_delay(gress_t gress) const; + int meter_alu_delay(gress_t gress, bool uses_divmod) const; + int pipelength(gress_t gress) const; + int pred_cycle(gress_t gress) const; + int tcam_delay(gress_t gress) const; + int cycles_contribute_to_latency(gress_t gress); + void verify_have_mpr(std::string key, int line_number); + static int first_table(gress_t gress); + static unsigned end_of_pipe() { return Target::END_OF_PIPE(); } + static Stage *stage(gress_t gress, int stageno); + void log_hashes(std::ofstream &out) const; + bitvec imem_use_all() const; +}; + +class AsmStage : public Section { + void start(int lineno, VECTOR(value_t) args); + void input(VECTOR(value_t) args, value_t data); + void output(json::map &); + + /// Propagates group_table_use to adjacent stages that are not match-dependent. + void propagate_group_table_use(); + + unsigned compute_latency(gress_t gress); + AsmStage(); + ~AsmStage() {} + std::vector pipe; + static AsmStage singleton_object; + bitvec stages_seen[NUM_GRESS_T]; + + public: + void process(); + static int numstages() { return singleton_object.pipe.size(); } + static std::vector &stages(gress_t gress) { return singleton_object.pipe; } + + // for gtest + void reset_stage(Stage &stage) { + for (auto &tbl : stage.tables) tbl->all->clear(); + stage.tables.clear(); + stage.all_refs.clear(); + stage.sram_use.clear(); + stage.sram_search_bus_use.clear(); + stage.stm_hbus_use.clear(); + stage.match_result_bus_use.clear(); + stage.mapram_use.clear(); + stage.tcam_use.clear(); + stage.tcam_match_bus_use.clear(); + stage.tcam_byte_group_use.clear(); + stage.gw_unit_use.clear(); + stage.gw_payload_use.clear(); + stage.logical_id_use.clear(); + stage.physical_id_use.clear(); + stage.tcam_id_use.clear(); + stage.ixbar_use.clear(); + stage.tcam_ixbar_input.clear(); + stage.hash_table_use.clear(); + stage.hash_group_use.clear(); + stage.hash_dist_use.clear(); + stage.action_bus_use.clear(); + stage.action_data_use.clear(); + stage.meter_bus_use.clear(); + stage.stats_bus_use.clear(); + stage.selector_adr_bus_use.clear(); + stage.overflow_bus_use.clear(); + stage.idletime_bus_use.clear(); + stage.imem_addr_use.clear(); + stage.long_branch_use.clear(); + } + + void reset() { + stages_seen[INGRESS].clear(); + stages_seen[EGRESS].clear(); + for (auto &stage : pipe) reset_stage(stage); + } +}; + +#endif /* BF_ASM_STAGE_H_ */ diff --git a/backends/tofino/bf-asm/stateful.cpp b/backends/tofino/bf-asm/stateful.cpp new file mode 100644 index 00000000000..b655a68baec --- /dev/null +++ b/backends/tofino/bf-asm/stateful.cpp @@ -0,0 +1,678 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "tofino/stateful.h" + +#include "algorithm.h" +#include "data_switchbox.h" +#include "input_xbar.h" +#include "instruction.h" +#include "jbay/stateful.h" +#include "misc.h" +#include "stage.h" +#include "tables.h" + +void StatefulTable::parse_register_params(int idx, const value_t &val) { + if (idx < 0 || idx > Target::STATEFUL_REGFILE_ROWS()) + error(lineno, + "Index out of range of the number of the register file rows (%d). " + "Reduce the number of large constants or RegisterParams.", + Target::STATEFUL_REGFILE_ROWS()); + if (const_vals.size() <= size_t(idx)) const_vals.resize(idx + 1); + if (CHECKTYPE(val, tMAP) && val.map.size == 1) + if (CHECKTYPE(val.map.data->key, tSTR) && CHECKTYPE(val.map.data->value, tINT)) + const_vals[idx] = std::move(const_info_t(val.lineno, val.map.data->value.i, true, + std::string(val.map.data->key.s))); +} + +void StatefulTable::setup(VECTOR(pair_t) & data) { + common_init_setup(data, false, P4Table::Stateful); + if (!format) error(lineno, "No format specified in table %s", name()); + for (auto &kv : MapIterChecked(data, true)) { + if (common_setup(kv, data, P4Table::Stateful)) { + } else if (kv.key == "initial_value") { + if (CHECKTYPE(kv.value, tMAP)) { + for (auto &v : kv.value.map) { + if (v.key == "lo") { + if (CHECKTYPE2(v.value, tINT, tBIGINT)) { + if (v.value.type == tINT) { + initial_value_lo = v.value.i; + } else { + initial_value_lo = v.value.bigi.data[0]; + if (v.value.bigi.size > 1) initial_value_hi = v.value.bigi.data[1]; + } + } + } else if (v.key == "hi") { + if (CHECKTYPE(v.value, tINT)) initial_value_hi = v.value.i; + } + } + } + } else if (kv.key == "input_xbar") { + if (CHECKTYPE(kv.value, tMAP)) + input_xbar.emplace_back(InputXbar::create(this, false, kv.key, kv.value.map)); + } else if (kv.key == "data_bytemask") { + if (CHECKTYPE(kv.value, tINT)) data_bytemask = kv.value.i; + } else if (kv.key == "hash_bytemask") { + if (CHECKTYPE(kv.value, tINT)) hash_bytemask = kv.value.i; + } else if (kv.key == "hash_dist") { + /* parsed in common_init_setup */ + } else if (kv.key == "actions") { + if (CHECKTYPE(kv.value, tMAP)) actions.reset(new Actions(this, kv.value.map)); + } else if (kv.key == "selection_table") { + bound_selector = kv.value; + } else if (kv.key == "register_params") { + if (!CHECKTYPE2(kv.value, tVEC, tMAP)) continue; + if (kv.value.type == tVEC) { + for (auto &v : kv.value.vec) parse_register_params(const_vals.size(), v); + } else { + for (auto &v : kv.value.map) + if (CHECKTYPE(v.key, tINT)) parse_register_params(v.key.i, v.value); + } + } else if (kv.key == "math_table") { + if (!CHECKTYPE(kv.value, tMAP)) continue; + math_table.lineno = kv.value.lineno; + for (auto &v : kv.value.map) { + if (v.key == "data") { + if (!CHECKTYPE2(v.value, tVEC, tMAP)) continue; + if (v.value.type == tVEC) { + parse_vector(math_table.data, v.value); + } else { + math_table.data.resize(16); + for (auto &d : v.value.map) + if (CHECKTYPE(d.key, tINT) && CHECKTYPE(d.value, tINT)) { + if (d.key.i < 0 || d.key.i >= 16) + error(v.key.lineno, "invalid index for math_table"); + else + math_table.data[v.key.i] = v.value.i; + } + } + } else if (v.key == "invert") { + math_table.invert = get_bool(v.value); + } else if (v.key == "shift") { + if (CHECKTYPE(v.value, tINT)) math_table.shift = v.value.i; + } else if (v.key == "scale") { + if (CHECKTYPE(v.value, tINT)) math_table.scale = v.value.i; + } else if (v.key.type == tINT && v.key.i >= 0 && v.key.i < 16) { + if (CHECKTYPE(v.value, tINT)) math_table.data[v.key.i] = v.value.i; + } else { + error(v.key.lineno, "Unknow item %s in math_table", value_desc(kv.key)); + } + } +#if HAVE_JBAY + } else if (options.target >= JBAY && setup_jbay(kv)) { + /* jbay specific extensions done in setup_jbay */ + // FIXME -- these should probably be based on individual Target::FEATURE() queries +#endif /* HAVE_JBAY */ + } else if (kv.key == "log_vpn") { + logvpn_lineno = kv.value.lineno; + if (CHECKTYPE2(kv.value, tINT, tRANGE)) { + if (kv.value.type == tINT) { + logvpn_min = logvpn_max = kv.value.i; + } else { + logvpn_min = kv.value.lo; + logvpn_max = kv.value.hi; + } + } + } else if (kv.key == "pred_shift") { + if (CHECKTYPE(kv.value, tINT)) + if ((pred_shift = kv.value.i) < 0 || pred_shift >= 32 || (pred_shift & 3) != 0) + error(kv.value.lineno, "Invalid pred_shift value %d: %s", pred_shift, + pred_shift < 0 ? "negative" + : pred_shift >= 32 ? "too large" + : "must be a mulitple of 4"); + } else if (kv.key == "pred_comb_shift") { + if (CHECKTYPE(kv.value, tINT)) + if ((pred_comb_shift = kv.value.i) < 0 || pred_comb_shift >= 32) + error(kv.value.lineno, "Invalid pred_comb_shift value %d: %s", pred_comb_shift, + pred_comb_shift < 0 ? "negative" : "too large"); + } else if (kv.key == "busy_value" && Target::SUPPORT_SALU_FAST_CLEAR()) { + if (CHECKTYPE(kv.value, tINT)) busy_value = kv.value.i; + } else if (kv.key == "clear_value" && Target::SUPPORT_SALU_FAST_CLEAR()) { + if (CHECKTYPE2(kv.value, tINT, tBIGINT)) + clear_value = get_bitvec(kv.value, 128, "Value too large for 128 bits"); + } else { + warning(kv.key.lineno, "ignoring unknown item %s in table %s", value_desc(kv.key), + name()); + } + } +} + +bool match_table_layouts(Table *t1, Table *t2) { + if (t1->layout.size() != t2->layout.size()) return false; + auto it = t2->layout.begin(); + for (auto &row : t1->layout) { + if (row.row != it->row) return false; + if (row.memunits != it->memunits) return false; + if (row.maprams.empty()) row.maprams = it->maprams; + if (row.maprams != it->maprams) return false; + ++it; + } + return true; +} + +void StatefulTable::MathTable::check() { + if (data.size() > 16) error(lineno, "math table only has 16 data entries"); + data.resize(16); + for (auto &v : data) + if (v < 0 || v >= 256) error(lineno, "%d out of range for math_table data", v); + if (shift < -1 || shift > 1) error(lineno, "%d out of range for math_table shift", shift); + if (scale < -32 || scale >= 32) error(lineno, "%d out of range for math_table scale", scale); +} + +void StatefulTable::pass1() { + LOG1("### Stateful table " << name() << " pass1 " << loc()); + if (!p4_table) + p4_table = P4Table::alloc(P4Table::Stateful, this); + else + p4_table->check(this); + alloc_vpns(); + if (bound_selector.check()) { + if (layout.empty()) + layout = bound_selector->layout; + else if (!match_table_layouts(this, bound_selector)) + error(layout[0].lineno, "Layout in %s does not match selector %s", name(), + bound_selector->name()); + // Add a back reference to this table + if (!bound_selector->get_stateful()) bound_selector->set_stateful(this); + if (logical_id < 0) logical_id = bound_selector->logical_id; + } else { + alloc_maprams(); + if (Target::SRAM_GLOBAL_ACCESS()) + alloc_global_srams(); + else + alloc_rams(true, stage->sram_use); + } + std::sort(layout.begin(), layout.end(), + [](const Layout &a, const Layout &b) -> bool { return a.row > b.row; }); + stage->table_use[timing_thread(gress)] |= Stage::USE_STATEFUL; + for (auto &hd : hash_dist) hd.pass1(this, HashDistribution::OTHER, false); + for (auto &ixb : input_xbar) ixb->pass1(); + int prev_row = -1; + for (auto &row : layout) { + if (prev_row >= 0) + need_bus(lineno, stage->overflow_bus_use, row.row, "Overflow"); + else + need_bus(lineno, stage->meter_bus_use, row.row, "Meter data"); + for (int r = (row.row + 1) | 1; r < prev_row; r += 2) + need_bus(lineno, stage->overflow_bus_use, r, "Overflow"); + prev_row = row.row; + } + unsigned idx = 0, size = 0; + for (auto &fld : *format) { + switch (idx++) { + case 0: + if ((size = fld.second.size) != 1 && size != 8 && size != 16 && size != 32 && + ((size != 64 && size != 128) || options.target == TOFINO)) { + error(format->lineno, "invalid size %d for stateful format field %s", size, + fld.first.c_str()); + break; + } + break; + case 1: + if (size != fld.second.size) + error(format->lineno, "stateful fields must be the same size"); + else if (size == 1) + error(format->lineno, "one bit stateful tables can only have a single field"); + break; + default: + error(format->lineno, "only two fields allowed in a stateful table"); + } + } + if ((idx == 2) && (format->size == 2 * size)) dual_mode = true; + if (actions) { + actions->pass1(this); + bool stop = false; + for (auto &act : *actions) { + for (auto &inst : act.instr) { + if (inst->salu_output()) { + need_bus(layout.at(0).lineno, stage->action_data_use, home_row(), + "action data"); + stop = true; + break; + } + } + if (stop) break; + } + } else { + error(lineno, "No actions in stateful table %s", name()); + } + if (math_table) math_table.check(); + for (auto &r : sbus_learn) + if (r.check() && (r->table_type() != STATEFUL || r->stage != stage)) + error(r.lineno, "%s is not a stateful table in the same stage as %s", r->name(), + name()); + for (auto &r : sbus_match) + if (r.check() && (r->table_type() != STATEFUL || r->stage != stage)) + error(r.lineno, "%s is not a stateful table in the same stage as %s", r->name(), + name()); + Synth2Port::pass1(); + if (underflow_action.set() && (!actions || !actions->exists(underflow_action.name))) + error(underflow_action.lineno, "No action %s in table %s", underflow_action.name.c_str(), + name()); + if (overflow_action.set() && (!actions || !actions->exists(overflow_action.name))) + error(overflow_action.lineno, "No action %s in table %s", overflow_action.name.c_str(), + name()); +} + +int StatefulTable::get_const(int lineno, int64_t v) { + size_t rv; + for (rv = 0; rv < const_vals.size(); rv++) { + // Skip constants allocated for RegisterParams as they cannot be shared + // as they are subject to change. + if (const_vals[rv].is_param) continue; + if (const_vals[rv].value == v) break; + } + if (rv == const_vals.size()) { + if (rv >= Target::STATEFUL_REGFILE_ROWS()) + error(lineno, + "Out of the number of register file rows (%d). Reduce the number" + " of large constants or RegisterParams.", + Target::STATEFUL_REGFILE_ROWS()); + const_vals.push_back(std::move(const_info_t(lineno, v))); + } + return rv; +} + +void StatefulTable::pass2() { + LOG1("### Stateful table " << name() << " pass2 " << loc()); + for (auto &ixb : input_xbar) ixb->pass2(); + if (actions) actions->stateful_pass2(this); + if (stateful_counter_mode) { + if (logvpn_min < 0) { + layout_vpn_bounds(logvpn_min, logvpn_max, true); + } else if (!offset_vpn) { + int min, max; + layout_vpn_bounds(min, max, true); + if (logvpn_min < min || logvpn_max > max) + error(logvpn_lineno, "log_vpn out of range (%d..%d)", min, max); + } + } + + for (auto &ixb : input_xbar) { + if (!data_bytemask && !hash_bytemask) { + hash_bytemask = bitmask2bytemask(ixb->hash_group_bituse()) & phv_byte_mask; + // should we also mask off bits not set in the ixbar of this table? + // as long as the compiler explicitly zeroes everything in the hash + // that needs to be zero, it should be ok. + data_bytemask = phv_byte_mask & ~hash_bytemask; + } + } + if (input_xbar.empty()) { + if (data_bytemask || hash_bytemask) { + error(lineno, "No input_xbar in %s, but %s is present", name(), + data_bytemask ? "data_bytemask" : "hash_bytemask"); + } else if (phv_byte_mask) { + error(lineno, "No input_xbar in %s, but raw phv_%s use is present", name(), + (phv_byte_mask & 1) ? "lo" : "hi"); + } + } + for (auto &hd : hash_dist) hd.pass2(this); +} + +void StatefulTable::pass3() { LOG1("### Stateful table " << name() << " pass3 " << loc()); } + +int StatefulTable::direct_shiftcount() const { + return 64 + METER_ADDRESS_ZERO_PAD - address_shift(); +} + +int StatefulTable::indirect_shiftcount() const { return METER_ADDRESS_ZERO_PAD - address_shift(); } + +int StatefulTable::address_shift() const { return ceil_log2(format->size) - meter_adr_shift; } + +unsigned StatefulTable::per_flow_enable_bit(MatchTable *match) const { + if (!per_flow_enable) + return METER_ADDRESS_BITS - METER_TYPE_BITS - 1; + else + return AttachedTable::per_flow_enable_bit(match); +} + +unsigned StatefulTable::determine_shiftcount(Table::Call &call, int group, unsigned word, + int tcam_shift) const { + return determine_meter_shiftcount(call, group, word, tcam_shift); +} + +/** Determine which stateful action a given table action invokes (if any) + * In theory, the stateful action to run could be an action data param or even come from + * hash_dist (so the action could run any stateful action), but currently the compiler will + * never geneate such code. If we add that ability, we'll need to revisit this, and need + * to revise the context.json appropriately. Currently, this code will return a nullptr + * for such bfa code (meter_type_arg would be a Field or HashDist) + */ +Table::Actions::Action *StatefulTable::action_for_table_action(const MatchTable *tbl, + const Actions::Action *act) const { + // Check for action args to determine which stateful action is + // called. If no args are present skip as the action does not + // invoke stateful + if (indirect) { + for (auto att : act->attached) { + if (att != this) continue; + if (att.args.size() == 0) continue; + auto meter_type_arg = att.args[0]; + if (meter_type_arg.type == Call::Arg::Name) { + // Check if stateful has this called action + return actions->action(meter_type_arg.name()); + } else if (meter_type_arg.type == Call::Arg::Const) { + int index = -1; + switch (meter_type_arg.value()) { + case STATEFUL_INSTRUCTION_0: + index = 0; + break; + case STATEFUL_INSTRUCTION_1: + index = 1; + break; + case STATEFUL_INSTRUCTION_2: + index = 2; + break; + case STATEFUL_INSTRUCTION_3: + index = 3; + break; + } + if (index == -1) continue; + auto it = actions->begin(); + while (it != actions->end() && index > 0) { + --index; + ++it; + } + if (it != actions->end()) return &(*it); + } + } + } else { + // If stateful is direct, all user defined actions will + // invoke stateful except for the miss action. This is + // defined as 'default_only' in p4, if not the compiler + // generates a default_only action and adds it + // FIXME: Brig should add these generated actions as + // default_only in assembly + if (!((act->name == tbl->default_action) && tbl->default_only_action)) { + // Direct has only one action + if (actions) return &*actions->begin(); + } + } + return nullptr; +} + +template +void StatefulTable::write_action_regs_vt(REGS ®s, const Actions::Action *act) { + int meter_alu = layout[0].row / 4U; + auto &stateful_regs = regs.rams.map_alu.meter_group[meter_alu].stateful; + auto &salu_instr_common = stateful_regs.salu_instr_common[act->code]; + if (act->minmax_use) { + salu_instr_common.salu_datasize = 7; + salu_instr_common.salu_op_dual = is_dual_mode(); + } else if (is_dual_mode() || p4c_5192_workaround(act)) { + salu_instr_common.salu_datasize = format->log2size - 1; + salu_instr_common.salu_op_dual = 1; + } else { + salu_instr_common.salu_datasize = format->log2size; + } +} + +template +void StatefulTable::write_merge_regs_vt(REGS ®s, MatchTable *match, int type, int bus, + const std::vector &args) { + auto &merge = regs.rams.match.merge; + unsigned adr_mask = 0U; + unsigned per_entry_en_mux_ctl = 0U; + unsigned adr_default = 0U; + unsigned meter_type_position = 0U; + METER_ACCESS_TYPE default_type = match->default_meter_access_type(true); + AttachedTable::determine_meter_merge_regs(match, type, bus, args, default_type, adr_mask, + per_entry_en_mux_ctl, adr_default, + meter_type_position); + merge.mau_meter_adr_default[type][bus] = adr_default; + merge.mau_meter_adr_mask[type][bus] = adr_mask; + merge.mau_meter_adr_per_entry_en_mux_ctl[type][bus] = per_entry_en_mux_ctl; + merge.mau_meter_adr_type_position[type][bus] = meter_type_position; +} + +template +void StatefulTable::write_regs_vt(REGS ®s) { + LOG1("### Stateful table " << name() << " write_regs " << loc()); + // FIXME -- factor common AttachedTable::write_regs + // FIXME -- factor common Synth2Port::write_regs + // FIXME -- factor common CounterTable::write_regs + // FIXME -- factor common MeterTable::write_regs + for (auto &ixb : input_xbar) ixb->write_regs(regs); + Layout *home = &layout[0]; + bool push_on_overflow = false; + auto &map_alu = regs.rams.map_alu; + auto &merge = regs.rams.match.merge; + auto &adrdist = regs.rams.match.adrdist; + DataSwitchboxSetup swbox(regs, this); + int minvpn, maxvpn; + layout_vpn_bounds(minvpn, maxvpn, true); + if (!bound_selector) { + for (Layout &logical_row : layout) { + unsigned row = logical_row.row / 2U; + unsigned side = logical_row.row & 1; /* 0 == left 1 == right */ + BUG_CHECK(side == 1); /* no map rams or alus on left side anymore */ + auto vpn = logical_row.vpns.begin(); + auto mapram = logical_row.maprams.begin(); + auto &map_alu_row = map_alu.row[row]; + LOG2("# DataSwitchbox.setup(" << row << ") home=" << home->row / 2U); + swbox.setup_row(row); + for (auto &memunit : logical_row.memunits) { + BUG_CHECK(memunit.stage == INT_MIN && memunit.row == logical_row.row, + "bogus %s in logical row %d", memunit.desc(), logical_row.row); + unsigned col = memunit.col + 6 * side; + swbox.setup_row_col(row, col, *vpn); + write_mapram_regs(regs, row, *mapram, *vpn, MapRam::STATEFUL); + if (gress) + regs.cfg_regs.mau_cfg_uram_thread[col / 4U] |= 1U << (col % 4U * 8U + row); + ++mapram, ++vpn; + } + /* FIXME -- factor with selector/meter? */ + if (&logical_row == home) { + auto &vh_adr_xbar = regs.rams.array.row[row].vh_adr_xbar; + auto &data_ctl = regs.rams.array.row[row].vh_xbar[side].stateful_meter_alu_data_ctl; + for (auto &ixb : input_xbar) { + if (hash_bytemask != 0U) { + vh_adr_xbar.alu_hashdata_bytemask.alu_hashdata_bytemask_right = + hash_bytemask; + setup_muxctl(vh_adr_xbar.exactmatch_row_hashadr_xbar_ctl[2 + side], + ixb->hash_group()); + } + if (data_bytemask != 0) { + data_ctl.stateful_meter_alu_data_bytemask = data_bytemask; + data_ctl.stateful_meter_alu_data_xbar_ctl = 8 | ixb->match_group(); + } + } + map_alu_row.i2portctl.synth2port_vpn_ctl.synth2port_vpn_base = minvpn; + map_alu_row.i2portctl.synth2port_vpn_ctl.synth2port_vpn_limit = maxvpn; + int meter_group_index = row / 2U; + auto &delay_ctl = map_alu.meter_alu_group_data_delay_ctl[meter_group_index]; + delay_ctl.meter_alu_right_group_delay = + Target::METER_ALU_GROUP_DATA_DELAY() + row / 4 + stage->tcam_delay(gress); + delay_ctl.meter_alu_right_group_enable = + meter_alu_fifo_enable_from_mask(regs, phv_byte_mask); + auto &error_ctl = map_alu.meter_alu_group_error_ctl[meter_group_index]; + error_ctl.meter_alu_group_ecc_error_enable = 1; + if (output_used) { + auto &action_ctl = map_alu.meter_alu_group_action_ctl[meter_group_index]; + action_ctl.right_alu_action_enable = 1; + action_ctl.right_alu_action_delay = stage->meter_alu_delay(gress, divmod_used); + auto &switch_ctl = regs.rams.array.switchbox.row[row].ctl; + switch_ctl.r_action_o_mux_select.r_action_o_sel_action_rd_r_i = 1; + // disable action data address huffman decoding, on the assumtion we're not + // trying to combine this with an action data table on the same home row. + // Otherwise, the huffman decoding will think this is an 8-bit value and + // replicate it. + regs.rams.array.row[row] + .action_hv_xbar.action_hv_xbar_disable_ram_adr + .action_hv_xbar_disable_ram_adr_right = 1; + } + } else { + auto &adr_ctl = map_alu_row.vh_xbars.adr_dist_oflo_adr_xbar_ctl[side]; + if (home->row >= 8 && logical_row.row < 8) { + adr_ctl.adr_dist_oflo_adr_xbar_source_index = 0; + adr_ctl.adr_dist_oflo_adr_xbar_source_sel = AdrDist::OVERFLOW; + push_on_overflow = true; + BUG_CHECK(options.target == TOFINO); + } else { + adr_ctl.adr_dist_oflo_adr_xbar_source_index = home->row % 8; + adr_ctl.adr_dist_oflo_adr_xbar_source_sel = AdrDist::METER; + } + adr_ctl.adr_dist_oflo_adr_xbar_enable = 1; + } + } + } + if (actions) actions->write_regs(regs, this); + unsigned meter_group = home->row / 4U; + for (MatchTable *m : match_tables) { + adrdist.mau_ad_meter_virt_lt[meter_group] |= 1U << m->logical_id; + adrdist.adr_dist_meter_adr_icxbar_ctl[m->logical_id] |= 1 << meter_group; + } + if (!bound_selector) { + bool first_match = true; + for (MatchTable *m : match_tables) { + adrdist.adr_dist_meter_adr_icxbar_ctl[m->logical_id] |= 1 << meter_group; + adrdist.movereg_ad_meter_alu_to_logical_xbar_ctl[m->logical_id / 8U].set_subfield( + 4 | meter_group, 3 * (m->logical_id % 8U), 3); + if (first_match) + adrdist.movereg_meter_ctl[meter_group].movereg_meter_ctl_lt = m->logical_id; + if (direct) { + if (first_match) + adrdist.movereg_meter_ctl[meter_group].movereg_meter_ctl_direct = 1; + adrdist.movereg_ad_direct[MoveReg::METER] |= 1U << m->logical_id; + } + first_match = false; + } + adrdist.movereg_meter_ctl[meter_group].movereg_ad_meter_shift = format->log2size; + if (push_on_overflow) { + adrdist.oflo_adr_user[0] = adrdist.oflo_adr_user[1] = AdrDist::METER; + adrdist.deferred_oflo_ctl = 1 << (home->row - 8) / 2U; + } + adrdist.packet_action_at_headertime[1][meter_group] = 1; + } + write_logging_regs(regs); + for (auto &hd : hash_dist) hd.write_regs(regs, this); + if (gress == INGRESS || gress == GHOST) { + merge.meter_alu_thread[0].meter_alu_thread_ingress |= 1U << meter_group; + merge.meter_alu_thread[1].meter_alu_thread_ingress |= 1U << meter_group; + } else if (gress == EGRESS) { + merge.meter_alu_thread[0].meter_alu_thread_egress |= 1U << meter_group; + merge.meter_alu_thread[1].meter_alu_thread_egress |= 1U << meter_group; + } + auto &salu = regs.rams.map_alu.meter_group[meter_group].stateful; + salu.stateful_ctl.salu_enable = 1; + salu.stateful_ctl.salu_output_pred_shift = pred_shift / 4; + salu.stateful_ctl.salu_output_pred_comb_shift = pred_comb_shift; + // The reset value for the CMP opcode is enabled by default -- we want to disable + // any unused cmp units + for (auto &inst : salu.salu_instr_cmp_alu) { + for (auto &alu : inst) { + if (!alu.salu_cmp_opcode.modified()) { + alu.salu_cmp_opcode = 2; + } + } + } + if (gress == EGRESS) { + regs.rams.map_alu.meter_group[meter_group].meter.meter_ctl.meter_alu_egress = 1; + } + if (math_table) { + for (size_t i = 0; i < math_table.data.size(); ++i) + salu.salu_mathtable[i / 4U].set_subfield(math_table.data[i], 8 * (i % 4U), 8); + salu.salu_mathunit_ctl.salu_mathunit_output_scale = math_table.scale & 0x3fU; + salu.salu_mathunit_ctl.salu_mathunit_exponent_invert = math_table.invert; + switch (math_table.shift) { + case -1: + salu.salu_mathunit_ctl.salu_mathunit_exponent_shift = 2; + break; + case 0: + salu.salu_mathunit_ctl.salu_mathunit_exponent_shift = 0; + break; + case 1: + salu.salu_mathunit_ctl.salu_mathunit_exponent_shift = 1; + break; + } + } +} + +void StatefulTable::gen_tbl_cfg(json::vector &out) const { + // FIXME -- factor common Synth2Port stuff + int size = (layout_size() - 1) * 1024 * (128U / format->size); + json::map &tbl = *base_tbl_cfg(out, "stateful", size); + unsigned alu_width = format->size / (dual_mode ? 2 : 1); + tbl["initial_value_lo"] = initial_value_lo; + tbl["initial_value_hi"] = initial_value_hi; + tbl["alu_width"] = alu_width; + tbl["dual_width_mode"] = dual_mode; + json::vector &act_to_sful_instr_slot = tbl["action_to_stateful_instruction_slot"]; + if (actions) { + for (auto &a : *actions) { + for (auto &i : a.instr) { + if ((i->name() == "set_bit_at") || (i->name() == "set_bitc_at")) + tbl["set_instr_adjust_total"] = a.code; + if ((i->name() == "set_bit") || (i->name() == "set_bitc")) + tbl["set_instr"] = a.code; + if ((i->name() == "clr_bit_at") || (i->name() == "clr_bitc_at")) + tbl["clr_instr_adjust_total"] = a.code; + if ((i->name() == "clr_bit") || (i->name() == "clr_bitc")) + tbl["clr_instr"] = a.code; + } + } + } + // Add action handle and instr slot for action which references stateful + for (auto *m : match_tables) { + if (auto *acts = m->get_actions()) { + for (auto &a : *acts) { + Actions::Action *stful_action = action_for_table_action(m, &a); + if (!stful_action) continue; + bool act_present = false; + // Do not add handle if already present, if stateful spans + // multiple stages this can happen as action handles are unique + // and this code will get called again + for (auto &s : act_to_sful_instr_slot) { + auto s_handle = s->to()["action_handle"]; + if (*s_handle->as_number() == a.handle) { + act_present = true; + break; + } + } + if (act_present) continue; + json::map instr_slot; + instr_slot["action_handle"] = a.handle; + instr_slot["instruction_slot"] = stful_action->code; + act_to_sful_instr_slot.push_back(std::move(instr_slot)); + } + } + } + json::vector ®ister_file = tbl["register_params"]; + for (size_t i = 0; i < const_vals.size(); i++) { + if (!const_vals[i].is_param) continue; + json::map register_file_row; + register_file_row["register_file_index"] = i; + register_file_row["initial_value"] = const_vals[i].value; + register_file_row["name"] = const_vals[i].param_name; + register_file_row["handle"] = const_vals[i].param_handle; + register_file.push_back(std::move(register_file_row)); + } + if (bound_selector) tbl["bound_to_selection_table_handle"] = bound_selector->handle(); + json::map &stage_tbl = *add_stage_tbl_cfg(tbl, "stateful", size); + add_alu_index(stage_tbl, "meter_alu_index"); + gen_tbl_cfg(tbl, stage_tbl); + if (context_json) stage_tbl.merge(*context_json); +} + +DEFINE_TABLE_TYPE_WITH_SPECIALIZATION(StatefulTable, TARGET_CLASS) +FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void StatefulTable::write_action_regs, + (mau_regs & regs, const Actions::Action *act), + { write_action_regs_vt(regs, act); }) +FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void StatefulTable::write_merge_regs, + (mau_regs & regs, MatchTable *match, int type, int bus, + const std::vector &args), + { write_merge_regs_vt(regs, match, type, bus, args); }) diff --git a/backends/tofino/bf-asm/synth2port.cpp b/backends/tofino/bf-asm/synth2port.cpp new file mode 100644 index 00000000000..398bd4e2d84 --- /dev/null +++ b/backends/tofino/bf-asm/synth2port.cpp @@ -0,0 +1,177 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "algorithm.h" +#include "data_switchbox.h" +#include "input_xbar.h" +#include "misc.h" +#include "stage.h" +#include "tables.h" + +void Synth2Port::common_init_setup(const VECTOR(pair_t) & data, bool, P4Table::type p4type) { + setup_layout(layout, data); + if (auto *fmt = get(data, "format")) { + if (CHECKTYPEPM(*fmt, tMAP, fmt->map.size > 0, "non-empty map")) + format.reset(new Format(this, fmt->map)); + } +} + +bool Synth2Port::common_setup(pair_t &kv, const VECTOR(pair_t) & data, P4Table::type p4type) { + if (kv.key == "vpns") { + if (kv.value == "null") { + no_vpns = true; + } else if (CHECKTYPE(kv.value, tVEC)) { + setup_vpns(layout, &kv.value.vec, true); + } + } else if (kv.key == "maprams") { + setup_maprams(kv.value); + } else if (kv.key == "global_binding") { + global_binding = get_bool(kv.value); + } else if (kv.key == "per_flow_enable") { + if (CHECKTYPE(kv.value, tSTR)) { + per_flow_enable = 1; + per_flow_enable_param = kv.value.s; + } + } else if (kv.key == "p4") { + if (CHECKTYPE(kv.value, tMAP)) p4_table = P4Table::get(p4type, kv.value.map); + } else if (kv.key == "context_json") { + setup_context_json(kv.value); + } else if (kv.key == "format" || kv.key == "row" || kv.key == "logical_row" || + kv.key == "column" || kv.key == "bus") { + /* already done in setup_layout */ + } else if (kv.key == "logical_bus") { + if (CHECKTYPE2(kv.value, tSTR, tVEC)) { + if (kv.value.type == tSTR) { + if (*kv.value.s != 'A' && *kv.value.s != 'O' && *kv.value.s != 'S') + error(kv.value.lineno, "Invalid logical bus %s", kv.value.s); + } else { + for (auto &v : kv.value.vec) { + if (CHECKTYPE(v, tSTR)) { + if (*v.s != 'A' && *v.s != 'O' && *v.s != 'S') + error(v.lineno, "Invalid logical bus %s", v.s); + } + } + } + } + } else if (kv.key == "home_row") { + home_lineno = kv.value.lineno; + if (CHECKTYPE2(kv.value, tINT, tVEC)) { + if (kv.value.type == tINT) { + if (kv.value.i >= 0 || kv.value.i < LOGICAL_SRAM_ROWS) + home_rows.insert(kv.value.i); + else + error(kv.value.lineno, "Invalid home row %" PRId64 "", kv.value.i); + } else { + for (auto &v : kv.value.vec) { + if (CHECKTYPE(v, tINT)) { + if (v.i >= 0 || v.i < LOGICAL_SRAM_ROWS) + home_rows.insert(v.i); + else + error(v.lineno, "Invalid home row %" PRId64 "", v.i); + } + } + } + } + } else { + return false; + } + return true; +} + +void Synth2Port::pass1() { + LOG1("### Synth2Port table " << name() << " pass1 " << loc()); + AttachedTable::pass1(); +} + +void Synth2Port::alloc_vpns(Target::Tofino) { AttachedTable::alloc_vpns(); } + +void Synth2Port::pass2() { LOG1("### Synth2Port table " << name() << " pass2 " << loc()); } + +void Synth2Port::pass3() { LOG1("### Synth2Port table " << name() << " pass3 " << loc()); } + +json::map *Synth2Port::add_stage_tbl_cfg(json::map &tbl, const char *type, int size) const { + json::map &stage_tbl = *AttachedTable::add_stage_tbl_cfg(tbl, type, size); + std::string hr = how_referenced(); + if (hr.empty()) hr = direct ? "direct" : "indirect"; + tbl["how_referenced"] = hr; + int entries = 1; + if (format) { + BUG_CHECK(format->log2size <= 7); + if (format->groups() > 1) { + BUG_CHECK(format->log2size == 7); + entries = format->groups(); + } else { + entries = 128U >> format->log2size; + } + } + add_pack_format(stage_tbl, 128, 1, entries); + stage_tbl["memory_resource_allocation"] = + gen_memory_resource_allocation_tbl_cfg("sram", layout, true); + return &stage_tbl; +} + +void Synth2Port::add_alu_indexes(json::map &stage_tbl, std::string alu_indexes) const { + json::vector home_alu; + + for (auto row : home_rows) home_alu.push_back(row / 4U); + + stage_tbl[alu_indexes] = home_alu.clone(); +} + +std::vector Synth2Port::determine_spare_bank_memory_units(Target::Tofino) const { + std::vector spare_mem; + int vpn_ctr = 0; + int minvpn, spare_vpn; + + // Retrieve the Spare VPN + layout_vpn_bounds(minvpn, spare_vpn, false); + for (auto &row : layout) { + auto vpn_itr = row.vpns.begin(); + for (auto &ram : row.memunits) { + BUG_CHECK(ram.stage == INT_MIN && ram.row == row.row, "bogus %s in row %d", ram.desc(), + row.row); + if (vpn_itr != row.vpns.end()) vpn_ctr = *vpn_itr++; + if (spare_vpn == vpn_ctr) { + spare_mem.push_back(json_memunit(ram)); + if (table_type() == SELECTION || table_type() == COUNTER || table_type() == METER || + table_type() == STATEFUL) + continue; + } + } + } + return spare_mem; +} + +int Synth2Port::get_home_row_for_row(int row) const { + for (int home_row : home_rows) { + // Tofino1 have an overflow bus in the middle of the SRAM array + if (options.target == TOFINO) + return home_row; + else if (row / 8 == home_row / 8) + return home_row; + } + BUG(); + return -1; +} + +template +void Synth2Port::write_regs_vt(REGS ®s) { + // FIXME move common Counter/Meter/StatefulTable::write_regs_vt stuff here +} + +REGSETS_IN_CLASS(Tofino, TARGET_OVERLOAD, void Synth2Port::write_regs, (mau_regs & regs), + { write_regs_vt(regs); }) diff --git a/backends/tofino/bf-asm/tables.cpp b/backends/tofino/bf-asm/tables.cpp new file mode 100644 index 00000000000..fdebf2aa6ee --- /dev/null +++ b/backends/tofino/bf-asm/tables.cpp @@ -0,0 +1,3356 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "tables.h" + +#include + +#include +#include + +#include "action_bus.h" +#include "algorithm.h" +#include "input_xbar.h" +#include "instruction.h" +#include "misc.h" +#include "stage.h" + +// template specialization declarations + +const char *MemUnit::desc() const { + static char buffer[256], *p = buffer; + char *end = buffer + sizeof(buffer), *rv; + do { + if (end - p < 7) p = buffer; + rv = p; + if (stage != INT_MIN) + p += snprintf(p, end - p, "Mem %d,%d,%d", stage, row, col); + else if (row >= 0) + p += snprintf(p, end - p, "Mem %d,%d", row, col); + else + p += snprintf(p, end - p, "Mem %d", col); + } while (p++ >= end); + return rv; +} + +bool Table::Layout::operator==(const Table::Layout &a) const { + return row == a.row && bus == a.bus && word == a.word && memunits == a.memunits; + // ignoring other fields as if the above are all the same, will use the same resources +} + +unsigned StatefulTable::const_info_t::unique_register_param_handle = REGISTER_PARAM_HANDLE_START; + +std::map *Table::all; +std::vector
*Table::by_uid; +std::map *Table::Type::all; + +Table::Table(int line, std::string &&n, gress_t gr, Stage *s, int lid) + : // NOLINT(whitespace/operators) + name_(n), + stage(s), + gress(gr), + lineno(line), + logical_id(lid) { + if (!all) all = new std::map; + if (!by_uid) by_uid = new std::vector
; + uid = by_uid->size(); + by_uid->push_back(this); + if (all->count(name_)) { + error(lineno, "Duplicate table %s", name()); + error(all->at(name_)->lineno, "previously defined here"); + } + all->emplace(name_, this); + if (stage) stage->all_refs.insert(&stage); +} +Table::~Table() { + BUG_CHECK(by_uid && uid >= 0 && uid < by_uid->size(), "invalid uid %d in table", uid); + all->erase(name_); + (*by_uid)[uid] = nullptr; + if (stage) stage->all_refs.erase(&stage); + if (all->empty()) { + delete all; + delete by_uid; + all = nullptr; + by_uid = nullptr; + } +} + +Table::Type::Type(std::string &&name) { // NOLINT(whitespace/operators) + if (!all) all = new std::map(); + if (get(name)) { + fprintf(stderr, "Duplicate table type %s\n", name.c_str()); + exit(1); + } + self = all->emplace(name, this).first; +} + +Table::Type::~Type() { + all->erase(self); + if (all->empty()) { + delete all; + all = nullptr; + } +} + +Table::NextTables::NextTables(value_t &v) : lineno(v.lineno) { + if (v.type == tVEC && (Target::LONG_BRANCH_TAGS() > 0 || v.vec.size == 0)) { + for (auto &el : v.vec) + if (CHECKTYPE(el, tSTR)) next.emplace(el); + } else if (CHECKTYPE(v, tSTR)) { + if (v != "END") next.emplace(v); + } +} + +bool Table::NextTables::can_use_lb(int stage, const NextTables &lbrch) { + if (options.disable_long_branch) return false; + if (!lbrch.subset_of(*this)) return false; + return true; +} + +void Table::NextTables::resolve_long_branch(const Table *tbl, + const std::map &lbrch) { + if (resolved) return; + resolved = true; + for (auto &lb : lbrch) { + if (can_use_lb(tbl->stage->stageno, lb.second)) { + lb_tags |= 1U << lb.first; + } + } + for (auto &lb : tbl->long_branch) { + if (can_use_lb(tbl->stage->stageno, lb.second)) { + lb_tags |= 1U << lb.first; + } + } + for (auto &n : next) { + if (!n) continue; + if (Target::LONG_BRANCH_TAGS() > 0 && !options.disable_long_branch) { + if (n->stage->stageno <= tbl->stage->stageno + 1) // local or global exec + continue; + auto lb_covers = [this, n](const std::pair &lb) -> bool { + return ((lb_tags >> lb.first) & 1) && lb.second.next.count(n); + }; + if (std::any_of(lbrch.begin(), lbrch.end(), lb_covers)) continue; + if (std::any_of(tbl->long_branch.begin(), tbl->long_branch.end(), lb_covers)) continue; + } + if (next_table_) { + error(n.lineno, "Can't have multiple next tables for table %s", tbl->name()); + break; + } + next_table_ = n; + continue2:; + } +} + +unsigned Table::NextTables::next_in_stage(int stage) const { + unsigned rv = 0; + for (auto &n : next) + if (n->stage->stageno == stage) rv |= 1U << n->logical_id; + return rv; +} + +bool Table::NextTables::need_next_map_lut() const { + BUG_CHECK(resolved); + return next.size() > 1 || (next.size() == 1 && !next_table_); +} + +void Table::NextTables::force_single_next_table() { + BUG_CHECK(resolved); // must be resolved already + if (next.size() > 1) + error(lineno, + "Can't support multiple next tables; next is directly in overhead " + "without using 8-entry lut"); + if (next.size() == 1) next_table_ = *next.begin(); +} + +int Table::table_id() const { return (stage->stageno << 4) + logical_id; } + +void Table::Call::setup(const value_t &val, Table *tbl) { + if (!CHECKTYPE2(val, tSTR, tCMD)) return; + if (val.type == tSTR) { + Ref::operator=(val); + return; + } + Ref::operator=(val[0]); + for (int i = 1; i < val.vec.size; i++) { + int mode; + if (val[i].type == tINT) { + args.emplace_back(val[i].i); + } else if (val[i].type == tCMD && val[i] == "hash_dist") { + if (PCHECKTYPE(val[i].vec.size > 1, val[i][1], tINT)) { + if (auto hd = tbl->find_hash_dist(val[i][1].i)) + args.emplace_back(hd); + else + error(val[i].lineno, "hash_dist %" PRId64 " not defined in table %s", + val[i][1].i, tbl->name()); + } + } else if ((mode = StatefulTable::parse_counter_mode(val[i])) >= 0) { + args.emplace_back(Arg::Counter, mode); + } else if (!CHECKTYPE(val[i], tSTR)) { + // syntax error message emit by CHEKCTYPE + } else if (auto arg = tbl->lookup_field(val[i].s)) { + if (arg->bits.size() != 1) error(val[i].lineno, "arg fields can't be split in format"); + args.emplace_back(arg); + } else { + args.emplace_back(val[i].s); + } + } + lineno = val.lineno; +} + +unsigned Table::Call::Arg::size() const { + switch (type) { + case Field: + return fld ? fld->size : 0; + case HashDist: + return hd ? hd->expand >= 0 ? 23 : 16 : 0; + case Counter: + return 23; + case Const: + case Name: + return 0; + default: + BUG(); + } + return -1; +} + +static void add_row(int lineno, std::vector &layout, int row) { + layout.push_back(Table::Layout(lineno, row)); +} + +static int add_rows(std::vector &layout, const value_t &rows) { + if (!CHECKTYPE2(rows, tINT, tRANGE)) return 1; + if (rows.type == tINT) { + add_row(rows.lineno, layout, rows.i); + } else { + int step = rows.lo > rows.hi ? -1 : 1; + for (int i = rows.lo; i != rows.hi; i += step) add_row(rows.lineno, layout, i); + add_row(rows.lineno, layout, rows.hi); + } + return 0; +} + +static int add_col(int lineno, int stage, Table::Layout &row, int col) { + for (auto &mu : row.memunits) { + if (mu.stage == stage && mu.col == col) { + error(lineno, "column %d duplicated", col); + return 1; + } + } + row.memunits.emplace_back(stage, row.row, col); + return 0; +} + +static int add_cols(int stage, Table::Layout &row, const value_t &cols) { + int rv = 0; + if (cols.type == tVEC) { + if (cols.vec.size == 1) return add_cols(stage, row, cols.vec[0]); + for (auto &col : cols.vec) { + if (col.type == tVEC) { + error(col.lineno, "Column shape doesn't match rows"); + rv |= 1; + } else { + rv |= add_cols(stage, row, col); + } + } + return rv; + } + if (cols.type == tMAP && Target::SRAM_GLOBAL_ACCESS()) { + bitvec stages_seen; + for (auto &kv : cols.map) { + if (kv.key == "stage" && kv.key.type == tCMD && kv.key[1].type == tINT) + stage = kv.key[1].i; + else { + error(kv.key.lineno, "syntax error, expecting a stage number"); + continue; + } + if (stage < 0 || stage > Target::NUM_MAU_STAGES()) { + error(kv.key.lineno, "stage %d out of range", stage); + } else if (stages_seen[stage]) { + error(kv.key.lineno, "duplicate stage %d", stage); + } else { + rv |= add_cols(stage, row, kv.value); + } + } + return rv; + } + if (!CHECKTYPE2(cols, tINT, tRANGE)) return 1; + if (cols.type == tINT) return add_col(cols.lineno, stage, row, cols.i); + int step = cols.lo > cols.hi ? -1 : 1; + for (int i = cols.lo; i != cols.hi; i += step) rv |= add_col(cols.lineno, stage, row, i); + rv |= add_col(cols.lineno, stage, row, cols.hi); + return rv; +} + +static int add_stages(Table::Layout &row, const value_t &stages) { + int rv = 0; + if (stages.type == tVEC) { + if (stages.vec.size == 1) return add_stages(row, stages.vec[0]); + for (auto &stg : stages.vec) { + if (stg.type == tVEC) { + error(stg.lineno, "Stages shape doesn't match rows"); + rv |= 1; + } else { + rv |= add_stages(row, stg); + } + } + return rv; + } + if (!CHECKTYPE2(stages, tINT, tRANGE)) return 1; + if (stages.type == tINT) return add_col(stages.lineno, stages.i, row, 0); + int step = stages.lo > stages.hi ? -1 : 1; + for (int i = stages.lo; i != stages.hi; i += step) rv |= add_col(stages.lineno, i, row, 0); + rv |= add_col(stages.lineno, stages.hi, row, 0); + return rv; +} + +std::ostream &operator<<(std::ostream &out, const Table::Layout::bus_type_t type) { + switch (type) { + case Table::Layout::SEARCH_BUS: + return out << "search_bus"; + case Table::Layout::RESULT_BUS: + return out << "result_bus"; + case Table::Layout::TIND_BUS: + return out << "tind_bus"; + case Table::Layout::IDLE_BUS: + return out << "idle_bus"; + case Table::Layout::L2R_BUS: + return out << "l2r bus"; + case Table::Layout::R2L_BUS: + return out << "r2l bus"; + default: + return out << "[bus_t " << static_cast(type) << "]"; + } +} + +std::ostream &operator<<(std::ostream &out, const Table::Layout &l) { + if (l.home_row) out << "home_"; + out << "row=" << l.row; + for (auto [type, idx] : l.bus) out << " " << type << "=" << idx; + if (l.word >= 0) out << " word=" << l.word; + if (!l.memunits.empty()) { + const char *sep = ""; + out << " ["; + for (auto &unit : l.memunits) { + out << sep << unit; + sep = ", "; + } + out << ']'; + } + if (!l.vpns.empty()) { + const char *sep = ""; + out << " vpns=["; + for (auto vpn : l.vpns) { + out << sep << vpn; + sep = ", "; + } + out << ']'; + } + if (!l.maprams.empty()) { + const char *sep = ""; + out << " maprams=["; + for (auto mr : l.maprams) { + out << sep << mr; + sep = ", "; + } + out << ']'; + } + return out; +} + +int Table::setup_layout_attrib(std::vector &layout, const value_t &data, const char *what, + int Layout::*attr) { + if (!CHECKTYPE2(data, tINT, tVEC)) { + return 1; + } else if (data.type == tVEC) { + if (data.vec.size != static_cast(layout.size())) { + error(data.lineno, "%s shape doesn't match rows", what); + return 1; + } else { + for (int i = 0; i < data.vec.size; i++) { + if (CHECKTYPE(data.vec[i], tINT)) + layout[i].*attr = data.vec[i].i; + else + return 1; + } + } + } else { + for (auto &lrow : layout) lrow.*attr = data.i; + } + return 0; +} + +int Table::setup_layout_bus_attrib(std::vector &layout, const value_t &data, + const char *what, Layout::bus_type_t type) { + int limit = Target::NUM_BUS_OF_TYPE(type); + int err = 0; + if (limit <= 0) { + error(data.lineno, "No %s on target %s", to_string(type).c_str(), Target::name()); + return 1; + } else if (!CHECKTYPE2(data, tINT, tVEC)) { + return 1; + } else if (data.type == tVEC) { + if (data.vec.size != static_cast(layout.size())) { + error(data.lineno, "%s shape doesn't match rows", what); + return 1; + } else { + for (int i = 0; i < data.vec.size; i++) { + if (!CHECKTYPE(data.vec[i], tINT)) return 1; + if (data.vec[i].i >= limit) { + error(data.vec[i].lineno, "%" PRId64 " to large for %s", data.vec[i].i, + to_string(type).c_str()); + err = 1; + } + if (data.vec[i].i >= 0) layout[i].bus[type] = data.vec[i].i; + } + } + } else if (data.i < 0) { + error(data.lineno, "%s value %" PRId64 " invalid", what, data.i); + err = 1; + } else if (data.i >= limit) { + error(data.lineno, "%" PRId64 " to large for %s", data.i, to_string(type).c_str()); + err = 1; + } else { + for (auto &lrow : layout) lrow.bus[type] = data.i; + } + return err; +} + +void Table::setup_layout(std::vector &layout, const VECTOR(pair_t) & data, + const char *subname) { + auto *row = get(data, "row"); + if (!row && this->to()) row = get(data, "logical_row"); + if (!row) { + if (table_type() != TERNARY && Target::TABLES_REQUIRE_ROW()) + error(lineno, "No 'row' attribute in table %s%s", name(), subname); + return; + } + int err = 0; + if (row->type == tVEC) + for (value_t &r : row->vec) err |= add_rows(layout, r); + else + err |= add_rows(layout, *row); + if (err) return; + bool global_access = + (table_type() == TERNARY) ? Target::TCAM_GLOBAL_ACCESS() : Target::SRAM_GLOBAL_ACCESS(); + if (global_access && table_type() == TERNARY && Target::TCAM_UNITS_PER_ROW() == 1) { + if (auto *stg = get(data, "stages")) { + if (stg->type == tVEC && stg->vec.size == static_cast(layout.size())) { + for (int i = 0; i < stg->vec.size; i++) err |= add_stages(layout[i], stg->vec[i]); + } else if (layout.size() == 1) + err |= add_stages(layout[0], *stg); + } else { + for (auto &lrow : layout) err |= add_col(lineno, this->stage->stageno, lrow, 0); + } + } else if (auto *col = get(data, "column")) { + int stage = global_access ? this->stage->stageno : INT_MIN; + if (col->type == tMAP && global_access) { + bitvec stages_seen; + for (auto &kv : col->map) { + if (kv.key.type == tINT) + stage = kv.key.i; + else if (kv.key == "stage" && kv.key.type == tCMD && kv.key[1].type == tINT) + stage = kv.key[1].i; + else { + error(kv.key.lineno, "syntax error, expecting a stage number"); + continue; + } + if (stage < 0 || stage > Target::NUM_STAGES(gress)) { + error(kv.key.lineno, "stage %d out of range", stage); + } else if (stages_seen[stage]) { + error(kv.key.lineno, "duplicate stage %d", stage); + } else { + if (kv.value.type == tVEC && kv.value.vec.size + 0U == layout.size()) { + for (int i = 0; i < kv.value.vec.size; i++) + err |= add_cols(stage, layout[i], kv.value.vec[i]); + } else { + for (auto &lrow : layout) + if ((err |= add_cols(stage, lrow, kv.value))) break; + } + } + } + } else if (col->type == tVEC && col->vec.size == static_cast(layout.size())) { + for (int i = 0; i < col->vec.size; i++) err |= add_cols(stage, layout[i], col->vec[i]); + } else { + for (auto &lrow : layout) + if ((err |= add_cols(stage, lrow, *col))) break; + } + } else if (layout.size() > 1) { + error(lineno, "No 'column' attribute in table %s%s", name(), subname); + return; + } + if (auto *bus = get(data, "bus")) + err |= Table::setup_layout_bus_attrib(layout, *bus, "Bus", default_bus_type()); + else if (auto *bus = get(data, "search_bus")) + err |= Table::setup_layout_bus_attrib(layout, *bus, "Bus", Layout::SEARCH_BUS); + if (auto *bus = get(data, "lhbus")) + err |= Table::setup_layout_bus_attrib(layout, *bus, "R2L hbus", Layout::R2L_BUS); + if (auto *bus = get(data, "rhbus")) + err |= Table::setup_layout_bus_attrib(layout, *bus, "L2R hbus", Layout::L2R_BUS); + if (auto *bus = get(data, "result_bus")) + err |= Table::setup_layout_bus_attrib(layout, *bus, "Bus", Layout::RESULT_BUS); + if (auto *word = get(data, "word")) + err |= Table::setup_layout_attrib(layout, *word, "Word", &Layout::word); + if (err) return; + for (auto i = layout.begin(); i != layout.end(); i++) + for (auto j = i + 1; j != layout.end(); j++) + if (*i == *j) { + std::stringstream bus; + if (!i->bus.empty()) + bus << " " << i->bus.begin()->first << " " << i->bus.begin()->second; + error(i->lineno, "row %d%s duplicated in table %s%s", i->row, bus.str().c_str(), + name(), subname); + } +} + +void Table::setup_logical_id() { + if (logical_id >= 0) { + if (Table *old = stage->logical_id_use[logical_id]) { + error(lineno, "table %s wants logical id %d:%d", name(), stage->stageno, logical_id); + error(old->lineno, "already in use by %s", old->name()); + } + stage->logical_id_use[logical_id] = this; + } +} + +void Table::setup_maprams(value_t &v) { + if (!CHECKTYPE2(v, tINT, tVEC)) return; + VECTOR(value_t) *rams = &v.vec, single_ram; + if (v.type == tINT) { + // treat as a vector of length 1 + rams = &single_ram; + single_ram.size = single_ram.capacity = 1; + single_ram.data = &v; + } + auto r = rams->begin(); + for (auto &row : layout) { + if (r == rams->end()) { + error(r->lineno, "Mapram layout doesn't match table layout"); + break; + } + auto &maprow = *r++; + VECTOR(value_t) * maprow_rams, tmp; + if (maprow.type == tINT) { + if (layout.size() == 1) { + maprow_rams = rams; + } else { + // treat as a vector of length 1 + maprow_rams = &tmp; + tmp.size = tmp.capacity = 1; + tmp.data = &maprow; + } + } else if (CHECKTYPE(maprow, tVEC)) { + maprow_rams = &maprow.vec; + } else { + continue; + } + if (maprow_rams->size != static_cast(row.memunits.size())) { + error(r->lineno, "Mapram layout doesn't match table layout"); + continue; + } + for (auto mapcol : *maprow_rams) + if (CHECKTYPE(mapcol, tINT)) { + if (mapcol.i < 0 || mapcol.i >= MAPRAM_UNITS_PER_ROW) + error(mapcol.lineno, "Invalid mapram column %" PRId64 "", mapcol.i); + else + row.maprams.push_back(mapcol.i); + } + } +} + +/** + * Guarantees that the instruction call provided to the table has valid entries, and that + * if multiple choices are required, the compiler can make that choices. + * + * The instruction address is a two piece address. The first argument is the address bits + * location. The second argument is a per flow enable bit location. These are both required. + * Additionally, the keyword $DEFAULT means that that particular portion of the address comes + * from the default register. + * + * FIXME -- this code is a messy hack -- various target-specific special cases. Should try + * to figure out a better way to organize this. + */ +bool Table::validate_instruction(Table::Call &call) const { + if (call.args.size() != 2) { + error(call.lineno, "Instruction call has invalid number of arguments"); + return false; + } + + bool field_address = false; + + if (call.args[0].name()) { + if (Target::GATEWAY_INHIBIT_INDEX() && call.args[0] == "$GATEWAY_IDX") { + field_address = true; + } else if (call.args[0] != "$DEFAULT") { + error(call.lineno, "Index %s for %s cannot be found", call.args[0].name(), + call->name()); + return false; + } + } else if (!call.args[0].field()) { + error(call.lineno, "Index for %s cannot be understood", call->name()); + return false; + } else { + field_address = true; + } + + if (call.args[1].name()) { + if (call.args[1] != "$DEFAULT") { + error(call.lineno, "Per flow enable %s for %s cannot be found", call.args[1].name(), + call->name()); + return false; + } + } else if (!call.args[1].field()) { + error(call.lineno, "Per flow enable for %s cannot be understood", call->name()); + return false; + } + + if (actions->hit_actions_count() > 1 && !field_address) + error(lineno, "No field to select between multiple action in table %s format", name()); + + return true; +} + +static bool column_match(const std::vector &a, const std::vector &b) { + auto it = b.begin(); + for (auto &u : a) { + if (it == b.end()) return false; + if (u.col != it->col) return false; + ++it; + } + return it == b.end(); +} + +void Table::setup_vpns(std::vector &layout, VECTOR(value_t) * vpn, bool allow_holes) { + int period, width, depth; + const char *period_name; + vpn_params(width, depth, period, period_name); + int word = width; + Layout *firstrow = 0; + auto vpniter = vpn ? vpn->begin() : 0; + int *vpn_ctr = new int[period]; + std::fill_n(vpn_ctr, period, get_start_vpn()); + std::vector used_vpns(period); + bool on_repeat = false; + for (auto &row : layout) { + if (++word < width) { + BUG_CHECK(firstrow); + if (!column_match(row.memunits, firstrow->memunits)) + error(row.lineno, "Columns across wide rows don't match in table %s", name()); + row.vpns = firstrow->vpns; + continue; + } + word = 0; + firstrow = &row; + row.vpns.resize(row.memunits.size()); + value_t *vpncoliter = 0; + for (int &el : row.vpns) { + // If VPN's are provided by the compiler, they need to match each + // element in the specified columns. Below code checks if all + // elements are present and errors out if there is any discrepancy. + if (vpniter) { + if (vpniter == vpn->end()) { + on_repeat = true; + vpniter = vpn->begin(); + } + if (CHECKTYPE2(*vpniter, tVEC, tINT)) { + if (vpniter->type == tVEC) { + if (!vpncoliter) { + if (static_cast(row.vpns.size()) != vpniter->vec.size) { + error(vpniter->lineno, + "Vpn entries for row %d is %d not equal to column " + "entries %d", + row.row, vpniter->vec.size, + static_cast(row.vpns.size())); + continue; + } else { + vpncoliter = vpniter->vec.begin(); + } + } + el = vpncoliter->i; + if (++vpncoliter == &*vpniter->vec.end()) ++vpniter; + continue; + } else if (vpniter->type == tINT) { + el = vpniter->i; + } + ++vpniter; + } + // Error out if VPN's are repeated in a table. For wide words, + // each individual word can have the same vpn + if (!on_repeat && used_vpns[period - 1][el].set(true)) + error(vpniter->lineno, "Vpn %d used twice in table %s", el, name()); + } else { + // If there is no word information provided in assembly (Ternary + // Indirect/Stats) tables, the allocation is always a single + // word. + // For SRamMatchTables, this should be handled by SRamMatchTable::alloc_vpns(), + // so this code will never be hit + // FIXME -- move this to Table::alloc_vpns and only call setup_vpns when + // there's a vpn specified in the bfa? + if (row.word < 0) row.word = word; + el = vpn_ctr[row.word]; + if ((vpn_ctr[row.word] += period) == depth) vpn_ctr[row.word] = 0; + } + } + } + delete[] vpn_ctr; +} + +void Table::common_init_setup(const VECTOR(pair_t) & data, bool, P4Table::type) { + setup_layout(layout, data); + if (auto *fmt = get(data, "format")) { + if (CHECKTYPEPM(*fmt, tMAP, fmt->map.size > 0, "non-empty map")) + format.reset(new Format(this, fmt->map)); + } + if (auto *hd = get(data, "hash_dist")) HashDistribution::parse(hash_dist, *hd); +} + +bool Table::common_setup(pair_t &kv, const VECTOR(pair_t) & data, P4Table::type p4type) { + bool global_access = + (table_type() == TERNARY) ? Target::TCAM_GLOBAL_ACCESS() : Target::SRAM_GLOBAL_ACCESS(); + if (kv.key == "format" || kv.key == "row" || kv.key == "column" || kv.key == "bus") { + /* done in Table::common_init_setup */ + } else if (global_access && (kv.key == "stages" || kv.key == "lhbus" || kv.key == "rhbus")) { + /* done in Table::common_init_setup */ + } else if (kv.key == "action") { + action.setup(kv.value, this); + } else if (kv.key == "instruction") { + instruction.setup(kv.value, this); + } else if (kv.key == "action_enable") { + if (CHECKTYPE(kv.value, tINT)) action_enable = kv.value.i; + if (get(data, "action")) enable_action_data_enable = true; + enable_action_instruction_enable = true; + } else if (kv.key == "enable_action_data_enable") { + enable_action_data_enable = get_bool(kv.value); + } else if (kv.key == "enable_action_instruction_enable") { + enable_action_instruction_enable = get_bool(kv.value); + } else if (kv.key == "actions") { + if (CHECKTYPE(kv.value, tMAP)) actions.reset(new Actions(this, kv.value.map)); + } else if (kv.key == "action_bus") { + if (CHECKTYPE(kv.value, tMAP)) action_bus = ActionBus::create(this, kv.value.map); + } else if ((kv.key == "default_action") || (kv.key == "default_only_action")) { + if (kv.key == "default_only_action") default_only_action = true; + default_action_lineno = kv.value.lineno; + if (CHECKTYPE2(kv.value, tSTR, tCMD)) + if (CHECKTYPE(kv.value, tSTR)) default_action = kv.value.s; + } else if (kv.key == "default_action_parameters") { + if (CHECKTYPE(kv.value, tMAP)) + for (auto &v : kv.value.map) + if (CHECKTYPE(v.key, tSTR) && CHECKTYPE(v.value, tSTR)) + default_action_parameters[v.key.s] = v.value.s; + } else if (kv.key == "default_action_handle") { + default_action_handle = kv.value.i; + } else if (kv.key == "hit") { + if (!hit_next.empty()) { + error(kv.key.lineno, "Specifying both 'hit' and 'next' in table %s", name()); + } else if (kv.value.type == tVEC) { + for (auto &v : kv.value.vec) hit_next.emplace_back(v); + } else { + hit_next.emplace_back(kv.value); + } + } else if (kv.key == "miss") { + if (miss_next.set()) { + error(kv.key.lineno, "Specifying both 'miss' and 'next' in table %s", name()); + } else { + miss_next = kv.value; + } + } else if (kv.key == "next") { + if (!hit_next.empty()) { + error(kv.key.lineno, "Specifying both 'hit' and 'next' in table %s", name()); + } else if (miss_next.set()) { + error(kv.key.lineno, "Specifying both 'miss' and 'next' in table %s", name()); + } else { + miss_next = kv.value; + hit_next.emplace_back(miss_next); + } + } else if (kv.key == "long_branch" && Target::LONG_BRANCH_TAGS() > 0) { + if (options.disable_long_branch) error(kv.key.lineno, "long branches disabled"); + if (CHECKTYPE(kv.value, tMAP)) { + for (auto &lb : kv.value.map) { + if (lb.key.type != tINT || lb.key.i < 0 || lb.key.i >= Target::LONG_BRANCH_TAGS()) + error(lb.key.lineno, "Invalid long branch tag %s", value_desc(lb.key)); + else if (long_branch.count(lb.key.i)) + error(lb.key.lineno, "Duplicate long branch tag %" PRId64, lb.key.i); + else + long_branch.emplace(lb.key.i, lb.value); + } + } + } else if (kv.key == "vpns") { + if (CHECKTYPESIZE(kv.value, tVEC)) setup_vpns(layout, &kv.value.vec); + } else if (kv.key == "p4") { + if (CHECKTYPE(kv.value, tMAP)) p4_table = P4Table::get(p4type, kv.value.map); + } else if (kv.key == "p4_param_order") { + if (CHECKTYPE(kv.value, tMAP)) { + unsigned position = 0; + for (auto &v : kv.value.map) { + if ((CHECKTYPE(v.key, tSTR)) && (CHECKTYPE(v.value, tMAP))) { + p4_param p(v.key.s); + for (auto &w : v.value.map) { + if (!CHECKTYPE(w.key, tSTR)) continue; + + if (w.key == "type" && CHECKTYPE(w.value, tSTR)) + p.type = w.value.s; + else if (w.key == "size" && CHECKTYPE(w.value, tINT)) + p.bit_width = w.value.i; + else if (w.key == "full_size" && CHECKTYPE(w.value, tINT)) + p.bit_width_full = w.value.i; + else if (w.key == "mask") + p.mask = get_bitvec(w.value); + else if (w.key == "alias" && CHECKTYPE(w.value, tSTR)) + p.alias = w.value.s; + else if (w.key == "key_name" && CHECKTYPE(w.value, tSTR)) + p.key_name = w.value.s; + else if (w.key == "start_bit" && CHECKTYPE(w.value, tINT)) + p.start_bit = w.value.i; + else if (w.key == "context_json" && CHECKTYPE(w.value, tMAP)) + p.context_json = toJson(w.value.map); + else + error(lineno, "Incorrect param type %s in p4_param_order", w.key.s); + } + // Determine position in p4_param_order. Repeated fields get + // the same position which is set on first occurrence. + // Driver relies on position to order fields. The case when + // we have multiple slices of same field based on position + // only one location is assigned for the entire field. + // However if the field has a name annotation (key_name) + // this overrides the position even if the field belongs to + // the same slice. + bool ppFound = false; + for (auto &pp : p4_params_list) { + if ((pp.name == p.name) && (pp.key_name == p.key_name)) { + ppFound = true; + p.position = pp.position; + break; + } + } + if (!ppFound) p.position = position++; + p4_params_list.emplace_back(std::move(p)); + } + } + } + } else if (kv.key == "context_json") { + setup_context_json(kv.value); + } else { + return false; + } + return true; +} + +void Table::setup_context_json(value_t &v) { + if (!CHECKTYPE(v, tMAP)) return; + + auto map = toJson(v.map); + if (context_json) + context_json->merge(*map); + else + context_json = std::move(map); +} + +/** check two tables to see if they can share ram. + * FIXME -- for now we just allow a STATEFUL and a SELECTION to share -- we should + * FIXME -- check to make sure they're mutually exclusive and use the memory in + * FIXME -- a compatible way + */ +bool Table::allow_ram_sharing(const Table *t1, const Table *t2) { + if (t1->table_type() == STATEFUL && t2->table_type() == SELECTION && + t1->to()->bound_selector == t2) + return true; + if (t2->table_type() == STATEFUL && t1->table_type() == SELECTION && + t2->to()->bound_selector == t1) + return true; + return false; +} + +/** check two tables to see if they can share action bus + * Two ATCAM tables or their action tables can occur in the same stage and share + * bytes on the action bus which is valid as they are always mutually exclusive + */ +bool Table::allow_bus_sharing(Table *t1, Table *t2) { + if (!t1 || !t2) return false; + if ((t1->table_type() == ATCAM) && (t2->table_type() == ATCAM) && + (t1->p4_name() == t2->p4_name())) + return true; + if ((t1->table_type() == ACTION) && (t2->table_type() == ACTION) && + (t1->p4_name() == t2->p4_name())) { + // Check if action tables are attached to atcam's + auto *m1 = t1->to()->get_match_table(); + auto *m2 = t2->to()->get_match_table(); + if (m1 && m2) { + if ((m1->table_type() == ATCAM) && (m2->table_type() == ATCAM)) return true; + } + } + return false; +} + +void Table::alloc_rams(bool logical, BFN::Alloc2Dbase
&use, + BFN::Alloc2Dbase
*bus_use, Layout::bus_type_t bus_type) { + for (auto &row : layout) { + for (auto &memunit : row.memunits) { + BUG_CHECK(memunit.stage == INT_MIN && memunit.row == row.row, "memunit fail"); + int r = row.row, c = memunit.col; + if (logical) { + c += 6 * (r & 1); + r >>= 1; + } + try { + if (Table *old = use[r][c]) { + if (!allow_ram_sharing(this, old)) { + error(lineno, + "Table %s trying to use (%d,%d) which is already in use " + "by table %s", + name(), r, c, old->name()); + } + } else { + use[r][c] = this; + } + } catch (std::out_of_range) { + error(lineno, "Table %s using out-of-bounds (%d,%d)", name(), r, c); + } + } + if (bus_use && row.bus.count(bus_type)) { + int bus = row.bus.at(bus_type); + if (Table *old = (*bus_use)[row.row][bus]) { + if (old != this && old->p4_name() != p4_name()) + error(lineno, + "Table %s trying to use bus %d on row %d which is already in " + "use by table %s", + name(), bus, row.row, old->name()); + } else { + (*bus_use)[row.row][bus] = this; + } + } + } +} + +void Table::alloc_global_busses() { BUG(); } +void Table::alloc_global_srams() { BUG(); } +void Table::alloc_global_tcams() { BUG(); } + +void Table::alloc_busses(BFN::Alloc2Dbase
&bus_use, Layout::bus_type_t bus_type) { + for (auto &row : layout) { + // If row.memunits is empty, we don't really need a bus here (won't use it + // for anything). + // E.g. An exact match table with 4 or less static entries (JBay) or 1 + // static entry (Tofino) + // In these examples compiler does gateway optimization where static + // entries are encoded in the gateway and no RAM's are used. We skip bus + // allocation in these cases. + if (!row.bus.count(bus_type) && !row.memunits.empty()) { + // FIXME -- iterate over bus_use[row.row] rather than assuming 2 rows + if (bus_use[row.row][0] == this) + row.bus[bus_type] = 0; + else if (bus_use[row.row][1] == this) + row.bus[bus_type] = 1; + else if (!bus_use[row.row][0]) + bus_use[row.row][row.bus[bus_type] = 0] = this; + else if (!bus_use[row.row][1]) + bus_use[row.row][row.bus[bus_type] = 1] = this; + else + error(lineno, "No bus available on row %d for table %s", row.row, name()); + } + } +} + +void Table::alloc_id(const char *idname, int &id, int &next_id, int max_id, bool order, + BFN::Alloc1Dbase
&use) { + if (id >= 0) { + next_id = id; + return; + } + while (++next_id < max_id && use[next_id]) { + } + if (next_id >= max_id && !order) { + next_id = -1; + while (++next_id < max_id && use[next_id]) { + } + } + if (next_id < max_id) + use[id = next_id] = this; + else + error(lineno, "Can't pick %s id for table %s (ran out)", idname, name()); +} + +void Table::alloc_maprams() { + if (!Target::SYNTH2PORT_NEED_MAPRAMS()) return; + for (auto &row : layout) { + int sram_row = row.row / 2; + if ((row.row & 1) == 0) { + error(row.lineno, "Can only use 2-port rams on right side srams (odd logical rows)"); + continue; + } + if (row.maprams.empty()) { + int use = 0; + for (unsigned i = 0; i < row.memunits.size(); i++) { + while (use < MAPRAM_UNITS_PER_ROW && stage->mapram_use[sram_row][use]) use++; + if (use >= MAPRAM_UNITS_PER_ROW) { + error(row.lineno, "Ran out of maprams on row %d in stage %d", sram_row, + stage->stageno); + break; + } + row.maprams.push_back(use); + stage->mapram_use[sram_row][use++] = this; + } + } else { + for (auto mapcol : row.maprams) { + if (auto *old = stage->mapram_use[sram_row][mapcol]) { + if (!allow_ram_sharing(this, old)) + error(lineno, + "Table %s trying to use mapram %d,%d which is use by " + "table %s", + name(), sram_row, mapcol, old->name()); + } else { + stage->mapram_use[sram_row][mapcol] = this; + } + } + } + } +} + +void Table::alloc_vpns() { + if (no_vpns || layout_size() == 0 || layout[0].vpns.size() > 0) return; + setup_vpns(layout, 0); +} + +void Table::check_next(const Table::Ref &n) { + if (n.check()) { + if (logical_id >= 0 && n->logical_id >= 0 ? table_id() > n->table_id() + : stage->stageno > n->stage->stageno) + error(n.lineno, "Next table %s comes before %s", n->name(), name()); + if (gress != n->gress) + error(n.lineno, "Next table %s in %s when %s is in %s", n->name(), + P4Table::direction_name(n->gress).c_str(), name(), + P4Table::direction_name(gress).c_str()); + // Need to add to the predication map + Table *tbl = get_match_table(); + if (!tbl) tbl = this; // standalone gateway + if (tbl != n) { + n->pred[tbl]; // ensure that its in the map, even as an empty set + } + } +} + +void Table::for_all_next(std::function fn) { + for (auto &n1 : hit_next) + for (auto &n2 : n1) fn(n2); + for (auto &n : miss_next) fn(n); +} + +void Table::check_next(NextTables &next) { + for (auto &n : next) check_next(n); + Table *tbl = get_match_table(); + if (!tbl) tbl = this; + next.resolve_long_branch(tbl, long_branch); +} + +void Table::check_next() { + for (auto &lb : long_branch) { + for (auto &t : lb.second) { + if (t.check()) { + if (t->stage->stageno <= stage->stageno) + error(t.lineno, "Long branch table %s is not in a later stage than %s", + t->name(), name()); + else if (stage->stageno + 1 == t->stage->stageno) + warning(t.lineno, "Long branch table %s is the next stage after %s", t->name(), + name()); + if (gress != t->gress) + error(t.lineno, "Long branch table %s in %s when %s is in %s", t->name(), + P4Table::direction_name(t->gress).c_str(), name(), + P4Table::direction_name(gress).c_str()); + } + } + } + for (auto &hn : hit_next) check_next(hn); + for (auto &hn : extra_next_lut) check_next(hn); + check_next(miss_next); +} + +void Table::set_pred() { + if (actions == nullptr) return; + for (auto &act : *actions) { + if (!act.default_only) + for (auto &n : act.next_table_ref) n->pred[this].insert(&act); + for (auto &n : act.next_table_miss_ref) n->pred[this].insert(&act); + } +} + +bool Table::choose_logical_id(const slist
*work) { + if (logical_id >= 0) return true; + if (work && find(*work, this) != work->end()) { + error(lineno, "Logical table loop with table %s", name()); + for (auto *tbl : *work) { + if (tbl == this) break; + warning(tbl->lineno, "loop involves table %s", tbl->name()); + } + return false; + } + slist
local(this, work); + for (auto *p : Keys(pred)) + if (!p->choose_logical_id(&local)) return false; + int min_id = 0, max_id = LOGICAL_TABLES_PER_STAGE - 1; + for (auto *p : Keys(pred)) + if (p->stage->stageno == stage->stageno && p->logical_id >= min_id) + min_id = p->logical_id + 1; + for_all_next([&max_id, this](const Ref &n) { + if (n && n->stage->stageno == stage->stageno && n->logical_id >= 0 && + n->logical_id <= max_id) { + max_id = n->logical_id - 1; + } + }); + for (int id = min_id; id <= max_id; ++id) { + if (!stage->logical_id_use[id]) { + logical_id = id; + stage->logical_id_use[id] = this; + return true; + } + } + error(lineno, "Can't find a logcial id for table %s", name()); + return false; +} + +void Table::need_bus(int lineno, BFN::Alloc1Dbase
&use, int idx, const char *busname) { + if (use[idx] && use[idx] != this) { + error(lineno, "%s bus conflict on row %d between tables %s and %s", busname, idx, name(), + use[idx]->name()); + error(use[idx]->lineno, "%s defined here", use[idx]->name()); + } else { + use[idx] = this; + } +} + +bitvec Table::compute_reachable_tables() { + reachable_tables_[uid] = 1; + for_all_next([this](const Ref &t) { + if (t) { + reachable_tables_ |= t->reachable_tables(); + } + }); + return reachable_tables_; +} + +std::string Table::loc() const { + std::stringstream ss; + ss << "(" << gress << ", stage=" << stage->stageno << ")"; + return ss.str(); +} + +void Table::pass1() { + alloc_vpns(); + check_next(); + if (auto att = get_attached()) att->pass1(get_match_table()); + if (action_bus) action_bus->pass1(this); + + if (actions) { + if (instruction) { + validate_instruction(instruction); + } else { + // Phase0 has empty actions which list param order + if (table_type() != PHASE0) { + error(lineno, "No instruction call provided, but actions provided"); + } + } + actions->pass1(this); + } + set_pred(); + + if (action) { + auto reqd_args = 2; + action->validate_call(action, get_match_table(), reqd_args, + HashDistribution::ACTION_DATA_ADDRESS, action); + } + for (auto &lb : long_branch) { + int last_stage = -1; + for (auto &n : lb.second) { + if (!n) continue; // already output error about invalid table + last_stage = std::max(last_stage, n->stage->stageno); + if (n->long_branch_input >= 0 && n->long_branch_input != lb.first) + error(lb.second.lineno, "Conflicting long branch input (%d and %d) for table %s", + lb.first, n->long_branch_input, n->name()); + n->long_branch_input = lb.first; + } + // we track the long branch as being 'live' from the stage it is set until the stage + // before it is terminated; it can still be use to trigger a table in that stage, even + // though it is not 'live' there. It can also be reused (set) in that stage for use in + // later stages. This matches the range of stages we need to set timing regs for. + for (int st = stage->stageno; st < last_stage; ++st) { + auto stg = Stage::stage(gress, st); + BUG_CHECK(stg); + auto &prev = stg->long_branch_use[lb.first]; + if (prev && *prev != lb.second) { + error(lb.second.lineno, "Conflicting use of long_branch tag %d", lb.first); + error(prev->lineno, "previous use"); + } else { + prev = &lb.second; + } + stg->long_branch_thread[gress] |= 1U << lb.first; + } + auto last_stg = Stage::stage(gress, last_stage); + BUG_CHECK(last_stg); + last_stg->long_branch_thread[gress] |= 1U << lb.first; + last_stg->long_branch_terminate |= 1U << lb.first; + } +} + +static void overlap_test(int lineno, unsigned a_bit, + ordered_map::iterator a, unsigned b_bit, + ordered_map::iterator b) { + if (b_bit <= a->second.hi(a_bit)) { + if (a->second.group || b->second.group) + error(lineno, "Field %s(%d) overlaps with %s(%d)", a->first.c_str(), a->second.group, + b->first.c_str(), b->second.group); + else + error(lineno, "Field %s overlaps with %s", a->first.c_str(), b->first.c_str()); + } +} + +static void append_bits(std::vector &vec, int lo, int hi) { + /* split any chunks that cross a word (128-bit) boundary */ + while (lo < hi && lo / 128U != hi / 128U) { + vec.emplace_back(lo, lo | 127); + lo = (lo | 127) + 1; + } + vec.emplace_back(lo, hi); +} + +bool Table::Format::equiv(const ordered_map &a, + const ordered_map &b) { + if (a.size() != b.size()) return false; + for (auto &el : a) + if (!b.count(el.first) || b.at(el.first) != el.second) return false; + return true; +} + +Table::Format::Format(Table *t, const VECTOR(pair_t) & data, bool may_overlap) : tbl(t) { + unsigned nextbit = 0; + fmt.resize(1); + for (auto &kv : data) { + if (lineno < 0) lineno = kv.key.lineno; + if (!CHECKTYPE2M(kv.key, tSTR, tCMD, "expecting field desc")) continue; + value_t &name = kv.key.type == tSTR ? kv.key : kv.key[0]; + unsigned idx = 0; + if (kv.key.type == tCMD && + (kv.key.vec.size != 2 || !CHECKTYPE(kv.key[1], tINT) || (idx = kv.key[1].i) > 15)) { + error(kv.key.lineno, "Invalid field group"); + continue; + } + if (kv.value.type != tVEC && + !(CHECKTYPE2(kv.value, tINT, tRANGE) && VALIDATE_RANGE(kv.value))) + continue; + if (idx >= fmt.size()) fmt.resize(idx + 1); + if (fmt[idx].count(name.s) > 0) { + if (kv.key.type == tCMD) + error(name.lineno, "Duplicate key %s(%d) in format", name.s, idx); + else + error(name.lineno, "Duplicate key %s in format", name.s); + continue; + } + Field *f = &fmt[idx].emplace(name.s, Field(this)).first->second; + f->group = idx; + if (kv.value.type == tINT) { + if (kv.value.i <= 0) + error(kv.value.lineno, "invalid size %" PRId64 " for format field %s", kv.value.i, + name.s); + f->size = kv.value.i; + append_bits(f->bits, nextbit, nextbit + f->size - 1); + } else if (kv.value.type == tRANGE) { + if (kv.value.lo > kv.value.hi) + error(kv.value.lineno, "invalid range %d..%d", kv.value.lo, kv.value.hi); + append_bits(f->bits, kv.value.lo, kv.value.hi); + f->size = kv.value.hi - kv.value.lo + 1; + } else if (kv.value.type == tVEC) { + f->size = 0; + for (auto &c : kv.value.vec) + if (CHECKTYPE(c, tRANGE) && VALIDATE_RANGE(c)) { + append_bits(f->bits, c.lo, c.hi); + f->size += c.hi - c.lo + 1; + if ((size_t)c.hi + 1 > size) size = c.hi + 1; + } + } + nextbit = f->bits.back().hi + 1; + if (nextbit > size) size = nextbit; + } + if (!may_overlap) { + for (auto &grp : fmt) { + for (auto it = grp.begin(); it != grp.end(); ++it) { + for (auto &piece : it->second.bits) { + auto p = byindex.upper_bound(piece.lo); + if (p != byindex.end()) overlap_test(lineno, piece.lo, it, p->first, p->second); + if (p != byindex.begin()) { + --p; + overlap_test(lineno, p->first, p->second, piece.lo, it); + if (p->first == piece.lo && piece.hi <= p->second->second.hi(piece.lo)) + continue; + } + byindex[piece.lo] = it; + } + } + } + } + for (size_t i = 1; i < fmt.size(); i++) + if (!equiv(fmt[0], fmt[i])) + error(data[0].key.lineno, "Format group %zu doesn't match group 0", i); + for (log2size = 0; (1U << log2size) < size; log2size++) { + } + if (error_count > 0) return; + for (auto &f : fmt[0]) { + f.second.by_group = new Field *[fmt.size()]; + f.second.by_group[0] = &f.second; + } + for (size_t i = 1; i < fmt.size(); i++) + for (auto &f : fmt[i]) { + Field &f0 = fmt[0].at(f.first); + f.second.by_group = f0.by_group; + f.second.by_group[i] = &f.second; + } +} + +Table::Format::~Format() { + for (auto &f : fmt[0]) delete[] f.second.by_group; +} + +void Table::Format::pass1(Table *tbl) { + std::map immed_fields; + unsigned lo = INT_MAX, hi = 0; + for (auto &f : fmt[0]) { + if (!(f.second.flags & Field::USED_IMMED)) continue; + if (f.second.bits.size() > 1) + error(lineno, "Immmediate action data %s cannot be split", f.first.c_str()); + immed_fields[f.second.bits[0].lo] = &f.second; + if (f.second.bits[0].lo < lo) { + immed = &f.second; + lo = immed->bits[0].lo; + } + if (f.second.bits[0].hi > hi) hi = f.second.bits[0].hi; + } + if (immed_fields.empty()) { + LOG2("table " << tbl->name() << " has no immediate data"); + } else { + LOG2("table " << tbl->name() << " has " << immed_fields.size() + << " immediate data fields " + "over " + << (hi + 1 - lo) << " bits"); + if (hi - lo >= Target::MAX_IMMED_ACTION_DATA()) { + error(lineno, "Immediate data for table %s spread over more than %d bits", tbl->name(), + Target::MAX_IMMED_ACTION_DATA()); + return; + } + immed_size = hi + 1 - lo; + for (unsigned i = 1; i < fmt.size(); i++) { + int delta = static_cast(immed->by_group[i]->bits[0].lo) - + static_cast(immed->bits[0].lo); + for (auto &f : fmt[0]) { + if (!(f.second.flags & Field::USED_IMMED)) continue; + if (delta != static_cast(f.second.by_group[i]->bits[0].lo) - + static_cast(f.second.bits[0].lo)) { + error(lineno, + "Immediate data field %s for table %s does not match across " + "ways in a ram", + f.first.c_str(), tbl->name()); + break; + } + } + } + } + lo = INT_MAX, hi = 0; + for (auto &[name, field] : fmt[0]) { + // FIXME -- should use a flag rather than names here? Someone would need to set the flag + if (name == "match" || name == "version" || name == "valid") continue; + lo = std::min(lo, field.bit(0)); + hi = std::max(hi, field.bit(field.size - 1)); + } + overhead_size = hi > lo ? hi - lo + 1 : 0; + overhead_start = hi > lo ? lo : 0; +} + +void Table::Format::pass2(Table *tbl) { + int byte[4] = {-1, -1, -1, -1}; + int half[2] = {-1, -1}; + int word = -1; + bool err = false; + for (auto &f : fmt[0]) { + int byte_slot = tbl->find_on_actionbus(&f.second, 0, 8 * f.second.size - 1, f.second.size); + if (byte_slot < 0) continue; + int slot = Stage::action_bus_slot_map[byte_slot]; + unsigned off = f.second.immed_bit(0); + switch (Stage::action_bus_slot_size[slot]) { + case 8: + for (unsigned b = off / 8; b <= (off + f.second.size - 1) / 8; b++) { + if (b >= 4 || (b & 3) != (slot & 3) || (byte[b] >= 0 && byte[b] != slot) || + (byte[b ^ 1] >= 0 && byte[b ^ 1] != (slot ^ 1)) || + Stage::action_bus_slot_size[slot] != 8) { + err = true; + break; + } + byte[b] = slot++; + } + break; + case 16: + for (unsigned w = off / 16; w <= (off + f.second.size - 1) / 16; w++) { + if (w >= 2 || (w & 1) != (slot & 1) || (half[w] >= 0 && half[w] != slot) || + Stage::action_bus_slot_size[slot] != 16) { + err = true; + break; + } + half[w] = slot++; + } + break; + case 32: + if (word >= 0 && word != slot) err = true; + word = slot; + break; + default: + BUG(); + } + if (err) error(lineno, "Immediate data misaligned for action bus byte %d", byte_slot); + } +} + +std::ostream &operator<<(std::ostream &out, const Table::Format::Field &f) { + out << "(size = " << f.size << " "; + for (auto b : f.bits) out << "[" << b.lo << ".." << b.hi << "]"; + out << ")"; + return out; +} + +bool Table::Actions::Action::equiv(Action *a) { + if (instr.size() != a->instr.size()) return false; + for (unsigned i = 0; i < instr.size(); i++) + if (!instr[i]->equiv(a->instr[i])) return false; + if (attached.size() != a->attached.size()) return false; + for (unsigned i = 0; i < attached.size(); i++) + if (attached[i] != a->attached[i]) return false; + return true; +} + +bool Table::Actions::Action::equivVLIW(Action *a) { + if (instr.size() != a->instr.size()) return false; + for (unsigned i = 0; i < instr.size(); i++) + if (!instr[i]->equiv(a->instr[i])) return false; + return true; +} + +std::map> +Table::Actions::Action::reverse_alias() const { + std::map> rv; + for (auto &a : alias) rv[a.second.name].push_back(&a); + return rv; +} + +std::string Table::Actions::Action::alias_lookup(int lineno, std::string name, int &lo, + int &hi) const { + bool err = false; + bool found = false; + while (alias.count(name) && !found) { + for (auto &a : ValuesForKey(alias, name)) { + // FIXME -- need better handling of multiple aliases... + if (lo >= 0 && a.name != "hash_dist") { + if (a.lo >= 0) { + if (a.hi >= 0 && hi + a.lo > a.hi) { + err = true; + continue; + } + lo += a.lo; + hi += a.lo; + name = a.name; + found = true; + } + } else { + lo = a.lo; + hi = a.hi; + name = (alias.count(a.name)) ? alias_lookup(lineno, a.name, lo, hi) : a.name; + } + lineno = a.lineno; + err = false; + break; + } + if (err) { + error(lineno, "invalid bitslice of %s", name.c_str()); + break; + } + } + return name; +} + +Table::Actions::Action::alias_t::alias_t(value_t &data) { + lineno = data.lineno; + if (CHECKTYPE3(data, tSTR, tCMD, tINT)) { + if (data.type == tSTR) { + name = data.s; + lo = 0; + hi = -1; + } else if (data.type == tCMD) { + name = data.vec[0].s; + if (CHECKTYPE2(data.vec[1], tINT, tRANGE)) { + if (data.vec[1].type == tINT) { + lo = hi = data.vec[1].i; + } else { + lo = data.vec[1].lo; + hi = data.vec[1].hi; + } + } + } else { + is_constant = true; + } + value = data.i; + } +} + +/** + * Builds a map of conditional variable to which bits in the action data format that they + * control. Used for JSON later. + * + * @sa asm_output::EmitAction::mod_cond_value + */ +void Table::Actions::Action::setup_mod_cond_values(value_t &map) { + for (auto &kv : map.map) { + if (CHECKTYPE(kv.key, tSTR) && CHECKTYPE(kv.value, tVEC)) { + mod_cond_values[kv.key.s].resize(2, bitvec()); + for (auto &v : kv.value.vec) { + if (CHECKTYPEPM(v, tCMD, v.vec.size == 2, "action data or immediate slice")) { + int array_index = -1; + if (v[0] == "action_data_table") { + array_index = MC_ADT; + } else if (v[0] == "immediate") { + array_index = MC_IMMED; + } else { + error(map.lineno, + "A non action_data_table or immediate value in the " + "mod_con_value map: %s", + v[0].s); + continue; + } + int lo = -1; + int hi = -1; + if (v[1].type == tINT) { + lo = hi = v[1].i; + } else if (v[1].type == tRANGE) { + lo = v[1].lo; + hi = v[1].hi; + } + mod_cond_values.at(kv.key.s).at(array_index).setrange(lo, hi - lo + 1); + } + } + } + } +} + +Table::Actions::Action::Action(Table *tbl, Actions *actions, pair_t &kv, int pos) { + lineno = kv.key.lineno; + position_in_assembly = pos; + if (kv.key.type == tCMD) { + name = kv.key[0].s; + if (CHECKTYPE(kv.key[1], tINT)) code = kv.key[1].i; + if (kv.key.vec.size > 2 && CHECKTYPE(kv.key[2], tINT)) { + if ((addr = kv.key[2].i) < 0 || addr >= ACTION_IMEM_ADDR_MAX) + error(kv.key[2].lineno, "Invalid instruction address %d", addr); + } + } else if (kv.key.type == tINT) { + name = std::to_string((code = kv.key.i)); + } else { + name = kv.key.s; + } + if (code >= 0) { + if (actions->code_use[code]) { + if (!equivVLIW(actions->by_code[code])) + error(kv.key.lineno, "Duplicate action code %d", code); + } else { + actions->by_code[code] = this; + actions->code_use[code] = true; + } + } + for (auto &i : kv.value.vec) { + if (i.type == tINT && instr.empty()) { + if ((addr = i.i) < 0 || i.i >= ACTION_IMEM_ADDR_MAX) + error(i.lineno, "Invalid instruction address %" PRId64 "", i.i); + } else if (i.type == tMAP) { + for (auto &a : i.map) + if (CHECKTYPE(a.key, tSTR)) { + if (a.key == "p4_param_order") { + if (!CHECKTYPE(a.value, tMAP)) continue; + + unsigned position = 0; + for (auto &v : a.value.map) { + if (!(CHECKTYPE(v.key, tSTR) && CHECKTYPE2(v.value, tINT, tMAP))) + continue; + + if (v.value.type == tINT) { + p4_params_list.emplace_back(v.key.s, position++, v.value.i); + } else { + p4_param p(v.key.s, position++); + for (auto &w : v.value.map) { + if (!CHECKTYPE(w.key, tSTR)) continue; + if (w.key == "width" && CHECKTYPE(w.value, tINT)) + p.bit_width = w.value.i; + else if (w.key == "context_json" && CHECKTYPE(w.value, tMAP)) + p.context_json = toJson(w.value.map); + else + error(lineno, "Incorrect param type %s in p4_param_order", + w.key.s); + } + + p4_params_list.emplace_back(std::move(p)); + } + } + } else if (a.key == "hit_allowed") { + if CHECKTYPE (a.value, tMAP) { + for (auto &p : a.value.map) { + if (CHECKTYPE(p.key, tSTR) && CHECKTYPE(p.value, tSTR)) { + if (p.key == "allowed") + hit_allowed = get_bool(p.value); + else if (p.key == "reason") + hit_disallowed_reason = p.value.s; + } + } + } + } else if (a.key == "default_action" || a.key == "default_only_action") { + if CHECKTYPE (a.value, tMAP) { + for (auto &p : a.value.map) { + if (CHECKTYPE(p.key, tSTR) && CHECKTYPE(p.value, tSTR)) { + if (p.key == "allowed") + default_allowed = get_bool(p.value); + else if (p.key == "is_constant") + is_constant = get_bool(p.value); + else if (p.key == "reason") + default_disallowed_reason = p.value.s; + } + } + } + default_only = a.key == "default_only_action"; + } else if (a.key == "handle") { + if CHECKTYPE (a.value, tINT) { + handle = a.value.i; + } + } else if (a.key == "next_table") { + if (a.value.type == tINT) + next_table_encode = a.value.i; + else + next_table_ref = a.value; + } else if (a.key == "next_table_miss") { + next_table_miss_ref = a.value; + } else if (a.key == "mod_cond_value") { + if (CHECKTYPE(a.value, tMAP)) { + setup_mod_cond_values(a.value); + } + } else if (a.key == "context_json") { + if (CHECKTYPE(a.value, tMAP)) { + context_json = toJson(a.value.map); + } + } else if (CHECKTYPE3(a.value, tSTR, tCMD, tINT)) { + if (a.value.type == tINT) { + auto k = alias.find(a.key.s); + if (k == alias.end()) { + alias.emplace(a.key.s, a.value); + } else { + k->second.is_constant = true; + k->second.value = a.value.i; + } + } else if (a.value.type == tSTR) { + auto k = alias.find(a.value.s); + if (k == alias.end()) { + alias.emplace(a.key.s, a.value); + } else { + auto alias_value = k->second; + alias.erase(k); + alias.emplace(a.key.s, alias_value); + } + } else { + alias.emplace(a.key.s, a.value); + } + } + } + + } else if (CHECKTYPE2(i, tSTR, tCMD)) { + VECTOR(value_t) tmp; + if (i.type == tSTR) { + if (!*i.s) continue; // skip blank line + VECTOR_init1(tmp, i); + } else { + VECTOR_initcopy(tmp, i.vec); + } + if (auto *p = Instruction::decode(tbl, this, tmp)) + instr.emplace_back(p); + else if (tbl->to() || tbl->to() || + tbl->to()) + attached.emplace_back(i, tbl); + else + error(i.lineno, "Unknown instruction %s", tmp[0].s); + VECTOR_fini(tmp); + } + } +} + +Table::Actions::Action::Action(const char *n, int l) : name(n), lineno(l) {} +Table::Actions::Action::~Action() {} + +Table::Actions::Actions(Table *tbl, VECTOR(pair_t) & data) { + table = tbl; + int pos = 0; + for (auto &kv : data) { + if ((kv.key.type != tINT && !CHECKTYPE2M(kv.key, tSTR, tCMD, "action")) || + !CHECKTYPE(kv.value, tVEC)) + continue; + std::string name = kv.key.type == tINT ? std::to_string(kv.key.i) + : kv.key.type == tSTR ? kv.key.s + : kv.key[0].s; + if (actions.count(name)) { + error(kv.key.lineno, "Duplicate action %s", name.c_str()); + continue; + } + actions.emplace(name, tbl, this, kv, pos++); + } +} + +int Table::Actions::hit_actions_count() const { + int cnt = 0; + for (auto &a : actions) { + if (a.second.hit_allowed) ++cnt; + } + return cnt; +} + +int Table::Actions::default_actions_count() const { + int cnt = 0; + for (auto &a : actions) { + if (a.second.default_allowed) ++cnt; + } + return cnt; +} + +AlwaysRunTable::AlwaysRunTable(gress_t gress, Stage *stage, pair_t &init) + : Table(init.key.lineno, + "always run " + to_string(gress) + " stage " + to_string(stage->stageno), gress, + stage) { + VECTOR(pair_t) tmp = {1, 1, &init}; + actions.reset(new Actions(this, tmp)); + if (actions->count() == 1) { // unless there was an error parsing the action... + auto &act = *actions->begin(); + if (act.addr >= 0) error(act.lineno, "always run action address is fixed"); + act.addr = ACTION_ALWAYS_RUN_IMEM_ADDR; + } +} + +void Table::Actions::Action::check_next_ref(Table *tbl, const Table::Ref &ref) const { + if (ref.check() && ref->table_id() >= 0 && ref->table_id() < tbl->table_id()) { + error(lineno, "Next table %s for action %s before containing table %s", ref->name(), + name.c_str(), tbl->name()); + return; + } + + if (ref->table_id() > (1U << NEXT_TABLE_MAX_RAM_EXTRACT_BITS) - 1 && + tbl->get_hit_next().size() == 0) { + error(lineno, "Next table cannot properly be saved on the RAM line for this action %s", + name.c_str()); + } +} + +/** + * By the end of this function, both next_table and next_table_miss_ref will have been created + * and validated. + * + * Each action must have at least next_table or a next_table_miss from the node. + * - next_table: The next table to run on hit + * - next_table_miss: The next table to run on miss + * + * The next_table_encode is the entry into the next_table_hitmap, if a next_table hit map is + * provided. If the next_table hit map is empty, then the next_table_encode won't have been + * set. If the action can be used on a hit, then either a next_table_ref/next_table_encode + * would be provided. + * + * The next_table_ref could come from the next_table as an int value, which would be on offset + * into the hit_map + */ +void Table::Actions::Action::check_next(Table *tbl) { + if (next_table_encode >= 0) { + int idx = next_table_encode; + if (idx < tbl->get_hit_next().size()) { + next_table_ref = tbl->get_hit_next().at(idx); + } else if ((idx -= tbl->get_hit_next().size()) < tbl->extra_next_lut.size()) { + next_table_ref = tbl->extra_next_lut.at(idx); + } else { + error(lineno, + "The encoding on action %s is outside the range of the hitmap in " + "table %s", + name.c_str(), tbl->name()); + } + } + + if (!next_table_miss_ref.set() && !next_table_ref.set()) { + if (tbl->get_hit_next().size() != 1) { + error(lineno, + "Either next_table or next_table_miss must be required on action %s " + "if the next table cannot be determined", + name.c_str()); + } else { + next_table_ref = tbl->get_hit_next()[0]; + next_table_miss_ref = next_table_ref; + next_table_encode = 0; + } + } else if (!next_table_ref.set()) { + if (!default_only) { + error(lineno, + "Action %s on table %s that can be programmed on hit must have " + "a next_table encoding", + name.c_str(), tbl->name()); + } + next_table_ref = next_table_miss_ref; + } else if (!next_table_miss_ref.set()) { + next_table_miss_ref = next_table_ref; + } + tbl->check_next(next_table_ref); + tbl->check_next(next_table_miss_ref); + if (next_table_encode < 0 && !default_only) next_table_ref.force_single_next_table(); + for (auto &n : next_table_ref) check_next_ref(tbl, n); + for (auto &n : next_table_miss_ref) check_next_ref(tbl, n); +} + +void Table::Actions::Action::pass1(Table *tbl) { + // The compiler generates all action handles which must be specified in the + // assembly, if not we throw an error. + if ((handle == 0) && tbl->needs_handle()) { + error(lineno, "No action handle specified for table - %s, action - %s", tbl->name(), + name.c_str()); + } + + if (tbl->needs_next()) { + check_next(tbl); + } + + if (tbl->get_default_action() == name) { + if (!tbl->default_action_handle) tbl->default_action_handle = handle; + if (tbl->default_only_action) default_only = true; + } + /* SALU actions always have addr == -1 (so iaddr == -1) */ + int iaddr = -1; + bool shared_VLIW = false; + for (auto &inst : instr) { + inst.reset(inst.release()->pass1(tbl, this)); + if (inst->slot >= 0) { + if (slot_use[inst->slot]) + error(inst->lineno, "instruction slot %d used multiple times in action %s", + inst->slot, name.c_str()); + slot_use[inst->slot] = 1; + } + } + if (addr >= 0) { + if (auto old = tbl->stage->imem_addr_use[imem_thread(tbl->gress)][addr]) { + if (equivVLIW(old)) { + shared_VLIW = true; + } else { + error(lineno, "action instruction addr %d in use elsewhere", addr); + warning(old->lineno, "also defined here"); + } + } + tbl->stage->imem_addr_use[imem_thread(tbl->gress)][addr] = this; + iaddr = addr / ACTION_IMEM_COLORS; + } + if (!shared_VLIW) { + for (auto &inst : instr) { + if (inst->slot >= 0 && iaddr >= 0) { + if (tbl->stage->imem_use[iaddr][inst->slot]) + error(lineno, "action instruction slot %d.%d in use elsewhere", iaddr, + inst->slot); + tbl->stage->imem_use[iaddr][inst->slot] = 1; + } + } + } + for (auto &a : alias) { + while (alias.count(a.second.name) >= 1) { + // the alias refers to something else in the alias list + auto &rec = alias.find(a.second.name)->second; + if (rec.name == a.first) { + error(a.second.lineno, "recursive alias %s", a.first.c_str()); + break; + } + if (rec.lo > 0) { + a.second.lo += rec.lo; + if (a.second.hi >= 0) a.second.hi += rec.lo; + } + if (rec.hi > 0 && a.second.hi < 0) a.second.hi = rec.hi; + if (a.second.lo < rec.lo || (rec.hi >= 0 && a.second.hi > rec.hi)) { + error(a.second.lineno, + "alias for %s:%s(%d:%d) has out of range index from allowed %s:%s(%d:%d)", + a.first.c_str(), a.second.name.c_str(), a.second.lo, a.second.hi, + a.second.name.c_str(), rec.name.c_str(), rec.lo, rec.hi); + break; + } + a.second.name = rec.name; + } + if (auto *f = tbl->lookup_field(a.second.name, name)) { + if (a.second.hi < 0) a.second.hi = f->size - 1; + } else if (a.second.name == "hash_dist" && a.second.lo >= 0) { + // nothing to be done for now. lo..hi is the hash dist index rather than + // a bit index, which will cause problems if we want to later slice the alias + // to access only some bits of it. + } else { + error(a.second.lineno, "No field %s in table %s", a.second.to_string().c_str(), + tbl->name()); + } + } + // Update default value for params if default action parameters present + for (auto &p : p4_params_list) { + if (auto def_act_params = tbl->get_default_action_parameters()) { + if (def_act_params->count(p.name) > 0) { + p.default_value = (*def_act_params)[p.name]; + p.defaulted = true; + } + } + } + for (auto &c : attached) { + if (!c) { + error(c.lineno, "Unknown instruction or table %s", c.name.c_str()); + continue; + } + if (c->table_type() != COUNTER && c->table_type() != METER && c->table_type() != STATEFUL) { + error(c.lineno, "%s is not a counter, meter or stateful table", c.name.c_str()); + continue; + } + } +} + +/** + * Determines if the field, which has a particular range of bits in the format, is controlled + * by a conditional variable. This is required for context JSON information on parameters in + * the action data table pack format, or in the immediate fields: + * + * -is_mod_field_conditionally_value + * -mod_field_conditionally_mask_field_name + * + * @sa asm_output::EmitAction::mod_cond_value + */ +void Table::Actions::Action::check_conditional(Table::Format::Field &field) const { + bool found = false; + std::string condition; + for (auto kv : mod_cond_values) { + for (auto br : field.bits) { + auto overlap = kv.second[MC_ADT].getslice(br.lo, br.size()); + if (overlap.empty()) { + BUG_CHECK(!found || (found && condition != kv.first)); + } else if (overlap.popcount() == br.size()) { + if (found) { + BUG_CHECK(condition == kv.first); + } else { + found = true; + condition = kv.first; + } + } else { + BUG(); + } + } + } + if (found) { + field.conditional_value = true; + field.condition = condition; + } +} + +/** + * @sa Table::Actions::Action::check_conditional + */ +bool Table::Actions::Action::immediate_conditional(int lo, int sz, std::string &condition) const { + bool found = false; + for (auto kv : mod_cond_values) { + auto overlap = kv.second[MC_IMMED].getslice(lo, sz); + if (overlap.empty()) { + BUG_CHECK(!found || (found && condition != kv.first)); + } else { + if (found) { + BUG_CHECK(condition == kv.first); + } else if (overlap.popcount() == sz) { + found = true; + condition = kv.first; + } else { + BUG(); + } + } + } + return found; +} + +void Table::Actions::pass1(Table *tbl) { + for (auto &act : *this) { + act.pass1(tbl); + slot_use |= act.slot_use; + } +} + +std::map
> Table::find_pred_in_stage( + int stageno, const std::set &acts) { + std::map
> rv; + if (stage->stageno < stageno) return rv; + if (stage->stageno == stageno) { + rv[this].insert(acts.begin(), acts.end()); + } + for (auto &p : pred) { + for (auto &kv : p.first->find_pred_in_stage(stageno, p.second)) { + rv[kv.first].insert(kv.second.begin(), kv.second.end()); + } + } + for (auto *mt : get_match_tables()) { + if (mt != this) { + for (auto &kv : mt->find_pred_in_stage(stageno, acts)) { + rv[kv.first].insert(kv.second.begin(), kv.second.end()); + } + } + } + return rv; +} + +void Table::Actions::pass2(Table *tbl) { + /* We do NOT call this for SALU actions, so we can assume VLIW actions here */ + BUG_CHECK(tbl->table_type() != STATEFUL); + int code = tbl->get_gateway() ? 1 : 0; // if there's a gateway, reserve code 0 for a NOP + // to run when the gateway inhibits the table + + /* figure out how many codes we can encode in the match table(s), and if we need a distinct + * code for every action to handle next_table properly */ + int code_limit = 0x10000; + bool use_code_for_next = false; // true iff a table uses the action code for next table + // selection in addition to using it for the action instruction + + for (auto match : tbl->get_match_tables()) { + // action is currently a default keyword for the instruction address + auto instruction = match->instruction_call(); + auto fld = instruction.args[0].field(); + if (fld) { + code_limit = 1 << fld->size; + if (match->hit_next_size() > 1 && !match->lookup_field("next")) + use_code_for_next = true; + } else { + code_limit = code + 1; + } + } + + /* figure out if we need more codes than can fit in the action_instruction_adr_map. + * use code = -1 to signal that condition. */ + int non_nop_actions = by_code.size(); + // Check if a nop action is defined. The action will be empty (no + // instructions). By default we will use code '0' for nop action, unless + // compiler has assigned a different value. + int nop_code = 0; + for (auto &bc : by_code) { + if (bc.second->instr.empty()) nop_code = bc.first; + } + if (by_code.count(nop_code) && by_code.at(nop_code)->instr.empty()) { + --non_nop_actions; // don't count nop code action + code = 1; + } + for (auto &act : *this) { + if (act.default_only) continue; + if (act.instr.empty() && !use_code_for_next) + code = 1; // nop action -- use code 0 unless it needs to be used as next + else if (act.code < 0) + ++non_nop_actions; + } // FIXME -- should combine identical actions? + if (code + non_nop_actions > ACTION_INSTRUCTION_SUCCESSOR_TABLE_DEPTH) code = -1; + bool code0_is_noop = (code != 0); + + for (auto &act : *this) { + for (auto &inst : act.instr) inst->pass2(tbl, &act); + if (act.addr < 0) { + for (int i = 0; i < ACTION_IMEM_ADDR_MAX; i++) { + if (auto old = tbl->stage->imem_addr_use[imem_thread(tbl->gress)][i]) { + if (act.equivVLIW(old)) { + act.addr = i; + break; + } + continue; + } + if (tbl->stage->imem_use[i / ACTION_IMEM_COLORS].intersects(act.slot_use)) continue; + act.addr = i; + tbl->stage->imem_use[i / ACTION_IMEM_COLORS] |= act.slot_use; + tbl->stage->imem_addr_use[imem_thread(tbl->gress)][i] = &act; + break; + } + } + if (act.addr < 0) error(act.lineno, "Can't find an available instruction address"); + if (act.code < 0 && !act.default_only) { + if (code < 0 && !code_use[act.addr]) { + act.code = act.addr; + } else if (act.instr.empty() && !use_code_for_next && code0_is_noop) { + act.code = 0; + } else { + while (code >= 0 && code_use[code]) code++; + act.code = code; + } + } else if (code < 0 && act.code != act.addr && !act.default_only) { + error(act.lineno, + "Action code must be the same as action instruction address " + "when there are more than %d actions", + ACTION_INSTRUCTION_SUCCESSOR_TABLE_DEPTH); + if (act.code < 0) + warning(act.lineno, "Code %d is already in use by another action", act.addr); + } + if (act.code >= 0) { + by_code[act.code] = &act; + code_use[act.code] = true; + } + if (act.code >= code_limit) + error(act.lineno, + "Action code %d for %s too large for action specifier in " + "table %s", + act.code, act.name.c_str(), tbl->name()); + if (act.code > max_code) max_code = act.code; + } + actions.sort([](const value_type &a, const value_type &b) -> bool { + return a.second.code < b.second.code; + }); + if (!tbl->default_action.empty()) { + if (!exists(tbl->default_action)) { + error(tbl->default_action_lineno, "no action %s in table %s", + tbl->default_action.c_str(), tbl->name()); + } else { + auto &defact = actions.at(tbl->default_action); + if (!defact.default_allowed) { + // FIXME -- should be an error, but the compiler currently does this? + // FIXME -- see p4_16_programs_tna_lpm_match + warning(tbl->default_action_lineno, + "default action %s in table %s is not allowed " + "to be default?", + tbl->default_action.c_str(), tbl->name()); + defact.default_allowed = true; + } + } + } + auto pred = tbl->find_pred_in_stage(tbl->stage->stageno); + for (auto &p : pred) { + auto *actions = p.first->get_actions(); + if (!actions || actions == this) continue; + if (!slot_use.intersects(actions->slot_use)) continue; + for (auto &a1 : *this) { + bool first = false; + for (auto a2 : p.second) { + if (a1.slot_use.intersects(a2->slot_use)) { + if (!first) + warning(a1.lineno, + "Conflicting instruction slot usage for non-exlusive " + "table %s action %s", + tbl->name(), a1.name.c_str()); + first = true; + warning(a2->lineno, "and table %s action %s", p.first->name(), + a2->name.c_str()); + } + } + } + } +} + +void Table::Actions::stateful_pass2(Table *tbl) { + BUG_CHECK(tbl->table_type() == STATEFUL); + auto *stbl = tbl->to(); + for (auto &act : *this) { + if (act.code >= 4) { + error(act.lineno, "Only 4 actions in a stateful table"); + } else if (act.code >= 0) { + if (code_use[act.code]) { + error(act.lineno, "duplicate use of code %d in SALU", act.code); + warning(by_code[act.code]->lineno, "previous use here"); + } + by_code[act.code] = &act; + code_use[act.code] = true; + } + if (act.code == 3 && stbl->clear_value) + error(act.lineno, "Can't use SALU action 3 with a non-zero clear value"); + for (const auto &inst : act.instr) inst->pass2(tbl, &act); + } + if (stbl->clear_value) code_use[3] = true; + for (auto &act : *this) { + if (act.code < 0) { + if ((act.code = code_use.ffz(0)) >= 4) { + error(act.lineno, "Only 4 actions in a stateful table"); + break; + } + by_code[act.code] = &act; + code_use[act.code] = true; + } + } +} + +template +void Table::Actions::write_regs(REGS ®s, Table *tbl) { + for (auto &act : *this) { + LOG2("# action " << act.name << " code=" << act.code << " addr=" << act.addr); + tbl->write_action_regs(regs, &act); + for (const auto &inst : act.instr) inst->write_regs(regs, tbl, &act); + if (options.fill_noop_slot) { + for (auto slot : Phv::use(tbl->gress) - tbl->stage->imem_use_all()) { + auto tmp = VLIW::genNoopFill(tbl, &act, options.fill_noop_slot, slot); + tmp->pass1(tbl, &act); + tmp->pass2(tbl, &act); + tmp->write_regs(regs, tbl, &act); + } + } + } +} +FOR_ALL_REGISTER_SETS(INSTANTIATE_TARGET_TEMPLATE, void Table::Actions::write_regs, mau_regs &, + Table *) + +/** + * Indirect Counters, Meters, and Stateful Alus can be addressed in many different ways, e.g. + * Hash Distribution, Overhead Index, Stateful Counter, Constant, etc. + * + * The indexing can be different per individual action. Say one action always uses an indirect + * address, while another one uses a constant. The driver has to know where to put that + * constant into the RAM line. + * + * Also, say an address is from hash, but can have multiple meter types. By using the override + * address of an action, when that action is programmed, the meter type written in overhead will + * be determined by the overhead address. + * + * override_addr - a boolean of whether to use the override value for these parameters. + * This is enabled if the address does not come from overhead. + * + * Override_addr_pfe - Not actually useful, given the override_full_addr contains the per flow + * enable bit + * + * Override_full_addr - the constant value to be written directly into the corresponding bit + * positions in the RAM line + */ +static void gen_override(json::map &cfg, const Table::Call &att) { + auto type = att->table_type(); + // Direct tables currently don't require overrides + // FIXME: Corner cases where miss actions do not use the stateful object should have + // an override of all 0 + if (att->to()->is_direct()) return; + std::string base; + bool override_addr = false; + bool override_addr_pfe = false; + unsigned override_full_addr = 0; + switch (type) { + case Table::COUNTER: + base = "override_stat"; + break; + case Table::METER: + base = "override_meter"; + break; + case Table::STATEFUL: + base = "override_stateful"; + break; + default: + error(att.lineno, "unsupported table type in action call"); + } + // Always true if the call is provided + override_addr_pfe = true; + override_full_addr |= 1U << (type == Table::COUNTER ? STATISTICS_PER_FLOW_ENABLE_START_BIT + : METER_PER_FLOW_ENABLE_START_BIT); + int idx = -1; + for (auto &arg : att.args) { + ++idx; + if (arg.type == Table::Call::Arg::Name) { + if (strcmp(arg.name(), "$hash_dist") == 0 || + strcmp(arg.name(), "$stful_counter") == 0) { + override_addr = true; + } else if (auto *st = att->to()) { + if (auto *act = st->actions->action(arg.name())) { + override_full_addr |= 1 << METER_TYPE_START_BIT; + override_full_addr |= act->code << (METER_TYPE_START_BIT + 1); + } + } + // FIXME -- else assume its a reference to a format field, so doesn't need to + // FIXME -- be in the override. Should check that somewhere, but need access + // FIXME -- to the match_table to do it here. + } else if (arg.type == Table::Call::Arg::Const) { + if (idx == 0 && att.args.size() > 1) { + // The first argument for meters/stateful is the meter type + override_full_addr |= arg.value() << METER_TYPE_START_BIT; + } else { + override_full_addr |= arg.value() << att->address_shift(); + override_addr = true; + } + } else if (arg.type == Table::Call::Arg::Counter) { + // does not affect context json + } else { + error(att.lineno, "argument not a constant"); + } + } + cfg[base + "_addr"] = override_addr; + cfg[base + "_addr_pfe"] = override_addr ? override_addr_pfe : false; + cfg[base + "_full_addr"] = override_addr ? override_full_addr : 0; +} + +bool Table::Actions::Action::is_color_aware() const { + for (auto &att : attached) { + if (att->table_type() != Table::METER) continue; + if (att.args.size() < 2) continue; + auto type_arg = att.args[0]; + if (type_arg.type == Table::Call::Arg::Const && type_arg.value() == METER_COLOR_AWARE) + return true; + } + return false; +} + +void Table::Actions::Action::check_and_add_resource(json::vector &resources, + json::map &resource) const { + // Check if resource already exists in the json::vector. For tables + // spanning multiple stages, the same resource gets added as an attached + // resource for every stage. To avoid duplication only add when not + // present in the resource array + bool found = false; + for (auto &r : resources) { + if (resource == r->to()) { + found = true; + break; + } + } + if (!found) resources.push_back(std::move(resource)); +} + +void Table::Actions::Action::add_direct_resources(json::vector &direct_resources, + const Call &att) const { + json::map direct_resource; + direct_resource["resource_name"] = att->p4_name(); + direct_resource["handle"] = att->handle(); + check_and_add_resource(direct_resources, direct_resource); +} + +void Table::Actions::Action::add_indirect_resources(json::vector &indirect_resources, + const Call &att) const { + auto addr_arg = att.args.back(); + json::map indirect_resource; + if (addr_arg.type == Table::Call::Arg::Name) { + auto *p = has_param(addr_arg.name()); + if (p) { + indirect_resource["access_mode"] = "index"; + indirect_resource["parameter_name"] = p->name; + indirect_resource["parameter_index"] = p->position; + } else { + return; + } + } else if (addr_arg.type == Table::Call::Arg::Const) { + indirect_resource["access_mode"] = "constant"; + indirect_resource["value"] = addr_arg.value(); + } else { + return; + } + indirect_resource["resource_name"] = att->p4_name(); + indirect_resource["handle"] = att->handle(); + check_and_add_resource(indirect_resources, indirect_resource); +} + +void Table::Actions::gen_tbl_cfg(json::vector &actions_cfg) const { + for (auto &act : *this) { + // Use action node if it already exists in json + bool act_json_present = false; + json::map *action_ptr = nullptr; + for (auto &_action_o : actions_cfg) { + auto &_action = _action_o->to(); + if (_action["name"] == act.name) { + action_ptr = &_action; + act_json_present = true; + break; + } + } + if (!act_json_present) action_ptr = new json::map(); + json::map &action_cfg = *action_ptr; + + action_cfg["name"] = act.name; + action_cfg["handle"] = act.handle; // FIXME-JSON + if (act.instr.empty() || action_cfg.count("primitives") == 0) + action_cfg["primitives"] = json::vector(); + auto &direct_resources = action_cfg["direct_resources"] = json::vector(); + auto &indirect_resources = action_cfg["indirect_resources"] = json::vector(); + for (auto &att : act.attached) { + if (att.is_direct_call()) + act.add_direct_resources(direct_resources, att); + else + act.add_indirect_resources(indirect_resources, att); + } + if (!act.hit_allowed && !act.default_allowed) + error(act.lineno, "Action %s must be allowed to be hit and/or default action.", + act.name.c_str()); + action_cfg["allowed_as_hit_action"] = act.hit_allowed; + // TODO: allowed_as_default_action info is directly passed through assembly + // This will be 'false' for following conditions: + // 1. Action requires hardware in hit path i.e. hash distribution or + // random number generator + // 2. There is a default action declared constant in program which + // implies all other actions cannot be set to default + action_cfg["allowed_as_default_action"] = act.default_allowed; + // TODO: "disallowed_as_default_action" is not used by driver. + // Keeping it here as debugging info. Will be set to "none", + // "has_const_default", "has_hash_dist". Once rng support is added + // to the compiler this must reflect "has_rng" or similar string. + if (!act.default_allowed) + action_cfg["disallowed_as_default_action_reason"] = act.default_disallowed_reason; + // TODO: Need to be set through assembly + action_cfg["is_compiler_added_action"] = false; + action_cfg["constant_default_action"] = act.is_constant; + + // TODO: These will be set to 'true' & "" for a keyless table to + // allow any action to be set as default by the control plane + // Exception is TernaryIndirectTables which dont have params list as they are on the main + // TernaryMatchTable, hence check for match_table to query params list + if (table->get_match_table()->p4_params_list.empty()) { + action_cfg["allowed_as_default_action"] = true; + action_cfg["disallowed_as_default_action_reason"] = ""; + } + + json::vector &p4_params = action_cfg["p4_parameters"] = json::vector(); + act.add_p4_params(p4_params); + action_cfg["override_meter_addr"] = false; + action_cfg["override_meter_addr_pfe"] = false; + action_cfg["override_meter_full_addr"] = 0; + action_cfg["override_stat_addr"] = false; + action_cfg["override_stat_addr_pfe"] = false; + action_cfg["override_stat_full_addr"] = 0; + action_cfg["override_stateful_addr"] = false; + action_cfg["override_stateful_addr_pfe"] = false; + action_cfg["override_stateful_full_addr"] = 0; + for (auto &att : act.attached) gen_override(action_cfg, att); + action_cfg["is_action_meter_color_aware"] = act.is_color_aware(); + if (act.context_json) action_cfg.merge(*act.context_json.get()); + if (!act_json_present) actions_cfg.push_back(std::move(action_cfg)); + } +} + +/** + * For action data tables, the entirety of the action configuration is not necessary, as the + * information is per match table, not per action data table. The only required parameters + * are the name, handle, and p4_parameters + * + * Even at some point, even actions that have the different p4_parameters could even share a + * member, if for example, one of the parameters is not stored in the action data table, + * but rather as an index for a counter/meter etc. The compiler/driver do not have support for + * this yet. + */ +void Table::Actions::Action::gen_simple_tbl_cfg(json::vector &actions_cfg) const { + json::map action_cfg; + action_cfg["name"] = name; + action_cfg["handle"] = handle; + json::vector &p4_params = action_cfg["p4_parameters"] = json::vector(); + add_p4_params(p4_params, false); + actions_cfg.push_back(std::move(action_cfg)); +} + +void Table::Actions::Action::add_p4_params(json::vector &cfg, bool include_default) const { + unsigned start_bit = 0; + for (auto &a : p4_params_list) { + json::map param; + param["name"] = a.name; + param["start_bit"] = start_bit; + param["position"] = a.position; + if (include_default && a.defaulted) param["default_value"] = a.default_value; + param["bit_width"] = a.bit_width; + if (a.context_json) param.merge(*a.context_json.get()); + cfg.push_back(std::move(param)); + start_bit += a.bit_width; + } +} + +void Table::Actions::add_p4_params(const Action &act, json::vector &cfg) const { + int index = 0; + unsigned start_bit = 0; + // Add p4 params if present. This will add params even if the action is + // otherwise empty. Driver will always generate an action spec if p4_params + // are present for an action + for (auto &a : act.p4_params_list) { + json::map param; + param["name"] = a.name; + param["start_bit"] = start_bit; + param["position"] = a.position; + if (a.defaulted) param["default_value"] = a.default_value; + param["bit_width"] = a.bit_width; + cfg.push_back(std::move(param)); + start_bit += a.bit_width; + } +} + +void Table::Actions::add_action_format(const Table *table, json::map &tbl) const { + json::vector &action_format = tbl["action_format"] = json::vector(); + for (auto &act : *this) { + json::map action_format_per_action; + unsigned next_table = -1; + + std::string next_table_name = "--END_OF_PIPELINE--"; + if (!act.default_only) { + if (act.next_table_encode >= 0) { + next_table = static_cast(act.next_table_encode); + } else { + // The RAM value is only 8 bits, for JBay must be solved by table placement + next_table = act.next_table_ref.next_table_id() & 0xff; + next_table_name = act.next_table_ref.next_table_name(); + if (next_table_name == "END") next_table_name = "--END_OF_PIPELINE--"; + } + } + unsigned next_table_full = act.next_table_miss_ref.next_table_id(); + + /** + * This following few fields are required on a per stage table action basis. + * The following information is: + * + * - next_table - The value that will be written into the next field RAM line on a hit, + * when the entry is specified with this action. This is either an index into + * the next_table_map_en (if that map is enabled), or the 8 bit next table value. + * + * - next_table_full - The value that will be written into the miss register for next + * table (next_table_format_data.match_next_table_adr_miss_value), if this action + * is set as the default action. This is the full 8 bit (9 bit for JBay) next + * table. + * + * - vliw_instruction - The value that will be written into the action instruction RAM + * entry when the entry is specified with this action. This is either an index + * into into the 8 entry table mau_action_instruction_adr_map_data, if that is + * enabled, or the full word instruction + * + * - vliw_instruction_full - The value that will written into the miss register for + * action_instruction (mau_action_instruction_adr_miss_value), when this + * action is specified as the default action. The full address with the PFE + * bit enabled. + */ + action_format_per_action["action_name"] = act.name; + action_format_per_action["action_handle"] = act.handle; + action_format_per_action["table_name"] = next_table_name; + action_format_per_action["next_table"] = next_table; + action_format_per_action["next_table_full"] = next_table_full; + if (Target::LONG_BRANCH_TAGS() > 0 && !options.disable_long_branch) { + if (Target::NEXT_TABLE_EXEC_COMBINED()) { + action_format_per_action["next_table_exec"] = + ((act.next_table_miss_ref.next_in_stage(table->stage->stageno) & 0xfffe) + << 15) + + (act.next_table_miss_ref.next_in_stage(table->stage->stageno + 1) & 0xffff); + } else { + action_format_per_action["next_table_local_exec"] = + act.next_table_miss_ref.next_in_stage(table->stage->stageno) >> 1; + action_format_per_action["next_table_global_exec"] = + act.next_table_miss_ref.next_in_stage(table->stage->stageno + 1); + } + action_format_per_action["next_table_long_brch"] = + act.next_table_miss_ref.long_branch_tags(); + } + action_format_per_action["vliw_instruction"] = act.code; + action_format_per_action["vliw_instruction_full"] = + ACTION_INSTRUCTION_ADR_ENABLE | act.addr; + + json::vector &next_tables = action_format_per_action["next_tables"] = json::vector(); + for (auto n : act.next_table_ref) { + auto nP4Name = n->p4_name(); + // Gateway next tables dont have a p4 Name + if (nP4Name == nullptr) { + nP4Name = n.name.c_str(); + } + next_tables.push_back( + json::map{{"next_table_name", json::string(nP4Name)}, + {"next_table_logical_id", json::number(n->logical_id)}, + {"next_table_stage_no", json::number(n->stage->stageno)}}); + } + json::vector &action_format_per_action_imm_fields = + action_format_per_action["immediate_fields"] = json::vector(); + for (auto &a : act.alias) { + json::string name = a.first; + int lo = remove_name_tail_range(name); + json::string immed_name = a.second.name; + if (immed_name != "immediate") continue; // output only immediate fields + if (!(act.has_param(name) || a.second.is_constant)) + continue; // and fields that are parameters or constants + json::map action_format_per_action_imm_field; + action_format_per_action_imm_field["param_name"] = name; + action_format_per_action_imm_field["param_type"] = "parameter"; + if (a.second.is_constant) { + action_format_per_action_imm_field["param_type"] = "constant"; + action_format_per_action_imm_field["const_value"] = a.second.value; + action_format_per_action_imm_field["param_name"] = + "constant_" + std::to_string(a.second.value); + } + action_format_per_action_imm_field["param_shift"] = lo; + action_format_per_action_imm_field["dest_start"] = a.second.lo; + action_format_per_action_imm_field["dest_width"] = a.second.size(); + std::string condition; + if (act.immediate_conditional(a.second.lo, a.second.size(), condition)) { + action_format_per_action_imm_field["is_mod_field_conditionally_value"] = true; + action_format_per_action_imm_field["mod_field_conditionally_mask_field_name"] = + condition; + } + action_format_per_action_imm_fields.push_back( + std::move(action_format_per_action_imm_field)); + } + action_format.push_back(std::move(action_format_per_action)); + } +} + +std::ostream &operator<<(std::ostream &out, const Table::Actions::Action::alias_t &a) { + out << "(" << a.name << ", lineno = " << a.lineno << ", lo = " << a.lo << ", hi = " << a.hi + << ", is_constant = " << a.is_constant << ", value = 0x" << std::hex << a.value << std::dec + << ")"; + return out; +} + +std::ostream &operator<<(std::ostream &out, const Table::Actions::Action &a) { + out << a.name << "("; + auto indent = a.name.length() + 10; + for (auto &p : a.p4_params_list) out << p << std::endl << std::setw(indent); + out << ")"; + return out; +} + +std::ostream &operator<<(std::ostream &out, const Table::p4_param &p) { + out << p.name << "[ w =" << p.bit_width << ", w_full =" << p.bit_width_full + << ", start_bit =" << p.start_bit << ", mask = 0x" << p.mask << ", position =" << p.position + << ", default_value =" << p.default_value << ", defaulted =" << p.defaulted + << ", is_valid =" << p.is_valid << ", type =" << p.type << ", alias =" << p.alias + << ", key_name =" << p.key_name << "]"; + return out; +} + +void Table::Actions::add_immediate_mapping(json::map &tbl) { + for (auto &act : *this) { + if (act.alias.empty()) continue; + json::vector &map = tbl["action_to_immediate_mapping"][act.name]; + for (auto &a : act.alias) { + json::string name = a.first; + json::string immed_name = a.second.name; + if (immed_name == "immediate") immed_name = "--immediate--"; + int lo = remove_name_tail_range(name); + map.push_back(json::vector{json::map{ + {"name", std::move(name)}, + {"parameter_least_significant_bit", json::number(lo)}, + {"parameter_most_significant_bit", json::number(lo + a.second.hi - a.second.lo)}, + {"immediate_least_significant_bit", json::number(a.second.lo)}, + {"immediate_most_significant_bit", json::number(a.second.hi)}, + {"field_called", std::move(immed_name)}}}); + } + } +} + +template +void Table::write_mapram_regs(REGS ®s, int row, int col, int vpn, int type) { + auto &mapram_config = regs.rams.map_alu.row[row].adrmux.mapram_config[col]; + // auto &mapram_ctl = map_alu_row.adrmux.mapram_ctl[col]; + mapram_config.mapram_type = type; + mapram_config.mapram_logical_table = logical_id; + mapram_config.mapram_vpn_members = 0; + if (!options.match_compiler) // FIXME -- glass doesn't set this? + mapram_config.mapram_vpn = vpn; + if (gress == INGRESS) + mapram_config.mapram_ingress = 1; + else + mapram_config.mapram_egress = 1; + mapram_config.mapram_enable = 1; + mapram_config.mapram_ecc_check = 1; + mapram_config.mapram_ecc_generate = 1; + if (gress) regs.cfg_regs.mau_cfg_mram_thread[col / 3U] |= 1U << (col % 3U * 8U + row); +} +FOR_ALL_REGISTER_SETS(INSTANTIATE_TARGET_TEMPLATE, void Table::write_mapram_regs, mau_regs &, int, + int, int, int) + +HashDistribution *Table::find_hash_dist(int unit) { + for (auto &hd : hash_dist) + if (hd.id == unit) return &hd; + for (auto t : get_match_tables()) + for (auto &hd : t->hash_dist) + if (hd.id == unit) return &hd; + if (auto *a = get_attached()) + for (auto &call : a->meters) + for (auto &hd : call->hash_dist) + if (hd.id == unit) return &hd; + return nullptr; +} + +int Table::find_on_actionbus(const char *name, TableOutputModifier mod, int lo, int hi, int size, + int *len) { + return action_bus ? action_bus->find(name, mod, lo, hi, size, len) : -1; +} + +void Table::need_on_actionbus(Table *att, TableOutputModifier mod, int lo, int hi, int size) { + if (!action_bus) action_bus = ActionBus::create(); + action_bus->need_alloc(this, att, mod, lo, hi, size); +} + +int Table::find_on_actionbus(const ActionBusSource &src, int lo, int hi, int size, int pos) { + return action_bus ? action_bus->find(src, lo, hi, size, pos) : -1; +} + +void Table::need_on_actionbus(const ActionBusSource &src, int lo, int hi, int size) { + if (!action_bus) action_bus = ActionBus::create(); + action_bus->need_alloc(this, src, lo, hi, size); +} + +int Table::find_on_ixbar(Phv::Slice sl, InputXbar::Group group, InputXbar::Group *found) { + for (auto &ixb : input_xbar) { + if (auto *i = ixb->find(sl, group, found)) { + unsigned bit = (i->lo + sl.lo - i->what->lo); + BUG_CHECK(bit < 128); + return bit / 8; + } + } + if (group.index >= 0) { + for (auto *in : stage->ixbar_use[group]) { + if (auto *i = in->find(sl, group)) { + unsigned bit = (i->lo + sl.lo - i->what->lo); + BUG_CHECK(bit < 128); + return bit / 8; + } + } + } else { + for (auto &g : Keys(stage->ixbar_use)) { + if (g.type != group.type) continue; + int t; + if ((t = find_on_ixbar(sl, g)) >= 0) { + if (found) *found = g; + return t; + } + } + } + return -1; +} + +int Table::json_memunit(const MemUnit &r) const { + if (r.stage >= 0) { + return r.stage * Target::SRAM_STRIDE_STAGE() + r.row * Target::SRAM_STRIDE_ROW() + + r.col * Target::SRAM_STRIDE_COLUMN(); + } else if (r.row >= 0) { + // per-stage physical sram + return r.row * Target::SRAM_UNITS_PER_ROW() + r.col; + } else { + // lamb + return r.col; + } +} + +std::unique_ptr Table::gen_memory_resource_allocation_tbl_cfg( + const char *type, const std::vector &layout, bool skip_spare_bank) const { + int width, depth, period; + const char *period_name; + // FIXME -- calling vpn_params here is only valid when layout == this->layout, but we also + // FIXME -- get here for color_maprams. It works out as we don't use depth or width, only + // FIXME -- period, which will always be 1 for meter layout or color_maprams + vpn_params(width, depth, period, period_name); + json::map mra; + mra["memory_type"] = type; + std::vector> mem_units; + json::vector &mem_units_and_vpns = mra["memory_units_and_vpns"] = json::vector(); + int vpn_ctr = 0; + bool no_vpns = false; + int spare_vpn; + std::vector spare_mem; + + // Retrieve the Spare banks + // skip_spare_bank is only false on tables don't have spare banks, or when building + // memory_units json for map rams + if (skip_spare_bank) { + BUG_CHECK(&layout == &this->layout, "layout not matching"); + spare_mem = determine_spare_bank_memory_units(); + BUG_CHECK(!spare_mem.empty(), "No spare banks in %s?", name()); + // if all the mems are "spare" this is really a DDP table, so we want to + // put the usits/vpns of the spares in the memory_units json + if (spare_mem.size() == layout_size()) skip_spare_bank = false; + } else if (&layout == &this->layout) { + BUG_CHECK(determine_spare_bank_memory_units().empty(), + "%s has spare banks, but we're not skipping them?", name()); + } + + for (auto &row : layout) { + int word = row.word >= 0 ? row.word : 0; + auto vpn_itr = row.vpns.begin(); + for (auto &ram : row.memunits) { + BUG_CHECK(ram.row == row.row, "bogus %s in row %d", ram.desc(), row.row); + if (vpn_itr == row.vpns.end()) + no_vpns = true; + else + vpn_ctr = *vpn_itr++; + if (size_t(vpn_ctr) >= mem_units.size()) mem_units.resize(vpn_ctr + 1); + // Create a vector indexed by vpn no where each element is a map + // having a RAM entry indexed by word number + // VPN WORD RAM + // 0 -> 0 90 + // 1 91 + // 1 -> 0 92 + // 1 93 + // E.g. VPN 0 has Ram 90 with word 0 and Ram 91 with word 1 + int unit = json_memunit(ram); + if (skip_spare_bank && + std::find(spare_mem.begin(), spare_mem.end(), unit) != spare_mem.end()) + continue; + mem_units[vpn_ctr][word] = json_memunit(ram); + } + } + if (mem_units.size() == 0) return nullptr; + int vpn = 0; + for (auto &mem_unit : mem_units) { + json::vector mem; + // Below for loop orders the mem unit as { .., word1, word0 } which is + // assumed to be what driver expects. + for (int word = mem_unit.size() - 1; word >= 0; word--) { + for (auto m : mem_unit) { + if (m.first == word) { + mem.push_back(m.second); + break; + } + } + } + if (mem.size() != 0) { + json::map tmp; + tmp["memory_units"] = std::move(mem); + json::vector vpns; + if (no_vpns) + vpns.push_back(nullptr); + else + vpns.push_back(vpn); + tmp["vpns"] = std::move(vpns); + mem_units_and_vpns.push_back(std::move(tmp)); + } + vpn++; + } + if (skip_spare_bank && spare_mem.size() != 0) { + if (spare_mem.size() == 1) { + mra["spare_bank_memory_unit"] = spare_mem[0]; + } else { + json::vector &spare = mra["spare_bank_memory_unit"]; + for (auto u : spare_mem) spare.push_back(u); + } + } + return json::mkuniq(std::move(mra)); +} + +json::map *Table::base_tbl_cfg(json::vector &out, const char *type, int size) const { + auto tbl = p4_table->base_tbl_cfg(out, size, this); + if (context_json) add_json_node_to_table(*tbl, "user_annotations"); + return tbl; +} + +json::map *Table::add_stage_tbl_cfg(json::map &tbl, const char *type, int size) const { + json::vector &stage_tables = tbl["stage_tables"]; + json::map stage_tbl; + stage_tbl["stage_number"] = stage->stageno; + stage_tbl["size"] = size; + stage_tbl["stage_table_type"] = type; + stage_tbl["logical_table_id"] = logical_id; + if (physical_ids) { + // this is only used by the driver to set miss entry imem/iad/next, so it should + // not matter which physical table it is set on if there are multiple + stage_tbl["physical_table_id"] = *physical_ids.begin(); + } + + if (this->to()) { + stage_tbl["has_attached_gateway"] = false; + if (get_gateway()) stage_tbl["has_attached_gateway"] = true; + } + if (!strcmp(type, "selection") && get_stateful()) + tbl["bound_to_stateful_table_handle"] = get_stateful()->handle(); + if (Target::SUPPORT_ALWAYS_RUN() && (this->to() || this->to())) + stage_tbl["always_run"] = is_always_run(); + + stage_tables.push_back(std::move(stage_tbl)); + return &(stage_tables.back()->to()); +} + +/** + * One can no longer use whether the table is directly or indirectly addressed on whether + * a table is referenced that way. This is due to the corner case on hash action tables + * For a hash action table, an attached table that was previously directly addressed is now + * addressed by hash. However, for the driver, the driver must know which tables used to be + * directly addressed vs. an attached table that is addressed by a hash based index. + * + * Thus, for those corner cases, a how_referenced in the p4 tag of the attached table is + * currently provided. Really for an attached table in hardware, it has no sense of how the + * table is addressed, as it only receives an address, so if somehow two tables, where one was + * direct while another was indirect (which is theoretically supportable if a hash action direct + * counter is shared), would break this parameter. + * + * However, for the moment, there are no realistic attached table not either directly or indirectly + * referenced + * + * If we need to change this, this was the delineation for how this was determined in match tables: + * + * In the call for both of these examples, the address field is a hash_dist object, as this is + * necessary for the set up of the address. This call, unlike every other type table, cannot + * be the place where the address is determined. + * + * Instead, the attached calls in the action is how the assembler can delineate whether the + * reference table is direct or indirect. If the address argument is $DIRECT, then the direct + * table has been converted to a hash, however if the argument is $hash_dist, then the original + * call was from a hash-based index, and is indirect + */ +void Table::add_reference_table(json::vector &table_refs, const Table::Call &c) const { + if (c) { + auto t_name = c->name(); + if (c->p4_table) { + t_name = c->p4_table->p4_name(); + if (!t_name) { + error(-1, "No p4 table name found for table : %s", c->name()); + return; + } + } + // Dont add ref table if already present in table_refs vector + for (auto &tref : table_refs) { + auto tref_name = tref->to()["name"]; + if (!strcmp(tref_name->as_string()->c_str(), t_name)) return; + } + json::map table_ref; + std::string hr = c->to()->how_referenced(); + if (hr.empty()) hr = c->to()->is_direct() ? "direct" : "indirect"; + table_ref["how_referenced"] = hr; + table_ref["handle"] = c->handle(); + table_ref["name"] = t_name; + auto mtr = c->to(); + if (mtr && mtr->uses_colormaprams()) { + BUG_CHECK(mtr->color_mapram_addr != MeterTable::NO_COLOR_MAP, + "inconsistent color mapram address bus for %s", mtr->name()); + table_ref["color_mapram_addr_type"] = + mtr->color_mapram_addr == MeterTable::IDLE_MAP_ADDR ? "idle" : "stats"; + } + + table_refs.push_back(std::move(table_ref)); + } +} + +bool Table::is_directly_referenced(const Table::Call &c) const { + if (c) { + std::string hr = c->to()->how_referenced(); + if (hr.empty()) { + if (c->to()->is_direct()) return true; + } + } + return false; +} + +json::map &Table::add_pack_format(json::map &stage_tbl, int memword, int words, int entries) const { + json::map pack_fmt; + pack_fmt["table_word_width"] = memword * words; + pack_fmt["memory_word_width"] = memword; + if (entries >= 0) pack_fmt["entries_per_table_word"] = entries; + pack_fmt["number_memory_units_per_table_word"] = words; + json::vector &pack_format = stage_tbl["pack_format"]; + pack_format.push_back(std::move(pack_fmt)); + return pack_format.back()->to(); +} + +void Table::canon_field_list(json::vector &field_list) const { + for (auto &field_ : field_list) { + auto &field = field_->to(); + auto &name = field["field_name"]->to(); + if (int lo = remove_name_tail_range(name)) field["start_bit"]->to().val += lo; + } +} + +std::vector Table::get_calls() const { + std::vector rv; + if (action) rv.emplace_back(action); + if (instruction) rv.emplace_back(instruction); + return rv; +} + +/** + * Determines both the start bit and the source name in the context JSON node for a particular + * field. Do not like string matching, and this should potentially be determined by looking + * through a list of fields, but this will work in the short term + */ +void Table::get_cjson_source(const std::string &field_name, std::string &source, + int &start_bit) const { + source = "spec"; + if (field_name == "hash_group") { + source = "proxy_hash"; + } else if (field_name == "version") { + source = "version"; + } else if (field_name == "immediate") { + source = "immediate"; + } else if (field_name == "action") { + source = "instr"; + } else if (field_name == "next") { + source = "next_table"; + } else if (field_name == "action_addr") { + source = "adt_ptr"; + if (auto adt = action->to()) start_bit = std::min(5U, adt->get_log2size() - 2); + } else if (field_name == "counter_addr") { + source = "stats_ptr"; + auto a = get_attached(); + if (a && a->stats.size() > 0) { + auto s = a->stats[0]; + start_bit = s->address_shift(); + } + } else if (field_name == "counter_pfe") { + source = "stats_ptr"; + start_bit = STATISTICS_PER_FLOW_ENABLE_START_BIT; + } else if (field_name == "meter_addr") { + if (auto m = get_meter()) { + source = "meter_ptr"; + start_bit = m->address_shift(); + } else if (auto s = get_selector()) { + source = "sel_ptr"; + start_bit = s->address_shift(); + } else if (auto s = get_stateful()) { + source = "stful_ptr"; + start_bit = s->address_shift(); + } else { + error(lineno, "Table %s has a meter_addr but no attached meter", name()); + } + } else if (field_name == "meter_pfe") { + if (get_meter()) { + source = "meter_ptr"; + } else if (get_selector()) { + source = "sel_ptr"; + } else if (get_stateful()) { + source = "stful_ptr"; + } else { + error(lineno, "Table %s has a meter_pfe but no attached meter", name()); + } + start_bit = METER_PER_FLOW_ENABLE_START_BIT; + } else if (field_name == "meter_type") { + if (get_meter()) + source = "meter_ptr"; + else if (get_selector()) + source = "sel_ptr"; + else if (get_stateful()) + source = "stful_ptr"; + else + error(lineno, "Table %s has a meter_type but no attached meter", name()); + start_bit = METER_TYPE_START_BIT; + } else if (field_name == "sel_len_mod") { + source = "selection_length"; + } else if (field_name == "sel_len_shift") { + source = "selection_length_shift"; + } else if (field_name == "valid") { + source = "valid"; + } +} + +/** + * Adds a field into the format of either a match or action table. Honestly, this is used + * for both action data tables and match tables, and this should be split up into two + * separate functions, as the corner casing for these different cases can be quite different + * and lead to some significant confusion + */ +void Table::add_field_to_pack_format(json::vector &field_list, int basebit, std::string name, + const Table::Format::Field &field, + const Table::Actions::Action *act) const { + decltype(act->reverse_alias()) aliases; + if (act) aliases = act->reverse_alias(); + auto alias = get(aliases, name); + + // we need to add only those aliases that are parameters, and there can be multiple + // such fields that contain slices of one or more other aliases + // FIXME: why aren't we de-aliasing in setup? + for (auto a : alias) { + json::string param_name = a->first; + int lo = remove_name_tail_range(param_name); + if (act->has_param(param_name) || a->second.is_constant) { + auto newField = field; + if (a->second.hi != -1) { + unsigned fieldSize = a->second.hi - a->second.lo + 1; + if (field.bits.size() > 1) warning(0, "multiple bit ranges for %s", name.c_str()); + newField = + Table::Format::Field(field.fmt, fieldSize, a->second.lo + field.bits[0].lo, + static_cast(field.flags)); + } + act->check_conditional(newField); + + if (a->second.is_constant) + output_field_to_pack_format(field_list, basebit, a->first, "constant", 0, newField, + a->second.value); + else + output_field_to_pack_format(field_list, basebit, a->first, "spec", 0, newField); + } + } + + // Determine the source of the field. If called recursively for an alias, + // act will be a nullptr + std::string source = ""; + int start_bit = 0; + if (!act) get_cjson_source(name, source, start_bit); + + if (field.flags == Format::Field::ZERO) source = "zero"; + + if (source != "") + output_field_to_pack_format(field_list, basebit, name, source, start_bit, field); + + // Convert fields with slices embedded in the name, eg. "foo.bar[4:0]", to + // slice-free field names with the start_bit incremented by the low bit of + // the slice. + canon_field_list(field_list); +} + +void Table::output_field_to_pack_format(json::vector &field_list, int basebit, std::string name, + std::string source, int start_bit, + const Table::Format::Field &field, unsigned value) const { + unsigned add_width = 0; + bool pfe_enable = false; + unsigned indirect_addr_start_bit = 0; + int lobit = 0; + for (auto &bits : field.bits) { + json::map field_entry; + field_entry["start_bit"] = lobit + start_bit; + field_entry["field_width"] = bits.size() + add_width; + field_entry["lsb_mem_word_idx"] = bits.lo / MEM_WORD_WIDTH; + field_entry["msb_mem_word_idx"] = bits.hi / MEM_WORD_WIDTH; + field_entry["source"] = json::string(source); + field_entry["enable_pfe"] = false; + if (source == "constant") { + field_entry["const_tuples"] = + json::vector{json::map{{"dest_start", json::number(0)}, + {"value", json::number(value)}, + {"dest_width", json::number(bits.size())}}}; + } + field_entry["lsb_mem_word_offset"] = basebit + (bits.lo % MEM_WORD_WIDTH); + field_entry["field_name"] = json::string(name); + field_entry["global_name"] = json::string(""); + + if (field.conditional_value) { + field_entry["is_mod_field_conditionally_value"] = true; + field_entry["mod_field_conditionally_mask_field_name"] = json::string(field.condition); + } + // field_entry["immediate_name"] = json::string(immediate_name); + // if (this->to()) + if (this->to()) { + // FIXME-JSON : match_mode only matters for ATCAM's not clear if + // 'unused' or 'exact' is used by driver + std::string match_mode = "unused"; + // For version bits field match mode is set to "s1q0" (to match + // glass) + if (name == "version") match_mode = "s1q0"; + field_entry["match_mode"] = match_mode; + } + field_list.push_back(std::move(field_entry)); + lobit += bits.size(); + } +} + +void Table::add_zero_padding_fields(Table::Format *format, Table::Actions::Action *act, + unsigned format_width) const { + if (!format) return; + // For an action with no format pad zeros for action table size + unsigned pad_count = 0; + if (format->log2size == 0) { + if (auto at = this->to()) { + format->size = at->get_size(); + BUG_CHECK(format->size); + format->log2size = at->get_log2size(); + // For wide action formats, entries per word is 1, so plug in a + // single pad field of 256 bits + unsigned action_entries_per_word = std::max(1U, 128U / format->size); + // Add a flag type to specify padding? + Format::Field f(format, format->size, 0, Format::Field::ZERO); + for (unsigned i = 0; i < action_entries_per_word; i++) + format->add_field(f, "--padding--"); + } else { + error(lineno, + "Adding zero padding to a non action table " + "which has no action entries in format"); + } + return; + } + decltype(act->reverse_alias()) alias; + if (act) alias = act->reverse_alias(); + + // Determine the zero padding necessary by creating a bitvector that has all + // bits cleared, and then iterate through parameters and immediates and set the + // bits that are used. Create padding for the remaining bit ranges. + bitvec padbits; + padbits.clrrange(0, format_width - 1); + for (int entry = 0; entry < format->groups(); ++entry) { + for (auto &field : format->group(entry)) { + auto aliases = get(alias, field.first); + for (auto a : aliases) { + auto newField = field.second; + json::string param_name = a->first; + int lo = remove_name_tail_range(param_name); + if (act->has_param(param_name) || a->second.is_constant) { + auto newField = Table::Format::Field( + field.second.fmt, a->second.size(), a->second.lo + field.second.bits[0].lo, + static_cast(field.second.flags)); + newField.set_field_bits(padbits); + } + } + if (aliases.size() == 0) field.second.set_field_bits(padbits); + } + } + + int idx_lo = 0; + for (auto p : padbits) { + if (p > idx_lo) { + Format::Field f(format, p - idx_lo, idx_lo, Format::Field::ZERO); + std::string pad_name = + "--padding_" + std::to_string(idx_lo) + "_" + std::to_string(p - 1) + "--"; + format->add_field(f, pad_name); + } + idx_lo = p + 1; + } + if (idx_lo < int(format_width)) { + Format::Field f(format, format_width - idx_lo, idx_lo, Format::Field::ZERO); + std::string pad_name = + "--padding_" + std::to_string(idx_lo) + "_" + std::to_string(format_width - 1) + "--"; + format->add_field(f, pad_name); + } +} + +json::map &Table::add_pack_format(json::map &stage_tbl, Table::Format *format, bool pad_zeros, + bool print_fields, Table::Actions::Action *act) const { + // Add zero padding fields to format + // FIXME: Can this be moved to a format pass? + if (pad_zeros) + add_zero_padding_fields(format, act, format ? format->get_padding_format_width() : -1); + json::map pack_fmt; + auto mem_word_width = ram_word_width(); + pack_fmt["memory_word_width"] = mem_word_width; + auto table_word_width = format ? format->get_table_word_width() : ram_word_width(); + pack_fmt["table_word_width"] = table_word_width; + pack_fmt["entries_per_table_word"] = format ? format->get_entries_per_table_word() : 1; + pack_fmt["number_memory_units_per_table_word"] = + format ? format->get_mem_units_per_table_word() : 1; + + /** + * Entry number has to be unique for all tables. However, for ATCAM tables specifically, + * the entry with the highest priority starts at entry number 0. The priority decreases + * as the entry number increases. + * + * This is actually reversed in the hardware. The compiler format entries are in priority + * order in the hardware, and have been validated in validate_format. Thus, the context + * JSON is reversed. + */ + if (print_fields) { + BUG_CHECK(format); + int basebit = std::max(0, mem_word_width - (1 << format->log2size)); + json::vector &entry_list = pack_fmt["entries"]; + if (format->is_wide_format()) { + for (int i = format->groups() - 1; i >= 0; --i) { + int entry_number = i; + if (table_type() == ATCAM) entry_number = format->groups() - 1 - i; + json::vector field_list; + for (auto it = format->begin(i); it != format->end(i); ++it) + add_field_to_pack_format(field_list, basebit, it->first, it->second, act); + entry_list.push_back(json::map{{"entry_number", json::number(entry_number)}, + {"fields", std::move(field_list)}}); + } + } else { + for (int i = format->get_entries_per_table_word() - 1; i >= 0; --i) { + int entry_number = i; + if (table_type() == ATCAM) + entry_number = format->get_entries_per_table_word() - 1 - i; + json::vector field_list; + for (auto &field : *format) + add_field_to_pack_format(field_list, basebit, field.first, field.second, act); + entry_list.push_back(json::map{{"entry_number", json::number(entry_number)}, + {"fields", std::move(field_list)}}); + basebit -= 1 << format->log2size; + } + } + } + if (act) pack_fmt["action_handle"] = act->handle; + json::vector &pack_format = stage_tbl["pack_format"]; + pack_format.push_back(std::move(pack_fmt)); + return pack_format.back()->to(); +} + +// Check if node exists in context_json entry in bfa, add entry to the input +// json node and remove the entry from context_json. +// +// Set parameter "append" to true in order to append to existing entries in +// specified section of context_json. Set to false to overwrite. Applies +// only to json::vector containers. +bool Table::add_json_node_to_table(json::map &tbl, const char *name, bool append) const { + if (context_json) { + if (context_json->count(name)) { + std::unique_ptr new_obj = context_json->remove(name); + json::vector *add_vect = nullptr; + if (append && (add_vect = dynamic_cast(new_obj.get()))) { + json::vector &new_vect = tbl[name]; + std::move(add_vect->begin(), add_vect->end(), std::back_inserter(new_vect)); + } else + tbl[name] = std::move(new_obj); + return true; + } + } + return false; +} + +void Table::add_match_key_cfg(json::map &tbl) const { + json::vector ¶ms = tbl["match_key_fields"]; + if ((!p4_params_list.empty()) && this->to()) { + // If a table is splitted to different stages in backend, the + // match_key_fields section will be populated every time the splitted + // tables are emitted. Therefore, we clear the vector before populating + // it again to avoid duplicated keys. + params.clear(); + for (auto &p : p4_params_list) { + json::map param; + std::string name = p.name; + std::string global_name = ""; + if (p.key_name.empty()) { + param["name"] = name; + } else { + // Presence of key name indicates the field has a name + // annotation. If the name annotation is on a field slice, then + // the slice is treated as a field with the key_name as its + // "name". The field output will have the same bit_width and + // bit_width_full indicating its not treated as a slice. We + // also provide the original p4 name as the "global_name" to + // allow driver to use it as a lookup up against the snapshot + // fields published in context.json. These fields will all have + // original p4 field names. + param["name"] = p.key_name; + param["global_name"] = p.name; + } + param["start_bit"] = p.start_bit; + param["bit_width"] = p.bit_width; + param["bit_width_full"] = p.bit_width_full; + if (!p.mask.empty()) { + std::stringstream ss; + ss << "0x" << p.mask; + param["mask"] = ss.str(); + } + param["position"] = p.position; + param["match_type"] = p.type; + param["is_valid"] = p.is_valid; + std::string fieldname, instname; + gen_instfield_name(name, instname, fieldname); + param["instance_name"] = instname; + param["field_name"] = fieldname; + if (!p.alias.empty()) param["alias"] = p.alias; + if (p.context_json) param.merge(*p.context_json.get()); + params.push_back(std::move(param)); + if (p.type == "range") tbl["uses_range"] = true; + } + } +} + +template +void Table::init_json_node(json::map &tbl, const char *name) const { + if (tbl.count(name)) return; + tbl[name] = T(); +} + +void Table::common_tbl_cfg(json::map &tbl) const { + tbl["default_action_handle"] = get_default_action_handle(); + tbl["action_profile"] = action_profile(); + // FIXME -- setting next_table_mask unconditionally only works because we process the + // stage table in stage order (so we'll end up with the value from the last stage table, + // which is what we want.) Should we check in case the ordering ever changes? + tbl["default_next_table_mask"] = next_table_adr_mask; + // FIXME -- the driver currently always assumes this is 0, so we arrange for it to be + // when choosing the action encoding. But we should be able to choose something else + tbl["default_next_table_default"] = 0; + // FIXME-JSON: PD related, check glass examples for false (ALPM) + tbl["is_resource_controllable"] = true; + tbl["uses_range"] = false; + if (p4_table && p4_table->disable_atomic_modify) tbl["disable_atomic_modify"] = true; + add_match_key_cfg(tbl); + init_json_node(tbl, "ap_bind_indirect_res_to_match"); + init_json_node(tbl, "static_entries"); + if (context_json) { + add_json_node_to_table(tbl, "ap_bind_indirect_res_to_match"); + } +} + +void Table::add_result_physical_buses(json::map &stage_tbl) const { + json::vector &result_physical_buses = stage_tbl["result_physical_buses"] = json::vector(); + for (auto l : layout) { + if (l.bus.count(Layout::RESULT_BUS)) + result_physical_buses.push_back(l.row * 2 + l.bus.at(Layout::RESULT_BUS)); + } +} + +void Table::merge_context_json(json::map &tbl, json::map &stage_tbl) const { + if (context_json) { + add_json_node_to_table(tbl, "static_entries", true); + stage_tbl.merge(*context_json); + } +} diff --git a/backends/tofino/bf-asm/tables.h b/backends/tofino/bf-asm/tables.h new file mode 100644 index 00000000000..80ff23409f3 --- /dev/null +++ b/backends/tofino/bf-asm/tables.h @@ -0,0 +1,2196 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_TABLES_H_ // NOLINT(build/header_guard) +#define BF_ASM_TABLES_H_ + +#include +#include + +#include +#include +#include +#include +#include + +#include "algorithm.h" +#include "alloc.h" +#include "asm-types.h" +#include "bitvec.h" +#include "constants.h" +#include "hash_dist.h" +#include "input_xbar.h" +#include "json.h" +#include "map.h" +#include "ordered_map.h" +#include "p4_table.h" +#include "phv.h" +#include "slist.h" +#include "target.h" + +class ActionBus; +struct ActionBusSource; +class AttachedTable; +struct AttachedTables; +class GatewayTable; +class IdletimeTable; +class ActionTable; +struct Instruction; +class InputXbar; +class MatchTable; +class SelectionTable; +class StatefulTable; +class MeterTable; +class Synth2Port; +class Stage; +struct HashCol; + +struct RandomNumberGen { + int unit; + explicit RandomNumberGen(int u) : unit(u) {} + bool operator==(const RandomNumberGen &a) const { return unit == a.unit; } +}; + +enum class TableOutputModifier { NONE, Color, Address }; +std::ostream &operator<<(std::ostream &, TableOutputModifier); + +/* a memory storage 'unit' somewhere on the chip */ +struct MemUnit { + int stage = INT_MIN; // current stage (only) for tofino1/2 + // can have negative stage numbers for tcams in egress + int row = -1; + int col; // (lamb) unit when row == -1 + MemUnit() = delete; + MemUnit(const MemUnit &) = default; + MemUnit(MemUnit &&) = default; + MemUnit &operator=(const MemUnit &) = default; + MemUnit &operator=(MemUnit &&) = default; + virtual ~MemUnit() {} + explicit MemUnit(int unit) : col(unit) {} + MemUnit(int r, int c) : row(r), col(c) {} + MemUnit(int s, int r, int c) : stage(s), row(r), col(c) {} + bool operator==(const MemUnit &a) const { + return std::tie(stage, row, col) == std::tie(a.stage, a.row, a.col); + } + bool operator!=(const MemUnit &a) const { + return std::tie(stage, row, col) != std::tie(a.stage, a.row, a.col); + } + bool operator<(const MemUnit &a) const { + return std::tie(stage, row, col) < std::tie(a.stage, a.row, a.col); + } + virtual const char *desc() const; // Short lived temp for messages + friend std::ostream &operator<<(std::ostream &out, const MemUnit &m) { return out << m.desc(); } +}; + +class Table { + public: + struct Layout { + /* Holds the layout of which rams/tcams/busses are used by the table + * These refer to rows/columns in different spaces: + * ternary match refers to tcams (12x2) + * exact match and ternary indirect refer to physical srams (8x12) + * action (and others?) refer to logical srams (16x6) + * vpns contains the (base)vpn index of each ram in the row + * maprams contain the map ram indexes for synthetic 2-port memories + * vpns/maprams (if not empty) must match up to memunits (same size) */ + int lineno = -1; + int row = -1; + enum bus_type_t { SEARCH_BUS, RESULT_BUS, TIND_BUS, IDLE_BUS, L2R_BUS, R2L_BUS }; + std::map bus; + + int word = -1; // which word for wide tables + bool home_row = false; // is this a home row + std::vector memunits; + std::vector vpns, maprams; + Layout() = default; + Layout(int l, int r) : lineno(l), row(r) {} + friend std::ostream &operator<<(std::ostream &, const Layout &); + + bool word_initialized() const { return word >= 0; } + bool operator==(const Layout &) const; + bool operator!=(const Layout &a) const { return !(*this == a); } + }; + + protected: + Table(int line, std::string &&n, gress_t gr, Stage *s, + int lid = -1); // NOLINT(whitespace/operators) + virtual ~Table(); + Table(const Table &) = delete; + Table(Table &&) = delete; + virtual void setup(VECTOR(pair_t) & data) = 0; + virtual void common_init_setup(const VECTOR(pair_t) &, bool, P4Table::type); + virtual bool common_setup(pair_t &, const VECTOR(pair_t) &, P4Table::type); + void setup_context_json(value_t &); + void setup_layout(std::vector &, const VECTOR(pair_t) & data, const char *subname = ""); + int setup_layout_bus_attrib(std::vector &, const value_t &data, const char *what, + Layout::bus_type_t type); + int setup_layout_attrib(std::vector &, const value_t &data, const char *what, + int Layout::*attr); + void setup_logical_id(); + void setup_actions(value_t &); + void setup_maprams(value_t &); + void setup_vpns(std::vector &, VECTOR(value_t) *, bool allow_holes = false); + virtual void vpn_params(int &width, int &depth, int &period, const char *&period_name) const { + BUG(); + } + virtual int get_start_vpn() { return 0; } + void alloc_rams(bool logical, BFN::Alloc2Dbase
&use, + BFN::Alloc2Dbase
*bus_use = 0, + Layout::bus_type_t bus_type = Layout::SEARCH_BUS); + void alloc_global_bus(Layout &, Layout::bus_type_t, int, int, int, int); + virtual void alloc_global_busses(); + void alloc_global_srams(); + void alloc_global_tcams(); + void alloc_busses(BFN::Alloc2Dbase
&bus_use, Layout::bus_type_t bus_type); + void alloc_id(const char *idname, int &id, int &next_id, int max_id, bool order, + BFN::Alloc1Dbase
&use); + void alloc_maprams(); + virtual void alloc_vpns(); + virtual Layout::bus_type_t default_bus_type() const { return Layout::SEARCH_BUS; } + void need_bus(int lineno, BFN::Alloc1Dbase
&use, int idx, const char *name); + static bool allow_ram_sharing(const Table *t1, const Table *t2); + + public: + class Type { + static std::map *all; + std::map::iterator self; + + protected: + explicit Type(std::string &&); // NOLINT(whitespace/operators) + explicit Type(const char *name) : Type(std::string(name)) {} + virtual ~Type(); + + public: + static Type *get(const char *name) { return ::get(all, name); } + static Type *get(const std::string &name) { return ::get(all, name); } + virtual Table *create(int lineno, const char *name, gress_t gress, Stage *stage, int lid, + VECTOR(pair_t) & data) = 0; + }; + + struct Ref { + int lineno; + std::string name; + Ref() : lineno(-1) {} + Ref(const Ref &) = default; + Ref(Ref &&) = default; + Ref &operator=(const Ref &a) & { + name = a.name; + if (lineno < 0) lineno = a.lineno; + return *this; + } + Ref &operator=(Ref &&a) & { + name = a.name; + if (lineno < 0) lineno = a.lineno; + return *this; + } + Ref &operator=(const value_t &a) & { + BUG_CHECK(a.type == tSTR); + name = a.s; + lineno = a.lineno; + return *this; + } + Ref(const std::string &n) : lineno(-1), name(n) {} // NOLINT(runtime/explicit) + Ref(const char *n) : lineno(-1), name(n) {} // NOLINT(runtime/explicit) + Ref(const value_t &a) : lineno(a.lineno) { // NOLINT(runtime/explicit) + if (CHECKTYPE(a, tSTR)) name = a.s; + } + Ref &operator=(const std::string &n) { + name = n; + return *this; + } + operator bool() const { return all && all->count(name) > 0; } + operator Table *() const { return ::get(all, name); } + Table *operator->() const { return ::get(all, name); } + bool set() const { return lineno >= 0; } + bool operator==(const Table *t) const { return name == t->name_; } + bool operator==(const char *t) const { return name == t; } + bool operator==(const std::string &t) const { return name == t; } + bool operator==(const Ref &a) const { return name == a.name; } + bool operator<(const Ref &a) const { return name < a.name; } + bool check() const { + if (set() && !*this) error(lineno, "No table named %s", name.c_str()); + return *this; + } + }; + + class NextTables { + std::set next; + unsigned lb_tags = 0; // long branch tags to use (bitmask) + const Table *next_table_ = nullptr; // table to use as next table (if any) + bool resolved = false; + bool can_use_lb(int stage, const NextTables &); + + public: + int lineno = -1; + NextTables() = default; + NextTables(const NextTables &) = default; + NextTables(NextTables &&) = default; + NextTables &operator=(const NextTables &a) = default; + NextTables &operator=(NextTables &&) = default; + NextTables(value_t &v); // NOLINT(runtime/explicit) + + std::set::iterator begin() const { return next.begin(); } + std::set::iterator end() const { return next.end(); } + int size() const { return next.size(); } + bool operator==(const NextTables &a) const { return next == a.next; } + bool subset_of(const NextTables &a) const { + for (auto &n : next) + if (!a.next.count(n)) return false; + return true; + } + void resolve_long_branch(const Table *tbl, const std::map &lbrch); + bool set() const { return lineno >= 0; } + int next_table_id() const { + BUG_CHECK(resolved); + return next_table_ ? next_table_->table_id() : Target::END_OF_PIPE(); + } + std::string next_table_name() const { + BUG_CHECK(resolved); + if (next_table_) { + if (auto nxt_p4_name = next_table_->p4_name()) return nxt_p4_name; + } + return "END"; + } + const Table *next_table() const { return next_table_; } + unsigned long_branch_tags() const { return lb_tags; } + unsigned next_in_stage(int stage) const; + bool need_next_map_lut() const; + void force_single_next_table(); + }; + + class Format { + public: + struct bitrange_t { + unsigned lo, hi; + bitrange_t(unsigned l, unsigned h) : lo(l), hi(h) {} + bool operator==(const bitrange_t &a) const { return lo == a.lo && hi == a.hi; } + bool disjoint(const bitrange_t &a) const { return lo > a.hi || a.lo > hi; } + bitrange_t overlap(const bitrange_t &a) const { + // only valid if !disjoint + return bitrange_t(std::max(lo, a.lo), std::min(hi, a.hi)); + } + int size() const { return hi - lo + 1; } + }; + struct Field { + unsigned size = 0, group = 0, flags = 0; + std::vector bits; + Field **by_group = 0; + Format *fmt; // containing format + bool operator==(const Field &a) const { return size == a.size; } + /* return the bit in the format that contains bit i of this field */ + unsigned bit(unsigned i) { + unsigned last = 0; + for (auto &chunk : bits) { + if (i < (unsigned)chunk.size()) return chunk.lo + i; + i -= chunk.size(); + last = chunk.hi + 1; + } + if (i == 0) return last; + BUG(); + return 0; // quiet -Wreturn-type warning + } + /* bit(i), adjusted for the immediate shift of the match group of the field + * returns the bit in the post-extract immediate containing bit i */ + unsigned immed_bit(unsigned i) { + auto rv = bit(i); + if (fmt && fmt->immed) rv -= fmt->immed->by_group[group]->bit(0); + return rv; + } + unsigned hi(unsigned bit) { + for (auto &chunk : bits) + if (bit >= chunk.lo && bit <= chunk.hi) return chunk.hi; + BUG(); + return 0; // quiet -Wreturn-type warning + } + enum flags_t { NONE = 0, USED_IMMED = 1, ZERO = 3 }; + bool conditional_value = false; + std::string condition; + explicit Field(Format *f) : fmt(f) {} + Field(Format *f, unsigned size, unsigned lo = 0, enum flags_t fl = NONE) + : size(size), flags(fl), fmt(f) { + if (size) bits.push_back({lo, lo + size - 1}); + } + Field(const Field &f, Format *fmt) + : size(f.size), flags(f.flags), bits(f.bits), fmt(fmt) {} + + /// mark all bits from the field in @param bitset + void set_field_bits(bitvec &bitset) const { + for (auto &b : bits) bitset.setrange(b.lo, b.size()); + } + }; + friend std::ostream &operator<<(std::ostream &, const Field &); + explicit Format(Table *t) : tbl(t) { fmt.resize(1); } + Format(Table *, const VECTOR(pair_t) & data, bool may_overlap = false); + ~Format(); + void pass1(Table *tbl); + void pass2(Table *tbl); + + private: + std::vector> fmt; + std::map::iterator> byindex; + static bool equiv(const ordered_map &, + const ordered_map &); + + public: + int lineno = -1; + Table *tbl; + unsigned size = 0, immed_size = 0; + Field *immed = 0; + unsigned log2size = 0; /* ceil(log2(size)) */ + unsigned overhead_start = 0, overhead_size = 0; // extent of non-match + int overhead_word = -1; + + unsigned groups() const { return fmt.size(); } + const ordered_map &group(int g) const { return fmt.at(g); } + Field *field(const std::string &n, int group = 0) { + BUG_CHECK(group >= 0 && (size_t)group < fmt.size()); + auto it = fmt[group].find(n); + if (it != fmt[group].end()) return &it->second; + return 0; + } + void apply_to_field(const std::string &n, std::function fn) { + for (auto &m : fmt) { + auto it = m.find(n); + if (it != m.end()) fn(&it->second); + } + } + std::string find_field(Field *field) { + for (auto &m : fmt) + for (auto &f : m) + if (field == &f.second) return f.first; + return ""; + } + int find_field_lineno(Field *field) { + for (auto &m : fmt) + for (auto &f : m) + if (field == &f.second) return lineno; + return -1; + } + void add_field(Field &f, std::string name = "dummy", int grp = 0) { + fmt[grp].emplace(name, Field(f, this)); + } + decltype(fmt[0].begin()) begin(int grp = 0) { return fmt[grp].begin(); } + decltype(fmt[0].end()) end(int grp = 0) { return fmt[grp].end(); } + decltype(fmt[0].cbegin()) begin(int grp = 0) const { return fmt[grp].begin(); } + decltype(fmt[0].cend()) end(int grp = 0) const { return fmt[grp].end(); } + bool is_wide_format() const { return (log2size >= 7 || groups() > 1) ? true : false; } + int get_entries_per_table_word() const { + // A phase0 table can only have 1 entry + if (tbl->table_type() == PHASE0) return 1; + if (is_wide_format()) return groups(); + return log2size ? (1U << (ceil_log2(tbl->ram_word_width()) - log2size)) : 0; + } + int get_mem_units_per_table_word() const { + return is_wide_format() ? ((size - 1) / tbl->ram_word_width()) + 1 : 1; + } + int get_table_word_width() const { + return is_wide_format() ? tbl->ram_word_width() * get_mem_units_per_table_word() + : tbl->ram_word_width(); + } + int get_padding_format_width() const { + return is_wide_format() ? get_mem_units_per_table_word() * tbl->ram_word_width() + : (1U << log2size); + } + }; + + struct Call : Ref { /* a Ref with arguments */ + struct Arg { + enum { Field, HashDist, Counter, Const, Name } type; + + private: + union { + Format::Field *fld; + HashDistribution *hd; + intptr_t val; + char *str; + }; + + void set(const Arg &a) { + type = a.type; + switch (type) { + case Field: + fld = a.fld; + return; + case HashDist: + hd = a.hd; + return; + case Counter: + case Const: + val = a.val; + return; + case Name: + str = a.str; + return; + } + } + + public: + Arg() = delete; + Arg(const Arg &a) { + set(a); + if (type == Name) str = strdup(str); + } + Arg(Arg &&a) { + set(a); + a.type = Const; + } + Arg &operator=(const Arg &a) { + if (&a == this) return *this; + if (a == *this) return *this; + if (type == Name) free(str); + set(a); + if (type == Name) str = strdup(a.str); + return *this; + } + Arg &operator=(Arg &&a) { + std::swap(type, a.type); + std::swap(val, a.val); + return *this; + } + Arg(Format::Field *f) : type(Field) { fld = f; } // NOLINT(runtime/explicit) + Arg(HashDistribution *hdist) : type(HashDist) { // NOLINT(runtime/explicit) + hd = hdist; + } + Arg(int v) : type(Const) { val = v; } // NOLINT(runtime/explicit) + Arg(const char *n) : type(Name) { str = strdup(n); } // NOLINT(runtime/explicit) + Arg(decltype(Counter) ctr, int mode) : type(Counter) { + val = mode; + BUG_CHECK(ctr == Counter); + } + ~Arg() { + if (type == Name) free(str); + } + bool operator==(const Arg &a) const { + if (type != a.type) return false; + switch (type) { + case Field: + return fld == a.fld; + case HashDist: + return hd == a.hd; + case Counter: + case Const: + return val == a.val; + case Name: + return !strcmp(str, a.str); + default: + BUG(); + } + return false; + } + bool operator!=(const Arg &a) const { return !operator==(a); } + Format::Field *field() const { return type == Field ? fld : nullptr; } + HashDistribution *hash_dist() const { return type == HashDist ? hd : nullptr; } + const char *name() const { return type == Name ? str : nullptr; } + int count_mode() const { return type == Counter ? val : 0; } + int value() const { return type == Const ? val : 0; } + operator bool() const { return fld != nullptr; } + unsigned size() const; + }; + std::vector args; + void setup(const value_t &v, Table *tbl); + Call() {} + Call(const value_t &v, Table *tbl) { setup(v, tbl); } + bool operator==(const Call &a) const { return Ref::operator==(a) && args == a.args; } + bool operator!=(const Call &a) const { return !(*this == a); } + bool is_direct_call() const { + if (args.size() == 0) return false; + for (auto &a : args) + if (a == "$DIRECT") return true; + return false; + } + }; + + struct p4_param { + std::string name; + std::string alias; + std::string key_name; + unsigned start_bit = 0; + unsigned position = 0; + unsigned bit_width = 0; + unsigned bit_width_full = 0; + bitvec mask; + std::string default_value; // value stored as hex string to accommodate large nos + bool defaulted = false; + bool is_valid = false; + std::string type; + std::unique_ptr context_json; + explicit p4_param(std::string n = "", unsigned p = 0, unsigned bw = 0) + : name(n), position(p), bit_width(bw) {} + }; + friend std::ostream &operator<<(std::ostream &, const p4_param &); + typedef std::vector p4_params; + + class Actions { + public: + struct Action { + struct alias_t { + std::string name; + int lineno = -1, lo = -1, hi = -1; + bool is_constant = false; + unsigned value = 0; + explicit alias_t(value_t &); + unsigned size() const { + if (hi != -1 && lo != -1) + return hi - lo + 1; + else + return 0; + } + std::string to_string() const { + if (hi >= 0 && lo >= 0) + return name + '(' + std::to_string(lo) + ".." + std::to_string(hi) + ')'; + return name; + } + }; + std::string name; + std::string rng_param_name = ""; + int lineno = -1, addr = -1, code = -1; + std::multimap alias; + std::vector> instr; + bitvec slot_use; + unsigned handle = 0; + p4_params p4_params_list; + bool hit_allowed = true; + bool default_allowed = false; + bool default_only = false; + bool is_constant = false; + std::string hit_disallowed_reason = ""; + std::string default_disallowed_reason = ""; + std::vector attached; + int next_table_encode = -1; + NextTables next_table_ref; + NextTables next_table_miss_ref; + std::map> mod_cond_values; + // The hit map points to next tables for actions as ordered in the + // assembly, we use 'position_in_assembly' to map the correct next + // table, as actions can be ordered in the map different from the + // assembly order. + int position_in_assembly = -1; + bool minmax_use = false; // jbay sful min/max + // Predication operand coming into the output ALUs in stateful actions. This attribute + // is used to make sure that all combined predicate outputs from a given stateful action + // have the same form, because the predication operand is always the same in every + // output ALU. + int pred_comb_sel = -1; + std::unique_ptr context_json; + Action(Table *, Actions *, pair_t &, int); + enum mod_cond_loc_t { MC_ADT, MC_IMMED }; + void setup_mod_cond_values(value_t &map); + Action(const char *n, int l); + Action(const Action &) = delete; + Action(Action &&) = delete; + ~Action(); + bool equiv(Action *a); + bool equivVLIW(Action *a); + typedef const decltype(alias)::value_type alias_value_t; + std::map> reverse_alias() const; + std::string alias_lookup(int lineno, std::string name, int &lo, int &hi) const; + bool has_rng() { return !rng_param_name.empty(); } + const p4_param *has_param(std::string param) const { + for (auto &e : p4_params_list) + if (e.name == param) return &e; + return nullptr; + } + void pass1(Table *tbl); + void check_next(Table *tbl); + void check_next_ref(Table *tbl, const Table::Ref &ref) const; + void add_direct_resources(json::vector &direct_resources, const Call &att) const; + void add_indirect_resources(json::vector &indirect_resources, const Call &att) const; + void check_and_add_resource(json::vector &resources, json::map &resource) const; + bool is_color_aware() const; + void gen_simple_tbl_cfg(json::vector &) const; + void add_p4_params(json::vector &, bool include_default = true) const; + void check_conditional(Table::Format::Field &field) const; + bool immediate_conditional(int lo, int sz, std::string &condition) const; + friend std::ostream &operator<<(std::ostream &, const alias_t &); + friend std::ostream &operator<<(std::ostream &, const Action &); + }; + + private: + typedef ordered_map map_t; + map_t actions; + bitvec code_use; + std::map by_code; + bitvec slot_use; + Table *table; + + public: + int max_code = -1; + Actions(Table *tbl, VECTOR(pair_t) &); + typedef map_t::value_type value_type; + typedef IterValues::iterator iterator; + typedef IterValues::iterator const_iterator; + iterator begin() { return iterator(actions.begin()); } + const_iterator begin() const { return const_iterator(actions.begin()); } + iterator end() { return iterator(actions.end()); } + const_iterator end() const { return const_iterator(actions.end()); } + int count() { return actions.size(); } + int hit_actions_count() const; + int default_actions_count() const; + Action *action(const std::string &n) { + auto it = actions.find(n); + return it == actions.end() ? nullptr : &it->second; + } + bool exists(const std::string &n) { return actions.count(n) > 0; } + void pass1(Table *); + void pass2(Table *); + void stateful_pass2(Table *); + template + void write_regs(REGS &, Table *); + void add_p4_params(const Action &, json::vector &) const; + void gen_tbl_cfg(json::vector &) const; + void add_immediate_mapping(json::map &); + void add_action_format(const Table *, json::map &) const; + bool has_hash_dist() { return (table->table_type() == HASH_ACTION); } + size_t size() { return actions.size(); } + }; + + public: + const char *name() const { return name_.c_str(); } + const char *p4_name() const { + if (p4_table) { + return p4_table->p4_name(); + } + return nullptr; + } + unsigned p4_size() const { + if (p4_table) { + return p4_table->p4_size(); + } + return 0; + } + unsigned handle() const { + if (p4_table) { + return p4_table->get_handle(); + } + return -1; + } + std::string action_profile() const { + if (p4_table) { + return p4_table->action_profile; + } + return ""; + } + std::string how_referenced() const { + if (p4_table) { + return p4_table->how_referenced; + } + return ""; + } + int table_id() const; + virtual bool is_always_run() const { return false; } + virtual void pass0() {} // only match tables need pass0 + virtual void pass1(); + virtual void pass2() = 0; + virtual void pass3() = 0; + /* C++ does not allow virtual template methods, so we work around it by explicitly + * instantiating overloads for all the virtual template methods we want. */ + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, virtual void write_action_regs, + (mau_regs &, const Actions::Action *), {}) + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, virtual void write_merge_regs, + (mau_regs &, int type, int bus), { assert(0); }) + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, virtual void write_merge_regs, + (mau_regs &, MatchTable *match, int type, int bus, + const std::vector &args), + { assert(0); }) + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, virtual void write_regs, (mau_regs &), = 0) + + virtual void gen_tbl_cfg(json::vector &out) const = 0; + virtual json::map *base_tbl_cfg(json::vector &out, const char *type, int size) const; + virtual json::map *add_stage_tbl_cfg(json::map &tbl, const char *type, int size) const; + virtual std::unique_ptr gen_memory_resource_allocation_tbl_cfg( + const char *type, const std::vector &layout, bool skip_spare_bank = false) const; + virtual std::vector determine_spare_bank_memory_units() const { return {}; } + virtual void common_tbl_cfg(json::map &tbl) const; + void add_match_key_cfg(json::map &tbl) const; + bool add_json_node_to_table(json::map &tbl, const char *name, bool append = false) const; + void allocate_physical_ids(unsigned usable = ~0U); + template + void init_json_node(json::map &tbl, const char *name) const; + enum table_type_t { + OTHER = 0, + TERNARY_INDIRECT, + GATEWAY, + ACTION, + SELECTION, + COUNTER, + METER, + IDLETIME, + STATEFUL, + HASH_ACTION, + EXACT, + TERNARY, + PHASE0, + ATCAM, + PROXY_HASH + }; + virtual table_type_t table_type() const { return OTHER; } + virtual int instruction_set() { return 0; /* VLIW_ALU */ } + virtual table_type_t set_match_table(MatchTable *m, bool indirect) { + assert(0); + return OTHER; + } + virtual const MatchTable *get_match_table() const { + assert(0); + return nullptr; + } + virtual MatchTable *get_match_table() { + assert(0); + return nullptr; + } + virtual std::set get_match_tables() { return std::set(); } + virtual const AttachedTables *get_attached() const { return 0; } + virtual AttachedTables *get_attached() { return 0; } + virtual const GatewayTable *get_gateway() const { return 0; } + virtual SelectionTable *get_selector() const { return 0; } + virtual MeterTable *get_meter() const { return 0; } + virtual void set_stateful(StatefulTable *s) { BUG(); } + virtual StatefulTable *get_stateful() const { return 0; } + virtual void set_address_used() { + // FIXME -- could use better error message(s) -- lineno is not accurate/useful + error(lineno, + "Tofino does not support extracting the address used on " + "a non-stateful table %s", + name()); + } + virtual void set_color_used() { + error(lineno, "Cannot extract color on a non-meter table %s", name()); + } + virtual void set_output_used() { + error(lineno, "Cannot extract output on a non-stateful table %s", name()); + } + virtual const Call &get_action() const { return action; } + virtual std::vector get_calls() const; + virtual bool is_attached(const Table *) const { + BUG(); + return false; + } + virtual Format::Field *find_address_field(const AttachedTable *) const { + BUG(); + return 0; + } + virtual Format::Field *get_per_flow_enable_param(MatchTable *) const { + BUG(); + return 0; + } + virtual Format::Field *get_meter_address_param(MatchTable *) const { + BUG(); + return 0; + } + virtual Format::Field *get_meter_type_param(MatchTable *) const { + BUG(); + return 0; + } + virtual int direct_shiftcount() const { + BUG(); + return -1; + } + virtual int indirect_shiftcount() const { + BUG(); + return -1; + } + virtual int address_shift() const { + BUG(); + return -1; + } + virtual int home_row() const { + BUG(); + return -1; + } + /* mem unitno mapping -- unit numbers used in context json */ + virtual int json_memunit(const MemUnit &u) const; + virtual int ram_word_width() const { return MEM_WORD_WIDTH; } + virtual int unitram_type() { + BUG(); + return -1; + } + virtual bool uses_colormaprams() const { return false; } + virtual int color_shiftcount(Table::Call &call, int group, int tcam_shift) const { + BUG(); + return -1; + } + virtual bool adr_mux_select_stats() { return false; } + virtual bool run_at_eop() { return false; } + virtual Format *get_format() const { return format.get(); } + virtual unsigned determine_shiftcount(Table::Call &call, int group, unsigned word, + int tcam_shift) const { + assert(0); + return -1; + } + template + void write_mapram_regs(REGS ®s, int row, int col, int vpn, int type); + template + T *to() { + return dynamic_cast(this); + } + template + const T *to() const { + return dynamic_cast(this); + } + virtual void determine_word_and_result_bus() { BUG(); } + virtual int stm_vbus_column() const { BUG(); } + + std::string name_; + int uid; + P4Table *p4_table = 0; + Stage *stage = 0; + gress_t gress; + int lineno = -1; + int logical_id = -1; + bitvec physical_ids; + std::vector dynamic_config; + std::vector> input_xbar; + std::vector layout; + bool no_vpns = false; // for odd actions with null vpns + // generated by compiler + std::unique_ptr format; + int action_enable = -1; + bool enable_action_data_enable = false; + bool enable_action_instruction_enable = false; + Call action; + Call instruction; + std::unique_ptr actions; + std::unique_ptr action_bus; + std::string default_action; + unsigned default_action_handle = 0; + int default_action_lineno = -1; + typedef std::map default_action_params; + default_action_params default_action_parameters; + bool default_only_action = false; + std::vector hit_next; + std::vector extra_next_lut; // extra entries not in the hit_next from gateway + // currently the assembler will add extra elements to the 8 entry next table lut if they + // are needed for a gateway and not present in the lut already. We add these in a separate + // vector from hit_next so that context.json only reports the original hit_next from the source + // and we don't try to get a next table hit index from the action. + NextTables miss_next; + std::map long_branch; + int long_branch_input = -1; + std::map
> pred; // predecessor tables w the actions in + // that table that call this table + std::vector hash_dist; + p4_params p4_params_list; + std::unique_ptr context_json; + // saved here in to extract into the context json + unsigned next_table_adr_mask = 0U; + bitvec reachable_tables_; + + static std::map *all; + static std::vector
*by_uid; + + unsigned layout_size() const { + unsigned rv = 0; + for (auto &row : layout) rv += row.memunits.size(); + return rv; + } + unsigned layout_get_vpn(const MemUnit &m) const { + for (auto &row : layout) { + if (row.row != m.row) continue; + auto u = find(row.memunits.begin(), row.memunits.end(), m); + if (u == row.memunits.end()) continue; + return row.vpns.at(u - row.memunits.begin()); + } + BUG(); + return 0; + } + void layout_vpn_bounds(int &min, int &max, bool spare = false) const { + min = 1000000; + max = -1; + for (const Layout &row : layout) + for (const auto v : row.vpns) { + if (v < min) min = v; + if (v > max) max = v; + } + if (spare && max > min) --max; + } + virtual Format::Field *lookup_field(const std::string &n, const std::string &act = "") const { + return format ? format->field(n) : 0; + } + virtual std::string find_field(Format::Field *field) { + return format ? format->find_field(field) : ""; + } + virtual int find_field_lineno(Format::Field *field) { + return format ? format->find_field_lineno(field) : -1; + } + virtual void apply_to_field(const std::string &n, std::function fn) { + if (format) format->apply_to_field(n, fn); + } + int find_on_ixbar(Phv::Slice sl, InputXbar::Group group, InputXbar::Group *found = nullptr); + int find_on_ixbar(Phv::Slice sl, int group) { + return find_on_ixbar(sl, InputXbar::Group(InputXbar::Group::EXACT, group)); + } + virtual HashDistribution *find_hash_dist(int unit); + virtual int find_on_actionbus(const ActionBusSource &src, int lo, int hi, int size, + int pos = -1); + virtual void need_on_actionbus(const ActionBusSource &src, int lo, int hi, int size); + virtual int find_on_actionbus(const char *n, TableOutputModifier mod, int lo, int hi, int size, + int *len = 0); + int find_on_actionbus(const char *n, int lo, int hi, int size, int *len = 0) { + return find_on_actionbus(n, TableOutputModifier::NONE, lo, hi, size, len); + } + int find_on_actionbus(const std::string &n, TableOutputModifier mod, int lo, int hi, int size, + int *len = 0) { + return find_on_actionbus(n.c_str(), mod, lo, hi, size, len); + } + int find_on_actionbus(const std::string &n, int lo, int hi, int size, int *len = 0) { + return find_on_actionbus(n.c_str(), TableOutputModifier::NONE, lo, hi, size, len); + } + virtual void need_on_actionbus(Table *att, TableOutputModifier mod, int lo, int hi, int size); + static bool allow_bus_sharing(Table *t1, Table *t2); + virtual Call &action_call() { return action; } + virtual Call &instruction_call() { return instruction; } + virtual Actions *get_actions() const { return actions.get(); } + virtual const std::vector &get_hit_next() const { return hit_next; } + virtual const NextTables &get_miss_next() const { return miss_next; } + virtual bool is_directly_referenced(const Table::Call &c) const; + virtual void add_reference_table(json::vector &table_refs, const Table::Call &c) const; + json::map &add_pack_format(json::map &stage_tbl, int memword, int words, + int entries = -1) const; + json::map &add_pack_format(json::map &stage_tbl, Table::Format *format, bool pad_zeros = true, + bool print_fields = true, + Table::Actions::Action *act = nullptr) const; + virtual void add_field_to_pack_format(json::vector &field_list, int basebit, std::string name, + const Table::Format::Field &field, + const Table::Actions::Action *act) const; + virtual bool validate_call(Table::Call &call, MatchTable *self, size_t required_args, + int hash_dist_type, Table::Call &first_call) { + BUG(); + return false; + } + bool validate_instruction(Table::Call &call) const; + // const std::vector &); + // Generate the context json for a field into field list. + // Use the bits specified in field, offset by the base bit. + // If the field is a constant, output a const_tuple map, including the specified value. + void output_field_to_pack_format(json::vector &field_list, int basebit, std::string name, + std::string source, int start_bit, + const Table::Format::Field &field, unsigned value = 0) const; + void add_zero_padding_fields(Table::Format *format, Table::Actions::Action *act = nullptr, + unsigned format_width = 64) const; + void get_cjson_source(const std::string &field_name, std::string &source, int &start_bit) const; + // Result physical buses should be setup for + // Exact/Hash/MatchwithNoKey/ATCAM/Ternary tables + virtual void add_result_physical_buses(json::map &stage_tbl) const; + virtual void merge_context_json(json::map &tbl, json::map &stage_tbl) const; + void canon_field_list(json::vector &field_list) const; + void for_all_next(std::function fn); + void check_next(const Ref &next); + void check_next(NextTables &next); + void check_next(); + virtual void set_pred(); + /* find the predecessors in the given stage that must run iff this table runs. + * includes `this` if it is in the stage. The values are the set of actions that + * (lead to) triggering this table, or empty if any action might */ + std::map
> find_pred_in_stage( + int stageno, const std::set &acts = std::set()); + + bool choose_logical_id(const slist
*work = nullptr); + virtual int hit_next_size() const { return hit_next.size(); } + virtual int get_tcam_id() const { BUG("%s not a TCAM table", name()); } + + const std::vector find_p4_params(std::string s, std::string t = "", + int start_bit = -1, int width = -1) const { + remove_name_tail_range(s); + std::vector params; + if (start_bit <= -1) return params; + if (width <= -1) return params; + int end_bit = start_bit + width; + for (auto &p : p4_params_list) { + if ((p.name == s) || (p.alias == s)) { + int p_end_bit = p.start_bit + p.bit_width; + if (!t.empty() && (p.type != t)) continue; + if (p.start_bit > start_bit) continue; + if (p_end_bit < end_bit) continue; + params.push_back(&p); + } + } + return params; + } + + const p4_param *find_p4_param(std::string s, std::string t = "", int start_bit = -1, + int width = -1) const { + remove_name_tail_range(s); + std::vector params; + for (auto &p : p4_params_list) { + if ((p.name == s) || (p.alias == s)) { + if (!t.empty() && (p.type != t)) continue; + if ((start_bit > -1) && (start_bit < p.start_bit)) continue; + if ((width > -1) && (p.start_bit + p.bit_width < start_bit + width)) continue; + return &p; + } + } + return nullptr; + } + + const p4_param *find_p4_param_type(std::string &s) const { + for (auto &p : p4_params_list) + if (p.type == s) return &p; + return nullptr; + } + virtual std::string get_default_action() { + return (!default_action.empty()) ? default_action : action ? action->default_action : ""; + } + virtual default_action_params *get_default_action_parameters() { + return (!default_action_parameters.empty()) ? &default_action_parameters + : action ? &action->default_action_parameters + : nullptr; + } + virtual unsigned get_default_action_handle() const { + return default_action_handle > 0 ? default_action_handle + : action ? action->default_action_handle + : 0; + } + int get_format_field_size(std::string s) const { + if (auto field = lookup_field(s)) return field->size; + return 0; + } + virtual bool needs_handle() const { return false; } + virtual bool needs_next() const { return false; } + virtual bitvec compute_reachable_tables(); + bitvec reachable_tables() { + if (!reachable_tables_) reachable_tables_ = compute_reachable_tables(); + return reachable_tables_; + } + std::string loc() const; +}; + +std::ostream &operator<<(std::ostream &, const Table::Layout &); +std::ostream &operator<<(std::ostream &, const Table::Layout::bus_type_t); + +class FakeTable : public Table { + public: + explicit FakeTable(const char *name) : Table(-1, name, INGRESS, 0, -1) {} + void setup(VECTOR(pair_t) & data) override { assert(0); } + void pass1() override { assert(0); } + void pass2() override { assert(0); } + void pass3() override { assert(0); } + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_regs, (mau_regs &), override { assert(0); }) + void gen_tbl_cfg(json::vector &out) const override { assert(0); } +}; + +class AlwaysRunTable : public Table { + /* a 'table' to hold the always run action in a stage */ + public: + AlwaysRunTable(gress_t gress, Stage *stage, pair_t &init); + void setup(VECTOR(pair_t) & data) override { assert(0); } + void pass1() override { actions->pass1(this); } + void pass2() override { actions->pass2(this); } + void pass3() override {} + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_regs, (mau_regs & regs), override;) + void gen_tbl_cfg(json::vector &out) const override {} +}; + +struct AttachedTables { + Table::Call selector; + Table::Call selector_length; + std::vector stats, meters, statefuls; + Table::Call meter_color; + SelectionTable *get_selector() const; + MeterTable *get_meter(std::string name = "") const; + StatefulTable *get_stateful(std::string name = "") const; + Table::Format::Field *find_address_field(const AttachedTable *tbl) const; + const Table::Call *get_call(const Table *) const; + bool is_attached(const Table *tbl) const { return get_call(tbl) != nullptr; } + void pass0(MatchTable *self); + void pass1(MatchTable *self); + template + void write_merge_regs(REGS ®s, MatchTable *self, int type, int bus); + template + void write_tcam_merge_regs(REGS ®s, MatchTable *self, int bus, int tcam_shift); + bool run_at_eop(); + bitvec compute_reachable_tables() const; +}; + +#define DECLARE_ABSTRACT_TABLE_TYPE(TYPE, PARENT, ...) \ + class TYPE : public PARENT { \ + protected: \ + TYPE(int l, const char *n, gress_t g, Stage *s, int lid) : PARENT(l, n, g, s, lid) {} \ + __VA_ARGS__ \ + }; + +DECLARE_ABSTRACT_TABLE_TYPE( + MatchTable, Table, GatewayTable *gateway = 0; IdletimeTable *idletime = 0; + AttachedTables attached; bool always_run = false; friend struct AttachedTables; + enum {NONE = 0, TABLE_MISS = 1, TABLE_HIT = 2, DISABLED = 3, GATEWAY_MISS = 4, GATEWAY_HIT = 5, + GATEWAY_INHIBIT = 6} table_counter = NONE; + + using Table::pass1; using Table::write_regs; + template void write_common_regs(typename TARGET::mau_regs &, int, Table *); + template void write_regs(REGS &, int type, Table *result); + template void write_next_table_regs(REGS &, Table *); + void common_init_setup(const VECTOR(pair_t) &, bool, P4Table::type) override; + bool common_setup(pair_t &, const VECTOR(pair_t) &, P4Table::type) override; + int get_address_mau_actiondata_adr_default(unsigned log2size, bool per_flow_enable); public + : bool is_always_run() const override { return always_run; } void pass0() override; + void pass1() override; void pass3() override; bool is_alpm() const { + if (p4_table) { + return p4_table->is_alpm(); + } + return false; + } bool is_attached(const Table *tbl) const override; + const Table::Call *get_call(const Table *tbl) const { + return get_attached()->get_call(tbl); + } const AttachedTables *get_attached() const override { return &attached; } std::vector + get_calls() const override; + AttachedTables * get_attached() override { return &attached; } Format * + get_format() const override; + const GatewayTable *get_gateway() + const override { return gateway; } const MatchTable *get_match_table() const override { + return this; + } MatchTable *get_match_table() override { return this; } std::set + get_match_tables() override { + std::set rv; + rv.insert(this); + return rv; + } Format::Field *find_address_field(const AttachedTable *tbl) const override { + return attached.find_address_field(tbl); + } Format::Field *lookup_field(const std::string &n, const std::string &act = "") + const override; + bool run_at_eop() override { return attached.run_at_eop(); } virtual bool is_ternary() { + return false; + } void gen_idletime_tbl_cfg(json::map &stage_tbl) const; + int direct_shiftcount() const override { + return 64; + } void gen_hash_bits(const std::map &hash_table, InputXbar::HashTable ht_id, + json::vector &hash_bits, unsigned hash_group_no, bitvec hash_bits_used) + const; + virtual void add_hash_functions(json::map &stage_tbl) const; + void add_all_reference_tables(json::map &tbl, Table *math_table = nullptr) const; + METER_ACCESS_TYPE default_meter_access_type(bool for_stateful); + bool needs_handle() const override { return true; } bool needs_next() + const override { return true; } bitvec compute_reachable_tables() override;) + +#define DECLARE_TABLE_TYPE(TYPE, PARENT, NAME, ...) \ + class TYPE : public PARENT { /* NOLINT */ \ + static struct Type : public Table::Type { \ + Type() : Table::Type(NAME) {} \ + TYPE *create(int lineno, const char *name, gress_t gress, Stage *stage, int lid, \ + VECTOR(pair_t) & data); \ + } table_type_singleton; \ + friend struct Type; \ + \ + protected: \ + TYPE(int l, const char *n, gress_t g, Stage *s, int lid) : PARENT(l, n, g, s, lid) {} \ + void setup(VECTOR(pair_t) & data) override; \ + \ + public: \ + void pass1() override; \ + void pass2() override; \ + void pass3() override; \ + /* gcc gets confused by overloading this template with the virtual \ + * functions if we try to specialize the templates, so we mangle \ + * the name with a _vt extension to help it out. */ \ + template \ + void write_regs_vt(REGS ®s); \ + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_regs, (mau_regs & regs), override;) \ + void gen_tbl_cfg(json::vector &out) const override; \ + \ + private: \ + __VA_ARGS__ \ + }; + +#define DEFINE_TABLE_TYPE(TYPE) \ + TYPE::Type TYPE::table_type_singleton; \ + TYPE *TYPE::Type::create(int lineno, const char *name, gress_t gress, Stage *stage, int lid, \ + VECTOR(pair_t) & data) { \ + TYPE *rv = new TYPE(lineno, name, gress, stage, lid); \ + rv->setup(data); \ + return rv; \ + } \ + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void TYPE::write_regs, (mau_regs & regs), \ + { write_regs_vt(regs); }) + +/* Used to create a subclass for a table type */ +#define DEFINE_TABLE_TYPE_WITH_SPECIALIZATION(TYPE, KIND) \ + TYPE::Type TYPE::table_type_singleton; \ + TYPE *TYPE::Type::create(int lineno, const char *name, gress_t gress, Stage *stage, int lid, \ + VECTOR(pair_t) & data) { \ + SWITCH_FOREACH_##KIND(options.target, \ + auto *rv = new TARGET::TYPE(lineno, name, gress, stage, lid); \ + rv->setup(data); return rv;) \ + } \ + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void TYPE::write_regs, (mau_regs & regs), \ + { write_regs_vt(regs); }) + +DECLARE_ABSTRACT_TABLE_TYPE(SRamMatchTable, MatchTable, // exact, atcam, or proxy_hash + public: + struct Ram : public MemUnit { + using MemUnit::MemUnit; + Ram(const MemUnit &m) : MemUnit(m) {} + Ram(MemUnit &&m) : MemUnit(std::move(m)) {} + bool isLamb() const { return stage == INT_MIN && row == -1; } + const char *desc() const; // Short lived temp for messages + }; + struct Way { + int lineno; + int group_xme; // hash group or xme + int index; // first bit of index + int index_hi = -1; // top bit (if set) for sanity checking + int subword_bits; + bitvec select; + std::vector rams; + bool isLamb() const { + BUG_CHECK(!rams.empty(), "no rams in way"); + return rams.at(0).isLamb(); } + bitvec select_bits() const { + bitvec rv = select; + rv.setrange(index, (isLamb() ? LAMB_DEPTH_BITS : SRAM_DEPTH_BITS) + subword_bits); + return rv; + } + }; + + protected: + std::vector ways; + struct WayRam { int way, index, word, bank; }; + std::map way_map; + std::vector match; + std::map match_by_bit; + std::vector> match_in_word; + std::vector word_ixbar_group; + struct GroupInfo { + /* info about which word(s) are used per format group with wide matches */ + int overhead_word; /* which word of wide match contains overhead */ + int overhead_bit; /* lowest bit that contains overhead in that word */ + // The word that is going to contain the result bus. Same as the overhead word, if + // the entry actually has overhead + int result_bus_word; + std::map match_group; /* which match group for each word with match */ + std::vector tofino_mask; /* 14-bit tofino byte/nibble mask for each word */ + int vpn_offset; /* which vpn to use for this group */ + GroupInfo() : overhead_word(-1), overhead_bit(-1), result_bus_word(-1), vpn_offset(-1) {} + // important function in order to determine shiftcount for exact match entries + int result_bus_word_group() const { return match_group.at(result_bus_word); } + }; // NOLINT + std::vector group_info; + std::vector> word_info; // which format group corresponds to each + // match group in each word + int mgm_lineno = -1; // match_group_map lineno + friend class GatewayTable; // Gateway needs to examine word group details for compat + friend class Target::Tofino::GatewayTable; + bitvec version_nibble_mask; + // Which hash groups are assigned to the hash_function_number in the hash_function json node + // This is to coordinate with the hash_function_id in the ways + std::map hash_fn_ids; + + // helper function only used/instantiated on tofino1/2 + template + void write_attached_merge_regs(REGS ®s, int bus, int word, int word_group); + + bool parse_ram(const value_t &, std::vector &); + bool parse_way(const value_t &); + void common_sram_setup(pair_t &, const VECTOR(pair_t) &); + void common_sram_checks(); + void alloc_global_busses() override; + void alloc_vpns() override; + int find_problematic_vpn_offset() const; + virtual void setup_ways(); + void setup_hash_function_ids(); + void pass1() override; + template void write_regs_vt(REGS ®s); + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, + void write_regs, (mau_regs ®s), override; ) + virtual std::string get_match_mode(const Phv::Ref &pref, int offset) const; + json::map* add_common_sram_tbl_cfgs(json::map &tbl, + std::string match_type, std::string stage_table_type) const; + void add_action_cfgs(json::map &tbl, json::map &stage_tbl) const; + virtual unsigned entry_ram_depth() const { return 1024; } + unsigned get_number_entries() const; + unsigned get_format_width() const; + virtual int determine_pre_byteswizzle_loc(MatchSource *ms, int lo, int hi, int word); + void add_field_to_pack_format(json::vector &field_list, int basebit, std::string name, + const Table::Format::Field &field, + const Table::Actions::Action *act) const override; + std::unique_ptr gen_memory_resource_allocation_tbl_cfg(const Way &) const; + Actions *get_actions() const override { + return actions ? actions.get() : (action ? action->actions.get() : nullptr); + } + void add_hash_functions(json::map &stage_tbl) const override; + virtual void gen_ghost_bits(int hash_function_number, json::vector &ghost_bits_to_hash_bits, + json::vector &ghost_bits_info) const { } + virtual void no_overhead_determine_result_bus_usage(); + public: + Format::Field *lookup_field(const std::string &n, const std::string &act = "") const override; + OVERLOAD_FUNC_FOREACH(TARGET_CLASS, virtual void, setup_word_ixbar_group, (), ()) + OVERLOAD_FUNC_FOREACH(TARGET_CLASS, virtual void, verify_format, (), ()) + OVERLOAD_FUNC_FOREACH(TARGET_CLASS, virtual void, verify_format_pass2, (), ()) + virtual bool verify_match_key(); + void verify_match(unsigned fmt_width); + void vpn_params(int &width, int &depth, int &period, const char *&period_name) const override { + width = (format->size-1)/128 + 1; + period = format->groups(); + depth = period * layout_size() / width; + period_name = "match group size"; } + template void write_merge_regs_vt(REGS ®s, int type, int bus) { + attached.write_merge_regs(regs, this, type, bus); } + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, + void write_merge_regs, (mau_regs ®s, int type, int bus), override { + write_merge_regs_vt(regs, type, bus); }) + bool is_match_bit(const std::string name, const int bit) const { + for (auto *m : match) { + std::string m_name = m->name(); + int m_lo = remove_name_tail_range(m_name) + m->fieldlobit(); + int m_hi = m_lo + m->size() -1; + if (m_name == name) { + if (m_lo <= bit + && m_hi >= bit) + return true; + } + } + return false; + } + void determine_word_and_result_bus() override; + SelectionTable *get_selector() const override { return attached.get_selector(); } + StatefulTable *get_stateful() const override { return attached.get_stateful(); } + MeterTable* get_meter() const override { return attached.get_meter(); } + const Way *way_for_ram(Ram r) const { + return way_map.count(r) ? &ways[way_map.at(r).way] : nullptr; } + const Way *way_for_xme(int xme) const { + for (auto &way : ways) if (way.group_xme == xme) return &way; + return nullptr; } +) + +DECLARE_TABLE_TYPE( + ExactMatchTable, SRamMatchTable, "exact_match", bool dynamic_key_masks = false; + + // The position of the ghost bits in a single hash function + // The key is name of the field and the field bit, the value is one-hot for all + // bits that this ghost bit has an impact on + using GhostBitPositions = std::map, bitvec>; + std::map ghost_bit_positions; std::unique_ptr stash_format; + std::vector stash_rows; std::vector stash_cols; std::vector stash_units; + std::vector stash_overhead_rows; + + public + : int unitram_type() override { return UnitRam::MATCH; } table_type_t table_type() + const override { return EXACT; } bool has_group(int grp) { + for (auto &way : ways) + if (way.group_xme == grp) return true; + return false; + } void determine_ghost_bits(); + void gen_ghost_bits(int hash_function_number, json::vector &ghost_bits_to_hash_bits, + json::vector &ghost_bits_info) const override; + void generate_stash_overhead_rows();) + +DECLARE_TABLE_TYPE( + AlgTcamMatchTable, SRamMatchTable, "atcam_match", + // key is column priority, value is way index + std::map col_priority_way; + int number_partitions = 0; int max_subtrees_per_partition = 0; int bins_per_partition = 0; + int atcam_subset_width = 0; int shift_granularity = 0; std::string partition_field_name = ""; + std::vector ixbar_subgroup, ixbar_mask; struct match_element { + Phv::Ref *field; + unsigned offset, width; + }; + bitvec s0q1_nibbles, s1q0_nibbles; std::vector s0q1_prefs, s1q0_prefs; + std::map s0q1, s1q0; table_type_t table_type() + const override { return ATCAM; } void verify_format(Target::Tofino) override; + void verify_entry_priority(); void setup_column_priority(); void find_tcam_match(); + void gen_unit_cfg(json::vector &units, int size) const; + std::unique_ptr gen_memory_resource_allocation_tbl_cfg() const; + void setup_nibble_mask(Table::Format::Field *match, int group, + std::map &elems, bitvec &mask); + std::string get_match_mode(const Phv::Ref &pref, int offset) const override; + void base_alpm_atcam_tbl_cfg(json::map &atcam_tbl, const char *type, int size) const { + if (p4_table) p4_table->base_alpm_tbl_cfg(atcam_tbl, size, this, P4Table::Atcam); + } + // For ATCAM tables, no hash functions are generated for the table, as the current + // interpretation of the table is that the partition index is an identity hash function. + // Potentially this could change at some point + void add_hash_functions(json::map &stage_tbl) + const override {} bool has_directly_attached_synth2port() const; + std::string get_lpm_field_name() const { + std::string lpm = "lpm"; + if (auto *p = find_p4_param_type(lpm)) + return p->key_name.empty() ? p->name : p->key_name; + else + error(lineno, "'lpm' type field not found in alpm atcam '%s-%s' p4 param order", name(), + p4_name()); + return ""; + } std::set + get_partition_action_handle() const { + if (p4_table) return p4_table->get_partition_action_handle(); + return {}; + } void no_overhead_determine_result_bus_usage() override; + std::string get_partition_field_name() const { + if (!p4_table) return ""; + auto name = p4_table->get_partition_field_name(); + if (auto *p = find_p4_param(name)) + if (!p->key_name.empty()) return p->key_name; + return name; + } unsigned entry_ram_depth() const override { + return std::min(number_partitions, 1024); + } void gen_alpm_cfg(json::map &) const;) + +DECLARE_TABLE_TYPE( + ProxyHashMatchTable, SRamMatchTable, "proxy_hash", bool dynamic_key_masks = false; + void setup_ways() override; int proxy_hash_group = -1; std::string proxy_hash_alg = ""; + bool verify_match_key() override; table_type_t table_type() + const override { return PROXY_HASH; } void setup_word_ixbar_group() override; + int determine_pre_byteswizzle_loc(MatchSource *ms, int lo, int hi, int word) override; + void add_proxy_hash_function(json::map &stage_tbl) const;) + +DECLARE_TABLE_TYPE(TernaryMatchTable, MatchTable, "ternary_match", + protected: + void vpn_params(int &width, int &depth, int &period, const char *&period_name) const override; + struct Match { + int lineno = -1, word_group = -1, byte_group = -1, byte_config = 0, dirtcam = 0; + Match() {} + explicit Match(const value_t &); + }; + enum range_match_t { TCAM_NORMAL = 0, DIRTCAM_2B = 1, DIRTCAM_4B_LO = 2, + DIRTCAM_4B_HI = 3, NONE = 4 }; + enum byte_config_t { MIDBYTE_NIBBLE_LO = 0, MIDBYTE_NIBBLE_HI = 1 }; + std::vector match; + int match_word(int word_group) const { + for (unsigned i = 0; i < match.size(); i++) + if (match[i].word_group == word_group) + return i; + return -1; } + unsigned chain_rows[TCAM_UNITS_PER_ROW]; /* bitvector per column */ + enum { ALWAYS_ENABLE_ROW = (1<<2) | (1<<5) | (1<<9) }; + friend class TernaryIndirectTable; + + virtual void check_tcam_match_bus(const std::vector &) = 0; + public: + void pass0() override; + int tcam_id = -1; + Table::Ref indirect; + int indirect_bus = -1; /* indirect bus to use if there's no indirect table */ + void alloc_vpns() override; + range_match_t get_dirtcam_mode(int group, int byte) const { + BUG_CHECK(group >= 0); + BUG_CHECK(byte >= 0); + range_match_t dirtcam_mode = NONE; + for (auto &m : match) { + if (m.word_group == group) { + dirtcam_mode = (range_match_t) ((m.dirtcam >> 2*byte) & 0x3); } } + return dirtcam_mode; } + Format::Field *lookup_field(const std::string &name, const std::string &action) const override; + HashDistribution *find_hash_dist(int unit) override { + return indirect ? indirect->find_hash_dist(unit) : Table::find_hash_dist(unit); } + int find_on_actionbus(const ActionBusSource &src, int lo, int hi, int size, + int pos = -1) override { + return indirect ? indirect->find_on_actionbus(src, lo, hi, size, pos) + : Table::find_on_actionbus(src, lo, hi, size, pos); } + void need_on_actionbus(const ActionBusSource &src, int lo, int hi, int size) override { + indirect ? indirect->need_on_actionbus(src, lo, hi, size) + : Table::need_on_actionbus(src, lo, hi, size); } + int find_on_actionbus(const char *n, TableOutputModifier mod, int lo, int hi, + int size, int *len = 0) override { + return indirect ? indirect->find_on_actionbus(n, mod, lo, hi, size, len) + : Table::find_on_actionbus(n, mod, lo, hi, size, len); } + void need_on_actionbus(Table *att, TableOutputModifier mod, int lo, int hi, int size) override { + indirect ? indirect->need_on_actionbus(att, mod, lo, hi, size) + : Table::need_on_actionbus(att, mod, lo, hi, size); } + const Call &get_action() const override { return indirect ? indirect->get_action() : action; } + Actions *get_actions() const override { return actions ? actions.get() : + (action ? action->actions.get() : indirect ? indirect->actions ? indirect->actions.get() : + indirect->action ? indirect->action->actions.get() : 0 : 0); } + const AttachedTables *get_attached() const override { + return indirect ? indirect->get_attached() : &attached; } + AttachedTables *get_attached() override { + return indirect ? indirect->get_attached() : &attached; } + SelectionTable *get_selector() const override { + return indirect ? indirect->get_selector() : 0; } + StatefulTable *get_stateful() const override { + return indirect ? indirect->get_stateful() : 0; } + MeterTable* get_meter() const override { + return indirect ? indirect->get_meter() : 0; } + bool is_attached(const Table *tbl) const override { + return indirect ? indirect->is_attached(tbl) : MatchTable::is_attached(tbl); } + Format::Field *find_address_field(const AttachedTable *tbl) const override { + return indirect ? indirect->find_address_field(tbl) : attached.find_address_field(tbl); } + std::unique_ptr gen_memory_resource_allocation_tbl_cfg( + const char *type, const std::vector &layout, + bool skip_spare_bank = false) const override; + json::map &get_tbl_top(json::vector &out) const; + Call &action_call() override { return indirect ? indirect->action : action; } + Call &instruction_call() override { return indirect ? indirect->instruction: instruction; } + int json_memunit(const MemUnit &u) const override { + return u.row + u.col*12; } + bool is_ternary() override { return true; } + bool has_indirect() { return indirect; } + int hit_next_size() const override { + if (indirect && indirect->hit_next.size() > 0) + return indirect->hit_next.size(); + return hit_next.size(); } + table_type_t table_type() const override { return TERNARY; } + void gen_entry_cfg(json::vector &out, std::string name, + unsigned lsb_offset, unsigned lsb_idx, unsigned msb_idx, + std::string source, unsigned start_bit, unsigned field_width, + unsigned index, bitvec &tcam_bits, unsigned byte_offset) const; + void gen_entry_cfg2(json::vector &out, std::string field_name, std::string global_name, + unsigned lsb_offset, unsigned lsb_idx, unsigned msb_idx, std::string source, + unsigned start_bit, unsigned field_width, bitvec &tcam_bits) const; + void gen_entry_range_cfg(json::map &entry, bool duplicate, unsigned nibble_offset) const; + void set_partition_action_handle(unsigned handle) { + if (p4_table) p4_table->set_partition_action_handle(handle); } + void set_partition_field_name(std::string name) { + if (p4_table) p4_table->set_partition_field_name(name); } + void base_alpm_pre_classifier_tbl_cfg(json::map &pre_classifier_tbl, + const char *type, int size) const { + if (p4_table) + p4_table->base_alpm_tbl_cfg(pre_classifier_tbl, size, this, P4Table::PreClassifier); + } + virtual void gen_match_fields_pvp(json::vector &match_field_list, unsigned word, + bool uses_versioning, unsigned version_word_group, bitvec &tcam_bits) const; + virtual void gen_match_fields(json::vector &match_field_list, + std::vector &tcam_bits) const; + unsigned get_default_action_handle() const override { + unsigned def_act_handle = Table::get_default_action_handle(); + return def_act_handle > 0 ? def_act_handle : + indirect ? indirect->get_default_action_handle() ? + indirect->get_default_action_handle() : action ? + action->default_action_handle : 0 : 0; + } + std::string get_default_action() override { + std::string def_act = Table::get_default_action(); + return !def_act.empty() ? def_act : indirect ? indirect->default_action : ""; } + Format* get_format() const override { + return indirect ? indirect->get_format() : MatchTable::get_format(); } + template void write_merge_regs_vt(REGS ®s, int type, int bus) { + attached.write_merge_regs(regs, this, type, bus); } + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, + void write_merge_regs, (mau_regs ®s, int type, int bus), override { + write_merge_regs_vt(regs, type, bus); }) + void add_result_physical_buses(json::map &stage_tbl) const override; + default_action_params* get_default_action_parameters() override { + if (!default_action_parameters.empty()) return &default_action_parameters; + auto def_action_params = indirect ? indirect->get_default_action_parameters() : nullptr; + return def_action_params; } + bitvec compute_reachable_tables() override; + int get_tcam_id() const override { return tcam_id; } + virtual void setup_indirect(const value_t &v) { + if (CHECKTYPE(v, tSTR)) + indirect = v; } + + private: + template void tcam_table_map(REGS ®s, int row, int col); +) + +DECLARE_TABLE_TYPE( + Phase0MatchTable, MatchTable, "phase0_match", int size = MAX_PORTS; int width = 1; + int constant_value = 0; table_type_t table_type() const override { return PHASE0; } + // Phase0 Tables are not actual tables. They cannot have action data + // or attached tables and do not need a logical id assignment, hence + // we skip pass0 + void pass0() override {} void set_pred() override { return; } bool needs_next() const override { + return false; + } int ram_word_width() const override { return Target::PHASE0_FORMAT_WIDTH(); }) +DECLARE_TABLE_TYPE( + HashActionTable, MatchTable, "hash_action", public + : + // int row = -1, bus = -1; + table_type_t table_type() const override { return HASH_ACTION; } template + void write_merge_regs_vt(REGS ®s, int type, int bus); + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_merge_regs, + (mau_regs & regs, int type, int bus), override;) Format::Field * + lookup_field(const std::string &n, const std::string &act = "") const override; + void add_hash_functions(json::map &stage_tbl) const override; + void determine_word_and_result_bus() override; + Layout::bus_type_t default_bus_type() const override { return Layout::RESULT_BUS; }) + +DECLARE_TABLE_TYPE(TernaryIndirectTable, Table, "ternary_indirect", + protected: + TernaryMatchTable *match_table = nullptr; + AttachedTables attached; + table_type_t table_type() const override { return TERNARY_INDIRECT; } + table_type_t set_match_table(MatchTable *m, bool indirect) override; + void vpn_params(int &width, int &depth, int &period, const char *&period_name) const override { + width = (format->size-1)/128 + 1; + depth = layout_size() / width; + period = 1; + period_name = 0; } + Actions *get_actions() const override { + return actions ? actions.get() : (match_table ? match_table->actions.get() : nullptr); + } + const AttachedTables *get_attached() const override { return &attached; } + AttachedTables *get_attached() override { return &attached; } + const GatewayTable *get_gateway() const override { return match_table->get_gateway(); } + const MatchTable *get_match_table() const override { return match_table; } + std::set get_match_tables() override { + std::set rv; + if (match_table) rv.insert(match_table); + return rv; } + SelectionTable *get_selector() const override { return attached.get_selector(); } + StatefulTable *get_stateful() const override { return attached.get_stateful(); } + MeterTable* get_meter() const override { return attached.get_meter(); } + bool is_attached(const Table *tbl) const override { return attached.is_attached(tbl); } + Format::Field *find_address_field(const AttachedTable *tbl) const override { + return attached.find_address_field(tbl); } + template void write_merge_regs_vt(REGS ®s, int type, int bus) { + attached.write_merge_regs(regs, match_table, type, bus); } + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, + void write_merge_regs, (mau_regs ®s, int type, int bus), override { + write_merge_regs_vt(regs, type, bus); }) + int unitram_type() override { return UnitRam::TERNARY_INDIRECTION; } + public: + Format::Field *lookup_field(const std::string &n, + const std::string &act = "") const override; + MatchTable *get_match_table() override { return match_table; } + const std::vector &get_hit_next() const override { + if (hit_next.empty() && match_table) + return match_table->get_hit_next(); + return Table::get_hit_next(); } + const NextTables &get_miss_next() const override { + if (!miss_next.set() && match_table) + return match_table->get_miss_next(); + return Table::get_miss_next(); } + int address_shift() const override { return std::min(5U, format->log2size - 2); } + unsigned get_default_action_handle() const override { + unsigned def_act_handle = Table::get_default_action_handle(); + return def_act_handle ? def_act_handle : action ? action->default_action_handle : 0; } + bool needs_handle() const override { return true; } + bool needs_next() const override { return true; } + void determine_word_and_result_bus() override; + bitvec compute_reachable_tables() override; + int get_tcam_id() const override { return match_table->tcam_id; } + Layout::bus_type_t default_bus_type() const override { return Layout::TIND_BUS; } +) + +DECLARE_ABSTRACT_TABLE_TYPE( + AttachedTable, Table, + /* table that can be attached to multiple match tables to do something */ + std::set match_tables; + bool direct = false, indirect = false; bool per_flow_enable = false; + std::string per_flow_enable_param = ""; + virtual unsigned per_flow_enable_bit(MatchTable *m = nullptr) const; + table_type_t set_match_table(MatchTable * m, bool indirect) override { + if ((indirect && direct) || (!indirect && this->indirect)) + error(lineno, "Table %s is accessed with direct and indirect indices", name()); + this->indirect = indirect; + direct = !indirect; + match_tables.insert(m); + if ((unsigned)m->logical_id < (unsigned)logical_id) logical_id = m->logical_id; + return table_type(); + } const GatewayTable *get_gateway() const override { + return match_tables.size() == 1 ? (*match_tables.begin())->get_gateway() : 0; + } SelectionTable *get_selector() const override; + StatefulTable * get_stateful() const override; MeterTable * get_meter() const override; + Call & + action_call() override { + return match_tables.size() == 1 ? (*match_tables.begin())->action_call() : action; + } int json_memunit(const MemUnit &u) const override; + void pass1() override; virtual unsigned get_alu_index() const { + if (layout.size() > 0) return layout[0].row / 4U; + error(lineno, "Cannot determine ALU Index for table %s", name()); + return 0; + } unsigned determine_meter_shiftcount(Table::Call &call, int group, int word, int tcam_shift) + const; + void determine_meter_merge_regs(MatchTable *match, int type, int bus, + const std::vector &arg, + METER_ACCESS_TYPE default_type, unsigned &adr_mask, + unsigned &per_entry_mux_ctl, unsigned &adr_default, + unsigned &meter_type_position); + protected + : + // Accessed by Meter/Selection/Stateful Tables as "meter_alu_index" + // Accessed by Statistics (Counter) Tables as "stats_alu_index" + void add_alu_index(json::map &stage_tbl, std::string alu_index) const; + public + : const MatchTable *get_match_table() + const override { return match_tables.size() == 1 ? *match_tables.begin() : 0; } MatchTable + *get_match_table() override { + return match_tables.size() == 1 ? *match_tables.begin() : 0; + } std::set + get_match_tables() override { return match_tables; } bool has_per_flow_enable() + const { return per_flow_enable; } std::string get_per_flow_enable_param() { + return per_flow_enable_param; + } Format::Field *get_per_flow_enable_param(MatchTable *m) const override { + return per_flow_enable ? m->lookup_field(per_flow_enable_param) : nullptr; + } Format::Field *get_meter_address_param(MatchTable *m) const override { + std::string pfe_name = + per_flow_enable_param.substr(0, per_flow_enable_param.find("_pfe")); + return per_flow_enable ? m->lookup_field(pfe_name + "_addr") : nullptr; + } Format::Field *get_meter_type_param(MatchTable *m) const override { + std::string pfe_name = + per_flow_enable_param.substr(0, per_flow_enable_param.find("_pfe")); + return per_flow_enable ? m->lookup_field(pfe_name + "_type") : nullptr; + } bool get_per_flow_enable() { return per_flow_enable; } bool is_direct() + const { return direct; } virtual int default_pfe_adjust() + const { return 0; } std::string get_default_action() override { + if (!default_action.empty()) return default_action; + for (auto m : match_tables) { + std::string def_action = m->get_default_action(); + if (!def_action.empty()) return def_action; + } + return ""; + } default_action_params *get_default_action_parameters() override { + if (!default_action_parameters.empty()) + return &default_action_parameters; + for (auto m : match_tables) { + if (auto def_action_params = m->get_default_action_parameters()) + if (!def_action_params->empty()) return def_action_params; + } + return nullptr; + } bool validate_call(Table::Call &call, MatchTable *self, + size_t required_args, int hash_dist_type, + Table::Call &first_call) override; + // used by Selection and Stateful tables. + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, int meter_alu_fifo_enable_from_mask, + (mau_regs &, unsigned bytemask))) + +DECLARE_TABLE_TYPE( + ActionTable, AttachedTable, "action", protected + : int action_id = -1; + std::map home_rows_per_word; int home_lineno = -1; + std::map> action_formats; + std::map pack_actions; + static const std::map> action_data_address_huffman_encoding; + void vpn_params(int &width, int &depth, int &period, const char *&period_name) const override; + int get_start_vpn() override; std::string find_field(Format::Field * field) override; + int find_field_lineno(Format::Field *field) override; + Format::Field * lookup_field(const std::string &name, const std::string &action) const override; + void apply_to_field(const std::string &n, std::function fn) override; + int find_on_actionbus(const char *n, TableOutputModifier mod, int lo, int hi, int size, + int *len) override; + int find_on_actionbus(const ActionBusSource &src, int lo, int hi, int size, int pos = -1) + override; + void need_on_actionbus(const ActionBusSource &src, int lo, int hi, int size) override; + void need_on_actionbus(Table *att, TableOutputModifier mod, int lo, int hi, int size) override; + table_type_t table_type() const override { return ACTION; } int unitram_type() + override { return UnitRam::ACTION; } void pad_format_fields(); + unsigned get_do_care_count(std::string bstring); + unsigned get_lower_huffman_encoding_bits(unsigned width); public + : const std::map> &get_action_formats() + const { return action_formats; } unsigned get_size() const { + unsigned size = 0; + if (format) size = format->size; + for (auto &f : get_action_formats()) { + unsigned fsize = f.second->size; + if (fsize > size) size = fsize; + } + return size; + } unsigned get_log2size() const { + unsigned size = get_size(); + return ceil_log2(size); + } unsigned determine_shiftcount(Table::Call &call, int group, unsigned word, int tcam_shift) + const override; + unsigned determine_default(Table::Call &call) const; + unsigned determine_mask(Table::Call &call) const; + unsigned determine_vpn_shiftcount(Table::Call &call) const; bool needs_handle() + const override { return true; } bool needs_next() const override { return true; }) + +DECLARE_TABLE_TYPE(GatewayTable, Table, "gateway", + protected: + MatchTable *match_table = 0; + uint64_t payload = -1; + int have_payload = -1; + std::vector payload_map; + int match_address = -1; + int gw_unit = -1; + int payload_unit = -1; + enum range_match_t { NONE, DC_2BIT, DC_4BIT } + range_match = NONE; + std::string gateway_name; + std::string gateway_cond; + bool always_run = false; // only for standalone + public: + struct MatchKey { + int offset; + Phv::Ref val; + bool valid; /* implicit valid bit for tofino1 only */ + MatchKey(gress_t gr, int stg, value_t &v) : + offset(-1), val(gr, stg, v), valid(false) {} + MatchKey(int off, gress_t gr, int stg, value_t &v) : + offset(off), val(gr, stg, v), valid(false) {} + // tofino1 only: phv has an implicit valid bit that can be matched in + // gateway or ternary table. + MatchKey(int off, gress_t gr, int stg, value_t &v, bool vld) : + offset(off), val(gr, stg, v), valid(vld) {} + bool operator<(const MatchKey &a) const { return offset < a.offset; } + }; + protected: + std::vector match, xor_match; + struct Match { + int lineno = 0; + uint16_t range[6] = { 0, 0, 0, 0, 0, 0 }; + wmatch_t val; + bool run_table = false; + NextTables next; + std::string action; // FIXME -- need arguments? + int next_map_lut = -1; + Match() {} + Match(value_t *v, value_t &data, range_match_t range_match); + } miss, cond_true, cond_false; + std::vector table; + bool need_next_map_lut = false; + template void payload_write_regs(REGS &, int row, int type, int bus); + template void standalone_write_regs(REGS ®s); + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, + virtual void write_next_table_regs, (mau_regs &), { BUG(); }) + bool gateway_needs_ixbar_group() { + for (auto& m : match) + if (m.offset < 32) + return true; + return !xor_match.empty(); } + public: + table_type_t table_type() const override { return GATEWAY; } + virtual int find_next_lut_entry(Table *tbl, const Match &match); + const MatchTable *get_match_table() const override { return match_table; } + MatchTable *get_match_table() override { return match_table; } + std::set get_match_tables() override { + std::set rv; + if (match_table) rv.insert(match_table); + return rv; } + table_type_t set_match_table(MatchTable *m, bool indirect) override { + match_table = m; + if ((unsigned)m->logical_id < (unsigned)logical_id) logical_id = m->logical_id; + return GATEWAY; } + virtual void setup_map_indexing(Table *tbl) { return; } + static GatewayTable *create(int lineno, const std::string &name, gress_t gress, + Stage *stage, int lid, VECTOR(pair_t) &data) + { return table_type_singleton.create(lineno, name.c_str(), gress, stage, lid, data); } + const GatewayTable *get_gateway() const override { return this; } + AttachedTables *get_attached() const override { + return match_table ? match_table->get_attached() : 0; } + SelectionTable *get_selector() const override { + return match_table ? match_table->get_selector() : 0; } + StatefulTable *get_stateful() const override { + return match_table ? match_table->get_stateful() : 0; } + MeterTable *get_meter() const override { + return match_table ? match_table->get_meter() : 0; } + bool empty_match() const { return match.empty() && xor_match.empty(); } + unsigned input_use() const; + bool needs_handle() const override { return true; } + bool needs_next() const override { return true; } + bool is_branch() const; // Tofino2 needs is_a_brnch set to use next_table + void verify_format(); + bool is_always_run() const override { return always_run; } + virtual bool check_match_key(MatchKey &, const std::vector &, bool); + virtual int gw_memory_unit() const = 0; +) + +DECLARE_TABLE_TYPE( + SelectionTable, AttachedTable, "selection", + bool non_linear_hash = false, /* == enable_sps_scrambling */ + resilient_hash = false; /* false is fair hash */ + int mode_lineno = -1, param = -1; std::vector pool_sizes; + int min_words = -1, max_words = -1; int selection_hash = -1; public + : StatefulTable *bound_stateful = nullptr; + table_type_t table_type() + const override { return SELECTION; } void vpn_params(int &width, int &depth, int &period, + const char *&period_name) + const override { + width = period = 1; + depth = layout_size(); + period_name = 0; + } + + template + void write_merge_regs_vt(REGS ®s, MatchTable *match, int type, int bus, + const std::vector &args); + template void setup_logical_alu_map(REGS ®s, int logical_id, int alu); + template void setup_physical_alu_map(REGS ®s, int type, int bus, int alu); + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_merge_regs, + (mau_regs & regs, MatchTable *match, int type, int bus, + const std::vector &args), + override;) int address_shift() + const override { return 7; } std::vector + determine_spare_bank_memory_units() const override; + unsigned meter_group() const { return layout.at(0).row / 4U; } int home_row() const override { + return layout.at(0).row | 3; + } int unitram_type() override { return UnitRam::SELECTOR; } StatefulTable *get_stateful() + const override { + return bound_stateful; + } unsigned determine_shiftcount(Table::Call &call, int group, unsigned word, int tcam_shift) + const override; + void set_stateful(StatefulTable *s) override { + bound_stateful = s; + } unsigned per_flow_enable_bit(MatchTable *m = nullptr) const override; + int indirect_shiftcount() const override; + unsigned determine_length_shiftcount(const Table::Call &call, int group, int word) const; + unsigned determine_length_mask(const Table::Call &call) const; + unsigned determine_length_default(const Table::Call &call) const; + bool validate_length_call(const Table::Call &call);) + +class IdletimeTable : public Table { + MatchTable *match_table = 0; + int sweep_interval = 7, precision = 3; + bool disable_notification = false; + bool two_way_notification = false; + bool per_flow_enable = false; + + IdletimeTable(int lineno, const char *name, gress_t gress, Stage *stage, int lid) + : Table(lineno, name, gress, stage, lid) {} + void setup(VECTOR(pair_t) & data) override; + + public: + table_type_t table_type() const override { return IDLETIME; } + table_type_t set_match_table(MatchTable *m, bool indirect) override { + match_table = m; + if ((unsigned)m->logical_id < (unsigned)logical_id) logical_id = m->logical_id; + return IDLETIME; + } + void vpn_params(int &width, int &depth, int &period, const char *&period_name) const override { + width = period = 1; + depth = layout_size(); + period_name = 0; + } + int json_memunit(const MemUnit &u) const override; + int precision_shift() const; + int direct_shiftcount() const override; + void pass1() override; + void pass2() override; + void pass3() override; + template + void write_merge_regs_vt(REGS ®s, int type, int bus); + template + void write_regs_vt(REGS ®s); + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_regs, (mau_regs & regs), override;) + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_merge_regs, + (mau_regs & regs, int type, int bus), override;) + void gen_tbl_cfg(json::vector &out) const override { /* nothing at top level */ } + void gen_stage_tbl_cfg(json::map &out) const; + static IdletimeTable *create(int lineno, const std::string &name, gress_t gress, Stage *stage, + int lid, VECTOR(pair_t) & data) { + IdletimeTable *rv = new IdletimeTable(lineno, name.c_str(), gress, stage, lid); + rv->setup(data); + return rv; + } + bool needs_handle() const override { return true; } + bool needs_next() const override { return true; } + Layout::bus_type_t default_bus_type() const override { return Layout::IDLE_BUS; } +}; + +DECLARE_ABSTRACT_TABLE_TYPE( + Synth2Port, AttachedTable, + void vpn_params(int &width, int &depth, int &period, const char *&period_name) const override { + width = period = 1; + depth = layout_size(); + period_name = 0; + } bool global_binding = false; + bool output_used = false; int home_lineno = -1; std::set> home_rows; + json::map * add_stage_tbl_cfg(json::map & tbl, const char *type, int size) const override; + public + : int get_home_row_for_row(int row) const; + void add_alu_indexes(json::map &stage_tbl, std::string alu_indexes) const; + OVERLOAD_FUNC_FOREACH(TARGET_CLASS, std::vector, determine_spare_bank_memory_units, + () const, (), override) + OVERLOAD_FUNC_FOREACH(TARGET_CLASS, void, alloc_vpns, (), ()) template + void write_regs_vt(REGS ®s); + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_regs, (mau_regs & regs), override) + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_merge_regs, + (mau_regs & regs, MatchTable *match, int type, int bus, + const std::vector &args), + override = 0) void common_init_setup(const VECTOR(pair_t) &, bool, + P4Table::type) override; + bool common_setup(pair_t &, const VECTOR(pair_t) &, P4Table::type) override; + void pass1() override; void pass2() override; void pass3() override;) + +DECLARE_TABLE_TYPE( + CounterTable, Synth2Port, "counter", + enum {NONE = 0, PACKETS = 1, BYTES = 2, BOTH = 3} type = NONE; + int teop = -1; bool teop_initialized = false; int bytecount_adjust = 0; + table_type_t table_type() const override { return COUNTER; } template + void write_merge_regs_vt(REGS ®s, MatchTable *match, int type, int bus, + const std::vector &args); + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_merge_regs, + (mau_regs & regs, MatchTable *match, int type, int bus, + const std::vector &args), + override;) + + template + void setup_teop_regs(REGS ®s, int stats_group_index); + template void write_alu_vpn_range(REGS ®s); + +#if HAVE_JBAY + template void setup_teop_regs_2(REGS ®s, int stats_group_index); + template void write_alu_vpn_range_2(REGS ®s); +#endif /* HAVE_JBAY || */ + + struct lrt_params { // largest recent with threshold paramters + int lineno; + int64_t threshold; + int interval; + lrt_params(int l, int64_t t, int i) : lineno(l), threshold(t), interval(i) {} + explicit lrt_params(const value_t &); + }; + std::vector lrt; public + : int home_row() const override { return layout.at(0).row; } int direct_shiftcount() + const override; + int indirect_shiftcount() const override; + unsigned determine_shiftcount(Table::Call &call, int group, unsigned word, int tcam_shift) + const override; + int address_shift() const override; + bool run_at_eop() override { return (type & BYTES) != 0; } bool adr_mux_select_stats() + override { return true; } int unitram_type() override { return UnitRam::STATISTICS; }) + +DECLARE_TABLE_TYPE( + MeterTable, Synth2Port, "meter", int red_nodrop_value = -1; int red_drop_value = -1; + int green_value = 0; int yellow_value = 1; int red_value = 3; int profile = 0; int teop = -1; + bool teop_initialized = false; int bytecount_adjust = 0; + enum {NONE = 0, STANDARD = 1, LPF = 2, RED = 3} type = NONE; + enum {NONE_ = 0, PACKETS = 1, BYTES = 2} count = NONE_; std::vector color_maprams; + table_type_t table_type() const override { return METER; } template + void write_merge_regs_vt(REGS ®s, MatchTable *match, int type, int bus, + const std::vector &args); + template void meter_color_logical_to_phys(REGS ®s, int logical_id, int alu); + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_merge_regs, + (mau_regs & regs, MatchTable *match, int type, int bus, + const std::vector &args), + override;) + + template + void setup_teop_regs(REGS ®s, int meter_group_index); + template void write_alu_vpn_range(REGS ®s); + template void write_regs_home_row(REGS ®s, unsigned row); + template void write_mapram_color_regs(REGS ®s, bool &push_on_overflow); + +#if HAVE_JBAY + template void setup_teop_regs_2(REGS ®s, int stats_group_index); + template void write_alu_vpn_range_2(REGS ®s); +#endif /* HAVE_JBAY || */ + + int sweep_interval = 2; public + : enum {NO_COLOR_MAP, IDLE_MAP_ADDR, STATS_MAP_ADDR} color_mapram_addr = NO_COLOR_MAP; + int direct_shiftcount() const override; int indirect_shiftcount() const override; + int address_shift() const override; bool color_aware = false; + bool color_aware_per_flow_enable = false; bool color_used = false; + int pre_color_hash_dist_unit = -1; int pre_color_bit_lo = -1; + bool run_at_eop() override { return type == STANDARD; } int unitram_type() override { + return UnitRam::METER; + } int home_row() const override { return layout.at(0).row | 3; } unsigned meter_group() + const { return layout.at(0).row / 4U; } bool uses_colormaprams() const override { + return !color_maprams.empty(); + } unsigned determine_shiftcount(Table::Call &call, int group, unsigned word, int tcam_shift) + const override; + void add_cfg_reg(json::vector &cfg_cache, std::string full_name, std::string name, unsigned val, + unsigned width); + Layout::bus_type_t default_bus_type() const override; int default_pfe_adjust() const override { + return color_aware ? -METER_TYPE_BITS : 0; + } void set_color_used() override { color_used = true; } void set_output_used() override { + output_used = true; + } int color_shiftcount(Table::Call &call, int group, int tcam_shift) const override; + template + void setup_exact_shift(REGS &merge, int bus, int group, int word, int word_group, + Call &meter_call, Call &color_call); + template + void setup_tcam_shift(REGS &merge, int bus, int tcam_shift, Call &meter_call, Call &color_call); + template void write_color_regs(REGS ®s, MatchTable *match, int type, int bus, + const std::vector &args);) + +namespace StatefulAlu { +struct TMatchOP; +struct TMatchInfo { + const Table::Actions::Action *act; + const TMatchOP *op; +}; + +Instruction *genNoop(StatefulTable *tbl, Table::Actions::Action *act); +} // namespace StatefulAlu + +DECLARE_TABLE_TYPE(StatefulTable, Synth2Port, "stateful", + table_type_t table_type() const override { return STATEFUL; } +#if HAVE_JBAY + bool setup_jbay(const pair_t &kv); +#endif /* HAVE_JBAY */ + template void write_action_regs_vt(REGS ®s, const Actions::Action *); + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, + void write_action_regs, (mau_regs ®s, const Actions::Action *act), override; ) + template void write_merge_regs_vt(REGS ®s, MatchTable *match, int type, int bus, + const std::vector &args); + template void write_logging_regs(REGS ®s); + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, + void write_merge_regs, (mau_regs ®s, MatchTable *match, int type, + int bus, const std::vector &args), override; ) +#if HAVE_JBAY + template void write_tofino2_common_regs(REGS ®s); +#endif /* HAVE_JBAY */ + struct const_info_t { + int lineno; + int64_t value; + bool is_param; + std::string param_name; + unsigned param_handle; + static unsigned unique_register_param_handle; + const_info_t() = default; + const_info_t(int lineno, + int64_t value, + bool is_param = false, + std::string param_name = "", + unsigned param_handle = 0) + : lineno(lineno), value(value), is_param(is_param), + param_name(param_name), param_handle(param_handle) { + if (is_param) this->param_handle = unique_register_param_handle++; + } + }; + std::vector const_vals; + struct MathTable { + int lineno = -1; + std::vector data; + bool invert = false; + int shift = 0, scale = 0; + explicit operator bool() { return lineno >= 0; } + void check(); + } math_table; + bool dual_mode = false; + bool offset_vpn = false; + bool address_used = false; + int meter_adr_shift = 0; + int stateful_counter_mode = 0; + int watermark_level = 0; + int watermark_pop_not_push = 0; + uint64_t initial_value_lo = 0; + uint64_t initial_value_hi = 0; + unsigned data_bytemask = 0; + unsigned hash_bytemask = 0; + int logvpn_lineno = -1; + int logvpn_min = -1, logvpn_max = -1; + int pred_shift = 0, pred_comb_shift = 0; + int stage_alu_id = -1; + Ref underflow_action, overflow_action; + public: + Ref bound_selector; + unsigned phv_byte_mask = 0; + std::vector sbus_learn, sbus_match; + enum { SBUS_OR = 0, SBUS_AND = 1 } sbus_comb = SBUS_OR; + int phv_hash_shift = 0; + bitvec phv_hash_mask = bitvec(0, 128); + Instruction *output_lmatch = nullptr; // output instruction using lmatch + bitvec clear_value; + uint32_t busy_value = 0; + bool divmod_used = false; + int instruction_set() override { return 1; /* STATEFUL_ALU */ } + int direct_shiftcount() const override; + int indirect_shiftcount() const override; + int address_shift() const override; + int unitram_type() override { return UnitRam::STATEFUL; } + int get_const(int lineno, int64_t v); + bool is_dual_mode() const { return dual_mode; } + int alu_size() const { return 1 << std::min(5U, format->log2size - is_dual_mode()); } + int home_row() const override { return layout.at(0).row | 3; } + unsigned meter_group() const { return layout.at(0).row/4U; } + unsigned determine_shiftcount(Table::Call &call, int group, unsigned word, + int tcam_shift) const override; + unsigned per_flow_enable_bit(MatchTable *m = nullptr) const override; + void set_address_used() override { address_used = true; } + void set_output_used() override { output_used = true; } + void parse_register_params(int idx, const value_t &val); + int64_t get_const_val(int index) const { return const_vals.at(index).value; } + Actions::Action *action_for_table_action(const MatchTable *tbl, const Actions::Action *) const; + OVERLOAD_FUNC_FOREACH(REGISTER_SET, static int, parse_counter_mode, (const value_t &v), (v)) + OVERLOAD_FUNC_FOREACH(REGISTER_SET, void, set_counter_mode, (int mode), (mode)) + OVERLOAD_FUNC_FOREACH(REGISTER_SET, + void, gen_tbl_cfg, (json::map &tbl, json::map &stage_tbl) const, (tbl, stage_tbl)) +#if HAVE_JBAY + BFN::Alloc1D tmatch_use; +#endif /* HAVE_JBAY */ + + bool p4c_5192_workaround(const Actions::Action *) const; +) + +#endif /* BF_ASM_TABLES_H_ */ // NOLINT(build/header_guard) diff --git a/backends/tofino/bf-asm/target.cpp b/backends/tofino/bf-asm/target.cpp new file mode 100644 index 00000000000..89628f0eb32 --- /dev/null +++ b/backends/tofino/bf-asm/target.cpp @@ -0,0 +1,324 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "target.h" + +#include + +#include "asm-types.h" +#include "bson.h" +#include "parser.h" +#include "tables.h" +#include "ubits.h" + +void declare_registers(const Target::Tofino::top_level_regs *regs) { + declare_registers(®s->mem_top, sizeof(regs->mem_top), + [=](std::ostream &out, const char *addr, const void *end) { + out << "memories.top"; + regs->mem_top.emit_fieldname(out, addr, end); + }); + declare_registers(®s->mem_pipe, sizeof(regs->mem_pipe), + [=](std::ostream &out, const char *addr, const void *end) { + out << "memories.pipe"; + regs->mem_pipe.emit_fieldname(out, addr, end); + }); + declare_registers(®s->reg_top, sizeof(regs->reg_top), + [=](std::ostream &out, const char *addr, const void *end) { + out << "registers.top"; + regs->reg_top.emit_fieldname(out, addr, end); + }); + declare_registers(®s->reg_pipe, sizeof(regs->reg_pipe), + [=](std::ostream &out, const char *addr, const void *end) { + out << "registers.pipe"; + regs->reg_pipe.emit_fieldname(out, addr, end); + }); +} +void undeclare_registers(const Target::Tofino::top_level_regs *regs) { + undeclare_registers(®s->mem_top); + undeclare_registers(®s->mem_pipe); + undeclare_registers(®s->reg_top); + undeclare_registers(®s->reg_pipe); +} + +void declare_registers(const Target::Tofino::parser_regs *regs) { + declare_registers(®s->memory[INGRESS], sizeof regs->memory[INGRESS], + [=](std::ostream &out, const char *addr, const void *end) { + out << "parser.mem[INGRESS]"; + regs->memory[INGRESS].emit_fieldname(out, addr, end); + }); + declare_registers(®s->memory[EGRESS], sizeof regs->memory[EGRESS], + [=](std::ostream &out, const char *addr, const void *end) { + out << "parser.mem[EGRESS]"; + regs->memory[EGRESS].emit_fieldname(out, addr, end); + }); + declare_registers(®s->ingress, sizeof regs->ingress, + [=](std::ostream &out, const char *addr, const void *end) { + out << "parser.ibp_reg"; + regs->ingress.emit_fieldname(out, addr, end); + }); + declare_registers(®s->egress, sizeof regs->egress, + [=](std::ostream &out, const char *addr, const void *end) { + out << "parser.ebp_reg"; + regs->egress.emit_fieldname(out, addr, end); + }); + declare_registers(®s->merge, sizeof regs->merge, + [=](std::ostream &out, const char *addr, const void *end) { + out << "parser.merge"; + regs->merge.emit_fieldname(out, addr, end); + }); +} +void undeclare_registers(const Target::Tofino::parser_regs *regs) { + undeclare_registers(®s->memory[INGRESS]); + undeclare_registers(®s->memory[EGRESS]); + undeclare_registers(®s->ingress); + undeclare_registers(®s->egress); + undeclare_registers(®s->merge); +} +void declare_registers(const Target::Tofino::mau_regs *regs, bool, int stage) { + declare_registers(regs, sizeof *regs, + [=](std::ostream &out, const char *addr, const void *end) { + out << "mau[" << stage << "]"; + regs->emit_fieldname(out, addr, end); + }); +} +void declare_registers(const Target::Tofino::deparser_regs *regs) { + declare_registers(®s->input, sizeof(regs->input), + [=](std::ostream &out, const char *addr, const void *end) { + out << "deparser.input_phase"; + regs->input.emit_fieldname(out, addr, end); + }); + declare_registers(®s->header, sizeof(regs->header), + [=](std::ostream &out, const char *addr, const void *end) { + out << "deparser.header_phase"; + regs->header.emit_fieldname(out, addr, end); + }); +} +void undeclare_registers(const Target::Tofino::deparser_regs *regs) { + undeclare_registers(®s->input); + undeclare_registers(®s->header); +} + +void emit_parser_registers(const Target::Tofino::top_level_regs *regs, std::ostream &out) { + std::set emitted_parsers; + // The driver can reprogram parser blocks at runtime. We output parser + // blocks in the binary with the same base address. The driver uses the + // parser handle at the start of each block to associate the parser block + // with its respective parser node in context.json. + // In a p4 program, the user can associate multiple parsers to a + // multi-parser configuration but only map a few ports. The unmapped + // parser(s) will be output in context.json node and binary but not have an + // associated port map in context.json. The driver will not initialize any + // parsers with these unmapped parser(s) but use them to reconfigure at + // runtime if required. + uint64_t pipe_mem_base_addr = 0x200000000000; + uint64_t prsr_mem_base_addr = (pipe_mem_base_addr + 0x1C800000000) >> 4; + uint64_t pipe_regs_base_addr = 0x2000000; + uint64_t prsr_regs_base_addr = pipe_regs_base_addr + 0x700000; + for (auto ig : regs->parser_ingress) { + out << binout::tag('P') << binout::byte4(ig.first); + ig.second->emit_binary(out, prsr_regs_base_addr); + } + for (auto ig : regs->parser_memory[INGRESS]) { + out << binout::tag('P') << binout::byte4(ig.first); + ig.second->emit_binary(out, prsr_mem_base_addr); + } + prsr_regs_base_addr = pipe_regs_base_addr + 0x740000; + for (auto eg : regs->parser_egress) { + out << binout::tag('P') << binout::byte4(eg.first); + eg.second->emit_binary(out, prsr_regs_base_addr); + } + prsr_mem_base_addr = (pipe_mem_base_addr + 0x1C800400000) >> 4; + for (auto eg : regs->parser_memory[EGRESS]) { + out << binout::tag('P') << binout::byte4(eg.first); + eg.second->emit_binary(out, prsr_mem_base_addr); + } +} + +#if HAVE_JBAY +void declare_registers(const Target::JBay::top_level_regs *regs) { + declare_registers(®s->mem_top, sizeof(regs->mem_top), + [=](std::ostream &out, const char *addr, const void *end) { + out << "memories.top"; + regs->mem_top.emit_fieldname(out, addr, end); + }); + declare_registers(®s->mem_pipe, sizeof(regs->mem_pipe), + [=](std::ostream &out, const char *addr, const void *end) { + out << "memories.pipe"; + regs->mem_pipe.emit_fieldname(out, addr, end); + }); + declare_registers(®s->reg_top, sizeof(regs->reg_top), + [=](std::ostream &out, const char *addr, const void *end) { + out << "registers.top"; + regs->reg_top.emit_fieldname(out, addr, end); + }); + declare_registers(®s->reg_pipe, sizeof(regs->reg_pipe), + [=](std::ostream &out, const char *addr, const void *end) { + out << "registers.pipe"; + regs->reg_pipe.emit_fieldname(out, addr, end); + }); +} +void undeclare_registers(const Target::JBay::top_level_regs *regs) { + undeclare_registers(®s->mem_top); + undeclare_registers(®s->mem_pipe); + undeclare_registers(®s->reg_top); + undeclare_registers(®s->reg_pipe); +} +void declare_registers(const Target::JBay::parser_regs *regs) { + declare_registers(®s->memory[INGRESS], sizeof regs->memory[INGRESS], + [=](std::ostream &out, const char *addr, const void *end) { + out << "parser.mem[INGRESS]"; + regs->memory[INGRESS].emit_fieldname(out, addr, end); + }); + declare_registers(®s->memory[EGRESS], sizeof regs->memory[EGRESS], + [=](std::ostream &out, const char *addr, const void *end) { + out << "parser.mem[EGRESS]"; + regs->memory[EGRESS].emit_fieldname(out, addr, end); + }); + declare_registers(®s->ingress, sizeof regs->ingress, + [=](std::ostream &out, const char *addr, const void *end) { + out << "parser.ipb_reg"; + regs->ingress.emit_fieldname(out, addr, end); + }); + declare_registers(®s->egress, sizeof regs->egress, + [=](std::ostream &out, const char *addr, const void *end) { + out << "parser.epb_reg"; + regs->egress.emit_fieldname(out, addr, end); + }); + declare_registers(®s->main[INGRESS], sizeof regs->main[INGRESS], + [=](std::ostream &out, const char *addr, const void *end) { + out << "parser.ingress.main"; + regs->main[INGRESS].emit_fieldname(out, addr, end); + }); + declare_registers(®s->main[EGRESS], sizeof regs->main[EGRESS], + [=](std::ostream &out, const char *addr, const void *end) { + out << "parser.egress.main"; + regs->main[EGRESS].emit_fieldname(out, addr, end); + }); + declare_registers(®s->merge, sizeof regs->merge, + [=](std::ostream &out, const char *addr, const void *end) { + out << "parser.merge"; + regs->merge.emit_fieldname(out, addr, end); + }); +} +void undeclare_registers(const Target::JBay::parser_regs *regs) { + undeclare_registers(®s->memory[INGRESS]); + undeclare_registers(®s->memory[EGRESS]); + undeclare_registers(®s->ingress); + undeclare_registers(®s->egress); + undeclare_registers(®s->main[INGRESS]); + undeclare_registers(®s->main[EGRESS]); + undeclare_registers(®s->merge); +} +void declare_registers(const Target::JBay::mau_regs *regs, bool, int stage) { + declare_registers(regs, sizeof *regs, + [=](std::ostream &out, const char *addr, const void *end) { + out << "mau[" << stage << "]"; + regs->emit_fieldname(out, addr, end); + }); +} +void declare_registers(const Target::JBay::deparser_regs *regs) { + declare_registers(regs, sizeof *regs, + [=](std::ostream &out, const char *addr, const void *end) { + out << "deparser.regs"; + regs->emit_fieldname(out, addr, end); + }); +} + +void emit_parser_registers(const Target::JBay::top_level_regs *regs, std::ostream &out) { + std::set emitted_parsers; + for (auto ig : regs->parser_ingress) { + json::map header; + header["handle"] = ig.first; + out << binout::tag('P') << json::binary(header); + ig.second->emit_binary(out, 0); + } + for (auto eg : regs->parser_egress) { + json::map header; + header["handle"] = eg.first; + out << binout::tag('P') << json::binary(header); + eg.second->emit_binary(out, 0); + } + for (auto ig : regs->parser_main[INGRESS]) { + json::map header; + header["handle"] = ig.first; + out << binout::tag('P') << json::binary(header); + ig.second->emit_binary(out, 0); + } + for (auto eg : regs->parser_main[EGRESS]) { + json::map header; + header["handle"] = eg.first; + out << binout::tag('P') << json::binary(header); + eg.second->emit_binary(out, 0); + } + for (auto ig : regs->parser_memory[INGRESS]) { + json::map header; + header["handle"] = ig.first; + out << binout::tag('P') << json::binary(header); + ig.second->emit_binary(out, 0); + } + for (auto eg : regs->parser_memory[EGRESS]) { + json::map header; + header["handle"] = eg.first; + out << binout::tag('P') << json::binary(header); + eg.second->emit_binary(out, 0); + } +} +#endif /* HAVE_JBAY */ + +int Target::numMauStagesOverride = 0; + +int Target::encodeConst(int src) { + SWITCH_FOREACH_TARGET(options.target, return TARGET::encodeConst(src);); + BUG(); + return 0; +} + +void Target::OVERRIDE_NUM_MAU_STAGES(int num) { + int allowed = NUM_MAU_STAGES_PRIVATE(); + BUG_CHECK(num > 0 && num <= allowed, + "Invalid override for NUM_MAU_STAGES. Allowed range is <1, %d>, got %d.", allowed, + num); + + numMauStagesOverride = num; + return; +} + +int Target::NUM_BUS_OF_TYPE_v(int bus_type) const { + // default values for Tofino1/2 + switch (static_cast(bus_type)) { + case Table::Layout::SEARCH_BUS: + case Table::Layout::RESULT_BUS: + case Table::Layout::TIND_BUS: + return 2; + case Table::Layout::IDLE_BUS: + return 20; + default: + return 0; + } +} + +int Target::NUM_BUS_OF_TYPE(int bus_type) { + SWITCH_FOREACH_TARGET(options.target, return TARGET().NUM_BUS_OF_TYPE_v(bus_type);) +} + +// should these be inline in the header file? +#define DEFINE_PER_TARGET_CONSTANT(TYPE, NAME) \ + TYPE Target::NAME() { \ + SWITCH_FOREACH_TARGET(options.target, return TARGET::NAME;) \ + return (TYPE){}; /* NOLINT(readability/braces) */ \ + } +PER_TARGET_CONSTANTS(DEFINE_PER_TARGET_CONSTANT) diff --git a/backends/tofino/bf-asm/target.h b/backends/tofino/bf-asm/target.h new file mode 100644 index 00000000000..3160c1cc9c5 --- /dev/null +++ b/backends/tofino/bf-asm/target.h @@ -0,0 +1,726 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef TARGET_H_ +#define TARGET_H_ + +#include + +#include "asm-types.h" +#include "bfas.h" +#include "map.h" + +struct MemUnit; + +/** FOR_ALL_TARGETS -- metamacro that expands a macro for each defined target + * FOR_ALL_REGISTER_SETS -- metamacro that expands for each distinct register set; + * basically a subset of targets with one per distinct register set + * FOR_ALL_TARGET_CLASSES -- metamacro that expands for each distinct target class + * a subset of the register sets + */ +#if HAVE_JBAY +#define FOR_ALL_TARGETS(M, ...) \ + M(Tofino, ##__VA_ARGS__) \ + M(JBay, ##__VA_ARGS__) \ + M(Tofino2H, ##__VA_ARGS__) \ + M(Tofino2M, ##__VA_ARGS__) \ + M(Tofino2U, ##__VA_ARGS__) \ + M(Tofino2A0, ##__VA_ARGS__) +#define FOR_ALL_REGISTER_SETS(M, ...) \ + M(Tofino, ##__VA_ARGS__) \ + M(JBay, ##__VA_ARGS__) +#define FOR_ALL_TARGET_CLASSES(M, ...) M(Tofino, ##__VA_ARGS__) +#else +#define FOR_ALL_TARGETS(M, ...) M(Tofino, ##__VA_ARGS__) +#define FOR_ALL_REGISTER_SETS(M, ...) M(Tofino, ##__VA_ARGS__) +#define FOR_ALL_TARGET_CLASSES(M, ...) M(Tofino, ##__VA_ARGS__) +#endif /* ! && !HAVE_CLOUBREAK && !HAVE_JBAY */ +// alias FOR_ALL -> FOR_EACH so the the group name does need to be plural +#define FOR_EACH_TARGET FOR_ALL_TARGETS +#define FOR_EACH_REGISTER_SET FOR_ALL_REGISTER_SETS +#define FOR_EACH_TARGET_CLASS FOR_ALL_TARGET_CLASSES + +#if HAVE_JBAY +#define TARGETS_IN_CLASS_Tofino(M, ...) \ + M(Tofino, ##__VA_ARGS__) \ + M(JBay, ##__VA_ARGS__) \ + M(Tofino2H, ##__VA_ARGS__) \ + M(Tofino2M, ##__VA_ARGS__) \ + M(Tofino2U, ##__VA_ARGS__) \ + M(Tofino2A0, ##__VA_ARGS__) +#define REGSETS_IN_CLASS_Tofino(M, ...) \ + M(Tofino, ##__VA_ARGS__) \ + M(JBay, ##__VA_ARGS__) +#else +#define TARGETS_IN_CLASS_Tofino(M, ...) M(Tofino, ##__VA_ARGS__) +#define REGSETS_IN_CLASS_Tofino(M, ...) M(Tofino, ##__VA_ARGS__) +#endif + +#if HAVE_JBAY +#define TARGETS_USING_REGS_JBay(M, ...) \ + M(JBay, ##__VA_ARGS__) \ + M(Tofino2H, ##__VA_ARGS__) \ + M(Tofino2M, ##__VA_ARGS__) \ + M(Tofino2U, ##__VA_ARGS__) \ + M(Tofino2A0, ##__VA_ARGS__) +#endif +#define TARGETS_USING_REGS_Tofino(M, ...) M(Tofino, ##__VA_ARGS__) + +#define TARGETS_IN_CLASS(CL, ...) TARGETS_IN_CLASS_##CL(__VA_ARGS__) +#define TARGETS_USING_REGS(CL, ...) TARGETS_USING_REGS_##CL(__VA_ARGS__) +#define REGSETS_IN_CLASS(CL, ...) REGSETS_IN_CLASS_##CL(__VA_ARGS__) + +#define EXPAND(...) __VA_ARGS__ +#define EXPAND_COMMA(...) , ##__VA_ARGS__ +#define EXPAND_COMMA_CLOSE(...) ,##__VA_ARGS__ ) +#define INSTANTIATE_TARGET_TEMPLATE(TARGET, FUNC, ...) template FUNC(Target::TARGET::__VA_ARGS__); +#define DECLARE_TARGET_CLASS(TARGET, ...) class TARGET __VA_ARGS__; +#define FRIEND_TARGET_CLASS(TARGET, ...) friend class Target::TARGET __VA_ARGS__; +#define TARGET_OVERLOAD(TARGET, FN, ARGS, ...) FN(Target::TARGET::EXPAND ARGS) __VA_ARGS__; + +#define PER_TARGET_CONSTANTS(M) \ + M(const char *, name) \ + M(target_t, register_set) \ + M(int, ARAM_UNITS_PER_STAGE) \ + M(int, DEPARSER_CHECKSUM_UNITS) \ + M(int, DEPARSER_CONSTANTS) \ + M(int, DEPARSER_MAX_FD_ENTRIES) \ + M(int, DEPARSER_MAX_POV_BYTES) \ + M(int, DEPARSER_MAX_POV_PER_USE) \ + M(int, DP_UNITS_PER_STAGE) \ + M(int, DYNAMIC_CONFIG) \ + M(int, DYNAMIC_CONFIG_INPUT_BITS) \ + M(bool, EGRESS_SEPARATE) \ + M(int, END_OF_PIPE) \ + M(int, EXACT_HASH_GROUPS) \ + M(int, EXACT_HASH_TABLES) \ + M(int, EXTEND_ALU_8_SLOTS) \ + M(int, EXTEND_ALU_16_SLOTS) \ + M(int, EXTEND_ALU_32_SLOTS) \ + M(bool, GATEWAY_INHIBIT_INDEX) \ + M(int, GATEWAY_MATCH_BITS) \ + M(bool, GATEWAY_NEEDS_SEARCH_BUS) \ + M(int, GATEWAY_PAYLOAD_GROUPS) \ + M(int, GATEWAY_ROWS) \ + M(bool, GATEWAY_SINGLE_XBAR_GROUP) \ + M(bool, HAS_MPR) \ + M(int, INSTR_SRC2_BITS) \ + M(int, IMEM_COLORS) \ + M(int, IXBAR_HASH_GROUPS) \ + M(int, IXBAR_HASH_INDEX_MAX) \ + M(int, IXBAR_HASH_INDEX_STRIDE) \ + M(int, LOCAL_TIND_UNITS) \ + M(int, LONG_BRANCH_TAGS) \ + M(int, MAX_IMMED_ACTION_DATA) \ + M(int, MAX_OVERHEAD_OFFSET) \ + M(int, MAX_OVERHEAD_OFFSET_NEXT) \ + M(int, MATCH_BYTE_16BIT_PAIRS) \ + M(int, MATCH_REQUIRES_PHYSID) \ + M(int, MAU_BASE_DELAY) \ + M(int, MAU_BASE_PREDICATION_DELAY) \ + M(int, MAU_ERROR_DELAY_ADJUST) \ + M(int, METER_ALU_GROUP_DATA_DELAY) \ + M(int, MINIMUM_INSTR_CONSTANT) \ + M(bool, NEXT_TABLE_EXEC_COMBINED) \ + M(int, NEXT_TABLE_SUCCESSOR_TABLE_DEPTH) \ + M(int, NUM_MAU_STAGES_PRIVATE) \ + M(int, NUM_EGRESS_STAGES_PRIVATE) \ + M(int, NUM_PARSERS) \ + M(int, NUM_PIPES) \ + M(bool, OUTPUT_STAGE_EXTENSION_PRIVATE) \ + M(int, PARSER_CHECKSUM_UNITS) \ + M(bool, PARSER_EXTRACT_BYTES) \ + M(int, PARSER_DEPTH_MAX_BYTES_INGRESS) \ + M(int, PARSER_DEPTH_MAX_BYTES_EGRESS) \ + M(int, PARSER_DEPTH_MAX_BYTES_MULTITHREADED_EGRESS) \ + M(int, PARSER_DEPTH_MIN_BYTES_INGRESS) \ + M(int, PARSER_DEPTH_MIN_BYTES_EGRESS) \ + M(int, PHASE0_FORMAT_WIDTH) \ + M(bool, REQUIRE_TCAM_ID) \ + M(int, SRAM_EGRESS_ROWS) \ + M(bool, SRAM_GLOBAL_ACCESS) \ + M(int, SRAM_HBUS_SECTIONS_PER_STAGE) \ + M(int, SRAM_HBUSSES_PER_ROW) \ + M(int, SRAM_INGRESS_ROWS) \ + M(int, SRAM_LOGICAL_UNITS_PER_ROW) \ + M(int, SRAM_LAMBS_PER_STAGE) \ + M(int, SRAM_REMOVED_COLUMNS) \ + M(int, SRAM_STRIDE_COLUMN) \ + M(int, SRAM_STRIDE_ROW) \ + M(int, SRAM_STRIDE_STAGE) \ + M(int, SRAM_UNITS_PER_ROW) \ + M(int, STATEFUL_ALU_ADDR_WIDTH) \ + M(int, STATEFUL_ALU_CONST_MASK) \ + M(int, STATEFUL_ALU_CONST_MAX) \ + M(int, STATEFUL_ALU_CONST_MIN) \ + M(int, STATEFUL_ALU_CONST_WIDTH) \ + M(int, STATEFUL_CMP_ADDR_WIDTH) \ + M(int, STATEFUL_CMP_CONST_MASK) \ + M(int, STATEFUL_CMP_CONST_MAX) \ + M(int, STATEFUL_CMP_CONST_MIN) \ + M(int, STATEFUL_CMP_CONST_WIDTH) \ + M(int, STATEFUL_CMP_UNITS) \ + M(int, STATEFUL_OUTPUT_UNITS) \ + M(int, STATEFUL_PRED_MASK) \ + M(int, STATEFUL_REGFILE_CONST_WIDTH) \ + M(int, STATEFUL_REGFILE_ROWS) \ + M(int, STATEFUL_TMATCH_UNITS) \ + M(bool, SUPPORT_ALWAYS_RUN) \ + M(bool, SUPPORT_CONCURRENT_STAGE_DEP) \ + M(bool, SUPPORT_OVERFLOW_BUS) \ + M(bool, SUPPORT_SALU_FAST_CLEAR) \ + M(bool, SUPPORT_TRUE_EOP) \ + M(bool, SYNTH2PORT_NEED_MAPRAMS) \ + M(bool, TCAM_EXTRA_NIBBLE) \ + M(bool, TCAM_GLOBAL_ACCESS) \ + M(int, TCAM_MATCH_BUSSES) \ + M(int, TCAM_MEMORY_FULL_WIDTH) \ + M(int, TCAM_ROWS) \ + M(int, TCAM_UNITS_PER_ROW) \ + M(int, TCAM_XBAR_GROUPS) \ + M(bool, TABLES_REQUIRE_ROW) + +#define DECLARE_PER_TARGET_CONSTANT(TYPE, NAME) static TYPE NAME(); + +#define TARGET_CLASS_SPECIFIC_CLASSES \ + class ActionTable; \ + class CounterTable; \ + class ExactMatchTable; \ + class GatewayTable; \ + class MeterTable; \ + class StatefulTable; \ + class TernaryIndirectTable; \ + class TernaryMatchTable; +#define REGISTER_SET_SPECIFIC_CLASSES /* none */ +#define TARGET_SPECIFIC_CLASSES /* none */ + +class Target { + public: + class Phv; + FOR_ALL_TARGETS(DECLARE_TARGET_CLASS) + PER_TARGET_CONSTANTS(DECLARE_PER_TARGET_CONSTANT) + + static int encodeConst(int src); + + static int NUM_MAU_STAGES() { + return numMauStagesOverride ? numMauStagesOverride : NUM_MAU_STAGES_PRIVATE(); + } + static int NUM_EGRESS_STAGES() { + int egress_stages = NUM_EGRESS_STAGES_PRIVATE(); + return numMauStagesOverride && numMauStagesOverride < egress_stages ? numMauStagesOverride + : egress_stages; + } + static int NUM_STAGES(gress_t gr) { + return gr == EGRESS ? NUM_EGRESS_STAGES() : NUM_MAU_STAGES(); + } + + static int OUTPUT_STAGE_EXTENSION() { + return numMauStagesOverride ? 1 : OUTPUT_STAGE_EXTENSION_PRIVATE(); + } + + static void OVERRIDE_NUM_MAU_STAGES(int num); + + static int SRAM_ROWS(gress_t gr) { + return gr == EGRESS ? SRAM_EGRESS_ROWS() : SRAM_INGRESS_ROWS(); + } + + // FIXME -- bus_type here is a Table::Layout::bus_type_t, but can't forward + // declare a nested type. + virtual int NUM_BUS_OF_TYPE_v(int bus_type) const; + static int NUM_BUS_OF_TYPE(int bus_type); + + private: + static int numMauStagesOverride; +}; + +#include "gen/tofino/memories.pipe_addrmap.h" +#include "gen/tofino/memories.pipe_top_level.h" +#include "gen/tofino/memories.prsr_mem_main_rspec.h" +#include "gen/tofino/regs.dprsr_hdr.h" +#include "gen/tofino/regs.dprsr_inp.h" +#include "gen/tofino/regs.ebp_rspec.h" +#include "gen/tofino/regs.ibp_rspec.h" +#include "gen/tofino/regs.mau_addrmap.h" +#include "gen/tofino/regs.pipe_addrmap.h" +#include "gen/tofino/regs.prsr_reg_merge_rspec.h" +#include "gen/tofino/regs.tofino.h" + +class Target::Tofino : public Target { + public: + static constexpr const char *const name = "tofino"; + static constexpr target_t tag = TOFINO; + static constexpr target_t register_set = TOFINO; + typedef Target::Tofino target_type; + typedef Target::Tofino register_type; + class Phv; + struct top_level_regs { + typedef ::Tofino::memories_top _mem_top; + typedef ::Tofino::memories_pipe _mem_pipe; + typedef ::Tofino::regs_top _regs_top; + typedef ::Tofino::regs_pipe _regs_pipe; + + ::Tofino::memories_top mem_top; + ::Tofino::memories_pipe mem_pipe; + ::Tofino::regs_top reg_top; + ::Tofino::regs_pipe reg_pipe; + + // map from handle to parser regs + std::map parser_memory[2]; + std::map parser_ingress; + std::map parser_egress; + ::Tofino::regs_all_parse_merge parser_merge; + }; + struct parser_regs : public ParserRegisterSet { + typedef ::Tofino::memories_all_parser_ _memory; + typedef ::Tofino::regs_all_parser_ingress _ingress; + typedef ::Tofino::regs_all_parser_egress _egress; + typedef ::Tofino::regs_all_parse_merge _merge; + + ::Tofino::memories_all_parser_ memory[2]; + ::Tofino::regs_all_parser_ingress ingress; + ::Tofino::regs_all_parser_egress egress; + ::Tofino::regs_all_parse_merge merge; + }; + + typedef ::Tofino::regs_match_action_stage_ mau_regs; + struct deparser_regs { + typedef ::Tofino::regs_all_deparser_input_phase _input; + typedef ::Tofino::regs_all_deparser_header_phase _header; + + ::Tofino::regs_all_deparser_input_phase input; + ::Tofino::regs_all_deparser_header_phase header; + }; + enum { + ARAM_UNITS_PER_STAGE = 0, + PARSER_CHECKSUM_UNITS = 2, + PARSER_EXTRACT_BYTES = false, + PARSER_DEPTH_MAX_BYTES_INGRESS = (((1 << 10) - 1) * 16), + PARSER_DEPTH_MAX_BYTES_EGRESS = (((1 << 10) - 1) * 16), + PARSER_DEPTH_MAX_BYTES_MULTITHREADED_EGRESS = 160, + PARSER_DEPTH_MIN_BYTES_INGRESS = 0, + PARSER_DEPTH_MIN_BYTES_EGRESS = 65, + MATCH_BYTE_16BIT_PAIRS = true, + MATCH_REQUIRES_PHYSID = false, + MAX_IMMED_ACTION_DATA = 32, + MAX_OVERHEAD_OFFSET = 64, + MAX_OVERHEAD_OFFSET_NEXT = 40, + NUM_MAU_STAGES_PRIVATE = 12, + NUM_EGRESS_STAGES_PRIVATE = NUM_MAU_STAGES_PRIVATE, + ACTION_INSTRUCTION_MAP_WIDTH = 7, + DEPARSER_CHECKSUM_UNITS = 6, + DEPARSER_CONSTANTS = 0, + DEPARSER_MAX_POV_BYTES = 32, + DEPARSER_MAX_POV_PER_USE = 1, + DEPARSER_MAX_FD_ENTRIES = 192, + DP_UNITS_PER_STAGE = 0, + DYNAMIC_CONFIG = 0, + DYNAMIC_CONFIG_INPUT_BITS = 0, + EGRESS_SEPARATE = false, + END_OF_PIPE = 0xff, + EXACT_HASH_GROUPS = 8, + EXACT_HASH_TABLES = 16, + EXTEND_ALU_8_SLOTS = 0, + EXTEND_ALU_16_SLOTS = 0, + EXTEND_ALU_32_SLOTS = 0, + GATEWAY_INHIBIT_INDEX = false, + GATEWAY_MATCH_BITS = 56, // includes extra expansion for range match + GATEWAY_NEEDS_SEARCH_BUS = true, + GATEWAY_PAYLOAD_GROUPS = 1, + GATEWAY_ROWS = 8, + GATEWAY_SINGLE_XBAR_GROUP = true, + SUPPORT_TRUE_EOP = 0, + INSTR_SRC2_BITS = 4, + IMEM_COLORS = 2, + IXBAR_HASH_GROUPS = 8, + IXBAR_HASH_INDEX_MAX = 40, + IXBAR_HASH_INDEX_STRIDE = 10, + LOCAL_TIND_UNITS = 0, + LONG_BRANCH_TAGS = 0, + MAU_BASE_DELAY = 20, + MAU_BASE_PREDICATION_DELAY = 11, + MAU_ERROR_DELAY_ADJUST = 2, + METER_ALU_GROUP_DATA_DELAY = 13, + // To avoid under run scenarios, there is a minimum egress pipeline latency required + MINIMUM_REQUIRED_EGRESS_PIPELINE_LATENCY = 160, + NEXT_TABLE_EXEC_COMBINED = false, // no next_exec on tofino1 at all + NEXT_TABLE_SUCCESSOR_TABLE_DEPTH = 8, + PHASE0_FORMAT_WIDTH = 64, + REQUIRE_TCAM_ID = false, // miss-only tables do not need a tcam id + SRAM_EGRESS_ROWS = 8, + SRAM_GLOBAL_ACCESS = false, + SRAM_HBUS_SECTIONS_PER_STAGE = 0, + SRAM_HBUSSES_PER_ROW = 0, + SRAM_INGRESS_ROWS = 8, + SRAM_LAMBS_PER_STAGE = 0, + SRAM_LOGICAL_UNITS_PER_ROW = 6, + SRAM_REMOVED_COLUMNS = 2, + SRAM_STRIDE_COLUMN = 1, + SRAM_STRIDE_ROW = 12, + SRAM_STRIDE_STAGE = 0, + SRAM_UNITS_PER_ROW = 12, + STATEFUL_CMP_UNITS = 2, + STATEFUL_CMP_ADDR_WIDTH = 2, + STATEFUL_CMP_CONST_WIDTH = 4, + STATEFUL_CMP_CONST_MASK = 0xf, + STATEFUL_CMP_CONST_MIN = -8, + STATEFUL_CMP_CONST_MAX = 7, + STATEFUL_TMATCH_UNITS = 0, + STATEFUL_OUTPUT_UNITS = 1, + STATEFUL_PRED_MASK = (1U << (1 << STATEFUL_CMP_UNITS)) - 1, + STATEFUL_REGFILE_ROWS = 4, + STATEFUL_REGFILE_CONST_WIDTH = 32, + SUPPORT_ALWAYS_RUN = 0, + HAS_MPR = 0, + SUPPORT_CONCURRENT_STAGE_DEP = 1, + SUPPORT_OVERFLOW_BUS = 1, + SUPPORT_SALU_FAST_CLEAR = 0, + STATEFUL_ALU_ADDR_WIDTH = 2, + STATEFUL_ALU_CONST_WIDTH = 4, + STATEFUL_ALU_CONST_MASK = 0xf, + STATEFUL_ALU_CONST_MIN = -8, // TODO Is the same as the following one? + STATEFUL_ALU_CONST_MAX = 7, + MINIMUM_INSTR_CONSTANT = -8, // TODO + NUM_PARSERS = 18, + NUM_PIPES = 4, + OUTPUT_STAGE_EXTENSION_PRIVATE = 0, + SYNTH2PORT_NEED_MAPRAMS = true, + TCAM_EXTRA_NIBBLE = true, + TCAM_GLOBAL_ACCESS = false, + TCAM_MATCH_BUSSES = 2, + TCAM_MEMORY_FULL_WIDTH = 47, + TCAM_ROWS = 12, + TCAM_UNITS_PER_ROW = 2, + TCAM_XBAR_GROUPS = 12, + TABLES_REQUIRE_ROW = 1, + }; + static int encodeConst(int src) { return (src >> 10 << 15) | (0x8 << 10) | (src & 0x3ff); } + TARGET_SPECIFIC_CLASSES + REGISTER_SET_SPECIFIC_CLASSES + TARGET_CLASS_SPECIFIC_CLASSES +}; + +void declare_registers(const Target::Tofino::top_level_regs *regs); +void undeclare_registers(const Target::Tofino::top_level_regs *regs); +void declare_registers(const Target::Tofino::parser_regs *regs); +void undeclare_registers(const Target::Tofino::parser_regs *regs); +void declare_registers(const Target::Tofino::mau_regs *regs, bool ignore, int stage); +void declare_registers(const Target::Tofino::deparser_regs *regs); +void undeclare_registers(const Target::Tofino::deparser_regs *regs); +void emit_parser_registers(const Target::Tofino::top_level_regs *regs, std::ostream &); + +#if HAVE_JBAY +#include "gen/jbay/memories.jbay_mem.h" +#include "gen/jbay/memories.pipe_addrmap.h" +#include "gen/jbay/memories.prsr_mem_main_rspec.h" +#include "gen/jbay/regs.dprsr_reg.h" +#include "gen/jbay/regs.epb_prsr4_reg.h" +#include "gen/jbay/regs.ipb_prsr4_reg.h" +#include "gen/jbay/regs.jbay_reg.h" +#include "gen/jbay/regs.mau_addrmap.h" +#include "gen/jbay/regs.pipe_addrmap.h" +#include "gen/jbay/regs.pmerge_reg.h" +#include "gen/jbay/regs.prsr_reg_main_rspec.h" + +class Target::JBay : public Target { + public: + static constexpr const char *const name = "tofino2"; + static constexpr target_t tag = JBAY; + static constexpr target_t register_set = JBAY; + typedef Target::JBay target_type; + typedef Target::JBay register_type; + class Phv; + struct top_level_regs { + typedef ::JBay::memories_top _mem_top; + typedef ::JBay::memories_pipe _mem_pipe; + typedef ::JBay::regs_top _regs_top; + typedef ::JBay::regs_pipe _regs_pipe; + + ::JBay::memories_top mem_top; + ::JBay::memories_pipe mem_pipe; + ::JBay::regs_top reg_top; + ::JBay::regs_pipe reg_pipe; + + // map from handle to parser regs + std::map parser_memory[2]; + std::map parser_ingress; + std::map parser_egress; + std::map parser_main[2]; + ::JBay::regs_parse_merge parser_merge; + }; + struct parser_regs : public ParserRegisterSet { + typedef ::JBay::memories_parser_ _memory; + typedef ::JBay::regs_parser_ingress _ingress; // [9] + typedef ::JBay::regs_parser_egress _egress; // [9] + typedef ::JBay::regs_parser_main_ _main; // [9] + typedef ::JBay::regs_parse_merge _merge; // [1] + + ::JBay::memories_parser_ memory[2]; + ::JBay::regs_parser_ingress ingress; + ::JBay::regs_parser_egress egress; + ::JBay::regs_parser_main_ main[2]; + ::JBay::regs_parse_merge merge; + }; + + typedef ::JBay::regs_match_action_stage_ mau_regs; + typedef ::JBay::regs_deparser deparser_regs; + enum { + ARAM_UNITS_PER_STAGE = 0, + PARSER_CHECKSUM_UNITS = 5, + PARSER_EXTRACT_BYTES = true, + PARSER_DEPTH_MAX_BYTES_INGRESS = (((1 << 10) - 1) * 16), + PARSER_DEPTH_MAX_BYTES_EGRESS = (32 * 16), + PARSER_DEPTH_MAX_BYTES_MULTITHREADED_EGRESS = (32 * 16), + PARSER_DEPTH_MIN_BYTES_INGRESS = 0, + PARSER_DEPTH_MIN_BYTES_EGRESS = 0, + MATCH_BYTE_16BIT_PAIRS = false, + MATCH_REQUIRES_PHYSID = false, + MAX_IMMED_ACTION_DATA = 32, + MAX_OVERHEAD_OFFSET = 64, + MAX_OVERHEAD_OFFSET_NEXT = 40, +#ifdef EMU_OVERRIDE_STAGE_COUNT + NUM_MAU_STAGES_PRIVATE = EMU_OVERRIDE_STAGE_COUNT, + OUTPUT_STAGE_EXTENSION_PRIVATE = 1, +#else + NUM_MAU_STAGES_PRIVATE = 20, + OUTPUT_STAGE_EXTENSION_PRIVATE = 0, +#endif + NUM_EGRESS_STAGES_PRIVATE = NUM_MAU_STAGES_PRIVATE, + ACTION_INSTRUCTION_MAP_WIDTH = 8, + DEPARSER_CHECKSUM_UNITS = 8, + DEPARSER_CONSTANTS = 8, + DEPARSER_MAX_POV_BYTES = 16, + DEPARSER_MAX_POV_PER_USE = 1, + DEPARSER_CHUNKS_PER_GROUP = 8, + DEPARSER_CHUNK_SIZE = 8, + DEPARSER_CHUNK_GROUPS = 16, + DEPARSER_CLOTS_PER_GROUP = 4, + DEPARSER_TOTAL_CHUNKS = DEPARSER_CHUNK_GROUPS * DEPARSER_CHUNKS_PER_GROUP, + DEPARSER_MAX_FD_ENTRIES = DEPARSER_TOTAL_CHUNKS, + DP_UNITS_PER_STAGE = 0, + DYNAMIC_CONFIG = 0, + DYNAMIC_CONFIG_INPUT_BITS = 0, + EGRESS_SEPARATE = false, + END_OF_PIPE = 0x1ff, + EXACT_HASH_GROUPS = 8, + EXACT_HASH_TABLES = 16, + EXTEND_ALU_8_SLOTS = 0, + EXTEND_ALU_16_SLOTS = 0, + EXTEND_ALU_32_SLOTS = 0, + GATEWAY_INHIBIT_INDEX = false, + GATEWAY_MATCH_BITS = 56, // includes extra expansion for range match + GATEWAY_NEEDS_SEARCH_BUS = true, + GATEWAY_PAYLOAD_GROUPS = 5, + GATEWAY_ROWS = 8, + GATEWAY_SINGLE_XBAR_GROUP = true, + SUPPORT_TRUE_EOP = 1, + INSTR_SRC2_BITS = 5, + IMEM_COLORS = 2, + IXBAR_HASH_GROUPS = 8, + IXBAR_HASH_INDEX_MAX = 40, + IXBAR_HASH_INDEX_STRIDE = 10, + LOCAL_TIND_UNITS = 0, + LONG_BRANCH_TAGS = 8, + MAU_BASE_DELAY = 23, + MAU_BASE_PREDICATION_DELAY = 13, + MAU_ERROR_DELAY_ADJUST = 3, + METER_ALU_GROUP_DATA_DELAY = 15, + NEXT_TABLE_EXEC_COMBINED = true, + NEXT_TABLE_SUCCESSOR_TABLE_DEPTH = 8, + PHASE0_FORMAT_WIDTH = 128, + REQUIRE_TCAM_ID = false, // miss-only tables do not need a tcam id + SRAM_EGRESS_ROWS = 8, + SRAM_GLOBAL_ACCESS = false, + SRAM_HBUS_SECTIONS_PER_STAGE = 0, + SRAM_HBUSSES_PER_ROW = 0, + SRAM_INGRESS_ROWS = 8, + SRAM_LAMBS_PER_STAGE = 0, + SRAM_LOGICAL_UNITS_PER_ROW = 6, + SRAM_REMOVED_COLUMNS = 2, + SRAM_STRIDE_COLUMN = 1, + SRAM_STRIDE_ROW = 12, + SRAM_STRIDE_STAGE = 0, + SRAM_UNITS_PER_ROW = 12, + STATEFUL_CMP_UNITS = 4, + STATEFUL_CMP_ADDR_WIDTH = 2, + STATEFUL_CMP_CONST_WIDTH = 6, + STATEFUL_CMP_CONST_MASK = 0x3f, + STATEFUL_CMP_CONST_MIN = -32, + STATEFUL_CMP_CONST_MAX = 31, + STATEFUL_TMATCH_UNITS = 2, + STATEFUL_OUTPUT_UNITS = 4, + STATEFUL_PRED_MASK = (1U << (1 << STATEFUL_CMP_UNITS)) - 1, + STATEFUL_REGFILE_ROWS = 4, + STATEFUL_REGFILE_CONST_WIDTH = 34, + SUPPORT_ALWAYS_RUN = 1, + HAS_MPR = 1, + SUPPORT_CONCURRENT_STAGE_DEP = 0, + SUPPORT_OVERFLOW_BUS = 0, + SUPPORT_SALU_FAST_CLEAR = 1, + STATEFUL_ALU_ADDR_WIDTH = 2, + STATEFUL_ALU_CONST_WIDTH = 4, + STATEFUL_ALU_CONST_MASK = 0xf, + STATEFUL_ALU_CONST_MIN = -8, // TODO Is the same as the following one? + STATEFUL_ALU_CONST_MAX = 7, + MINIMUM_INSTR_CONSTANT = -4, // TODO + NUM_PARSERS = 36, + NUM_PIPES = 4, + TABLES_REQUIRE_ROW = 1, + SYNTH2PORT_NEED_MAPRAMS = true, + TCAM_EXTRA_NIBBLE = true, + TCAM_GLOBAL_ACCESS = false, + TCAM_MATCH_BUSSES = 2, + TCAM_MEMORY_FULL_WIDTH = 47, + TCAM_ROWS = 12, + TCAM_UNITS_PER_ROW = 2, + TCAM_XBAR_GROUPS = 12, + }; + static int encodeConst(int src) { return (src >> 11 << 16) | (0x8 << 11) | (src & 0x7ff); } + TARGET_SPECIFIC_CLASSES + REGISTER_SET_SPECIFIC_CLASSES +}; +void declare_registers(const Target::JBay::top_level_regs *regs); +void undeclare_registers(const Target::JBay::top_level_regs *regs); +void declare_registers(const Target::JBay::parser_regs *regs); +void undeclare_registers(const Target::JBay::parser_regs *regs); +void declare_registers(const Target::JBay::mau_regs *regs, bool ignore, int stage); +void declare_registers(const Target::JBay::deparser_regs *regs); + +class Target::Tofino2H : public Target::JBay { + public: + static constexpr const char *const name = "tofino2h"; + static constexpr target_t tag = TOFINO2H; + typedef Target::Tofino2H target_type; + class Phv; + enum { + NUM_MAU_STAGES_PRIVATE = 6, + NUM_EGRESS_STAGES_PRIVATE = NUM_MAU_STAGES_PRIVATE, + OUTPUT_STAGE_EXTENSION_PRIVATE = 1, + }; + TARGET_SPECIFIC_CLASSES +}; + +class Target::Tofino2M : public Target::JBay { + public: + static constexpr const char *const name = "tofino2m"; + static constexpr target_t tag = TOFINO2M; + typedef Target::Tofino2M target_type; + class Phv; + enum { + NUM_MAU_STAGES_PRIVATE = 12, + NUM_EGRESS_STAGES_PRIVATE = NUM_MAU_STAGES_PRIVATE, + OUTPUT_STAGE_EXTENSION_PRIVATE = 1, + }; + TARGET_SPECIFIC_CLASSES +}; + +class Target::Tofino2U : public Target::JBay { + public: + static constexpr const char *const name = "tofino2u"; + static constexpr target_t tag = TOFINO2U; + typedef Target::Tofino2U target_type; + class Phv; + enum { + NUM_MAU_STAGES_PRIVATE = 20, + NUM_EGRESS_STAGES_PRIVATE = NUM_MAU_STAGES_PRIVATE, + }; + TARGET_SPECIFIC_CLASSES +}; + +class Target::Tofino2A0 : public Target::JBay { + public: + static constexpr const char *const name = "tofino2a0"; + static constexpr target_t tag = TOFINO2A0; + typedef Target::Tofino2A0 target_type; + class Phv; + enum { + NUM_MAU_STAGES_PRIVATE = 20, + NUM_EGRESS_STAGES_PRIVATE = NUM_MAU_STAGES_PRIVATE, + }; + TARGET_SPECIFIC_CLASSES +}; + +void emit_parser_registers(const Target::JBay::top_level_regs *regs, std::ostream &); + +#endif /* HAVE_JBAY */ + +/** Macro to buid a switch table switching on a target_t, expanding to the same + * code for each target, with TARGET being a typedef for the target type */ +#define SWITCH_FOREACH_TARGET(VAR, ...) \ + switch (VAR) { \ + FOR_ALL_TARGETS(DO_SWITCH_FOREACH_TARGET, __VA_ARGS__) \ + default: \ + BUG("invalid target"); \ + } + +#define DO_SWITCH_FOREACH_TARGET(TARGET_, ...) \ + case Target::TARGET_::tag: { \ + typedef Target::TARGET_ TARGET; \ + __VA_ARGS__ \ + break; \ + } + +#define SWITCH_FOREACH_REGISTER_SET(VAR, ...) \ + switch (VAR) { \ + FOR_ALL_REGISTER_SETS(DO_SWITCH_FOREACH_REGISTER_SET, __VA_ARGS__) \ + default: \ + BUG("invalid target"); \ + } + +#define DO_SWITCH_FOREACH_REGISTER_SET(REGS_, ...) \ + TARGETS_USING_REGS(REGS_, CASE_FOR_TARGET) { \ + typedef Target::REGS_ TARGET; \ + __VA_ARGS__ \ + break; \ + } + +#define SWITCH_FOREACH_TARGET_CLASS(VAR, ...) \ + switch (VAR) { \ + FOR_ALL_TARGET_CLASSES(DO_SWITCH_FOREACH_TARGET_CLASS, __VA_ARGS__) \ + default: \ + BUG("invalid target"); \ + } + +#define DO_SWITCH_FOREACH_TARGET_CLASS(CLASS_, ...) \ + TARGETS_IN_CLASS(CLASS_, CASE_FOR_TARGET) { \ + typedef Target::CLASS_ TARGET; \ + __VA_ARGS__ \ + break; \ + } + +#define CASE_FOR_TARGET(TARGET) case Target::TARGET::tag: + +/* macro to define a function that overloads over a GROUP of types -- will declare all the + * functions that overload on a Target::type argument and a 'generic' overload that calls + * the right specific overload based on options.target + * GROUP can be one of + * TARGET -- overload on all the different targets + * REGISTER_SET -- overload just on the register sets (targets that share a register + * set will only have one overload) + * TARGET_CLASS -- overload based on the CLASS + * RTYPE NAME ARGDECL together make the declaration of the (generic) function, the overloads + * will all have a Target::type argument prepended. The final ARGS argument is the argument + * list that that will be forwarded (basically ARGDECL without the types) + */ +#define DECL_OVERLOAD_FUNC(TARGET, RTYPE, NAME, ARGDECL, ARGS) \ + RTYPE NAME(Target::TARGET EXPAND_COMMA_CLOSE ARGDECL; +#define OVERLOAD_FUNC_FOREACH(GROUP, RTYPE, NAME, ARGDECL, ARGS, ...) \ + FOR_EACH_##GROUP(DECL_OVERLOAD_FUNC, RTYPE, NAME, ARGDECL, ARGS) \ + RTYPE NAME ARGDECL __VA_ARGS__ { \ + SWITCH_FOREACH_##GROUP(options.target, return NAME(TARGET() EXPAND_COMMA ARGS);) \ + } + +#endif /* TARGET_H_ */ diff --git a/backends/tofino/bf-asm/ternary_match.cpp b/backends/tofino/bf-asm/ternary_match.cpp new file mode 100644 index 00000000000..c13fcab80f1 --- /dev/null +++ b/backends/tofino/bf-asm/ternary_match.cpp @@ -0,0 +1,1223 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "tofino/ternary_match.h" + +#include "action_bus.h" +#include "algorithm.h" +#include "input_xbar.h" +#include "instruction.h" +#include "misc.h" +#include "range.h" +#include "stage.h" +#include "tables.h" + +Table::Format::Field *TernaryMatchTable::lookup_field(const std::string &n, + const std::string &act) const { + auto *rv = format ? format->field(n) : nullptr; + if (!rv && gateway) rv = gateway->lookup_field(n, act); + if (!rv && indirect) rv = indirect->lookup_field(n, act); + if (!rv && !act.empty()) { + if (auto call = get_action()) { + rv = call->lookup_field(n, act); + } + } + return rv; +} + +Table::Format::Field *TernaryIndirectTable::lookup_field(const std::string &n, + const std::string &act) const { + auto *rv = format ? format->field(n) : nullptr; + if (!rv && !act.empty()) { + if (auto call = get_action()) rv = call->lookup_field(n, act); + } + return rv; +} + +void TernaryMatchTable::vpn_params(int &width, int &depth, int &period, + const char *&period_name) const { + if ((width = match.size()) == 0) { + BUG_CHECK(input_xbar.size() == 1, "%s does not have one input xbar", name()); + width = input_xbar[0]->tcam_width(); + } + depth = width ? layout_size() / width : 0; + period = 1; + period_name = 0; +} + +void TernaryMatchTable::alloc_vpns() { + if (no_vpns || layout.size() == 0 || layout[0].vpns.size() > 0) return; + int period, width, depth; + const char *period_name; + vpn_params(width, depth, period, period_name); + if (width == 0) return; + std::vector rows; + std::set> stage_cols; + for (auto &r : layout) { + for (auto &mem : r.memunits) stage_cols.emplace(mem.stage, mem.col); + rows.push_back(&r); + r.vpns.resize(r.memunits.size()); + } + std::sort(rows.begin(), rows.end(), + [](Layout *const &a, Layout *const &b) -> bool { return a->row < b->row; }); + int vpn = 0; + for (auto [stage, col] : stage_cols) { + for (auto *r : rows) { + unsigned idx = find(r->memunits, MemUnit(stage, r->row, col)) - r->memunits.begin(); + if (idx < r->vpns.size()) r->vpns[idx] = vpn++ / width; + } + if (vpn % width != 0) + error(layout[0].lineno, + "%d-wide ternary match must use a multiple of %d tcams " + "in each column", + width, width); + } +} + +TernaryMatchTable::Match::Match(const value_t &v) : lineno(v.lineno) { + if (v.type == tVEC) { + if (v.vec.size < 2 || v.vec.size > 3) { + error(v.lineno, "Syntax error"); + return; + } + if (!CHECKTYPE(v[0], tINT) || !CHECKTYPE(v[v.vec.size - 1], tINT)) return; + if ((word_group = v[0].i) < 0 || v[0].i >= Target::TCAM_XBAR_GROUPS()) + error(v[0].lineno, "Invalid input xbar group %" PRId64, v[0].i); + if (Target::TCAM_EXTRA_NIBBLE() && v.vec.size == 3 && CHECKTYPE(v[1], tINT)) { + if ((byte_group = v[1].i) < 0 || v[1].i >= Target::TCAM_XBAR_GROUPS() / 2) + error(v[1].lineno, "Invalid input xbar group %" PRId64, v[1].i); + } else { + byte_group = -1; + } + if ((byte_config = v[v.vec.size - 1].i) < 0 || byte_config >= 4) + error(v[v.vec.size - 1].lineno, "Invalid input xbar byte control %d", byte_config); + } else if (CHECKTYPE(v, tMAP)) { + for (auto &kv : MapIterChecked(v.map)) { + if (kv.key == "group") { + if (kv.value.type != tINT || kv.value.i < 0 || + kv.value.i >= Target::TCAM_XBAR_GROUPS()) + error(kv.value.lineno, "Invalid input xbar group %s", value_desc(kv.value)); + else + word_group = kv.value.i; + } else if (Target::TCAM_EXTRA_NIBBLE() && kv.key == "byte_group") { + if (kv.value.type != tINT || kv.value.i < 0 || + kv.value.i >= Target::TCAM_XBAR_GROUPS() / 2) + error(kv.value.lineno, "Invalid input xbar group %s", value_desc(kv.value)); + else + byte_group = kv.value.i; + } else if (Target::TCAM_EXTRA_NIBBLE() && kv.key == "byte_config") { + if (kv.value.type != tINT || kv.value.i < 0 || kv.value.i >= 4) + error(kv.value.lineno, "Invalid byte group config %s", value_desc(kv.value)); + else + byte_config = kv.value.i; + } else if (kv.key == "dirtcam") { + if (kv.value.type != tINT || kv.value.i < 0 || kv.value.i > 0xfff) + error(kv.value.lineno, "Invalid dirtcam mode %s", value_desc(kv.value)); + else + dirtcam = kv.value.i; + } else { + error(kv.key.lineno, "Unknown key '%s' in ternary match spec", value_desc(kv.key)); + } + } + } +} + +void TernaryMatchTable::setup(VECTOR(pair_t) & data) { + tcam_id = -1; + indirect_bus = -1; + common_init_setup(data, true, P4Table::MatchEntry); + if (input_xbar.empty()) input_xbar.emplace_back(InputXbar::create(this)); + if (auto *m = get(data, "match")) { + if (CHECKTYPE2(*m, tVEC, tMAP)) { + if (m->type == tVEC) + for (auto &v : m->vec) match.emplace_back(v); + else + match.emplace_back(*m); + } + } + for (auto &kv : MapIterChecked(data, {"meter", "stats", "stateful"})) { + if (common_setup(kv, data, P4Table::MatchEntry)) { + } else if (kv.key == "match") { + /* done above to be done before vpns */ + } else if (kv.key == "indirect") { + setup_indirect(kv.value); + } else if (kv.key == "indirect_bus") { + if (CHECKTYPE(kv.value, tINT)) { + if (kv.value.i < 0 || kv.value.i >= 16) { + error(kv.value.lineno, "Invalid ternary indirect bus number"); + } else { + indirect_bus = kv.value.i; + if (auto *old = + stage->tcam_indirect_bus_use[indirect_bus / 2][indirect_bus & 1]) + error(kv.value.lineno, "Indirect bus %d already in use by table %s", + indirect_bus, old->name()); + } + } + } else if (kv.key == "tcam_id") { + if (CHECKTYPE(kv.value, tINT)) { + if ((tcam_id = kv.value.i) < 0 || tcam_id >= TCAM_TABLES_PER_STAGE) + error(kv.key.lineno, "Invalid tcam_id %d", tcam_id); + else if (stage->tcam_id_use[tcam_id]) + error(kv.key.lineno, "Tcam id %d already in use by table %s", tcam_id, + stage->tcam_id_use[tcam_id]->name()); + else + stage->tcam_id_use[tcam_id] = this; + physical_ids[tcam_id] = 1; + } + } else { + warning(kv.key.lineno, "ignoring unknown item %s in table %s", value_desc(kv.key), + name()); + } + } + if (Target::TCAM_GLOBAL_ACCESS()) + alloc_global_tcams(); + else + alloc_rams(false, stage->tcam_use, &stage->tcam_match_bus_use); + check_tcam_match_bus(layout); + if (indirect_bus >= 0) { + stage->tcam_indirect_bus_use[indirect_bus / 2][indirect_bus & 1] = this; + } + if (indirect.set()) { + if (indirect_bus >= 0) + error(lineno, "Table %s has both ternary indirect table and explicit indirect bus", + name()); + if (!attached.stats.empty() || !attached.meters.empty() || !attached.statefuls.empty()) + error(lineno, + "Table %s has ternary indirect table and directly attached stats/meters" + " -- move them to indirect table", + name()); + } else if (!action.set() && !actions) { + error(lineno, "Table %s has no indirect, action table or immediate actions", name()); + } + if (action && !action_bus) action_bus = ActionBus::create(); +} + +bitvec TernaryMatchTable::compute_reachable_tables() { + MatchTable::compute_reachable_tables(); + if (indirect) reachable_tables_ |= indirect->reachable_tables(); + return reachable_tables_; +} + +void TernaryMatchTable::pass0() { + MatchTable::pass0(); + if (indirect.check() && indirect->set_match_table(this, false) != TERNARY_INDIRECT) + error(indirect.lineno, "%s is not a ternary indirect table", indirect->name()); +} + +void TernaryMatchTable::pass1() { + LOG1("### Ternary match table " << name() << " pass1 " << loc()); + if (action_bus) action_bus->pass1(this); + MatchTable::pass1(); + stage->table_use[timing_thread(gress)] |= Stage::USE_TCAM; + if (layout_size() == 0) layout.clear(); + BUG_CHECK(input_xbar.size() == 1, "%s does not have one input xbar", name()); + if (match.empty() && input_xbar[0]->tcam_width() && layout.size() != 0) { + match.resize(input_xbar[0]->tcam_width()); + for (unsigned i = 0; i < match.size(); i++) { + match[i].word_group = input_xbar[0]->tcam_word_group(i); + match[i].byte_group = input_xbar[0]->tcam_byte_group(i / 2); + match[i].byte_config = i & 1; + } + match.back().byte_config = 3; + } + if (match.size() == 0) { + if (layout.size() != 0) + error(layout[0].lineno, "No match or input_xbar in non-empty ternary table %s", name()); + } else if (layout.size() % match.size() != 0) { + error(layout[0].lineno, "Rows not a multiple of the match width in tables %s", name()); + } else if (layout.size() == 0) { + error(lineno, "Empty ternary table with non-empty match"); + } else { + auto mg = match.begin(); + for (auto &row : layout) { + if (!row.bus.count(Layout::SEARCH_BUS)) + row.bus[Layout::SEARCH_BUS] = row.memunits.at(0).col; + auto bus = row.bus.at(Layout::SEARCH_BUS); + if (mg->byte_group >= 0) { + auto &bg_use = stage->tcam_byte_group_use[row.row / 2][bus]; + if (bg_use.first) { + if (bg_use.second != mg->byte_group) { + error(mg->lineno, + "Conflicting tcam byte group between rows %d and %d " + "in col %d for table %s", + row.row, row.row ^ 1, bus, name()); + if (bg_use.first != this) + error(bg_use.first->lineno, "...also used in table %s", + bg_use.first->name()); + } + } else { + bg_use.first = this; + bg_use.second = mg->byte_group; + } + } + if (++mg == match.end()) mg = match.begin(); + } + } + if (error_count > 0) return; + for (auto &chain_rows_col : chain_rows) chain_rows_col = 0; + unsigned row_use = 0; + for (auto &row : layout) row_use |= 1U << row.row; + unsigned word = 0, wide_row_use = 0; + int prev_row = -1; + std::vector *memunits = nullptr; + for (auto &row : layout) { + if (row.memunits.empty()) { + error(row.lineno, "Empty row in ternary table %s", name()); + continue; + } + if (memunits) { + if (row.memunits.size() != memunits->size()) + error(row.lineno, "Column mismatch across rows in wide tcam match"); + for (size_t i = 0; i < row.memunits.size(); ++i) + if (row.memunits[i].stage != memunits->at(i).stage || + row.memunits[i].col != memunits->at(i).col) + error(row.lineno, "Column mismatch across rows in wide tcam match"); + } else { + memunits = &row.memunits; + } + wide_row_use |= 1U << row.row; + if (++word == match.size()) { + int top_row = floor_log2(wide_row_use); + int bottom_row = top_row + 1 - match.size(); + if (wide_row_use + (1U << bottom_row) != 1U << (top_row + 1)) { + error(row.lineno, + "Ternary match rows must be contiguous " + "within each group of rows in a wide match"); + } else { + // rows chain towards row 6 + if (top_row < 6) + wide_row_use -= 1U << top_row; + else if (bottom_row > 6) + wide_row_use -= 1U << bottom_row; + else + wide_row_use -= 1U << 6; + for (auto &memunit : *memunits) { + int col = memunit.col; + if (col < 0 || col >= TCAM_UNITS_PER_ROW) + error(row.lineno, "Invalid column %d in table %s", col, name()); + else + chain_rows[col] |= wide_row_use; + } + } + word = 0; + memunits = nullptr; + wide_row_use = 0; + } + } + if (indirect) { + if (hit_next.size() > 0 && indirect->hit_next.size() > 0) + error(lineno, "Ternary Match table with both direct and indirect next tables"); + if (!indirect->p4_table) indirect->p4_table = p4_table; + if (hit_next.size() > 1 || indirect->hit_next.size() > 1) { + if (auto *next = indirect->format->field("next")) { + if (next->bit(0) != 0) + error(indirect->format->lineno, + "ternary indirect 'next' field must be" + " at bit 0"); + } else if (auto *action = indirect->format->field("action")) { + if (action->bit(0) != 0) + error(indirect->format->lineno, + "ternary indirect 'action' field must be" + " at bit 0 to be used as next table selector"); + } else { + error(indirect->format->lineno, "No 'next' or 'action' field in format"); + } + } + if (format) + error(format->lineno, + "Format unexpected in Ternary Match table %s with separate " + "Indirect table %s", + name(), indirect->name()); + } else if (format) { + format->pass1(this); + } + attached.pass1(this); + if (hit_next.size() > 2 && !indirect) + error(lineno, "Ternary Match tables cannot directly specify more than 2 hit next tables"); +} + +void TernaryMatchTable::pass2() { + LOG1("### Ternary match table " << name() << " pass2 " << loc()); + if (logical_id < 0) choose_logical_id(); + for (auto &ixb : input_xbar) ixb->pass2(); + if (!indirect && indirect_bus < 0) { + for (int i = 0; i < 16; i++) + if (!stage->tcam_indirect_bus_use[i / 2][i & 1]) { + indirect_bus = i; + stage->tcam_indirect_bus_use[i / 2][i & 1] = this; + break; + } + if (indirect_bus < 0) + error(lineno, "No ternary indirect bus available for table %s", name()); + } + if (actions) actions->pass2(this); + if (action_bus) action_bus->pass2(this); + if (gateway) gateway->pass2(); + if (idletime) idletime->pass2(); + if (is_alpm()) { + if (auto *acts = get_actions()) { + for (auto act = acts->begin(); act != acts->end(); act++) { + set_partition_action_handle(act->handle); + if (act->p4_params_list.size() > 0) { + // assume first parameter is partition_field_name + set_partition_field_name(act->p4_params_list[0].name); + } + } + } + } + for (auto &hd : hash_dist) hd.pass2(this); +} + +void TernaryMatchTable::pass3() { + LOG1("### Ternary match table " << name() << " pass3 " << loc()); + MatchTable::pass3(); + if (action_bus) action_bus->pass3(this); +} + +extern int get_address_mau_actiondata_adr_default(unsigned log2size, bool per_flow_enable); + +template +inline static void tcam_ghost_enable(REGS ®s, int row, int col) { + regs.tcams.col[col].tcam_ghost_thread_en[row] = 1; +} +template <> +void tcam_ghost_enable(Target::Tofino::mau_regs ®s, int row, int col) {} + +template +void TernaryMatchTable::tcam_table_map(REGS ®s, int row, int col) { + if (tcam_id >= 0) { + if (!((chain_rows[col] >> row) & 1)) + regs.tcams.col[col].tcam_table_map[tcam_id] |= 1U << row; + } +} + +static void set_tcam_mode_logical_table(ubits<4> ®, int tcam_id, int logical_id) { + reg = logical_id; +} +static void set_tcam_mode_logical_table(ubits<8> ®, int tcam_id, int logical_id) { + reg |= 1U << tcam_id; +} + +template +void TernaryMatchTable::write_regs_vt(REGS ®s) { + LOG1("### Ternary match table " << name() << " write_regs " << loc()); + MatchTable::write_regs(regs, 1, indirect); + unsigned word = 0; + auto &merge = regs.rams.match.merge; + for (Layout &row : layout) { + auto vpn = row.vpns.begin(); + for (const auto &tcam : row.memunits) { + BUG_CHECK(tcam.stage == INT_MIN && tcam.row == row.row, "bogus tcam %s in row %d", + tcam.desc(), row.row); + auto &tcam_mode = regs.tcams.col[tcam.col].tcam_mode[row.row]; + // tcam_mode.tcam_data1_select = row.bus; -- no longer used + if (options.match_compiler) tcam_mode.tcam_data1_select = tcam.col; + tcam_mode.tcam_chain_out_enable = (chain_rows[tcam.col] >> row.row) & 1; + if (gress == INGRESS) + tcam_mode.tcam_ingress = 1; + else if (gress == EGRESS) + tcam_mode.tcam_egress = 1; + else if (gress == GHOST) + tcam_ghost_enable(regs, row.row, tcam.col); + tcam_mode.tcam_match_output_enable = + ((~chain_rows[tcam.col] | ALWAYS_ENABLE_ROW) >> row.row) & 1; + tcam_mode.tcam_vpn = *vpn++; + set_tcam_mode_logical_table(tcam_mode.tcam_logical_table, tcam_id, logical_id); + tcam_mode.tcam_data_dirtcam_mode = match[word].dirtcam & 0x3ff; + tcam_mode.tcam_vbit_dirtcam_mode = match[word].dirtcam >> 10; + /* TODO -- always disable tcam_validbit_xbar? */ + auto &tcam_vh_xbar = regs.tcams.vh_data_xbar; + if (options.match_compiler) { + for (int i = 0; i < 8; i++) + tcam_vh_xbar.tcam_validbit_xbar_ctl[tcam.col][row.row / 2][i] |= 15; + } + auto &halfbyte_mux_ctl = tcam_vh_xbar.tcam_row_halfbyte_mux_ctl[tcam.col][row.row]; + halfbyte_mux_ctl.tcam_row_halfbyte_mux_ctl_select = match[word].byte_config; + halfbyte_mux_ctl.tcam_row_halfbyte_mux_ctl_enable = 1; + halfbyte_mux_ctl.tcam_row_search_thread = timing_thread(gress); + if (match[word].word_group >= 0) + setup_muxctl(tcam_vh_xbar.tcam_row_output_ctl[tcam.col][row.row], + match[word].word_group); + if (match[word].byte_group >= 0) + setup_muxctl(tcam_vh_xbar.tcam_extra_byte_ctl[tcam.col][row.row / 2], + match[word].byte_group); + tcam_table_map(regs, row.row, tcam.col); + } + if (++word == match.size()) word = 0; + } + if (tcam_id >= 0) + setup_muxctl(merge.tcam_hit_to_logical_table_ixbar_outputmap[tcam_id], logical_id); + if (tcam_id >= 0) { + if (stage->table_use[timing_thread(gress)] & Stage::USE_TCAM) + merge.tcam_table_prop[tcam_id].tcam_piped = 1; + merge.tcam_table_prop[tcam_id].thread = timing_thread(gress); + merge.tcam_table_prop[tcam_id].enabled = 1; + regs.tcams.tcam_output_table_thread[tcam_id] = 1 << timing_thread(gress); + } + if (indirect_bus >= 0) { + /* FIXME -- factor into corresponding code in MatchTable::write_regs */ + setup_muxctl(merge.match_to_logical_table_ixbar_outputmap[1][indirect_bus], logical_id); + setup_muxctl(merge.match_to_logical_table_ixbar_outputmap[3][indirect_bus], logical_id); + if (tcam_id >= 0) { + setup_muxctl(merge.tcam_match_adr_to_physical_oxbar_outputmap[indirect_bus], tcam_id); + } + if (action) { + /* FIXME -- factor with TernaryIndirect code below */ + if (auto adt = action->to()) { + merge.mau_actiondata_adr_default[1][indirect_bus] = adt->determine_default(action); + merge.mau_actiondata_adr_mask[1][indirect_bus] = adt->determine_mask(action); + merge.mau_actiondata_adr_vpn_shiftcount[1][indirect_bus] = + adt->determine_vpn_shiftcount(action); + merge.mau_actiondata_adr_tcam_shiftcount[indirect_bus] = + adt->determine_shiftcount(action, 0, 0, 0); + } + } + attached.write_tcam_merge_regs(regs, this, indirect_bus, 0); + merge.tind_bus_prop[indirect_bus].tcam_piped = 1; + merge.tind_bus_prop[indirect_bus].thread = timing_thread(gress); + merge.tind_bus_prop[indirect_bus].enabled = 1; + if (idletime) + merge.mau_idletime_adr_tcam_shiftcount[indirect_bus] = idletime->direct_shiftcount(); + } + if (actions) actions->write_regs(regs, this); + if (gateway) gateway->write_regs(regs); + if (idletime) idletime->write_regs(regs); + for (auto &hd : hash_dist) hd.write_regs(regs, this); + merge.exact_match_logical_result_delay |= 1 << logical_id; + regs.cfg_regs.mau_cfg_movereg_tcam_only |= 1U << logical_id; + + // FIXME -- this is wrong; when should we use the actionbit? glass never does any more? + // if (hit_next.size() > 1 && !indirect) + // merge.next_table_tcam_actionbit_map_en |= 1 << logical_id; + // if (!indirect) + // merge.mau_action_instruction_adr_tcam_actionbit_map_en |= 1 << logical_id; +} + +std::unique_ptr TernaryMatchTable::gen_memory_resource_allocation_tbl_cfg( + const char *type, const std::vector &layout, bool skip_spare_bank) const { + if (layout.size() == 0) return nullptr; + BUG_CHECK(!skip_spare_bank); // never spares in tcam + json::map mra{{"memory_type", json::string(type)}}; + json::vector &mem_units_and_vpns = mra["memory_units_and_vpns"]; + json::vector mem_units; + unsigned word = 0; + bool done = false; + unsigned lrow = 0; + for (auto colnum = 0U; !done; colnum++) { + done = true; + for (auto &row : layout) { + if (colnum >= row.memunits.size()) continue; + auto mu = row.memunits[colnum]; + auto vpn = row.vpns[colnum]; + mem_units.push_back(json_memunit(mu)); + lrow = json_memunit(mu); + if (++word == match.size()) { + mem_units_and_vpns.push_back(json::map{{"memory_units", std::move(mem_units)}, + {"vpns", json::vector{json::number(vpn)}}}); + mem_units = json::vector(); + word = 0; + } + done = false; + } + } + // For keyless table, add empty vectors + if (mem_units_and_vpns.size() == 0) + mem_units_and_vpns.push_back( + json::map{{"memory_units", json::vector()}, {"vpns", json::vector()}}); + mra["spare_bank_memory_unit"] = lrow; + return json::mkuniq(std::move(mra)); +} + +void TernaryMatchTable::gen_entry_cfg2(json::vector &out, std::string field_name, + std::string global_name, unsigned lsb_offset, + unsigned lsb_idx, unsigned msb_idx, std::string source, + unsigned start_bit, unsigned field_width, + bitvec &tcam_bits) const { + json::map entry; + entry["field_name"] = field_name; + entry["global_name"] = global_name; + entry["lsb_mem_word_offset"] = lsb_offset; + entry["lsb_mem_word_idx"] = lsb_idx; + entry["msb_mem_word_idx"] = msb_idx; + entry["source"] = source; + entry["start_bit"] = start_bit; + entry["field_width"] = field_width; + out.push_back(std::move(entry)); + // For a range with field width < nibble width, mark the entire + // nibble in tcam_bits as used. The driver expects no overlap with other + // format entries with the unused bits in the nibble. + int tcam_bit_width = source == "range" ? 4 : field_width; + tcam_bits.setrange(lsb_offset, tcam_bit_width); +} + +void TernaryMatchTable::gen_entry_range_cfg(json::map &entry, bool duplicate, + unsigned nibble_offset) const { + json::map &entry_range = entry["range"]; + entry_range["type"] = 4; + entry_range["is_duplicate"] = duplicate; + entry_range["nibble_offset"] = nibble_offset; +} + +void TernaryMatchTable::gen_entry_cfg(json::vector &out, std::string name, unsigned lsb_offset, + unsigned lsb_idx, unsigned msb_idx, std::string source, + unsigned start_bit, unsigned field_width, unsigned index, + bitvec &tcam_bits, unsigned nibble_offset = 0) const { + LOG3("Adding entry to Ternary Table : name: " + << name << " lsb_offset: " << lsb_offset << " lsb_idx: " << lsb_idx + << " msb_idx: " << msb_idx << " source: " << source << " start_bit: " << start_bit + << " field_width: " << field_width << " index: " << index << " tcam_bits: " << tcam_bits + << " nibble_offset: " << nibble_offset); + std::string field_name(name); + + // If the name has a slice in it, remove it and add the lo bit of + // the slice to field_bit. This takes the place of + // canon_field_list(), rather than extracting the slice component + // of the field name, if present, and appending it to the key name. + int slice_offset = remove_name_tail_range(field_name); + LOG4(" Field Name: " << field_name << " slice_offset: " << slice_offset); + + // Get the key name, if any. + int param_start_bit = slice_offset + start_bit; + auto params = find_p4_params(field_name, "", param_start_bit, field_width); + std::string global_name = ""; + if (params.size() == 0) { + gen_entry_cfg2(out, field_name, global_name, lsb_offset, lsb_idx, msb_idx, source, + param_start_bit, field_width, tcam_bits); + } else { + for (auto param : params) { + if (!param) continue; + if (!param->key_name.empty()) { + LOG4(" Found param : " << *param); + field_name = param->key_name; + global_name = param->name; + } + // For multiple params concatenated within the field width, we only + // chose the param width which represents the slice. + field_width = std::min(param->bit_width, field_width); + + // For range match we need bytes to decide which nibble is being used, hence + // split the field in bytes. For normal match entire slice can be used + // directly. + auto *p = find_p4_param(name, "range", param_start_bit, field_width); + if (p) { + int lsb_lo = lsb_offset - TCAM_MATCH_BITS_START; + int lsb_hi = lsb_lo + field_width - 1; + /** + * For each byte of range match, the range match happens over either the lower + * nibble or higher nibble given the encoding scheme. The nibble is transformed + * into an encoding over a byte. This breaks up the range over each match nibble on + * a byte by byte boundary, and outputs the JSON for that nibble + * + * @seealso bf-p4c/mau/table_format.cpp comments on range + * @seealso bf-p4c/mau/resource_estimate.cpp comments on range + * + * The range context JSON encoding is the following: + * - The lsb_mem_word_offset is always the beginning of the byte (as the + * encoding takes the whole byte) + * - The width is the width of the field in the nibble (up to 4 bits) + * - The nibble_offset is where in the nibble the key starts in the ixbar byte + * + * A "is_duplicate" nibble is provided.The driver uses this for not double counting, + * maybe. Henry and I both agree that is really doesn't make any sense and can be + * deleted, but remains in there now + */ + for (int bit = (lsb_lo / 8) * 8; bit <= (lsb_hi / 8) * 8; bit += 8) { + int lsb_lo_bit_in_byte = std::max(lsb_lo, bit) % 8; + int lsb_hi_bit_in_byte = std::min(lsb_hi, bit + 7) % 8; + auto dirtcam_mode = get_dirtcam_mode(index, (bit / 8)); + + if (!(DIRTCAM_4B_LO == dirtcam_mode || DIRTCAM_4B_HI == dirtcam_mode)) continue; + + bitvec nibbles_of_range; + nibbles_of_range.setbit(lsb_lo_bit_in_byte / 4); + nibbles_of_range.setbit(lsb_hi_bit_in_byte / 4); + int range_start_bit = start_bit + slice_offset; + int range_width; + int nibble_offset; + + // Determine which section of the byte based on which nibble is provided + if (dirtcam_mode == DIRTCAM_4B_LO) { + BUG_CHECK(nibbles_of_range.getbit(0)); + // Add the difference from the first bit of this byte and the lowest bit + range_start_bit += bit + lsb_lo_bit_in_byte - lsb_lo; + range_width = + std::min(static_cast(field_width), 4 - lsb_lo_bit_in_byte); + range_width = std::min(static_cast(range_width), lsb_hi - bit + 1); + nibble_offset = lsb_lo_bit_in_byte % 4; + } else { + BUG_CHECK(nibbles_of_range.getbit(1)); + // Because the bit starts at the upper nibble, the start bit is either the + // beginning of the nibble or more + range_start_bit += bit + std::max(4, lsb_lo_bit_in_byte) - lsb_lo; + range_width = + std::min(static_cast(field_width), lsb_hi_bit_in_byte - 3); + range_width = std::min(static_cast(range_width), + lsb_hi_bit_in_byte - lsb_lo_bit_in_byte + 1); + nibble_offset = std::max(4, lsb_lo_bit_in_byte) % 4; + } + + // Add the range entry + gen_entry_cfg2(out, field_name, global_name, bit + TCAM_MATCH_BITS_START, + lsb_idx, msb_idx, "range", range_start_bit, range_width, + tcam_bits); + auto &last_entry = out.back()->to(); + gen_entry_range_cfg(last_entry, false, nibble_offset); + + // Adding the duplicate range entry + gen_entry_cfg2(out, field_name, global_name, bit + TCAM_MATCH_BITS_START + 4, + lsb_idx, msb_idx, "range", range_start_bit, range_width, + tcam_bits); + auto &last_entry_dup = out.back()->to(); + gen_entry_range_cfg(last_entry_dup, true, nibble_offset); + } + + } else { + gen_entry_cfg2(out, field_name, global_name, lsb_offset, lsb_idx, msb_idx, source, + param_start_bit, field_width, tcam_bits); + } + param_start_bit += field_width; + } + } +} + +void TernaryMatchTable::gen_match_fields_pvp(json::vector &match_field_list, unsigned word, + bool uses_versioning, unsigned version_word_group, + bitvec &tcam_bits) const { + // Tcam bits are arranged as follows in each tcam word + // LSB -------------------------------------MSB + // PAYLOAD BIT - TCAM BITS - [VERSION] - PARITY + auto start_bit = 0; // always 0 for fields not on input xbar + auto dirtcam_index = 0; // not relevant for fields not on input xbar + auto payload_name = "--tcam_payload_" + std::to_string(word) + "--"; + auto parity_name = "--tcam_parity_" + std::to_string(word) + "--"; + auto version_name = "--version--"; + gen_entry_cfg(match_field_list, payload_name, TCAM_PAYLOAD_BITS_START, word, word, "payload", + start_bit, TCAM_PAYLOAD_BITS, dirtcam_index, tcam_bits); + if (uses_versioning && (version_word_group == word)) { + gen_entry_cfg(match_field_list, version_name, TCAM_VERSION_BITS_START, word, word, + "version", start_bit, TCAM_VERSION_BITS, dirtcam_index, tcam_bits); + } + gen_entry_cfg(match_field_list, parity_name, TCAM_PARITY_BITS_START, word, word, "parity", + start_bit, TCAM_PARITY_BITS, dirtcam_index, tcam_bits); +} + +void TernaryMatchTable::gen_match_fields(json::vector &match_field_list, + std::vector &tcam_bits) const { + unsigned match_index = match.size() - 1; + for (auto &ixb : input_xbar) { + for (const auto &[field_group, field_phv] : *ixb) { + switch (field_group.type) { + case InputXbar::Group::EXACT: + continue; + case InputXbar::Group::TERNARY: { + int word = match_index - match_word(field_group.index); + if (word < 0) continue; + std::string source = "spec"; + std::string field_name = field_phv.what.name(); + unsigned lsb_mem_word_offset = 0; + if (field_phv.hi > 40) { + // FIXME -- no longer needed if we always convert these to Group::BYTE? + // a field in the (mid) byte group, which is shared with the adjacent word + // group each word gets only 4 bits of the byte group and is placed at msb + // Check mid-byte field does not cross byte boundary (40-47) + BUG_CHECK(field_phv.hi < 48); + // Check mid-byte field is associated with even group + // | == 5 == | == 1 == | == 5 == | == 5 == | == 1 == | == 5 == | + // | Grp 0 | Midbyte0| Grp 1 | Grp 2 | Midbyte1| Grp 3 | + BUG_CHECK((field_group.index & 1) == 0); + // Find groups to place this byte nibble. Check group which has this + // group as the byte_group + for (auto &m : match) { + if (m.byte_group * 2 == field_group.index) { + // Check byte_config to determine where to place the nibble + lsb_mem_word_offset = 1 + field_phv.lo; + int nibble_offset = 0; + int hwidth = 44 - field_phv.lo; + int start_bit = 0; + if (m.byte_config == MIDBYTE_NIBBLE_HI) { + nibble_offset += 4; + start_bit = hwidth; + hwidth = field_phv.hi - 43; + } + int midbyte_word_group = match_index - match_word(m.word_group); + gen_entry_cfg(match_field_list, field_name, lsb_mem_word_offset, + midbyte_word_group, midbyte_word_group, source, + field_phv.what.lobit() + start_bit, hwidth, + field_group.index, tcam_bits[midbyte_word_group]); + } + } + } else { + lsb_mem_word_offset = 1 + field_phv.lo; + gen_entry_cfg(match_field_list, field_name, lsb_mem_word_offset, word, word, + source, field_phv.what.lobit(), + field_phv.hi - field_phv.lo + 1, field_group.index, + tcam_bits[word], field_phv.what->lo % 4); + } + break; + } + case InputXbar::Group::BYTE: + // The byte group represents what goes in top nibble in the tcam + // word. Based on the byte config, the corresponding match word is + // selected and the field (slice) is placed in the nibble. + // byte group 5: { 0: HillTop.Lamona.Whitefish(0..1) , + // 2: HillTop.RossFork.Adona(0..5) } + // match: + // - { group: 10, byte_group: 5, byte_config: 0, dirtcam: 0x555 } + // - { group: 11, byte_group: 5, byte_config: 1, dirtcam: 0x555 } + // Placement + // -------------------------- + // Group 10 - Midbyte Nibble Lo + // -------------------------- + // Word 1 : 41 42 43 44 + // Whitefish : 0 1 X X + // Adona : X X 0 1 + // -------------------------- + // Group 11 - Midbyte Nibble Hi + // -------------------------- + // Word 0 : 41 42 43 44 + // Whitefish : X X X X + // Adona : 2 3 4 5 + // -------------------------- + for (size_t word = 0; word < match.size(); word++) { + if (match[word].byte_group != field_group.index) continue; + auto source = "spec"; + auto field_name = field_phv.what.name(); + int byte_lo = field_phv.lo; + int field_lo = field_phv.what.lobit(); + int width = field_phv.what.size(); + int nibble_lo = byte_lo; + if (match[word].byte_config == MIDBYTE_NIBBLE_HI) { + if (byte_lo >= 4) { + // NIBBLE HI | NIBBLE LO + // 7 6 5 4 | 3 2 1 0 + // x x x | + // byte_lo = 5 (start of byte) + nibble_lo = byte_lo - 4; // Get nibble_lo from nibble boundary + // nibble_lo = 1 + } else { + // NIBBLE HI | NIBBLE LO + // 7 6 5 4 | 3 2 1 0 + // x x | x x + // say field f1(3..7) + // field_lo = 3 + // byte_lo = 2 (start of byte) + // width = 4 + width -= 4 - byte_lo; // Adjust width to what must + // fit in the nibble + if (width <= 0) continue; // No field in nibble, skip + // width = 2 + nibble_lo = 0; // Field starts at nibble boundary + field_lo += 4 - byte_lo; // Adjust field lo bit to start of nibble + // field_lo = 5 + } + } else if (match[word].byte_config == MIDBYTE_NIBBLE_LO) { + if (byte_lo >= 4) { + // NIBBLE HI | NIBBLE LO + // 7 6 5 4 | 3 2 1 0 + // x x x | + // byte_lo = 5 (start of byte) + continue; // No field in nibble, skip + } else { + // NIBBLE HI | NIBBLE LO + // 7 6 5 4 | 3 2 1 0 + // x x x | x x + // byte_lo = 2 (start of byte) + // width = 5 + nibble_lo = byte_lo; + int nibble_left = 4 - nibble_lo; + width = (width > nibble_left) ? nibble_left : width; + // width = 2 + } + } + gen_entry_cfg(match_field_list, field_name, 41 + nibble_lo, + match_index - word, match_index - word, source, field_lo, + width, match[word].byte_group, tcam_bits[match_index - word]); + } + break; + } + } + } +} + +json::map &TernaryMatchTable::get_tbl_top(json::vector &out) const { + unsigned number_entries = match.size() ? layout_size() / match.size() * 512 : 0; + // For ALPM tables, this sets up the top level ALPM table and this ternary + // table as its preclassifier. As the pre_classifier is always in the + // previous stage as the atcams, this function will be called before the + // atcam cfg generation. The atcam will check for presence of this table and + // add the atcam cfg gen + if (is_alpm()) { + json::map *alpm_ptr = base_tbl_cfg(out, "match_entry", number_entries); + json::map &alpm = *alpm_ptr; + json::map &match_attributes = alpm["match_attributes"]; + match_attributes["match_type"] = "algorithmic_lpm"; + json::map &alpm_pre_classifier = match_attributes["pre_classifier"]; + base_alpm_pre_classifier_tbl_cfg(alpm_pre_classifier, "match_entry", number_entries); + // top level alpm table has the same key as alpm preclassifier + add_match_key_cfg(alpm); + return alpm_pre_classifier; + } else { + return *base_tbl_cfg(out, "match_entry", number_entries); + } +} + +void TernaryMatchTable::gen_tbl_cfg(json::vector &out) const { + unsigned number_entries = match.size() ? layout_size() / match.size() * 512 : 0; + json::map &tbl = get_tbl_top(out); + bool uses_versioning = false; + unsigned version_word_group = -1; + unsigned match_index = match.size() - 1; + unsigned index = 0; + json::vector match_field_list; + for (auto &m : match) { + if (m.byte_config == 3) { + uses_versioning = true; + version_word_group = match_index - index; + break; + } + index++; + } + // Determine the zero padding necessary by creating a bitvector (for each + // word). While creating entries for pack format set bits used. The unused + // bits must be padded with zero field entries. + std::vector tcam_bits(match.size()); + // Set pvp bits for each tcam word + for (unsigned i = 0; i < match.size(); i++) { + gen_match_fields_pvp(match_field_list, i, uses_versioning, version_word_group, + tcam_bits[i]); + } + json::map &match_attributes = tbl["match_attributes"]; + json::vector &stage_tables = match_attributes["stage_tables"]; + json::map &stage_tbl = *add_stage_tbl_cfg(match_attributes, "ternary_match", number_entries); + // This is a only a glass required field, as it is only required when no default action + // is specified, which is impossible for Brig through p4-16 + stage_tbl["default_next_table"] = Stage::end_of_pipe(); + json::map &pack_fmt = + add_pack_format(stage_tbl, Target::TCAM_MEMORY_FULL_WIDTH(), match.size(), 1); + stage_tbl["memory_resource_allocation"] = + gen_memory_resource_allocation_tbl_cfg("tcam", layout); + // FIXME-JSON: If the next table is modifiable then we set it to what it's mapped + // to. Otherwise, set it to the default next table for this stage. + // stage_tbl["default_next_table"] = Target::END_OF_PIPE(); + // FIXME: How to deal with multiple next hit tables? + stage_tbl["default_next_table"] = + hit_next.size() > 0 ? hit_next[0].next_table_id() : Target::END_OF_PIPE(); + add_result_physical_buses(stage_tbl); + gen_match_fields(match_field_list, tcam_bits); + + // For keyless table, just add parity & payload bits + if (p4_params_list.empty()) { + tcam_bits.resize(1); + gen_match_fields_pvp(match_field_list, 0, false, -1, tcam_bits[0]); + } + + // tcam_bits is a vector indexed by tcam word and has all used bits set. We + // loop through this bitvec for each word and add a zero padding entry for + // the unused bits. + // For ternary all unused bits must be marked as source + // 'zero' for correctness during entry encoding. + for (unsigned word = 0; word < match.size(); word++) { + bitvec &pb = tcam_bits[word]; + unsigned start_bit = 0; // always 0 for padded fields + int dirtcam_index = -1; // irrelevant in this context + if (pb != bitvec(0)) { + int idx_lo = 0; + std::string pad_name = "--unused--"; + for (auto p : pb) { + if (p > idx_lo) { + gen_entry_cfg(match_field_list, pad_name, idx_lo, word, word, "zero", start_bit, + p - idx_lo, dirtcam_index, tcam_bits[word]); + } + idx_lo = p + 1; + } + auto fw = TCAM_VERSION_BITS; + if (idx_lo < fw) { + gen_entry_cfg(match_field_list, pad_name, idx_lo, word, word, "zero", start_bit, + fw - idx_lo, dirtcam_index, tcam_bits[word]); + } + } + } + + pack_fmt["entries"] = json::vector{ + json::map{{"entry_number", json::number(0)}, {"fields", std::move(match_field_list)}}}; + add_all_reference_tables(tbl); + json::map &tind = stage_tbl["ternary_indirection_stage_table"] = json::map(); + if (indirect) { + unsigned fmt_width = 1U << indirect->format->log2size; + // json::map tind; + tind["stage_number"] = stage->stageno; + tind["stage_table_type"] = "ternary_indirection"; + tind["size"] = indirect->layout_size() * 128 / fmt_width * 1024; + indirect->add_pack_format(tind, indirect->format.get()); + tind["memory_resource_allocation"] = + indirect->gen_memory_resource_allocation_tbl_cfg("sram", indirect->layout); + // Add action formats for actions present in table or attached action table + auto *acts = indirect->get_actions(); + if (acts) acts->add_action_format(this, tind); + add_all_reference_tables(tbl, indirect); + if (indirect->actions) + indirect->actions->gen_tbl_cfg(tbl["actions"]); + else if (indirect->action && indirect->action->actions) + indirect->action->actions->gen_tbl_cfg(tbl["actions"]); + indirect->common_tbl_cfg(tbl); + } else { + // FIXME: Add a fake ternary indirect table (as otherwise driver complains) + // if tind not present - to be removed with update on driver side + auto *acts = get_actions(); + if (acts) acts->add_action_format(this, tind); + tind["memory_resource_allocation"] = nullptr; + json::vector &pack_format = tind["pack_format"] = json::vector(); + json::map pack_format_entry; + pack_format_entry["memory_word_width"] = 128; + pack_format_entry["entries_per_table_word"] = 1; + json::vector &entries = pack_format_entry["entries"] = json::vector(); + entries.push_back(json::map{{"entry_number", json::number(0)}, {"fields", json::vector()}}); + pack_format_entry["table_word_width"] = 0; + pack_format_entry["number_memory_units_per_table_word"] = 0; + pack_format.push_back(std::move(pack_format_entry)); + tind["logical_table_id"] = logical_id; + tind["stage_number"] = stage->stageno; + tind["stage_table_type"] = "ternary_indirection"; + tind["size"] = 0; + } + common_tbl_cfg(tbl); + if (actions) + actions->gen_tbl_cfg(tbl["actions"]); + else if (action && action->actions) + action->actions->gen_tbl_cfg(tbl["actions"]); + gen_idletime_tbl_cfg(stage_tbl); + merge_context_json(tbl, stage_tbl); + match_attributes["match_type"] = "ternary"; +} + +void TernaryIndirectTable::setup(VECTOR(pair_t) & data) { + match_table = 0; + common_init_setup(data, true, P4Table::MatchEntry); + if (format) { + if (format->size > 64) error(format->lineno, "ternary indirect format larger than 64 bits"); + if (format->size < 4) { + /* pad out to minumum size */ + format->size = 4; + format->log2size = 2; + } + } else { + error(lineno, "No format specified in table %s", name()); + } + for (auto &kv : MapIterChecked(data, {"meter", "stats", "stateful"})) { + if (common_setup(kv, data, P4Table::MatchEntry)) { + } else if (kv.key == "input_xbar") { + if (CHECKTYPE(kv.value, tMAP)) + input_xbar.emplace_back(InputXbar::create(this, false, kv.key, kv.value.map)); + } else if (kv.key == "hash_dist") { + /* parsed in common_init_setup */ + } else if (kv.key == "selector") { + attached.selector.setup(kv.value, this); + } else if (kv.key == "selector_length") { + attached.selector_length.setup(kv.value, this); + } else if (kv.key == "meter_color") { + attached.meter_color.setup(kv.value, this); + } else if (kv.key == "stats") { + if (kv.value.type == tVEC) + for (auto &v : kv.value.vec) attached.stats.emplace_back(v, this); + else + attached.stats.emplace_back(kv.value, this); + } else if (kv.key == "meter") { + if (kv.value.type == tVEC) + for (auto &v : kv.value.vec) attached.meters.emplace_back(v, this); + else + attached.meters.emplace_back(kv.value, this); + } else if (kv.key == "stateful") { + if (kv.value.type == tVEC) + for (auto &v : kv.value.vec) attached.statefuls.emplace_back(v, this); + else + attached.statefuls.emplace_back(kv.value, this); + } else { + warning(kv.key.lineno, "ignoring unknown item %s in table %s", value_desc(kv.key), + name()); + } + } + if (Target::SRAM_GLOBAL_ACCESS()) + alloc_global_srams(); + else + alloc_rams(false, stage->sram_use, &stage->tcam_indirect_bus_use, Layout::TIND_BUS); + if (!action.set() && !actions) + error(lineno, "Table %s has neither action table nor immediate actions", name()); + if (actions && !action_bus) action_bus = ActionBus::create(); +} + +Table::table_type_t TernaryIndirectTable::set_match_table(MatchTable *m, bool indirect) { + if (match_table) { + error(lineno, "Multiple references to ternary indirect table %s", name()); + } else if (!(match_table = dynamic_cast(m))) { + error(lineno, "Trying to link ternary indirect table %s to non-ternary table %s", name(), + m->name()); + } else { + if (action.check() && action->set_match_table(m, !action.is_direct_call()) != ACTION) + error(action.lineno, "%s is not an action table", action->name()); + attached.pass0(m); + logical_id = m->logical_id; + p4_table = m->p4_table; + } + return TERNARY_INDIRECT; +} + +bitvec TernaryIndirectTable::compute_reachable_tables() { + Table::compute_reachable_tables(); + if (match_table) reachable_tables_ |= match_table->reachable_tables(); + reachable_tables_ |= attached.compute_reachable_tables(); + return reachable_tables_; +} + +void TernaryIndirectTable::pass1() { + LOG1("### Ternary indirect table " << name() << " pass1"); + determine_word_and_result_bus(); + Table::pass1(); + if (action_enable >= 0) + if (action.args.size() < 1 || action.args[0].size() <= (unsigned)action_enable) + error(lineno, "Action enable bit %d out of range for action selector", action_enable); + if (format) format->pass1(this); + for (auto &hd : hash_dist) { + hd.pass1(this, HashDistribution::OTHER, false); + } +} + +/** + * The bus by definition for ternary indirect is the result bus, and all TernaryIndirect tables + * are at most 64 bits, meaning that all their words are equal to 0. + */ +void TernaryIndirectTable::determine_word_and_result_bus() { + for (auto &row : layout) { + row.word = 0; + } +} + +void TernaryIndirectTable::pass2() { + LOG1("### Ternary indirect table " << name() << " pass2"); + if (logical_id < 0 && match_table) logical_id = match_table->logical_id; + if (!match_table) error(lineno, "No match table for ternary indirect table %s", name()); + if (actions) actions->pass2(this); + if (action_bus) action_bus->pass2(this); + if (format) format->pass2(this); +} + +void TernaryIndirectTable::pass3() { + LOG1("### Ternary indirect table " << name() << " pass3"); + if (action_bus) action_bus->pass3(this); +} + +template +void TernaryIndirectTable::write_regs_vt(REGS ®s) { + LOG1("### Ternary indirect table " << name() << " write_regs"); + int tcam_id = match_table->tcam_id; + int tcam_shift = format->log2size - 2; + if (tcam_id >= 0) regs.tcams.tcam_match_adr_shift[tcam_id] = tcam_shift; + auto &merge = regs.rams.match.merge; + for (Layout &row : layout) { + int bus = row.bus.at(Layout::TIND_BUS); + auto vpn = row.vpns.begin(); + auto &ram_row = regs.rams.array.row[row.row]; + for (auto &memunit : row.memunits) { + int col = memunit.col; + BUG_CHECK(memunit.stage == INT_MIN && memunit.row == row.row, "bogus %s in row %d", + memunit.desc(), row.row); + auto &unit_ram_ctl = ram_row.ram[col].unit_ram_ctl; + unit_ram_ctl.match_ram_write_data_mux_select = 7; /* disable */ + unit_ram_ctl.match_ram_read_data_mux_select = 7; /* disable */ + unit_ram_ctl.tind_result_bus_select = 1U << bus; + auto &mux_ctl = + regs.rams.map_alu.row[row.row].adrmux.ram_address_mux_ctl[col / 6][col % 6]; + mux_ctl.ram_unitram_adr_mux_select = bus + 2; + auto &unitram_config = + regs.rams.map_alu.row[row.row].adrmux.unitram_config[col / 6][col % 6]; + unitram_config.unitram_type = 6; + unitram_config.unitram_vpn = *vpn++; + unitram_config.unitram_logical_table = logical_id; + if (gress == INGRESS || gress == GHOST) + unitram_config.unitram_ingress = 1; + else + unitram_config.unitram_egress = 1; + unitram_config.unitram_enable = 1; + auto &xbar_ctl = + regs.rams.map_alu.row[row.row].vh_xbars.adr_dist_tind_adr_xbar_ctl[bus]; + if (tcam_id >= 0) setup_muxctl(xbar_ctl, tcam_id); + if (gress == EGRESS) + regs.cfg_regs.mau_cfg_uram_thread[col / 4U] |= 1U << (col % 4U * 8U + row.row); + ram_row.tind_ecc_error_uram_ctl[timing_thread(gress)] |= 1 << (col - 2); + } + int r_bus = row.row * 2 + bus; + merge.tind_ram_data_size[r_bus] = format->log2size - 1; + if (tcam_id >= 0) + setup_muxctl(merge.tcam_match_adr_to_physical_oxbar_outputmap[r_bus], tcam_id); + merge.tind_bus_prop[r_bus].tcam_piped = 1; + merge.tind_bus_prop[r_bus].thread = timing_thread(gress); + merge.tind_bus_prop[r_bus].enabled = 1; + if (instruction) { + int shiftcount = 0; + if (auto field = instruction.args[0].field()) + shiftcount = field->bit(0); + else if (auto field = instruction.args[1].field()) + shiftcount = field->immed_bit(0); + merge.mau_action_instruction_adr_tcam_shiftcount[r_bus] = shiftcount; + } + if (format->immed) merge.mau_immediate_data_tcam_shiftcount[r_bus] = format->immed->bit(0); + if (action) { + if (auto adt = action->to()) { + merge.mau_actiondata_adr_default[1][r_bus] = adt->determine_default(action); + merge.mau_actiondata_adr_mask[1][r_bus] = adt->determine_mask(action); + merge.mau_actiondata_adr_vpn_shiftcount[1][r_bus] = + adt->determine_vpn_shiftcount(action); + merge.mau_actiondata_adr_tcam_shiftcount[r_bus] = + adt->determine_shiftcount(action, 0, 0, tcam_shift); + } + } + if (attached.selector) { + auto sel = get_selector(); + merge.mau_meter_adr_tcam_shiftcount[r_bus] = + sel->determine_shiftcount(attached.selector, 0, 0, format->log2size - 2); + merge.mau_selectorlength_shiftcount[1][r_bus] = + sel->determine_length_shiftcount(attached.selector_length, 0, 0); + merge.mau_selectorlength_mask[1][r_bus] = + sel->determine_length_mask(attached.selector_length); + merge.mau_selectorlength_default[1][r_bus] = + sel->determine_length_default(attached.selector_length); + } + if (match_table->idletime) + merge.mau_idletime_adr_tcam_shiftcount[r_bus] = + 66 + format->log2size - match_table->idletime->precision_shift(); + attached.write_tcam_merge_regs(regs, match_table, r_bus, tcam_shift); + } + if (actions) actions->write_regs(regs, this); + for (auto &hd : hash_dist) hd.write_regs(regs, this); +} + +void TernaryIndirectTable::gen_tbl_cfg(json::vector &out) const {} + +void TernaryMatchTable::add_result_physical_buses(json::map &stage_tbl) const { + json::vector &result_physical_buses = stage_tbl["result_physical_buses"] = json::vector(); + if (indirect) { + for (auto l : indirect->layout) { + if (l.bus.count(Layout::TIND_BUS)) { + result_physical_buses.push_back(l.row * 2 + l.bus.at(Layout::TIND_BUS)); + } + } + } else { + result_physical_buses.push_back(indirect_bus); + } +} + +DEFINE_TABLE_TYPE_WITH_SPECIALIZATION(TernaryMatchTable, TARGET_CLASS) +DEFINE_TABLE_TYPE_WITH_SPECIALIZATION(TernaryIndirectTable, TARGET_CLASS) diff --git a/backends/tofino/bf-asm/test/CMakeLists.txt b/backends/tofino/bf-asm/test/CMakeLists.txt new file mode 100644 index 00000000000..0e0df7246b9 --- /dev/null +++ b/backends/tofino/bf-asm/test/CMakeLists.txt @@ -0,0 +1,112 @@ +####### Tofino assembler -- tests +cmake_minimum_required (VERSION 3.16.3 FATAL_ERROR) + +project (BFASM_TEST) + +set (CMAKE_MODULE_PATH ${BFN_P4C_SOURCE_DIR}/p4c/cmake) + +MESSAGE("-- Adding bf-asm test suite") + +# common test utils +#include(../../p4-tests/TestUtils.cmake) + +if (ENABLE_TEST_ISOLATION) + get_filename_component(P4C_RUNTEST ../../p4-tests/internal/runtest-isolated REALPATH) +else() + get_filename_component(P4C_RUNTEST ../../p4-tests/runtest REALPATH) +endif() + + +# extra test args can be passed as unamed arguments +function(bfas_add_test_with_args device toolsdevice alias bfafile test_args cmake_args) + # create the test + MESSAGE("Invoking: p4c_add_test_with_args (${device} ${P4C_RUNTEST} FALSE ${alias} ${bfafile} \"${test_args}\" \"-${device} ${cmake_args}\")") + MESSAGE("#macro(p4c_add_test_with_args tag driver isXfail alias p4test test_args cmake_args)") + #macro(p4c_add_test_with_args tag driver isXfail alias p4test test_args cmake_args) + p4c_add_test_with_args (${device} ${P4C_RUNTEST} FALSE ${alias} + ${bfafile} "${test_args}" "-${device} ${cmake_args}") + if (PTF_REQUIREMENTS_MET) + set(__havePTF 0) + string (REGEX REPLACE ".bfa$" ".stf" __stffile ${bfafile}) + if (ENABLE_STF2PTF AND NOT ${__havePTF} AND EXISTS ${BFASM_TEST_SOURCE_DIR}/${__stffile}) + # Also add as PTF test the STF + # MESSAGE(STATUS "STF2PTF: Generating ${P4C_BINARY_DIR}/${device}/${__ptffile}/test.py") + set(__havePTF 1) + endif() + if (${__havePTF}) + p4c_test_set_name(__testname ${device} ${alias}) + set_ptf_test_locks(${__testname}) + p4c_add_test_label(${device} "ptf" ${alias}) + endif() + endif() # PTF_REQUIREMENTS_MET + if (HARLYN_STF_${toolsdevice}) + string (REGEX REPLACE ".bfa$" ".stf" __stffile ${bfafile}) + if (EXISTS ${BFASM_TEST_SOURCE_DIR}/${__stffile}) + p4c_add_test_label(${device} "stf" ${alias}) + endif() + endif(HARLYN_STF_${toolsdevice}) +endfunction(bfas_add_test_with_args) + +# extra test args can be passed as unamed arguments +#macro(p4c_add_bf_backend_tests device toolsdevice arch label tests) +#endmacro(p4c_add_bf_backend_tests) +macro(bfas_add_tests device toolsdevice arch label tests) + set (_testExtraArgs "${ARGN}") + # do not add the device directly to _testExtraArgs + # this is used later to add other tests for multiple configurations. + # set (_testExtraArgs "${_testExtraArgs} -${device}") + + # if STF is not found, disable all stf tests + if (NOT HARLYN_STF_${toolsdevice}) + set (_testExtraArgs "${_testExtraArgs} -norun") + endif() + + if (PTF_REQUIREMENTS_MET) + set (_testExtraArgs "${_testExtraArgs} -ptf") + if (ENABLE_STF2PTF) + if ( "${device}" STREQUAL "tofino") + set (_testExtraArgs "${_testExtraArgs} -stf2ptf") + endif() + endif() + endif() + + # If label is not empty, add it to the tests + foreach (ts "${tests}") + MESSAGE("Processing ${ts}") + file (GLOB __testfiles RELATIVE ${BFASM_SOURCE_DIR} ${ts}) + foreach (__p4file ${__testfiles}) + bfas_add_backend_test_and_label(${device} ${toolsdevice} ${__p4file} ${__p4file} "${label}" + "${_testExtraArgs}" "") + endforeach() # __p4file + endforeach() +endmacro(bfas_add_tests) + +macro(bfas_add_backend_test_and_label device toolsdevice alias bfa_file label test_args cmake_args) + bfas_add_test_with_args(${device} ${toolsdevice} ${alias} ${bfa_file} "${test_args}" "${cmake_args}") + p4c_add_test_label(${device} "${label}" ${alias}) +endmacro(bfas_add_backend_test_and_label ) + + +if (ENABLE_TESTING) + # Replace P4C source/binary paths temporarily to override the defaults used by p4c_add_test_with_args + set(P4C_SOURCE_DIR_ORIG ${P4C_SOURCE_DIR}) + set(P4C_SOURCE_DIR ${BFASM_SOURCE_DIR}) + set(P4C_BINARY_DIR_ORIG ${P4C_BINARY_DIR}) + set(P4C_BINARY_DIR ${BFASM_BINARY_DIR}) + + set (JBAY_INCLUDE_PATTERNS "target:.*Tofino2") + #set (JBAY_EXCLUDE_PATTERNS ) + #set (JBAY_EXCLUDE_FILES ) + + set (BFA_FILES + "${CMAKE_CURRENT_SOURCE_DIR}/stf/*.bfa") + p4c_find_tests("${BFA_FILES}" JBAY_TESTS_PRE1 INCLUDE "${JBAY_INCLUDE_PATTERNS}" EXCLUDE "${JBAY_EXCLUDE_PATTERNS}") + bfn_find_tests("${JBAY_TESTS_PRE1}" JBAY_TESTS EXCLUDE "${JBAY_EXCLUDE_FILES}") + + bfas_add_tests("tofino2_asm" "jbay" "bfas_jbay" "base" "${JBAY_TESTS}") + + # Restore the P4C source/binary dirs + set(P4C_SOURCE_DIR ${P4C_SOURCE_DIR_ORIG}) + set(P4C_BINARY_DIR ${P4C_BINARY_DIR_ORIG}) +endif() + diff --git a/backends/tofino/bf-asm/test/acl1.p4 b/backends/tofino/bf-asm/test/acl1.p4 new file mode 100644 index 00000000000..3e4417736da --- /dev/null +++ b/backends/tofino/bf-asm/test/acl1.p4 @@ -0,0 +1,319 @@ + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +/* + * ACL and QoS metadata + */ +header_type acl_metadata_t { + fields { + acl_deny : 1; /* ifacl/vacl deny action */ + racl_deny : 1; /* racl deny action */ + acl_nexthop : 16; /* next hop from ifacl/vacl */ + racl_nexthop : 16; /* next hop from racl */ + acl_nexthop_type : 1; /* ecmp or nexthop */ + racl_nexthop_type : 1; /* ecmp or nexthop */ + acl_redirect : 1; /* ifacl/vacl redirect action */ + racl_redirect : 1; /* racl redirect action */ + if_label : 15; /* if label for acls */ + bd_label : 16; /* bd label for acls */ + mirror_session_id : 10; /* mirror session id */ + } +} + +@pragma pa_solitary ingress acl_metadata.if_label + +metadata acl_metadata_t acl_metadata; + +header_type ingress_metadata_t { + fields { + ingress_port : 9; /* input physical port */ + ifindex : 16; /* input interface index */ + egress_ifindex : 16; /* egress interface index */ + port_type : 2; /* ingress port type */ + + outer_bd : 16; /* outer BD */ + bd : 16; /* BD */ + + drop_flag : 1; /* if set, drop the packet */ + drop_reason : 8; /* drop reason */ + control_frame: 1; /* control frame */ + enable_dod : 1; /* enable deflect on drop */ + } +} + +metadata ingress_metadata_t ingress_metadata; + +header_type fabric_metadata_t { + fields { + packetType : 3; + fabric_header_present : 1; + reason_code : 16; /* cpu reason code */ + } +} + +metadata fabric_metadata_t fabric_metadata; + +header_type ipv4_metadata_t { + fields { + lkp_ipv4_sa : 32; + lkp_ipv4_da : 32; + ipv4_unicast_enabled : 1; /* is ipv4 unicast routing enabled */ + ipv4_urpf_mode : 2; /* 0: none, 1: strict, 3: loose */ + } +} + +metadata ipv4_metadata_t ipv4_metadata; + +header_type ipv6_metadata_t { + fields { + lkp_ipv6_sa : 128; /* ipv6 source address */ + lkp_ipv6_da : 128; /* ipv6 destination address*/ + + ipv6_unicast_enabled : 1; /* is ipv6 unicast routing enabled on BD */ + ipv6_src_is_link_local : 1; /* source is link local address */ + ipv6_urpf_mode : 2; /* 0: none, 1: strict, 3: loose */ + } +} + +//@pragma pa_alias ingress ipv4_metadata.lkp_ipv4_sa ipv6_metadata.lkp_ipv6_sa +//@pragma pa_alias ingress ipv4_metadata.lkp_ipv4_da ipv6_metadata.lkp_ipv6_da + +metadata ipv6_metadata_t ipv6_metadata; + + +header_type l2_metadata_t { + fields { + lkp_pkt_type : 3; + lkp_mac_sa : 48; + lkp_mac_da : 48; + lkp_mac_type : 16; + + l2_nexthop : 16; /* next hop from l2 */ + l2_nexthop_type : 1; /* ecmp or nexthop */ + l2_redirect : 1; /* l2 redirect action */ + l2_src_miss : 1; /* l2 source miss */ + l2_src_move : 16; /* l2 source interface mis-match */ + stp_group: 10; /* spanning tree group id */ + stp_state : 3; /* spanning tree port state */ + bd_stats_idx : 16; /* ingress BD stats index */ + learning_enabled : 1; /* is learning enabled */ + port_vlan_mapping_miss : 1; /* port vlan mapping miss */ + same_if_check : 16; /* same interface check */ + } +} + +metadata l2_metadata_t l2_metadata; + +header_type l3_metadata_t { + fields { + lkp_ip_type : 2; + lkp_ip_version : 4; + lkp_ip_proto : 8; + lkp_ip_tc : 8; + lkp_ip_ttl : 8; + lkp_l4_sport : 16; + lkp_l4_dport : 16; + lkp_inner_l4_sport : 16; + lkp_inner_l4_dport : 16; + + vrf : 12; /* VRF */ + rmac_group : 10; /* Rmac group, for rmac indirection */ + rmac_hit : 1; /* dst mac is the router's mac */ + urpf_mode : 2; /* urpf mode for current lookup */ + urpf_hit : 1; /* hit in urpf table */ + urpf_check_fail :1; /* urpf check failed */ + urpf_bd_group : 16; /* urpf bd group */ + fib_hit : 1; /* fib hit */ + fib_nexthop : 16; /* next hop from fib */ + fib_nexthop_type : 1; /* ecmp or nexthop */ + same_bd_check : 16; /* ingress bd xor egress bd */ + nexthop_index : 16; /* nexthop/rewrite index */ + routed : 1; /* is packet routed? */ + outer_routed : 1; /* is outer packet routed? */ + mtu_index : 8; /* index into mtu table */ + l3_mtu_check : 16 (saturating); /* result of mtu check */ + } +} + +metadata l3_metadata_t l3_metadata; + +header_type security_metadata_t { + fields { + storm_control_color : 1; /* 0 : pass, 1 : fail */ + ipsg_enabled : 1; /* is ip source guard feature enabled */ + ipsg_check_fail : 1; /* ipsg check failed */ + } +} + +metadata security_metadata_t security_metadata; + +header_type tunnel_metadata_t { + fields { + ingress_tunnel_type : 5; /* tunnel type from parser */ + tunnel_vni : 24; /* tunnel id */ + mpls_enabled : 1; /* is mpls enabled on BD */ + mpls_label: 20; /* Mpls label */ + mpls_exp: 3; /* Mpls Traffic Class */ + mpls_ttl: 8; /* Mpls Ttl */ + egress_tunnel_type : 5; /* type of tunnel */ + tunnel_index: 14; /* tunnel index */ + tunnel_src_index : 9; /* index to tunnel src ip */ + tunnel_smac_index : 9; /* index to tunnel src mac */ + tunnel_dst_index : 14; /* index to tunnel dst ip */ + tunnel_dmac_index : 14; /* index to tunnel dst mac */ + vnid : 24; /* tunnel vnid */ + tunnel_terminate : 1; /* is tunnel being terminated? */ + tunnel_if_check : 1; /* tun terminate xor originate */ + egress_header_count: 4; /* number of mpls header stack */ + } +} +metadata tunnel_metadata_t tunnel_metadata; + +/*****************************************************************************/ +/* System ACL */ +/*****************************************************************************/ +counter drop_stats { + type : packets; + instance_count : 256; +} + +counter drop_stats_2 { + type : packets; + instance_count : 256; +} + +field_list mirror_info { + ingress_metadata.ifindex; + ingress_metadata.drop_reason; +} + +action negative_mirror(session_id) { + //clone_ingress_pkt_to_egress(session_id, mirror_info); + //drop(); +} + +action redirect_to_cpu(reason_code) { + copy_to_cpu(reason_code); + //drop(); +} + +field_list cpu_info { + ingress_metadata.bd; + ingress_metadata.ifindex; + fabric_metadata.reason_code; +} + +action copy_to_cpu(reason_code) { + modify_field(fabric_metadata.reason_code, reason_code); + //clone_ingress_pkt_to_egress(250, cpu_info); +} + +action drop_packet() { + //drop(); +} + +action drop_packet_with_reason(drop_reason) { + count(drop_stats, drop_reason); + //drop(); +} + +action congestion_mirror_set() { +} + +action nop() { +} + + +table system_acl { + reads { + acl_metadata.if_label : ternary; + acl_metadata.bd_label : ternary; + + /* ip acl */ + ipv4_metadata.lkp_ipv4_sa : ternary; + ipv4_metadata.lkp_ipv4_da : ternary; + l3_metadata.lkp_ip_proto : ternary; + + /* mac acl */ + l2_metadata.lkp_mac_sa : ternary; + l2_metadata.lkp_mac_da : ternary; + l2_metadata.lkp_mac_type : ternary; + + ingress_metadata.ifindex : ternary; + + /* drop reasons */ + l2_metadata.port_vlan_mapping_miss : ternary; + security_metadata.ipsg_check_fail : ternary; + acl_metadata.acl_deny : ternary; + acl_metadata.racl_deny: ternary; + l3_metadata.urpf_check_fail : ternary; + ingress_metadata.drop_flag : ternary; + + l3_metadata.rmac_hit : ternary; + + /* + * other checks, routed link_local packet, l3 same if check, + * expired ttl + */ + l3_metadata.routed : ternary; + ipv6_metadata.ipv6_src_is_link_local : ternary; + l2_metadata.same_if_check : ternary; + tunnel_metadata.tunnel_if_check : ternary; + l3_metadata.same_bd_check : ternary; + l3_metadata.lkp_ip_ttl : ternary; + l2_metadata.stp_state : ternary; + ingress_metadata.control_frame: ternary; + ipv4_metadata.ipv4_unicast_enabled : ternary; + + /* egress information */ + ingress_metadata.egress_ifindex : ternary; + + /* deflect on drop (-ve mirror) */ + ingress_metadata.enable_dod: ternary; + } + actions { + nop; + redirect_to_cpu; + copy_to_cpu; + drop_packet; + drop_packet_with_reason; + negative_mirror; + congestion_mirror_set; + } + size : 512; +} + +action drop_stats_update() { + count(drop_stats_2, ingress_metadata.drop_reason); +} + +table drop_stats { + actions { + drop_stats_update; + } + size : 256; +} + +control ingress { + apply(system_acl); + if (ingress_metadata.drop_flag == 1) { + apply(drop_stats); + } +} diff --git a/backends/tofino/bf-asm/test/action_bus1.p4 b/backends/tofino/bf-asm/test/action_bus1.p4 new file mode 100644 index 00000000000..490be365449 --- /dev/null +++ b/backends/tofino/bf-asm/test/action_bus1.p4 @@ -0,0 +1,40 @@ +/* try to fill the action bus with 32-bit values... */ +#define REP5(M, ...) M(__VA_ARGS__, 1) M(__VA_ARGS__, 2) M(__VA_ARGS__, 3) \ + M(__VA_ARGS__, 4) M(__VA_ARGS__, 5) +#define REP8(M, ...) M(__VA_ARGS__, 1) M(__VA_ARGS__, 2) M(__VA_ARGS__, 3) \ + M(__VA_ARGS__, 4) M(__VA_ARGS__, 5) M(__VA_ARGS__, 6) \ + M(__VA_ARGS__, 7) M(__VA_ARGS__, 8) + +header_type data_t { + fields { +#define F32(A,B) f##A##_##B : 32; +REP8(REP5,F32) + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +#define MF(A,B) modify_field(data.f##A##_##B, v##B); +#define SET(_,A) action set##A(v1,v2,v3,v4,v5) { REP5(MF,A) } +REP8(SET) + +#define TBL(_,A) table tbl##A { \ + reads { \ + data.f##A##_1 : exact; \ + } \ + actions { \ + set##A; \ + noop; \ + } \ +} +REP8(TBL) +#define USE_TBL(_,A) apply(tbl##A); + +control ingress { + REP8(USE_TBL) +} diff --git a/backends/tofino/bf-asm/test/action_chain1.p4 b/backends/tofino/bf-asm/test/action_chain1.p4 new file mode 100644 index 00000000000..f8c7d0a652e --- /dev/null +++ b/backends/tofino/bf-asm/test/action_chain1.p4 @@ -0,0 +1,83 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + h1 : 16; + b1 : 8; + b2 : 8; + } +} + +header_type extra_t { + fields { + h : 16; + b1 : 8; + b2 : 8; + } +} + +header data_t data; +header extra_t extra[4]; + +parser start { + extract(data); + return extra; +} +parser extra { + extract(extra[next]); + return select(latest.b2) { + 0x80 mask 0x80: extra; + default: ingress; + } +} + +action setb1(port, val) { + modify_field(data.b1, val); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} +action noop() { } +action setb2(val) { modify_field(data.b2, val); } +action set0b1(val) { modify_field(extra[0].b1, val); } +action set1b1(val) { modify_field(extra[1].b1, val); } +action set2b2(val) { modify_field(extra[2].b2, val); } +action act1(val) { modify_field(extra[0].b1, val); } +action act2(val) { modify_field(extra[0].b1, val); } +action act3(val) { modify_field(extra[0].b1, val); } + +table test1 { + reads { data.f1 : ternary; } + actions { + setb1; + noop; + } +} +table ex1 { + reads { extra[0].h : ternary; } + actions { + set0b1; + act1; + act2; + act3; + noop; + } +} +table tbl1 { + reads { data.f2 : ternary; } + actions { setb2; noop; } } +table tbl2 { + reads { data.f2 : ternary; } + actions { set1b1; noop; } } +table tbl3 { + reads { data.f2 : ternary; } + actions { set2b2; noop; } } + +control ingress { + apply(test1); + apply(ex1) { + act1 { apply(tbl1); } + act2 { apply(tbl2); } + act3 { apply(tbl3); } + } +} diff --git a/backends/tofino/bf-asm/test/action_chain1.stf b/backends/tofino/bf-asm/test/action_chain1.stf new file mode 100644 index 00000000000..766ff01b893 --- /dev/null +++ b/backends/tofino/bf-asm/test/action_chain1.stf @@ -0,0 +1,20 @@ + +add test1 0 data.f1:0x****0101 setb1(val:0x7f, port:2) +add test1 503 data.f1:0x****0202 setb1(val:7, port:3) + +#expect 2 00000101 ******** **** 7f 66 +#packet 0 00000101 00000202 0303 55 66 7777 88 00 +#expect 3 00000202 ******** **** 07 66 +#packet 2 00000202 00000303 0404 55 66 7777 88 00 +#wait + +add ex1 100 extra$0.h:0x25** act1(val:0x25) +add tbl1 100 data.f2:0x0202**** setb2(val:0x26) +add ex1 110 extra$0.h:0x2525 act2(val:0x27) +add tbl2 100 data.f2:0x0202**** set1b1(val:0x28) + +# compiler+asm bug: not setting up next table from ex1 properly +packet 0 01010101 02020202 0303 55 66 2500 ff 7f 01020304 +expect 2 01010101 02020202 0303 7f 26 2500 25 7f 01020304 +#packet 0 01010101 02020202 0303 55 66 2525 ff ff 3333 ff 7f 01020304 +#expect 2 01010101 02020202 0303 7f 66 2525 27 ff 3333 28 7f 01020304 diff --git a/backends/tofino/bf-asm/test/action_chain2.p4 b/backends/tofino/bf-asm/test/action_chain2.p4 new file mode 100644 index 00000000000..8916b64e2b9 --- /dev/null +++ b/backends/tofino/bf-asm/test/action_chain2.p4 @@ -0,0 +1,83 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + h1 : 16; + b1 : 8; + b2 : 8; + } +} + +header_type extra_t { + fields { + h : 16; + b1 : 8; + b2 : 8; + } +} + +header data_t data; +header extra_t extra[4]; + +parser start { + extract(data); + return extra; +} +parser extra { + extract(extra[next]); + return select(latest.b2) { + 0x80 mask 0x80: extra; + default: ingress; + } +} + +action setb1(port, val) { + modify_field(data.b1, val); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} +action noop() { } +action setb2(val) { modify_field(data.b2, val); } +action set0b1(val) { modify_field(extra[0].b1, val); } +action set1b1(val) { modify_field(extra[1].b1, val); } +action set2b2(val) { modify_field(extra[2].b2, val); } +action act1(val) { modify_field(extra[0].b1, val); } +action act2(val) { modify_field(extra[0].b1, val); } +action act3(val) { modify_field(extra[0].b1, val); } + +table test1 { + reads { data.f1 : exact; } + actions { + setb1; + noop; + } +} +table ex1 { + reads { extra[0].h : exact; } + actions { + set0b1; + act1; + act2; + act3; + noop; + } +} +table tbl1 { + reads { data.f2 : exact; } + actions { setb2; noop; } } +table tbl2 { + reads { data.f2 : exact; } + actions { set1b1; noop; } } +table tbl3 { + reads { data.f2 : exact; } + actions { set2b2; noop; } } + +control ingress { + apply(test1); + apply(ex1) { + act1 { apply(tbl1); } + act2 { apply(tbl2); } + act3 { apply(tbl3); } + } +} diff --git a/backends/tofino/bf-asm/test/asm/action_bus_alignment.tfa b/backends/tofino/bf-asm/test/asm/action_bus_alignment.tfa new file mode 100644 index 00000000000..d04b91b80bc --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/action_bus_alignment.tfa @@ -0,0 +1,422 @@ +version: 1.0.0 +phv ingress: + $always_deparse: B34(0) + $bridged_metadata_indicator: B32 + data.f1: W37 + data.f2: W36 + data.f3: W38 + data.h1: W35(16..31) + data.h2: W35(0..15) + data.h3: W34(16..31) + data.h4: W34(0..15) + data.h5: W33(16..31) + data.h6: W33(0..15) + data.b1: B33 + data.b2: H32(8..15) + data.b3: H32(0..7) + data.b4: W32(24..31) + data.b5: W32(16..23) + data.b6: W32(8..15) + data.b7: W32(0..7) + data.$valid: B35(0) +phv egress: + eg_intr_md.egress_port: H40(0..8) + data.f1: TW5 + data.f2: TW4 + data.f3: TW6 + data.h1: TW3(16..31) + data.h2: TW3(0..15) + data.h3: TW2(16..31) + data.h4: TW2(0..15) + data.h5: TW1(16..31) + data.h6: TW1(0..15) + data.b1: TB0 + data.b2: TH0(8..15) + data.b3: TH0(0..7) + data.b4: TW0(24..31) + data.b5: TW0(16..23) + data.b6: TW0(8..15) + data.b7: TW0(0..7) + data.$valid: B40(0) +parser ingress: + start: $entry_point + hdr_len_adj: 16 + states: + $entry_point: # from state ingress::$entry_point + 0x*: + B32: 0 # value 0 -> B32 L[0..7]b: ingress::$bridged_metadata_indicator + B34: 1 # value 1 -> B34 L[0]b: ingress::$always_deparse + buf_req: 0 + next: $ingress_tna_entry_point + $ingress_tna_entry_point: # from state ingress::$ingress_tna_entry_point + 0x*: + buf_req: 0 + next: $ingress_metadata + $ingress_metadata: # from state ingress::$ingress_metadata + 0x*: + buf_req: 1 + next: $check_resubmit + $check_resubmit: # from state ingress::$check_resubmit + match: [ 0 ] + # - match N[0]B: cast + 0b0*******: + shift: 8 + buf_req: 8 + next: $phase0 + 0b1*******: + shift: 8 + buf_req: 8 + next: end + $phase0: # from state ingress::$phase0 + 0x*: + shift: 8 + buf_req: 8 + next: $skip_to_packet + $skip_to_packet: # from state ingress::$skip_to_packet + 0x*: + buf_req: 0 + next: start + start: # from state ingress::start + 0x*: + 0..3: W37 # ingress::data.f1 + 4..7: W36 # ingress::data.f2 + 8..11: W38 # ingress::data.f3 + 12..15: W35 + # - N[96..111]b -> W35 L[16..31]b: ingress::data.h1 + # - N[112..127]b -> W35 L[0..15]b: ingress::data.h2 + 24: B33 # ingress::data.b1 + 25..26: H32 + # - N[200..207]b -> H32 L[8..15]b: ingress::data.b2 + # - N[208..215]b -> H32 L[0..7]b: ingress::data.b3 + B35: 1 # value 1 -> B35 L[0]b: ingress::data.$valid + shift: 16 + buf_req: 27 + next: start.$split + start.$split: # from state ingress::start + 0x*: + 0..3: W34 + # - N[128..143]b -> W34 L[16..31]b: ingress::data.h3 + # - N[144..159]b -> W34 L[0..15]b: ingress::data.h4 + 4..7: W33 + # - N[160..175]b -> W33 L[16..31]b: ingress::data.h5 + # - N[176..191]b -> W33 L[0..15]b: ingress::data.h6 + 11..14: W32 + # - N[216..223]b -> W32 L[24..31]b: ingress::data.b4 + # - N[224..231]b -> W32 L[16..23]b: ingress::data.b5 + # - N[232..239]b -> W32 L[8..15]b: ingress::data.b6 + # - N[240..247]b -> W32 L[0..7]b: ingress::data.b7 + shift: 15 + buf_req: 15 + next: end +deparser ingress: + dictionary: + B32: B34(0) # ingress::$bridged_metadata_indicator if ingress::$always_deparse + W37: B35(0) # ingress::data.f1 if ingress::data.$valid + W36: B35(0) # ingress::data.f2 if ingress::data.$valid + W38: B35(0) # ingress::data.f3 if ingress::data.$valid + W35: B35(0) + # - L[16..31]b: ingress::data.h1 if ingress::data.$valid + # - L[0..15]b: ingress::data.h2 if ingress::data.$valid + W34: B35(0) + # - L[16..31]b: ingress::data.h3 if ingress::data.$valid + # - L[0..15]b: ingress::data.h4 if ingress::data.$valid + W33: B35(0) + # - L[16..31]b: ingress::data.h5 if ingress::data.$valid + # - L[0..15]b: ingress::data.h6 if ingress::data.$valid + B33: B35(0) # ingress::data.b1 if ingress::data.$valid + H32: B35(0) + # - L[8..15]b: ingress::data.b2 if ingress::data.$valid + # - L[0..7]b: ingress::data.b3 if ingress::data.$valid + W32: B35(0) + # - L[24..31]b: ingress::data.b4 if ingress::data.$valid + # - L[16..23]b: ingress::data.b5 if ingress::data.$valid + # - L[8..15]b: ingress::data.b6 if ingress::data.$valid + # - L[0..7]b: ingress::data.b7 if ingress::data.$valid +parser egress: + start: $entry_point + hdr_len_adj: 27 + meta_opt: 8191 + states: + $entry_point: # from state egress::$entry_point + 0x*: + buf_req: 0 + next: $egress_tna_entry_point + $egress_tna_entry_point: # from state egress::$egress_tna_entry_point + 0x*: + buf_req: 0 + next: $egress_metadata + $egress_metadata: # from state egress::$egress_metadata + 0x*: + 0..1: H40 # N[7..15]b -> H40 L[0..8]b: egress::eg_intr_md.egress_port + shift: 27 + buf_req: 28 + next: $check_mirrored + $check_mirrored: # from state egress::$check_mirrored + match: [ 0 ] + # - match N[0]B: BFN::LookaheadExpression + 0b****0***: + buf_req: 0 + next: $bridge_metadata_extract + 0b****1***: + buf_req: 0 + next: end + $bridge_metadata_extract: # from state egress::$bridge_metadata_extract + 0x*: + shift: 1 + buf_req: 1 + next: start + start: # from state egress::start + 0x*: + 0..3: TW5 # egress::data.f1 + 4..7: TW4 # egress::data.f2 + 8..11: TW6 # egress::data.f3 + 12..15: TW3 + # - N[96..111]b -> TW3 L[16..31]b: egress::data.h1 + # - N[112..127]b -> TW3 L[0..15]b: egress::data.h2 + 24: TB0 # egress::data.b1 + 25..26: TH0 + # - N[200..207]b -> TH0 L[8..15]b: egress::data.b2 + # - N[208..215]b -> TH0 L[0..7]b: egress::data.b3 + B40: 1 # value 1 -> B40 L[0]b: egress::data.$valid + shift: 16 + buf_req: 27 + next: start.$split.0 + start.$split.0: # from state egress::start + 0x*: + 0..3: TW2 + # - N[128..143]b -> TW2 L[16..31]b: egress::data.h3 + # - N[144..159]b -> TW2 L[0..15]b: egress::data.h4 + 4..7: TW1 + # - N[160..175]b -> TW1 L[16..31]b: egress::data.h5 + # - N[176..191]b -> TW1 L[0..15]b: egress::data.h6 + 11..14: TW0 + # - N[216..223]b -> TW0 L[24..31]b: egress::data.b4 + # - N[224..231]b -> TW0 L[16..23]b: egress::data.b5 + # - N[232..239]b -> TW0 L[8..15]b: egress::data.b6 + # - N[240..247]b -> TW0 L[0..7]b: egress::data.b7 + shift: 15 + buf_req: 15 + next: end +deparser egress: + dictionary: + TW5: B40(0) # egress::data.f1 if egress::data.$valid + TW4: B40(0) # egress::data.f2 if egress::data.$valid + TW6: B40(0) # egress::data.f3 if egress::data.$valid + TW3: B40(0) + # - L[16..31]b: egress::data.h1 if egress::data.$valid + # - L[0..15]b: egress::data.h2 if egress::data.$valid + TW2: B40(0) + # - L[16..31]b: egress::data.h3 if egress::data.$valid + # - L[0..15]b: egress::data.h4 if egress::data.$valid + TW1: B40(0) + # - L[16..31]b: egress::data.h5 if egress::data.$valid + # - L[0..15]b: egress::data.h6 if egress::data.$valid + TB0: B40(0) # egress::data.b1 if egress::data.$valid + TH0: B40(0) + # - L[8..15]b: egress::data.b2 if egress::data.$valid + # - L[0..7]b: egress::data.b3 if egress::data.$valid + TW0: B40(0) + # - L[24..31]b: egress::data.b4 if egress::data.$valid + # - L[16..23]b: egress::data.b5 if egress::data.$valid + # - L[8..15]b: egress::data.b6 if egress::data.$valid + # - L[0..7]b: egress::data.b7 if egress::data.$valid + egress_unicast_port: H40 # L[0..8]b: egress::eg_intr_md.egress_port +stage 0 ingress: + exact_match test3_0 0: + p4: { name: test3, size: 1024 } + p4_param_order: + data.f3: { type: exact, size: 32 } + row: 7 + bus: 0 + column: [ 2, 3, 4 ] + ways: + - [0, 0, 0x0, [7, 2]] + - [0, 1, 0x0, [7, 3]] + - [0, 2, 0x0, [7, 4]] + input_xbar: + exact group 0: { 0: data.f3 } + hash 0: + 0..7: random(data.f3(10..31)) ^ data.f3(0..7) + 10..17: random(data.f3(10..31)) ^ data.f3(0..7) + 20..27: random(data.f3(10..31)) ^ data.f3(0..7) + 8..9: random(data.f3(10..31)) ^ data.f3(8..9) + 18..19: random(data.f3(10..31)) ^ data.f3(8..9) + 28..29: random(data.f3(10..31)) ^ data.f3(8..9) + hash group 0: + table: [0] + format: { action(0): 0..0, version(0): 112..115, counter_addr(0): 1..12, counter_pfe(0): 13..13, match(0): [34..39, 16..31 ] } + match: [ data.f3(10..31) ] + next: test2_0 + stats: test3_0$counter..test3_counter(counter_addr) + actions: + my_count: + - p4_param_order: {idx: 32 } + - default_action: { allowed: true } + - { idx: counter_addr } + - test3_0$counter..test3_counter(idx) + NoAction: + - default_action: { allowed: true } + - 0 + default_action: NoAction + counter test3_0$counter..test3_counter: + p4: { name: test3_counter, size: 4000 } + row: 13 + column: [ 0, 1 ] + maprams: [ 0, 1 ] + count: packets + format: {packets(0): 96..127, packets(1): 64..95, packets(2): 32..63, packets(3): 0..31} + per_flow_enable: counter_pfe + exact_match test2_0 1: + p4: { name: test2, size: 5000, action_profile: set_b4_6 } + p4_param_order: + data.f2: { type: exact, size: 32 } + row: [ 6, 7 ] + bus: [ 0, 1 ] + column: + - 2 + - [ 5, 6, 7 ] + ways: + - [1, 0, 0x0, [7, 5]] + - [1, 1, 0x0, [7, 6]] + - [1, 2, 0x0, [7, 7]] + - [1, 3, 0x0, [6, 2]] + input_xbar: + exact group 0: { 64: data.f2 } + hash 1: + 0..7: random(data.f2(10..31)) ^ data.f2(0..7) + 10..17: random(data.f2(10..31)) ^ data.f2(0..7) + 20..27: random(data.f2(10..31)) ^ data.f2(0..7) + 30..37: random(data.f2(10..31)) ^ data.f2(0..7) + 8..9: random(data.f2(10..31)) ^ data.f2(8..9) + 18..19: random(data.f2(10..31)) ^ data.f2(8..9) + 28..29: random(data.f2(10..31)) ^ data.f2(8..9) + 38..39: random(data.f2(10..31)) ^ data.f2(8..9) + hash group 1: + table: [1] + format: { action(0): 0..1, version(0): 112..115, meter_addr(0): 4..13, meter_pfe(0): 14..14, action_addr(0): 15..25, match(0): [66..71, 48..63 ], action(1): 2..3, version(1): 116..119, meter_addr(1): 26..35, meter_pfe(1): 36..36, action_addr(1): 37..47, match(1): [90..95, 72..87 ] } + match: [ data.f2(10..31) ] + next: test1_0 + action: test2_0$action(action, action_addr) + selector: test2_0$act_sel..set_b4_6(meter_addr) + default_action: NoAction + action test2_0$action: + p4: { name: set_b4_6, size: 1024 } + row: 15 + column: 4 + home_row: 15 + format setb4: { $adf_f0: 0..31 } + format setb5: { $adf_f0: 0..31 } + format setb6: { $adf_f0: 0..31 } + action_bus: { 96..99 : $adf_f0 } + actions: + setb4: + - p4_param_order: {val4: 8 } + - default_action: { allowed: true } + - { val4: $adf_f0(24..31) } + - set data.b4, val4 + setb5: + - p4_param_order: {val5: 8 } + - default_action: { allowed: true } + - { val5: $adf_f0(16..23) } + - set data.b5, val5 + setb6: + - p4_param_order: {val6: 8 } + - default_action: { allowed: true } + - { val6: $adf_f0(8..15) } + - set data.b6, val6 + NoAction: + - default_action: { allowed: true } + - { } + selection test2_0$act_sel..set_b4_6: + p4: { name: set_b4_6 } + row: 15 + column: [ 2, 3 ] + maprams: [ 2, 3 ] + input_xbar: + exact group 1: { 0: data.h4, 16: data.h5, 32: data.h6 } + hash 2: + 0..13: random(data.h4, data.h5, data.h6) + hash group 2: + table: [2] + mode: fair 0 + per_flow_enable: meter_pfe + non_linear: true + pool_sizes: [120] +stage 1 ingress: + exact_match test1_0 0: + p4: { name: test1, size: 10000, action_profile: set_b1_3 } + p4_param_order: + data.f1: { type: exact, size: 32 } + row: 7 + bus: 0 + column: [ 2, 3, 4, 5, 6 ] + ways: + - [0, 0, 0x1, [7, 2], [7, 3]] + - [0, 1, 0x0, [7, 4]] + - [0, 2, 0x0, [7, 5]] + - [0, 3, 0x0, [7, 6]] + input_xbar: + exact group 0: { 0: data.f1 } + hash 0: + 0..7: random(data.f1(10..31)) ^ data.f1(0..7) + 10..17: random(data.f1(10..31)) ^ data.f1(0..7) + 20..27: random(data.f1(10..31)) ^ data.f1(0..7) + 30..37: random(data.f1(10..31)) ^ data.f1(0..7) + 8..9: random(data.f1(10..31)) ^ data.f1(8..9) + 18..19: random(data.f1(10..31)) ^ data.f1(8..9) + 28..29: random(data.f1(10..31)) ^ data.f1(8..9) + 38..39: random(data.f1(10..31)) ^ data.f1(8..9) + 40: random(data.f1(10..31)) + hash group 0: + table: [0] + format: { action(0): 0..1, version(0): 112..115, meter_addr(0): 4..13, meter_pfe(0): 14..14, action_addr(0): 15..32, match(0): [82..87, 64..79 ], action(1): 2..3, version(1): 116..119, meter_addr(1): 33..42, meter_pfe(1): 43..43, action_addr(1): 44..61, match(1): [106..111, 88..103 ] } + match: [ data.f1(10..31) ] + next: END + action: test1_0$action(action, action_addr) + selector: test1_0$act_sel..set_b1_3(meter_addr) + default_action: NoAction + action test1_0$action: + p4: { name: set_b1_3, size: 80000 } + row: [ 15, 13 ] + column: + - [ 3, 4, 5 ] + - [ 0, 1 ] + home_row: 15 + format setb1: { $adf_b0: 0..7 } + format setb2: { $adf_h0: 0..15 } + format setb3: { $adf_h0: 0..15 } + action_bus: { 0 : $adf_b0, 32..33 : $adf_h0 } + actions: + setb1: + - p4_param_order: {val1: 8 } + - default_action: { allowed: true } + - { val1: $adf_b0 } + - set data.b1, val1 + setb2: + - p4_param_order: {val2: 8 } + - default_action: { allowed: true } + - { val2: $adf_h0(8..15) } + - set data.b2, val2 + setb3: + - p4_param_order: {val3: 8 } + - default_action: { allowed: true } + - { val3: $adf_h0(0..7) } + - set data.b3, val3 + NoAction: + - default_action: { allowed: true } + - { } + selection test1_0$act_sel..set_b1_3: + p4: { name: set_b1_3 } + row: 15 + column: [ 1, 2 ] + maprams: [ 1, 2 ] + input_xbar: + exact group 0: { 64: data.h2, 80: data.h1, 112: data.h3 } + hash 1: + 0..13: stripe(crc(0x8fdb, data.h2, data.h1, data.h3)) + hash group 1: + table: [1] + mode: fair 0 + per_flow_enable: meter_pfe + non_linear: true + pool_sizes: [120] diff --git a/backends/tofino/bf-asm/test/asm/action_default_multiple.tfa b/backends/tofino/bf-asm/test/asm/action_default_multiple.tfa new file mode 100644 index 00000000000..9175efea79c --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/action_default_multiple.tfa @@ -0,0 +1,112 @@ +version: 1.0.0 +phv ingress: + standard_metadata.egress_spec: H0(0..8) + data.b1: B3 + data.b2: B2 + data.b3: B1 + data.b4: B0 + data.$valid: B15(7) +phv egress: + standard_metadata.egress_port: H16(0..8) + data.$valid: B31(7) +parser ingress: + start: $ingress_metadata_shim + $ingress_metadata_shim: + 0x*: + shift: 16 + next: start$ + start$: + 0x*: + 0: data.b1 + 1: data.b2 + 2: data.b3 + 3: data.b4 + shift: 4 + next: start$.0 + start$.0: + 0x*: + data.$valid: 1 + next: end +deparser ingress: + dictionary: + data.b1: data.$valid + data.b2: data.$valid + data.b3: data.$valid + data.b4: data.$valid + egress_unicast_port: standard_metadata.egress_spec +parser egress: + start: $egress_metadata_shim + $egress_metadata_shim: + 0x*: + 0..1: H16 + shift: 2 + next: end +deparser egress: + dictionary: {} + egress_unicast_port: standard_metadata.egress_port +stage 0 ingress: + exact_match first 0: + p4: { name: first } + row: 1 + bus: 1 + column: [ ] + next: second + actions: + b1_act: + - { b1: immediate(0..7) } + - set data.b1, b1 + default_action: b1_act + default_action_parameters: + b1: 1 + exact_match second 1: + p4: { name: second } + row: 1 + bus: 0 + column: [ ] + next: third + actions: + b2_act: + - { b2: immediate(0..7) } + - set data.b2, b2 + default_action: b2_act + default_action_parameters: + b2: 2 + exact_match third 2: + p4: { name: third } + row: 0 + bus: 1 + column: [ ] + next: fourth + actions: + b3_act: + - { b3: immediate(0..7) } + - set data.b3, b3 + default_action: b3_act + default_action_parameters: + b3: 3 + exact_match fourth 3: + p4: { name: fourth } + row: 0 + bus: 0 + column: [ ] + next: port_set + actions: + b4_act: + - { b4: immediate(0..7) } + - set data.b4, b4 + default_action: b4_act + default_action_parameters: + b4: 4 + exact_match port_set 4: + p4: { name: port_set } + row: 2 + bus: 0 + column: [ ] + next: END + actions: + set_port: + - { port: immediate(0..8) } + - set standard_metadata.egress_spec, port + default_action: set_port + default_action_parameters: + port: 5 diff --git a/backends/tofino/bf-asm/test/asm/always_run.jba b/backends/tofino/bf-asm/test/asm/always_run.jba new file mode 100644 index 00000000000..35fad4ad4c5 --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/always_run.jba @@ -0,0 +1,16 @@ +parser ingress: + start: + 0x*: + shift: 32 + next: end +stage 0 ingress: + always_run_action: + - set H0, 3 + - set B1, 1 +deparser ingress: + egress_unicast_port: { H0: B1(0) } +parser egress: + start: + 0x*: + shift: 4 + next: end diff --git a/backends/tofino/bf-asm/test/asm/always_run.stf b/backends/tofino/bf-asm/test/asm/always_run.stf new file mode 100644 index 00000000000..345a9126bb8 --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/always_run.stf @@ -0,0 +1,2 @@ +expect 3 0102030405060708090a0b0c0d0e0f +packet 0 0102030405060708090a0b0c0d0e0f diff --git a/backends/tofino/bf-asm/test/asm/counter_lrt1.tfa b/backends/tofino/bf-asm/test/asm/counter_lrt1.tfa new file mode 100644 index 00000000000..d981af1c5e0 --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/counter_lrt1.tfa @@ -0,0 +1,10 @@ +stage 0 ingress: + counter a: + row: 15 + column: [ 0, 1, 2, 3 ] + count: bytes + format: { bytes(0): 32, bytes(1): 32, bytes(2): 32, bytes(3): 32 } + lrt: + - { threshold: 0x1000, interval: 0x1000000 } + - { threshold: 0x10000, interval: 0x100000 } + - { threshold: 0x100000, interval: 0x10000 } diff --git a/backends/tofino/bf-asm/test/asm/em1-clot.jba b/backends/tofino/bf-asm/test/asm/em1-clot.jba new file mode 100644 index 00000000000..1b6ad53164e --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/em1-clot.jba @@ -0,0 +1,98 @@ +version: 1.0.0 +phv ingress: + standard_metadata.egress_spec: H0(0..8) + data.f1: W0 + data.b1: B0 + data.$valid: B11(7) +phv egress: + standard_metadata.egress_port: H16(0..8) + data.$valid: B31(7) +parser ingress: + start: $ingress_metadata_shim + $ingress_metadata_shim: + match: [ 0 ] + # - [0] (buffer) + 0b0*******: + next: $ingress_metadata + 0b1*******: + next: $ingress_metadata + $ingress_metadata: + 0x*: + shift: 8 + next: $phase0 + $phase0: + 0x*: + shift: 24 + next: start + start: + 0x*: + clot 1: 0..11 + 0..3: data.f1 + 10: data.b1 + data.$valid: 1 + shift: 12 + next: end +deparser ingress: + dictionary: + clot 1: + pov: data.$valid + 10: data.b1 + egress_unicast_port: { standard_metadata.egress_spec: data.$valid } +parser egress: + start: $egress_metadata_shim + $egress_metadata_shim: + 0x*: + 0..1: H16 + # - L[0..8]b standard_metadata.egress_port + shift: 2 + next: $bridged_metadata + $bridged_metadata: + 0x*: + next: start + start: + 0x*: + clot X: + start: 0 + length: 12 + data.$valid: 1 + shift: 12 + next: end +deparser egress: + dictionary: + clot X: data.$valid + egress_unicast_port: { standard_metadata.egress_port: data.$valid } +stage 0 ingress: + exact_match test1 0: + p4: { name: test1 } + p4_param_order: + data.f1: { type: exact, size: 32 } + row: 7 + bus: 0 + column: [ 2, 3, 4 ] + ways: + - [0, 0, 0x0, [7, 2]] + - [0, 1, 0x0, [7, 3]] + - [0, 2, 0x0, [7, 4]] + input_xbar: + exact group 0: { 0: data.f1 } + hash 0: + 0..9: random(data.f1(10..31)) ^ stripe(data.f1(0..7), data.f1(8..9)) + 10..19: random(data.f1(10..31)) ^ stripe(data.f1(0..7), data.f1(8..9)) + 20..29: random(data.f1(10..31)) ^ stripe(data.f1(0..7), data.f1(8..9)) + hash group 0: + table: [0] + format: { action(0): 0..1, immediate(0): 2..25, version(0): 112..115, match(0): [50..55, 40..47, 32..39 ] } + match: [ data.f1(10..31) ] + next: END + action_bus: { 2 : immediate(16..23), 32..33 : immediate(0..15) } + actions: + setb1: + - p4_param_order: {val: 8, port: 9 } + - { port: immediate(0..8), val: immediate(16..23) } + - set data.b1, val + - set standard_metadata.egress_spec, port + noop: + - { } + NoAction: + - { } + default_action: NoAction diff --git a/backends/tofino/bf-asm/test/asm/em1-clot.stf b/backends/tofino/bf-asm/test/asm/em1-clot.stf new file mode 100644 index 00000000000..88e0059e450 --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/em1-clot.stf @@ -0,0 +1,8 @@ + +add test1 data.f1:0x01010101 setb1(val:0x7f, port:2) +add test1 data.f1:0x02020202 setb1(val:7, port:3) + +expect 2 01010101 00000202 0303 7f 66 77 88 +packet 0 01010101 00000202 0303 55 66 77 88 +#expect 3 02020202 00000303 0404 07 66 77 88 +#packet 2 02020202 00000303 0404 55 66 77 88 diff --git a/backends/tofino/bf-asm/test/asm/expected_failures.txt b/backends/tofino/bf-asm/test/asm/expected_failures.txt new file mode 100644 index 00000000000..0e41bd93111 --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/expected_failures.txt @@ -0,0 +1,14 @@ +- assembler failures on assembly tests. + +stateful_multiple_output_error.tfa bfas +- assembler must fail due to multiple output instructions in a stateful table + +table_alias_fields_error.tfa bfas +- alias fields index are out of range with allowed values + +-- the rest give various assembler errors -- delete them? +hash_action_basic.tfa bfas +hash_action_gateway2.tfa bfas +action_default_multiple.tfa bfas +switch_l2_profile_tofino.tfa bfas +tor.tfa bfas diff --git a/backends/tofino/bf-asm/test/asm/hash_action_basic.tfa b/backends/tofino/bf-asm/test/asm/hash_action_basic.tfa new file mode 100644 index 00000000000..2fab4ec4dc8 --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/hash_action_basic.tfa @@ -0,0 +1,112 @@ +version: 1.0.0 +phv ingress: + standard_metadata.egress_spec: H0(0..8) + data.f1: W1 + data.f2: W0 + data.h1: TH0 + data.h2: TH1 + data.h3: TH2 + data.h4: TH3 + counter_metadata.counter_index: H1 + data.$valid: B11(7) +phv egress: + standard_metadata.egress_port: H16(0..8) +parser ingress: + start: $ingress_metadata_shim + $ingress_metadata_shim: + 0x*: + shift: 16 + next: start$ + start$: + 0x*: + 0..3: data.f1 + 4..7: data.f2 + 8..9: data.h1 + 10..11: data.h2 + 12..13: data.h3 + 14..15: data.h4 + data.$valid: 1 + shift: 16 + next: end +deparser ingress: + dictionary: + data.f1: data.$valid + data.f2: data.$valid + data.h1: data.$valid + data.h2: data.$valid + data.h3: data.$valid + data.h4: data.$valid + egress_unicast_port: standard_metadata.egress_spec +parser egress: + start: $egress_metadata_shim + $egress_metadata_shim: + 0x*: + 0..1: H16 + shift: 2 + next: end +deparser egress: + dictionary: {} + egress_unicast_port: standard_metadata.egress_port +stage 0 ingress: + exact_match index_setter 0: + p4: { name: index_setter, size: 2048 } + row: 7 + bus: 0 + column: [ 2, 3, 4, 5 ] + ways: + - [0, 0, 0x0, [7, 2]] + - [0, 1, 0x0, [7, 3]] + - [0, 2, 0x0, [7, 4]] + - [0, 3, 0x0, [7, 5]] + input_xbar: + group 0: { 0: data.f1, 32: data.f2 } + hash 0: + 0..9: random(data.f1(10..31), data.f2) ^ stripe(data.f1(0..9)) + 10..19: random(data.f1(10..31), data.f2) ^ stripe(data.f1(0..9)) + 20..29: random(data.f1(10..31), data.f2) ^ stripe(data.f1(0..9)) + 30..39: random(data.f1(10..31), data.f2) ^ stripe(data.f1(0..9)) + hash group 0: + table: [0] + format: { action(0): 1, immediate(0): 32, version(0): 124..127, match(0): 34..87 } + match: [ data.f1(10..31), data.f2 ] + next: stats + actions: + set_index: + - { index: immediate(0..15), port: immediate(16..31) } + - set counter_metadata.counter_index, index + - set standard_metadata.egress_spec, port + NoAction_1: + - 0 + default_action: NoAction_1 +stage 1 ingress: + hash_action stats 0: + p4: { name: stats } + hash_dist: + 0: {hash: 0, mask: 65535} + row: 0 + bus: 0 + input_xbar: + group 0: { 0: counter_metadata.counter_index } + hash 0: + 0..15: counter_metadata.counter_index + hash group 0: + table: [0] + gateway: + row: 0 + #bus: 0 + 0x0: END + miss: END + next: END + stats: + - stats$counter.count1(hash_dist 0) + actions: + count_entries: + - 0 + default_action: count_entries + counter stats$counter.count1: + p4: { name: count1 } + row: 13 + column: [ 0, 1, 2, 3 ] + maprams: [ 0, 1, 2, 3 ] + count: packets + format: {packets(0): 106..126, packets(1): 85..105, packets(2): 64..84, packets(3): 42..62, packets(4): 21..41, packets(5): 0..20} diff --git a/backends/tofino/bf-asm/test/asm/hash_action_gateway2.stf b/backends/tofino/bf-asm/test/asm/hash_action_gateway2.stf new file mode 100644 index 00000000000..19b896fd5dd --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/hash_action_gateway2.stf @@ -0,0 +1,22 @@ + +add index_setter data.f1:0x11111111 data.f2:0x22222222 set_index(index:9, port:1) +add index_setter data.f1:0x22222222 data.f2:0x33333333 set_index(index:9, port:2) +add index_setter data.f1:0x33333333 data.f2:0x44444444 set_index(index:9, port:2) +add index_setter data.f1:0x44444444 data.f2:0x55555555 set_index(index:8, port:3) + + +expect 1 11111111 22222222 0101 0202 0303 0404 +packet 0 11111111 22222222 0101 0202 0303 0404 + +# expect 2 22222222 33333333 0202 0303 0404 0505 +# packet 0 22222222 33333333 0202 0303 0404 0505 + +# expect 2 33333333 44444444 0303 0404 0505 0606 +# packet 0 33333333 44444444 0303 0404 0505 0606 + +# expect 3 44444444 55555555 0404 0505 0606 0707 +# packet 0 44444444 55555555 0404 0505 0606 0707 + +wait +# check_counter count1(8) packets == 1 +check_counter count1(9) packets == 1 diff --git a/backends/tofino/bf-asm/test/asm/hash_action_gateway2.tfa b/backends/tofino/bf-asm/test/asm/hash_action_gateway2.tfa new file mode 100644 index 00000000000..f0bd5f653b5 --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/hash_action_gateway2.tfa @@ -0,0 +1,120 @@ +version: 1.0.0 +phv ingress: + standard_metadata.egress_spec: H0(0..8) + data.f1: W1 + data.f2: W0 + data.h1: TH0 + data.h2: TH2 + data.h3: TH1 + data.h4: TH3 + counter_metadata.counter_index: H1 + counter_metadata.counter_run: B0(0..3) + data.$valid: B0(7) +phv egress: + standard_metadata.egress_port: H16(0..8) +parser ingress: + start: $ingress_metadata_shim + $ingress_metadata_shim: + 0x*: + shift: 16 + next: start$ + start$: + 0x*: + 0..3: data.f1 + 4..7: data.f2 + 8..9: data.h1 + 10..11: data.h2 + 12..13: data.h3 + 14..15: data.h4 + data.$valid: 1 + shift: 16 + next: end +deparser ingress: + dictionary: + data.f1: data.$valid + data.f2: data.$valid + data.h1: data.$valid + data.h2: data.$valid + data.h3: data.$valid + data.h4: data.$valid + egress_unicast_port: standard_metadata.egress_spec +parser egress: + start: $egress_metadata_shim + $egress_metadata_shim: + 0x*: + 0..1: H16 + shift: 2 + next: end +deparser egress: + dictionary: {} + egress_unicast_port: standard_metadata.egress_port +stage 0 ingress: + exact_match index_setter 0: + p4: { name: index_setter, size: 2048 } + row: 7 + bus: 0 + column: [ 2, 3, 4, 5 ] + ways: + - [0, 0, 0x0, [7, 2]] + - [0, 1, 0x0, [7, 3]] + - [0, 2, 0x0, [7, 4]] + - [0, 3, 0x0, [7, 5]] + input_xbar: + group 0: { 0: data.f1, 32: data.f2 } + hash 0: + 0..9: random(data.f1(10..31), data.f2) ^ stripe(data.f1(0..9)) + 10..19: random(data.f1(10..31), data.f2) ^ stripe(data.f1(0..9)) + 20..29: random(data.f1(10..31), data.f2) ^ stripe(data.f1(0..9)) + 30..39: random(data.f1(10..31), data.f2) ^ stripe(data.f1(0..9)) + hash group 0: + table: [0] + format: { action(0): 1, immediate(0): 32, version(0): 124..127, match(0): 34..87 } + match: [ data.f1(10..31), data.f2 ] + next: stats + actions: + set_index: + - { index: immediate(0..15), port: immediate(16..31) } + - set counter_metadata.counter_index, index + - set standard_metadata.egress_spec, port + - set counter_metadata.counter_run, 1 + NoAction_1: + - 0 + default_action: NoAction_1 +stage 1 ingress: + hash_action stats 0: + p4: { name: stats } + row: 0 + bus: 0 + #column: [ ] + hash_dist: + 0: {hash: 0, mask: 65535, shift: 1} + input_xbar: + group 0: { 0: counter_metadata.counter_index } + hash 0: + 0..15: counter_metadata.counter_index + hash group 0: + table: [0] + gateway: + input_xbar: + group 0: { 16: counter_metadata.counter_run } + row: 0 + #bus: 0 + payload: 1 + match: { 0: counter_metadata.counter_run } + 0x*1: END + miss: run_table + next: END + stats: + - stats$counter.count1(hash_dist 0) + actions: + count_entries: + - 0 + default_action: count_entries + counter stats$counter.count1: + p4: { name: count1 } + row: 13 + column: [ 0, 1, 2, 3, 4, 5 ] + maprams: [ 0, 1, 2, 3, 4, 5 ] + count: packets + per_flow_enable: true + format: {packets(0): 96..127, packets(1): 64..95, packets(2): 32..63, packets(3): 0..31} diff --git a/backends/tofino/bf-asm/test/asm/jbay_sful_syntax.jba b/backends/tofino/bf-asm/test/asm/jbay_sful_syntax.jba new file mode 100644 index 00000000000..9ba417d3b15 --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/jbay_sful_syntax.jba @@ -0,0 +1,51 @@ +version: 1.0.0 +phv ingress: + $always_deparse: B1(0) + $bridged_metadata_indicator: B0 + data.f1: W7 + data.f2: W0 + data.f3: W1 + data.f4: W10 + data.h1: W3(16..31) + data.h2: W3(0..15) + data.h3: W6(16..31) + data.h4: W6(0..15) + data.b1: W2(24..31) + data.b2: W2(16..23) + data.b3: W2(8..15) + data.b4: W2(0..7) + ig_intr_md_for_tm.ucast_egress_port: H4(0..8) + $tmp1: B1(1) + data.$valid: B1(2) +stage 0 ingress: + stateful test1_0$salu..accum: + p4: { name: accum } + row: 15 + column: [ 0, 1 ] + maprams: [ 0, 1 ] + input_xbar: + exact group 1: { 0: data.f2, 32: data.f3 } + format: { lo: 32, hi:32 } + actions: + sful_0: + - add hi, hi, 1 + - grt.u p2, data.f2, -1000 + - lss.u p1, data.f2, -2000 + - add cmp2 & cmp1, lo, lo, data.f3 + - sub !cmp2 & cmp1, lo, lo, data.f3 + - output word0, mem_lo + - output word1, alu_hi + per_flow_enable: meter_pfe + stateful test2: + row: 11 + column: [ 0, 1, 2, 3, 4, 5 ] + maprams: [ 0, 1, 2, 3, 4, 5 ] + input_xbar: + exact group 2: { 0: data.h2, 16: data.h1 } + sbus and not: + match: test1_0$salu..accum + format: { lo: 16, hi: 16 } + actions: + a0: + - lss.s p3, data.h1, lo + - grt.s p2, data.h2, lo, -100 diff --git a/backends/tofino/bf-asm/test/asm/network_tap.bfa b/backends/tofino/bf-asm/test/asm/network_tap.bfa new file mode 100644 index 00000000000..bba4bc4ebef --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/network_tap.bfa @@ -0,0 +1,13304 @@ +version: + version: 1.0.1 + run_id: "adab53b4e08ee326" + target: Tofino +phv ingress: + ig_md.lkp.ip_proto: B11 + ig_md.lkp.ip_src_addr.0-31: W49 + ig_md.lkp.ip_src_addr.32-63: W50 + ig_md.lkp.ip_src_addr.64-95: W51 + ig_md.lkp.ip_src_addr.96-127: W52 + ig_md.lkp.ip_dst_addr.0-31: W53 + ig_md.lkp.ip_dst_addr.32-63: W54 + ig_md.lkp.ip_dst_addr.64-95: W55 + ig_md.lkp.ip_dst_addr.96-127: W56 + ig_md.lkp.l4_src_port: H9 + ig_md.lkp.l4_dst_port: H11 + ig_md.lkp.inner_l4_src_port: H10 + ig_md.lkp.inner_l4_dst_port: H12 + ig_md.count_index.0-7: B5 + ig_md.count_index.8-17: H6(0..9) + ig_md.hash: W2 + ig_md.in_ig_port_type: B6(0..2) + ig_md.trunc_type: B2(6..7) + ig_md.action_type: W1(13..20) + ig_md.ip_hdr_location: H3(0..7) + ig_md.pkt_proto_type: H3(8..15) + ig_md.port_group_id: W0(13..28) + ig_md.tunnel_type.0-4: B6(3..7) + ig_md.tunnel_type.5-5: B7(0) + ig_md.vlan_index: H8 + ig_md.mirror.src: B9 + ig_md.mirror.type: B10 + ig_md.mirror.session_id: H2(0..9) + hdr.bridged_md.src: B0 + hdr.bridged_md.pkt_proto_type: H3(8..15) + hdr.bridged_md.ip_hdr_location: H3(0..7) + hdr.bridged_md.pad1: B7(1..7) + hdr.bridged_md.tunnel_type.0-4: B6(3..7) + hdr.bridged_md.tunnel_type.5-5: B7(0) + hdr.bridged_md.in_ig_port_type: B6(0..2) + hdr.ethernet.dst_addr.0-15: H7 + hdr.ethernet.dst_addr.16-47: TW26 + hdr.ethernet.src_addr.0-15: TH25 + hdr.ethernet.src_addr.16-47: TW27 + hdr.ethernet.ether_type: H5 + hdr.ipv4.version: TW0(28..31) + hdr.ipv4.ihl: TW0(24..27) + hdr.ipv4.diffserv: TW0(16..23) + hdr.ipv4.total_len: TW0(0..15) + hdr.ipv4.identification.0-7: TB10 + hdr.ipv4.identification.8-15: TB11 + hdr.ipv4.flags: TB8(5..7) + hdr.ipv4.frag_offset.0-7: TB9 + hdr.ipv4.frag_offset.8-12: TB8(0..4) + hdr.ipv4.ttl: TW16(24..31) + hdr.ipv4.protocol: TW16(16..23) + hdr.ipv4.hdr_checksum: TW16(0..15) + hdr.ipv4.src_addr.0-15: TH29 + hdr.ipv4.src_addr.16-31: TH36 + hdr.ipv4.dst_addr.0-15: TH37 + hdr.ipv4.dst_addr.16-31: TH38 + hdr.tcp.src_port: TW18(16..31) + hdr.tcp.dst_port: TW18(0..15) + hdr.tcp.seq_no: TW25 + hdr.tcp.ack_no.0-7: TB19 + hdr.tcp.ack_no.8-15: TB24 + hdr.tcp.ack_no.16-31: TH39 + hdr.tcp.data_offset: TW1(28..31) + hdr.tcp.res: TW1(24..27) + hdr.tcp.flags: TW1(16..23) + hdr.tcp.window: TW1(0..15) + hdr.tcp.checksum: TW19(16..31) + hdr.tcp.urgent_ptr: TW19(0..15) + hdr.gtpv2_8b.version: TH0(13..15) + hdr.gtpv2_8b.pb: TH0(12) + hdr.gtpv2_8b.tf: TH0(11) + hdr.gtpv2_8b.spare1: TH0(8..10) + hdr.gtpv2_8b.message_type: TH0(0..7) + hdr.gtpv2_8b.total_len: TH1 + hdr.gtpv2_8b.seq_no.0-7: TB18 + hdr.gtpv2_8b.seq_no.8-23: TH26 + hdr.gtpv2_8b.spare2: TB17 + hdr.imsi.type: TW2(24..31) + hdr.imsi.len: TW2(8..23) + hdr.imsi.spare: TW2(4..7) + hdr.imsi.instance: TW2(0..3) + hdr.imsi.num_digit.0-31: TW17 + hdr.imsi.num_digit.32-63: TW24 + hdr.imsi.num_digit.64-79: TH24 + hdr.imsi.num_digit.80-95: TH27 + hdr.imsi.num_digit.96-103: TB16 + hdr.imsi.num_digit.104-111: TB25 + hdr.imsi.num_digit.112-127: TH28 + hdr.cause_ie_6b.type: TB1 + hdr.cause_ie_6b.len: TW3(16..31) + hdr.cause_ie_6b.spare1: TW3(12..15) + hdr.cause_ie_6b.instance: TW3(8..11) + hdr.cause_ie_6b.cause_value: TW3(0..7) + hdr.cause_ie_6b.spare2: TB0(3..7) + hdr.cause_ie_6b.pce: TB0(2) + hdr.cause_ie_6b.bce: TB0(1) + hdr.cause_ie_6b.cs: TB0(0) + hdr.cause_ie_10b.type: TB1 + hdr.cause_ie_10b.len: TW3(16..31) + hdr.cause_ie_10b.spare1: TW3(12..15) + hdr.cause_ie_10b.instance: TW3(8..11) + hdr.cause_ie_10b.cause_value: TW3(0..7) + hdr.cause_ie_10b.spare2: TB0(3..7) + hdr.cause_ie_10b.pce: TB0(2) + hdr.cause_ie_10b.bce: TB0(1) + hdr.cause_ie_10b.cs: TB0(0) + hdr.cause_ie_10b.type_oe: TH3(8..15) + hdr.cause_ie_10b.len_oe.0-7: TH2(8..15) + hdr.cause_ie_10b.len_oe.8-15: TH3(0..7) + hdr.cause_ie_10b.spare_oe: TH2(4..7) + hdr.cause_ie_10b.instance_oe: TH2(0..3) + hdr.inner_ipv4.version: TW2(28..31) + hdr.inner_ipv4.ihl: TW2(24..27) + hdr.inner_ipv4.diffserv: TW2(16..23) + hdr.inner_ipv4.total_len: TW2(0..15) + hdr.inner_ipv4.identification: TH24 + hdr.inner_ipv4.flags: TH3(13..15) + hdr.inner_ipv4.frag_offset: TH3(0..12) + hdr.inner_ipv4.ttl: TW17(24..31) + hdr.inner_ipv4.protocol: TW17(16..23) + hdr.inner_ipv4.hdr_checksum: TW17(0..15) + hdr.inner_ipv4.src_addr.0-7: TB16 + hdr.inner_ipv4.src_addr.8-15: TB25 + hdr.inner_ipv4.src_addr.16-31: TH40 + hdr.inner_ipv4.dst_addr.0-7: TB26 + hdr.inner_ipv4.dst_addr.8-15: TB27 + hdr.inner_ipv4.dst_addr.16-31: TH41 + hdr.inner_tcp.src_port: TH28 + hdr.inner_tcp.dst_port: TH27 + hdr.inner_tcp.seq_no: W6 + hdr.inner_tcp.ack_no: W7 + hdr.inner_tcp.data_offset: TW3(28..31) + hdr.inner_tcp.res: TW3(24..27) + hdr.inner_tcp.flags: TW3(16..23) + hdr.inner_tcp.window: TW3(0..15) + hdr.inner_tcp.checksum: TW24(16..31) + hdr.inner_tcp.urgent_ptr: TW24(0..15) + hdr.sip.data: W8 + hdr.inner_udp.src_port: TW3(16..31) + hdr.inner_udp.dst_port: TW3(0..15) + hdr.inner_udp.hdr_length: TW24(16..31) + hdr.inner_udp.checksum: TW24(0..15) + hdr.inner_icmp.type_: TW3(24..31) + hdr.inner_icmp.code: TW3(16..23) + hdr.inner_icmp.hdr_checksum: TW3(0..15) + hdr.ipsec_esp.spi: W9 + hdr.ipsec_esp.sn: W10 + hdr.inner_ipv6.version: TW2(28..31) + hdr.inner_ipv6.traffic_class: TW2(20..27) + hdr.inner_ipv6.flow_label: TW2(0..19) + hdr.inner_ipv6.payload_len: TH3 + hdr.inner_ipv6.next_hdr: B8 + hdr.inner_ipv6.hop_limit: TB16 + hdr.inner_ipv6.src_addr.0-31: W11 + hdr.inner_ipv6.src_addr.32-63: W12 + hdr.inner_ipv6.src_addr.64-95: W13 + hdr.inner_ipv6.src_addr.96-127: W14 + hdr.inner_ipv6.dst_addr.0-31: W15 + hdr.inner_ipv6.dst_addr.32-63: W32 + hdr.inner_ipv6.dst_addr.64-95: W33 + hdr.inner_ipv6.dst_addr.96-127: W34 + hdr.gtpv2_12b.version: TH0(13..15) + hdr.gtpv2_12b.pb: TH0(12) + hdr.gtpv2_12b.tf: TH0(11) + hdr.gtpv2_12b.spare1: TH0(8..10) + hdr.gtpv2_12b.message_type: TH0(0..7) + hdr.gtpv2_12b.total_len: TH1 + hdr.gtpv2_12b.teid: W35 + hdr.gtpv2_12b.seq_no.0-7: TB18 + hdr.gtpv2_12b.seq_no.8-23: TH26 + hdr.gtpv2_12b.spare2: TB17 + hdr.udp.src_port: TW18(16..31) + hdr.udp.dst_port: TW18(0..15) + hdr.udp.hdr_length: TW19(16..31) + hdr.udp.checksum: TW19(0..15) + hdr.vxlan.flags: TW1(24..31) + hdr.vxlan.reserved: TW1(0..23) + hdr.vxlan.vni.0-7: TH0(8..15) + hdr.vxlan.vni.8-23: TH1 + hdr.vxlan.reserved2: TH0(0..7) + hdr.inner_ethernet.dst_addr.0-7: TB17 + hdr.inner_ethernet.dst_addr.8-15: TB18 + hdr.inner_ethernet.dst_addr.16-47: TW25 + hdr.inner_ethernet.src_addr.0-15: TH26 + hdr.inner_ethernet.src_addr.16-23: TB0 + hdr.inner_ethernet.src_addr.24-31: TB1 + hdr.inner_ethernet.src_addr.32-47: TH39 + hdr.inner_ethernet.ether_type: TH2 + hdr.gtpv1_8b.version: TH0(13..15) + hdr.gtpv1_8b.pt: TH0(12) + hdr.gtpv1_8b.reserved: TH0(11) + hdr.gtpv1_8b.e: TH0(10) + hdr.gtpv1_8b.s: TH0(9) + hdr.gtpv1_8b.pn: TH0(8) + hdr.gtpv1_8b.message_type: TH0(0..7) + hdr.gtpv1_8b.message_len: TH1 + hdr.gtpv1_8b.teid: TW1 + hdr.gtpv1_12b.version: TH0(13..15) + hdr.gtpv1_12b.pt: TH0(12) + hdr.gtpv1_12b.reserved: TH0(11) + hdr.gtpv1_12b.e: TH0(10) + hdr.gtpv1_12b.s: TH0(9) + hdr.gtpv1_12b.pn: TH0(8) + hdr.gtpv1_12b.message_type: TH0(0..7) + hdr.gtpv1_12b.message_len: TH1 + hdr.gtpv1_12b.teid: TW25 + hdr.gtpv1_12b.seq_no: TW1(16..31) + hdr.gtpv1_12b.n_pdu_no: TW1(8..15) + hdr.gtpv1_12b.next_ex_hdr_t: TW1(0..7) + hdr.l2tp.TLxxSxOP: TW1(20..31) + hdr.l2tp.version: TW1(16..19) + hdr.l2tp.l2tp_length: TW1(8..15) + hdr.l2tp.tunnel_id.0-7: TB0 + hdr.l2tp.tunnel_id.8-15: TW1(0..7) + hdr.l2tp.session_id: TH26 + hdr.l2tp.Ns.0-7: TB18 + hdr.l2tp.Ns.8-15: TB19 + hdr.l2tp.Nr: TH0 + hdr.l2tp.offset_size: TB17 + hdr.l2tp.offset_pad: TB1 + hdr.pppoe.version: TH1(12..15) + hdr.pppoe.type: TH1(8..11) + hdr.pppoe.code: TH1(0..7) + hdr.pppoe.session_id: TH2 + hdr.pppoe.pppoe_length: TW25(16..31) + hdr.pppoe.ppp_proto: TW25(0..15) + hdr.icmp.type_: TW1(24..31) + hdr.icmp.code: TW1(16..23) + hdr.icmp.hdr_checksum: TW1(0..15) + hdr.sctp.src_port: TW1(16..31) + hdr.sctp.dst_port: TW1(0..15) + hdr.sctp.verifTag: TW2 + hdr.sctp.checksum: TH0 + hdr.gre.C: TH0(15) + hdr.gre.R: TH0(14) + hdr.gre.K: TH0(13) + hdr.gre.S: TH0(12) + hdr.gre.s: TH0(11) + hdr.gre.recurse: TH0(8..10) + hdr.gre.flags: TH0(3..7) + hdr.gre.version: TH0(0..2) + hdr.gre.proto.0-7: TB0 + hdr.gre.proto.8-15: TB1 + hdr.ipv6.version: TW0(28..31) + hdr.ipv6.traffic_class: TW0(20..27) + hdr.ipv6.flow_label: TW0(0..19) + hdr.ipv6.payload_len: TW16(16..31) + hdr.ipv6.next_hdr: TW16(8..15) + hdr.ipv6.hop_limit: TW16(0..7) + hdr.ipv6.src_addr.0-15: TH29 + hdr.ipv6.src_addr.16-31: TH36 + hdr.ipv6.src_addr.32-47: TH37 + hdr.ipv6.src_addr.48-63: TH38 + hdr.ipv6.src_addr.64-71: TB8 + hdr.ipv6.src_addr.72-79: TB9 + hdr.ipv6.src_addr.80-87: TB10 + hdr.ipv6.src_addr.88-95: TB11 + hdr.ipv6.src_addr.96-127: W36 + hdr.ipv6.dst_addr.0-31: W37 + hdr.ipv6.dst_addr.32-63: W38 + hdr.ipv6.dst_addr.64-95: W39 + hdr.ipv6.dst_addr.96-127: W40 + hdr.vlan_tag$0.pcp: H4(13..15) + hdr.vlan_tag$0.cfi: H4(12) + hdr.vlan_tag$0.vid: H4(0..11) + hdr.vlan_tag$0.ether_type: TH4 + hdr.vlan_tag$1.pcp: TH5(13..15) + hdr.vlan_tag$1.cfi: TH5(12) + hdr.vlan_tag$1.vid: TH5(0..11) + hdr.vlan_tag$1.ether_type.0-7: TB2 + hdr.vlan_tag$1.ether_type.8-15: TB3 + hdr.vlan_tag$2.pcp: TW8(29..31) + hdr.vlan_tag$2.cfi: TW8(28) + hdr.vlan_tag$2.vid: TW8(16..27) + hdr.vlan_tag$2.ether_type: TW8(0..15) + hdr.vlan_tag$3.pcp: TW9(29..31) + hdr.vlan_tag$3.cfi: TW9(28) + hdr.vlan_tag$3.vid: TW9(16..27) + hdr.vlan_tag$3.ether_type: TW9(0..15) + hdr.vlan_tag$4.pcp: TW10(29..31) + hdr.vlan_tag$4.cfi: TW10(28) + hdr.vlan_tag$4.vid: TW10(16..27) + hdr.vlan_tag$4.ether_type: TW10(0..15) + hdr.mpls$0.label: TW11(12..31) + hdr.mpls$0.exp: TW11(9..11) + hdr.mpls$0.bos: TW11(8) + hdr.mpls$0.ttl: TW11(0..7) + hdr.mpls$1.label.0-3: TH12(12..15) + hdr.mpls$1.label.4-19: TH13 + hdr.mpls$1.exp: TH12(9..11) + hdr.mpls$1.bos: TH12(8) + hdr.mpls$1.ttl: TH12(0..7) + hdr.mpls$2.label.0-3: TH14(12..15) + hdr.mpls$2.label.4-19: TH15 + hdr.mpls$2.exp: TH14(9..11) + hdr.mpls$2.bos: TH14(8) + hdr.mpls$2.ttl: TH14(0..7) + hdr.mpls$3.label.0-3: TH16(12..15) + hdr.mpls$3.label.4-19: TH17 + hdr.mpls$3.exp: TH16(9..11) + hdr.mpls$3.bos: TH16(8) + hdr.mpls$3.ttl: TH16(0..7) + hdr.fabric.pad1: W5(31) + hdr.fabric.is_hit: W5(30) + hdr.fabric.is_to_cn78: W5(29) + hdr.fabric.is_to_td3: W5(28) + hdr.fabric.is_hdr_decap: W5(27) + hdr.fabric.ig_port_type: W5(24..26) + hdr.fabric.pad2: W5(18..23) + hdr.fabric.mac_index: W5(0..17) + hdr.fabric.pad4: B4(4..7) + hdr.fabric.flags_drop: B4(3) + hdr.fabric.is_trunc_mir: B4(2) + hdr.fabric.count_index.0-15: W3(16..31) + hdr.fabric.count_index.16-17: B4(0..1) + hdr.fabric.mc_index: W3(0..15) + hdr.fabric.vlan_index: W4(16..31) + hdr.fabric.ether_type: W4(0..15) + hdr.fabric_from_cn78.action_type: W4(24..31) + hdr.fabric_from_cn78.port_group_id: W3(16..31) + hdr.fabric_from_cn78.ether_type: W3(0..15) + ig_intr_md_for_tm.ucast_egress_port: H1(0..8) + ig_intr_md_for_tm.bypass_egress: B2(5) + ig_intr_md_for_tm.mcast_grp_b: H0 + ig_intr_md_for_tm.level1_mcast_hash: W0(0..12) + ig_intr_md_for_tm.level2_mcast_hash: W1(0..12) + ig_intr_md_for_dprsr.drop_ctl: B3(4..6) + ig_intr_md_for_dprsr.mirror_type: B1(0..2) + __pad_3: H2(10..15) + __pad_4: H6(10..15) + hdr.bridged_md.$valid: W41(0) + hdr.ethernet.$valid: W41(1) + hdr.ipv4.$valid: W41(2) + hdr.tcp.$valid: W41(3) + hdr.gtpv2_8b.$valid: W41(4) + hdr.imsi.$valid: W41(5) + hdr.cause_ie_6b.$valid: W41(6) + hdr.cause_ie_10b.$valid: W41(7) + hdr.inner_ipv4.$valid: W41(8) + hdr.inner_tcp.$valid: W41(9) + hdr.sip.$valid: W41(10) + hdr.inner_udp.$valid: W41(11) + hdr.inner_icmp.$valid: W41(12) + hdr.ipsec_esp.$valid: W41(13) + hdr.inner_ipv6.$valid: W41(14) + hdr.gtpv2_12b.$valid: W41(15) + hdr.udp.$valid: W41(16) + hdr.vxlan.$valid: W41(17) + hdr.inner_ethernet.$valid: W41(18) + hdr.gtpv1_8b.$valid: W41(19) + hdr.gtpv1_12b.$valid: W41(20) + hdr.l2tp.$valid: W41(21) + hdr.pppoe.$valid: W41(22) + hdr.icmp.$valid: W41(23) + hdr.sctp.$valid: W41(24) + hdr.gre.$valid: W41(25) + hdr.ipv6.$valid: W41(26) + hdr.fabric.$valid: W41(27) + hdr.fabric_from_cn78.$valid: W41(28) + hdr.mpls.$stkvalid: B3(0..3) + hdr.mpls$0.$valid: B3(3) + hdr.mpls$1.$valid: B3(2) + hdr.mpls$2.$valid: B3(1) + hdr.mpls$3.$valid: B3(0) + hdr.vlan_tag.$stkvalid: B2(0..4) + hdr.vlan_tag$0.$valid: B2(4) + hdr.vlan_tag$1.$valid: B2(3) + hdr.vlan_tag$2.$valid: B2(2) + hdr.vlan_tag$3.$valid: B2(1) + hdr.vlan_tag$4.$valid: B2(0) + context_json: + TB8: + - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.flags, hdr.ipv4.frag_offset ] } + TB9: + - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.frag_offset ] } + TB10: + - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.identification ] } + TB11: + - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.identification ] } + TH29: + - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.src_addr ] } + TH36: + - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.src_addr ] } + TH37: + - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.dst_addr ] } + TH38: + - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.dst_addr ] } + TW26: + - { name : hdr.ethernet.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B0: + - { name : hdr.bridged_md.src, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + B1: + - { name : ig_intr_md_for_dprsr.mirror_type, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } + B2: + - { name : hdr.vlan_tag$0.$valid, live_start : 0, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan_tag$1.$valid, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan_tag$2.$valid, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan_tag$3.$valid, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan_tag$4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan_tag.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_intr_md_for_tm.bypass_egress, live_start : 0, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_md.trunc_type, live_start : 9, live_end : 11, mutually_exclusive_with: [ ] } + B3: + - { name : hdr.mpls$0.$valid, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.mpls$1.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.mpls$2.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.mpls$3.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.mpls.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_intr_md_for_dprsr.drop_ctl, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } + B4: + - { name : hdr.fabric.count_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.flags_drop, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.is_trunc_mir, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.pad4, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B5: + - { name : ig_md.count_index, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + B6: + - { name : hdr.bridged_md.in_ig_port_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.bridged_md.tunnel_type, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_md.in_ig_port_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_md.tunnel_type, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } + B7: + - { name : hdr.bridged_md.pad1, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.bridged_md.tunnel_type, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_md.tunnel_type, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } + B8: + - { name : hdr.inner_ipv6.next_hdr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B9: + - { name : ig_md.mirror.src, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } + B10: + - { name : ig_md.mirror.type, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } + B11: + - { name : ig_md.lkp.ip_proto, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } + H0: + - { name : ig_intr_md_for_tm.mcast_grp_b, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } + H1: + - { name : ig_intr_md_for_tm.ucast_egress_port, live_start : 10, live_end : deparser, mutually_exclusive_with: [ ] } + H2: + - { name : __pad_3, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_md.mirror.session_id, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } + H3: + - { name : hdr.bridged_md.ip_hdr_location, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.bridged_md.pkt_proto_type, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_md.ip_hdr_location, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_md.pkt_proto_type, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } + H4: + - { name : hdr.vlan_tag$0.cfi, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan_tag$0.pcp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan_tag$0.vid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H5: + - { name : hdr.ethernet.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H6: + - { name : __pad_4, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_md.count_index, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + H7: + - { name : hdr.ethernet.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H8: + - { name : ig_md.vlan_index, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + H9: + - { name : ig_md.lkp.l4_src_port, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } + H10: + - { name : ig_md.lkp.inner_l4_src_port, live_start : parser, live_end : 9, mutually_exclusive_with: [ ] } + H11: + - { name : ig_md.lkp.l4_dst_port, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } + H12: + - { name : ig_md.lkp.inner_l4_dst_port, live_start : parser, live_end : 9, mutually_exclusive_with: [ ] } + W0: + - { name : ig_intr_md_for_tm.level1_mcast_hash, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_md.port_group_id, live_start : 0, live_end : 1, mutually_exclusive_with: [ ] } + W1: + - { name : ig_intr_md_for_tm.level2_mcast_hash, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_md.action_type, live_start : 0, live_end : 1, mutually_exclusive_with: [ ] } + W2: + - { name : ig_md.hash, live_start : 0, live_end : 11, mutually_exclusive_with: [ ] } + W3: + - { name : hdr.fabric.count_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.fabric_from_cn78.ether_type, hdr.fabric_from_cn78.port_group_id ] } + - { name : hdr.fabric.mc_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.fabric_from_cn78.ether_type, hdr.fabric_from_cn78.port_group_id ] } + - { name : hdr.fabric_from_cn78.ether_type, live_start : parser, live_end : 0, mutually_exclusive_with: [ hdr.fabric.count_index, hdr.fabric.mc_index ] } + - { name : hdr.fabric_from_cn78.port_group_id, live_start : parser, live_end : 0, mutually_exclusive_with: [ hdr.fabric.count_index, hdr.fabric.mc_index ] } + W4: + - { name : hdr.fabric.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.fabric_from_cn78.action_type ] } + - { name : hdr.fabric.vlan_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.fabric_from_cn78.action_type ] } + - { name : hdr.fabric_from_cn78.action_type, live_start : parser, live_end : 0, mutually_exclusive_with: [ hdr.fabric.ether_type, hdr.fabric.vlan_index ] } + W5: + - { name : hdr.fabric.ig_port_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.is_hdr_decap, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.is_hit, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.is_to_cn78, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.is_to_td3, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.mac_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.pad1, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.pad2, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W6: + - { name : hdr.inner_tcp.seq_no, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W7: + - { name : hdr.inner_tcp.ack_no, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W8: + - { name : hdr.sip.data, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W9: + - { name : hdr.ipsec_esp.spi, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W10: + - { name : hdr.ipsec_esp.sn, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W11: + - { name : hdr.inner_ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W12: + - { name : hdr.inner_ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W13: + - { name : hdr.inner_ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W14: + - { name : hdr.inner_ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W15: + - { name : hdr.inner_ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W32: + - { name : hdr.inner_ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W33: + - { name : hdr.inner_ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W34: + - { name : hdr.inner_ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W35: + - { name : hdr.gtpv2_12b.teid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W36: + - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W37: + - { name : hdr.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W38: + - { name : hdr.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W39: + - { name : hdr.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W40: + - { name : hdr.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W41: + - { name : hdr.bridged_md.$valid, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.cause_ie_10b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.cause_ie_6b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ethernet.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_from_cn78.$valid, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } + - { name : hdr.gre.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.gtpv1_12b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.gtpv1_8b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.gtpv2_12b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.gtpv2_8b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.icmp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.imsi.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.inner_ethernet.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.inner_icmp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.inner_ipv4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.inner_ipv6.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.inner_tcp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.inner_udp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ipsec_esp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ipv4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ipv6.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.l2tp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.pppoe.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.sctp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.sip.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.tcp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.udp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vxlan.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W49: + - { name : ig_md.lkp.ip_src_addr, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } + W50: + - { name : ig_md.lkp.ip_src_addr, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } + W51: + - { name : ig_md.lkp.ip_src_addr, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } + W52: + - { name : ig_md.lkp.ip_src_addr, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } + W53: + - { name : ig_md.lkp.ip_dst_addr, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } + W54: + - { name : ig_md.lkp.ip_dst_addr, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } + W55: + - { name : ig_md.lkp.ip_dst_addr, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } + W56: + - { name : ig_md.lkp.ip_dst_addr, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } +phv egress: + eg_intr_md.egress_port: H16(0..8) + eg_md.lkp.inner_l4_src_port: H25 + eg_md.lkp.inner_l4_dst_port: H26 + eg_md.in_ig_port_type: B20(0..2) + eg_md.ip_hdr_location: H23(0..7) + eg_md.pkt_proto_type: H23(8..15) + hdr.fabric_to_cn78.pkt_proto_type: H23(8..15) + hdr.fabric_to_cn78.ip_hdr_location: H23(0..7) + hdr.fabric_to_cn78.payload_crc32: TH7 + hdr.fabric_to_cn78.ether_type: H18 + hdr.ethernet.dst_addr.0-15: H24 + hdr.ethernet.dst_addr.16-47: TW31 + hdr.ethernet.src_addr.0-15: TH6 + hdr.ethernet.src_addr.16-31: TH35 + hdr.ethernet.src_addr.32-47: TH42 + hdr.ethernet.ether_type: H19 + hdr.ipv4.version: TW4(28..31) + hdr.ipv4.ihl: TW4(24..27) + hdr.ipv4.diffserv: TW4(16..23) + hdr.ipv4.total_len: TW4(0..15) + hdr.ipv4.identification: TW20(16..31) + hdr.ipv4.flags: TW20(13..15) + hdr.ipv4.frag_offset: TW20(0..12) + hdr.ipv4.ttl: TH31(8..15) + hdr.ipv4.protocol: TH31(0..7) + hdr.ipv4.hdr_checksum: TW22(0..15) + hdr.ipv4.src_addr.0-15: TH43 + hdr.ipv4.src_addr.16-31: TH44 + hdr.ipv4.dst_addr.0-15: TH45 + hdr.ipv4.dst_addr.16-31: TH46 + hdr.tcp.src_port: TW23(16..31) + hdr.tcp.dst_port: TW23(0..15) + hdr.tcp.seq_no: TW30 + hdr.tcp.ack_no.0-7: TB23 + hdr.tcp.ack_no.8-15: TB28 + hdr.tcp.ack_no.16-31: TH47 + hdr.tcp.data_offset: TW5(28..31) + hdr.tcp.res: TW5(24..27) + hdr.tcp.flags: TW5(16..23) + hdr.tcp.window: TW5(0..15) + hdr.tcp.checksum: TH32 + hdr.tcp.urgent_ptr.0-7: TB21 + hdr.tcp.urgent_ptr.8-15: TB22 + hdr.gtpv2_8b.version: TH8(13..15) + hdr.gtpv2_8b.pb: TH8(12) + hdr.gtpv2_8b.tf: TH8(11) + hdr.gtpv2_8b.spare1: TH8(8..10) + hdr.gtpv2_8b.message_type: TH8(0..7) + hdr.gtpv2_8b.total_len: TH9 + hdr.gtpv2_8b.seq_no.0-7: TH33(8..15) + hdr.gtpv2_8b.seq_no.8-23: TH34 + hdr.gtpv2_8b.spare2: TH33(0..7) + hdr.imsi.type: TW6(24..31) + hdr.imsi.len: TW6(8..23) + hdr.imsi.spare: TW6(4..7) + hdr.imsi.instance: TW6(0..3) + hdr.imsi.num_digit.0-31: TW21 + hdr.imsi.num_digit.32-63: TW28 + hdr.imsi.num_digit.64-95: TW29 + hdr.imsi.num_digit.96-103: TB20 + hdr.imsi.num_digit.104-111: TB29 + hdr.imsi.num_digit.112-127: TH30 + hdr.cause_ie_6b.type: TB5 + hdr.cause_ie_6b.len: TW7(16..31) + hdr.cause_ie_6b.spare1: TW7(12..15) + hdr.cause_ie_6b.instance: TW7(8..11) + hdr.cause_ie_6b.cause_value: TW7(0..7) + hdr.cause_ie_6b.spare2: TB4(3..7) + hdr.cause_ie_6b.pce: TB4(2) + hdr.cause_ie_6b.bce: TB4(1) + hdr.cause_ie_6b.cs: TB4(0) + hdr.cause_ie_10b.type: TB5 + hdr.cause_ie_10b.len: TW7(16..31) + hdr.cause_ie_10b.spare1: TW7(12..15) + hdr.cause_ie_10b.instance: TW7(8..11) + hdr.cause_ie_10b.cause_value: TW7(0..7) + hdr.cause_ie_10b.spare2: TB4(3..7) + hdr.cause_ie_10b.pce: TB4(2) + hdr.cause_ie_10b.bce: TB4(1) + hdr.cause_ie_10b.cs: TB4(0) + hdr.cause_ie_10b.type_oe: TH11(8..15) + hdr.cause_ie_10b.len_oe.0-7: TH10(8..15) + hdr.cause_ie_10b.len_oe.8-15: TH11(0..7) + hdr.cause_ie_10b.spare_oe: TH10(4..7) + hdr.cause_ie_10b.instance_oe: TH10(0..3) + hdr.inner_ipv4.version: TW6(28..31) + hdr.inner_ipv4.ihl: TW6(24..27) + hdr.inner_ipv4.diffserv: TW6(16..23) + hdr.inner_ipv4.total_len: TW6(0..15) + hdr.inner_ipv4.identification: TH30 + hdr.inner_ipv4.flags: TH11(13..15) + hdr.inner_ipv4.frag_offset: TH11(0..12) + hdr.inner_ipv4.ttl: TW21(24..31) + hdr.inner_ipv4.protocol: TW21(16..23) + hdr.inner_ipv4.hdr_checksum: TW21(0..15) + hdr.inner_ipv4.src_addr.0-7: TB20 + hdr.inner_ipv4.src_addr.8-15: TB29 + hdr.inner_ipv4.src_addr.16-23: TB30 + hdr.inner_ipv4.src_addr.24-31: TB31 + hdr.inner_ipv4.dst_addr: W18 + hdr.inner_tcp.src_port: TW28(16..31) + hdr.inner_tcp.dst_port: TW28(0..15) + hdr.inner_tcp.seq_no: W19 + hdr.inner_tcp.ack_no: W20 + hdr.inner_tcp.data_offset: TW7(28..31) + hdr.inner_tcp.res: TW7(24..27) + hdr.inner_tcp.flags: TW7(16..23) + hdr.inner_tcp.window: TW7(0..15) + hdr.inner_tcp.checksum: TW29(16..31) + hdr.inner_tcp.urgent_ptr: TW29(0..15) + hdr.sip.data: W21 + hdr.inner_udp.src_port: TW7(16..31) + hdr.inner_udp.dst_port: TW7(0..15) + hdr.inner_udp.hdr_length: TW28(16..31) + hdr.inner_udp.checksum: TW28(0..15) + hdr.inner_icmp.type_: TW7(24..31) + hdr.inner_icmp.code: TW7(16..23) + hdr.inner_icmp.hdr_checksum: TW7(0..15) + hdr.ipsec_esp.spi: W22 + hdr.ipsec_esp.sn: W23 + hdr.inner_ipv6.version: TW6(28..31) + hdr.inner_ipv6.traffic_class: TW6(20..27) + hdr.inner_ipv6.flow_label: TW6(0..19) + hdr.inner_ipv6.payload_len: TH11 + hdr.inner_ipv6.next_hdr: B19 + hdr.inner_ipv6.hop_limit: TB20 + hdr.inner_ipv6.src_addr.0-31: W18 + hdr.inner_ipv6.src_addr.32-63: W24 + hdr.inner_ipv6.src_addr.64-95: W25 + hdr.inner_ipv6.src_addr.96-127: W26 + hdr.inner_ipv6.dst_addr.0-31: W27 + hdr.inner_ipv6.dst_addr.32-63: W28 + hdr.inner_ipv6.dst_addr.64-95: W29 + hdr.inner_ipv6.dst_addr.96-127: W30 + hdr.gtpv2_12b.version: TH8(13..15) + hdr.gtpv2_12b.pb: TH8(12) + hdr.gtpv2_12b.tf: TH8(11) + hdr.gtpv2_12b.spare1: TH8(8..10) + hdr.gtpv2_12b.message_type: TH8(0..7) + hdr.gtpv2_12b.total_len: TH9 + hdr.gtpv2_12b.teid: W31 + hdr.gtpv2_12b.seq_no.0-7: TH33(8..15) + hdr.gtpv2_12b.seq_no.8-23: TH34 + hdr.gtpv2_12b.spare2: TH33(0..7) + hdr.udp.src_port: TW23(16..31) + hdr.udp.dst_port: TW23(0..15) + hdr.udp.hdr_length: TH32 + hdr.udp.checksum.0-7: TB22 + hdr.udp.checksum.8-15: TB23 + hdr.vxlan.flags: TW5(24..31) + hdr.vxlan.reserved: TW5(0..23) + hdr.vxlan.vni.0-7: TH8(8..15) + hdr.vxlan.vni.8-23: TH9 + hdr.vxlan.reserved2: TH8(0..7) + hdr.inner_ethernet.dst_addr.0-7: TB4 + hdr.inner_ethernet.dst_addr.8-15: TB5 + hdr.inner_ethernet.dst_addr.16-47: TW30 + hdr.inner_ethernet.src_addr.0-15: TH33 + hdr.inner_ethernet.src_addr.16-31: TH34 + hdr.inner_ethernet.src_addr.32-47: TH47 + hdr.inner_ethernet.ether_type: TH10 + hdr.gtpv1_8b.version: TH8(13..15) + hdr.gtpv1_8b.pt: TH8(12) + hdr.gtpv1_8b.reserved: TH8(11) + hdr.gtpv1_8b.e: TH8(10) + hdr.gtpv1_8b.s: TH8(9) + hdr.gtpv1_8b.pn: TH8(8) + hdr.gtpv1_8b.message_type: TH8(0..7) + hdr.gtpv1_8b.message_len: TH9 + hdr.gtpv1_8b.teid: TW5 + hdr.gtpv1_12b.version: TH8(13..15) + hdr.gtpv1_12b.pt: TH8(12) + hdr.gtpv1_12b.reserved: TH8(11) + hdr.gtpv1_12b.e: TH8(10) + hdr.gtpv1_12b.s: TH8(9) + hdr.gtpv1_12b.pn: TH8(8) + hdr.gtpv1_12b.message_type: TH8(0..7) + hdr.gtpv1_12b.message_len: TH9 + hdr.gtpv1_12b.teid: TW30 + hdr.gtpv1_12b.seq_no: TW5(16..31) + hdr.gtpv1_12b.n_pdu_no: TW5(8..15) + hdr.gtpv1_12b.next_ex_hdr_t: TW5(0..7) + hdr.l2tp.TLxxSxOP: TW5(20..31) + hdr.l2tp.version: TW5(16..19) + hdr.l2tp.l2tp_length: TW5(8..15) + hdr.l2tp.tunnel_id.0-7: TB4 + hdr.l2tp.tunnel_id.8-15: TW5(0..7) + hdr.l2tp.session_id: TH34 + hdr.l2tp.Ns: TH33 + hdr.l2tp.Nr: TH8 + hdr.l2tp.offset_size: TB21 + hdr.l2tp.offset_pad: TB5 + hdr.pppoe.version: TH9(12..15) + hdr.pppoe.type: TH9(8..11) + hdr.pppoe.code: TH9(0..7) + hdr.pppoe.session_id: TH10 + hdr.pppoe.pppoe_length: TW30(16..31) + hdr.pppoe.ppp_proto: TW30(0..15) + hdr.icmp.type_: TW5(24..31) + hdr.icmp.code: TW5(16..23) + hdr.icmp.hdr_checksum: TW5(0..15) + hdr.sctp.src_port: TW5(16..31) + hdr.sctp.dst_port: TW5(0..15) + hdr.sctp.verifTag: TW6 + hdr.sctp.checksum: TH8 + hdr.gre.C: TH8(15) + hdr.gre.R: TH8(14) + hdr.gre.K: TH8(13) + hdr.gre.S: TH8(12) + hdr.gre.s: TH8(11) + hdr.gre.recurse: TH8(8..10) + hdr.gre.flags: TH8(3..7) + hdr.gre.version: TH8(0..2) + hdr.gre.proto.0-7: TB4 + hdr.gre.proto.8-15: TB5 + hdr.ipv6.version: TW4(28..31) + hdr.ipv6.traffic_class: TW4(20..27) + hdr.ipv6.flow_label: TW4(0..19) + hdr.ipv6.payload_len: TW20(16..31) + hdr.ipv6.next_hdr: TW20(8..15) + hdr.ipv6.hop_limit: TW20(0..7) + hdr.ipv6.src_addr.0-15: TH31 + hdr.ipv6.src_addr.16-31: TH43 + hdr.ipv6.src_addr.32-47: TH44 + hdr.ipv6.src_addr.48-63: TH45 + hdr.ipv6.src_addr.64-95: TW22 + hdr.ipv6.src_addr.96-111: TH46 + hdr.ipv6.src_addr.112-127: H22 + hdr.ipv6.dst_addr.0-31: W44 + hdr.ipv6.dst_addr.32-63: W45 + hdr.ipv6.dst_addr.64-95: W46 + hdr.ipv6.dst_addr.96-127: W47 + hdr.vlan_tag$0.pcp: H21(13..15) + hdr.vlan_tag$0.cfi: H21(12) + hdr.vlan_tag$0.vid: H21(0..11) + hdr.vlan_tag$0.ether_type.0-7: TB6 + hdr.vlan_tag$0.ether_type.8-15: TB7 + hdr.vlan_tag$1.pcp: TW12(29..31) + hdr.vlan_tag$1.cfi: TW12(28) + hdr.vlan_tag$1.vid: TW12(16..27) + hdr.vlan_tag$1.ether_type: TW12(0..15) + hdr.vlan_tag$2.pcp: TW13(29..31) + hdr.vlan_tag$2.cfi: TW13(28) + hdr.vlan_tag$2.vid: TW13(16..27) + hdr.vlan_tag$2.ether_type: TW13(0..15) + hdr.vlan_tag$3.pcp: TW14(29..31) + hdr.vlan_tag$3.cfi: TW14(28) + hdr.vlan_tag$3.vid: TW14(16..27) + hdr.vlan_tag$3.ether_type: TW14(0..15) + hdr.vlan_tag$4.pcp: TW15(29..31) + hdr.vlan_tag$4.cfi: TW15(28) + hdr.vlan_tag$4.vid: TW15(16..27) + hdr.vlan_tag$4.ether_type: TW15(0..15) + hdr.mpls$0.label.0-3: TH18(12..15) + hdr.mpls$0.label.4-19: TH19 + hdr.mpls$0.exp: TH18(9..11) + hdr.mpls$0.bos: TH18(8) + hdr.mpls$0.ttl: TH18(0..7) + hdr.mpls$1.label.0-3: TH20(12..15) + hdr.mpls$1.label.4-19: TH21 + hdr.mpls$1.exp: TH20(9..11) + hdr.mpls$1.bos: TH20(8) + hdr.mpls$1.ttl: TH20(0..7) + hdr.mpls$2.label.0-3: TH22(12..15) + hdr.mpls$2.label.4-19: TH23 + hdr.mpls$2.exp: TH22(9..11) + hdr.mpls$2.bos: TH22(8) + hdr.mpls$2.ttl: TH22(0..7) + hdr.mpls$3.label.0-3: TB12(4..7) + hdr.mpls$3.label.4-11: TB14 + hdr.mpls$3.label.12-19: TB15 + hdr.mpls$3.exp: TB12(1..3) + hdr.mpls$3.bos: TB12(0) + hdr.mpls$3.ttl: TB13 + hdr.fabric.pad1: W16(31) + hdr.fabric.is_hit: W16(30) + hdr.fabric.is_to_cn78: W16(29) + hdr.fabric.is_to_td3: W16(28) + hdr.fabric.is_hdr_decap: W16(27) + hdr.fabric.ig_port_type: W16(24..26) + hdr.fabric.pad2: W16(18..23) + hdr.fabric.mac_index: W16(0..17) + hdr.fabric.pad4: W17(28..31) + hdr.fabric.flags_drop: W17(27) + hdr.fabric.is_trunc_mir: W17(26) + hdr.fabric.count_index: W17(8..25) + hdr.fabric.mc_index.0-7: B18 + hdr.fabric.mc_index.8-15: W17(0..7) + hdr.fabric.vlan_index: H20 + hdr.fabric.ether_type: H17 + hdr.fabric_to_cn78.$valid: W48(0) + hdr.ethernet.$valid: W48(1) + hdr.ipv4.$valid: W48(2) + hdr.tcp.$valid: W48(3) + hdr.gtpv2_8b.$valid: W48(4) + hdr.imsi.$valid: W48(5) + hdr.cause_ie_6b.$valid: W48(6) + hdr.cause_ie_10b.$valid: W48(7) + hdr.inner_ipv4.$valid: W48(8) + hdr.inner_tcp.$valid: W48(9) + hdr.sip.$valid: W48(10) + hdr.inner_udp.$valid: W48(11) + hdr.inner_icmp.$valid: W48(12) + hdr.ipsec_esp.$valid: W48(13) + hdr.inner_ipv6.$valid: W48(14) + hdr.gtpv2_12b.$valid: W48(15) + hdr.udp.$valid: W48(16) + hdr.vxlan.$valid: W48(17) + hdr.inner_ethernet.$valid: W48(18) + hdr.gtpv1_8b.$valid: W48(19) + hdr.gtpv1_12b.$valid: W48(20) + hdr.l2tp.$valid: W48(21) + hdr.pppoe.$valid: W48(22) + hdr.icmp.$valid: W48(23) + hdr.sctp.$valid: W48(24) + hdr.gre.$valid: W48(25) + hdr.ipv6.$valid: W48(26) + hdr.fabric.$valid: W48(27) + hdr.mpls.$stkvalid: B17(0..3) + hdr.mpls$0.$valid: B17(3) + hdr.mpls$1.$valid: B17(2) + hdr.mpls$2.$valid: B17(1) + hdr.mpls$3.$valid: B17(0) + hdr.vlan_tag.$stkvalid: B16(0..4) + hdr.vlan_tag$0.$valid: B16(4) + hdr.vlan_tag$1.$valid: B16(3) + hdr.vlan_tag$2.$valid: B16(2) + hdr.vlan_tag$3.$valid: B16(1) + hdr.vlan_tag$4.$valid: B16(0) + context_json: + TH31: + - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.protocol, hdr.ipv4.ttl ] } + TH43: + - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.src_addr ] } + TH44: + - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.src_addr ] } + TH45: + - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.dst_addr ] } + TH46: + - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.dst_addr ] } + TW22: + - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.hdr_checksum ] } + TW31: + - { name : hdr.ethernet.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B16: + - { name : hdr.vlan_tag$0.$valid, live_start : 0, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan_tag$1.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan_tag$2.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan_tag$3.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan_tag$4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan_tag.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B17: + - { name : hdr.mpls$0.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.mpls$1.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.mpls$2.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.mpls$3.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.mpls.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B18: + - { name : hdr.fabric.mc_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B19: + - { name : hdr.inner_ipv6.next_hdr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B20: + - { name : eg_md.in_ig_port_type, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } + H16: + - { name : eg_intr_md.egress_port, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H17: + - { name : hdr.fabric.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H18: + - { name : hdr.fabric_to_cn78.ether_type, live_start : 1, live_end : deparser, mutually_exclusive_with: [ ] } + H19: + - { name : hdr.ethernet.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H20: + - { name : hdr.fabric.vlan_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H21: + - { name : hdr.vlan_tag$0.cfi, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan_tag$0.pcp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vlan_tag$0.vid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H22: + - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H23: + - { name : eg_md.ip_hdr_location, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : eg_md.pkt_proto_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_to_cn78.ip_hdr_location, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_to_cn78.pkt_proto_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H24: + - { name : hdr.ethernet.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H25: + - { name : eg_md.lkp.inner_l4_src_port, live_start : parser, live_end : 3, mutually_exclusive_with: [ ] } + H26: + - { name : eg_md.lkp.inner_l4_dst_port, live_start : parser, live_end : 3, mutually_exclusive_with: [ ] } + W16: + - { name : hdr.fabric.ig_port_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.is_hdr_decap, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.is_hit, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.is_to_cn78, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.is_to_td3, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.mac_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.pad1, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.pad2, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W17: + - { name : hdr.fabric.count_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.flags_drop, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.is_trunc_mir, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.mc_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.pad4, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W18: + - { name : hdr.inner_ipv4.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.inner_ipv6.src_addr ] } + - { name : hdr.inner_ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.inner_ipv4.dst_addr ] } + W19: + - { name : hdr.inner_tcp.seq_no, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W20: + - { name : hdr.inner_tcp.ack_no, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W21: + - { name : hdr.sip.data, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W22: + - { name : hdr.ipsec_esp.spi, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W23: + - { name : hdr.ipsec_esp.sn, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W24: + - { name : hdr.inner_ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W25: + - { name : hdr.inner_ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W26: + - { name : hdr.inner_ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W27: + - { name : hdr.inner_ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W28: + - { name : hdr.inner_ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W29: + - { name : hdr.inner_ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W30: + - { name : hdr.inner_ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W31: + - { name : hdr.gtpv2_12b.teid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W44: + - { name : hdr.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W45: + - { name : hdr.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W46: + - { name : hdr.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W47: + - { name : hdr.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W48: + - { name : hdr.cause_ie_10b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.cause_ie_6b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ethernet.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_to_cn78.$valid, live_start : 1, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.gre.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.gtpv1_12b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.gtpv1_8b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.gtpv2_12b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.gtpv2_8b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.icmp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.imsi.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.inner_ethernet.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.inner_icmp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.inner_ipv4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.inner_ipv6.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.inner_tcp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.inner_udp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ipsec_esp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ipv4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ipv6.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.l2tp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.pppoe.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.sctp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.sip.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.tcp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.udp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.vxlan.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } +parser ingress: + start: $entry_point + init_zero: [ B11, W49, W50, W51, W52, W53, W54, W55, W56, H9, H11, H10, H12, B5, H6, W2, B6, B2, W1, W0, H8, B9, B10, H2, B3, W41, B0 ] + bitwise_or: [ B2, B3, W41 ] + hdr_len_adj: 16 + states: + $entry_point: + *: + load: { byte1 : 0 } + buf_req: 1 + next: start + start: + match: [ byte1 ] + 0b1*******: + shift: 8 + buf_req: 8 + next: end + 0b0*******: + load: { half : 28..29 } + shift: 8 + buf_req: 30 + next: TofinoIngressParserInner_2_parse_port_metadata + TofinoIngressParserInner_2_parse_port_metadata: + match: [ half ] + 0x0800: + 0: B6 # bit[5..7] -> B6 bit[2..0]: ingress::ig_md.in_ig_port_type + 8..11: TW26 # ingress::hdr.ethernet.dst_addr[47:16].16-47 + 12..13: H7 # ingress::hdr.ethernet.dst_addr[15:0].0-15 + 14..17: TW27 # ingress::hdr.ethernet.src_addr[47:16].16-47 + 18..19: TH25 # ingress::hdr.ethernet.src_addr[15:0].0-15 + 20..21: H5 # ingress::hdr.ethernet.ether_type + W41: 2 # value 1 -> W41 bit[1]: ingress::hdr.ethernet.$valid + shift: 22 + buf_req: 22 + next: parse_ipv4 + 0x86dd: + 0: B6 # bit[5..7] -> B6 bit[2..0]: ingress::ig_md.in_ig_port_type + 8..11: TW26 # ingress::hdr.ethernet.dst_addr[47:16].16-47 + 12..13: H7 # ingress::hdr.ethernet.dst_addr[15:0].0-15 + 14..17: TW27 # ingress::hdr.ethernet.src_addr[47:16].16-47 + 18..19: TH25 # ingress::hdr.ethernet.src_addr[15:0].0-15 + 20..21: H5 # ingress::hdr.ethernet.ether_type + W41: 2 # value 1 -> W41 bit[1]: ingress::hdr.ethernet.$valid + shift: 22 + buf_req: 22 + next: parse_ipv6 + 0x8100: + 0: B6 # bit[5..7] -> B6 bit[2..0]: ingress::ig_md.in_ig_port_type + 8..11: TW26 # ingress::hdr.ethernet.dst_addr[47:16].16-47 + 12..13: H7 # ingress::hdr.ethernet.dst_addr[15:0].0-15 + 14..17: TW27 # ingress::hdr.ethernet.src_addr[47:16].16-47 + 18..19: TH25 # ingress::hdr.ethernet.src_addr[15:0].0-15 + 20..21: H5 # ingress::hdr.ethernet.ether_type + W41: 2 # value 1 -> W41 bit[1]: ingress::hdr.ethernet.$valid + load: { half : 24..25 } + shift: 22 + buf_req: 26 + next: parse_vlan + 0x8847: + 0: B6 # bit[5..7] -> B6 bit[2..0]: ingress::ig_md.in_ig_port_type + 8..11: TW26 # ingress::hdr.ethernet.dst_addr[47:16].16-47 + 12..13: H7 # ingress::hdr.ethernet.dst_addr[15:0].0-15 + 14..17: TW27 # ingress::hdr.ethernet.src_addr[47:16].16-47 + 18..19: TH25 # ingress::hdr.ethernet.src_addr[15:0].0-15 + 20..21: H5 # ingress::hdr.ethernet.ether_type + W41: 2 # value 1 -> W41 bit[1]: ingress::hdr.ethernet.$valid + load: { byte1 : 24 } + shift: 22 + buf_req: 25 + next: parse_mpls + 0x81fe: + 0: B6 # bit[5..7] -> B6 bit[2..0]: ingress::ig_md.in_ig_port_type + 8..11: TW26 # ingress::hdr.ethernet.dst_addr[47:16].16-47 + 12..13: H7 # ingress::hdr.ethernet.dst_addr[15:0].0-15 + 14..17: TW27 # ingress::hdr.ethernet.src_addr[47:16].16-47 + 18..19: TH25 # ingress::hdr.ethernet.src_addr[15:0].0-15 + 20..21: H5 # ingress::hdr.ethernet.ether_type + W41: 2 # value 1 -> W41 bit[1]: ingress::hdr.ethernet.$valid + shift: 22 + buf_req: 22 + next: TofinoIngressParserInner_2_parse_port_metadata.$oob_stall_0 + 0x81ff: + 0: B6 # bit[5..7] -> B6 bit[2..0]: ingress::ig_md.in_ig_port_type + 8..11: TW26 # ingress::hdr.ethernet.dst_addr[47:16].16-47 + 12..13: H7 # ingress::hdr.ethernet.dst_addr[15:0].0-15 + 14..17: TW27 # ingress::hdr.ethernet.src_addr[47:16].16-47 + 18..19: TH25 # ingress::hdr.ethernet.src_addr[15:0].0-15 + 20..21: H5 # ingress::hdr.ethernet.ether_type + W41: 2 # value 1 -> W41 bit[1]: ingress::hdr.ethernet.$valid + load: { half : 26..27 } + shift: 22 + buf_req: 28 + next: parse_from_cn78 + 0x****: + 0: B6 # bit[5..7] -> B6 bit[2..0]: ingress::ig_md.in_ig_port_type + 8..11: TW26 # ingress::hdr.ethernet.dst_addr[47:16].16-47 + 12..13: H7 # ingress::hdr.ethernet.dst_addr[15:0].0-15 + 14..17: TW27 # ingress::hdr.ethernet.src_addr[47:16].16-47 + 18..19: TH25 # ingress::hdr.ethernet.src_addr[15:0].0-15 + 20..21: H5 # ingress::hdr.ethernet.ether_type + W41: 2 # value 1 -> W41 bit[1]: ingress::hdr.ethernet.$valid + shift: 22 + buf_req: 22 + next: end + parse_ipv4: + *: + 0..3: TW0 + # - bit[0..3] -> TW0 bit[31..28]: ingress::hdr.ipv4.version + # - bit[4..7] -> TW0 bit[27..24]: ingress::hdr.ipv4.ihl + # - bit[8..15] -> TW0 bit[23..16]: ingress::hdr.ipv4.diffserv + # - bit[16..31] -> TW0 bit[15..0]: ingress::hdr.ipv4.total_len + 4: TB11 # ingress::hdr.ipv4.identification[15:8].8-15 + 5: TB10 # ingress::hdr.ipv4.identification[7:0].0-7 + 6: TB8 + # - bit[48..50] -> TB8 bit[7..5]: ingress::hdr.ipv4.flags + # - bit[51..55] -> TB8 bit[4..0]: ingress::hdr.ipv4.frag_offset[12:8].8-12 + 7: TB9 # ingress::hdr.ipv4.frag_offset[7:0].0-7 + 8..11: TW16 + # - bit[64..71] -> TW16 bit[31..24]: ingress::hdr.ipv4.ttl + # - bit[72..79] -> TW16 bit[23..16]: ingress::hdr.ipv4.protocol + # - bit[80..95] -> TW16 bit[15..0]: ingress::hdr.ipv4.hdr_checksum + 12..13: TH36 # ingress::hdr.ipv4.src_addr[31:16].16-31 + 12..15: W49 # ingress::ig_md.lkp.ip_src_addr[31:0].0-31 + 14..15: TH29 # ingress::hdr.ipv4.src_addr[15:0].0-15 + 16..17: TH38 # ingress::hdr.ipv4.dst_addr[31:16].16-31 + 16..19: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 + 18..19: TH37 # ingress::hdr.ipv4.dst_addr[15:0].0-15 + load: { byte1 : 9 } + shift: 9 + buf_req: 20 + next: parse_ipv4.$split_0 + parse_ipv4.$split_0: + match: [ byte1 ] + 0x06: + 0: B11 # ingress::ig_md.lkp.ip_proto + W41: 4 # value 1 -> W41 bit[2]: ingress::hdr.ipv4.$valid + shift: 11 + buf_req: 11 + next: parse_tcp + 0x11: + 0: B11 # ingress::ig_md.lkp.ip_proto + W41: 4 # value 1 -> W41 bit[2]: ingress::hdr.ipv4.$valid + load: { half : 13..14 } + shift: 11 + buf_req: 15 + next: parse_udp + 0x01: + 0: B11 # ingress::ig_md.lkp.ip_proto + W41: 4 # value 1 -> W41 bit[2]: ingress::hdr.ipv4.$valid + shift: 11 + buf_req: 11 + next: parse_icmp + 0x84: + 0: B11 # ingress::ig_md.lkp.ip_proto + W41: 4 # value 1 -> W41 bit[2]: ingress::hdr.ipv4.$valid + load: { half : 13..14 } + shift: 11 + buf_req: 15 + next: parse_sctp + 0x29: + 0: B11 # ingress::ig_md.lkp.ip_proto + W41: 4 # value 1 -> W41 bit[2]: ingress::hdr.ipv4.$valid + shift: 11 + buf_req: 11 + next: parse_inner_ipv6 + 0x04: + 0: B11 # ingress::ig_md.lkp.ip_proto + W41: 4 # value 1 -> W41 bit[2]: ingress::hdr.ipv4.$valid + load: { byte1 : 20 } + shift: 11 + buf_req: 21 + next: parse_inner_ipv4 + 0x2f: + 0: B11 # ingress::ig_md.lkp.ip_proto + W41: 4 # value 1 -> W41 bit[2]: ingress::hdr.ipv4.$valid + load: { half : 12..13, byte0 : 14 } + shift: 11 + buf_req: 15 + next: parse_gre + 0x**: + 0: B11 # ingress::ig_md.lkp.ip_proto + W41: 4 # value 1 -> W41 bit[2]: ingress::hdr.ipv4.$valid + shift: 11 + buf_req: 11 + next: end + parse_tcp: + *: + 0..1: H9 # ingress::ig_md.lkp.l4_src_port + 0..3: TW18 + # - bit[0..15] -> TW18 bit[31..16]: ingress::hdr.tcp.src_port + # - bit[16..31] -> TW18 bit[15..0]: ingress::hdr.tcp.dst_port + 2..3: H11 # ingress::ig_md.lkp.l4_dst_port + 4..7: TW25 # ingress::hdr.tcp.seq_no + 8..9: TH39 # ingress::hdr.tcp.ack_no[31:16].16-31 + 10: TB24 # ingress::hdr.tcp.ack_no[15:8].8-15 + 11: TB19 # ingress::hdr.tcp.ack_no[7:0].0-7 + 12..15: TW1 + # - bit[96..99] -> TW1 bit[31..28]: ingress::hdr.tcp.data_offset + # - bit[100..103] -> TW1 bit[27..24]: ingress::hdr.tcp.res + # - bit[104..111] -> TW1 bit[23..16]: ingress::hdr.tcp.flags + # - bit[112..127] -> TW1 bit[15..0]: ingress::hdr.tcp.window + 16..19: TW19 + # - bit[128..143] -> TW19 bit[31..16]: ingress::hdr.tcp.checksum + # - bit[144..159] -> TW19 bit[15..0]: ingress::hdr.tcp.urgent_ptr + load: { half : 2..3 } + shift: 20 + buf_req: 20 + next: parse_tcp.$split_0 + parse_tcp.$split_0: + match: [ half ] + 0x01bb: + W41: 8 # value 1 -> W41 bit[3]: ingress::hdr.tcp.$valid + buf_req: 0 + next: end + 0x084b: + W41: 8 # value 1 -> W41 bit[3]: ingress::hdr.tcp.$valid + load: { byte1 : 0 } + buf_req: 1 + next: parse_gtpv2 + 0x****: + W41: 8 # value 1 -> W41 bit[3]: ingress::hdr.tcp.$valid + buf_req: 0 + next: end + parse_gtpv2: + match: [ byte1 ] + 0b***0****: + load: { byte1 : 1 } + buf_req: 2 + next: parse_gtpv2_8b + 0b***1****: + load: { byte1 : 1 } + buf_req: 2 + next: parse_gtpv2_12b + 0x**: + buf_req: 0 + next: end + parse_gtpv2_8b: + match: [ byte1 ] + 0x20: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len + 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 + 7: TB17 # ingress::hdr.gtpv2_8b.spare2 + W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x26: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len + 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 + 7: TB17 # ingress::hdr.gtpv2_8b.spare2 + W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x27: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len + 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 + 7: TB17 # ingress::hdr.gtpv2_8b.spare2 + W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x47: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len + 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 + 7: TB17 # ingress::hdr.gtpv2_8b.spare2 + W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x67: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len + 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 + 7: TB17 # ingress::hdr.gtpv2_8b.spare2 + W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x85: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len + 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 + 7: TB17 # ingress::hdr.gtpv2_8b.spare2 + W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x88: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len + 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 + 7: TB17 # ingress::hdr.gtpv2_8b.spare2 + W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x97: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len + 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 + 7: TB17 # ingress::hdr.gtpv2_8b.spare2 + W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x9f: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len + 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 + 7: TB17 # ingress::hdr.gtpv2_8b.spare2 + W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0xa2: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len + 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 + 7: TB17 # ingress::hdr.gtpv2_8b.spare2 + W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0xa4: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len + 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 + 7: TB17 # ingress::hdr.gtpv2_8b.spare2 + W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0xa6: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len + 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 + 7: TB17 # ingress::hdr.gtpv2_8b.spare2 + W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x68: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len + 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 + 7: TB17 # ingress::hdr.gtpv2_8b.spare2 + W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x82: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len + 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 + 7: TB17 # ingress::hdr.gtpv2_8b.spare2 + W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0xff: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len + 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 + 7: TB17 # ingress::hdr.gtpv2_8b.spare2 + W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid + load: { byte1 : 8 } + shift: 8 + buf_req: 9 + next: parse_volte + 0x**: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len + 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 + 7: TB17 # ingress::hdr.gtpv2_8b.spare2 + W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid + shift: 8 + buf_req: 8 + next: end + parse_gtp_base: + match: [ half, byte0 ] + 0x01****: + 0..3: TW2 + # - bit[0..7] -> TW2 bit[31..24]: ingress::hdr.imsi.type + # - bit[8..23] -> TW2 bit[23..8]: ingress::hdr.imsi.len + # - bit[24..27] -> TW2 bit[7..4]: ingress::hdr.imsi.spare + # - bit[28..31] -> TW2 bit[3..0]: ingress::hdr.imsi.instance + 4..5: TH28 # ingress::hdr.imsi.num_digit[127:112].112-127 + 6: TB25 # ingress::hdr.imsi.num_digit[111:104].104-111 + 7: TB16 # ingress::hdr.imsi.num_digit[103:96].96-103 + 8..9: TH27 # ingress::hdr.imsi.num_digit[95:80].80-95 + 10..11: TH24 # ingress::hdr.imsi.num_digit[79:64].64-79 + 12..15: TW24 # ingress::hdr.imsi.num_digit[63:32].32-63 + 16..19: TW17 # ingress::hdr.imsi.num_digit[31:0].0-31 + W41: 32 # value 1 -> W41 bit[5]: ingress::hdr.imsi.$valid + shift: 20 + buf_req: 20 + next: end + 0x020002: + 0: TB1 # ingress::hdr.cause_ie_6b.type + 1..4: TW3 + # - bit[8..23] -> TW3 bit[31..16]: ingress::hdr.cause_ie_6b.len + # - bit[24..27] -> TW3 bit[15..12]: ingress::hdr.cause_ie_6b.spare1 + # - bit[28..31] -> TW3 bit[11..8]: ingress::hdr.cause_ie_6b.instance + # - bit[32..39] -> TW3 bit[7..0]: ingress::hdr.cause_ie_6b.cause_value + 5: TB0 + # - bit[40..44] -> TB0 bit[7..3]: ingress::hdr.cause_ie_6b.spare2 + # - bit[45] -> TB0 bit[2]: ingress::hdr.cause_ie_6b.pce + # - bit[46] -> TB0 bit[1]: ingress::hdr.cause_ie_6b.bce + # - bit[47] -> TB0 bit[0]: ingress::hdr.cause_ie_6b.cs + W41: 64 # value 1 -> W41 bit[6]: ingress::hdr.cause_ie_6b.$valid + shift: 6 + buf_req: 6 + next: parse_imsi + 0x020006: + 0: TB1 # ingress::hdr.cause_ie_10b.type + 1..4: TW3 + # - bit[8..23] -> TW3 bit[31..16]: ingress::hdr.cause_ie_10b.len + # - bit[24..27] -> TW3 bit[15..12]: ingress::hdr.cause_ie_10b.spare1 + # - bit[28..31] -> TW3 bit[11..8]: ingress::hdr.cause_ie_10b.instance + # - bit[32..39] -> TW3 bit[7..0]: ingress::hdr.cause_ie_10b.cause_value + 5: TB0 + # - bit[40..44] -> TB0 bit[7..3]: ingress::hdr.cause_ie_10b.spare2 + # - bit[45] -> TB0 bit[2]: ingress::hdr.cause_ie_10b.pce + # - bit[46] -> TB0 bit[1]: ingress::hdr.cause_ie_10b.bce + # - bit[47] -> TB0 bit[0]: ingress::hdr.cause_ie_10b.cs + 6..7: TH3 + # - bit[48..55] -> TH3 bit[15..8]: ingress::hdr.cause_ie_10b.type_oe + # - bit[56..63] -> TH3 bit[7..0]: ingress::hdr.cause_ie_10b.len_oe[15:8].8-15 + 8..9: TH2 + # - bit[64..71] -> TH2 bit[15..8]: ingress::hdr.cause_ie_10b.len_oe[7:0].0-7 + # - bit[72..75] -> TH2 bit[7..4]: ingress::hdr.cause_ie_10b.spare_oe + # - bit[76..79] -> TH2 bit[3..0]: ingress::hdr.cause_ie_10b.instance_oe + W41: 128 # value 1 -> W41 bit[7]: ingress::hdr.cause_ie_10b.$valid + shift: 10 + buf_req: 10 + next: parse_imsi + 0x******: + buf_req: 0 + next: end + parse_imsi: + *: + 0..3: TW2 + # - bit[0..7] -> TW2 bit[31..24]: ingress::hdr.imsi.type + # - bit[8..23] -> TW2 bit[23..8]: ingress::hdr.imsi.len + # - bit[24..27] -> TW2 bit[7..4]: ingress::hdr.imsi.spare + # - bit[28..31] -> TW2 bit[3..0]: ingress::hdr.imsi.instance + 4..5: TH28 # ingress::hdr.imsi.num_digit[127:112].112-127 + 6: TB25 # ingress::hdr.imsi.num_digit[111:104].104-111 + 7: TB16 # ingress::hdr.imsi.num_digit[103:96].96-103 + 8..9: TH27 # ingress::hdr.imsi.num_digit[95:80].80-95 + 10..11: TH24 # ingress::hdr.imsi.num_digit[79:64].64-79 + 12..15: TW24 # ingress::hdr.imsi.num_digit[63:32].32-63 + 16..19: TW17 # ingress::hdr.imsi.num_digit[31:0].0-31 + W41: 32 # value 1 -> W41 bit[5]: ingress::hdr.imsi.$valid + shift: 20 + buf_req: 20 + next: end + parse_volte: + match: [ byte1 ] + 0x4*: + load: { byte1 : 9 } + buf_req: 10 + next: parse_inner_ipv4 + 0x6*: + 0..3: TW2 + # - bit[0..3] -> TW2 bit[31..28]: ingress::hdr.inner_ipv6.version + # - bit[4..11] -> TW2 bit[27..20]: ingress::hdr.inner_ipv6.traffic_class + # - bit[12..31] -> TW2 bit[19..0]: ingress::hdr.inner_ipv6.flow_label + 4..5: TH3 # ingress::hdr.inner_ipv6.payload_len + 6: B8 # ingress::hdr.inner_ipv6.next_hdr + 7: TB16 # ingress::hdr.inner_ipv6.hop_limit + 8..11: W14 # ingress::hdr.inner_ipv6.src_addr[127:96].96-127 + 12..15: W13 # ingress::hdr.inner_ipv6.src_addr[95:64].64-95 + 16..19: W12 # ingress::hdr.inner_ipv6.src_addr[63:32].32-63 + W41: 16384 # value 1 -> W41 bit[14]: ingress::hdr.inner_ipv6.$valid + load: { byte1 : 6 } + shift: 20 + buf_req: 20 + next: parse_inner_ipv6.$split_0 + 0x**: + buf_req: 0 + next: end + parse_inner_ipv4: + match: [ byte1 ] + 0x06: + 0..3: TW2 + # - bit[0..3] -> TW2 bit[31..28]: ingress::hdr.inner_ipv4.version + # - bit[4..7] -> TW2 bit[27..24]: ingress::hdr.inner_ipv4.ihl + # - bit[8..15] -> TW2 bit[23..16]: ingress::hdr.inner_ipv4.diffserv + # - bit[16..31] -> TW2 bit[15..0]: ingress::hdr.inner_ipv4.total_len + 4..5: TH24 # ingress::hdr.inner_ipv4.identification + 6..7: TH3 + # - bit[48..50] -> TH3 bit[15..13]: ingress::hdr.inner_ipv4.flags + # - bit[51..63] -> TH3 bit[12..0]: ingress::hdr.inner_ipv4.frag_offset + 8..11: TW17 + # - bit[64..71] -> TW17 bit[31..24]: ingress::hdr.inner_ipv4.ttl + # - bit[72..79] -> TW17 bit[23..16]: ingress::hdr.inner_ipv4.protocol + # - bit[80..95] -> TW17 bit[15..0]: ingress::hdr.inner_ipv4.hdr_checksum + 12..13: TH40 # ingress::hdr.inner_ipv4.src_addr[31:16].16-31 + 14: TB25 # ingress::hdr.inner_ipv4.src_addr[15:8].8-15 + 15: TB16 # ingress::hdr.inner_ipv4.src_addr[7:0].0-7 + 16..17: TH41 # ingress::hdr.inner_ipv4.dst_addr[31:16].16-31 + 18: TB27 # ingress::hdr.inner_ipv4.dst_addr[15:8].8-15 + 19: TB26 # ingress::hdr.inner_ipv4.dst_addr[7:0].0-7 + W41: 256 # value 1 -> W41 bit[8]: ingress::hdr.inner_ipv4.$valid + shift: 20 + buf_req: 20 + next: parse_inner_tcp + 0x11: + 0..3: TW2 + # - bit[0..3] -> TW2 bit[31..28]: ingress::hdr.inner_ipv4.version + # - bit[4..7] -> TW2 bit[27..24]: ingress::hdr.inner_ipv4.ihl + # - bit[8..15] -> TW2 bit[23..16]: ingress::hdr.inner_ipv4.diffserv + # - bit[16..31] -> TW2 bit[15..0]: ingress::hdr.inner_ipv4.total_len + 4..5: TH24 # ingress::hdr.inner_ipv4.identification + 6..7: TH3 + # - bit[48..50] -> TH3 bit[15..13]: ingress::hdr.inner_ipv4.flags + # - bit[51..63] -> TH3 bit[12..0]: ingress::hdr.inner_ipv4.frag_offset + 8..11: TW17 + # - bit[64..71] -> TW17 bit[31..24]: ingress::hdr.inner_ipv4.ttl + # - bit[72..79] -> TW17 bit[23..16]: ingress::hdr.inner_ipv4.protocol + # - bit[80..95] -> TW17 bit[15..0]: ingress::hdr.inner_ipv4.hdr_checksum + 12..13: TH40 # ingress::hdr.inner_ipv4.src_addr[31:16].16-31 + 14: TB25 # ingress::hdr.inner_ipv4.src_addr[15:8].8-15 + 15: TB16 # ingress::hdr.inner_ipv4.src_addr[7:0].0-7 + 16..17: TH41 # ingress::hdr.inner_ipv4.dst_addr[31:16].16-31 + 18: TB27 # ingress::hdr.inner_ipv4.dst_addr[15:8].8-15 + 19: TB26 # ingress::hdr.inner_ipv4.dst_addr[7:0].0-7 + W41: 256 # value 1 -> W41 bit[8]: ingress::hdr.inner_ipv4.$valid + shift: 20 + buf_req: 20 + next: parse_inner_udp + 0x01: + 0..3: TW2 + # - bit[0..3] -> TW2 bit[31..28]: ingress::hdr.inner_ipv4.version + # - bit[4..7] -> TW2 bit[27..24]: ingress::hdr.inner_ipv4.ihl + # - bit[8..15] -> TW2 bit[23..16]: ingress::hdr.inner_ipv4.diffserv + # - bit[16..31] -> TW2 bit[15..0]: ingress::hdr.inner_ipv4.total_len + 4..5: TH24 # ingress::hdr.inner_ipv4.identification + 6..7: TH3 + # - bit[48..50] -> TH3 bit[15..13]: ingress::hdr.inner_ipv4.flags + # - bit[51..63] -> TH3 bit[12..0]: ingress::hdr.inner_ipv4.frag_offset + 8..11: TW17 + # - bit[64..71] -> TW17 bit[31..24]: ingress::hdr.inner_ipv4.ttl + # - bit[72..79] -> TW17 bit[23..16]: ingress::hdr.inner_ipv4.protocol + # - bit[80..95] -> TW17 bit[15..0]: ingress::hdr.inner_ipv4.hdr_checksum + 12..13: TH40 # ingress::hdr.inner_ipv4.src_addr[31:16].16-31 + 14: TB25 # ingress::hdr.inner_ipv4.src_addr[15:8].8-15 + 15: TB16 # ingress::hdr.inner_ipv4.src_addr[7:0].0-7 + 16..17: TH41 # ingress::hdr.inner_ipv4.dst_addr[31:16].16-31 + 18: TB27 # ingress::hdr.inner_ipv4.dst_addr[15:8].8-15 + 19: TB26 # ingress::hdr.inner_ipv4.dst_addr[7:0].0-7 + W41: 256 # value 1 -> W41 bit[8]: ingress::hdr.inner_ipv4.$valid + shift: 20 + buf_req: 20 + next: parse_inner_icmp + 0x32: + 0..3: TW2 + # - bit[0..3] -> TW2 bit[31..28]: ingress::hdr.inner_ipv4.version + # - bit[4..7] -> TW2 bit[27..24]: ingress::hdr.inner_ipv4.ihl + # - bit[8..15] -> TW2 bit[23..16]: ingress::hdr.inner_ipv4.diffserv + # - bit[16..31] -> TW2 bit[15..0]: ingress::hdr.inner_ipv4.total_len + 4..5: TH24 # ingress::hdr.inner_ipv4.identification + 6..7: TH3 + # - bit[48..50] -> TH3 bit[15..13]: ingress::hdr.inner_ipv4.flags + # - bit[51..63] -> TH3 bit[12..0]: ingress::hdr.inner_ipv4.frag_offset + 8..11: TW17 + # - bit[64..71] -> TW17 bit[31..24]: ingress::hdr.inner_ipv4.ttl + # - bit[72..79] -> TW17 bit[23..16]: ingress::hdr.inner_ipv4.protocol + # - bit[80..95] -> TW17 bit[15..0]: ingress::hdr.inner_ipv4.hdr_checksum + 12..13: TH40 # ingress::hdr.inner_ipv4.src_addr[31:16].16-31 + 14: TB25 # ingress::hdr.inner_ipv4.src_addr[15:8].8-15 + 15: TB16 # ingress::hdr.inner_ipv4.src_addr[7:0].0-7 + 16..17: TH41 # ingress::hdr.inner_ipv4.dst_addr[31:16].16-31 + 18: TB27 # ingress::hdr.inner_ipv4.dst_addr[15:8].8-15 + 19: TB26 # ingress::hdr.inner_ipv4.dst_addr[7:0].0-7 + W41: 256 # value 1 -> W41 bit[8]: ingress::hdr.inner_ipv4.$valid + shift: 20 + buf_req: 20 + next: parse_inner_esp + 0x**: + 0..3: TW2 + # - bit[0..3] -> TW2 bit[31..28]: ingress::hdr.inner_ipv4.version + # - bit[4..7] -> TW2 bit[27..24]: ingress::hdr.inner_ipv4.ihl + # - bit[8..15] -> TW2 bit[23..16]: ingress::hdr.inner_ipv4.diffserv + # - bit[16..31] -> TW2 bit[15..0]: ingress::hdr.inner_ipv4.total_len + 4..5: TH24 # ingress::hdr.inner_ipv4.identification + 6..7: TH3 + # - bit[48..50] -> TH3 bit[15..13]: ingress::hdr.inner_ipv4.flags + # - bit[51..63] -> TH3 bit[12..0]: ingress::hdr.inner_ipv4.frag_offset + 8..11: TW17 + # - bit[64..71] -> TW17 bit[31..24]: ingress::hdr.inner_ipv4.ttl + # - bit[72..79] -> TW17 bit[23..16]: ingress::hdr.inner_ipv4.protocol + # - bit[80..95] -> TW17 bit[15..0]: ingress::hdr.inner_ipv4.hdr_checksum + 12..13: TH40 # ingress::hdr.inner_ipv4.src_addr[31:16].16-31 + 14: TB25 # ingress::hdr.inner_ipv4.src_addr[15:8].8-15 + 15: TB16 # ingress::hdr.inner_ipv4.src_addr[7:0].0-7 + 16..17: TH41 # ingress::hdr.inner_ipv4.dst_addr[31:16].16-31 + 18: TB27 # ingress::hdr.inner_ipv4.dst_addr[15:8].8-15 + 19: TB26 # ingress::hdr.inner_ipv4.dst_addr[7:0].0-7 + W41: 256 # value 1 -> W41 bit[8]: ingress::hdr.inner_ipv4.$valid + shift: 20 + buf_req: 20 + next: end + parse_inner_tcp: + *: + 0..1: TH28 # ingress::hdr.inner_tcp.src_port + 0..1: H10 # ingress::ig_md.lkp.inner_l4_src_port + 2..3: TH27 # ingress::hdr.inner_tcp.dst_port + 2..3: H12 # ingress::ig_md.lkp.inner_l4_dst_port + 4..7: W6 # ingress::hdr.inner_tcp.seq_no + 8..11: W7 # ingress::hdr.inner_tcp.ack_no + 12..15: TW3 + # - bit[96..99] -> TW3 bit[31..28]: ingress::hdr.inner_tcp.data_offset + # - bit[100..103] -> TW3 bit[27..24]: ingress::hdr.inner_tcp.res + # - bit[104..111] -> TW3 bit[23..16]: ingress::hdr.inner_tcp.flags + # - bit[112..127] -> TW3 bit[15..0]: ingress::hdr.inner_tcp.window + 16..19: TW24 + # - bit[128..143] -> TW24 bit[31..16]: ingress::hdr.inner_tcp.checksum + # - bit[144..159] -> TW24 bit[15..0]: ingress::hdr.inner_tcp.urgent_ptr + W41: 1536 + # - value 1 -> W41 bit[9]: ingress::hdr.inner_tcp.$valid + # - value 1 -> W41 bit[10]: ingress::hdr.sip.$valid + shift: 20 + buf_req: 20 + next: parse_inner_tcp.$split_0 + parse_inner_tcp.$split_0: + *: + 0..3: W8 # ingress::hdr.sip.data + shift: 4 + buf_req: 4 + next: end + parse_inner_udp: + *: + 0..1: H10 # ingress::ig_md.lkp.inner_l4_src_port + 0..3: TW3 + # - bit[0..15] -> TW3 bit[31..16]: ingress::hdr.inner_udp.src_port + # - bit[16..31] -> TW3 bit[15..0]: ingress::hdr.inner_udp.dst_port + 2..3: H12 # ingress::ig_md.lkp.inner_l4_dst_port + 4..7: TW24 + # - bit[32..47] -> TW24 bit[31..16]: ingress::hdr.inner_udp.hdr_length + # - bit[48..63] -> TW24 bit[15..0]: ingress::hdr.inner_udp.checksum + W41: 2048 # value 1 -> W41 bit[11]: ingress::hdr.inner_udp.$valid + shift: 8 + buf_req: 8 + next: end + parse_inner_icmp: + *: + 0..3: TW3 + # - bit[0..7] -> TW3 bit[31..24]: ingress::hdr.inner_icmp.type_ + # - bit[8..15] -> TW3 bit[23..16]: ingress::hdr.inner_icmp.code + # - bit[16..31] -> TW3 bit[15..0]: ingress::hdr.inner_icmp.hdr_checksum + W41: 4096 # value 1 -> W41 bit[12]: ingress::hdr.inner_icmp.$valid + shift: 4 + buf_req: 4 + next: end + parse_inner_esp: + *: + 0..3: W9 # ingress::hdr.ipsec_esp.spi + 4..7: W10 # ingress::hdr.ipsec_esp.sn + W41: 8192 # value 1 -> W41 bit[13]: ingress::hdr.ipsec_esp.$valid + shift: 8 + buf_req: 8 + next: parse_inner_tcp + parse_inner_ipv6.$split_0: + *: + 0..3: W11 # ingress::hdr.inner_ipv6.src_addr[31:0].0-31 + 4..7: W34 # ingress::hdr.inner_ipv6.dst_addr[127:96].96-127 + 8..11: W33 # ingress::hdr.inner_ipv6.dst_addr[95:64].64-95 + 12..15: W32 # ingress::hdr.inner_ipv6.dst_addr[63:32].32-63 + shift: 16 + buf_req: 16 + next: parse_inner_ipv6.$split_1 + parse_inner_ipv6.$split_1: + match: [ byte1 ] + 0x06: + 0..3: W15 # ingress::hdr.inner_ipv6.dst_addr[31:0].0-31 + shift: 4 + buf_req: 4 + next: parse_inner_tcp + 0x11: + 0..3: W15 # ingress::hdr.inner_ipv6.dst_addr[31:0].0-31 + shift: 4 + buf_req: 4 + next: parse_inner_udp + 0x3a: + 0..3: W15 # ingress::hdr.inner_ipv6.dst_addr[31:0].0-31 + shift: 4 + buf_req: 4 + next: parse_inner_icmp + 0x32: + 0..3: W15 # ingress::hdr.inner_ipv6.dst_addr[31:0].0-31 + shift: 4 + buf_req: 4 + next: parse_inner_esp + 0x**: + 0..3: W15 # ingress::hdr.inner_ipv6.dst_addr[31:0].0-31 + shift: 4 + buf_req: 4 + next: end + parse_gtpv2_12b: + match: [ byte1 ] + 0x20: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len + 4..7: W35 # ingress::hdr.gtpv2_12b.teid + 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 + 11: TB17 # ingress::hdr.gtpv2_12b.spare2 + W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x26: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len + 4..7: W35 # ingress::hdr.gtpv2_12b.teid + 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 + 11: TB17 # ingress::hdr.gtpv2_12b.spare2 + W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x27: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len + 4..7: W35 # ingress::hdr.gtpv2_12b.teid + 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 + 11: TB17 # ingress::hdr.gtpv2_12b.spare2 + W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x47: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len + 4..7: W35 # ingress::hdr.gtpv2_12b.teid + 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 + 11: TB17 # ingress::hdr.gtpv2_12b.spare2 + W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x67: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len + 4..7: W35 # ingress::hdr.gtpv2_12b.teid + 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 + 11: TB17 # ingress::hdr.gtpv2_12b.spare2 + W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x85: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len + 4..7: W35 # ingress::hdr.gtpv2_12b.teid + 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 + 11: TB17 # ingress::hdr.gtpv2_12b.spare2 + W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x88: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len + 4..7: W35 # ingress::hdr.gtpv2_12b.teid + 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 + 11: TB17 # ingress::hdr.gtpv2_12b.spare2 + W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x97: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len + 4..7: W35 # ingress::hdr.gtpv2_12b.teid + 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 + 11: TB17 # ingress::hdr.gtpv2_12b.spare2 + W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x9f: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len + 4..7: W35 # ingress::hdr.gtpv2_12b.teid + 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 + 11: TB17 # ingress::hdr.gtpv2_12b.spare2 + W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0xa2: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len + 4..7: W35 # ingress::hdr.gtpv2_12b.teid + 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 + 11: TB17 # ingress::hdr.gtpv2_12b.spare2 + W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0xa4: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len + 4..7: W35 # ingress::hdr.gtpv2_12b.teid + 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 + 11: TB17 # ingress::hdr.gtpv2_12b.spare2 + W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0xa6: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len + 4..7: W35 # ingress::hdr.gtpv2_12b.teid + 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 + 11: TB17 # ingress::hdr.gtpv2_12b.spare2 + W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x68: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len + 4..7: W35 # ingress::hdr.gtpv2_12b.teid + 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 + 11: TB17 # ingress::hdr.gtpv2_12b.spare2 + W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x82: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len + 4..7: W35 # ingress::hdr.gtpv2_12b.teid + 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 + 11: TB17 # ingress::hdr.gtpv2_12b.spare2 + W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0xff: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len + 4..7: W35 # ingress::hdr.gtpv2_12b.teid + 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 + 11: TB17 # ingress::hdr.gtpv2_12b.spare2 + W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid + load: { byte1 : 12 } + shift: 12 + buf_req: 13 + next: parse_volte + 0x**: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len + 4..7: W35 # ingress::hdr.gtpv2_12b.teid + 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 + 11: TB17 # ingress::hdr.gtpv2_12b.spare2 + W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid + shift: 12 + buf_req: 12 + next: end + parse_udp: + match: [ half ] + value_set IgParser_inner_2.udp_port_vxlan 1: + handle: 507 + field_mapping: + hdr.udp.dst_port(0..15) : half(0..15) + 0..1: H9 # ingress::ig_md.lkp.l4_src_port + 0..3: TW18 + # - bit[0..15] -> TW18 bit[31..16]: ingress::hdr.udp.src_port + # - bit[16..31] -> TW18 bit[15..0]: ingress::hdr.udp.dst_port + 2..3: H11 # ingress::ig_md.lkp.l4_dst_port + 4..7: TW19 + # - bit[32..47] -> TW19 bit[31..16]: ingress::hdr.udp.hdr_length + # - bit[48..63] -> TW19 bit[15..0]: ingress::hdr.udp.checksum + W41: 65536 # value 1 -> W41 bit[16]: ingress::hdr.udp.$valid + shift: 8 + buf_req: 8 + next: parse_vxlan + 0x0868: + 0..1: H9 # ingress::ig_md.lkp.l4_src_port + 0..3: TW18 + # - bit[0..15] -> TW18 bit[31..16]: ingress::hdr.udp.src_port + # - bit[16..31] -> TW18 bit[15..0]: ingress::hdr.udp.dst_port + 2..3: H11 # ingress::ig_md.lkp.l4_dst_port + 4..7: TW19 + # - bit[32..47] -> TW19 bit[31..16]: ingress::hdr.udp.hdr_length + # - bit[48..63] -> TW19 bit[15..0]: ingress::hdr.udp.checksum + W41: 65536 # value 1 -> W41 bit[16]: ingress::hdr.udp.$valid + shift: 8 + buf_req: 8 + next: parse_gtpu + 0x0d3a: + 0..1: H9 # ingress::ig_md.lkp.l4_src_port + 0..3: TW18 + # - bit[0..15] -> TW18 bit[31..16]: ingress::hdr.udp.src_port + # - bit[16..31] -> TW18 bit[15..0]: ingress::hdr.udp.dst_port + 2..3: H11 # ingress::ig_md.lkp.l4_dst_port + 4..7: TW19 + # - bit[32..47] -> TW19 bit[31..16]: ingress::hdr.udp.hdr_length + # - bit[48..63] -> TW19 bit[15..0]: ingress::hdr.udp.checksum + W41: 65536 # value 1 -> W41 bit[16]: ingress::hdr.udp.$valid + shift: 8 + buf_req: 8 + next: parse_gtp + 0x084b: + 0..1: H9 # ingress::ig_md.lkp.l4_src_port + 0..3: TW18 + # - bit[0..15] -> TW18 bit[31..16]: ingress::hdr.udp.src_port + # - bit[16..31] -> TW18 bit[15..0]: ingress::hdr.udp.dst_port + 2..3: H11 # ingress::ig_md.lkp.l4_dst_port + 4..7: TW19 + # - bit[32..47] -> TW19 bit[31..16]: ingress::hdr.udp.hdr_length + # - bit[48..63] -> TW19 bit[15..0]: ingress::hdr.udp.checksum + W41: 65536 # value 1 -> W41 bit[16]: ingress::hdr.udp.$valid + load: { byte1 : 8 } + shift: 8 + buf_req: 9 + next: parse_gtp_verx + 0x06a5: + 0..1: H9 # ingress::ig_md.lkp.l4_src_port + 0..3: TW18 + # - bit[0..15] -> TW18 bit[31..16]: ingress::hdr.udp.src_port + # - bit[16..31] -> TW18 bit[15..0]: ingress::hdr.udp.dst_port + 2..3: H11 # ingress::ig_md.lkp.l4_dst_port + 4..7: TW19 + # - bit[32..47] -> TW19 bit[31..16]: ingress::hdr.udp.hdr_length + # - bit[48..63] -> TW19 bit[15..0]: ingress::hdr.udp.checksum + W41: 65536 # value 1 -> W41 bit[16]: ingress::hdr.udp.$valid + shift: 8 + buf_req: 8 + next: parse_l2tp + 0x****: + 0..1: H9 # ingress::ig_md.lkp.l4_src_port + 0..3: TW18 + # - bit[0..15] -> TW18 bit[31..16]: ingress::hdr.udp.src_port + # - bit[16..31] -> TW18 bit[15..0]: ingress::hdr.udp.dst_port + 2..3: H11 # ingress::ig_md.lkp.l4_dst_port + 4..7: TW19 + # - bit[32..47] -> TW19 bit[31..16]: ingress::hdr.udp.hdr_length + # - bit[48..63] -> TW19 bit[15..0]: ingress::hdr.udp.checksum + W41: 65536 # value 1 -> W41 bit[16]: ingress::hdr.udp.$valid + shift: 8 + buf_req: 8 + next: end + parse_vxlan: + *: + 0..3: TW1 + # - bit[0..7] -> TW1 bit[31..24]: ingress::hdr.vxlan.flags + # - bit[8..31] -> TW1 bit[23..0]: ingress::hdr.vxlan.reserved + 4..5: TH1 # ingress::hdr.vxlan.vni[23:8].8-23 + 6..7: TH0 + # - bit[48..55] -> TH0 bit[15..8]: ingress::hdr.vxlan.vni[7:0].0-7 + # - bit[56..63] -> TH0 bit[7..0]: ingress::hdr.vxlan.reserved2 + 8..11: TW25 # ingress::hdr.inner_ethernet.dst_addr[47:16].16-47 + 12: TB18 # ingress::hdr.inner_ethernet.dst_addr[15:8].8-15 + 13: TB17 # ingress::hdr.inner_ethernet.dst_addr[7:0].0-7 + 14..15: TH39 # ingress::hdr.inner_ethernet.src_addr[47:32].32-47 + 16: TB1 # ingress::hdr.inner_ethernet.src_addr[31:24].24-31 + 17: TB0 # ingress::hdr.inner_ethernet.src_addr[23:16].16-23 + 18..19: TH26 # ingress::hdr.inner_ethernet.src_addr[15:0].0-15 + W41: 393216 + # - value 1 -> W41 bit[17]: ingress::hdr.vxlan.$valid + # - value 1 -> W41 bit[18]: ingress::hdr.inner_ethernet.$valid + load: { half : 20..21 } + shift: 20 + buf_req: 22 + next: parse_vxlan.$split_0 + parse_vxlan.$split_0: + match: [ half ] + 0x0800: + 0..1: TH2 # ingress::hdr.inner_ethernet.ether_type + load: { byte1 : 11 } + shift: 2 + buf_req: 12 + next: parse_inner_ipv4 + 0x86dd: + 0..1: TH2 # ingress::hdr.inner_ethernet.ether_type + shift: 2 + buf_req: 2 + next: parse_inner_ipv6 + 0x****: + 0..1: TH2 # ingress::hdr.inner_ethernet.ether_type + shift: 2 + buf_req: 2 + next: end + parse_inner_ipv6: + *: + 0..3: TW2 + # - bit[0..3] -> TW2 bit[31..28]: ingress::hdr.inner_ipv6.version + # - bit[4..11] -> TW2 bit[27..20]: ingress::hdr.inner_ipv6.traffic_class + # - bit[12..31] -> TW2 bit[19..0]: ingress::hdr.inner_ipv6.flow_label + 4..5: TH3 # ingress::hdr.inner_ipv6.payload_len + 6: B8 # ingress::hdr.inner_ipv6.next_hdr + 7: TB16 # ingress::hdr.inner_ipv6.hop_limit + 8..11: W14 # ingress::hdr.inner_ipv6.src_addr[127:96].96-127 + 12..15: W13 # ingress::hdr.inner_ipv6.src_addr[95:64].64-95 + 16..19: W12 # ingress::hdr.inner_ipv6.src_addr[63:32].32-63 + W41: 16384 # value 1 -> W41 bit[14]: ingress::hdr.inner_ipv6.$valid + load: { byte1 : 6 } + shift: 20 + buf_req: 20 + next: parse_inner_ipv6.$split_0 + parse_gtpu: + *: + load: { byte1 : 0 } + buf_req: 1 + next: parse_gtpv1 + parse_gtpv1: + match: [ byte1 ] + 0b*****000: + load: { byte1 : 1 } + buf_req: 2 + next: parse_gtpv1_8b + 0b*****0*1: + load: { byte1 : 1 } + buf_req: 2 + next: parse_gtpv1_12b + 0b*****01*: + load: { byte1 : 1 } + buf_req: 2 + next: parse_gtpv1_12b + 0x**: + buf_req: 0 + next: end + parse_gtpv1_8b: + match: [ byte1 ] + 0x20: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len + 4..7: TW1 # ingress::hdr.gtpv1_8b.teid + W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x26: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len + 4..7: TW1 # ingress::hdr.gtpv1_8b.teid + W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x27: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len + 4..7: TW1 # ingress::hdr.gtpv1_8b.teid + W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x47: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len + 4..7: TW1 # ingress::hdr.gtpv1_8b.teid + W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x67: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len + 4..7: TW1 # ingress::hdr.gtpv1_8b.teid + W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x85: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len + 4..7: TW1 # ingress::hdr.gtpv1_8b.teid + W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x88: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len + 4..7: TW1 # ingress::hdr.gtpv1_8b.teid + W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x97: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len + 4..7: TW1 # ingress::hdr.gtpv1_8b.teid + W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x9f: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len + 4..7: TW1 # ingress::hdr.gtpv1_8b.teid + W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0xa2: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len + 4..7: TW1 # ingress::hdr.gtpv1_8b.teid + W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0xa4: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len + 4..7: TW1 # ingress::hdr.gtpv1_8b.teid + W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0xa6: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len + 4..7: TW1 # ingress::hdr.gtpv1_8b.teid + W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x68: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len + 4..7: TW1 # ingress::hdr.gtpv1_8b.teid + W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x82: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len + 4..7: TW1 # ingress::hdr.gtpv1_8b.teid + W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0xff: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len + 4..7: TW1 # ingress::hdr.gtpv1_8b.teid + W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid + load: { byte1 : 8 } + shift: 8 + buf_req: 9 + next: parse_volte + 0x**: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len + 4..7: TW1 # ingress::hdr.gtpv1_8b.teid + W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid + shift: 8 + buf_req: 8 + next: end + parse_gtpv1_12b: + match: [ byte1 ] + 0x20: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len + 4..7: TW25 # ingress::hdr.gtpv1_12b.teid + 8..11: TW1 + # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t + W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x26: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len + 4..7: TW25 # ingress::hdr.gtpv1_12b.teid + 8..11: TW1 + # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t + W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x27: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len + 4..7: TW25 # ingress::hdr.gtpv1_12b.teid + 8..11: TW1 + # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t + W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x47: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len + 4..7: TW25 # ingress::hdr.gtpv1_12b.teid + 8..11: TW1 + # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t + W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x67: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len + 4..7: TW25 # ingress::hdr.gtpv1_12b.teid + 8..11: TW1 + # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t + W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x85: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len + 4..7: TW25 # ingress::hdr.gtpv1_12b.teid + 8..11: TW1 + # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t + W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x88: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len + 4..7: TW25 # ingress::hdr.gtpv1_12b.teid + 8..11: TW1 + # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t + W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x97: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len + 4..7: TW25 # ingress::hdr.gtpv1_12b.teid + 8..11: TW1 + # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t + W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x9f: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len + 4..7: TW25 # ingress::hdr.gtpv1_12b.teid + 8..11: TW1 + # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t + W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0xa2: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len + 4..7: TW25 # ingress::hdr.gtpv1_12b.teid + 8..11: TW1 + # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t + W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0xa4: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len + 4..7: TW25 # ingress::hdr.gtpv1_12b.teid + 8..11: TW1 + # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t + W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0xa6: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len + 4..7: TW25 # ingress::hdr.gtpv1_12b.teid + 8..11: TW1 + # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t + W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x68: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len + 4..7: TW25 # ingress::hdr.gtpv1_12b.teid + 8..11: TW1 + # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t + W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x82: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len + 4..7: TW25 # ingress::hdr.gtpv1_12b.teid + 8..11: TW1 + # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t + W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0xff: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len + 4..7: TW25 # ingress::hdr.gtpv1_12b.teid + 8..11: TW1 + # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t + W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid + load: { byte1 : 12 } + shift: 12 + buf_req: 13 + next: parse_volte + 0x**: + 0..1: TH0 + # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version + # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt + # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e + # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s + # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type + 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len + 4..7: TW25 # ingress::hdr.gtpv1_12b.teid + 8..11: TW1 + # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t + W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid + shift: 12 + buf_req: 12 + next: end + parse_gtp: + *: + load: { byte1 : 0 } + buf_req: 1 + next: parse_gtpv1 + parse_gtp_verx: + match: [ byte1 ] + 0b001*****: + load: { byte1 : 0 } + buf_req: 1 + next: parse_gtpv1 + 0b010*****: + load: { byte1 : 0 } + buf_req: 1 + next: parse_gtpv2 + 0x**: + buf_req: 0 + next: end + parse_l2tp: + *: + 0..3: TW1 + # - bit[0..11] -> TW1 bit[31..20]: ingress::hdr.l2tp.TLxxSxOP + # - bit[12..15] -> TW1 bit[19..16]: ingress::hdr.l2tp.version + # - bit[16..23] -> TW1 bit[15..8]: ingress::hdr.l2tp.l2tp_length + # - bit[24..31] -> TW1 bit[7..0]: ingress::hdr.l2tp.tunnel_id[15:8].8-15 + 4: TB0 # ingress::hdr.l2tp.tunnel_id[7:0].0-7 + 5..6: TH26 # ingress::hdr.l2tp.session_id + 7: TB19 # ingress::hdr.l2tp.Ns[15:8].8-15 + 8: TB18 # ingress::hdr.l2tp.Ns[7:0].0-7 + 9..10: TH0 # ingress::hdr.l2tp.Nr + 11: TB17 # ingress::hdr.l2tp.offset_size + W41: 2097152 # value 1 -> W41 bit[21]: ingress::hdr.l2tp.$valid + load: { byte1 : 0 } + shift: 12 + buf_req: 12 + next: parse_l2tp.$split_0 + parse_l2tp.$split_0: + match: [ byte1 ] + 0b0*******: + 0: TB1 # ingress::hdr.l2tp.offset_pad + load: { half : 7..8, byte0 : 9 } + shift: 1 + buf_req: 10 + next: parse_pppoe + 0x**: + 0: TB1 # ingress::hdr.l2tp.offset_pad + shift: 1 + buf_req: 1 + next: end + parse_pppoe: + match: [ half, byte0 ] + 0x00214*: + 0..1: TH1 + # - bit[0..3] -> TH1 bit[15..12]: ingress::hdr.pppoe.version + # - bit[4..7] -> TH1 bit[11..8]: ingress::hdr.pppoe.type + # - bit[8..15] -> TH1 bit[7..0]: ingress::hdr.pppoe.code + 2..3: TH2 # ingress::hdr.pppoe.session_id + 4..7: TW25 + # - bit[32..47] -> TW25 bit[31..16]: ingress::hdr.pppoe.pppoe_length + # - bit[48..63] -> TW25 bit[15..0]: ingress::hdr.pppoe.ppp_proto + W41: 4194304 # value 1 -> W41 bit[22]: ingress::hdr.pppoe.$valid + load: { byte1 : 17 } + shift: 8 + buf_req: 18 + next: parse_inner_ipv4 + 0x00216*: + 0..1: TH1 + # - bit[0..3] -> TH1 bit[15..12]: ingress::hdr.pppoe.version + # - bit[4..7] -> TH1 bit[11..8]: ingress::hdr.pppoe.type + # - bit[8..15] -> TH1 bit[7..0]: ingress::hdr.pppoe.code + 2..3: TH2 # ingress::hdr.pppoe.session_id + 4..7: TW25 + # - bit[32..47] -> TW25 bit[31..16]: ingress::hdr.pppoe.pppoe_length + # - bit[48..63] -> TW25 bit[15..0]: ingress::hdr.pppoe.ppp_proto + W41: 4194304 # value 1 -> W41 bit[22]: ingress::hdr.pppoe.$valid + shift: 8 + buf_req: 8 + next: parse_inner_ipv6 + 0x******: + 0..1: TH1 + # - bit[0..3] -> TH1 bit[15..12]: ingress::hdr.pppoe.version + # - bit[4..7] -> TH1 bit[11..8]: ingress::hdr.pppoe.type + # - bit[8..15] -> TH1 bit[7..0]: ingress::hdr.pppoe.code + 2..3: TH2 # ingress::hdr.pppoe.session_id + 4..7: TW25 + # - bit[32..47] -> TW25 bit[31..16]: ingress::hdr.pppoe.pppoe_length + # - bit[48..63] -> TW25 bit[15..0]: ingress::hdr.pppoe.ppp_proto + W41: 4194304 # value 1 -> W41 bit[22]: ingress::hdr.pppoe.$valid + shift: 8 + buf_req: 8 + next: end + parse_icmp: + *: + 0..3: TW1 + # - bit[0..7] -> TW1 bit[31..24]: ingress::hdr.icmp.type_ + # - bit[8..15] -> TW1 bit[23..16]: ingress::hdr.icmp.code + # - bit[16..31] -> TW1 bit[15..0]: ingress::hdr.icmp.hdr_checksum + W41: 8388608 # value 1 -> W41 bit[23]: ingress::hdr.icmp.$valid + shift: 4 + buf_req: 4 + next: end + parse_sctp: + match: [ half ] + 0x8e3c: + 0..3: TW1 + # - bit[0..15] -> TW1 bit[31..16]: ingress::hdr.sctp.src_port + # - bit[16..31] -> TW1 bit[15..0]: ingress::hdr.sctp.dst_port + 4..7: TW2 # ingress::hdr.sctp.verifTag + 8..9: TH0 # ingress::hdr.sctp.checksum + W41: 16777216 # value 1 -> W41 bit[24]: ingress::hdr.sctp.$valid + shift: 10 + buf_req: 10 + next: end + 0x960c: + 0..3: TW1 + # - bit[0..15] -> TW1 bit[31..16]: ingress::hdr.sctp.src_port + # - bit[16..31] -> TW1 bit[15..0]: ingress::hdr.sctp.dst_port + 4..7: TW2 # ingress::hdr.sctp.verifTag + 8..9: TH0 # ingress::hdr.sctp.checksum + W41: 16777216 # value 1 -> W41 bit[24]: ingress::hdr.sctp.$valid + shift: 10 + buf_req: 10 + next: end + 0x0f1c: + 0..3: TW1 + # - bit[0..15] -> TW1 bit[31..16]: ingress::hdr.sctp.src_port + # - bit[16..31] -> TW1 bit[15..0]: ingress::hdr.sctp.dst_port + 4..7: TW2 # ingress::hdr.sctp.verifTag + 8..9: TH0 # ingress::hdr.sctp.checksum + W41: 16777216 # value 1 -> W41 bit[24]: ingress::hdr.sctp.$valid + shift: 10 + buf_req: 10 + next: end + 0x71be: + 0..3: TW1 + # - bit[0..15] -> TW1 bit[31..16]: ingress::hdr.sctp.src_port + # - bit[16..31] -> TW1 bit[15..0]: ingress::hdr.sctp.dst_port + 4..7: TW2 # ingress::hdr.sctp.verifTag + 8..9: TH0 # ingress::hdr.sctp.checksum + W41: 16777216 # value 1 -> W41 bit[24]: ingress::hdr.sctp.$valid + shift: 10 + buf_req: 10 + next: end + 0x****: + 0..3: TW1 + # - bit[0..15] -> TW1 bit[31..16]: ingress::hdr.sctp.src_port + # - bit[16..31] -> TW1 bit[15..0]: ingress::hdr.sctp.dst_port + 4..7: TW2 # ingress::hdr.sctp.verifTag + 8..9: TH0 # ingress::hdr.sctp.checksum + W41: 16777216 # value 1 -> W41 bit[24]: ingress::hdr.sctp.$valid + shift: 10 + buf_req: 10 + next: end + parse_gre: + match: [ half, byte0 ] + 0b*****0011000100000001011: + 0..1: TH0 + # - bit[0] -> TH0 bit[15]: ingress::hdr.gre.C + # - bit[1] -> TH0 bit[14]: ingress::hdr.gre.R + # - bit[2] -> TH0 bit[13]: ingress::hdr.gre.K + # - bit[3] -> TH0 bit[12]: ingress::hdr.gre.S + # - bit[4] -> TH0 bit[11]: ingress::hdr.gre.s + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gre.recurse + # - bit[8..12] -> TH0 bit[7..3]: ingress::hdr.gre.flags + # - bit[13..15] -> TH0 bit[2..0]: ingress::hdr.gre.version + 2: TB1 # ingress::hdr.gre.proto[15:8].8-15 + 3: TB0 # ingress::hdr.gre.proto[7:0].0-7 + W41: 33554432 # value 1 -> W41 bit[25]: ingress::hdr.gre.$valid + load: { half : 10..11, byte0 : 12 } + shift: 4 + buf_req: 13 + next: parse_pptp + 0b*****0000000100000000000: + 0..1: TH0 + # - bit[0] -> TH0 bit[15]: ingress::hdr.gre.C + # - bit[1] -> TH0 bit[14]: ingress::hdr.gre.R + # - bit[2] -> TH0 bit[13]: ingress::hdr.gre.K + # - bit[3] -> TH0 bit[12]: ingress::hdr.gre.S + # - bit[4] -> TH0 bit[11]: ingress::hdr.gre.s + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gre.recurse + # - bit[8..12] -> TH0 bit[7..3]: ingress::hdr.gre.flags + # - bit[13..15] -> TH0 bit[2..0]: ingress::hdr.gre.version + 2: TB1 # ingress::hdr.gre.proto[15:8].8-15 + 3: TB0 # ingress::hdr.gre.proto[7:0].0-7 + W41: 33554432 # value 1 -> W41 bit[25]: ingress::hdr.gre.$valid + shift: 4 + buf_req: 4 + next: parse_gre_ipv4 + 0b*****0001000011011011101: + 0..1: TH0 + # - bit[0] -> TH0 bit[15]: ingress::hdr.gre.C + # - bit[1] -> TH0 bit[14]: ingress::hdr.gre.R + # - bit[2] -> TH0 bit[13]: ingress::hdr.gre.K + # - bit[3] -> TH0 bit[12]: ingress::hdr.gre.S + # - bit[4] -> TH0 bit[11]: ingress::hdr.gre.s + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gre.recurse + # - bit[8..12] -> TH0 bit[7..3]: ingress::hdr.gre.flags + # - bit[13..15] -> TH0 bit[2..0]: ingress::hdr.gre.version + 2: TB1 # ingress::hdr.gre.proto[15:8].8-15 + 3: TB0 # ingress::hdr.gre.proto[7:0].0-7 + W41: 33554432 # value 1 -> W41 bit[25]: ingress::hdr.gre.$valid + shift: 4 + buf_req: 4 + next: parse_inner_ipv6 + 0x******: + 0..1: TH0 + # - bit[0] -> TH0 bit[15]: ingress::hdr.gre.C + # - bit[1] -> TH0 bit[14]: ingress::hdr.gre.R + # - bit[2] -> TH0 bit[13]: ingress::hdr.gre.K + # - bit[3] -> TH0 bit[12]: ingress::hdr.gre.S + # - bit[4] -> TH0 bit[11]: ingress::hdr.gre.s + # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gre.recurse + # - bit[8..12] -> TH0 bit[7..3]: ingress::hdr.gre.flags + # - bit[13..15] -> TH0 bit[2..0]: ingress::hdr.gre.version + 2: TB1 # ingress::hdr.gre.proto[15:8].8-15 + 3: TB0 # ingress::hdr.gre.proto[7:0].0-7 + W41: 33554432 # value 1 -> W41 bit[25]: ingress::hdr.gre.$valid + shift: 4 + buf_req: 4 + next: end + parse_pptp: + match: [ half, byte0 ] + 0x00214*: + 0..1: TH1 + # - bit[0..3] -> TH1 bit[15..12]: ingress::hdr.pppoe.version + # - bit[4..7] -> TH1 bit[11..8]: ingress::hdr.pppoe.type + # - bit[8..15] -> TH1 bit[7..0]: ingress::hdr.pppoe.code + 2..3: TH2 # ingress::hdr.pppoe.session_id + 4..7: TW25 + # - bit[32..47] -> TW25 bit[31..16]: ingress::hdr.pppoe.pppoe_length + # - bit[48..63] -> TW25 bit[15..0]: ingress::hdr.pppoe.ppp_proto + W41: 4194304 # value 1 -> W41 bit[22]: ingress::hdr.pppoe.$valid + load: { byte1 : 17 } + shift: 8 + buf_req: 18 + next: parse_inner_ipv4 + 0x00216*: + 0..1: TH1 + # - bit[0..3] -> TH1 bit[15..12]: ingress::hdr.pppoe.version + # - bit[4..7] -> TH1 bit[11..8]: ingress::hdr.pppoe.type + # - bit[8..15] -> TH1 bit[7..0]: ingress::hdr.pppoe.code + 2..3: TH2 # ingress::hdr.pppoe.session_id + 4..7: TW25 + # - bit[32..47] -> TW25 bit[31..16]: ingress::hdr.pppoe.pppoe_length + # - bit[48..63] -> TW25 bit[15..0]: ingress::hdr.pppoe.ppp_proto + W41: 4194304 # value 1 -> W41 bit[22]: ingress::hdr.pppoe.$valid + shift: 8 + buf_req: 8 + next: parse_inner_ipv6 + 0x******: + 0..1: TH1 + # - bit[0..3] -> TH1 bit[15..12]: ingress::hdr.pppoe.version + # - bit[4..7] -> TH1 bit[11..8]: ingress::hdr.pppoe.type + # - bit[8..15] -> TH1 bit[7..0]: ingress::hdr.pppoe.code + 2..3: TH2 # ingress::hdr.pppoe.session_id + 4..7: TW25 + # - bit[32..47] -> TW25 bit[31..16]: ingress::hdr.pppoe.pppoe_length + # - bit[48..63] -> TW25 bit[15..0]: ingress::hdr.pppoe.ppp_proto + W41: 4194304 # value 1 -> W41 bit[22]: ingress::hdr.pppoe.$valid + shift: 8 + buf_req: 8 + next: end + parse_gre_ipv4: + *: + load: { byte1 : 9 } + buf_req: 10 + next: parse_inner_ipv4 + parse_ipv6: + *: + 0..3: TW0 + # - bit[0..3] -> TW0 bit[31..28]: ingress::hdr.ipv6.version + # - bit[4..11] -> TW0 bit[27..20]: ingress::hdr.ipv6.traffic_class + # - bit[12..31] -> TW0 bit[19..0]: ingress::hdr.ipv6.flow_label + 4..7: TW16 + # - bit[32..47] -> TW16 bit[31..16]: ingress::hdr.ipv6.payload_len + # - bit[48..55] -> TW16 bit[15..8]: ingress::hdr.ipv6.next_hdr + # - bit[56..63] -> TW16 bit[7..0]: ingress::hdr.ipv6.hop_limit + 6: B11 # ingress::ig_md.lkp.ip_proto + 8..11: W36 # ingress::hdr.ipv6.src_addr[127:96].96-127 + 8..11: W52 # ingress::ig_md.lkp.ip_src_addr[127:96].96-127 + 12: TB11 # ingress::hdr.ipv6.src_addr[95:88].88-95 + 13: TB10 # ingress::hdr.ipv6.src_addr[87:80].80-87 + 14: TB9 # ingress::hdr.ipv6.src_addr[79:72].72-79 + 16..17: TH38 # ingress::hdr.ipv6.src_addr[63:48].48-63 + 18..19: TH37 # ingress::hdr.ipv6.src_addr[47:32].32-47 + 20..21: TH36 # ingress::hdr.ipv6.src_addr[31:16].16-31 + 22..23: TH29 # ingress::hdr.ipv6.src_addr[15:0].0-15 + load: { byte1 : 6 } + shift: 12 + buf_req: 24 + next: parse_ipv6.$split_0 + parse_ipv6.$split_0: + *: + 0..3: W51 # ingress::ig_md.lkp.ip_src_addr[95:64].64-95 + 3: TB8 # ingress::hdr.ipv6.src_addr[71:64].64-71 + 4..7: W50 # ingress::ig_md.lkp.ip_src_addr[63:32].32-63 + 8..11: W49 # ingress::ig_md.lkp.ip_src_addr[31:0].0-31 + 12..15: W40 # ingress::hdr.ipv6.dst_addr[127:96].96-127 + shift: 12 + buf_req: 16 + next: parse_ipv6.$split_1 + parse_ipv6.$split_1: + *: + 0..3: W56 # ingress::ig_md.lkp.ip_dst_addr[127:96].96-127 + 4..7: W39 # ingress::hdr.ipv6.dst_addr[95:64].64-95 + 4..7: W55 # ingress::ig_md.lkp.ip_dst_addr[95:64].64-95 + 8..11: W38 # ingress::hdr.ipv6.dst_addr[63:32].32-63 + W41: 67108864 # value 1 -> W41 bit[26]: ingress::hdr.ipv6.$valid + shift: 8 + buf_req: 12 + next: parse_ipv6.$split_2 + parse_ipv6.$split_2: + match: [ byte1 ] + 0x06: + 0..3: W54 # ingress::ig_md.lkp.ip_dst_addr[63:32].32-63 + 4..7: W37 # ingress::hdr.ipv6.dst_addr[31:0].0-31 + 4..7: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 + shift: 8 + buf_req: 8 + next: parse_tcp + 0x11: + 0..3: W54 # ingress::ig_md.lkp.ip_dst_addr[63:32].32-63 + 4..7: W37 # ingress::hdr.ipv6.dst_addr[31:0].0-31 + 4..7: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 + load: { half : 10..11 } + shift: 8 + buf_req: 12 + next: parse_udp + 0x3a: + 0..3: W54 # ingress::ig_md.lkp.ip_dst_addr[63:32].32-63 + 4..7: W37 # ingress::hdr.ipv6.dst_addr[31:0].0-31 + 4..7: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 + shift: 8 + buf_req: 8 + next: parse_icmp + 0x84: + 0..3: W54 # ingress::ig_md.lkp.ip_dst_addr[63:32].32-63 + 4..7: W37 # ingress::hdr.ipv6.dst_addr[31:0].0-31 + 4..7: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 + load: { half : 10..11 } + shift: 8 + buf_req: 12 + next: parse_sctp + 0x29: + 0..3: W54 # ingress::ig_md.lkp.ip_dst_addr[63:32].32-63 + 4..7: W37 # ingress::hdr.ipv6.dst_addr[31:0].0-31 + 4..7: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 + shift: 8 + buf_req: 8 + next: parse_inner_ipv6 + 0x04: + 0..3: W54 # ingress::ig_md.lkp.ip_dst_addr[63:32].32-63 + 4..7: W37 # ingress::hdr.ipv6.dst_addr[31:0].0-31 + 4..7: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 + load: { byte1 : 17 } + shift: 8 + buf_req: 18 + next: parse_inner_ipv4 + 0x2f: + 0..3: W54 # ingress::ig_md.lkp.ip_dst_addr[63:32].32-63 + 4..7: W37 # ingress::hdr.ipv6.dst_addr[31:0].0-31 + 4..7: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 + load: { half : 9..10, byte0 : 11 } + shift: 8 + buf_req: 12 + next: parse_gre + 0x**: + 0..3: W54 # ingress::ig_md.lkp.ip_dst_addr[63:32].32-63 + 4..7: W37 # ingress::hdr.ipv6.dst_addr[31:0].0-31 + 4..7: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 + shift: 8 + buf_req: 8 + next: end + parse_vlan: + match: [ half ] + 0x0800: + 0..1: H4 + # - bit[0..2] -> H4 bit[15..13]: ingress::hdr.vlan_tag[0].pcp + # - bit[3] -> H4 bit[12]: ingress::hdr.vlan_tag[0].cfi + # - bit[4..15] -> H4 bit[11..0]: ingress::hdr.vlan_tag[0].vid + 2..3: TH4 # ingress::hdr.vlan_tag[0].ether_type + B2: 16 # value 16 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv4 + 0x86dd: + 0..1: H4 + # - bit[0..2] -> H4 bit[15..13]: ingress::hdr.vlan_tag[0].pcp + # - bit[3] -> H4 bit[12]: ingress::hdr.vlan_tag[0].cfi + # - bit[4..15] -> H4 bit[11..0]: ingress::hdr.vlan_tag[0].vid + 2..3: TH4 # ingress::hdr.vlan_tag[0].ether_type + B2: 16 # value 16 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv6 + 0x8100: + 0..1: H4 + # - bit[0..2] -> H4 bit[15..13]: ingress::hdr.vlan_tag[0].pcp + # - bit[3] -> H4 bit[12]: ingress::hdr.vlan_tag[0].cfi + # - bit[4..15] -> H4 bit[11..0]: ingress::hdr.vlan_tag[0].vid + 2..3: TH4 # ingress::hdr.vlan_tag[0].ether_type + B2: 16 # value 16 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + load: { half : 6..7 } + shift: 4 + buf_req: 8 + next: parse_vlan.$it1 + 0x8847: + 0..1: H4 + # - bit[0..2] -> H4 bit[15..13]: ingress::hdr.vlan_tag[0].pcp + # - bit[3] -> H4 bit[12]: ingress::hdr.vlan_tag[0].cfi + # - bit[4..15] -> H4 bit[11..0]: ingress::hdr.vlan_tag[0].vid + 2..3: TH4 # ingress::hdr.vlan_tag[0].ether_type + B2: 16 # value 16 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + load: { byte1 : 6 } + shift: 4 + buf_req: 7 + next: parse_mpls + 0x****: + 0..1: H4 + # - bit[0..2] -> H4 bit[15..13]: ingress::hdr.vlan_tag[0].pcp + # - bit[3] -> H4 bit[12]: ingress::hdr.vlan_tag[0].cfi + # - bit[4..15] -> H4 bit[11..0]: ingress::hdr.vlan_tag[0].vid + 2..3: TH4 # ingress::hdr.vlan_tag[0].ether_type + B2: 16 # value 16 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_vlan.$it1: + match: [ half ] + 0x0800: + 0..1: TH5 + # - bit[0..2] -> TH5 bit[15..13]: ingress::hdr.vlan_tag[1].pcp + # - bit[3] -> TH5 bit[12]: ingress::hdr.vlan_tag[1].cfi + # - bit[4..15] -> TH5 bit[11..0]: ingress::hdr.vlan_tag[1].vid + 2: TB3 # ingress::hdr.vlan_tag[1].ether_type[15:8].8-15 + 3: TB2 # ingress::hdr.vlan_tag[1].ether_type[7:0].0-7 + B2: 8 # value 8 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv4 + 0x86dd: + 0..1: TH5 + # - bit[0..2] -> TH5 bit[15..13]: ingress::hdr.vlan_tag[1].pcp + # - bit[3] -> TH5 bit[12]: ingress::hdr.vlan_tag[1].cfi + # - bit[4..15] -> TH5 bit[11..0]: ingress::hdr.vlan_tag[1].vid + 2: TB3 # ingress::hdr.vlan_tag[1].ether_type[15:8].8-15 + 3: TB2 # ingress::hdr.vlan_tag[1].ether_type[7:0].0-7 + B2: 8 # value 8 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv6 + 0x8100: + 0..1: TH5 + # - bit[0..2] -> TH5 bit[15..13]: ingress::hdr.vlan_tag[1].pcp + # - bit[3] -> TH5 bit[12]: ingress::hdr.vlan_tag[1].cfi + # - bit[4..15] -> TH5 bit[11..0]: ingress::hdr.vlan_tag[1].vid + 2: TB3 # ingress::hdr.vlan_tag[1].ether_type[15:8].8-15 + 3: TB2 # ingress::hdr.vlan_tag[1].ether_type[7:0].0-7 + B2: 8 # value 8 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + load: { half : 6..7 } + shift: 4 + buf_req: 8 + next: parse_vlan.$it2 + 0x8847: + 0..1: TH5 + # - bit[0..2] -> TH5 bit[15..13]: ingress::hdr.vlan_tag[1].pcp + # - bit[3] -> TH5 bit[12]: ingress::hdr.vlan_tag[1].cfi + # - bit[4..15] -> TH5 bit[11..0]: ingress::hdr.vlan_tag[1].vid + 2: TB3 # ingress::hdr.vlan_tag[1].ether_type[15:8].8-15 + 3: TB2 # ingress::hdr.vlan_tag[1].ether_type[7:0].0-7 + B2: 8 # value 8 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + load: { byte1 : 6 } + shift: 4 + buf_req: 7 + next: parse_mpls + 0x****: + 0..1: TH5 + # - bit[0..2] -> TH5 bit[15..13]: ingress::hdr.vlan_tag[1].pcp + # - bit[3] -> TH5 bit[12]: ingress::hdr.vlan_tag[1].cfi + # - bit[4..15] -> TH5 bit[11..0]: ingress::hdr.vlan_tag[1].vid + 2: TB3 # ingress::hdr.vlan_tag[1].ether_type[15:8].8-15 + 3: TB2 # ingress::hdr.vlan_tag[1].ether_type[7:0].0-7 + B2: 8 # value 8 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_vlan.$it2: + match: [ half ] + 0x0800: + 0..3: TW8 + # - bit[0..2] -> TW8 bit[31..29]: ingress::hdr.vlan_tag[2].pcp + # - bit[3] -> TW8 bit[28]: ingress::hdr.vlan_tag[2].cfi + # - bit[4..15] -> TW8 bit[27..16]: ingress::hdr.vlan_tag[2].vid + # - bit[16..31] -> TW8 bit[15..0]: ingress::hdr.vlan_tag[2].ether_type + B2: 4 # value 4 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv4 + 0x86dd: + 0..3: TW8 + # - bit[0..2] -> TW8 bit[31..29]: ingress::hdr.vlan_tag[2].pcp + # - bit[3] -> TW8 bit[28]: ingress::hdr.vlan_tag[2].cfi + # - bit[4..15] -> TW8 bit[27..16]: ingress::hdr.vlan_tag[2].vid + # - bit[16..31] -> TW8 bit[15..0]: ingress::hdr.vlan_tag[2].ether_type + B2: 4 # value 4 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv6 + 0x8100: + 0..3: TW8 + # - bit[0..2] -> TW8 bit[31..29]: ingress::hdr.vlan_tag[2].pcp + # - bit[3] -> TW8 bit[28]: ingress::hdr.vlan_tag[2].cfi + # - bit[4..15] -> TW8 bit[27..16]: ingress::hdr.vlan_tag[2].vid + # - bit[16..31] -> TW8 bit[15..0]: ingress::hdr.vlan_tag[2].ether_type + B2: 4 # value 4 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + load: { half : 6..7 } + shift: 4 + buf_req: 8 + next: parse_vlan.$it3 + 0x8847: + 0..3: TW8 + # - bit[0..2] -> TW8 bit[31..29]: ingress::hdr.vlan_tag[2].pcp + # - bit[3] -> TW8 bit[28]: ingress::hdr.vlan_tag[2].cfi + # - bit[4..15] -> TW8 bit[27..16]: ingress::hdr.vlan_tag[2].vid + # - bit[16..31] -> TW8 bit[15..0]: ingress::hdr.vlan_tag[2].ether_type + B2: 4 # value 4 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + load: { byte1 : 6 } + shift: 4 + buf_req: 7 + next: parse_mpls + 0x****: + 0..3: TW8 + # - bit[0..2] -> TW8 bit[31..29]: ingress::hdr.vlan_tag[2].pcp + # - bit[3] -> TW8 bit[28]: ingress::hdr.vlan_tag[2].cfi + # - bit[4..15] -> TW8 bit[27..16]: ingress::hdr.vlan_tag[2].vid + # - bit[16..31] -> TW8 bit[15..0]: ingress::hdr.vlan_tag[2].ether_type + B2: 4 # value 4 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_vlan.$it3: + match: [ half ] + 0x0800: + 0..3: TW9 + # - bit[0..2] -> TW9 bit[31..29]: ingress::hdr.vlan_tag[3].pcp + # - bit[3] -> TW9 bit[28]: ingress::hdr.vlan_tag[3].cfi + # - bit[4..15] -> TW9 bit[27..16]: ingress::hdr.vlan_tag[3].vid + # - bit[16..31] -> TW9 bit[15..0]: ingress::hdr.vlan_tag[3].ether_type + B2: 2 # value 2 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv4 + 0x86dd: + 0..3: TW9 + # - bit[0..2] -> TW9 bit[31..29]: ingress::hdr.vlan_tag[3].pcp + # - bit[3] -> TW9 bit[28]: ingress::hdr.vlan_tag[3].cfi + # - bit[4..15] -> TW9 bit[27..16]: ingress::hdr.vlan_tag[3].vid + # - bit[16..31] -> TW9 bit[15..0]: ingress::hdr.vlan_tag[3].ether_type + B2: 2 # value 2 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv6 + 0x8100: + 0..3: TW9 + # - bit[0..2] -> TW9 bit[31..29]: ingress::hdr.vlan_tag[3].pcp + # - bit[3] -> TW9 bit[28]: ingress::hdr.vlan_tag[3].cfi + # - bit[4..15] -> TW9 bit[27..16]: ingress::hdr.vlan_tag[3].vid + # - bit[16..31] -> TW9 bit[15..0]: ingress::hdr.vlan_tag[3].ether_type + B2: 2 # value 2 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + load: { half : 6..7 } + shift: 4 + buf_req: 8 + next: parse_vlan.$it4 + 0x8847: + 0..3: TW9 + # - bit[0..2] -> TW9 bit[31..29]: ingress::hdr.vlan_tag[3].pcp + # - bit[3] -> TW9 bit[28]: ingress::hdr.vlan_tag[3].cfi + # - bit[4..15] -> TW9 bit[27..16]: ingress::hdr.vlan_tag[3].vid + # - bit[16..31] -> TW9 bit[15..0]: ingress::hdr.vlan_tag[3].ether_type + B2: 2 # value 2 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + load: { byte1 : 6 } + shift: 4 + buf_req: 7 + next: parse_mpls + 0x****: + 0..3: TW9 + # - bit[0..2] -> TW9 bit[31..29]: ingress::hdr.vlan_tag[3].pcp + # - bit[3] -> TW9 bit[28]: ingress::hdr.vlan_tag[3].cfi + # - bit[4..15] -> TW9 bit[27..16]: ingress::hdr.vlan_tag[3].vid + # - bit[16..31] -> TW9 bit[15..0]: ingress::hdr.vlan_tag[3].ether_type + B2: 2 # value 2 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_vlan.$it4: + match: [ half ] + 0x0800: + 0..3: TW10 + # - bit[0..2] -> TW10 bit[31..29]: ingress::hdr.vlan_tag[4].pcp + # - bit[3] -> TW10 bit[28]: ingress::hdr.vlan_tag[4].cfi + # - bit[4..15] -> TW10 bit[27..16]: ingress::hdr.vlan_tag[4].vid + # - bit[16..31] -> TW10 bit[15..0]: ingress::hdr.vlan_tag[4].ether_type + B2: 1 # value 1 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv4 + 0x86dd: + 0..3: TW10 + # - bit[0..2] -> TW10 bit[31..29]: ingress::hdr.vlan_tag[4].pcp + # - bit[3] -> TW10 bit[28]: ingress::hdr.vlan_tag[4].cfi + # - bit[4..15] -> TW10 bit[27..16]: ingress::hdr.vlan_tag[4].vid + # - bit[16..31] -> TW10 bit[15..0]: ingress::hdr.vlan_tag[4].ether_type + B2: 1 # value 1 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv6 + 0x8100: + 0..3: TW10 + # - bit[0..2] -> TW10 bit[31..29]: ingress::hdr.vlan_tag[4].pcp + # - bit[3] -> TW10 bit[28]: ingress::hdr.vlan_tag[4].cfi + # - bit[4..15] -> TW10 bit[27..16]: ingress::hdr.vlan_tag[4].vid + # - bit[16..31] -> TW10 bit[15..0]: ingress::hdr.vlan_tag[4].ether_type + B2: 1 # value 1 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + 0x8847: + 0..3: TW10 + # - bit[0..2] -> TW10 bit[31..29]: ingress::hdr.vlan_tag[4].pcp + # - bit[3] -> TW10 bit[28]: ingress::hdr.vlan_tag[4].cfi + # - bit[4..15] -> TW10 bit[27..16]: ingress::hdr.vlan_tag[4].vid + # - bit[16..31] -> TW10 bit[15..0]: ingress::hdr.vlan_tag[4].ether_type + B2: 1 # value 1 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + load: { byte1 : 6 } + shift: 4 + buf_req: 7 + next: parse_mpls + 0x****: + 0..3: TW10 + # - bit[0..2] -> TW10 bit[31..29]: ingress::hdr.vlan_tag[4].pcp + # - bit[3] -> TW10 bit[28]: ingress::hdr.vlan_tag[4].cfi + # - bit[4..15] -> TW10 bit[27..16]: ingress::hdr.vlan_tag[4].vid + # - bit[16..31] -> TW10 bit[15..0]: ingress::hdr.vlan_tag[4].ether_type + B2: 1 # value 1 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_mpls: + match: [ byte1 ] + 0b*******0: + 0..3: TW11 + # - bit[0..19] -> TW11 bit[31..12]: ingress::hdr.mpls[0].label + # - bit[20..22] -> TW11 bit[11..9]: ingress::hdr.mpls[0].exp + # - bit[23] -> TW11 bit[8]: ingress::hdr.mpls[0].bos + # - bit[24..31] -> TW11 bit[7..0]: ingress::hdr.mpls[0].ttl + B3: 8 # value 8 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid + load: { byte1 : 6 } + shift: 4 + buf_req: 7 + next: parse_mpls.$it1 + 0b*******1: + 0..3: TW11 + # - bit[0..19] -> TW11 bit[31..12]: ingress::hdr.mpls[0].label + # - bit[20..22] -> TW11 bit[11..9]: ingress::hdr.mpls[0].exp + # - bit[23] -> TW11 bit[8]: ingress::hdr.mpls[0].bos + # - bit[24..31] -> TW11 bit[7..0]: ingress::hdr.mpls[0].ttl + B3: 8 # value 8 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid + load: { byte1 : 4 } + shift: 4 + buf_req: 5 + next: parse_mpls_bos + 0x**: + 0..3: TW11 + # - bit[0..19] -> TW11 bit[31..12]: ingress::hdr.mpls[0].label + # - bit[20..22] -> TW11 bit[11..9]: ingress::hdr.mpls[0].exp + # - bit[23] -> TW11 bit[8]: ingress::hdr.mpls[0].bos + # - bit[24..31] -> TW11 bit[7..0]: ingress::hdr.mpls[0].ttl + B3: 8 # value 8 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_mpls.$it1: + match: [ byte1 ] + 0b*******0: + 0..1: TH13 # ingress::hdr.mpls[1].label[19:4].4-19 + 2..3: TH12 + # - bit[16..19] -> TH12 bit[15..12]: ingress::hdr.mpls[1].label[3:0].0-3 + # - bit[20..22] -> TH12 bit[11..9]: ingress::hdr.mpls[1].exp + # - bit[23] -> TH12 bit[8]: ingress::hdr.mpls[1].bos + # - bit[24..31] -> TH12 bit[7..0]: ingress::hdr.mpls[1].ttl + B3: 4 # value 4 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid + load: { byte1 : 6 } + shift: 4 + buf_req: 7 + next: parse_mpls.$it2 + 0b*******1: + 0..1: TH13 # ingress::hdr.mpls[1].label[19:4].4-19 + 2..3: TH12 + # - bit[16..19] -> TH12 bit[15..12]: ingress::hdr.mpls[1].label[3:0].0-3 + # - bit[20..22] -> TH12 bit[11..9]: ingress::hdr.mpls[1].exp + # - bit[23] -> TH12 bit[8]: ingress::hdr.mpls[1].bos + # - bit[24..31] -> TH12 bit[7..0]: ingress::hdr.mpls[1].ttl + B3: 4 # value 4 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid + load: { byte1 : 4 } + shift: 4 + buf_req: 5 + next: parse_mpls_bos + 0x**: + 0..1: TH13 # ingress::hdr.mpls[1].label[19:4].4-19 + 2..3: TH12 + # - bit[16..19] -> TH12 bit[15..12]: ingress::hdr.mpls[1].label[3:0].0-3 + # - bit[20..22] -> TH12 bit[11..9]: ingress::hdr.mpls[1].exp + # - bit[23] -> TH12 bit[8]: ingress::hdr.mpls[1].bos + # - bit[24..31] -> TH12 bit[7..0]: ingress::hdr.mpls[1].ttl + B3: 4 # value 4 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_mpls.$it2: + match: [ byte1 ] + 0b*******0: + 0..1: TH15 # ingress::hdr.mpls[2].label[19:4].4-19 + 2..3: TH14 + # - bit[16..19] -> TH14 bit[15..12]: ingress::hdr.mpls[2].label[3:0].0-3 + # - bit[20..22] -> TH14 bit[11..9]: ingress::hdr.mpls[2].exp + # - bit[23] -> TH14 bit[8]: ingress::hdr.mpls[2].bos + # - bit[24..31] -> TH14 bit[7..0]: ingress::hdr.mpls[2].ttl + B3: 2 # value 2 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid + load: { byte1 : 6 } + shift: 4 + buf_req: 7 + next: parse_mpls.$it3 + 0b*******1: + 0..1: TH15 # ingress::hdr.mpls[2].label[19:4].4-19 + 2..3: TH14 + # - bit[16..19] -> TH14 bit[15..12]: ingress::hdr.mpls[2].label[3:0].0-3 + # - bit[20..22] -> TH14 bit[11..9]: ingress::hdr.mpls[2].exp + # - bit[23] -> TH14 bit[8]: ingress::hdr.mpls[2].bos + # - bit[24..31] -> TH14 bit[7..0]: ingress::hdr.mpls[2].ttl + B3: 2 # value 2 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid + load: { byte1 : 4 } + shift: 4 + buf_req: 5 + next: parse_mpls_bos + 0x**: + 0..1: TH15 # ingress::hdr.mpls[2].label[19:4].4-19 + 2..3: TH14 + # - bit[16..19] -> TH14 bit[15..12]: ingress::hdr.mpls[2].label[3:0].0-3 + # - bit[20..22] -> TH14 bit[11..9]: ingress::hdr.mpls[2].exp + # - bit[23] -> TH14 bit[8]: ingress::hdr.mpls[2].bos + # - bit[24..31] -> TH14 bit[7..0]: ingress::hdr.mpls[2].ttl + B3: 2 # value 2 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_mpls.$it3: + match: [ byte1 ] + 0b*******0: + 0..1: TH17 # ingress::hdr.mpls[3].label[19:4].4-19 + 2..3: TH16 + # - bit[16..19] -> TH16 bit[15..12]: ingress::hdr.mpls[3].label[3:0].0-3 + # - bit[20..22] -> TH16 bit[11..9]: ingress::hdr.mpls[3].exp + # - bit[23] -> TH16 bit[8]: ingress::hdr.mpls[3].bos + # - bit[24..31] -> TH16 bit[7..0]: ingress::hdr.mpls[3].ttl + B3: 1 # value 1 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid + shift: 4 + buf_req: 4 + next: end + 0b*******1: + 0..1: TH17 # ingress::hdr.mpls[3].label[19:4].4-19 + 2..3: TH16 + # - bit[16..19] -> TH16 bit[15..12]: ingress::hdr.mpls[3].label[3:0].0-3 + # - bit[20..22] -> TH16 bit[11..9]: ingress::hdr.mpls[3].exp + # - bit[23] -> TH16 bit[8]: ingress::hdr.mpls[3].bos + # - bit[24..31] -> TH16 bit[7..0]: ingress::hdr.mpls[3].ttl + B3: 1 # value 1 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid + load: { byte1 : 4 } + shift: 4 + buf_req: 5 + next: parse_mpls_bos + 0x**: + 0..1: TH17 # ingress::hdr.mpls[3].label[19:4].4-19 + 2..3: TH16 + # - bit[16..19] -> TH16 bit[15..12]: ingress::hdr.mpls[3].label[3:0].0-3 + # - bit[20..22] -> TH16 bit[11..9]: ingress::hdr.mpls[3].exp + # - bit[23] -> TH16 bit[8]: ingress::hdr.mpls[3].bos + # - bit[24..31] -> TH16 bit[7..0]: ingress::hdr.mpls[3].ttl + B3: 1 # value 1 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_mpls_bos: + match: [ byte1 ] + 0x4*: + 0..3: TW0 + # - bit[0..3] -> TW0 bit[31..28]: ingress::hdr.ipv4.version + # - bit[4..7] -> TW0 bit[27..24]: ingress::hdr.ipv4.ihl + # - bit[8..15] -> TW0 bit[23..16]: ingress::hdr.ipv4.diffserv + # - bit[16..31] -> TW0 bit[15..0]: ingress::hdr.ipv4.total_len + 4: TB11 # ingress::hdr.ipv4.identification[15:8].8-15 + 5: TB10 # ingress::hdr.ipv4.identification[7:0].0-7 + 6: TB8 + # - bit[48..50] -> TB8 bit[7..5]: ingress::hdr.ipv4.flags + # - bit[51..55] -> TB8 bit[4..0]: ingress::hdr.ipv4.frag_offset[12:8].8-12 + 7: TB9 # ingress::hdr.ipv4.frag_offset[7:0].0-7 + 8..11: TW16 + # - bit[64..71] -> TW16 bit[31..24]: ingress::hdr.ipv4.ttl + # - bit[72..79] -> TW16 bit[23..16]: ingress::hdr.ipv4.protocol + # - bit[80..95] -> TW16 bit[15..0]: ingress::hdr.ipv4.hdr_checksum + 12..13: TH36 # ingress::hdr.ipv4.src_addr[31:16].16-31 + 12..15: W49 # ingress::ig_md.lkp.ip_src_addr[31:0].0-31 + 14..15: TH29 # ingress::hdr.ipv4.src_addr[15:0].0-15 + 16..17: TH38 # ingress::hdr.ipv4.dst_addr[31:16].16-31 + 16..19: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 + 18..19: TH37 # ingress::hdr.ipv4.dst_addr[15:0].0-15 + load: { byte1 : 9 } + shift: 9 + buf_req: 20 + next: parse_ipv4.$split_0 + 0x6*: + 0..3: TW0 + # - bit[0..3] -> TW0 bit[31..28]: ingress::hdr.ipv6.version + # - bit[4..11] -> TW0 bit[27..20]: ingress::hdr.ipv6.traffic_class + # - bit[12..31] -> TW0 bit[19..0]: ingress::hdr.ipv6.flow_label + 4..7: TW16 + # - bit[32..47] -> TW16 bit[31..16]: ingress::hdr.ipv6.payload_len + # - bit[48..55] -> TW16 bit[15..8]: ingress::hdr.ipv6.next_hdr + # - bit[56..63] -> TW16 bit[7..0]: ingress::hdr.ipv6.hop_limit + 6: B11 # ingress::ig_md.lkp.ip_proto + 8..11: W36 # ingress::hdr.ipv6.src_addr[127:96].96-127 + 8..11: W52 # ingress::ig_md.lkp.ip_src_addr[127:96].96-127 + 12: TB11 # ingress::hdr.ipv6.src_addr[95:88].88-95 + 13: TB10 # ingress::hdr.ipv6.src_addr[87:80].80-87 + 14: TB9 # ingress::hdr.ipv6.src_addr[79:72].72-79 + 16..17: TH38 # ingress::hdr.ipv6.src_addr[63:48].48-63 + 18..19: TH37 # ingress::hdr.ipv6.src_addr[47:32].32-47 + 20..21: TH36 # ingress::hdr.ipv6.src_addr[31:16].16-31 + 22..23: TH29 # ingress::hdr.ipv6.src_addr[15:0].0-15 + load: { byte1 : 6 } + shift: 12 + buf_req: 24 + next: parse_ipv6.$split_0 + 0x**: + buf_req: 0 + next: end + TofinoIngressParserInner_2_parse_port_metadata.$oob_stall_0: + *: + load: { half : 11..12 } + buf_req: 13 + next: parse_fabric + parse_fabric: + match: [ half ] + 0x0800: + 0..3: W5 + # - bit[0] -> W5 bit[31]: ingress::hdr.fabric.pad1 + # - bit[1] -> W5 bit[30]: ingress::hdr.fabric.is_hit + # - bit[2] -> W5 bit[29]: ingress::hdr.fabric.is_to_cn78 + # - bit[3] -> W5 bit[28]: ingress::hdr.fabric.is_to_td3 + # - bit[4] -> W5 bit[27]: ingress::hdr.fabric.is_hdr_decap + # - bit[5..7] -> W5 bit[26..24]: ingress::hdr.fabric.ig_port_type + # - bit[8..13] -> W5 bit[23..18]: ingress::hdr.fabric.pad2 + # - bit[14..31] -> W5 bit[17..0]: ingress::hdr.fabric.mac_index + 4: B4 + # - bit[32..35] -> B4 bit[7..4]: ingress::hdr.fabric.pad4 + # - bit[36] -> B4 bit[3]: ingress::hdr.fabric.flags_drop + # - bit[37] -> B4 bit[2]: ingress::hdr.fabric.is_trunc_mir + # - bit[38..39] -> B4 bit[1..0]: ingress::hdr.fabric.count_index[17:16].16-17 + 5..8: W3 + # - bit[40..55] -> W3 bit[31..16]: ingress::hdr.fabric.count_index[15:0].0-15 + # - bit[56..71] -> W3 bit[15..0]: ingress::hdr.fabric.mc_index + 9..12: W4 + # - bit[72..87] -> W4 bit[31..16]: ingress::hdr.fabric.vlan_index + # - bit[88..103] -> W4 bit[15..0]: ingress::hdr.fabric.ether_type + W41: 134217728 # value 1 -> W41 bit[27]: ingress::hdr.fabric.$valid + shift: 13 + buf_req: 13 + next: parse_ipv4 + 0x86dd: + 0..3: W5 + # - bit[0] -> W5 bit[31]: ingress::hdr.fabric.pad1 + # - bit[1] -> W5 bit[30]: ingress::hdr.fabric.is_hit + # - bit[2] -> W5 bit[29]: ingress::hdr.fabric.is_to_cn78 + # - bit[3] -> W5 bit[28]: ingress::hdr.fabric.is_to_td3 + # - bit[4] -> W5 bit[27]: ingress::hdr.fabric.is_hdr_decap + # - bit[5..7] -> W5 bit[26..24]: ingress::hdr.fabric.ig_port_type + # - bit[8..13] -> W5 bit[23..18]: ingress::hdr.fabric.pad2 + # - bit[14..31] -> W5 bit[17..0]: ingress::hdr.fabric.mac_index + 4: B4 + # - bit[32..35] -> B4 bit[7..4]: ingress::hdr.fabric.pad4 + # - bit[36] -> B4 bit[3]: ingress::hdr.fabric.flags_drop + # - bit[37] -> B4 bit[2]: ingress::hdr.fabric.is_trunc_mir + # - bit[38..39] -> B4 bit[1..0]: ingress::hdr.fabric.count_index[17:16].16-17 + 5..8: W3 + # - bit[40..55] -> W3 bit[31..16]: ingress::hdr.fabric.count_index[15:0].0-15 + # - bit[56..71] -> W3 bit[15..0]: ingress::hdr.fabric.mc_index + 9..12: W4 + # - bit[72..87] -> W4 bit[31..16]: ingress::hdr.fabric.vlan_index + # - bit[88..103] -> W4 bit[15..0]: ingress::hdr.fabric.ether_type + W41: 134217728 # value 1 -> W41 bit[27]: ingress::hdr.fabric.$valid + shift: 13 + buf_req: 13 + next: parse_ipv6 + 0x8100: + 0..3: W5 + # - bit[0] -> W5 bit[31]: ingress::hdr.fabric.pad1 + # - bit[1] -> W5 bit[30]: ingress::hdr.fabric.is_hit + # - bit[2] -> W5 bit[29]: ingress::hdr.fabric.is_to_cn78 + # - bit[3] -> W5 bit[28]: ingress::hdr.fabric.is_to_td3 + # - bit[4] -> W5 bit[27]: ingress::hdr.fabric.is_hdr_decap + # - bit[5..7] -> W5 bit[26..24]: ingress::hdr.fabric.ig_port_type + # - bit[8..13] -> W5 bit[23..18]: ingress::hdr.fabric.pad2 + # - bit[14..31] -> W5 bit[17..0]: ingress::hdr.fabric.mac_index + 4: B4 + # - bit[32..35] -> B4 bit[7..4]: ingress::hdr.fabric.pad4 + # - bit[36] -> B4 bit[3]: ingress::hdr.fabric.flags_drop + # - bit[37] -> B4 bit[2]: ingress::hdr.fabric.is_trunc_mir + # - bit[38..39] -> B4 bit[1..0]: ingress::hdr.fabric.count_index[17:16].16-17 + 5..8: W3 + # - bit[40..55] -> W3 bit[31..16]: ingress::hdr.fabric.count_index[15:0].0-15 + # - bit[56..71] -> W3 bit[15..0]: ingress::hdr.fabric.mc_index + 9..12: W4 + # - bit[72..87] -> W4 bit[31..16]: ingress::hdr.fabric.vlan_index + # - bit[88..103] -> W4 bit[15..0]: ingress::hdr.fabric.ether_type + W41: 134217728 # value 1 -> W41 bit[27]: ingress::hdr.fabric.$valid + load: { half : 15..16 } + shift: 13 + buf_req: 17 + next: parse_vlan + 0x8847: + 0..3: W5 + # - bit[0] -> W5 bit[31]: ingress::hdr.fabric.pad1 + # - bit[1] -> W5 bit[30]: ingress::hdr.fabric.is_hit + # - bit[2] -> W5 bit[29]: ingress::hdr.fabric.is_to_cn78 + # - bit[3] -> W5 bit[28]: ingress::hdr.fabric.is_to_td3 + # - bit[4] -> W5 bit[27]: ingress::hdr.fabric.is_hdr_decap + # - bit[5..7] -> W5 bit[26..24]: ingress::hdr.fabric.ig_port_type + # - bit[8..13] -> W5 bit[23..18]: ingress::hdr.fabric.pad2 + # - bit[14..31] -> W5 bit[17..0]: ingress::hdr.fabric.mac_index + 4: B4 + # - bit[32..35] -> B4 bit[7..4]: ingress::hdr.fabric.pad4 + # - bit[36] -> B4 bit[3]: ingress::hdr.fabric.flags_drop + # - bit[37] -> B4 bit[2]: ingress::hdr.fabric.is_trunc_mir + # - bit[38..39] -> B4 bit[1..0]: ingress::hdr.fabric.count_index[17:16].16-17 + 5..8: W3 + # - bit[40..55] -> W3 bit[31..16]: ingress::hdr.fabric.count_index[15:0].0-15 + # - bit[56..71] -> W3 bit[15..0]: ingress::hdr.fabric.mc_index + 9..12: W4 + # - bit[72..87] -> W4 bit[31..16]: ingress::hdr.fabric.vlan_index + # - bit[88..103] -> W4 bit[15..0]: ingress::hdr.fabric.ether_type + W41: 134217728 # value 1 -> W41 bit[27]: ingress::hdr.fabric.$valid + load: { byte1 : 15 } + shift: 13 + buf_req: 16 + next: parse_mpls + 0x****: + 0..3: W5 + # - bit[0] -> W5 bit[31]: ingress::hdr.fabric.pad1 + # - bit[1] -> W5 bit[30]: ingress::hdr.fabric.is_hit + # - bit[2] -> W5 bit[29]: ingress::hdr.fabric.is_to_cn78 + # - bit[3] -> W5 bit[28]: ingress::hdr.fabric.is_to_td3 + # - bit[4] -> W5 bit[27]: ingress::hdr.fabric.is_hdr_decap + # - bit[5..7] -> W5 bit[26..24]: ingress::hdr.fabric.ig_port_type + # - bit[8..13] -> W5 bit[23..18]: ingress::hdr.fabric.pad2 + # - bit[14..31] -> W5 bit[17..0]: ingress::hdr.fabric.mac_index + 4: B4 + # - bit[32..35] -> B4 bit[7..4]: ingress::hdr.fabric.pad4 + # - bit[36] -> B4 bit[3]: ingress::hdr.fabric.flags_drop + # - bit[37] -> B4 bit[2]: ingress::hdr.fabric.is_trunc_mir + # - bit[38..39] -> B4 bit[1..0]: ingress::hdr.fabric.count_index[17:16].16-17 + 5..8: W3 + # - bit[40..55] -> W3 bit[31..16]: ingress::hdr.fabric.count_index[15:0].0-15 + # - bit[56..71] -> W3 bit[15..0]: ingress::hdr.fabric.mc_index + 9..12: W4 + # - bit[72..87] -> W4 bit[31..16]: ingress::hdr.fabric.vlan_index + # - bit[88..103] -> W4 bit[15..0]: ingress::hdr.fabric.ether_type + W41: 134217728 # value 1 -> W41 bit[27]: ingress::hdr.fabric.$valid + shift: 13 + buf_req: 13 + next: end + parse_from_cn78: + match: [ half ] + 0x0800: + 0..3: W4 # bit[0..7] -> W4 bit[31..24]: ingress::hdr.fabric_from_cn78.action_type + 2..5: W3 + # - bit[16..31] -> W3 bit[31..16]: ingress::hdr.fabric_from_cn78.port_group_id + # - bit[32..47] -> W3 bit[15..0]: ingress::hdr.fabric_from_cn78.ether_type + W41: 268435456 # value 1 -> W41 bit[28]: ingress::hdr.fabric_from_cn78.$valid + shift: 6 + buf_req: 6 + next: parse_ipv4 + 0x86dd: + 0..3: W4 # bit[0..7] -> W4 bit[31..24]: ingress::hdr.fabric_from_cn78.action_type + 2..5: W3 + # - bit[16..31] -> W3 bit[31..16]: ingress::hdr.fabric_from_cn78.port_group_id + # - bit[32..47] -> W3 bit[15..0]: ingress::hdr.fabric_from_cn78.ether_type + W41: 268435456 # value 1 -> W41 bit[28]: ingress::hdr.fabric_from_cn78.$valid + shift: 6 + buf_req: 6 + next: parse_ipv6 + 0x8100: + 0..3: W4 # bit[0..7] -> W4 bit[31..24]: ingress::hdr.fabric_from_cn78.action_type + 2..5: W3 + # - bit[16..31] -> W3 bit[31..16]: ingress::hdr.fabric_from_cn78.port_group_id + # - bit[32..47] -> W3 bit[15..0]: ingress::hdr.fabric_from_cn78.ether_type + W41: 268435456 # value 1 -> W41 bit[28]: ingress::hdr.fabric_from_cn78.$valid + load: { half : 8..9 } + shift: 6 + buf_req: 10 + next: parse_vlan + 0x8847: + 0..3: W4 # bit[0..7] -> W4 bit[31..24]: ingress::hdr.fabric_from_cn78.action_type + 2..5: W3 + # - bit[16..31] -> W3 bit[31..16]: ingress::hdr.fabric_from_cn78.port_group_id + # - bit[32..47] -> W3 bit[15..0]: ingress::hdr.fabric_from_cn78.ether_type + W41: 268435456 # value 1 -> W41 bit[28]: ingress::hdr.fabric_from_cn78.$valid + load: { byte1 : 8 } + shift: 6 + buf_req: 9 + next: parse_mpls + 0x****: + 0..3: W4 # bit[0..7] -> W4 bit[31..24]: ingress::hdr.fabric_from_cn78.action_type + 2..5: W3 + # - bit[16..31] -> W3 bit[31..16]: ingress::hdr.fabric_from_cn78.port_group_id + # - bit[32..47] -> W3 bit[15..0]: ingress::hdr.fabric_from_cn78.ether_type + W41: 268435456 # value 1 -> W41 bit[28]: ingress::hdr.fabric_from_cn78.$valid + shift: 6 + buf_req: 6 + next: end +deparser ingress: + dictionary: + B0: W41(0) # ingress::hdr.bridged_md.src if ingress::hdr.bridged_md.$valid + H3: W41(0) + # - bit[15..8]: ingress::hdr.bridged_md.pkt_proto_type if ingress::hdr.bridged_md.$valid + # - bit[7..0]: ingress::hdr.bridged_md.ip_hdr_location if ingress::hdr.bridged_md.$valid + B7: W41(0) + # - bit[7..1]: ingress::hdr.bridged_md.pad1 if ingress::hdr.bridged_md.$valid + # - bit[0]: ingress::hdr.bridged_md.tunnel_type.5-5 if ingress::hdr.bridged_md.$valid + B6: W41(0) + # - bit[7..3]: ingress::hdr.bridged_md.tunnel_type.0-4 if ingress::hdr.bridged_md.$valid + # - bit[2..0]: ingress::hdr.bridged_md.in_ig_port_type if ingress::hdr.bridged_md.$valid + TW26: W41(1) # ingress::hdr.ethernet.dst_addr.16-47 if ingress::hdr.ethernet.$valid + H7: W41(1) # ingress::hdr.ethernet.dst_addr.0-15 if ingress::hdr.ethernet.$valid + TW27: W41(1) # ingress::hdr.ethernet.src_addr.16-47 if ingress::hdr.ethernet.$valid + TH25: W41(1) # ingress::hdr.ethernet.src_addr.0-15 if ingress::hdr.ethernet.$valid + H5: W41(1) # ingress::hdr.ethernet.ether_type if ingress::hdr.ethernet.$valid + W5: W41(27) + # - bit[31]: ingress::hdr.fabric.pad1 if ingress::hdr.fabric.$valid + # - bit[30]: ingress::hdr.fabric.is_hit if ingress::hdr.fabric.$valid + # - bit[29]: ingress::hdr.fabric.is_to_cn78 if ingress::hdr.fabric.$valid + # - bit[28]: ingress::hdr.fabric.is_to_td3 if ingress::hdr.fabric.$valid + # - bit[27]: ingress::hdr.fabric.is_hdr_decap if ingress::hdr.fabric.$valid + # - bit[26..24]: ingress::hdr.fabric.ig_port_type if ingress::hdr.fabric.$valid + # - bit[23..18]: ingress::hdr.fabric.pad2 if ingress::hdr.fabric.$valid + # - bit[17..0]: ingress::hdr.fabric.mac_index if ingress::hdr.fabric.$valid + B4: W41(27) + # - bit[7..4]: ingress::hdr.fabric.pad4 if ingress::hdr.fabric.$valid + # - bit[3]: ingress::hdr.fabric.flags_drop if ingress::hdr.fabric.$valid + # - bit[2]: ingress::hdr.fabric.is_trunc_mir if ingress::hdr.fabric.$valid + # - bit[1..0]: ingress::hdr.fabric.count_index.16-17 if ingress::hdr.fabric.$valid + W3: W41(27) + # - bit[31..16]: ingress::hdr.fabric.count_index.0-15 if ingress::hdr.fabric.$valid + # - bit[15..0]: ingress::hdr.fabric.mc_index if ingress::hdr.fabric.$valid + W4: W41(27) + # - bit[31..16]: ingress::hdr.fabric.vlan_index if ingress::hdr.fabric.$valid + # - bit[15..0]: ingress::hdr.fabric.ether_type if ingress::hdr.fabric.$valid + H4: B2(4) + # - bit[15..13]: ingress::hdr.vlan_tag[0].pcp if ingress::hdr.vlan_tag[0].$valid + # - bit[12]: ingress::hdr.vlan_tag[0].cfi if ingress::hdr.vlan_tag[0].$valid + # - bit[11..0]: ingress::hdr.vlan_tag[0].vid if ingress::hdr.vlan_tag[0].$valid + TH4: B2(4) # ingress::hdr.vlan_tag[0].ether_type if ingress::hdr.vlan_tag[0].$valid + TH5: B2(3) + # - bit[15..13]: ingress::hdr.vlan_tag[1].pcp if ingress::hdr.vlan_tag[1].$valid + # - bit[12]: ingress::hdr.vlan_tag[1].cfi if ingress::hdr.vlan_tag[1].$valid + # - bit[11..0]: ingress::hdr.vlan_tag[1].vid if ingress::hdr.vlan_tag[1].$valid + TB3: B2(3) # ingress::hdr.vlan_tag[1].ether_type.8-15 if ingress::hdr.vlan_tag[1].$valid + TB2: B2(3) # ingress::hdr.vlan_tag[1].ether_type.0-7 if ingress::hdr.vlan_tag[1].$valid + TW8: B2(2) + # - bit[31..29]: ingress::hdr.vlan_tag[2].pcp if ingress::hdr.vlan_tag[2].$valid + # - bit[28]: ingress::hdr.vlan_tag[2].cfi if ingress::hdr.vlan_tag[2].$valid + # - bit[27..16]: ingress::hdr.vlan_tag[2].vid if ingress::hdr.vlan_tag[2].$valid + # - bit[15..0]: ingress::hdr.vlan_tag[2].ether_type if ingress::hdr.vlan_tag[2].$valid + TW9: B2(1) + # - bit[31..29]: ingress::hdr.vlan_tag[3].pcp if ingress::hdr.vlan_tag[3].$valid + # - bit[28]: ingress::hdr.vlan_tag[3].cfi if ingress::hdr.vlan_tag[3].$valid + # - bit[27..16]: ingress::hdr.vlan_tag[3].vid if ingress::hdr.vlan_tag[3].$valid + # - bit[15..0]: ingress::hdr.vlan_tag[3].ether_type if ingress::hdr.vlan_tag[3].$valid + TW10: B2(0) + # - bit[31..29]: ingress::hdr.vlan_tag[4].pcp if ingress::hdr.vlan_tag[4].$valid + # - bit[28]: ingress::hdr.vlan_tag[4].cfi if ingress::hdr.vlan_tag[4].$valid + # - bit[27..16]: ingress::hdr.vlan_tag[4].vid if ingress::hdr.vlan_tag[4].$valid + # - bit[15..0]: ingress::hdr.vlan_tag[4].ether_type if ingress::hdr.vlan_tag[4].$valid + TW11: B3(3) + # - bit[31..12]: ingress::hdr.mpls[0].label if ingress::hdr.mpls[0].$valid + # - bit[11..9]: ingress::hdr.mpls[0].exp if ingress::hdr.mpls[0].$valid + # - bit[8]: ingress::hdr.mpls[0].bos if ingress::hdr.mpls[0].$valid + # - bit[7..0]: ingress::hdr.mpls[0].ttl if ingress::hdr.mpls[0].$valid + TH13: B3(2) # ingress::hdr.mpls[1].label.4-19 if ingress::hdr.mpls[1].$valid + TH12: B3(2) + # - bit[15..12]: ingress::hdr.mpls[1].label.0-3 if ingress::hdr.mpls[1].$valid + # - bit[11..9]: ingress::hdr.mpls[1].exp if ingress::hdr.mpls[1].$valid + # - bit[8]: ingress::hdr.mpls[1].bos if ingress::hdr.mpls[1].$valid + # - bit[7..0]: ingress::hdr.mpls[1].ttl if ingress::hdr.mpls[1].$valid + TH15: B3(1) # ingress::hdr.mpls[2].label.4-19 if ingress::hdr.mpls[2].$valid + TH14: B3(1) + # - bit[15..12]: ingress::hdr.mpls[2].label.0-3 if ingress::hdr.mpls[2].$valid + # - bit[11..9]: ingress::hdr.mpls[2].exp if ingress::hdr.mpls[2].$valid + # - bit[8]: ingress::hdr.mpls[2].bos if ingress::hdr.mpls[2].$valid + # - bit[7..0]: ingress::hdr.mpls[2].ttl if ingress::hdr.mpls[2].$valid + TH17: B3(0) # ingress::hdr.mpls[3].label.4-19 if ingress::hdr.mpls[3].$valid + TH16: B3(0) + # - bit[15..12]: ingress::hdr.mpls[3].label.0-3 if ingress::hdr.mpls[3].$valid + # - bit[11..9]: ingress::hdr.mpls[3].exp if ingress::hdr.mpls[3].$valid + # - bit[8]: ingress::hdr.mpls[3].bos if ingress::hdr.mpls[3].$valid + # - bit[7..0]: ingress::hdr.mpls[3].ttl if ingress::hdr.mpls[3].$valid + TW0: W41(2) + # - bit[31..28]: ingress::hdr.ipv4.version if ingress::hdr.ipv4.$valid + # - bit[27..24]: ingress::hdr.ipv4.ihl if ingress::hdr.ipv4.$valid + # - bit[23..16]: ingress::hdr.ipv4.diffserv if ingress::hdr.ipv4.$valid + # - bit[15..0]: ingress::hdr.ipv4.total_len if ingress::hdr.ipv4.$valid + TB11: W41(2) # ingress::hdr.ipv4.identification.8-15 if ingress::hdr.ipv4.$valid + TB10: W41(2) # ingress::hdr.ipv4.identification.0-7 if ingress::hdr.ipv4.$valid + TB8: W41(2) + # - bit[7..5]: ingress::hdr.ipv4.flags if ingress::hdr.ipv4.$valid + # - bit[4..0]: ingress::hdr.ipv4.frag_offset.8-12 if ingress::hdr.ipv4.$valid + TB9: W41(2) # ingress::hdr.ipv4.frag_offset.0-7 if ingress::hdr.ipv4.$valid + TW16: W41(2) + # - bit[31..24]: ingress::hdr.ipv4.ttl if ingress::hdr.ipv4.$valid + # - bit[23..16]: ingress::hdr.ipv4.protocol if ingress::hdr.ipv4.$valid + # - bit[15..0]: ingress::hdr.ipv4.hdr_checksum if ingress::hdr.ipv4.$valid + TH36: W41(2) # ingress::hdr.ipv4.src_addr.16-31 if ingress::hdr.ipv4.$valid + TH29: W41(2) # ingress::hdr.ipv4.src_addr.0-15 if ingress::hdr.ipv4.$valid + TH38: W41(2) # ingress::hdr.ipv4.dst_addr.16-31 if ingress::hdr.ipv4.$valid + TH37: W41(2) # ingress::hdr.ipv4.dst_addr.0-15 if ingress::hdr.ipv4.$valid + TW0: W41(26) + # - bit[31..28]: ingress::hdr.ipv6.version if ingress::hdr.ipv6.$valid + # - bit[27..20]: ingress::hdr.ipv6.traffic_class if ingress::hdr.ipv6.$valid + # - bit[19..0]: ingress::hdr.ipv6.flow_label if ingress::hdr.ipv6.$valid + TW16: W41(26) + # - bit[31..16]: ingress::hdr.ipv6.payload_len if ingress::hdr.ipv6.$valid + # - bit[15..8]: ingress::hdr.ipv6.next_hdr if ingress::hdr.ipv6.$valid + # - bit[7..0]: ingress::hdr.ipv6.hop_limit if ingress::hdr.ipv6.$valid + W36: W41(26) # ingress::hdr.ipv6.src_addr.96-127 if ingress::hdr.ipv6.$valid + TB11: W41(26) # ingress::hdr.ipv6.src_addr.88-95 if ingress::hdr.ipv6.$valid + TB10: W41(26) # ingress::hdr.ipv6.src_addr.80-87 if ingress::hdr.ipv6.$valid + TB9: W41(26) # ingress::hdr.ipv6.src_addr.72-79 if ingress::hdr.ipv6.$valid + TB8: W41(26) # ingress::hdr.ipv6.src_addr.64-71 if ingress::hdr.ipv6.$valid + TH38: W41(26) # ingress::hdr.ipv6.src_addr.48-63 if ingress::hdr.ipv6.$valid + TH37: W41(26) # ingress::hdr.ipv6.src_addr.32-47 if ingress::hdr.ipv6.$valid + TH36: W41(26) # ingress::hdr.ipv6.src_addr.16-31 if ingress::hdr.ipv6.$valid + TH29: W41(26) # ingress::hdr.ipv6.src_addr.0-15 if ingress::hdr.ipv6.$valid + W40: W41(26) # ingress::hdr.ipv6.dst_addr.96-127 if ingress::hdr.ipv6.$valid + W39: W41(26) # ingress::hdr.ipv6.dst_addr.64-95 if ingress::hdr.ipv6.$valid + W38: W41(26) # ingress::hdr.ipv6.dst_addr.32-63 if ingress::hdr.ipv6.$valid + W37: W41(26) # ingress::hdr.ipv6.dst_addr.0-31 if ingress::hdr.ipv6.$valid + TW18: W41(16) + # - bit[31..16]: ingress::hdr.udp.src_port if ingress::hdr.udp.$valid + # - bit[15..0]: ingress::hdr.udp.dst_port if ingress::hdr.udp.$valid + TW19: W41(16) + # - bit[31..16]: ingress::hdr.udp.hdr_length if ingress::hdr.udp.$valid + # - bit[15..0]: ingress::hdr.udp.checksum if ingress::hdr.udp.$valid + TW18: W41(3) + # - bit[31..16]: ingress::hdr.tcp.src_port if ingress::hdr.tcp.$valid + # - bit[15..0]: ingress::hdr.tcp.dst_port if ingress::hdr.tcp.$valid + TW25: W41(3) # ingress::hdr.tcp.seq_no if ingress::hdr.tcp.$valid + TH39: W41(3) # ingress::hdr.tcp.ack_no.16-31 if ingress::hdr.tcp.$valid + TB24: W41(3) # ingress::hdr.tcp.ack_no.8-15 if ingress::hdr.tcp.$valid + TB19: W41(3) # ingress::hdr.tcp.ack_no.0-7 if ingress::hdr.tcp.$valid + TW1: W41(3) + # - bit[31..28]: ingress::hdr.tcp.data_offset if ingress::hdr.tcp.$valid + # - bit[27..24]: ingress::hdr.tcp.res if ingress::hdr.tcp.$valid + # - bit[23..16]: ingress::hdr.tcp.flags if ingress::hdr.tcp.$valid + # - bit[15..0]: ingress::hdr.tcp.window if ingress::hdr.tcp.$valid + TW19: W41(3) + # - bit[31..16]: ingress::hdr.tcp.checksum if ingress::hdr.tcp.$valid + # - bit[15..0]: ingress::hdr.tcp.urgent_ptr if ingress::hdr.tcp.$valid + TW1: W41(23) + # - bit[31..24]: ingress::hdr.icmp.type_ if ingress::hdr.icmp.$valid + # - bit[23..16]: ingress::hdr.icmp.code if ingress::hdr.icmp.$valid + # - bit[15..0]: ingress::hdr.icmp.hdr_checksum if ingress::hdr.icmp.$valid + TW1: W41(24) + # - bit[31..16]: ingress::hdr.sctp.src_port if ingress::hdr.sctp.$valid + # - bit[15..0]: ingress::hdr.sctp.dst_port if ingress::hdr.sctp.$valid + TW2: W41(24) # ingress::hdr.sctp.verifTag if ingress::hdr.sctp.$valid + TH0: W41(24) # ingress::hdr.sctp.checksum if ingress::hdr.sctp.$valid + TW1: W41(21) + # - bit[31..20]: ingress::hdr.l2tp.TLxxSxOP if ingress::hdr.l2tp.$valid + # - bit[19..16]: ingress::hdr.l2tp.version if ingress::hdr.l2tp.$valid + # - bit[15..8]: ingress::hdr.l2tp.l2tp_length if ingress::hdr.l2tp.$valid + # - bit[7..0]: ingress::hdr.l2tp.tunnel_id.8-15 if ingress::hdr.l2tp.$valid + TB0: W41(21) # ingress::hdr.l2tp.tunnel_id.0-7 if ingress::hdr.l2tp.$valid + TH26: W41(21) # ingress::hdr.l2tp.session_id if ingress::hdr.l2tp.$valid + TB19: W41(21) # ingress::hdr.l2tp.Ns.8-15 if ingress::hdr.l2tp.$valid + TB18: W41(21) # ingress::hdr.l2tp.Ns.0-7 if ingress::hdr.l2tp.$valid + TH0: W41(21) # ingress::hdr.l2tp.Nr if ingress::hdr.l2tp.$valid + TB17: W41(21) # ingress::hdr.l2tp.offset_size if ingress::hdr.l2tp.$valid + TB1: W41(21) # ingress::hdr.l2tp.offset_pad if ingress::hdr.l2tp.$valid + TH1: W41(22) + # - bit[15..12]: ingress::hdr.pppoe.version if ingress::hdr.pppoe.$valid + # - bit[11..8]: ingress::hdr.pppoe.type if ingress::hdr.pppoe.$valid + # - bit[7..0]: ingress::hdr.pppoe.code if ingress::hdr.pppoe.$valid + TH2: W41(22) # ingress::hdr.pppoe.session_id if ingress::hdr.pppoe.$valid + TW25: W41(22) + # - bit[31..16]: ingress::hdr.pppoe.pppoe_length if ingress::hdr.pppoe.$valid + # - bit[15..0]: ingress::hdr.pppoe.ppp_proto if ingress::hdr.pppoe.$valid + TH1: W41(22) + # - bit[15..12]: ingress::hdr.pppoe.version if ingress::hdr.pppoe.$valid + # - bit[11..8]: ingress::hdr.pppoe.type if ingress::hdr.pppoe.$valid + # - bit[7..0]: ingress::hdr.pppoe.code if ingress::hdr.pppoe.$valid + TH2: W41(22) # ingress::hdr.pppoe.session_id if ingress::hdr.pppoe.$valid + TW25: W41(22) + # - bit[31..16]: ingress::hdr.pppoe.pppoe_length if ingress::hdr.pppoe.$valid + # - bit[15..0]: ingress::hdr.pppoe.ppp_proto if ingress::hdr.pppoe.$valid + TH0: W41(25) + # - bit[15]: ingress::hdr.gre.C if ingress::hdr.gre.$valid + # - bit[14]: ingress::hdr.gre.R if ingress::hdr.gre.$valid + # - bit[13]: ingress::hdr.gre.K if ingress::hdr.gre.$valid + # - bit[12]: ingress::hdr.gre.S if ingress::hdr.gre.$valid + # - bit[11]: ingress::hdr.gre.s if ingress::hdr.gre.$valid + # - bit[10..8]: ingress::hdr.gre.recurse if ingress::hdr.gre.$valid + # - bit[7..3]: ingress::hdr.gre.flags if ingress::hdr.gre.$valid + # - bit[2..0]: ingress::hdr.gre.version if ingress::hdr.gre.$valid + TB1: W41(25) # ingress::hdr.gre.proto.8-15 if ingress::hdr.gre.$valid + TB0: W41(25) # ingress::hdr.gre.proto.0-7 if ingress::hdr.gre.$valid + TH0: W41(19) + # - bit[15..13]: ingress::hdr.gtpv1_8b.version if ingress::hdr.gtpv1_8b.$valid + # - bit[12]: ingress::hdr.gtpv1_8b.pt if ingress::hdr.gtpv1_8b.$valid + # - bit[11]: ingress::hdr.gtpv1_8b.reserved if ingress::hdr.gtpv1_8b.$valid + # - bit[10]: ingress::hdr.gtpv1_8b.e if ingress::hdr.gtpv1_8b.$valid + # - bit[9]: ingress::hdr.gtpv1_8b.s if ingress::hdr.gtpv1_8b.$valid + # - bit[8]: ingress::hdr.gtpv1_8b.pn if ingress::hdr.gtpv1_8b.$valid + # - bit[7..0]: ingress::hdr.gtpv1_8b.message_type if ingress::hdr.gtpv1_8b.$valid + TH1: W41(19) # ingress::hdr.gtpv1_8b.message_len if ingress::hdr.gtpv1_8b.$valid + TW1: W41(19) # ingress::hdr.gtpv1_8b.teid if ingress::hdr.gtpv1_8b.$valid + TH0: W41(20) + # - bit[15..13]: ingress::hdr.gtpv1_12b.version if ingress::hdr.gtpv1_12b.$valid + # - bit[12]: ingress::hdr.gtpv1_12b.pt if ingress::hdr.gtpv1_12b.$valid + # - bit[11]: ingress::hdr.gtpv1_12b.reserved if ingress::hdr.gtpv1_12b.$valid + # - bit[10]: ingress::hdr.gtpv1_12b.e if ingress::hdr.gtpv1_12b.$valid + # - bit[9]: ingress::hdr.gtpv1_12b.s if ingress::hdr.gtpv1_12b.$valid + # - bit[8]: ingress::hdr.gtpv1_12b.pn if ingress::hdr.gtpv1_12b.$valid + # - bit[7..0]: ingress::hdr.gtpv1_12b.message_type if ingress::hdr.gtpv1_12b.$valid + TH1: W41(20) # ingress::hdr.gtpv1_12b.message_len if ingress::hdr.gtpv1_12b.$valid + TW25: W41(20) # ingress::hdr.gtpv1_12b.teid if ingress::hdr.gtpv1_12b.$valid + TW1: W41(20) + # - bit[31..16]: ingress::hdr.gtpv1_12b.seq_no if ingress::hdr.gtpv1_12b.$valid + # - bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no if ingress::hdr.gtpv1_12b.$valid + # - bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t if ingress::hdr.gtpv1_12b.$valid + TH0: W41(4) + # - bit[15..13]: ingress::hdr.gtpv2_8b.version if ingress::hdr.gtpv2_8b.$valid + # - bit[12]: ingress::hdr.gtpv2_8b.pb if ingress::hdr.gtpv2_8b.$valid + # - bit[11]: ingress::hdr.gtpv2_8b.tf if ingress::hdr.gtpv2_8b.$valid + # - bit[10..8]: ingress::hdr.gtpv2_8b.spare1 if ingress::hdr.gtpv2_8b.$valid + # - bit[7..0]: ingress::hdr.gtpv2_8b.message_type if ingress::hdr.gtpv2_8b.$valid + TH1: W41(4) # ingress::hdr.gtpv2_8b.total_len if ingress::hdr.gtpv2_8b.$valid + TH26: W41(4) # ingress::hdr.gtpv2_8b.seq_no.8-23 if ingress::hdr.gtpv2_8b.$valid + TB18: W41(4) # ingress::hdr.gtpv2_8b.seq_no.0-7 if ingress::hdr.gtpv2_8b.$valid + TB17: W41(4) # ingress::hdr.gtpv2_8b.spare2 if ingress::hdr.gtpv2_8b.$valid + TH0: W41(15) + # - bit[15..13]: ingress::hdr.gtpv2_12b.version if ingress::hdr.gtpv2_12b.$valid + # - bit[12]: ingress::hdr.gtpv2_12b.pb if ingress::hdr.gtpv2_12b.$valid + # - bit[11]: ingress::hdr.gtpv2_12b.tf if ingress::hdr.gtpv2_12b.$valid + # - bit[10..8]: ingress::hdr.gtpv2_12b.spare1 if ingress::hdr.gtpv2_12b.$valid + # - bit[7..0]: ingress::hdr.gtpv2_12b.message_type if ingress::hdr.gtpv2_12b.$valid + TH1: W41(15) # ingress::hdr.gtpv2_12b.total_len if ingress::hdr.gtpv2_12b.$valid + W35: W41(15) # ingress::hdr.gtpv2_12b.teid if ingress::hdr.gtpv2_12b.$valid + TH26: W41(15) # ingress::hdr.gtpv2_12b.seq_no.8-23 if ingress::hdr.gtpv2_12b.$valid + TB18: W41(15) # ingress::hdr.gtpv2_12b.seq_no.0-7 if ingress::hdr.gtpv2_12b.$valid + TB17: W41(15) # ingress::hdr.gtpv2_12b.spare2 if ingress::hdr.gtpv2_12b.$valid + TB1: W41(6) # ingress::hdr.cause_ie_6b.type if ingress::hdr.cause_ie_6b.$valid + TW3: W41(6) + # - bit[31..16]: ingress::hdr.cause_ie_6b.len if ingress::hdr.cause_ie_6b.$valid + # - bit[15..12]: ingress::hdr.cause_ie_6b.spare1 if ingress::hdr.cause_ie_6b.$valid + # - bit[11..8]: ingress::hdr.cause_ie_6b.instance if ingress::hdr.cause_ie_6b.$valid + # - bit[7..0]: ingress::hdr.cause_ie_6b.cause_value if ingress::hdr.cause_ie_6b.$valid + TB0: W41(6) + # - bit[7..3]: ingress::hdr.cause_ie_6b.spare2 if ingress::hdr.cause_ie_6b.$valid + # - bit[2]: ingress::hdr.cause_ie_6b.pce if ingress::hdr.cause_ie_6b.$valid + # - bit[1]: ingress::hdr.cause_ie_6b.bce if ingress::hdr.cause_ie_6b.$valid + # - bit[0]: ingress::hdr.cause_ie_6b.cs if ingress::hdr.cause_ie_6b.$valid + TB1: W41(7) # ingress::hdr.cause_ie_10b.type if ingress::hdr.cause_ie_10b.$valid + TW3: W41(7) + # - bit[31..16]: ingress::hdr.cause_ie_10b.len if ingress::hdr.cause_ie_10b.$valid + # - bit[15..12]: ingress::hdr.cause_ie_10b.spare1 if ingress::hdr.cause_ie_10b.$valid + # - bit[11..8]: ingress::hdr.cause_ie_10b.instance if ingress::hdr.cause_ie_10b.$valid + # - bit[7..0]: ingress::hdr.cause_ie_10b.cause_value if ingress::hdr.cause_ie_10b.$valid + TB0: W41(7) + # - bit[7..3]: ingress::hdr.cause_ie_10b.spare2 if ingress::hdr.cause_ie_10b.$valid + # - bit[2]: ingress::hdr.cause_ie_10b.pce if ingress::hdr.cause_ie_10b.$valid + # - bit[1]: ingress::hdr.cause_ie_10b.bce if ingress::hdr.cause_ie_10b.$valid + # - bit[0]: ingress::hdr.cause_ie_10b.cs if ingress::hdr.cause_ie_10b.$valid + TH3: W41(7) + # - bit[15..8]: ingress::hdr.cause_ie_10b.type_oe if ingress::hdr.cause_ie_10b.$valid + # - bit[7..0]: ingress::hdr.cause_ie_10b.len_oe.8-15 if ingress::hdr.cause_ie_10b.$valid + TH2: W41(7) + # - bit[15..8]: ingress::hdr.cause_ie_10b.len_oe.0-7 if ingress::hdr.cause_ie_10b.$valid + # - bit[7..4]: ingress::hdr.cause_ie_10b.spare_oe if ingress::hdr.cause_ie_10b.$valid + # - bit[3..0]: ingress::hdr.cause_ie_10b.instance_oe if ingress::hdr.cause_ie_10b.$valid + TW2: W41(5) + # - bit[31..24]: ingress::hdr.imsi.type if ingress::hdr.imsi.$valid + # - bit[23..8]: ingress::hdr.imsi.len if ingress::hdr.imsi.$valid + # - bit[7..4]: ingress::hdr.imsi.spare if ingress::hdr.imsi.$valid + # - bit[3..0]: ingress::hdr.imsi.instance if ingress::hdr.imsi.$valid + TH28: W41(5) # ingress::hdr.imsi.num_digit.112-127 if ingress::hdr.imsi.$valid + TB25: W41(5) # ingress::hdr.imsi.num_digit.104-111 if ingress::hdr.imsi.$valid + TB16: W41(5) # ingress::hdr.imsi.num_digit.96-103 if ingress::hdr.imsi.$valid + TH27: W41(5) # ingress::hdr.imsi.num_digit.80-95 if ingress::hdr.imsi.$valid + TH24: W41(5) # ingress::hdr.imsi.num_digit.64-79 if ingress::hdr.imsi.$valid + TW24: W41(5) # ingress::hdr.imsi.num_digit.32-63 if ingress::hdr.imsi.$valid + TW17: W41(5) # ingress::hdr.imsi.num_digit.0-31 if ingress::hdr.imsi.$valid + TW1: W41(17) + # - bit[31..24]: ingress::hdr.vxlan.flags if ingress::hdr.vxlan.$valid + # - bit[23..0]: ingress::hdr.vxlan.reserved if ingress::hdr.vxlan.$valid + TH1: W41(17) # ingress::hdr.vxlan.vni.8-23 if ingress::hdr.vxlan.$valid + TH0: W41(17) + # - bit[15..8]: ingress::hdr.vxlan.vni.0-7 if ingress::hdr.vxlan.$valid + # - bit[7..0]: ingress::hdr.vxlan.reserved2 if ingress::hdr.vxlan.$valid + TW25: W41(18) # ingress::hdr.inner_ethernet.dst_addr.16-47 if ingress::hdr.inner_ethernet.$valid + TB18: W41(18) # ingress::hdr.inner_ethernet.dst_addr.8-15 if ingress::hdr.inner_ethernet.$valid + TB17: W41(18) # ingress::hdr.inner_ethernet.dst_addr.0-7 if ingress::hdr.inner_ethernet.$valid + TH39: W41(18) # ingress::hdr.inner_ethernet.src_addr.32-47 if ingress::hdr.inner_ethernet.$valid + TB1: W41(18) # ingress::hdr.inner_ethernet.src_addr.24-31 if ingress::hdr.inner_ethernet.$valid + TB0: W41(18) # ingress::hdr.inner_ethernet.src_addr.16-23 if ingress::hdr.inner_ethernet.$valid + TH26: W41(18) # ingress::hdr.inner_ethernet.src_addr.0-15 if ingress::hdr.inner_ethernet.$valid + TH2: W41(18) # ingress::hdr.inner_ethernet.ether_type if ingress::hdr.inner_ethernet.$valid + TW2: W41(8) + # - bit[31..28]: ingress::hdr.inner_ipv4.version if ingress::hdr.inner_ipv4.$valid + # - bit[27..24]: ingress::hdr.inner_ipv4.ihl if ingress::hdr.inner_ipv4.$valid + # - bit[23..16]: ingress::hdr.inner_ipv4.diffserv if ingress::hdr.inner_ipv4.$valid + # - bit[15..0]: ingress::hdr.inner_ipv4.total_len if ingress::hdr.inner_ipv4.$valid + TH24: W41(8) # ingress::hdr.inner_ipv4.identification if ingress::hdr.inner_ipv4.$valid + TH3: W41(8) + # - bit[15..13]: ingress::hdr.inner_ipv4.flags if ingress::hdr.inner_ipv4.$valid + # - bit[12..0]: ingress::hdr.inner_ipv4.frag_offset if ingress::hdr.inner_ipv4.$valid + TW17: W41(8) + # - bit[31..24]: ingress::hdr.inner_ipv4.ttl if ingress::hdr.inner_ipv4.$valid + # - bit[23..16]: ingress::hdr.inner_ipv4.protocol if ingress::hdr.inner_ipv4.$valid + # - bit[15..0]: ingress::hdr.inner_ipv4.hdr_checksum if ingress::hdr.inner_ipv4.$valid + TH40: W41(8) # ingress::hdr.inner_ipv4.src_addr.16-31 if ingress::hdr.inner_ipv4.$valid + TB25: W41(8) # ingress::hdr.inner_ipv4.src_addr.8-15 if ingress::hdr.inner_ipv4.$valid + TB16: W41(8) # ingress::hdr.inner_ipv4.src_addr.0-7 if ingress::hdr.inner_ipv4.$valid + TH41: W41(8) # ingress::hdr.inner_ipv4.dst_addr.16-31 if ingress::hdr.inner_ipv4.$valid + TB27: W41(8) # ingress::hdr.inner_ipv4.dst_addr.8-15 if ingress::hdr.inner_ipv4.$valid + TB26: W41(8) # ingress::hdr.inner_ipv4.dst_addr.0-7 if ingress::hdr.inner_ipv4.$valid + TW2: W41(14) + # - bit[31..28]: ingress::hdr.inner_ipv6.version if ingress::hdr.inner_ipv6.$valid + # - bit[27..20]: ingress::hdr.inner_ipv6.traffic_class if ingress::hdr.inner_ipv6.$valid + # - bit[19..0]: ingress::hdr.inner_ipv6.flow_label if ingress::hdr.inner_ipv6.$valid + TH3: W41(14) # ingress::hdr.inner_ipv6.payload_len if ingress::hdr.inner_ipv6.$valid + B8: W41(14) # ingress::hdr.inner_ipv6.next_hdr if ingress::hdr.inner_ipv6.$valid + TB16: W41(14) # ingress::hdr.inner_ipv6.hop_limit if ingress::hdr.inner_ipv6.$valid + W14: W41(14) # ingress::hdr.inner_ipv6.src_addr.96-127 if ingress::hdr.inner_ipv6.$valid + W13: W41(14) # ingress::hdr.inner_ipv6.src_addr.64-95 if ingress::hdr.inner_ipv6.$valid + W12: W41(14) # ingress::hdr.inner_ipv6.src_addr.32-63 if ingress::hdr.inner_ipv6.$valid + W11: W41(14) # ingress::hdr.inner_ipv6.src_addr.0-31 if ingress::hdr.inner_ipv6.$valid + W34: W41(14) # ingress::hdr.inner_ipv6.dst_addr.96-127 if ingress::hdr.inner_ipv6.$valid + W33: W41(14) # ingress::hdr.inner_ipv6.dst_addr.64-95 if ingress::hdr.inner_ipv6.$valid + W32: W41(14) # ingress::hdr.inner_ipv6.dst_addr.32-63 if ingress::hdr.inner_ipv6.$valid + W15: W41(14) # ingress::hdr.inner_ipv6.dst_addr.0-31 if ingress::hdr.inner_ipv6.$valid + TW3: W41(11) + # - bit[31..16]: ingress::hdr.inner_udp.src_port if ingress::hdr.inner_udp.$valid + # - bit[15..0]: ingress::hdr.inner_udp.dst_port if ingress::hdr.inner_udp.$valid + TW24: W41(11) + # - bit[31..16]: ingress::hdr.inner_udp.hdr_length if ingress::hdr.inner_udp.$valid + # - bit[15..0]: ingress::hdr.inner_udp.checksum if ingress::hdr.inner_udp.$valid + TH28: W41(9) # ingress::hdr.inner_tcp.src_port if ingress::hdr.inner_tcp.$valid + TH27: W41(9) # ingress::hdr.inner_tcp.dst_port if ingress::hdr.inner_tcp.$valid + W6: W41(9) # ingress::hdr.inner_tcp.seq_no if ingress::hdr.inner_tcp.$valid + W7: W41(9) # ingress::hdr.inner_tcp.ack_no if ingress::hdr.inner_tcp.$valid + TW3: W41(9) + # - bit[31..28]: ingress::hdr.inner_tcp.data_offset if ingress::hdr.inner_tcp.$valid + # - bit[27..24]: ingress::hdr.inner_tcp.res if ingress::hdr.inner_tcp.$valid + # - bit[23..16]: ingress::hdr.inner_tcp.flags if ingress::hdr.inner_tcp.$valid + # - bit[15..0]: ingress::hdr.inner_tcp.window if ingress::hdr.inner_tcp.$valid + TW24: W41(9) + # - bit[31..16]: ingress::hdr.inner_tcp.checksum if ingress::hdr.inner_tcp.$valid + # - bit[15..0]: ingress::hdr.inner_tcp.urgent_ptr if ingress::hdr.inner_tcp.$valid + TW3: W41(12) + # - bit[31..24]: ingress::hdr.inner_icmp.type_ if ingress::hdr.inner_icmp.$valid + # - bit[23..16]: ingress::hdr.inner_icmp.code if ingress::hdr.inner_icmp.$valid + # - bit[15..0]: ingress::hdr.inner_icmp.hdr_checksum if ingress::hdr.inner_icmp.$valid + W9: W41(13) # ingress::hdr.ipsec_esp.spi if ingress::hdr.ipsec_esp.$valid + W10: W41(13) # ingress::hdr.ipsec_esp.sn if ingress::hdr.ipsec_esp.$valid + W8: W41(10) # ingress::hdr.sip.data if ingress::hdr.sip.$valid + egress_unicast_port: H1(0..8) # bit[8..0]: ingress::ig_intr_md_for_tm.ucast_egress_port + bypss_egr: B2(5..5) # bit[5]: ingress::ig_intr_md_for_tm.bypass_egress + drop_ctl: B3(4..6) # bit[6..4]: ingress::ig_intr_md_for_dprsr.drop_ctl + egress_multicast_group_1: + - H0 # ingress::ig_intr_md_for_tm.mcast_grp_b + hash_lag_ecmp_mcast_0: + - W0(0..12) # bit[12..0]: ingress::ig_intr_md_for_tm.level1_mcast_hash + hash_lag_ecmp_mcast_1: + - W1(0..12) # bit[12..0]: ingress::ig_intr_md_for_tm.level2_mcast_hash + mirror: + select: B1(0..2) # bit[2..0]: ingress::ig_intr_md_for_dprsr.mirror_type + 5: + - H2(0..9) # bit[9..0]: ingress::ig_md.mirror.session_id + - B9 # ingress::ig_md.mirror.src + - B10 # ingress::ig_md.mirror.type + - H2(0..9) # bit[9..0]: ingress::ig_md.mirror.session_id + - H6(0..9) # bit[9..0]: ingress::ig_md.count_index.8-17 + - B5 # ingress::ig_md.count_index.0-7 + - H8 # ingress::ig_md.vlan_index +parser egress: + start: $entry_point + init_zero: [ H25, H26, B20, W48, B17, B16 ] + bitwise_or: [ B16, B17, W48 ] + hdr_len_adj: 27 + meta_opt: 8191 + states: + $entry_point: + *: + load: { byte1 : 27 } + buf_req: 28 + next: start + start: + match: [ byte1 ] + 0x00: + 0..1: H16 # bit[7..15] -> H16 bit[8..0]: egress::eg_intr_md.egress_port + shift: 27 + buf_req: 27 + next: parse_bridged_metadata + 0x01: + 0..1: H16 # bit[7..15] -> H16 bit[8..0]: egress::eg_intr_md.egress_port + shift: 27 + buf_req: 27 + next: parse_truncate_only_metadata + 0x**: + 0..1: H16 # bit[7..15] -> H16 bit[8..0]: egress::eg_intr_md.egress_port + shift: 27 + buf_req: 27 + next: end + parse_bridged_metadata: + *: + 1..2: H23 + # - bit[8..15] -> H23 bit[15..8]: egress::eg_md.pkt_proto_type + # - bit[16..23] -> H23 bit[7..0]: egress::eg_md.ip_hdr_location + 4: B20 # bit[37..39] -> B20 bit[2..0]: egress::eg_md.in_ig_port_type + shift: 5 + buf_req: 5 + next: parse_ethernet + parse_ethernet: + *: + 0..3: TW31 # egress::hdr.ethernet.dst_addr[47:16].16-47 + 4..5: H24 # egress::hdr.ethernet.dst_addr[15:0].0-15 + 6..7: TH42 # egress::hdr.ethernet.src_addr[47:32].32-47 + 8..9: TH35 # egress::hdr.ethernet.src_addr[31:16].16-31 + 10..11: TH6 # egress::hdr.ethernet.src_addr[15:0].0-15 + W48: 2 # value 1 -> W48 bit[1]: egress::hdr.ethernet.$valid + load: { half : 12..13 } + shift: 12 + buf_req: 14 + next: parse_ethernet.$split_0 + parse_ethernet.$split_0: + match: [ half ] + 0x0800: + 0..1: H19 # egress::hdr.ethernet.ether_type + shift: 2 + buf_req: 2 + next: parse_ipv4 + 0x86dd: + 0..1: H19 # egress::hdr.ethernet.ether_type + shift: 2 + buf_req: 2 + next: parse_ipv6 + 0x8100: + 0..1: H19 # egress::hdr.ethernet.ether_type + load: { half : 4..5 } + shift: 2 + buf_req: 6 + next: parse_vlan + 0x8847: + 0..1: H19 # egress::hdr.ethernet.ether_type + load: { byte1 : 4 } + shift: 2 + buf_req: 5 + next: parse_mpls + 0x81fe: + 0..1: H19 # egress::hdr.ethernet.ether_type + load: { half : 13..14 } + shift: 2 + buf_req: 15 + next: parse_fabric + 0x****: + 0..1: H19 # egress::hdr.ethernet.ether_type + shift: 2 + buf_req: 2 + next: end + parse_ipv4: + *: + 0..3: TW4 + # - bit[0..3] -> TW4 bit[31..28]: egress::hdr.ipv4.version + # - bit[4..7] -> TW4 bit[27..24]: egress::hdr.ipv4.ihl + # - bit[8..15] -> TW4 bit[23..16]: egress::hdr.ipv4.diffserv + # - bit[16..31] -> TW4 bit[15..0]: egress::hdr.ipv4.total_len + 4..7: TW20 + # - bit[32..47] -> TW20 bit[31..16]: egress::hdr.ipv4.identification + # - bit[48..50] -> TW20 bit[15..13]: egress::hdr.ipv4.flags + # - bit[51..63] -> TW20 bit[12..0]: egress::hdr.ipv4.frag_offset + 8..9: TH31 + # - bit[64..71] -> TH31 bit[15..8]: egress::hdr.ipv4.ttl + # - bit[72..79] -> TH31 bit[7..0]: egress::hdr.ipv4.protocol + 8..11: TW22 # bit[80..95] -> TW22 bit[15..0]: egress::hdr.ipv4.hdr_checksum + 12..13: TH44 # egress::hdr.ipv4.src_addr[31:16].16-31 + 14..15: TH43 # egress::hdr.ipv4.src_addr[15:0].0-15 + 16..17: TH46 # egress::hdr.ipv4.dst_addr[31:16].16-31 + W48: 4 # value 1 -> W48 bit[2]: egress::hdr.ipv4.$valid + load: { byte1 : 9 } + shift: 18 + buf_req: 18 + next: parse_ipv4.$split_0 + parse_ipv4.$split_0: + match: [ byte1 ] + 0x06: + 0..1: TH45 # egress::hdr.ipv4.dst_addr[15:0].0-15 + load: { half : 4..5 } + shift: 2 + buf_req: 6 + next: parse_tcp + 0x11: + 0..1: TH45 # egress::hdr.ipv4.dst_addr[15:0].0-15 + load: { half : 4..5 } + shift: 2 + buf_req: 6 + next: parse_udp + 0x01: + 0..1: TH45 # egress::hdr.ipv4.dst_addr[15:0].0-15 + shift: 2 + buf_req: 2 + next: parse_icmp + 0x84: + 0..1: TH45 # egress::hdr.ipv4.dst_addr[15:0].0-15 + load: { half : 4..5 } + shift: 2 + buf_req: 6 + next: parse_sctp + 0x29: + 0..1: TH45 # egress::hdr.ipv4.dst_addr[15:0].0-15 + shift: 2 + buf_req: 2 + next: parse_inner_ipv6 + 0x04: + 0..1: TH45 # egress::hdr.ipv4.dst_addr[15:0].0-15 + load: { byte1 : 11 } + shift: 2 + buf_req: 12 + next: parse_inner_ipv4 + 0x2f: + 0..1: TH45 # egress::hdr.ipv4.dst_addr[15:0].0-15 + load: { half : 3..4, byte0 : 5 } + shift: 2 + buf_req: 6 + next: parse_gre + 0x**: + 0..1: TH45 # egress::hdr.ipv4.dst_addr[15:0].0-15 + shift: 2 + buf_req: 2 + next: end + parse_tcp: + match: [ half ] + 0x01bb: + 0..3: TW23 + # - bit[0..15] -> TW23 bit[31..16]: egress::hdr.tcp.src_port + # - bit[16..31] -> TW23 bit[15..0]: egress::hdr.tcp.dst_port + 4..7: TW30 # egress::hdr.tcp.seq_no + 8..9: TH47 # egress::hdr.tcp.ack_no[31:16].16-31 + 10: TB28 # egress::hdr.tcp.ack_no[15:8].8-15 + 11: TB23 # egress::hdr.tcp.ack_no[7:0].0-7 + 12..15: TW5 + # - bit[96..99] -> TW5 bit[31..28]: egress::hdr.tcp.data_offset + # - bit[100..103] -> TW5 bit[27..24]: egress::hdr.tcp.res + # - bit[104..111] -> TW5 bit[23..16]: egress::hdr.tcp.flags + # - bit[112..127] -> TW5 bit[15..0]: egress::hdr.tcp.window + 16..17: TH32 # egress::hdr.tcp.checksum + 18: TB22 # egress::hdr.tcp.urgent_ptr[15:8].8-15 + 19: TB21 # egress::hdr.tcp.urgent_ptr[7:0].0-7 + W48: 8 # value 1 -> W48 bit[3]: egress::hdr.tcp.$valid + shift: 20 + buf_req: 20 + next: end + 0x084b: + 0..3: TW23 + # - bit[0..15] -> TW23 bit[31..16]: egress::hdr.tcp.src_port + # - bit[16..31] -> TW23 bit[15..0]: egress::hdr.tcp.dst_port + 4..7: TW30 # egress::hdr.tcp.seq_no + 8..9: TH47 # egress::hdr.tcp.ack_no[31:16].16-31 + 10: TB28 # egress::hdr.tcp.ack_no[15:8].8-15 + 11: TB23 # egress::hdr.tcp.ack_no[7:0].0-7 + 12..15: TW5 + # - bit[96..99] -> TW5 bit[31..28]: egress::hdr.tcp.data_offset + # - bit[100..103] -> TW5 bit[27..24]: egress::hdr.tcp.res + # - bit[104..111] -> TW5 bit[23..16]: egress::hdr.tcp.flags + # - bit[112..127] -> TW5 bit[15..0]: egress::hdr.tcp.window + 16..17: TH32 # egress::hdr.tcp.checksum + 18: TB22 # egress::hdr.tcp.urgent_ptr[15:8].8-15 + 19: TB21 # egress::hdr.tcp.urgent_ptr[7:0].0-7 + W48: 8 # value 1 -> W48 bit[3]: egress::hdr.tcp.$valid + load: { byte1 : 20 } + shift: 20 + buf_req: 21 + next: parse_gtpv2 + 0x****: + 0..3: TW23 + # - bit[0..15] -> TW23 bit[31..16]: egress::hdr.tcp.src_port + # - bit[16..31] -> TW23 bit[15..0]: egress::hdr.tcp.dst_port + 4..7: TW30 # egress::hdr.tcp.seq_no + 8..9: TH47 # egress::hdr.tcp.ack_no[31:16].16-31 + 10: TB28 # egress::hdr.tcp.ack_no[15:8].8-15 + 11: TB23 # egress::hdr.tcp.ack_no[7:0].0-7 + 12..15: TW5 + # - bit[96..99] -> TW5 bit[31..28]: egress::hdr.tcp.data_offset + # - bit[100..103] -> TW5 bit[27..24]: egress::hdr.tcp.res + # - bit[104..111] -> TW5 bit[23..16]: egress::hdr.tcp.flags + # - bit[112..127] -> TW5 bit[15..0]: egress::hdr.tcp.window + 16..17: TH32 # egress::hdr.tcp.checksum + 18: TB22 # egress::hdr.tcp.urgent_ptr[15:8].8-15 + 19: TB21 # egress::hdr.tcp.urgent_ptr[7:0].0-7 + W48: 8 # value 1 -> W48 bit[3]: egress::hdr.tcp.$valid + shift: 20 + buf_req: 20 + next: end + parse_gtpv2: + match: [ byte1 ] + 0b***0****: + load: { byte1 : 1 } + buf_req: 2 + next: parse_gtpv2_8b + 0b***1****: + load: { byte1 : 1 } + buf_req: 2 + next: parse_gtpv2_12b + 0x**: + buf_req: 0 + next: end + parse_gtpv2_8b: + match: [ byte1 ] + 0x20: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type + 2..3: TH9 # egress::hdr.gtpv2_8b.total_len + 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6..7: TH33 + # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 + # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 + W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x26: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type + 2..3: TH9 # egress::hdr.gtpv2_8b.total_len + 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6..7: TH33 + # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 + # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 + W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x27: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type + 2..3: TH9 # egress::hdr.gtpv2_8b.total_len + 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6..7: TH33 + # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 + # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 + W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x47: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type + 2..3: TH9 # egress::hdr.gtpv2_8b.total_len + 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6..7: TH33 + # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 + # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 + W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x67: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type + 2..3: TH9 # egress::hdr.gtpv2_8b.total_len + 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6..7: TH33 + # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 + # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 + W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x85: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type + 2..3: TH9 # egress::hdr.gtpv2_8b.total_len + 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6..7: TH33 + # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 + # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 + W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x88: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type + 2..3: TH9 # egress::hdr.gtpv2_8b.total_len + 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6..7: TH33 + # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 + # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 + W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x97: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type + 2..3: TH9 # egress::hdr.gtpv2_8b.total_len + 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6..7: TH33 + # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 + # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 + W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x9f: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type + 2..3: TH9 # egress::hdr.gtpv2_8b.total_len + 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6..7: TH33 + # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 + # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 + W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0xa2: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type + 2..3: TH9 # egress::hdr.gtpv2_8b.total_len + 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6..7: TH33 + # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 + # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 + W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0xa4: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type + 2..3: TH9 # egress::hdr.gtpv2_8b.total_len + 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6..7: TH33 + # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 + # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 + W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0xa6: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type + 2..3: TH9 # egress::hdr.gtpv2_8b.total_len + 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6..7: TH33 + # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 + # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 + W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x68: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type + 2..3: TH9 # egress::hdr.gtpv2_8b.total_len + 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6..7: TH33 + # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 + # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 + W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x82: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type + 2..3: TH9 # egress::hdr.gtpv2_8b.total_len + 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6..7: TH33 + # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 + # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 + W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0xff: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type + 2..3: TH9 # egress::hdr.gtpv2_8b.total_len + 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6..7: TH33 + # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 + # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 + W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid + load: { byte1 : 8 } + shift: 8 + buf_req: 9 + next: parse_volte + 0x**: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type + 2..3: TH9 # egress::hdr.gtpv2_8b.total_len + 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 + 6..7: TH33 + # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 + # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 + W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid + shift: 8 + buf_req: 8 + next: end + parse_gtp_base: + match: [ half, byte0 ] + 0x01****: + 0..3: TW6 + # - bit[0..7] -> TW6 bit[31..24]: egress::hdr.imsi.type + # - bit[8..23] -> TW6 bit[23..8]: egress::hdr.imsi.len + # - bit[24..27] -> TW6 bit[7..4]: egress::hdr.imsi.spare + # - bit[28..31] -> TW6 bit[3..0]: egress::hdr.imsi.instance + 4..5: TH30 # egress::hdr.imsi.num_digit[127:112].112-127 + 6: TB29 # egress::hdr.imsi.num_digit[111:104].104-111 + 7: TB20 # egress::hdr.imsi.num_digit[103:96].96-103 + 8..11: TW29 # egress::hdr.imsi.num_digit[95:64].64-95 + 12..15: TW28 # egress::hdr.imsi.num_digit[63:32].32-63 + 16..19: TW21 # egress::hdr.imsi.num_digit[31:0].0-31 + W48: 32 # value 1 -> W48 bit[5]: egress::hdr.imsi.$valid + shift: 20 + buf_req: 20 + next: end + 0x020002: + 0: TB5 # egress::hdr.cause_ie_6b.type + 1..4: TW7 + # - bit[8..23] -> TW7 bit[31..16]: egress::hdr.cause_ie_6b.len + # - bit[24..27] -> TW7 bit[15..12]: egress::hdr.cause_ie_6b.spare1 + # - bit[28..31] -> TW7 bit[11..8]: egress::hdr.cause_ie_6b.instance + # - bit[32..39] -> TW7 bit[7..0]: egress::hdr.cause_ie_6b.cause_value + 5: TB4 + # - bit[40..44] -> TB4 bit[7..3]: egress::hdr.cause_ie_6b.spare2 + # - bit[45] -> TB4 bit[2]: egress::hdr.cause_ie_6b.pce + # - bit[46] -> TB4 bit[1]: egress::hdr.cause_ie_6b.bce + # - bit[47] -> TB4 bit[0]: egress::hdr.cause_ie_6b.cs + W48: 64 # value 1 -> W48 bit[6]: egress::hdr.cause_ie_6b.$valid + shift: 6 + buf_req: 6 + next: parse_imsi + 0x020006: + 0: TB5 # egress::hdr.cause_ie_10b.type + 1..4: TW7 + # - bit[8..23] -> TW7 bit[31..16]: egress::hdr.cause_ie_10b.len + # - bit[24..27] -> TW7 bit[15..12]: egress::hdr.cause_ie_10b.spare1 + # - bit[28..31] -> TW7 bit[11..8]: egress::hdr.cause_ie_10b.instance + # - bit[32..39] -> TW7 bit[7..0]: egress::hdr.cause_ie_10b.cause_value + 5: TB4 + # - bit[40..44] -> TB4 bit[7..3]: egress::hdr.cause_ie_10b.spare2 + # - bit[45] -> TB4 bit[2]: egress::hdr.cause_ie_10b.pce + # - bit[46] -> TB4 bit[1]: egress::hdr.cause_ie_10b.bce + # - bit[47] -> TB4 bit[0]: egress::hdr.cause_ie_10b.cs + 6..7: TH11 + # - bit[48..55] -> TH11 bit[15..8]: egress::hdr.cause_ie_10b.type_oe + # - bit[56..63] -> TH11 bit[7..0]: egress::hdr.cause_ie_10b.len_oe[15:8].8-15 + 8..9: TH10 + # - bit[64..71] -> TH10 bit[15..8]: egress::hdr.cause_ie_10b.len_oe[7:0].0-7 + # - bit[72..75] -> TH10 bit[7..4]: egress::hdr.cause_ie_10b.spare_oe + # - bit[76..79] -> TH10 bit[3..0]: egress::hdr.cause_ie_10b.instance_oe + W48: 128 # value 1 -> W48 bit[7]: egress::hdr.cause_ie_10b.$valid + shift: 10 + buf_req: 10 + next: parse_imsi + 0x******: + buf_req: 0 + next: end + parse_imsi: + *: + 0..3: TW6 + # - bit[0..7] -> TW6 bit[31..24]: egress::hdr.imsi.type + # - bit[8..23] -> TW6 bit[23..8]: egress::hdr.imsi.len + # - bit[24..27] -> TW6 bit[7..4]: egress::hdr.imsi.spare + # - bit[28..31] -> TW6 bit[3..0]: egress::hdr.imsi.instance + 4..5: TH30 # egress::hdr.imsi.num_digit[127:112].112-127 + 6: TB29 # egress::hdr.imsi.num_digit[111:104].104-111 + 7: TB20 # egress::hdr.imsi.num_digit[103:96].96-103 + 8..11: TW29 # egress::hdr.imsi.num_digit[95:64].64-95 + 12..15: TW28 # egress::hdr.imsi.num_digit[63:32].32-63 + 16..19: TW21 # egress::hdr.imsi.num_digit[31:0].0-31 + W48: 32 # value 1 -> W48 bit[5]: egress::hdr.imsi.$valid + shift: 20 + buf_req: 20 + next: end + parse_volte: + match: [ byte1 ] + 0x4*: + load: { byte1 : 9 } + buf_req: 10 + next: parse_inner_ipv4 + 0x6*: + 0..3: TW6 + # - bit[0..3] -> TW6 bit[31..28]: egress::hdr.inner_ipv6.version + # - bit[4..11] -> TW6 bit[27..20]: egress::hdr.inner_ipv6.traffic_class + # - bit[12..31] -> TW6 bit[19..0]: egress::hdr.inner_ipv6.flow_label + 4..5: TH11 # egress::hdr.inner_ipv6.payload_len + 6: B19 # egress::hdr.inner_ipv6.next_hdr + 7: TB20 # egress::hdr.inner_ipv6.hop_limit + 8..11: W26 # egress::hdr.inner_ipv6.src_addr[127:96].96-127 + 12..15: W25 # egress::hdr.inner_ipv6.src_addr[95:64].64-95 + 16..19: W24 # egress::hdr.inner_ipv6.src_addr[63:32].32-63 + W48: 16384 # value 1 -> W48 bit[14]: egress::hdr.inner_ipv6.$valid + load: { byte1 : 6 } + shift: 20 + buf_req: 20 + next: parse_inner_ipv6.$split_0 + 0x**: + buf_req: 0 + next: end + parse_inner_ipv4: + match: [ byte1 ] + 0x06: + 0..3: TW6 + # - bit[0..3] -> TW6 bit[31..28]: egress::hdr.inner_ipv4.version + # - bit[4..7] -> TW6 bit[27..24]: egress::hdr.inner_ipv4.ihl + # - bit[8..15] -> TW6 bit[23..16]: egress::hdr.inner_ipv4.diffserv + # - bit[16..31] -> TW6 bit[15..0]: egress::hdr.inner_ipv4.total_len + 4..5: TH30 # egress::hdr.inner_ipv4.identification + 6..7: TH11 + # - bit[48..50] -> TH11 bit[15..13]: egress::hdr.inner_ipv4.flags + # - bit[51..63] -> TH11 bit[12..0]: egress::hdr.inner_ipv4.frag_offset + 8..11: TW21 + # - bit[64..71] -> TW21 bit[31..24]: egress::hdr.inner_ipv4.ttl + # - bit[72..79] -> TW21 bit[23..16]: egress::hdr.inner_ipv4.protocol + # - bit[80..95] -> TW21 bit[15..0]: egress::hdr.inner_ipv4.hdr_checksum + 12: TB31 # egress::hdr.inner_ipv4.src_addr[31:24].24-31 + 13: TB30 # egress::hdr.inner_ipv4.src_addr[23:16].16-23 + 14: TB29 # egress::hdr.inner_ipv4.src_addr[15:8].8-15 + 15: TB20 # egress::hdr.inner_ipv4.src_addr[7:0].0-7 + 16..19: W18 # egress::hdr.inner_ipv4.dst_addr + W48: 256 # value 1 -> W48 bit[8]: egress::hdr.inner_ipv4.$valid + shift: 20 + buf_req: 20 + next: parse_inner_tcp + 0x11: + 0..3: TW6 + # - bit[0..3] -> TW6 bit[31..28]: egress::hdr.inner_ipv4.version + # - bit[4..7] -> TW6 bit[27..24]: egress::hdr.inner_ipv4.ihl + # - bit[8..15] -> TW6 bit[23..16]: egress::hdr.inner_ipv4.diffserv + # - bit[16..31] -> TW6 bit[15..0]: egress::hdr.inner_ipv4.total_len + 4..5: TH30 # egress::hdr.inner_ipv4.identification + 6..7: TH11 + # - bit[48..50] -> TH11 bit[15..13]: egress::hdr.inner_ipv4.flags + # - bit[51..63] -> TH11 bit[12..0]: egress::hdr.inner_ipv4.frag_offset + 8..11: TW21 + # - bit[64..71] -> TW21 bit[31..24]: egress::hdr.inner_ipv4.ttl + # - bit[72..79] -> TW21 bit[23..16]: egress::hdr.inner_ipv4.protocol + # - bit[80..95] -> TW21 bit[15..0]: egress::hdr.inner_ipv4.hdr_checksum + 12: TB31 # egress::hdr.inner_ipv4.src_addr[31:24].24-31 + 13: TB30 # egress::hdr.inner_ipv4.src_addr[23:16].16-23 + 14: TB29 # egress::hdr.inner_ipv4.src_addr[15:8].8-15 + 15: TB20 # egress::hdr.inner_ipv4.src_addr[7:0].0-7 + 16..19: W18 # egress::hdr.inner_ipv4.dst_addr + W48: 256 # value 1 -> W48 bit[8]: egress::hdr.inner_ipv4.$valid + shift: 20 + buf_req: 20 + next: parse_inner_udp + 0x01: + 0..3: TW6 + # - bit[0..3] -> TW6 bit[31..28]: egress::hdr.inner_ipv4.version + # - bit[4..7] -> TW6 bit[27..24]: egress::hdr.inner_ipv4.ihl + # - bit[8..15] -> TW6 bit[23..16]: egress::hdr.inner_ipv4.diffserv + # - bit[16..31] -> TW6 bit[15..0]: egress::hdr.inner_ipv4.total_len + 4..5: TH30 # egress::hdr.inner_ipv4.identification + 6..7: TH11 + # - bit[48..50] -> TH11 bit[15..13]: egress::hdr.inner_ipv4.flags + # - bit[51..63] -> TH11 bit[12..0]: egress::hdr.inner_ipv4.frag_offset + 8..11: TW21 + # - bit[64..71] -> TW21 bit[31..24]: egress::hdr.inner_ipv4.ttl + # - bit[72..79] -> TW21 bit[23..16]: egress::hdr.inner_ipv4.protocol + # - bit[80..95] -> TW21 bit[15..0]: egress::hdr.inner_ipv4.hdr_checksum + 12: TB31 # egress::hdr.inner_ipv4.src_addr[31:24].24-31 + 13: TB30 # egress::hdr.inner_ipv4.src_addr[23:16].16-23 + 14: TB29 # egress::hdr.inner_ipv4.src_addr[15:8].8-15 + 15: TB20 # egress::hdr.inner_ipv4.src_addr[7:0].0-7 + 16..19: W18 # egress::hdr.inner_ipv4.dst_addr + W48: 256 # value 1 -> W48 bit[8]: egress::hdr.inner_ipv4.$valid + shift: 20 + buf_req: 20 + next: parse_inner_icmp + 0x32: + 0..3: TW6 + # - bit[0..3] -> TW6 bit[31..28]: egress::hdr.inner_ipv4.version + # - bit[4..7] -> TW6 bit[27..24]: egress::hdr.inner_ipv4.ihl + # - bit[8..15] -> TW6 bit[23..16]: egress::hdr.inner_ipv4.diffserv + # - bit[16..31] -> TW6 bit[15..0]: egress::hdr.inner_ipv4.total_len + 4..5: TH30 # egress::hdr.inner_ipv4.identification + 6..7: TH11 + # - bit[48..50] -> TH11 bit[15..13]: egress::hdr.inner_ipv4.flags + # - bit[51..63] -> TH11 bit[12..0]: egress::hdr.inner_ipv4.frag_offset + 8..11: TW21 + # - bit[64..71] -> TW21 bit[31..24]: egress::hdr.inner_ipv4.ttl + # - bit[72..79] -> TW21 bit[23..16]: egress::hdr.inner_ipv4.protocol + # - bit[80..95] -> TW21 bit[15..0]: egress::hdr.inner_ipv4.hdr_checksum + 12: TB31 # egress::hdr.inner_ipv4.src_addr[31:24].24-31 + 13: TB30 # egress::hdr.inner_ipv4.src_addr[23:16].16-23 + 14: TB29 # egress::hdr.inner_ipv4.src_addr[15:8].8-15 + 15: TB20 # egress::hdr.inner_ipv4.src_addr[7:0].0-7 + 16..19: W18 # egress::hdr.inner_ipv4.dst_addr + W48: 256 # value 1 -> W48 bit[8]: egress::hdr.inner_ipv4.$valid + shift: 20 + buf_req: 20 + next: parse_inner_esp + 0x**: + 0..3: TW6 + # - bit[0..3] -> TW6 bit[31..28]: egress::hdr.inner_ipv4.version + # - bit[4..7] -> TW6 bit[27..24]: egress::hdr.inner_ipv4.ihl + # - bit[8..15] -> TW6 bit[23..16]: egress::hdr.inner_ipv4.diffserv + # - bit[16..31] -> TW6 bit[15..0]: egress::hdr.inner_ipv4.total_len + 4..5: TH30 # egress::hdr.inner_ipv4.identification + 6..7: TH11 + # - bit[48..50] -> TH11 bit[15..13]: egress::hdr.inner_ipv4.flags + # - bit[51..63] -> TH11 bit[12..0]: egress::hdr.inner_ipv4.frag_offset + 8..11: TW21 + # - bit[64..71] -> TW21 bit[31..24]: egress::hdr.inner_ipv4.ttl + # - bit[72..79] -> TW21 bit[23..16]: egress::hdr.inner_ipv4.protocol + # - bit[80..95] -> TW21 bit[15..0]: egress::hdr.inner_ipv4.hdr_checksum + 12: TB31 # egress::hdr.inner_ipv4.src_addr[31:24].24-31 + 13: TB30 # egress::hdr.inner_ipv4.src_addr[23:16].16-23 + 14: TB29 # egress::hdr.inner_ipv4.src_addr[15:8].8-15 + 15: TB20 # egress::hdr.inner_ipv4.src_addr[7:0].0-7 + 16..19: W18 # egress::hdr.inner_ipv4.dst_addr + W48: 256 # value 1 -> W48 bit[8]: egress::hdr.inner_ipv4.$valid + shift: 20 + buf_req: 20 + next: end + parse_inner_tcp: + *: + 0..1: H25 # egress::eg_md.lkp.inner_l4_src_port + 0..3: TW28 + # - bit[0..15] -> TW28 bit[31..16]: egress::hdr.inner_tcp.src_port + # - bit[16..31] -> TW28 bit[15..0]: egress::hdr.inner_tcp.dst_port + 2..3: H26 # egress::eg_md.lkp.inner_l4_dst_port + 4..7: W19 # egress::hdr.inner_tcp.seq_no + 8..11: W20 # egress::hdr.inner_tcp.ack_no + 12..15: TW7 + # - bit[96..99] -> TW7 bit[31..28]: egress::hdr.inner_tcp.data_offset + # - bit[100..103] -> TW7 bit[27..24]: egress::hdr.inner_tcp.res + # - bit[104..111] -> TW7 bit[23..16]: egress::hdr.inner_tcp.flags + # - bit[112..127] -> TW7 bit[15..0]: egress::hdr.inner_tcp.window + W48: 1536 + # - value 1 -> W48 bit[9]: egress::hdr.inner_tcp.$valid + # - value 1 -> W48 bit[10]: egress::hdr.sip.$valid + shift: 16 + buf_req: 16 + next: parse_inner_tcp.$split_0 + parse_inner_tcp.$split_0: + *: + 0..3: TW29 + # - bit[0..15] -> TW29 bit[31..16]: egress::hdr.inner_tcp.checksum + # - bit[16..31] -> TW29 bit[15..0]: egress::hdr.inner_tcp.urgent_ptr + 4..7: W21 # egress::hdr.sip.data + shift: 8 + buf_req: 8 + next: end + parse_inner_udp: + *: + 0..1: H25 # egress::eg_md.lkp.inner_l4_src_port + 0..3: TW7 + # - bit[0..15] -> TW7 bit[31..16]: egress::hdr.inner_udp.src_port + # - bit[16..31] -> TW7 bit[15..0]: egress::hdr.inner_udp.dst_port + 2..3: H26 # egress::eg_md.lkp.inner_l4_dst_port + 4..7: TW28 + # - bit[32..47] -> TW28 bit[31..16]: egress::hdr.inner_udp.hdr_length + # - bit[48..63] -> TW28 bit[15..0]: egress::hdr.inner_udp.checksum + W48: 2048 # value 1 -> W48 bit[11]: egress::hdr.inner_udp.$valid + shift: 8 + buf_req: 8 + next: end + parse_inner_icmp: + *: + 0..3: TW7 + # - bit[0..7] -> TW7 bit[31..24]: egress::hdr.inner_icmp.type_ + # - bit[8..15] -> TW7 bit[23..16]: egress::hdr.inner_icmp.code + # - bit[16..31] -> TW7 bit[15..0]: egress::hdr.inner_icmp.hdr_checksum + W48: 4096 # value 1 -> W48 bit[12]: egress::hdr.inner_icmp.$valid + shift: 4 + buf_req: 4 + next: end + parse_inner_esp: + *: + 0..3: W22 # egress::hdr.ipsec_esp.spi + 4..7: W23 # egress::hdr.ipsec_esp.sn + W48: 8192 # value 1 -> W48 bit[13]: egress::hdr.ipsec_esp.$valid + shift: 8 + buf_req: 8 + next: parse_inner_tcp + parse_inner_ipv6.$split_0: + *: + 0..3: W18 # egress::hdr.inner_ipv6.src_addr[31:0].0-31 + 4..7: W30 # egress::hdr.inner_ipv6.dst_addr[127:96].96-127 + 8..11: W29 # egress::hdr.inner_ipv6.dst_addr[95:64].64-95 + 12..15: W28 # egress::hdr.inner_ipv6.dst_addr[63:32].32-63 + shift: 16 + buf_req: 16 + next: parse_inner_ipv6.$split_1 + parse_inner_ipv6.$split_1: + match: [ byte1 ] + 0x06: + 0..3: W27 # egress::hdr.inner_ipv6.dst_addr[31:0].0-31 + shift: 4 + buf_req: 4 + next: parse_inner_tcp + 0x11: + 0..3: W27 # egress::hdr.inner_ipv6.dst_addr[31:0].0-31 + shift: 4 + buf_req: 4 + next: parse_inner_udp + 0x3a: + 0..3: W27 # egress::hdr.inner_ipv6.dst_addr[31:0].0-31 + shift: 4 + buf_req: 4 + next: parse_inner_icmp + 0x32: + 0..3: W27 # egress::hdr.inner_ipv6.dst_addr[31:0].0-31 + shift: 4 + buf_req: 4 + next: parse_inner_esp + 0x**: + 0..3: W27 # egress::hdr.inner_ipv6.dst_addr[31:0].0-31 + shift: 4 + buf_req: 4 + next: end + parse_gtpv2_12b: + match: [ byte1 ] + 0x20: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type + 2..3: TH9 # egress::hdr.gtpv2_12b.total_len + 4..7: W31 # egress::hdr.gtpv2_12b.teid + 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10..11: TH33 + # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 + # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 + W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x26: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type + 2..3: TH9 # egress::hdr.gtpv2_12b.total_len + 4..7: W31 # egress::hdr.gtpv2_12b.teid + 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10..11: TH33 + # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 + # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 + W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x27: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type + 2..3: TH9 # egress::hdr.gtpv2_12b.total_len + 4..7: W31 # egress::hdr.gtpv2_12b.teid + 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10..11: TH33 + # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 + # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 + W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x47: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type + 2..3: TH9 # egress::hdr.gtpv2_12b.total_len + 4..7: W31 # egress::hdr.gtpv2_12b.teid + 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10..11: TH33 + # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 + # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 + W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x67: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type + 2..3: TH9 # egress::hdr.gtpv2_12b.total_len + 4..7: W31 # egress::hdr.gtpv2_12b.teid + 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10..11: TH33 + # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 + # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 + W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x85: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type + 2..3: TH9 # egress::hdr.gtpv2_12b.total_len + 4..7: W31 # egress::hdr.gtpv2_12b.teid + 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10..11: TH33 + # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 + # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 + W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x88: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type + 2..3: TH9 # egress::hdr.gtpv2_12b.total_len + 4..7: W31 # egress::hdr.gtpv2_12b.teid + 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10..11: TH33 + # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 + # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 + W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x97: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type + 2..3: TH9 # egress::hdr.gtpv2_12b.total_len + 4..7: W31 # egress::hdr.gtpv2_12b.teid + 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10..11: TH33 + # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 + # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 + W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x9f: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type + 2..3: TH9 # egress::hdr.gtpv2_12b.total_len + 4..7: W31 # egress::hdr.gtpv2_12b.teid + 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10..11: TH33 + # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 + # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 + W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0xa2: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type + 2..3: TH9 # egress::hdr.gtpv2_12b.total_len + 4..7: W31 # egress::hdr.gtpv2_12b.teid + 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10..11: TH33 + # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 + # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 + W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0xa4: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type + 2..3: TH9 # egress::hdr.gtpv2_12b.total_len + 4..7: W31 # egress::hdr.gtpv2_12b.teid + 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10..11: TH33 + # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 + # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 + W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0xa6: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type + 2..3: TH9 # egress::hdr.gtpv2_12b.total_len + 4..7: W31 # egress::hdr.gtpv2_12b.teid + 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10..11: TH33 + # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 + # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 + W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x68: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type + 2..3: TH9 # egress::hdr.gtpv2_12b.total_len + 4..7: W31 # egress::hdr.gtpv2_12b.teid + 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10..11: TH33 + # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 + # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 + W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x82: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type + 2..3: TH9 # egress::hdr.gtpv2_12b.total_len + 4..7: W31 # egress::hdr.gtpv2_12b.teid + 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10..11: TH33 + # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 + # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 + W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0xff: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type + 2..3: TH9 # egress::hdr.gtpv2_12b.total_len + 4..7: W31 # egress::hdr.gtpv2_12b.teid + 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10..11: TH33 + # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 + # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 + W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid + load: { byte1 : 12 } + shift: 12 + buf_req: 13 + next: parse_volte + 0x**: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type + 2..3: TH9 # egress::hdr.gtpv2_12b.total_len + 4..7: W31 # egress::hdr.gtpv2_12b.teid + 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 + 10..11: TH33 + # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 + # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 + W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid + shift: 12 + buf_req: 12 + next: end + parse_udp: + match: [ half ] + value_set EgParser_inner_2.udp_port_vxlan 1: + handle: 506 + field_mapping: + hdr.udp.dst_port(0..15) : half(0..15) + 0..3: TW23 + # - bit[0..15] -> TW23 bit[31..16]: egress::hdr.udp.src_port + # - bit[16..31] -> TW23 bit[15..0]: egress::hdr.udp.dst_port + 4..5: TH32 # egress::hdr.udp.hdr_length + 6: TB23 # egress::hdr.udp.checksum[15:8].8-15 + 7: TB22 # egress::hdr.udp.checksum[7:0].0-7 + W48: 65536 # value 1 -> W48 bit[16]: egress::hdr.udp.$valid + shift: 8 + buf_req: 8 + next: parse_vxlan + 0x0868: + 0..3: TW23 + # - bit[0..15] -> TW23 bit[31..16]: egress::hdr.udp.src_port + # - bit[16..31] -> TW23 bit[15..0]: egress::hdr.udp.dst_port + 4..5: TH32 # egress::hdr.udp.hdr_length + 6: TB23 # egress::hdr.udp.checksum[15:8].8-15 + 7: TB22 # egress::hdr.udp.checksum[7:0].0-7 + W48: 65536 # value 1 -> W48 bit[16]: egress::hdr.udp.$valid + shift: 8 + buf_req: 8 + next: parse_gtpu + 0x0d3a: + 0..3: TW23 + # - bit[0..15] -> TW23 bit[31..16]: egress::hdr.udp.src_port + # - bit[16..31] -> TW23 bit[15..0]: egress::hdr.udp.dst_port + 4..5: TH32 # egress::hdr.udp.hdr_length + 6: TB23 # egress::hdr.udp.checksum[15:8].8-15 + 7: TB22 # egress::hdr.udp.checksum[7:0].0-7 + W48: 65536 # value 1 -> W48 bit[16]: egress::hdr.udp.$valid + shift: 8 + buf_req: 8 + next: parse_gtp + 0x084b: + 0..3: TW23 + # - bit[0..15] -> TW23 bit[31..16]: egress::hdr.udp.src_port + # - bit[16..31] -> TW23 bit[15..0]: egress::hdr.udp.dst_port + 4..5: TH32 # egress::hdr.udp.hdr_length + 6: TB23 # egress::hdr.udp.checksum[15:8].8-15 + 7: TB22 # egress::hdr.udp.checksum[7:0].0-7 + W48: 65536 # value 1 -> W48 bit[16]: egress::hdr.udp.$valid + load: { byte1 : 8 } + shift: 8 + buf_req: 9 + next: parse_gtp_verx + 0x06a5: + 0..3: TW23 + # - bit[0..15] -> TW23 bit[31..16]: egress::hdr.udp.src_port + # - bit[16..31] -> TW23 bit[15..0]: egress::hdr.udp.dst_port + 4..5: TH32 # egress::hdr.udp.hdr_length + 6: TB23 # egress::hdr.udp.checksum[15:8].8-15 + 7: TB22 # egress::hdr.udp.checksum[7:0].0-7 + W48: 65536 # value 1 -> W48 bit[16]: egress::hdr.udp.$valid + load: { byte1 : 8 } + shift: 8 + buf_req: 9 + next: parse_l2tp + 0x****: + 0..3: TW23 + # - bit[0..15] -> TW23 bit[31..16]: egress::hdr.udp.src_port + # - bit[16..31] -> TW23 bit[15..0]: egress::hdr.udp.dst_port + 4..5: TH32 # egress::hdr.udp.hdr_length + 6: TB23 # egress::hdr.udp.checksum[15:8].8-15 + 7: TB22 # egress::hdr.udp.checksum[7:0].0-7 + W48: 65536 # value 1 -> W48 bit[16]: egress::hdr.udp.$valid + shift: 8 + buf_req: 8 + next: end + parse_vxlan: + *: + 0..3: TW5 + # - bit[0..7] -> TW5 bit[31..24]: egress::hdr.vxlan.flags + # - bit[8..31] -> TW5 bit[23..0]: egress::hdr.vxlan.reserved + 4..5: TH9 # egress::hdr.vxlan.vni[23:8].8-23 + 6..7: TH8 + # - bit[48..55] -> TH8 bit[15..8]: egress::hdr.vxlan.vni[7:0].0-7 + # - bit[56..63] -> TH8 bit[7..0]: egress::hdr.vxlan.reserved2 + 8..11: TW30 # egress::hdr.inner_ethernet.dst_addr[47:16].16-47 + 12: TB5 # egress::hdr.inner_ethernet.dst_addr[15:8].8-15 + 13: TB4 # egress::hdr.inner_ethernet.dst_addr[7:0].0-7 + 14..15: TH47 # egress::hdr.inner_ethernet.src_addr[47:32].32-47 + 16..17: TH34 # egress::hdr.inner_ethernet.src_addr[31:16].16-31 + W48: 393216 + # - value 1 -> W48 bit[17]: egress::hdr.vxlan.$valid + # - value 1 -> W48 bit[18]: egress::hdr.inner_ethernet.$valid + load: { half : 20..21 } + shift: 18 + buf_req: 22 + next: parse_vxlan.$split_0 + parse_vxlan.$split_0: + match: [ half ] + 0x0800: + 0..1: TH33 # egress::hdr.inner_ethernet.src_addr[15:0].0-15 + 2..3: TH10 # egress::hdr.inner_ethernet.ether_type + load: { byte1 : 13 } + shift: 4 + buf_req: 14 + next: parse_inner_ipv4 + 0x86dd: + 0..1: TH33 # egress::hdr.inner_ethernet.src_addr[15:0].0-15 + 2..3: TH10 # egress::hdr.inner_ethernet.ether_type + shift: 4 + buf_req: 4 + next: parse_inner_ipv6 + 0x****: + 0..1: TH33 # egress::hdr.inner_ethernet.src_addr[15:0].0-15 + 2..3: TH10 # egress::hdr.inner_ethernet.ether_type + shift: 4 + buf_req: 4 + next: end + parse_inner_ipv6: + *: + 0..3: TW6 + # - bit[0..3] -> TW6 bit[31..28]: egress::hdr.inner_ipv6.version + # - bit[4..11] -> TW6 bit[27..20]: egress::hdr.inner_ipv6.traffic_class + # - bit[12..31] -> TW6 bit[19..0]: egress::hdr.inner_ipv6.flow_label + 4..5: TH11 # egress::hdr.inner_ipv6.payload_len + 6: B19 # egress::hdr.inner_ipv6.next_hdr + 7: TB20 # egress::hdr.inner_ipv6.hop_limit + 8..11: W26 # egress::hdr.inner_ipv6.src_addr[127:96].96-127 + 12..15: W25 # egress::hdr.inner_ipv6.src_addr[95:64].64-95 + 16..19: W24 # egress::hdr.inner_ipv6.src_addr[63:32].32-63 + W48: 16384 # value 1 -> W48 bit[14]: egress::hdr.inner_ipv6.$valid + load: { byte1 : 6 } + shift: 20 + buf_req: 20 + next: parse_inner_ipv6.$split_0 + parse_gtpu: + *: + load: { byte1 : 0 } + buf_req: 1 + next: parse_gtpv1 + parse_gtpv1: + match: [ byte1 ] + 0b*****000: + load: { byte1 : 1 } + buf_req: 2 + next: parse_gtpv1_8b + 0b*****0*1: + load: { byte1 : 1 } + buf_req: 2 + next: parse_gtpv1_12b + 0b*****01*: + load: { byte1 : 1 } + buf_req: 2 + next: parse_gtpv1_12b + 0x**: + buf_req: 0 + next: end + parse_gtpv1_8b: + match: [ byte1 ] + 0x20: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type + 2..3: TH9 # egress::hdr.gtpv1_8b.message_len + 4..7: TW5 # egress::hdr.gtpv1_8b.teid + W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x26: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type + 2..3: TH9 # egress::hdr.gtpv1_8b.message_len + 4..7: TW5 # egress::hdr.gtpv1_8b.teid + W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x27: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type + 2..3: TH9 # egress::hdr.gtpv1_8b.message_len + 4..7: TW5 # egress::hdr.gtpv1_8b.teid + W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x47: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type + 2..3: TH9 # egress::hdr.gtpv1_8b.message_len + 4..7: TW5 # egress::hdr.gtpv1_8b.teid + W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x67: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type + 2..3: TH9 # egress::hdr.gtpv1_8b.message_len + 4..7: TW5 # egress::hdr.gtpv1_8b.teid + W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x85: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type + 2..3: TH9 # egress::hdr.gtpv1_8b.message_len + 4..7: TW5 # egress::hdr.gtpv1_8b.teid + W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x88: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type + 2..3: TH9 # egress::hdr.gtpv1_8b.message_len + 4..7: TW5 # egress::hdr.gtpv1_8b.teid + W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x97: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type + 2..3: TH9 # egress::hdr.gtpv1_8b.message_len + 4..7: TW5 # egress::hdr.gtpv1_8b.teid + W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x9f: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type + 2..3: TH9 # egress::hdr.gtpv1_8b.message_len + 4..7: TW5 # egress::hdr.gtpv1_8b.teid + W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0xa2: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type + 2..3: TH9 # egress::hdr.gtpv1_8b.message_len + 4..7: TW5 # egress::hdr.gtpv1_8b.teid + W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0xa4: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type + 2..3: TH9 # egress::hdr.gtpv1_8b.message_len + 4..7: TW5 # egress::hdr.gtpv1_8b.teid + W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0xa6: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type + 2..3: TH9 # egress::hdr.gtpv1_8b.message_len + 4..7: TW5 # egress::hdr.gtpv1_8b.teid + W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x68: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type + 2..3: TH9 # egress::hdr.gtpv1_8b.message_len + 4..7: TW5 # egress::hdr.gtpv1_8b.teid + W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0x82: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type + 2..3: TH9 # egress::hdr.gtpv1_8b.message_len + 4..7: TW5 # egress::hdr.gtpv1_8b.teid + W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid + load: { half : 8..9, byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_gtp_base + 0xff: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type + 2..3: TH9 # egress::hdr.gtpv1_8b.message_len + 4..7: TW5 # egress::hdr.gtpv1_8b.teid + W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid + load: { byte1 : 8 } + shift: 8 + buf_req: 9 + next: parse_volte + 0x**: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type + 2..3: TH9 # egress::hdr.gtpv1_8b.message_len + 4..7: TW5 # egress::hdr.gtpv1_8b.teid + W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid + shift: 8 + buf_req: 8 + next: end + parse_gtpv1_12b: + match: [ byte1 ] + 0x20: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type + 2..3: TH9 # egress::hdr.gtpv1_12b.message_len + 4..7: TW30 # egress::hdr.gtpv1_12b.teid + 8..11: TW5 + # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t + W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x26: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type + 2..3: TH9 # egress::hdr.gtpv1_12b.message_len + 4..7: TW30 # egress::hdr.gtpv1_12b.teid + 8..11: TW5 + # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t + W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x27: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type + 2..3: TH9 # egress::hdr.gtpv1_12b.message_len + 4..7: TW30 # egress::hdr.gtpv1_12b.teid + 8..11: TW5 + # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t + W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x47: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type + 2..3: TH9 # egress::hdr.gtpv1_12b.message_len + 4..7: TW30 # egress::hdr.gtpv1_12b.teid + 8..11: TW5 + # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t + W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x67: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type + 2..3: TH9 # egress::hdr.gtpv1_12b.message_len + 4..7: TW30 # egress::hdr.gtpv1_12b.teid + 8..11: TW5 + # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t + W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x85: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type + 2..3: TH9 # egress::hdr.gtpv1_12b.message_len + 4..7: TW30 # egress::hdr.gtpv1_12b.teid + 8..11: TW5 + # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t + W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x88: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type + 2..3: TH9 # egress::hdr.gtpv1_12b.message_len + 4..7: TW30 # egress::hdr.gtpv1_12b.teid + 8..11: TW5 + # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t + W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x97: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type + 2..3: TH9 # egress::hdr.gtpv1_12b.message_len + 4..7: TW30 # egress::hdr.gtpv1_12b.teid + 8..11: TW5 + # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t + W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x9f: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type + 2..3: TH9 # egress::hdr.gtpv1_12b.message_len + 4..7: TW30 # egress::hdr.gtpv1_12b.teid + 8..11: TW5 + # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t + W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0xa2: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type + 2..3: TH9 # egress::hdr.gtpv1_12b.message_len + 4..7: TW30 # egress::hdr.gtpv1_12b.teid + 8..11: TW5 + # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t + W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0xa4: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type + 2..3: TH9 # egress::hdr.gtpv1_12b.message_len + 4..7: TW30 # egress::hdr.gtpv1_12b.teid + 8..11: TW5 + # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t + W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0xa6: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type + 2..3: TH9 # egress::hdr.gtpv1_12b.message_len + 4..7: TW30 # egress::hdr.gtpv1_12b.teid + 8..11: TW5 + # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t + W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x68: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type + 2..3: TH9 # egress::hdr.gtpv1_12b.message_len + 4..7: TW30 # egress::hdr.gtpv1_12b.teid + 8..11: TW5 + # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t + W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0x82: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type + 2..3: TH9 # egress::hdr.gtpv1_12b.message_len + 4..7: TW30 # egress::hdr.gtpv1_12b.teid + 8..11: TW5 + # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t + W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid + load: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: parse_gtp_base + 0xff: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type + 2..3: TH9 # egress::hdr.gtpv1_12b.message_len + 4..7: TW30 # egress::hdr.gtpv1_12b.teid + 8..11: TW5 + # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t + W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid + load: { byte1 : 12 } + shift: 12 + buf_req: 13 + next: parse_volte + 0x**: + 0..1: TH8 + # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version + # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt + # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved + # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e + # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s + # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn + # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type + 2..3: TH9 # egress::hdr.gtpv1_12b.message_len + 4..7: TW30 # egress::hdr.gtpv1_12b.teid + 8..11: TW5 + # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no + # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no + # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t + W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid + shift: 12 + buf_req: 12 + next: end + parse_gtp: + *: + load: { byte1 : 0 } + buf_req: 1 + next: parse_gtpv1 + parse_gtp_verx: + match: [ byte1 ] + 0b001*****: + load: { byte1 : 0 } + buf_req: 1 + next: parse_gtpv1 + 0b010*****: + load: { byte1 : 0 } + buf_req: 1 + next: parse_gtpv2 + 0x**: + buf_req: 0 + next: end + parse_l2tp: + match: [ byte1 ] + 0b0*******: + 0..3: TW5 + # - bit[0..11] -> TW5 bit[31..20]: egress::hdr.l2tp.TLxxSxOP + # - bit[12..15] -> TW5 bit[19..16]: egress::hdr.l2tp.version + # - bit[16..23] -> TW5 bit[15..8]: egress::hdr.l2tp.l2tp_length + # - bit[24..31] -> TW5 bit[7..0]: egress::hdr.l2tp.tunnel_id[15:8].8-15 + 4: TB4 # egress::hdr.l2tp.tunnel_id[7:0].0-7 + 5..6: TH34 # egress::hdr.l2tp.session_id + 7..8: TH33 # egress::hdr.l2tp.Ns + 9..10: TH8 # egress::hdr.l2tp.Nr + 11: TB21 # egress::hdr.l2tp.offset_size + 12: TB5 # egress::hdr.l2tp.offset_pad + W48: 2097152 # value 1 -> W48 bit[21]: egress::hdr.l2tp.$valid + load: { half : 19..20, byte0 : 21 } + shift: 13 + buf_req: 22 + next: parse_pppoe + 0x**: + 0..3: TW5 + # - bit[0..11] -> TW5 bit[31..20]: egress::hdr.l2tp.TLxxSxOP + # - bit[12..15] -> TW5 bit[19..16]: egress::hdr.l2tp.version + # - bit[16..23] -> TW5 bit[15..8]: egress::hdr.l2tp.l2tp_length + # - bit[24..31] -> TW5 bit[7..0]: egress::hdr.l2tp.tunnel_id[15:8].8-15 + 4: TB4 # egress::hdr.l2tp.tunnel_id[7:0].0-7 + 5..6: TH34 # egress::hdr.l2tp.session_id + 7..8: TH33 # egress::hdr.l2tp.Ns + 9..10: TH8 # egress::hdr.l2tp.Nr + 11: TB21 # egress::hdr.l2tp.offset_size + 12: TB5 # egress::hdr.l2tp.offset_pad + W48: 2097152 # value 1 -> W48 bit[21]: egress::hdr.l2tp.$valid + shift: 13 + buf_req: 13 + next: end + parse_pppoe: + match: [ half, byte0 ] + 0x00214*: + 0..1: TH9 + # - bit[0..3] -> TH9 bit[15..12]: egress::hdr.pppoe.version + # - bit[4..7] -> TH9 bit[11..8]: egress::hdr.pppoe.type + # - bit[8..15] -> TH9 bit[7..0]: egress::hdr.pppoe.code + 2..3: TH10 # egress::hdr.pppoe.session_id + 4..7: TW30 + # - bit[32..47] -> TW30 bit[31..16]: egress::hdr.pppoe.pppoe_length + # - bit[48..63] -> TW30 bit[15..0]: egress::hdr.pppoe.ppp_proto + W48: 4194304 # value 1 -> W48 bit[22]: egress::hdr.pppoe.$valid + load: { byte1 : 17 } + shift: 8 + buf_req: 18 + next: parse_inner_ipv4 + 0x00216*: + 0..1: TH9 + # - bit[0..3] -> TH9 bit[15..12]: egress::hdr.pppoe.version + # - bit[4..7] -> TH9 bit[11..8]: egress::hdr.pppoe.type + # - bit[8..15] -> TH9 bit[7..0]: egress::hdr.pppoe.code + 2..3: TH10 # egress::hdr.pppoe.session_id + 4..7: TW30 + # - bit[32..47] -> TW30 bit[31..16]: egress::hdr.pppoe.pppoe_length + # - bit[48..63] -> TW30 bit[15..0]: egress::hdr.pppoe.ppp_proto + W48: 4194304 # value 1 -> W48 bit[22]: egress::hdr.pppoe.$valid + shift: 8 + buf_req: 8 + next: parse_inner_ipv6 + 0x******: + 0..1: TH9 + # - bit[0..3] -> TH9 bit[15..12]: egress::hdr.pppoe.version + # - bit[4..7] -> TH9 bit[11..8]: egress::hdr.pppoe.type + # - bit[8..15] -> TH9 bit[7..0]: egress::hdr.pppoe.code + 2..3: TH10 # egress::hdr.pppoe.session_id + 4..7: TW30 + # - bit[32..47] -> TW30 bit[31..16]: egress::hdr.pppoe.pppoe_length + # - bit[48..63] -> TW30 bit[15..0]: egress::hdr.pppoe.ppp_proto + W48: 4194304 # value 1 -> W48 bit[22]: egress::hdr.pppoe.$valid + shift: 8 + buf_req: 8 + next: end + parse_icmp: + *: + 0..3: TW5 + # - bit[0..7] -> TW5 bit[31..24]: egress::hdr.icmp.type_ + # - bit[8..15] -> TW5 bit[23..16]: egress::hdr.icmp.code + # - bit[16..31] -> TW5 bit[15..0]: egress::hdr.icmp.hdr_checksum + W48: 8388608 # value 1 -> W48 bit[23]: egress::hdr.icmp.$valid + shift: 4 + buf_req: 4 + next: end + parse_sctp: + match: [ half ] + 0x8e3c: + 0..3: TW5 + # - bit[0..15] -> TW5 bit[31..16]: egress::hdr.sctp.src_port + # - bit[16..31] -> TW5 bit[15..0]: egress::hdr.sctp.dst_port + 4..7: TW6 # egress::hdr.sctp.verifTag + 8..9: TH8 # egress::hdr.sctp.checksum + W48: 16777216 # value 1 -> W48 bit[24]: egress::hdr.sctp.$valid + shift: 10 + buf_req: 10 + next: end + 0x960c: + 0..3: TW5 + # - bit[0..15] -> TW5 bit[31..16]: egress::hdr.sctp.src_port + # - bit[16..31] -> TW5 bit[15..0]: egress::hdr.sctp.dst_port + 4..7: TW6 # egress::hdr.sctp.verifTag + 8..9: TH8 # egress::hdr.sctp.checksum + W48: 16777216 # value 1 -> W48 bit[24]: egress::hdr.sctp.$valid + shift: 10 + buf_req: 10 + next: end + 0x0f1c: + 0..3: TW5 + # - bit[0..15] -> TW5 bit[31..16]: egress::hdr.sctp.src_port + # - bit[16..31] -> TW5 bit[15..0]: egress::hdr.sctp.dst_port + 4..7: TW6 # egress::hdr.sctp.verifTag + 8..9: TH8 # egress::hdr.sctp.checksum + W48: 16777216 # value 1 -> W48 bit[24]: egress::hdr.sctp.$valid + shift: 10 + buf_req: 10 + next: end + 0x71be: + 0..3: TW5 + # - bit[0..15] -> TW5 bit[31..16]: egress::hdr.sctp.src_port + # - bit[16..31] -> TW5 bit[15..0]: egress::hdr.sctp.dst_port + 4..7: TW6 # egress::hdr.sctp.verifTag + 8..9: TH8 # egress::hdr.sctp.checksum + W48: 16777216 # value 1 -> W48 bit[24]: egress::hdr.sctp.$valid + shift: 10 + buf_req: 10 + next: end + 0x****: + 0..3: TW5 + # - bit[0..15] -> TW5 bit[31..16]: egress::hdr.sctp.src_port + # - bit[16..31] -> TW5 bit[15..0]: egress::hdr.sctp.dst_port + 4..7: TW6 # egress::hdr.sctp.verifTag + 8..9: TH8 # egress::hdr.sctp.checksum + W48: 16777216 # value 1 -> W48 bit[24]: egress::hdr.sctp.$valid + shift: 10 + buf_req: 10 + next: end + parse_gre: + match: [ half, byte0 ] + 0b*****0011000100000001011: + 0..1: TH8 + # - bit[0] -> TH8 bit[15]: egress::hdr.gre.C + # - bit[1] -> TH8 bit[14]: egress::hdr.gre.R + # - bit[2] -> TH8 bit[13]: egress::hdr.gre.K + # - bit[3] -> TH8 bit[12]: egress::hdr.gre.S + # - bit[4] -> TH8 bit[11]: egress::hdr.gre.s + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gre.recurse + # - bit[8..12] -> TH8 bit[7..3]: egress::hdr.gre.flags + # - bit[13..15] -> TH8 bit[2..0]: egress::hdr.gre.version + 2: TB5 # egress::hdr.gre.proto[15:8].8-15 + 3: TB4 # egress::hdr.gre.proto[7:0].0-7 + W48: 33554432 # value 1 -> W48 bit[25]: egress::hdr.gre.$valid + load: { half : 10..11, byte0 : 12 } + shift: 4 + buf_req: 13 + next: parse_pptp + 0b*****0000000100000000000: + 0..1: TH8 + # - bit[0] -> TH8 bit[15]: egress::hdr.gre.C + # - bit[1] -> TH8 bit[14]: egress::hdr.gre.R + # - bit[2] -> TH8 bit[13]: egress::hdr.gre.K + # - bit[3] -> TH8 bit[12]: egress::hdr.gre.S + # - bit[4] -> TH8 bit[11]: egress::hdr.gre.s + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gre.recurse + # - bit[8..12] -> TH8 bit[7..3]: egress::hdr.gre.flags + # - bit[13..15] -> TH8 bit[2..0]: egress::hdr.gre.version + 2: TB5 # egress::hdr.gre.proto[15:8].8-15 + 3: TB4 # egress::hdr.gre.proto[7:0].0-7 + W48: 33554432 # value 1 -> W48 bit[25]: egress::hdr.gre.$valid + shift: 4 + buf_req: 4 + next: parse_gre_ipv4 + 0b*****0001000011011011101: + 0..1: TH8 + # - bit[0] -> TH8 bit[15]: egress::hdr.gre.C + # - bit[1] -> TH8 bit[14]: egress::hdr.gre.R + # - bit[2] -> TH8 bit[13]: egress::hdr.gre.K + # - bit[3] -> TH8 bit[12]: egress::hdr.gre.S + # - bit[4] -> TH8 bit[11]: egress::hdr.gre.s + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gre.recurse + # - bit[8..12] -> TH8 bit[7..3]: egress::hdr.gre.flags + # - bit[13..15] -> TH8 bit[2..0]: egress::hdr.gre.version + 2: TB5 # egress::hdr.gre.proto[15:8].8-15 + 3: TB4 # egress::hdr.gre.proto[7:0].0-7 + W48: 33554432 # value 1 -> W48 bit[25]: egress::hdr.gre.$valid + shift: 4 + buf_req: 4 + next: parse_inner_ipv6 + 0x******: + 0..1: TH8 + # - bit[0] -> TH8 bit[15]: egress::hdr.gre.C + # - bit[1] -> TH8 bit[14]: egress::hdr.gre.R + # - bit[2] -> TH8 bit[13]: egress::hdr.gre.K + # - bit[3] -> TH8 bit[12]: egress::hdr.gre.S + # - bit[4] -> TH8 bit[11]: egress::hdr.gre.s + # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gre.recurse + # - bit[8..12] -> TH8 bit[7..3]: egress::hdr.gre.flags + # - bit[13..15] -> TH8 bit[2..0]: egress::hdr.gre.version + 2: TB5 # egress::hdr.gre.proto[15:8].8-15 + 3: TB4 # egress::hdr.gre.proto[7:0].0-7 + W48: 33554432 # value 1 -> W48 bit[25]: egress::hdr.gre.$valid + shift: 4 + buf_req: 4 + next: end + parse_pptp: + match: [ half, byte0 ] + 0x00214*: + 0..1: TH9 + # - bit[0..3] -> TH9 bit[15..12]: egress::hdr.pppoe.version + # - bit[4..7] -> TH9 bit[11..8]: egress::hdr.pppoe.type + # - bit[8..15] -> TH9 bit[7..0]: egress::hdr.pppoe.code + 2..3: TH10 # egress::hdr.pppoe.session_id + 4..7: TW30 + # - bit[32..47] -> TW30 bit[31..16]: egress::hdr.pppoe.pppoe_length + # - bit[48..63] -> TW30 bit[15..0]: egress::hdr.pppoe.ppp_proto + W48: 4194304 # value 1 -> W48 bit[22]: egress::hdr.pppoe.$valid + load: { byte1 : 17 } + shift: 8 + buf_req: 18 + next: parse_inner_ipv4 + 0x00216*: + 0..1: TH9 + # - bit[0..3] -> TH9 bit[15..12]: egress::hdr.pppoe.version + # - bit[4..7] -> TH9 bit[11..8]: egress::hdr.pppoe.type + # - bit[8..15] -> TH9 bit[7..0]: egress::hdr.pppoe.code + 2..3: TH10 # egress::hdr.pppoe.session_id + 4..7: TW30 + # - bit[32..47] -> TW30 bit[31..16]: egress::hdr.pppoe.pppoe_length + # - bit[48..63] -> TW30 bit[15..0]: egress::hdr.pppoe.ppp_proto + W48: 4194304 # value 1 -> W48 bit[22]: egress::hdr.pppoe.$valid + shift: 8 + buf_req: 8 + next: parse_inner_ipv6 + 0x******: + 0..1: TH9 + # - bit[0..3] -> TH9 bit[15..12]: egress::hdr.pppoe.version + # - bit[4..7] -> TH9 bit[11..8]: egress::hdr.pppoe.type + # - bit[8..15] -> TH9 bit[7..0]: egress::hdr.pppoe.code + 2..3: TH10 # egress::hdr.pppoe.session_id + 4..7: TW30 + # - bit[32..47] -> TW30 bit[31..16]: egress::hdr.pppoe.pppoe_length + # - bit[48..63] -> TW30 bit[15..0]: egress::hdr.pppoe.ppp_proto + W48: 4194304 # value 1 -> W48 bit[22]: egress::hdr.pppoe.$valid + shift: 8 + buf_req: 8 + next: end + parse_gre_ipv4: + *: + load: { byte1 : 9 } + buf_req: 10 + next: parse_inner_ipv4 + parse_ipv6: + *: + 0..3: TW4 + # - bit[0..3] -> TW4 bit[31..28]: egress::hdr.ipv6.version + # - bit[4..11] -> TW4 bit[27..20]: egress::hdr.ipv6.traffic_class + # - bit[12..31] -> TW4 bit[19..0]: egress::hdr.ipv6.flow_label + 4..7: TW20 + # - bit[32..47] -> TW20 bit[31..16]: egress::hdr.ipv6.payload_len + # - bit[48..55] -> TW20 bit[15..8]: egress::hdr.ipv6.next_hdr + # - bit[56..63] -> TW20 bit[7..0]: egress::hdr.ipv6.hop_limit + 8..9: H22 # egress::hdr.ipv6.src_addr[127:112].112-127 + 10..11: TH46 # egress::hdr.ipv6.src_addr[111:96].96-111 + 12..15: TW22 # egress::hdr.ipv6.src_addr[95:64].64-95 + 16..17: TH45 # egress::hdr.ipv6.src_addr[63:48].48-63 + 18..19: TH44 # egress::hdr.ipv6.src_addr[47:32].32-47 + 24..27: W47 # egress::hdr.ipv6.dst_addr[127:96].96-127 + W48: 67108864 # value 1 -> W48 bit[26]: egress::hdr.ipv6.$valid + load: { byte1 : 6 } + shift: 20 + buf_req: 28 + next: parse_ipv6.$split_0 + parse_ipv6.$split_0: + match: [ byte1 ] + 0x06: + 0..1: TH43 # egress::hdr.ipv6.src_addr[31:16].16-31 + 2..3: TH31 # egress::hdr.ipv6.src_addr[15:0].0-15 + 8..11: W46 # egress::hdr.ipv6.dst_addr[95:64].64-95 + 12..15: W45 # egress::hdr.ipv6.dst_addr[63:32].32-63 + 16..19: W44 # egress::hdr.ipv6.dst_addr[31:0].0-31 + load: { half : 22..23 } + shift: 20 + buf_req: 24 + next: parse_tcp + 0x11: + 0..1: TH43 # egress::hdr.ipv6.src_addr[31:16].16-31 + 2..3: TH31 # egress::hdr.ipv6.src_addr[15:0].0-15 + 8..11: W46 # egress::hdr.ipv6.dst_addr[95:64].64-95 + 12..15: W45 # egress::hdr.ipv6.dst_addr[63:32].32-63 + 16..19: W44 # egress::hdr.ipv6.dst_addr[31:0].0-31 + load: { half : 22..23 } + shift: 20 + buf_req: 24 + next: parse_udp + 0x3a: + 0..1: TH43 # egress::hdr.ipv6.src_addr[31:16].16-31 + 2..3: TH31 # egress::hdr.ipv6.src_addr[15:0].0-15 + 8..11: W46 # egress::hdr.ipv6.dst_addr[95:64].64-95 + 12..15: W45 # egress::hdr.ipv6.dst_addr[63:32].32-63 + 16..19: W44 # egress::hdr.ipv6.dst_addr[31:0].0-31 + shift: 20 + buf_req: 20 + next: parse_icmp + 0x84: + 0..1: TH43 # egress::hdr.ipv6.src_addr[31:16].16-31 + 2..3: TH31 # egress::hdr.ipv6.src_addr[15:0].0-15 + 8..11: W46 # egress::hdr.ipv6.dst_addr[95:64].64-95 + 12..15: W45 # egress::hdr.ipv6.dst_addr[63:32].32-63 + 16..19: W44 # egress::hdr.ipv6.dst_addr[31:0].0-31 + load: { half : 22..23 } + shift: 20 + buf_req: 24 + next: parse_sctp + 0x29: + 0..1: TH43 # egress::hdr.ipv6.src_addr[31:16].16-31 + 2..3: TH31 # egress::hdr.ipv6.src_addr[15:0].0-15 + 8..11: W46 # egress::hdr.ipv6.dst_addr[95:64].64-95 + 12..15: W45 # egress::hdr.ipv6.dst_addr[63:32].32-63 + 16..19: W44 # egress::hdr.ipv6.dst_addr[31:0].0-31 + shift: 20 + buf_req: 20 + next: parse_inner_ipv6 + 0x04: + 0..1: TH43 # egress::hdr.ipv6.src_addr[31:16].16-31 + 2..3: TH31 # egress::hdr.ipv6.src_addr[15:0].0-15 + 8..11: W46 # egress::hdr.ipv6.dst_addr[95:64].64-95 + 12..15: W45 # egress::hdr.ipv6.dst_addr[63:32].32-63 + 16..19: W44 # egress::hdr.ipv6.dst_addr[31:0].0-31 + load: { byte1 : 29 } + shift: 20 + buf_req: 30 + next: parse_inner_ipv4 + 0x2f: + 0..1: TH43 # egress::hdr.ipv6.src_addr[31:16].16-31 + 2..3: TH31 # egress::hdr.ipv6.src_addr[15:0].0-15 + 8..11: W46 # egress::hdr.ipv6.dst_addr[95:64].64-95 + 12..15: W45 # egress::hdr.ipv6.dst_addr[63:32].32-63 + 16..19: W44 # egress::hdr.ipv6.dst_addr[31:0].0-31 + load: { half : 21..22, byte0 : 23 } + shift: 20 + buf_req: 24 + next: parse_gre + 0x**: + 0..1: TH43 # egress::hdr.ipv6.src_addr[31:16].16-31 + 2..3: TH31 # egress::hdr.ipv6.src_addr[15:0].0-15 + 8..11: W46 # egress::hdr.ipv6.dst_addr[95:64].64-95 + 12..15: W45 # egress::hdr.ipv6.dst_addr[63:32].32-63 + 16..19: W44 # egress::hdr.ipv6.dst_addr[31:0].0-31 + shift: 20 + buf_req: 20 + next: end + parse_vlan: + match: [ half ] + 0x0800: + 0..1: H21 + # - bit[0..2] -> H21 bit[15..13]: egress::hdr.vlan_tag[0].pcp + # - bit[3] -> H21 bit[12]: egress::hdr.vlan_tag[0].cfi + # - bit[4..15] -> H21 bit[11..0]: egress::hdr.vlan_tag[0].vid + 2: TB7 # egress::hdr.vlan_tag[0].ether_type[15:8].8-15 + 3: TB6 # egress::hdr.vlan_tag[0].ether_type[7:0].0-7 + B16: 16 # value 16 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv4 + 0x86dd: + 0..1: H21 + # - bit[0..2] -> H21 bit[15..13]: egress::hdr.vlan_tag[0].pcp + # - bit[3] -> H21 bit[12]: egress::hdr.vlan_tag[0].cfi + # - bit[4..15] -> H21 bit[11..0]: egress::hdr.vlan_tag[0].vid + 2: TB7 # egress::hdr.vlan_tag[0].ether_type[15:8].8-15 + 3: TB6 # egress::hdr.vlan_tag[0].ether_type[7:0].0-7 + B16: 16 # value 16 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv6 + 0x8100: + 0..1: H21 + # - bit[0..2] -> H21 bit[15..13]: egress::hdr.vlan_tag[0].pcp + # - bit[3] -> H21 bit[12]: egress::hdr.vlan_tag[0].cfi + # - bit[4..15] -> H21 bit[11..0]: egress::hdr.vlan_tag[0].vid + 2: TB7 # egress::hdr.vlan_tag[0].ether_type[15:8].8-15 + 3: TB6 # egress::hdr.vlan_tag[0].ether_type[7:0].0-7 + B16: 16 # value 16 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + load: { half : 6..7 } + shift: 4 + buf_req: 8 + next: parse_vlan.$it1 + 0x8847: + 0..1: H21 + # - bit[0..2] -> H21 bit[15..13]: egress::hdr.vlan_tag[0].pcp + # - bit[3] -> H21 bit[12]: egress::hdr.vlan_tag[0].cfi + # - bit[4..15] -> H21 bit[11..0]: egress::hdr.vlan_tag[0].vid + 2: TB7 # egress::hdr.vlan_tag[0].ether_type[15:8].8-15 + 3: TB6 # egress::hdr.vlan_tag[0].ether_type[7:0].0-7 + B16: 16 # value 16 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + load: { byte1 : 6 } + shift: 4 + buf_req: 7 + next: parse_mpls + 0x****: + 0..1: H21 + # - bit[0..2] -> H21 bit[15..13]: egress::hdr.vlan_tag[0].pcp + # - bit[3] -> H21 bit[12]: egress::hdr.vlan_tag[0].cfi + # - bit[4..15] -> H21 bit[11..0]: egress::hdr.vlan_tag[0].vid + 2: TB7 # egress::hdr.vlan_tag[0].ether_type[15:8].8-15 + 3: TB6 # egress::hdr.vlan_tag[0].ether_type[7:0].0-7 + B16: 16 # value 16 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_vlan.$it1: + match: [ half ] + 0x0800: + 0..3: TW12 + # - bit[0..2] -> TW12 bit[31..29]: egress::hdr.vlan_tag[1].pcp + # - bit[3] -> TW12 bit[28]: egress::hdr.vlan_tag[1].cfi + # - bit[4..15] -> TW12 bit[27..16]: egress::hdr.vlan_tag[1].vid + # - bit[16..31] -> TW12 bit[15..0]: egress::hdr.vlan_tag[1].ether_type + B16: 8 # value 8 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv4 + 0x86dd: + 0..3: TW12 + # - bit[0..2] -> TW12 bit[31..29]: egress::hdr.vlan_tag[1].pcp + # - bit[3] -> TW12 bit[28]: egress::hdr.vlan_tag[1].cfi + # - bit[4..15] -> TW12 bit[27..16]: egress::hdr.vlan_tag[1].vid + # - bit[16..31] -> TW12 bit[15..0]: egress::hdr.vlan_tag[1].ether_type + B16: 8 # value 8 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv6 + 0x8100: + 0..3: TW12 + # - bit[0..2] -> TW12 bit[31..29]: egress::hdr.vlan_tag[1].pcp + # - bit[3] -> TW12 bit[28]: egress::hdr.vlan_tag[1].cfi + # - bit[4..15] -> TW12 bit[27..16]: egress::hdr.vlan_tag[1].vid + # - bit[16..31] -> TW12 bit[15..0]: egress::hdr.vlan_tag[1].ether_type + B16: 8 # value 8 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + load: { half : 6..7 } + shift: 4 + buf_req: 8 + next: parse_vlan.$it2 + 0x8847: + 0..3: TW12 + # - bit[0..2] -> TW12 bit[31..29]: egress::hdr.vlan_tag[1].pcp + # - bit[3] -> TW12 bit[28]: egress::hdr.vlan_tag[1].cfi + # - bit[4..15] -> TW12 bit[27..16]: egress::hdr.vlan_tag[1].vid + # - bit[16..31] -> TW12 bit[15..0]: egress::hdr.vlan_tag[1].ether_type + B16: 8 # value 8 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + load: { byte1 : 6 } + shift: 4 + buf_req: 7 + next: parse_mpls + 0x****: + 0..3: TW12 + # - bit[0..2] -> TW12 bit[31..29]: egress::hdr.vlan_tag[1].pcp + # - bit[3] -> TW12 bit[28]: egress::hdr.vlan_tag[1].cfi + # - bit[4..15] -> TW12 bit[27..16]: egress::hdr.vlan_tag[1].vid + # - bit[16..31] -> TW12 bit[15..0]: egress::hdr.vlan_tag[1].ether_type + B16: 8 # value 8 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_vlan.$it2: + match: [ half ] + 0x0800: + 0..3: TW13 + # - bit[0..2] -> TW13 bit[31..29]: egress::hdr.vlan_tag[2].pcp + # - bit[3] -> TW13 bit[28]: egress::hdr.vlan_tag[2].cfi + # - bit[4..15] -> TW13 bit[27..16]: egress::hdr.vlan_tag[2].vid + # - bit[16..31] -> TW13 bit[15..0]: egress::hdr.vlan_tag[2].ether_type + B16: 4 # value 4 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv4 + 0x86dd: + 0..3: TW13 + # - bit[0..2] -> TW13 bit[31..29]: egress::hdr.vlan_tag[2].pcp + # - bit[3] -> TW13 bit[28]: egress::hdr.vlan_tag[2].cfi + # - bit[4..15] -> TW13 bit[27..16]: egress::hdr.vlan_tag[2].vid + # - bit[16..31] -> TW13 bit[15..0]: egress::hdr.vlan_tag[2].ether_type + B16: 4 # value 4 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv6 + 0x8100: + 0..3: TW13 + # - bit[0..2] -> TW13 bit[31..29]: egress::hdr.vlan_tag[2].pcp + # - bit[3] -> TW13 bit[28]: egress::hdr.vlan_tag[2].cfi + # - bit[4..15] -> TW13 bit[27..16]: egress::hdr.vlan_tag[2].vid + # - bit[16..31] -> TW13 bit[15..0]: egress::hdr.vlan_tag[2].ether_type + B16: 4 # value 4 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + load: { half : 6..7 } + shift: 4 + buf_req: 8 + next: parse_vlan.$it3 + 0x8847: + 0..3: TW13 + # - bit[0..2] -> TW13 bit[31..29]: egress::hdr.vlan_tag[2].pcp + # - bit[3] -> TW13 bit[28]: egress::hdr.vlan_tag[2].cfi + # - bit[4..15] -> TW13 bit[27..16]: egress::hdr.vlan_tag[2].vid + # - bit[16..31] -> TW13 bit[15..0]: egress::hdr.vlan_tag[2].ether_type + B16: 4 # value 4 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + load: { byte1 : 6 } + shift: 4 + buf_req: 7 + next: parse_mpls + 0x****: + 0..3: TW13 + # - bit[0..2] -> TW13 bit[31..29]: egress::hdr.vlan_tag[2].pcp + # - bit[3] -> TW13 bit[28]: egress::hdr.vlan_tag[2].cfi + # - bit[4..15] -> TW13 bit[27..16]: egress::hdr.vlan_tag[2].vid + # - bit[16..31] -> TW13 bit[15..0]: egress::hdr.vlan_tag[2].ether_type + B16: 4 # value 4 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_vlan.$it3: + match: [ half ] + 0x0800: + 0..3: TW14 + # - bit[0..2] -> TW14 bit[31..29]: egress::hdr.vlan_tag[3].pcp + # - bit[3] -> TW14 bit[28]: egress::hdr.vlan_tag[3].cfi + # - bit[4..15] -> TW14 bit[27..16]: egress::hdr.vlan_tag[3].vid + # - bit[16..31] -> TW14 bit[15..0]: egress::hdr.vlan_tag[3].ether_type + B16: 2 # value 2 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv4 + 0x86dd: + 0..3: TW14 + # - bit[0..2] -> TW14 bit[31..29]: egress::hdr.vlan_tag[3].pcp + # - bit[3] -> TW14 bit[28]: egress::hdr.vlan_tag[3].cfi + # - bit[4..15] -> TW14 bit[27..16]: egress::hdr.vlan_tag[3].vid + # - bit[16..31] -> TW14 bit[15..0]: egress::hdr.vlan_tag[3].ether_type + B16: 2 # value 2 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv6 + 0x8100: + 0..3: TW14 + # - bit[0..2] -> TW14 bit[31..29]: egress::hdr.vlan_tag[3].pcp + # - bit[3] -> TW14 bit[28]: egress::hdr.vlan_tag[3].cfi + # - bit[4..15] -> TW14 bit[27..16]: egress::hdr.vlan_tag[3].vid + # - bit[16..31] -> TW14 bit[15..0]: egress::hdr.vlan_tag[3].ether_type + B16: 2 # value 2 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + load: { half : 6..7 } + shift: 4 + buf_req: 8 + next: parse_vlan.$it4 + 0x8847: + 0..3: TW14 + # - bit[0..2] -> TW14 bit[31..29]: egress::hdr.vlan_tag[3].pcp + # - bit[3] -> TW14 bit[28]: egress::hdr.vlan_tag[3].cfi + # - bit[4..15] -> TW14 bit[27..16]: egress::hdr.vlan_tag[3].vid + # - bit[16..31] -> TW14 bit[15..0]: egress::hdr.vlan_tag[3].ether_type + B16: 2 # value 2 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + load: { byte1 : 6 } + shift: 4 + buf_req: 7 + next: parse_mpls + 0x****: + 0..3: TW14 + # - bit[0..2] -> TW14 bit[31..29]: egress::hdr.vlan_tag[3].pcp + # - bit[3] -> TW14 bit[28]: egress::hdr.vlan_tag[3].cfi + # - bit[4..15] -> TW14 bit[27..16]: egress::hdr.vlan_tag[3].vid + # - bit[16..31] -> TW14 bit[15..0]: egress::hdr.vlan_tag[3].ether_type + B16: 2 # value 2 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_vlan.$it4: + match: [ half ] + 0x0800: + 0..3: TW15 + # - bit[0..2] -> TW15 bit[31..29]: egress::hdr.vlan_tag[4].pcp + # - bit[3] -> TW15 bit[28]: egress::hdr.vlan_tag[4].cfi + # - bit[4..15] -> TW15 bit[27..16]: egress::hdr.vlan_tag[4].vid + # - bit[16..31] -> TW15 bit[15..0]: egress::hdr.vlan_tag[4].ether_type + B16: 1 # value 1 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv4 + 0x86dd: + 0..3: TW15 + # - bit[0..2] -> TW15 bit[31..29]: egress::hdr.vlan_tag[4].pcp + # - bit[3] -> TW15 bit[28]: egress::hdr.vlan_tag[4].cfi + # - bit[4..15] -> TW15 bit[27..16]: egress::hdr.vlan_tag[4].vid + # - bit[16..31] -> TW15 bit[15..0]: egress::hdr.vlan_tag[4].ether_type + B16: 1 # value 1 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv6 + 0x8100: + 0..3: TW15 + # - bit[0..2] -> TW15 bit[31..29]: egress::hdr.vlan_tag[4].pcp + # - bit[3] -> TW15 bit[28]: egress::hdr.vlan_tag[4].cfi + # - bit[4..15] -> TW15 bit[27..16]: egress::hdr.vlan_tag[4].vid + # - bit[16..31] -> TW15 bit[15..0]: egress::hdr.vlan_tag[4].ether_type + B16: 1 # value 1 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + 0x8847: + 0..3: TW15 + # - bit[0..2] -> TW15 bit[31..29]: egress::hdr.vlan_tag[4].pcp + # - bit[3] -> TW15 bit[28]: egress::hdr.vlan_tag[4].cfi + # - bit[4..15] -> TW15 bit[27..16]: egress::hdr.vlan_tag[4].vid + # - bit[16..31] -> TW15 bit[15..0]: egress::hdr.vlan_tag[4].ether_type + B16: 1 # value 1 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + load: { byte1 : 6 } + shift: 4 + buf_req: 7 + next: parse_mpls + 0x****: + 0..3: TW15 + # - bit[0..2] -> TW15 bit[31..29]: egress::hdr.vlan_tag[4].pcp + # - bit[3] -> TW15 bit[28]: egress::hdr.vlan_tag[4].cfi + # - bit[4..15] -> TW15 bit[27..16]: egress::hdr.vlan_tag[4].vid + # - bit[16..31] -> TW15 bit[15..0]: egress::hdr.vlan_tag[4].ether_type + B16: 1 # value 1 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_mpls: + match: [ byte1 ] + 0b*******0: + 0..1: TH19 # egress::hdr.mpls[0].label[19:4].4-19 + 2..3: TH18 + # - bit[16..19] -> TH18 bit[15..12]: egress::hdr.mpls[0].label[3:0].0-3 + # - bit[20..22] -> TH18 bit[11..9]: egress::hdr.mpls[0].exp + # - bit[23] -> TH18 bit[8]: egress::hdr.mpls[0].bos + # - bit[24..31] -> TH18 bit[7..0]: egress::hdr.mpls[0].ttl + B17: 8 # value 8 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid + load: { byte1 : 6 } + shift: 4 + buf_req: 7 + next: parse_mpls.$it1 + 0b*******1: + 0..1: TH19 # egress::hdr.mpls[0].label[19:4].4-19 + 2..3: TH18 + # - bit[16..19] -> TH18 bit[15..12]: egress::hdr.mpls[0].label[3:0].0-3 + # - bit[20..22] -> TH18 bit[11..9]: egress::hdr.mpls[0].exp + # - bit[23] -> TH18 bit[8]: egress::hdr.mpls[0].bos + # - bit[24..31] -> TH18 bit[7..0]: egress::hdr.mpls[0].ttl + B17: 8 # value 8 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid + load: { byte1 : 4 } + shift: 4 + buf_req: 5 + next: parse_mpls_bos + 0x**: + 0..1: TH19 # egress::hdr.mpls[0].label[19:4].4-19 + 2..3: TH18 + # - bit[16..19] -> TH18 bit[15..12]: egress::hdr.mpls[0].label[3:0].0-3 + # - bit[20..22] -> TH18 bit[11..9]: egress::hdr.mpls[0].exp + # - bit[23] -> TH18 bit[8]: egress::hdr.mpls[0].bos + # - bit[24..31] -> TH18 bit[7..0]: egress::hdr.mpls[0].ttl + B17: 8 # value 8 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_mpls.$it1: + match: [ byte1 ] + 0b*******0: + 0..1: TH21 # egress::hdr.mpls[1].label[19:4].4-19 + 2..3: TH20 + # - bit[16..19] -> TH20 bit[15..12]: egress::hdr.mpls[1].label[3:0].0-3 + # - bit[20..22] -> TH20 bit[11..9]: egress::hdr.mpls[1].exp + # - bit[23] -> TH20 bit[8]: egress::hdr.mpls[1].bos + # - bit[24..31] -> TH20 bit[7..0]: egress::hdr.mpls[1].ttl + B17: 4 # value 4 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid + load: { byte1 : 6 } + shift: 4 + buf_req: 7 + next: parse_mpls.$it2 + 0b*******1: + 0..1: TH21 # egress::hdr.mpls[1].label[19:4].4-19 + 2..3: TH20 + # - bit[16..19] -> TH20 bit[15..12]: egress::hdr.mpls[1].label[3:0].0-3 + # - bit[20..22] -> TH20 bit[11..9]: egress::hdr.mpls[1].exp + # - bit[23] -> TH20 bit[8]: egress::hdr.mpls[1].bos + # - bit[24..31] -> TH20 bit[7..0]: egress::hdr.mpls[1].ttl + B17: 4 # value 4 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid + load: { byte1 : 4 } + shift: 4 + buf_req: 5 + next: parse_mpls_bos + 0x**: + 0..1: TH21 # egress::hdr.mpls[1].label[19:4].4-19 + 2..3: TH20 + # - bit[16..19] -> TH20 bit[15..12]: egress::hdr.mpls[1].label[3:0].0-3 + # - bit[20..22] -> TH20 bit[11..9]: egress::hdr.mpls[1].exp + # - bit[23] -> TH20 bit[8]: egress::hdr.mpls[1].bos + # - bit[24..31] -> TH20 bit[7..0]: egress::hdr.mpls[1].ttl + B17: 4 # value 4 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_mpls.$it2: + match: [ byte1 ] + 0b*******0: + 0..1: TH23 # egress::hdr.mpls[2].label[19:4].4-19 + 2..3: TH22 + # - bit[16..19] -> TH22 bit[15..12]: egress::hdr.mpls[2].label[3:0].0-3 + # - bit[20..22] -> TH22 bit[11..9]: egress::hdr.mpls[2].exp + # - bit[23] -> TH22 bit[8]: egress::hdr.mpls[2].bos + # - bit[24..31] -> TH22 bit[7..0]: egress::hdr.mpls[2].ttl + B17: 2 # value 2 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid + shift: 4 + buf_req: 4 + next: parse_mpls.$it3 + 0b*******1: + 0..1: TH23 # egress::hdr.mpls[2].label[19:4].4-19 + 2..3: TH22 + # - bit[16..19] -> TH22 bit[15..12]: egress::hdr.mpls[2].label[3:0].0-3 + # - bit[20..22] -> TH22 bit[11..9]: egress::hdr.mpls[2].exp + # - bit[23] -> TH22 bit[8]: egress::hdr.mpls[2].bos + # - bit[24..31] -> TH22 bit[7..0]: egress::hdr.mpls[2].ttl + B17: 2 # value 2 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid + load: { byte1 : 4 } + shift: 4 + buf_req: 5 + next: parse_mpls_bos + 0x**: + 0..1: TH23 # egress::hdr.mpls[2].label[19:4].4-19 + 2..3: TH22 + # - bit[16..19] -> TH22 bit[15..12]: egress::hdr.mpls[2].label[3:0].0-3 + # - bit[20..22] -> TH22 bit[11..9]: egress::hdr.mpls[2].exp + # - bit[23] -> TH22 bit[8]: egress::hdr.mpls[2].bos + # - bit[24..31] -> TH22 bit[7..0]: egress::hdr.mpls[2].ttl + B17: 2 # value 2 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_mpls.$it3: + *: + 0: TB15 # egress::hdr.mpls[3].label[19:12].12-19 + 1: TB14 # egress::hdr.mpls[3].label[11:4].4-11 + 2: TB12 + # - bit[16..19] -> TB12 bit[7..4]: egress::hdr.mpls[3].label[3:0].0-3 + # - bit[20..22] -> TB12 bit[3..1]: egress::hdr.mpls[3].exp + # - bit[23] -> TB12 bit[0]: egress::hdr.mpls[3].bos + 3: TB13 # egress::hdr.mpls[3].ttl + load: { byte1 : 2 } + shift: 4 + buf_req: 4 + next: parse_mpls.$it3.$split_0 + parse_mpls.$it3.$split_0: + match: [ byte1 ] + 0b*******0: + B17: 1 # value 1 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid + buf_req: 0 + next: end + 0b*******1: + B17: 1 # value 1 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid + load: { byte1 : 0 } + buf_req: 1 + next: parse_mpls_bos + 0x**: + B17: 1 # value 1 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid + buf_req: 0 + next: end + parse_mpls_bos: + match: [ byte1 ] + 0x4*: + 0..3: TW4 + # - bit[0..3] -> TW4 bit[31..28]: egress::hdr.ipv4.version + # - bit[4..7] -> TW4 bit[27..24]: egress::hdr.ipv4.ihl + # - bit[8..15] -> TW4 bit[23..16]: egress::hdr.ipv4.diffserv + # - bit[16..31] -> TW4 bit[15..0]: egress::hdr.ipv4.total_len + 4..7: TW20 + # - bit[32..47] -> TW20 bit[31..16]: egress::hdr.ipv4.identification + # - bit[48..50] -> TW20 bit[15..13]: egress::hdr.ipv4.flags + # - bit[51..63] -> TW20 bit[12..0]: egress::hdr.ipv4.frag_offset + 8..9: TH31 + # - bit[64..71] -> TH31 bit[15..8]: egress::hdr.ipv4.ttl + # - bit[72..79] -> TH31 bit[7..0]: egress::hdr.ipv4.protocol + 8..11: TW22 # bit[80..95] -> TW22 bit[15..0]: egress::hdr.ipv4.hdr_checksum + 12..13: TH44 # egress::hdr.ipv4.src_addr[31:16].16-31 + 14..15: TH43 # egress::hdr.ipv4.src_addr[15:0].0-15 + 16..17: TH46 # egress::hdr.ipv4.dst_addr[31:16].16-31 + W48: 4 # value 1 -> W48 bit[2]: egress::hdr.ipv4.$valid + load: { byte1 : 9 } + shift: 18 + buf_req: 18 + next: parse_ipv4.$split_0 + 0x6*: + 0..3: TW4 + # - bit[0..3] -> TW4 bit[31..28]: egress::hdr.ipv6.version + # - bit[4..11] -> TW4 bit[27..20]: egress::hdr.ipv6.traffic_class + # - bit[12..31] -> TW4 bit[19..0]: egress::hdr.ipv6.flow_label + 4..7: TW20 + # - bit[32..47] -> TW20 bit[31..16]: egress::hdr.ipv6.payload_len + # - bit[48..55] -> TW20 bit[15..8]: egress::hdr.ipv6.next_hdr + # - bit[56..63] -> TW20 bit[7..0]: egress::hdr.ipv6.hop_limit + 8..9: H22 # egress::hdr.ipv6.src_addr[127:112].112-127 + 10..11: TH46 # egress::hdr.ipv6.src_addr[111:96].96-111 + 12..15: TW22 # egress::hdr.ipv6.src_addr[95:64].64-95 + 16..17: TH45 # egress::hdr.ipv6.src_addr[63:48].48-63 + 18..19: TH44 # egress::hdr.ipv6.src_addr[47:32].32-47 + 24..27: W47 # egress::hdr.ipv6.dst_addr[127:96].96-127 + W48: 67108864 # value 1 -> W48 bit[26]: egress::hdr.ipv6.$valid + load: { byte1 : 6 } + shift: 20 + buf_req: 28 + next: parse_ipv6.$split_0 + 0x**: + buf_req: 0 + next: end + parse_fabric: + match: [ half ] + 0x0800: + 0..3: W16 + # - bit[0] -> W16 bit[31]: egress::hdr.fabric.pad1 + # - bit[1] -> W16 bit[30]: egress::hdr.fabric.is_hit + # - bit[2] -> W16 bit[29]: egress::hdr.fabric.is_to_cn78 + # - bit[3] -> W16 bit[28]: egress::hdr.fabric.is_to_td3 + # - bit[4] -> W16 bit[27]: egress::hdr.fabric.is_hdr_decap + # - bit[5..7] -> W16 bit[26..24]: egress::hdr.fabric.ig_port_type + # - bit[8..13] -> W16 bit[23..18]: egress::hdr.fabric.pad2 + # - bit[14..31] -> W16 bit[17..0]: egress::hdr.fabric.mac_index + 4..7: W17 + # - bit[32..35] -> W17 bit[31..28]: egress::hdr.fabric.pad4 + # - bit[36] -> W17 bit[27]: egress::hdr.fabric.flags_drop + # - bit[37] -> W17 bit[26]: egress::hdr.fabric.is_trunc_mir + # - bit[38..55] -> W17 bit[25..8]: egress::hdr.fabric.count_index + # - bit[56..63] -> W17 bit[7..0]: egress::hdr.fabric.mc_index[15:8].8-15 + 8: B18 # egress::hdr.fabric.mc_index[7:0].0-7 + 9..10: H20 # egress::hdr.fabric.vlan_index + 11..12: H17 # egress::hdr.fabric.ether_type + W48: 134217728 # value 1 -> W48 bit[27]: egress::hdr.fabric.$valid + shift: 13 + buf_req: 13 + next: parse_ipv4 + 0x86dd: + 0..3: W16 + # - bit[0] -> W16 bit[31]: egress::hdr.fabric.pad1 + # - bit[1] -> W16 bit[30]: egress::hdr.fabric.is_hit + # - bit[2] -> W16 bit[29]: egress::hdr.fabric.is_to_cn78 + # - bit[3] -> W16 bit[28]: egress::hdr.fabric.is_to_td3 + # - bit[4] -> W16 bit[27]: egress::hdr.fabric.is_hdr_decap + # - bit[5..7] -> W16 bit[26..24]: egress::hdr.fabric.ig_port_type + # - bit[8..13] -> W16 bit[23..18]: egress::hdr.fabric.pad2 + # - bit[14..31] -> W16 bit[17..0]: egress::hdr.fabric.mac_index + 4..7: W17 + # - bit[32..35] -> W17 bit[31..28]: egress::hdr.fabric.pad4 + # - bit[36] -> W17 bit[27]: egress::hdr.fabric.flags_drop + # - bit[37] -> W17 bit[26]: egress::hdr.fabric.is_trunc_mir + # - bit[38..55] -> W17 bit[25..8]: egress::hdr.fabric.count_index + # - bit[56..63] -> W17 bit[7..0]: egress::hdr.fabric.mc_index[15:8].8-15 + 8: B18 # egress::hdr.fabric.mc_index[7:0].0-7 + 9..10: H20 # egress::hdr.fabric.vlan_index + 11..12: H17 # egress::hdr.fabric.ether_type + W48: 134217728 # value 1 -> W48 bit[27]: egress::hdr.fabric.$valid + shift: 13 + buf_req: 13 + next: parse_ipv6 + 0x8100: + 0..3: W16 + # - bit[0] -> W16 bit[31]: egress::hdr.fabric.pad1 + # - bit[1] -> W16 bit[30]: egress::hdr.fabric.is_hit + # - bit[2] -> W16 bit[29]: egress::hdr.fabric.is_to_cn78 + # - bit[3] -> W16 bit[28]: egress::hdr.fabric.is_to_td3 + # - bit[4] -> W16 bit[27]: egress::hdr.fabric.is_hdr_decap + # - bit[5..7] -> W16 bit[26..24]: egress::hdr.fabric.ig_port_type + # - bit[8..13] -> W16 bit[23..18]: egress::hdr.fabric.pad2 + # - bit[14..31] -> W16 bit[17..0]: egress::hdr.fabric.mac_index + 4..7: W17 + # - bit[32..35] -> W17 bit[31..28]: egress::hdr.fabric.pad4 + # - bit[36] -> W17 bit[27]: egress::hdr.fabric.flags_drop + # - bit[37] -> W17 bit[26]: egress::hdr.fabric.is_trunc_mir + # - bit[38..55] -> W17 bit[25..8]: egress::hdr.fabric.count_index + # - bit[56..63] -> W17 bit[7..0]: egress::hdr.fabric.mc_index[15:8].8-15 + 8: B18 # egress::hdr.fabric.mc_index[7:0].0-7 + 9..10: H20 # egress::hdr.fabric.vlan_index + 11..12: H17 # egress::hdr.fabric.ether_type + W48: 134217728 # value 1 -> W48 bit[27]: egress::hdr.fabric.$valid + load: { half : 15..16 } + shift: 13 + buf_req: 17 + next: parse_vlan + 0x8847: + 0..3: W16 + # - bit[0] -> W16 bit[31]: egress::hdr.fabric.pad1 + # - bit[1] -> W16 bit[30]: egress::hdr.fabric.is_hit + # - bit[2] -> W16 bit[29]: egress::hdr.fabric.is_to_cn78 + # - bit[3] -> W16 bit[28]: egress::hdr.fabric.is_to_td3 + # - bit[4] -> W16 bit[27]: egress::hdr.fabric.is_hdr_decap + # - bit[5..7] -> W16 bit[26..24]: egress::hdr.fabric.ig_port_type + # - bit[8..13] -> W16 bit[23..18]: egress::hdr.fabric.pad2 + # - bit[14..31] -> W16 bit[17..0]: egress::hdr.fabric.mac_index + 4..7: W17 + # - bit[32..35] -> W17 bit[31..28]: egress::hdr.fabric.pad4 + # - bit[36] -> W17 bit[27]: egress::hdr.fabric.flags_drop + # - bit[37] -> W17 bit[26]: egress::hdr.fabric.is_trunc_mir + # - bit[38..55] -> W17 bit[25..8]: egress::hdr.fabric.count_index + # - bit[56..63] -> W17 bit[7..0]: egress::hdr.fabric.mc_index[15:8].8-15 + 8: B18 # egress::hdr.fabric.mc_index[7:0].0-7 + 9..10: H20 # egress::hdr.fabric.vlan_index + 11..12: H17 # egress::hdr.fabric.ether_type + W48: 134217728 # value 1 -> W48 bit[27]: egress::hdr.fabric.$valid + load: { byte1 : 15 } + shift: 13 + buf_req: 16 + next: parse_mpls + 0x****: + 0..3: W16 + # - bit[0] -> W16 bit[31]: egress::hdr.fabric.pad1 + # - bit[1] -> W16 bit[30]: egress::hdr.fabric.is_hit + # - bit[2] -> W16 bit[29]: egress::hdr.fabric.is_to_cn78 + # - bit[3] -> W16 bit[28]: egress::hdr.fabric.is_to_td3 + # - bit[4] -> W16 bit[27]: egress::hdr.fabric.is_hdr_decap + # - bit[5..7] -> W16 bit[26..24]: egress::hdr.fabric.ig_port_type + # - bit[8..13] -> W16 bit[23..18]: egress::hdr.fabric.pad2 + # - bit[14..31] -> W16 bit[17..0]: egress::hdr.fabric.mac_index + 4..7: W17 + # - bit[32..35] -> W17 bit[31..28]: egress::hdr.fabric.pad4 + # - bit[36] -> W17 bit[27]: egress::hdr.fabric.flags_drop + # - bit[37] -> W17 bit[26]: egress::hdr.fabric.is_trunc_mir + # - bit[38..55] -> W17 bit[25..8]: egress::hdr.fabric.count_index + # - bit[56..63] -> W17 bit[7..0]: egress::hdr.fabric.mc_index[15:8].8-15 + 8: B18 # egress::hdr.fabric.mc_index[7:0].0-7 + 9..10: H20 # egress::hdr.fabric.vlan_index + 11..12: H17 # egress::hdr.fabric.ether_type + W48: 134217728 # value 1 -> W48 bit[27]: egress::hdr.fabric.$valid + shift: 13 + buf_req: 13 + next: end + parse_truncate_only_metadata: + *: + 9..12: TW31 # egress::hdr.ethernet.dst_addr[47:16].16-47 + 13..14: H24 # egress::hdr.ethernet.dst_addr[15:0].0-15 + 15..16: TH42 # egress::hdr.ethernet.src_addr[47:32].32-47 + 17..18: TH35 # egress::hdr.ethernet.src_addr[31:16].16-31 + 19..20: TH6 # egress::hdr.ethernet.src_addr[15:0].0-15 + W48: 2 # value 1 -> W48 bit[1]: egress::hdr.ethernet.$valid + load: { half : 21..22 } + shift: 21 + buf_req: 23 + next: parse_ethernet.$split_0 +deparser egress: + dictionary: + TW31: W48(1) # egress::hdr.ethernet.dst_addr.16-47 if egress::hdr.ethernet.$valid + H24: W48(1) # egress::hdr.ethernet.dst_addr.0-15 if egress::hdr.ethernet.$valid + TH42: W48(1) # egress::hdr.ethernet.src_addr.32-47 if egress::hdr.ethernet.$valid + TH35: W48(1) # egress::hdr.ethernet.src_addr.16-31 if egress::hdr.ethernet.$valid + TH6: W48(1) # egress::hdr.ethernet.src_addr.0-15 if egress::hdr.ethernet.$valid + H19: W48(1) # egress::hdr.ethernet.ether_type if egress::hdr.ethernet.$valid + W16: W48(27) + # - bit[31]: egress::hdr.fabric.pad1 if egress::hdr.fabric.$valid + # - bit[30]: egress::hdr.fabric.is_hit if egress::hdr.fabric.$valid + # - bit[29]: egress::hdr.fabric.is_to_cn78 if egress::hdr.fabric.$valid + # - bit[28]: egress::hdr.fabric.is_to_td3 if egress::hdr.fabric.$valid + # - bit[27]: egress::hdr.fabric.is_hdr_decap if egress::hdr.fabric.$valid + # - bit[26..24]: egress::hdr.fabric.ig_port_type if egress::hdr.fabric.$valid + # - bit[23..18]: egress::hdr.fabric.pad2 if egress::hdr.fabric.$valid + # - bit[17..0]: egress::hdr.fabric.mac_index if egress::hdr.fabric.$valid + W17: W48(27) + # - bit[31..28]: egress::hdr.fabric.pad4 if egress::hdr.fabric.$valid + # - bit[27]: egress::hdr.fabric.flags_drop if egress::hdr.fabric.$valid + # - bit[26]: egress::hdr.fabric.is_trunc_mir if egress::hdr.fabric.$valid + # - bit[25..8]: egress::hdr.fabric.count_index if egress::hdr.fabric.$valid + # - bit[7..0]: egress::hdr.fabric.mc_index.8-15 if egress::hdr.fabric.$valid + B18: W48(27) # egress::hdr.fabric.mc_index.0-7 if egress::hdr.fabric.$valid + H20: W48(27) # egress::hdr.fabric.vlan_index if egress::hdr.fabric.$valid + H17: W48(27) # egress::hdr.fabric.ether_type if egress::hdr.fabric.$valid + H23: W48(0) + # - bit[15..8]: egress::hdr.fabric_to_cn78.pkt_proto_type if egress::hdr.fabric_to_cn78.$valid + # - bit[7..0]: egress::hdr.fabric_to_cn78.ip_hdr_location if egress::hdr.fabric_to_cn78.$valid + TH7: W48(0) # egress::hdr.fabric_to_cn78.payload_crc32 if egress::hdr.fabric_to_cn78.$valid + H18: W48(0) # egress::hdr.fabric_to_cn78.ether_type if egress::hdr.fabric_to_cn78.$valid + H21: B16(4) + # - bit[15..13]: egress::hdr.vlan_tag[0].pcp if egress::hdr.vlan_tag[0].$valid + # - bit[12]: egress::hdr.vlan_tag[0].cfi if egress::hdr.vlan_tag[0].$valid + # - bit[11..0]: egress::hdr.vlan_tag[0].vid if egress::hdr.vlan_tag[0].$valid + TB7: B16(4) # egress::hdr.vlan_tag[0].ether_type.8-15 if egress::hdr.vlan_tag[0].$valid + TB6: B16(4) # egress::hdr.vlan_tag[0].ether_type.0-7 if egress::hdr.vlan_tag[0].$valid + TW12: B16(3) + # - bit[31..29]: egress::hdr.vlan_tag[1].pcp if egress::hdr.vlan_tag[1].$valid + # - bit[28]: egress::hdr.vlan_tag[1].cfi if egress::hdr.vlan_tag[1].$valid + # - bit[27..16]: egress::hdr.vlan_tag[1].vid if egress::hdr.vlan_tag[1].$valid + # - bit[15..0]: egress::hdr.vlan_tag[1].ether_type if egress::hdr.vlan_tag[1].$valid + TW13: B16(2) + # - bit[31..29]: egress::hdr.vlan_tag[2].pcp if egress::hdr.vlan_tag[2].$valid + # - bit[28]: egress::hdr.vlan_tag[2].cfi if egress::hdr.vlan_tag[2].$valid + # - bit[27..16]: egress::hdr.vlan_tag[2].vid if egress::hdr.vlan_tag[2].$valid + # - bit[15..0]: egress::hdr.vlan_tag[2].ether_type if egress::hdr.vlan_tag[2].$valid + TW14: B16(1) + # - bit[31..29]: egress::hdr.vlan_tag[3].pcp if egress::hdr.vlan_tag[3].$valid + # - bit[28]: egress::hdr.vlan_tag[3].cfi if egress::hdr.vlan_tag[3].$valid + # - bit[27..16]: egress::hdr.vlan_tag[3].vid if egress::hdr.vlan_tag[3].$valid + # - bit[15..0]: egress::hdr.vlan_tag[3].ether_type if egress::hdr.vlan_tag[3].$valid + TW15: B16(0) + # - bit[31..29]: egress::hdr.vlan_tag[4].pcp if egress::hdr.vlan_tag[4].$valid + # - bit[28]: egress::hdr.vlan_tag[4].cfi if egress::hdr.vlan_tag[4].$valid + # - bit[27..16]: egress::hdr.vlan_tag[4].vid if egress::hdr.vlan_tag[4].$valid + # - bit[15..0]: egress::hdr.vlan_tag[4].ether_type if egress::hdr.vlan_tag[4].$valid + TH19: B17(3) # egress::hdr.mpls[0].label.4-19 if egress::hdr.mpls[0].$valid + TH18: B17(3) + # - bit[15..12]: egress::hdr.mpls[0].label.0-3 if egress::hdr.mpls[0].$valid + # - bit[11..9]: egress::hdr.mpls[0].exp if egress::hdr.mpls[0].$valid + # - bit[8]: egress::hdr.mpls[0].bos if egress::hdr.mpls[0].$valid + # - bit[7..0]: egress::hdr.mpls[0].ttl if egress::hdr.mpls[0].$valid + TH21: B17(2) # egress::hdr.mpls[1].label.4-19 if egress::hdr.mpls[1].$valid + TH20: B17(2) + # - bit[15..12]: egress::hdr.mpls[1].label.0-3 if egress::hdr.mpls[1].$valid + # - bit[11..9]: egress::hdr.mpls[1].exp if egress::hdr.mpls[1].$valid + # - bit[8]: egress::hdr.mpls[1].bos if egress::hdr.mpls[1].$valid + # - bit[7..0]: egress::hdr.mpls[1].ttl if egress::hdr.mpls[1].$valid + TH23: B17(1) # egress::hdr.mpls[2].label.4-19 if egress::hdr.mpls[2].$valid + TH22: B17(1) + # - bit[15..12]: egress::hdr.mpls[2].label.0-3 if egress::hdr.mpls[2].$valid + # - bit[11..9]: egress::hdr.mpls[2].exp if egress::hdr.mpls[2].$valid + # - bit[8]: egress::hdr.mpls[2].bos if egress::hdr.mpls[2].$valid + # - bit[7..0]: egress::hdr.mpls[2].ttl if egress::hdr.mpls[2].$valid + TB15: B17(0) # egress::hdr.mpls[3].label.12-19 if egress::hdr.mpls[3].$valid + TB14: B17(0) # egress::hdr.mpls[3].label.4-11 if egress::hdr.mpls[3].$valid + TB12: B17(0) + # - bit[7..4]: egress::hdr.mpls[3].label.0-3 if egress::hdr.mpls[3].$valid + # - bit[3..1]: egress::hdr.mpls[3].exp if egress::hdr.mpls[3].$valid + # - bit[0]: egress::hdr.mpls[3].bos if egress::hdr.mpls[3].$valid + TB13: B17(0) # egress::hdr.mpls[3].ttl if egress::hdr.mpls[3].$valid + TW4: W48(2) + # - bit[31..28]: egress::hdr.ipv4.version if egress::hdr.ipv4.$valid + # - bit[27..24]: egress::hdr.ipv4.ihl if egress::hdr.ipv4.$valid + # - bit[23..16]: egress::hdr.ipv4.diffserv if egress::hdr.ipv4.$valid + # - bit[15..0]: egress::hdr.ipv4.total_len if egress::hdr.ipv4.$valid + TW20: W48(2) + # - bit[31..16]: egress::hdr.ipv4.identification if egress::hdr.ipv4.$valid + # - bit[15..13]: egress::hdr.ipv4.flags if egress::hdr.ipv4.$valid + # - bit[12..0]: egress::hdr.ipv4.frag_offset if egress::hdr.ipv4.$valid + TH31: W48(2) + # - bit[15..8]: egress::hdr.ipv4.ttl if egress::hdr.ipv4.$valid + # - bit[7..0]: egress::hdr.ipv4.protocol if egress::hdr.ipv4.$valid + TH44: W48(2) # egress::hdr.ipv4.src_addr.16-31 if egress::hdr.ipv4.$valid + TH43: W48(2) # egress::hdr.ipv4.src_addr.0-15 if egress::hdr.ipv4.$valid + TH46: W48(2) # egress::hdr.ipv4.dst_addr.16-31 if egress::hdr.ipv4.$valid + TH45: W48(2) # egress::hdr.ipv4.dst_addr.0-15 if egress::hdr.ipv4.$valid + TW4: W48(26) + # - bit[31..28]: egress::hdr.ipv6.version if egress::hdr.ipv6.$valid + # - bit[27..20]: egress::hdr.ipv6.traffic_class if egress::hdr.ipv6.$valid + # - bit[19..0]: egress::hdr.ipv6.flow_label if egress::hdr.ipv6.$valid + TW20: W48(26) + # - bit[31..16]: egress::hdr.ipv6.payload_len if egress::hdr.ipv6.$valid + # - bit[15..8]: egress::hdr.ipv6.next_hdr if egress::hdr.ipv6.$valid + # - bit[7..0]: egress::hdr.ipv6.hop_limit if egress::hdr.ipv6.$valid + H22: W48(26) # egress::hdr.ipv6.src_addr.112-127 if egress::hdr.ipv6.$valid + TH46: W48(26) # egress::hdr.ipv6.src_addr.96-111 if egress::hdr.ipv6.$valid + TW22: W48(26) # egress::hdr.ipv6.src_addr.64-95 if egress::hdr.ipv6.$valid + TH45: W48(26) # egress::hdr.ipv6.src_addr.48-63 if egress::hdr.ipv6.$valid + TH44: W48(26) # egress::hdr.ipv6.src_addr.32-47 if egress::hdr.ipv6.$valid + TH43: W48(26) # egress::hdr.ipv6.src_addr.16-31 if egress::hdr.ipv6.$valid + TH31: W48(26) # egress::hdr.ipv6.src_addr.0-15 if egress::hdr.ipv6.$valid + W47: W48(26) # egress::hdr.ipv6.dst_addr.96-127 if egress::hdr.ipv6.$valid + W46: W48(26) # egress::hdr.ipv6.dst_addr.64-95 if egress::hdr.ipv6.$valid + W45: W48(26) # egress::hdr.ipv6.dst_addr.32-63 if egress::hdr.ipv6.$valid + W44: W48(26) # egress::hdr.ipv6.dst_addr.0-31 if egress::hdr.ipv6.$valid + TW23: W48(16) + # - bit[31..16]: egress::hdr.udp.src_port if egress::hdr.udp.$valid + # - bit[15..0]: egress::hdr.udp.dst_port if egress::hdr.udp.$valid + TH32: W48(16) # egress::hdr.udp.hdr_length if egress::hdr.udp.$valid + TB23: W48(16) # egress::hdr.udp.checksum.8-15 if egress::hdr.udp.$valid + TB22: W48(16) # egress::hdr.udp.checksum.0-7 if egress::hdr.udp.$valid + TW23: W48(3) + # - bit[31..16]: egress::hdr.tcp.src_port if egress::hdr.tcp.$valid + # - bit[15..0]: egress::hdr.tcp.dst_port if egress::hdr.tcp.$valid + TW30: W48(3) # egress::hdr.tcp.seq_no if egress::hdr.tcp.$valid + TH47: W48(3) # egress::hdr.tcp.ack_no.16-31 if egress::hdr.tcp.$valid + TB28: W48(3) # egress::hdr.tcp.ack_no.8-15 if egress::hdr.tcp.$valid + TB23: W48(3) # egress::hdr.tcp.ack_no.0-7 if egress::hdr.tcp.$valid + TW5: W48(3) + # - bit[31..28]: egress::hdr.tcp.data_offset if egress::hdr.tcp.$valid + # - bit[27..24]: egress::hdr.tcp.res if egress::hdr.tcp.$valid + # - bit[23..16]: egress::hdr.tcp.flags if egress::hdr.tcp.$valid + # - bit[15..0]: egress::hdr.tcp.window if egress::hdr.tcp.$valid + TH32: W48(3) # egress::hdr.tcp.checksum if egress::hdr.tcp.$valid + TB22: W48(3) # egress::hdr.tcp.urgent_ptr.8-15 if egress::hdr.tcp.$valid + TB21: W48(3) # egress::hdr.tcp.urgent_ptr.0-7 if egress::hdr.tcp.$valid + TW5: W48(23) + # - bit[31..24]: egress::hdr.icmp.type_ if egress::hdr.icmp.$valid + # - bit[23..16]: egress::hdr.icmp.code if egress::hdr.icmp.$valid + # - bit[15..0]: egress::hdr.icmp.hdr_checksum if egress::hdr.icmp.$valid + TW5: W48(24) + # - bit[31..16]: egress::hdr.sctp.src_port if egress::hdr.sctp.$valid + # - bit[15..0]: egress::hdr.sctp.dst_port if egress::hdr.sctp.$valid + TW6: W48(24) # egress::hdr.sctp.verifTag if egress::hdr.sctp.$valid + TH8: W48(24) # egress::hdr.sctp.checksum if egress::hdr.sctp.$valid + TW5: W48(21) + # - bit[31..20]: egress::hdr.l2tp.TLxxSxOP if egress::hdr.l2tp.$valid + # - bit[19..16]: egress::hdr.l2tp.version if egress::hdr.l2tp.$valid + # - bit[15..8]: egress::hdr.l2tp.l2tp_length if egress::hdr.l2tp.$valid + # - bit[7..0]: egress::hdr.l2tp.tunnel_id.8-15 if egress::hdr.l2tp.$valid + TB4: W48(21) # egress::hdr.l2tp.tunnel_id.0-7 if egress::hdr.l2tp.$valid + TH34: W48(21) # egress::hdr.l2tp.session_id if egress::hdr.l2tp.$valid + TH33: W48(21) # egress::hdr.l2tp.Ns if egress::hdr.l2tp.$valid + TH8: W48(21) # egress::hdr.l2tp.Nr if egress::hdr.l2tp.$valid + TB21: W48(21) # egress::hdr.l2tp.offset_size if egress::hdr.l2tp.$valid + TB5: W48(21) # egress::hdr.l2tp.offset_pad if egress::hdr.l2tp.$valid + TH9: W48(22) + # - bit[15..12]: egress::hdr.pppoe.version if egress::hdr.pppoe.$valid + # - bit[11..8]: egress::hdr.pppoe.type if egress::hdr.pppoe.$valid + # - bit[7..0]: egress::hdr.pppoe.code if egress::hdr.pppoe.$valid + TH10: W48(22) # egress::hdr.pppoe.session_id if egress::hdr.pppoe.$valid + TW30: W48(22) + # - bit[31..16]: egress::hdr.pppoe.pppoe_length if egress::hdr.pppoe.$valid + # - bit[15..0]: egress::hdr.pppoe.ppp_proto if egress::hdr.pppoe.$valid + TH9: W48(22) + # - bit[15..12]: egress::hdr.pppoe.version if egress::hdr.pppoe.$valid + # - bit[11..8]: egress::hdr.pppoe.type if egress::hdr.pppoe.$valid + # - bit[7..0]: egress::hdr.pppoe.code if egress::hdr.pppoe.$valid + TH10: W48(22) # egress::hdr.pppoe.session_id if egress::hdr.pppoe.$valid + TW30: W48(22) + # - bit[31..16]: egress::hdr.pppoe.pppoe_length if egress::hdr.pppoe.$valid + # - bit[15..0]: egress::hdr.pppoe.ppp_proto if egress::hdr.pppoe.$valid + TH8: W48(25) + # - bit[15]: egress::hdr.gre.C if egress::hdr.gre.$valid + # - bit[14]: egress::hdr.gre.R if egress::hdr.gre.$valid + # - bit[13]: egress::hdr.gre.K if egress::hdr.gre.$valid + # - bit[12]: egress::hdr.gre.S if egress::hdr.gre.$valid + # - bit[11]: egress::hdr.gre.s if egress::hdr.gre.$valid + # - bit[10..8]: egress::hdr.gre.recurse if egress::hdr.gre.$valid + # - bit[7..3]: egress::hdr.gre.flags if egress::hdr.gre.$valid + # - bit[2..0]: egress::hdr.gre.version if egress::hdr.gre.$valid + TB5: W48(25) # egress::hdr.gre.proto.8-15 if egress::hdr.gre.$valid + TB4: W48(25) # egress::hdr.gre.proto.0-7 if egress::hdr.gre.$valid + TH8: W48(19) + # - bit[15..13]: egress::hdr.gtpv1_8b.version if egress::hdr.gtpv1_8b.$valid + # - bit[12]: egress::hdr.gtpv1_8b.pt if egress::hdr.gtpv1_8b.$valid + # - bit[11]: egress::hdr.gtpv1_8b.reserved if egress::hdr.gtpv1_8b.$valid + # - bit[10]: egress::hdr.gtpv1_8b.e if egress::hdr.gtpv1_8b.$valid + # - bit[9]: egress::hdr.gtpv1_8b.s if egress::hdr.gtpv1_8b.$valid + # - bit[8]: egress::hdr.gtpv1_8b.pn if egress::hdr.gtpv1_8b.$valid + # - bit[7..0]: egress::hdr.gtpv1_8b.message_type if egress::hdr.gtpv1_8b.$valid + TH9: W48(19) # egress::hdr.gtpv1_8b.message_len if egress::hdr.gtpv1_8b.$valid + TW5: W48(19) # egress::hdr.gtpv1_8b.teid if egress::hdr.gtpv1_8b.$valid + TH8: W48(20) + # - bit[15..13]: egress::hdr.gtpv1_12b.version if egress::hdr.gtpv1_12b.$valid + # - bit[12]: egress::hdr.gtpv1_12b.pt if egress::hdr.gtpv1_12b.$valid + # - bit[11]: egress::hdr.gtpv1_12b.reserved if egress::hdr.gtpv1_12b.$valid + # - bit[10]: egress::hdr.gtpv1_12b.e if egress::hdr.gtpv1_12b.$valid + # - bit[9]: egress::hdr.gtpv1_12b.s if egress::hdr.gtpv1_12b.$valid + # - bit[8]: egress::hdr.gtpv1_12b.pn if egress::hdr.gtpv1_12b.$valid + # - bit[7..0]: egress::hdr.gtpv1_12b.message_type if egress::hdr.gtpv1_12b.$valid + TH9: W48(20) # egress::hdr.gtpv1_12b.message_len if egress::hdr.gtpv1_12b.$valid + TW30: W48(20) # egress::hdr.gtpv1_12b.teid if egress::hdr.gtpv1_12b.$valid + TW5: W48(20) + # - bit[31..16]: egress::hdr.gtpv1_12b.seq_no if egress::hdr.gtpv1_12b.$valid + # - bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no if egress::hdr.gtpv1_12b.$valid + # - bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t if egress::hdr.gtpv1_12b.$valid + TH8: W48(4) + # - bit[15..13]: egress::hdr.gtpv2_8b.version if egress::hdr.gtpv2_8b.$valid + # - bit[12]: egress::hdr.gtpv2_8b.pb if egress::hdr.gtpv2_8b.$valid + # - bit[11]: egress::hdr.gtpv2_8b.tf if egress::hdr.gtpv2_8b.$valid + # - bit[10..8]: egress::hdr.gtpv2_8b.spare1 if egress::hdr.gtpv2_8b.$valid + # - bit[7..0]: egress::hdr.gtpv2_8b.message_type if egress::hdr.gtpv2_8b.$valid + TH9: W48(4) # egress::hdr.gtpv2_8b.total_len if egress::hdr.gtpv2_8b.$valid + TH34: W48(4) # egress::hdr.gtpv2_8b.seq_no.8-23 if egress::hdr.gtpv2_8b.$valid + TH33: W48(4) + # - bit[15..8]: egress::hdr.gtpv2_8b.seq_no.0-7 if egress::hdr.gtpv2_8b.$valid + # - bit[7..0]: egress::hdr.gtpv2_8b.spare2 if egress::hdr.gtpv2_8b.$valid + TH8: W48(15) + # - bit[15..13]: egress::hdr.gtpv2_12b.version if egress::hdr.gtpv2_12b.$valid + # - bit[12]: egress::hdr.gtpv2_12b.pb if egress::hdr.gtpv2_12b.$valid + # - bit[11]: egress::hdr.gtpv2_12b.tf if egress::hdr.gtpv2_12b.$valid + # - bit[10..8]: egress::hdr.gtpv2_12b.spare1 if egress::hdr.gtpv2_12b.$valid + # - bit[7..0]: egress::hdr.gtpv2_12b.message_type if egress::hdr.gtpv2_12b.$valid + TH9: W48(15) # egress::hdr.gtpv2_12b.total_len if egress::hdr.gtpv2_12b.$valid + W31: W48(15) # egress::hdr.gtpv2_12b.teid if egress::hdr.gtpv2_12b.$valid + TH34: W48(15) # egress::hdr.gtpv2_12b.seq_no.8-23 if egress::hdr.gtpv2_12b.$valid + TH33: W48(15) + # - bit[15..8]: egress::hdr.gtpv2_12b.seq_no.0-7 if egress::hdr.gtpv2_12b.$valid + # - bit[7..0]: egress::hdr.gtpv2_12b.spare2 if egress::hdr.gtpv2_12b.$valid + TB5: W48(6) # egress::hdr.cause_ie_6b.type if egress::hdr.cause_ie_6b.$valid + TW7: W48(6) + # - bit[31..16]: egress::hdr.cause_ie_6b.len if egress::hdr.cause_ie_6b.$valid + # - bit[15..12]: egress::hdr.cause_ie_6b.spare1 if egress::hdr.cause_ie_6b.$valid + # - bit[11..8]: egress::hdr.cause_ie_6b.instance if egress::hdr.cause_ie_6b.$valid + # - bit[7..0]: egress::hdr.cause_ie_6b.cause_value if egress::hdr.cause_ie_6b.$valid + TB4: W48(6) + # - bit[7..3]: egress::hdr.cause_ie_6b.spare2 if egress::hdr.cause_ie_6b.$valid + # - bit[2]: egress::hdr.cause_ie_6b.pce if egress::hdr.cause_ie_6b.$valid + # - bit[1]: egress::hdr.cause_ie_6b.bce if egress::hdr.cause_ie_6b.$valid + # - bit[0]: egress::hdr.cause_ie_6b.cs if egress::hdr.cause_ie_6b.$valid + TB5: W48(7) # egress::hdr.cause_ie_10b.type if egress::hdr.cause_ie_10b.$valid + TW7: W48(7) + # - bit[31..16]: egress::hdr.cause_ie_10b.len if egress::hdr.cause_ie_10b.$valid + # - bit[15..12]: egress::hdr.cause_ie_10b.spare1 if egress::hdr.cause_ie_10b.$valid + # - bit[11..8]: egress::hdr.cause_ie_10b.instance if egress::hdr.cause_ie_10b.$valid + # - bit[7..0]: egress::hdr.cause_ie_10b.cause_value if egress::hdr.cause_ie_10b.$valid + TB4: W48(7) + # - bit[7..3]: egress::hdr.cause_ie_10b.spare2 if egress::hdr.cause_ie_10b.$valid + # - bit[2]: egress::hdr.cause_ie_10b.pce if egress::hdr.cause_ie_10b.$valid + # - bit[1]: egress::hdr.cause_ie_10b.bce if egress::hdr.cause_ie_10b.$valid + # - bit[0]: egress::hdr.cause_ie_10b.cs if egress::hdr.cause_ie_10b.$valid + TH11: W48(7) + # - bit[15..8]: egress::hdr.cause_ie_10b.type_oe if egress::hdr.cause_ie_10b.$valid + # - bit[7..0]: egress::hdr.cause_ie_10b.len_oe.8-15 if egress::hdr.cause_ie_10b.$valid + TH10: W48(7) + # - bit[15..8]: egress::hdr.cause_ie_10b.len_oe.0-7 if egress::hdr.cause_ie_10b.$valid + # - bit[7..4]: egress::hdr.cause_ie_10b.spare_oe if egress::hdr.cause_ie_10b.$valid + # - bit[3..0]: egress::hdr.cause_ie_10b.instance_oe if egress::hdr.cause_ie_10b.$valid + TW6: W48(5) + # - bit[31..24]: egress::hdr.imsi.type if egress::hdr.imsi.$valid + # - bit[23..8]: egress::hdr.imsi.len if egress::hdr.imsi.$valid + # - bit[7..4]: egress::hdr.imsi.spare if egress::hdr.imsi.$valid + # - bit[3..0]: egress::hdr.imsi.instance if egress::hdr.imsi.$valid + TH30: W48(5) # egress::hdr.imsi.num_digit.112-127 if egress::hdr.imsi.$valid + TB29: W48(5) # egress::hdr.imsi.num_digit.104-111 if egress::hdr.imsi.$valid + TB20: W48(5) # egress::hdr.imsi.num_digit.96-103 if egress::hdr.imsi.$valid + TW29: W48(5) # egress::hdr.imsi.num_digit.64-95 if egress::hdr.imsi.$valid + TW28: W48(5) # egress::hdr.imsi.num_digit.32-63 if egress::hdr.imsi.$valid + TW21: W48(5) # egress::hdr.imsi.num_digit.0-31 if egress::hdr.imsi.$valid + TW5: W48(17) + # - bit[31..24]: egress::hdr.vxlan.flags if egress::hdr.vxlan.$valid + # - bit[23..0]: egress::hdr.vxlan.reserved if egress::hdr.vxlan.$valid + TH9: W48(17) # egress::hdr.vxlan.vni.8-23 if egress::hdr.vxlan.$valid + TH8: W48(17) + # - bit[15..8]: egress::hdr.vxlan.vni.0-7 if egress::hdr.vxlan.$valid + # - bit[7..0]: egress::hdr.vxlan.reserved2 if egress::hdr.vxlan.$valid + TW30: W48(18) # egress::hdr.inner_ethernet.dst_addr.16-47 if egress::hdr.inner_ethernet.$valid + TB5: W48(18) # egress::hdr.inner_ethernet.dst_addr.8-15 if egress::hdr.inner_ethernet.$valid + TB4: W48(18) # egress::hdr.inner_ethernet.dst_addr.0-7 if egress::hdr.inner_ethernet.$valid + TH47: W48(18) # egress::hdr.inner_ethernet.src_addr.32-47 if egress::hdr.inner_ethernet.$valid + TH34: W48(18) # egress::hdr.inner_ethernet.src_addr.16-31 if egress::hdr.inner_ethernet.$valid + TH33: W48(18) # egress::hdr.inner_ethernet.src_addr.0-15 if egress::hdr.inner_ethernet.$valid + TH10: W48(18) # egress::hdr.inner_ethernet.ether_type if egress::hdr.inner_ethernet.$valid + TW6: W48(8) + # - bit[31..28]: egress::hdr.inner_ipv4.version if egress::hdr.inner_ipv4.$valid + # - bit[27..24]: egress::hdr.inner_ipv4.ihl if egress::hdr.inner_ipv4.$valid + # - bit[23..16]: egress::hdr.inner_ipv4.diffserv if egress::hdr.inner_ipv4.$valid + # - bit[15..0]: egress::hdr.inner_ipv4.total_len if egress::hdr.inner_ipv4.$valid + TH30: W48(8) # egress::hdr.inner_ipv4.identification if egress::hdr.inner_ipv4.$valid + TH11: W48(8) + # - bit[15..13]: egress::hdr.inner_ipv4.flags if egress::hdr.inner_ipv4.$valid + # - bit[12..0]: egress::hdr.inner_ipv4.frag_offset if egress::hdr.inner_ipv4.$valid + TW21: W48(8) + # - bit[31..24]: egress::hdr.inner_ipv4.ttl if egress::hdr.inner_ipv4.$valid + # - bit[23..16]: egress::hdr.inner_ipv4.protocol if egress::hdr.inner_ipv4.$valid + # - bit[15..0]: egress::hdr.inner_ipv4.hdr_checksum if egress::hdr.inner_ipv4.$valid + TB31: W48(8) # egress::hdr.inner_ipv4.src_addr.24-31 if egress::hdr.inner_ipv4.$valid + TB30: W48(8) # egress::hdr.inner_ipv4.src_addr.16-23 if egress::hdr.inner_ipv4.$valid + TB29: W48(8) # egress::hdr.inner_ipv4.src_addr.8-15 if egress::hdr.inner_ipv4.$valid + TB20: W48(8) # egress::hdr.inner_ipv4.src_addr.0-7 if egress::hdr.inner_ipv4.$valid + W18: W48(8) # egress::hdr.inner_ipv4.dst_addr if egress::hdr.inner_ipv4.$valid + TW6: W48(14) + # - bit[31..28]: egress::hdr.inner_ipv6.version if egress::hdr.inner_ipv6.$valid + # - bit[27..20]: egress::hdr.inner_ipv6.traffic_class if egress::hdr.inner_ipv6.$valid + # - bit[19..0]: egress::hdr.inner_ipv6.flow_label if egress::hdr.inner_ipv6.$valid + TH11: W48(14) # egress::hdr.inner_ipv6.payload_len if egress::hdr.inner_ipv6.$valid + B19: W48(14) # egress::hdr.inner_ipv6.next_hdr if egress::hdr.inner_ipv6.$valid + TB20: W48(14) # egress::hdr.inner_ipv6.hop_limit if egress::hdr.inner_ipv6.$valid + W26: W48(14) # egress::hdr.inner_ipv6.src_addr.96-127 if egress::hdr.inner_ipv6.$valid + W25: W48(14) # egress::hdr.inner_ipv6.src_addr.64-95 if egress::hdr.inner_ipv6.$valid + W24: W48(14) # egress::hdr.inner_ipv6.src_addr.32-63 if egress::hdr.inner_ipv6.$valid + W18: W48(14) # egress::hdr.inner_ipv6.src_addr.0-31 if egress::hdr.inner_ipv6.$valid + W30: W48(14) # egress::hdr.inner_ipv6.dst_addr.96-127 if egress::hdr.inner_ipv6.$valid + W29: W48(14) # egress::hdr.inner_ipv6.dst_addr.64-95 if egress::hdr.inner_ipv6.$valid + W28: W48(14) # egress::hdr.inner_ipv6.dst_addr.32-63 if egress::hdr.inner_ipv6.$valid + W27: W48(14) # egress::hdr.inner_ipv6.dst_addr.0-31 if egress::hdr.inner_ipv6.$valid + TW7: W48(11) + # - bit[31..16]: egress::hdr.inner_udp.src_port if egress::hdr.inner_udp.$valid + # - bit[15..0]: egress::hdr.inner_udp.dst_port if egress::hdr.inner_udp.$valid + TW28: W48(11) + # - bit[31..16]: egress::hdr.inner_udp.hdr_length if egress::hdr.inner_udp.$valid + # - bit[15..0]: egress::hdr.inner_udp.checksum if egress::hdr.inner_udp.$valid + TW28: W48(9) + # - bit[31..16]: egress::hdr.inner_tcp.src_port if egress::hdr.inner_tcp.$valid + # - bit[15..0]: egress::hdr.inner_tcp.dst_port if egress::hdr.inner_tcp.$valid + W19: W48(9) # egress::hdr.inner_tcp.seq_no if egress::hdr.inner_tcp.$valid + W20: W48(9) # egress::hdr.inner_tcp.ack_no if egress::hdr.inner_tcp.$valid + TW7: W48(9) + # - bit[31..28]: egress::hdr.inner_tcp.data_offset if egress::hdr.inner_tcp.$valid + # - bit[27..24]: egress::hdr.inner_tcp.res if egress::hdr.inner_tcp.$valid + # - bit[23..16]: egress::hdr.inner_tcp.flags if egress::hdr.inner_tcp.$valid + # - bit[15..0]: egress::hdr.inner_tcp.window if egress::hdr.inner_tcp.$valid + TW29: W48(9) + # - bit[31..16]: egress::hdr.inner_tcp.checksum if egress::hdr.inner_tcp.$valid + # - bit[15..0]: egress::hdr.inner_tcp.urgent_ptr if egress::hdr.inner_tcp.$valid + TW7: W48(12) + # - bit[31..24]: egress::hdr.inner_icmp.type_ if egress::hdr.inner_icmp.$valid + # - bit[23..16]: egress::hdr.inner_icmp.code if egress::hdr.inner_icmp.$valid + # - bit[15..0]: egress::hdr.inner_icmp.hdr_checksum if egress::hdr.inner_icmp.$valid + W22: W48(13) # egress::hdr.ipsec_esp.spi if egress::hdr.ipsec_esp.$valid + W23: W48(13) # egress::hdr.ipsec_esp.sn if egress::hdr.ipsec_esp.$valid + W21: W48(10) # egress::hdr.sip.data if egress::hdr.sip.$valid + egress_unicast_port: H16(0..8) # bit[8..0]: egress::eg_intr_md.egress_port +stage 0 ingress: + dependency: match + phase0_match IgParser_inner_2.$PORT_METADATA: + p4: + name: IgParser_inner_2.$PORT_METADATA + size: 288 + preferred_match_type: exact + match_type: exact + size: 288 + p4_param_order: + ig_intr_md.ingress_port: { type: exact, size: 9 } + format: {ig_port_type: 56..58} + constant_value: 0 + actions: + set_port_metadata: + - handle: 0x20020000 + - p4_param_order: { ig_port_type: 3 } + hash_action tbl_compute_ip_hash 0: + p4: { name: tbl_compute_ip_hash, hidden: true } + row: 0 + bus: 0 + hash_dist: + 0: { hash: 0, mask: 0xffff, shift: 0 } + 1: { hash: 0, mask: 0xffff, shift: 0 } + input_xbar: + exact group 0: { 0: ig_md.lkp.ip_src_addr.0-31, 32: ig_md.lkp.ip_src_addr.32-63, 64: ig_md.lkp.ip_src_addr.64-95, 96: ig_md.lkp.ip_src_addr.96-127 } + exact group 1: { 0: ig_md.lkp.ip_dst_addr.0-31, 32: ig_md.lkp.ip_dst_addr.32-63, 64: ig_md.lkp.ip_dst_addr.64-95, 96: ig_md.lkp.ip_dst_addr.96-127 } + exact group 2: { 0: ig_md.lkp.l4_dst_port, 16: ig_md.lkp.l4_src_port, 32: ig_md.lkp.ip_proto } + hash 0: + 0..15: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 168: ig_md.lkp.ip_src_addr.0-31, 200: ig_md.lkp.ip_src_addr.32-63 }, { })), 0..15) + hash 1: + 0..15: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 232: ig_md.lkp.ip_src_addr.64-95, 264: ig_md.lkp.ip_src_addr.96-127 }, { })), 0..15) + hash 2: + 0..15: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 40: ig_md.lkp.ip_dst_addr.0-31, 72: ig_md.lkp.ip_dst_addr.32-63 }, { })), 0..15) + hash 3: + 0..15: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 104: ig_md.lkp.ip_dst_addr.64-95, 136: ig_md.lkp.ip_dst_addr.96-127 }, { })), 0..15) + hash 4: + 0..15: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 0: ig_md.lkp.l4_src_port, 16: ig_md.lkp.l4_dst_port, 32: ig_md.lkp.ip_proto }, { })), 0..15) + hash group 0: + table: [0, 1, 2, 3, 4] + seed: 0x7f64 + exact group 0: { 0: ig_md.lkp.ip_src_addr.0-31, 32: ig_md.lkp.ip_src_addr.32-63, 64: ig_md.lkp.ip_src_addr.64-95, 96: ig_md.lkp.ip_src_addr.96-127 } + exact group 1: { 0: ig_md.lkp.ip_dst_addr.0-31, 32: ig_md.lkp.ip_dst_addr.32-63, 64: ig_md.lkp.ip_dst_addr.64-95, 96: ig_md.lkp.ip_dst_addr.96-127 } + exact group 2: { 0: ig_md.lkp.l4_dst_port, 16: ig_md.lkp.l4_src_port, 32: ig_md.lkp.ip_proto } + hash 0: + 16..31: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 168: ig_md.lkp.ip_src_addr.0-31, 200: ig_md.lkp.ip_src_addr.32-63 }, { })), 16..31) + hash 1: + 16..31: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 232: ig_md.lkp.ip_src_addr.64-95, 264: ig_md.lkp.ip_src_addr.96-127 }, { })), 16..31) + hash 2: + 16..31: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 40: ig_md.lkp.ip_dst_addr.0-31, 72: ig_md.lkp.ip_dst_addr.32-63 }, { })), 16..31) + hash 3: + 16..31: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 104: ig_md.lkp.ip_dst_addr.64-95, 136: ig_md.lkp.ip_dst_addr.96-127 }, { })), 16..31) + hash 4: + 16..31: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 0: ig_md.lkp.l4_src_port, 16: ig_md.lkp.l4_dst_port, 32: ig_md.lkp.ip_proto }, { })), 16..31) + hash group 0: + table: [0, 1, 2, 3, 4] + seed: 0x24d10000 + gateway: + name: tbl_compute_ip_hash-gateway + row: 2 + bus: 0 + unit: 1 + 0x0: cond-73 + miss: cond-73 + condition: + expression: "true(always hit)" + true: cond-73 + false: cond-73 + next: [] + action_bus: { 96..99 : hash_dist(0, 1) } + instruction: tbl_compute_ip_hash($DEFAULT, $DEFAULT) + actions: + compute_ip_hash(0, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000015 + - next_table: 0 + - set W2, hash_dist(0, 1, 0..31) + default_action: compute_ip_hash + gateway cond-73 1: + name: cond-73 + input_xbar: + exact group 2: { 64: ig_md.in_ig_port_type } + row: 4 + bus: 1 + unit: 0 + match: { 0: ig_md.in_ig_port_type } + 0b*****010: cn78_decap_inner_fabric_bfn_from_cn78 + miss: tbl_network_tap331 + condition: + expression: "(ig_md.in_ig_port_type == 2)" + true: cn78_decap_inner_fabric_bfn_from_cn78 + false: tbl_network_tap331 + ternary_match cn78_decap_inner_fabric_bfn_from_cn78 2: + p4: { name: Ig_inner_2.cn78_decap_inner.fabric_bfn_from_cn78, size: 1024 } + gateway: + name: cond-74 + input_xbar: + exact group 2: { 92: hdr.fabric_from_cn78.$valid } + row: 3 + bus: 1 + unit: 0 + match: { 4: hdr.fabric_from_cn78.$valid } + 0b***1: run_table + miss: cn78_decap_inner_handle_from_cn78_normal + condition: + expression: "(hdr.fabric_from_cn78.$valid == 1)" + true: cn78_decap_inner_fabric_bfn_from_cn78 + false: cn78_decap_inner_handle_from_cn78_normal + hit: [ cn78_decap_inner_handle_from_cn78_normal ] + miss: cn78_decap_inner_handle_from_cn78_normal + indirect: cn78_decap_inner_fabric_bfn_from_cn78$tind + ternary_indirect cn78_decap_inner_fabric_bfn_from_cn78$tind: + row: 1 + bus: 1 + format: { action: 0..0 } + instruction: cn78_decap_inner_fabric_bfn_from_cn78$tind(action, $DEFAULT) + actions: + Ig_inner_2.cn78_decap_inner.terminate_from_cn78_and_add_fabric(1, 2): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000001 + - next_table: 0 + - set hdr.fabric.$valid, 1 + - set hdr.ethernet.ether_type, 33278 + - set hdr.fabric.mc_index, 0 + - set hdr.fabric.is_hdr_decap, 0 + - set hdr.fabric.is_trunc_mir, 0 + - set ig_md.action_type, hdr.fabric_from_cn78.action_type + - set ig_md.port_group_id, hdr.fabric_from_cn78.port_group_id + - deposit-field W4(16..31), 0, W3 + default_action: Ig_inner_2.cn78_decap_inner.terminate_from_cn78_and_add_fabric + ternary_match tbl_network_tap331 3: + p4: { name: tbl_network_tap331 } + gateway: + name: cond-75 + input_xbar: + exact group 2: { 64: ig_md.in_ig_port_type } + row: 2 + bus: 1 + unit: 0 + match: { 0: ig_md.in_ig_port_type } + 0b*****011: run_table + miss: in_ipv6_t_acl$st0 + condition: + expression: "(ig_md.in_ig_port_type == 3)" + true: tbl_network_tap331 + false: in_ipv6_t_acl$st0 + hit: [ ip_hdr_location_locate ] + miss: ip_hdr_location_locate + indirect: tbl_network_tap331$tind + ternary_indirect tbl_network_tap331$tind: + row: 1 + bus: 0 + format: { action: 0..0 } + instruction: tbl_network_tap331$tind(action, $DEFAULT) + actions: + network_tap331(1, 3): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000007 + - next_table: 0 + - set ig_intr_md_for_tm.bypass_egress, 1 + default_action: network_tap331 + ternary_match in_ipv6_t_acl$st0 4: + p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } + hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } + ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } + ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } + hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } + row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + match: + - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } + - { group: 1, byte_config: 3, dirtcam: 0x155 } + - { group: 2, dirtcam: 0x155 } + - { group: 3, dirtcam: 0x155 } + - { group: 4, dirtcam: 0x155 } + - { group: 5, dirtcam: 0x155 } + - { group: 6, dirtcam: 0x155 } + - { group: 7, dirtcam: 0x55 } + gateway: + name: cond-76 + input_xbar: + exact group 2: { 78: hdr.inner_ipv6.$valid, 84: hdr.vlan_tag$0.$valid, 120: hdr.fabric.ig_port_type } + row: 1 + bus: 1 + unit: 1 + match: { 0: hdr.fabric.ig_port_type, 12: hdr.vlan_tag$0.$valid, 22: hdr.inner_ipv6.$valid } + 0b*1*********1*********001: run_table + miss: ip_hdr_location_locate + condition: + expression: "(hdr.fabric.ig_port_type == 1 && hdr.vlan_tag[0].$valid == 1 && hdr.inner_ipv6.$valid == 1)" + true: in_ipv6_t_acl$st0 + false: ip_hdr_location_locate + hit: [ ip_hdr_location_locate ] + miss: in_ipv6_t_acl$st1 + indirect: in_ipv6_t_acl$st0$tind + ternary_indirect in_ipv6_t_acl$st0$tind: + row: 0 + bus: 0 + column: 2 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + format: { action: 0..5 } + action: in_ipv6_t_acl$st0$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_t_acl$st0$tind(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000008 + - next_table: 0 + - { } + Ig_inner_2.in_ipv6_t.drop(4, 4): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000009 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.drop_and_count(6, 6): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000a + - next_table: 0 + - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - bitmasked-set B4, $data0, B4 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.redirect_port(8, 8): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000b + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.redirect_port_and_count(10, 10): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000c + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_to_eg(12, 12): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000d + - next_table: 0 + - { } + - set W5(29..30), 3 + Ig_inner_2.in_ipv6_t.forward_and_modify_mac(14, 14): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000e + - next_table: 0 + - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(16, 16): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000f + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.set_mc(18, 18): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000010 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } + - set hdr.fabric.mc_index, mc_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir(20, 20): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000011 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(22, 22): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000012 + - next_table: 0 + - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set B4(0..2), $data0 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(24, 24): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000013 + - next_table: 0 + - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(26, 26): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000014 + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + default_action: NoAction + action in_ipv6_t_acl$st0$action_data: + p4: { name: Ig_inner_2.in_ipv6_t.acl$action } + row: 3 + column: 0 + vpns: [ 0 ] + home_row: + - 3 + format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } + format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 104..107 : $adf_f2, 108..111 : $adf_f3, 112..115 : $adf_f0, 116..119 : $adf_f1 } +stage 1 ingress: + dependency: match + exact_match cn78_decap_inner_handle_from_cn78_normal 1: + p4: { name: Ig_inner_2.cn78_decap_inner.handle_from_cn78_normal, size: 1024 } + p4_param_order: + ig_md.action_type: { type: exact, size: 8, full_size: 8 } + row: 4 + search_bus: 1 + result_bus: 0 + column: 11 + stash: + row: [ 4 ] + col: [ 11 ] + unit: [ 0 ] + ways: + - [0, 0, 0x0, [4, 11]] + input_xbar: + exact group 0: { 13: ig_md.action_type } + hash 0: + 0..2: ig_md.action_type(0..2) + 3..7: ig_md.action_type(3..7) + hash group 0: + table: [0] + seed: 0x0 + format: { action(0): 0..2, version(0): 112..115 } + match_group_map: [ [ 0 ] ] + hit: [ ip_hdr_location_locate ] + miss: ip_hdr_location_locate + action: cn78_decap_inner_handle_from_cn78_normal$action_data($DIRECT, $DEFAULT) + instruction: cn78_decap_inner_handle_from_cn78_normal(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000002 + - next_table: 0 + - { } + Ig_inner_2.cn78_decap_inner.set_duplication(1, 24): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000003 + - next_table: 0 + - { } + - set hdr.fabric.is_hit, 1 + - set hdr.fabric.mc_index, ig_md.port_group_id + Ig_inner_2.cn78_decap_inner.set_redirect(2, 26): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000004 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, ig_md.port_group_id + - bitmasked-set W5, $data0, W5 + Ig_inner_2.cn78_decap_inner.set_hdr_decap(3, 28): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000005 + - next_table: 0 + - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } + - bitmasked-set W5, $data0, W5 + Ig_inner_2.cn78_decap_inner.set_trunc_mir(4, 30): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000006 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W5, $data0, W5 + default_action: NoAction + action cn78_decap_inner_handle_from_cn78_normal$action_data: + p4: { name: Ig_inner_2.cn78_decap_inner.handle_from_cn78_normal$action } + row: 3 + column: 0 + vpns: [ 0 ] + home_row: + - 3 + format Ig_inner_2.cn78_decap_inner.set_redirect: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Ig_inner_2.cn78_decap_inner.set_hdr_decap: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Ig_inner_2.cn78_decap_inner.set_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63 } + action_bus: { 112..115 : $adf_f0, 116..119 : $adf_f1 } + ternary_match in_ipv6_t_acl$st1 0: + p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } + hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } + ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } + ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } + hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } + row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + match: + - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } + - { group: 1, byte_config: 3, dirtcam: 0x155 } + - { group: 2, dirtcam: 0x155 } + - { group: 3, dirtcam: 0x155 } + - { group: 4, dirtcam: 0x155 } + - { group: 5, dirtcam: 0x155 } + - { group: 6, dirtcam: 0x155 } + - { group: 7, dirtcam: 0x55 } + hit: [ ip_hdr_location_locate ] + miss: in_ipv6_t_acl$st2 + indirect: in_ipv6_t_acl$st1$tind + ternary_indirect in_ipv6_t_acl$st1$tind: + row: 0 + bus: 0 + column: 2 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + format: { action: 0..5 } + action: in_ipv6_t_acl$st1$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_t_acl$st1$tind(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000008 + - next_table: 0 + - { } + Ig_inner_2.in_ipv6_t.drop(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000009 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.drop_and_count(2, 2): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000a + - next_table: 0 + - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - bitmasked-set B4, $data0, B4 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.redirect_port(4, 4): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000b + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.redirect_port_and_count(6, 6): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000c + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_to_eg(8, 8): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000d + - next_table: 0 + - { } + - set W5(29..30), 3 + Ig_inner_2.in_ipv6_t.forward_and_modify_mac(10, 10): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000e + - next_table: 0 + - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000f + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.set_mc(14, 14): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000010 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } + - set hdr.fabric.mc_index, mc_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir(16, 16): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000011 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(18, 18): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000012 + - next_table: 0 + - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set B4(0..2), $data0 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(20, 20): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000013 + - next_table: 0 + - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(22, 22): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000014 + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + default_action: NoAction + action in_ipv6_t_acl$st1$action_data: + p4: { name: Ig_inner_2.in_ipv6_t.acl$action } + row: 2 + column: 2 + vpns: [ 0 ] + home_row: + - 2 + format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } + format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } +stage 2 ingress: + dependency: match + ternary_match in_ipv6_t_acl$st2 0: + p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } + hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } + ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } + ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } + hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } + row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + match: + - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } + - { group: 1, byte_config: 3, dirtcam: 0x155 } + - { group: 2, dirtcam: 0x155 } + - { group: 3, dirtcam: 0x155 } + - { group: 4, dirtcam: 0x155 } + - { group: 5, dirtcam: 0x155 } + - { group: 6, dirtcam: 0x155 } + - { group: 7, dirtcam: 0x55 } + hit: [ ip_hdr_location_locate ] + miss: in_ipv6_t_acl$st3 + indirect: in_ipv6_t_acl$st2$tind + ternary_indirect in_ipv6_t_acl$st2$tind: + row: 0 + bus: 0 + column: 2 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + format: { action: 0..5 } + action: in_ipv6_t_acl$st2$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_t_acl$st2$tind(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000008 + - next_table: 0 + - { } + Ig_inner_2.in_ipv6_t.drop(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000009 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.drop_and_count(2, 2): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000a + - next_table: 0 + - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - bitmasked-set B4, $data0, B4 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.redirect_port(4, 4): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000b + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.redirect_port_and_count(6, 6): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000c + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_to_eg(8, 8): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000d + - next_table: 0 + - { } + - set W5(29..30), 3 + Ig_inner_2.in_ipv6_t.forward_and_modify_mac(10, 10): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000e + - next_table: 0 + - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000f + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.set_mc(14, 14): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000010 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } + - set hdr.fabric.mc_index, mc_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir(16, 16): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000011 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(18, 18): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000012 + - next_table: 0 + - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set B4(0..2), $data0 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(20, 20): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000013 + - next_table: 0 + - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(22, 22): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000014 + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + default_action: NoAction + action in_ipv6_t_acl$st2$action_data: + p4: { name: Ig_inner_2.in_ipv6_t.acl$action } + row: 3 + column: 0 + vpns: [ 0 ] + home_row: + - 3 + format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } + format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } +stage 3 ingress: + dependency: match + ternary_match in_ipv6_t_acl$st3 0: + p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } + hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } + ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } + ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } + hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } + row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + match: + - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } + - { group: 1, byte_config: 3, dirtcam: 0x155 } + - { group: 2, dirtcam: 0x155 } + - { group: 3, dirtcam: 0x155 } + - { group: 4, dirtcam: 0x155 } + - { group: 5, dirtcam: 0x155 } + - { group: 6, dirtcam: 0x155 } + - { group: 7, dirtcam: 0x55 } + hit: [ ip_hdr_location_locate ] + miss: in_ipv6_t_acl$st4 + indirect: in_ipv6_t_acl$st3$tind + ternary_indirect in_ipv6_t_acl$st3$tind: + row: 0 + bus: 0 + column: 2 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + format: { action: 0..5 } + action: in_ipv6_t_acl$st3$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_t_acl$st3$tind(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000008 + - next_table: 0 + - { } + Ig_inner_2.in_ipv6_t.drop(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000009 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.drop_and_count(2, 2): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000a + - next_table: 0 + - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - bitmasked-set B4, $data0, B4 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.redirect_port(4, 4): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000b + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.redirect_port_and_count(6, 6): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000c + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_to_eg(8, 8): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000d + - next_table: 0 + - { } + - set W5(29..30), 3 + Ig_inner_2.in_ipv6_t.forward_and_modify_mac(10, 10): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000e + - next_table: 0 + - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000f + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.set_mc(14, 14): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000010 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } + - set hdr.fabric.mc_index, mc_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir(16, 16): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000011 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(18, 18): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000012 + - next_table: 0 + - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set B4(0..2), $data0 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(20, 20): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000013 + - next_table: 0 + - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(22, 22): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000014 + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + default_action: NoAction + action in_ipv6_t_acl$st3$action_data: + p4: { name: Ig_inner_2.in_ipv6_t.acl$action } + row: 3 + column: 0 + vpns: [ 0 ] + home_row: + - 3 + format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } + format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } +stage 4 ingress: + dependency: match + ternary_match in_ipv6_t_acl$st4 0: + p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } + hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } + ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } + ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } + hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } + row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + match: + - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } + - { group: 1, byte_config: 3, dirtcam: 0x155 } + - { group: 2, dirtcam: 0x155 } + - { group: 3, dirtcam: 0x155 } + - { group: 4, dirtcam: 0x155 } + - { group: 5, dirtcam: 0x155 } + - { group: 6, dirtcam: 0x155 } + - { group: 7, dirtcam: 0x55 } + hit: [ ip_hdr_location_locate ] + miss: in_ipv6_t_acl$st5 + indirect: in_ipv6_t_acl$st4$tind + ternary_indirect in_ipv6_t_acl$st4$tind: + row: 0 + bus: 0 + column: 2 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + format: { action: 0..5 } + action: in_ipv6_t_acl$st4$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_t_acl$st4$tind(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000008 + - next_table: 0 + - { } + Ig_inner_2.in_ipv6_t.drop(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000009 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.drop_and_count(2, 2): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000a + - next_table: 0 + - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - bitmasked-set B4, $data0, B4 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.redirect_port(4, 4): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000b + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.redirect_port_and_count(6, 6): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000c + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_to_eg(8, 8): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000d + - next_table: 0 + - { } + - set W5(29..30), 3 + Ig_inner_2.in_ipv6_t.forward_and_modify_mac(10, 10): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000e + - next_table: 0 + - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000f + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.set_mc(14, 14): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000010 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } + - set hdr.fabric.mc_index, mc_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir(16, 16): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000011 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(18, 18): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000012 + - next_table: 0 + - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set B4(0..2), $data0 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(20, 20): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000013 + - next_table: 0 + - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(22, 22): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000014 + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + default_action: NoAction + action in_ipv6_t_acl$st4$action_data: + p4: { name: Ig_inner_2.in_ipv6_t.acl$action } + row: 3 + column: 0 + vpns: [ 0 ] + home_row: + - 3 + format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } + format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } +stage 5 ingress: + dependency: match + ternary_match in_ipv6_t_acl$st5 0: + p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } + hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } + ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } + ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } + hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } + row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + match: + - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } + - { group: 1, byte_config: 3, dirtcam: 0x155 } + - { group: 2, dirtcam: 0x155 } + - { group: 3, dirtcam: 0x155 } + - { group: 4, dirtcam: 0x155 } + - { group: 5, dirtcam: 0x155 } + - { group: 6, dirtcam: 0x155 } + - { group: 7, dirtcam: 0x55 } + hit: [ ip_hdr_location_locate ] + miss: in_ipv6_t_acl$st6 + indirect: in_ipv6_t_acl$st5$tind + ternary_indirect in_ipv6_t_acl$st5$tind: + row: 0 + bus: 0 + column: 2 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + format: { action: 0..5 } + action: in_ipv6_t_acl$st5$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_t_acl$st5$tind(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000008 + - next_table: 0 + - { } + Ig_inner_2.in_ipv6_t.drop(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000009 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.drop_and_count(2, 2): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000a + - next_table: 0 + - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - bitmasked-set B4, $data0, B4 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.redirect_port(4, 4): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000b + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.redirect_port_and_count(6, 6): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000c + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_to_eg(8, 8): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000d + - next_table: 0 + - { } + - set W5(29..30), 3 + Ig_inner_2.in_ipv6_t.forward_and_modify_mac(10, 10): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000e + - next_table: 0 + - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000f + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.set_mc(14, 14): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000010 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } + - set hdr.fabric.mc_index, mc_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir(16, 16): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000011 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(18, 18): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000012 + - next_table: 0 + - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set B4(0..2), $data0 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(20, 20): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000013 + - next_table: 0 + - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(22, 22): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000014 + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + default_action: NoAction + action in_ipv6_t_acl$st5$action_data: + p4: { name: Ig_inner_2.in_ipv6_t.acl$action } + row: 3 + column: 0 + vpns: [ 0 ] + home_row: + - 3 + format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } + format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } +stage 6 ingress: + dependency: match + ternary_match in_ipv6_t_acl$st6 0: + p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } + hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } + ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } + ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } + hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } + row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + match: + - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } + - { group: 1, byte_config: 3, dirtcam: 0x155 } + - { group: 2, dirtcam: 0x155 } + - { group: 3, dirtcam: 0x155 } + - { group: 4, dirtcam: 0x155 } + - { group: 5, dirtcam: 0x155 } + - { group: 6, dirtcam: 0x155 } + - { group: 7, dirtcam: 0x55 } + hit: [ ip_hdr_location_locate ] + miss: in_ipv6_t_acl$st7 + indirect: in_ipv6_t_acl$st6$tind + ternary_indirect in_ipv6_t_acl$st6$tind: + row: 0 + bus: 0 + column: 2 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + format: { action: 0..5 } + action: in_ipv6_t_acl$st6$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_t_acl$st6$tind(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000008 + - next_table: 0 + - { } + Ig_inner_2.in_ipv6_t.drop(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000009 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.drop_and_count(2, 2): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000a + - next_table: 0 + - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - bitmasked-set B4, $data0, B4 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.redirect_port(4, 4): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000b + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.redirect_port_and_count(6, 6): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000c + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_to_eg(8, 8): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000d + - next_table: 0 + - { } + - set W5(29..30), 3 + Ig_inner_2.in_ipv6_t.forward_and_modify_mac(10, 10): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000e + - next_table: 0 + - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000f + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.set_mc(14, 14): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000010 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } + - set hdr.fabric.mc_index, mc_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir(16, 16): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000011 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(18, 18): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000012 + - next_table: 0 + - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set B4(0..2), $data0 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(20, 20): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000013 + - next_table: 0 + - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(22, 22): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000014 + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + default_action: NoAction + action in_ipv6_t_acl$st6$action_data: + p4: { name: Ig_inner_2.in_ipv6_t.acl$action } + row: 3 + column: 0 + vpns: [ 0 ] + home_row: + - 3 + format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } + format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } +stage 7 ingress: + dependency: match + ternary_match in_ipv6_t_acl$st7 0: + p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } + hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } + ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } + ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } + hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } + row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + match: + - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } + - { group: 1, byte_config: 3, dirtcam: 0x155 } + - { group: 2, dirtcam: 0x155 } + - { group: 3, dirtcam: 0x155 } + - { group: 4, dirtcam: 0x155 } + - { group: 5, dirtcam: 0x155 } + - { group: 6, dirtcam: 0x155 } + - { group: 7, dirtcam: 0x55 } + hit: [ ip_hdr_location_locate ] + miss: in_ipv6_t_acl$st8 + indirect: in_ipv6_t_acl$st7$tind + ternary_indirect in_ipv6_t_acl$st7$tind: + row: 0 + bus: 0 + column: 2 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + format: { action: 0..5 } + action: in_ipv6_t_acl$st7$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_t_acl$st7$tind(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000008 + - next_table: 0 + - { } + Ig_inner_2.in_ipv6_t.drop(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000009 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.drop_and_count(2, 2): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000a + - next_table: 0 + - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - bitmasked-set B4, $data0, B4 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.redirect_port(4, 4): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000b + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.redirect_port_and_count(6, 6): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000c + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_to_eg(8, 8): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000d + - next_table: 0 + - { } + - set W5(29..30), 3 + Ig_inner_2.in_ipv6_t.forward_and_modify_mac(10, 10): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000e + - next_table: 0 + - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000f + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.set_mc(14, 14): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000010 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } + - set hdr.fabric.mc_index, mc_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir(16, 16): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000011 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(18, 18): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000012 + - next_table: 0 + - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set B4(0..2), $data0 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(20, 20): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000013 + - next_table: 0 + - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(22, 22): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000014 + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + default_action: NoAction + action in_ipv6_t_acl$st7$action_data: + p4: { name: Ig_inner_2.in_ipv6_t.acl$action } + row: 3 + column: 0 + vpns: [ 0 ] + home_row: + - 3 + format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } + format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } +stage 8 ingress: + dependency: match + ternary_match in_ipv6_t_acl$st8 0: + p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } + hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } + ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } + ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } + hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } + row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + match: + - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } + - { group: 1, byte_config: 3, dirtcam: 0x155 } + - { group: 2, dirtcam: 0x155 } + - { group: 3, dirtcam: 0x155 } + - { group: 4, dirtcam: 0x155 } + - { group: 5, dirtcam: 0x155 } + - { group: 6, dirtcam: 0x155 } + - { group: 7, dirtcam: 0x55 } + hit: [ ip_hdr_location_locate ] + miss: in_ipv6_t_acl$st9 + indirect: in_ipv6_t_acl$st8$tind + ternary_indirect in_ipv6_t_acl$st8$tind: + row: 0 + bus: 0 + column: 4 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + format: { action: 0..5 } + action: in_ipv6_t_acl$st8$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_t_acl$st8$tind(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000008 + - next_table: 0 + - { } + Ig_inner_2.in_ipv6_t.drop(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000009 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.drop_and_count(2, 2): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000a + - next_table: 0 + - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - bitmasked-set B4, $data0, B4 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.redirect_port(4, 4): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000b + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.redirect_port_and_count(6, 6): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000c + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_to_eg(8, 8): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000d + - next_table: 0 + - { } + - set W5(29..30), 3 + Ig_inner_2.in_ipv6_t.forward_and_modify_mac(10, 10): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000e + - next_table: 0 + - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000f + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.set_mc(14, 14): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000010 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } + - set hdr.fabric.mc_index, mc_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir(16, 16): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000011 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(18, 18): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000012 + - next_table: 0 + - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set B4(0..2), $data0 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(20, 20): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000013 + - next_table: 0 + - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(22, 22): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000014 + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + default_action: NoAction + action in_ipv6_t_acl$st8$action_data: + p4: { name: Ig_inner_2.in_ipv6_t.acl$action } + row: 14 + column: 4 + vpns: [ 0 ] + home_row: + - 14 + format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } + format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } +stage 9 ingress: + dependency: match + ternary_match in_ipv6_t_acl$st9 0: + p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } + hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } + ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } + ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } + hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } + row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + match: + - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } + - { group: 1, byte_config: 3, dirtcam: 0x155 } + - { group: 2, dirtcam: 0x155 } + - { group: 3, dirtcam: 0x155 } + - { group: 4, dirtcam: 0x155 } + - { group: 5, dirtcam: 0x155 } + - { group: 6, dirtcam: 0x155 } + - { group: 7, dirtcam: 0x55 } + hit: [ ip_hdr_location_locate ] + miss: ip_hdr_location_locate + indirect: in_ipv6_t_acl$st9$tind + ternary_indirect in_ipv6_t_acl$st9$tind: + row: 1 + bus: 0 + column: 4 + input_xbar: + ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } + ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } + ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } + ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } + ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } + ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } + ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } + ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } + byte group 2: { 6: hdr.fabric.is_hit } + format: { action: 0..5 } + action: in_ipv6_t_acl$st9$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_t_acl$st9$tind(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000008 + - next_table: 0 + - { } + Ig_inner_2.in_ipv6_t.drop(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000009 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.drop_and_count(2, 2): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000a + - next_table: 0 + - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - bitmasked-set B4, $data0, B4 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.redirect_port(4, 4): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000b + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.redirect_port_and_count(6, 6): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000c + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_to_eg(8, 8): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000d + - next_table: 0 + - { } + - set W5(29..30), 3 + Ig_inner_2.in_ipv6_t.forward_and_modify_mac(10, 10): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000e + - next_table: 0 + - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000000f + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.set_mc(14, 14): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000010 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } + - set hdr.fabric.mc_index, mc_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir(16, 16): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000011 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(18, 18): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000012 + - next_table: 0 + - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set B4(0..2), $data0 + - bitmasked-set W5, $data1, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(20, 20): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000013 + - next_table: 0 + - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W5, $data0, W5 + Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(22, 22): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000014 + - next_table: 0 + - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index.0-15, count_idx.0-15 + - set hdr.fabric.count_index.16-17, count_idx.16-17 + - bitmasked-set W5, $data0, W5 + default_action: NoAction + action in_ipv6_t_acl$st9$action_data: + p4: { name: Ig_inner_2.in_ipv6_t.acl$action } + row: 14 + column: 4 + vpns: [ 0 ] + home_row: + - 14 + format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } + format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } + ternary_match ip_hdr_location_locate 1: + p4: { name: Ig_inner_2.ip_hdr_location.locate, size: 2048 } + p4_param_order: + hdr.ethernet.$valid: { type: exact, size: 1, full_size: 1 } + hdr.vlan_tag$0.$valid: { type: ternary, size: 1, full_size: 1 } + hdr.vlan_tag$1.$valid: { type: ternary, size: 1, full_size: 1 } + hdr.vlan_tag$2.$valid: { type: ternary, size: 1, full_size: 1 } + hdr.vlan_tag$3.$valid: { type: ternary, size: 1, full_size: 1 } + hdr.mpls$0.$valid: { type: exact, size: 1, full_size: 1 } + hdr.ipv4.$valid: { type: exact, size: 1, full_size: 1 } + hdr.ipv6.$valid: { type: exact, size: 1, full_size: 1 } + hdr.tcp.$valid: { type: exact, size: 1, full_size: 1 } + hdr.udp.$valid: { type: exact, size: 1, full_size: 1 } + hdr.sctp.$valid: { type: exact, size: 1, full_size: 1 } + hdr.gre.$valid: { type: exact, size: 1, full_size: 1 } + hdr.pppoe.$valid: { type: exact, size: 1, full_size: 1 } + hdr.gtpv1_8b.$valid: { type: exact, size: 1, full_size: 1 } + hdr.gtpv1_12b.$valid: { type: exact, size: 1, full_size: 1 } + hdr.gtpv2_8b.$valid: { type: exact, size: 1, full_size: 1 } + hdr.gtpv2_12b.$valid: { type: exact, size: 1, full_size: 1 } + hdr.vxlan.$valid: { type: exact, size: 1, full_size: 1 } + hdr.inner_ethernet.$valid: { type: exact, size: 1, full_size: 1 } + hdr.inner_ipv4.$valid: { type: exact, size: 1, full_size: 1 } + hdr.inner_ipv6.$valid: { type: exact, size: 1, full_size: 1 } + row: [ 8, 9, 10, 11, 8, 9, 10, 11 ] + bus: [ 0, 0, 0, 0, 1, 1, 1, 1 ] + column: + - 0 + - 0 + - 0 + - 0 + - 1 + - 1 + - 1 + - 1 + input_xbar: + ternary group 8: { 1: hdr.ethernet.$valid, 2: hdr.ipv4.$valid, 3: hdr.tcp.$valid, 4: hdr.gtpv2_8b.$valid, 8: hdr.inner_ipv4.$valid, 14: hdr.inner_ipv6.$valid, 15: hdr.gtpv2_12b.$valid, 16: hdr.udp.$valid, 17: hdr.vxlan.$valid, 18: hdr.inner_ethernet.$valid, 19: hdr.gtpv1_8b.$valid, 20: hdr.gtpv1_12b.$valid, 22: hdr.pppoe.$valid, 24: hdr.sctp.$valid, 25: hdr.gre.$valid, 26: hdr.ipv6.$valid, 33: hdr.vlan_tag$3.$valid, 34: hdr.vlan_tag$2.$valid, 35: hdr.vlan_tag$1.$valid, 36: hdr.vlan_tag$0.$valid } + byte group 0: { 3: hdr.mpls$0.$valid } + match: + - { group: 8, byte_group: 0, byte_config: 0, dirtcam: 0x555 } + - { byte_config: 3, dirtcam: 0x0 } + hit: [ tbl_add_bridged_md_pipe_2 ] + miss: tbl_add_bridged_md_pipe_2 + indirect: ip_hdr_location_locate$tind + ternary_indirect ip_hdr_location_locate$tind: + row: 0 + bus: 0 + column: 4 + input_xbar: + ternary group 8: { 1: hdr.ethernet.$valid, 2: hdr.ipv4.$valid, 3: hdr.tcp.$valid, 4: hdr.gtpv2_8b.$valid, 8: hdr.inner_ipv4.$valid, 14: hdr.inner_ipv6.$valid, 15: hdr.gtpv2_12b.$valid, 16: hdr.udp.$valid, 17: hdr.vxlan.$valid, 18: hdr.inner_ethernet.$valid, 19: hdr.gtpv1_8b.$valid, 20: hdr.gtpv1_12b.$valid, 22: hdr.pppoe.$valid, 24: hdr.sctp.$valid, 25: hdr.gre.$valid, 26: hdr.ipv6.$valid, 33: hdr.vlan_tag$3.$valid, 34: hdr.vlan_tag$2.$valid, 35: hdr.vlan_tag$1.$valid, 36: hdr.vlan_tag$0.$valid } + byte group 0: { 3: hdr.mpls$0.$valid } + format: { action: 0..0, immediate: 1..24 } + action_bus: { 2 : immediate(16..23), 32..33 : immediate(0..15) } + instruction: ip_hdr_location_locate$tind(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000016 + - next_table: 0 + - { } + Ig_inner_2.ip_hdr_location.set_ip_hdr_location(1, 3): + - p4_param_order: { len_before_ip: 8, proto_type: 8, tunnel_type: 6, trunc_type: 2 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000017 + - next_table: 0 + - { $data0: immediate(0..15), len_before_ip: $data0(0..7), proto_type: $data0(8..15), tunnel_type.0-4: immediate(16..20), trunc_type: immediate(21..22), tunnel_type.5-5: immediate(23..23) } + - set ig_md.tunnel_type.0-4, tunnel_type.0-4 + - set ig_md.tunnel_type.5-5, tunnel_type.5-5 + - set ig_md.trunc_type, trunc_type + - set H3, $data0 + default_action: NoAction + ternary_match tbl_add_bridged_md_pipe_2 2: + p4: { name: tbl_add_bridged_md_pipe_2 } + gateway: + name: cond-79 + input_xbar: + exact group 0: { 5: ig_intr_md_for_tm.bypass_egress } + row: 0 + bus: 1 + unit: 0 + match: { 5: ig_intr_md_for_tm.bypass_egress } + 0b**0: run_table + miss: lag_inner_last_lag + condition: + expression: "(ig_intr_md_for_tm.bypass_egress == 0)" + true: tbl_add_bridged_md_pipe_2 + false: lag_inner_last_lag + hit: [ lag_inner_last_lag ] + miss: lag_inner_last_lag + indirect: tbl_add_bridged_md_pipe_2$tind + ternary_indirect tbl_add_bridged_md_pipe_2$tind: + row: 0 + bus: 1 + format: { action: 0..0 } + instruction: tbl_add_bridged_md_pipe_2$tind(action, $DEFAULT) + actions: + add_bridged_md_pipe(1, 5): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x2000001e + - next_table: 0 + - set hdr.bridged_md.$valid, 1 + default_action: add_bridged_md_pipe +stage 10 ingress: + dependency: match + exact_match lag_inner_last_lag 1: + p4: { name: Ig_inner_2.lag_inner_last.lag, size: 256, action_profile: Ig_inner_2.lag_inner_last.lag_selector } + p4_param_order: + hdr.fabric.is_to_cn78: { type: exact, size: 1, full_size: 1, key_name: "is_to_cn78" } + hdr.fabric.is_to_td3: { type: exact, size: 1, full_size: 1, key_name: "is_to_td3" } + row: 1 + search_bus: 1 + result_bus: 0 + column: 6 + stash: + row: [ 1 ] + col: [ 6 ] + unit: [ 0 ] + ways: + - [1, 0, 0x0, [1, 6]] + input_xbar: + exact group 1: { 92: hdr.fabric.is_to_td3, 93: hdr.fabric.is_to_cn78 } + hash 3: + 0: hdr.fabric.is_to_td3 + 1: hdr.fabric.is_to_cn78 + hash group 1: + table: [3] + seed: 0x0 + format: { action(0): 0..1, version(0): 112..115, meter_addr(0): 2..11, meter_pfe(0): 12..12, action_addr(0): 13..23 } + match_group_map: [ [ 0 ] ] + gateway: + name: cond-78 + input_xbar: + exact group 1: { 32: hdr.fabric.mc_index } + row: 1 + bus: 1 + unit: 0 + match: { 0: hdr.fabric.mc_index(0..7), 8: hdr.fabric.mc_index(8..15) } + 0x0000: run_table + miss: truncate_mirror + condition: + expression: "(hdr.fabric.mc_index == 0)" + true: lag_inner_last_lag + false: truncate_mirror + hit: [ truncate_mirror ] + miss: truncate_mirror + selector: lag_inner_last_lag$selector.Ig_inner_2.lag_inner_last.lag_selector_sel(meter_addr, meter_pfe, $DEFAULT) + selector_length: lag_inner_last_lag$selector.Ig_inner_2.lag_inner_last.lag_selector_sel($DEFAULT, $DEFAULT) + action: lag_inner_last_lag$action_data.Ig_inner_2.lag_inner_last.lag_selector(action_addr, $DEFAULT) + instruction: lag_inner_last_lag(action, $DEFAULT) + actions: + Ig_inner_2.lag_inner_last.lag_miss(1, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x2000001c + - next_table: 0 + - { } + Ig_inner_2.lag_inner_last.set_lag_port(2, 1): + - p4_param_order: { port: 9 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000001d + - next_table: 0 + - { port: $adf_h0(0..8) } + - set ig_intr_md_for_tm.ucast_egress_port, port + default_action: Ig_inner_2.lag_inner_last.lag_miss + selection lag_inner_last_lag$selector.Ig_inner_2.lag_inner_last.lag_selector_sel: + p4: { name: Ig_inner_2.lag_inner_last.lag_selector_sel, size: 4 } + row: 15 + column: [ 3, 4 ] + maprams: [ 3, 4 ] + input_xbar: + exact group 2: { 0: ig_md.hash(0..15) } + hash 4: + 0..13: ig_md.hash(0..13) + hash group 2: + table: [4] + seed: 0x0 + mode: fair 0 + non_linear: true + pool_sizes: [120] + action lag_inner_last_lag$action_data.Ig_inner_2.lag_inner_last.lag_selector: + p4: { name: Ig_inner_2.lag_inner_last.lag_selector, size: 1024 } + row: 13 + column: 3 + vpns: [ 0 ] + home_row: + - 13 + format Ig_inner_2.lag_inner_last.set_lag_port: { $adf_h0: 0..15 } + action_bus: { 36..37 : $adf_h0 } + stateful lag_inner_last_lag$salu.Ig_inner_2.lag_inner_last.lag_selector_sel$salu: + p4: { name: Ig_inner_2.lag_inner_last.lag_selector_sel$salu, size: 131072, hidden: true } + selection_table: lag_inner_last_lag$selector.Ig_inner_2.lag_inner_last.lag_selector_sel + row: 15 + column: [ 3, 4 ] + maprams: [ 3, 4 ] + format: { lo: 1 } + actions: + set_bit_at_alu$0: + - set_bit_at + clr_bit_at_alu$0: + - clr_bit_at +stage 11 ingress: + dependency: concurrent + exact_match truncate_mirror 0: + p4: { name: Ig_inner_2.truncate.mirror, size: 512, action_profile: Ig_inner_2.truncate.lag_selector } + p4_param_order: + ig_md.trunc_type: { type: exact, size: 2, full_size: 2, key_name: "trunc_type" } + row: 5 + bus: 1 + column: 4 + stash: + row: [ 5 ] + col: [ 4 ] + unit: [ 0 ] + ways: + - [0, 0, 0x0, [5, 4]] + input_xbar: + exact group 0: { 6: ig_md.trunc_type } + hash 0: + 0..1: ig_md.trunc_type + hash group 0: + table: [0] + seed: 0x0 + format: { action(0): 0..1, version(0): 112..115, meter_addr(0): 2..11, meter_pfe(0): 12..12, action_addr(0): 13..23 } + match_group_map: [ [ 0 ] ] + gateway: + name: cond-77 + input_xbar: + exact group 0: { 10: hdr.fabric.is_trunc_mir } + row: 5 + bus: 1 + unit: 0 + match: { 2: hdr.fabric.is_trunc_mir } + 0b*****1: run_table + miss: mc_duplicate + condition: + expression: "(hdr.fabric.is_trunc_mir == 1)" + true: truncate_mirror + false: mc_duplicate + hit: [ mc_duplicate ] + miss: mc_duplicate + selector: truncate_mirror$selector.Ig_inner_2.truncate.lag_selector_sel(meter_addr, meter_pfe, $DEFAULT) + selector_length: truncate_mirror$selector.Ig_inner_2.truncate.lag_selector_sel($DEFAULT, $DEFAULT) + action: truncate_mirror$action_data.Ig_inner_2.truncate.lag_selector(action_addr, $DEFAULT) + instruction: truncate_mirror(action, $DEFAULT) + actions: + NoAction(1, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x2000001a + - next_table: 0 + - { } + Ig_inner_2.truncate.set_lag_session(2, 1): + - p4_param_order: { session_id: 10 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000001b + - next_table: 0 + - { session_id: $adf_h0(0..9) } + - set ig_intr_md_for_dprsr.drop_ctl, 1 + - set ig_md.mirror.src, 1 + - set ig_md.mirror.type, 5 + - set ig_md.mirror.session_id, session_id + - set ig_intr_md_for_dprsr.mirror_type, 5 + default_action: NoAction + selection truncate_mirror$selector.Ig_inner_2.truncate.lag_selector_sel: + p4: { name: Ig_inner_2.truncate.lag_selector_sel, size: 4 } + row: 15 + column: [ 2, 3 ] + maprams: [ 2, 3 ] + input_xbar: + exact group 0: { 64: ig_md.hash(0..15) } + hash 1: + 0..13: ig_md.hash(0..13) + hash group 1: + table: [1] + seed: 0x0 + mode: fair 0 + non_linear: true + pool_sizes: [120] + action truncate_mirror$action_data.Ig_inner_2.truncate.lag_selector: + p4: { name: Ig_inner_2.truncate.lag_selector, size: 1024 } + row: 13 + column: 2 + vpns: [ 0 ] + home_row: + - 13 + format Ig_inner_2.truncate.set_lag_session: { $adf_h0: 0..15 } + action_bus: { 32..33 : $adf_h0 } + stateful truncate_mirror$salu.Ig_inner_2.truncate.lag_selector_sel$salu: + p4: { name: Ig_inner_2.truncate.lag_selector_sel$salu, size: 131072, hidden: true } + selection_table: truncate_mirror$selector.Ig_inner_2.truncate.lag_selector_sel + row: 15 + column: [ 2, 3 ] + maprams: [ 2, 3 ] + format: { lo: 1 } + actions: + set_bit_at_alu$0: + - set_bit_at + clr_bit_at_alu$0: + - clr_bit_at + exact_match mc_duplicate 1: + p4: { name: Ig_inner_2.mc.duplicate, size: 65536 } + p4_param_order: + hdr.fabric.mc_index: { type: exact, size: 16, full_size: 16 } + row: [ 7, 6, 5 ] + bus: [ 0, 0, 0 ] + column: + - [ 2, 3, 4, 5, 6, 7 ] + - [ 2, 3, 4, 5, 6, 7 ] + - [ 2, 3 ] + stash: + row: [ 7 ] + col: [ 2 ] + unit: [ 0 ] + ways: + - [2, 0, 0x1, [7, 2], [7, 3]] + - [2, 1, 0x2, [7, 4], [7, 5]] + - [2, 2, 0x4, [7, 6], [7, 7]] + - [2, 3, 0x8, [6, 2], [6, 3]] + - [2, 0, 0x1, [6, 4], [6, 5]] + - [2, 1, 0x2, [6, 6], [6, 7]] + - [2, 2, 0x4, [5, 2], [5, 3]] + input_xbar: + exact group 1: { 0: hdr.fabric.mc_index } + hash 2: + 0..7: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(0..7) + 8..9: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(8..9) + 40: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(10) + 11..18: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(0..7) + 19: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(8) + 10: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(10) + 41: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(9) + 22..29: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(0..7) + 20..21: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(9..10) + 42: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(8) + 33..39: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(0..6) + 30..32: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(8..10) + 43: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(7) + hash group 2: + table: [2] + seed: 0xf63800a4eec + format: { action(0): 0..0, version(0): 112..115, match(0): 35..39, action(1): 1..1, version(1): 116..119, match(1): 43..47, action(2): 2..2, version(2): 120..123, match(2): 51..55, action(3): 3..3, version(3): 124..127, match(3): 59..63, action(4): 4..4, version(4): 8..11, match(4): 67..71 } + match: [ hdr.fabric.mc_index(11..15) ] + match_group_map: [ [ 0, 1, 2, 3, 4 ] ] + hit: [ END ] + miss: END + action: mc_duplicate$action_data($DIRECT, $DEFAULT) + instruction: mc_duplicate(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000018 + - next_table: 0 + - { } + Ig_inner_2.mc.set_mgid(1, 2): + - p4_param_order: { mgid: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000019 + - next_table: 0 + - { mgid: $adf_h0(0..15) } + - set ig_intr_md_for_tm.mcast_grp_b, mgid + - set ig_intr_md_for_tm.level1_mcast_hash, ig_md.hash(0..12) + - set ig_intr_md_for_tm.level2_mcast_hash, ig_md.hash(16..28) + default_action: NoAction + action mc_duplicate$action_data: + p4: { name: Ig_inner_2.mc.duplicate$action } + row: [ 15, 13, 11 ] + word: [ 0, 0, 0 ] + column: + - [ 4, 5 ] + - [ 3, 4, 5 ] + - [ 0, 1, 2, 3 ] + vpns: + - [ 0, 1 ] + - [ 2, 3, 4 ] + - [ 5, 6, 7, 8 ] + home_row: + - 15 + format Ig_inner_2.mc.set_mgid: { $adf_h0: 0..15 } + action_bus: { 36..37 : $adf_h0 } +stage 0 egress: + dependency: match + gateway cond-80 5: + name: cond-80 + input_xbar: + exact group 2: { 96: eg_md.in_ig_port_type } + row: 1 + bus: 0 + unit: 0 + match: { 0: eg_md.in_ig_port_type } + 0b*****101: fabric_decap_inner_decap + miss: in_ipv6_e_acl_2$st0 + condition: + expression: "(eg_md.in_ig_port_type == 5)" + true: fabric_decap_inner_decap + false: in_ipv6_e_acl_2$st0 + ternary_match fabric_decap_inner_decap 6: + p4: { name: Eg_inner_2.fabric_decap_inner.decap, size: 128 } + gateway: + name: cond-81 + input_xbar: + exact group 3: { 27: hdr.fabric.$valid } + row: 0 + bus: 1 + unit: 1 + match: { 3: hdr.fabric.$valid } + 0b****1: run_table + miss: cn78_encap_inner_fabric_bfn_to_cn78 + condition: + expression: "(hdr.fabric.$valid == 1)" + true: fabric_decap_inner_decap + false: cn78_encap_inner_fabric_bfn_to_cn78 + hit: [ cn78_encap_inner_fabric_bfn_to_cn78 ] + miss: cn78_encap_inner_fabric_bfn_to_cn78 + indirect: fabric_decap_inner_decap$tind + ternary_indirect fabric_decap_inner_decap$tind: + row: 0 + bus: 1 + format: { action: 0..0 } + instruction: fabric_decap_inner_decap$tind(action, $DEFAULT) + actions: + Eg_inner_2.fabric_decap_inner.remove_fabric(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x2000001f + - next_table: 0 + - set hdr.fabric.$valid, 0 + - set hdr.ethernet.ether_type, hdr.fabric.ether_type + default_action: Eg_inner_2.fabric_decap_inner.remove_fabric + exact_match in_ipv6_e_acl_2$st0 7: + p4: { name: Eg_inner_2.in_ipv6_e.acl, size: 38912 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } + hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } + eg_md.lkp.inner_l4_src_port: { type: exact, size: 16, full_size: 16, key_name: "in_l4_src_port" } + eg_md.lkp.inner_l4_dst_port: { type: exact, size: 16, full_size: 16, key_name: "in_l4_dst_port" } + hdr.inner_ipv6.next_hdr: { type: exact, size: 8, full_size: 8, key_name: "in_ip_proto" } + row: [ 5, 6, 7, 2, 3, 4 ] + bus: [ 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + stash: + row: [ 5, 6, 7 ] + col: [ 2, 2, 2 ] + unit: [ 0, 0, 0 ] + ways: + - [1, 0, 0x3, [7, 2], [6, 2], [5, 2], [7, 3], [6, 3], [5, 3], [7, 4], [6, 4], [5, 4], [7, 5], [6, 5], [5, 5]] + - [1, 1, 0xc, [7, 6], [6, 6], [5, 6], [7, 7], [6, 7], [5, 7], [7, 8], [6, 8], [5, 8], [7, 9], [6, 9], [5, 9]] + - [1, 2, 0x30, [7, 10], [6, 10], [5, 10], [7, 11], [6, 11], [5, 11], [4, 2], [3, 2], [2, 2], [4, 3], [3, 3], [2, 3]] + - [1, 3, 0xc0, [4, 4], [3, 4], [2, 4], [4, 5], [3, 5], [2, 5], [4, 6], [3, 6], [2, 6], [4, 7], [3, 7], [2, 7]] + - [1, 0, 0x1, [4, 8], [3, 8], [2, 8], [4, 9], [3, 9], [2, 9]] + - [1, 1, 0x0, [4, 10], [3, 10], [2, 10]] + input_xbar: + exact group 3: { 0: hdr.inner_ipv6.src_addr.0-31(0..23), 32: hdr.inner_ipv6.src_addr.32-63(0..23), 62: hdr.fabric.is_hit, 64: hdr.inner_ipv6.src_addr.64-95(0..23), 88: hdr.inner_ipv6.src_addr.0-31(24..31), 96: hdr.inner_ipv6.src_addr.96-127(0..23), 120: hdr.inner_ipv6.src_addr.32-63(24..31) } + exact group 4: { 0: hdr.inner_ipv6.dst_addr.0-31(0..23), 24: hdr.inner_ipv6.src_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.32-63(0..23), 56: hdr.inner_ipv6.src_addr.96-127(24..31), 64: hdr.inner_ipv6.dst_addr.64-95(0..23), 88: hdr.inner_ipv6.dst_addr.0-31(24..31), 96: hdr.inner_ipv6.dst_addr.96-127(0..23), 120: hdr.inner_ipv6.dst_addr.32-63(24..31) } + exact group 5: { 0: hdr.vlan_tag$0.vid, 16: eg_md.lkp.inner_l4_src_port(0..7), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: eg_md.lkp.inner_l4_dst_port(0..7), 40: eg_md.lkp.inner_l4_src_port(8..15), 48: hdr.inner_ipv6.next_hdr, 56: hdr.inner_ipv6.dst_addr.96-127(24..31), 72: eg_md.lkp.inner_l4_dst_port(8..15) } + hash 6: + 0..9: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.fabric.is_hit) + 40..41: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.fabric.is_hit) + 10..19: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.fabric.is_hit) + 42..43: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.fabric.is_hit) + 20..29: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.fabric.is_hit) + 44..45: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.fabric.is_hit) + 30..39: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.fabric.is_hit) + 46..47: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.fabric.is_hit) + hash 7: + 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.32-63(24..31)) + 40..41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.32-63(24..31)) + 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.32-63(24..31)) + 42..43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.32-63(24..31)) + 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.32-63(24..31)) + 44..45: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.32-63(24..31)) + 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.32-63(24..31)) + 46..47: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.32-63(24..31)) + hash 8: + 0..9: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.src_addr.96-127(24..31)) + 40..41: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.src_addr.96-127(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.src_addr.96-127(24..31)) + 42..43: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.src_addr.96-127(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.src_addr.96-127(24..31)) + 44..45: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.src_addr.96-127(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.src_addr.96-127(24..31)) + 46..47: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.src_addr.96-127(24..31)) + hash 9: + 0..9: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31)) + 40..41: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31)) + 42..43: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31)) + 44..45: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31)) + 46..47: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31)) + hash 10: + 0..3: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) + 4..9: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..5) + 40..41: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + 11..14: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) + 15..19: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..4) + 10: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(5) + 42..43: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + 22..25: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) + 26..29: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..3) + 20..21: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(4..5) + 44..45: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + 33..36: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) + 37..39: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..2) + 30..32: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(3..5) + 46..47: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + hash 11: + 0..9: random(eg_md.lkp.inner_l4_dst_port(8..15)) + 40..41: random(eg_md.lkp.inner_l4_dst_port(8..15)) + 10..19: random(eg_md.lkp.inner_l4_dst_port(8..15)) + 42..43: random(eg_md.lkp.inner_l4_dst_port(8..15)) + 20..29: random(eg_md.lkp.inner_l4_dst_port(8..15)) + 44..45: random(eg_md.lkp.inner_l4_dst_port(8..15)) + 30..39: random(eg_md.lkp.inner_l4_dst_port(8..15)) + 46..47: random(eg_md.lkp.inner_l4_dst_port(8..15)) + hash group 1: + table: [6, 7, 8, 9, 10, 11] + seed: 0x923c1cbfc7f + format: { action(0): 0..5, version(0): 88..91, match(0): [94..95, 32..71, 246..246, 160..239, 128..135, 288..295, 136..159, 296..367, 256..279, 72..79, 280..287, 368..383, 80..87 ] } + match: [ hdr.inner_ipv6.next_hdr(6..7), hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_dst_port(8..15), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.0-31(0..7), hdr.inner_ipv6.src_addr.0-31(8..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] + match_group_map: [ [ 0 ], [ 0 ], [ 0 ] ] + gateway: + name: cond-83 + input_xbar: + exact group 5: { 68: hdr.vlan_tag$0.$valid, 88: hdr.fabric.ig_port_type, 110: hdr.inner_ipv6.$valid } + row: 0 + bus: 0 + unit: 0 + match: { 0: hdr.fabric.ig_port_type, 12: hdr.vlan_tag$0.$valid, 22: hdr.inner_ipv6.$valid } + 0b*1*********1*********001: run_table + miss: END + condition: + expression: "(hdr.fabric.ig_port_type == 1 && hdr.vlan_tag[0].$valid == 1 && hdr.inner_ipv6.$valid == 1)" + true: in_ipv6_e_acl_2$st0 + false: END + hit: [ END ] + miss: in_ipv6_e_acl_2$st1 + action: in_ipv6_e_acl_2$st0$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_e_acl_2$st0(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000021 + - next_table: 0 + - { } + Eg_inner_2.in_ipv6_e.drop(2, 2): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000022 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.drop_and_count(4, 4): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000023 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } + - bitmasked-set W16, $data0, W16 + - bitmasked-set W17, $data1, W17 + Eg_inner_2.in_ipv6_e.redirect_port(6, 6): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000024 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.redirect_port_and_count(8, 8): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000025 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_to_eg(10, 10): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000026 + - next_table: 0 + - { } + - set W16(29..30), 3 + Eg_inner_2.in_ipv6_e.forward_and_modify_mac(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000027 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(14, 14): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000028 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.set_mc(16, 16): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000029 + - next_table: 0 + - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.mc_index.0-7, mc_idx.0-7 + - set hdr.fabric.mc_index.8-15, mc_idx.8-15 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir(18, 18): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000002a + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(20, 20): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000002b + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + - set W17(8..26), $data1 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(22, 22): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000002c + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(24, 24): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000002d + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + default_action: NoAction + action in_ipv6_e_acl_2$st0$action_data: + p4: { name: Eg_inner_2.in_ipv6_e.acl$action } + row: [ 9, 7, 5, 3, 2, 1, 0 ] + word: [ 0, 0, 0, 0, 0, 0, 0 ] + column: + - 5 + - 5 + - 5 + - [ 1, 2, 3, 4, 5 ] + - [ 2, 3, 4, 5 ] + - [ 0, 1, 2, 3, 4, 5 ] + - 3 + vpns: + - [ 0 ] + - [ 1 ] + - [ 2 ] + - [ 3, 4, 5, 6, 7 ] + - [ 8, 9, 10, 11 ] + - [ 12, 13, 14, 15, 16, 17 ] + - [ 18 ] + home_row: + - 9 + format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 120..123 : $adf_f2, 124..127 : $adf_f3, 64..67 : $adf_f0, 68..71 : $adf_f1 } +stage 1 egress: + dependency: match + ternary_match cn78_encap_inner_fabric_bfn_to_cn78 2: + p4: { name: Eg_inner_2.cn78_encap_inner.fabric_bfn_to_cn78, size: 1024 } + gateway: + name: cond-82 + input_xbar: + exact group 0: { 29: hdr.fabric.is_to_cn78 } + row: 4 + bus: 1 + unit: 0 + match: { 5: hdr.fabric.is_to_cn78 } + 0b**1: run_table + miss: END + condition: + expression: "(hdr.fabric.is_to_cn78 == 1)" + true: cn78_encap_inner_fabric_bfn_to_cn78 + false: END + hit: [ END ] + miss: END + indirect: cn78_encap_inner_fabric_bfn_to_cn78$tind + ternary_indirect cn78_encap_inner_fabric_bfn_to_cn78$tind: + row: 0 + bus: 1 + format: { action: 0..0 } + instruction: cn78_encap_inner_fabric_bfn_to_cn78$tind(action, $DEFAULT) + actions: + Eg_inner_2.cn78_encap_inner.bfn_to_cn78(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000020 + - next_table: 0 + - set hdr.fabric_to_cn78.$valid, 1 + - set hdr.fabric_to_cn78.ether_type, hdr.ethernet.ether_type + - set hdr.ethernet.ether_type, 33279 + default_action: Eg_inner_2.cn78_encap_inner.bfn_to_cn78 + exact_match in_ipv6_e_acl_2$st1 3: + p4: { name: Eg_inner_2.in_ipv6_e.acl, size: 38912 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } + hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } + eg_md.lkp.inner_l4_src_port: { type: exact, size: 16, full_size: 16, key_name: "in_l4_src_port" } + eg_md.lkp.inner_l4_dst_port: { type: exact, size: 16, full_size: 16, key_name: "in_l4_dst_port" } + hdr.inner_ipv6.next_hdr: { type: exact, size: 8, full_size: 8, key_name: "in_ip_proto" } + row: [ 5, 6, 7, 2, 3, 4 ] + bus: [ 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + stash: + row: [ 5, 6, 7 ] + col: [ 2, 2, 2 ] + unit: [ 0, 0, 0 ] + ways: + - [1, 0, 0x3, [7, 2], [6, 2], [5, 2], [7, 3], [6, 3], [5, 3], [7, 4], [6, 4], [5, 4], [7, 5], [6, 5], [5, 5]] + - [1, 1, 0xc, [7, 6], [6, 6], [5, 6], [7, 7], [6, 7], [5, 7], [7, 8], [6, 8], [5, 8], [7, 9], [6, 9], [5, 9]] + - [1, 2, 0x30, [7, 10], [6, 10], [5, 10], [7, 11], [6, 11], [5, 11], [4, 2], [3, 2], [2, 2], [4, 3], [3, 3], [2, 3]] + - [1, 3, 0xc0, [4, 4], [3, 4], [2, 4], [4, 5], [3, 5], [2, 5], [4, 6], [3, 6], [2, 6], [4, 7], [3, 7], [2, 7]] + - [1, 0, 0x1, [4, 8], [3, 8], [2, 8], [4, 9], [3, 9], [2, 9]] + - [1, 1, 0x0, [4, 10], [3, 10], [2, 10]] + input_xbar: + exact group 1: { 0: hdr.inner_ipv6.src_addr.0-31(0..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.src_addr.32-63(0..23), 56: hdr.inner_ipv6.src_addr.0-31(24..31), 64: hdr.inner_ipv6.src_addr.64-95(0..23), 88: hdr.inner_ipv6.src_addr.32-63(24..31), 96: hdr.inner_ipv6.src_addr.96-127(0..23), 120: hdr.inner_ipv6.src_addr.64-95(24..31) } + exact group 2: { 0: hdr.inner_ipv6.dst_addr.0-31(0..23), 24: hdr.inner_ipv6.src_addr.96-127(24..31), 32: hdr.inner_ipv6.dst_addr.32-63(0..23), 56: hdr.inner_ipv6.dst_addr.0-31(24..31), 64: hdr.inner_ipv6.dst_addr.64-95(0..23), 88: hdr.inner_ipv6.dst_addr.32-63(24..31), 96: hdr.inner_ipv6.dst_addr.96-127(0..23), 120: hdr.inner_ipv6.dst_addr.64-95(24..31) } + exact group 3: { 0: hdr.vlan_tag$0.vid, 16: eg_md.lkp.inner_l4_src_port(0..7), 24: hdr.inner_ipv6.dst_addr.96-127(24..31), 32: eg_md.lkp.inner_l4_dst_port(0..7), 40: eg_md.lkp.inner_l4_src_port(8..15), 48: hdr.inner_ipv6.next_hdr, 56: eg_md.lkp.inner_l4_dst_port(8..15) } + hash 2: + 0..9: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 40..41: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 10..19: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 42..43: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 20..29: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 44..45: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 30..39: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 46..47: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + hash 3: + 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 40..41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 42..43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 44..45: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 46..47: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + hash 4: + 0..9: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 40..41: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 42..43: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 44..45: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 46..47: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + hash 5: + 0..9: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 40..41: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 42..43: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 44..45: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 46..47: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + hash 6: + 0..3: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..11) + 4..9: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.inner_ipv6.next_hdr(0..5) + 40..41: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) + 11..14: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..11) + 15..19: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.inner_ipv6.next_hdr(0..4) + 10: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.inner_ipv6.next_hdr(5) + 42..43: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) + 22..25: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..11) + 26..29: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.inner_ipv6.next_hdr(0..3) + 20..21: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.inner_ipv6.next_hdr(4..5) + 44..45: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) + 33..36: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..11) + 37..39: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.inner_ipv6.next_hdr(0..2) + 30..32: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.inner_ipv6.next_hdr(3..5) + 46..47: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) + hash group 1: + table: [2, 3, 4, 5, 6] + seed: 0x1d01fd8930e + format: { action(0): 0..5, version(0): 80..83, match(0): [86..87, 32..71, 254..254, 160..239, 128..159, 240..247, 288..367, 256..287, 368..383, 72..79 ] } + match: [ hdr.inner_ipv6.next_hdr(6..7), hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_dst_port(8..15), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.0-31(0..7), hdr.inner_ipv6.src_addr.0-31(8..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] + match_group_map: [ [ 0 ], [ 0 ], [ 0 ] ] + hit: [ END ] + miss: in_ipv6_e_acl_1$st0 + action: in_ipv6_e_acl_2$st1$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_e_acl_2$st1(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000021 + - next_table_miss: in_ipv6_e_acl_1$st0 + - next_table: 0 + - { } + Eg_inner_2.in_ipv6_e.drop(2, 2): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000022 + - next_table_miss: in_ipv6_e_acl_1$st0 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.drop_and_count(4, 4): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000023 + - next_table_miss: in_ipv6_e_acl_1$st0 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } + - bitmasked-set W16, $data0, W16 + - bitmasked-set W17, $data1, W17 + Eg_inner_2.in_ipv6_e.redirect_port(6, 6): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000024 + - next_table_miss: in_ipv6_e_acl_1$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.redirect_port_and_count(8, 8): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000025 + - next_table_miss: in_ipv6_e_acl_1$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_to_eg(10, 10): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000026 + - next_table_miss: in_ipv6_e_acl_1$st0 + - next_table: 0 + - { } + - set W16(29..30), 3 + Eg_inner_2.in_ipv6_e.forward_and_modify_mac(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000027 + - next_table_miss: in_ipv6_e_acl_1$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(14, 14): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000028 + - next_table_miss: in_ipv6_e_acl_1$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.set_mc(16, 16): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000029 + - next_table_miss: in_ipv6_e_acl_1$st0 + - next_table: 0 + - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.mc_index.0-7, mc_idx.0-7 + - set hdr.fabric.mc_index.8-15, mc_idx.8-15 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir(18, 18): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000002a + - next_table_miss: in_ipv6_e_acl_1$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(20, 20): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000002b + - next_table_miss: in_ipv6_e_acl_1$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + - set W17(8..26), $data1 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(22, 22): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000002c + - next_table_miss: in_ipv6_e_acl_1$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(24, 24): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000002d + - next_table_miss: in_ipv6_e_acl_1$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + default_action: NoAction + action in_ipv6_e_acl_2$st1$action_data: + p4: { name: Eg_inner_2.in_ipv6_e.acl$action } + row: [ 7, 5, 3, 2, 1, 0 ] + word: [ 0, 0, 0, 0, 0, 0 ] + column: + - 5 + - 5 + - [ 1, 2, 3, 4, 5 ] + - [ 3, 4, 5 ] + - [ 0, 1, 2, 3, 4, 5 ] + - [ 3, 4, 5 ] + vpns: + - [ 0 ] + - [ 1 ] + - [ 2, 3, 4, 5, 6 ] + - [ 7, 8, 9 ] + - [ 10, 11, 12, 13, 14, 15 ] + - [ 16, 17, 18 ] + home_row: + - 7 + format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 120..123 : $adf_f2, 124..127 : $adf_f3, 64..67 : $adf_f0, 68..71 : $adf_f1 } +stage 2 egress: + dependency: match + exact_match in_ipv6_e_acl_1$st0 1: + p4: { name: Eg_inner_2.in_ipv6_e.acl_4, size: 38912 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } + hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } + eg_md.lkp.inner_l4_src_port: { type: exact, size: 16, full_size: 16, key_name: "in_l4_src_port" } + eg_md.lkp.inner_l4_dst_port: { type: exact, size: 16, full_size: 16, key_name: "in_l4_dst_port" } + row: [ 5, 6, 7, 2, 3, 4 ] + bus: [ 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + stash: + row: [ 5, 6, 7 ] + col: [ 2, 2, 2 ] + unit: [ 0, 0, 0 ] + ways: + - [0, 0, 0x3, [7, 2], [6, 2], [5, 2], [7, 3], [6, 3], [5, 3], [7, 4], [6, 4], [5, 4], [7, 5], [6, 5], [5, 5]] + - [0, 1, 0xc, [7, 6], [6, 6], [5, 6], [7, 7], [6, 7], [5, 7], [7, 8], [6, 8], [5, 8], [7, 9], [6, 9], [5, 9]] + - [0, 2, 0x30, [7, 10], [6, 10], [5, 10], [7, 11], [6, 11], [5, 11], [4, 2], [3, 2], [2, 2], [4, 3], [3, 3], [2, 3]] + - [0, 3, 0xc0, [4, 4], [3, 4], [2, 4], [4, 5], [3, 5], [2, 5], [4, 6], [3, 6], [2, 6], [4, 7], [3, 7], [2, 7]] + - [0, 0, 0x1, [4, 8], [3, 8], [2, 8], [4, 9], [3, 9], [2, 9]] + - [0, 1, 0x0, [4, 10], [3, 10], [2, 10]] + input_xbar: + exact group 0: { 0: hdr.inner_ipv6.src_addr.0-31(0..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.src_addr.32-63(0..23), 56: hdr.inner_ipv6.src_addr.0-31(24..31), 64: hdr.inner_ipv6.src_addr.64-95(0..23), 88: hdr.inner_ipv6.src_addr.32-63(24..31), 96: hdr.inner_ipv6.src_addr.96-127(0..23), 120: hdr.inner_ipv6.src_addr.64-95(24..31) } + exact group 1: { 0: hdr.inner_ipv6.dst_addr.0-31(0..23), 24: hdr.inner_ipv6.src_addr.96-127(24..31), 32: hdr.inner_ipv6.dst_addr.32-63(0..23), 56: hdr.inner_ipv6.dst_addr.0-31(24..31), 64: hdr.inner_ipv6.dst_addr.64-95(0..23), 88: hdr.inner_ipv6.dst_addr.32-63(24..31), 96: hdr.inner_ipv6.dst_addr.96-127(0..23), 120: hdr.inner_ipv6.dst_addr.64-95(24..31) } + exact group 2: { 0: hdr.vlan_tag$0.vid, 16: eg_md.lkp.inner_l4_src_port(0..7), 24: hdr.inner_ipv6.dst_addr.96-127(24..31), 32: eg_md.lkp.inner_l4_dst_port(0..7), 40: eg_md.lkp.inner_l4_src_port(8..15), 56: eg_md.lkp.inner_l4_dst_port(8..15) } + hash 0: + 0..9: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 40..41: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 10..19: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 42..43: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 20..29: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 44..45: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 30..39: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 46..47: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + hash 1: + 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 40..41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 42..43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 44..45: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 46..47: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + hash 2: + 0..9: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 40..41: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 42..43: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 44..45: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 46..47: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + hash 3: + 0..9: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 40..41: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 42..43: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 44..45: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 46..47: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + hash 4: + 0..5: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(0..5) + 6..9: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..11) + 40..41: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) + 11..16: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(0..5) + 17..19: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..10) + 10: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(11) + 42..43: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) + 22..27: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(0..5) + 28..29: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..9) + 20..21: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(10..11) + 44..45: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) + 33..38: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(0..5) + 39: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8) + 30..32: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(9..11) + 46..47: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) + hash group 0: + table: [0, 1, 2, 3, 4] + seed: 0x7f91152fffff + format: { action(0): 0..5, version(0): 72..75, match(0): [78..79, 32..63, 254..254, 160..239, 128..159, 240..247, 288..367, 256..287, 368..383, 64..71 ] } + match: [ hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_dst_port(8..15), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.0-31(0..7), hdr.inner_ipv6.src_addr.0-31(8..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] + match_group_map: [ [ 0 ], [ 0 ], [ 0 ] ] + hit: [ END ] + miss: in_ipv6_e_acl_1$st1 + action: in_ipv6_e_acl_1$st0$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_e_acl_1$st0(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x2000002e + - next_table: 0 + - { } + Eg_inner_2.in_ipv6_e.drop(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000002f + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.drop_and_count(2, 2): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000030 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } + - bitmasked-set W16, $data0, W16 + - bitmasked-set W17, $data1, W17 + Eg_inner_2.in_ipv6_e.redirect_port(4, 4): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000031 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.redirect_port_and_count(6, 6): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000032 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_to_eg(8, 8): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000033 + - next_table: 0 + - { } + - set W16(29..30), 3 + Eg_inner_2.in_ipv6_e.forward_and_modify_mac(10, 10): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000034 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000035 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.set_mc(14, 14): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000036 + - next_table: 0 + - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.mc_index.0-7, mc_idx.0-7 + - set hdr.fabric.mc_index.8-15, mc_idx.8-15 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir(16, 16): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000037 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(18, 18): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000038 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + - set W17(8..26), $data1 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(20, 20): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000039 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(22, 22): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000003a + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + default_action: NoAction + action in_ipv6_e_acl_1$st0$action_data: + p4: { name: Eg_inner_2.in_ipv6_e.acl_4$action } + row: [ 9, 7, 5, 3, 2, 1, 0 ] + word: [ 0, 0, 0, 0, 0, 0, 0 ] + column: + - 5 + - 5 + - 5 + - [ 1, 2, 3, 4, 5 ] + - [ 2, 3, 4, 5 ] + - [ 0, 1, 2, 3, 4, 5 ] + - 3 + vpns: + - [ 0 ] + - [ 1 ] + - [ 2 ] + - [ 3, 4, 5, 6, 7 ] + - [ 8, 9, 10, 11 ] + - [ 12, 13, 14, 15, 16, 17 ] + - [ 18 ] + home_row: + - 9 + format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 112..115 : $adf_f2, 116..119 : $adf_f3, 120..123 : $adf_f0, 124..127 : $adf_f1 } +stage 3 egress: + dependency: match + exact_match in_ipv6_e_acl_1$st1 1: + p4: { name: Eg_inner_2.in_ipv6_e.acl_4, size: 38912 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } + hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } + eg_md.lkp.inner_l4_src_port: { type: exact, size: 16, full_size: 16, key_name: "in_l4_src_port" } + eg_md.lkp.inner_l4_dst_port: { type: exact, size: 16, full_size: 16, key_name: "in_l4_dst_port" } + row: [ 5, 6, 7, 2, 3, 4 ] + bus: [ 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + stash: + row: [ 5, 6, 7 ] + col: [ 2, 2, 2 ] + unit: [ 0, 0, 0 ] + ways: + - [0, 0, 0x3, [7, 2], [6, 2], [5, 2], [7, 3], [6, 3], [5, 3], [7, 4], [6, 4], [5, 4], [7, 5], [6, 5], [5, 5]] + - [0, 1, 0xc, [7, 6], [6, 6], [5, 6], [7, 7], [6, 7], [5, 7], [7, 8], [6, 8], [5, 8], [7, 9], [6, 9], [5, 9]] + - [0, 2, 0x30, [7, 10], [6, 10], [5, 10], [7, 11], [6, 11], [5, 11], [4, 2], [3, 2], [2, 2], [4, 3], [3, 3], [2, 3]] + - [0, 3, 0xc0, [4, 4], [3, 4], [2, 4], [4, 5], [3, 5], [2, 5], [4, 6], [3, 6], [2, 6], [4, 7], [3, 7], [2, 7]] + - [0, 0, 0x1, [4, 8], [3, 8], [2, 8], [4, 9], [3, 9], [2, 9]] + - [0, 1, 0x0, [4, 10], [3, 10], [2, 10]] + input_xbar: + exact group 0: { 0: hdr.inner_ipv6.src_addr.0-31(0..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.src_addr.32-63(0..23), 56: hdr.inner_ipv6.src_addr.0-31(24..31), 64: hdr.inner_ipv6.src_addr.64-95(0..23), 88: hdr.inner_ipv6.src_addr.32-63(24..31), 96: hdr.inner_ipv6.src_addr.96-127(0..23), 120: hdr.inner_ipv6.src_addr.64-95(24..31) } + exact group 1: { 0: hdr.inner_ipv6.dst_addr.0-31(0..23), 24: hdr.inner_ipv6.src_addr.96-127(24..31), 32: hdr.inner_ipv6.dst_addr.32-63(0..23), 56: hdr.inner_ipv6.dst_addr.0-31(24..31), 64: hdr.inner_ipv6.dst_addr.64-95(0..23), 88: hdr.inner_ipv6.dst_addr.32-63(24..31), 96: hdr.inner_ipv6.dst_addr.96-127(0..23), 120: hdr.inner_ipv6.dst_addr.64-95(24..31) } + exact group 2: { 0: hdr.vlan_tag$0.vid, 16: eg_md.lkp.inner_l4_src_port(0..7), 24: hdr.inner_ipv6.dst_addr.96-127(24..31), 32: eg_md.lkp.inner_l4_dst_port(0..7), 40: eg_md.lkp.inner_l4_src_port(8..15), 56: eg_md.lkp.inner_l4_dst_port(8..15) } + hash 0: + 0..9: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 40..41: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 10..19: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 42..43: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 20..29: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 44..45: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 30..39: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 46..47: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + hash 1: + 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 40..41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 42..43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 44..45: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 46..47: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + hash 2: + 0..9: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 40..41: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 42..43: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 44..45: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 46..47: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + hash 3: + 0..9: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 40..41: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 42..43: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 44..45: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 46..47: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + hash 4: + 0..5: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(0..5) + 6..9: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..11) + 40..41: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) + 11..16: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(0..5) + 17..19: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..10) + 10: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(11) + 42..43: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) + 22..27: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(0..5) + 28..29: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..9) + 20..21: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(10..11) + 44..45: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) + 33..38: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(0..5) + 39: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8) + 30..32: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(9..11) + 46..47: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) + hash group 0: + table: [0, 1, 2, 3, 4] + seed: 0x472a058ede7f + format: { action(0): 0..5, version(0): 72..75, match(0): [78..79, 32..63, 254..254, 160..239, 128..159, 240..247, 288..367, 256..287, 368..383, 64..71 ] } + match: [ hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_dst_port(8..15), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.0-31(0..7), hdr.inner_ipv6.src_addr.0-31(8..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] + match_group_map: [ [ 0 ], [ 0 ], [ 0 ] ] + hit: [ END ] + miss: in_ipv6_e_acl_0$st0 + action: in_ipv6_e_acl_1$st1$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_e_acl_1$st1(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x2000002e + - next_table_miss: in_ipv6_e_acl_0$st0 + - next_table: 0 + - { } + Eg_inner_2.in_ipv6_e.drop(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000002f + - next_table_miss: in_ipv6_e_acl_0$st0 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.drop_and_count(2, 2): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000030 + - next_table_miss: in_ipv6_e_acl_0$st0 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } + - bitmasked-set W16, $data0, W16 + - bitmasked-set W17, $data1, W17 + Eg_inner_2.in_ipv6_e.redirect_port(4, 4): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000031 + - next_table_miss: in_ipv6_e_acl_0$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.redirect_port_and_count(6, 6): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000032 + - next_table_miss: in_ipv6_e_acl_0$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_to_eg(8, 8): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000033 + - next_table_miss: in_ipv6_e_acl_0$st0 + - next_table: 0 + - { } + - set W16(29..30), 3 + Eg_inner_2.in_ipv6_e.forward_and_modify_mac(10, 10): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000034 + - next_table_miss: in_ipv6_e_acl_0$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000035 + - next_table_miss: in_ipv6_e_acl_0$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.set_mc(14, 14): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000036 + - next_table_miss: in_ipv6_e_acl_0$st0 + - next_table: 0 + - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.mc_index.0-7, mc_idx.0-7 + - set hdr.fabric.mc_index.8-15, mc_idx.8-15 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir(16, 16): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000037 + - next_table_miss: in_ipv6_e_acl_0$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(18, 18): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000038 + - next_table_miss: in_ipv6_e_acl_0$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + - set W17(8..26), $data1 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(20, 20): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000039 + - next_table_miss: in_ipv6_e_acl_0$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(22, 22): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000003a + - next_table_miss: in_ipv6_e_acl_0$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + default_action: NoAction + action in_ipv6_e_acl_1$st1$action_data: + p4: { name: Eg_inner_2.in_ipv6_e.acl_4$action } + row: [ 9, 7, 5, 3, 2, 1, 0 ] + word: [ 0, 0, 0, 0, 0, 0, 0 ] + column: + - 5 + - 5 + - 5 + - [ 1, 2, 3, 4, 5 ] + - [ 2, 3, 4, 5 ] + - [ 0, 1, 2, 3, 4, 5 ] + - 3 + vpns: + - [ 0 ] + - [ 1 ] + - [ 2 ] + - [ 3, 4, 5, 6, 7 ] + - [ 8, 9, 10, 11 ] + - [ 12, 13, 14, 15, 16, 17 ] + - [ 18 ] + home_row: + - 9 + format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 112..115 : $adf_f2, 116..119 : $adf_f3, 120..123 : $adf_f0, 124..127 : $adf_f1 } +stage 4 egress: + dependency: match + exact_match in_ipv6_e_acl_0$st0 1: + p4: { name: Eg_inner_2.in_ipv6_e.acl_3, size: 38912 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } + hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } + hdr.inner_ipv6.next_hdr: { type: exact, size: 8, full_size: 8, key_name: "in_ip_proto" } + row: [ 5, 6, 7, 2, 3, 4 ] + bus: [ 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + stash: + row: [ 5, 6, 7 ] + col: [ 2, 2, 2 ] + unit: [ 0, 0, 0 ] + ways: + - [0, 0, 0x3, [7, 2], [6, 2], [5, 2], [7, 3], [6, 3], [5, 3], [7, 4], [6, 4], [5, 4], [7, 5], [6, 5], [5, 5]] + - [0, 1, 0xc, [7, 6], [6, 6], [5, 6], [7, 7], [6, 7], [5, 7], [7, 8], [6, 8], [5, 8], [7, 9], [6, 9], [5, 9]] + - [0, 2, 0x30, [7, 10], [6, 10], [5, 10], [7, 11], [6, 11], [5, 11], [4, 2], [3, 2], [2, 2], [4, 3], [3, 3], [2, 3]] + - [0, 3, 0xc0, [4, 4], [3, 4], [2, 4], [4, 5], [3, 5], [2, 5], [4, 6], [3, 6], [2, 6], [4, 7], [3, 7], [2, 7]] + - [0, 0, 0x1, [4, 8], [3, 8], [2, 8], [4, 9], [3, 9], [2, 9]] + - [0, 1, 0x0, [4, 10], [3, 10], [2, 10]] + input_xbar: + exact group 0: { 0: hdr.inner_ipv6.src_addr.0-31(0..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.src_addr.32-63(0..23), 56: hdr.inner_ipv6.src_addr.0-31(24..31), 64: hdr.inner_ipv6.src_addr.64-95(0..23), 88: hdr.inner_ipv6.src_addr.32-63(24..31), 96: hdr.inner_ipv6.src_addr.96-127(0..23), 120: hdr.inner_ipv6.src_addr.64-95(24..31) } + exact group 1: { 0: hdr.inner_ipv6.dst_addr.0-31(0..23), 24: hdr.inner_ipv6.src_addr.96-127(24..31), 32: hdr.inner_ipv6.dst_addr.32-63(0..23), 56: hdr.inner_ipv6.dst_addr.0-31(24..31), 64: hdr.inner_ipv6.dst_addr.64-95(0..23), 88: hdr.inner_ipv6.dst_addr.32-63(24..31), 96: hdr.inner_ipv6.dst_addr.96-127(0..23), 120: hdr.inner_ipv6.dst_addr.64-95(24..31) } + exact group 2: { 0: hdr.vlan_tag$0.vid, 16: hdr.inner_ipv6.next_hdr, 24: hdr.inner_ipv6.dst_addr.96-127(24..31) } + hash 0: + 0..9: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 40..41: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 10..19: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 42..43: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 20..29: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 44..45: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 30..39: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 46..47: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + hash 1: + 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 40..41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 42..43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 44..45: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 46..47: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + hash 2: + 0..9: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 40..41: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 42..43: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 44..45: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 46..47: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + hash 3: + 0..9: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 40..41: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 42..43: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 44..45: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 46..47: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + hash 4: + 0..3: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) + 4..9: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..5) + 40..41: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + 11..14: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) + 15..19: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..4) + 10: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(5) + 42..43: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + 22..25: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) + 26..29: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..3) + 20..21: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(4..5) + 44..45: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + 33..36: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) + 37..39: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..2) + 30..32: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(3..5) + 46..47: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + hash group 0: + table: [0, 1, 2, 3, 4] + seed: 0xfd025c2f5bff + format: { action(0): 0..5, version(0): 48..51, match(0): [54..55, 32..39, 254..254, 160..239, 128..159, 240..247, 288..367, 256..287, 368..383, 40..47 ] } + match: [ hdr.inner_ipv6.next_hdr(6..7), hdr.vlan_tag$0.vid(0..7), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.0-31(0..7), hdr.inner_ipv6.src_addr.0-31(8..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] + match_group_map: [ [ 0 ], [ 0 ], [ 0 ] ] + hit: [ END ] + miss: in_ipv6_e_acl_0$st1 + action: in_ipv6_e_acl_0$st0$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_e_acl_0$st0(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x2000003b + - next_table: 0 + - { } + Eg_inner_2.in_ipv6_e.drop(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000003c + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.drop_and_count(2, 2): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000003d + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } + - bitmasked-set W16, $data0, W16 + - bitmasked-set W17, $data1, W17 + Eg_inner_2.in_ipv6_e.redirect_port(4, 4): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000003e + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.redirect_port_and_count(6, 6): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000003f + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_to_eg(8, 8): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000040 + - next_table: 0 + - { } + - set W16(29..30), 3 + Eg_inner_2.in_ipv6_e.forward_and_modify_mac(10, 10): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000041 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000042 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.set_mc(14, 14): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000043 + - next_table: 0 + - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.mc_index.0-7, mc_idx.0-7 + - set hdr.fabric.mc_index.8-15, mc_idx.8-15 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir(16, 16): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000044 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(18, 18): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000045 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + - set W17(8..26), $data1 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(20, 20): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000046 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(22, 22): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000047 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + default_action: NoAction + action in_ipv6_e_acl_0$st0$action_data: + p4: { name: Eg_inner_2.in_ipv6_e.acl_3$action } + row: [ 9, 7, 5, 3, 2, 1, 0 ] + word: [ 0, 0, 0, 0, 0, 0, 0 ] + column: + - 5 + - 5 + - 5 + - [ 1, 2, 3, 4, 5 ] + - [ 2, 3, 4, 5 ] + - [ 0, 1, 2, 3, 4, 5 ] + - 3 + vpns: + - [ 0 ] + - [ 1 ] + - [ 2 ] + - [ 3, 4, 5, 6, 7 ] + - [ 8, 9, 10, 11 ] + - [ 12, 13, 14, 15, 16, 17 ] + - [ 18 ] + home_row: + - 9 + format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 112..115 : $adf_f2, 116..119 : $adf_f3, 120..123 : $adf_f0, 124..127 : $adf_f1 } +stage 5 egress: + dependency: match + exact_match in_ipv6_e_acl_0$st1 1: + p4: { name: Eg_inner_2.in_ipv6_e.acl_3, size: 38912 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } + hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } + hdr.inner_ipv6.next_hdr: { type: exact, size: 8, full_size: 8, key_name: "in_ip_proto" } + row: [ 5, 6, 7, 2, 3, 4 ] + bus: [ 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + stash: + row: [ 5, 6, 7 ] + col: [ 2, 2, 2 ] + unit: [ 0, 0, 0 ] + ways: + - [0, 0, 0x3, [7, 2], [6, 2], [5, 2], [7, 3], [6, 3], [5, 3], [7, 4], [6, 4], [5, 4], [7, 5], [6, 5], [5, 5]] + - [0, 1, 0xc, [7, 6], [6, 6], [5, 6], [7, 7], [6, 7], [5, 7], [7, 8], [6, 8], [5, 8], [7, 9], [6, 9], [5, 9]] + - [0, 2, 0x30, [7, 10], [6, 10], [5, 10], [7, 11], [6, 11], [5, 11], [4, 2], [3, 2], [2, 2], [4, 3], [3, 3], [2, 3]] + - [0, 3, 0xc0, [4, 4], [3, 4], [2, 4], [4, 5], [3, 5], [2, 5], [4, 6], [3, 6], [2, 6], [4, 7], [3, 7], [2, 7]] + - [0, 0, 0x1, [4, 8], [3, 8], [2, 8], [4, 9], [3, 9], [2, 9]] + - [0, 1, 0x0, [4, 10], [3, 10], [2, 10]] + input_xbar: + exact group 0: { 0: hdr.inner_ipv6.src_addr.0-31(0..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.src_addr.32-63(0..23), 56: hdr.inner_ipv6.src_addr.0-31(24..31), 64: hdr.inner_ipv6.src_addr.64-95(0..23), 88: hdr.inner_ipv6.src_addr.32-63(24..31), 96: hdr.inner_ipv6.src_addr.96-127(0..23), 120: hdr.inner_ipv6.src_addr.64-95(24..31) } + exact group 1: { 0: hdr.inner_ipv6.dst_addr.0-31(0..23), 24: hdr.inner_ipv6.src_addr.96-127(24..31), 32: hdr.inner_ipv6.dst_addr.32-63(0..23), 56: hdr.inner_ipv6.dst_addr.0-31(24..31), 64: hdr.inner_ipv6.dst_addr.64-95(0..23), 88: hdr.inner_ipv6.dst_addr.32-63(24..31), 96: hdr.inner_ipv6.dst_addr.96-127(0..23), 120: hdr.inner_ipv6.dst_addr.64-95(24..31) } + exact group 2: { 0: hdr.vlan_tag$0.vid, 16: hdr.inner_ipv6.next_hdr, 24: hdr.inner_ipv6.dst_addr.96-127(24..31) } + hash 0: + 0..9: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 40..41: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 10..19: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 42..43: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 20..29: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 44..45: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 30..39: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 46..47: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + hash 1: + 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 40..41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 42..43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 44..45: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 46..47: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + hash 2: + 0..9: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 40..41: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 42..43: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 44..45: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 46..47: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + hash 3: + 0..9: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 40..41: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 42..43: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 44..45: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 46..47: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + hash 4: + 0..3: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) + 4..9: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..5) + 40..41: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + 11..14: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) + 15..19: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..4) + 10: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(5) + 42..43: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + 22..25: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) + 26..29: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..3) + 20..21: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(4..5) + 44..45: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + 33..36: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) + 37..39: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..2) + 30..32: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(3..5) + 46..47: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + hash group 0: + table: [0, 1, 2, 3, 4] + seed: 0xa77436bffcbf + format: { action(0): 0..5, version(0): 48..51, match(0): [54..55, 32..39, 254..254, 160..239, 128..159, 240..247, 288..367, 256..287, 368..383, 40..47 ] } + match: [ hdr.inner_ipv6.next_hdr(6..7), hdr.vlan_tag$0.vid(0..7), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.0-31(0..7), hdr.inner_ipv6.src_addr.0-31(8..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] + match_group_map: [ [ 0 ], [ 0 ], [ 0 ] ] + hit: [ END ] + miss: in_ipv6_e_acl$st0 + action: in_ipv6_e_acl_0$st1$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_e_acl_0$st1(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x2000003b + - next_table_miss: in_ipv6_e_acl$st0 + - next_table: 0 + - { } + Eg_inner_2.in_ipv6_e.drop(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000003c + - next_table_miss: in_ipv6_e_acl$st0 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.drop_and_count(2, 2): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000003d + - next_table_miss: in_ipv6_e_acl$st0 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } + - bitmasked-set W16, $data0, W16 + - bitmasked-set W17, $data1, W17 + Eg_inner_2.in_ipv6_e.redirect_port(4, 4): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000003e + - next_table_miss: in_ipv6_e_acl$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.redirect_port_and_count(6, 6): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000003f + - next_table_miss: in_ipv6_e_acl$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_to_eg(8, 8): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000040 + - next_table_miss: in_ipv6_e_acl$st0 + - next_table: 0 + - { } + - set W16(29..30), 3 + Eg_inner_2.in_ipv6_e.forward_and_modify_mac(10, 10): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000041 + - next_table_miss: in_ipv6_e_acl$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000042 + - next_table_miss: in_ipv6_e_acl$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.set_mc(14, 14): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000043 + - next_table_miss: in_ipv6_e_acl$st0 + - next_table: 0 + - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.mc_index.0-7, mc_idx.0-7 + - set hdr.fabric.mc_index.8-15, mc_idx.8-15 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir(16, 16): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000044 + - next_table_miss: in_ipv6_e_acl$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(18, 18): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000045 + - next_table_miss: in_ipv6_e_acl$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + - set W17(8..26), $data1 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(20, 20): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000046 + - next_table_miss: in_ipv6_e_acl$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(22, 22): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000047 + - next_table_miss: in_ipv6_e_acl$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + default_action: NoAction + action in_ipv6_e_acl_0$st1$action_data: + p4: { name: Eg_inner_2.in_ipv6_e.acl_3$action } + row: [ 9, 7, 5, 3, 2, 1, 0 ] + word: [ 0, 0, 0, 0, 0, 0, 0 ] + column: + - 5 + - 5 + - 5 + - [ 1, 2, 3, 4, 5 ] + - [ 2, 3, 4, 5 ] + - [ 0, 1, 2, 3, 4, 5 ] + - 3 + vpns: + - [ 0 ] + - [ 1 ] + - [ 2 ] + - [ 3, 4, 5, 6, 7 ] + - [ 8, 9, 10, 11 ] + - [ 12, 13, 14, 15, 16, 17 ] + - [ 18 ] + home_row: + - 9 + format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 112..115 : $adf_f2, 116..119 : $adf_f3, 120..123 : $adf_f0, 124..127 : $adf_f1 } +stage 6 egress: + dependency: match + exact_match in_ipv6_e_acl$st0 1: + p4: { name: Eg_inner_2.in_ipv6_e.acl_2, size: 38912 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } + hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } + row: [ 5, 6, 7, 2, 3, 4 ] + bus: [ 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + stash: + row: [ 5, 6, 7 ] + col: [ 2, 2, 2 ] + unit: [ 0, 0, 0 ] + ways: + - [0, 0, 0x3, [7, 2], [6, 2], [5, 2], [7, 3], [6, 3], [5, 3], [7, 4], [6, 4], [5, 4], [7, 5], [6, 5], [5, 5]] + - [0, 1, 0xc, [7, 6], [6, 6], [5, 6], [7, 7], [6, 7], [5, 7], [7, 8], [6, 8], [5, 8], [7, 9], [6, 9], [5, 9]] + - [0, 2, 0x30, [7, 10], [6, 10], [5, 10], [7, 11], [6, 11], [5, 11], [4, 2], [3, 2], [2, 2], [4, 3], [3, 3], [2, 3]] + - [0, 3, 0xc0, [4, 4], [3, 4], [2, 4], [4, 5], [3, 5], [2, 5], [4, 6], [3, 6], [2, 6], [4, 7], [3, 7], [2, 7]] + - [0, 0, 0x1, [4, 8], [3, 8], [2, 8], [4, 9], [3, 9], [2, 9]] + - [0, 1, 0x0, [4, 10], [3, 10], [2, 10]] + input_xbar: + exact group 0: { 0: hdr.inner_ipv6.src_addr.0-31(0..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.src_addr.32-63(0..23), 56: hdr.inner_ipv6.src_addr.0-31(24..31), 64: hdr.inner_ipv6.src_addr.64-95(0..23), 88: hdr.inner_ipv6.src_addr.32-63(24..31), 96: hdr.inner_ipv6.src_addr.96-127(0..23), 120: hdr.inner_ipv6.src_addr.64-95(24..31) } + exact group 1: { 0: hdr.inner_ipv6.dst_addr.0-31(0..23), 24: hdr.inner_ipv6.src_addr.96-127(24..31), 32: hdr.inner_ipv6.dst_addr.32-63(0..23), 56: hdr.inner_ipv6.dst_addr.0-31(24..31), 64: hdr.inner_ipv6.dst_addr.64-95(0..23), 88: hdr.inner_ipv6.dst_addr.32-63(24..31), 96: hdr.inner_ipv6.dst_addr.96-127(0..23), 120: hdr.inner_ipv6.dst_addr.64-95(24..31) } + exact group 2: { 0: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.dst_addr.96-127(24..31) } + hash 0: + 0..9: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 40..41: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 10..19: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 42..43: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 20..29: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 44..45: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 30..39: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 46..47: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + hash 1: + 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 40..41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 42..43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 44..45: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 46..47: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + hash 2: + 0..9: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 40..41: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 42..43: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 44..45: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 46..47: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + hash 3: + 0..9: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 40..41: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 42..43: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 44..45: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 46..47: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + hash 4: + 0..5: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) + 6..9: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) + 40..41: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + 11..16: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) + 17..19: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..10) + 10: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(11) + 42..43: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + 22..27: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) + 28..29: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..9) + 20..21: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(10..11) + 44..45: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + 33..38: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) + 39: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8) + 30..32: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(9..11) + 46..47: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + hash group 0: + table: [0, 1, 2, 3, 4] + seed: 0x93751dcdffef + format: { action(0): 0..5, version(0): 40..43, match(0): [46..47, 254..254, 160..239, 128..159, 240..247, 288..367, 256..287, 368..383, 32..39 ] } + match: [ hdr.vlan_tag$0.vid(6..7), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.0-31(0..7), hdr.inner_ipv6.src_addr.0-31(8..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] + match_group_map: [ [ 0 ], [ 0 ], [ 0 ] ] + hit: [ END ] + miss: in_ipv6_e_acl$st1 + action: in_ipv6_e_acl$st0$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_e_acl$st0(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000048 + - next_table: 0 + - { } + Eg_inner_2.in_ipv6_e.drop(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000049 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.drop_and_count(2, 2): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000004a + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } + - bitmasked-set W16, $data0, W16 + - bitmasked-set W17, $data1, W17 + Eg_inner_2.in_ipv6_e.redirect_port(4, 4): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000004b + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.redirect_port_and_count(6, 6): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000004c + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_to_eg(8, 8): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000004d + - next_table: 0 + - { } + - set W16(29..30), 3 + Eg_inner_2.in_ipv6_e.forward_and_modify_mac(10, 10): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000004e + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000004f + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.set_mc(14, 14): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000050 + - next_table: 0 + - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.mc_index.0-7, mc_idx.0-7 + - set hdr.fabric.mc_index.8-15, mc_idx.8-15 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir(16, 16): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000051 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(18, 18): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000052 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + - set W17(8..26), $data1 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(20, 20): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000053 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(22, 22): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000054 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + default_action: NoAction + action in_ipv6_e_acl$st0$action_data: + p4: { name: Eg_inner_2.in_ipv6_e.acl_2$action } + row: [ 9, 7, 5, 3, 2, 1, 0 ] + word: [ 0, 0, 0, 0, 0, 0, 0 ] + column: + - 5 + - 5 + - 5 + - [ 1, 2, 3, 4, 5 ] + - [ 2, 3, 4, 5 ] + - [ 0, 1, 2, 3, 4, 5 ] + - 3 + vpns: + - [ 0 ] + - [ 1 ] + - [ 2 ] + - [ 3, 4, 5, 6, 7 ] + - [ 8, 9, 10, 11 ] + - [ 12, 13, 14, 15, 16, 17 ] + - [ 18 ] + home_row: + - 9 + format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 112..115 : $adf_f2, 116..119 : $adf_f3, 120..123 : $adf_f0, 124..127 : $adf_f1 } +stage 7 egress: + dependency: match + exact_match in_ipv6_e_acl$st1 1: + p4: { name: Eg_inner_2.in_ipv6_e.acl_2, size: 38912 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } + hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } + row: [ 5, 6, 7, 2, 3, 4 ] + bus: [ 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + stash: + row: [ 5, 6, 7 ] + col: [ 2, 2, 2 ] + unit: [ 0, 0, 0 ] + ways: + - [0, 0, 0x3, [7, 2], [6, 2], [5, 2], [7, 3], [6, 3], [5, 3], [7, 4], [6, 4], [5, 4], [7, 5], [6, 5], [5, 5]] + - [0, 1, 0xc, [7, 6], [6, 6], [5, 6], [7, 7], [6, 7], [5, 7], [7, 8], [6, 8], [5, 8], [7, 9], [6, 9], [5, 9]] + - [0, 2, 0x30, [7, 10], [6, 10], [5, 10], [7, 11], [6, 11], [5, 11], [4, 2], [3, 2], [2, 2], [4, 3], [3, 3], [2, 3]] + - [0, 3, 0xc0, [4, 4], [3, 4], [2, 4], [4, 5], [3, 5], [2, 5], [4, 6], [3, 6], [2, 6], [4, 7], [3, 7], [2, 7]] + - [0, 0, 0x1, [4, 8], [3, 8], [2, 8], [4, 9], [3, 9], [2, 9]] + - [0, 1, 0x0, [4, 10], [3, 10], [2, 10]] + input_xbar: + exact group 0: { 0: hdr.inner_ipv6.src_addr.0-31(0..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.src_addr.32-63(0..23), 56: hdr.inner_ipv6.src_addr.0-31(24..31), 64: hdr.inner_ipv6.src_addr.64-95(0..23), 88: hdr.inner_ipv6.src_addr.32-63(24..31), 96: hdr.inner_ipv6.src_addr.96-127(0..23), 120: hdr.inner_ipv6.src_addr.64-95(24..31) } + exact group 1: { 0: hdr.inner_ipv6.dst_addr.0-31(0..23), 24: hdr.inner_ipv6.src_addr.96-127(24..31), 32: hdr.inner_ipv6.dst_addr.32-63(0..23), 56: hdr.inner_ipv6.dst_addr.0-31(24..31), 64: hdr.inner_ipv6.dst_addr.64-95(0..23), 88: hdr.inner_ipv6.dst_addr.32-63(24..31), 96: hdr.inner_ipv6.dst_addr.96-127(0..23), 120: hdr.inner_ipv6.dst_addr.64-95(24..31) } + exact group 2: { 0: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.dst_addr.96-127(24..31) } + hash 0: + 0..9: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 40..41: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 10..19: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 42..43: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 20..29: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 44..45: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 30..39: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 46..47: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + hash 1: + 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 40..41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 42..43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 44..45: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 46..47: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + hash 2: + 0..9: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 40..41: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 42..43: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 44..45: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 46..47: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + hash 3: + 0..9: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 40..41: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 42..43: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 44..45: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 46..47: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + hash 4: + 0..5: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) + 6..9: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) + 40..41: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + 11..16: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) + 17..19: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..10) + 10: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(11) + 42..43: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + 22..27: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) + 28..29: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..9) + 20..21: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(10..11) + 44..45: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + 33..38: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) + 39: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8) + 30..32: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(9..11) + 46..47: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + hash group 0: + table: [0, 1, 2, 3, 4] + seed: 0x84055d6bf57e + format: { action(0): 0..5, version(0): 40..43, match(0): [46..47, 254..254, 160..239, 128..159, 240..247, 288..367, 256..287, 368..383, 32..39 ] } + match: [ hdr.vlan_tag$0.vid(6..7), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.0-31(0..7), hdr.inner_ipv6.src_addr.0-31(8..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] + match_group_map: [ [ 0 ], [ 0 ], [ 0 ] ] + hit: [ END ] + miss: in_ipv6_e_acl_dip$st0 + action: in_ipv6_e_acl$st1$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_e_acl$st1(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000048 + - next_table_miss: in_ipv6_e_acl_dip$st0 + - next_table: 0 + - { } + Eg_inner_2.in_ipv6_e.drop(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000049 + - next_table_miss: in_ipv6_e_acl_dip$st0 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.drop_and_count(2, 2): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000004a + - next_table_miss: in_ipv6_e_acl_dip$st0 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } + - bitmasked-set W16, $data0, W16 + - bitmasked-set W17, $data1, W17 + Eg_inner_2.in_ipv6_e.redirect_port(4, 4): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000004b + - next_table_miss: in_ipv6_e_acl_dip$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.redirect_port_and_count(6, 6): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000004c + - next_table_miss: in_ipv6_e_acl_dip$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_to_eg(8, 8): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000004d + - next_table_miss: in_ipv6_e_acl_dip$st0 + - next_table: 0 + - { } + - set W16(29..30), 3 + Eg_inner_2.in_ipv6_e.forward_and_modify_mac(10, 10): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000004e + - next_table_miss: in_ipv6_e_acl_dip$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000004f + - next_table_miss: in_ipv6_e_acl_dip$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.set_mc(14, 14): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000050 + - next_table_miss: in_ipv6_e_acl_dip$st0 + - next_table: 0 + - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.mc_index.0-7, mc_idx.0-7 + - set hdr.fabric.mc_index.8-15, mc_idx.8-15 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir(16, 16): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000051 + - next_table_miss: in_ipv6_e_acl_dip$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(18, 18): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000052 + - next_table_miss: in_ipv6_e_acl_dip$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + - set W17(8..26), $data1 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(20, 20): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000053 + - next_table_miss: in_ipv6_e_acl_dip$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(22, 22): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000054 + - next_table_miss: in_ipv6_e_acl_dip$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + default_action: NoAction + action in_ipv6_e_acl$st1$action_data: + p4: { name: Eg_inner_2.in_ipv6_e.acl_2$action } + row: [ 9, 7, 5, 3, 2, 1, 0 ] + word: [ 0, 0, 0, 0, 0, 0, 0 ] + column: + - 5 + - 5 + - 5 + - [ 1, 2, 3, 4, 5 ] + - [ 2, 3, 4, 5 ] + - [ 0, 1, 2, 3, 4, 5 ] + - 3 + vpns: + - [ 0 ] + - [ 1 ] + - [ 2 ] + - [ 3, 4, 5, 6, 7 ] + - [ 8, 9, 10, 11 ] + - [ 12, 13, 14, 15, 16, 17 ] + - [ 18 ] + home_row: + - 9 + format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 112..115 : $adf_f2, 116..119 : $adf_f3, 120..123 : $adf_f0, 124..127 : $adf_f1 } +stage 8 egress: + dependency: match + exact_match in_ipv6_e_acl_dip$st0 1: + p4: { name: Eg_inner_2.in_ipv6_e.acl_dip, size: 38912 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } + row: [ 6, 7, 4, 5, 2, 3, 0, 1 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 6, 7, 8, 9, 10 ] + - [ 2, 3, 6, 7, 8, 9, 10 ] + - [ 2, 3, 6, 7, 8, 9, 10 ] + - [ 2, 3, 6, 7, 8, 9, 10 ] + - [ 2, 3, 6, 7, 8, 9, 10 ] + - [ 2, 3, 6, 7, 8, 9, 10 ] + - [ 2, 3, 6, 7, 8 ] + - [ 2, 3, 6, 7, 8 ] + stash: + row: [ 6, 7 ] + col: [ 2, 2 ] + unit: [ 0, 0 ] + ways: + - [0, 0, 0x3, [7, 2], [6, 2], [7, 3], [6, 3], [7, 6], [6, 6], [7, 7], [6, 7]] + - [0, 1, 0xc, [7, 8], [6, 8], [7, 9], [6, 9], [7, 10], [6, 10], [5, 2], [4, 2]] + - [0, 2, 0x30, [5, 3], [4, 3], [5, 6], [4, 6], [5, 7], [4, 7], [5, 8], [4, 8]] + - [0, 3, 0xc0, [5, 9], [4, 9], [5, 10], [4, 10], [3, 2], [2, 2], [3, 3], [2, 3]] + - [0, 0, 0x3, [3, 6], [2, 6], [3, 7], [2, 7], [3, 8], [2, 8], [3, 9], [2, 9]] + - [0, 1, 0xc, [3, 10], [2, 10], [1, 2], [0, 2], [1, 3], [0, 3], [1, 6], [0, 6]] + - [0, 2, 0x10, [1, 7], [0, 7], [1, 8], [0, 8]] + input_xbar: + exact group 0: { 0: hdr.inner_ipv6.dst_addr.0-31(0..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.dst_addr.32-63(0..23), 56: hdr.inner_ipv6.dst_addr.0-31(24..31), 64: hdr.inner_ipv6.dst_addr.64-95(0..23), 88: hdr.inner_ipv6.dst_addr.32-63(24..31), 96: hdr.inner_ipv6.dst_addr.96-127(0..23), 120: hdr.inner_ipv6.dst_addr.64-95(24..31) } + exact group 1: { 0: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.dst_addr.96-127(24..31) } + hash 0: + 0..9: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 40..41: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 42..43: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 44..45: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 46..47: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + hash 1: + 0..9: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 40..41: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 42..43: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 44..45: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 46..47: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + hash 2: + 0..6: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..6) + 7..9: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..10) + 41: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + 40: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(11) + 11..17: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..6) + 18..19: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..9) + 10: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(11) + 43: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + 42: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(10) + 22..28: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..6) + 29: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8) + 20..21: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(10..11) + 45: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + 44: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(9) + 33..39: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..6) + 30..32: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(9..11) + 47: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) + 46: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8) + hash group 0: + table: [0, 1, 2] + seed: 0x457c7df0a5eb + format: { action(0): 0..5, version(0): 40..43, match(0): [47..47, 254..254, 160..239, 128..159, 240..247, 32..39 ] } + match: [ hdr.vlan_tag$0.vid(7), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] + match_group_map: [ [ 0 ], [ 0 ] ] + hit: [ END ] + miss: in_ipv6_e_acl_dip$st1 + action: in_ipv6_e_acl_dip$st0$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_e_acl_dip$st0(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000055 + - next_table: 0 + - { } + Eg_inner_2.in_ipv6_e.drop(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000056 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.drop_and_count(2, 2): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000057 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } + - bitmasked-set W16, $data0, W16 + - bitmasked-set W17, $data1, W17 + Eg_inner_2.in_ipv6_e.redirect_port(4, 4): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000058 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.redirect_port_and_count(6, 6): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000059 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_to_eg(8, 8): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000005a + - next_table: 0 + - { } + - set W16(29..30), 3 + Eg_inner_2.in_ipv6_e.forward_and_modify_mac(10, 10): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000005b + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000005c + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.set_mc(14, 14): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000005d + - next_table: 0 + - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.mc_index.0-7, mc_idx.0-7 + - set hdr.fabric.mc_index.8-15, mc_idx.8-15 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir(16, 16): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000005e + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(18, 18): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000005f + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + - set W17(8..26), $data1 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(20, 20): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000060 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(22, 22): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000061 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + default_action: NoAction + action in_ipv6_e_acl_dip$st0$action_data: + p4: { name: Eg_inner_2.in_ipv6_e.acl_dip$action } + row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ] + word: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - 5 + - 5 + - 5 + - [ 4, 5 ] + - 5 + - [ 4, 5 ] + - 5 + - [ 4, 5 ] + - 5 + - [ 4, 5 ] + - 5 + - [ 4, 5 ] + - [ 3, 4, 5 ] + - [ 4, 5 ] + - [ 3, 4, 5 ] + - 5 + vpns: + - [ 0 ] + - [ 1 ] + - [ 2 ] + - [ 3, 4 ] + - [ 5 ] + - [ 6, 7 ] + - [ 8 ] + - [ 9, 10 ] + - [ 11 ] + - [ 12, 13 ] + - [ 14 ] + - [ 15, 16 ] + - [ 17, 18, 19 ] + - [ 20, 21 ] + - [ 22, 23, 24 ] + - [ 25 ] + home_row: + - [ 15, 3 ] + format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 112..115 : $adf_f2, 116..119 : $adf_f3, 120..123 : $adf_f0, 124..127 : $adf_f1 } +stage 9 egress: + dependency: match + exact_match in_ipv6_e_acl_dip$st1 3: + p4: { name: Eg_inner_2.in_ipv6_e.acl_dip, size: 38912 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } + row: [ 6, 7, 4, 5 ] + bus: [ 0, 0, 0, 0 ] + column: + - [ 2, 3, 6, 7, 8, 9, 10 ] + - [ 2, 3, 6, 7, 8, 9, 10 ] + - [ 2, 3, 6, 7, 8 ] + - [ 2, 3, 6, 7, 8 ] + stash: + row: [ 6, 7 ] + col: [ 2, 2 ] + unit: [ 0, 0 ] + ways: + - [0, 0, 0x1, [7, 2], [6, 2], [7, 3], [6, 3]] + - [0, 1, 0x2, [7, 6], [6, 6], [7, 7], [6, 7]] + - [0, 2, 0x4, [7, 8], [6, 8], [7, 9], [6, 9]] + - [0, 3, 0x8, [7, 10], [6, 10], [5, 2], [4, 2]] + - [0, 0, 0x1, [5, 3], [4, 3], [5, 6], [4, 6]] + - [0, 1, 0x2, [5, 7], [4, 7], [5, 8], [4, 8]] + input_xbar: + exact group 0: { 8: hdr.inner_ipv6.dst_addr.0-31(8..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.dst_addr.0-31(0..7), 40: hdr.inner_ipv6.dst_addr.32-63(8..23), 56: hdr.inner_ipv6.dst_addr.0-31(24..31), 64: hdr.inner_ipv6.dst_addr.32-63(0..7), 72: hdr.inner_ipv6.dst_addr.64-95(8..23), 88: hdr.inner_ipv6.dst_addr.32-63(24..31), 96: hdr.inner_ipv6.dst_addr.64-95(0..7), 104: hdr.inner_ipv6.dst_addr.96-127(8..23), 120: hdr.inner_ipv6.dst_addr.64-95(24..31) } + exact group 1: { 0: hdr.inner_ipv6.dst_addr.96-127(0..7), 8: hdr.vlan_tag$0.vid(8..11), 16: hdr.vlan_tag$0.vid(0..7), 24: hdr.inner_ipv6.dst_addr.96-127(24..31) } + hash 0: + 0..9: random(hdr.inner_ipv6.dst_addr.0-31(8..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.32-63(8..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 40: random(hdr.inner_ipv6.dst_addr.0-31(8..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.32-63(8..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.0-31(8..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.32-63(8..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 41: random(hdr.inner_ipv6.dst_addr.0-31(8..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.32-63(8..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.0-31(8..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.32-63(8..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 42: random(hdr.inner_ipv6.dst_addr.0-31(8..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.32-63(8..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.0-31(8..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.32-63(8..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + 43: random(hdr.inner_ipv6.dst_addr.0-31(8..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.32-63(8..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) + hash 1: + 0..9: random(hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.64-95(8..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.96-127(8..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 40: random(hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.64-95(8..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.96-127(8..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 10..19: random(hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.64-95(8..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.96-127(8..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 41: random(hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.64-95(8..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.96-127(8..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 20..29: random(hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.64-95(8..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.96-127(8..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 42: random(hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.64-95(8..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.96-127(8..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 30..39: random(hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.64-95(8..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.96-127(8..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + 43: random(hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.64-95(8..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.96-127(8..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) + hash 2: + 0..3: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) + 4..9: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) + 40: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(6) + 11..14: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) + 15..19: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..4) + 10: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(6) + 41: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(5) + 22..25: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) + 26..29: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..3) + 20..21: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(5..6) + 42: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(4) + 33..36: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) + 37..39: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..2) + 30..32: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(4..6) + 43: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(3) + hash group 0: + table: [0, 1, 2] + seed: 0x74b6340977c + format: { action(0): 0..5, version(0): 48..51, match(0): [55..55, 246..246, 160..239, 128..143, 32..39, 144..159, 40..47 ] } + match: [ hdr.vlan_tag$0.vid(7), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] + match_group_map: [ [ 0 ], [ 0 ] ] + hit: [ END ] + miss: in_ipv6_e_acl_sip$st0 + action: in_ipv6_e_acl_dip$st1$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_e_acl_dip$st1(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000055 + - next_table_miss: in_ipv6_e_acl_sip$st0 + - next_table: 0 + - { } + Eg_inner_2.in_ipv6_e.drop(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000056 + - next_table_miss: in_ipv6_e_acl_sip$st0 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.drop_and_count(2, 2): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000057 + - next_table_miss: in_ipv6_e_acl_sip$st0 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } + - bitmasked-set W16, $data0, W16 + - bitmasked-set W17, $data1, W17 + Eg_inner_2.in_ipv6_e.redirect_port(4, 4): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000058 + - next_table_miss: in_ipv6_e_acl_sip$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.redirect_port_and_count(6, 6): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000059 + - next_table_miss: in_ipv6_e_acl_sip$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_to_eg(8, 8): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000005a + - next_table_miss: in_ipv6_e_acl_sip$st0 + - next_table: 0 + - { } + - set W16(29..30), 3 + Eg_inner_2.in_ipv6_e.forward_and_modify_mac(10, 10): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000005b + - next_table_miss: in_ipv6_e_acl_sip$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000005c + - next_table_miss: in_ipv6_e_acl_sip$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.set_mc(14, 14): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000005d + - next_table_miss: in_ipv6_e_acl_sip$st0 + - next_table: 0 + - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.mc_index.0-7, mc_idx.0-7 + - set hdr.fabric.mc_index.8-15, mc_idx.8-15 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir(16, 16): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000005e + - next_table_miss: in_ipv6_e_acl_sip$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(18, 18): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000005f + - next_table_miss: in_ipv6_e_acl_sip$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + - set W17(8..26), $data1 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(20, 20): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000060 + - next_table_miss: in_ipv6_e_acl_sip$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(22, 22): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000061 + - next_table_miss: in_ipv6_e_acl_sip$st0 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + default_action: NoAction + action in_ipv6_e_acl_dip$st1$action_data: + p4: { name: Eg_inner_2.in_ipv6_e.acl_dip$action } + row: [ 6, 5, 4, 3, 2, 1 ] + word: [ 0, 0, 0, 0, 0, 0 ] + column: + - 5 + - 5 + - [ 4, 5 ] + - [ 2, 3, 4, 5 ] + - 5 + - [ 2, 3, 4 ] + vpns: + - [ 0 ] + - [ 1 ] + - [ 2, 3 ] + - [ 4, 5, 6, 7 ] + - [ 8 ] + - [ 9, 10, 11 ] + home_row: + - 6 + format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 1 : $adf_b1, 36..37 : $adf_h0, 112..115 : $adf_f2, 116..119 : $adf_f3, 120..123 : $adf_f0, 124..127 : $adf_f1 } + exact_match in_ipv6_e_acl_sip$st0 4: + p4: { name: Eg_inner_2.in_ipv6_e.acl_sip, size: 38912 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } + row: [ 4, 5, 2, 3, 0, 1 ] + bus: [ 1, 1, 0, 0, 0, 0 ] + column: + - [ 9, 10 ] + - [ 9, 10 ] + - [ 2, 3, 6, 7, 8, 9, 10 ] + - [ 2, 3, 6, 7, 8, 9, 10 ] + - [ 2, 3, 6, 7 ] + - [ 2, 3, 6, 7 ] + stash: + row: [ 4, 5 ] + col: [ 9, 9 ] + unit: [ 0, 0 ] + ways: + - [1, 0, 0x1, [5, 9], [4, 9], [5, 10], [4, 10]] + - [1, 1, 0x2, [3, 2], [2, 2], [3, 3], [2, 3]] + - [1, 2, 0x4, [3, 6], [2, 6], [3, 7], [2, 7]] + - [1, 3, 0x8, [3, 8], [2, 8], [3, 9], [2, 9]] + - [1, 0, 0x1, [3, 10], [2, 10], [1, 2], [0, 2]] + - [1, 1, 0x2, [1, 3], [0, 3], [1, 6], [0, 6]] + - [1, 2, 0x0, [1, 7], [0, 7]] + input_xbar: + exact group 1: { 64: hdr.inner_ipv6.src_addr.0-31(0..23), 94: hdr.fabric.is_hit, 96: hdr.inner_ipv6.src_addr.32-63(0..23), 120: hdr.inner_ipv6.src_addr.0-31(24..31) } + exact group 2: { 0: hdr.inner_ipv6.src_addr.64-95(0..23), 24: hdr.inner_ipv6.src_addr.32-63(24..31), 32: hdr.inner_ipv6.src_addr.96-127(0..23), 56: hdr.inner_ipv6.src_addr.64-95(24..31), 64: hdr.vlan_tag$0.vid, 88: hdr.inner_ipv6.src_addr.96-127(24..31) } + hash 3: + 0..7: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.inner_ipv6.src_addr.0-31(0..7) + 8: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.inner_ipv6.src_addr.0-31(8) + 9: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.fabric.is_hit + 40: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 11..18: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.inner_ipv6.src_addr.0-31(0..7) + 19: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.inner_ipv6.src_addr.0-31(8) + 10: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.fabric.is_hit + 41: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 22..29: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.inner_ipv6.src_addr.0-31(0..7) + 20: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.inner_ipv6.src_addr.0-31(8) + 21: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.fabric.is_hit + 42: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 33..39: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.inner_ipv6.src_addr.0-31(0..6) + 30: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.inner_ipv6.src_addr.0-31(7) + 31: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.inner_ipv6.src_addr.0-31(8) + 32: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.fabric.is_hit + 43: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + hash 4: + 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 40: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 42: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + hash 5: + 0..9: random(hdr.vlan_tag$0.vid, hdr.inner_ipv6.src_addr.96-127(24..31)) + 40: random(hdr.vlan_tag$0.vid, hdr.inner_ipv6.src_addr.96-127(24..31)) + 10..19: random(hdr.vlan_tag$0.vid, hdr.inner_ipv6.src_addr.96-127(24..31)) + 41: random(hdr.vlan_tag$0.vid, hdr.inner_ipv6.src_addr.96-127(24..31)) + 20..29: random(hdr.vlan_tag$0.vid, hdr.inner_ipv6.src_addr.96-127(24..31)) + 42: random(hdr.vlan_tag$0.vid, hdr.inner_ipv6.src_addr.96-127(24..31)) + 30..39: random(hdr.vlan_tag$0.vid, hdr.inner_ipv6.src_addr.96-127(24..31)) + 43: random(hdr.vlan_tag$0.vid, hdr.inner_ipv6.src_addr.96-127(24..31)) + hash group 1: + table: [3, 4, 5] + seed: 0x93dbbf23750 + format: { action(0): 0..5, version(0): 112..115, match(0): [160..167, 128..131, 73..79, 32..71, 168..239 ] } + match: [ hdr.vlan_tag$0.vid(0..7), hdr.vlan_tag$0.vid(8..11), hdr.inner_ipv6.src_addr.0-31(9..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31) ] + match_group_map: [ [ 0 ], [ 0 ] ] + hit: [ END ] + miss: in_ipv6_e_acl_sip$st1 + action: in_ipv6_e_acl_sip$st0$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_e_acl_sip$st0(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000062 + - next_table: 0 + - { } + Eg_inner_2.in_ipv6_e.drop(24, 24): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000063 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.drop_and_count(26, 26): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000064 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } + - bitmasked-set W16, $data0, W16 + - bitmasked-set W17, $data1, W17 + Eg_inner_2.in_ipv6_e.redirect_port(28, 28): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000065 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.redirect_port_and_count(30, 30): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000066 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_to_eg(32, 32): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000067 + - next_table: 0 + - { } + - set W16(29..30), 3 + Eg_inner_2.in_ipv6_e.forward_and_modify_mac(34, 34): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000068 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(36, 36): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000069 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.set_mc(38, 38): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000006a + - next_table: 0 + - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.mc_index.0-7, mc_idx.0-7 + - set hdr.fabric.mc_index.8-15, mc_idx.8-15 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir(40, 40): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000006b + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(42, 42): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000006c + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + - set W17(8..26), $data1 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(44, 44): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000006d + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(46, 46): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000006e + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + default_action: NoAction + action in_ipv6_e_acl_sip$st0$action_data: + p4: { name: Eg_inner_2.in_ipv6_e.acl_sip$action } + row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6 ] + word: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - 5 + - 5 + - 5 + - [ 4, 5 ] + - 5 + - [ 4, 5 ] + - 5 + - [ 4, 5 ] + - 5 + - 4 + vpns: + - [ 0 ] + - [ 1 ] + - [ 2 ] + - [ 3, 4 ] + - [ 5 ] + - [ 6, 7 ] + - [ 8 ] + - [ 9, 10 ] + - [ 11 ] + - [ 12 ] + home_row: + - 15 + format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 5 : $adf_b1, 40..41 : $adf_h0, 64..67 : $adf_f2, 68..71 : $adf_f3, 72..75 : $adf_f0, 76..79 : $adf_f1 } +stage 10 egress: + dependency: match + exact_match in_ipv6_e_acl_sip$st1 0: + p4: { name: Eg_inner_2.in_ipv6_e.acl_sip, size: 38912 } + p4_param_order: + hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } + hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } + hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } + row: [ 6, 7, 4, 5, 2, 3, 0, 1 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 5, 6, 7, 8 ] + - [ 2, 3, 4, 5, 6, 7, 8 ] + - [ 2, 3, 4, 5, 6, 7, 8 ] + - [ 2, 3, 4, 5, 6, 7, 8 ] + - [ 2, 3, 4, 5, 6, 7, 8 ] + - [ 2, 3, 4, 5, 6, 7, 8 ] + - [ 2, 3, 4, 5 ] + - [ 2, 3, 4, 5 ] + stash: + row: [ 6, 7 ] + col: [ 2, 2 ] + unit: [ 0, 0 ] + ways: + - [0, 0, 0x3, [7, 2], [6, 2], [7, 3], [6, 3], [7, 4], [6, 4], [7, 5], [6, 5]] + - [0, 1, 0xc, [7, 6], [6, 6], [7, 7], [6, 7], [7, 8], [6, 8], [5, 2], [4, 2]] + - [0, 2, 0x30, [5, 3], [4, 3], [5, 4], [4, 4], [5, 5], [4, 5], [5, 6], [4, 6]] + - [0, 3, 0xc0, [5, 7], [4, 7], [5, 8], [4, 8], [3, 2], [2, 2], [3, 3], [2, 3]] + - [0, 0, 0x3, [3, 4], [2, 4], [3, 5], [2, 5], [3, 6], [2, 6], [3, 7], [2, 7]] + - [0, 1, 0xc, [3, 8], [2, 8], [1, 2], [0, 2], [1, 3], [0, 3], [1, 4], [0, 4]] + - [0, 2, 0x0, [1, 5], [0, 5]] + input_xbar: + exact group 0: { 0: hdr.inner_ipv6.src_addr.0-31(0..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.src_addr.32-63(0..23), 56: hdr.inner_ipv6.src_addr.0-31(24..31), 64: hdr.inner_ipv6.src_addr.64-95(0..23), 88: hdr.inner_ipv6.src_addr.32-63(24..31), 96: hdr.inner_ipv6.src_addr.96-127(0..23), 120: hdr.inner_ipv6.src_addr.64-95(24..31) } + exact group 1: { 0: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.src_addr.96-127(24..31) } + hash 0: + 0..9: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 40..41: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 10..19: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 42..43: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 20..29: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 44..45: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 30..39: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + 46..47: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) + hash 1: + 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 40..41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 42..43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 44..45: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + 46..47: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) + hash 2: + 0..5: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) + 6..9: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) + 40..41: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) + 11..16: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) + 17..19: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..10) + 10: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(11) + 42..43: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) + 22..27: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) + 28..29: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..9) + 20..21: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(10..11) + 44..45: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) + 33..38: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) + 39: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8) + 30..32: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(9..11) + 46..47: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) + hash group 0: + table: [0, 1, 2] + seed: 0xa950ff70f805 + format: { action(0): 0..5, version(0): 40..43, match(0): [46..47, 254..254, 160..239, 128..159, 240..247, 32..39 ] } + match: [ hdr.vlan_tag$0.vid(6..7), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.0-31(0..7), hdr.inner_ipv6.src_addr.0-31(8..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31) ] + match_group_map: [ [ 0 ], [ 0 ] ] + hit: [ END ] + miss: END + action: in_ipv6_e_acl_sip$st1$action_data($DIRECT, $DEFAULT) + instruction: in_ipv6_e_acl_sip$st1(action, $DEFAULT) + actions: + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000062 + - next_table: 0 + - { } + Eg_inner_2.in_ipv6_e.drop(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000063 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.flags_drop, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.drop_and_count(2, 2): + - p4_param_order: { count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000064 + - next_table: 0 + - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } + - bitmasked-set W16, $data0, W16 + - bitmasked-set W17, $data1, W17 + Eg_inner_2.in_ipv6_e.redirect_port(4, 4): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000065 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.redirect_port_and_count(6, 6): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000066 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_to_eg(8, 8): + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000067 + - next_table: 0 + - { } + - set W16(29..30), 3 + Eg_inner_2.in_ipv6_e.forward_and_modify_mac(10, 10): + - p4_param_order: { mac_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000068 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(12, 12): + - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x20000069 + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.set_mc(14, 14): + - p4_param_order: { mc_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000006a + - next_table: 0 + - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.mc_index.0-7, mc_idx.0-7 + - set hdr.fabric.mc_index.8-15, mc_idx.8-15 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir(16, 16): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000006b + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.is_trunc_mir, 1 + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(18, 18): + - p4_param_order: { count_idx: 18, vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000006c + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + - set W17(8..26), $data1 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(20, 20): + - p4_param_order: { vlan_idx: 16 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000006d + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } + - set hdr.fabric.vlan_index, vlan_idx + - bitmasked-set W16, $data0, W16 + Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(22, 22): + - p4_param_order: { vlan_idx: 16, count_idx: 18 } + - hit_allowed: { allowed: true } + - default_action: { allowed: false, reason: has_const_default_action } + - handle: 0x2000006e + - next_table: 0 + - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } + - set hdr.fabric.vlan_index, vlan_idx + - set hdr.fabric.count_index, count_idx + - bitmasked-set W16, $data0, W16 + default_action: NoAction + action in_ipv6_e_acl_sip$st1$action_data: + p4: { name: Eg_inner_2.in_ipv6_e.acl_sip$action } + row: [ 15, 13, 11, 9, 7, 5, 3, 1 ] + word: [ 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - 5 + - [ 4, 5 ] + - [ 3, 4, 5 ] + - [ 3, 4, 5 ] + - [ 3, 4, 5 ] + - [ 3, 4, 5 ] + - [ 1, 2, 3, 4, 5 ] + - [ 0, 1, 2, 3, 4 ] + vpns: + - [ 0 ] + - [ 1, 2 ] + - [ 3, 4, 5 ] + - [ 6, 7, 8 ] + - [ 9, 10, 11 ] + - [ 12, 13, 14 ] + - [ 15, 16, 17, 18, 19 ] + - [ 20, 21, 22, 23, 24 ] + home_row: + - [ 15, 3 ] + format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } + format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } + action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } + + +primitives: "./network_tap/pp_inner_2//network_tap.prim.json" +dynhash: "./network_tap/pp_inner_2//network_tap.dynhash.json" diff --git a/backends/tofino/bf-asm/test/asm/p4c-2257.bfa b/backends/tofino/bf-asm/test/asm/p4c-2257.bfa new file mode 100644 index 00000000000..99aa0db048e --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/p4c-2257.bfa @@ -0,0 +1,16228 @@ +version: + version: 1.0.1 + run_id: "e8fcabd5512471f2" + target: Tofino +phv ingress: + HillTop.Lamona.Fristoe: W14(8..21) + HillTop.Lamona.Traverse: H1(0..11) + HillTop.Lamona.Pachuta: B34(0) + HillTop.Lamona.Whitefish: W0(0..1) + Millston.Belgrade.Roachdale: H6(8..15) + Millston.Belgrade.Rugby: H6(5..7) + Millston.Belgrade.Davie: H6(4) + Millston.Belgrade.Cacao: H6(0..3) + Millston.Belgrade.Mankato: B36 + Millston.Belgrade.Virgil: W13(8..31) + Millston.Belgrade.Florin.0-15: H63 + Millston.Belgrade.Florin.16-23: W13(0..7) + Millston.Belgrade.Ronan: TW12 + Millston.Belgrade.Corinth: H51 + Millston.Belgrade.__pad_0: B11(4..7) + Millston.Belgrade.Union: B11(1..3) + Millston.Belgrade.Rockport: B11(0) + Millston.Belgrade.__pad_1: B9(6..7) + Millston.Belgrade.Anacortes: B9(5) + Millston.Belgrade.Shabbona: B9(4) + Millston.Belgrade.Allgood: B9(1..3) + Millston.Belgrade.Waipahu: B9(0) + Millston.Belgrade.__pad_2: B34(1..7) + Millston.Belgrade.Freeburg: B34(0) + Millston.Belgrade.__pad_3: W1(8..31) + Millston.Belgrade.Sudbury: W1(2..7) + Millston.Belgrade.Selawik: W1(0..1) + Millston.Belgrade.__pad_4: B7(3..7) + Millston.Belgrade.Willard: B7(0..2) + Millston.Belgrade.__pad_5: H90(6..15) + Millston.Belgrade.Matheson: H90(0..5) + Millston.Belgrade.__pad_6: H48(9..15) + Millston.Belgrade.Chaska: H48(0..8) + Millston.Belgrade.__pad_7: H2(12..15) + Millston.Belgrade.Requa: H2(0..11) + Millston.Belgrade.__pad_8: H4(12..15) + Millston.Belgrade.Bayshore: H4(0..11) + Millston.Belgrade.__pad_9: H3(12..15) + Millston.Belgrade.Florien: H3(0..11) + HillTop.Tiburon.Arnold: H53(0..8) + Millston.Hayfield.Blitchton: W48(26..31) + Millston.Hayfield.Avondale: W48(16..25) + Millston.Hayfield.Glassboro: W48(12..15) + Millston.Hayfield.Grabill: W48(0..11) + Millston.Hayfield.AquaPark: B47(6..7) + Millston.Hayfield.Vichy: B47(3..5) + Millston.Calabash.Adona: W12(8..31) + Millston.Calabash.Connell.0-15: H54 + Millston.Calabash.Connell.16-23: W12(0..7) + Millston.Calabash.Goldsboro.0-7: W6(24..31) + Millston.Calabash.Goldsboro.8-23: H36 + Millston.Calabash.Fabens: W6(0..23) + Millston.Calabash.McCaulley.0-7: B50 + Millston.Calabash.McCaulley.8-15: B53 + Millston.Wondervu$0.Higginson: H0(13..15) + Millston.Wondervu$0.Oriskany: H0(12) + Millston.Wondervu$0.Bowden: H0(0..11) + Millston.Wondervu$0.McCaulley.0-7: B48 + Millston.Wondervu$0.McCaulley.8-15: B51 + Millston.Wondervu$1.Higginson: TH24(13..15) + Millston.Wondervu$1.Oriskany: TH24(12) + Millston.Wondervu$1.Bowden: TH24(0..11) + Millston.Wondervu$1.McCaulley.0-7: B49 + Millston.Wondervu$1.McCaulley.8-15: B52 + Millston.Rainelle.Conner: TW1(16..31) + Millston.Rainelle.Ledoux: TW1(0..15) + Millston.Rainelle.Steger: TH0(8..15) + Millston.Rainelle.Quogue: TH0(0..7) + Millston.Rainelle.Findlay: H35 + Millston.GlenAvon.Fayette: H89(12..15) + Millston.GlenAvon.Osterdock: H89(8..11) + Millston.GlenAvon.PineCity: H89(2..7) + Millston.GlenAvon.Alameda: H89(0..1) + Millston.GlenAvon.Rexville: H38 + Millston.GlenAvon.Quinwood: TW0(16..31) + Millston.GlenAvon.Marfa: TW0(15) + Millston.GlenAvon.Palatine: TW0(14) + Millston.GlenAvon.Mabelle: TW0(13) + Millston.GlenAvon.Hoagland: TW0(0..12) + Millston.GlenAvon.Exton: TB1 + Millston.GlenAvon.Ocoee: B33 + Millston.GlenAvon.Hackett: TH25 + Millston.GlenAvon.Kaluaaha: W32 + Millston.GlenAvon.Calcasieu: W33 + HillTop.Aldan.Vinemont: B42 + HillTop.Aldan.Kenbridge: B58 + HillTop.Aldan.Parkville: B13(0..3) + HillTop.Aldan.Mystic.0-1: B10(4..5) + HillTop.Aldan.Mystic.2-2: B14(0) + HillTop.Aldan.Kearns.0-0: B7(0) + HillTop.Aldan.Kearns.1-2: H50(0..1) + HillTop.Aldan.Malinta.0-0: B8(0) + HillTop.Aldan.Malinta.1-2: H56(0..1) + HillTop.Aldan.Blakeley: H63(0) + HillTop.Aldan.Poulan: H48(0) + HillTop.RossFork.Adona: W0(2..25) + HillTop.RossFork.Connell.0-15: H55 + HillTop.RossFork.Connell.16-23: W14(0..7) + HillTop.RossFork.Goldsboro.0-7: W8(0..7) + HillTop.RossFork.Goldsboro.8-23: H37 + HillTop.RossFork.Fabens: W7(0..23) + HillTop.RossFork.McCaulley.0-7: B56 + HillTop.RossFork.McCaulley.8-15: B57 + HillTop.RossFork.CeeVee: H4(0..11) + HillTop.RossFork.Quebrada: W4(0..19) + HillTop.RossFork.Bicknell: H3(0..11) + HillTop.RossFork.Ocoee: B44 + HillTop.RossFork.Exton: B59 + HillTop.RossFork.Naruna.0-1: B8(3..4) + HillTop.RossFork.Naruna.2-2: B13(5) + HillTop.RossFork.Suttle: B2(0) + HillTop.RossFork.Ankeny: B45 + HillTop.RossFork.Denhoff.0-0: B7(3) + HillTop.RossFork.Denhoff.1-2: H62(2..3) + HillTop.RossFork.Joslin: H34(5..7) + HillTop.RossFork.Weyauwega: B12(5) + HillTop.RossFork.Powderly: B11(6) + HillTop.RossFork.Welcome: H85(6) + HillTop.RossFork.Teigen: B38(0) + HillTop.RossFork.Lowes: B15(5) + HillTop.RossFork.Almedia: H14(12) + HillTop.RossFork.Chugwater: B15(6) + HillTop.RossFork.Charco: B12(6) + HillTop.RossFork.Daphne: B12(7) + HillTop.RossFork.Level: B15(4) + HillTop.RossFork.Algoa: W11(1) + HillTop.RossFork.Thayne: B5(0) + HillTop.RossFork.Parkland: H62(1) + HillTop.RossFork.Kapalua: W10(8) + HillTop.RossFork.Halaula: W1(8) + HillTop.RossFork.Uvalde: W9(9) + HillTop.RossFork.Tenino: H66(14) + HillTop.RossFork.Pridgen: H66(15) + HillTop.RossFork.Juniata: H95(11) + HillTop.RossFork.Beaverdam: W1(18) + HillTop.RossFork.ElVerano: B12(2) + HillTop.RossFork.Brinkman: B8(5) + HillTop.RossFork.Boerne: B3(0) + HillTop.RossFork.Alamosa: B12(3) + HillTop.RossFork.Knierim: W1(19..30) + HillTop.RossFork.Montross: W39(0..11) + HillTop.RossFork.Glenmora: H11 + HillTop.RossFork.DonaAna: H40 + HillTop.RossFork.Altus: H61 + HillTop.RossFork.Merrill: H41 + HillTop.RossFork.Hickox: H42 + HillTop.RossFork.Tehachapi: H43 + HillTop.RossFork.Sewaren: H90(12..13) + HillTop.RossFork.WindGap: H90(14) + HillTop.RossFork.Caroleen: H3(14..15) + HillTop.RossFork.Lordstown: H90(15) + HillTop.RossFork.Belfair: H14(14) + HillTop.RossFork.Luzerne: H65(0..13) + HillTop.RossFork.Devers: H66(0..13) + HillTop.RossFork.Crozet: H5 + HillTop.RossFork.Laxon: W38 + HillTop.RossFork.Chaffee: H14(0..7) + HillTop.RossFork.Brinklow: W1(9..16) + HillTop.RossFork.Everton: W49(0..15) + HillTop.RossFork.Lafayette: B55 + HillTop.RossFork.Chevak: H9 + HillTop.RossFork.Mendocino: H32 + HillTop.RossFork.Kremlin: B40 + HillTop.RossFork.TroutRun: H65(14..15) + HillTop.RossFork.Bradner: H3(12..13) + HillTop.RossFork.Ravena: H4(12) + HillTop.RossFork.Redden: B6(0) + HillTop.RossFork.Yaurel: B9(0) + HillTop.RossFork.Bucktown: W51 + HillTop.RossFork.Hulbert: H62(12..13) + Millston.Ramos.Fayette: TW1(28..31) + Millston.Ramos.Osterdock: TW1(24..27) + Millston.Ramos.PineCity: TW1(18..23) + Millston.Ramos.Alameda: TW1(16..17) + Millston.Ramos.Rexville: TW1(0..15) + Millston.Ramos.Quinwood: TW2(16..31) + Millston.Ramos.Marfa: TW2(15) + Millston.Ramos.Palatine: TW2(14) + Millston.Ramos.Mabelle: TW2(13) + Millston.Ramos.Hoagland: TW2(0..12) + Millston.Ramos.Exton: TH1(8..15) + Millston.Ramos.Ocoee: TH1(0..7) + Millston.Ramos.Hackett: TH2 + Millston.Ramos.Kaluaaha: TW13 + Millston.Ramos.Calcasieu: TW14 + HillTop.Maddock.Kaluaaha: W37 + HillTop.Maddock.Calcasieu: W36 + HillTop.Maddock.PineCity: H83(2..7) + Millston.Bergton.Chevak: W47(16..31) + Millston.Bergton.Mendocino: W47(0..15) + Millston.Pawtucket.StarLake: TH5 + Millston.Buckhorn.SoapLake: TH26 + Millston.Cassa.Chloride: TW15 + Millston.Cassa.Garibaldi.0-15: TH5 + Millston.Cassa.Garibaldi.16-31: TH18 + Millston.Cassa.Weinert: TW3(28..31) + Millston.Cassa.Cornell: TW3(24..27) + Millston.Cassa.Noyes: TW3(16..23) + Millston.Cassa.Helton: TW3(0..15) + Millston.Provencal.Fayette: TB3(4..7) + Millston.Provencal.PineCity.0-1: H35(14..15) + Millston.Provencal.PineCity.2-5: TB3(0..3) + Millston.Provencal.Alameda: H35(12..13) + Millston.Provencal.Maryhill.0-7: B39 + Millston.Provencal.Maryhill.8-19: H35(0..11) + Millston.Provencal.Norwood: TW1(16..31) + Millston.Provencal.Dassel: TW1(8..15) + Millston.Provencal.Bushland: TW1(0..7) + Millston.Provencal.Kaluaaha.0-31: TW2 + Millston.Provencal.Kaluaaha.32-63: TW13 + Millston.Provencal.Kaluaaha.64-95: TW14 + Millston.Provencal.Kaluaaha.96-111: TH1 + Millston.Provencal.Kaluaaha.112-127: TH2 + Millston.Provencal.Calcasieu.0-15: TH19 + Millston.Provencal.Calcasieu.16-31: TH20 + Millston.Provencal.Calcasieu.32-47: TH21 + Millston.Provencal.Calcasieu.48-63: TH22 + Millston.Provencal.Calcasieu.64-71: TB12 + Millston.Provencal.Calcasieu.72-79: TB13 + Millston.Provencal.Calcasieu.80-95: TH23 + Millston.Provencal.Calcasieu.96-127: TW16 + HillTop.Sublett.Kaluaaha.0-31: W37 + HillTop.Sublett.Kaluaaha.32-63: W3 + HillTop.Sublett.Kaluaaha.64-95: W39 + HillTop.Sublett.Kaluaaha.96-127: W40 + HillTop.Sublett.Calcasieu.0-31: W44 + HillTop.Sublett.Calcasieu.32-63: W45 + HillTop.Sublett.Calcasieu.64-95: W46 + HillTop.Sublett.Calcasieu.96-127: W36 + HillTop.Sublett.PineCity: H84(6..11) + Millston.Grays.Chevak: H10 + Millston.Grays.Mendocino: H33 + Millston.Gotham.StarLake.0-7: TB2 + Millston.Gotham.StarLake.8-15: TB14 + Millston.Brookneal.SoapLake: W50(0..15) + Millston.Hoven.Noyes: TB0 + Millston.Hoven.Allison.0-7: TH3(8..15) + Millston.Hoven.Allison.8-23: TH4 + Millston.Hoven.Petrey.0-15: TH27 + Millston.Hoven.Petrey.16-23: TH3(0..7) + Millston.Hoven.Roosville: B32 + Millston.Shirley.Adona: W15(8..31) + Millston.Shirley.Connell.0-15: H39 + Millston.Shirley.Connell.16-23: W15(0..7) + Millston.Shirley.Goldsboro.0-7: B35 + Millston.Shirley.Goldsboro.8-23: H92 + Millston.Shirley.Fabens.0-7: B37 + Millston.Shirley.Fabens.8-23: H93 + Millston.Shirley.McCaulley: H94 + Millston.Osyka.Chloride: TW1 + Millston.Osyka.Garibaldi: TW2 + Millston.Osyka.Weinert: TB0(4..7) + Millston.Osyka.Cornell: TB0(0..3) + Millston.Osyka.Noyes: B32 + Millston.Osyka.Helton: TH0 + Millston.Broadwell.Palmhurst: TH0(15) + Millston.Broadwell.Comfrey: TH0(14) + Millston.Broadwell.Kalida: TH0(13) + Millston.Broadwell.Wallula: TH0(12) + Millston.Broadwell.Dennison: TH0(11) + Millston.Broadwell.Fairhaven: TH0(8..10) + Millston.Broadwell.Noyes: TH0(3..7) + Millston.Broadwell.Woodfield: TH0(0..2) + Millston.Broadwell.LasVegas.0-7: TB0 + Millston.Broadwell.LasVegas.8-15: TB2 + Millston.Maumee.Fayette: H89(12..15) + Millston.Maumee.PineCity: H89(6..11) + Millston.Maumee.Alameda: H89(4..5) + Millston.Maumee.Maryhill.0-15: H38 + Millston.Maumee.Maryhill.16-19: H89(0..3) + Millston.Maumee.Norwood.0-7: B37 + Millston.Maumee.Norwood.8-15: B35 + Millston.Maumee.Dassel: B33 + Millston.Maumee.Bushland: TB1 + Millston.Maumee.Kaluaaha.0-31: W33 + Millston.Maumee.Kaluaaha.32-63: W15 + Millston.Maumee.Kaluaaha.64-95: W34 + Millston.Maumee.Kaluaaha.96-127: W35 + Millston.Maumee.Calcasieu.0-31: W41 + Millston.Maumee.Calcasieu.32-63: W42 + Millston.Maumee.Calcasieu.64-95: W43 + Millston.Maumee.Calcasieu.96-127: W32 + HillTop.Cutten.Pathfork: H59 + HillTop.Cutten.Tombstone: H56 + HillTop.Cutten.Subiaco: H58 + HillTop.Cutten.Marcus: H60 + HillTop.Cutten.Pittsboro: H57 + HillTop.Wisdom.Adona: W13(8..31) + HillTop.Wisdom.Connell.0-15: H63 + HillTop.Wisdom.Connell.16-23: W13(0..7) + HillTop.Wisdom.Dyess: B11(0) + HillTop.Wisdom.Westhoff: B9(1..3) + HillTop.Wisdom.Havana: W11(0) + HillTop.Wisdom.Nenana: H2(0..11) + HillTop.Wisdom.Morstein: W3(0..19) + HillTop.Wisdom.Waubun: W1(2..7) + HillTop.Wisdom.Onycha: B11(1..3) + HillTop.Wisdom.Blencoe: B36 + HillTop.Wisdom.Delavan: B15(7) + HillTop.Wisdom.Miller: H48(0..8) + HillTop.Wisdom.Piqua: B9(4) + HillTop.Wisdom.RioPecos: B9(0) + HillTop.Wisdom.Dolores: W1(0..1) + HillTop.Edwards.AquaPark: B14(5..6) + HillTop.Edwards.LaConner: H86(0..5) + HillTop.Edwards.McGrady: B14(2..4) + HillTop.Edwards.Oilmont: B7(4) + HillTop.Edwards.Tornillo: B7(5) + HillTop.Edwards.Satolah: W1(17) + HillTop.Edwards.RedElm: H6(5..7) + HillTop.Edwards.Oriskany: H6(4) + HillTop.Edwards.PineCity: H90(0..5) + HillTop.Edwards.Pajaros: B56(0..4) + HillTop.Murphy.Standish: B15(3) + HillTop.Murphy.Blairsden: H64(14) + HillTop.Bessie.Kaluaaha: H48 + HillTop.Bessie.Calcasieu: H46 + HillTop.Bessie.Heuvelton: W11(2..17) + HillTop.Bessie.Chavies: H8 + HillTop.Bessie.Chevak: H12 + HillTop.Bessie.Mendocino: H44 + HillTop.Bessie.LasVegas: B43 + HillTop.Bessie.Exton: B60 + HillTop.Bessie.Noyes: B41 + HillTop.Bessie.Miranda: H62(4..11) + HillTop.Bessie.Peebles: B9(5) + HillTop.Bessie.PineCity: H90(6..11) + HillTop.Ovett.Manilla: B4 + HillTop.Ovett.Hammond.0-0: H14(11) + HillTop.Ovett.Hammond.1-3: H14(8..10) + HillTop.Ovett.Hematite: H4(13) + HillTop.Mausdale.Kenney: W5 + HillTop.Quinault.Foster: B11(4..5) + HillTop.Savery.Kaluaaha: H49 + HillTop.Savery.Calcasieu: H47 + HillTop.Savery.Chevak: H13 + HillTop.Savery.Mendocino: H45 + HillTop.Savery.LasVegas: B42 + HillTop.Savery.Exton: B58 + HillTop.Savery.Noyes: B40 + HillTop.Savery.Peebles: B10(5) + HillTop.Savery.PineCity: H85(6..11) + HillTop.Naubinway.Ayden: B9(6..7) + HillTop.Naubinway.Bonduel: H64(0..13) + HillTop.Naubinway.Sardinia: H64(0..13) + HillTop.Lewiston.Staunton: H51 + HillTop.Lewiston.Lugert: H61 + HillTop.Salix.Hueytown: H15 + HillTop.Komatke.Townville.0-11: H1(0..11) + HillTop.Komatke.Townville.12-15: H5(12..15) + HillTop.Komatke.Monahans: B12(4) + HillTop.Komatke.Pinole: H62(0) + HillTop.Freeny.Dunedin: B8(0..2) + ig_intr_md_for_tm.ucast_egress_port: W2(0..8) + ig_intr_md_for_tm.ingress_cos: B8(0..2) + ig_intr_md_for_tm.qid: B13(0..4) + ig_intr_md_for_tm.copy_to_cpu: H52(0) + ig_intr_md_for_tm.mcast_grp_a: H7 + ig_intr_md_for_tm.level2_mcast_hash: H50(0..12) + ig_intr_md_for_tm.level1_exclusion_id: H8 + ig_intr_md_for_tm.level2_exclusion_id: W9(0..8) + ig_intr_md_for_tm.rid: H5 + HillTop.Minturn.Grassflat: H34(0..9) + HillTop.Minturn.Whitewood: H34(0..9) + HillTop.Minturn.Tilton: B14(0..1) + HillTop.Moose.Townville: H8 + HillTop.Moose.Monahans: H14(13) + HillTop.Moose.Pinole: H56(0) + ig_intr_md_for_dprsr.drop_ctl: B15(0..2) + ig_intr_md_for_dprsr.digest_type: B0(0..2) + ig_intr_md_for_dprsr.mirror_type: B1(0..2) + HillTop.Plains.Roachdale: B38 + HillTop.Plains.Miller: H57(0..8) + Millston.Belgrade.$valid: B54(0) + Millston.Hayfield.$valid: B54(1) + Millston.Calabash.$valid: B54(2) + Millston.Rainelle.$valid: B54(3) + Millston.GlenAvon.$valid: B54(4) + Millston.Ramos.$valid: B54(5) + Millston.Bergton.$valid: B54(6) + Millston.Pawtucket.$valid: B54(7) + Millston.Buckhorn.$valid: H95(0) + Millston.Cassa.$valid: H95(1) + Millston.Provencal.$valid: H95(2) + Millston.Grays.$valid: H95(3) + Millston.Gotham.$valid: H95(4) + Millston.Brookneal.$valid: H95(5) + Millston.Hoven.$valid: H95(7) + Millston.Shirley.$valid: H95(8) + Millston.Osyka.$valid: H95(6) + Millston.Broadwell.$valid: H95(9) + Millston.Maumee.$valid: H95(10) + Millston.Wondervu.$stkvalid: B12(0..1) + Millston.Wondervu$0.$valid: B12(1) + Millston.Wondervu$1.$valid: B12(0) + context_json: + TB0: + Millston.Osyka.Cornell: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Hoven.Noyes, Millston.Broadwell.LasVegas ] + Millston.Osyka.Weinert: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Hoven.Noyes, Millston.Broadwell.LasVegas ] + Millston.Hoven.Noyes: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Osyka.Cornell, Millston.Osyka.Weinert, Millston.Broadwell.LasVegas ] + Millston.Broadwell.LasVegas: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Osyka.Cornell, Millston.Osyka.Weinert, Millston.Hoven.Noyes ] + TB1: + Millston.Maumee.Bushland: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.GlenAvon.Exton ] + Millston.GlenAvon.Exton: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Bushland ] + TB2: + Millston.Broadwell.LasVegas: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Gotham.StarLake ] + Millston.Gotham.StarLake: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Broadwell.LasVegas ] + TB3: + Millston.Provencal.PineCity: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Provencal.Fayette: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TB12: + Millston.Provencal.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TB13: + Millston.Provencal.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TB14: + Millston.Gotham.StarLake: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH0: + Millston.Osyka.Helton: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Broadwell.Woodfield, Millston.Broadwell.Noyes, Millston.Broadwell.Fairhaven, Millston.Broadwell.Dennison, Millston.Broadwell.Wallula, Millston.Broadwell.Kalida, Millston.Broadwell.Comfrey, Millston.Broadwell.Palmhurst, Millston.Rainelle.Quogue, Millston.Rainelle.Steger ] + Millston.Broadwell.Woodfield: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Rainelle.Quogue, Millston.Rainelle.Steger ] + Millston.Broadwell.Noyes: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Rainelle.Quogue, Millston.Rainelle.Steger ] + Millston.Broadwell.Fairhaven: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Rainelle.Quogue, Millston.Rainelle.Steger ] + Millston.Broadwell.Dennison: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Rainelle.Quogue, Millston.Rainelle.Steger ] + Millston.Broadwell.Wallula: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Rainelle.Quogue, Millston.Rainelle.Steger ] + Millston.Broadwell.Kalida: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Rainelle.Quogue, Millston.Rainelle.Steger ] + Millston.Broadwell.Comfrey: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Rainelle.Quogue, Millston.Rainelle.Steger ] + Millston.Broadwell.Palmhurst: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Rainelle.Quogue, Millston.Rainelle.Steger ] + Millston.Rainelle.Quogue: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Broadwell.Woodfield, Millston.Broadwell.Noyes, Millston.Broadwell.Fairhaven, Millston.Broadwell.Dennison, Millston.Broadwell.Wallula, Millston.Broadwell.Kalida, Millston.Broadwell.Comfrey, Millston.Broadwell.Palmhurst ] + Millston.Rainelle.Steger: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Broadwell.Woodfield, Millston.Broadwell.Noyes, Millston.Broadwell.Fairhaven, Millston.Broadwell.Dennison, Millston.Broadwell.Wallula, Millston.Broadwell.Kalida, Millston.Broadwell.Comfrey, Millston.Broadwell.Palmhurst ] + TH1: + Millston.Ramos.Ocoee: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] + Millston.Ramos.Exton: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] + Millston.Provencal.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Ocoee, Millston.Ramos.Exton ] + TH2: + Millston.Ramos.Hackett: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] + Millston.Provencal.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Hackett ] + TH3: + Millston.Hoven.Petrey: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Hoven.Allison: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH4: + Millston.Hoven.Allison: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH5: + Millston.Cassa.Garibaldi: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Pawtucket.StarLake ] + Millston.Pawtucket.StarLake: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Cassa.Garibaldi ] + TH18: + Millston.Cassa.Garibaldi: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH19: + Millston.Provencal.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH20: + Millston.Provencal.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH21: + Millston.Provencal.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH22: + Millston.Provencal.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH23: + Millston.Provencal.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH24: + Millston.Wondervu$1.Bowden: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Wondervu$1.Oriskany: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Wondervu$1.Higginson: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH25: + Millston.GlenAvon.Hackett: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH26: + Millston.Buckhorn.SoapLake: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH27: + Millston.Hoven.Petrey: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TW0: + Millston.GlenAvon.Hoagland: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.GlenAvon.Mabelle: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.GlenAvon.Palatine: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.GlenAvon.Marfa: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.GlenAvon.Quinwood: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TW1: + Millston.Ramos.Rexville: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Chloride ] + Millston.Ramos.Alameda: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Chloride ] + Millston.Ramos.PineCity: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Chloride ] + Millston.Ramos.Osterdock: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Chloride ] + Millston.Ramos.Fayette: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Chloride ] + Millston.Provencal.Bushland: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Rexville, Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Chloride ] + Millston.Provencal.Dassel: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Rexville, Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Chloride ] + Millston.Provencal.Norwood: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Rexville, Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Chloride ] + Millston.Rainelle.Ledoux: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Rexville, Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] + Millston.Rainelle.Conner: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Rexville, Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] + Millston.Osyka.Chloride: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Rexville, Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner ] + TW2: + Millston.Ramos.Hoagland: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Kaluaaha, Millston.Osyka.Garibaldi ] + Millston.Ramos.Mabelle: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Kaluaaha, Millston.Osyka.Garibaldi ] + Millston.Ramos.Palatine: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Kaluaaha, Millston.Osyka.Garibaldi ] + Millston.Ramos.Marfa: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Kaluaaha, Millston.Osyka.Garibaldi ] + Millston.Ramos.Quinwood: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Kaluaaha, Millston.Osyka.Garibaldi ] + Millston.Provencal.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Hoagland, Millston.Ramos.Mabelle, Millston.Ramos.Palatine, Millston.Ramos.Marfa, Millston.Ramos.Quinwood, Millston.Osyka.Garibaldi ] + Millston.Osyka.Garibaldi: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Hoagland, Millston.Ramos.Mabelle, Millston.Ramos.Palatine, Millston.Ramos.Marfa, Millston.Ramos.Quinwood, Millston.Provencal.Kaluaaha ] + TW3: + Millston.Cassa.Helton: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Cassa.Noyes: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Cassa.Cornell: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Cassa.Weinert: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TW12: + Millston.Belgrade.Ronan: + mutually_exclusive_with: [ ] + TW13: + Millston.Ramos.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] + Millston.Provencal.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Kaluaaha ] + TW14: + Millston.Ramos.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] + Millston.Provencal.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Calcasieu ] + TW15: + Millston.Cassa.Chloride: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TW16: + Millston.Provencal.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + B0: + ig_intr_md_for_dprsr.digest_type: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + B1: + ig_intr_md_for_dprsr.mirror_type: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + B2: + HillTop.RossFork.Suttle: + live_start: parser + live_end: 9 + mutually_exclusive_with: [ ] + B3: + HillTop.RossFork.Boerne: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + B4: + HillTop.Ovett.Manilla: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + B5: + HillTop.RossFork.Thayne: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + B6: + HillTop.RossFork.Redden: + live_start: parser + live_end: 10 + mutually_exclusive_with: [ ] + B7: + Millston.Belgrade.Willard: + live_start: 8 + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Belgrade.__pad_4: + mutually_exclusive_with: [ ] + HillTop.RossFork.Denhoff: + live_start: 0 + live_end: 6 + mutually_exclusive_with: [ ] + HillTop.Aldan.Kearns: + live_start: parser + live_end: 0 + mutually_exclusive_with: [ ] + HillTop.Edwards.Oilmont: + live_start: 7 + live_end: 8 + mutually_exclusive_with: [ ] + HillTop.Edwards.Tornillo: + live_start: 7 + live_end: 8 + mutually_exclusive_with: [ ] + B8: + ig_intr_md_for_tm.ingress_cos: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + HillTop.Aldan.Malinta: + live_start: parser + live_end: 0 + mutually_exclusive_with: [ ] + HillTop.RossFork.Naruna: + live_start: 0 + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.RossFork.Brinkman: + live_start: 2 + live_end: 10 + mutually_exclusive_with: [ ] + HillTop.Freeny.Dunedin: + live_start: 7 + live_end: 8 + mutually_exclusive_with: [ ] + B9: + Millston.Belgrade.Waipahu: + mutually_exclusive_with: [ ] + Millston.Belgrade.Allgood: + mutually_exclusive_with: [ ] + Millston.Belgrade.Shabbona: + mutually_exclusive_with: [ ] + Millston.Belgrade.Anacortes: + mutually_exclusive_with: [ ] + Millston.Belgrade.__pad_1: + mutually_exclusive_with: [ ] + HillTop.Naubinway.Ayden: + live_start: parser + live_end: 6 + mutually_exclusive_with: [ ] + HillTop.RossFork.Yaurel: + live_start: parser + live_end: 10 + mutually_exclusive_with: [ ] + HillTop.Bessie.Peebles: + live_start: 0 + live_end: 9 + mutually_exclusive_with: [ ] + HillTop.Wisdom.Piqua: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.Wisdom.Westhoff: + live_start: parser + live_end: 10 + mutually_exclusive_with: [ ] + HillTop.Wisdom.RioPecos: + mutually_exclusive_with: [ ] + B10: + HillTop.Savery.Peebles: + live_start: 2 + live_end: 10 + mutually_exclusive_with: [ ] + HillTop.Aldan.Mystic: + live_start: parser + live_end: 0 + mutually_exclusive_with: [ ] + B11: + Millston.Belgrade.Rockport: + mutually_exclusive_with: [ ] + Millston.Belgrade.Union: + mutually_exclusive_with: [ ] + Millston.Belgrade.__pad_0: + mutually_exclusive_with: [ ] + HillTop.Quinault.Foster: + live_start: parser + live_end: 8 + mutually_exclusive_with: [ ] + HillTop.RossFork.Powderly: + live_start: parser + live_end: 8 + mutually_exclusive_with: [ ] + HillTop.Wisdom.Onycha: + live_start: 0 + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.Wisdom.Dyess: + mutually_exclusive_with: [ ] + B12: + Millston.Wondervu.$stkvalid: + mutually_exclusive_with: [ ] + HillTop.RossFork.ElVerano: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.RossFork.Alamosa: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.Komatke.Monahans: + live_start: parser + live_end: 10 + mutually_exclusive_with: [ ] + HillTop.RossFork.Weyauwega: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.RossFork.Charco: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.RossFork.Daphne: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + Millston.Wondervu$0.$valid: + live_start: 7 + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Wondervu$1.$valid: + mutually_exclusive_with: [ ] + B13: + ig_intr_md_for_tm.qid: + live_start: 7 + live_end: deparser + mutually_exclusive_with: [ ] + HillTop.Aldan.Parkville: + live_start: parser + live_end: 1 + mutually_exclusive_with: [ ] + HillTop.RossFork.Naruna: + live_start: 0 + live_end: 11 + mutually_exclusive_with: [ ] + B14: + HillTop.Aldan.Mystic: + live_start: parser + live_end: 0 + mutually_exclusive_with: [ ] + HillTop.Minturn.Tilton: + live_start: 10 + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.Edwards.McGrady: + live_start: 0 + live_end: 7 + mutually_exclusive_with: [ ] + HillTop.Edwards.AquaPark: + live_start: 0 + live_end: 8 + mutually_exclusive_with: [ ] + B15: + ig_intr_md_for_dprsr.drop_ctl: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + HillTop.Murphy.Standish: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.RossFork.Level: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.RossFork.Lowes: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.RossFork.Chugwater: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.Wisdom.Delavan: + live_start: parser + live_end: 6 + mutually_exclusive_with: [ ] + B32: + Millston.Osyka.Noyes: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Hoven.Roosville ] + Millston.Hoven.Roosville: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Osyka.Noyes ] + B33: + Millston.Maumee.Dassel: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.GlenAvon.Ocoee ] + Millston.GlenAvon.Ocoee: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Dassel ] + B34: + Millston.Belgrade.Freeburg: + mutually_exclusive_with: [ ] + Millston.Belgrade.__pad_2: + mutually_exclusive_with: [ ] + HillTop.Lamona.Pachuta: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + B35: + Millston.Maumee.Norwood: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Shirley.Goldsboro ] + Millston.Shirley.Goldsboro: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Norwood ] + B36: + Millston.Belgrade.Mankato: + mutually_exclusive_with: [ ] + HillTop.Wisdom.Blencoe: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + B37: + Millston.Shirley.Fabens: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Norwood ] + Millston.Maumee.Norwood: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Shirley.Fabens ] + B38: + HillTop.Plains.Roachdale: + live_start: 8 + live_end: deparser + mutually_exclusive_with: [ ] + HillTop.RossFork.Teigen: + live_start: parser + live_end: 1 + mutually_exclusive_with: [ ] + B39: + Millston.Provencal.Maryhill: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + B40: + HillTop.RossFork.Kremlin: + live_start: parser + live_end: 1 + mutually_exclusive_with: [ ] + HillTop.Savery.Noyes: + live_start: 2 + live_end: 10 + mutually_exclusive_with: [ ] + B41: + HillTop.Bessie.Noyes: + live_start: parser + live_end: 9 + mutually_exclusive_with: [ ] + B42: + HillTop.Aldan.Vinemont: + live_start: parser + live_end: 0 + mutually_exclusive_with: [ ] + HillTop.Savery.LasVegas: + live_start: 2 + live_end: 10 + mutually_exclusive_with: [ ] + B43: + HillTop.Bessie.LasVegas: + live_start: parser + live_end: 9 + mutually_exclusive_with: [ ] + B44: + HillTop.RossFork.Ocoee: + live_start: 0 + live_end: 10 + mutually_exclusive_with: [ ] + B45: + HillTop.RossFork.Ankeny: + live_start: 0 + live_end: 9 + mutually_exclusive_with: [ ] + B47: + Millston.Hayfield.Vichy: + live_start: parser + live_end: 7 + mutually_exclusive_with: [ ] + Millston.Hayfield.AquaPark: + live_start: parser + live_end: 7 + mutually_exclusive_with: [ ] + B48: + Millston.Wondervu$0.McCaulley: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + B49: + Millston.Wondervu$1.McCaulley: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + B50: + Millston.Calabash.McCaulley: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + B51: + Millston.Wondervu$0.McCaulley: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + B52: + Millston.Wondervu$1.McCaulley: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + B53: + Millston.Calabash.McCaulley: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + B54: + Millston.Belgrade.$valid: + live_start: 8 + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Hayfield.$valid: + live_start: parser + live_end: 7 + mutually_exclusive_with: [ ] + Millston.Calabash.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Rainelle.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.GlenAvon.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Ramos.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Bergton.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Pawtucket.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + B55: + HillTop.RossFork.Lafayette: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + B56: + HillTop.RossFork.McCaulley: + live_start: parser + live_end: 7 + mutually_exclusive_with: [ ] + HillTop.Edwards.Pajaros: + live_start: 10 + live_end: 11 + mutually_exclusive_with: [ ] + B57: + HillTop.RossFork.McCaulley: + live_start: parser + live_end: 7 + mutually_exclusive_with: [ ] + B58: + HillTop.Aldan.Kenbridge: + live_start: parser + live_end: 0 + mutually_exclusive_with: [ ] + HillTop.Savery.Exton: + live_start: 2 + live_end: 10 + mutually_exclusive_with: [ ] + B59: + HillTop.RossFork.Exton: + live_start: parser + live_end: 7 + mutually_exclusive_with: [ ] + B60: + HillTop.Bessie.Exton: + live_start: parser + live_end: 9 + mutually_exclusive_with: [ ] + H0: + Millston.Wondervu$0.Bowden: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Wondervu$0.Oriskany: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Wondervu$0.Higginson: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H1: + HillTop.Lamona.Traverse: + live_start: parser + live_end: 0 + mutually_exclusive_with: [ ] + HillTop.Komatke.Townville: + live_start: parser + live_end: 10 + mutually_exclusive_with: [ ] + H2: + Millston.Belgrade.Requa: + mutually_exclusive_with: [ ] + Millston.Belgrade.__pad_7: + mutually_exclusive_with: [ ] + HillTop.Wisdom.Nenana: + live_start: parser + live_end: 10 + mutually_exclusive_with: [ ] + H3: + Millston.Belgrade.Florien: + mutually_exclusive_with: [ ] + Millston.Belgrade.__pad_9: + mutually_exclusive_with: [ ] + HillTop.RossFork.Bradner: + live_start: parser + live_end: 9 + mutually_exclusive_with: [ ] + HillTop.RossFork.Caroleen: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + HillTop.RossFork.Bicknell: + live_start: parser + live_end: 6 + mutually_exclusive_with: [ ] + H4: + Millston.Belgrade.Bayshore: + mutually_exclusive_with: [ ] + Millston.Belgrade.__pad_8: + mutually_exclusive_with: [ ] + HillTop.RossFork.Ravena: + live_start: parser + live_end: 9 + mutually_exclusive_with: [ ] + HillTop.Ovett.Hematite: + live_start: parser + live_end: 10 + mutually_exclusive_with: [ ] + HillTop.RossFork.CeeVee: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H5: + ig_intr_md_for_tm.rid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + HillTop.Komatke.Townville: + live_start: parser + live_end: 10 + mutually_exclusive_with: [ ] + HillTop.RossFork.Crozet: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + H6: + Millston.Belgrade.Cacao: + mutually_exclusive_with: [ ] + Millston.Belgrade.Davie: + mutually_exclusive_with: [ ] + Millston.Belgrade.Rugby: + mutually_exclusive_with: [ ] + Millston.Belgrade.Roachdale: + mutually_exclusive_with: [ ] + HillTop.Edwards.Oriskany: + mutually_exclusive_with: [ ] + HillTop.Edwards.RedElm: + live_start: parser + live_end: 7 + mutually_exclusive_with: [ ] + H7: + ig_intr_md_for_tm.mcast_grp_a: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H8: + HillTop.Moose.Townville: + live_start: parser + live_end: 10 + mutually_exclusive_with: [ ] + ig_intr_md_for_tm.level1_exclusion_id: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + HillTop.Bessie.Chavies: + live_start: parser + live_end: 7 + mutually_exclusive_with: [ ] + H9: + HillTop.RossFork.Chevak: + live_start: parser + live_end: 10 + mutually_exclusive_with: [ ] + H10: + Millston.Grays.Chevak: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H11: + HillTop.RossFork.Glenmora: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + H12: + HillTop.Bessie.Chevak: + live_start: 0 + live_end: 9 + mutually_exclusive_with: [ ] + H13: + HillTop.Savery.Chevak: + live_start: 2 + live_end: 10 + mutually_exclusive_with: [ ] + H14: + HillTop.RossFork.Chaffee: + live_start: parser + live_end: 9 + mutually_exclusive_with: [ ] + HillTop.Ovett.Hammond: + live_start: parser + live_end: 10 + mutually_exclusive_with: [ ] + HillTop.RossFork.Almedia: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.Moose.Monahans: + live_start: parser + live_end: 10 + mutually_exclusive_with: [ ] + HillTop.RossFork.Belfair: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + H15: + HillTop.Salix.Hueytown: + live_start: parser + live_end: 8 + mutually_exclusive_with: [ ] + H32: + HillTop.RossFork.Mendocino: + live_start: parser + live_end: 10 + mutually_exclusive_with: [ ] + H33: + Millston.Grays.Mendocino: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H34: + HillTop.Minturn.Whitewood: + live_start: parser + live_end: 10 + mutually_exclusive_with: [ ] + HillTop.RossFork.Joslin: + live_start: parser + live_end: 7 + mutually_exclusive_with: [ ] + HillTop.Minturn.Grassflat: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H35: + Millston.Provencal.Maryhill: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Rainelle.Findlay ] + Millston.Provencal.Alameda: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Rainelle.Findlay ] + Millston.Provencal.PineCity: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Rainelle.Findlay ] + Millston.Rainelle.Findlay: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Maryhill, Millston.Provencal.Alameda, Millston.Provencal.PineCity ] + H36: + Millston.Calabash.Goldsboro: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H37: + HillTop.RossFork.Goldsboro: + live_start: 0 + live_end: deparser + mutually_exclusive_with: [ ] + H38: + Millston.GlenAvon.Rexville: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Maryhill ] + Millston.Maumee.Maryhill: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.GlenAvon.Rexville ] + H39: + Millston.Shirley.Connell: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H40: + HillTop.RossFork.DonaAna: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + H41: + HillTop.RossFork.Merrill: + live_start: parser + live_end: 9 + mutually_exclusive_with: [ ] + H42: + HillTop.RossFork.Hickox: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + H43: + HillTop.RossFork.Tehachapi: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + H44: + HillTop.Bessie.Mendocino: + live_start: parser + live_end: 9 + mutually_exclusive_with: [ ] + H45: + HillTop.Savery.Mendocino: + live_start: 2 + live_end: 10 + mutually_exclusive_with: [ ] + H46: + HillTop.Bessie.Calcasieu: + live_start: parser + live_end: 9 + mutually_exclusive_with: [ ] + H47: + HillTop.Savery.Calcasieu: + live_start: 2 + live_end: 10 + mutually_exclusive_with: [ ] + H48: + HillTop.Bessie.Kaluaaha: + live_start: parser + live_end: 9 + mutually_exclusive_with: [ ] + HillTop.Aldan.Poulan: + live_start: parser + live_end: 0 + mutually_exclusive_with: [ ] + Millston.Belgrade.Chaska: + mutually_exclusive_with: [ ] + Millston.Belgrade.__pad_6: + mutually_exclusive_with: [ ] + HillTop.Wisdom.Miller: + mutually_exclusive_with: [ ] + H49: + HillTop.Savery.Kaluaaha: + live_start: 2 + live_end: 10 + mutually_exclusive_with: [ ] + H50: + ig_intr_md_for_tm.level2_mcast_hash: + live_start: 8 + live_end: deparser + mutually_exclusive_with: [ ] + HillTop.Aldan.Kearns: + live_start: parser + live_end: 0 + mutually_exclusive_with: [ ] + H51: + Millston.Belgrade.Corinth: + mutually_exclusive_with: [ ] + HillTop.Lewiston.Staunton: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + H52: + ig_intr_md_for_tm.copy_to_cpu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H53: + HillTop.Tiburon.Arnold: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + H54: + Millston.Calabash.Connell: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H55: + HillTop.RossFork.Connell: + live_start: 0 + live_end: 6 + mutually_exclusive_with: [ ] + H56: + HillTop.Cutten.Tombstone: + live_start: 3 + live_end: 6 + mutually_exclusive_with: [ ] + HillTop.Moose.Pinole: + live_start: 6 + live_end: 10 + mutually_exclusive_with: [ ] + HillTop.Aldan.Malinta: + live_start: parser + live_end: 0 + mutually_exclusive_with: [ ] + H57: + HillTop.Cutten.Pittsboro: + live_start: 3 + live_end: 6 + mutually_exclusive_with: [ ] + HillTop.Plains.Miller: + live_start: 8 + live_end: deparser + mutually_exclusive_with: [ ] + H58: + HillTop.Cutten.Subiaco: + live_start: 2 + live_end: 6 + mutually_exclusive_with: [ ] + H59: + HillTop.Cutten.Pathfork: + live_start: 2 + live_end: 6 + mutually_exclusive_with: [ ] + H60: + HillTop.Cutten.Marcus: + live_start: parser + live_end: 6 + mutually_exclusive_with: [ ] + H61: + HillTop.Lewiston.Lugert: + live_start: parser + live_end: 6 + mutually_exclusive_with: [ ] + HillTop.RossFork.Altus: + live_start: parser + live_end: 1 + mutually_exclusive_with: [ ] + H62: + HillTop.Komatke.Pinole: + live_start: parser + live_end: 10 + mutually_exclusive_with: [ ] + HillTop.RossFork.Parkland: + live_start: 2 + live_end: 8 + mutually_exclusive_with: [ ] + HillTop.RossFork.Denhoff: + live_start: 0 + live_end: 6 + mutually_exclusive_with: [ ] + HillTop.Bessie.Miranda: + live_start: parser + live_end: 10 + mutually_exclusive_with: [ ] + HillTop.RossFork.Hulbert: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + H63: + HillTop.Aldan.Blakeley: + live_start: parser + live_end: 1 + mutually_exclusive_with: [ ] + Millston.Belgrade.Florin: + live_start: 2 + live_end: deparser + mutually_exclusive_with: [ ] + HillTop.Wisdom.Connell: + live_start: parser + live_end: 8 + mutually_exclusive_with: [ ] + H64: + HillTop.Naubinway.Sardinia: + live_start: parser + live_end: 6 + mutually_exclusive_with: [ HillTop.Naubinway.Bonduel ] + HillTop.Naubinway.Bonduel: + live_start: parser + live_end: 7 + mutually_exclusive_with: [ HillTop.Naubinway.Sardinia ] + HillTop.Murphy.Blairsden: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + H65: + HillTop.RossFork.Luzerne: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + HillTop.RossFork.TroutRun: + live_start: parser + live_end: 9 + mutually_exclusive_with: [ ] + H66: + HillTop.RossFork.Devers: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + HillTop.RossFork.Tenino: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.RossFork.Pridgen: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + H83: + HillTop.Maddock.PineCity: + live_start: parser + live_end: 3 + mutually_exclusive_with: [ ] + H84: + HillTop.Sublett.PineCity: + live_start: parser + live_end: 3 + mutually_exclusive_with: [ ] + H85: + HillTop.Savery.PineCity: + live_start: 2 + live_end: 10 + mutually_exclusive_with: [ ] + HillTop.RossFork.Welcome: + live_start: parser + live_end: 1 + mutually_exclusive_with: [ ] + H86: + HillTop.Edwards.LaConner: + live_start: 0 + live_end: 3 + mutually_exclusive_with: [ ] + H89: + Millston.GlenAvon.Alameda: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Maryhill, Millston.Maumee.Alameda, Millston.Maumee.PineCity, Millston.Maumee.Fayette ] + Millston.GlenAvon.PineCity: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Maryhill, Millston.Maumee.Alameda, Millston.Maumee.PineCity, Millston.Maumee.Fayette ] + Millston.GlenAvon.Osterdock: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Maryhill, Millston.Maumee.Alameda, Millston.Maumee.PineCity, Millston.Maumee.Fayette ] + Millston.GlenAvon.Fayette: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Maryhill, Millston.Maumee.Alameda, Millston.Maumee.PineCity, Millston.Maumee.Fayette ] + Millston.Maumee.Maryhill: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.GlenAvon.Alameda, Millston.GlenAvon.PineCity, Millston.GlenAvon.Osterdock, Millston.GlenAvon.Fayette ] + Millston.Maumee.Alameda: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.GlenAvon.Alameda, Millston.GlenAvon.PineCity, Millston.GlenAvon.Osterdock, Millston.GlenAvon.Fayette ] + Millston.Maumee.PineCity: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.GlenAvon.Alameda, Millston.GlenAvon.PineCity, Millston.GlenAvon.Osterdock, Millston.GlenAvon.Fayette ] + Millston.Maumee.Fayette: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.GlenAvon.Alameda, Millston.GlenAvon.PineCity, Millston.GlenAvon.Osterdock, Millston.GlenAvon.Fayette ] + H90: + Millston.Belgrade.Matheson: + mutually_exclusive_with: [ ] + Millston.Belgrade.__pad_5: + mutually_exclusive_with: [ ] + HillTop.Bessie.PineCity: + live_start: parser + live_end: 9 + mutually_exclusive_with: [ ] + HillTop.RossFork.Sewaren: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + HillTop.RossFork.WindGap: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + HillTop.RossFork.Lordstown: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + HillTop.Edwards.PineCity: + live_start: parser + live_end: 7 + mutually_exclusive_with: [ ] + H92: + Millston.Shirley.Goldsboro: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H93: + Millston.Shirley.Fabens: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H94: + Millston.Shirley.McCaulley: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H95: + Millston.Buckhorn.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Cassa.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Provencal.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Grays.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Gotham.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Brookneal.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Osyka.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Hoven.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Shirley.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Broadwell.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Maumee.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + HillTop.RossFork.Juniata: + live_start: parser + live_end: 10 + mutually_exclusive_with: [ ] + W0: + HillTop.Lamona.Whitefish: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.RossFork.Adona: + live_start: 0 + live_end: 6 + mutually_exclusive_with: [ ] + W1: + Millston.Belgrade.Selawik: + mutually_exclusive_with: [ ] + Millston.Belgrade.Sudbury: + mutually_exclusive_with: [ ] + Millston.Belgrade.__pad_3: + mutually_exclusive_with: [ ] + HillTop.RossFork.Halaula: + live_start: parser + live_end: 6 + mutually_exclusive_with: [ ] + HillTop.RossFork.Brinklow: + live_start: parser + live_end: 9 + mutually_exclusive_with: [ ] + HillTop.Edwards.Satolah: + live_start: parser + live_end: 7 + mutually_exclusive_with: [ ] + HillTop.RossFork.Beaverdam: + live_start: parser + live_end: 8 + mutually_exclusive_with: [ ] + HillTop.RossFork.Knierim: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + HillTop.Wisdom.Dolores: + mutually_exclusive_with: [ ] + HillTop.Wisdom.Waubun: + mutually_exclusive_with: [ ] + W2: + ig_intr_md_for_tm.ucast_egress_port: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + W3: + HillTop.Wisdom.Morstein: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.Sublett.Kaluaaha: + live_start: parser + live_end: 1 + mutually_exclusive_with: [ ] + W4: + HillTop.RossFork.Quebrada: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + W5: + HillTop.Mausdale.Kenney: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + W6: + Millston.Calabash.Fabens: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Calabash.Goldsboro: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + W7: + HillTop.RossFork.Fabens: + live_start: 0 + live_end: deparser + mutually_exclusive_with: [ ] + W8: + HillTop.RossFork.Goldsboro: + live_start: 0 + live_end: deparser + mutually_exclusive_with: [ ] + W9: + ig_intr_md_for_tm.level2_exclusion_id: + live_start: 8 + live_end: deparser + mutually_exclusive_with: [ ] + HillTop.RossFork.Uvalde: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + W10: + HillTop.RossFork.Kapalua: + live_start: parser + live_end: 7 + mutually_exclusive_with: [ ] + W11: + HillTop.Wisdom.Havana: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.RossFork.Algoa: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.Bessie.Heuvelton: + live_start: parser + live_end: 7 + mutually_exclusive_with: [ ] + W12: + Millston.Calabash.Connell: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Calabash.Adona: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + W13: + Millston.Belgrade.Florin: + live_start: 2 + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Belgrade.Virgil: + mutually_exclusive_with: [ ] + HillTop.Wisdom.Adona: + live_start: parser + live_end: 8 + mutually_exclusive_with: [ ] + HillTop.Wisdom.Connell: + live_start: parser + live_end: 8 + mutually_exclusive_with: [ ] + W14: + HillTop.RossFork.Connell: + live_start: 0 + live_end: 6 + mutually_exclusive_with: [ ] + HillTop.Lamona.Fristoe: + live_start: parser + live_end: 7 + mutually_exclusive_with: [ ] + W15: + Millston.Maumee.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Shirley.Connell, Millston.Shirley.Adona ] + Millston.Shirley.Connell: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] + Millston.Shirley.Adona: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] + W32: + Millston.Maumee.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.GlenAvon.Kaluaaha ] + Millston.GlenAvon.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Calcasieu ] + W33: + Millston.GlenAvon.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] + Millston.Maumee.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.GlenAvon.Calcasieu ] + W34: + Millston.Maumee.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + W35: + Millston.Maumee.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + W36: + HillTop.Sublett.Calcasieu: + live_start: parser + live_end: 6 + mutually_exclusive_with: [ HillTop.Maddock.Calcasieu ] + HillTop.Maddock.Calcasieu: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ HillTop.Sublett.Calcasieu ] + W37: + HillTop.Maddock.Kaluaaha: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ HillTop.Sublett.Kaluaaha ] + HillTop.Sublett.Kaluaaha: + live_start: parser + live_end: 1 + mutually_exclusive_with: [ HillTop.Maddock.Kaluaaha ] + W38: + HillTop.RossFork.Laxon: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + W39: + HillTop.Sublett.Kaluaaha: + live_start: parser + live_end: 1 + mutually_exclusive_with: [ ] + HillTop.RossFork.Montross: + live_start: 6 + live_end: 9 + mutually_exclusive_with: [ ] + W40: + HillTop.Sublett.Kaluaaha: + live_start: parser + live_end: 1 + mutually_exclusive_with: [ ] + W41: + Millston.Maumee.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + W42: + Millston.Maumee.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + W43: + Millston.Maumee.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + W44: + HillTop.Sublett.Calcasieu: + live_start: parser + live_end: 6 + mutually_exclusive_with: [ ] + W45: + HillTop.Sublett.Calcasieu: + live_start: parser + live_end: 6 + mutually_exclusive_with: [ ] + W46: + HillTop.Sublett.Calcasieu: + live_start: parser + live_end: 6 + mutually_exclusive_with: [ ] + W47: + Millston.Bergton.Mendocino: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Bergton.Chevak: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + W48: + Millston.Hayfield.Grabill: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + Millston.Hayfield.Glassboro: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + Millston.Hayfield.Avondale: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + Millston.Hayfield.Blitchton: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + W49: + HillTop.RossFork.Everton: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + W50: + Millston.Brookneal.SoapLake: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + W51: + HillTop.RossFork.Bucktown: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] +phv egress: + eg_intr_md.egress_port: H16(0..8) + eg_intr_md.egress_rid: W27(0..15) + eg_intr_md.egress_qid: W31(0..4) + HillTop.Sonoma.Iberia: H17 + HillTop.Wisdom.Adona.0-7: B21 + HillTop.Wisdom.Adona.8-23: H91 + HillTop.Wisdom.Connell.0-7: B30 + HillTop.Wisdom.Connell.8-23: H67 + HillTop.Wisdom.Dyess: W29(0) + HillTop.Wisdom.Westhoff: W28(1..3) + HillTop.Wisdom.Nenana: H21(0..11) + HillTop.Wisdom.Waubun: W30(2..7) + HillTop.Wisdom.Bowden: H23(0..11) + HillTop.Wisdom.Onycha: W29(1..3) + HillTop.Wisdom.Blencoe: B27 + HillTop.Wisdom.Bennet.0-15: TW23(0..15) + HillTop.Wisdom.Bennet.16-23: W25(0..7) + HillTop.Wisdom.Bennet.24-31: TB10 + HillTop.Wisdom.Jenners: H23(14..15) + HillTop.Wisdom.Miller.0-7: W24(8..15) + HillTop.Wisdom.Miller.8-8: B25(0) + HillTop.Wisdom.Toklat: H23(12..13) + HillTop.Wisdom.Piqua: W28(4) + HillTop.Wisdom.Stratford: B63(0) + HillTop.Wisdom.RioPecos: W28(0) + HillTop.Wisdom.Weatherby: B19(5) + HillTop.Wisdom.Lathrop: B20(3) + HillTop.Wisdom.DeGraff: B20(4..5) + HillTop.Wisdom.Dolores: W30(0..1) + Millston.Belgrade.Rugby: H20(5..7) + Millston.Belgrade.Davie: H20(4) + Millston.Belgrade.Mankato: B27 + Millston.Belgrade.Virgil.0-7: B21 + Millston.Belgrade.Virgil.8-23: H91 + Millston.Belgrade.Florin.0-7: B30 + Millston.Belgrade.Florin.8-23: H67 + Millston.Belgrade.Ronan.0-15: TW23(0..15) + Millston.Belgrade.Ronan.16-23: W25(0..7) + Millston.Belgrade.Ronan.24-31: TB10 + Millston.Belgrade.Corinth: W26(0..15) + Millston.Belgrade.Union: W29(1..3) + Millston.Belgrade.Rockport: W29(0) + Millston.Belgrade.Anacortes: W28(5) + Millston.Belgrade.Shabbona: W28(4) + Millston.Belgrade.Allgood: W28(1..3) + Millston.Belgrade.Waipahu: W28(0) + Millston.Belgrade.Freeburg: B61(0) + Millston.Belgrade.Sudbury: W30(2..7) + Millston.Belgrade.Selawik: W30(0..1) + Millston.Belgrade.Willard: B62(0..2) + Millston.Belgrade.Matheson: H80(0..5) + Millston.Belgrade.Chaska.0-7: W24(8..15) + Millston.Belgrade.Chaska.8-8: B25(0) + Millston.Belgrade.Requa: H21(0..11) + Millston.Belgrade.Bayshore: H29(0..11) + Millston.Belgrade.Florien: H27(0..11) + Millston.Calabash.Adona.0-7: B22 + Millston.Calabash.Adona.8-23: H87 + Millston.Calabash.Connell.0-7: B31 + Millston.Calabash.Connell.8-23: H68 + Millston.Calabash.Goldsboro.0-15: H73 + Millston.Calabash.Goldsboro.16-23: B29 + Millston.Calabash.Fabens.0-15: H26 + Millston.Calabash.Fabens.16-23: B24 + Millston.Calabash.McCaulley: H25 + Millston.Wondervu$0.Higginson: H22(13..15) + Millston.Wondervu$0.Oriskany: H22(12) + Millston.Wondervu$0.Bowden: H22(0..11) + Millston.Wondervu$0.McCaulley: H24 + Millston.Wondervu$1.Higginson: TW5(29..31) + Millston.Wondervu$1.Oriskany: TW5(28) + Millston.Wondervu$1.Bowden: TW5(16..27) + Millston.Wondervu$1.McCaulley: TW5(0..15) + Millston.Rainelle.Conner: TW6(16..31) + Millston.Rainelle.Ledoux: TW6(0..15) + Millston.Rainelle.Steger: TW4(24..31) + Millston.Rainelle.Quogue: TW4(16..23) + Millston.Rainelle.Findlay: TW4(0..15) + Millston.GlenAvon.Fayette: H81(12..15) + Millston.GlenAvon.Osterdock: H81(8..11) + Millston.GlenAvon.PineCity: H81(2..7) + Millston.GlenAvon.Alameda: H81(0..1) + Millston.GlenAvon.Rexville: H18 + Millston.GlenAvon.Quinwood: W16(16..31) + Millston.GlenAvon.Marfa: W16(15) + Millston.GlenAvon.Palatine: W16(14) + Millston.GlenAvon.Mabelle: W16(13) + Millston.GlenAvon.Hoagland: W16(0..12) + Millston.GlenAvon.Exton: B16 + Millston.GlenAvon.Ocoee: B23 + Millston.GlenAvon.Hackett.0-7: TB11 + Millston.GlenAvon.Hackett.8-15: TB20 + Millston.GlenAvon.Kaluaaha: W17 + Millston.GlenAvon.Calcasieu: W18 + Millston.Ramos.Fayette: H82(12..15) + Millston.Ramos.Osterdock: H82(8..11) + Millston.Ramos.PineCity: H82(2..7) + Millston.Ramos.Alameda: H82(0..1) + Millston.Ramos.Rexville: TH15 + Millston.Ramos.Quinwood: TW4(16..31) + Millston.Ramos.Marfa: TW4(15) + Millston.Ramos.Palatine: TW4(14) + Millston.Ramos.Mabelle: TW4(13) + Millston.Ramos.Hoagland: TW4(0..12) + Millston.Ramos.Exton: TH6(8..15) + Millston.Ramos.Ocoee: TH6(0..7) + Millston.Ramos.Hackett.0-7: TB6 + Millston.Ramos.Hackett.8-15: TB7 + Millston.Ramos.Kaluaaha: TW10 + Millston.Ramos.Calcasieu: TW11 + Millston.Bergton.Chevak: TH8 + Millston.Bergton.Mendocino: TH7 + Millston.Pawtucket.StarLake: TH11 + Millston.Buckhorn.SoapLake: TH31 + Millston.Cassa.Chloride.0-15: TH11 + Millston.Cassa.Chloride.16-31: TH12 + Millston.Cassa.Garibaldi.0-15: TH13 + Millston.Cassa.Garibaldi.16-31: TH14 + Millston.Cassa.Weinert: TW6(28..31) + Millston.Cassa.Cornell: TW6(24..27) + Millston.Cassa.Noyes: TW6(16..23) + Millston.Cassa.Helton: TW6(0..15) + Millston.Provencal.Fayette: H82(12..15) + Millston.Provencal.PineCity: H82(6..11) + Millston.Provencal.Alameda: H82(4..5) + Millston.Provencal.Maryhill.0-15: TH30 + Millston.Provencal.Maryhill.16-19: H82(0..3) + Millston.Provencal.Norwood: TW4(16..31) + Millston.Provencal.Dassel: TW4(8..15) + Millston.Provencal.Bushland: TW4(0..7) + Millston.Provencal.Kaluaaha.0-31: TW10 + Millston.Provencal.Kaluaaha.32-63: TW11 + Millston.Provencal.Kaluaaha.64-71: TB6 + Millston.Provencal.Kaluaaha.72-79: TB7 + Millston.Provencal.Kaluaaha.80-95: TH6 + Millston.Provencal.Kaluaaha.96-111: TH15 + Millston.Provencal.Kaluaaha.112-127: TH16 + Millston.Provencal.Calcasieu.0-7: TB8 + Millston.Provencal.Calcasieu.8-15: TB9 + Millston.Provencal.Calcasieu.16-31: TH17 + Millston.Provencal.Calcasieu.32-63: TW20 + Millston.Provencal.Calcasieu.64-95: TW21 + Millston.Provencal.Calcasieu.96-127: TW22 + Millston.Grays.Chevak: H70 + Millston.Grays.Mendocino: H69 + Millston.Gotham.StarLake: TH32 + Millston.Brookneal.SoapLake: TH33 + Millston.Hoven.Noyes: TW7(24..31) + Millston.Hoven.Allison: TW7(0..23) + Millston.Hoven.Petrey.0-7: TH9(8..15) + Millston.Hoven.Petrey.8-23: TH10 + Millston.Hoven.Roosville: TH9(0..7) + Millston.Shirley.Adona.0-7: TB4 + Millston.Shirley.Adona.8-23: TH34 + Millston.Shirley.Connell: TW8(8..31) + Millston.Shirley.Goldsboro.0-15: TH35 + Millston.Shirley.Goldsboro.16-23: TW8(0..7) + Millston.Shirley.Fabens: TW9(8..31) + Millston.Shirley.McCaulley.0-7: TB5 + Millston.Shirley.McCaulley.8-15: TW9(0..7) + Millston.Osyka.Chloride: TW4 + Millston.Osyka.Garibaldi: TW6 + Millston.Osyka.Weinert: TB4(4..7) + Millston.Osyka.Cornell: TB4(0..3) + Millston.Osyka.Noyes: B46 + Millston.Osyka.Helton.0-7: TB5 + Millston.Osyka.Helton.8-15: TB6 + Millston.Broadwell.Palmhurst: TB5(7) + Millston.Broadwell.Comfrey: TB5(6) + Millston.Broadwell.Kalida: TB5(5) + Millston.Broadwell.Wallula: TB5(4) + Millston.Broadwell.Dennison: TB5(3) + Millston.Broadwell.Fairhaven: TB5(0..2) + Millston.Broadwell.Noyes: TB4(3..7) + Millston.Broadwell.Woodfield: TB4(0..2) + Millston.Broadwell.LasVegas: H69 + Millston.Maumee.Fayette: H81(12..15) + Millston.Maumee.PineCity: H81(6..11) + Millston.Maumee.Alameda: H81(4..5) + Millston.Maumee.Maryhill.0-15: TW7(16..31) + Millston.Maumee.Maryhill.16-19: H81(0..3) + Millston.Maumee.Norwood: TW7(0..15) + Millston.Maumee.Dassel: B23 + Millston.Maumee.Bushland: B16 + Millston.Maumee.Kaluaaha.0-31: W16 + Millston.Maumee.Kaluaaha.32-63: W17 + Millston.Maumee.Kaluaaha.64-95: W18 + Millston.Maumee.Kaluaaha.96-111: H18 + Millston.Maumee.Kaluaaha.112-127: H71 + Millston.Maumee.Calcasieu.0-31: W19 + Millston.Maumee.Calcasieu.32-63: W20 + Millston.Maumee.Calcasieu.64-95: W21 + Millston.Maumee.Calcasieu.96-127: W22 + HillTop.Freeny.Dunedin: B62(0..2) + HillTop.Edwards.RedElm: H20(5..7) + HillTop.Edwards.Oriskany: H20(4) + HillTop.Edwards.PineCity: H80(0..5) + HillTop.Edwards.Renick: H88(0..5) + HillTop.Edwards.SomesBar: B62(0) + HillTop.McCaskill.Grassflat: H19(0..9) + HillTop.McCaskill.Whitewood: H19(0..9) + HillTop.McCaskill.Tilton: B19(2..3) + HillTop.McGonigle.Buncombe: B18 + HillTop.Lamona.Pachuta: B61(0) + Millston.Hayfield.Blitchton: H72(10..15) + Millston.Hayfield.Avondale: H72(0..9) + Millston.Hayfield.Glassboro: H31(12..15) + Millston.Hayfield.Grabill: H31(0..11) + Millston.Hayfield.Moorcroft: H30(14..15) + Millston.Hayfield.Toklat: H30(12..13) + Millston.Hayfield.Bledsoe: H30(0..11) + Millston.Hayfield.Blencoe: B28 + Millston.Hayfield.AquaPark: B26(6..7) + Millston.Hayfield.Vichy: B26(3..5) + Millston.Hayfield.Lathrop: B26(2) + Millston.Hayfield.Clyde: B26(1) + Millston.Hayfield.Clarion: B26(0) + Millston.Hayfield.Aguilita: H28(12..15) + Millston.Hayfield.Harbor: H28(0..11) + HillTop.Lewiston.Staunton: W26(0..15) + eg_intr_md_for_dprsr.drop_ctl: B20(0..2) + eg_intr_md_for_dprsr.mirror_type: B17(0..2) + HillTop.RossFork.CeeVee: H29(0..11) + HillTop.RossFork.Bicknell: H27(0..11) + HillTop.Bessie.Peebles: W28(5) + HillTop.Stennett.Standish: B19(4) + HillTop.Stennett.Blairsden: H74(11) + HillTop.Plains.Roachdale: B25 + HillTop.Plains.Miller: H17(0..8) + Millston.Belgrade.$valid: W23(0) + Millston.Calabash.$valid: W23(1) + Millston.Rainelle.$valid: W23(2) + Millston.GlenAvon.$valid: W23(3) + Millston.Ramos.$valid: W23(4) + Millston.Bergton.$valid: W23(5) + Millston.Pawtucket.$valid: W23(6) + Millston.Buckhorn.$valid: W23(7) + Millston.Cassa.$valid: H74(0) + Millston.Provencal.$valid: H74(1) + Millston.Grays.$valid: H74(2) + Millston.Gotham.$valid: H74(3) + Millston.Brookneal.$valid: H74(4) + Millston.Hoven.$valid: H74(6) + Millston.Shirley.$valid: H74(7) + Millston.Osyka.$valid: H74(5) + Millston.Broadwell.$valid: H74(8) + Millston.Maumee.$valid: H74(9) + Millston.Hayfield.$valid: H74(10) + Millston.Wondervu.$stkvalid: B19(0..1) + Millston.Wondervu$0.$valid: B19(1) + Millston.Wondervu$1.$valid: B19(0) + context_json: + TB4: + Millston.Shirley.Adona: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Broadwell.Woodfield, Millston.Broadwell.Noyes, Millston.Osyka.Cornell, Millston.Osyka.Weinert ] + Millston.Broadwell.Woodfield: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Shirley.Adona, Millston.Osyka.Cornell, Millston.Osyka.Weinert ] + Millston.Broadwell.Noyes: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Shirley.Adona, Millston.Osyka.Cornell, Millston.Osyka.Weinert ] + Millston.Osyka.Cornell: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Shirley.Adona, Millston.Broadwell.Woodfield, Millston.Broadwell.Noyes ] + Millston.Osyka.Weinert: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Shirley.Adona, Millston.Broadwell.Woodfield, Millston.Broadwell.Noyes ] + TB5: + Millston.Shirley.McCaulley: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Broadwell.Fairhaven, Millston.Broadwell.Dennison, Millston.Broadwell.Wallula, Millston.Broadwell.Kalida, Millston.Broadwell.Comfrey, Millston.Broadwell.Palmhurst, Millston.Osyka.Helton ] + Millston.Broadwell.Fairhaven: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Shirley.McCaulley, Millston.Osyka.Helton ] + Millston.Broadwell.Dennison: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Shirley.McCaulley, Millston.Osyka.Helton ] + Millston.Broadwell.Wallula: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Shirley.McCaulley, Millston.Osyka.Helton ] + Millston.Broadwell.Kalida: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Shirley.McCaulley, Millston.Osyka.Helton ] + Millston.Broadwell.Comfrey: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Shirley.McCaulley, Millston.Osyka.Helton ] + Millston.Broadwell.Palmhurst: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Shirley.McCaulley, Millston.Osyka.Helton ] + Millston.Osyka.Helton: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Shirley.McCaulley, Millston.Broadwell.Fairhaven, Millston.Broadwell.Dennison, Millston.Broadwell.Wallula, Millston.Broadwell.Kalida, Millston.Broadwell.Comfrey, Millston.Broadwell.Palmhurst ] + TB6: + Millston.Osyka.Helton: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Hackett, Millston.Provencal.Kaluaaha ] + Millston.Ramos.Hackett: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Provencal.Kaluaaha ] + Millston.Provencal.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Ramos.Hackett ] + TB7: + Millston.Ramos.Hackett: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] + Millston.Provencal.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Hackett ] + TB8: + Millston.Provencal.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TB9: + Millston.Provencal.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TB10: + Millston.Belgrade.Ronan: + mutually_exclusive_with: [ ] + HillTop.Wisdom.Bennet: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TB11: + Millston.GlenAvon.Hackett: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TB20: + Millston.GlenAvon.Hackett: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH6: + Millston.Ramos.Ocoee: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] + Millston.Ramos.Exton: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] + Millston.Provencal.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Ocoee, Millston.Ramos.Exton ] + TH7: + Millston.Bergton.Mendocino: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH8: + Millston.Bergton.Chevak: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH9: + Millston.Hoven.Roosville: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Hoven.Petrey: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH10: + Millston.Hoven.Petrey: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH11: + Millston.Cassa.Chloride: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Pawtucket.StarLake ] + Millston.Pawtucket.StarLake: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Cassa.Chloride ] + TH12: + Millston.Cassa.Chloride: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH13: + Millston.Cassa.Garibaldi: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH14: + Millston.Cassa.Garibaldi: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH15: + Millston.Provencal.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Rexville ] + Millston.Ramos.Rexville: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] + TH16: + Millston.Provencal.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH17: + Millston.Provencal.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH30: + Millston.Provencal.Maryhill: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH31: + Millston.Buckhorn.SoapLake: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH32: + Millston.Gotham.StarLake: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH33: + Millston.Brookneal.SoapLake: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH34: + Millston.Shirley.Adona: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TH35: + Millston.Shirley.Goldsboro: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TW4: + Millston.Ramos.Hoagland: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Rainelle.Findlay, Millston.Rainelle.Quogue, Millston.Rainelle.Steger, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] + Millston.Ramos.Mabelle: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Rainelle.Findlay, Millston.Rainelle.Quogue, Millston.Rainelle.Steger, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] + Millston.Ramos.Palatine: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Rainelle.Findlay, Millston.Rainelle.Quogue, Millston.Rainelle.Steger, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] + Millston.Ramos.Marfa: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Rainelle.Findlay, Millston.Rainelle.Quogue, Millston.Rainelle.Steger, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] + Millston.Ramos.Quinwood: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Rainelle.Findlay, Millston.Rainelle.Quogue, Millston.Rainelle.Steger, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] + Millston.Rainelle.Findlay: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Hoagland, Millston.Ramos.Mabelle, Millston.Ramos.Palatine, Millston.Ramos.Marfa, Millston.Ramos.Quinwood, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] + Millston.Rainelle.Quogue: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Hoagland, Millston.Ramos.Mabelle, Millston.Ramos.Palatine, Millston.Ramos.Marfa, Millston.Ramos.Quinwood, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] + Millston.Rainelle.Steger: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Hoagland, Millston.Ramos.Mabelle, Millston.Ramos.Palatine, Millston.Ramos.Marfa, Millston.Ramos.Quinwood, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] + Millston.Provencal.Bushland: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Hoagland, Millston.Ramos.Mabelle, Millston.Ramos.Palatine, Millston.Ramos.Marfa, Millston.Ramos.Quinwood, Millston.Rainelle.Findlay, Millston.Rainelle.Quogue, Millston.Rainelle.Steger, Millston.Osyka.Chloride ] + Millston.Provencal.Dassel: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Hoagland, Millston.Ramos.Mabelle, Millston.Ramos.Palatine, Millston.Ramos.Marfa, Millston.Ramos.Quinwood, Millston.Rainelle.Findlay, Millston.Rainelle.Quogue, Millston.Rainelle.Steger, Millston.Osyka.Chloride ] + Millston.Provencal.Norwood: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Hoagland, Millston.Ramos.Mabelle, Millston.Ramos.Palatine, Millston.Ramos.Marfa, Millston.Ramos.Quinwood, Millston.Rainelle.Findlay, Millston.Rainelle.Quogue, Millston.Rainelle.Steger, Millston.Osyka.Chloride ] + Millston.Osyka.Chloride: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Hoagland, Millston.Ramos.Mabelle, Millston.Ramos.Palatine, Millston.Ramos.Marfa, Millston.Ramos.Quinwood, Millston.Rainelle.Findlay, Millston.Rainelle.Quogue, Millston.Rainelle.Steger, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood ] + TW5: + Millston.Wondervu$1.McCaulley: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Wondervu$1.Bowden: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Wondervu$1.Oriskany: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Wondervu$1.Higginson: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TW6: + Millston.Cassa.Helton: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Garibaldi ] + Millston.Cassa.Noyes: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Garibaldi ] + Millston.Cassa.Cornell: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Garibaldi ] + Millston.Cassa.Weinert: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Garibaldi ] + Millston.Rainelle.Ledoux: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Cassa.Helton, Millston.Cassa.Noyes, Millston.Cassa.Cornell, Millston.Cassa.Weinert, Millston.Osyka.Garibaldi ] + Millston.Rainelle.Conner: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Cassa.Helton, Millston.Cassa.Noyes, Millston.Cassa.Cornell, Millston.Cassa.Weinert, Millston.Osyka.Garibaldi ] + Millston.Osyka.Garibaldi: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Cassa.Helton, Millston.Cassa.Noyes, Millston.Cassa.Cornell, Millston.Cassa.Weinert, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner ] + TW7: + Millston.Maumee.Norwood: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Hoven.Allison, Millston.Hoven.Noyes ] + Millston.Maumee.Maryhill: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Hoven.Allison, Millston.Hoven.Noyes ] + Millston.Hoven.Allison: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Norwood, Millston.Maumee.Maryhill ] + Millston.Hoven.Noyes: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Norwood, Millston.Maumee.Maryhill ] + TW8: + Millston.Shirley.Goldsboro: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Shirley.Connell: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TW9: + Millston.Shirley.McCaulley: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Shirley.Fabens: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TW10: + Millston.Ramos.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] + Millston.Provencal.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Kaluaaha ] + TW11: + Millston.Ramos.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] + Millston.Provencal.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Calcasieu ] + TW20: + Millston.Provencal.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TW21: + Millston.Provencal.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TW22: + Millston.Provencal.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + TW23: + Millston.Belgrade.Ronan: + mutually_exclusive_with: [ ] + HillTop.Wisdom.Bennet: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + B16: + Millston.GlenAvon.Exton: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Bushland ] + Millston.Maumee.Bushland: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.GlenAvon.Exton ] + B17: + eg_intr_md_for_dprsr.mirror_type: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + B18: + HillTop.McGonigle.Buncombe: + live_start: parser + live_end: 10 + mutually_exclusive_with: [ ] + B19: + Millston.Wondervu.$stkvalid: + mutually_exclusive_with: [ ] + HillTop.McCaskill.Tilton: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.Stennett.Standish: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.Wisdom.Weatherby: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + Millston.Wondervu$0.$valid: + live_start: 5 + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Wondervu$1.$valid: + mutually_exclusive_with: [ ] + B20: + eg_intr_md_for_dprsr.drop_ctl: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + HillTop.Wisdom.Lathrop: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + HillTop.Wisdom.DeGraff: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + B21: + Millston.Belgrade.Virgil: + mutually_exclusive_with: [ ] + HillTop.Wisdom.Adona: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + B22: + Millston.Calabash.Adona: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + B23: + Millston.Maumee.Dassel: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.GlenAvon.Ocoee ] + Millston.GlenAvon.Ocoee: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Dassel ] + B24: + Millston.Calabash.Fabens: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + B25: + HillTop.Plains.Roachdale: + live_start: 5 + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Belgrade.Chaska: + mutually_exclusive_with: [ ] + HillTop.Wisdom.Miller: + live_start: parser + live_end: 4 + mutually_exclusive_with: [ ] + B26: + Millston.Hayfield.Clarion: + mutually_exclusive_with: [ ] + Millston.Hayfield.Clyde: + mutually_exclusive_with: [ ] + Millston.Hayfield.Lathrop: + live_start: 5 + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Hayfield.Vichy: + mutually_exclusive_with: [ ] + Millston.Hayfield.AquaPark: + mutually_exclusive_with: [ ] + B27: + Millston.Belgrade.Mankato: + mutually_exclusive_with: [ ] + HillTop.Wisdom.Blencoe: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + B28: + Millston.Hayfield.Blencoe: + live_start: 5 + live_end: deparser + mutually_exclusive_with: [ ] + B29: + Millston.Calabash.Goldsboro: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + B30: + Millston.Belgrade.Florin: + mutually_exclusive_with: [ ] + HillTop.Wisdom.Connell: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + B31: + Millston.Calabash.Connell: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + B46: + Millston.Osyka.Noyes: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + B61: + Millston.Belgrade.Freeburg: + mutually_exclusive_with: [ ] + HillTop.Lamona.Pachuta: + live_start: parser + live_end: 4 + mutually_exclusive_with: [ ] + B62: + Millston.Belgrade.Willard: + mutually_exclusive_with: [ ] + HillTop.Edwards.SomesBar: + live_start: 5 + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.Freeny.Dunedin: + live_start: parser + live_end: 4 + mutually_exclusive_with: [ ] + B63: + HillTop.Wisdom.Stratford: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + H16: + eg_intr_md.egress_port: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H17: + HillTop.Plains.Miller: + live_start: 5 + live_end: deparser + mutually_exclusive_with: [ ] + HillTop.Sonoma.Iberia: + live_start: parser + live_end: 0 + mutually_exclusive_with: [ ] + H18: + Millston.GlenAvon.Rexville: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] + Millston.Maumee.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.GlenAvon.Rexville ] + H19: + HillTop.McCaskill.Whitewood: + live_start: parser + live_end: 4 + mutually_exclusive_with: [ ] + HillTop.McCaskill.Grassflat: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H20: + Millston.Belgrade.Davie: + mutually_exclusive_with: [ ] + Millston.Belgrade.Rugby: + mutually_exclusive_with: [ ] + HillTop.Edwards.RedElm: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.Edwards.Oriskany: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + H21: + Millston.Belgrade.Requa: + mutually_exclusive_with: [ ] + HillTop.Wisdom.Nenana: + live_start: parser + live_end: 4 + mutually_exclusive_with: [ ] + H22: + Millston.Wondervu$0.Bowden: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Wondervu$0.Oriskany: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Wondervu$0.Higginson: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H23: + HillTop.Wisdom.Bowden: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.Wisdom.Toklat: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + HillTop.Wisdom.Jenners: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + H24: + Millston.Wondervu$0.McCaulley: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H25: + Millston.Calabash.McCaulley: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H26: + Millston.Calabash.Fabens: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H27: + Millston.Belgrade.Florien: + mutually_exclusive_with: [ ] + HillTop.RossFork.Bicknell: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + H28: + Millston.Hayfield.Harbor: + live_start: 5 + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Hayfield.Aguilita: + live_start: 4 + live_end: deparser + mutually_exclusive_with: [ ] + H29: + Millston.Belgrade.Bayshore: + mutually_exclusive_with: [ ] + HillTop.RossFork.CeeVee: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + H30: + Millston.Hayfield.Bledsoe: + live_start: 5 + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Hayfield.Toklat: + live_start: 5 + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Hayfield.Moorcroft: + live_start: 5 + live_end: deparser + mutually_exclusive_with: [ ] + H31: + Millston.Hayfield.Grabill: + live_start: 4 + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Hayfield.Glassboro: + live_start: 4 + live_end: deparser + mutually_exclusive_with: [ ] + H67: + Millston.Belgrade.Florin: + mutually_exclusive_with: [ ] + HillTop.Wisdom.Connell: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + H68: + Millston.Calabash.Connell: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H69: + Millston.Broadwell.LasVegas: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Grays.Mendocino ] + Millston.Grays.Mendocino: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Broadwell.LasVegas ] + H70: + Millston.Grays.Chevak: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H71: + Millston.Maumee.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H72: + Millston.Hayfield.Avondale: + live_start: 4 + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Hayfield.Blitchton: + live_start: 4 + live_end: deparser + mutually_exclusive_with: [ ] + H73: + Millston.Calabash.Goldsboro: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H74: + Millston.Cassa.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Provencal.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Grays.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Gotham.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Brookneal.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Osyka.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Hoven.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Shirley.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Broadwell.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Maumee.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Hayfield.$valid: + live_start: 5 + live_end: deparser + mutually_exclusive_with: [ ] + HillTop.Stennett.Blairsden: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + H80: + Millston.Belgrade.Matheson: + mutually_exclusive_with: [ ] + HillTop.Edwards.PineCity: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + H81: + Millston.Maumee.Maryhill: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.GlenAvon.Alameda, Millston.GlenAvon.PineCity, Millston.GlenAvon.Osterdock, Millston.GlenAvon.Fayette ] + Millston.Maumee.Alameda: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.GlenAvon.Alameda, Millston.GlenAvon.PineCity, Millston.GlenAvon.Osterdock, Millston.GlenAvon.Fayette ] + Millston.Maumee.PineCity: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.GlenAvon.Alameda, Millston.GlenAvon.PineCity, Millston.GlenAvon.Osterdock, Millston.GlenAvon.Fayette ] + Millston.Maumee.Fayette: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.GlenAvon.Alameda, Millston.GlenAvon.PineCity, Millston.GlenAvon.Osterdock, Millston.GlenAvon.Fayette ] + Millston.GlenAvon.Alameda: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Maryhill, Millston.Maumee.Alameda, Millston.Maumee.PineCity, Millston.Maumee.Fayette ] + Millston.GlenAvon.PineCity: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Maryhill, Millston.Maumee.Alameda, Millston.Maumee.PineCity, Millston.Maumee.Fayette ] + Millston.GlenAvon.Osterdock: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Maryhill, Millston.Maumee.Alameda, Millston.Maumee.PineCity, Millston.Maumee.Fayette ] + Millston.GlenAvon.Fayette: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Maryhill, Millston.Maumee.Alameda, Millston.Maumee.PineCity, Millston.Maumee.Fayette ] + H82: + Millston.Ramos.Alameda: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Maryhill, Millston.Provencal.Alameda, Millston.Provencal.PineCity, Millston.Provencal.Fayette ] + Millston.Ramos.PineCity: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Maryhill, Millston.Provencal.Alameda, Millston.Provencal.PineCity, Millston.Provencal.Fayette ] + Millston.Ramos.Osterdock: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Maryhill, Millston.Provencal.Alameda, Millston.Provencal.PineCity, Millston.Provencal.Fayette ] + Millston.Ramos.Fayette: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Provencal.Maryhill, Millston.Provencal.Alameda, Millston.Provencal.PineCity, Millston.Provencal.Fayette ] + Millston.Provencal.Maryhill: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette ] + Millston.Provencal.Alameda: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette ] + Millston.Provencal.PineCity: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette ] + Millston.Provencal.Fayette: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette ] + H87: + Millston.Calabash.Adona: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + H88: + HillTop.Edwards.Renick: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + H91: + Millston.Belgrade.Virgil: + mutually_exclusive_with: [ ] + HillTop.Wisdom.Adona: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + W16: + Millston.GlenAvon.Hoagland: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] + Millston.GlenAvon.Mabelle: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] + Millston.GlenAvon.Palatine: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] + Millston.GlenAvon.Marfa: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] + Millston.GlenAvon.Quinwood: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] + Millston.Maumee.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.GlenAvon.Hoagland, Millston.GlenAvon.Mabelle, Millston.GlenAvon.Palatine, Millston.GlenAvon.Marfa, Millston.GlenAvon.Quinwood ] + W17: + Millston.GlenAvon.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] + Millston.Maumee.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.GlenAvon.Kaluaaha ] + W18: + Millston.GlenAvon.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] + Millston.Maumee.Kaluaaha: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ Millston.GlenAvon.Calcasieu ] + W19: + Millston.Maumee.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + W20: + Millston.Maumee.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + W21: + Millston.Maumee.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + W22: + Millston.Maumee.Calcasieu: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + W23: + Millston.Belgrade.$valid: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + Millston.Calabash.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Rainelle.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.GlenAvon.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Ramos.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Bergton.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Pawtucket.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + Millston.Buckhorn.$valid: + live_start: parser + live_end: deparser + mutually_exclusive_with: [ ] + W24: + Millston.Belgrade.Chaska: + mutually_exclusive_with: [ ] + HillTop.Wisdom.Miller: + live_start: parser + live_end: 4 + mutually_exclusive_with: [ ] + W25: + Millston.Belgrade.Ronan: + mutually_exclusive_with: [ ] + HillTop.Wisdom.Bennet: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + W26: + Millston.Belgrade.Corinth: + mutually_exclusive_with: [ ] + HillTop.Lewiston.Staunton: + live_start: parser + live_end: 6 + mutually_exclusive_with: [ ] + W27: + eg_intr_md.egress_rid: + live_start: parser + live_end: 0 + mutually_exclusive_with: [ ] + W28: + Millston.Belgrade.Waipahu: + mutually_exclusive_with: [ ] + Millston.Belgrade.Allgood: + mutually_exclusive_with: [ ] + Millston.Belgrade.Shabbona: + mutually_exclusive_with: [ ] + Millston.Belgrade.Anacortes: + mutually_exclusive_with: [ ] + HillTop.Wisdom.Piqua: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + HillTop.Wisdom.Westhoff: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.Wisdom.RioPecos: + live_start: parser + live_end: 4 + mutually_exclusive_with: [ ] + HillTop.Bessie.Peebles: + live_start: parser + live_end: 6 + mutually_exclusive_with: [ ] + W29: + Millston.Belgrade.Rockport: + mutually_exclusive_with: [ ] + Millston.Belgrade.Union: + mutually_exclusive_with: [ ] + HillTop.Wisdom.Onycha: + live_start: parser + live_end: 11 + mutually_exclusive_with: [ ] + HillTop.Wisdom.Dyess: + live_start: parser + live_end: 4 + mutually_exclusive_with: [ ] + W30: + Millston.Belgrade.Selawik: + mutually_exclusive_with: [ ] + Millston.Belgrade.Sudbury: + mutually_exclusive_with: [ ] + HillTop.Wisdom.Waubun: + live_start: parser + live_end: 2 + mutually_exclusive_with: [ ] + HillTop.Wisdom.Dolores: + live_start: parser + live_end: 5 + mutually_exclusive_with: [ ] + W31: + eg_intr_md.egress_qid: + live_start: parser + live_end: 4 + mutually_exclusive_with: [ ] +parser ingress: + start: $entry_point + init_zero: [ W14, H1, W0, H53, B42, B58, B13, B10, B14, H50, B7, B8, H56, H63, H48, H55, W8, H37, W7, B56, B57, H4, W4, H3, B44, B59, B2, B45, H62, H34, B12, B11, H85, B38, B15, H14, W11, B5, W10, W1, W9, H66, H95, B3, W39, H11, H40, H61, H41, H42, H43, H90, H65, H5, W38, W49, B55, H9, H32, B40, B6, B9, W51, W37, W36, H83, W3, W40, W44, W45, W46, H84, H59, H58, H60, H2, B36, H86, H64, H46, H8, H12, H44, B43, B60, B41, B4, W5, H49, H47, H13, H45, H15, H52, B54 ] + bitwise_or: [ B12, B54, H95 ] + hdr_len_adj: 16 + states: + $entry_point: # from state ingress::$entry_point + *: + save: { half : 0..1 } + buf_req: 2 + next: start + start: # from state ingress::start + match: [ half ] + value_set Guion 2: + handle: 511 + field_mapping: + ig_intr_md.ingress_port(0..8) : half(0..8) + 0..1: H53 # bit[7..15] -> H53 bit[8..0]: ingress::HillTop.Tiburon.Arnold + 7..10: W14 # bit[66..79] -> W14 bit[21..8]: ingress::HillTop.Lamona.Fristoe + 10..11: H1 # bit[84..95] -> H1 bit[11..0]: ingress::HillTop.Lamona.Traverse + 10..13: W0 # bit[110..111] -> W0 bit[1..0]: ingress::HillTop.Lamona.Whitefish + 12: B34 # bit[103] -> B34 bit[0]: ingress::HillTop.Lamona.Pachuta + shift: 16 + buf_req: 16 + next: Nuyaka + 0x****: + 0..1: H53 # bit[7..15] -> H53 bit[8..0]: ingress::HillTop.Tiburon.Arnold + 7..10: W14 # bit[66..79] -> W14 bit[21..8]: ingress::HillTop.Lamona.Fristoe + 10..11: H1 # bit[84..95] -> H1 bit[11..0]: ingress::HillTop.Lamona.Traverse + 10..13: W0 # bit[110..111] -> W0 bit[1..0]: ingress::HillTop.Lamona.Whitefish + 12: B34 # bit[103] -> B34 bit[0]: ingress::HillTop.Lamona.Pachuta + save: { half : 28..29, byte0 : 30 } + shift: 16 + buf_req: 31 + next: Mentone + Nuyaka: # from state ingress::Nuyaka + *: + 14..17: W48 + # - bit[112..117] -> W48 bit[31..26]: ingress::Millston.Hayfield.Blitchton + # - bit[118..127] -> W48 bit[25..16]: ingress::Millston.Hayfield.Avondale + # - bit[128..131] -> W48 bit[15..12]: ingress::Millston.Hayfield.Glassboro + # - bit[132..143] -> W48 bit[11..0]: ingress::Millston.Hayfield.Grabill + 21: B47 + # - bit[168..169] -> B47 bit[7..6]: ingress::Millston.Hayfield.AquaPark + # - bit[170..172] -> B47 bit[5..3]: ingress::Millston.Hayfield.Vichy + B54: 2 # value 1 -> B54 bit[1]: ingress::Millston.Hayfield.$valid + shift: 24 + buf_req: 24 + next: Nuyaka.$oob_stall_0 + Nuyaka.$oob_stall_0: # from state ingress::Nuyaka.$oob_stall_0 + *: + save: { half : 12..13, byte0 : 14 } + buf_req: 15 + next: Mentone + Mentone: # from state ingress::Mentone + match: [ byte0, half ] + 0x**9100: + 0..3: W12 + # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona + # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 + 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 + 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 + 8..11: W6 + # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 + # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens + 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 + 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 + B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid + save: { half : 16..17, byte0 : 18 } + shift: 14 + buf_req: 19 + next: Elvaston + 0x**88a8: + 0..3: W12 + # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona + # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 + 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 + 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 + 8..11: W6 + # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 + # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens + 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 + 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 + B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid + save: { half : 16..17, byte0 : 18 } + shift: 14 + buf_req: 19 + next: Elvaston + 0x**8100: + 0..3: W12 + # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona + # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 + 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 + 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 + 8..11: W6 + # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 + # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens + 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 + 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 + B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid + save: { half : 16..17, byte0 : 18 } + shift: 14 + buf_req: 19 + next: Elvaston + 0x**0806: + 0..3: W12 + # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona + # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 + 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 + 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 + 8..11: W6 + # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 + # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens + 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 + 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 + B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid + save: { half : 14..15, byte0 : 16, byte1 : 17 } + shift: 14 + buf_req: 18 + next: Corvallis + 0x450800: + 0..3: W12 + # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona + # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 + 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 + 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 + 8..11: W6 + # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 + # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens + 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 + 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 + B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid + shift: 14 + buf_req: 14 + next: Belmont + 0x*50800: + 0..3: W12 + # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona + # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 + 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 + 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 + 8..11: W6 + # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 + # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens + 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 + 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 + B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid + shift: 14 + buf_req: 14 + next: Gastonia + 0x**0800: + 0..3: W12 + # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona + # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 + 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 + 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 + 8..11: W6 + # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 + # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens + 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 + 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 + B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid + shift: 14 + buf_req: 14 + next: Hillsview + 0x6*86dd: + 0..3: W12 + # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona + # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 + 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 + 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 + 8..11: W6 + # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 + # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens + 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 + 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 + B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid + shift: 14 + buf_req: 14 + next: Westbury + 0x**86dd: + 0..3: W12 + # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona + # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 + 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 + 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 + 8..11: W6 + # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 + # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens + 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 + 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 + B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid + shift: 14 + buf_req: 14 + next: Gambrills + 0x**8808: + 0..3: W12 + # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona + # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 + 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 + 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 + 8..11: W6 + # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 + # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens + 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 + 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 + B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid + shift: 14 + buf_req: 14 + next: Masontown + 0x******: + 0..3: W12 + # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona + # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 + 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 + 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 + 8..11: W6 + # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 + # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens + 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 + 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 + B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid + shift: 14 + buf_req: 14 + next: end + Elvaston: # from state ingress::Elvaston + match: [ byte0, half ] + 0x**8100: + 0..1: H0 + # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson + # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden + 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 + 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 + B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid + save: { half : 6..7, byte0 : 8 } + shift: 4 + buf_req: 9 + next: Elkville + 0x**0806: + 0..1: H0 + # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson + # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden + 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 + 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 + B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid + save: { half : 4..5, byte0 : 6, byte1 : 7 } + shift: 4 + buf_req: 8 + next: Corvallis + 0x450800: + 0..1: H0 + # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson + # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden + 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 + 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 + B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Belmont + 0x*50800: + 0..1: H0 + # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson + # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden + 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 + 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 + B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Gastonia + 0x**0800: + 0..1: H0 + # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson + # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden + 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 + 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 + B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Hillsview + 0x6*86dd: + 0..1: H0 + # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson + # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden + 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 + 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 + B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Westbury + 0x6*86dd: + 0..1: H0 + # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson + # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden + 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 + 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 + B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Westbury + 0x**86dd: + 0..1: H0 + # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson + # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden + 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 + 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 + B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Gambrills + 0x**8808: + 0..1: H0 + # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson + # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden + 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 + 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 + B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Masontown + 0x******: + 0..1: H0 + # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson + # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden + 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 + 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 + B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: end + Elkville: # from state ingress::Elkville + match: [ byte0, half ] + 0x**0806: + 0..1: TH24 + # - bit[0..2] -> TH24 bit[15..13]: ingress::Millston.Wondervu[1].Higginson + # - bit[3] -> TH24 bit[12]: ingress::Millston.Wondervu[1].Oriskany + # - bit[4..15] -> TH24 bit[11..0]: ingress::Millston.Wondervu[1].Bowden + 2: B52 # ingress::Millston.Wondervu[1].McCaulley[15:8].8-15 + 3: B49 # ingress::Millston.Wondervu[1].McCaulley[7:0].0-7 + B12: 1 # value 1 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid + save: { half : 4..5, byte0 : 6, byte1 : 7 } + shift: 4 + buf_req: 8 + next: Corvallis + 0x450800: + 0..1: TH24 + # - bit[0..2] -> TH24 bit[15..13]: ingress::Millston.Wondervu[1].Higginson + # - bit[3] -> TH24 bit[12]: ingress::Millston.Wondervu[1].Oriskany + # - bit[4..15] -> TH24 bit[11..0]: ingress::Millston.Wondervu[1].Bowden + 2: B52 # ingress::Millston.Wondervu[1].McCaulley[15:8].8-15 + 3: B49 # ingress::Millston.Wondervu[1].McCaulley[7:0].0-7 + B12: 1 # value 1 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Belmont + 0x*50800: + 0..1: TH24 + # - bit[0..2] -> TH24 bit[15..13]: ingress::Millston.Wondervu[1].Higginson + # - bit[3] -> TH24 bit[12]: ingress::Millston.Wondervu[1].Oriskany + # - bit[4..15] -> TH24 bit[11..0]: ingress::Millston.Wondervu[1].Bowden + 2: B52 # ingress::Millston.Wondervu[1].McCaulley[15:8].8-15 + 3: B49 # ingress::Millston.Wondervu[1].McCaulley[7:0].0-7 + B12: 1 # value 1 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Gastonia + 0x**0800: + 0..1: TH24 + # - bit[0..2] -> TH24 bit[15..13]: ingress::Millston.Wondervu[1].Higginson + # - bit[3] -> TH24 bit[12]: ingress::Millston.Wondervu[1].Oriskany + # - bit[4..15] -> TH24 bit[11..0]: ingress::Millston.Wondervu[1].Bowden + 2: B52 # ingress::Millston.Wondervu[1].McCaulley[15:8].8-15 + 3: B49 # ingress::Millston.Wondervu[1].McCaulley[7:0].0-7 + B12: 1 # value 1 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Hillsview + 0x6*86dd: + 0..1: TH24 + # - bit[0..2] -> TH24 bit[15..13]: ingress::Millston.Wondervu[1].Higginson + # - bit[3] -> TH24 bit[12]: ingress::Millston.Wondervu[1].Oriskany + # - bit[4..15] -> TH24 bit[11..0]: ingress::Millston.Wondervu[1].Bowden + 2: B52 # ingress::Millston.Wondervu[1].McCaulley[15:8].8-15 + 3: B49 # ingress::Millston.Wondervu[1].McCaulley[7:0].0-7 + B12: 1 # value 1 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Westbury + 0x6*86dd: + 0..1: TH24 + # - bit[0..2] -> TH24 bit[15..13]: ingress::Millston.Wondervu[1].Higginson + # - bit[3] -> TH24 bit[12]: ingress::Millston.Wondervu[1].Oriskany + # - bit[4..15] -> TH24 bit[11..0]: ingress::Millston.Wondervu[1].Bowden + 2: B52 # ingress::Millston.Wondervu[1].McCaulley[15:8].8-15 + 3: B49 # ingress::Millston.Wondervu[1].McCaulley[7:0].0-7 + B12: 1 # value 1 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Westbury + 0x**86dd: + 0..1: TH24 + # - bit[0..2] -> TH24 bit[15..13]: ingress::Millston.Wondervu[1].Higginson + # - bit[3] -> TH24 bit[12]: ingress::Millston.Wondervu[1].Oriskany + # - bit[4..15] -> TH24 bit[11..0]: ingress::Millston.Wondervu[1].Bowden + 2: B52 # ingress::Millston.Wondervu[1].McCaulley[15:8].8-15 + 3: B49 # ingress::Millston.Wondervu[1].McCaulley[7:0].0-7 + B12: 1 # value 1 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Gambrills + 0x**8808: + 0..1: TH24 + # - bit[0..2] -> TH24 bit[15..13]: ingress::Millston.Wondervu[1].Higginson + # - bit[3] -> TH24 bit[12]: ingress::Millston.Wondervu[1].Oriskany + # - bit[4..15] -> TH24 bit[11..0]: ingress::Millston.Wondervu[1].Bowden + 2: B52 # ingress::Millston.Wondervu[1].McCaulley[15:8].8-15 + 3: B49 # ingress::Millston.Wondervu[1].McCaulley[7:0].0-7 + B12: 1 # value 1 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Masontown + 0x******: + 0..1: TH24 + # - bit[0..2] -> TH24 bit[15..13]: ingress::Millston.Wondervu[1].Higginson + # - bit[3] -> TH24 bit[12]: ingress::Millston.Wondervu[1].Oriskany + # - bit[4..15] -> TH24 bit[11..0]: ingress::Millston.Wondervu[1].Bowden + 2: B52 # ingress::Millston.Wondervu[1].McCaulley[15:8].8-15 + 3: B49 # ingress::Millston.Wondervu[1].McCaulley[7:0].0-7 + B12: 1 # value 1 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: end + Corvallis: # from state ingress::Corvallis + match: [ half, byte0, byte1 ] + 0x00010800: + 0..3: TW1 + # - bit[0..15] -> TW1 bit[31..16]: ingress::Millston.Rainelle.Conner + # - bit[16..31] -> TW1 bit[15..0]: ingress::Millston.Rainelle.Ledoux + 4..5: TH0 + # - bit[32..39] -> TH0 bit[15..8]: ingress::Millston.Rainelle.Steger + # - bit[40..47] -> TH0 bit[7..0]: ingress::Millston.Rainelle.Quogue + 6..7: H35 # ingress::Millston.Rainelle.Findlay + B54: 8 # value 1 -> B54 bit[3]: ingress::Millston.Rainelle.$valid + shift: 8 + buf_req: 8 + next: end + 0x********: + buf_req: 0 + next: end + Belmont: # from state ingress::Belmont + *: + checksum 0: + type: VERIFY + mask: [ 0, 1, 2..3, 4..5, 6, 6..7, 8, 9, 10..11, 12..15, 16..19 ] + swap: 0 + start: 1 + end: 1 + dest: H63(0) + 0..1: H89 + # - bit[0..3] -> H89 bit[15..12]: ingress::Millston.GlenAvon.Fayette + # - bit[4..7] -> H89 bit[11..8]: ingress::Millston.GlenAvon.Osterdock + # - bit[8..13] -> H89 bit[7..2]: ingress::Millston.GlenAvon.PineCity + # - bit[14..15] -> H89 bit[1..0]: ingress::Millston.GlenAvon.Alameda + 2..3: H38 # ingress::Millston.GlenAvon.Rexville + 4..7: TW0 + # - bit[32..47] -> TW0 bit[31..16]: ingress::Millston.GlenAvon.Quinwood + # - bit[48] -> TW0 bit[15]: ingress::Millston.GlenAvon.Marfa + # - bit[49] -> TW0 bit[14]: ingress::Millston.GlenAvon.Palatine + # - bit[50] -> TW0 bit[13]: ingress::Millston.GlenAvon.Mabelle + # - bit[51..63] -> TW0 bit[12..0]: ingress::Millston.GlenAvon.Hoagland + 8: TB1 # ingress::Millston.GlenAvon.Exton + 8: B59 # ingress::HillTop.RossFork.Exton + 9: B33 # ingress::Millston.GlenAvon.Ocoee + 10..11: TH25 # ingress::Millston.GlenAvon.Hackett + 12..15: W32 # ingress::Millston.GlenAvon.Kaluaaha + 16..19: W33 # ingress::Millston.GlenAvon.Calcasieu + B54: 16 # value 1 -> B54 bit[4]: ingress::Millston.GlenAvon.$valid + save: { half : 6..7, byte0 : 9 } + shift: 20 + buf_req: 20 + next: Belmont.$split_0 + Belmont.$split_0: # from state ingress::Belmont.$split_0 + match: [ half, byte0 ] + 0o*0000004: + B13: 1 # value 1 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville + save: { byte1 : 0 } + buf_req: 1 + next: Baytown + 0o*0000051: + B13: 1 # value 1 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville + buf_req: 0 + next: Lynch + 0o*0000001: + B13: 1 # value 1 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville + buf_req: 0 + next: BealCity + 0o*0000021: + B13: 1 # value 1 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville + save: { half : 2..3 } + buf_req: 4 + next: Toluca + 0o*0000006: + B13: 1 # value 1 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville + buf_req: 0 + next: Readsboro + 0o*0000057: + B13: 1 # value 1 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville + save: { half : 0..1, byte0 : 2, byte1 : 3 } + buf_req: 4 + next: Astor + 0o*0000000: + B13: 1 # value 1 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville + buf_req: 0 + next: end + 0x****06: + B13: 1 # value 1 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville + buf_req: 0 + next: Greenland + 0x******: + B13: 1 # value 1 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville + buf_req: 0 + next: Shingler + Baytown: # from state ingress::Baytown + match: [ byte1 ] + 0x45: + B57: 8 # value 8 -> B57 bit[7..0]: ingress::HillTop.RossFork.McCaulley[15:8].8-15 + H34: 128 # value 4 -> H34 bit[7..5]: ingress::HillTop.RossFork.Joslin + buf_req: 0 + next: McBrides + 0x**: + B57: 8 # value 8 -> B57 bit[7..0]: ingress::HillTop.RossFork.McCaulley[15:8].8-15 + H34: 128 # value 4 -> H34 bit[7..5]: ingress::HillTop.RossFork.Joslin + buf_req: 0 + next: Ocracoke + McBrides: # from state ingress::McBrides + *: + checksum 0: + type: VERIFY + mask: [ 0, 1, 2..3, 4..5, 6, 6..7, 8, 9, 10..11, 12..15, 16..19 ] + swap: 0 + start: 1 + end: 1 + dest: H48(0) + 0..1: H83 # bit[8..13] -> H83 bit[7..2]: ingress::HillTop.Maddock.PineCity + 0..3: TW1 + # - bit[0..3] -> TW1 bit[31..28]: ingress::Millston.Ramos.Fayette + # - bit[4..7] -> TW1 bit[27..24]: ingress::Millston.Ramos.Osterdock + # - bit[8..13] -> TW1 bit[23..18]: ingress::Millston.Ramos.PineCity + # - bit[14..15] -> TW1 bit[17..16]: ingress::Millston.Ramos.Alameda + # - bit[16..31] -> TW1 bit[15..0]: ingress::Millston.Ramos.Rexville + 4..7: TW2 + # - bit[32..47] -> TW2 bit[31..16]: ingress::Millston.Ramos.Quinwood + # - bit[48] -> TW2 bit[15]: ingress::Millston.Ramos.Marfa + # - bit[49] -> TW2 bit[14]: ingress::Millston.Ramos.Palatine + # - bit[50] -> TW2 bit[13]: ingress::Millston.Ramos.Mabelle + # - bit[51..63] -> TW2 bit[12..0]: ingress::Millston.Ramos.Hoagland + 8: B58 # ingress::HillTop.Aldan.Kenbridge + 8..9: TH1 + # - bit[64..71] -> TH1 bit[15..8]: ingress::Millston.Ramos.Exton + # - bit[72..79] -> TH1 bit[7..0]: ingress::Millston.Ramos.Ocoee + 9: B42 # ingress::HillTop.Aldan.Vinemont + 10..11: TH2 # ingress::Millston.Ramos.Hackett + 12..15: TW13 # ingress::Millston.Ramos.Kaluaaha + 12..15: W37 # ingress::HillTop.Maddock.Kaluaaha + B10: 16 # value 1 -> B10 bit[5..4]: ingress::HillTop.Aldan.Mystic[1:0].0-1 + B54: 32 # value 1 -> B54 bit[5]: ingress::Millston.Ramos.$valid + save: { half : 6..7, byte0 : 9 } + shift: 16 + buf_req: 20 + next: McBrides.$split_0 + McBrides.$split_0: # from state ingress::McBrides.$split_0 + match: [ half, byte0 ] + 0o*0000001: + 0..3: TW14 # ingress::Millston.Ramos.Calcasieu + 0..3: W36 # ingress::HillTop.Maddock.Calcasieu + shift: 4 + buf_req: 4 + next: Hapeville + 0o*0000021: + 0..3: TW14 # ingress::Millston.Ramos.Calcasieu + 0..3: W36 # ingress::HillTop.Maddock.Calcasieu + shift: 4 + buf_req: 4 + next: Barnhill + 0o*0000006: + 0..3: TW14 # ingress::Millston.Ramos.Calcasieu + 0..3: W36 # ingress::HillTop.Maddock.Calcasieu + shift: 4 + buf_req: 4 + next: NantyGlo + 0o*0000000: + 0..3: TW14 # ingress::Millston.Ramos.Calcasieu + 0..3: W36 # ingress::HillTop.Maddock.Calcasieu + shift: 4 + buf_req: 4 + next: end + 0x****06: + 0..3: TW14 # ingress::Millston.Ramos.Calcasieu + 0..3: W36 # ingress::HillTop.Maddock.Calcasieu + shift: 4 + buf_req: 4 + next: Wildorado + 0x******: + 0..3: TW14 # ingress::Millston.Ramos.Calcasieu + 0..3: W36 # ingress::HillTop.Maddock.Calcasieu + shift: 4 + buf_req: 4 + next: Dozier + Hapeville: # from state ingress::Hapeville + *: + 0..1: H9 # ingress::HillTop.RossFork.Chevak + 0..3: W47 + # - bit[0..15] -> W47 bit[31..16]: ingress::Millston.Bergton.Chevak + # - bit[16..31] -> W47 bit[15..0]: ingress::Millston.Bergton.Mendocino + B54: 64 # value 1 -> B54 bit[6]: ingress::Millston.Bergton.$valid + shift: 4 + buf_req: 4 + next: end + Barnhill: # from state ingress::Barnhill + *: + 0..1: H9 # ingress::HillTop.RossFork.Chevak + 0..3: W47 + # - bit[0..15] -> W47 bit[31..16]: ingress::Millston.Bergton.Chevak + # - bit[16..31] -> W47 bit[15..0]: ingress::Millston.Bergton.Mendocino + 2..3: H32 # ingress::HillTop.RossFork.Mendocino + 4..5: TH5 # ingress::Millston.Pawtucket.StarLake + 6..7: TH26 # ingress::Millston.Buckhorn.SoapLake + B54: 192 + # - value 1 -> B54 bit[6]: ingress::Millston.Bergton.$valid + # - value 1 -> B54 bit[7]: ingress::Millston.Pawtucket.$valid + shift: 8 + buf_req: 8 + next: Barnhill.$split_0 + Barnhill.$split_0: # from state ingress::Barnhill.$split_0 + *: + H50: 1 # value 1 -> H50 bit[1..0]: ingress::HillTop.Aldan.Kearns[2:1].1-2 + H95: 1 # value 1 -> H95 bit[0]: ingress::Millston.Buckhorn.$valid + buf_req: 0 + next: end + NantyGlo: # from state ingress::NantyGlo + *: + 0..1: H9 # ingress::HillTop.RossFork.Chevak + 0..3: W47 + # - bit[0..15] -> W47 bit[31..16]: ingress::Millston.Bergton.Chevak + # - bit[16..31] -> W47 bit[15..0]: ingress::Millston.Bergton.Mendocino + 2..3: H32 # ingress::HillTop.RossFork.Mendocino + 4..7: TW15 # ingress::Millston.Cassa.Chloride + 8..9: TH18 # ingress::Millston.Cassa.Garibaldi[31:16].16-31 + 10..11: TH5 # ingress::Millston.Cassa.Garibaldi[15:0].0-15 + 12..15: TW3 + # - bit[96..99] -> TW3 bit[31..28]: ingress::Millston.Cassa.Weinert + # - bit[100..103] -> TW3 bit[27..24]: ingress::Millston.Cassa.Cornell + # - bit[104..111] -> TW3 bit[23..16]: ingress::Millston.Cassa.Noyes + # - bit[112..127] -> TW3 bit[15..0]: ingress::Millston.Cassa.Helton + 13: B40 # ingress::HillTop.RossFork.Kremlin + B54: 64 # value 1 -> B54 bit[6]: ingress::Millston.Bergton.$valid + shift: 16 + buf_req: 16 + next: NantyGlo.$split_0 + NantyGlo.$split_0: # from state ingress::NantyGlo.$split_0 + *: + 0..1: TH26 # ingress::Millston.Buckhorn.SoapLake + H50: 3 # value 3 -> H50 bit[1..0]: ingress::HillTop.Aldan.Kearns[2:1].1-2 + H95: 3 + # - value 1 -> H95 bit[1]: ingress::Millston.Cassa.$valid + # - value 1 -> H95 bit[0]: ingress::Millston.Buckhorn.$valid + shift: 2 + buf_req: 2 + next: end + Wildorado: # from state ingress::Wildorado + *: + B7: 1 # value 1 -> B7 bit[0]: ingress::HillTop.Aldan.Kearns[0:0].0-0 + H50: 2 # value 2 -> H50 bit[1..0]: ingress::HillTop.Aldan.Kearns[2:1].1-2 + buf_req: 0 + next: end + Dozier: # from state ingress::Dozier + *: + B7: 1 # value 1 -> B7 bit[0]: ingress::HillTop.Aldan.Kearns[0:0].0-0 + buf_req: 0 + next: end + Ocracoke: # from state ingress::Ocracoke + *: + 0..1: H83 # bit[8..13] -> H83 bit[7..2]: ingress::HillTop.Maddock.PineCity + B10: 48 # value 3 -> B10 bit[5..4]: ingress::HillTop.Aldan.Mystic[1:0].0-1 + buf_req: 2 + next: end + Lynch: # from state ingress::Lynch + *: + B56: 221 # value 221 -> B56 bit[7..0]: ingress::HillTop.RossFork.McCaulley[7:0].0-7 + B57: 134 # value 134 -> B57 bit[7..0]: ingress::HillTop.RossFork.McCaulley[15:8].8-15 + H34: 128 # value 4 -> H34 bit[7..5]: ingress::HillTop.RossFork.Joslin + buf_req: 0 + next: Sanford + Sanford: # from state ingress::Sanford + *: + 0: TB3 + # - bit[0..3] -> TB3 bit[7..4]: ingress::Millston.Provencal.Fayette + # - bit[4..7] -> TB3 bit[3..0]: ingress::Millston.Provencal.PineCity[5:2].2-5 + 0..1: H84 # bit[4..9] -> H84 bit[11..6]: ingress::HillTop.Sublett.PineCity + 1..2: H35 + # - bit[8..9] -> H35 bit[15..14]: ingress::Millston.Provencal.PineCity[1:0].0-1 + # - bit[10..11] -> H35 bit[13..12]: ingress::Millston.Provencal.Alameda + # - bit[12..23] -> H35 bit[11..0]: ingress::Millston.Provencal.Maryhill[19:8].8-19 + 3: B39 # ingress::Millston.Provencal.Maryhill[7:0].0-7 + 4..7: TW1 + # - bit[32..47] -> TW1 bit[31..16]: ingress::Millston.Provencal.Norwood + # - bit[48..55] -> TW1 bit[15..8]: ingress::Millston.Provencal.Dassel + # - bit[56..63] -> TW1 bit[7..0]: ingress::Millston.Provencal.Bushland + 6: B42 # ingress::HillTop.Aldan.Vinemont + 7: B58 # ingress::HillTop.Aldan.Kenbridge + 8..9: TH2 # ingress::Millston.Provencal.Kaluaaha[127:112].112-127 + 8..11: W40 # ingress::HillTop.Sublett.Kaluaaha[127:96].96-127 + 10..11: TH1 # ingress::Millston.Provencal.Kaluaaha[111:96].96-111 + 12..15: TW14 # ingress::Millston.Provencal.Kaluaaha[95:64].64-95 + 12..15: W39 # ingress::HillTop.Sublett.Kaluaaha[95:64].64-95 + save: { byte1 : 6 } + shift: 16 + buf_req: 16 + next: Sanford.$split_0 + Sanford.$split_0: # from state ingress::Sanford.$split_0 + *: + 0..3: TW13 # ingress::Millston.Provencal.Kaluaaha[63:32].32-63 + 0..3: W3 # ingress::HillTop.Sublett.Kaluaaha[63:32].32-63 + 4..7: TW2 # ingress::Millston.Provencal.Kaluaaha[31:0].0-31 + 4..7: W37 # ingress::HillTop.Sublett.Kaluaaha[31:0].0-31 + 12..13: TH23 # ingress::Millston.Provencal.Calcasieu[95:80].80-95 + 14: TB13 # ingress::Millston.Provencal.Calcasieu[79:72].72-79 + 15: TB12 # ingress::Millston.Provencal.Calcasieu[71:64].64-71 + 16..17: TH22 # ingress::Millston.Provencal.Calcasieu[63:48].48-63 + 18..19: TH21 # ingress::Millston.Provencal.Calcasieu[47:32].32-47 + 20..21: TH20 # ingress::Millston.Provencal.Calcasieu[31:16].16-31 + B10: 32 # value 2 -> B10 bit[5..4]: ingress::HillTop.Aldan.Mystic[1:0].0-1 + shift: 8 + buf_req: 22 + next: Sanford.$split_1 + Sanford.$split_1: # from state ingress::Sanford.$split_1 + *: + 0..3: TW16 # ingress::Millston.Provencal.Calcasieu[127:96].96-127 + 0..3: W36 # ingress::HillTop.Sublett.Calcasieu[127:96].96-127 + 4..7: W46 # ingress::HillTop.Sublett.Calcasieu[95:64].64-95 + 8..11: W45 # ingress::HillTop.Sublett.Calcasieu[63:32].32-63 + 14..15: TH19 # ingress::Millston.Provencal.Calcasieu[15:0].0-15 + H95: 4 # value 1 -> H95 bit[2]: ingress::Millston.Provencal.$valid + shift: 12 + buf_req: 16 + next: Sanford.$split_2 + Sanford.$split_2: # from state ingress::Sanford.$split_2 + match: [ byte1 ] + 0x3a: + 0..3: W44 # ingress::HillTop.Sublett.Calcasieu[31:0].0-31 + shift: 4 + buf_req: 4 + next: Hapeville + 0x11: + 0..3: W44 # ingress::HillTop.Sublett.Calcasieu[31:0].0-31 + shift: 4 + buf_req: 4 + next: Barnhill + 0x06: + 0..3: W44 # ingress::HillTop.Sublett.Calcasieu[31:0].0-31 + shift: 4 + buf_req: 4 + next: NantyGlo + 0x**: + 0..3: W44 # ingress::HillTop.Sublett.Calcasieu[31:0].0-31 + shift: 4 + buf_req: 4 + next: end + BealCity: # from state ingress::BealCity + *: + 0..1: H10 # ingress::Millston.Grays.Chevak + 2..3: H33 # ingress::Millston.Grays.Mendocino + H95: 8 # value 1 -> H95 bit[3]: ingress::Millston.Grays.$valid + shift: 4 + buf_req: 4 + next: end + Toluca: # from state ingress::Toluca + match: [ half ] + 0x12b5: + 0..1: H10 # ingress::Millston.Grays.Chevak + 2..3: H33 # ingress::Millston.Grays.Mendocino + 4: TB14 # ingress::Millston.Gotham.StarLake[15:8].8-15 + 4..7: W50 # bit[48..63] -> W50 bit[15..0]: ingress::Millston.Brookneal.SoapLake + 5: TB2 # ingress::Millston.Gotham.StarLake[7:0].0-7 + H56: 1 # value 1 -> H56 bit[1..0]: ingress::HillTop.Aldan.Malinta[2:1].1-2 + H95: 56 + # - value 1 -> H95 bit[3]: ingress::Millston.Grays.$valid + # - value 1 -> H95 bit[4]: ingress::Millston.Gotham.$valid + # - value 1 -> H95 bit[5]: ingress::Millston.Brookneal.$valid + shift: 8 + buf_req: 8 + next: Goodwin + 0xff32: + 0..1: H10 # ingress::Millston.Grays.Chevak + 2..3: H33 # ingress::Millston.Grays.Mendocino + 4: TB14 # ingress::Millston.Gotham.StarLake[15:8].8-15 + 4..7: W50 # bit[48..63] -> W50 bit[15..0]: ingress::Millston.Brookneal.SoapLake + 5: TB2 # ingress::Millston.Gotham.StarLake[7:0].0-7 + H56: 1 # value 1 -> H56 bit[1..0]: ingress::HillTop.Aldan.Malinta[2:1].1-2 + H95: 56 + # - value 1 -> H95 bit[3]: ingress::Millston.Grays.$valid + # - value 1 -> H95 bit[4]: ingress::Millston.Gotham.$valid + # - value 1 -> H95 bit[5]: ingress::Millston.Brookneal.$valid + shift: 8 + buf_req: 8 + next: Goodwin + 0x****: + 0..1: H10 # ingress::Millston.Grays.Chevak + 2..3: H33 # ingress::Millston.Grays.Mendocino + 4: TB14 # ingress::Millston.Gotham.StarLake[15:8].8-15 + 4..7: W50 # bit[48..63] -> W50 bit[15..0]: ingress::Millston.Brookneal.SoapLake + 5: TB2 # ingress::Millston.Gotham.StarLake[7:0].0-7 + H56: 1 # value 1 -> H56 bit[1..0]: ingress::HillTop.Aldan.Malinta[2:1].1-2 + H95: 56 + # - value 1 -> H95 bit[3]: ingress::Millston.Grays.$valid + # - value 1 -> H95 bit[4]: ingress::Millston.Gotham.$valid + # - value 1 -> H95 bit[5]: ingress::Millston.Brookneal.$valid + shift: 8 + buf_req: 8 + next: end + Goodwin: # from state ingress::Goodwin + *: + 0: TB0 # ingress::Millston.Hoven.Noyes + 1..2: TH4 # ingress::Millston.Hoven.Allison[23:8].8-23 + 2..5: W49 # bit[32..47] -> W49 bit[15..0]: ingress::HillTop.RossFork.Everton + 3..4: TH3 + # - bit[24..31] -> TH3 bit[15..8]: ingress::Millston.Hoven.Allison[7:0].0-7 + # - bit[32..39] -> TH3 bit[7..0]: ingress::Millston.Hoven.Petrey[23:16].16-23 + 5..6: TH27 # ingress::Millston.Hoven.Petrey[15:0].0-15 + 6: B55 # ingress::HillTop.RossFork.Lafayette + 7: B32 # ingress::Millston.Hoven.Roosville + 8..11: W15 + # - bit[64..87] -> W15 bit[31..8]: ingress::Millston.Shirley.Adona + # - bit[88..95] -> W15 bit[7..0]: ingress::Millston.Shirley.Connell[23:16].16-23 + 12..13: H39 # ingress::Millston.Shirley.Connell[15:0].0-15 + 16: B35 # ingress::Millston.Shirley.Goldsboro[7:0].0-7 + shift: 14 + buf_req: 17 + next: Goodwin.$split_0 + Goodwin.$split_0: # from state ingress::Goodwin.$split_0 + *: + 0..1: H92 # ingress::Millston.Shirley.Goldsboro[23:8].8-23 + 3..4: H93 # ingress::Millston.Shirley.Fabens[23:8].8-23 + 5: B37 # ingress::Millston.Shirley.Fabens[7:0].0-7 + 6: B57 # ingress::HillTop.RossFork.McCaulley[15:8].8-15 + 6..7: H94 # ingress::Millston.Shirley.McCaulley + 7: B56 # ingress::HillTop.RossFork.McCaulley[7:0].0-7 + H34: 32 # value 1 -> H34 bit[7..5]: ingress::HillTop.RossFork.Joslin + save: { byte1 : 8, half : 6..7 } + shift: 8 + buf_req: 9 + next: Goodwin.$split_1 + Goodwin.$split_1: # from state ingress::Goodwin.$split_1 + match: [ byte1, half ] + 0x**0806: + H95: 384 + # - value 1 -> H95 bit[7]: ingress::Millston.Hoven.$valid + # - value 1 -> H95 bit[8]: ingress::Millston.Shirley.$valid + save: { half : 0..1, byte0 : 2, byte1 : 3 } + buf_req: 4 + next: Corvallis + 0x450800: + H95: 384 + # - value 1 -> H95 bit[7]: ingress::Millston.Hoven.$valid + # - value 1 -> H95 bit[8]: ingress::Millston.Shirley.$valid + buf_req: 0 + next: McBrides + 0x*50800: + H95: 384 + # - value 1 -> H95 bit[7]: ingress::Millston.Hoven.$valid + # - value 1 -> H95 bit[8]: ingress::Millston.Shirley.$valid + buf_req: 0 + next: Bernice + 0x**0800: + H95: 384 + # - value 1 -> H95 bit[7]: ingress::Millston.Hoven.$valid + # - value 1 -> H95 bit[8]: ingress::Millston.Shirley.$valid + buf_req: 0 + next: Ocracoke + 0x6*86dd: + H95: 384 + # - value 1 -> H95 bit[7]: ingress::Millston.Hoven.$valid + # - value 1 -> H95 bit[8]: ingress::Millston.Shirley.$valid + buf_req: 0 + next: Sanford + 0x**86dd: + H95: 384 + # - value 1 -> H95 bit[7]: ingress::Millston.Hoven.$valid + # - value 1 -> H95 bit[8]: ingress::Millston.Shirley.$valid + buf_req: 0 + next: Greenwood + 0x******: + H95: 384 + # - value 1 -> H95 bit[7]: ingress::Millston.Hoven.$valid + # - value 1 -> H95 bit[8]: ingress::Millston.Shirley.$valid + buf_req: 0 + next: end + Bernice: # from state ingress::Bernice + *: + B10: 16 # value 1 -> B10 bit[5..4]: ingress::HillTop.Aldan.Mystic[1:0].0-1 + B14: 1 # value 1 -> B14 bit[0]: ingress::HillTop.Aldan.Mystic[2:2].2-2 + buf_req: 0 + next: end + Greenwood: # from state ingress::Greenwood + *: + B10: 32 # value 2 -> B10 bit[5..4]: ingress::HillTop.Aldan.Mystic[1:0].0-1 + B14: 1 # value 1 -> B14 bit[0]: ingress::HillTop.Aldan.Mystic[2:2].2-2 + buf_req: 0 + next: end + Readsboro: # from state ingress::Readsboro + *: + 0..1: H10 # ingress::Millston.Grays.Chevak + 2..3: H33 # ingress::Millston.Grays.Mendocino + 4..7: TW1 # ingress::Millston.Osyka.Chloride + 8..11: TW2 # ingress::Millston.Osyka.Garibaldi + 12: TB0 + # - bit[96..99] -> TB0 bit[7..4]: ingress::Millston.Osyka.Weinert + # - bit[100..103] -> TB0 bit[3..0]: ingress::Millston.Osyka.Cornell + 13: B32 # ingress::Millston.Osyka.Noyes + 14..15: TH0 # ingress::Millston.Osyka.Helton + 14..17: W50 # bit[128..143] -> W50 bit[15..0]: ingress::Millston.Brookneal.SoapLake + H56: 3 # value 3 -> H56 bit[1..0]: ingress::HillTop.Aldan.Malinta[2:1].1-2 + shift: 18 + buf_req: 18 + next: Readsboro.$split_0 + Readsboro.$split_0: # from state ingress::Readsboro.$split_0 + *: + H95: 104 + # - value 1 -> H95 bit[3]: ingress::Millston.Grays.$valid + # - value 1 -> H95 bit[6]: ingress::Millston.Osyka.$valid + # - value 1 -> H95 bit[5]: ingress::Millston.Brookneal.$valid + buf_req: 0 + next: end + Astor: # from state ingress::Astor + match: [ half, byte0, byte1 ] + 0x00000800: + 0..1: TH0 + # - bit[0] -> TH0 bit[15]: ingress::Millston.Broadwell.Palmhurst + # - bit[1] -> TH0 bit[14]: ingress::Millston.Broadwell.Comfrey + # - bit[2] -> TH0 bit[13]: ingress::Millston.Broadwell.Kalida + # - bit[3] -> TH0 bit[12]: ingress::Millston.Broadwell.Wallula + # - bit[4] -> TH0 bit[11]: ingress::Millston.Broadwell.Dennison + # - bit[5..7] -> TH0 bit[10..8]: ingress::Millston.Broadwell.Fairhaven + # - bit[8..12] -> TH0 bit[7..3]: ingress::Millston.Broadwell.Noyes + # - bit[13..15] -> TH0 bit[2..0]: ingress::Millston.Broadwell.Woodfield + 2: TB2 # ingress::Millston.Broadwell.LasVegas[15:8].8-15 + 3: TB0 # ingress::Millston.Broadwell.LasVegas[7:0].0-7 + H95: 512 # value 1 -> H95 bit[9]: ingress::Millston.Broadwell.$valid + save: { byte1 : 4 } + shift: 4 + buf_req: 5 + next: Hohenwald + 0x000086dd: + 0..1: TH0 + # - bit[0] -> TH0 bit[15]: ingress::Millston.Broadwell.Palmhurst + # - bit[1] -> TH0 bit[14]: ingress::Millston.Broadwell.Comfrey + # - bit[2] -> TH0 bit[13]: ingress::Millston.Broadwell.Kalida + # - bit[3] -> TH0 bit[12]: ingress::Millston.Broadwell.Wallula + # - bit[4] -> TH0 bit[11]: ingress::Millston.Broadwell.Dennison + # - bit[5..7] -> TH0 bit[10..8]: ingress::Millston.Broadwell.Fairhaven + # - bit[8..12] -> TH0 bit[7..3]: ingress::Millston.Broadwell.Noyes + # - bit[13..15] -> TH0 bit[2..0]: ingress::Millston.Broadwell.Woodfield + 2: TB2 # ingress::Millston.Broadwell.LasVegas[15:8].8-15 + 3: TB0 # ingress::Millston.Broadwell.LasVegas[7:0].0-7 + H95: 512 # value 1 -> H95 bit[9]: ingress::Millston.Broadwell.$valid + save: { byte1 : 4 } + shift: 4 + buf_req: 5 + next: Eolia + 0x********: + 0..1: TH0 + # - bit[0] -> TH0 bit[15]: ingress::Millston.Broadwell.Palmhurst + # - bit[1] -> TH0 bit[14]: ingress::Millston.Broadwell.Comfrey + # - bit[2] -> TH0 bit[13]: ingress::Millston.Broadwell.Kalida + # - bit[3] -> TH0 bit[12]: ingress::Millston.Broadwell.Wallula + # - bit[4] -> TH0 bit[11]: ingress::Millston.Broadwell.Dennison + # - bit[5..7] -> TH0 bit[10..8]: ingress::Millston.Broadwell.Fairhaven + # - bit[8..12] -> TH0 bit[7..3]: ingress::Millston.Broadwell.Noyes + # - bit[13..15] -> TH0 bit[2..0]: ingress::Millston.Broadwell.Woodfield + 2: TB2 # ingress::Millston.Broadwell.LasVegas[15:8].8-15 + 3: TB0 # ingress::Millston.Broadwell.LasVegas[7:0].0-7 + H95: 512 # value 1 -> H95 bit[9]: ingress::Millston.Broadwell.$valid + shift: 4 + buf_req: 4 + next: end + Hohenwald: # from state ingress::Hohenwald + match: [ byte1 ] + 0x4*: + save: { byte1 : 0 } + buf_req: 1 + next: Sumner + 0x**: + buf_req: 0 + next: end + Sumner: # from state ingress::Sumner + match: [ byte1 ] + 0x*5: + H34: 64 # value 2 -> H34 bit[7..5]: ingress::HillTop.RossFork.Joslin + buf_req: 0 + next: McBrides + 0x**: + H34: 64 # value 2 -> H34 bit[7..5]: ingress::HillTop.RossFork.Joslin + buf_req: 0 + next: Ocracoke + Eolia: # from state ingress::Eolia + match: [ byte1 ] + 0x6*: + H34: 64 # value 2 -> H34 bit[7..5]: ingress::HillTop.RossFork.Joslin + buf_req: 0 + next: Sanford + 0x**: + buf_req: 0 + next: end + Greenland: # from state ingress::Greenland + *: + B8: 1 # value 1 -> B8 bit[0]: ingress::HillTop.Aldan.Malinta[0:0].0-0 + H56: 2 # value 2 -> H56 bit[1..0]: ingress::HillTop.Aldan.Malinta[2:1].1-2 + buf_req: 0 + next: end + Shingler: # from state ingress::Shingler + *: + B8: 1 # value 1 -> B8 bit[0]: ingress::HillTop.Aldan.Malinta[0:0].0-0 + buf_req: 0 + next: end + Gastonia: # from state ingress::Gastonia + *: + B13: 5 # value 5 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville + buf_req: 0 + next: end + Hillsview: # from state ingress::Hillsview + *: + 0..1: H89 # bit[8..13] -> H89 bit[7..2]: ingress::Millston.GlenAvon.PineCity + 8: B59 # ingress::HillTop.RossFork.Exton + 9: B33 # ingress::Millston.GlenAvon.Ocoee + 16..19: W33 # ingress::Millston.GlenAvon.Calcasieu + B13: 3 # value 3 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville + buf_req: 20 + next: end + Westbury: # from state ingress::Westbury + *: + 0..1: H89 + # - bit[0..3] -> H89 bit[15..12]: ingress::Millston.Maumee.Fayette + # - bit[4..9] -> H89 bit[11..6]: ingress::Millston.Maumee.PineCity + # - bit[10..11] -> H89 bit[5..4]: ingress::Millston.Maumee.Alameda + # - bit[12..15] -> H89 bit[3..0]: ingress::Millston.Maumee.Maryhill[19:16].16-19 + 2..3: H38 # ingress::Millston.Maumee.Maryhill[15:0].0-15 + 4: B35 # ingress::Millston.Maumee.Norwood[15:8].8-15 + 5: B37 # ingress::Millston.Maumee.Norwood[7:0].0-7 + 6: B33 # ingress::Millston.Maumee.Dassel + 7: TB1 # ingress::Millston.Maumee.Bushland + 8..11: W35 # ingress::Millston.Maumee.Kaluaaha[127:96].96-127 + 12..15: W34 # ingress::Millston.Maumee.Kaluaaha[95:64].64-95 + 16..19: W15 # ingress::Millston.Maumee.Kaluaaha[63:32].32-63 + 20..23: W33 # ingress::Millston.Maumee.Kaluaaha[31:0].0-31 + H95: 1024 # value 1 -> H95 bit[10]: ingress::Millston.Maumee.$valid + save: { byte1 : 6 } + shift: 7 + buf_req: 24 + next: Westbury.$split_0 + Westbury.$split_0: # from state ingress::Westbury.$split_0 + *: + 0: B59 # ingress::HillTop.RossFork.Exton + 17..20: W32 # ingress::Millston.Maumee.Calcasieu[127:96].96-127 + 21..24: W43 # ingress::Millston.Maumee.Calcasieu[95:64].64-95 + 25..28: W42 # ingress::Millston.Maumee.Calcasieu[63:32].32-63 + B13: 2 # value 2 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville + shift: 29 + buf_req: 29 + next: Westbury.$split_1 + Westbury.$split_1: # from state ingress::Westbury.$split_1 + match: [ byte1 ] + 0x3a: + 0..3: W41 # ingress::Millston.Maumee.Calcasieu[31:0].0-31 + shift: 4 + buf_req: 4 + next: BealCity + 0x11: + 0..3: W41 # ingress::Millston.Maumee.Calcasieu[31:0].0-31 + save: { half : 6..7 } + shift: 4 + buf_req: 8 + next: Makawao + 0x06: + 0..3: W41 # ingress::Millston.Maumee.Calcasieu[31:0].0-31 + shift: 4 + buf_req: 4 + next: Readsboro + 0x04: + 0..3: W41 # ingress::Millston.Maumee.Calcasieu[31:0].0-31 + save: { byte1 : 4 } + shift: 4 + buf_req: 5 + next: Baytown + 0x29: + 0..3: W41 # ingress::Millston.Maumee.Calcasieu[31:0].0-31 + shift: 4 + buf_req: 4 + next: Mather + 0x**: + 0..3: W41 # ingress::Millston.Maumee.Calcasieu[31:0].0-31 + shift: 4 + buf_req: 4 + next: end + Makawao: # from state ingress::Makawao + match: [ half ] + 0x****: + 0..1: H10 # ingress::Millston.Grays.Chevak + 2..3: H33 # ingress::Millston.Grays.Mendocino + 4: TB14 # ingress::Millston.Gotham.StarLake[15:8].8-15 + 4..7: W50 # bit[48..63] -> W50 bit[15..0]: ingress::Millston.Brookneal.SoapLake + 5: TB2 # ingress::Millston.Gotham.StarLake[7:0].0-7 + H56: 1 # value 1 -> H56 bit[1..0]: ingress::HillTop.Aldan.Malinta[2:1].1-2 + H95: 56 + # - value 1 -> H95 bit[3]: ingress::Millston.Grays.$valid + # - value 1 -> H95 bit[4]: ingress::Millston.Gotham.$valid + # - value 1 -> H95 bit[5]: ingress::Millston.Brookneal.$valid + shift: 8 + buf_req: 8 + next: end + Mather: # from state ingress::Mather + *: + B56: 221 # value 221 -> B56 bit[7..0]: ingress::HillTop.RossFork.McCaulley[7:0].0-7 + B57: 134 # value 134 -> B57 bit[7..0]: ingress::HillTop.RossFork.McCaulley[15:8].8-15 + H34: 128 # value 4 -> H34 bit[7..5]: ingress::HillTop.RossFork.Joslin + buf_req: 0 + next: Sanford + Gambrills: # from state ingress::Gambrills + *: + B13: 6 # value 6 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville + buf_req: 0 + next: end + Masontown: # from state ingress::Masontown + *: + B13: 8 # value 8 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville + buf_req: 0 + next: end +deparser ingress: + dictionary: + H6: B54(0) + # - bit[15..8]: ingress::Millston.Belgrade.Roachdale if ingress::Millston.Belgrade.$valid + # - bit[7..5]: ingress::Millston.Belgrade.Rugby if ingress::Millston.Belgrade.$valid + # - bit[4]: ingress::Millston.Belgrade.Davie if ingress::Millston.Belgrade.$valid + # - bit[3..0]: ingress::Millston.Belgrade.Cacao if ingress::Millston.Belgrade.$valid + B36: B54(0) # ingress::Millston.Belgrade.Mankato if ingress::Millston.Belgrade.$valid + W13: B54(0) + # - bit[31..8]: ingress::Millston.Belgrade.Virgil if ingress::Millston.Belgrade.$valid + # - bit[7..0]: ingress::Millston.Belgrade.Florin.16-23 if ingress::Millston.Belgrade.$valid + H63: B54(0) # ingress::Millston.Belgrade.Florin.0-15 if ingress::Millston.Belgrade.$valid + TW12: B54(0) # ingress::Millston.Belgrade.Ronan if ingress::Millston.Belgrade.$valid + H51: B54(0) # ingress::Millston.Belgrade.Corinth if ingress::Millston.Belgrade.$valid + B11: B54(0) + # - bit[7..4]: ingress::Millston.Belgrade.__pad_0 if ingress::Millston.Belgrade.$valid + # - bit[3..1]: ingress::Millston.Belgrade.Union if ingress::Millston.Belgrade.$valid + # - bit[0]: ingress::Millston.Belgrade.Rockport if ingress::Millston.Belgrade.$valid + B9: B54(0) + # - bit[7..6]: ingress::Millston.Belgrade.__pad_1 if ingress::Millston.Belgrade.$valid + # - bit[5]: ingress::Millston.Belgrade.Anacortes if ingress::Millston.Belgrade.$valid + # - bit[4]: ingress::Millston.Belgrade.Shabbona if ingress::Millston.Belgrade.$valid + # - bit[3..1]: ingress::Millston.Belgrade.Allgood if ingress::Millston.Belgrade.$valid + # - bit[0]: ingress::Millston.Belgrade.Waipahu if ingress::Millston.Belgrade.$valid + B34: B54(0) + # - bit[7..1]: ingress::Millston.Belgrade.__pad_2 if ingress::Millston.Belgrade.$valid + # - bit[0]: ingress::Millston.Belgrade.Freeburg if ingress::Millston.Belgrade.$valid + W1: B54(0) + # - bit[31..8]: ingress::Millston.Belgrade.__pad_3 if ingress::Millston.Belgrade.$valid + # - bit[7..2]: ingress::Millston.Belgrade.Sudbury if ingress::Millston.Belgrade.$valid + # - bit[1..0]: ingress::Millston.Belgrade.Selawik if ingress::Millston.Belgrade.$valid + B7: B54(0) + # - bit[7..3]: ingress::Millston.Belgrade.__pad_4 if ingress::Millston.Belgrade.$valid + # - bit[2..0]: ingress::Millston.Belgrade.Willard if ingress::Millston.Belgrade.$valid + H90: B54(0) + # - bit[15..6]: ingress::Millston.Belgrade.__pad_5 if ingress::Millston.Belgrade.$valid + # - bit[5..0]: ingress::Millston.Belgrade.Matheson if ingress::Millston.Belgrade.$valid + H48: B54(0) + # - bit[15..9]: ingress::Millston.Belgrade.__pad_6 if ingress::Millston.Belgrade.$valid + # - bit[8..0]: ingress::Millston.Belgrade.Chaska if ingress::Millston.Belgrade.$valid + H2: B54(0) + # - bit[15..12]: ingress::Millston.Belgrade.__pad_7 if ingress::Millston.Belgrade.$valid + # - bit[11..0]: ingress::Millston.Belgrade.Requa if ingress::Millston.Belgrade.$valid + H4: B54(0) + # - bit[15..12]: ingress::Millston.Belgrade.__pad_8 if ingress::Millston.Belgrade.$valid + # - bit[11..0]: ingress::Millston.Belgrade.Bayshore if ingress::Millston.Belgrade.$valid + H3: B54(0) + # - bit[15..12]: ingress::Millston.Belgrade.__pad_9 if ingress::Millston.Belgrade.$valid + # - bit[11..0]: ingress::Millston.Belgrade.Florien if ingress::Millston.Belgrade.$valid + W12: B54(2) + # - bit[31..8]: ingress::Millston.Calabash.Adona if ingress::Millston.Calabash.$valid + # - bit[7..0]: ingress::Millston.Calabash.Connell.16-23 if ingress::Millston.Calabash.$valid + H54: B54(2) # ingress::Millston.Calabash.Connell.0-15 if ingress::Millston.Calabash.$valid + H36: B54(2) # ingress::Millston.Calabash.Goldsboro.8-23 if ingress::Millston.Calabash.$valid + W6: B54(2) + # - bit[31..24]: ingress::Millston.Calabash.Goldsboro.0-7 if ingress::Millston.Calabash.$valid + # - bit[23..0]: ingress::Millston.Calabash.Fabens if ingress::Millston.Calabash.$valid + B53: B54(2) # ingress::Millston.Calabash.McCaulley.8-15 if ingress::Millston.Calabash.$valid + B50: B54(2) # ingress::Millston.Calabash.McCaulley.0-7 if ingress::Millston.Calabash.$valid + H0: B12(1) + # - bit[15..13]: ingress::Millston.Wondervu[0].Higginson if ingress::Millston.Wondervu[0].$valid + # - bit[12]: ingress::Millston.Wondervu[0].Oriskany if ingress::Millston.Wondervu[0].$valid + # - bit[11..0]: ingress::Millston.Wondervu[0].Bowden if ingress::Millston.Wondervu[0].$valid + B51: B12(1) # ingress::Millston.Wondervu[0].McCaulley.8-15 if ingress::Millston.Wondervu[0].$valid + B48: B12(1) # ingress::Millston.Wondervu[0].McCaulley.0-7 if ingress::Millston.Wondervu[0].$valid + TH24: B12(0) + # - bit[15..13]: ingress::Millston.Wondervu[1].Higginson if ingress::Millston.Wondervu[1].$valid + # - bit[12]: ingress::Millston.Wondervu[1].Oriskany if ingress::Millston.Wondervu[1].$valid + # - bit[11..0]: ingress::Millston.Wondervu[1].Bowden if ingress::Millston.Wondervu[1].$valid + B52: B12(0) # ingress::Millston.Wondervu[1].McCaulley.8-15 if ingress::Millston.Wondervu[1].$valid + B49: B12(0) # ingress::Millston.Wondervu[1].McCaulley.0-7 if ingress::Millston.Wondervu[1].$valid + H89: B54(4) + # - bit[15..12]: ingress::Millston.GlenAvon.Fayette if ingress::Millston.GlenAvon.$valid + # - bit[11..8]: ingress::Millston.GlenAvon.Osterdock if ingress::Millston.GlenAvon.$valid + # - bit[7..2]: ingress::Millston.GlenAvon.PineCity if ingress::Millston.GlenAvon.$valid + # - bit[1..0]: ingress::Millston.GlenAvon.Alameda if ingress::Millston.GlenAvon.$valid + H38: B54(4) # ingress::Millston.GlenAvon.Rexville if ingress::Millston.GlenAvon.$valid + TW0: B54(4) + # - bit[31..16]: ingress::Millston.GlenAvon.Quinwood if ingress::Millston.GlenAvon.$valid + # - bit[15]: ingress::Millston.GlenAvon.Marfa if ingress::Millston.GlenAvon.$valid + # - bit[14]: ingress::Millston.GlenAvon.Palatine if ingress::Millston.GlenAvon.$valid + # - bit[13]: ingress::Millston.GlenAvon.Mabelle if ingress::Millston.GlenAvon.$valid + # - bit[12..0]: ingress::Millston.GlenAvon.Hoagland if ingress::Millston.GlenAvon.$valid + TB1: B54(4) # ingress::Millston.GlenAvon.Exton if ingress::Millston.GlenAvon.$valid + B33: B54(4) # ingress::Millston.GlenAvon.Ocoee if ingress::Millston.GlenAvon.$valid + TH25: B54(4) # ingress::Millston.GlenAvon.Hackett if ingress::Millston.GlenAvon.$valid + W32: B54(4) # ingress::Millston.GlenAvon.Kaluaaha if ingress::Millston.GlenAvon.$valid + W33: B54(4) # ingress::Millston.GlenAvon.Calcasieu if ingress::Millston.GlenAvon.$valid + H89: H95(10) + # - bit[15..12]: ingress::Millston.Maumee.Fayette if ingress::Millston.Maumee.$valid + # - bit[11..6]: ingress::Millston.Maumee.PineCity if ingress::Millston.Maumee.$valid + # - bit[5..4]: ingress::Millston.Maumee.Alameda if ingress::Millston.Maumee.$valid + # - bit[3..0]: ingress::Millston.Maumee.Maryhill.16-19 if ingress::Millston.Maumee.$valid + H38: H95(10) # ingress::Millston.Maumee.Maryhill.0-15 if ingress::Millston.Maumee.$valid + B35: H95(10) # ingress::Millston.Maumee.Norwood.8-15 if ingress::Millston.Maumee.$valid + B37: H95(10) # ingress::Millston.Maumee.Norwood.0-7 if ingress::Millston.Maumee.$valid + B33: H95(10) # ingress::Millston.Maumee.Dassel if ingress::Millston.Maumee.$valid + TB1: H95(10) # ingress::Millston.Maumee.Bushland if ingress::Millston.Maumee.$valid + W35: H95(10) # ingress::Millston.Maumee.Kaluaaha.96-127 if ingress::Millston.Maumee.$valid + W34: H95(10) # ingress::Millston.Maumee.Kaluaaha.64-95 if ingress::Millston.Maumee.$valid + W15: H95(10) # ingress::Millston.Maumee.Kaluaaha.32-63 if ingress::Millston.Maumee.$valid + W33: H95(10) # ingress::Millston.Maumee.Kaluaaha.0-31 if ingress::Millston.Maumee.$valid + W32: H95(10) # ingress::Millston.Maumee.Calcasieu.96-127 if ingress::Millston.Maumee.$valid + W43: H95(10) # ingress::Millston.Maumee.Calcasieu.64-95 if ingress::Millston.Maumee.$valid + W42: H95(10) # ingress::Millston.Maumee.Calcasieu.32-63 if ingress::Millston.Maumee.$valid + W41: H95(10) # ingress::Millston.Maumee.Calcasieu.0-31 if ingress::Millston.Maumee.$valid + TH0: H95(9) + # - bit[15]: ingress::Millston.Broadwell.Palmhurst if ingress::Millston.Broadwell.$valid + # - bit[14]: ingress::Millston.Broadwell.Comfrey if ingress::Millston.Broadwell.$valid + # - bit[13]: ingress::Millston.Broadwell.Kalida if ingress::Millston.Broadwell.$valid + # - bit[12]: ingress::Millston.Broadwell.Wallula if ingress::Millston.Broadwell.$valid + # - bit[11]: ingress::Millston.Broadwell.Dennison if ingress::Millston.Broadwell.$valid + # - bit[10..8]: ingress::Millston.Broadwell.Fairhaven if ingress::Millston.Broadwell.$valid + # - bit[7..3]: ingress::Millston.Broadwell.Noyes if ingress::Millston.Broadwell.$valid + # - bit[2..0]: ingress::Millston.Broadwell.Woodfield if ingress::Millston.Broadwell.$valid + TB2: H95(9) # ingress::Millston.Broadwell.LasVegas.8-15 if ingress::Millston.Broadwell.$valid + TB0: H95(9) # ingress::Millston.Broadwell.LasVegas.0-7 if ingress::Millston.Broadwell.$valid + H10: H95(3) # ingress::Millston.Grays.Chevak if ingress::Millston.Grays.$valid + H33: H95(3) # ingress::Millston.Grays.Mendocino if ingress::Millston.Grays.$valid + TB14: H95(4) # ingress::Millston.Gotham.StarLake.8-15 if ingress::Millston.Gotham.$valid + TB2: H95(4) # ingress::Millston.Gotham.StarLake.0-7 if ingress::Millston.Gotham.$valid + TW1: H95(6) # ingress::Millston.Osyka.Chloride if ingress::Millston.Osyka.$valid + TW2: H95(6) # ingress::Millston.Osyka.Garibaldi if ingress::Millston.Osyka.$valid + TB0: H95(6) + # - bit[7..4]: ingress::Millston.Osyka.Weinert if ingress::Millston.Osyka.$valid + # - bit[3..0]: ingress::Millston.Osyka.Cornell if ingress::Millston.Osyka.$valid + B32: H95(6) # ingress::Millston.Osyka.Noyes if ingress::Millston.Osyka.$valid + TH0: H95(6) # ingress::Millston.Osyka.Helton if ingress::Millston.Osyka.$valid + checksum 0: H95(5) # ingress::Millston.Brookneal.$valid + TB0: H95(7) # ingress::Millston.Hoven.Noyes if ingress::Millston.Hoven.$valid + TH4: H95(7) # ingress::Millston.Hoven.Allison.8-23 if ingress::Millston.Hoven.$valid + TH3: H95(7) + # - bit[15..8]: ingress::Millston.Hoven.Allison.0-7 if ingress::Millston.Hoven.$valid + # - bit[7..0]: ingress::Millston.Hoven.Petrey.16-23 if ingress::Millston.Hoven.$valid + TH27: H95(7) # ingress::Millston.Hoven.Petrey.0-15 if ingress::Millston.Hoven.$valid + B32: H95(7) # ingress::Millston.Hoven.Roosville if ingress::Millston.Hoven.$valid + W15: H95(8) + # - bit[31..8]: ingress::Millston.Shirley.Adona if ingress::Millston.Shirley.$valid + # - bit[7..0]: ingress::Millston.Shirley.Connell.16-23 if ingress::Millston.Shirley.$valid + H39: H95(8) # ingress::Millston.Shirley.Connell.0-15 if ingress::Millston.Shirley.$valid + H92: H95(8) # ingress::Millston.Shirley.Goldsboro.8-23 if ingress::Millston.Shirley.$valid + B35: H95(8) # ingress::Millston.Shirley.Goldsboro.0-7 if ingress::Millston.Shirley.$valid + H93: H95(8) # ingress::Millston.Shirley.Fabens.8-23 if ingress::Millston.Shirley.$valid + B37: H95(8) # ingress::Millston.Shirley.Fabens.0-7 if ingress::Millston.Shirley.$valid + H94: H95(8) # ingress::Millston.Shirley.McCaulley if ingress::Millston.Shirley.$valid + TW1: B54(5) + # - bit[31..28]: ingress::Millston.Ramos.Fayette if ingress::Millston.Ramos.$valid + # - bit[27..24]: ingress::Millston.Ramos.Osterdock if ingress::Millston.Ramos.$valid + # - bit[23..18]: ingress::Millston.Ramos.PineCity if ingress::Millston.Ramos.$valid + # - bit[17..16]: ingress::Millston.Ramos.Alameda if ingress::Millston.Ramos.$valid + # - bit[15..0]: ingress::Millston.Ramos.Rexville if ingress::Millston.Ramos.$valid + TW2: B54(5) + # - bit[31..16]: ingress::Millston.Ramos.Quinwood if ingress::Millston.Ramos.$valid + # - bit[15]: ingress::Millston.Ramos.Marfa if ingress::Millston.Ramos.$valid + # - bit[14]: ingress::Millston.Ramos.Palatine if ingress::Millston.Ramos.$valid + # - bit[13]: ingress::Millston.Ramos.Mabelle if ingress::Millston.Ramos.$valid + # - bit[12..0]: ingress::Millston.Ramos.Hoagland if ingress::Millston.Ramos.$valid + TH1: B54(5) + # - bit[15..8]: ingress::Millston.Ramos.Exton if ingress::Millston.Ramos.$valid + # - bit[7..0]: ingress::Millston.Ramos.Ocoee if ingress::Millston.Ramos.$valid + TH2: B54(5) # ingress::Millston.Ramos.Hackett if ingress::Millston.Ramos.$valid + TW13: B54(5) # ingress::Millston.Ramos.Kaluaaha if ingress::Millston.Ramos.$valid + TW14: B54(5) # ingress::Millston.Ramos.Calcasieu if ingress::Millston.Ramos.$valid + TB3: H95(2) + # - bit[7..4]: ingress::Millston.Provencal.Fayette if ingress::Millston.Provencal.$valid + # - bit[3..0]: ingress::Millston.Provencal.PineCity.2-5 if ingress::Millston.Provencal.$valid + H35: H95(2) + # - bit[15..14]: ingress::Millston.Provencal.PineCity.0-1 if ingress::Millston.Provencal.$valid + # - bit[13..12]: ingress::Millston.Provencal.Alameda if ingress::Millston.Provencal.$valid + # - bit[11..0]: ingress::Millston.Provencal.Maryhill.8-19 if ingress::Millston.Provencal.$valid + B39: H95(2) # ingress::Millston.Provencal.Maryhill.0-7 if ingress::Millston.Provencal.$valid + TW1: H95(2) + # - bit[31..16]: ingress::Millston.Provencal.Norwood if ingress::Millston.Provencal.$valid + # - bit[15..8]: ingress::Millston.Provencal.Dassel if ingress::Millston.Provencal.$valid + # - bit[7..0]: ingress::Millston.Provencal.Bushland if ingress::Millston.Provencal.$valid + TH2: H95(2) # ingress::Millston.Provencal.Kaluaaha.112-127 if ingress::Millston.Provencal.$valid + TH1: H95(2) # ingress::Millston.Provencal.Kaluaaha.96-111 if ingress::Millston.Provencal.$valid + TW14: H95(2) # ingress::Millston.Provencal.Kaluaaha.64-95 if ingress::Millston.Provencal.$valid + TW13: H95(2) # ingress::Millston.Provencal.Kaluaaha.32-63 if ingress::Millston.Provencal.$valid + TW2: H95(2) # ingress::Millston.Provencal.Kaluaaha.0-31 if ingress::Millston.Provencal.$valid + TW16: H95(2) # ingress::Millston.Provencal.Calcasieu.96-127 if ingress::Millston.Provencal.$valid + TH23: H95(2) # ingress::Millston.Provencal.Calcasieu.80-95 if ingress::Millston.Provencal.$valid + TB13: H95(2) # ingress::Millston.Provencal.Calcasieu.72-79 if ingress::Millston.Provencal.$valid + TB12: H95(2) # ingress::Millston.Provencal.Calcasieu.64-71 if ingress::Millston.Provencal.$valid + TH22: H95(2) # ingress::Millston.Provencal.Calcasieu.48-63 if ingress::Millston.Provencal.$valid + TH21: H95(2) # ingress::Millston.Provencal.Calcasieu.32-47 if ingress::Millston.Provencal.$valid + TH20: H95(2) # ingress::Millston.Provencal.Calcasieu.16-31 if ingress::Millston.Provencal.$valid + TH19: H95(2) # ingress::Millston.Provencal.Calcasieu.0-15 if ingress::Millston.Provencal.$valid + W47: B54(6) + # - bit[31..16]: ingress::Millston.Bergton.Chevak if ingress::Millston.Bergton.$valid + # - bit[15..0]: ingress::Millston.Bergton.Mendocino if ingress::Millston.Bergton.$valid + TW15: H95(1) # ingress::Millston.Cassa.Chloride if ingress::Millston.Cassa.$valid + TH18: H95(1) # ingress::Millston.Cassa.Garibaldi.16-31 if ingress::Millston.Cassa.$valid + TH5: H95(1) # ingress::Millston.Cassa.Garibaldi.0-15 if ingress::Millston.Cassa.$valid + TW3: H95(1) + # - bit[31..28]: ingress::Millston.Cassa.Weinert if ingress::Millston.Cassa.$valid + # - bit[27..24]: ingress::Millston.Cassa.Cornell if ingress::Millston.Cassa.$valid + # - bit[23..16]: ingress::Millston.Cassa.Noyes if ingress::Millston.Cassa.$valid + # - bit[15..0]: ingress::Millston.Cassa.Helton if ingress::Millston.Cassa.$valid + TH5: B54(7) # ingress::Millston.Pawtucket.StarLake if ingress::Millston.Pawtucket.$valid + TH26: H95(0) # ingress::Millston.Buckhorn.SoapLake if ingress::Millston.Buckhorn.$valid + TW1: B54(3) + # - bit[31..16]: ingress::Millston.Rainelle.Conner if ingress::Millston.Rainelle.$valid + # - bit[15..0]: ingress::Millston.Rainelle.Ledoux if ingress::Millston.Rainelle.$valid + TH0: B54(3) + # - bit[15..8]: ingress::Millston.Rainelle.Steger if ingress::Millston.Rainelle.$valid + # - bit[7..0]: ingress::Millston.Rainelle.Quogue if ingress::Millston.Rainelle.$valid + H35: B54(3) # ingress::Millston.Rainelle.Findlay if ingress::Millston.Rainelle.$valid + checksum 0: + - W51: { } # ingress::HillTop.RossFork.Bucktown + - W50(0..15): { } # bit[15..0]: ingress::Millston.Brookneal.SoapLake + egress_unicast_port: W2(0..8) # bit[8..0]: ingress::ig_intr_md_for_tm.ucast_egress_port + icos: B8(0..2) # bit[2..0]: ingress::ig_intr_md_for_tm.ingress_cos + qid: B13(0..4) # bit[4..0]: ingress::ig_intr_md_for_tm.qid + copy_to_cpu: H52(0..0) # bit[0]: ingress::ig_intr_md_for_tm.copy_to_cpu + xid: H8 # ingress::ig_intr_md_for_tm.level1_exclusion_id + yid: W9(0..8) # bit[8..0]: ingress::ig_intr_md_for_tm.level2_exclusion_id + rid: H5 # ingress::ig_intr_md_for_tm.rid + drop_ctl: B15(0..2) # bit[2..0]: ingress::ig_intr_md_for_dprsr.drop_ctl + egress_multicast_group_0: + - H7 # ingress::ig_intr_md_for_tm.mcast_grp_a + hash_lag_ecmp_mcast_1: + - H50(0..12) # bit[12..0]: ingress::ig_intr_md_for_tm.level2_mcast_hash + learning: + select: B0(0..2) # bit[2..0]: ingress::ig_intr_md_for_dprsr.digest_type + 1: + - B0(0..2) # bit[2..0]: ingress::ig_intr_md_for_dprsr.digest_type + - H37 # ingress::HillTop.RossFork.Goldsboro.8-23 + - W8(0..7) # bit[7..0]: ingress::HillTop.RossFork.Goldsboro.0-7 + - W7(0..23) # bit[23..0]: ingress::HillTop.RossFork.Fabens + - H4(0..11) # bit[11..0]: ingress::HillTop.RossFork.CeeVee + - W4(0..19) # bit[19..0]: ingress::HillTop.RossFork.Quebrada + 2: + - B0(0..2) # bit[2..0]: ingress::ig_intr_md_for_dprsr.digest_type + - H4(0..11) # bit[11..0]: ingress::HillTop.RossFork.CeeVee + - H92 # ingress::Millston.Shirley.Goldsboro.8-23 + - B35 # ingress::Millston.Shirley.Goldsboro.0-7 + - H93 # ingress::Millston.Shirley.Fabens.8-23 + - B37 # ingress::Millston.Shirley.Fabens.0-7 + - W32 # ingress::Millston.GlenAvon.Kaluaaha + - W35 # ingress::Millston.Maumee.Kaluaaha.96-127 + - W34 # ingress::Millston.Maumee.Kaluaaha.64-95 + - W15 # ingress::Millston.Maumee.Kaluaaha.32-63 + - W33 # ingress::Millston.Maumee.Kaluaaha.0-31 + - B53 # ingress::Millston.Calabash.McCaulley.8-15 + - B50 # ingress::Millston.Calabash.McCaulley.0-7 + - W49(0..15) # bit[15..0]: ingress::HillTop.RossFork.Everton + - B55 # ingress::HillTop.RossFork.Lafayette + - B32 # ingress::Millston.Hoven.Roosville + context_json: + 1: + - [ HillTop.RossFork.Goldsboro, 1, 16, 7, 8] + - [ HillTop.RossFork.Goldsboro, 6, 8, 7, 0] + - [ HillTop.RossFork.Fabens, 8, 24, 7, 0] + - [ HillTop.RossFork.CeeVee, 11, 12, 3, 0] + - [ HillTop.RossFork.Quebrada, 14, 20, 3, 0] + 2: + - [ HillTop.RossFork.CeeVee, 1, 12, 3, 0] + - [ Millston.Shirley.Goldsboro, 3, 16, 7, 8] + - [ Millston.Shirley.Goldsboro, 5, 8, 7, 0] + - [ Millston.Shirley.Fabens, 6, 16, 7, 8] + - [ Millston.Shirley.Fabens, 8, 8, 7, 0] + - [ Millston.GlenAvon.Kaluaaha, 9, 32, 7, 0] + - [ Millston.Maumee.Kaluaaha, 13, 32, 7, 96] + - [ Millston.Maumee.Kaluaaha, 17, 32, 7, 64] + - [ Millston.Maumee.Kaluaaha, 21, 32, 7, 32] + - [ Millston.Maumee.Kaluaaha, 25, 32, 7, 0] + - [ Millston.Calabash.McCaulley, 29, 8, 7, 8] + - [ Millston.Calabash.McCaulley, 30, 8, 7, 0] + - [ HillTop.RossFork.Everton, 33, 16, 7, 0] + - [ HillTop.RossFork.Lafayette, 35, 8, 7, 0] + - [ Millston.Hoven.Roosville, 36, 8, 7, 0] + name: [ Newhalem, Westville ] + mirror: + select: B1(0..2) # bit[2..0]: ingress::ig_intr_md_for_dprsr.mirror_type + 1: + - H34(0..9) # bit[9..0]: ingress::HillTop.Minturn.Grassflat + - B38 # ingress::HillTop.Plains.Roachdale + - H57(0..8) # bit[8..0]: ingress::HillTop.Plains.Miller +parser egress: + start: $entry_point + init_zero: [ B21, H91, B30, H67, W29, W28, H21, W30, H23, B27, TW23, W25, TB10, W24, B25, B63, B19, B20, B62, H20, H80, H88, H19, B18, B61, W26, H29, H27, H74, W23 ] + bitwise_or: [ B19, H74, W23 ] + hdr_len_adj: 27 + meta_opt: 8191 + states: + $entry_point: # from state egress::$entry_point + *: + save: { half : 0..1, byte0 : 27 } + buf_req: 28 + next: start + start: # from state egress::start + match: [ half, byte0 ] + 0b*******00100001*********: + 0..1: H16 # bit[7..15] -> H16 bit[8..0]: egress::eg_intr_md.egress_port + 17..20: W27 # bit[152..167] -> W27 bit[15..0]: egress::eg_intr_md.egress_rid + 19..22: W31 # bit[179..183] -> W31 bit[4..0]: egress::eg_intr_md.egress_qid + 25..26: H17 # egress::HillTop.Sonoma.Iberia + save: { byte1 : 27 } + shift: 27 + buf_req: 28 + next: Rumson + 0x****00: + 0..1: H16 # bit[7..15] -> H16 bit[8..0]: egress::eg_intr_md.egress_port + 17..20: W27 # bit[152..167] -> W27 bit[15..0]: egress::eg_intr_md.egress_rid + 19..22: W31 # bit[179..183] -> W31 bit[4..0]: egress::eg_intr_md.egress_qid + 25..26: H17 # egress::HillTop.Sonoma.Iberia + shift: 27 + buf_req: 27 + next: Moxley + 0x******: + 0..1: H16 # bit[7..15] -> H16 bit[8..0]: egress::eg_intr_md.egress_port + 17..20: W27 # bit[152..167] -> W27 bit[15..0]: egress::eg_intr_md.egress_rid + 19..22: W31 # bit[179..183] -> W31 bit[4..0]: egress::eg_intr_md.egress_qid + 25..26: H17 # egress::HillTop.Sonoma.Iberia + save: { byte1 : 27 } + shift: 27 + buf_req: 28 + next: Stout + Rumson: # from state egress::Rumson + match: [ byte1 ] + 0x00: + B63: 1 # value 1 -> B63 bit[0]: egress::HillTop.Wisdom.Stratford + buf_req: 0 + next: Moxley + 0x**: + B63: 1 # value 1 -> B63 bit[0]: egress::HillTop.Wisdom.Stratford + save: { byte1 : 0 } + buf_req: 1 + next: Stout + Moxley: # from state egress::Moxley + *: + 0..1: H20 + # - bit[8..10] -> H20 bit[7..5]: egress::Millston.Belgrade.Rugby + # - bit[11] -> H20 bit[4]: egress::Millston.Belgrade.Davie + 2: B27 # egress::Millston.Belgrade.Mankato + 3..4: H91 # egress::Millston.Belgrade.Virgil[23:8].8-23 + 5: B21 # egress::Millston.Belgrade.Virgil[7:0].0-7 + 6..7: H67 # egress::Millston.Belgrade.Florin[23:8].8-23 + 7..10: W25 # bit[80..87] -> W25 bit[7..0]: egress::Millston.Belgrade.Ronan[23:16].16-23 + 8: B30 # egress::Millston.Belgrade.Florin[7:0].0-7 + 9: TB10 # egress::Millston.Belgrade.Ronan[31:24].24-31 + 9..12: TW23 # bit[88..103] -> TW23 bit[15..0]: egress::Millston.Belgrade.Ronan[15:0].0-15 + 11..14: W26 # bit[104..119] -> W26 bit[15..0]: egress::Millston.Belgrade.Corinth + 12..15: W29 + # - bit[124..126] -> W29 bit[3..1]: egress::Millston.Belgrade.Union + # - bit[127] -> W29 bit[0]: egress::Millston.Belgrade.Rockport + 23..24: H80 # bit[194..199] -> H80 bit[5..0]: egress::Millston.Belgrade.Matheson + shift: 13 + buf_req: 25 + next: Moxley.$oob_stall_0 + Moxley.$oob_stall_0: # from state egress::Moxley.$oob_stall_0 + *: + save: { byte1 : 23 } + buf_req: 24 + next: Moxley.$split_0 + Moxley.$split_0: # from state egress::Moxley.$split_0 + match: [ byte1 ] + 0x00: + 0..3: W28 + # - bit[26] -> W28 bit[5]: egress::Millston.Belgrade.Anacortes + # - bit[27] -> W28 bit[4]: egress::Millston.Belgrade.Shabbona + # - bit[28..30] -> W28 bit[3..1]: egress::Millston.Belgrade.Allgood + # - bit[31] -> W28 bit[0]: egress::Millston.Belgrade.Waipahu + 4: B61 # bit[39] -> B61 bit[0]: egress::Millston.Belgrade.Freeburg + 5..8: W30 + # - bit[64..69] -> W30 bit[7..2]: egress::Millston.Belgrade.Sudbury + # - bit[70..71] -> W30 bit[1..0]: egress::Millston.Belgrade.Selawik + 9: B62 # bit[77..79] -> B62 bit[2..0]: egress::Millston.Belgrade.Willard + 11..14: W24 # bit[104..111] -> W24 bit[15..8]: egress::Millston.Belgrade.Chaska[7:0].0-7 + 12: B25 # bit[103] -> B25 bit[0]: egress::Millston.Belgrade.Chaska[8:8].8-8 + 14..15: H21 # bit[116..127] -> H21 bit[11..0]: egress::Millston.Belgrade.Requa + 16..17: H29 # bit[132..143] -> H29 bit[11..0]: egress::Millston.Belgrade.Bayshore + 18..19: H27 # bit[148..159] -> H27 bit[11..0]: egress::Millston.Belgrade.Florien + W23: 1 # value 1 -> W23 bit[0]: egress::Millston.Belgrade.$valid + shift: 20 + buf_req: 20 + next: Decorah + 0x**: + 0..3: W28 + # - bit[26] -> W28 bit[5]: egress::Millston.Belgrade.Anacortes + # - bit[27] -> W28 bit[4]: egress::Millston.Belgrade.Shabbona + # - bit[28..30] -> W28 bit[3..1]: egress::Millston.Belgrade.Allgood + # - bit[31] -> W28 bit[0]: egress::Millston.Belgrade.Waipahu + 4: B61 # bit[39] -> B61 bit[0]: egress::Millston.Belgrade.Freeburg + 5..8: W30 + # - bit[64..69] -> W30 bit[7..2]: egress::Millston.Belgrade.Sudbury + # - bit[70..71] -> W30 bit[1..0]: egress::Millston.Belgrade.Selawik + 9: B62 # bit[77..79] -> B62 bit[2..0]: egress::Millston.Belgrade.Willard + 11..14: W24 # bit[104..111] -> W24 bit[15..8]: egress::Millston.Belgrade.Chaska[7:0].0-7 + 12: B25 # bit[103] -> B25 bit[0]: egress::Millston.Belgrade.Chaska[8:8].8-8 + 14..15: H21 # bit[116..127] -> H21 bit[11..0]: egress::Millston.Belgrade.Requa + 16..17: H29 # bit[132..143] -> H29 bit[11..0]: egress::Millston.Belgrade.Bayshore + 18..19: H27 # bit[148..159] -> H27 bit[11..0]: egress::Millston.Belgrade.Florien + W23: 1 # value 1 -> W23 bit[0]: egress::Millston.Belgrade.$valid + shift: 20 + buf_req: 20 + next: Decorah + Decorah: # from state egress::Decorah + *: + 0..1: H87 # egress::Millston.Calabash.Adona[23:8].8-23 + 2: B22 # egress::Millston.Calabash.Adona[7:0].0-7 + 3..4: H68 # egress::Millston.Calabash.Connell[23:8].8-23 + 5: B31 # egress::Millston.Calabash.Connell[7:0].0-7 + 6: B29 # egress::Millston.Calabash.Goldsboro[23:16].16-23 + 7..8: H73 # egress::Millston.Calabash.Goldsboro[15:0].0-15 + 9: B24 # egress::Millston.Calabash.Fabens[23:16].16-23 + 10..11: H26 # egress::Millston.Calabash.Fabens[15:0].0-15 + W23: 2 # value 1 -> W23 bit[1]: egress::Millston.Calabash.$valid + save: { half : 12..13, byte0 : 14 } + shift: 12 + buf_req: 15 + next: Decorah.$split_0 + Decorah.$split_0: # from state egress::Decorah.$split_0 + match: [ byte0, half ] + 0x**9100: + 0..1: H25 # egress::Millston.Calabash.McCaulley + save: { half : 4..5, byte0 : 6 } + shift: 2 + buf_req: 7 + next: Elvaston + 0x**88a8: + 0..1: H25 # egress::Millston.Calabash.McCaulley + save: { half : 4..5, byte0 : 6 } + shift: 2 + buf_req: 7 + next: Elvaston + 0x**8100: + 0..1: H25 # egress::Millston.Calabash.McCaulley + save: { half : 4..5, byte0 : 6 } + shift: 2 + buf_req: 7 + next: Elvaston + 0x**0806: + 0..1: H25 # egress::Millston.Calabash.McCaulley + save: { half : 2..3, byte0 : 4, byte1 : 5 } + shift: 2 + buf_req: 6 + next: Corvallis + 0x450800: + 0..1: H25 # egress::Millston.Calabash.McCaulley + save: { half : 8..9, byte0 : 11 } + shift: 2 + buf_req: 12 + next: Belmont + 0x*50800: + 0..1: H25 # egress::Millston.Calabash.McCaulley + shift: 2 + buf_req: 2 + next: end + 0x**0800: + 0..1: H25 # egress::Millston.Calabash.McCaulley + shift: 2 + buf_req: 2 + next: Hillsview + 0x6*86dd: + 0..1: H25 # egress::Millston.Calabash.McCaulley + shift: 2 + buf_req: 2 + next: Westbury + 0x**86dd: + 0..1: H25 # egress::Millston.Calabash.McCaulley + shift: 2 + buf_req: 2 + next: end + 0x**8808: + 0..1: H25 # egress::Millston.Calabash.McCaulley + shift: 2 + buf_req: 2 + next: end + 0x******: + 0..1: H25 # egress::Millston.Calabash.McCaulley + shift: 2 + buf_req: 2 + next: end + Elvaston: # from state egress::Elvaston + match: [ byte0, half ] + 0x**8100: + 0..1: H22 + # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson + # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden + 2..3: H24 # egress::Millston.Wondervu[0].McCaulley + B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid + save: { half : 6..7, byte0 : 8 } + shift: 4 + buf_req: 9 + next: Elkville + 0x**0806: + 0..1: H22 + # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson + # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden + 2..3: H24 # egress::Millston.Wondervu[0].McCaulley + B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid + save: { half : 4..5, byte0 : 6, byte1 : 7 } + shift: 4 + buf_req: 8 + next: Corvallis + 0x450800: + 0..1: H22 + # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson + # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden + 2..3: H24 # egress::Millston.Wondervu[0].McCaulley + B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid + save: { half : 10..11, byte0 : 13 } + shift: 4 + buf_req: 14 + next: Belmont + 0x*50800: + 0..1: H22 + # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson + # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden + 2..3: H24 # egress::Millston.Wondervu[0].McCaulley + B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: end + 0x**0800: + 0..1: H22 + # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson + # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden + 2..3: H24 # egress::Millston.Wondervu[0].McCaulley + B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Hillsview + 0x6*86dd: + 0..1: H22 + # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson + # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden + 2..3: H24 # egress::Millston.Wondervu[0].McCaulley + B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Westbury + 0x6*86dd: + 0..1: H22 + # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson + # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden + 2..3: H24 # egress::Millston.Wondervu[0].McCaulley + B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Westbury + 0x**86dd: + 0..1: H22 + # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson + # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden + 2..3: H24 # egress::Millston.Wondervu[0].McCaulley + B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: end + 0x**8808: + 0..1: H22 + # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson + # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden + 2..3: H24 # egress::Millston.Wondervu[0].McCaulley + B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: end + 0x******: + 0..1: H22 + # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson + # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany + # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden + 2..3: H24 # egress::Millston.Wondervu[0].McCaulley + B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: end + Elkville: # from state egress::Elkville + match: [ byte0, half ] + 0x**0806: + 0..3: TW5 + # - bit[0..2] -> TW5 bit[31..29]: egress::Millston.Wondervu[1].Higginson + # - bit[3] -> TW5 bit[28]: egress::Millston.Wondervu[1].Oriskany + # - bit[4..15] -> TW5 bit[27..16]: egress::Millston.Wondervu[1].Bowden + # - bit[16..31] -> TW5 bit[15..0]: egress::Millston.Wondervu[1].McCaulley + B19: 1 # value 1 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid + save: { half : 4..5, byte0 : 6, byte1 : 7 } + shift: 4 + buf_req: 8 + next: Corvallis + 0x450800: + 0..3: TW5 + # - bit[0..2] -> TW5 bit[31..29]: egress::Millston.Wondervu[1].Higginson + # - bit[3] -> TW5 bit[28]: egress::Millston.Wondervu[1].Oriskany + # - bit[4..15] -> TW5 bit[27..16]: egress::Millston.Wondervu[1].Bowden + # - bit[16..31] -> TW5 bit[15..0]: egress::Millston.Wondervu[1].McCaulley + B19: 1 # value 1 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid + save: { half : 10..11, byte0 : 13 } + shift: 4 + buf_req: 14 + next: Belmont + 0x*50800: + 0..3: TW5 + # - bit[0..2] -> TW5 bit[31..29]: egress::Millston.Wondervu[1].Higginson + # - bit[3] -> TW5 bit[28]: egress::Millston.Wondervu[1].Oriskany + # - bit[4..15] -> TW5 bit[27..16]: egress::Millston.Wondervu[1].Bowden + # - bit[16..31] -> TW5 bit[15..0]: egress::Millston.Wondervu[1].McCaulley + B19: 1 # value 1 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: end + 0x**0800: + 0..3: TW5 + # - bit[0..2] -> TW5 bit[31..29]: egress::Millston.Wondervu[1].Higginson + # - bit[3] -> TW5 bit[28]: egress::Millston.Wondervu[1].Oriskany + # - bit[4..15] -> TW5 bit[27..16]: egress::Millston.Wondervu[1].Bowden + # - bit[16..31] -> TW5 bit[15..0]: egress::Millston.Wondervu[1].McCaulley + B19: 1 # value 1 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Hillsview + 0x6*86dd: + 0..3: TW5 + # - bit[0..2] -> TW5 bit[31..29]: egress::Millston.Wondervu[1].Higginson + # - bit[3] -> TW5 bit[28]: egress::Millston.Wondervu[1].Oriskany + # - bit[4..15] -> TW5 bit[27..16]: egress::Millston.Wondervu[1].Bowden + # - bit[16..31] -> TW5 bit[15..0]: egress::Millston.Wondervu[1].McCaulley + B19: 1 # value 1 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Westbury + 0x6*86dd: + 0..3: TW5 + # - bit[0..2] -> TW5 bit[31..29]: egress::Millston.Wondervu[1].Higginson + # - bit[3] -> TW5 bit[28]: egress::Millston.Wondervu[1].Oriskany + # - bit[4..15] -> TW5 bit[27..16]: egress::Millston.Wondervu[1].Bowden + # - bit[16..31] -> TW5 bit[15..0]: egress::Millston.Wondervu[1].McCaulley + B19: 1 # value 1 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: Westbury + 0x**86dd: + 0..3: TW5 + # - bit[0..2] -> TW5 bit[31..29]: egress::Millston.Wondervu[1].Higginson + # - bit[3] -> TW5 bit[28]: egress::Millston.Wondervu[1].Oriskany + # - bit[4..15] -> TW5 bit[27..16]: egress::Millston.Wondervu[1].Bowden + # - bit[16..31] -> TW5 bit[15..0]: egress::Millston.Wondervu[1].McCaulley + B19: 1 # value 1 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: end + 0x**8808: + 0..3: TW5 + # - bit[0..2] -> TW5 bit[31..29]: egress::Millston.Wondervu[1].Higginson + # - bit[3] -> TW5 bit[28]: egress::Millston.Wondervu[1].Oriskany + # - bit[4..15] -> TW5 bit[27..16]: egress::Millston.Wondervu[1].Bowden + # - bit[16..31] -> TW5 bit[15..0]: egress::Millston.Wondervu[1].McCaulley + B19: 1 # value 1 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: end + 0x******: + 0..3: TW5 + # - bit[0..2] -> TW5 bit[31..29]: egress::Millston.Wondervu[1].Higginson + # - bit[3] -> TW5 bit[28]: egress::Millston.Wondervu[1].Oriskany + # - bit[4..15] -> TW5 bit[27..16]: egress::Millston.Wondervu[1].Bowden + # - bit[16..31] -> TW5 bit[15..0]: egress::Millston.Wondervu[1].McCaulley + B19: 1 # value 1 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid + shift: 4 + buf_req: 4 + next: end + Corvallis: # from state egress::Corvallis + match: [ half, byte0, byte1 ] + 0x00010800: + 0..3: TW6 + # - bit[0..15] -> TW6 bit[31..16]: egress::Millston.Rainelle.Conner + # - bit[16..31] -> TW6 bit[15..0]: egress::Millston.Rainelle.Ledoux + 4..7: TW4 + # - bit[32..39] -> TW4 bit[31..24]: egress::Millston.Rainelle.Steger + # - bit[40..47] -> TW4 bit[23..16]: egress::Millston.Rainelle.Quogue + # - bit[48..63] -> TW4 bit[15..0]: egress::Millston.Rainelle.Findlay + W23: 4 # value 1 -> W23 bit[2]: egress::Millston.Rainelle.$valid + shift: 8 + buf_req: 8 + next: end + 0x********: + buf_req: 0 + next: end + Belmont: # from state egress::Belmont + match: [ half, byte0 ] + 0o*0000004: + 0..1: H81 + # - bit[0..3] -> H81 bit[15..12]: egress::Millston.GlenAvon.Fayette + # - bit[4..7] -> H81 bit[11..8]: egress::Millston.GlenAvon.Osterdock + # - bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity + # - bit[14..15] -> H81 bit[1..0]: egress::Millston.GlenAvon.Alameda + 2..3: H18 # egress::Millston.GlenAvon.Rexville + 4..7: W16 + # - bit[32..47] -> W16 bit[31..16]: egress::Millston.GlenAvon.Quinwood + # - bit[48] -> W16 bit[15]: egress::Millston.GlenAvon.Marfa + # - bit[49] -> W16 bit[14]: egress::Millston.GlenAvon.Palatine + # - bit[50] -> W16 bit[13]: egress::Millston.GlenAvon.Mabelle + # - bit[51..63] -> W16 bit[12..0]: egress::Millston.GlenAvon.Hoagland + 8: B16 # egress::Millston.GlenAvon.Exton + 9: B23 # egress::Millston.GlenAvon.Ocoee + 10: TB20 # egress::Millston.GlenAvon.Hackett[15:8].8-15 + 11: TB11 # egress::Millston.GlenAvon.Hackett[7:0].0-7 + 12..15: W17 # egress::Millston.GlenAvon.Kaluaaha + 16..19: W18 # egress::Millston.GlenAvon.Calcasieu + W23: 8 # value 1 -> W23 bit[3]: egress::Millston.GlenAvon.$valid + save: { byte1 : 20 } + shift: 20 + buf_req: 21 + next: Baytown + 0o*0000051: + 0..1: H81 + # - bit[0..3] -> H81 bit[15..12]: egress::Millston.GlenAvon.Fayette + # - bit[4..7] -> H81 bit[11..8]: egress::Millston.GlenAvon.Osterdock + # - bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity + # - bit[14..15] -> H81 bit[1..0]: egress::Millston.GlenAvon.Alameda + 2..3: H18 # egress::Millston.GlenAvon.Rexville + 4..7: W16 + # - bit[32..47] -> W16 bit[31..16]: egress::Millston.GlenAvon.Quinwood + # - bit[48] -> W16 bit[15]: egress::Millston.GlenAvon.Marfa + # - bit[49] -> W16 bit[14]: egress::Millston.GlenAvon.Palatine + # - bit[50] -> W16 bit[13]: egress::Millston.GlenAvon.Mabelle + # - bit[51..63] -> W16 bit[12..0]: egress::Millston.GlenAvon.Hoagland + 8: B16 # egress::Millston.GlenAvon.Exton + 9: B23 # egress::Millston.GlenAvon.Ocoee + 10: TB20 # egress::Millston.GlenAvon.Hackett[15:8].8-15 + 11: TB11 # egress::Millston.GlenAvon.Hackett[7:0].0-7 + 12..15: W17 # egress::Millston.GlenAvon.Kaluaaha + 16..19: W18 # egress::Millston.GlenAvon.Calcasieu + W23: 8 # value 1 -> W23 bit[3]: egress::Millston.GlenAvon.$valid + shift: 20 + buf_req: 20 + next: Sanford + 0o*0000001: + 0..1: H81 + # - bit[0..3] -> H81 bit[15..12]: egress::Millston.GlenAvon.Fayette + # - bit[4..7] -> H81 bit[11..8]: egress::Millston.GlenAvon.Osterdock + # - bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity + # - bit[14..15] -> H81 bit[1..0]: egress::Millston.GlenAvon.Alameda + 2..3: H18 # egress::Millston.GlenAvon.Rexville + 4..7: W16 + # - bit[32..47] -> W16 bit[31..16]: egress::Millston.GlenAvon.Quinwood + # - bit[48] -> W16 bit[15]: egress::Millston.GlenAvon.Marfa + # - bit[49] -> W16 bit[14]: egress::Millston.GlenAvon.Palatine + # - bit[50] -> W16 bit[13]: egress::Millston.GlenAvon.Mabelle + # - bit[51..63] -> W16 bit[12..0]: egress::Millston.GlenAvon.Hoagland + 8: B16 # egress::Millston.GlenAvon.Exton + 9: B23 # egress::Millston.GlenAvon.Ocoee + 10: TB20 # egress::Millston.GlenAvon.Hackett[15:8].8-15 + 11: TB11 # egress::Millston.GlenAvon.Hackett[7:0].0-7 + 12..15: W17 # egress::Millston.GlenAvon.Kaluaaha + 16..19: W18 # egress::Millston.GlenAvon.Calcasieu + W23: 8 # value 1 -> W23 bit[3]: egress::Millston.GlenAvon.$valid + shift: 20 + buf_req: 20 + next: BealCity + 0o*0000021: + 0..1: H81 + # - bit[0..3] -> H81 bit[15..12]: egress::Millston.GlenAvon.Fayette + # - bit[4..7] -> H81 bit[11..8]: egress::Millston.GlenAvon.Osterdock + # - bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity + # - bit[14..15] -> H81 bit[1..0]: egress::Millston.GlenAvon.Alameda + 2..3: H18 # egress::Millston.GlenAvon.Rexville + 4..7: W16 + # - bit[32..47] -> W16 bit[31..16]: egress::Millston.GlenAvon.Quinwood + # - bit[48] -> W16 bit[15]: egress::Millston.GlenAvon.Marfa + # - bit[49] -> W16 bit[14]: egress::Millston.GlenAvon.Palatine + # - bit[50] -> W16 bit[13]: egress::Millston.GlenAvon.Mabelle + # - bit[51..63] -> W16 bit[12..0]: egress::Millston.GlenAvon.Hoagland + 8: B16 # egress::Millston.GlenAvon.Exton + 9: B23 # egress::Millston.GlenAvon.Ocoee + 10: TB20 # egress::Millston.GlenAvon.Hackett[15:8].8-15 + 11: TB11 # egress::Millston.GlenAvon.Hackett[7:0].0-7 + 12..15: W17 # egress::Millston.GlenAvon.Kaluaaha + 16..19: W18 # egress::Millston.GlenAvon.Calcasieu + W23: 8 # value 1 -> W23 bit[3]: egress::Millston.GlenAvon.$valid + shift: 20 + buf_req: 20 + next: Toluca + 0o*0000006: + 0..1: H81 + # - bit[0..3] -> H81 bit[15..12]: egress::Millston.GlenAvon.Fayette + # - bit[4..7] -> H81 bit[11..8]: egress::Millston.GlenAvon.Osterdock + # - bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity + # - bit[14..15] -> H81 bit[1..0]: egress::Millston.GlenAvon.Alameda + 2..3: H18 # egress::Millston.GlenAvon.Rexville + 4..7: W16 + # - bit[32..47] -> W16 bit[31..16]: egress::Millston.GlenAvon.Quinwood + # - bit[48] -> W16 bit[15]: egress::Millston.GlenAvon.Marfa + # - bit[49] -> W16 bit[14]: egress::Millston.GlenAvon.Palatine + # - bit[50] -> W16 bit[13]: egress::Millston.GlenAvon.Mabelle + # - bit[51..63] -> W16 bit[12..0]: egress::Millston.GlenAvon.Hoagland + 8: B16 # egress::Millston.GlenAvon.Exton + 9: B23 # egress::Millston.GlenAvon.Ocoee + 10: TB20 # egress::Millston.GlenAvon.Hackett[15:8].8-15 + 11: TB11 # egress::Millston.GlenAvon.Hackett[7:0].0-7 + 12..15: W17 # egress::Millston.GlenAvon.Kaluaaha + 16..19: W18 # egress::Millston.GlenAvon.Calcasieu + W23: 8 # value 1 -> W23 bit[3]: egress::Millston.GlenAvon.$valid + shift: 20 + buf_req: 20 + next: Readsboro + 0o*0000057: + 0..1: H81 + # - bit[0..3] -> H81 bit[15..12]: egress::Millston.GlenAvon.Fayette + # - bit[4..7] -> H81 bit[11..8]: egress::Millston.GlenAvon.Osterdock + # - bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity + # - bit[14..15] -> H81 bit[1..0]: egress::Millston.GlenAvon.Alameda + 2..3: H18 # egress::Millston.GlenAvon.Rexville + 4..7: W16 + # - bit[32..47] -> W16 bit[31..16]: egress::Millston.GlenAvon.Quinwood + # - bit[48] -> W16 bit[15]: egress::Millston.GlenAvon.Marfa + # - bit[49] -> W16 bit[14]: egress::Millston.GlenAvon.Palatine + # - bit[50] -> W16 bit[13]: egress::Millston.GlenAvon.Mabelle + # - bit[51..63] -> W16 bit[12..0]: egress::Millston.GlenAvon.Hoagland + 8: B16 # egress::Millston.GlenAvon.Exton + 9: B23 # egress::Millston.GlenAvon.Ocoee + 10: TB20 # egress::Millston.GlenAvon.Hackett[15:8].8-15 + 11: TB11 # egress::Millston.GlenAvon.Hackett[7:0].0-7 + 12..15: W17 # egress::Millston.GlenAvon.Kaluaaha + 16..19: W18 # egress::Millston.GlenAvon.Calcasieu + W23: 8 # value 1 -> W23 bit[3]: egress::Millston.GlenAvon.$valid + save: { half : 20..21, byte0 : 22, byte1 : 23 } + shift: 20 + buf_req: 24 + next: Astor + 0o*0000000: + 0..1: H81 + # - bit[0..3] -> H81 bit[15..12]: egress::Millston.GlenAvon.Fayette + # - bit[4..7] -> H81 bit[11..8]: egress::Millston.GlenAvon.Osterdock + # - bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity + # - bit[14..15] -> H81 bit[1..0]: egress::Millston.GlenAvon.Alameda + 2..3: H18 # egress::Millston.GlenAvon.Rexville + 4..7: W16 + # - bit[32..47] -> W16 bit[31..16]: egress::Millston.GlenAvon.Quinwood + # - bit[48] -> W16 bit[15]: egress::Millston.GlenAvon.Marfa + # - bit[49] -> W16 bit[14]: egress::Millston.GlenAvon.Palatine + # - bit[50] -> W16 bit[13]: egress::Millston.GlenAvon.Mabelle + # - bit[51..63] -> W16 bit[12..0]: egress::Millston.GlenAvon.Hoagland + 8: B16 # egress::Millston.GlenAvon.Exton + 9: B23 # egress::Millston.GlenAvon.Ocoee + 10: TB20 # egress::Millston.GlenAvon.Hackett[15:8].8-15 + 11: TB11 # egress::Millston.GlenAvon.Hackett[7:0].0-7 + 12..15: W17 # egress::Millston.GlenAvon.Kaluaaha + 16..19: W18 # egress::Millston.GlenAvon.Calcasieu + W23: 8 # value 1 -> W23 bit[3]: egress::Millston.GlenAvon.$valid + shift: 20 + buf_req: 20 + next: end + 0x****06: + 0..1: H81 + # - bit[0..3] -> H81 bit[15..12]: egress::Millston.GlenAvon.Fayette + # - bit[4..7] -> H81 bit[11..8]: egress::Millston.GlenAvon.Osterdock + # - bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity + # - bit[14..15] -> H81 bit[1..0]: egress::Millston.GlenAvon.Alameda + 2..3: H18 # egress::Millston.GlenAvon.Rexville + 4..7: W16 + # - bit[32..47] -> W16 bit[31..16]: egress::Millston.GlenAvon.Quinwood + # - bit[48] -> W16 bit[15]: egress::Millston.GlenAvon.Marfa + # - bit[49] -> W16 bit[14]: egress::Millston.GlenAvon.Palatine + # - bit[50] -> W16 bit[13]: egress::Millston.GlenAvon.Mabelle + # - bit[51..63] -> W16 bit[12..0]: egress::Millston.GlenAvon.Hoagland + 8: B16 # egress::Millston.GlenAvon.Exton + 9: B23 # egress::Millston.GlenAvon.Ocoee + 10: TB20 # egress::Millston.GlenAvon.Hackett[15:8].8-15 + 11: TB11 # egress::Millston.GlenAvon.Hackett[7:0].0-7 + 12..15: W17 # egress::Millston.GlenAvon.Kaluaaha + 16..19: W18 # egress::Millston.GlenAvon.Calcasieu + W23: 8 # value 1 -> W23 bit[3]: egress::Millston.GlenAvon.$valid + shift: 20 + buf_req: 20 + next: end + 0x******: + 0..1: H81 + # - bit[0..3] -> H81 bit[15..12]: egress::Millston.GlenAvon.Fayette + # - bit[4..7] -> H81 bit[11..8]: egress::Millston.GlenAvon.Osterdock + # - bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity + # - bit[14..15] -> H81 bit[1..0]: egress::Millston.GlenAvon.Alameda + 2..3: H18 # egress::Millston.GlenAvon.Rexville + 4..7: W16 + # - bit[32..47] -> W16 bit[31..16]: egress::Millston.GlenAvon.Quinwood + # - bit[48] -> W16 bit[15]: egress::Millston.GlenAvon.Marfa + # - bit[49] -> W16 bit[14]: egress::Millston.GlenAvon.Palatine + # - bit[50] -> W16 bit[13]: egress::Millston.GlenAvon.Mabelle + # - bit[51..63] -> W16 bit[12..0]: egress::Millston.GlenAvon.Hoagland + 8: B16 # egress::Millston.GlenAvon.Exton + 9: B23 # egress::Millston.GlenAvon.Ocoee + 10: TB20 # egress::Millston.GlenAvon.Hackett[15:8].8-15 + 11: TB11 # egress::Millston.GlenAvon.Hackett[7:0].0-7 + 12..15: W17 # egress::Millston.GlenAvon.Kaluaaha + 16..19: W18 # egress::Millston.GlenAvon.Calcasieu + W23: 8 # value 1 -> W23 bit[3]: egress::Millston.GlenAvon.$valid + shift: 20 + buf_req: 20 + next: end + Baytown: # from state egress::Baytown + match: [ byte1 ] + 0x45: + save: { half : 6..7, byte0 : 9 } + buf_req: 10 + next: McBrides + 0x**: + buf_req: 0 + next: end + McBrides: # from state egress::McBrides + match: [ half, byte0 ] + 0o*0000001: + 0..1: H82 + # - bit[0..3] -> H82 bit[15..12]: egress::Millston.Ramos.Fayette + # - bit[4..7] -> H82 bit[11..8]: egress::Millston.Ramos.Osterdock + # - bit[8..13] -> H82 bit[7..2]: egress::Millston.Ramos.PineCity + # - bit[14..15] -> H82 bit[1..0]: egress::Millston.Ramos.Alameda + 2..3: TH15 # egress::Millston.Ramos.Rexville + 4..7: TW4 + # - bit[32..47] -> TW4 bit[31..16]: egress::Millston.Ramos.Quinwood + # - bit[48] -> TW4 bit[15]: egress::Millston.Ramos.Marfa + # - bit[49] -> TW4 bit[14]: egress::Millston.Ramos.Palatine + # - bit[50] -> TW4 bit[13]: egress::Millston.Ramos.Mabelle + # - bit[51..63] -> TW4 bit[12..0]: egress::Millston.Ramos.Hoagland + 8..9: TH6 + # - bit[64..71] -> TH6 bit[15..8]: egress::Millston.Ramos.Exton + # - bit[72..79] -> TH6 bit[7..0]: egress::Millston.Ramos.Ocoee + 10: TB7 # egress::Millston.Ramos.Hackett[15:8].8-15 + 11: TB6 # egress::Millston.Ramos.Hackett[7:0].0-7 + 12..15: TW10 # egress::Millston.Ramos.Kaluaaha + 16..19: TW11 # egress::Millston.Ramos.Calcasieu + W23: 16 # value 1 -> W23 bit[4]: egress::Millston.Ramos.$valid + shift: 20 + buf_req: 20 + next: Hapeville + 0o*0000021: + 0..1: H82 + # - bit[0..3] -> H82 bit[15..12]: egress::Millston.Ramos.Fayette + # - bit[4..7] -> H82 bit[11..8]: egress::Millston.Ramos.Osterdock + # - bit[8..13] -> H82 bit[7..2]: egress::Millston.Ramos.PineCity + # - bit[14..15] -> H82 bit[1..0]: egress::Millston.Ramos.Alameda + 2..3: TH15 # egress::Millston.Ramos.Rexville + 4..7: TW4 + # - bit[32..47] -> TW4 bit[31..16]: egress::Millston.Ramos.Quinwood + # - bit[48] -> TW4 bit[15]: egress::Millston.Ramos.Marfa + # - bit[49] -> TW4 bit[14]: egress::Millston.Ramos.Palatine + # - bit[50] -> TW4 bit[13]: egress::Millston.Ramos.Mabelle + # - bit[51..63] -> TW4 bit[12..0]: egress::Millston.Ramos.Hoagland + 8..9: TH6 + # - bit[64..71] -> TH6 bit[15..8]: egress::Millston.Ramos.Exton + # - bit[72..79] -> TH6 bit[7..0]: egress::Millston.Ramos.Ocoee + 10: TB7 # egress::Millston.Ramos.Hackett[15:8].8-15 + 11: TB6 # egress::Millston.Ramos.Hackett[7:0].0-7 + 12..15: TW10 # egress::Millston.Ramos.Kaluaaha + 16..19: TW11 # egress::Millston.Ramos.Calcasieu + W23: 16 # value 1 -> W23 bit[4]: egress::Millston.Ramos.$valid + shift: 20 + buf_req: 20 + next: Barnhill + 0o*0000006: + 0..1: H82 + # - bit[0..3] -> H82 bit[15..12]: egress::Millston.Ramos.Fayette + # - bit[4..7] -> H82 bit[11..8]: egress::Millston.Ramos.Osterdock + # - bit[8..13] -> H82 bit[7..2]: egress::Millston.Ramos.PineCity + # - bit[14..15] -> H82 bit[1..0]: egress::Millston.Ramos.Alameda + 2..3: TH15 # egress::Millston.Ramos.Rexville + 4..7: TW4 + # - bit[32..47] -> TW4 bit[31..16]: egress::Millston.Ramos.Quinwood + # - bit[48] -> TW4 bit[15]: egress::Millston.Ramos.Marfa + # - bit[49] -> TW4 bit[14]: egress::Millston.Ramos.Palatine + # - bit[50] -> TW4 bit[13]: egress::Millston.Ramos.Mabelle + # - bit[51..63] -> TW4 bit[12..0]: egress::Millston.Ramos.Hoagland + 8..9: TH6 + # - bit[64..71] -> TH6 bit[15..8]: egress::Millston.Ramos.Exton + # - bit[72..79] -> TH6 bit[7..0]: egress::Millston.Ramos.Ocoee + 10: TB7 # egress::Millston.Ramos.Hackett[15:8].8-15 + 11: TB6 # egress::Millston.Ramos.Hackett[7:0].0-7 + 12..15: TW10 # egress::Millston.Ramos.Kaluaaha + 16..19: TW11 # egress::Millston.Ramos.Calcasieu + W23: 16 # value 1 -> W23 bit[4]: egress::Millston.Ramos.$valid + shift: 20 + buf_req: 20 + next: NantyGlo + 0o*0000000: + 0..1: H82 + # - bit[0..3] -> H82 bit[15..12]: egress::Millston.Ramos.Fayette + # - bit[4..7] -> H82 bit[11..8]: egress::Millston.Ramos.Osterdock + # - bit[8..13] -> H82 bit[7..2]: egress::Millston.Ramos.PineCity + # - bit[14..15] -> H82 bit[1..0]: egress::Millston.Ramos.Alameda + 2..3: TH15 # egress::Millston.Ramos.Rexville + 4..7: TW4 + # - bit[32..47] -> TW4 bit[31..16]: egress::Millston.Ramos.Quinwood + # - bit[48] -> TW4 bit[15]: egress::Millston.Ramos.Marfa + # - bit[49] -> TW4 bit[14]: egress::Millston.Ramos.Palatine + # - bit[50] -> TW4 bit[13]: egress::Millston.Ramos.Mabelle + # - bit[51..63] -> TW4 bit[12..0]: egress::Millston.Ramos.Hoagland + 8..9: TH6 + # - bit[64..71] -> TH6 bit[15..8]: egress::Millston.Ramos.Exton + # - bit[72..79] -> TH6 bit[7..0]: egress::Millston.Ramos.Ocoee + 10: TB7 # egress::Millston.Ramos.Hackett[15:8].8-15 + 11: TB6 # egress::Millston.Ramos.Hackett[7:0].0-7 + 12..15: TW10 # egress::Millston.Ramos.Kaluaaha + 16..19: TW11 # egress::Millston.Ramos.Calcasieu + W23: 16 # value 1 -> W23 bit[4]: egress::Millston.Ramos.$valid + shift: 20 + buf_req: 20 + next: end + 0x****06: + 0..1: H82 + # - bit[0..3] -> H82 bit[15..12]: egress::Millston.Ramos.Fayette + # - bit[4..7] -> H82 bit[11..8]: egress::Millston.Ramos.Osterdock + # - bit[8..13] -> H82 bit[7..2]: egress::Millston.Ramos.PineCity + # - bit[14..15] -> H82 bit[1..0]: egress::Millston.Ramos.Alameda + 2..3: TH15 # egress::Millston.Ramos.Rexville + 4..7: TW4 + # - bit[32..47] -> TW4 bit[31..16]: egress::Millston.Ramos.Quinwood + # - bit[48] -> TW4 bit[15]: egress::Millston.Ramos.Marfa + # - bit[49] -> TW4 bit[14]: egress::Millston.Ramos.Palatine + # - bit[50] -> TW4 bit[13]: egress::Millston.Ramos.Mabelle + # - bit[51..63] -> TW4 bit[12..0]: egress::Millston.Ramos.Hoagland + 8..9: TH6 + # - bit[64..71] -> TH6 bit[15..8]: egress::Millston.Ramos.Exton + # - bit[72..79] -> TH6 bit[7..0]: egress::Millston.Ramos.Ocoee + 10: TB7 # egress::Millston.Ramos.Hackett[15:8].8-15 + 11: TB6 # egress::Millston.Ramos.Hackett[7:0].0-7 + 12..15: TW10 # egress::Millston.Ramos.Kaluaaha + 16..19: TW11 # egress::Millston.Ramos.Calcasieu + W23: 16 # value 1 -> W23 bit[4]: egress::Millston.Ramos.$valid + shift: 20 + buf_req: 20 + next: end + 0x******: + 0..1: H82 + # - bit[0..3] -> H82 bit[15..12]: egress::Millston.Ramos.Fayette + # - bit[4..7] -> H82 bit[11..8]: egress::Millston.Ramos.Osterdock + # - bit[8..13] -> H82 bit[7..2]: egress::Millston.Ramos.PineCity + # - bit[14..15] -> H82 bit[1..0]: egress::Millston.Ramos.Alameda + 2..3: TH15 # egress::Millston.Ramos.Rexville + 4..7: TW4 + # - bit[32..47] -> TW4 bit[31..16]: egress::Millston.Ramos.Quinwood + # - bit[48] -> TW4 bit[15]: egress::Millston.Ramos.Marfa + # - bit[49] -> TW4 bit[14]: egress::Millston.Ramos.Palatine + # - bit[50] -> TW4 bit[13]: egress::Millston.Ramos.Mabelle + # - bit[51..63] -> TW4 bit[12..0]: egress::Millston.Ramos.Hoagland + 8..9: TH6 + # - bit[64..71] -> TH6 bit[15..8]: egress::Millston.Ramos.Exton + # - bit[72..79] -> TH6 bit[7..0]: egress::Millston.Ramos.Ocoee + 10: TB7 # egress::Millston.Ramos.Hackett[15:8].8-15 + 11: TB6 # egress::Millston.Ramos.Hackett[7:0].0-7 + 12..15: TW10 # egress::Millston.Ramos.Kaluaaha + 16..19: TW11 # egress::Millston.Ramos.Calcasieu + W23: 16 # value 1 -> W23 bit[4]: egress::Millston.Ramos.$valid + shift: 20 + buf_req: 20 + next: end + Hapeville: # from state egress::Hapeville + *: + 0..1: TH8 # egress::Millston.Bergton.Chevak + 2..3: TH7 # egress::Millston.Bergton.Mendocino + W23: 32 # value 1 -> W23 bit[5]: egress::Millston.Bergton.$valid + shift: 4 + buf_req: 4 + next: end + Barnhill: # from state egress::Barnhill + *: + 0..1: TH8 # egress::Millston.Bergton.Chevak + 2..3: TH7 # egress::Millston.Bergton.Mendocino + 4..5: TH11 # egress::Millston.Pawtucket.StarLake + 6..7: TH31 # egress::Millston.Buckhorn.SoapLake + W23: 224 + # - value 1 -> W23 bit[5]: egress::Millston.Bergton.$valid + # - value 1 -> W23 bit[6]: egress::Millston.Pawtucket.$valid + # - value 1 -> W23 bit[7]: egress::Millston.Buckhorn.$valid + shift: 8 + buf_req: 8 + next: end + NantyGlo: # from state egress::NantyGlo + *: + 0..1: TH8 # egress::Millston.Bergton.Chevak + 2..3: TH7 # egress::Millston.Bergton.Mendocino + 4..5: TH12 # egress::Millston.Cassa.Chloride[31:16].16-31 + 6..7: TH11 # egress::Millston.Cassa.Chloride[15:0].0-15 + 12..15: TW6 + # - bit[96..99] -> TW6 bit[31..28]: egress::Millston.Cassa.Weinert + # - bit[100..103] -> TW6 bit[27..24]: egress::Millston.Cassa.Cornell + # - bit[104..111] -> TW6 bit[23..16]: egress::Millston.Cassa.Noyes + # - bit[112..127] -> TW6 bit[15..0]: egress::Millston.Cassa.Helton + W23: 160 + # - value 1 -> W23 bit[5]: egress::Millston.Bergton.$valid + # - value 1 -> W23 bit[7]: egress::Millston.Buckhorn.$valid + shift: 8 + buf_req: 16 + next: NantyGlo.$split_0 + NantyGlo.$split_0: # from state egress::NantyGlo.$split_0 + *: + 0..1: TH14 # egress::Millston.Cassa.Garibaldi[31:16].16-31 + 2..3: TH13 # egress::Millston.Cassa.Garibaldi[15:0].0-15 + 8..9: TH31 # egress::Millston.Buckhorn.SoapLake + H74: 1 # value 1 -> H74 bit[0]: egress::Millston.Cassa.$valid + shift: 10 + buf_req: 10 + next: end + Sanford: # from state egress::Sanford + *: + 0..1: H82 + # - bit[0..3] -> H82 bit[15..12]: egress::Millston.Provencal.Fayette + # - bit[4..9] -> H82 bit[11..6]: egress::Millston.Provencal.PineCity + # - bit[10..11] -> H82 bit[5..4]: egress::Millston.Provencal.Alameda + # - bit[12..15] -> H82 bit[3..0]: egress::Millston.Provencal.Maryhill[19:16].16-19 + 2..3: TH30 # egress::Millston.Provencal.Maryhill[15:0].0-15 + 4..7: TW4 + # - bit[32..47] -> TW4 bit[31..16]: egress::Millston.Provencal.Norwood + # - bit[48..55] -> TW4 bit[15..8]: egress::Millston.Provencal.Dassel + # - bit[56..63] -> TW4 bit[7..0]: egress::Millston.Provencal.Bushland + 8..9: TH16 # egress::Millston.Provencal.Kaluaaha[127:112].112-127 + 10..11: TH15 # egress::Millston.Provencal.Kaluaaha[111:96].96-111 + 14: TB7 # egress::Millston.Provencal.Kaluaaha[79:72].72-79 + 15: TB6 # egress::Millston.Provencal.Kaluaaha[71:64].64-71 + 16..19: TW11 # egress::Millston.Provencal.Kaluaaha[63:32].32-63 + 20..23: TW10 # egress::Millston.Provencal.Kaluaaha[31:0].0-31 + 24..27: TW22 # egress::Millston.Provencal.Calcasieu[127:96].96-127 + save: { byte1 : 6 } + shift: 12 + buf_req: 28 + next: Sanford.$split_0 + Sanford.$split_0: # from state egress::Sanford.$split_0 + match: [ byte1 ] + 0x3a: + 0..1: TH6 # egress::Millston.Provencal.Kaluaaha[95:80].80-95 + 16..19: TW21 # egress::Millston.Provencal.Calcasieu[95:64].64-95 + 20..23: TW20 # egress::Millston.Provencal.Calcasieu[63:32].32-63 + 24..25: TH17 # egress::Millston.Provencal.Calcasieu[31:16].16-31 + 26: TB9 # egress::Millston.Provencal.Calcasieu[15:8].8-15 + 27: TB8 # egress::Millston.Provencal.Calcasieu[7:0].0-7 + H74: 2 # value 1 -> H74 bit[1]: egress::Millston.Provencal.$valid + shift: 28 + buf_req: 28 + next: Hapeville + 0x11: + 0..1: TH6 # egress::Millston.Provencal.Kaluaaha[95:80].80-95 + 16..19: TW21 # egress::Millston.Provencal.Calcasieu[95:64].64-95 + 20..23: TW20 # egress::Millston.Provencal.Calcasieu[63:32].32-63 + 24..25: TH17 # egress::Millston.Provencal.Calcasieu[31:16].16-31 + 26: TB9 # egress::Millston.Provencal.Calcasieu[15:8].8-15 + 27: TB8 # egress::Millston.Provencal.Calcasieu[7:0].0-7 + H74: 2 # value 1 -> H74 bit[1]: egress::Millston.Provencal.$valid + shift: 28 + buf_req: 28 + next: Barnhill + 0x06: + 0..1: TH6 # egress::Millston.Provencal.Kaluaaha[95:80].80-95 + 16..19: TW21 # egress::Millston.Provencal.Calcasieu[95:64].64-95 + 20..23: TW20 # egress::Millston.Provencal.Calcasieu[63:32].32-63 + 24..25: TH17 # egress::Millston.Provencal.Calcasieu[31:16].16-31 + 26: TB9 # egress::Millston.Provencal.Calcasieu[15:8].8-15 + 27: TB8 # egress::Millston.Provencal.Calcasieu[7:0].0-7 + H74: 2 # value 1 -> H74 bit[1]: egress::Millston.Provencal.$valid + shift: 28 + buf_req: 28 + next: NantyGlo + 0x**: + 0..1: TH6 # egress::Millston.Provencal.Kaluaaha[95:80].80-95 + 16..19: TW21 # egress::Millston.Provencal.Calcasieu[95:64].64-95 + 20..23: TW20 # egress::Millston.Provencal.Calcasieu[63:32].32-63 + 24..25: TH17 # egress::Millston.Provencal.Calcasieu[31:16].16-31 + 26: TB9 # egress::Millston.Provencal.Calcasieu[15:8].8-15 + 27: TB8 # egress::Millston.Provencal.Calcasieu[7:0].0-7 + H74: 2 # value 1 -> H74 bit[1]: egress::Millston.Provencal.$valid + shift: 28 + buf_req: 28 + next: end + BealCity: # from state egress::BealCity + *: + 0..1: H70 # egress::Millston.Grays.Chevak + 2..3: H69 # egress::Millston.Grays.Mendocino + H74: 4 # value 1 -> H74 bit[2]: egress::Millston.Grays.$valid + shift: 4 + buf_req: 4 + next: end + Toluca: # from state egress::Toluca + *: + 0..1: H70 # egress::Millston.Grays.Chevak + 2..3: H69 # egress::Millston.Grays.Mendocino + 4..5: TH32 # egress::Millston.Gotham.StarLake + 6..7: TH33 # egress::Millston.Brookneal.SoapLake + save: { half : 2..3 } + shift: 8 + buf_req: 8 + next: Toluca.$split_0 + Toluca.$split_0: # from state egress::Toluca.$split_0 + match: [ half ] + 0x12b5: + H74: 28 + # - value 1 -> H74 bit[2]: egress::Millston.Grays.$valid + # - value 1 -> H74 bit[3]: egress::Millston.Gotham.$valid + # - value 1 -> H74 bit[4]: egress::Millston.Brookneal.$valid + buf_req: 0 + next: Goodwin + 0xff32: + H74: 28 + # - value 1 -> H74 bit[2]: egress::Millston.Grays.$valid + # - value 1 -> H74 bit[3]: egress::Millston.Gotham.$valid + # - value 1 -> H74 bit[4]: egress::Millston.Brookneal.$valid + buf_req: 0 + next: Goodwin + 0x****: + H74: 28 + # - value 1 -> H74 bit[2]: egress::Millston.Grays.$valid + # - value 1 -> H74 bit[3]: egress::Millston.Gotham.$valid + # - value 1 -> H74 bit[4]: egress::Millston.Brookneal.$valid + buf_req: 0 + next: end + Goodwin: # from state egress::Goodwin + *: + 0..3: TW7 + # - bit[0..7] -> TW7 bit[31..24]: egress::Millston.Hoven.Noyes + # - bit[8..31] -> TW7 bit[23..0]: egress::Millston.Hoven.Allison + 4..5: TH10 # egress::Millston.Hoven.Petrey[23:8].8-23 + 6..7: TH9 + # - bit[48..55] -> TH9 bit[15..8]: egress::Millston.Hoven.Petrey[7:0].0-7 + # - bit[56..63] -> TH9 bit[7..0]: egress::Millston.Hoven.Roosville + 8..9: TH34 # egress::Millston.Shirley.Adona[23:8].8-23 + 10: TB4 # egress::Millston.Shirley.Adona[7:0].0-7 + 11..14: TW8 + # - bit[88..111] -> TW8 bit[31..8]: egress::Millston.Shirley.Connell + # - bit[112..119] -> TW8 bit[7..0]: egress::Millston.Shirley.Goldsboro[23:16].16-23 + 15..16: TH35 # egress::Millston.Shirley.Goldsboro[15:0].0-15 + 17..20: TW9 + # - bit[136..159] -> TW9 bit[31..8]: egress::Millston.Shirley.Fabens + # - bit[160..167] -> TW9 bit[7..0]: egress::Millston.Shirley.McCaulley[15:8].8-15 + 21: TB5 # egress::Millston.Shirley.McCaulley[7:0].0-7 + save: { byte1 : 22, half : 20..21 } + shift: 22 + buf_req: 23 + next: Goodwin.$split_0 + Goodwin.$split_0: # from state egress::Goodwin.$split_0 + match: [ byte1, half ] + 0x**0806: + H74: 192 + # - value 1 -> H74 bit[6]: egress::Millston.Hoven.$valid + # - value 1 -> H74 bit[7]: egress::Millston.Shirley.$valid + save: { half : 0..1, byte0 : 2, byte1 : 3 } + buf_req: 4 + next: Corvallis + 0x450800: + H74: 192 + # - value 1 -> H74 bit[6]: egress::Millston.Hoven.$valid + # - value 1 -> H74 bit[7]: egress::Millston.Shirley.$valid + save: { half : 6..7, byte0 : 9 } + buf_req: 10 + next: McBrides + 0x*50800: + H74: 192 + # - value 1 -> H74 bit[6]: egress::Millston.Hoven.$valid + # - value 1 -> H74 bit[7]: egress::Millston.Shirley.$valid + buf_req: 0 + next: end + 0x**0800: + H74: 192 + # - value 1 -> H74 bit[6]: egress::Millston.Hoven.$valid + # - value 1 -> H74 bit[7]: egress::Millston.Shirley.$valid + buf_req: 0 + next: end + 0x6*86dd: + H74: 192 + # - value 1 -> H74 bit[6]: egress::Millston.Hoven.$valid + # - value 1 -> H74 bit[7]: egress::Millston.Shirley.$valid + buf_req: 0 + next: Sanford + 0x**86dd: + H74: 192 + # - value 1 -> H74 bit[6]: egress::Millston.Hoven.$valid + # - value 1 -> H74 bit[7]: egress::Millston.Shirley.$valid + buf_req: 0 + next: end + 0x******: + H74: 192 + # - value 1 -> H74 bit[6]: egress::Millston.Hoven.$valid + # - value 1 -> H74 bit[7]: egress::Millston.Shirley.$valid + buf_req: 0 + next: end + Readsboro: # from state egress::Readsboro + *: + 0..1: H70 # egress::Millston.Grays.Chevak + 2..3: H69 # egress::Millston.Grays.Mendocino + 4..7: TW4 # egress::Millston.Osyka.Chloride + 8..11: TW6 # egress::Millston.Osyka.Garibaldi + 12: TB4 + # - bit[96..99] -> TB4 bit[7..4]: egress::Millston.Osyka.Weinert + # - bit[100..103] -> TB4 bit[3..0]: egress::Millston.Osyka.Cornell + 13: B46 # egress::Millston.Osyka.Noyes + 14: TB6 # egress::Millston.Osyka.Helton[15:8].8-15 + 15: TB5 # egress::Millston.Osyka.Helton[7:0].0-7 + 16..17: TH33 # egress::Millston.Brookneal.SoapLake + H74: 52 + # - value 1 -> H74 bit[2]: egress::Millston.Grays.$valid + # - value 1 -> H74 bit[5]: egress::Millston.Osyka.$valid + # - value 1 -> H74 bit[4]: egress::Millston.Brookneal.$valid + shift: 18 + buf_req: 18 + next: end + Astor: # from state egress::Astor + match: [ half, byte0, byte1 ] + 0x00000800: + 0: TB5 + # - bit[0] -> TB5 bit[7]: egress::Millston.Broadwell.Palmhurst + # - bit[1] -> TB5 bit[6]: egress::Millston.Broadwell.Comfrey + # - bit[2] -> TB5 bit[5]: egress::Millston.Broadwell.Kalida + # - bit[3] -> TB5 bit[4]: egress::Millston.Broadwell.Wallula + # - bit[4] -> TB5 bit[3]: egress::Millston.Broadwell.Dennison + # - bit[5..7] -> TB5 bit[2..0]: egress::Millston.Broadwell.Fairhaven + 1: TB4 + # - bit[8..12] -> TB4 bit[7..3]: egress::Millston.Broadwell.Noyes + # - bit[13..15] -> TB4 bit[2..0]: egress::Millston.Broadwell.Woodfield + 2..3: H69 # egress::Millston.Broadwell.LasVegas + H74: 256 # value 1 -> H74 bit[8]: egress::Millston.Broadwell.$valid + save: { byte1 : 4 } + shift: 4 + buf_req: 5 + next: Hohenwald + 0x000086dd: + 0: TB5 + # - bit[0] -> TB5 bit[7]: egress::Millston.Broadwell.Palmhurst + # - bit[1] -> TB5 bit[6]: egress::Millston.Broadwell.Comfrey + # - bit[2] -> TB5 bit[5]: egress::Millston.Broadwell.Kalida + # - bit[3] -> TB5 bit[4]: egress::Millston.Broadwell.Wallula + # - bit[4] -> TB5 bit[3]: egress::Millston.Broadwell.Dennison + # - bit[5..7] -> TB5 bit[2..0]: egress::Millston.Broadwell.Fairhaven + 1: TB4 + # - bit[8..12] -> TB4 bit[7..3]: egress::Millston.Broadwell.Noyes + # - bit[13..15] -> TB4 bit[2..0]: egress::Millston.Broadwell.Woodfield + 2..3: H69 # egress::Millston.Broadwell.LasVegas + H74: 256 # value 1 -> H74 bit[8]: egress::Millston.Broadwell.$valid + save: { byte1 : 4 } + shift: 4 + buf_req: 5 + next: Eolia + 0x********: + 0: TB5 + # - bit[0] -> TB5 bit[7]: egress::Millston.Broadwell.Palmhurst + # - bit[1] -> TB5 bit[6]: egress::Millston.Broadwell.Comfrey + # - bit[2] -> TB5 bit[5]: egress::Millston.Broadwell.Kalida + # - bit[3] -> TB5 bit[4]: egress::Millston.Broadwell.Wallula + # - bit[4] -> TB5 bit[3]: egress::Millston.Broadwell.Dennison + # - bit[5..7] -> TB5 bit[2..0]: egress::Millston.Broadwell.Fairhaven + 1: TB4 + # - bit[8..12] -> TB4 bit[7..3]: egress::Millston.Broadwell.Noyes + # - bit[13..15] -> TB4 bit[2..0]: egress::Millston.Broadwell.Woodfield + 2..3: H69 # egress::Millston.Broadwell.LasVegas + H74: 256 # value 1 -> H74 bit[8]: egress::Millston.Broadwell.$valid + shift: 4 + buf_req: 4 + next: end + Hohenwald: # from state egress::Hohenwald + match: [ byte1 ] + 0x4*: + save: { byte1 : 0 } + buf_req: 1 + next: Sumner + 0x**: + buf_req: 0 + next: end + Sumner: # from state egress::Sumner + match: [ byte1 ] + 0x*5: + save: { half : 6..7, byte0 : 9 } + buf_req: 10 + next: McBrides + 0x**: + buf_req: 0 + next: end + Eolia: # from state egress::Eolia + match: [ byte1 ] + 0x6*: + 0..1: H82 + # - bit[0..3] -> H82 bit[15..12]: egress::Millston.Provencal.Fayette + # - bit[4..9] -> H82 bit[11..6]: egress::Millston.Provencal.PineCity + # - bit[10..11] -> H82 bit[5..4]: egress::Millston.Provencal.Alameda + # - bit[12..15] -> H82 bit[3..0]: egress::Millston.Provencal.Maryhill[19:16].16-19 + 2..3: TH30 # egress::Millston.Provencal.Maryhill[15:0].0-15 + 4..7: TW4 + # - bit[32..47] -> TW4 bit[31..16]: egress::Millston.Provencal.Norwood + # - bit[48..55] -> TW4 bit[15..8]: egress::Millston.Provencal.Dassel + # - bit[56..63] -> TW4 bit[7..0]: egress::Millston.Provencal.Bushland + 8..9: TH16 # egress::Millston.Provencal.Kaluaaha[127:112].112-127 + 10..11: TH15 # egress::Millston.Provencal.Kaluaaha[111:96].96-111 + 14: TB7 # egress::Millston.Provencal.Kaluaaha[79:72].72-79 + 15: TB6 # egress::Millston.Provencal.Kaluaaha[71:64].64-71 + 16..19: TW11 # egress::Millston.Provencal.Kaluaaha[63:32].32-63 + 20..23: TW10 # egress::Millston.Provencal.Kaluaaha[31:0].0-31 + 24..27: TW22 # egress::Millston.Provencal.Calcasieu[127:96].96-127 + save: { byte1 : 6 } + shift: 12 + buf_req: 28 + next: Sanford.$split_0 + 0x**: + buf_req: 0 + next: end + Hillsview: # from state egress::Hillsview + *: + 0..1: H81 # bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity + 9: B23 # egress::Millston.GlenAvon.Ocoee + 16..19: W18 # egress::Millston.GlenAvon.Calcasieu + buf_req: 20 + next: end + Westbury: # from state egress::Westbury + *: + 0..1: H81 + # - bit[0..3] -> H81 bit[15..12]: egress::Millston.Maumee.Fayette + # - bit[4..9] -> H81 bit[11..6]: egress::Millston.Maumee.PineCity + # - bit[10..11] -> H81 bit[5..4]: egress::Millston.Maumee.Alameda + # - bit[12..15] -> H81 bit[3..0]: egress::Millston.Maumee.Maryhill[19:16].16-19 + 2..5: TW7 + # - bit[16..31] -> TW7 bit[31..16]: egress::Millston.Maumee.Maryhill[15:0].0-15 + # - bit[32..47] -> TW7 bit[15..0]: egress::Millston.Maumee.Norwood + 6: B23 # egress::Millston.Maumee.Dassel + 7: B16 # egress::Millston.Maumee.Bushland + 8..9: H71 # egress::Millston.Maumee.Kaluaaha[127:112].112-127 + 10..11: H18 # egress::Millston.Maumee.Kaluaaha[111:96].96-111 + 12..15: W18 # egress::Millston.Maumee.Kaluaaha[95:64].64-95 + 16..19: W17 # egress::Millston.Maumee.Kaluaaha[63:32].32-63 + 20..23: W16 # egress::Millston.Maumee.Kaluaaha[31:0].0-31 + H74: 512 # value 1 -> H74 bit[9]: egress::Millston.Maumee.$valid + save: { byte1 : 6 } + shift: 24 + buf_req: 24 + next: Westbury.$split_0 + Westbury.$split_0: # from state egress::Westbury.$split_0 + match: [ byte1 ] + 0x3a: + 0..3: W22 # egress::Millston.Maumee.Calcasieu[127:96].96-127 + 4..7: W21 # egress::Millston.Maumee.Calcasieu[95:64].64-95 + 8..11: W20 # egress::Millston.Maumee.Calcasieu[63:32].32-63 + 12..15: W19 # egress::Millston.Maumee.Calcasieu[31:0].0-31 + shift: 16 + buf_req: 16 + next: BealCity + 0x11: + 0..3: W22 # egress::Millston.Maumee.Calcasieu[127:96].96-127 + 4..7: W21 # egress::Millston.Maumee.Calcasieu[95:64].64-95 + 8..11: W20 # egress::Millston.Maumee.Calcasieu[63:32].32-63 + 12..15: W19 # egress::Millston.Maumee.Calcasieu[31:0].0-31 + shift: 16 + buf_req: 16 + next: Makawao + 0x06: + 0..3: W22 # egress::Millston.Maumee.Calcasieu[127:96].96-127 + 4..7: W21 # egress::Millston.Maumee.Calcasieu[95:64].64-95 + 8..11: W20 # egress::Millston.Maumee.Calcasieu[63:32].32-63 + 12..15: W19 # egress::Millston.Maumee.Calcasieu[31:0].0-31 + shift: 16 + buf_req: 16 + next: Readsboro + 0x04: + 0..3: W22 # egress::Millston.Maumee.Calcasieu[127:96].96-127 + 4..7: W21 # egress::Millston.Maumee.Calcasieu[95:64].64-95 + 8..11: W20 # egress::Millston.Maumee.Calcasieu[63:32].32-63 + 12..15: W19 # egress::Millston.Maumee.Calcasieu[31:0].0-31 + save: { byte1 : 16 } + shift: 16 + buf_req: 17 + next: Baytown + 0x29: + 0..3: W22 # egress::Millston.Maumee.Calcasieu[127:96].96-127 + 4..7: W21 # egress::Millston.Maumee.Calcasieu[95:64].64-95 + 8..11: W20 # egress::Millston.Maumee.Calcasieu[63:32].32-63 + 12..15: W19 # egress::Millston.Maumee.Calcasieu[31:0].0-31 + shift: 16 + buf_req: 16 + next: Sanford + 0x**: + 0..3: W22 # egress::Millston.Maumee.Calcasieu[127:96].96-127 + 4..7: W21 # egress::Millston.Maumee.Calcasieu[95:64].64-95 + 8..11: W20 # egress::Millston.Maumee.Calcasieu[63:32].32-63 + 12..15: W19 # egress::Millston.Maumee.Calcasieu[31:0].0-31 + shift: 16 + buf_req: 16 + next: end + Makawao: # from state egress::Makawao + *: + 0..1: H70 # egress::Millston.Grays.Chevak + 2..3: H69 # egress::Millston.Grays.Mendocino + 4..5: TH32 # egress::Millston.Gotham.StarLake + 6..7: TH33 # egress::Millston.Brookneal.SoapLake + save: { half : 2..3 } + shift: 8 + buf_req: 8 + next: Makawao.$split_0 + Makawao.$split_0: # from state egress::Makawao.$split_0 + match: [ half ] + 0x****: + H74: 28 + # - value 1 -> H74 bit[2]: egress::Millston.Grays.$valid + # - value 1 -> H74 bit[3]: egress::Millston.Gotham.$valid + # - value 1 -> H74 bit[4]: egress::Millston.Brookneal.$valid + buf_req: 0 + next: end + Stout: # from state egress::Stout + match: [ byte1 ] + 0x01: + 0..3: W24 # bit[16..23] -> W24 bit[15..8]: egress::HillTop.Wisdom.Miller[7:0].0-7 + 1: B25 # bit[15] -> B25 bit[0]: egress::HillTop.Wisdom.Miller[8:8].8-8 + shift: 3 + buf_req: 4 + next: end + 0x02: + 0..3: W24 # bit[16..23] -> W24 bit[15..8]: egress::HillTop.Wisdom.Miller[7:0].0-7 + 1: B25 # bit[15] -> B25 bit[0]: egress::HillTop.Wisdom.Miller[8:8].8-8 + shift: 3 + buf_req: 4 + next: end + 0x**: + 0..3: W24 # bit[16..23] -> W24 bit[15..8]: egress::HillTop.Wisdom.Miller[7:0].0-7 + 1: B25 # bit[15] -> B25 bit[0]: egress::HillTop.Wisdom.Miller[8:8].8-8 + shift: 3 + buf_req: 4 + next: end +deparser egress: + dictionary: + H72: H74(10) + # - bit[15..10]: egress::Millston.Hayfield.Blitchton if egress::Millston.Hayfield.$valid + # - bit[9..0]: egress::Millston.Hayfield.Avondale if egress::Millston.Hayfield.$valid + H31: H74(10) + # - bit[15..12]: egress::Millston.Hayfield.Glassboro if egress::Millston.Hayfield.$valid + # - bit[11..0]: egress::Millston.Hayfield.Grabill if egress::Millston.Hayfield.$valid + H30: H74(10) + # - bit[15..14]: egress::Millston.Hayfield.Moorcroft if egress::Millston.Hayfield.$valid + # - bit[13..12]: egress::Millston.Hayfield.Toklat if egress::Millston.Hayfield.$valid + # - bit[11..0]: egress::Millston.Hayfield.Bledsoe if egress::Millston.Hayfield.$valid + B28: H74(10) # egress::Millston.Hayfield.Blencoe if egress::Millston.Hayfield.$valid + B26: H74(10) + # - bit[7..6]: egress::Millston.Hayfield.AquaPark if egress::Millston.Hayfield.$valid + # - bit[5..3]: egress::Millston.Hayfield.Vichy if egress::Millston.Hayfield.$valid + # - bit[2]: egress::Millston.Hayfield.Lathrop if egress::Millston.Hayfield.$valid + # - bit[1]: egress::Millston.Hayfield.Clyde if egress::Millston.Hayfield.$valid + # - bit[0]: egress::Millston.Hayfield.Clarion if egress::Millston.Hayfield.$valid + H28: H74(10) + # - bit[15..12]: egress::Millston.Hayfield.Aguilita if egress::Millston.Hayfield.$valid + # - bit[11..0]: egress::Millston.Hayfield.Harbor if egress::Millston.Hayfield.$valid + H87: W23(1) # egress::Millston.Calabash.Adona.8-23 if egress::Millston.Calabash.$valid + B22: W23(1) # egress::Millston.Calabash.Adona.0-7 if egress::Millston.Calabash.$valid + H68: W23(1) # egress::Millston.Calabash.Connell.8-23 if egress::Millston.Calabash.$valid + B31: W23(1) # egress::Millston.Calabash.Connell.0-7 if egress::Millston.Calabash.$valid + B29: W23(1) # egress::Millston.Calabash.Goldsboro.16-23 if egress::Millston.Calabash.$valid + H73: W23(1) # egress::Millston.Calabash.Goldsboro.0-15 if egress::Millston.Calabash.$valid + B24: W23(1) # egress::Millston.Calabash.Fabens.16-23 if egress::Millston.Calabash.$valid + H26: W23(1) # egress::Millston.Calabash.Fabens.0-15 if egress::Millston.Calabash.$valid + H25: W23(1) # egress::Millston.Calabash.McCaulley if egress::Millston.Calabash.$valid + H22: B19(1) + # - bit[15..13]: egress::Millston.Wondervu[0].Higginson if egress::Millston.Wondervu[0].$valid + # - bit[12]: egress::Millston.Wondervu[0].Oriskany if egress::Millston.Wondervu[0].$valid + # - bit[11..0]: egress::Millston.Wondervu[0].Bowden if egress::Millston.Wondervu[0].$valid + H24: B19(1) # egress::Millston.Wondervu[0].McCaulley if egress::Millston.Wondervu[0].$valid + TW5: B19(0) + # - bit[31..29]: egress::Millston.Wondervu[1].Higginson if egress::Millston.Wondervu[1].$valid + # - bit[28]: egress::Millston.Wondervu[1].Oriskany if egress::Millston.Wondervu[1].$valid + # - bit[27..16]: egress::Millston.Wondervu[1].Bowden if egress::Millston.Wondervu[1].$valid + # - bit[15..0]: egress::Millston.Wondervu[1].McCaulley if egress::Millston.Wondervu[1].$valid + H81: W23(3) + # - bit[15..12]: egress::Millston.GlenAvon.Fayette if egress::Millston.GlenAvon.$valid + # - bit[11..8]: egress::Millston.GlenAvon.Osterdock if egress::Millston.GlenAvon.$valid + # - bit[7..2]: egress::Millston.GlenAvon.PineCity if egress::Millston.GlenAvon.$valid + # - bit[1..0]: egress::Millston.GlenAvon.Alameda if egress::Millston.GlenAvon.$valid + H18: W23(3) # egress::Millston.GlenAvon.Rexville if egress::Millston.GlenAvon.$valid + W16: W23(3) + # - bit[31..16]: egress::Millston.GlenAvon.Quinwood if egress::Millston.GlenAvon.$valid + # - bit[15]: egress::Millston.GlenAvon.Marfa if egress::Millston.GlenAvon.$valid + # - bit[14]: egress::Millston.GlenAvon.Palatine if egress::Millston.GlenAvon.$valid + # - bit[13]: egress::Millston.GlenAvon.Mabelle if egress::Millston.GlenAvon.$valid + # - bit[12..0]: egress::Millston.GlenAvon.Hoagland if egress::Millston.GlenAvon.$valid + B16: W23(3) # egress::Millston.GlenAvon.Exton if egress::Millston.GlenAvon.$valid + B23: W23(3) # egress::Millston.GlenAvon.Ocoee if egress::Millston.GlenAvon.$valid + checksum 0: W23(3) # egress::Millston.GlenAvon.$valid + W17: W23(3) # egress::Millston.GlenAvon.Kaluaaha if egress::Millston.GlenAvon.$valid + W18: W23(3) # egress::Millston.GlenAvon.Calcasieu if egress::Millston.GlenAvon.$valid + H81: H74(9) + # - bit[15..12]: egress::Millston.Maumee.Fayette if egress::Millston.Maumee.$valid + # - bit[11..6]: egress::Millston.Maumee.PineCity if egress::Millston.Maumee.$valid + # - bit[5..4]: egress::Millston.Maumee.Alameda if egress::Millston.Maumee.$valid + # - bit[3..0]: egress::Millston.Maumee.Maryhill.16-19 if egress::Millston.Maumee.$valid + TW7: H74(9) + # - bit[31..16]: egress::Millston.Maumee.Maryhill.0-15 if egress::Millston.Maumee.$valid + # - bit[15..0]: egress::Millston.Maumee.Norwood if egress::Millston.Maumee.$valid + B23: H74(9) # egress::Millston.Maumee.Dassel if egress::Millston.Maumee.$valid + B16: H74(9) # egress::Millston.Maumee.Bushland if egress::Millston.Maumee.$valid + H71: H74(9) # egress::Millston.Maumee.Kaluaaha.112-127 if egress::Millston.Maumee.$valid + H18: H74(9) # egress::Millston.Maumee.Kaluaaha.96-111 if egress::Millston.Maumee.$valid + W18: H74(9) # egress::Millston.Maumee.Kaluaaha.64-95 if egress::Millston.Maumee.$valid + W17: H74(9) # egress::Millston.Maumee.Kaluaaha.32-63 if egress::Millston.Maumee.$valid + W16: H74(9) # egress::Millston.Maumee.Kaluaaha.0-31 if egress::Millston.Maumee.$valid + W22: H74(9) # egress::Millston.Maumee.Calcasieu.96-127 if egress::Millston.Maumee.$valid + W21: H74(9) # egress::Millston.Maumee.Calcasieu.64-95 if egress::Millston.Maumee.$valid + W20: H74(9) # egress::Millston.Maumee.Calcasieu.32-63 if egress::Millston.Maumee.$valid + W19: H74(9) # egress::Millston.Maumee.Calcasieu.0-31 if egress::Millston.Maumee.$valid + TB5: H74(8) + # - bit[7]: egress::Millston.Broadwell.Palmhurst if egress::Millston.Broadwell.$valid + # - bit[6]: egress::Millston.Broadwell.Comfrey if egress::Millston.Broadwell.$valid + # - bit[5]: egress::Millston.Broadwell.Kalida if egress::Millston.Broadwell.$valid + # - bit[4]: egress::Millston.Broadwell.Wallula if egress::Millston.Broadwell.$valid + # - bit[3]: egress::Millston.Broadwell.Dennison if egress::Millston.Broadwell.$valid + # - bit[2..0]: egress::Millston.Broadwell.Fairhaven if egress::Millston.Broadwell.$valid + TB4: H74(8) + # - bit[7..3]: egress::Millston.Broadwell.Noyes if egress::Millston.Broadwell.$valid + # - bit[2..0]: egress::Millston.Broadwell.Woodfield if egress::Millston.Broadwell.$valid + H69: H74(8) # egress::Millston.Broadwell.LasVegas if egress::Millston.Broadwell.$valid + H70: H74(2) # egress::Millston.Grays.Chevak if egress::Millston.Grays.$valid + H69: H74(2) # egress::Millston.Grays.Mendocino if egress::Millston.Grays.$valid + TH32: H74(3) # egress::Millston.Gotham.StarLake if egress::Millston.Gotham.$valid + TW4: H74(5) # egress::Millston.Osyka.Chloride if egress::Millston.Osyka.$valid + TW6: H74(5) # egress::Millston.Osyka.Garibaldi if egress::Millston.Osyka.$valid + TB4: H74(5) + # - bit[7..4]: egress::Millston.Osyka.Weinert if egress::Millston.Osyka.$valid + # - bit[3..0]: egress::Millston.Osyka.Cornell if egress::Millston.Osyka.$valid + B46: H74(5) # egress::Millston.Osyka.Noyes if egress::Millston.Osyka.$valid + TB6: H74(5) # egress::Millston.Osyka.Helton.8-15 if egress::Millston.Osyka.$valid + TB5: H74(5) # egress::Millston.Osyka.Helton.0-7 if egress::Millston.Osyka.$valid + TH33: H74(4) # egress::Millston.Brookneal.SoapLake if egress::Millston.Brookneal.$valid + TW7: H74(6) + # - bit[31..24]: egress::Millston.Hoven.Noyes if egress::Millston.Hoven.$valid + # - bit[23..0]: egress::Millston.Hoven.Allison if egress::Millston.Hoven.$valid + TH10: H74(6) # egress::Millston.Hoven.Petrey.8-23 if egress::Millston.Hoven.$valid + TH9: H74(6) + # - bit[15..8]: egress::Millston.Hoven.Petrey.0-7 if egress::Millston.Hoven.$valid + # - bit[7..0]: egress::Millston.Hoven.Roosville if egress::Millston.Hoven.$valid + TH34: H74(7) # egress::Millston.Shirley.Adona.8-23 if egress::Millston.Shirley.$valid + TB4: H74(7) # egress::Millston.Shirley.Adona.0-7 if egress::Millston.Shirley.$valid + TW8: H74(7) + # - bit[31..8]: egress::Millston.Shirley.Connell if egress::Millston.Shirley.$valid + # - bit[7..0]: egress::Millston.Shirley.Goldsboro.16-23 if egress::Millston.Shirley.$valid + TH35: H74(7) # egress::Millston.Shirley.Goldsboro.0-15 if egress::Millston.Shirley.$valid + TW9: H74(7) + # - bit[31..8]: egress::Millston.Shirley.Fabens if egress::Millston.Shirley.$valid + # - bit[7..0]: egress::Millston.Shirley.McCaulley.8-15 if egress::Millston.Shirley.$valid + TB5: H74(7) # egress::Millston.Shirley.McCaulley.0-7 if egress::Millston.Shirley.$valid + H82: W23(4) + # - bit[15..12]: egress::Millston.Ramos.Fayette if egress::Millston.Ramos.$valid + # - bit[11..8]: egress::Millston.Ramos.Osterdock if egress::Millston.Ramos.$valid + # - bit[7..2]: egress::Millston.Ramos.PineCity if egress::Millston.Ramos.$valid + # - bit[1..0]: egress::Millston.Ramos.Alameda if egress::Millston.Ramos.$valid + TH15: W23(4) # egress::Millston.Ramos.Rexville if egress::Millston.Ramos.$valid + TW4: W23(4) + # - bit[31..16]: egress::Millston.Ramos.Quinwood if egress::Millston.Ramos.$valid + # - bit[15]: egress::Millston.Ramos.Marfa if egress::Millston.Ramos.$valid + # - bit[14]: egress::Millston.Ramos.Palatine if egress::Millston.Ramos.$valid + # - bit[13]: egress::Millston.Ramos.Mabelle if egress::Millston.Ramos.$valid + # - bit[12..0]: egress::Millston.Ramos.Hoagland if egress::Millston.Ramos.$valid + TH6: W23(4) + # - bit[15..8]: egress::Millston.Ramos.Exton if egress::Millston.Ramos.$valid + # - bit[7..0]: egress::Millston.Ramos.Ocoee if egress::Millston.Ramos.$valid + checksum 1: W23(4) # egress::Millston.Ramos.$valid + TW10: W23(4) # egress::Millston.Ramos.Kaluaaha if egress::Millston.Ramos.$valid + TW11: W23(4) # egress::Millston.Ramos.Calcasieu if egress::Millston.Ramos.$valid + H82: H74(1) + # - bit[15..12]: egress::Millston.Provencal.Fayette if egress::Millston.Provencal.$valid + # - bit[11..6]: egress::Millston.Provencal.PineCity if egress::Millston.Provencal.$valid + # - bit[5..4]: egress::Millston.Provencal.Alameda if egress::Millston.Provencal.$valid + # - bit[3..0]: egress::Millston.Provencal.Maryhill.16-19 if egress::Millston.Provencal.$valid + TH30: H74(1) # egress::Millston.Provencal.Maryhill.0-15 if egress::Millston.Provencal.$valid + TW4: H74(1) + # - bit[31..16]: egress::Millston.Provencal.Norwood if egress::Millston.Provencal.$valid + # - bit[15..8]: egress::Millston.Provencal.Dassel if egress::Millston.Provencal.$valid + # - bit[7..0]: egress::Millston.Provencal.Bushland if egress::Millston.Provencal.$valid + TH16: H74(1) # egress::Millston.Provencal.Kaluaaha.112-127 if egress::Millston.Provencal.$valid + TH15: H74(1) # egress::Millston.Provencal.Kaluaaha.96-111 if egress::Millston.Provencal.$valid + TH6: H74(1) # egress::Millston.Provencal.Kaluaaha.80-95 if egress::Millston.Provencal.$valid + TB7: H74(1) # egress::Millston.Provencal.Kaluaaha.72-79 if egress::Millston.Provencal.$valid + TB6: H74(1) # egress::Millston.Provencal.Kaluaaha.64-71 if egress::Millston.Provencal.$valid + TW11: H74(1) # egress::Millston.Provencal.Kaluaaha.32-63 if egress::Millston.Provencal.$valid + TW10: H74(1) # egress::Millston.Provencal.Kaluaaha.0-31 if egress::Millston.Provencal.$valid + TW22: H74(1) # egress::Millston.Provencal.Calcasieu.96-127 if egress::Millston.Provencal.$valid + TW21: H74(1) # egress::Millston.Provencal.Calcasieu.64-95 if egress::Millston.Provencal.$valid + TW20: H74(1) # egress::Millston.Provencal.Calcasieu.32-63 if egress::Millston.Provencal.$valid + TH17: H74(1) # egress::Millston.Provencal.Calcasieu.16-31 if egress::Millston.Provencal.$valid + TB9: H74(1) # egress::Millston.Provencal.Calcasieu.8-15 if egress::Millston.Provencal.$valid + TB8: H74(1) # egress::Millston.Provencal.Calcasieu.0-7 if egress::Millston.Provencal.$valid + TH8: W23(5) # egress::Millston.Bergton.Chevak if egress::Millston.Bergton.$valid + TH7: W23(5) # egress::Millston.Bergton.Mendocino if egress::Millston.Bergton.$valid + TH12: H74(0) # egress::Millston.Cassa.Chloride.16-31 if egress::Millston.Cassa.$valid + TH11: H74(0) # egress::Millston.Cassa.Chloride.0-15 if egress::Millston.Cassa.$valid + TH14: H74(0) # egress::Millston.Cassa.Garibaldi.16-31 if egress::Millston.Cassa.$valid + TH13: H74(0) # egress::Millston.Cassa.Garibaldi.0-15 if egress::Millston.Cassa.$valid + TW6: H74(0) + # - bit[31..28]: egress::Millston.Cassa.Weinert if egress::Millston.Cassa.$valid + # - bit[27..24]: egress::Millston.Cassa.Cornell if egress::Millston.Cassa.$valid + # - bit[23..16]: egress::Millston.Cassa.Noyes if egress::Millston.Cassa.$valid + # - bit[15..0]: egress::Millston.Cassa.Helton if egress::Millston.Cassa.$valid + TH11: W23(6) # egress::Millston.Pawtucket.StarLake if egress::Millston.Pawtucket.$valid + TH31: W23(7) # egress::Millston.Buckhorn.SoapLake if egress::Millston.Buckhorn.$valid + TW6: W23(2) + # - bit[31..16]: egress::Millston.Rainelle.Conner if egress::Millston.Rainelle.$valid + # - bit[15..0]: egress::Millston.Rainelle.Ledoux if egress::Millston.Rainelle.$valid + TW4: W23(2) + # - bit[31..24]: egress::Millston.Rainelle.Steger if egress::Millston.Rainelle.$valid + # - bit[23..16]: egress::Millston.Rainelle.Quogue if egress::Millston.Rainelle.$valid + # - bit[15..0]: egress::Millston.Rainelle.Findlay if egress::Millston.Rainelle.$valid + checksum 0: + - H81: { } + # - bit[15..12]: egress::Millston.GlenAvon.Fayette + # - bit[11..8]: egress::Millston.GlenAvon.Osterdock + # - bit[7..2]: egress::Millston.GlenAvon.PineCity + # - bit[1..0]: egress::Millston.GlenAvon.Alameda + - H18: { } # egress::Millston.GlenAvon.Rexville + - W16: { } + # - bit[31..16]: egress::Millston.GlenAvon.Quinwood + # - bit[15]: egress::Millston.GlenAvon.Marfa + # - bit[14]: egress::Millston.GlenAvon.Palatine + # - bit[13]: egress::Millston.GlenAvon.Mabelle + # - bit[12..0]: egress::Millston.GlenAvon.Hoagland + - B16: { swap: 1 } # egress::Millston.GlenAvon.Exton + - B23: { } # egress::Millston.GlenAvon.Ocoee + - W17: { } # egress::Millston.GlenAvon.Kaluaaha + - W18: { } # egress::Millston.GlenAvon.Calcasieu + checksum 1: + - H82: { } + # - bit[15..12]: egress::Millston.Ramos.Fayette + # - bit[11..8]: egress::Millston.Ramos.Osterdock + # - bit[7..2]: egress::Millston.Ramos.PineCity + # - bit[1..0]: egress::Millston.Ramos.Alameda + - TH15: { } # egress::Millston.Ramos.Rexville + - TW4: { } + # - bit[31..16]: egress::Millston.Ramos.Quinwood + # - bit[15]: egress::Millston.Ramos.Marfa + # - bit[14]: egress::Millston.Ramos.Palatine + # - bit[13]: egress::Millston.Ramos.Mabelle + # - bit[12..0]: egress::Millston.Ramos.Hoagland + - TH6: { } + # - bit[15..8]: egress::Millston.Ramos.Exton + # - bit[7..0]: egress::Millston.Ramos.Ocoee + - TW10: { } # egress::Millston.Ramos.Kaluaaha + - TW11: { } # egress::Millston.Ramos.Calcasieu + drop_ctl: B20(0..2) # bit[2..0]: egress::eg_intr_md_for_dprsr.drop_ctl + egress_unicast_port: H16(0..8) # bit[8..0]: egress::eg_intr_md.egress_port + mirror: + select: B17(0..2) # bit[2..0]: egress::eg_intr_md_for_dprsr.mirror_type + 2: + - H19(0..9) # bit[9..0]: egress::HillTop.McCaskill.Grassflat + - B25 # egress::HillTop.Plains.Roachdale + - H17(0..8) # bit[8..0]: egress::HillTop.Plains.Miller +stage 0 ingress: + phase0_match Thaxton.$PORT_METADATA: + p4: + name: Thaxton.$PORT_METADATA + size: 288 + preferred_match_type: exact + match_type: exact + size: 288 + p4_param_order: + Tiburon.ingress_port: { type: exact, size: 9 } + format: {Fristoe: 48..61, Traverse: 32..43, Pachuta: 24..24, Sopris: 16..17} + constant_value: 0 + actions: + set_port_metadata: + - handle: 0x20000000 + - p4_param_order: { Fristoe: 14, Traverse: 12, Pachuta: 1, Sopris: 2 } + ternary_match Rotonda_0 0: + p4: { name: Rotonda, size: 2, disable_atomic_modify : true } + p4_param_order: + Millston.Ramos.$valid: { type: exact, size: 1, full_size: 1, key_name: "Ramos" } + Millston.Provencal.$valid: { type: exact, size: 1, full_size: 1, key_name: "Provencal" } + row: 11 + bus: 1 + column: 1 + hash_dist: + 0: { hash: 0, mask: 0xffff, shift: 0 } + 1: { hash: 0, mask: 0xffff, shift: 0 } + input_xbar: + ternary group 0: { 2: Millston.Provencal.$valid, 13: Millston.Ramos.$valid } + exact group 0: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.Maddock.Kaluaaha, 64: HillTop.Aldan.Vinemont } + hash 0: + 0..15: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 72, { 8: HillTop.Maddock.Calcasieu, 40: HillTop.Maddock.Kaluaaha }, { })), 0..15) + hash 1: + 0..15: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 72, { 0: HillTop.Aldan.Vinemont }, { })), 0..15) + hash group 0: + table: [0, 1] + seed: 0x0 + exact group 0: { 0: HillTop.Sublett.Calcasieu.96-127, 32: HillTop.Sublett.Kaluaaha.0-31, 64: HillTop.Aldan.Vinemont, 72: HillTop.Sublett.Kaluaaha.32-63(8..31), 96: HillTop.Sublett.Kaluaaha.32-63(0..7), 104: HillTop.Sublett.Kaluaaha.64-95(8..31) } + exact group 1: { 0: HillTop.Sublett.Kaluaaha.64-95(0..7), 8: HillTop.Sublett.Kaluaaha.96-127(8..31), 32: HillTop.Sublett.Kaluaaha.96-127(0..7), 40: HillTop.Sublett.Calcasieu.0-31(8..31), 64: HillTop.Sublett.Calcasieu.0-31(0..7), 72: HillTop.Sublett.Calcasieu.32-63(8..31), 96: HillTop.Sublett.Calcasieu.32-63(0..7), 104: HillTop.Sublett.Calcasieu.64-95(8..31) } + exact group 2: { 0: HillTop.Sublett.Calcasieu.64-95(0..7), 8: Millston.Provencal.Maryhill.8-19(8..11), 16: Millston.Provencal.Maryhill.8-19(0..7), 24: Millston.Provencal.Maryhill.0-7 } + hash 0: + 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 124: HillTop.Sublett.Calcasieu.96-127, 156: HillTop.Sublett.Kaluaaha.0-31 }, { })), 0..15) + hash 1: + 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 0: HillTop.Aldan.Vinemont, 188: HillTop.Sublett.Kaluaaha.32-63(0..7), 196: HillTop.Sublett.Kaluaaha.32-63(8..31), 228: HillTop.Sublett.Kaluaaha.64-95(8..31) }, { })), 0..15) + hash 2: + 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 36: HillTop.Sublett.Calcasieu.0-31(8..31), 220: HillTop.Sublett.Kaluaaha.64-95(0..7), 252: HillTop.Sublett.Kaluaaha.96-127(0..7), 260: HillTop.Sublett.Kaluaaha.96-127(8..31) }, { })), 0..15) + hash 3: + 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 28: HillTop.Sublett.Calcasieu.0-31(0..7), 60: HillTop.Sublett.Calcasieu.32-63(0..7), 68: HillTop.Sublett.Calcasieu.32-63(8..31), 100: HillTop.Sublett.Calcasieu.64-95(8..31) }, { })), 0..15) + hash 4: + 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 8: Millston.Provencal.Maryhill.0-7, 16: Millston.Provencal.Maryhill.8-19(0..7), 24: Millston.Provencal.Maryhill.8-19(8..11), 92: HillTop.Sublett.Calcasieu.64-95(0..7) }, { })), 0..15) + hash group 0: + table: [0, 1, 2, 3, 4] + seed: 0x0 + match: + - { group: 0, byte_config: 3, dirtcam: 0x5 } + hit: [ _Cheyenne ] + miss: _Cheyenne + indirect: Rotonda_0$tind + ternary_indirect Rotonda_0$tind: + row: 4 + bus: 0 + column: 5 + hash_dist: + 0: { hash: 0, mask: 0xffff, shift: 0 } + 1: { hash: 0, mask: 0xffff, shift: 0 } + input_xbar: + ternary group 0: { 2: Millston.Provencal.$valid, 13: Millston.Ramos.$valid } + exact group 0: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.Maddock.Kaluaaha, 64: HillTop.Aldan.Vinemont } + hash 0: + 0..15: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 72, { 8: HillTop.Maddock.Calcasieu, 40: HillTop.Maddock.Kaluaaha }, { })), 0..15) + hash 1: + 0..15: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 72, { 0: HillTop.Aldan.Vinemont }, { })), 0..15) + hash group 0: + table: [0, 1] + seed: 0x0 + exact group 0: { 0: HillTop.Sublett.Calcasieu.96-127, 32: HillTop.Sublett.Kaluaaha.0-31, 64: HillTop.Aldan.Vinemont, 72: HillTop.Sublett.Kaluaaha.32-63(8..31), 96: HillTop.Sublett.Kaluaaha.32-63(0..7), 104: HillTop.Sublett.Kaluaaha.64-95(8..31) } + exact group 1: { 0: HillTop.Sublett.Kaluaaha.64-95(0..7), 8: HillTop.Sublett.Kaluaaha.96-127(8..31), 32: HillTop.Sublett.Kaluaaha.96-127(0..7), 40: HillTop.Sublett.Calcasieu.0-31(8..31), 64: HillTop.Sublett.Calcasieu.0-31(0..7), 72: HillTop.Sublett.Calcasieu.32-63(8..31), 96: HillTop.Sublett.Calcasieu.32-63(0..7), 104: HillTop.Sublett.Calcasieu.64-95(8..31) } + exact group 2: { 0: HillTop.Sublett.Calcasieu.64-95(0..7), 8: Millston.Provencal.Maryhill.8-19(8..11), 16: Millston.Provencal.Maryhill.8-19(0..7), 24: Millston.Provencal.Maryhill.0-7 } + hash 0: + 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 124: HillTop.Sublett.Calcasieu.96-127, 156: HillTop.Sublett.Kaluaaha.0-31 }, { })), 0..15) + hash 1: + 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 0: HillTop.Aldan.Vinemont, 188: HillTop.Sublett.Kaluaaha.32-63(0..7), 196: HillTop.Sublett.Kaluaaha.32-63(8..31), 228: HillTop.Sublett.Kaluaaha.64-95(8..31) }, { })), 0..15) + hash 2: + 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 36: HillTop.Sublett.Calcasieu.0-31(8..31), 220: HillTop.Sublett.Kaluaaha.64-95(0..7), 252: HillTop.Sublett.Kaluaaha.96-127(0..7), 260: HillTop.Sublett.Kaluaaha.96-127(8..31) }, { })), 0..15) + hash 3: + 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 28: HillTop.Sublett.Calcasieu.0-31(0..7), 60: HillTop.Sublett.Calcasieu.32-63(0..7), 68: HillTop.Sublett.Calcasieu.32-63(8..31), 100: HillTop.Sublett.Calcasieu.64-95(8..31) }, { })), 0..15) + hash 4: + 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 8: Millston.Provencal.Maryhill.0-7, 16: Millston.Provencal.Maryhill.8-19(0..7), 24: Millston.Provencal.Maryhill.8-19(8..11), 92: HillTop.Sublett.Calcasieu.64-95(0..7) }, { })), 0..15) + hash group 0: + table: [0, 1, 2, 3, 4] + seed: 0x0 + format: { action: 0..0 } + action_bus: { 64..65 : hash_dist(0, lo), 66..67 : hash_dist(1, hi) } + instruction: Rotonda_0$tind(action, $DEFAULT) + actions: + Kinard(0, 1): + - default_action: { allowed: true } + - handle: 0x20000001 + - next_table: 0 + - set H60, hash_dist(0, 0..15) + Pendleton(1, 2): + - default_action: { allowed: true } + - handle: 0x20000002 + - next_table: 0 + - set H60, hash_dist(1, 0..15) + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x20000003 + - next_table: 0 + default_only_action: NoAction + ternary_match _Cheyenne 1: + p4: { name: Cheyenne, size: 512, disable_atomic_modify : true } + p4_param_order: + Millston.Calabash.Adona: { type: ternary, size: 24, full_size: 24, key_name: "Calabash.Adona" } + Millston.Calabash.Connell: { type: ternary, size: 24, full_size: 24, key_name: "Calabash.Connell" } + Millston.GlenAvon.Calcasieu: { type: ternary, size: 32, full_size: 32, key_name: "GlenAvon.Calcasieu" } + Millston.Maumee.Calcasieu: { type: ternary, size: 128, full_size: 128, key_name: "Maumee.Calcasieu" } + HillTop.RossFork.Joslin: { type: ternary, size: 3, full_size: 3, key_name: "RossFork.Joslin" } + Millston.Maumee.$valid: { type: exact, size: 1, full_size: 1, key_name: "Maumee" } + row: [ 0, 1, 2, 3, 4 ] + bus: [ 0, 0, 0, 0, 0 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + input_xbar: + ternary group 1: { 0: Millston.Calabash.Adona(8..15), 8: Millston.Maumee.Calcasieu.96-127(24..31), 16: Millston.Maumee.Calcasieu.96-127(0..7), 24: Millston.Calabash.Adona(0..7), 32: Millston.Maumee.Calcasieu.96-127(16..23) } + ternary group 2: { 0: Millston.Maumee.Calcasieu.0-31(24..31), 8: Millston.Maumee.Calcasieu.0-31(0..23), 32: Millston.Maumee.Calcasieu.32-63(24..31) } + ternary group 3: { 0: Millston.Maumee.Calcasieu.96-127(8..15), 8: Millston.GlenAvon.Calcasieu(16..31), 24: Millston.GlenAvon.Calcasieu(0..15) } + ternary group 4: { 0: Millston.Maumee.Calcasieu.32-63(16..23), 8: Millston.Maumee.Calcasieu.64-95(24..31), 16: Millston.Maumee.Calcasieu.32-63(0..15), 32: Millston.Maumee.Calcasieu.64-95(16..23) } + ternary group 5: { 0: Millston.Maumee.Calcasieu.64-95(0..15), 21: HillTop.RossFork.Joslin, 24: Millston.Calabash.Connell.0-15(8..15), 32: Millston.Calabash.Connell.0-15(0..7) } + byte group 0: { 2: Millston.Maumee.$valid } + byte group 1: { 0: Millston.Calabash.Connell.16-23 } + byte group 2: { 0: Millston.Calabash.Adona(16..23) } + match: + - { group: 1, byte_group: 1, byte_config: 0, dirtcam: 0x555 } + - { group: 2, byte_group: 1, byte_config: 1, dirtcam: 0x555 } + - { group: 3, byte_group: 2, byte_config: 0, dirtcam: 0x555 } + - { group: 4, byte_group: 2, byte_config: 1, dirtcam: 0x555 } + - { group: 5, byte_group: 0, byte_config: 0, dirtcam: 0x555 } + hit: [ _Pacifica ] + miss: _Pacifica + indirect: _Cheyenne$tind + ternary_indirect _Cheyenne$tind: + row: 3 + bus: 0 + column: 5 + input_xbar: + ternary group 1: { 0: Millston.Calabash.Adona(8..15), 8: Millston.Maumee.Calcasieu.96-127(24..31), 16: Millston.Maumee.Calcasieu.96-127(0..7), 24: Millston.Calabash.Adona(0..7), 32: Millston.Maumee.Calcasieu.96-127(16..23) } + ternary group 2: { 0: Millston.Maumee.Calcasieu.0-31(24..31), 8: Millston.Maumee.Calcasieu.0-31(0..23), 32: Millston.Maumee.Calcasieu.32-63(24..31) } + ternary group 3: { 0: Millston.Maumee.Calcasieu.96-127(8..15), 8: Millston.GlenAvon.Calcasieu(16..31), 24: Millston.GlenAvon.Calcasieu(0..15) } + ternary group 4: { 0: Millston.Maumee.Calcasieu.32-63(16..23), 8: Millston.Maumee.Calcasieu.64-95(24..31), 16: Millston.Maumee.Calcasieu.32-63(0..15), 32: Millston.Maumee.Calcasieu.64-95(16..23) } + ternary group 5: { 0: Millston.Maumee.Calcasieu.64-95(0..15), 21: HillTop.RossFork.Joslin, 24: Millston.Calabash.Connell.0-15(8..15), 32: Millston.Calabash.Connell.0-15(0..7) } + byte group 0: { 2: Millston.Maumee.$valid } + byte group 1: { 0: Millston.Calabash.Connell.16-23 } + byte group 2: { 0: Millston.Calabash.Adona(16..23) } + format: { action: 0..0 } + instruction: _Cheyenne$tind(action, $DEFAULT) + actions: + Aguila(0, 3): + - default_action: { allowed: true } + - handle: 0x20000013 + - next_table: 0 + - set HillTop.Wisdom.Onycha, 5 + - set HillTop.RossFork.Adona, Millston.Calabash.Adona + - set HillTop.RossFork.Connell.0-15, Millston.Calabash.Connell.0-15 + - set HillTop.RossFork.Connell.16-23, Millston.Calabash.Connell.16-23 + - set HillTop.RossFork.Goldsboro.0-7, Millston.Calabash.Goldsboro.0-7 + - set HillTop.RossFork.Goldsboro.8-23, Millston.Calabash.Goldsboro.8-23 + - set HillTop.RossFork.Fabens, Millston.Calabash.Fabens + - set Millston.Calabash.McCaulley.0-7, HillTop.RossFork.McCaulley.0-7 + - set Millston.Calabash.McCaulley.8-15, HillTop.RossFork.McCaulley.8-15 + - set HillTop.Edwards.Oriskany, 0 + - set HillTop.RossFork.Denhoff.0-0, HillTop.Aldan.Kearns.0-0 + - set HillTop.RossFork.Denhoff.1-2, HillTop.Aldan.Kearns.1-2 + - set HillTop.RossFork.Ocoee, HillTop.Aldan.Vinemont + - set HillTop.RossFork.Exton, HillTop.Aldan.Kenbridge + - set HillTop.RossFork.Naruna.0-1, HillTop.Aldan.Mystic.0-1 + - set HillTop.RossFork.Naruna.2-2, HillTop.Aldan.Mystic.2-2 + - set HillTop.Bessie.Chevak, HillTop.RossFork.Chevak + - set HillTop.Bessie.Peebles, HillTop.Aldan.Kearns.0-0 + - or H63, H48, H63 + Kapowsin(1, 4): + - default_action: { allowed: true } + - handle: 0x20000014 + - next_table: 0 + - set HillTop.Wisdom.Onycha, 0 + - set HillTop.Edwards.Oriskany, Millston.Wondervu$0.Oriskany + - set HillTop.RossFork.ElVerano, Millston.Wondervu$0.$valid + - set HillTop.RossFork.Joslin, 0 + - set HillTop.RossFork.Adona, Millston.Calabash.Adona + - set HillTop.RossFork.Connell.0-15, Millston.Calabash.Connell.0-15 + - set HillTop.RossFork.Connell.16-23, Millston.Calabash.Connell.16-23 + - set HillTop.RossFork.Goldsboro.0-7, Millston.Calabash.Goldsboro.0-7 + - set HillTop.RossFork.Goldsboro.8-23, Millston.Calabash.Goldsboro.8-23 + - set HillTop.RossFork.Fabens, Millston.Calabash.Fabens + - set HillTop.RossFork.Naruna.0-1, HillTop.Aldan.Parkville(0..1) + - set HillTop.RossFork.Naruna.2-2, HillTop.Aldan.Parkville(2..2) + - set HillTop.RossFork.McCaulley.0-7, Millston.Calabash.McCaulley.0-7 + - set HillTop.RossFork.McCaulley.8-15, Millston.Calabash.McCaulley.8-15 + - set HillTop.Sublett.Kaluaaha.0-31, Millston.Maumee.Kaluaaha.0-31 + - set HillTop.Sublett.Kaluaaha.32-63, Millston.Maumee.Kaluaaha.32-63 + - set HillTop.Sublett.Kaluaaha.64-95, Millston.Maumee.Kaluaaha.64-95 + - set HillTop.Sublett.Kaluaaha.96-127, Millston.Maumee.Kaluaaha.96-127 + - set HillTop.Sublett.Calcasieu.0-31, Millston.Maumee.Calcasieu.0-31 + - set HillTop.Sublett.Calcasieu.32-63, Millston.Maumee.Calcasieu.32-63 + - set HillTop.Sublett.Calcasieu.64-95, Millston.Maumee.Calcasieu.64-95 + - set HillTop.Sublett.Calcasieu.96-127, Millston.Maumee.Calcasieu.96-127 + - set HillTop.Sublett.PineCity, Millston.Maumee.PineCity + - set HillTop.RossFork.Ocoee, Millston.Maumee.Dassel + - set HillTop.RossFork.Chevak, Millston.Grays.Chevak + - set HillTop.RossFork.Mendocino, Millston.Grays.Mendocino + - set HillTop.RossFork.Kremlin, Millston.Osyka.Noyes + - set HillTop.RossFork.Denhoff.0-0, HillTop.Aldan.Malinta.0-0 + - set HillTop.RossFork.Denhoff.1-2, HillTop.Aldan.Malinta.1-2 + - set HillTop.RossFork.Glenmora, Millston.Grays.Chevak + - set HillTop.RossFork.DonaAna, Millston.Grays.Mendocino + - set HillTop.Bessie.Chevak, Millston.Grays.Chevak + - set HillTop.Bessie.Peebles, HillTop.Aldan.Malinta.0-0 + Crown(-1, 6): + - default_only_action: { allowed: true } + - handle: 0x20000015 + - next_table: 0 + - set HillTop.Wisdom.Onycha, 0 + - set HillTop.Edwards.Oriskany, Millston.Wondervu$0.Oriskany + - set HillTop.RossFork.ElVerano, Millston.Wondervu$0.$valid + - set HillTop.RossFork.Joslin, 0 + - set HillTop.RossFork.Adona, Millston.Calabash.Adona + - set HillTop.RossFork.Connell.0-15, Millston.Calabash.Connell.0-15 + - set HillTop.RossFork.Connell.16-23, Millston.Calabash.Connell.16-23 + - set HillTop.RossFork.Goldsboro.0-7, Millston.Calabash.Goldsboro.0-7 + - set HillTop.RossFork.Goldsboro.8-23, Millston.Calabash.Goldsboro.8-23 + - set HillTop.RossFork.Fabens, Millston.Calabash.Fabens + - set HillTop.RossFork.Naruna.0-1, HillTop.Aldan.Parkville(0..1) + - set HillTop.RossFork.Naruna.2-2, HillTop.Aldan.Parkville(2..2) + - set HillTop.RossFork.McCaulley.0-7, Millston.Calabash.McCaulley.0-7 + - set HillTop.RossFork.McCaulley.8-15, Millston.Calabash.McCaulley.8-15 + - set HillTop.Maddock.Kaluaaha, Millston.GlenAvon.Kaluaaha + - set HillTop.Maddock.Calcasieu, Millston.GlenAvon.Calcasieu + - set HillTop.Maddock.PineCity, Millston.GlenAvon.PineCity + - set HillTop.RossFork.Ocoee, Millston.GlenAvon.Ocoee + - set HillTop.RossFork.Chevak, Millston.Grays.Chevak + - set HillTop.RossFork.Mendocino, Millston.Grays.Mendocino + - set HillTop.RossFork.Kremlin, Millston.Osyka.Noyes + - set HillTop.RossFork.Denhoff.0-0, HillTop.Aldan.Malinta.0-0 + - set HillTop.RossFork.Denhoff.1-2, HillTop.Aldan.Malinta.1-2 + - set HillTop.RossFork.Glenmora, Millston.Grays.Chevak + - set HillTop.RossFork.DonaAna, Millston.Grays.Mendocino + - set HillTop.Bessie.Chevak, Millston.Grays.Chevak + - set HillTop.Bessie.Peebles, HillTop.Aldan.Malinta.0-0 + default_only_action: Crown + ternary_match _Pacifica 2: + p4: { name: Pacifica, size: 3072, disable_atomic_modify : true } + p4_param_order: + HillTop.Lamona.Pachuta: { type: exact, size: 1, full_size: 1, key_name: "Lamona.Pachuta" } + HillTop.Lamona.Fristoe: { type: exact, size: 14, full_size: 14, key_name: "Lamona.Fristoe" } + Millston.Wondervu$0.$valid: { type: exact, size: 1, full_size: 1, key_name: "Wondervu$0" } + Millston.Wondervu$0.Bowden: { type: ternary, size: 12, full_size: 12, key_name: "Wondervu$0.Bowden" } + row: [ 2, 3, 4, 5, 6, 7 ] + bus: [ 1, 1, 1, 1, 1, 1 ] + column: + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + input_xbar: + ternary group 6: { 0: HillTop.Lamona.Fristoe, 17: Millston.Wondervu$0.$valid, 24: Millston.Wondervu$0.Bowden(0..7), 32: HillTop.Lamona.Pachuta } + byte group 4: { 0: Millston.Wondervu$0.Bowden(8..11) } + match: + - { group: 6, byte_group: 4, byte_config: 0, dirtcam: 0x555 } + hit: [ _Mogadore ] + miss: _Mogadore + indirect: _Pacifica$tind + ternary_indirect _Pacifica$tind: + row: 0 + bus: 0 + column: [ 2, 3 ] + input_xbar: + ternary group 6: { 0: HillTop.Lamona.Fristoe, 17: Millston.Wondervu$0.$valid, 24: Millston.Wondervu$0.Bowden(0..7), 32: HillTop.Lamona.Pachuta } + byte group 4: { 0: Millston.Wondervu$0.Bowden(8..11) } + format: { action: 0..1, immediate: 2..33 } + action_bus: { 34..35 : immediate(16..31), 96..99 : immediate(0..31) } + instruction: _Pacifica$tind(action, $DEFAULT) + actions: + Vanoss(0, 5): + - p4_param_order: { Potosi: 20 } + - default_action: { allowed: true } + - handle: 0x20000016 + - next_table: 0 + - { Potosi: immediate(0..19) } + - set HillTop.RossFork.CeeVee, HillTop.Lamona.Traverse + - set HillTop.RossFork.Quebrada, Potosi + Mulvane(1, 7): + - p4_param_order: { Luning: 12, Potosi: 20 } + - default_action: { allowed: true } + - handle: 0x20000017 + - next_table: 0 + - { Potosi: immediate(0..19), Luning: immediate(20..31) } + - set HillTop.RossFork.CeeVee, Luning + - set HillTop.RossFork.Quebrada, Potosi + - set HillTop.Lamona.Pachuta, 1 + Flippen(2, 8): + - p4_param_order: { Potosi: 20 } + - default_action: { allowed: true } + - handle: 0x20000018 + - next_table: 0 + - { Potosi: immediate(0..19) } + - set HillTop.RossFork.CeeVee, Millston.Wondervu$0.Bowden + - set HillTop.RossFork.Quebrada, Potosi + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x20000019 + - next_table: 0 + - { } + default_only_action: NoAction + exact_match _Mogadore 3: + p4: { name: Mogadore, size: 1024, disable_atomic_modify : true } + p4_param_order: + HillTop.Lamona.Fristoe: { type: exact, size: 14, full_size: 14, key_name: "Lamona.Fristoe" } + Millston.Wondervu$0.Bowden: { type: exact, size: 12, full_size: 12, key_name: "Wondervu$0.Bowden" } + row: [ 2, 1 ] + bus: [ 1, 0 ] + column: + - 6 + - [ 2, 3, 4 ] + stash: + row: [ 2 ] + col: [ 6 ] + unit: [ 1 ] + ways: + - [1, 0, 0x0, [2, 6]] + - [1, 1, 0x0, [1, 2]] + - [1, 2, 0x0, [1, 3]] + - [1, 3, 0x0, [1, 4]] + input_xbar: + exact group 2: { 64: Millston.Wondervu$0.Bowden(0..7), 72: HillTop.Lamona.Fristoe, 88: Millston.Wondervu$0.Bowden(8..11) } + hash 5: + 0..5: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ HillTop.Lamona.Fristoe(8..13) + 6..9: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ Millston.Wondervu$0.Bowden(8..11) + 11..16: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ HillTop.Lamona.Fristoe(8..13) + 17..19: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ Millston.Wondervu$0.Bowden(8..10) + 10: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ Millston.Wondervu$0.Bowden(11) + 22..27: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ HillTop.Lamona.Fristoe(8..13) + 28..29: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ Millston.Wondervu$0.Bowden(8..9) + 20..21: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ Millston.Wondervu$0.Bowden(10..11) + 33..38: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ HillTop.Lamona.Fristoe(8..13) + 39: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ Millston.Wondervu$0.Bowden(8) + 30..32: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ Millston.Wondervu$0.Bowden(9..11) + hash group 1: + table: [5] + seed: 0x73aa5b9aca + format: { action(0): 0..0, immediate(0): 1..28, version(0): 112..115, match(0): 32..47 } + match: [ Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7) ] + gateway: + name: cond-2 + input_xbar: + exact group 2: { 64: Millston.Wondervu$0.Bowden(0..7), 88: Millston.Wondervu$0.Bowden(8..11), 97: Millston.Wondervu$0.$valid } + row: 2 + bus: 1 + unit: 1 + match: { 17: Millston.Wondervu$0.$valid, 0: Millston.Wondervu$0.Bowden(0..7), 8: Millston.Wondervu$0.Bowden(8..11) } + 0b******0*****************: _Judson + 0x***000: _Judson + miss: run_table + condition: + expression: "(Millston.Wondervu[0].$valid == 1 && Millston.Wondervu[0].Bowden != 0)" + true: _Mogadore + false: _Judson + hit: [ [], _Florahome ] + miss: _Florahome + action_bus: { 68..69 : immediate(0..15), 70..71 : immediate(16..27) } + action: _Mogadore$action_data($DIRECT, $DEFAULT) + instruction: _Mogadore(action, $DEFAULT) + actions: + Micro(1, 9): + - p4_param_order: { Luning: 12, Boring: 32, Manilla: 8, Hammond: 4, Panaca: 16 } + - default_action: { allowed: true } + - handle: 0x2000001c + - next_table: 1 + - { Manilla: $adf_b0(0..7), Luning: immediate(0..11), $data0: immediate(16..27), Panaca.0-7: $data0(0..7), Hammond.1-3: $data0(8..10), Hammond.0-0: $data0(11..11) } + - set HillTop.RossFork.Bicknell, Luning + - set HillTop.Ovett.Manilla, Manilla + - set H14(0..11), $data0 + Sequim(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x2000001d + - next_table_miss: _Westview + - { } + default_only_action: Sequim + action _Mogadore$action_data: + p4: { name: Mogadore$action } + row: 5 + column: 1 + vpns: [ 0 ] + home_row: + - 5 + format Micro: { $adf_b0: 0..7 } + action_bus: { 0 : $adf_b0 } + exact_match _Judson 5: + p4: { name: Judson, size: 4096, disable_atomic_modify : true } + p4_param_order: + HillTop.Lamona.Traverse: { type: exact, size: 12, full_size: 12, key_name: "Lamona.Traverse" } + row: 6 + bus: 1 + column: [ 4, 6 ] + stash: + row: [ 6 ] + col: [ 4 ] + unit: [ 0 ] + ways: + - [2, 1, 0x2, [6, 4], [6, 6]] + input_xbar: + exact group 3: { 16: HillTop.Lamona.Traverse } + hash 6: + 10..16: random(HillTop.Lamona.Traverse(7)) ^ HillTop.Lamona.Traverse(0..6) + 17..19: random(HillTop.Lamona.Traverse(7)) ^ HillTop.Lamona.Traverse(8..10) + 41: random(HillTop.Lamona.Traverse(7)) ^ HillTop.Lamona.Traverse(11) + hash group 2: + table: [6] + seed: 0xc7c00 + format: { immediate(0): 0..23, version(0): 112..115, match(0): 55..55, immediate(1): 24..47, version(1): 116..119, match(1): 63..63 } + match: [ HillTop.Lamona.Traverse(7) ] + hit: [ _Florahome ] + miss: _Florahome + action_bus: { 6 : immediate(16..23), 36..37 : immediate(0..15) } + instruction: _Judson($DEFAULT, $DEFAULT) + actions: + Tillson(0, 12): + - p4_param_order: { Boring: 32, Manilla: 8, Hammond: 4, Panaca: 16 } + - default_action: { allowed: true } + - handle: 0x2000001a + - next_table: 0 + - { $data0: immediate(0..11), Panaca.0-7: $data0(0..7), Hammond.1-3: $data0(8..10), Hammond.0-0: $data0(11..11), Manilla: immediate(16..23) } + - set HillTop.RossFork.Bicknell, HillTop.Lamona.Traverse + - set HillTop.Ovett.Manilla, Manilla + - set H14(0..11), $data0 + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x2000001b + - next_table: 0 + - { } + default_only_action: NoAction + exact_match _Westview 4: + p4: { name: Westview, size: 4096, disable_atomic_modify : true } + p4_param_order: + Millston.Wondervu$0.Bowden: { type: exact, size: 12, full_size: 12, key_name: "Wondervu$0.Bowden" } + row: 6 + bus: 0 + column: [ 2, 3 ] + stash: + row: [ 6 ] + col: [ 2 ] + unit: [ 1 ] + ways: + - [2, 0, 0x1, [6, 2], [6, 3]] + input_xbar: + exact group 3: { 0: Millston.Wondervu$0.Bowden } + hash 6: + 0..6: random(Millston.Wondervu$0.Bowden(7)) ^ Millston.Wondervu$0.Bowden(0..6) + 7..9: random(Millston.Wondervu$0.Bowden(7)) ^ Millston.Wondervu$0.Bowden(8..10) + 40: random(Millston.Wondervu$0.Bowden(7)) ^ Millston.Wondervu$0.Bowden(11) + hash group 2: + table: [6] + seed: 0x182 + format: { immediate(0): 0..23, version(0): 112..115, match(0): 55..55, immediate(1): 24..47, version(1): 116..119, match(1): 63..63 } + match: [ Millston.Wondervu$0.Bowden(7) ] + hit: [ _Florahome ] + miss: _Florahome + action_bus: { 2 : immediate(16..23), 32..33 : immediate(0..15) } + instruction: _Westview($DEFAULT, $DEFAULT) + actions: + Lattimore(0, 10): + - p4_param_order: { Boring: 32, Manilla: 8, Hammond: 4, Panaca: 16 } + - default_action: { allowed: true } + - handle: 0x2000001e + - next_table: 0 + - { $data0: immediate(0..11), Panaca.0-7: $data0(0..7), Hammond.1-3: $data0(8..10), Hammond.0-0: $data0(11..11), Manilla: immediate(16..23) } + - set HillTop.RossFork.Bicknell, Millston.Wondervu$0.Bowden + - set HillTop.Ovett.Manilla, Manilla + - set H14(0..11), $data0 + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x2000001f + - next_table: 0 + - { } + default_only_action: NoAction + ternary_match _Florahome 6: + p4: { name: Florahome, size: 2048, disable_atomic_modify : true } + p4_param_order: + HillTop.Tiburon.Arnold: { type: exact, size: 7, full_size: 9, key_name: "Tiburon.Arnold" } + Millston.Calabash.Adona: { type: ternary, size: 24, full_size: 24, key_name: "Calabash.Adona" } + Millston.Calabash.Connell: { type: ternary, size: 24, full_size: 24, key_name: "Calabash.Connell" } + row: [ 6, 7, 8, 9, 10, 11, 0, 1 ] + bus: [ 0, 0, 0, 0, 0, 0, 1, 1 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 1 + - 1 + input_xbar: + ternary group 0: { 16: Millston.Calabash.Adona(8..23), 32: Millston.Calabash.Connell.16-23 } + ternary group 7: { 0: Millston.Calabash.Connell.0-15(8..15), 8: HillTop.Tiburon.Arnold(0..6), 16: Millston.Calabash.Adona(0..7), 24: Millston.Calabash.Connell.0-15(0..7) } + match: + - { group: 0, dirtcam: 0x150 } + - { group: 7, dirtcam: 0x55 } + gateway: + name: cond-1 + input_xbar: + exact group 2: { 105: Millston.Hayfield.$valid } + row: 1 + bus: 0 + unit: 0 + match: { 1: Millston.Hayfield.$valid } + 0b******0: run_table + miss: _Leacock + condition: + expression: "(Millston.Hayfield.$valid == 1 == 0)" + true: _Florahome + false: _Leacock + hit: [ _McIntyre_0, _Newtonia ] + miss: _McIntyre_0 + indirect: _Florahome$tind + counter _Florahome$stats.Meyers: + p4: { name: Meyers } + row: 13 + column: [ 1, 2 ] + maprams: [ 1, 2 ] + count: packets_and_bytes + format: {packets(0): 64..91, bytes(0): 92..127, packets(1): 0..27, bytes(1): 28..63} + lrt: + - { threshold: 404246592, interval: 25265664 } + - { threshold: 404246592, interval: 25265664 } + - { threshold: 404246592, interval: 25265664 } + ternary_indirect _Florahome$tind: + row: 2 + bus: 0 + column: 5 + input_xbar: + ternary group 0: { 16: Millston.Calabash.Adona(8..23), 32: Millston.Calabash.Connell.16-23 } + ternary group 7: { 0: Millston.Calabash.Connell.0-15(8..15), 8: HillTop.Tiburon.Arnold(0..6), 16: Millston.Calabash.Adona(0..7), 24: Millston.Calabash.Connell.0-15(0..7) } + format: { next: 0..0, action: 1..6, immediate: 7..16 } + action_bus: { 4 : immediate(0..7), 100..103 : immediate(0..9) } + stats: _Florahome$stats.Meyers($DIRECT, $DEFAULT) + instruction: _Florahome$tind(action, $DEFAULT) + actions: + Earlham(11, 11): + - p4_param_order: { Blencoe: 8, Satolah: 1 } + - default_action: { allowed: true } + - handle: 0x20000004 + - next_table: 1 + - { Blencoe: immediate(0..7), $data0: immediate(8..9), Satolah: $data0(0..0), $constant0: $data0(1..1), $constant0: 1 } + - set HillTop.Wisdom.Havana, 1 + - set HillTop.Wisdom.Blencoe, Blencoe + - set HillTop.RossFork.Tenino, 1 + - set W1(17..18), $data0 + - _Florahome$stats.Meyers($DIRECT) + Lewellen(13, 13): + - default_action: { allowed: true } + - handle: 0x20000005 + - next_table: 0 + - { } + - set HillTop.RossFork.Welcome, 1 + - _Florahome$stats.Meyers($DIRECT) + Absecon(14, 14): + - default_action: { allowed: true } + - handle: 0x20000006 + - next_table: 0 + - { } + - set HillTop.RossFork.Tenino, 1 + - _Florahome$stats.Meyers($DIRECT) + Brodnax(16, 16): + - default_action: { allowed: true } + - handle: 0x20000007 + - next_table: 0 + - { } + - set HillTop.RossFork.Pridgen, 1 + - _Florahome$stats.Meyers($DIRECT) + Bowers(0, 0): + - default_action: { allowed: true } + - handle: 0x20000008 + - next_table: 0 + - { } + - _Florahome$stats.Meyers($DIRECT) + Skene(18, 18): + - default_action: { allowed: true } + - handle: 0x20000009 + - next_table: 0 + - { } + - set HillTop.RossFork.Tenino, 1 + - set HillTop.RossFork.Juniata, 1 + - _Florahome$stats.Meyers($DIRECT) + Scottdale(20, 20): + - p4_param_order: { Blencoe: 8, Satolah: 1 } + - default_action: { allowed: true } + - handle: 0x2000000a + - next_table: 0 + - { Blencoe: immediate(0..7), Satolah: immediate(8..8) } + - set HillTop.Wisdom.Blencoe, Blencoe + - set HillTop.RossFork.Tenino, 1 + - set HillTop.Edwards.Satolah, Satolah + - _Florahome$stats.Meyers($DIRECT) + Camargo(15, 15): + - default_action: { allowed: true } + - handle: 0x2000000b + - next_table: 0 + - { } + - _Florahome$stats.Meyers($DIRECT) + default_action: Camargo + ternary_match _Newtonia 9: + p4: { name: Newtonia, size: 512, disable_atomic_modify : true } + p4_param_order: + Millston.Calabash.Goldsboro: { type: ternary, size: 24, full_size: 24, key_name: "Calabash.Goldsboro" } + Millston.Calabash.Fabens: { type: ternary, size: 24, full_size: 24, key_name: "Calabash.Fabens" } + row: [ 8, 9 ] + bus: [ 1, 1 ] + column: + - 1 + - 1 + indirect_bus: 3 + input_xbar: + ternary group 8: { 0: Millston.Calabash.Fabens, 24: Millston.Calabash.Goldsboro.0-7, 32: Millston.Calabash.Goldsboro.8-23(0..7) } + ternary group 9: { 8: Millston.Calabash.Goldsboro.8-23(8..15) } + match: + - { group: 8, dirtcam: 0x155 } + - { group: 9, dirtcam: 0x4 } + hit: [ _Leacock ] + miss: _Leacock + instruction: _Newtonia($DEFAULT, $DEFAULT) + actions: + Pioche(0, 21): + - default_action: { allowed: true } + - handle: 0x2000000e + - next_table: 0 + - set HillTop.RossFork.Teigen, 1 + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x2000000f + - next_table: 0 + default_only_action: NoAction + hash_action _McIntyre_0 7: + p4: { name: McIntyre, size: 1, disable_atomic_modify : true } + row: 4 + bus: 1 + hash_dist: + 3: { hash: 3, mask: 0x7ffff, shift: 0, expand: 0 } + input_xbar: + exact group 3: { 64: Millston.Wondervu$0.Bowden, 80: HillTop.Tiburon.Arnold } + hash 7: + 0..11: stripe(Millston.Wondervu$0.Bowden) + 12..15: stripe(HillTop.Tiburon.Arnold(0..3)) + 32..34: stripe(HillTop.Tiburon.Arnold(4..6)) + hash group 3: + table: [7] + seed: 0x0 + gateway: + name: _McIntyre_0-gateway + row: 3 + bus: 0 + unit: 0 + 0x0: _Aynor_0 + miss: _Aynor_0 + condition: + expression: "true(always hit)" + true: _Aynor_0 + false: _Aynor_0 + next: [] + action_bus: { 40..41 : _McIntyre_0$salu..McDonough(0..15) } + stateful: _McIntyre_0$salu..McDonough(hash_dist 3, $DEFAULT, $DEFAULT) + instruction: _McIntyre_0($DEFAULT, $DEFAULT) + actions: + Leland(0, 17): + - default_action: { allowed: true } + - handle: 0x2000000d + - next_table: 0 + - set HillTop.Murphy.Blairsden, _McIntyre_0$salu..McDonough + - _McIntyre_0$salu..McDonough(_Ozona_0, $hash_dist) + default_action: Leland + stateful _McIntyre_0$salu..McDonough: + p4: { name: McDonough, size: 294912 } + row: 11 + column: [ 1, 2, 3, 4 ] + maprams: [ 1, 2, 3, 4 ] + format: { lo: 1 } + actions: + _Ozona_0: + - read_bit + - output alu_lo + set_bit_alu$0: + - set_bit + clr_bit_alu$0: + - clr_bit + hash_action _Aynor_0 8: + p4: { name: Aynor, size: 1, disable_atomic_modify : true } + row: 0 + bus: 1 + hash_dist: + 4: { hash: 3, mask: 0x7ffff, shift: 0, expand: 7 } + input_xbar: + exact group 3: { 64: Millston.Wondervu$0.Bowden, 80: HillTop.Tiburon.Arnold } + hash 7: + 16..27: stripe(Millston.Wondervu$0.Bowden) + 28..31: stripe(HillTop.Tiburon.Arnold(0..3)) + 39..41: stripe(HillTop.Tiburon.Arnold(4..6)) + hash group 3: + table: [7] + seed: 0x0 + gateway: + name: _Aynor_0-gateway + row: 1 + bus: 0 + unit: 1 + 0x0: _Newtonia + miss: _Newtonia + condition: + expression: "true(always hit)" + true: _Newtonia + false: _Newtonia + next: [] + action_bus: { 8 : _Aynor_0$salu..Exeter(0..7) } + stateful: _Aynor_0$salu..Exeter(hash_dist 4, $DEFAULT, $DEFAULT) + instruction: _Aynor_0($DEFAULT, $DEFAULT) + actions: + Dahlgren(0, 19): + - default_action: { allowed: true } + - handle: 0x2000000c + - next_table: 0 + - set HillTop.Murphy.Standish, _Aynor_0$salu..Exeter + - _Aynor_0$salu..Exeter(_Yulee_0, $hash_dist) + default_action: Dahlgren + stateful _Aynor_0$salu..Exeter: + p4: { name: Exeter, size: 294912 } + row: 15 + column: [ 1, 2, 3, 4 ] + maprams: [ 1, 2, 3, 4 ] + format: { lo: 1 } + actions: + _Yulee_0: + - read_bitc + - output alu_lo + set_bit_alu$0: + - set_bit + clr_bit_alu$0: + - clr_bit + hash_action _Leacock 10: + p4: { name: Leacock, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.Tiburon.Arnold: { type: exact, size: 9, full_size: 9, key_name: "Tiburon.Arnold" } + row: 0 + bus: 0 + hash_dist: + 2: { hash: 0, mask: 0x1ff, shift: 2 } + input_xbar: + exact group 4: { 0: HillTop.Tiburon.Arnold } + hash 8: + 32..40: stripe(HillTop.Tiburon.Arnold) + hash group 0: + table: [8] + seed: 0x0 + gateway: + name: _Leacock-gateway + row: 0 + bus: 0 + unit: 1 + 0x0: _Armagh + miss: _Armagh + condition: + expression: "true(always hit)" + true: _Armagh + false: _Armagh + next: [] + action: _Leacock$action_data(hash_dist 2, $DEFAULT) + instruction: _Leacock($DEFAULT, $DEFAULT) + actions: + Burmah(0, 22): + - p4_param_order: { McGrady: 3, LaConner: 6, AquaPark: 2 } + - default_action: { allowed: true } + - handle: 0x2000005b + - next_table: 0 + - { $data0: $adf_b0(0..4), McGrady: $data0(0..2), AquaPark: $data0(3..4), LaConner: $adf_h0(5..10) } + - set HillTop.Edwards.LaConner, LaConner + - set B14(2..6), $data0 + default_action: Burmah + default_action_parameters: + McGrady: "0x0" + LaConner: "0x0" + AquaPark: "0x0" + action _Leacock$action_data: + p4: { name: Leacock$action, how_referenced: direct } + row: 7 + column: 1 + vpns: [ 0 ] + home_row: + - 7 + format Burmah: { $adf_b0: 0..7, $adf_h0: 0..15 } + action_bus: { 10 : $adf_b0, 44..45 : $adf_h0 } + exact_match _Armagh 11: + p4: { name: Armagh, size: 20480, disable_atomic_modify : true } + p4_param_order: + Millston.GlenAvon.Kaluaaha: { type: exact, size: 32, full_size: 32, key_name: "GlenAvon.Kaluaaha" } + Millston.GlenAvon.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "GlenAvon.Calcasieu" } + row: [ 5, 4, 3 ] + bus: [ 0, 0, 0 ] + column: + - [ 2, 3, 4, 6 ] + - [ 2, 3, 4, 6 ] + - [ 2, 3 ] + stash: + row: [ 3 ] + col: [ 2 ] + unit: [ 0 ] + ways: + - [4, 0, 0x1, [3, 2], [3, 3]] + - [4, 1, 0x2, [4, 4], [4, 6]] + - [4, 2, 0x4, [4, 2], [4, 3]] + - [4, 3, 0x8, [5, 4], [5, 6]] + - [4, 0, 0x1, [5, 2], [5, 3]] + input_xbar: + exact group 5: { 0: Millston.GlenAvon.Kaluaaha, 32: Millston.GlenAvon.Calcasieu } + hash 10: + 0..7: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(0..7) + 8..9: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(8..9) + 40: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(10) + 11..18: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(0..7) + 19: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(8) + 10: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(10) + 41: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(9) + 22..29: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(0..7) + 20..21: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(9..10) + 42: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(8) + 33..39: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(0..6) + 30..32: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(8..10) + 43: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(7) + hash group 4: + table: [10] + seed: 0x66d75f86f49 + format: { action(0): 0..1, version(0): 112..115, match(0): [83..87, 32..79 ], action(1): 2..3, version(1): 116..119, match(1): [123..127, 88..111, 8..31 ] } + match: [ Millston.GlenAvon.Kaluaaha(11..15), Millston.GlenAvon.Kaluaaha(16..23), Millston.GlenAvon.Kaluaaha(24..31), Millston.GlenAvon.Calcasieu(0..7), Millston.GlenAvon.Calcasieu(8..15), Millston.GlenAvon.Calcasieu(16..23), Millston.GlenAvon.Calcasieu(24..31) ] + hit: [ _Ankeny ] + miss: _Ankeny + action: _Armagh$action_data($DIRECT, $DEFAULT) + instruction: _Armagh(action, $DEFAULT) + actions: + Knights(0, 23): + - p4_param_order: { Lookeba: 16, Alstown: 16, Longwood: 2, Yorkshire: 1, Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x20000010 + - next_table: 0 + - { Alstown: $adf_h0(0..15), Lookeba: $adf_h1(0..15), Bonduel: $adf_h2(0..13), $data0: $adf_h3(0..2), Longwood: $data0(0..1), Yorkshire: $data0(2..2) } + - set HillTop.RossFork.Altus, Lookeba + - set HillTop.RossFork.Hickox, Alstown + - set HillTop.RossFork.Luzerne, Bonduel + - set H90(12..14), $data0 + Humeston(1, 24): + - p4_param_order: { Lookeba: 16, Alstown: 16, Longwood: 2, Yorkshire: 1, Sardinia: 14 } + - default_action: { allowed: true } + - handle: 0x20000011 + - next_table: 0 + - { Alstown: $adf_h0(0..15), Lookeba: $adf_h1(0..15), Sardinia: $adf_h2(0..13), $data0: $adf_h3(0..3), Longwood: $data0(0..1), Yorkshire: $data0(2..2), $constant0: $data0(3..3), $constant0: 1 } + - set HillTop.RossFork.Altus, Lookeba + - set HillTop.RossFork.Hickox, Alstown + - set HillTop.RossFork.Luzerne, Sardinia + - set H90(12..15), $data0 + Sequim(2, 0): + - default_action: { allowed: true } + - handle: 0x20000012 + - next_table: 0 + - { } + default_action: Sequim + action _Armagh$action_data: + p4: { name: Armagh$action } + row: [ 14, 13, 12, 11, 10, 9 ] + word: [ 0, 0, 0, 0, 0, 0 ] + column: + - 5 + - [ 4, 5 ] + - 5 + - 5 + - 5 + - [ 2, 3, 4, 5 ] + vpns: + - [ 0 ] + - [ 1, 2 ] + - [ 3 ] + - [ 4 ] + - [ 5 ] + - [ 6, 7, 8, 9 ] + home_row: + - 14 + format Knights: { $adf_h0: 0..15, $adf_h1: 16..31, $adf_h2: 32..47, $adf_h3: 48..63 } + format Humeston: { $adf_h0: 0..15, $adf_h1: 16..31, $adf_h2: 32..47, $adf_h3: 48..63 } + action_bus: { 72..73 : $adf_h0, 74..75 : $adf_h1, 76..77 : $adf_h2, 78..79 : $adf_h3 } + ternary_match _Ankeny 12: + p4: { name: Ankeny, size: 512, disable_atomic_modify : true } + p4_param_order: + Millston.Osyka.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Osyka" } + Millston.Osyka.Noyes: { type: ternary, size: 8, full_size: 8, key_name: "Osyka.Noyes" } + row: 10 + bus: 1 + column: 1 + input_xbar: + ternary group 9: { 6: Millston.Osyka.$valid, 16: Millston.Osyka.Noyes } + match: + - { group: 9, dirtcam: 0x11 } + hit: [ Turney_0 ] + miss: Turney_0 + indirect: _Ankeny$tind + ternary_indirect _Ankeny$tind: + row: 1 + bus: 0 + column: 5 + input_xbar: + ternary group 9: { 6: Millston.Osyka.$valid, 16: Millston.Osyka.Noyes } + format: { action: 0..0 } + instruction: _Ankeny$tind(action, $DEFAULT) + actions: + Funston(0, 25): + - default_action: { allowed: true } + - handle: 0x200000c9 + - next_table: 0 + - set HillTop.RossFork.Ankeny, 25 + Mayflower(1, 26): + - default_action: { allowed: true } + - handle: 0x200000ca + - next_table: 0 + - set HillTop.RossFork.Ankeny, 10 + default_action: Mayflower +stage 1 ingress: + exact_match Turney_0 0: + p4: { name: Turney, size: 1024, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Chaffee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Chaffee" } + HillTop.RossFork.Ocoee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } + row: 1 + bus: 1 + column: 7 + stash: + row: [ 1 ] + col: [ 7 ] + unit: [ 1 ] + ways: + - [0, 0, 0x0, [1, 7]] + input_xbar: + exact group 0: { 0: HillTop.RossFork.Chaffee, 8: HillTop.RossFork.Ocoee } + hash 0: + 0..1: random(HillTop.RossFork.Chaffee(2..7)) ^ HillTop.RossFork.Chaffee(0..1) + 2..9: random(HillTop.RossFork.Chaffee(2..7)) ^ HillTop.RossFork.Ocoee + hash group 0: + table: [0] + seed: 0x2e8 + format: { action(0): 0..0, version(0): 112..115, match(0): 34..39 } + match: [ HillTop.RossFork.Chaffee(2..7) ] + hit: [ _TinCity_0 ] + miss: _TinCity_0 + instruction: Turney_0(action, $DEFAULT) + actions: + Bodcaw(0, 1): + - default_action: { allowed: true } + - handle: 0x20000042 + - next_table: 0 + - set HillTop.RossFork.Laxon, HillTop.Maddock.Kaluaaha + - set HillTop.RossFork.Crozet, Millston.Grays.Chevak + Weimar(1, 2): + - default_action: { allowed: true } + - handle: 0x20000043 + - next_table: 0 + - set HillTop.RossFork.Crozet(0..7), HillTop.RossFork.Chaffee + default_action: Bodcaw + ternary_match _TinCity_0 1: + p4: { name: TinCity, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.Maddock.Calcasieu: { type: ternary, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } + row: 1 + bus: 1 + column: 1 + input_xbar: + ternary group 0: { 0: HillTop.Maddock.Calcasieu } + match: + - { group: 0, dirtcam: 0x55 } + gateway: + name: cond-4 + input_xbar: + exact group 0: { 21: HillTop.RossFork.Naruna.2-2, 27: HillTop.RossFork.Naruna.0-1 } + row: 5 + bus: 1 + unit: 0 + match: { 3: HillTop.RossFork.Naruna.0-1, 13: HillTop.RossFork.Naruna.2-2 } + 0b**0********01: run_table + miss: _Comunas_0 + condition: + expression: "(HillTop.RossFork.Naruna == 1)" + true: _TinCity_0 + false: _Comunas_0 + hit: [ _Stone_0 ] + miss: _Stone_0 + indirect: _TinCity_0$tind + ternary_indirect _TinCity_0$tind: + row: 6 + bus: 0 + column: 2 + input_xbar: + ternary group 0: { 0: HillTop.Maddock.Calcasieu } + format: { action: 0..1, immediate: 2..33 } + action_bus: { 64..65 : immediate(0..15), 66..67 : immediate(16..31) } + instruction: _TinCity_0$tind(action, $DEFAULT) + actions: + Bagwell(1, 3): + - p4_param_order: { Liberal: 16, Doyline: 16 } + - default_action: { allowed: true } + - handle: 0x20000026 + - next_table: 0 + - { Doyline: immediate(0..15), Liberal: immediate(16..31) } + - set HillTop.Bessie.Calcasieu, Liberal + - set HillTop.Bessie.Chavies, Doyline + Wright(2, 4): + - default_action: { allowed: true } + - handle: 0x20000027 + - next_table: 0 + - { } + - set HillTop.RossFork.Halaula, 1 + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x20000028 + - next_table: 0 + - { } + default_only_action: NoAction + ternary_match _Comunas_0 3: + p4: { name: Comunas, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.Sublett.Calcasieu: { type: ternary, size: 128, full_size: 128, key_name: "Sublett.Calcasieu" } + row: [ 5, 4, 3 ] + bus: [ 0, 0, 0 ] + column: + - 0 + - 0 + - 0 + input_xbar: + ternary group 2: { 0: HillTop.Sublett.Calcasieu.96-127(24..31), 8: HillTop.Sublett.Calcasieu.96-127(0..7), 16: HillTop.Sublett.Calcasieu.0-31(8..15), 24: HillTop.Sublett.Calcasieu.96-127(16..23), 32: HillTop.Sublett.Calcasieu.0-31(24..31) } + ternary group 4: { 0: HillTop.Sublett.Calcasieu.0-31(16..23), 8: HillTop.Sublett.Calcasieu.32-63(24..31), 16: HillTop.Sublett.Calcasieu.0-31(0..7), 24: HillTop.Sublett.Calcasieu.32-63(8..23) } + ternary group 5: { 0: HillTop.Sublett.Calcasieu.32-63(0..7), 8: HillTop.Sublett.Calcasieu.64-95(8..31), 32: HillTop.Sublett.Calcasieu.64-95(0..7) } + byte group 0: { 0: HillTop.Sublett.Calcasieu.96-127(8..15) } + match: + - { group: 2, byte_group: 0, byte_config: 0, dirtcam: 0x555 } + - { group: 4, byte_group: 0, byte_config: 1, dirtcam: 0x555 } + - { group: 5, dirtcam: 0x155 } + gateway: + name: cond-5 + input_xbar: + exact group 0: { 21: HillTop.RossFork.Naruna.2-2, 27: HillTop.RossFork.Naruna.0-1 } + row: 4 + bus: 1 + unit: 0 + match: { 3: HillTop.RossFork.Naruna.0-1, 13: HillTop.RossFork.Naruna.2-2 } + 0b**0********10: run_table + miss: _Virginia + condition: + expression: "(HillTop.RossFork.Naruna == 2)" + true: _Comunas_0 + false: _Virginia + hit: [ _Milltown_0 ] + miss: _Milltown_0 + indirect: _Comunas_0$tind + ternary_indirect _Comunas_0$tind: + row: 4 + bus: 0 + column: 2 + input_xbar: + ternary group 2: { 0: HillTop.Sublett.Calcasieu.96-127(24..31), 8: HillTop.Sublett.Calcasieu.96-127(0..7), 16: HillTop.Sublett.Calcasieu.0-31(8..15), 24: HillTop.Sublett.Calcasieu.96-127(16..23), 32: HillTop.Sublett.Calcasieu.0-31(24..31) } + ternary group 4: { 0: HillTop.Sublett.Calcasieu.0-31(16..23), 8: HillTop.Sublett.Calcasieu.32-63(24..31), 16: HillTop.Sublett.Calcasieu.0-31(0..7), 24: HillTop.Sublett.Calcasieu.32-63(8..23) } + ternary group 5: { 0: HillTop.Sublett.Calcasieu.32-63(0..7), 8: HillTop.Sublett.Calcasieu.64-95(8..31), 32: HillTop.Sublett.Calcasieu.64-95(0..7) } + byte group 0: { 0: HillTop.Sublett.Calcasieu.96-127(8..15) } + format: { action: 0..1, immediate: 2..33 } + action_bus: { 68..69 : immediate(0..15), 70..71 : immediate(16..31) } + instruction: _Comunas_0$tind(action, $DEFAULT) + actions: + Bagwell(1, 7): + - p4_param_order: { Liberal: 16, Doyline: 16 } + - default_action: { allowed: true } + - handle: 0x2000002c + - next_table: 0 + - { Doyline: immediate(0..15), Liberal: immediate(16..31) } + - set HillTop.Bessie.Calcasieu, Liberal + - set HillTop.Bessie.Chavies, Doyline + Wright(2, 9): + - default_action: { allowed: true } + - handle: 0x2000002d + - next_table: 0 + - { } + - set HillTop.RossFork.Halaula, 1 + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x2000002e + - next_table: 0 + - { } + default_only_action: NoAction + ternary_match _Milltown_0 4: + p4: { name: Milltown, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.Sublett.Kaluaaha: { type: ternary, size: 128, full_size: 128, key_name: "Sublett.Kaluaaha" } + row: [ 0, 1, 2 ] + bus: [ 0, 0, 0 ] + column: + - 0 + - 0 + - 0 + input_xbar: + ternary group 3: { 0: HillTop.Sublett.Kaluaaha.32-63(8..31), 24: HillTop.Sublett.Kaluaaha.0-31(0..15) } + ternary group 7: { 0: HillTop.Sublett.Kaluaaha.0-31(24..31), 8: HillTop.Sublett.Kaluaaha.64-95(0..15), 24: HillTop.Sublett.Kaluaaha.0-31(16..23), 32: HillTop.Sublett.Kaluaaha.64-95(24..31) } + ternary group 9: { 0: HillTop.Sublett.Kaluaaha.64-95(16..23), 8: HillTop.Sublett.Kaluaaha.96-127(24..31), 16: HillTop.Sublett.Kaluaaha.96-127(0..23) } + byte group 1: { 0: HillTop.Sublett.Kaluaaha.32-63(0..7) } + match: + - { group: 3, byte_group: 1, byte_config: 0, dirtcam: 0x555 } + - { group: 7, byte_group: 1, byte_config: 1, dirtcam: 0x555 } + - { group: 9, dirtcam: 0x155 } + hit: [ _Virginia ] + miss: _Virginia + indirect: _Milltown_0$tind + ternary_indirect _Milltown_0$tind: + row: 3 + bus: 0 + column: 2 + input_xbar: + ternary group 3: { 0: HillTop.Sublett.Kaluaaha.32-63(8..31), 24: HillTop.Sublett.Kaluaaha.0-31(0..15) } + ternary group 7: { 0: HillTop.Sublett.Kaluaaha.0-31(24..31), 8: HillTop.Sublett.Kaluaaha.64-95(0..15), 24: HillTop.Sublett.Kaluaaha.0-31(16..23), 32: HillTop.Sublett.Kaluaaha.64-95(24..31) } + ternary group 9: { 0: HillTop.Sublett.Kaluaaha.64-95(16..23), 8: HillTop.Sublett.Kaluaaha.96-127(24..31), 16: HillTop.Sublett.Kaluaaha.96-127(0..23) } + byte group 1: { 0: HillTop.Sublett.Kaluaaha.32-63(0..7) } + format: { action: 0..1, immediate: 2..33 } + action_bus: { 38..39 : immediate(16..31), 100..103 : immediate(0..31) } + instruction: _Milltown_0$tind(action, $DEFAULT) + actions: + Parmelee(0, 10): + - p4_param_order: { Liberal: 16, Doyline: 16 } + - default_action: { allowed: true } + - handle: 0x20000029 + - next_table: 0 + - { Doyline: immediate(0..15), Liberal: immediate(16..31) } + - set HillTop.RossFork.Kapalua, 0 + - set HillTop.Bessie.LasVegas, HillTop.RossFork.Ocoee + - set HillTop.Bessie.PineCity, HillTop.Sublett.PineCity + - set HillTop.Bessie.Exton, HillTop.RossFork.Exton + - set HillTop.Bessie.Noyes, HillTop.RossFork.Kremlin + - set HillTop.Bessie.Kaluaaha, Liberal + - set HillTop.Bessie.Heuvelton, Doyline + Belcourt(1, 12): + - default_action: { allowed: true } + - handle: 0x2000002a + - next_table: 0 + - { } + - set HillTop.RossFork.Kapalua, 1 + Moorman(2, 14): + - default_action: { allowed: true } + - handle: 0x2000002b + - next_table: 0 + - { } + - set HillTop.RossFork.Kapalua, 0 + - set HillTop.Bessie.LasVegas, HillTop.RossFork.Ocoee + - set HillTop.Bessie.PineCity, HillTop.Sublett.PineCity + - set HillTop.Bessie.Exton, HillTop.RossFork.Exton + - set HillTop.Bessie.Noyes, HillTop.RossFork.Kremlin + default_action: Moorman + ternary_match _Stone_0 2: + p4: { name: Stone, size: 2048, disable_atomic_modify : true } + p4_param_order: + HillTop.Maddock.Kaluaaha: { type: ternary, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } + row: [ 9, 10, 11, 0 ] + bus: [ 0, 0, 0, 1 ] + column: + - 0 + - 0 + - 0 + - 1 + input_xbar: + ternary group 1: { 0: HillTop.Maddock.Kaluaaha(16..31), 16: HillTop.Maddock.Kaluaaha(0..15) } + match: + - { group: 1, dirtcam: 0x55 } + hit: [ _Virginia ] + miss: _Virginia + indirect: _Stone_0$tind + ternary_indirect _Stone_0$tind: + row: 5 + bus: 0 + column: 2 + input_xbar: + ternary group 1: { 0: HillTop.Maddock.Kaluaaha(16..31), 16: HillTop.Maddock.Kaluaaha(0..15) } + format: { action: 0..1, immediate: 2..33 } + action_bus: { 34..35 : immediate(16..31), 96..99 : immediate(0..31) } + instruction: _Stone_0$tind(action, $DEFAULT) + actions: + Capitola(0, 5): + - p4_param_order: { Liberal: 16, Doyline: 16 } + - default_action: { allowed: true } + - handle: 0x20000023 + - next_table: 0 + - { Doyline: immediate(0..15), Liberal: immediate(16..31) } + - set HillTop.RossFork.Kapalua, 0 + - set HillTop.Bessie.LasVegas, HillTop.RossFork.Ocoee + - set HillTop.Bessie.PineCity, HillTop.Maddock.PineCity + - set HillTop.Bessie.Exton, HillTop.RossFork.Exton + - set HillTop.Bessie.Noyes, HillTop.RossFork.Kremlin + - set HillTop.Bessie.Kaluaaha, Liberal + - set HillTop.Bessie.Heuvelton, Doyline + Belcourt(1, 6): + - default_action: { allowed: true } + - handle: 0x20000024 + - next_table: 0 + - { } + - set HillTop.RossFork.Kapalua, 1 + Council(2, 8): + - default_action: { allowed: true } + - handle: 0x20000025 + - next_table: 0 + - { } + - set HillTop.RossFork.Kapalua, 0 + - set HillTop.Bessie.LasVegas, HillTop.RossFork.Ocoee + - set HillTop.Bessie.PineCity, HillTop.Maddock.PineCity + - set HillTop.Bessie.Exton, HillTop.RossFork.Exton + - set HillTop.Bessie.Noyes, HillTop.RossFork.Kremlin + default_action: Council + exact_match _Virginia 5: + p4: { name: Virginia, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Naruna: { type: exact, size: 2, full_size: 3, key_name: "RossFork.Naruna" } + HillTop.Tiburon.Arnold: { type: exact, size: 7, full_size: 9, key_name: "Tiburon.Arnold" } + row: 1 + bus: 0 + column: 6 + stash: + row: [ 1 ] + col: [ 6 ] + unit: [ 0 ] + ways: + - [0, 1, 0x0, [1, 6]] + input_xbar: + exact group 0: { 27: HillTop.RossFork.Naruna.0-1, 32: HillTop.Tiburon.Arnold(0..6) } + hash 0: + 10..11: HillTop.RossFork.Naruna.0-1 + 12..18: HillTop.Tiburon.Arnold(0..6) + hash group 0: + table: [0] + seed: 0x0 + format: { action(0): 0..1, immediate(0): 2..25, version(0): 112..115 } + gateway: + name: cond-7 + input_xbar: + exact group 0: { 41: HillTop.Wisdom.Onycha } + row: 3 + bus: 1 + unit: 1 + match: { 1: HillTop.Wisdom.Onycha } + 0b****000: run_table + miss: _Cornish + condition: + expression: "(HillTop.Wisdom.Onycha == 0)" + true: _Virginia + false: _Cornish + hit: [ [], _Archer, _Cornish ] + miss: _Archer + action_bus: { 42..43 : immediate(16..23), 104..107 : immediate(0..23) } + instruction: _Virginia(action, $DEFAULT) + actions: + Bluff(1, 11): + - p4_param_order: { Miranda: 8, Bedrock: 32 } + - default_action: { allowed: true } + - handle: 0x20000033 + - next_table: 1 + - { Bedrock.0-15: immediate(0..15), Miranda: immediate(16..23) } + - set HillTop.Mausdale.Kenney(0..15), Bedrock.0-15 + - set HillTop.Bessie.Miranda, Miranda + Sequim(2, 0): + - default_action: { allowed: true } + - handle: 0x20000034 + - next_table: 2 + - { } + default_action: Sequim + exact_match _Cornish 6: + p4: { name: Cornish, size: 8192, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Naruna: { type: exact, size: 2, full_size: 3, key_name: "RossFork.Naruna" } + HillTop.RossFork.Bicknell: { type: exact, size: 12, full_size: 12, key_name: "RossFork.Bicknell" } + row: [ 3, 2 ] + bus: [ 1, 1 ] + column: + - [ 7, 8, 9 ] + - 8 + stash: + row: [ 3 ] + col: [ 7 ] + unit: [ 0 ] + ways: + - [1, 0, 0x1, [3, 7], [3, 8]] + - [1, 1, 0x0, [3, 9]] + - [1, 2, 0x0, [2, 8]] + input_xbar: + exact group 0: { 64: HillTop.RossFork.Bicknell, 83: HillTop.RossFork.Naruna.0-1 } + hash 1: + 0..3: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Bicknell(0..3) + 4..7: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Bicknell(8..11) + 8..9: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Naruna.0-1 + 40: random(HillTop.RossFork.Bicknell(4..7)) + 11..14: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Bicknell(0..3) + 15..18: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Bicknell(8..11) + 19: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Naruna.0-1(0) + 10: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Naruna.0-1(1) + 22..25: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Bicknell(0..3) + 26..29: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Bicknell(8..11) + 20..21: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Naruna.0-1 + hash group 1: + table: [1] + seed: 0x2f4d580e + format: { immediate(0): 0..23, version(0): 112..115, match(0): 52..55, immediate(1): 24..47, version(1): 116..119, match(1): 60..63 } + match: [ HillTop.RossFork.Bicknell(4..7) ] + hit: [ _Archer ] + miss: _Archer + action_bus: { 46..47 : immediate(16..23), 108..111 : immediate(0..23) } + instruction: _Cornish($DEFAULT, $DEFAULT) + actions: + Silvertip(0, 13): + - p4_param_order: { Miranda: 8, Bedrock: 32 } + - default_action: { allowed: true } + - handle: 0x20000035 + - next_table: 0 + - { Bedrock.0-15: immediate(0..15), Miranda: immediate(16..23) } + - set HillTop.Mausdale.Kenney(0..15), Bedrock.0-15 + - set HillTop.Bessie.Miranda, Miranda + - set HillTop.RossFork.Yaurel, 1 + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x20000036 + - next_table: 0 + - { } + default_only_action: NoAction + ternary_match _Archer 7: + p4: { name: Archer, size: 1024, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Mendocino: { type: ternary, size: 16, full_size: 16, key_name: "RossFork.Mendocino" } + row: [ 4, 5 ] + bus: [ 1, 1 ] + column: + - 1 + - 1 + input_xbar: + ternary group 6: { 0: HillTop.RossFork.Mendocino(8..15), 8: HillTop.RossFork.Mendocino(0..7) } + match: + - { group: 6, byte_config: 3, dirtcam: 0x5 } + gateway: + name: cond-6 + input_xbar: + exact group 0: { 50: HillTop.RossFork.Denhoff.1-2(0) } + row: 2 + bus: 1 + unit: 0 + match: { 2: HillTop.RossFork.Denhoff.1-2(0) } + 0b*****1: run_table + miss: _Thawville + condition: + expression: "(HillTop.RossFork.Denhoff & 2 == 2)" + true: _Archer + false: _Thawville + hit: [ _Hatchel ] + miss: _Hatchel + indirect: _Archer$tind + ternary_indirect _Archer$tind: + row: 2 + bus: 0 + column: 2 + input_xbar: + ternary group 6: { 0: HillTop.RossFork.Mendocino(8..15), 8: HillTop.RossFork.Mendocino(0..7) } + format: { action: 0..0 } + action: _Archer$action_data($DIRECT, $DEFAULT) + instruction: _Archer$tind(action, $DEFAULT) + actions: + Kilbourne(1, 15): + - p4_param_order: { Liberal: 16 } + - default_action: { allowed: true } + - handle: 0x20000031 + - next_table: 0 + - { Liberal: $adf_h0(0..15) } + - set HillTop.Bessie.Mendocino, Liberal + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x20000032 + - next_table: 0 + - { } + default_only_action: NoAction + action _Archer$action_data: + p4: { name: Archer$action } + row: 13 + column: 5 + vpns: [ 0 ] + home_row: + - 13 + format Kilbourne: { $adf_h0: 0..15 } + action_bus: { 32..33 : $adf_h0 } + ternary_match _Hatchel 8: + p4: { name: Hatchel, size: 1024, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Chevak: { type: ternary, size: 16, full_size: 16, key_name: "RossFork.Chevak" } + row: [ 2, 3 ] + bus: [ 1, 1 ] + column: + - 1 + - 1 + indirect_bus: 1 + input_xbar: + ternary group 6: { 16: HillTop.RossFork.Chevak(8..15), 24: HillTop.RossFork.Chevak(0..7) } + match: + - { group: 6, byte_config: 3, dirtcam: 0x50 } + hit: [ _Thawville ] + miss: _Thawville + action: _Hatchel$action_data($DIRECT, $DEFAULT) + instruction: _Hatchel($DEFAULT, $DEFAULT) + actions: + Thatcher(0, 16): + - p4_param_order: { Liberal: 16 } + - default_action: { allowed: true } + - handle: 0x2000002f + - next_table: 0 + - { Liberal: $adf_h0(0..15) } + - set HillTop.Bessie.Chevak, Liberal + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x20000030 + - next_table: 0 + - { } + default_only_action: NoAction + action _Hatchel$action_data: + p4: { name: Hatchel$action } + row: 14 + column: 3 + vpns: [ 0 ] + home_row: + - 14 + format Thatcher: { $adf_h0: 0..15 } + action_bus: { 36..37 : $adf_h0 } + exact_match _Thawville 9: + p4: { name: Thawville, size: 20480, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Altus: { type: exact, size: 16, full_size: 16, key_name: "RossFork.Altus" } + Millston.Grays.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Grays.Chevak" } + Millston.Grays.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Grays.Mendocino" } + row: [ 7, 5, 4, 3 ] + bus: [ 1, 0, 0, 0 ] + column: + - 9 + - [ 6, 7, 8, 9 ] + - [ 6, 7, 8, 9 ] + - 6 + stash: + row: [ 7 ] + col: [ 9 ] + unit: [ 1 ] + ways: + - [2, 0, 0x1, [7, 9], [5, 6]] + - [2, 1, 0x2, [5, 7], [5, 8]] + - [2, 2, 0x4, [5, 9], [4, 6]] + - [2, 3, 0x8, [4, 7], [4, 8]] + - [2, 0, 0x1, [4, 9], [3, 6]] + input_xbar: + exact group 1: { 0: Millston.Grays.Chevak, 16: Millston.Grays.Mendocino, 32: HillTop.RossFork.Altus } + hash 2: + 0..7: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(0..7) + 8..9: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(8..9) + 40: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(10) + 11..18: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(0..7) + 19: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(8) + 10: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(10) + 41: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(9) + 22..29: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(0..7) + 20..21: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(9..10) + 42: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(8) + 33..39: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(0..6) + 30..32: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(8..10) + 43: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(7) + hash group 2: + table: [2] + seed: 0x474c02dbdc8 + format: { action(0): 0..1, immediate(0): 4..19, version(0): 112..115, match(0): [75..79, 40..71 ], action(1): 2..3, immediate(1): 20..35, version(1): 116..119, match(1): [123..127, 80..111 ] } + match: [ Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino(0..7), Millston.Grays.Mendocino(8..15), HillTop.RossFork.Altus(0..7), HillTop.RossFork.Altus(8..15) ] + gateway: + name: cond-3 + input_xbar: + exact group 1: { 32: HillTop.RossFork.Altus } + row: 3 + bus: 0 + unit: 0 + match: { 0: HillTop.RossFork.Altus(0..7), 8: HillTop.RossFork.Altus(8..15) } + 0x0000: _Nevis + miss: run_table + condition: + expression: "(HillTop.RossFork.Altus != 0)" + true: _Thawville + false: _Nevis + hit: [ _Nevis ] + miss: _Nevis + action_bus: { 40..41 : immediate(0..15) } + action: _Thawville$action_data($DIRECT, $DEFAULT) + instruction: _Thawville(action, $DEFAULT) + actions: + Orting(1, 17): + - p4_param_order: { Alstown: 16, Longwood: 2, Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x20000020 + - next_table: 0 + - { Bonduel: $adf_h0(0..13), Longwood: $adf_h0(14..15), Alstown: immediate(0..15) } + - set HillTop.RossFork.Tehachapi, Alstown + - set HillTop.RossFork.Caroleen, Longwood + - set HillTop.RossFork.Devers, Bonduel + SanRemo(2, 18): + - p4_param_order: { Alstown: 16, Longwood: 2, Sardinia: 14 } + - default_action: { allowed: true } + - handle: 0x20000021 + - next_table: 0 + - { Sardinia: $adf_h0(0..13), Longwood: $adf_h0(14..15), Alstown: immediate(0..15) } + - set HillTop.RossFork.Tehachapi, Alstown + - set HillTop.RossFork.Caroleen, Longwood + - set HillTop.RossFork.Belfair, 1 + - set HillTop.RossFork.Devers, Sardinia + Sequim(3, 0): + - default_action: { allowed: true } + - handle: 0x20000022 + - next_table: 0 + - { } + default_action: Sequim + action _Thawville$action_data: + p4: { name: Thawville$action } + row: [ 15, 14 ] + word: [ 0, 0 ] + column: + - [ 4, 5 ] + - 2 + vpns: + - [ 0, 1 ] + - [ 2 ] + home_row: + - 15 + format Orting: { $adf_h0: 0..15 } + format SanRemo: { $adf_h0: 0..15 } + action_bus: { 44..45 : $adf_h0 } + ternary_match _Nevis 10: + p4: { name: Nevis, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.Tiburon.Arnold: { type: exact, size: 7, full_size: 9, key_name: "Tiburon.Arnold" } + HillTop.RossFork.Powderly: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Powderly" } + HillTop.RossFork.Teigen: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Teigen" } + HillTop.RossFork.Welcome: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Welcome" } + HillTop.Aldan.Parkville: { type: ternary, size: 1, full_size: 4, key_name: "Aldan.Parkville", start_bit: 3 } + HillTop.Aldan.Blakeley: { type: ternary, size: 1, full_size: 1, key_name: "Aldan.Blakeley" } + row: 8 + bus: 0 + column: 0 + input_xbar: + ternary group 8: { 0: HillTop.Tiburon.Arnold(0..6), 14: HillTop.RossFork.Powderly, 22: HillTop.RossFork.Welcome, 27: HillTop.Aldan.Parkville(3), 32: HillTop.RossFork.Teigen } + byte group 3: { 0: HillTop.Aldan.Blakeley } + match: + - { group: 8, byte_group: 3, byte_config: 0, dirtcam: 0x555 } + gateway: + name: cond-8 + input_xbar: + exact group 0: { 57: Millston.Hayfield.$valid } + row: 1 + bus: 1 + unit: 1 + match: { 1: Millston.Hayfield.$valid } + 0b******0: run_table + miss: _Redfield + condition: + expression: "(Millston.Hayfield.$valid == 1 == 0)" + true: _Nevis + false: _Redfield + hit: [ [], _Redfield, _Lindsborg ] + miss: _Redfield + indirect: _Nevis$tind + counter _Nevis$stats.Hallwood: + p4: { name: Hallwood } + row: 13 + column: [ 3, 4 ] + maprams: [ 3, 4 ] + count: packets + format: {packets(0): 64..127, packets(1): 0..63} + ternary_indirect _Nevis$tind: + row: 1 + bus: 0 + column: 2 + input_xbar: + ternary group 8: { 0: HillTop.Tiburon.Arnold(0..6), 14: HillTop.RossFork.Powderly, 22: HillTop.RossFork.Welcome, 27: HillTop.Aldan.Parkville(3), 32: HillTop.RossFork.Teigen } + byte group 3: { 0: HillTop.Aldan.Blakeley } + format: { action: 0..1 } + stats: _Nevis$stats.Hallwood($DIRECT, $DEFAULT) + instruction: _Nevis$tind(action, $DEFAULT) + actions: + Empire(1, 19): + - default_action: { allowed: true } + - handle: 0x20000037 + - next_table: 1 + - set HillTop.RossFork.Weyauwega, 1 + - _Nevis$stats.Hallwood($DIRECT) + Daisytown(2, 0): + - default_action: { allowed: true } + - handle: 0x20000038 + - next_table: 2 + - _Nevis$stats.Hallwood($DIRECT) + default_action: Daisytown + exact_match _Lindsborg 11: + p4: { name: Lindsborg, size: 4096, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Goldsboro: { type: exact, size: 24, full_size: 24, key_name: "RossFork.Goldsboro" } + HillTop.RossFork.Fabens: { type: exact, size: 24, full_size: 24, key_name: "RossFork.Fabens" } + HillTop.RossFork.CeeVee: { type: exact, size: 12, full_size: 12, key_name: "RossFork.CeeVee" } + row: 2 + bus: 0 + column: [ 6, 7 ] + stash: + row: [ 2 ] + col: [ 6 ] + unit: [ 0 ] + ways: + - [0, 2, 0x0, [2, 6]] + - [0, 3, 0x0, [2, 7]] + input_xbar: + exact group 2: { 0: HillTop.RossFork.Fabens, 24: HillTop.RossFork.Goldsboro.8-23(8..15), 32: HillTop.RossFork.Goldsboro.0-7, 40: HillTop.RossFork.CeeVee(8..11), 48: HillTop.RossFork.Goldsboro.8-23(0..7), 64: HillTop.RossFork.CeeVee(0..7) } + hash 4: + 20..23: random(HillTop.RossFork.Fabens, HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(6..7)) ^ HillTop.RossFork.CeeVee(8..11) + 24..29: random(HillTop.RossFork.Fabens, HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(6..7)) ^ HillTop.RossFork.Goldsboro.8-23(0..5) + 31..34: random(HillTop.RossFork.Fabens, HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(6..7)) ^ HillTop.RossFork.CeeVee(8..11) + 35..39: random(HillTop.RossFork.Fabens, HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(6..7)) ^ HillTop.RossFork.Goldsboro.8-23(0..4) + 30: random(HillTop.RossFork.Fabens, HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(6..7)) ^ HillTop.RossFork.Goldsboro.8-23(5) + hash 5: + 20..29: random(HillTop.RossFork.CeeVee(0..7)) + 30..39: random(HillTop.RossFork.CeeVee(0..7)) + hash group 0: + table: [4, 5] + seed: 0x8cb1300000 + format: { action(0): 0..1, version(0): 112..115, match(0): [86..87, 32..79 ], action(1): 2..3, version(1): 116..119, match(1): [6..7, 88..111, 8..31 ] } + match: [ HillTop.RossFork.Goldsboro.8-23(6..7), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.CeeVee(0..7), HillTop.RossFork.Fabens(0..7), HillTop.RossFork.Fabens(8..15), HillTop.RossFork.Fabens(16..23), HillTop.RossFork.Goldsboro.0-7 ] + gateway: + name: cond-9 + input_xbar: + exact group 2: { 40: HillTop.RossFork.CeeVee(8..11), 64: HillTop.RossFork.CeeVee(0..7) } + row: 0 + bus: 1 + unit: 0 + match: { 0: HillTop.RossFork.CeeVee(0..7), 8: HillTop.RossFork.CeeVee(8..11) } + 0x*000: _Boonsboro + miss: run_table + condition: + expression: "(HillTop.RossFork.CeeVee != 0)" + true: _Lindsborg + false: _Boonsboro + hit: [ [], _Redfield, _Magasco ] + miss: _Redfield + instruction: _Lindsborg(action, $DEFAULT) + actions: + Balmorhea(1, 20): + - default_action: { allowed: true } + - handle: 0x2000003e + - next_table: 1 + - set HillTop.RossFork.Lowes, 1 + Sequim(2, 0): + - default_action: { allowed: true } + - handle: 0x2000003f + - next_table: 2 + default_action: Sequim + ternary_match _Boonsboro 14: + p4: { name: Boonsboro, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Bicknell: { type: ternary, size: 12, full_size: 12, key_name: "RossFork.Bicknell" } + HillTop.RossFork.Adona: { type: ternary, size: 24, full_size: 24, key_name: "RossFork.Adona" } + HillTop.RossFork.Connell: { type: ternary, size: 24, full_size: 24, key_name: "RossFork.Connell" } + HillTop.RossFork.Naruna: { type: ternary, size: 3, full_size: 3, key_name: "RossFork.Naruna" } + HillTop.Lamona.Whitefish: { type: ternary, size: 2, full_size: 2, key_name: "Lamona.Whitefish" } + row: [ 6, 7 ] + bus: [ 0, 0 ] + column: + - 0 + - 0 + input_xbar: + ternary group 10: { 0: HillTop.RossFork.Adona(22..23), 8: HillTop.RossFork.Connell.16-23, 16: HillTop.RossFork.Adona(6..21), 32: HillTop.RossFork.Bicknell(8..11) } + ternary group 11: { 0: HillTop.RossFork.Connell.0-15(8..15), 8: HillTop.RossFork.Bicknell(0..7), 21: HillTop.RossFork.Naruna.2-2, 24: HillTop.RossFork.Connell.0-15(0..7), 35: HillTop.RossFork.Naruna.0-1 } + byte group 5: { 0: HillTop.Lamona.Whitefish, 2: HillTop.RossFork.Adona(0..5) } + match: + - { group: 10, byte_group: 5, byte_config: 0, dirtcam: 0x555 } + - { group: 11, byte_group: 5, byte_config: 1, dirtcam: 0x555 } + hit: [ _Redfield, _Redfield, _Twain ] + miss: _Redfield + indirect: _Boonsboro$tind + ternary_indirect _Boonsboro$tind: + row: 0 + bus: 0 + column: 2 + input_xbar: + ternary group 10: { 0: HillTop.RossFork.Adona(22..23), 8: HillTop.RossFork.Connell.16-23, 16: HillTop.RossFork.Adona(6..21), 32: HillTop.RossFork.Bicknell(8..11) } + ternary group 11: { 0: HillTop.RossFork.Connell.0-15(8..15), 8: HillTop.RossFork.Bicknell(0..7), 21: HillTop.RossFork.Naruna.2-2, 24: HillTop.RossFork.Connell.0-15(0..7), 35: HillTop.RossFork.Naruna.0-1 } + byte group 5: { 0: HillTop.Lamona.Whitefish, 2: HillTop.RossFork.Adona(0..5) } + format: { action: 0..1 } + instruction: _Boonsboro$tind(action, $DEFAULT) + actions: + Aniak(0, 0): + - default_action: { allowed: true } + - handle: 0x20000039 + - next_table: 0 + Crannell(1, 22): + - default_action: { allowed: true } + - handle: 0x2000003a + - next_table: 1 + - set HillTop.Ovett.Hematite, 1 + Sequim(2, 23): + - default_action: { allowed: true } + - handle: 0x2000003b + - next_table: 2 + default_action: Sequim + exact_match _Twain 15: + p4: { name: Twain, size: 2048, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Bicknell: { type: exact, size: 12, full_size: 12, key_name: "RossFork.Bicknell" } + HillTop.RossFork.Adona: { type: exact, size: 24, full_size: 24, key_name: "RossFork.Adona" } + HillTop.RossFork.Connell: { type: exact, size: 24, full_size: 24, key_name: "RossFork.Connell" } + row: 0 + bus: 0 + column: [ 6, 7 ] + stash: + row: [ 0 ] + col: [ 6 ] + unit: [ 0 ] + ways: + - [3, 2, 0x0, [0, 6]] + - [3, 3, 0x0, [0, 7]] + input_xbar: + exact group 4: { 2: HillTop.RossFork.Adona, 32: HillTop.RossFork.Connell.16-23, 40: HillTop.RossFork.Bicknell(8..11), 48: HillTop.RossFork.Bicknell(0..7), 56: HillTop.RossFork.Connell.0-15(8..15), 64: HillTop.RossFork.Connell.0-15(0..7) } + hash 8: + 20..23: random(HillTop.RossFork.Adona(4..21), HillTop.RossFork.Connell.16-23, HillTop.RossFork.Bicknell(0..7), HillTop.RossFork.Connell.0-15(8..15)) ^ HillTop.RossFork.Adona(0..3) + 24..25: random(HillTop.RossFork.Adona(4..21), HillTop.RossFork.Connell.16-23, HillTop.RossFork.Bicknell(0..7), HillTop.RossFork.Connell.0-15(8..15)) ^ HillTop.RossFork.Adona(22..23) + 26..29: random(HillTop.RossFork.Adona(4..21), HillTop.RossFork.Connell.16-23, HillTop.RossFork.Bicknell(0..7), HillTop.RossFork.Connell.0-15(8..15)) ^ HillTop.RossFork.Bicknell(8..11) + 31..34: random(HillTop.RossFork.Adona(4..21), HillTop.RossFork.Connell.16-23, HillTop.RossFork.Bicknell(0..7), HillTop.RossFork.Connell.0-15(8..15)) ^ HillTop.RossFork.Adona(0..3) + 35..36: random(HillTop.RossFork.Adona(4..21), HillTop.RossFork.Connell.16-23, HillTop.RossFork.Bicknell(0..7), HillTop.RossFork.Connell.0-15(8..15)) ^ HillTop.RossFork.Adona(22..23) + 37..39: random(HillTop.RossFork.Adona(4..21), HillTop.RossFork.Connell.16-23, HillTop.RossFork.Bicknell(0..7), HillTop.RossFork.Connell.0-15(8..15)) ^ HillTop.RossFork.Bicknell(8..10) + 30: random(HillTop.RossFork.Adona(4..21), HillTop.RossFork.Connell.16-23, HillTop.RossFork.Bicknell(0..7), HillTop.RossFork.Connell.0-15(8..15)) ^ HillTop.RossFork.Bicknell(11) + hash 9: + 20..29: random(HillTop.RossFork.Connell.0-15(0..7)) + 30..39: random(HillTop.RossFork.Connell.0-15(0..7)) + hash group 3: + table: [8, 9] + seed: 0x51fe300000 + format: { version(0): 112..115, match(0): [32..55, 86..87, 56..79 ] } + match: [ HillTop.RossFork.Bicknell(0..7), HillTop.RossFork.Connell.0-15(0..7), HillTop.RossFork.Connell.0-15(8..15), HillTop.RossFork.Adona(4..5), HillTop.RossFork.Adona(6..13), HillTop.RossFork.Adona(14..21), HillTop.RossFork.Connell.16-23 ] + hit: [ _Redfield ] + miss: _Redfield + instruction: _Twain($DEFAULT, $DEFAULT) + actions: + Crannell(0, 24): + - default_action: { allowed: true } + - handle: 0x2000003c + - next_table: 0 + - set HillTop.Ovett.Hematite, 1 + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x2000003d + - next_table: 0 + default_only_action: NoAction + exact_match _Magasco 12: + p4: { name: Magasco, size: 8192, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Goldsboro: { type: exact, size: 24, full_size: 24, key_name: "RossFork.Goldsboro" } + HillTop.RossFork.Fabens: { type: exact, size: 24, full_size: 24, key_name: "RossFork.Fabens" } + HillTop.RossFork.CeeVee: { type: exact, size: 12, full_size: 12, key_name: "RossFork.CeeVee" } + HillTop.RossFork.Quebrada: { type: exact, size: 20, full_size: 20, key_name: "RossFork.Quebrada" } + row: [ 6, 7 ] + bus: [ 0, 0 ] + column: + - [ 6, 7, 8 ] + - [ 6, 7, 8 ] + stash: + row: [ 6, 7 ] + col: [ 6, 6 ] + unit: [ 0, 0 ] + ways: + - [3, 0, 0x1, [7, 6], [6, 6], [7, 7], [6, 7]] + - [3, 1, 0x0, [7, 8], [6, 8]] + input_xbar: + exact group 3: { 0: HillTop.RossFork.Quebrada, 24: HillTop.RossFork.Goldsboro.8-23(8..15), 32: HillTop.RossFork.Fabens, 56: HillTop.RossFork.CeeVee(8..11), 64: HillTop.RossFork.Goldsboro.0-7, 80: HillTop.RossFork.Goldsboro.8-23(0..7), 96: HillTop.RossFork.CeeVee(0..7) } + hash 6: + 8..9: random(HillTop.RossFork.Quebrada(0..15), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Fabens) + 0..3: random(HillTop.RossFork.Quebrada(0..15), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Fabens) ^ HillTop.RossFork.Quebrada(16..19) + 4..7: random(HillTop.RossFork.Quebrada(0..15), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Fabens) ^ HillTop.RossFork.CeeVee(8..11) + 40: random(HillTop.RossFork.Quebrada(0..15), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Fabens) + 10: random(HillTop.RossFork.Quebrada(0..15), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Fabens) + 19: random(HillTop.RossFork.Quebrada(0..15), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Fabens) + 11..14: random(HillTop.RossFork.Quebrada(0..15), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Fabens) ^ HillTop.RossFork.Quebrada(16..19) + 15..18: random(HillTop.RossFork.Quebrada(0..15), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Fabens) ^ HillTop.RossFork.CeeVee(8..11) + hash 7: + 0..7: random(HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(2..7), HillTop.RossFork.CeeVee(0..7)) + 8..9: random(HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(2..7), HillTop.RossFork.CeeVee(0..7)) ^ HillTop.RossFork.Goldsboro.8-23(0..1) + 40: random(HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(2..7), HillTop.RossFork.CeeVee(0..7)) + 11..18: random(HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(2..7), HillTop.RossFork.CeeVee(0..7)) + 19: random(HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(2..7), HillTop.RossFork.CeeVee(0..7)) ^ HillTop.RossFork.Goldsboro.8-23(0) + 10: random(HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(2..7), HillTop.RossFork.CeeVee(0..7)) ^ HillTop.RossFork.Goldsboro.8-23(1) + hash group 3: + table: [6, 7] + seed: 0x24a4e + format: { action(0): 0..1, version(0): 4..7, match(0): [74..79, 8..71 ], action(1): 2..3, version(1): 244..247, match(1): [218..223, 80..127, 200..215 ], action(2): 128..129, version(2): 240..243, match(2): 130..199 } + match: [ HillTop.RossFork.Goldsboro.8-23(2..7), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.CeeVee(0..7), HillTop.RossFork.Quebrada(0..7), HillTop.RossFork.Quebrada(8..15), HillTop.RossFork.Fabens(0..7), HillTop.RossFork.Fabens(8..15), HillTop.RossFork.Fabens(16..23), HillTop.RossFork.Goldsboro.0-7 ] + gateway: + name: cond-10 + input_xbar: + exact group 0: { 44: HillTop.Quinault.Foster, 88: HillTop.Lamona.Pachuta, 102: HillTop.RossFork.Welcome, 104: HillTop.RossFork.Teigen } + row: 1 + bus: 0 + unit: 0 + match: { 4: HillTop.Quinault.Foster, 8: HillTop.Lamona.Pachuta, 16: HillTop.RossFork.Teigen, 30: HillTop.RossFork.Welcome } + 0b*0*************0*******1**00: run_table + miss: _Boonsboro + condition: + expression: "(HillTop.Quinault.Foster == 0 && HillTop.Lamona.Pachuta == 1 && HillTop.RossFork.Teigen == 0 && HillTop.RossFork.Welcome == 0)" + true: _Magasco + false: _Boonsboro + hit: [ _Boonsboro ] + miss: _Boonsboro + instruction: _Magasco(action, $DEFAULT) + actions: + Swisshome(1, 0): + - default_action: { allowed: true } + - handle: 0x20000040 + - next_table: 0 + Earling(2, 21): + - default_action: { allowed: true } + - handle: 0x20000041 + - next_table: 0 + - set HillTop.Quinault.Foster, 2 + default_action: Earling + idletime: + row: 0 + bus: 0 + column: [ 0, 1, 2, 3, 4 ] + precision: 3 + sweep_interval: 7 + notification: two_way + per_flow_enable: true +stage 2 ingress: + hash_action _Redfield 0: + p4: { name: Redfield, size: 256, disable_atomic_modify : true } + p4_param_order: + HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } + row: 5 + bus: 1 + hash_dist: + 0: { hash: 0, mask: 0xff, shift: 5 } + input_xbar: + exact group 0: { 4: HillTop.Bessie.Miranda } + hash 0: + 0..7: stripe(HillTop.Bessie.Miranda) + hash group 0: + table: [0] + seed: 0x0 + gateway: + name: _Redfield-gateway + row: 3 + bus: 0 + unit: 1 + 0x0: _Covert + miss: _Covert + condition: + expression: "true(always hit)" + true: _Covert + false: _Covert + next: [] + action: _Redfield$action_data(hash_dist 0, $DEFAULT) + instruction: _Redfield($DEFAULT, $DEFAULT) + actions: + Rockfield(0, 1): + - p4_param_order: { Kaluaaha: 16, Calcasieu: 16, Chevak: 16, Mendocino: 16, LasVegas: 8, PineCity: 6, Exton: 8, Noyes: 8, Peebles: 1 } + - default_action: { allowed: true } + - handle: 0x20000044 + - next_table: 0 + - { Peebles: $adf_b0(5..5), Noyes: $adf_b1(0..7), LasVegas: $adf_b2(0..7), Exton: $adf_b3(0..7), Chevak: $adf_h2(0..15), Mendocino: $adf_h3(0..15), Calcasieu: $adf_h4(0..15), Kaluaaha: $adf_h5(0..15), PineCity: $adf_h6(6..11) } + - and HillTop.Savery.Kaluaaha, HillTop.Bessie.Kaluaaha, Kaluaaha + - and HillTop.Savery.Calcasieu, HillTop.Bessie.Calcasieu, Calcasieu + - and HillTop.Savery.Chevak, HillTop.Bessie.Chevak, Chevak + - and HillTop.Savery.Mendocino, HillTop.Bessie.Mendocino, Mendocino + - and HillTop.Savery.LasVegas, HillTop.Bessie.LasVegas, LasVegas + - and HillTop.Savery.Exton, HillTop.Bessie.Exton, Exton + - and HillTop.Savery.Noyes, HillTop.Bessie.Noyes, Noyes + - set Millston.Belgrade.Florin.0-15, 0 + - and B10, Peebles, B9 + - and H85, PineCity, H90 + default_action: Rockfield + default_action_parameters: + Kaluaaha: "0xffff" + Calcasieu: "0xffff" + Chevak: "0xffff" + Mendocino: "0xffff" + LasVegas: "0xff" + PineCity: "0x3f" + Exton: "0xff" + Noyes: "0xff" + Peebles: "0x1" + action _Redfield$action_data: + p4: { name: Redfield$action, how_referenced: direct } + row: 12 + column: 4 + vpns: [ 0 ] + home_row: + - 12 + format Rockfield: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_b2: 16..23, $adf_b3: 24..31, $adf_h2: 32..47, $adf_h3: 48..63, $adf_h4: 64..79, $adf_h5: 80..95, $adf_h6: 96..111 } + action_bus: { 16 : $adf_b0, 17 : $adf_b1, 18 : $adf_b2, 19 : $adf_b3, 64..65 : $adf_h4, 66..67 : $adf_h5, 68..69 : $adf_h6, 32..33 : $adf_h2, 34..35 : $adf_h3 } + hash_action _Covert 1: + p4: { name: Covert, size: 4096, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.CeeVee: { type: exact, size: 12, full_size: 12, key_name: "RossFork.CeeVee" } + row: 4 + bus: 1 + hash_dist: + 1: { hash: 0, mask: 0xfff, shift: 2 } + input_xbar: + exact group 0: { 16: HillTop.RossFork.CeeVee } + hash 0: + 16..27: stripe(HillTop.RossFork.CeeVee) + hash group 0: + table: [0] + seed: 0x0 + gateway: + name: _Covert-gateway + row: 2 + bus: 0 + unit: 1 + 0x0: _Bucklin + miss: _Bucklin + condition: + expression: "true(always hit)" + true: _Bucklin + false: _Bucklin + next: [] + action: _Covert$action_data(hash_dist 1, $DEFAULT) + instruction: _Covert($DEFAULT, $DEFAULT) + actions: + Terral(0, 2): + - p4_param_order: { Brinkman: 1, HighRock: 1, WebbCity: 1 } + - default_action: { allowed: true } + - handle: 0x20000047 + - next_table: 0 + - { HighRock: $adf_h0(0..0), Brinkman: $adf_b0(1..1) } + - set HillTop.RossFork.Brinkman, Brinkman + - set HillTop.RossFork.Parkland, HighRock + default_action: Terral + default_action_parameters: + Brinkman: "0x0" + HighRock: "0x0" + WebbCity: "0x0" + action _Covert$action_data: + p4: { name: Covert$action, how_referenced: direct } + row: 14 + column: 4 + vpns: [ 0 ] + home_row: + - 14 + format Terral: { $adf_h0: 0..15, $adf_b0: 0..7 } + action_bus: { 0 : $adf_b0, 36..37 : $adf_h0 } + hash_action _Bucklin 2: + p4: { name: Bucklin, size: 1, disable_atomic_modify : true } + row: 0 + bus: 1 + hash_dist: + 2: { hash: 0, mask: 0xffff, shift: 0 } + input_xbar: + exact group 0: { 32: Millston.Maumee.Kaluaaha.32-63, 64: Millston.Maumee.Calcasieu.96-127, 96: Millston.Maumee.Kaluaaha.0-31 } + exact group 1: { 0: Millston.Maumee.Kaluaaha.64-95, 32: Millston.Maumee.Kaluaaha.96-127, 64: Millston.Maumee.Calcasieu.0-31, 96: Millston.Maumee.Calcasieu.32-63 } + exact group 2: { 0: Millston.Maumee.Calcasieu.64-95, 32: Millston.Maumee.Maryhill.0-15, 48: Millston.Maumee.Maryhill.16-19, 56: Millston.Maumee.Dassel } + hash 0: + 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 188: Millston.Maumee.Kaluaaha.32-63 }, { })), 0..15) + hash 1: + 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 124: Millston.Maumee.Calcasieu.96-127, 156: Millston.Maumee.Kaluaaha.0-31 }, { })), 0..15) + hash 2: + 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 220: Millston.Maumee.Kaluaaha.64-95, 252: Millston.Maumee.Kaluaaha.96-127 }, { })), 0..15) + hash 3: + 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 28: Millston.Maumee.Calcasieu.0-31, 60: Millston.Maumee.Calcasieu.32-63 }, { })), 0..15) + hash 4: + 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 0: Millston.Maumee.Dassel, 8: Millston.Maumee.Maryhill.0-15, 24: Millston.Maumee.Maryhill.16-19, 92: Millston.Maumee.Calcasieu.64-95 }, { })), 0..15) + hash group 0: + table: [0, 1, 2, 3, 4] + seed: 0x0 + gateway: + name: cond-11 + input_xbar: + exact group 2: { 68: Millston.GlenAvon.$valid } + row: 0 + bus: 1 + unit: 0 + payload: 0x1 + format: { action: 0..0 } + match: { 4: Millston.GlenAvon.$valid } + 0b***1: run_table + miss: _Forepaugh + condition: + expression: "(Millston.GlenAvon.$valid == 1)" + true: _Decherd + false: _Forepaugh + next: _Decherd + action_bus: { 40..41 : hash_dist(2, lo) } + instruction: _Bucklin(action, $DEFAULT) + actions: + McKenney(1, 3): + - default_action: { allowed: true } + - handle: 0x20000046 + - next_table: 0 + - set H59, hash_dist(2, 0..15) + default_action: McKenney + hash_action _Decherd 3: + p4: { name: Decherd, size: 1, disable_atomic_modify : true } + row: 3 + bus: 1 + hash_dist: + 3: { hash: 1, mask: 0xffff, shift: 0 } + input_xbar: + exact group 3: { 0: Millston.GlenAvon.Kaluaaha, 32: Millston.GlenAvon.Calcasieu, 64: Millston.GlenAvon.Ocoee } + hash 6: + 0..15: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 72, { 0: Millston.GlenAvon.Calcasieu, 32: Millston.GlenAvon.Kaluaaha }, { })), 0..15) + hash 7: + 0..15: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 72, { 64: Millston.GlenAvon.Ocoee }, { })), 0..15) + hash group 1: + table: [6, 7] + seed: 0x0 + gateway: + name: _Decherd-gateway + row: 1 + bus: 0 + unit: 1 + 0x0: _Forepaugh + miss: _Forepaugh + condition: + expression: "true(always hit)" + true: _Forepaugh + false: _Forepaugh + next: [] + action_bus: { 44..45 : hash_dist(3, lo) } + instruction: _Decherd($DEFAULT, $DEFAULT) + actions: + Kellner(0, 4): + - default_action: { allowed: true } + - handle: 0x20000045 + - next_table: 0 + - set H59, hash_dist(3, 0..15) + default_action: Kellner + hash_action _Forepaugh 4: + p4: { name: Forepaugh, size: 1, disable_atomic_modify : true } + row: 2 + bus: 1 + hash_dist: + 4: { hash: 1, mask: 0xffff, shift: 0 } + input_xbar: + exact group 4: { 0: Millston.Shirley.Connell.16-23, 8: Millston.Shirley.Adona, 32: Millston.Shirley.Connell.0-15, 48: Millston.Shirley.Goldsboro.8-23, 64: Millston.Shirley.Fabens.8-23, 80: Millston.Shirley.McCaulley, 96: Millston.Shirley.Goldsboro.0-7, 104: Millston.Shirley.Fabens.0-7 } + hash 8: + 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 112, { 48: Millston.Shirley.Goldsboro.8-23, 64: Millston.Shirley.Connell.0-15, 80: Millston.Shirley.Connell.16-23, 88: Millston.Shirley.Adona }, { })), 0..15) + hash 9: + 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 112, { 0: Millston.Shirley.McCaulley, 16: Millston.Shirley.Fabens.0-7, 24: Millston.Shirley.Fabens.8-23, 40: Millston.Shirley.Goldsboro.0-7 }, { })), 0..15) + hash group 1: + table: [8, 9] + seed: 0x0 + gateway: + name: _Forepaugh-gateway + row: 0 + bus: 0 + unit: 1 + 0x0: cond-12 + miss: cond-12 + condition: + expression: "true(always hit)" + true: cond-12 + false: cond-12 + next: [] + action_bus: { 48..49 : hash_dist(4, lo) } + instruction: _Forepaugh($DEFAULT, $DEFAULT) + actions: + SanPablo(0, 5): + - default_action: { allowed: true } + - handle: 0x20000057 + - next_table: 0 + - set H58, hash_dist(4, 0..15) + default_action: SanPablo + gateway cond-12 5: + name: cond-12 + input_xbar: + exact group 2: { 77: HillTop.Ovett.Hematite, 85: HillTop.RossFork.Weyauwega, 94: HillTop.Murphy.Blairsden, 99: HillTop.Murphy.Standish } + row: 3 + bus: 1 + unit: 0 + match: { 5: HillTop.RossFork.Weyauwega, 13: HillTop.Ovett.Hematite, 19: HillTop.Murphy.Standish, 30: HillTop.Murphy.Blairsden } + 0b*0**********0*****1*******0: _Levasy$st0 + miss: _Bigspring + condition: + expression: "(HillTop.RossFork.Weyauwega == 0 && HillTop.Ovett.Hematite == 1 && HillTop.Murphy.Standish == 0 && HillTop.Murphy.Blairsden == 0)" + true: _Levasy$st0 + false: _Bigspring + ternary_match _Levasy$st0 6: + p4: { name: Levasy, size: 4096, disable_atomic_modify : true } + p4_param_order: + HillTop.Ovett.Manilla: { type: exact, size: 8, full_size: 8, key_name: "Ovett.Manilla" } + HillTop.Sublett.Calcasieu: { type: lpm, size: 128, full_size: 128, key_name: "Sublett.Calcasieu" } + row: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + input_xbar: + ternary group 0: { 0: HillTop.Sublett.Calcasieu.96-127(0..7), 8: HillTop.Sublett.Calcasieu.0-31(8..15), 16: HillTop.Sublett.Calcasieu.96-127(16..31), 32: HillTop.Sublett.Calcasieu.0-31(0..7) } + ternary group 1: { 0: HillTop.Sublett.Calcasieu.0-31(16..31), 16: HillTop.Sublett.Calcasieu.32-63(0..23) } + ternary group 2: { 0: HillTop.Sublett.Calcasieu.32-63(24..31), 8: HillTop.Sublett.Calcasieu.64-95 } + ternary group 3: { 0: HillTop.Ovett.Manilla } + byte group 0: { 0: HillTop.Sublett.Calcasieu.96-127(8..15) } + match: + - { group: 0, byte_group: 0, byte_config: 0, dirtcam: 0x555 } + - { group: 1, byte_group: 0, byte_config: 1, dirtcam: 0x555 } + - { group: 2, byte_config: 3, dirtcam: 0x155 } + - { group: 3, dirtcam: 0x1 } + gateway: + name: cond-13 + input_xbar: + exact group 5: { 5: HillTop.RossFork.Naruna.2-2, 8: HillTop.Ovett.Hammond.1-3(0), 19: HillTop.RossFork.Naruna.0-1 } + row: 2 + bus: 1 + unit: 0 + match: { 16: HillTop.Ovett.Hammond.1-3(0), 3: HillTop.RossFork.Naruna.0-1, 13: HillTop.RossFork.Naruna.2-2 } + 0b*******1**0********10: run_table + miss: _Glenoma_0 + condition: + expression: "(HillTop.Ovett.Hammond & 2 == 2 && HillTop.RossFork.Naruna == 2)" + true: _Levasy$st0 + false: _Glenoma_0 + hit: [ _Bigspring ] + miss: _Levasy$st1 + indirect: _Levasy$st0$tind + idletime: + row: 0 + bus: 0 + column: 0 + precision: 1 + sweep_interval: 7 + notification: enable + per_flow_enable: false + ternary_indirect _Levasy$st0$tind: + row: 0 + bus: 0 + column: 4 + input_xbar: + ternary group 0: { 0: HillTop.Sublett.Calcasieu.96-127(0..7), 8: HillTop.Sublett.Calcasieu.0-31(8..15), 16: HillTop.Sublett.Calcasieu.96-127(16..31), 32: HillTop.Sublett.Calcasieu.0-31(0..7) } + ternary group 1: { 0: HillTop.Sublett.Calcasieu.0-31(16..31), 16: HillTop.Sublett.Calcasieu.32-63(0..23) } + ternary group 2: { 0: HillTop.Sublett.Calcasieu.32-63(24..31), 8: HillTop.Sublett.Calcasieu.64-95 } + ternary group 3: { 0: HillTop.Ovett.Manilla } + byte group 0: { 0: HillTop.Sublett.Calcasieu.96-127(8..15) } + format: { action: 0..2, immediate: 3..16 } + action_bus: { 52..53 : immediate(0..13) } + instruction: _Levasy$st0$tind(action, $DEFAULT) + actions: + Tofte(1, 6): + - p4_param_order: { Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x20000048 + - next_table: 0 + - { Bonduel: immediate(0..13) } + - set HillTop.Naubinway.Bonduel, Bonduel + Jerico(2, 8): + - p4_param_order: { Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x20000049 + - next_table: 0 + - { Bonduel: immediate(0..13) } + - set HillTop.Naubinway.Ayden, 2 + - set HillTop.Naubinway.Bonduel, Bonduel + Wabbaseka(3, 10): + - p4_param_order: { Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x2000004a + - next_table: 0 + - { Bonduel: immediate(0..13) } + - set HillTop.Naubinway.Ayden, 3 + - set HillTop.Naubinway.Bonduel, Bonduel + Clearmont(4, 12): + - p4_param_order: { Sardinia: 14 } + - default_action: { allowed: true } + - handle: 0x2000004b + - next_table: 0 + - { Sardinia: immediate(0..13) } + - set HillTop.Naubinway.Sardinia, Sardinia + - set HillTop.Naubinway.Ayden, 1 + Ponder(-1, 14): + - default_only_action: { allowed: true } + - handle: 0x2000004c + - next_table: 0 + - { } + - set HillTop.Naubinway.Bonduel, 1 + default_only_action: Ponder + exact_match _Glenoma_0 7: + p4: { name: Glenoma, size: 97280, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Ocoee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } + HillTop.RossFork.Laxon: { type: exact, size: 32, full_size: 32, key_name: "RossFork.Laxon" } + HillTop.RossFork.Crozet: { type: exact, size: 16, full_size: 16, key_name: "RossFork.Crozet" } + HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } + Millston.Grays.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Grays.Mendocino" } + row: [ 6, 7, 4, 5, 2, 3, 0, 1 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 6, 7, 8, 9, 10 ] + - [ 2, 3, 6, 7, 8, 9, 10 ] + - [ 2, 3, 6, 7, 8, 9, 10 ] + - [ 2, 3, 6, 7, 8, 9, 10 ] + - [ 2, 3, 6, 7, 8, 9, 10 ] + - [ 2, 3, 6, 7, 8, 9, 10 ] + - [ 2, 3, 6, 7 ] + - [ 2, 3, 6, 7 ] + stash: + row: [ 6, 7 ] + col: [ 2, 2 ] + unit: [ 0, 0 ] + ways: + - [2, 0, 0x3, [7, 2], [6, 2], [7, 3], [6, 3], [7, 6], [6, 6], [7, 7], [6, 7]] + - [2, 1, 0xc, [7, 8], [6, 8], [7, 9], [6, 9], [7, 10], [6, 10], [5, 2], [4, 2]] + - [2, 2, 0x30, [5, 3], [4, 3], [5, 6], [4, 6], [5, 7], [4, 7], [5, 8], [4, 8]] + - [2, 3, 0xc0, [5, 9], [4, 9], [5, 10], [4, 10], [3, 2], [2, 2], [3, 3], [2, 3]] + - [2, 0, 0x3, [3, 6], [2, 6], [3, 7], [2, 7], [3, 8], [2, 8], [3, 9], [2, 9]] + - [2, 1, 0xc, [3, 10], [2, 10], [1, 2], [0, 2], [1, 3], [0, 3], [1, 6], [0, 6]] + - [2, 2, 0x0, [1, 7], [0, 7]] + input_xbar: + exact group 6: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.RossFork.Laxon, 64: Millston.Grays.Mendocino, 80: HillTop.RossFork.Crozet, 96: HillTop.RossFork.Ocoee } + hash 12: + 0..9: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 40..41: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 10..19: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 42..43: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 20..29: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 44..45: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 30..39: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 46..47: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + hash 13: + 0..1: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) + 2..9: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee + 40..41: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) + 11..12: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) + 13..19: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..6) + 10: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(7) + 42..43: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) + 22..23: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) + 24..29: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..5) + 20..21: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(6..7) + 44..45: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) + 33..34: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) + 35..39: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..4) + 30..32: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(5..7) + 46..47: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) + hash group 2: + table: [12, 13] + seed: 0x22703fbf7838 + format: { action(0): 0..2, immediate(0): 3..16, version(0): 112..115, match(0): [18..23, 32..111, 24..31 ], action(1): 128..130, immediate(1): 131..144, version(1): 240..243, match(1): [146..151, 160..239, 152..159 ] } + match: [ Millston.Grays.Mendocino(2..7), Millston.Grays.Mendocino(8..15), HillTop.RossFork.Crozet(0..7), HillTop.RossFork.Crozet(8..15), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31), HillTop.RossFork.Laxon(0..7), HillTop.RossFork.Laxon(8..15), HillTop.RossFork.Laxon(16..23), HillTop.RossFork.Laxon(24..31) ] + gateway: + name: cond-14 + input_xbar: + exact group 5: { 5: HillTop.RossFork.Naruna.2-2, 11: HillTop.Ovett.Hammond.0-0, 19: HillTop.RossFork.Naruna.0-1 } + row: 1 + bus: 1 + unit: 0 + match: { 19: HillTop.Ovett.Hammond.0-0, 3: HillTop.RossFork.Naruna.0-1, 13: HillTop.RossFork.Naruna.2-2 } + 0b****1*****0********01: run_table + miss: _Indios + condition: + expression: "(HillTop.Ovett.Hammond & 1 == 1 && HillTop.RossFork.Naruna == 1)" + true: _Glenoma_0 + false: _Indios + hit: [ [], _Bigspring, _Bigspring, _Bigspring, _Bigspring, _Bigspring, _Bigspring, _Baker_0 ] + miss: _Glenoma_0$st1 + action_bus: { 56..57 : immediate(0..13) } + action: _Glenoma_0$action_data($DIRECT, $DEFAULT) + instruction: _Glenoma_0(action, $DEFAULT) + actions: + Callao(1, 16): + - p4_param_order: { Calcasieu: 32, Bratt: 32, Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x2000004d + - next_table: 1 + - { Bratt.0-15: $adf_f0(0..15), Bonduel: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Bonduel, Bonduel + - set HillTop.RossFork.Suttle, 1 + Ambler(2, 18): + - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x2000004e + - next_table: 2 + - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Bonduel: immediate(0..13) } + - set HillTop.RossFork.DonaAna, Avondale + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Bonduel, Bonduel + - set HillTop.RossFork.Suttle, 1 + Wagener(3, 20): + - p4_param_order: { Calcasieu: 32, Bratt: 32, Sardinia: 14 } + - default_action: { allowed: true } + - handle: 0x2000004f + - next_table: 3 + - { Bratt.0-15: $adf_f0(0..15), Sardinia: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 1 + - set HillTop.Naubinway.Sardinia, Sardinia + - set HillTop.RossFork.Suttle, 1 + Olmitz(4, 22): + - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Sardinia: 14 } + - default_action: { allowed: true } + - handle: 0x20000050 + - next_table: 4 + - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Sardinia: immediate(0..13) } + - set HillTop.RossFork.DonaAna, Avondale + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 1 + - set HillTop.Naubinway.Sardinia, Sardinia + - set HillTop.RossFork.Suttle, 1 + Milano(5, 7): + - p4_param_order: { Kaluaaha: 32, Bratt: 32 } + - default_action: { allowed: true } + - handle: 0x20000051 + - next_table: 5 + - { Kaluaaha: $adf_f0(0..31), Bratt.0-15: $adf_f1(0..15) } + - set HillTop.Maddock.Kaluaaha, Kaluaaha + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Boerne, 1 + - set HillTop.RossFork.Suttle, 1 + Biggers(6, 9): + - p4_param_order: { Kaluaaha: 32, Avondale: 16, Bratt: 32 } + - default_action: { allowed: true } + - handle: 0x20000052 + - next_table: 6 + - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Kaluaaha: $adf_f1(0..31) } + - set HillTop.RossFork.Glenmora, Avondale + - set HillTop.Maddock.Kaluaaha, Kaluaaha + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Boerne, 1 + - set HillTop.RossFork.Suttle, 1 + Sequim(7, 0): + - default_action: { allowed: true } + - handle: 0x20000053 + - next_table: 7 + - { } + default_action: Sequim + idletime: + row: [ 4, 5 ] + bus: [ 0, 0 ] + column: + - [ 0, 1, 2, 3, 4, 5 ] + - 0 + precision: 1 + sweep_interval: 7 + notification: enable + per_flow_enable: false + action _Glenoma_0$action_data: + p4: { name: Glenoma$action } + row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ] + word: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - 5 + - 5 + - 5 + - 5 + - 5 + - [ 4, 5 ] + - 5 + - [ 4, 5 ] + - 5 + - [ 4, 5 ] + - 5 + - [ 4, 5 ] + - [ 4, 5 ] + - [ 4, 5 ] + - [ 2, 3, 4, 5 ] + - 5 + vpns: + - [ 0 ] + - [ 1 ] + - [ 2 ] + - [ 3 ] + - [ 4 ] + - [ 5, 6 ] + - [ 7 ] + - [ 8, 9 ] + - [ 10 ] + - [ 11, 12 ] + - [ 13 ] + - [ 14, 15 ] + - [ 16, 17 ] + - [ 18, 19 ] + - [ 20, 21, 22, 23 ] + - [ 24 ] + home_row: + - [ 15, 3 ] + format Callao: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + format Ambler: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + format Wagener: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + format Olmitz: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + format Milano: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Biggers: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + action_bus: { 62..63 : $adf_h1, 100..103 : $adf_f1, 60..63 : $adf_f0 } +stage 3 ingress: + exact_match _Indios 3: + p4: { name: Indios, size: 2, disable_atomic_modify : true } + p4_param_order: + HillTop.Ovett.Hammond: { type: exact, size: 1, full_size: 4, key_name: "Ovett.Hammond" } + HillTop.RossFork.Naruna: { type: exact, size: 3, full_size: 3, key_name: "RossFork.Naruna" } + row: 1 + bus: 1 + column: 7 + stash: + row: [ 1 ] + col: [ 7 ] + unit: [ 0 ] + ways: + - [1, 0, 0x0, [1, 7]] + input_xbar: + exact group 1: { 5: HillTop.RossFork.Naruna.2-2, 11: HillTop.Ovett.Hammond.0-0, 19: HillTop.RossFork.Naruna.0-1 } + hash 2: + 0: HillTop.RossFork.Naruna.2-2 + 1: HillTop.Ovett.Hammond.0-0 + 2..3: HillTop.RossFork.Naruna.0-1 + hash group 1: + table: [2] + seed: 0x0 + format: { action(0): 0..0, immediate(0): 1..14, version(0): 112..115 } + gateway: + name: cond-15 + input_xbar: + exact group 1: { 5: HillTop.RossFork.Naruna.2-2, 11: HillTop.Ovett.Hammond.0-0, 19: HillTop.RossFork.Naruna.0-1, 32: HillTop.Wisdom.Havana, 49: HillTop.RossFork.Parkland } + hash 2: + 40: HillTop.Ovett.Hammond.0-0 + hash group 1: + table: [2] + seed: 0x0 + row: 0 + bus: 0 + unit: 0 + match: { 16: HillTop.Wisdom.Havana, 25: HillTop.RossFork.Parkland, 32: HillTop.Ovett.Hammond.0-0, 3: HillTop.RossFork.Naruna.0-1, 13: HillTop.RossFork.Naruna.2-2 } + 0b*******1********0*************: run_table + 0b1***************0**0********11: run_table + miss: _Bigspring + condition: + expression: "(HillTop.Wisdom.Havana == 0 && (HillTop.RossFork.Parkland == 1 || HillTop.Ovett.Hammond & 1 == 1 && HillTop.RossFork.Naruna == 3))" + true: _Indios + false: _Bigspring + hit: [ _Bigspring ] + miss: _Bigspring + action_bus: { 44..45 : immediate(0..13) } + instruction: _Indios(action, $DEFAULT) + actions: + Fishers(1, 18): + - p4_param_order: { Philip: 14 } + - default_action: { allowed: true } + - handle: 0x20000056 + - next_table: 0 + - { Philip: immediate(0..13) } + - set HillTop.Naubinway.Bonduel, Philip + default_action: Fishers + default_action_parameters: + Philip: "0x0" + ternary_match _Baker_0 2: + p4: { name: Baker, size: 4096, disable_atomic_modify : true } + p4_param_order: + HillTop.Maddock.Kaluaaha: { type: ternary, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } + HillTop.RossFork.Ocoee: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } + HillTop.Bessie.Peebles: { type: ternary, size: 1, full_size: 1, key_name: "Bessie.Peebles" } + row: [ 8, 9, 10, 11, 0, 1, 2, 3 ] + bus: [ 0, 0, 0, 0, 1, 1, 1, 1 ] + column: + - 0 + - 0 + - 0 + - 0 + - 1 + - 1 + - 1 + - 1 + input_xbar: + ternary group 4: { 0: HillTop.Maddock.Kaluaaha(16..31), 16: HillTop.Maddock.Kaluaaha(0..15), 32: HillTop.RossFork.Ocoee } + byte group 1: { 5: HillTop.Bessie.Peebles } + match: + - { group: 4, byte_group: 1, byte_config: 1, dirtcam: 0x555 } + hit: [ _Bigspring ] + miss: _Bigspring + indirect: _Baker_0$tind + ternary_indirect _Baker_0$tind: + row: 0 + bus: 1 + column: 4 + input_xbar: + ternary group 4: { 0: HillTop.Maddock.Kaluaaha(16..31), 16: HillTop.Maddock.Kaluaaha(0..15), 32: HillTop.RossFork.Ocoee } + byte group 1: { 5: HillTop.Bessie.Peebles } + format: { action: 0..0, immediate: 1..12 } + action_bus: { 104..107 : immediate(0..11) } + instruction: _Baker_0$tind(action, $DEFAULT) + actions: + Recluse(0, 3): + - p4_param_order: { Moultrie: 12 } + - default_action: { allowed: true } + - handle: 0x20000054 + - next_table: 0 + - { Moultrie: immediate(0..11) } + - set HillTop.RossFork.Knierim, Moultrie + Arapahoe(1, 0): + - default_action: { allowed: true } + - handle: 0x20000055 + - next_table: 0 + - { } + default_action: Arapahoe + exact_match _Glenoma_0$st1 0: + p4: { name: Glenoma, size: 97280, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Ocoee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } + HillTop.RossFork.Laxon: { type: exact, size: 32, full_size: 32, key_name: "RossFork.Laxon" } + HillTop.RossFork.Crozet: { type: exact, size: 16, full_size: 16, key_name: "RossFork.Crozet" } + HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } + Millston.Grays.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Grays.Mendocino" } + row: [ 6, 7, 4, 5, 2, 3 ] + bus: [ 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 6, 7, 8, 9, 10 ] + - [ 2, 3, 6, 7, 8, 9, 10 ] + stash: + row: [ 6, 7 ] + col: [ 2, 2 ] + unit: [ 0, 0 ] + ways: + - [0, 0, 0x3, [7, 2], [6, 2], [7, 3], [6, 3], [7, 6], [6, 6], [7, 7], [6, 7]] + - [0, 1, 0xc, [7, 8], [6, 8], [7, 9], [6, 9], [7, 10], [6, 10], [7, 11], [6, 11]] + - [0, 2, 0x30, [5, 2], [4, 2], [5, 3], [4, 3], [5, 6], [4, 6], [5, 7], [4, 7]] + - [0, 3, 0xc0, [5, 8], [4, 8], [5, 9], [4, 9], [5, 10], [4, 10], [5, 11], [4, 11]] + - [0, 0, 0x3, [3, 2], [2, 2], [3, 3], [2, 3], [3, 6], [2, 6], [3, 7], [2, 7]] + - [0, 1, 0x4, [3, 8], [2, 8], [3, 9], [2, 9]] + - [0, 2, 0x0, [3, 10], [2, 10]] + input_xbar: + exact group 0: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.RossFork.Laxon, 64: Millston.Grays.Mendocino, 80: HillTop.RossFork.Crozet, 96: HillTop.RossFork.Ocoee } + hash 0: + 0..9: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 40..41: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 10..19: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 42..43: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 20..29: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 44..45: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 30..39: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 46..47: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + hash 1: + 0..1: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) + 2..9: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee + 40..41: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) + 11..12: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) + 13..19: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..6) + 10: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(7) + 42..43: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) + 22..23: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) + 24..29: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..5) + 20..21: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(6..7) + 44..45: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) + 33..34: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) + 35..39: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..4) + 30..32: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(5..7) + 46..47: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) + hash group 0: + table: [0, 1] + seed: 0x2db23bf76022 + format: { action(0): 0..2, immediate(0): 3..16, version(0): 112..115, match(0): [18..23, 32..111, 24..31 ], action(1): 128..130, immediate(1): 131..144, version(1): 240..243, match(1): [146..151, 160..239, 152..159 ] } + match: [ Millston.Grays.Mendocino(2..7), Millston.Grays.Mendocino(8..15), HillTop.RossFork.Crozet(0..7), HillTop.RossFork.Crozet(8..15), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31), HillTop.RossFork.Laxon(0..7), HillTop.RossFork.Laxon(8..15), HillTop.RossFork.Laxon(16..23), HillTop.RossFork.Laxon(24..31) ] + hit: [ _Bigspring, _Bigspring, _Bigspring, _Bigspring, _Bigspring, _Bigspring, _Baker_0 ] + miss: _Bigspring + action_bus: { 32..33 : immediate(0..13) } + action: _Glenoma_0$st1$action_data($DIRECT, $DEFAULT) + instruction: _Glenoma_0$st1(action, $DEFAULT) + actions: + Callao(0, 1): + - p4_param_order: { Calcasieu: 32, Bratt: 32, Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x2000004d + - next_table: 0 + - { Bratt.0-15: $adf_f0(0..15), Bonduel: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Bonduel, Bonduel + - set HillTop.RossFork.Suttle, 1 + Ambler(1, 2): + - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x2000004e + - next_table: 1 + - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Bonduel: immediate(0..13) } + - set HillTop.RossFork.DonaAna, Avondale + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Bonduel, Bonduel + - set HillTop.RossFork.Suttle, 1 + Wagener(2, 4): + - p4_param_order: { Calcasieu: 32, Bratt: 32, Sardinia: 14 } + - default_action: { allowed: true } + - handle: 0x2000004f + - next_table: 2 + - { Bratt.0-15: $adf_f0(0..15), Sardinia: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 1 + - set HillTop.Naubinway.Sardinia, Sardinia + - set HillTop.RossFork.Suttle, 1 + Olmitz(3, 6): + - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Sardinia: 14 } + - default_action: { allowed: true } + - handle: 0x20000050 + - next_table: 3 + - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Sardinia: immediate(0..13) } + - set HillTop.RossFork.DonaAna, Avondale + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 1 + - set HillTop.Naubinway.Sardinia, Sardinia + - set HillTop.RossFork.Suttle, 1 + Milano(4, 8): + - p4_param_order: { Kaluaaha: 32, Bratt: 32 } + - default_action: { allowed: true } + - handle: 0x20000051 + - next_table: 4 + - { Kaluaaha: $adf_f0(0..31), Bratt.0-15: $adf_f1(0..15) } + - set HillTop.Maddock.Kaluaaha, Kaluaaha + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Boerne, 1 + - set HillTop.RossFork.Suttle, 1 + Biggers(5, 10): + - p4_param_order: { Kaluaaha: 32, Avondale: 16, Bratt: 32 } + - default_action: { allowed: true } + - handle: 0x20000052 + - next_table: 5 + - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Kaluaaha: $adf_f1(0..31) } + - set HillTop.RossFork.Glenmora, Avondale + - set HillTop.Maddock.Kaluaaha, Kaluaaha + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Boerne, 1 + - set HillTop.RossFork.Suttle, 1 + Sequim(6, 0): + - default_action: { allowed: true } + - handle: 0x20000053 + - next_table: 6 + - { } + default_action: Sequim + idletime: + row: 4 + bus: 0 + column: [ 0, 1, 2, 3, 4, 5 ] + precision: 1 + sweep_interval: 7 + notification: enable + per_flow_enable: false + action _Glenoma_0$st1$action_data: + p4: { name: Glenoma$action } + row: [ 14, 12, 10, 8, 6, 5, 4, 3, 2, 1, 0 ] + word: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - [ 4, 5 ] + - 5 + - 5 + - [ 4, 5 ] + - [ 4, 5 ] + - 5 + - [ 4, 5 ] + - [ 2, 3, 4, 5 ] + - 5 + - [ 0, 1, 2, 3, 4, 5 ] + - 5 + vpns: + - [ 0, 1 ] + - [ 2 ] + - [ 3 ] + - [ 4, 5 ] + - [ 6, 7 ] + - [ 8 ] + - [ 9, 10 ] + - [ 11, 12, 13, 14 ] + - [ 15 ] + - [ 16, 17, 18, 19, 20, 21 ] + - [ 22 ] + home_row: + - [ 14, 3 ] + format Callao: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + format Ambler: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + format Wagener: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + format Olmitz: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + format Milano: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Biggers: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + action_bus: { 38..39 : $adf_h1, 100..103 : $adf_f1, 36..39 : $adf_f0 } + ternary_match _Levasy$st1 1: + p4: { name: Levasy, size: 4096, disable_atomic_modify : true } + p4_param_order: + HillTop.Ovett.Manilla: { type: exact, size: 8, full_size: 8, key_name: "Ovett.Manilla" } + HillTop.Sublett.Calcasieu: { type: lpm, size: 128, full_size: 128, key_name: "Sublett.Calcasieu" } + row: [ 0, 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + input_xbar: + ternary group 0: { 0: HillTop.Sublett.Calcasieu.96-127(0..7), 8: HillTop.Sublett.Calcasieu.0-31(8..15), 16: HillTop.Sublett.Calcasieu.96-127(16..31), 32: HillTop.Sublett.Calcasieu.0-31(0..7) } + ternary group 1: { 0: HillTop.Sublett.Calcasieu.0-31(16..31), 16: HillTop.Sublett.Calcasieu.32-63(0..23) } + ternary group 2: { 0: HillTop.Sublett.Calcasieu.32-63(24..31), 8: HillTop.Sublett.Calcasieu.64-95 } + ternary group 3: { 0: HillTop.Ovett.Manilla } + byte group 0: { 0: HillTop.Sublett.Calcasieu.96-127(8..15) } + match: + - { group: 0, byte_group: 0, byte_config: 0, dirtcam: 0x555 } + - { group: 1, byte_group: 0, byte_config: 1, dirtcam: 0x555 } + - { group: 2, byte_config: 3, dirtcam: 0x155 } + - { group: 3, dirtcam: 0x1 } + hit: [ _Bigspring ] + miss: _Bigspring + indirect: _Levasy$st1$tind + idletime: + row: 0 + bus: 0 + column: 0 + precision: 1 + sweep_interval: 7 + notification: enable + per_flow_enable: false + ternary_indirect _Levasy$st1$tind: + row: 1 + bus: 0 + column: 4 + input_xbar: + ternary group 0: { 0: HillTop.Sublett.Calcasieu.96-127(0..7), 8: HillTop.Sublett.Calcasieu.0-31(8..15), 16: HillTop.Sublett.Calcasieu.96-127(16..31), 32: HillTop.Sublett.Calcasieu.0-31(0..7) } + ternary group 1: { 0: HillTop.Sublett.Calcasieu.0-31(16..31), 16: HillTop.Sublett.Calcasieu.32-63(0..23) } + ternary group 2: { 0: HillTop.Sublett.Calcasieu.32-63(24..31), 8: HillTop.Sublett.Calcasieu.64-95 } + ternary group 3: { 0: HillTop.Ovett.Manilla } + byte group 0: { 0: HillTop.Sublett.Calcasieu.96-127(8..15) } + format: { action: 0..1, immediate: 2..15 } + action_bus: { 40..41 : immediate(0..13) } + instruction: _Levasy$st1$tind(action, $DEFAULT) + actions: + Tofte(0, 9): + - p4_param_order: { Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x20000048 + - next_table: 0 + - { Bonduel: immediate(0..13) } + - set HillTop.Naubinway.Bonduel, Bonduel + Jerico(1, 11): + - p4_param_order: { Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x20000049 + - next_table: 0 + - { Bonduel: immediate(0..13) } + - set HillTop.Naubinway.Ayden, 2 + - set HillTop.Naubinway.Bonduel, Bonduel + Wabbaseka(2, 12): + - p4_param_order: { Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x2000004a + - next_table: 0 + - { Bonduel: immediate(0..13) } + - set HillTop.Naubinway.Ayden, 3 + - set HillTop.Naubinway.Bonduel, Bonduel + Clearmont(3, 14): + - p4_param_order: { Sardinia: 14 } + - default_action: { allowed: true } + - handle: 0x2000004b + - next_table: 0 + - { Sardinia: immediate(0..13) } + - set HillTop.Naubinway.Sardinia, Sardinia + - set HillTop.Naubinway.Ayden, 1 + Ponder(-1, 16): + - default_only_action: { allowed: true } + - handle: 0x2000004c + - next_table: 0 + - { } + - set HillTop.Naubinway.Bonduel, 1 + default_only_action: Ponder + exact_match _Bigspring 4: + p4: { name: Bigspring, size: 4096, disable_atomic_modify : true } + p4_param_order: + HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } + HillTop.Savery.Kaluaaha: { type: exact, size: 16, full_size: 16, key_name: "Savery.Kaluaaha" } + HillTop.Savery.Calcasieu: { type: exact, size: 16, full_size: 16, key_name: "Savery.Calcasieu" } + HillTop.Savery.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Savery.Chevak" } + HillTop.Savery.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Savery.Mendocino" } + HillTop.Savery.LasVegas: { type: exact, size: 8, full_size: 8, key_name: "Savery.LasVegas" } + HillTop.Savery.PineCity: { type: exact, size: 6, full_size: 6, key_name: "Savery.PineCity" } + HillTop.Savery.Exton: { type: exact, size: 8, full_size: 8, key_name: "Savery.Exton" } + HillTop.Savery.Noyes: { type: exact, size: 8, full_size: 8, key_name: "Savery.Noyes" } + HillTop.Savery.Peebles: { type: exact, size: 1, full_size: 1, key_name: "Savery.Peebles" } + row: [ 3, 1 ] + bus: [ 1, 0 ] + column: + - 11 + - [ 2, 3, 6 ] + stash: + row: [ 3 ] + col: [ 11 ] + unit: [ 0 ] + ways: + - [1, 1, 0x6, [3, 11], [1, 2], [1, 3], [1, 6]] + input_xbar: + exact group 2: { 0: HillTop.Savery.Chevak, 16: HillTop.Savery.Mendocino, 32: HillTop.Savery.Calcasieu, 48: HillTop.Savery.Kaluaaha, 68: HillTop.Bessie.Miranda, 86: HillTop.Savery.PineCity, 101: HillTop.Savery.Peebles, 104: HillTop.Savery.Noyes, 112: HillTop.Savery.LasVegas, 120: HillTop.Savery.Exton } + hash 4: + 10..19: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) + 41..42: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) + hash 5: + 10..13: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(0..3) + 14..17: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(4..7) + 18..19: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(0..1) + 41: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(2) + 42: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.Peebles + hash group 1: + table: [4, 5] + seed: 0x20000072000 + format: { version(0): 112..115, match(0): [32..111, 0..7, 9..11 ] } + match: [ HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton, HillTop.Savery.Chevak(0..7), HillTop.Savery.Chevak(8..15), HillTop.Savery.Mendocino(0..7), HillTop.Savery.Mendocino(8..15), HillTop.Savery.Calcasieu(0..7), HillTop.Savery.Calcasieu(8..15), HillTop.Savery.Kaluaaha(0..7), HillTop.Savery.Kaluaaha(8..15), HillTop.Savery.PineCity(3..5) ] + hit: [ _LasLomas ] + miss: _LasLomas + action: _Bigspring$action_data($DIRECT, $DEFAULT) + instruction: _Bigspring($DEFAULT, $DEFAULT) + actions: + Unionvale(0, 5): + - p4_param_order: { Cornell: 32 } + - default_action: { allowed: true } + - handle: 0x20000058 + - next_table: 0 + - { Cornell: $adf_f0(0..31) } + - maxu HillTop.Mausdale.Kenney, HillTop.Mausdale.Kenney, Cornell + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x20000059 + - next_table: 0 + - { } + default_only_action: NoAction + action _Bigspring$action_data: + p4: { name: Bigspring$action } + row: 10 + column: 4 + vpns: [ 0 ] + home_row: + - 10 + format Unionvale: { $adf_f0: 0..31 } + action_bus: { 112..115 : $adf_f0 } + hash_action _LasLomas 5: + p4: { name: LasLomas, size: 256, disable_atomic_modify : true } + p4_param_order: + HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } + row: 2 + bus: 1 + hash_dist: + 0: { hash: 2, mask: 0xff, shift: 5 } + input_xbar: + exact group 1: { 68: HillTop.Bessie.Miranda } + hash 3: + 0..7: stripe(HillTop.Bessie.Miranda) + hash group 2: + table: [3] + seed: 0x0 + gateway: + name: _LasLomas-gateway + row: 1 + bus: 0 + unit: 0 + 0x0: _Anita + miss: _Anita + condition: + expression: "true(always hit)" + true: _Anita + false: _Anita + next: [] + action: _LasLomas$action_data(hash_dist 0, $DEFAULT) + instruction: _LasLomas($DEFAULT, $DEFAULT) + actions: + Crystola(0, 7): + - p4_param_order: { Kaluaaha: 16, Calcasieu: 16, Chevak: 16, Mendocino: 16, LasVegas: 8, PineCity: 6, Exton: 8, Noyes: 8, Peebles: 1 } + - default_action: { allowed: true } + - handle: 0x2000005a + - next_table: 0 + - { Peebles: $adf_b0(5..5), Noyes: $adf_b1(0..7), LasVegas: $adf_b2(0..7), Exton: $adf_b3(0..7), Chevak: $adf_h2(0..15), Mendocino: $adf_h3(0..15), Calcasieu: $adf_h4(0..15), Kaluaaha: $adf_h5(0..15), PineCity: $adf_h6(6..11) } + - and HillTop.Savery.Kaluaaha, HillTop.Bessie.Kaluaaha, Kaluaaha + - and HillTop.Savery.Calcasieu, HillTop.Bessie.Calcasieu, Calcasieu + - and HillTop.Savery.Chevak, HillTop.Bessie.Chevak, Chevak + - and HillTop.Savery.Mendocino, HillTop.Bessie.Mendocino, Mendocino + - and HillTop.Savery.LasVegas, HillTop.Bessie.LasVegas, LasVegas + - and HillTop.Savery.Exton, HillTop.Bessie.Exton, Exton + - and HillTop.Savery.Noyes, HillTop.Bessie.Noyes, Noyes + - and B10, Peebles, B9 + - and H85, PineCity, H90 + default_action: Crystola + default_action_parameters: + Kaluaaha: "0xffff" + Calcasieu: "0xffff" + Chevak: "0xffff" + Mendocino: "0xffff" + LasVegas: "0xff" + PineCity: "0x3f" + Exton: "0xff" + Noyes: "0xff" + Peebles: "0x1" + action _LasLomas$action_data: + p4: { name: LasLomas$action, how_referenced: direct } + row: 12 + column: 4 + vpns: [ 0 ] + home_row: + - 12 + format Crystola: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_b2: 16..23, $adf_b3: 24..31, $adf_h2: 32..47, $adf_h3: 48..63, $adf_h4: 64..79, $adf_h5: 80..95, $adf_h6: 96..111 } + action_bus: { 16 : $adf_b0, 17 : $adf_b1, 18 : $adf_b2, 19 : $adf_b3, 64..65 : $adf_h4, 66..67 : $adf_h5, 68..69 : $adf_h6, 48..49 : $adf_h2, 50..51 : $adf_h3 } + hash_action _Anita 6: + p4: { name: Anita, size: 1, disable_atomic_modify : true } + row: 0 + bus: 1 + hash_dist: + 1: { hash: 2, mask: 0xffff, shift: 0 } + 2: { hash: 2, mask: 0xffff, shift: 0 } + input_xbar: + exact group 3: { 0: Millston.Grays.Chevak, 16: Millston.Grays.Mendocino, 32: HillTop.Cutten.Pathfork } + hash 6: + 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 48, { 0: Millston.Grays.Mendocino, 16: Millston.Grays.Chevak, 32: HillTop.Cutten.Pathfork }, { })), 0..15) + hash group 2: + table: [6] + seed: 0x0 + exact group 3: { 48: Millston.Bergton.Chevak, 64: Millston.Bergton.Mendocino, 80: HillTop.Cutten.Marcus } + hash 6: + 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 48, { 16: Millston.Bergton.Chevak }, { })), 0..15) + hash 7: + 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 48, { 0: Millston.Bergton.Mendocino, 32: HillTop.Cutten.Marcus }, { })), 0..15) + hash group 2: + table: [6, 7] + seed: 0x0 + gateway: + name: _Anita-gateway + row: 0 + bus: 0 + unit: 1 + 0x0: _Plano + miss: _Plano + condition: + expression: "true(always hit)" + true: _Plano + false: _Plano + next: [] + action_bus: { 72..73 : hash_dist(1, lo), 74..75 : hash_dist(2, hi) } + instruction: _Anita($DEFAULT, $DEFAULT) + actions: + Baranof(0, 13): + - default_action: { allowed: true } + - handle: 0x2000005c + - next_table: 0 + - set H56, hash_dist(1, 0..15) + - set H57, hash_dist(2, 0..15) + default_action: Baranof + ternary_match _Plano 7: + p4: { name: Plano, size: 256, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.ElVerano: { type: exact, size: 1, full_size: 1, key_name: "RossFork.ElVerano" } + HillTop.Edwards.McGrady: { type: exact, size: 3, full_size: 3, key_name: "Edwards.McGrady" } + Millston.Wondervu$0.Higginson: { type: exact, size: 3, full_size: 3, key_name: "Wondervu$0.Higginson" } + Millston.Wondervu$1.$valid: { type: exact, size: 1, full_size: 1, key_name: "Wondervu$1" } + row: 4 + bus: 1 + column: 1 + input_xbar: + ternary group 3: { 8: Millston.Wondervu$1.$valid, 10: HillTop.RossFork.ElVerano, 21: Millston.Wondervu$0.Higginson, 26: HillTop.Edwards.McGrady } + match: + - { group: 3, byte_config: 3, dirtcam: 0x54 } + hit: [ _Leoma ] + miss: _Leoma + indirect: _Plano$tind + ternary_indirect _Plano$tind: + row: 0 + bus: 0 + column: 3 + input_xbar: + ternary group 3: { 8: Millston.Wondervu$1.$valid, 10: HillTop.RossFork.ElVerano, 21: Millston.Wondervu$0.Higginson, 26: HillTop.Edwards.McGrady } + format: { action: 0..1, immediate: 2..4 } + action_bus: { 52..53 : immediate(0..2) } + instruction: _Plano$tind(action, $DEFAULT) + actions: + WestEnd(0, 15): + - p4_param_order: { RedElm: 3 } + - default_action: { allowed: true } + - handle: 0x2000007c + - next_table: 0 + - { RedElm: immediate(0..2) } + - set HillTop.Edwards.RedElm, RedElm + Jenifer(1, 17): + - p4_param_order: { Willey: 3 } + - default_action: { allowed: true } + - handle: 0x2000007d + - next_table: 0 + - { Willey: immediate(0..2) } + - set HillTop.Edwards.RedElm, Willey + - set HillTop.RossFork.McCaulley.0-7, Millston.Wondervu$0.McCaulley.0-7 + - set HillTop.RossFork.McCaulley.8-15, Millston.Wondervu$0.McCaulley.8-15 + Endicott(2, 19): + - p4_param_order: { Willey: 3 } + - default_action: { allowed: true } + - handle: 0x2000007e + - next_table: 0 + - { Willey: immediate(0..2) } + - set HillTop.Edwards.RedElm, Willey + - set HillTop.RossFork.McCaulley.0-7, Millston.Wondervu$1.McCaulley.0-7 + - set HillTop.RossFork.McCaulley.8-15, Millston.Wondervu$1.McCaulley.8-15 + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x2000007f + - next_table: 0 + - { } + default_only_action: NoAction + exact_match _Leoma 8: + p4: { name: Leoma, size: 1024, disable_atomic_modify : true } + p4_param_order: + HillTop.Wisdom.Onycha: { type: exact, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } + HillTop.RossFork.Naruna: { type: exact, size: 3, full_size: 3, key_name: "RossFork.Naruna" } + row: 0 + bus: 0 + column: 2 + stash: + row: [ 0 ] + col: [ 2 ] + unit: [ 0 ] + ways: + - [1, 2, 0x0, [0, 2]] + input_xbar: + exact group 1: { 5: HillTop.RossFork.Naruna.2-2, 19: HillTop.RossFork.Naruna.0-1, 25: HillTop.Wisdom.Onycha } + hash 2: + 20: HillTop.RossFork.Naruna.2-2 + 21..22: HillTop.RossFork.Naruna.0-1 + 23..25: HillTop.Wisdom.Onycha + hash group 1: + table: [2] + seed: 0x0 + format: { action(0): 0..2, version(0): 112..115 } + hit: [ _Wakenda ] + miss: _Wakenda + instruction: _Leoma(action, $DEFAULT) + actions: + BigRock(0, 20): + - default_action: { allowed: true } + - handle: 0x20000080 + - next_table: 0 + - set HillTop.Edwards.PineCity, HillTop.Edwards.LaConner + Timnath(1, 22): + - default_action: { allowed: true } + - handle: 0x20000081 + - next_table: 0 + - set HillTop.Edwards.PineCity, 0 + Woodsboro(2, 24): + - default_action: { allowed: true } + - handle: 0x20000082 + - next_table: 0 + - set HillTop.Edwards.PineCity, HillTop.Maddock.PineCity + Amherst(3, 26): + - default_action: { allowed: true } + - handle: 0x20000083 + - next_table: 0 + - set HillTop.Edwards.PineCity, HillTop.Maddock.PineCity + Luttrell(4, 28): + - default_action: { allowed: true } + - handle: 0x20000084 + - next_table: 0 + - set HillTop.Edwards.PineCity, HillTop.Sublett.PineCity + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x20000085 + - next_table: 0 + default_only_action: NoAction +stage 4 ingress: + exact_match _Wakenda 0: + p4: { name: Wakenda, size: 4096, disable_atomic_modify : true } + p4_param_order: + HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } + HillTop.Savery.Kaluaaha: { type: exact, size: 16, full_size: 16, key_name: "Savery.Kaluaaha" } + HillTop.Savery.Calcasieu: { type: exact, size: 16, full_size: 16, key_name: "Savery.Calcasieu" } + HillTop.Savery.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Savery.Chevak" } + HillTop.Savery.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Savery.Mendocino" } + HillTop.Savery.LasVegas: { type: exact, size: 8, full_size: 8, key_name: "Savery.LasVegas" } + HillTop.Savery.PineCity: { type: exact, size: 6, full_size: 6, key_name: "Savery.PineCity" } + HillTop.Savery.Exton: { type: exact, size: 8, full_size: 8, key_name: "Savery.Exton" } + HillTop.Savery.Noyes: { type: exact, size: 8, full_size: 8, key_name: "Savery.Noyes" } + HillTop.Savery.Peebles: { type: exact, size: 1, full_size: 1, key_name: "Savery.Peebles" } + row: 1 + bus: 1 + column: [ 4, 6, 7, 8 ] + stash: + row: [ 1 ] + col: [ 4 ] + unit: [ 0 ] + ways: + - [0, 0, 0x3, [1, 4], [1, 6], [1, 7], [1, 8]] + input_xbar: + exact group 0: { 0: HillTop.Savery.Chevak, 16: HillTop.Savery.Mendocino, 32: HillTop.Savery.Calcasieu, 48: HillTop.Savery.Kaluaaha, 68: HillTop.Bessie.Miranda, 86: HillTop.Savery.PineCity, 101: HillTop.Savery.Peebles, 104: HillTop.Savery.Noyes, 112: HillTop.Savery.LasVegas, 120: HillTop.Savery.Exton } + hash 0: + 0..9: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) + 40..41: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) + hash 1: + 0..3: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(0..3) + 4..7: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(4..7) + 8..9: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(0..1) + 40: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(2) + 41: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.Peebles + hash group 0: + table: [0, 1] + seed: 0x3000000037c + format: { version(0): 112..115, match(0): [32..111, 0..7, 9..11 ] } + match: [ HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton, HillTop.Savery.Chevak(0..7), HillTop.Savery.Chevak(8..15), HillTop.Savery.Mendocino(0..7), HillTop.Savery.Mendocino(8..15), HillTop.Savery.Calcasieu(0..7), HillTop.Savery.Calcasieu(8..15), HillTop.Savery.Kaluaaha(0..7), HillTop.Savery.Kaluaaha(8..15), HillTop.Savery.PineCity(3..5) ] + hit: [ cond-16 ] + miss: cond-16 + action: _Wakenda$action_data($DIRECT, $DEFAULT) + instruction: _Wakenda($DEFAULT, $DEFAULT) + actions: + Unionvale(0, 1): + - p4_param_order: { Cornell: 32 } + - default_action: { allowed: true } + - handle: 0x2000005d + - next_table: 0 + - { Cornell: $adf_f0(0..31) } + - maxu HillTop.Mausdale.Kenney, HillTop.Mausdale.Kenney, Cornell + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x2000005e + - next_table: 0 + - { } + default_only_action: NoAction + action _Wakenda$action_data: + p4: { name: Wakenda$action } + row: 5 + column: 3 + vpns: [ 0 ] + home_row: + - 5 + format Unionvale: { $adf_f0: 0..31 } + action_bus: { 96..99 : $adf_f0 } + gateway cond-16 1: + name: cond-16 + input_xbar: + exact group 1: { 5: HillTop.RossFork.Weyauwega, 13: HillTop.Ovett.Hematite, 19: HillTop.Murphy.Standish, 30: HillTop.Murphy.Blairsden } + row: 4 + bus: 1 + unit: 0 + match: { 5: HillTop.RossFork.Weyauwega, 13: HillTop.Ovett.Hematite, 19: HillTop.Murphy.Standish, 30: HillTop.Murphy.Blairsden } + 0b*0**********0*****1*******0: cond-17 + miss: English_0 + condition: + expression: "(HillTop.RossFork.Weyauwega == 0 && HillTop.Ovett.Hematite == 1 && HillTop.Murphy.Standish == 0 && HillTop.Murphy.Blairsden == 0)" + true: cond-17 + false: English_0 + gateway cond-17 2: + name: cond-17 + input_xbar: + exact group 1: { 37: HillTop.RossFork.Naruna.2-2, 43: HillTop.Ovett.Hammond.0-0, 51: HillTop.RossFork.Naruna.0-1 } + row: 3 + bus: 1 + unit: 0 + match: { 19: HillTop.Ovett.Hammond.0-0, 3: HillTop.RossFork.Naruna.0-1, 13: HillTop.RossFork.Naruna.2-2 } + 0b****1*****0********01: _Brady_0 + miss: English_0 + condition: + expression: "(HillTop.Ovett.Hammond & 1 == 1 && HillTop.RossFork.Naruna == 1)" + true: _Brady_0 + false: English_0 + exact_match _Brady_0 3: + p4: { name: Brady, size: 75776, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Ocoee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } + HillTop.RossFork.Laxon: { type: exact, size: 32, full_size: 32, key_name: "RossFork.Laxon" } + HillTop.RossFork.Crozet: { type: exact, size: 16, full_size: 16, key_name: "RossFork.Crozet" } + HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } + Millston.Grays.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Grays.Mendocino" } + row: [ 6, 7, 4, 5, 2, 3, 0, 1 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 6, 7, 8 ] + - [ 2, 3, 4, 6, 7, 8 ] + - [ 2, 3, 4, 6, 7, 8 ] + - [ 2, 3, 4, 6, 7, 8 ] + - [ 2, 3, 4, 6, 7, 8 ] + - [ 2, 3, 4, 6, 7, 8 ] + - [ 2, 3 ] + - [ 2, 3 ] + stash: + row: [ 6, 7 ] + col: [ 2, 2 ] + unit: [ 0, 0 ] + ways: + - [1, 0, 0x3, [7, 2], [6, 2], [7, 3], [6, 3], [7, 4], [6, 4], [7, 6], [6, 6]] + - [1, 1, 0xc, [7, 7], [6, 7], [7, 8], [6, 8], [5, 2], [4, 2], [5, 3], [4, 3]] + - [1, 2, 0x30, [5, 4], [4, 4], [5, 6], [4, 6], [5, 7], [4, 7], [5, 8], [4, 8]] + - [1, 3, 0xc0, [3, 2], [2, 2], [3, 3], [2, 3], [3, 4], [2, 4], [3, 6], [2, 6]] + - [1, 0, 0x3, [3, 7], [2, 7], [3, 8], [2, 8], [1, 2], [0, 2], [1, 3], [0, 3]] + input_xbar: + exact group 2: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.RossFork.Laxon, 64: Millston.Grays.Mendocino, 80: HillTop.RossFork.Crozet, 96: HillTop.RossFork.Ocoee } + hash 4: + 0..9: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 40..41: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 10..19: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 42..43: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 20..29: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 44..45: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 30..39: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 46..47: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + hash 5: + 0..3: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..3) + 4..9: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..5) + 40..41: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(6..7) + 11..14: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..3) + 15..19: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..4) + 10: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(7) + 42..43: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(5..6) + 22..25: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..3) + 26..29: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..3) + 20..21: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(6..7) + 44..45: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(4..5) + 33..36: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..3) + 37..39: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..2) + 30..32: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(5..7) + 46..47: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(3..4) + hash group 1: + table: [4, 5] + seed: 0xb94f5d19db47 + format: { action(0): 0..2, immediate(0): 3..16, version(0): 112..115, match(0): [20..23, 32..111, 24..31 ], action(1): 128..130, immediate(1): 131..144, version(1): 240..243, match(1): [148..151, 160..239, 152..159 ] } + match: [ Millston.Grays.Mendocino(4..7), Millston.Grays.Mendocino(8..15), HillTop.RossFork.Crozet(0..7), HillTop.RossFork.Crozet(8..15), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31), HillTop.RossFork.Laxon(0..7), HillTop.RossFork.Laxon(8..15), HillTop.RossFork.Laxon(16..23), HillTop.RossFork.Laxon(24..31) ] + gateway: + name: cond-18 + input_xbar: + exact group 1: { 3: HillTop.RossFork.Alamosa } + row: 0 + bus: 1 + unit: 0 + match: { 3: HillTop.RossFork.Alamosa } + 0b****0: run_table + miss: English_0 + condition: + expression: "(HillTop.RossFork.Alamosa == 0)" + true: _Brady_0 + false: English_0 + hit: [ [], English_0, English_0, English_0, English_0, _Lindy_0 ] + miss: _Brady_0$st1 + action_bus: { 32..33 : immediate(0..13) } + action: _Brady_0$action_data($DIRECT, $DEFAULT) + instruction: _Brady_0(action, $DEFAULT) + actions: + Callao(1, 2): + - p4_param_order: { Calcasieu: 32, Bratt: 32, Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x20000062 + - next_table: 1 + - { Bratt.0-15: $adf_f0(0..15), Bonduel: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 0 + - set HillTop.Naubinway.Bonduel, Bonduel + - set HillTop.RossFork.Suttle, 1 + Ambler(2, 4): + - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x20000063 + - next_table: 2 + - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Bonduel: immediate(0..13) } + - set HillTop.RossFork.DonaAna, Avondale + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 0 + - set HillTop.Naubinway.Bonduel, Bonduel + - set HillTop.RossFork.Suttle, 1 + Wagener(3, 6): + - p4_param_order: { Calcasieu: 32, Bratt: 32, Sardinia: 14 } + - default_action: { allowed: true } + - handle: 0x20000064 + - next_table: 3 + - { Bratt.0-15: $adf_f0(0..15), Sardinia: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 1 + - set HillTop.Naubinway.Sardinia, Sardinia + - set HillTop.RossFork.Suttle, 1 + Olmitz(4, 8): + - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Sardinia: 14 } + - default_action: { allowed: true } + - handle: 0x20000065 + - next_table: 4 + - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Sardinia: immediate(0..13) } + - set HillTop.RossFork.DonaAna, Avondale + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 1 + - set HillTop.Naubinway.Sardinia, Sardinia + - set HillTop.RossFork.Suttle, 1 + Sequim(5, 0): + - default_action: { allowed: true } + - handle: 0x20000066 + - next_table: 5 + - { } + default_action: Sequim + idletime: + row: 0 + bus: 0 + column: [ 0, 1, 2, 3, 4 ] + precision: 1 + sweep_interval: 7 + notification: enable + per_flow_enable: false + action _Brady_0$action_data: + p4: { name: Brady$action } + row: [ 15, 14, 12, 11, 10, 9, 8, 7, 5, 3, 1 ] + word: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - 5 + - 5 + - 5 + - 5 + - 5 + - [ 4, 5 ] + - 5 + - [ 4, 5 ] + - [ 4, 5 ] + - [ 3, 4, 5 ] + - [ 1, 2, 3, 4, 5 ] + vpns: + - [ 0 ] + - [ 1 ] + - [ 2 ] + - [ 3 ] + - [ 4 ] + - [ 5, 6 ] + - [ 7 ] + - [ 8, 9 ] + - [ 10, 11 ] + - [ 12, 13, 14 ] + - [ 15, 16, 17, 18, 19 ] + home_row: + - [ 15, 11 ] + format Callao: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + format Ambler: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + format Wagener: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + format Olmitz: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + action_bus: { 38..39 : $adf_h1, 108..111 : $adf_f1, 36..39 : $adf_f0 } +stage 5 ingress: + ternary_match _Lindy_0 1: + p4: { name: Lindy, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Lordstown: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Lordstown" } + HillTop.RossFork.Sewaren: { type: ternary, size: 2, full_size: 2, key_name: "RossFork.Sewaren" } + HillTop.RossFork.WindGap: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.WindGap" } + HillTop.RossFork.Belfair: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Belfair" } + HillTop.RossFork.Caroleen: { type: ternary, size: 2, full_size: 2, key_name: "RossFork.Caroleen" } + HillTop.RossFork.Ocoee: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } + HillTop.Bessie.Peebles: { type: ternary, size: 1, full_size: 1, key_name: "Bessie.Peebles" } + row: 8 + bus: 1 + column: 1 + input_xbar: + ternary group 2: { 6: HillTop.RossFork.Belfair, 8: HillTop.RossFork.Ocoee, 22: HillTop.RossFork.Caroleen, 29: HillTop.Bessie.Peebles, 36: HillTop.RossFork.Sewaren, 38: HillTop.RossFork.WindGap, 39: HillTop.RossFork.Lordstown } + match: + - { group: 2, dirtcam: 0x155 } + hit: [ English_0, English_0, English_0, English_0, _Geistown_0 ] + miss: English_0 + indirect: _Lindy_0$tind + ternary_indirect _Lindy_0$tind: + row: 4 + bus: 0 + column: 2 + input_xbar: + ternary group 2: { 6: HillTop.RossFork.Belfair, 8: HillTop.RossFork.Ocoee, 22: HillTop.RossFork.Caroleen, 29: HillTop.Bessie.Peebles, 36: HillTop.RossFork.Sewaren, 38: HillTop.RossFork.WindGap, 39: HillTop.RossFork.Lordstown } + format: { action: 0..2 } + instruction: _Lindy_0$tind(action, $DEFAULT) + actions: + Lauada(0, 8): + - default_action: { allowed: true } + - handle: 0x20000067 + - next_table: 0 + - set HillTop.RossFork.Merrill, HillTop.RossFork.Hickox + - set HillTop.Naubinway.Ayden, 0 + - set HillTop.Naubinway.Bonduel, HillTop.RossFork.Luzerne + RichBar(1, 10): + - default_action: { allowed: true } + - handle: 0x20000068 + - next_table: 1 + - set HillTop.RossFork.Merrill, HillTop.RossFork.Hickox + - set HillTop.Naubinway.Ayden, 1 + - set HillTop.Naubinway.Sardinia, HillTop.RossFork.Luzerne + Harding(2, 12): + - default_action: { allowed: true } + - handle: 0x20000069 + - next_table: 2 + - set HillTop.RossFork.Merrill, HillTop.RossFork.Tehachapi + - set HillTop.Naubinway.Ayden, 0 + - set HillTop.Naubinway.Bonduel, HillTop.RossFork.Devers + Nephi(3, 14): + - default_action: { allowed: true } + - handle: 0x2000006a + - next_table: 3 + - set HillTop.RossFork.Merrill, HillTop.RossFork.Tehachapi + - set HillTop.Naubinway.Ayden, 1 + - set HillTop.Naubinway.Sardinia, HillTop.RossFork.Devers + Sequim(4, 0): + - default_action: { allowed: true } + - handle: 0x2000006b + - next_table: 4 + default_action: Sequim + exact_match _Geistown_0 2: + p4: { name: Geistown, size: 4096, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Knierim: { type: exact, size: 12, full_size: 12, key_name: "RossFork.Knierim" } + HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } + Millston.Grays.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Grays.Mendocino" } + HillTop.RossFork.Chaffee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Chaffee" } + row: 0 + bus: 1 + column: [ 8, 9, 10, 11 ] + stash: + row: [ 0 ] + col: [ 8 ] + unit: [ 1 ] + ways: + - [1, 0, 0x0, [0, 8]] + - [1, 1, 0x0, [0, 9]] + - [1, 2, 0x0, [0, 10]] + - [1, 3, 0x0, [0, 11]] + input_xbar: + exact group 1: { 0: HillTop.Maddock.Calcasieu(0..15), 19: HillTop.RossFork.Knierim, 32: HillTop.RossFork.Chaffee, 40: Millston.Grays.Mendocino(8..15), 48: HillTop.Maddock.Calcasieu(16..31), 64: Millston.Grays.Mendocino(0..7) } + hash 2: + 0..4: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(0..4) + 5..9: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(5..9) + 11..15: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(0..4) + 16..19: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(5..8) + 10: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(9) + 22..26: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(0..4) + 27..29: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(5..7) + 20..21: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(8..9) + 33..37: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(0..4) + 38..39: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(5..6) + 30..32: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(7..9) + hash 3: + 0..9: random(Millston.Grays.Mendocino(0..7)) + 10..19: random(Millston.Grays.Mendocino(0..7)) + 20..29: random(Millston.Grays.Mendocino(0..7)) + 30..39: random(Millston.Grays.Mendocino(0..7)) + hash group 1: + table: [2, 3] + seed: 0xce0e6f30b6 + format: { action(0): 0..2, immediate(0): 3..16, version(0): 112..115, match(0): [32..55, 93..94, 56..87 ] } + match: [ HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(0..7), Millston.Grays.Mendocino(8..15), HillTop.RossFork.Knierim(10..11), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31) ] + hit: [ English_0, English_0, English_0, English_0, _Swanlake_0 ] + miss: English_0 + action_bus: { 40..41 : immediate(0..13) } + action: _Geistown_0$action_data($DIRECT, $DEFAULT) + instruction: _Geistown_0(action, $DEFAULT) + actions: + Palouse(0, 16): + - p4_param_order: { Calcasieu: 32, Bratt: 32, Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x2000006c + - next_table: 0 + - { Bratt.0-15: $adf_f0(0..15), Bonduel: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 0 + - set HillTop.Naubinway.Bonduel, Bonduel + Monrovia(1, 18): + - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x2000006d + - next_table: 1 + - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Bonduel: immediate(0..13) } + - set HillTop.RossFork.DonaAna, Avondale + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 0 + - set HillTop.Naubinway.Bonduel, Bonduel + Sespe(2, 20): + - p4_param_order: { Calcasieu: 32, Bratt: 32, Sardinia: 14 } + - default_action: { allowed: true } + - handle: 0x2000006e + - next_table: 2 + - { Bratt.0-15: $adf_f0(0..15), Sardinia: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 1 + - set HillTop.Naubinway.Sardinia, Sardinia + Rienzi(3, 22): + - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Sardinia: 14 } + - default_action: { allowed: true } + - handle: 0x2000006f + - next_table: 3 + - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Sardinia: immediate(0..13) } + - set HillTop.RossFork.DonaAna, Avondale + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 1 + - set HillTop.Naubinway.Sardinia, Sardinia + Sequim(4, 0): + - default_action: { allowed: true } + - handle: 0x20000070 + - next_table: 4 + - { } + default_action: Sequim + action _Geistown_0$action_data: + p4: { name: Geistown$action } + row: 12 + column: [ 2, 3 ] + vpns: [ 0, 1 ] + home_row: + - 12 + format Palouse: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + format Monrovia: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + format Sespe: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + format Rienzi: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + action_bus: { 46..47 : $adf_h1, 108..111 : $adf_f1, 44..47 : $adf_f0 } + exact_match _Swanlake_0 3: + p4: { name: Swanlake, size: 1024, disable_atomic_modify : true } + p4_param_order: + HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } + HillTop.RossFork.Chaffee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Chaffee" } + row: [ 1, 0 ] + bus: [ 1, 0 ] + column: + - [ 10, 11 ] + - [ 6, 7 ] + stash: + row: [ 0 ] + col: [ 7 ] + unit: [ 0 ] + ways: + - [2, 0, 0x0, [0, 7]] + - [2, 1, 0x0, [1, 10]] + - [2, 2, 0x0, [1, 11]] + - [2, 3, 0x0, [0, 6]] + input_xbar: + exact group 2: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.RossFork.Chaffee } + hash 4: + 0..1: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.Maddock.Calcasieu(0..1) + 2..9: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.RossFork.Chaffee + 11..12: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.Maddock.Calcasieu(0..1) + 13..19: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.RossFork.Chaffee(0..6) + 10: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.RossFork.Chaffee(7) + 22..23: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.Maddock.Calcasieu(0..1) + 24..29: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.RossFork.Chaffee(0..5) + 20..21: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.RossFork.Chaffee(6..7) + 33..34: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.Maddock.Calcasieu(0..1) + 35..39: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.RossFork.Chaffee(0..4) + 30..32: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.RossFork.Chaffee(5..7) + hash group 2: + table: [4] + seed: 0xee1f27531a + format: { action(0): 0..1, immediate(0): 2..31, version(0): 112..115, match(0): [58..63, 32..55 ] } + match: [ HillTop.Maddock.Calcasieu(2..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31) ] + hit: [ English_0, English_0, _Rochert_0 ] + miss: English_0 + action_bus: { 34..35 : immediate(16..29), 112..115 : immediate(0..29) } + action: _Swanlake_0$action_data($DIRECT, $DEFAULT) + instruction: _Swanlake_0(action, $DEFAULT) + actions: + Callao(0, 24): + - p4_param_order: { Calcasieu: 32, Bratt: 32, Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x20000071 + - next_table: 0 + - { Calcasieu: $adf_f0(0..31), Bratt.0-15: immediate(0..15), Bonduel: immediate(16..29) } + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 0 + - set HillTop.Naubinway.Bonduel, Bonduel + - set HillTop.RossFork.Suttle, 1 + Wagener(1, 26): + - p4_param_order: { Calcasieu: 32, Bratt: 32, Sardinia: 14 } + - default_action: { allowed: true } + - handle: 0x20000072 + - next_table: 1 + - { Calcasieu: $adf_f0(0..31), Bratt.0-15: immediate(0..15), Sardinia: immediate(16..29) } + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 1 + - set HillTop.Naubinway.Sardinia, Sardinia + - set HillTop.RossFork.Suttle, 1 + Sequim(2, 0): + - default_action: { allowed: true } + - handle: 0x20000073 + - next_table: 2 + - { } + default_action: Sequim + idletime: + row: 0 + bus: 1 + column: 1 + precision: 1 + sweep_interval: 7 + notification: enable + per_flow_enable: false + action _Swanlake_0$action_data: + p4: { name: Swanlake$action } + row: 8 + column: 3 + vpns: [ 0 ] + home_row: + - 8 + format Callao: { $adf_f0: 0..31 } + format Wagener: { $adf_f0: 0..31 } + action_bus: { 120..123 : $adf_f0 } + exact_match _Rochert_0 4: + p4: { name: Rochert, size: 10240, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Knierim: { type: exact, size: 12, full_size: 12, key_name: "RossFork.Knierim" } + HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } + HillTop.RossFork.Chaffee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Chaffee" } + row: [ 3, 1 ] + bus: [ 1, 0 ] + column: + - 11 + - [ 6, 7, 8, 9 ] + stash: + row: [ 3 ] + col: [ 11 ] + unit: [ 0 ] + ways: + - [3, 0, 0x1, [3, 11], [1, 6]] + - [3, 1, 0x0, [1, 9]] + - [3, 2, 0x0, [1, 8]] + - [3, 3, 0x0, [1, 7]] + input_xbar: + exact group 2: { 64: HillTop.Maddock.Calcasieu(0..15), 83: HillTop.RossFork.Knierim, 96: HillTop.RossFork.Chaffee, 112: HillTop.Maddock.Calcasieu(16..31) } + hash 5: + 0..4: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(0..4) + 5..9: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(5..9) + 40: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) + 11..15: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(0..4) + 16..19: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(5..8) + 10: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(9) + 22..26: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(0..4) + 27..29: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(5..7) + 20..21: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(8..9) + 33..37: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(0..4) + 38..39: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(5..6) + 30..32: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(7..9) + hash group 3: + table: [5] + seed: 0x15431402ade + format: { action(0): 0..1, version(0): 112..115, match(0): [32..39, 77..78, 40..71 ], action(1): 2..3, version(1): 116..119, match(1): [80..87, 5..6, 88..111, 8..15 ] } + match: [ HillTop.RossFork.Chaffee, HillTop.RossFork.Knierim(10..11), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31) ] + hit: [ English_0, English_0, _Emden_0 ] + miss: English_0 + action: _Rochert_0$action_data($DIRECT, $DEFAULT) + instruction: _Rochert_0(action, $DEFAULT) + actions: + Palouse(0, 28): + - p4_param_order: { Calcasieu: 32, Bratt: 32, Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x20000074 + - next_table: 0 + - { Bratt.0-15: $adf_f0(0..15), Bonduel: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 0 + - set HillTop.Naubinway.Bonduel, Bonduel + Sespe(1, 30): + - p4_param_order: { Calcasieu: 32, Bratt: 32, Sardinia: 14 } + - default_action: { allowed: true } + - handle: 0x20000075 + - next_table: 1 + - { Bratt.0-15: $adf_f0(0..15), Sardinia: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 1 + - set HillTop.Naubinway.Sardinia, Sardinia + Sequim(2, 0): + - default_action: { allowed: true } + - handle: 0x20000076 + - next_table: 2 + - { } + default_action: Sequim + action _Rochert_0$action_data: + p4: { name: Rochert$action } + row: [ 2, 0 ] + word: [ 0, 0 ] + column: + - [ 3, 4, 5 ] + - [ 4, 5 ] + vpns: + - [ 0, 1, 2 ] + - [ 3, 4 ] + home_row: + - 2 + format Palouse: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + format Sespe: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + action_bus: { 50..51 : $adf_h1, 68..71 : $adf_f1, 48..51 : $adf_f0 } + ternary_match _Emden_0 5: + p4: { name: Emden, size: 8192, disable_atomic_modify : true } + p4_param_order: + HillTop.Ovett.Manilla: { type: exact, size: 8, full_size: 8, key_name: "Ovett.Manilla" } + HillTop.Maddock.Calcasieu: { type: lpm, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } + row: [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + input_xbar: + ternary group 0: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.Ovett.Manilla } + match: + - { group: 0, byte_config: 3, dirtcam: 0x155 } + hit: [ English_0 ] + miss: English_0 + indirect: _Emden_0$tind + idletime: + row: 0 + bus: 0 + column: 0 + precision: 1 + sweep_interval: 7 + notification: enable + per_flow_enable: false + ternary_indirect _Emden_0$tind: + row: 3 + bus: 0 + column: 2 + input_xbar: + ternary group 0: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.Ovett.Manilla } + format: { action: 0..1, immediate: 2..15 } + action_bus: { 52..53 : immediate(0..13) } + instruction: _Emden_0$tind(action, $DEFAULT) + actions: + Tofte(0, 32): + - p4_param_order: { Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x20000077 + - next_table: 0 + - { Bonduel: immediate(0..13) } + - set HillTop.Naubinway.Ayden, 0 + - set HillTop.Naubinway.Bonduel, Bonduel + Jerico(1, 34): + - p4_param_order: { Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x20000078 + - next_table: 0 + - { Bonduel: immediate(0..13) } + - set HillTop.Naubinway.Ayden, 2 + - set HillTop.Naubinway.Bonduel, Bonduel + Wabbaseka(2, 36): + - p4_param_order: { Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x20000079 + - next_table: 0 + - { Bonduel: immediate(0..13) } + - set HillTop.Naubinway.Ayden, 3 + - set HillTop.Naubinway.Bonduel, Bonduel + Clearmont(3, 38): + - p4_param_order: { Sardinia: 14 } + - default_action: { allowed: true } + - handle: 0x2000007a + - next_table: 0 + - { Sardinia: immediate(0..13) } + - set HillTop.Naubinway.Sardinia, Sardinia + - set HillTop.Naubinway.Ayden, 1 + Ruffin(-1, 40): + - default_only_action: { allowed: true } + - handle: 0x2000007b + - next_table: 0 + - { } + - set HillTop.Naubinway.Ayden, 0 + - set HillTop.Naubinway.Bonduel, 1 + default_only_action: Ruffin + exact_match _Brady_0$st1 0: + p4: { name: Brady, size: 75776, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Ocoee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } + HillTop.RossFork.Laxon: { type: exact, size: 32, full_size: 32, key_name: "RossFork.Laxon" } + HillTop.RossFork.Crozet: { type: exact, size: 16, full_size: 16, key_name: "RossFork.Crozet" } + HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } + Millston.Grays.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Grays.Mendocino" } + row: [ 6, 7, 4, 5, 2, 3 ] + bus: [ 0, 0, 0, 0, 0, 0 ] + column: + - [ 6, 7, 8, 9, 10, 11 ] + - [ 6, 7, 8, 9, 10, 11 ] + - [ 6, 7, 8, 9, 10, 11 ] + - [ 6, 7, 8, 9, 10, 11 ] + - [ 6, 7, 8, 9, 10 ] + - [ 6, 7, 8, 9, 10 ] + stash: + row: [ 2, 3 ] + col: [ 6, 6 ] + unit: [ 1, 1 ] + ways: + - [0, 0, 0x3, [3, 6], [2, 6], [3, 7], [2, 7], [3, 8], [2, 8], [3, 9], [2, 9]] + - [0, 1, 0xc, [5, 8], [4, 8], [5, 9], [4, 9], [5, 10], [4, 10], [5, 11], [4, 11]] + - [0, 2, 0x30, [7, 10], [6, 10], [7, 11], [6, 11], [5, 6], [4, 6], [5, 7], [4, 7]] + - [0, 3, 0xc0, [7, 6], [6, 6], [7, 7], [6, 7], [7, 8], [6, 8], [7, 9], [6, 9]] + - [0, 0, 0x0, [3, 10], [2, 10]] + input_xbar: + exact group 0: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.RossFork.Laxon, 64: Millston.Grays.Mendocino, 80: HillTop.RossFork.Crozet, 96: HillTop.RossFork.Ocoee } + hash 0: + 0..9: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 40..41: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 10..19: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 42..43: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 20..29: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 44..45: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 30..39: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + 46..47: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) + hash 1: + 0..1: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) + 2..9: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee + 40..41: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) + 11..12: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) + 13..19: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..6) + 10: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(7) + 42..43: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) + 22..23: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) + 24..29: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..5) + 20..21: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(6..7) + 44..45: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) + 33..34: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) + 35..39: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..4) + 30..32: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(5..7) + 46..47: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) + hash group 0: + table: [0, 1] + seed: 0x7971b8f945b3 + format: { action(0): 0..2, immediate(0): 3..16, version(0): 112..115, match(0): [18..23, 32..111, 24..31 ], action(1): 128..130, immediate(1): 131..144, version(1): 240..243, match(1): [146..151, 160..239, 152..159 ] } + match: [ Millston.Grays.Mendocino(2..7), Millston.Grays.Mendocino(8..15), HillTop.RossFork.Crozet(0..7), HillTop.RossFork.Crozet(8..15), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31), HillTop.RossFork.Laxon(0..7), HillTop.RossFork.Laxon(8..15), HillTop.RossFork.Laxon(16..23), HillTop.RossFork.Laxon(24..31) ] + hit: [ English_0, English_0, English_0, English_0, _Lindy_0 ] + miss: English_0 + action_bus: { 32..33 : immediate(0..13) } + action: _Brady_0$st1$action_data($DIRECT, $DEFAULT) + instruction: _Brady_0$st1(action, $DEFAULT) + actions: + Callao(0, 1): + - p4_param_order: { Calcasieu: 32, Bratt: 32, Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x20000062 + - next_table: 0 + - { Bratt.0-15: $adf_f0(0..15), Bonduel: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 0 + - set HillTop.Naubinway.Bonduel, Bonduel + - set HillTop.RossFork.Suttle, 1 + Ambler(1, 2): + - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x20000063 + - next_table: 1 + - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Bonduel: immediate(0..13) } + - set HillTop.RossFork.DonaAna, Avondale + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 0 + - set HillTop.Naubinway.Bonduel, Bonduel + - set HillTop.RossFork.Suttle, 1 + Wagener(2, 4): + - p4_param_order: { Calcasieu: 32, Bratt: 32, Sardinia: 14 } + - default_action: { allowed: true } + - handle: 0x20000064 + - next_table: 2 + - { Bratt.0-15: $adf_f0(0..15), Sardinia: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 1 + - set HillTop.Naubinway.Sardinia, Sardinia + - set HillTop.RossFork.Suttle, 1 + Olmitz(3, 6): + - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Sardinia: 14 } + - default_action: { allowed: true } + - handle: 0x20000065 + - next_table: 3 + - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Sardinia: immediate(0..13) } + - set HillTop.RossFork.DonaAna, Avondale + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.Naubinway.Ayden, 1 + - set HillTop.Naubinway.Sardinia, Sardinia + - set HillTop.RossFork.Suttle, 1 + Sequim(4, 0): + - default_action: { allowed: true } + - handle: 0x20000066 + - next_table: 4 + - { } + default_action: Sequim + idletime: + row: 4 + bus: 0 + column: [ 0, 1, 2, 3, 4 ] + precision: 1 + sweep_interval: 7 + notification: enable + per_flow_enable: false + action _Brady_0$st1$action_data: + p4: { name: Brady$action } + row: [ 14, 12, 10, 8, 6, 4, 0 ] + word: [ 0, 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 5 ] + - [ 4, 5 ] + - [ 4, 5 ] + - [ 4, 5 ] + - [ 3, 4, 5 ] + - [ 3, 4, 5 ] + - 3 + vpns: + - [ 0, 1, 2, 3 ] + - [ 4, 5 ] + - [ 6, 7 ] + - [ 8, 9 ] + - [ 10, 11, 12 ] + - [ 13, 14, 15 ] + - [ 16 ] + home_row: + - [ 14, 0 ] + format Callao: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + format Ambler: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + format Wagener: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + format Olmitz: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + action_bus: { 38..39 : $adf_h1, 100..103 : $adf_f1, 36..39 : $adf_f0 } + ternary_match English_0 6: + p4: { name: English, size: 512, disable_atomic_modify : true } + p4_param_order: + Millston.Bergton.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Bergton" } + Millston.Ramos.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Ramos" } + Millston.Provencal.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Provencal" } + Millston.Shirley.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Shirley" } + Millston.Grays.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Grays" } + Millston.Maumee.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Maumee" } + Millston.GlenAvon.$valid: { type: ternary, size: 1, full_size: 1, key_name: "GlenAvon" } + row: 10 + bus: 1 + column: 1 + input_xbar: + ternary group 1: { 2: Millston.Provencal.$valid, 3: Millston.Grays.$valid, 8: Millston.Shirley.$valid, 10: Millston.Maumee.$valid, 20: Millston.GlenAvon.$valid, 21: Millston.Ramos.$valid, 22: Millston.Bergton.$valid } + match: + - { group: 1, dirtcam: 0x15 } + hit: [ cond-19 ] + miss: cond-19 + indirect: English_0$tind + ternary_indirect English_0$tind: + row: 2 + bus: 0 + column: 2 + input_xbar: + ternary group 1: { 2: Millston.Provencal.$valid, 3: Millston.Grays.$valid, 8: Millston.Shirley.$valid, 10: Millston.Maumee.$valid, 20: Millston.GlenAvon.$valid, 21: Millston.Ramos.$valid, 22: Millston.Bergton.$valid } + format: { action: 0..2 } + instruction: English_0$tind(action, $DEFAULT) + actions: + Dresden(0, 3): + - default_action: { allowed: true } + - handle: 0x20000089 + - next_table: 0 + - set HillTop.Lewiston.Lugert, HillTop.Cutten.Pathfork + Lorane(1, 5): + - default_action: { allowed: true } + - handle: 0x2000008a + - next_table: 0 + - set HillTop.Lewiston.Lugert, HillTop.Cutten.Tombstone + Dundalk(2, 7): + - default_action: { allowed: true } + - handle: 0x2000008b + - next_table: 0 + - set HillTop.Lewiston.Lugert, HillTop.Cutten.Marcus + Bellville(3, 9): + - default_action: { allowed: true } + - handle: 0x2000008c + - next_table: 0 + - set HillTop.Lewiston.Lugert, HillTop.Cutten.Pittsboro + DeerPark(4, 11): + - default_action: { allowed: true } + - handle: 0x2000008d + - next_table: 0 + - set HillTop.Lewiston.Lugert, HillTop.Cutten.Subiaco + Sequim(5, 0): + - default_action: { allowed: true } + - handle: 0x2000008e + - next_table: 0 + NoAction(-1, 13): + - default_only_action: { allowed: true } + - handle: 0x2000008f + - next_table: 0 + default_only_action: NoAction + gateway cond-19 7: + name: cond-19 + input_xbar: + exact group 0: { 105: Millston.Hayfield.$valid } + row: 6 + bus: 1 + unit: 0 + match: { 1: Millston.Hayfield.$valid } + 0b******0: _Sardinia + miss: _Jemison + condition: + expression: "(Millston.Hayfield.$valid == 1 == 0)" + true: _Sardinia + false: _Jemison + ternary_match _Jemison 8: + p4: { name: Jemison, size: 1024, disable_atomic_modify : true } + p4_param_order: + Millston.Hayfield.Blitchton: { type: exact, size: 6, full_size: 6, key_name: "Hayfield.Blitchton" } + Millston.Hayfield.Avondale: { type: exact, size: 10, full_size: 10, key_name: "Hayfield.Avondale" } + Millston.Hayfield.Glassboro: { type: exact, size: 4, full_size: 4, key_name: "Hayfield.Glassboro" } + Millston.Hayfield.Grabill: { type: exact, size: 12, full_size: 12, key_name: "Hayfield.Grabill" } + HillTop.Wisdom.Onycha: { type: ternary, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } + row: [ 6, 7 ] + bus: [ 1, 1 ] + column: + - 1 + - 1 + input_xbar: + ternary group 3: { 0: Millston.Hayfield.Grabill(8..11), 4: Millston.Hayfield.Glassboro, 8: Millston.Hayfield.Avondale, 18: Millston.Hayfield.Blitchton, 24: Millston.Hayfield.Grabill(0..7), 33: HillTop.Wisdom.Onycha } + match: + - { group: 3, dirtcam: 0x155 } + gateway: + name: cond-21 + input_xbar: + exact group 0: { 105: Millston.Hayfield.$valid } + row: 5 + bus: 1 + unit: 0 + match: { 1: Millston.Hayfield.$valid } + 0b******1: run_table + miss: _Romeo + condition: + expression: "(Millston.Hayfield.$valid == 1)" + true: _Jemison + false: _Romeo + hit: [ _Romeo ] + miss: _Romeo + indirect: _Jemison$tind + ternary_indirect _Jemison$tind: + row: 1 + bus: 0 + column: 2 + input_xbar: + ternary group 3: { 0: Millston.Hayfield.Grabill(8..11), 4: Millston.Hayfield.Glassboro, 8: Millston.Hayfield.Avondale, 18: Millston.Hayfield.Blitchton, 24: Millston.Hayfield.Grabill(0..7), 33: HillTop.Wisdom.Onycha } + format: { action: 0..2, immediate: 3..22 } + action_bus: { 116..119 : immediate(0..19) } + instruction: _Jemison$tind(action, $DEFAULT) + actions: + Neosho(1, 15): + - p4_param_order: { Stilwell: 20 } + - default_action: { allowed: true } + - handle: 0x20000092 + - next_table: 0 + - { Stilwell: immediate(0..19) } + - set HillTop.Wisdom.Onycha, 2 + - set HillTop.Wisdom.Morstein, Stilwell + - set HillTop.Wisdom.Nenana, HillTop.RossFork.CeeVee + Islen(2, 17): + - default_action: { allowed: true } + - handle: 0x20000093 + - next_table: 0 + - { } + - set HillTop.Wisdom.Onycha, 3 + - set HillTop.RossFork.Brinkman, 0 + - set HillTop.RossFork.Parkland, 0 + BarNunn(3, 19): + - default_action: { allowed: true } + - handle: 0x20000094 + - next_table: 0 + - { } + - set HillTop.RossFork.Chugwater, 1 + Swandale(4, 0): + - default_action: { allowed: true } + - handle: 0x20000095 + - next_table: 0 + - { } + default_action: BarNunn +stage 6 ingress: + exact_match _Sardinia 0: + p4: { name: Sardinia, size: 256, action_profile: Coryville, disable_atomic_modify : true } + p4_param_order: + HillTop.Naubinway.Sardinia: { type: exact, size: 8, full_size: 14, key_name: "Naubinway.Sardinia" } + row: 2 + bus: 1 + column: 7 + stash: + row: [ 2 ] + col: [ 7 ] + unit: [ 1 ] + ways: + - [0, 0, 0x0, [2, 7]] + input_xbar: + exact group 0: { 0: HillTop.Naubinway.Sardinia(0..7) } + hash 0: + 0..7: HillTop.Naubinway.Sardinia(0..7) + hash group 0: + table: [0] + seed: 0x0 + exact group 1: { 0: HillTop.Tiburon.Arnold, 16: HillTop.Lewiston.Lugert } + hash 2: + 0..9: slice(stripe(crc_rev(0x18005, 0x0, 0x0, 25, { 0: HillTop.Tiburon.Arnold, 9: HillTop.Lewiston.Lugert }, { })), 0..9) + hash group 2: + table: [2] + seed: 0x0 + format: { action(0): 2..2, version(0): 112..115, meter_addr(0): 3..12, meter_pfe(0): 13..13, action_addr(0): 14..28, sel_len_mod(0): 0..1 } + gateway: + name: cond-20 + input_xbar: + exact group 1: { 70: HillTop.Naubinway.Ayden } + row: 1 + bus: 0 + unit: 1 + match: { 6: HillTop.Naubinway.Ayden } + 0x1: run_table + miss: _Romeo + condition: + expression: "(HillTop.Naubinway.Ayden == 1)" + true: _Sardinia + false: _Romeo + hit: [ _Romeo ] + miss: _Romeo + selector: _Sardinia$selector.Bellamy(meter_addr, meter_pfe, $DEFAULT) + selector_length: _Sardinia$selector.Bellamy(sel_len_mod, $DEFAULT) + action: _Sardinia$action_data.Coryville(action_addr, $DEFAULT) + instruction: _Sardinia(action, $DEFAULT) + actions: + Ackerly(1, 1): + - p4_param_order: { Ayden: 2, Bonduel: 14 } + - default_action: { allowed: true } + - handle: 0x20000090 + - next_table: 0 + - { Bonduel: $adf_h0(0..13) } + - set HillTop.Naubinway.Bonduel, Bonduel + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x20000091 + - next_table: 0 + - { } + default_only_action: NoAction + selection _Sardinia$selector.Bellamy: + p4: { name: Bellamy, size: 192 } + row: 15 + column: [ 2, 3 ] + maprams: [ 2, 3 ] + input_xbar: + exact group 0: { 64: HillTop.Tiburon.Arnold, 80: HillTop.Lewiston.Lugert } + hash 1: + 0..50: slice(stripe(crc_rev(0x18005, 0x0, 0x0, 25, { 0: HillTop.Tiburon.Arnold, 9: HillTop.Lewiston.Lugert })), 0..50) + hash group 1: + table: [1] + seed: 0x0 + mode: resilient 0 + non_linear: true + pool_sizes: [256] + hash_dist: + 0: { hash: 2, mask: 0x3ff, shift: 0 } + action _Sardinia$action_data.Coryville: + p4: { name: Coryville, size: 16384 } + row: 5 + column: [ 2, 3 ] + vpns: [ 0, 1 ] + home_row: + - 5 + format Ackerly: { $adf_h0: 0..15 } + action_bus: { 32..33 : $adf_h0 } + stateful _Sardinia$salu.Bellamy$salu: + p4: { name: Bellamy$salu, size: 122880, hidden: true } + selection_table: _Sardinia$selector.Bellamy + row: 15 + column: [ 2, 3 ] + maprams: [ 2, 3 ] + format: { lo: 1 } + actions: + set_bit_at_alu$0: + - set_bit_at + clr_bit_at_alu$0: + - clr_bit_at + set_bit_alu$0: + - set_bit + clr_bit_alu$0: + - clr_bit + exact_match _Romeo 1: + p4: { name: Romeo, size: 16384, disable_atomic_modify : true } + p4_param_order: + HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } + HillTop.RossFork.Bicknell: { type: exact, size: 12, full_size: 12, key_name: "RossFork.Bicknell" } + row: [ 1, 2 ] + bus: [ 0, 0 ] + column: + - [ 2, 3, 4, 6 ] + - [ 2, 3, 4, 6 ] + stash: + row: [ 1, 2 ] + col: [ 2, 2 ] + unit: [ 0, 0 ] + ways: + - [3, 0, 0x0, [2, 2], [1, 2]] + - [3, 1, 0x0, [2, 3], [1, 3]] + - [3, 2, 0x0, [2, 4], [1, 4]] + - [3, 3, 0x0, [2, 6], [1, 6]] + input_xbar: + exact group 1: { 72: HillTop.Maddock.Calcasieu(8..31), 96: HillTop.Maddock.Calcasieu(0..7), 104: HillTop.RossFork.Bicknell(8..11), 112: HillTop.RossFork.Bicknell(0..7) } + hash 3: + 0..3: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(8..11) + 4..9: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(0..5) + 11..14: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(8..11) + 15..19: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(0..4) + 10: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(5) + 22..25: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(8..11) + 26..29: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(0..3) + 20..21: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(4..5) + 33..36: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(8..11) + 37..39: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(0..2) + 30..32: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(3..5) + hash group 3: + table: [3] + seed: 0x957f7806d9 + format: { action(0): 0..0, immediate(0): 3..4, version(0): 112..115, match(0): 14..47, action(1): 1..1, immediate(1): 5..6, version(1): 116..119, match(1): [86..87, 48..79 ], action(2): 2..2, immediate(2): 7..8, version(2): 248..251, match(2): [214..215, 88..111, 120..127 ], action(3): 128..128, immediate(3): 130..131, version(3): 240..243, match(3): 134..167, action(4): 129..129, immediate(4): 132..133, version(4): 244..247, match(4): [206..207, 168..199 ] } + match: [ HillTop.RossFork.Bicknell(6..7), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31) ] + gateway: + name: cond-23 + input_xbar: + exact group 0: { 9: HillTop.Ovett.Hammond.1-3(1), 21: HillTop.RossFork.Weyauwega, 30: HillTop.Murphy.Blairsden, 37: HillTop.RossFork.Naruna.2-2, 43: HillTop.RossFork.Juniata, 51: HillTop.Murphy.Standish, 59: HillTop.RossFork.Naruna.0-1 } + hash 0: + 40: HillTop.Murphy.Blairsden + 41: HillTop.Ovett.Hammond.1-3(1) + 42: HillTop.RossFork.Juniata + hash group 0: + table: [0] + seed: 0x0 + row: 1 + bus: 1 + unit: 0 + match: { 21: HillTop.RossFork.Weyauwega, 27: HillTop.Murphy.Standish, 32: HillTop.Murphy.Blairsden, 33: HillTop.Ovett.Hammond.1-3(1), 34: HillTop.RossFork.Juniata, 3: HillTop.RossFork.Naruna.0-1, 13: HillTop.RossFork.Naruna.2-2 } + 0b110****0*****0*******0********01: run_table + miss: _Elkton + condition: + expression: "(HillTop.RossFork.Weyauwega == 0 && HillTop.Murphy.Standish == 0 && HillTop.Murphy.Blairsden == 0 && HillTop.Ovett.Hammond & 4 == 4 && HillTop.RossFork.Juniata == 1 && HillTop.RossFork.Naruna == 1)" + true: _Romeo + false: _Elkton + hit: [ _Elkton ] + miss: _Elkton + action_bus: { 0 : immediate(0..1), 36..37 : immediate(0..1) } + action: _Romeo$action_data($DIRECT, $DEFAULT) + instruction: _Romeo(action, $DEFAULT) + actions: + Catlin(1, 2): + - p4_param_order: { Antoine: 16, Townville: 16, Monahans: 1, Pinole: 1 } + - default_action: { allowed: true } + - handle: 0x200000a1 + - next_table: 0 + - { Antoine: $adf_h0(0..15), Townville.12-15: $adf_h1(0..3), Townville.0-11: $adf_h1(4..15), Pinole: immediate(0..0), Monahans: immediate(1..1) } + - set HillTop.Salix.Hueytown, Antoine + - set HillTop.Komatke.Monahans, Monahans + - set HillTop.Komatke.Townville.0-11, Townville.0-11 + - set HillTop.Komatke.Townville.12-15, Townville.12-15 + - set HillTop.Komatke.Pinole, Pinole + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x200000a2 + - next_table: 0 + - { } + default_only_action: NoAction + idletime: + row: 4 + bus: 0 + column: [ 0, 1, 4 ] + precision: 1 + sweep_interval: 7 + notification: enable + per_flow_enable: false + action _Romeo$action_data: + p4: { name: Romeo$action } + row: [ 3, 1 ] + word: [ 0, 0 ] + column: + - [ 3, 4, 5 ] + - [ 4, 5 ] + vpns: + - [ 0, 1, 2 ] + - [ 3, 4 ] + home_row: + - 3 + format Catlin: { $adf_h0: 0..15, $adf_h1: 16..31 } + action_bus: { 40..41 : $adf_h0, 42..43 : $adf_h1 } + hash_action _Elkton 2: + p4: { name: Elkton, size: 2, disable_atomic_modify : true } + p4_param_order: + Millston.Calabash.$valid: { type: exact, size: 1, full_size: 1, key_name: "Calabash" } + row: 3 + bus: 1 + hash_dist: + 1: { hash: 2, mask: 0x1, shift: 3 } + input_xbar: + exact group 1: { 34: Millston.Calabash.$valid } + hash 2: + 16..16: stripe(Millston.Calabash.$valid) + hash group 2: + table: [2] + seed: 0x0 + gateway: + name: cond-22 + input_xbar: + exact group 0: { 97: HillTop.Wisdom.Onycha } + row: 2 + bus: 1 + unit: 0 + payload: 0x1 + format: { action: 0..0 } + match: { 1: HillTop.Wisdom.Onycha } + 0b****010: run_table + miss: Fittstown_0 + condition: + expression: "(HillTop.Wisdom.Onycha != 2)" + true: Fittstown_0 + false: Fittstown_0 + next: Fittstown_0 + action: _Elkton$action_data(hash_dist 1, $DEFAULT) + instruction: _Elkton(action, $DEFAULT) + actions: + Beatrice(1, 3): + - p4_param_order: { Avondale: 20 } + - default_action: { allowed: true } + - handle: 0x200000a0 + - next_table: 0 + - { Avondale: $adf_f0(0..19) } + - set HillTop.Wisdom.Dolores, HillTop.Lamona.Whitefish + - set HillTop.Wisdom.Connell.0-15, HillTop.RossFork.Connell.0-15 + - set HillTop.Wisdom.Nenana, HillTop.RossFork.CeeVee + - set HillTop.Wisdom.Morstein, Avondale + - or W10, W1, W10 + - deposit-field W13(8..31), W0(2..25), W14 + default_action: Beatrice + default_action_parameters: + Avondale: "0x1ff" + action _Elkton$action_data: + p4: { name: Elkton$action, how_referenced: direct } + row: 13 + column: 4 + vpns: [ 0 ] + home_row: + - 13 + format Beatrice: { $adf_f0: 0..31 } + action_bus: { 96..99 : $adf_f0 } + ternary_match Fittstown_0 3: + p4: { name: Fittstown, size: 256, disable_atomic_modify : true } + p4_param_order: + Millston.Bergton.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Bergton" } + Millston.Ramos.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Ramos" } + Millston.Provencal.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Provencal" } + Millston.Shirley.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Shirley" } + Millston.Grays.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Grays" } + Millston.GlenAvon.$valid: { type: ternary, size: 1, full_size: 1, key_name: "GlenAvon" } + Millston.Maumee.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Maumee" } + Millston.Calabash.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Calabash" } + row: 6 + bus: 1 + column: 1 + hash_dist: + 2: { hash: 2, mask: 0xffff, shift: 0 } + input_xbar: + ternary group 0: { 2: Millston.Provencal.$valid, 3: Millston.Grays.$valid, 8: Millston.Shirley.$valid, 10: Millston.Maumee.$valid, 18: Millston.Calabash.$valid, 20: Millston.GlenAvon.$valid, 21: Millston.Ramos.$valid, 22: Millston.Bergton.$valid } + exact group 2: { 0: Millston.Calabash.Connell.16-23, 8: Millston.Calabash.Adona, 32: Millston.Calabash.Fabens, 56: Millston.Calabash.Goldsboro.0-7, 64: Millston.Calabash.Goldsboro.8-23, 80: Millston.Calabash.Connell.0-15, 96: HillTop.RossFork.McCaulley.0-7, 104: HillTop.RossFork.McCaulley.8-15 } + hash 4: + 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 112, { 16: Millston.Calabash.Fabens, 40: Millston.Calabash.Goldsboro.0-7, 80: Millston.Calabash.Connell.16-23, 88: Millston.Calabash.Adona }, { })), 0..15) + hash 5: + 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 112, { 0: HillTop.RossFork.McCaulley.0-7, 8: HillTop.RossFork.McCaulley.8-15, 48: Millston.Calabash.Goldsboro.8-23, 64: Millston.Calabash.Connell.0-15 }, { })), 0..15) + hash group 2: + table: [4, 5] + seed: 0x0 + match: + - { group: 0, dirtcam: 0x15 } + hit: [ _Havana ] + miss: _Havana + indirect: Fittstown_0$tind + ternary_indirect Fittstown_0$tind: + row: 1 + bus: 0 + column: 5 + hash_dist: + 2: { hash: 2, mask: 0xffff, shift: 0 } + input_xbar: + ternary group 0: { 2: Millston.Provencal.$valid, 3: Millston.Grays.$valid, 8: Millston.Shirley.$valid, 10: Millston.Maumee.$valid, 18: Millston.Calabash.$valid, 20: Millston.GlenAvon.$valid, 21: Millston.Ramos.$valid, 22: Millston.Bergton.$valid } + exact group 2: { 0: Millston.Calabash.Connell.16-23, 8: Millston.Calabash.Adona, 32: Millston.Calabash.Fabens, 56: Millston.Calabash.Goldsboro.0-7, 64: Millston.Calabash.Goldsboro.8-23, 80: Millston.Calabash.Connell.0-15, 96: HillTop.RossFork.McCaulley.0-7, 104: HillTop.RossFork.McCaulley.8-15 } + hash 4: + 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 112, { 16: Millston.Calabash.Fabens, 40: Millston.Calabash.Goldsboro.0-7, 80: Millston.Calabash.Connell.16-23, 88: Millston.Calabash.Adona }, { })), 0..15) + hash 5: + 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 112, { 0: HillTop.RossFork.McCaulley.0-7, 8: HillTop.RossFork.McCaulley.8-15, 48: Millston.Calabash.Goldsboro.8-23, 64: Millston.Calabash.Connell.0-15 }, { })), 0..15) + hash group 2: + table: [4, 5] + seed: 0x0 + format: { action: 0..2 } + action_bus: { 44..45 : hash_dist(2, lo) } + instruction: Fittstown_0$tind(action, $DEFAULT) + actions: + Watters(0, 4): + - default_action: { allowed: true } + - handle: 0x20000096 + - next_table: 0 + - set H51, hash_dist(2, 0..15) + Burmester(1, 6): + - default_action: { allowed: true } + - handle: 0x20000097 + - next_table: 0 + - set HillTop.Lewiston.Staunton, HillTop.Cutten.Pathfork + Petrolia(2, 8): + - default_action: { allowed: true } + - handle: 0x20000098 + - next_table: 0 + - set HillTop.Lewiston.Staunton, HillTop.Cutten.Tombstone + Aguada(3, 10): + - default_action: { allowed: true } + - handle: 0x20000099 + - next_table: 0 + - set HillTop.Lewiston.Staunton, HillTop.Cutten.Subiaco + Brush(4, 12): + - default_action: { allowed: true } + - handle: 0x2000009a + - next_table: 0 + - set HillTop.Lewiston.Staunton, HillTop.Cutten.Marcus + Ceiba(5, 14): + - default_action: { allowed: true } + - handle: 0x2000009b + - next_table: 0 + - set HillTop.Lewiston.Staunton, HillTop.Cutten.Pittsboro + Sequim(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x2000009c + - next_table: 0 + default_only_action: Sequim + ternary_match _Havana 4: + p4: { name: Havana, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.McCaulley: { type: ternary, size: 16, full_size: 16, key_name: "RossFork.McCaulley" } + HillTop.RossFork.Pridgen: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Pridgen" } + HillTop.RossFork.Tenino: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Tenino" } + HillTop.RossFork.Denhoff: { type: ternary, size: 3, full_size: 3, key_name: "RossFork.Denhoff" } + HillTop.RossFork.Chevak: { type: ternary, size: 16, full_size: 16, key_name: "RossFork.Chevak" } + HillTop.RossFork.Mendocino: { type: ternary, size: 16, full_size: 16, key_name: "RossFork.Mendocino" } + HillTop.Lamona.Fristoe: { type: ternary, size: 14, full_size: 14, key_name: "Lamona.Fristoe" } + HillTop.RossFork.Bicknell: { type: ternary, size: 12, full_size: 12, key_name: "RossFork.Bicknell" } + HillTop.Ovett.Hematite: { type: ternary, size: 1, full_size: 1, key_name: "Ovett.Hematite" } + HillTop.RossFork.Exton: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Exton" } + Millston.Rainelle.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Rainelle" } + Millston.Rainelle.Findlay: { type: ternary, size: 16, full_size: 16, key_name: "Rainelle.Findlay" } + HillTop.RossFork.Brinkman: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Brinkman" } + HillTop.Maddock.Calcasieu: { type: ternary, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } + HillTop.RossFork.Ocoee: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } + HillTop.Wisdom.Delavan: { type: ternary, size: 1, full_size: 1, key_name: "Wisdom.Delavan" } + HillTop.Wisdom.Onycha: { type: ternary, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } + HillTop.Sublett.Calcasieu: { type: ternary, size: 16, full_size: 128, key_name: "Sublett.Calcasieu", start_bit: 112 } + HillTop.RossFork.Parkland: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Parkland" } + HillTop.Wisdom.Blencoe: { type: ternary, size: 8, full_size: 8, key_name: "Wisdom.Blencoe" } + row: [ 0, 1, 2, 3, 4, 5 ] + bus: [ 0, 0, 0, 0, 0, 0 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + input_xbar: + ternary group 1: { 0: HillTop.Lamona.Fristoe(8..13), 8: HillTop.Maddock.Calcasieu(24..31), 16: HillTop.Maddock.Calcasieu(0..7), 24: HillTop.Lamona.Fristoe(0..7), 32: HillTop.Maddock.Calcasieu(16..23) } + ternary group 2: { 0: HillTop.Sublett.Calcasieu.96-127(24..31), 8: HillTop.RossFork.Bicknell(0..7), 16: HillTop.Maddock.Calcasieu(8..15), 24: HillTop.Sublett.Calcasieu.96-127(16..23), 32: HillTop.RossFork.Bicknell(8..11) } + ternary group 3: { 0: HillTop.RossFork.Mendocino(8..15), 8: HillTop.RossFork.Mendocino(0..7), 16: Millston.Rainelle.Findlay(8..15), 24: Millston.Rainelle.Findlay(0..7), 37: HillTop.Ovett.Hematite } + ternary group 4: { 0: HillTop.RossFork.Chevak(0..7), 14: HillTop.RossFork.Tenino, 15: HillTop.RossFork.Pridgen, 17: HillTop.Wisdom.Onycha, 24: HillTop.RossFork.Chevak(8..15), 39: HillTop.Wisdom.Delavan } + ternary group 5: { 0: HillTop.Wisdom.Blencoe, 8: HillTop.RossFork.Ocoee, 19: Millston.Rainelle.$valid, 24: HillTop.RossFork.McCaulley.0-7, 32: HillTop.RossFork.McCaulley.8-15 } + ternary group 6: { 0: HillTop.RossFork.Exton, 11: HillTop.RossFork.Denhoff.0-0, 21: HillTop.RossFork.Brinkman } + byte group 3: { 1: HillTop.RossFork.Parkland, 2: HillTop.RossFork.Denhoff.1-2 } + match: + - { group: 1, byte_group: 3, byte_config: 0, dirtcam: 0x555 } + - { group: 2, dirtcam: 0x155 } + - { group: 3, dirtcam: 0x155 } + - { group: 4, dirtcam: 0x155 } + - { group: 5, dirtcam: 0x155 } + - { group: 6, dirtcam: 0x15 } + hit: [ _Nooksack ] + miss: _Nooksack + indirect: _Havana$tind + counter _Havana$stats.Palco: + p4: { name: Palco } + row: 13 + column: [ 2, 3 ] + maprams: [ 2, 3 ] + count: packets_and_bytes + format: {packets(0): 0..63, bytes(0): 64..127} + ternary_indirect _Havana$tind: + row: 0 + bus: 1 + column: 3 + input_xbar: + ternary group 1: { 0: HillTop.Lamona.Fristoe(8..13), 8: HillTop.Maddock.Calcasieu(24..31), 16: HillTop.Maddock.Calcasieu(0..7), 24: HillTop.Lamona.Fristoe(0..7), 32: HillTop.Maddock.Calcasieu(16..23) } + ternary group 2: { 0: HillTop.Sublett.Calcasieu.96-127(24..31), 8: HillTop.RossFork.Bicknell(0..7), 16: HillTop.Maddock.Calcasieu(8..15), 24: HillTop.Sublett.Calcasieu.96-127(16..23), 32: HillTop.RossFork.Bicknell(8..11) } + ternary group 3: { 0: HillTop.RossFork.Mendocino(8..15), 8: HillTop.RossFork.Mendocino(0..7), 16: Millston.Rainelle.Findlay(8..15), 24: Millston.Rainelle.Findlay(0..7), 37: HillTop.Ovett.Hematite } + ternary group 4: { 0: HillTop.RossFork.Chevak(0..7), 14: HillTop.RossFork.Tenino, 15: HillTop.RossFork.Pridgen, 17: HillTop.Wisdom.Onycha, 24: HillTop.RossFork.Chevak(8..15), 39: HillTop.Wisdom.Delavan } + ternary group 5: { 0: HillTop.Wisdom.Blencoe, 8: HillTop.RossFork.Ocoee, 19: Millston.Rainelle.$valid, 24: HillTop.RossFork.McCaulley.0-7, 32: HillTop.RossFork.McCaulley.8-15 } + ternary group 6: { 0: HillTop.RossFork.Exton, 11: HillTop.RossFork.Denhoff.0-0, 21: HillTop.RossFork.Brinkman } + byte group 3: { 1: HillTop.RossFork.Parkland, 2: HillTop.RossFork.Denhoff.1-2 } + format: { action: 0..1, immediate: 2..17 } + action_bus: { 16 : immediate(0..7), 17 : immediate(8..15) } + stats: _Havana$stats.Palco($DIRECT, $DEFAULT) + instruction: _Havana$tind(action, $DEFAULT) + actions: + Melder(0, 5): + - p4_param_order: { Blencoe: 8 } + - default_action: { allowed: true } + - handle: 0x200000a7 + - next_table: 0 + - { Blencoe: immediate(0..7) } + - set ig_intr_md_for_tm.mcast_grp_a, 0 + - set HillTop.Wisdom.Havana, 1 + - set HillTop.Wisdom.Blencoe, Blencoe + - set HillTop.RossFork.Montross, 0 + - set HillTop.Moose.Pinole, 0 + - _Havana$stats.Palco($DIRECT) + FourTown(1, 7): + - p4_param_order: { Blencoe: 8, Redden: 1 } + - default_action: { allowed: true } + - handle: 0x200000a8 + - next_table: 0 + - { Redden: immediate(0..0), Blencoe: immediate(8..15) } + - set ig_intr_md_for_tm.copy_to_cpu, 1 + - set HillTop.Wisdom.Blencoe, Blencoe + - set HillTop.RossFork.Redden, Redden + - set HillTop.RossFork.Montross, 0 + - set HillTop.Moose.Pinole, 0 + - _Havana$stats.Palco($DIRECT) + Hyrum(2, 9): + - default_action: { allowed: true } + - handle: 0x200000a9 + - next_table: 0 + - { } + - set HillTop.RossFork.Redden, 1 + - set HillTop.RossFork.Montross, 0 + - set HillTop.Moose.Pinole, 0 + - _Havana$stats.Palco($DIRECT) + Farner(3, 11): + - default_action: { allowed: true } + - handle: 0x200000aa + - next_table: 0 + - { } + - set HillTop.RossFork.Montross, 0 + - set HillTop.Moose.Pinole, 0 + - _Havana$stats.Palco($DIRECT) + NoAction(-1, 13): + - default_only_action: { allowed: true } + - handle: 0x200000ab + - next_table: 0 + - { } + - set HillTop.RossFork.Montross, 0 + - set HillTop.Moose.Pinole, 0 + default_only_action: NoAction + exact_match _Nooksack 5: + p4: { name: Nooksack, size: 67584, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Ocoee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } + HillTop.Maddock.Kaluaaha: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } + Millston.Grays.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Grays.Chevak" } + HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } + Millston.Grays.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Grays.Mendocino" } + row: [ 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 6, 7 ] + - [ 2, 3, 4, 6, 7 ] + - [ 2, 3, 4, 6, 7 ] + - [ 2, 3, 4, 6, 7 ] + - [ 2, 3, 4, 6, 7 ] + stash: + row: [ 3, 4, 5, 6, 7 ] + col: [ 2, 2, 2, 2, 2 ] + unit: [ 0, 0, 0, 0, 0 ] + ways: + - [4, 0, 0x1, [7, 2], [6, 2], [5, 2], [4, 2], [3, 2], [7, 3], [6, 3], [5, 3], [4, 3], [3, 3]] + - [4, 1, 0x0, [7, 4], [6, 4], [5, 4], [4, 4], [3, 4]] + - [4, 2, 0x0, [7, 6], [6, 6], [5, 6], [4, 6], [3, 6]] + - [4, 3, 0x0, [7, 7], [6, 7], [5, 7], [4, 7], [3, 7]] + input_xbar: + exact group 3: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.Maddock.Kaluaaha, 64: Millston.Grays.Chevak, 80: Millston.Grays.Mendocino, 96: HillTop.RossFork.Ocoee } + hash 6: + 0..9: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) + 40: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) + 10..19: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) + 20..29: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) + 30..39: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) + hash 7: + 0..1: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) + 2..9: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee + 40: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) + 11..12: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) + 13..19: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(0..6) + 10: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(7) + 22..23: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) + 24..29: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(0..5) + 20..21: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(6..7) + 33..34: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) + 35..39: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(0..4) + 30..32: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(5..7) + hash group 4: + table: [6, 7] + seed: 0x15ad646b5e0 + format: { action(0): 2..3, version(0): 4..7, match(0): [98..103, 8..95 ], action(1): 0..1, version(1): 244..247, match(1): [506..511, 104..127, 224..239, 248..255, 352..367, 376..383, 480..495 ], action(2): 128..129, version(2): 240..243, match(2): 130..223, action(3): 256..257, version(3): 368..371, match(3): 258..351, action(4): 384..385, version(4): 496..499, match(4): 386..479, action(5): 512..513, version(5): 624..627, match(5): 514..607 } + match: [ Millston.Grays.Chevak(2..7), Millston.Grays.Chevak(8..15), Millston.Grays.Mendocino(0..7), Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31), HillTop.Maddock.Kaluaaha(0..7), HillTop.Maddock.Kaluaaha(8..15), HillTop.Maddock.Kaluaaha(16..23), HillTop.Maddock.Kaluaaha(24..31) ] + gateway: + name: cond-24 + input_xbar: + exact group 4: { 0: HillTop.RossFork.Merrill(0..7), 11: HillTop.Ovett.Hammond.0-0, 19: HillTop.RossFork.Alamosa, 21: HillTop.RossFork.Weyauwega, 29: HillTop.Ovett.Hematite, 37: HillTop.RossFork.Naruna.2-2, 40: HillTop.RossFork.Merrill(8..15), 51: HillTop.Murphy.Standish, 62: HillTop.Murphy.Blairsden, 67: HillTop.RossFork.Naruna.0-1 } + hash 8: + 44: HillTop.RossFork.Weyauwega + 45: HillTop.Ovett.Hematite + 46: HillTop.Murphy.Standish + 47: HillTop.Murphy.Blairsden + 48: HillTop.Ovett.Hammond.0-0 + 49: HillTop.RossFork.Alamosa + hash 9: + hash group 0: + table: [8, 9] + seed: 0x0 + row: 0 + bus: 1 + unit: 1 + match: { 36: HillTop.RossFork.Weyauwega, 37: HillTop.Ovett.Hematite, 38: HillTop.Murphy.Standish, 39: HillTop.Murphy.Blairsden, 40: HillTop.Ovett.Hammond.0-0, 19: HillTop.RossFork.Naruna.0-1, 29: HillTop.RossFork.Naruna.2-2, 0: HillTop.RossFork.Merrill(0..7), 8: HillTop.RossFork.Merrill(8..15), 41: HillTop.RossFork.Alamosa } + 0b010010******0********01***0000000000000000: run_table + miss: _Buras + condition: + expression: "(HillTop.RossFork.Weyauwega == 0 && HillTop.Ovett.Hematite == 1 && HillTop.Murphy.Standish == 0 && HillTop.Murphy.Blairsden == 0 && (HillTop.Ovett.Hammond & 1 == 1 && HillTop.RossFork.Naruna == 1 && HillTop.RossFork.Merrill == 0 && HillTop.RossFork.Alamosa == 0))" + true: _Nooksack + false: _Buras + hit: [ [], _Buras, _Buras, _Pineville ] + miss: _Nooksack$st1 + action: _Nooksack$action_data($DIRECT, $DEFAULT) + instruction: _Nooksack(action, $DEFAULT) + actions: + Milano(1, 15): + - p4_param_order: { Kaluaaha: 32, Bratt: 32 } + - default_action: { allowed: true } + - handle: 0x200000ac + - next_table: 1 + - { Kaluaaha: $adf_f0(0..31), Bratt.0-15: $adf_f1(0..15) } + - set HillTop.Maddock.Kaluaaha, Kaluaaha + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Boerne, 1 + - set HillTop.RossFork.Suttle, 1 + Biggers(2, 16): + - p4_param_order: { Kaluaaha: 32, Avondale: 16, Bratt: 32 } + - default_action: { allowed: true } + - handle: 0x200000ad + - next_table: 2 + - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Kaluaaha: $adf_f1(0..31) } + - set HillTop.RossFork.Glenmora, Avondale + - set HillTop.Maddock.Kaluaaha, Kaluaaha + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Boerne, 1 + - set HillTop.RossFork.Suttle, 1 + Sequim(3, 0): + - default_action: { allowed: true } + - handle: 0x200000ae + - next_table: 3 + - { } + default_action: Sequim + idletime: + row: 0 + bus: 0 + column: [ 0, 1, 2, 3 ] + precision: 1 + sweep_interval: 7 + notification: enable + per_flow_enable: false + action _Nooksack$action_data: + p4: { name: Nooksack$action } + row: [ 15, 14, 13, 12, 10, 9, 8, 6, 5, 1 ] + word: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - [ 4, 5 ] + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - [ 4, 5 ] + - [ 0, 1, 2, 3 ] + vpns: + - [ 0, 1 ] + - [ 2 ] + - [ 3 ] + - [ 4 ] + - [ 5 ] + - [ 6 ] + - [ 7 ] + - [ 8 ] + - [ 9, 10 ] + - [ 11, 12, 13, 14 ] + home_row: + - [ 15, 1 ] + format Milano: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Biggers: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + action_bus: { 50..51 : $adf_h1, 108..111 : $adf_f1, 48..51 : $adf_f0 } +stage 7 ingress: + ternary_match _Pineville 1: + p4: { name: Pineville, size: 4096, disable_atomic_modify : true } + p4_param_order: + HillTop.Maddock.Calcasieu: { type: ternary, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } + HillTop.RossFork.Ocoee: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } + HillTop.Bessie.Peebles: { type: ternary, size: 1, full_size: 1, key_name: "Bessie.Peebles" } + row: [ 10, 11, 0, 1, 2, 3, 4, 5 ] + bus: [ 0, 0, 1, 1, 1, 1, 1, 1 ] + column: + - 0 + - 0 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + input_xbar: + ternary group 0: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.RossFork.Ocoee } + byte group 0: { 5: HillTop.Bessie.Peebles } + match: + - { group: 0, byte_group: 0, byte_config: 1, dirtcam: 0x555 } + hit: [ _Buras ] + miss: _Buras + indirect: _Pineville$tind + ternary_indirect _Pineville$tind: + row: 2 + bus: 0 + column: 3 + input_xbar: + ternary group 0: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.RossFork.Ocoee } + byte group 0: { 5: HillTop.Bessie.Peebles } + format: { action: 0..0, immediate: 1..12 } + action_bus: { 104..107 : immediate(0..11) } + instruction: _Pineville$tind(action, $DEFAULT) + actions: + Hearne(0, 3): + - p4_param_order: { Moultrie: 12 } + - default_action: { allowed: true } + - handle: 0x200000af + - next_table: 0 + - { Moultrie: immediate(0..11) } + - set HillTop.RossFork.Montross, Moultrie + Pinetop(1, 0): + - default_action: { allowed: true } + - handle: 0x200000b0 + - next_table: 0 + - { } + default_action: Pinetop + exact_match _Nooksack$st1 0: + p4: { name: Nooksack, size: 67584, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Ocoee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } + HillTop.Maddock.Kaluaaha: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } + Millston.Grays.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Grays.Chevak" } + HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } + Millston.Grays.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Grays.Mendocino" } + row: [ 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0 ] + column: + - [ 2, 6, 7, 8, 9, 10 ] + - [ 2, 6, 7, 8, 9, 10 ] + - [ 2, 6, 7, 8, 9, 10 ] + - [ 2, 6, 7, 8, 9, 10 ] + - [ 2, 6, 7, 8, 9, 10 ] + stash: + row: [ 3, 4, 5, 6, 7 ] + col: [ 2, 2, 2, 2, 2 ] + unit: [ 0, 0, 0, 0, 0 ] + ways: + - [0, 0, 0x1, [7, 2], [6, 2], [5, 2], [4, 2], [3, 2], [7, 6], [6, 6], [5, 6], [4, 6], [3, 6]] + - [0, 1, 0x2, [7, 7], [6, 7], [5, 7], [4, 7], [3, 7], [7, 8], [6, 8], [5, 8], [4, 8], [3, 8]] + - [0, 2, 0x0, [7, 9], [6, 9], [5, 9], [4, 9], [3, 9]] + - [0, 3, 0x0, [7, 10], [6, 10], [5, 10], [4, 10], [3, 10]] + input_xbar: + exact group 0: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.Maddock.Kaluaaha, 64: Millston.Grays.Chevak, 80: Millston.Grays.Mendocino, 96: HillTop.RossFork.Ocoee } + hash 0: + 0..9: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) + 40: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) + 10..19: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) + 41: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) + 20..29: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) + 30..39: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) + hash 1: + 0..1: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) + 2..9: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee + 40: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) + 11..12: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) + 13..19: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(0..6) + 10: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(7) + 41: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) + 22..23: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) + 24..29: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(0..5) + 20..21: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(6..7) + 33..34: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) + 35..39: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(0..4) + 30..32: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(5..7) + hash group 0: + table: [0, 1] + seed: 0xe86e73c23b + format: { action(0): 2..3, version(0): 4..7, match(0): [98..103, 8..95 ], action(1): 0..1, version(1): 244..247, match(1): [506..511, 104..127, 224..239, 248..255, 352..367, 376..383, 480..495 ], action(2): 128..129, version(2): 240..243, match(2): 130..223, action(3): 256..257, version(3): 368..371, match(3): 258..351, action(4): 384..385, version(4): 496..499, match(4): 386..479, action(5): 512..513, version(5): 624..627, match(5): 514..607 } + match: [ Millston.Grays.Chevak(2..7), Millston.Grays.Chevak(8..15), Millston.Grays.Mendocino(0..7), Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31), HillTop.Maddock.Kaluaaha(0..7), HillTop.Maddock.Kaluaaha(8..15), HillTop.Maddock.Kaluaaha(16..23), HillTop.Maddock.Kaluaaha(24..31) ] + hit: [ _Buras, _Buras, _Pineville ] + miss: _Buras + action: _Nooksack$st1$action_data($DIRECT, $DEFAULT) + instruction: _Nooksack$st1(action, $DEFAULT) + actions: + Milano(0, 1): + - p4_param_order: { Kaluaaha: 32, Bratt: 32 } + - default_action: { allowed: true } + - handle: 0x200000ac + - next_table: 0 + - { Kaluaaha: $adf_f0(0..31), Bratt.0-15: $adf_f1(0..15) } + - set HillTop.Maddock.Kaluaaha, Kaluaaha + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Boerne, 1 + - set HillTop.RossFork.Suttle, 1 + Biggers(1, 2): + - p4_param_order: { Kaluaaha: 32, Avondale: 16, Bratt: 32 } + - default_action: { allowed: true } + - handle: 0x200000ad + - next_table: 1 + - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Kaluaaha: $adf_f1(0..31) } + - set HillTop.RossFork.Glenmora, Avondale + - set HillTop.Maddock.Kaluaaha, Kaluaaha + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Boerne, 1 + - set HillTop.RossFork.Suttle, 1 + Sequim(2, 0): + - default_action: { allowed: true } + - handle: 0x200000ae + - next_table: 2 + - { } + default_action: Sequim + idletime: + row: 4 + bus: 0 + column: [ 0, 1, 2, 3, 4 ] + precision: 1 + sweep_interval: 7 + notification: enable + per_flow_enable: false + action _Nooksack$st1$action_data: + p4: { name: Nooksack$action } + row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4 ] + word: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - 5 + - 5 + - 5 + - [ 4, 5 ] + - 5 + - [ 4, 5 ] + - 5 + - [ 3, 4, 5 ] + - 5 + - [ 3, 4, 5 ] + - 5 + - 4 + vpns: + - [ 0 ] + - [ 1 ] + - [ 2 ] + - [ 3, 4 ] + - [ 5 ] + - [ 6, 7 ] + - [ 8 ] + - [ 9, 10, 11 ] + - [ 12 ] + - [ 13, 14, 15 ] + - [ 16 ] + - [ 17 ] + home_row: + - 15 + format Milano: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Biggers: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + action_bus: { 34..35 : $adf_h1, 100..103 : $adf_f1, 32..35 : $adf_f0 } + hash_action _Buras 2: + p4: { name: Buras, size: 256, disable_atomic_modify : true } + p4_param_order: + HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } + row: 3 + bus: 1 + hash_dist: + 0: { hash: 1, mask: 0xff, shift: 5 } + input_xbar: + exact group 1: { 4: HillTop.Bessie.Miranda } + hash 2: + 0..7: stripe(HillTop.Bessie.Miranda) + hash group 1: + table: [2] + seed: 0x0 + gateway: + name: _Buras-gateway + row: 2 + bus: 0 + unit: 1 + 0x0: _Mabana + miss: _Mabana + condition: + expression: "true(always hit)" + true: _Mabana + false: _Mabana + next: [] + action: _Buras$action_data(hash_dist 0, $DEFAULT) + instruction: _Buras($DEFAULT, $DEFAULT) + actions: + Eudora(0, 4): + - p4_param_order: { Kaluaaha: 16, Calcasieu: 16, Chevak: 16, Mendocino: 16, LasVegas: 8, PineCity: 6, Exton: 8, Noyes: 8, Peebles: 1 } + - default_action: { allowed: true } + - handle: 0x2000005f + - next_table: 0 + - { Peebles: $adf_b0(5..5), Noyes: $adf_b1(0..7), LasVegas: $adf_b2(0..7), Exton: $adf_b3(0..7), Chevak: $adf_h2(0..15), Mendocino: $adf_h3(0..15), Calcasieu: $adf_h4(0..15), Kaluaaha: $adf_h5(0..15), PineCity: $adf_h6(6..11) } + - and HillTop.Savery.Kaluaaha, HillTop.Bessie.Kaluaaha, Kaluaaha + - and HillTop.Savery.Calcasieu, HillTop.Bessie.Calcasieu, Calcasieu + - and HillTop.Savery.Chevak, HillTop.Bessie.Chevak, Chevak + - and HillTop.Savery.Mendocino, HillTop.Bessie.Mendocino, Mendocino + - and HillTop.Savery.LasVegas, HillTop.Bessie.LasVegas, LasVegas + - and HillTop.Savery.Exton, HillTop.Bessie.Exton, Exton + - and HillTop.Savery.Noyes, HillTop.Bessie.Noyes, Noyes + - and B10, Peebles, B9 + - and H85, PineCity, H90 + default_action: Eudora + default_action_parameters: + Kaluaaha: "0xffff" + Calcasieu: "0xffff" + Chevak: "0xffff" + Mendocino: "0xffff" + LasVegas: "0xff" + PineCity: "0x3f" + Exton: "0xff" + Noyes: "0xff" + Peebles: "0x1" + action _Buras$action_data: + p4: { name: Buras$action, how_referenced: direct } + row: 10 + column: 3 + vpns: [ 0 ] + home_row: + - 10 + format Eudora: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_b2: 16..23, $adf_b3: 24..31, $adf_h2: 32..47, $adf_h3: 48..63, $adf_h4: 64..79, $adf_h5: 80..95, $adf_h6: 96..111 } + action_bus: { 16 : $adf_b0, 17 : $adf_b1, 18 : $adf_b2, 19 : $adf_b3, 64..65 : $adf_h4, 66..67 : $adf_h5, 68..69 : $adf_h6, 36..37 : $adf_h2, 38..39 : $adf_h3 } + ternary_match _Mabana 3: + p4: { name: Mabana, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Naruna: { type: exact, size: 3, full_size: 3, key_name: "RossFork.Naruna" } + HillTop.RossFork.Joslin: { type: exact, size: 3, full_size: 3, key_name: "RossFork.Joslin" } + Millston.GlenAvon.$valid: { type: exact, size: 1, full_size: 1, key_name: "GlenAvon" } + Millston.GlenAvon.Rexville: { type: ternary, size: 14, full_size: 16, key_name: "GlenAvon.Rexville" } + Millston.Maumee.Norwood: { type: ternary, size: 14, full_size: 16, key_name: "Maumee.Norwood" } + row: [ 8, 9 ] + bus: [ 0, 0 ] + column: + - 0 + - 0 + input_xbar: + ternary group 1: { 5: HillTop.RossFork.Joslin, 8: Millston.GlenAvon.Rexville(8..13), 16: Millston.GlenAvon.Rexville(0..7), 29: HillTop.RossFork.Naruna.2-2, 32: Millston.Maumee.Norwood.8-15(0..5) } + ternary group 2: { 0: Millston.Maumee.Norwood.0-7, 12: Millston.GlenAvon.$valid, 19: HillTop.RossFork.Naruna.0-1 } + match: + - { group: 1, dirtcam: 0x155 } + - { group: 2, dirtcam: 0x15 } + hit: [ _Somis ] + miss: _Somis + indirect: _Mabana$tind + ternary_indirect _Mabana$tind: + row: 1 + bus: 0 + column: 3 + input_xbar: + ternary group 1: { 5: HillTop.RossFork.Joslin, 8: Millston.GlenAvon.Rexville(8..13), 16: Millston.GlenAvon.Rexville(0..7), 29: HillTop.RossFork.Naruna.2-2, 32: Millston.Maumee.Norwood.8-15(0..5) } + ternary group 2: { 0: Millston.Maumee.Norwood.0-7, 12: Millston.GlenAvon.$valid, 19: HillTop.RossFork.Naruna.0-1 } + format: { action: 0..0, immediate: 1..2 } + action_bus: { 40..41 : immediate(0..1) } + instruction: _Mabana$tind(action, $DEFAULT) + actions: + Sneads(0, 5): + - p4_param_order: { Bradner: 2 } + - default_action: { allowed: true } + - handle: 0x20000060 + - next_table: 0 + - { Bradner: immediate(0..1) } + - set HillTop.RossFork.Bradner, Bradner + Hemlock(1, 6): + - default_action: { allowed: true } + - handle: 0x20000061 + - next_table: 0 + - { } + - set HillTop.RossFork.Ravena, 1 + default_action: Hemlock + ternary_match _Somis 4: + p4: { name: Somis, size: 1024, disable_atomic_modify : true } + p4_param_order: + HillTop.Lamona.Fristoe: { type: ternary, size: 14, full_size: 14, key_name: "Lamona.Fristoe" } + HillTop.Tiburon.Arnold: { type: ternary, size: 9, full_size: 9, key_name: "Tiburon.Arnold" } + HillTop.Edwards.PineCity: { type: ternary, size: 6, full_size: 6, key_name: "Edwards.PineCity" } + HillTop.Bessie.Heuvelton: { type: ternary, size: 16, full_size: 16, key_name: "Bessie.Heuvelton" } + HillTop.Bessie.Chavies: { type: ternary, size: 16, full_size: 16, key_name: "Bessie.Chavies" } + HillTop.RossFork.Ocoee: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } + HillTop.RossFork.Exton: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Exton" } + Millston.Grays.Chevak: { type: ternary, size: 16, full_size: 16, key_name: "Grays.Chevak" } + Millston.Grays.Mendocino: { type: ternary, size: 16, full_size: 16, key_name: "Grays.Mendocino" } + Millston.Grays.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Grays" } + HillTop.Bessie.Peebles: { type: ternary, size: 1, full_size: 1, key_name: "Bessie.Peebles" } + HillTop.Bessie.Noyes: { type: ternary, size: 8, full_size: 8, key_name: "Bessie.Noyes" } + HillTop.RossFork.Naruna: { type: ternary, size: 3, full_size: 3, key_name: "RossFork.Naruna" } + row: [ 0, 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + input_xbar: + ternary group 3: { 0: HillTop.Bessie.Heuvelton(6..13), 8: HillTop.Lamona.Fristoe(8..13), 16: Millston.Grays.Chevak(8..15), 26: HillTop.Bessie.Heuvelton(0..5), 32: HillTop.Lamona.Fristoe(0..7) } + ternary group 4: { 0: Millston.Grays.Chevak(0..7), 8: Millston.Grays.Mendocino(8..15), 16: Millston.Grays.Mendocino(0..7), 24: HillTop.Tiburon.Arnold(8), 32: HillTop.Tiburon.Arnold(0..7) } + ternary group 5: { 0: HillTop.Bessie.Chavies, 16: HillTop.Edwards.PineCity, 29: HillTop.RossFork.Naruna.2-2, 35: Millston.Grays.$valid } + ternary group 6: { 0: HillTop.Bessie.Noyes, 8: HillTop.RossFork.Ocoee, 16: HillTop.RossFork.Exton, 27: HillTop.RossFork.Naruna.0-1 } + byte group 0: { 5: HillTop.Bessie.Peebles } + byte group 3: { 0: HillTop.Bessie.Heuvelton(14..15) } + match: + - { group: 3, byte_group: 0, byte_config: 1, dirtcam: 0x555 } + - { group: 4, dirtcam: 0x155 } + - { group: 5, byte_group: 3, byte_config: 0, dirtcam: 0x555 } + - { group: 6, dirtcam: 0x55 } + hit: [ _Sanborn ] + miss: _Sanborn + indirect: _Somis$tind + ternary_indirect _Somis$tind: + row: 0 + bus: 0 + column: 3 + input_xbar: + ternary group 3: { 0: HillTop.Bessie.Heuvelton(6..13), 8: HillTop.Lamona.Fristoe(8..13), 16: Millston.Grays.Chevak(8..15), 26: HillTop.Bessie.Heuvelton(0..5), 32: HillTop.Lamona.Fristoe(0..7) } + ternary group 4: { 0: Millston.Grays.Chevak(0..7), 8: Millston.Grays.Mendocino(8..15), 16: Millston.Grays.Mendocino(0..7), 24: HillTop.Tiburon.Arnold(8), 32: HillTop.Tiburon.Arnold(0..7) } + ternary group 5: { 0: HillTop.Bessie.Chavies, 16: HillTop.Edwards.PineCity, 29: HillTop.RossFork.Naruna.2-2, 35: Millston.Grays.$valid } + ternary group 6: { 0: HillTop.Bessie.Noyes, 8: HillTop.RossFork.Ocoee, 16: HillTop.RossFork.Exton, 27: HillTop.RossFork.Naruna.0-1 } + byte group 0: { 5: HillTop.Bessie.Peebles } + byte group 3: { 0: HillTop.Bessie.Heuvelton(14..15) } + format: { action: 0..0, immediate: 1..10 } + action_bus: { 44..45 : immediate(0..9) } + instruction: _Somis$tind(action, $DEFAULT) + actions: + Level(0, 7): + - default_action: { allowed: true } + - handle: 0x200000a4 + - next_table: 0 + - { } + - set HillTop.RossFork.Level, 1 + Tullytown(1, 8): + - p4_param_order: { Heaton: 10 } + - default_action: { allowed: true } + - handle: 0x200000a5 + - next_table: 0 + - { Heaton: immediate(0..9) } + - set HillTop.Minturn.Grassflat, Heaton + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x200000a6 + - next_table: 0 + - { } + default_only_action: NoAction + exact_match _Sanborn 5: + p4: { name: Sanborn, size: 16384, disable_atomic_modify : true } + p4_param_order: + HillTop.Wisdom.Adona: { type: exact, size: 24, full_size: 24, key_name: "Wisdom.Adona" } + HillTop.Wisdom.Connell: { type: exact, size: 24, full_size: 24, key_name: "Wisdom.Connell" } + HillTop.Wisdom.Nenana: { type: exact, size: 12, full_size: 12, key_name: "Wisdom.Nenana" } + row: [ 2, 1 ] + bus: [ 0, 0 ] + column: + - [ 2, 6, 7, 8, 9, 10 ] + - [ 2, 6 ] + stash: + row: [ 2 ] + col: [ 2 ] + unit: [ 0 ] + ways: + - [2, 0, 0x1, [2, 2], [2, 6]] + - [2, 1, 0x2, [2, 7], [2, 8]] + - [2, 2, 0x4, [2, 9], [2, 10]] + - [2, 3, 0x8, [1, 2], [1, 6]] + input_xbar: + exact group 2: { 0: HillTop.Wisdom.Connell.16-23, 8: HillTop.Wisdom.Adona, 32: HillTop.Wisdom.Nenana, 48: HillTop.Wisdom.Connell.0-15 } + hash 4: + 0..6: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(0..6) + 7..9: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(8..10) + 40: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(11) + 11..17: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(0..6) + 18..19: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(8..9) + 10: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(11) + 41: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(10) + 22..28: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(0..6) + 29: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(8) + 20..21: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(10..11) + 42: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(9) + 33..39: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(0..6) + 30..32: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(9..11) + 43: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(8) + hash group 2: + table: [4] + seed: 0x158d36c8b1b + format: { action(0): 0..0, immediate(0): 2..3, version(0): 112..115, match(0): [87..87, 32..79 ], action(1): 1..1, immediate(1): 4..5, version(1): 116..119, match(1): [7..7, 88..111, 8..31 ] } + match: [ HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15(0..7), HillTop.Wisdom.Connell.0-15(8..15), HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona(0..7), HillTop.Wisdom.Adona(8..15), HillTop.Wisdom.Adona(16..23) ] + gateway: + name: cond-25 + input_xbar: + exact group 0: { 110: HillTop.RossFork.Tenino } + row: 2 + bus: 1 + unit: 0 + match: { 6: HillTop.RossFork.Tenino } + 0b*1: run_table + miss: _Uvalde + condition: + expression: "(HillTop.RossFork.Tenino == 1)" + true: _Sanborn + false: _Uvalde + hit: [ _Uvalde ] + miss: _Uvalde + action_bus: { 48..49 : immediate(0..1) } + action: _Sanborn$action_data($DIRECT, $DEFAULT) + instruction: _Sanborn(action, $DEFAULT) + actions: + CassCity(1, 9): + - p4_param_order: { Townville: 16, Monahans: 1, Pinole: 1 } + - default_action: { allowed: true } + - handle: 0x200000b1 + - next_table: 0 + - { Townville: $adf_h0(0..15), Pinole: immediate(0..0), Monahans: immediate(1..1) } + - set HillTop.Moose.Townville, Townville + - set HillTop.Moose.Monahans, Monahans + - set HillTop.Moose.Pinole, Pinole + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x200000b2 + - next_table: 0 + - { } + default_only_action: NoAction + action _Sanborn$action_data: + p4: { name: Sanborn$action } + row: 14 + column: [ 3, 4 ] + vpns: [ 0, 1 ] + home_row: + - 14 + format CassCity: { $adf_h0: 0..15 } + action_bus: { 52..53 : $adf_h0 } + ternary_match _Uvalde 6: + p4: { name: Uvalde, size: 1, disable_atomic_modify : true } + gateway: + name: cond-26 + input_xbar: + exact group 1: { 64: HillTop.Naubinway.Bonduel } + row: 0 + bus: 1 + unit: 1 + match: { 0: HillTop.Naubinway.Bonduel(0..7), 8: HillTop.Naubinway.Bonduel(8..13) } + 0b**00000000000000: Sodaville_0 + miss: run_table + condition: + expression: "(HillTop.Naubinway.Bonduel != 0)" + true: _Uvalde + false: Sodaville_0 + hit: [ _Bonduel ] + miss: _Bonduel + indirect: _Uvalde$tind + ternary_indirect _Uvalde$tind: + row: 2 + bus: 1 + format: { action: 0..0 } + instruction: _Uvalde$tind(action, $DEFAULT) + actions: + Uniopolis(1, 10): + - default_action: { allowed: true } + - handle: 0x200000b5 + - next_table: 0 + - set HillTop.RossFork.Uvalde, HillTop.RossFork.Kapalua + default_action: Uniopolis + hash_action _Bonduel 7: + p4: { name: Bonduel, size: 16384, disable_atomic_modify : true } + p4_param_order: + HillTop.Naubinway.Bonduel: { type: exact, size: 14, full_size: 14, key_name: "Naubinway.Bonduel" } + row: 0 + bus: 1 + hash_dist: + 1: { hash: 1, mask: 0x3fff, shift: 4 } + input_xbar: + exact group 1: { 64: HillTop.Naubinway.Bonduel } + hash 3: + 16..29: stripe(HillTop.Naubinway.Bonduel) + hash group 1: + table: [3] + seed: 0x0 + gateway: + name: cond-27 + input_xbar: + exact group 2: { 68: HillTop.Naubinway.Bonduel(4..13) } + row: 0 + bus: 0 + unit: 0 + payload: 0x1 + format: { action: 0..0 } + match: { 4: HillTop.Naubinway.Bonduel(4..7), 8: HillTop.Naubinway.Bonduel(8..13) } + 0b**0000000000: run_table + miss: _GunnCity + condition: + expression: "(HillTop.Naubinway.Bonduel & 16368 == 0)" + true: _Kempton + false: _GunnCity + next: _Kempton + action: _Bonduel$action_data(hash_dist 1, $DEFAULT) + instruction: _Bonduel(action, $DEFAULT) + actions: + Ossining(1, 11): + - p4_param_order: { Adona: 24, Connell: 24, Nason: 12 } + - default_action: { allowed: true } + - handle: 0x200000b9 + - next_table: 0 + - { Nason: $adf_h0(0..11), Connell.0-15: $adf_h1(0..15), $data0: $adf_f1(0..31), Connell.16-23: $data0(0..7), Adona: $data0(8..31) } + - set HillTop.Wisdom.Connell.0-15, Connell.0-15 + - set HillTop.Wisdom.Nenana, Nason + - set W13, $data0 + default_action: Ossining + default_action_parameters: + Adona: "0x0" + Connell: "0x0" + Nason: "0x0" + action _Bonduel$action_data: + p4: { name: Bonduel$action, how_referenced: direct } + row: [ 4, 3, 2, 1 ] + word: [ 0, 0, 0, 0 ] + column: + - 5 + - [ 2, 3, 4, 5 ] + - [ 4, 5 ] + - 0 + vpns: + - [ 0 ] + - [ 1, 2, 3, 4 ] + - [ 5, 6 ] + - [ 7 ] + home_row: + - 4 + format Ossining: { $adf_h0: 0..15, $adf_h1: 16..31, $adf_f1: 32..63 } + action_bus: { 56..57 : $adf_h0, 58..59 : $adf_h1, 116..119 : $adf_f1 } + exact_match _Kempton 8: + p4: { name: Kempton, size: 16, disable_atomic_modify : true } + p4_param_order: + HillTop.Naubinway.Bonduel: { type: exact, size: 4, full_size: 14, key_name: "Naubinway.Bonduel" } + row: 0 + bus: 0 + column: 2 + stash: + row: [ 0 ] + col: [ 2 ] + unit: [ 0 ] + ways: + - [3, 0, 0x0, [0, 2]] + input_xbar: + exact group 2: { 64: HillTop.Naubinway.Bonduel(0..3) } + hash 5: + 0..3: HillTop.Naubinway.Bonduel(0..3) + hash group 3: + table: [5] + seed: 0x0 + format: { immediate(0): 0..7, version(0): 112..115 } + hit: [ Sodaville_0 ] + miss: Sodaville_0 + action_bus: { 0 : immediate(0..7) } + instruction: _Kempton($DEFAULT, $DEFAULT) + actions: + Moosic(0, 12): + - p4_param_order: { Blencoe: 8 } + - default_action: { allowed: true } + - handle: 0x200000b6 + - next_table: 0 + - { Blencoe: immediate(0..7) } + - set HillTop.Wisdom.Havana, 1 + - set HillTop.Wisdom.Blencoe, Blencoe + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x200000b7 + - next_table: 0 + - { } + default_only_action: NoAction + hash_action _GunnCity 9: + p4: { name: GunnCity, size: 16384, disable_atomic_modify : true } + p4_param_order: + HillTop.Naubinway.Bonduel: { type: exact, size: 14, full_size: 14, key_name: "Naubinway.Bonduel" } + row: 2 + bus: 1 + hash_dist: + 2: { hash: 1, mask: 0x3fff, shift: 3 } + input_xbar: + exact group 1: { 64: HillTop.Naubinway.Bonduel } + hash 3: + 32..45: stripe(HillTop.Naubinway.Bonduel) + hash group 1: + table: [3] + seed: 0x0 + gateway: + name: _GunnCity-gateway + row: 1 + bus: 0 + unit: 1 + 0x0: Sodaville_0 + miss: Sodaville_0 + condition: + expression: "true(always hit)" + true: Sodaville_0 + false: Sodaville_0 + next: [] + action: _GunnCity$action_data(hash_dist 2, $DEFAULT) + instruction: _GunnCity($DEFAULT, $DEFAULT) + actions: + Marquand(0, 13): + - p4_param_order: { Morstein: 20, Placedo: 10, TroutRun: 2 } + - default_action: { allowed: true } + - handle: 0x200000b8 + - next_table: 0 + - { Morstein: $adf_f0(0..19), TroutRun: $adf_h1(4..5) } + - set HillTop.Wisdom.Piqua, 1 + - set HillTop.Wisdom.Morstein, Morstein + - set HillTop.RossFork.TroutRun, TroutRun + default_action: Marquand + default_action_parameters: + Morstein: "0x1ff" + Placedo: "0x0" + TroutRun: "0x0" + action _GunnCity$action_data: + p4: { name: GunnCity$action, how_referenced: direct } + row: 1 + column: [ 1, 2, 3, 4 ] + vpns: [ 0, 1, 2, 3 ] + home_row: + - 1 + format Marquand: { $adf_f0: 0..31, $adf_h1: 16..31 } + action_bus: { 62..63 : $adf_h1, 60..63 : $adf_f0 } + exact_match Sodaville_0 10: + p4: { name: Sodaville, size: 1024, disable_atomic_modify : true } + p4_param_order: + HillTop.Wisdom.Onycha: { type: exact, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } + HillTop.RossFork.Ocoee: { type: exact, size: 1, full_size: 8, key_name: "RossFork.Ocoee", start_bit: 7 } + Millston.GlenAvon.$valid: { type: exact, size: 1, full_size: 1, key_name: "GlenAvon" } + Millston.Maumee.$valid: { type: exact, size: 1, full_size: 1, key_name: "Maumee" } + row: 1 + bus: 1 + column: 7 + stash: + row: [ 1 ] + col: [ 7 ] + unit: [ 0 ] + ways: + - [3, 1, 0x0, [1, 7]] + input_xbar: + exact group 2: { 81: HillTop.Wisdom.Onycha, 90: Millston.Maumee.$valid, 103: HillTop.RossFork.Ocoee(7), 108: Millston.GlenAvon.$valid } + hash 5: + 10..12: HillTop.Wisdom.Onycha + 13: Millston.Maumee.$valid + 14: HillTop.RossFork.Ocoee(7) + 15: Millston.GlenAvon.$valid + hash group 3: + table: [5] + seed: 0x0 + format: { action(0): 0..1, immediate(0): 2..17, version(0): 112..115 } + hit: [ _Weissert ] + miss: _Weissert + action_bus: { 20 : immediate(0..7), 21 : immediate(8..15) } + instruction: Sodaville_0(action, $DEFAULT) + actions: + Boyes(0, 14): + - p4_param_order: { Renfroe: 1 } + - default_action: { allowed: true } + - handle: 0x200000e3 + - next_table: 0 + - { Renfroe: immediate(0..0), $constant0: immediate(8..15), $constant0: 128 } + - set HillTop.Wisdom.Dyess, Renfroe + - or Millston.GlenAvon.Ocoee, Millston.GlenAvon.Ocoee, $constant0 + McCallum(1, 16): + - p4_param_order: { Renfroe: 1 } + - default_action: { allowed: true } + - handle: 0x200000e4 + - next_table: 0 + - { Renfroe: immediate(0..0), $constant0: immediate(8..15), $constant0: 128 } + - set HillTop.Wisdom.Dyess, Renfroe + - or Millston.Maumee.Dassel, Millston.Maumee.Dassel, $constant0 + Waucousta(2, 15): + - default_action: { allowed: true } + - handle: 0x200000e5 + - next_table: 0 + - { } + - set Millston.GlenAvon.$valid, 0 + - set Millston.Wondervu$0.$valid, 0 + - set Millston.Calabash.McCaulley.0-7, HillTop.RossFork.McCaulley.0-7 + - set Millston.Calabash.McCaulley.8-15, HillTop.RossFork.McCaulley.8-15 + Selvin(3, 17): + - default_action: { allowed: true } + - handle: 0x200000e6 + - next_table: 0 + - { } + - set Millston.Maumee.$valid, 0 + - set Millston.Wondervu$0.$valid, 0 + - set Millston.Calabash.McCaulley.0-7, HillTop.RossFork.McCaulley.0-7 + - set Millston.Calabash.McCaulley.8-15, HillTop.RossFork.McCaulley.8-15 + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x200000e7 + - next_table: 0 + - { } + default_only_action: NoAction + ternary_match _Weissert 11: + p4: { name: Weissert, size: 306, disable_atomic_modify : true } + p4_param_order: + HillTop.Edwards.AquaPark: { type: ternary, size: 2, full_size: 2, key_name: "Edwards.AquaPark" } + HillTop.Edwards.McGrady: { type: ternary, size: 3, full_size: 3, key_name: "Edwards.McGrady" } + HillTop.Edwards.RedElm: { type: ternary, size: 3, full_size: 3, key_name: "Edwards.RedElm" } + HillTop.Edwards.PineCity: { type: ternary, size: 6, full_size: 6, key_name: "Edwards.PineCity" } + HillTop.Edwards.Satolah: { type: ternary, size: 1, full_size: 1, key_name: "Edwards.Satolah" } + HillTop.Wisdom.Onycha: { type: ternary, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } + Millston.Hayfield.AquaPark: { type: ternary, size: 2, full_size: 2, key_name: "Hayfield.AquaPark" } + Millston.Hayfield.Vichy: { type: ternary, size: 3, full_size: 3, key_name: "Hayfield.Vichy" } + row: 6 + bus: 1 + column: 1 + indirect_bus: 3 + input_xbar: + ternary group 7: { 1: HillTop.Wisdom.Onycha, 8: HillTop.Edwards.PineCity, 18: HillTop.Edwards.McGrady, 21: HillTop.Edwards.AquaPark, 25: HillTop.Edwards.Satolah, 35: Millston.Hayfield.Vichy, 38: Millston.Hayfield.AquaPark } + byte group 1: { 5: HillTop.Edwards.RedElm } + match: + - { group: 7, byte_group: 1, byte_config: 1, dirtcam: 0x555 } + hit: [ _Barnsboro ] + miss: _Barnsboro + action: _Weissert$action_data($DIRECT, $DEFAULT) + instruction: _Weissert($DEFAULT, $DEFAULT) + actions: + Anawalt(0, 18): + - p4_param_order: { Vichy: 3, Asharoken: 5 } + - default_action: { allowed: true } + - handle: 0x200000a3 + - next_table: 0 + - { Asharoken: $adf_b0(0..4), Vichy: $adf_b0(5..7) } + - set HillTop.Freeny.Dunedin, Vichy + - set ig_intr_md_for_tm.qid, Asharoken + default_action: Anawalt + default_action_parameters: + Vichy: "0x0" + Asharoken: "0x0" + action _Weissert$action_data: + p4: { name: Weissert$action } + row: 12 + column: 3 + vpns: [ 0 ] + home_row: + - 12 + format Anawalt: { $adf_b0: 0..7 } + action_bus: { 2 : $adf_b0 } + ternary_match _Barnsboro 12: + p4: { name: Barnsboro, size: 1, disable_atomic_modify : true } + gateway: + name: cond-40 + input_xbar: + exact group 2: { 105: Millston.Hayfield.$valid } + row: 1 + bus: 1 + unit: 0 + match: { 1: Millston.Hayfield.$valid } + 0b******0: run_table + miss: _Lowemont + condition: + expression: "(Millston.Hayfield.$valid == 1 == 0)" + true: _Barnsboro + false: _Lowemont + hit: [ _Standard ] + miss: _Standard + indirect: _Barnsboro$tind + ternary_indirect _Barnsboro$tind: + row: 3 + bus: 0 + format: { action: 0..0, immediate: 1..2 } + action_bus: { 4 : immediate(0..1) } + instruction: _Barnsboro$tind(action, $DEFAULT) + actions: + NorthRim(1, 19): + - p4_param_order: { Oilmont: 1, Tornillo: 1 } + - default_action: { allowed: true } + - handle: 0x200000f3 + - next_table: 0 + - { $data0: immediate(0..1), Oilmont: $data0(0..0), Tornillo: $data0(1..1) } + - set B7(4..5), $data0 + default_action: NorthRim + default_action_parameters: + Oilmont: "0x0" + Tornillo: "0x0" +stage 8 ingress: + exact_match _Standard 0: + p4: { name: Standard, size: 1024, disable_atomic_modify : true } + p4_param_order: + HillTop.Edwards.AquaPark: { type: exact, size: 2, full_size: 2, key_name: "Edwards.AquaPark" } + HillTop.Edwards.Oilmont: { type: exact, size: 1, full_size: 1, key_name: "Edwards.Oilmont" } + HillTop.Edwards.Tornillo: { type: exact, size: 1, full_size: 1, key_name: "Edwards.Tornillo" } + HillTop.Freeny.Dunedin: { type: exact, size: 3, full_size: 3, key_name: "Freeny.Dunedin" } + HillTop.Wisdom.Onycha: { type: exact, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } + row: 5 + bus: 1 + column: 7 + stash: + row: [ 5 ] + col: [ 7 ] + unit: [ 0 ] + ways: + - [0, 0, 0x0, [5, 7]] + input_xbar: + exact group 0: { 1: HillTop.Wisdom.Onycha, 13: HillTop.Edwards.AquaPark, 20: HillTop.Edwards.Oilmont, 21: HillTop.Edwards.Tornillo, 24: HillTop.Freeny.Dunedin } + hash 0: + 0..2: HillTop.Wisdom.Onycha + 3..4: HillTop.Edwards.AquaPark + 5: HillTop.Edwards.Oilmont + 6: HillTop.Edwards.Tornillo + 7..9: HillTop.Freeny.Dunedin + hash group 0: + table: [0] + seed: 0x0 + format: { action(0): 0..1, immediate(0): 2..10, version(0): 112..115 } + hit: [ _Lowemont ] + miss: _Lowemont + action_bus: { 32..33 : immediate(0..8) } + instruction: _Standard(action, $DEFAULT) + actions: + Wardville(0, 1): + - p4_param_order: { PineCity: 6 } + - default_action: { allowed: true } + - handle: 0x200000f4 + - next_table: 0 + - { PineCity: immediate(0..5) } + - set HillTop.Edwards.PineCity, PineCity + Oregon(1, 2): + - p4_param_order: { RedElm: 3 } + - default_action: { allowed: true } + - handle: 0x200000f5 + - next_table: 0 + - { RedElm: immediate(0..2) } + - set HillTop.Edwards.RedElm, RedElm + Ranburne(2, 4): + - p4_param_order: { RedElm: 3, PineCity: 6 } + - default_action: { allowed: true } + - handle: 0x200000f6 + - next_table: 0 + - { PineCity: immediate(0..5), RedElm: immediate(6..8) } + - set HillTop.Edwards.RedElm, RedElm + - set HillTop.Edwards.PineCity, PineCity + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x200000f7 + - next_table: 0 + - { } + default_only_action: NoAction + exact_match _Lowemont 1: + p4: { name: Lowemont, size: 16384, disable_atomic_modify : true } + p4_param_order: + HillTop.Maddock.Kaluaaha: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } + HillTop.Salix.Hueytown: { type: exact, size: 16, full_size: 16, key_name: "Salix.Hueytown" } + row: 0 + bus: 0 + column: [ 2, 3, 4, 6, 7, 8, 9, 10 ] + stash: + row: [ 0 ] + col: [ 2 ] + unit: [ 0 ] + ways: + - [0, 1, 0x3, [0, 2], [0, 3], [0, 4], [0, 6]] + - [0, 2, 0xc, [0, 7], [0, 8], [0, 9], [0, 10]] + input_xbar: + exact group 0: { 32: HillTop.Maddock.Kaluaaha, 64: HillTop.Salix.Hueytown } + hash 0: + 10..19: random(HillTop.Maddock.Kaluaaha) + 40..41: random(HillTop.Maddock.Kaluaaha) + 20..29: random(HillTop.Maddock.Kaluaaha) + 42..43: random(HillTop.Maddock.Kaluaaha) + hash 1: + 10..17: random(HillTop.Salix.Hueytown(12..15)) ^ HillTop.Salix.Hueytown(0..7) + 18..19: random(HillTop.Salix.Hueytown(12..15)) ^ HillTop.Salix.Hueytown(8..9) + 40..41: random(HillTop.Salix.Hueytown(12..15)) ^ HillTop.Salix.Hueytown(10..11) + 21..28: random(HillTop.Salix.Hueytown(12..15)) ^ HillTop.Salix.Hueytown(0..7) + 29: random(HillTop.Salix.Hueytown(12..15)) ^ HillTop.Salix.Hueytown(8) + 20: random(HillTop.Salix.Hueytown(12..15)) ^ HillTop.Salix.Hueytown(11) + 42..43: random(HillTop.Salix.Hueytown(12..15)) ^ HillTop.Salix.Hueytown(9..10) + hash group 0: + table: [0, 1] + seed: 0xc0032cb5c00 + format: { action(0): 0..0, immediate(0): 2..2, version(0): 112..115, match(0): [68..71, 32..63 ], action(1): 1..1, immediate(1): 3..3, version(1): 116..119, match(1): [108..111, 72..103 ] } + match: [ HillTop.Salix.Hueytown(12..15), HillTop.Maddock.Kaluaaha(0..7), HillTop.Maddock.Kaluaaha(8..15), HillTop.Maddock.Kaluaaha(16..23), HillTop.Maddock.Kaluaaha(24..31) ] + gateway: + name: cond-28 + input_xbar: + exact group 0: { 27: HillTop.RossFork.Naruna.0-1, 64: HillTop.Salix.Hueytown, 85: HillTop.RossFork.Naruna.2-2 } + row: 3 + bus: 1 + unit: 0 + match: { 0: HillTop.Salix.Hueytown(0..7), 8: HillTop.Salix.Hueytown(8..15), 19: HillTop.RossFork.Naruna.0-1, 29: HillTop.RossFork.Naruna.2-2 } + 0x****0000: _Cranbury + 0b**0********01*******************: run_table + miss: _Cranbury + condition: + expression: "(HillTop.Salix.Hueytown != 0 && HillTop.RossFork.Naruna == 1)" + true: _Lowemont + false: _Cranbury + hit: [ _Cranbury ] + miss: _Cranbury + action_bus: { 36..37 : immediate(0..0) } + action: _Lowemont$action_data($DIRECT, $DEFAULT) + instruction: _Lowemont(action, $DEFAULT) + actions: + Norridge(1, 3): + - p4_param_order: { Townville: 16, Pinole: 1 } + - default_action: { allowed: true } + - handle: 0x200000ba + - next_table: 0 + - { Townville.12-15: $adf_h0(0..3), Townville.0-11: $adf_h0(4..15), Pinole: immediate(0..0) } + - set HillTop.Komatke.Townville.0-11, Townville.0-11 + - set HillTop.Komatke.Townville.12-15, Townville.12-15 + - set HillTop.Komatke.Monahans, 1 + - set HillTop.Komatke.Pinole, Pinole + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x200000bb + - next_table: 0 + - { } + default_only_action: NoAction + idletime: + row: 4 + bus: 1 + column: [ 0, 1 ] + precision: 1 + sweep_interval: 7 + notification: enable + per_flow_enable: false + action _Lowemont$action_data: + p4: { name: Lowemont$action } + row: 9 + column: [ 1, 2 ] + vpns: [ 0, 1 ] + home_row: + - 9 + format Norridge: { $adf_h0: 0..15 } + action_bus: { 40..41 : $adf_h0 } + exact_match _Cranbury 2: + p4: { name: Cranbury, size: 32768, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Ocoee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } + HillTop.Maddock.Kaluaaha: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } + Millston.Grays.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Grays.Chevak" } + HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } + Millston.Grays.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Grays.Mendocino" } + row: [ 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 6 ] + - [ 2, 3, 4, 6 ] + - [ 2, 3, 4, 6 ] + - [ 2, 3, 4, 6 ] + - [ 2, 3, 4, 6 ] + - [ 2, 3, 4, 6 ] + - [ 2, 3, 4, 6 ] + stash: + row: [ 1, 2, 3, 4, 5, 6, 7 ] + col: [ 2, 2, 2, 2, 2, 2, 2 ] + unit: [ 1, 1, 1, 1, 1, 1, 1 ] + ways: + - [1, 0, 0x0, [7, 2], [6, 2], [5, 2], [4, 2], [3, 2], [2, 2], [1, 2]] + - [1, 1, 0x0, [7, 3], [6, 3], [5, 3], [4, 3], [3, 3], [2, 3], [1, 3]] + - [1, 2, 0x0, [7, 4], [6, 4], [5, 4], [4, 4], [3, 4], [2, 4], [1, 4]] + - [1, 3, 0x0, [7, 6], [6, 6], [5, 6], [4, 6], [3, 6], [2, 6], [1, 6]] + input_xbar: + exact group 1: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.Maddock.Kaluaaha, 64: Millston.Grays.Chevak, 80: Millston.Grays.Mendocino, 96: HillTop.RossFork.Ocoee } + hash 2: + 0..9: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) + 10..19: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) + 20..29: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) + 30..39: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) + hash 3: + 0..1: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) + 2..9: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee + 11..12: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) + 13..19: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(0..6) + 10: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(7) + 22..23: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) + 24..29: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(0..5) + 20..21: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(6..7) + 33..34: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) + 35..39: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(0..4) + 30..32: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(5..7) + hash group 1: + table: [2, 3] + seed: 0x62805adaf2 + format: { action(0): 2..3, version(0): 4..7, match(0): [98..103, 8..95 ], action(1): 0..1, version(1): 244..247, match(1): [506..511, 104..127, 224..239, 248..255, 352..367, 376..383, 480..495 ], action(2): 128..129, version(2): 240..243, match(2): 130..223, action(3): 256..257, version(3): 368..371, match(3): 258..351, action(4): 384..385, version(4): 496..499, match(4): 386..479, action(5): 512..513, version(5): 624..627, match(5): 514..607, action(6): 640..641, version(6): 752..755, match(6): 642..735, action(7): 768..769, version(7): 880..883, match(7): 770..863 } + match: [ Millston.Grays.Chevak(2..7), Millston.Grays.Chevak(8..15), Millston.Grays.Mendocino(0..7), Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31), HillTop.Maddock.Kaluaaha(0..7), HillTop.Maddock.Kaluaaha(8..15), HillTop.Maddock.Kaluaaha(16..23), HillTop.Maddock.Kaluaaha(24..31) ] + gateway: + name: cond-32 + input_xbar: + exact group 2: { 0: HillTop.RossFork.Merrill(0..7), 11: HillTop.Ovett.Hammond.0-0, 19: HillTop.RossFork.Alamosa, 21: HillTop.RossFork.Weyauwega, 29: HillTop.Ovett.Hematite, 37: HillTop.RossFork.Naruna.2-2, 40: HillTop.RossFork.Merrill(8..15), 48: HillTop.RossFork.Boerne, 59: HillTop.RossFork.Naruna.0-1 } + hash 4: + 44: HillTop.RossFork.Weyauwega + 45: HillTop.Ovett.Hematite + 46: HillTop.Ovett.Hammond.0-0 + 47: HillTop.RossFork.Boerne + 48: HillTop.RossFork.Alamosa + hash group 0: + table: [4] + seed: 0x0 + row: 2 + bus: 1 + unit: 0 + match: { 36: HillTop.RossFork.Weyauwega, 37: HillTop.Ovett.Hematite, 38: HillTop.Ovett.Hammond.0-0, 19: HillTop.RossFork.Naruna.0-1, 29: HillTop.RossFork.Naruna.2-2, 0: HillTop.RossFork.Merrill(0..7), 8: HillTop.RossFork.Merrill(8..15), 39: HillTop.RossFork.Boerne, 40: HillTop.RossFork.Alamosa } + 0b00110******0********01***0000000000000000: run_table + miss: _Devola + condition: + expression: "(HillTop.RossFork.Weyauwega == 0 && HillTop.Ovett.Hematite == 1 && HillTop.Ovett.Hammond & 1 == 1 && HillTop.RossFork.Naruna == 1 && HillTop.RossFork.Merrill == 0 && HillTop.RossFork.Boerne == 0 && HillTop.RossFork.Alamosa == 0)" + true: _Cranbury + false: _Devola + hit: [ [], _Devola, _Devola, _PeaRidge ] + miss: _Devola + action: _Cranbury$action_data($DIRECT, $DEFAULT) + instruction: _Cranbury(action, $DEFAULT) + actions: + Milano(1, 5): + - p4_param_order: { Kaluaaha: 32, Bratt: 32 } + - default_action: { allowed: true } + - handle: 0x200000cb + - next_table: 1 + - { Kaluaaha: $adf_f0(0..31), Bratt.0-15: $adf_f1(0..15) } + - set HillTop.Maddock.Kaluaaha, Kaluaaha + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Boerne, 1 + - set HillTop.RossFork.Suttle, 1 + Biggers(2, 6): + - p4_param_order: { Kaluaaha: 32, Avondale: 16, Bratt: 32 } + - default_action: { allowed: true } + - handle: 0x200000cc + - next_table: 2 + - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Kaluaaha: $adf_f1(0..31) } + - set HillTop.RossFork.Glenmora, Avondale + - set HillTop.Maddock.Kaluaaha, Kaluaaha + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Boerne, 1 + - set HillTop.RossFork.Suttle, 1 + Sequim(3, 0): + - default_action: { allowed: true } + - handle: 0x200000cd + - next_table: 3 + - { } + default_action: Sequim + idletime: + row: 0 + bus: 0 + column: [ 0, 1, 2, 3 ] + precision: 1 + sweep_interval: 7 + notification: enable + per_flow_enable: false + action _Cranbury$action_data: + p4: { name: Cranbury$action } + row: [ 14, 12, 11, 10, 9, 8, 7, 6, 5 ] + word: [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - 5 + - 5 + - [ 4, 5 ] + - 5 + - [ 3, 4, 5 ] + - 5 + - [ 2, 3, 4, 5 ] + - 5 + - [ 1, 2 ] + vpns: + - [ 0 ] + - [ 1 ] + - [ 2, 3 ] + - [ 4 ] + - [ 5, 6, 7 ] + - [ 8 ] + - [ 9, 10, 11, 12 ] + - [ 13 ] + - [ 14, 15 ] + home_row: + - [ 14, 12 ] + format Milano: { $adf_f0: 0..31, $adf_f1: 32..63 } + format Biggers: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } + action_bus: { 46..47 : $adf_h1, 100..103 : $adf_f1, 44..47 : $adf_f0 } + hash_action _PeaRidge 3: + p4: { name: PeaRidge, size: 4096, disable_atomic_modify : true } + p4_param_order: + HillTop.Wisdom.Nenana: { type: exact, size: 12, full_size: 12, key_name: "Wisdom.Nenana" } + row: 1 + bus: 1 + hash_dist: + 0: { hash: 2, mask: 0xfff, shift: 3 } + input_xbar: + exact group 2: { 64: HillTop.Wisdom.Nenana } + hash 5: + 0..11: stripe(HillTop.Wisdom.Nenana) + hash group 2: + table: [5] + seed: 0x0 + gateway: + name: _PeaRidge-gateway + row: 2 + bus: 0 + unit: 1 + 0x0: _Devola + miss: _Devola + condition: + expression: "true(always hit)" + true: _Devola + false: _Devola + next: [] + action: _PeaRidge$action_data(hash_dist 0, $DEFAULT) + instruction: _PeaRidge($DEFAULT, $DEFAULT) + actions: + Swifton(0, 7): + - p4_param_order: { Panaca: 8 } + - default_action: { allowed: true } + - handle: 0x200000ce + - next_table: 0 + - { Panaca: $adf_f0(0..7) } + - set HillTop.RossFork.Brinklow, Panaca + default_action: Swifton + default_action_parameters: + Panaca: "0x0" + action _PeaRidge$action_data: + p4: { name: PeaRidge$action, how_referenced: direct } + row: 3 + column: 1 + vpns: [ 0 ] + home_row: + - 3 + format Swifton: { $adf_f0: 0..31 } + action_bus: { 104..107 : $adf_f0 } + exact_match _Devola 4: + p4: { name: Devola, size: 4096, disable_atomic_modify : true } + p4_param_order: + HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } + HillTop.Savery.Kaluaaha: { type: exact, size: 16, full_size: 16, key_name: "Savery.Kaluaaha" } + HillTop.Savery.Calcasieu: { type: exact, size: 16, full_size: 16, key_name: "Savery.Calcasieu" } + HillTop.Savery.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Savery.Chevak" } + HillTop.Savery.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Savery.Mendocino" } + HillTop.Savery.LasVegas: { type: exact, size: 8, full_size: 8, key_name: "Savery.LasVegas" } + HillTop.Savery.PineCity: { type: exact, size: 6, full_size: 6, key_name: "Savery.PineCity" } + HillTop.Savery.Exton: { type: exact, size: 8, full_size: 8, key_name: "Savery.Exton" } + HillTop.Savery.Noyes: { type: exact, size: 8, full_size: 8, key_name: "Savery.Noyes" } + HillTop.Savery.Peebles: { type: exact, size: 1, full_size: 1, key_name: "Savery.Peebles" } + row: 7 + bus: 1 + column: [ 7, 8, 9, 10 ] + stash: + row: [ 7 ] + col: [ 7 ] + unit: [ 0 ] + ways: + - [0, 3, 0x600, [7, 7], [7, 8], [7, 9], [7, 10]] + input_xbar: + exact group 3: { 0: HillTop.Savery.Chevak, 16: HillTop.Savery.Mendocino, 32: HillTop.Savery.Calcasieu, 48: HillTop.Savery.Kaluaaha, 68: HillTop.Bessie.Miranda, 86: HillTop.Savery.PineCity, 101: HillTop.Savery.Peebles, 104: HillTop.Savery.Noyes, 112: HillTop.Savery.LasVegas, 120: HillTop.Savery.Exton } + hash 6: + 30..39: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) + 49..50: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) + hash 7: + 30..33: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(0..3) + 34..37: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(4..7) + 38..39: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(0..1) + 49: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(2) + 50: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.Peebles + hash group 0: + table: [6, 7] + seed: 0x4000200000000 + format: { version(0): 112..115, match(0): [32..111, 0..7, 9..11 ] } + match: [ HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton, HillTop.Savery.Chevak(0..7), HillTop.Savery.Chevak(8..15), HillTop.Savery.Mendocino(0..7), HillTop.Savery.Mendocino(8..15), HillTop.Savery.Calcasieu(0..7), HillTop.Savery.Calcasieu(8..15), HillTop.Savery.Kaluaaha(0..7), HillTop.Savery.Kaluaaha(8..15), HillTop.Savery.PineCity(3..5) ] + hit: [ _Ammon ] + miss: _Ammon + action: _Devola$action_data($DIRECT, $DEFAULT) + instruction: _Devola($DEFAULT, $DEFAULT) + actions: + Unionvale(0, 8): + - p4_param_order: { Cornell: 32 } + - default_action: { allowed: true } + - handle: 0x20000086 + - next_table: 0 + - { Cornell: $adf_f0(0..31) } + - maxu HillTop.Mausdale.Kenney, HillTop.Mausdale.Kenney, Cornell + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x20000087 + - next_table: 0 + - { } + default_only_action: NoAction + action _Devola$action_data: + p4: { name: Devola$action } + row: 4 + column: 5 + vpns: [ 0 ] + home_row: + - 4 + format Unionvale: { $adf_f0: 0..31 } + action_bus: { 112..115 : $adf_f0 } + hash_action _Ammon 5: + p4: { name: Ammon, size: 256, disable_atomic_modify : true } + p4_param_order: + HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } + row: 0 + bus: 1 + hash_dist: + 1: { hash: 2, mask: 0xff, shift: 5 } + input_xbar: + exact group 2: { 84: HillTop.Bessie.Miranda } + hash 5: + 16..23: stripe(HillTop.Bessie.Miranda) + hash group 2: + table: [5] + seed: 0x0 + gateway: + name: _Ammon-gateway + row: 1 + bus: 0 + unit: 1 + 0x0: cond-29 + miss: cond-29 + condition: + expression: "true(always hit)" + true: cond-29 + false: cond-29 + next: [] + action: _Ammon$action_data(hash_dist 1, $DEFAULT) + instruction: _Ammon($DEFAULT, $DEFAULT) + actions: + Angeles(0, 9): + - p4_param_order: { Kaluaaha: 16, Calcasieu: 16, Chevak: 16, Mendocino: 16, LasVegas: 8, PineCity: 6, Exton: 8, Noyes: 8, Peebles: 1 } + - default_action: { allowed: true } + - handle: 0x20000088 + - next_table: 0 + - { Peebles: $adf_b0(5..5), Noyes: $adf_b1(0..7), LasVegas: $adf_b2(0..7), Exton: $adf_b3(0..7), Chevak: $adf_h2(0..15), Mendocino: $adf_h3(0..15), Calcasieu: $adf_h4(0..15), Kaluaaha: $adf_h5(0..15), PineCity: $adf_h6(6..11) } + - and HillTop.Savery.Kaluaaha, HillTop.Bessie.Kaluaaha, Kaluaaha + - and HillTop.Savery.Calcasieu, HillTop.Bessie.Calcasieu, Calcasieu + - and HillTop.Savery.Chevak, HillTop.Bessie.Chevak, Chevak + - and HillTop.Savery.Mendocino, HillTop.Bessie.Mendocino, Mendocino + - and HillTop.Savery.LasVegas, HillTop.Bessie.LasVegas, LasVegas + - and HillTop.Savery.Exton, HillTop.Bessie.Exton, Exton + - and HillTop.Savery.Noyes, HillTop.Bessie.Noyes, Noyes + - and B10, Peebles, B9 + - and H85, PineCity, H90 + default_action: Angeles + default_action_parameters: + Kaluaaha: "0xffff" + Calcasieu: "0xffff" + Chevak: "0xffff" + Mendocino: "0xffff" + LasVegas: "0xff" + PineCity: "0x3f" + Exton: "0xff" + Noyes: "0xff" + Peebles: "0x1" + action _Ammon$action_data: + p4: { name: Ammon$action, how_referenced: direct } + row: 5 + column: 3 + vpns: [ 0 ] + home_row: + - 5 + format Angeles: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_b2: 16..23, $adf_b3: 24..31, $adf_h2: 32..47, $adf_h3: 48..63, $adf_h4: 64..79, $adf_h5: 80..95, $adf_h6: 96..111 } + action_bus: { 16 : $adf_b0, 17 : $adf_b1, 18 : $adf_b2, 19 : $adf_b3, 64..65 : $adf_h4, 66..67 : $adf_h5, 68..69 : $adf_h6, 48..49 : $adf_h2, 50..51 : $adf_h3 } + gateway cond-29 6: + name: cond-29 + input_xbar: + exact group 0: { 1: HillTop.Wisdom.Onycha, 93: HillTop.RossFork.Weyauwega, 96: HillTop.Wisdom.Havana, 107: HillTop.Murphy.Standish } + row: 1 + bus: 1 + unit: 0 + match: { 8: HillTop.Wisdom.Havana, 1: HillTop.Wisdom.Onycha, 21: HillTop.RossFork.Weyauwega, 27: HillTop.Murphy.Standish } + 0b***********************1*******: _Circle + 0b****************************010: _Circle + 0b**********1********************: _Circle + 0b****1**************************: _Circle + miss: cond-29$split + condition: + expression: "(HillTop.Wisdom.Havana == 0 && HillTop.Wisdom.Onycha != 2 && HillTop.RossFork.Weyauwega == 0 && HillTop.Murphy.Standish == 0 && HillTop.Murphy.Blairsden == 0)" + true: cond-29$split + false: _Circle + gateway cond-29$split 7: + name: cond-29$split + input_xbar: + exact group 0: { 126: HillTop.Murphy.Blairsden } + row: 5 + bus: 1 + unit: 0 + match: { 6: HillTop.Murphy.Blairsden } + 0b*1: _Circle + miss: _Horatio + condition: + expression: "(HillTop.Wisdom.Havana == 0 && HillTop.Wisdom.Onycha != 2 && HillTop.RossFork.Weyauwega == 0 && HillTop.Murphy.Standish == 0 && HillTop.Murphy.Blairsden == 0)" + true: _Horatio + false: _Circle + exact_match _Horatio 8: + p4: { name: Horatio, size: 8192, disable_atomic_modify : true } + p4_param_order: + HillTop.Wisdom.Adona: { type: exact, size: 24, full_size: 24, key_name: "Wisdom.Adona" } + HillTop.Wisdom.Connell: { type: exact, size: 24, full_size: 24, key_name: "Wisdom.Connell" } + HillTop.Wisdom.Nenana: { type: exact, size: 12, full_size: 12, key_name: "Wisdom.Nenana" } + row: 6 + bus: 1 + column: [ 7, 8, 9, 10 ] + stash: + row: [ 6 ] + col: [ 7 ] + unit: [ 0 ] + ways: + - [3, 0, 0x0, [6, 7]] + - [3, 1, 0x0, [6, 8]] + - [3, 2, 0x0, [6, 9]] + - [3, 3, 0x0, [6, 10]] + input_xbar: + exact group 4: { 0: HillTop.Wisdom.Connell.16-23, 8: HillTop.Wisdom.Adona, 32: HillTop.Wisdom.Nenana, 48: HillTop.Wisdom.Connell.0-15 } + hash 8: + 0..5: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(0..5) + 6..9: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(8..11) + 11..16: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(0..5) + 17..19: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(8..10) + 10: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(11) + 22..27: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(0..5) + 28..29: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(8..9) + 20..21: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(10..11) + 33..38: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(0..5) + 39: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(8) + 30..32: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(9..11) + hash group 3: + table: [8] + seed: 0xac1adff564 + format: { action(0): 0..2, version(0): 112..115, match(0): [86..87, 32..79 ], action(1): 3..5, version(1): 116..119, match(1): [6..7, 88..111, 8..31 ] } + match: [ HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15(0..7), HillTop.Wisdom.Connell.0-15(8..15), HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona(0..7), HillTop.Wisdom.Adona(8..15), HillTop.Wisdom.Adona(16..23) ] + gateway: + name: cond-30 + input_xbar: + exact group 4: { 64: HillTop.Wisdom.Morstein } + row: 0 + bus: 1 + unit: 1 + match: { 0: HillTop.Wisdom.Morstein(0..7), 8: HillTop.Wisdom.Morstein(8..15), 16: HillTop.Wisdom.Morstein(16..19) } + 0x*001ff: run_table + miss: _Circle + condition: + expression: "(HillTop.Wisdom.Morstein == 511)" + true: _Horatio + false: _Circle + hit: [ [], _Circle, _Circle, _Circle, _Circle, _DeepGap ] + miss: _Circle + action: _Horatio$action_data($DIRECT, $DEFAULT) + instruction: _Horatio(action, $DEFAULT) + actions: + Laclede(1, 10): + - p4_param_order: { Stilwell: 20 } + - default_action: { allowed: true } + - handle: 0x200000bc + - next_table: 1 + - { Stilwell: $adf_f0(0..19) } + - set HillTop.Wisdom.Morstein, Stilwell + RedLake(2, 11): + - p4_param_order: { Minto: 16 } + - default_action: { allowed: true } + - handle: 0x200000bd + - next_table: 2 + - { Minto: $adf_h0(0..15) } + - set ig_intr_md_for_tm.mcast_grp_a, Minto + Ruston(3, 12): + - p4_param_order: { Stilwell: 20, Placedo: 10 } + - default_action: { allowed: true } + - handle: 0x200000be + - next_table: 3 + - { Stilwell: $adf_f0(0..19) } + - set HillTop.Wisdom.Morstein, Stilwell + - set HillTop.Wisdom.Westhoff, 5 + LaPlant(4, 13): + - default_action: { allowed: true } + - handle: 0x200000bf + - next_table: 4 + - { } + - set HillTop.RossFork.Almedia, 1 + Sequim(5, 0): + - default_action: { allowed: true } + - handle: 0x200000c0 + - next_table: 5 + - { } + default_action: Sequim + action _Horatio$action_data: + p4: { name: Horatio$action } + row: 11 + column: [ 2, 3 ] + vpns: [ 0, 1 ] + home_row: + - 11 + format Laclede: { $adf_f0: 0..31 } + format RedLake: { $adf_h0: 0..15 } + format Ruston: { $adf_f0: 0..31 } + action_bus: { 52..53 : $adf_h0, 52..55 : $adf_f0 } + ternary_match _DeepGap 9: + p4: { name: DeepGap, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.Tiburon.Arnold: { type: ternary, size: 7, full_size: 9, key_name: "Tiburon.Arnold" } + HillTop.Wisdom.Adona: { type: ternary, size: 24, full_size: 24, key_name: "Wisdom.Adona" } + HillTop.Wisdom.Connell: { type: ternary, size: 24, full_size: 24, key_name: "Wisdom.Connell" } + row: [ 2, 3 ] + bus: [ 0, 0 ] + column: + - 0 + - 0 + input_xbar: + ternary group 0: { 0: HillTop.Wisdom.Connell.16-23, 8: HillTop.Wisdom.Adona, 32: HillTop.Tiburon.Arnold(0..6) } + ternary group 1: { 0: HillTop.Wisdom.Connell.0-15 } + match: + - { group: 0, dirtcam: 0x155 } + - { group: 1, dirtcam: 0x5 } + hit: [ _Circle ] + miss: _Circle + indirect: _DeepGap$tind + meter _DeepGap$meter..Morrow: + p4: { name: Morrow } + row: [ 15, 13 ] + column: + - 5 + - 5 + maprams: + - 5 + - 5 + color_maprams: + row: 7 + bus: 0 + column: 0 + address: idletime + type: standard + count: bytes + ternary_indirect _DeepGap$tind: + row: 1 + bus: 0 + column: 5 + input_xbar: + ternary group 0: { 0: HillTop.Wisdom.Connell.16-23, 8: HillTop.Wisdom.Adona, 32: HillTop.Tiburon.Arnold(0..6) } + ternary group 1: { 0: HillTop.Wisdom.Connell.0-15 } + format: { action: 0..1 } + action_bus: { 3 : _DeepGap$meter..Morrow color } + meter: _DeepGap$meter..Morrow($DIRECT, $DEFAULT, $DEFAULT) + meter_color : _DeepGap$meter..Morrow($DIRECT, $DEFAULT) + action: _DeepGap$action_data($DIRECT, $DEFAULT) + instruction: _DeepGap$tind(action, $DEFAULT) + actions: + Shasta(0, 14): + - default_action: { allowed: true } + - handle: 0x200000c1 + - next_table: 0 + - { } + - set HillTop.RossFork.Thayne, _DeepGap$meter..Morrow color(0..0) + - set ig_intr_md_for_tm.copy_to_cpu, HillTop.RossFork.Parkland + - deposit-field H7(12..15), 0, H2 + - _DeepGap$meter..Morrow(2, $DIRECT) + Weathers(1, 16): + - default_action: { allowed: true } + - handle: 0x200000c2 + - next_table: 0 + - { $constant0: $adf_h0(0..15), $constant0: 4096 } + - set HillTop.RossFork.Thayne, _DeepGap$meter..Morrow color(0..0) + - add ig_intr_md_for_tm.mcast_grp_a, HillTop.Wisdom.Nenana, $constant0 + - set HillTop.RossFork.Tenino, 1 + - _DeepGap$meter..Morrow(2, $DIRECT) + Coupland(2, 18): + - default_action: { allowed: true } + - handle: 0x200000c3 + - next_table: 0 + - { } + - set HillTop.RossFork.Thayne, _DeepGap$meter..Morrow color(0..0) + - deposit-field H7(12..15), 0, H2 + - _DeepGap$meter..Morrow(2, $DIRECT) + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x200000c4 + - next_table: 0 + - { } + default_only_action: NoAction + action _DeepGap$action_data: + p4: { name: DeepGap$action } + row: 7 + column: 1 + vpns: [ 0 ] + home_row: + - 7 + format Weathers: { $adf_h0: 0..15 } + action_bus: { 56..57 : $adf_h0 } + ternary_match _Circle 10: + p4: { name: Circle, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.Quinault.Foster: { type: exact, size: 2, full_size: 2, key_name: "Quinault.Foster" } + HillTop.RossFork.Powderly: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Powderly" } + HillTop.Tiburon.Arnold: { type: ternary, size: 9, full_size: 9, key_name: "Tiburon.Arnold" } + HillTop.RossFork.Quebrada: { type: ternary, size: 1, full_size: 20, key_name: "RossFork.Quebrada", start_bit: 19 } + HillTop.Murphy.Blairsden: { type: ternary, size: 1, full_size: 1, key_name: "Murphy.Blairsden" } + HillTop.Murphy.Standish: { type: ternary, size: 1, full_size: 1, key_name: "Murphy.Standish" } + HillTop.RossFork.Beaverdam: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Beaverdam" } + row: [ 0, 1 ] + bus: [ 0, 0 ] + column: + - 0 + - 0 + input_xbar: + ternary group 1: { 16: HillTop.Tiburon.Arnold, 35: HillTop.RossFork.Quebrada(19) } + ternary group 2: { 6: HillTop.Murphy.Blairsden, 12: HillTop.Quinault.Foster, 14: HillTop.RossFork.Powderly, 19: HillTop.Murphy.Standish } + byte group 3: { 2: HillTop.RossFork.Beaverdam } + match: + - { group: 1, byte_group: 3, byte_config: 0, dirtcam: 0x550 } + - { group: 2, dirtcam: 0x15 } + gateway: + name: cond-31 + input_xbar: + exact group 0: { 4: HillTop.Quinault.Foster } + row: 0 + bus: 0 + unit: 0 + match: { 4: HillTop.Quinault.Foster } + 0b**00: _Mapleton + miss: run_table + condition: + expression: "(HillTop.Quinault.Foster != 0)" + true: _Circle + false: _Mapleton + hit: [ _Mapleton ] + miss: _Mapleton + indirect: _Circle$tind + ternary_indirect _Circle$tind: + row: 0 + bus: 0 + column: 5 + input_xbar: + ternary group 1: { 16: HillTop.Tiburon.Arnold, 35: HillTop.RossFork.Quebrada(19) } + ternary group 2: { 6: HillTop.Murphy.Blairsden, 12: HillTop.Quinault.Foster, 14: HillTop.RossFork.Powderly, 19: HillTop.Murphy.Standish } + byte group 3: { 2: HillTop.RossFork.Beaverdam } + format: { action: 0..2 } + instruction: _Circle$tind(action, $DEFAULT) + actions: + Wyndmoor(1, 15): + - default_action: { allowed: true } + - handle: 0x200000c5 + - next_table: 0 + - set ig_intr_md_for_dprsr.digest_type, 1 + Picabo(2, 17): + - default_action: { allowed: true } + - handle: 0x200000c6 + - next_table: 0 + - set HillTop.Wisdom.Havana, 1 + - set HillTop.Wisdom.Blencoe, 22 + - set HillTop.Murphy.Blairsden, 0 + - set HillTop.Murphy.Standish, 0 + Algoa(3, 19): + - default_action: { allowed: true } + - handle: 0x200000c7 + - next_table: 0 + - set HillTop.RossFork.Algoa, 1 + Crump(4, 0): + - default_action: { allowed: true } + - handle: 0x200000c8 + - next_table: 0 + default_action: Crump + ternary_match _Mapleton 11: + p4: { name: Mapleton, disable_atomic_modify : true } + hit: [ _Nowlin ] + miss: _Nowlin + indirect: _Mapleton$tind + ternary_indirect _Mapleton$tind: + row: 0 + bus: 1 + format: { action: 0..0 } + instruction: _Mapleton$tind(action, $DEFAULT) + actions: + Claypool(0, 20): + - default_action: { allowed: true } + - handle: 0x2000011b + - next_table: 0 + - set HillTop.Plains.Roachdale, 1 + - set HillTop.Plains.Miller, HillTop.Tiburon.Arnold + - set Millston.Belgrade.$valid, 1 + - set Millston.Belgrade.Willard, HillTop.Freeny.Dunedin + default_action: Claypool + hash_action _Nowlin 12: + p4: { name: Nowlin, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.Tiburon.Arnold: { type: exact, size: 9, full_size: 9, key_name: "Tiburon.Arnold" } + row: 2 + bus: 1 + hash_dist: + 2: { hash: 2, mask: 0x1ff, shift: 3 } + input_xbar: + exact group 2: { 96: HillTop.Tiburon.Arnold } + hash 5: + 32..40: stripe(HillTop.Tiburon.Arnold) + hash group 2: + table: [5] + seed: 0x0 + gateway: + name: _Nowlin-gateway + row: 3 + bus: 0 + unit: 1 + 0x0: _Walland + miss: _Walland + condition: + expression: "true(always hit)" + true: _Walland + false: _Walland + next: [] + action: _Nowlin$action_data(hash_dist 2, $DEFAULT) + instruction: _Nowlin($DEFAULT, $DEFAULT) + actions: + Newland(0, 21): + - p4_param_order: { Waumandee: 9 } + - default_action: { allowed: true } + - handle: 0x200000f8 + - next_table: 0 + - { Waumandee: $adf_f0(0..8) } + - set ig_intr_md_for_tm.level2_mcast_hash, HillTop.Lewiston.Staunton(0..12) + - set ig_intr_md_for_tm.level2_exclusion_id, Waumandee + default_action: Newland + default_action_parameters: + Waumandee: "0x0" + action _Nowlin$action_data: + p4: { name: Nowlin$action, how_referenced: direct } + row: 1 + column: 5 + vpns: [ 0 ] + home_row: + - 1 + format Newland: { $adf_f0: 0..31 } + action_bus: { 120..123 : $adf_f0 } +stage 9 ingress: + exact_match _Walland 0: + p4: { name: Walland, size: 8192, disable_atomic_modify : true } + p4_param_order: + HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } + HillTop.Savery.Kaluaaha: { type: exact, size: 16, full_size: 16, key_name: "Savery.Kaluaaha" } + HillTop.Savery.Calcasieu: { type: exact, size: 16, full_size: 16, key_name: "Savery.Calcasieu" } + HillTop.Savery.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Savery.Chevak" } + HillTop.Savery.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Savery.Mendocino" } + HillTop.Savery.LasVegas: { type: exact, size: 8, full_size: 8, key_name: "Savery.LasVegas" } + HillTop.Savery.PineCity: { type: exact, size: 6, full_size: 6, key_name: "Savery.PineCity" } + HillTop.Savery.Exton: { type: exact, size: 8, full_size: 8, key_name: "Savery.Exton" } + HillTop.Savery.Noyes: { type: exact, size: 8, full_size: 8, key_name: "Savery.Noyes" } + HillTop.Savery.Peebles: { type: exact, size: 1, full_size: 1, key_name: "Savery.Peebles" } + row: [ 7, 4, 3 ] + bus: [ 1, 0, 0 ] + column: + - [ 4, 6 ] + - [ 2, 3, 4, 6 ] + - [ 2, 3 ] + stash: + row: [ 7 ] + col: [ 4 ] + unit: [ 1 ] + ways: + - [0, 0, 0x7, [7, 4], [7, 6], [4, 2], [4, 3], [4, 4], [4, 6], [3, 2], [3, 3]] + input_xbar: + exact group 0: { 0: HillTop.Savery.Chevak, 16: HillTop.Savery.Mendocino, 32: HillTop.Savery.Calcasieu, 48: HillTop.Savery.Kaluaaha, 68: HillTop.Bessie.Miranda, 86: HillTop.Savery.PineCity, 101: HillTop.Savery.Peebles, 104: HillTop.Savery.Noyes, 112: HillTop.Savery.LasVegas, 120: HillTop.Savery.Exton } + hash 0: + 0..9: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) + 40..42: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) + hash 1: + 0..3: random(HillTop.Savery.PineCity(4..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(0..3) + 4..7: random(HillTop.Savery.PineCity(4..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(4..7) + 8..9: random(HillTop.Savery.PineCity(4..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(0..1) + 40..41: random(HillTop.Savery.PineCity(4..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(2..3) + 42: random(HillTop.Savery.PineCity(4..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.Peebles + hash group 0: + table: [0, 1] + seed: 0x30 + format: { version(0): 112..115, match(0): [32..111, 0..7, 10..11 ] } + match: [ HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton, HillTop.Savery.Chevak(0..7), HillTop.Savery.Chevak(8..15), HillTop.Savery.Mendocino(0..7), HillTop.Savery.Mendocino(8..15), HillTop.Savery.Calcasieu(0..7), HillTop.Savery.Calcasieu(8..15), HillTop.Savery.Kaluaaha(0..7), HillTop.Savery.Kaluaaha(8..15), HillTop.Savery.PineCity(4..5) ] + hit: [ _Ferndale ] + miss: _Ferndale + action: _Walland$action_data($DIRECT, $DEFAULT) + instruction: _Walland($DEFAULT, $DEFAULT) + actions: + Unionvale(0, 1): + - p4_param_order: { Cornell: 32 } + - default_action: { allowed: true } + - handle: 0x2000009d + - next_table: 0 + - { Cornell: $adf_f0(0..31) } + - maxu HillTop.Mausdale.Kenney, HillTop.Mausdale.Kenney, Cornell + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x2000009e + - next_table: 0 + - { } + default_only_action: NoAction + action _Walland$action_data: + p4: { name: Walland$action } + row: 11 + column: [ 0, 1 ] + vpns: [ 0, 1 ] + home_row: + - 11 + format Unionvale: { $adf_f0: 0..31 } + action_bus: { 96..99 : $adf_f0 } + hash_action _Ferndale 1: + p4: { name: Ferndale, size: 256, disable_atomic_modify : true } + p4_param_order: + HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } + row: 4 + bus: 1 + hash_dist: + 0: { hash: 1, mask: 0xff, shift: 5 } + input_xbar: + exact group 1: { 4: HillTop.Bessie.Miranda } + hash 2: + 0..7: stripe(HillTop.Bessie.Miranda) + hash group 1: + table: [2] + seed: 0x0 + gateway: + name: _Ferndale-gateway + row: 0 + bus: 0 + unit: 1 + 0x0: _Chilson + miss: _Chilson + condition: + expression: "true(always hit)" + true: _Chilson + false: _Chilson + next: [] + action: _Ferndale$action_data(hash_dist 0, $DEFAULT) + instruction: _Ferndale($DEFAULT, $DEFAULT) + actions: + Twichell(0, 2): + - p4_param_order: { Kaluaaha: 16, Calcasieu: 16, Chevak: 16, Mendocino: 16, LasVegas: 8, PineCity: 6, Exton: 8, Noyes: 8, Peebles: 1 } + - default_action: { allowed: true } + - handle: 0x2000009f + - next_table: 0 + - { Peebles: $adf_b0(5..5), Noyes: $adf_b1(0..7), LasVegas: $adf_b2(0..7), Exton: $adf_b3(0..7), Chevak: $adf_h2(0..15), Mendocino: $adf_h3(0..15), Calcasieu: $adf_h4(0..15), Kaluaaha: $adf_h5(0..15), PineCity: $adf_h6(6..11) } + - and HillTop.Savery.Kaluaaha, HillTop.Bessie.Kaluaaha, Kaluaaha + - and HillTop.Savery.Calcasieu, HillTop.Bessie.Calcasieu, Calcasieu + - and HillTop.Savery.Chevak, HillTop.Bessie.Chevak, Chevak + - and HillTop.Savery.Mendocino, HillTop.Bessie.Mendocino, Mendocino + - and HillTop.Savery.LasVegas, HillTop.Bessie.LasVegas, LasVegas + - and HillTop.Savery.Exton, HillTop.Bessie.Exton, Exton + - and HillTop.Savery.Noyes, HillTop.Bessie.Noyes, Noyes + - and B10, Peebles, B9 + - and H85, PineCity, H90 + default_action: Twichell + default_action_parameters: + Kaluaaha: "0xffff" + Calcasieu: "0xffff" + Chevak: "0xffff" + Mendocino: "0xffff" + LasVegas: "0xff" + PineCity: "0x3f" + Exton: "0xff" + Noyes: "0xff" + Peebles: "0x1" + action _Ferndale$action_data: + p4: { name: Ferndale$action, how_referenced: direct } + row: 6 + column: 5 + vpns: [ 0 ] + home_row: + - 6 + format Twichell: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_b2: 16..23, $adf_b3: 24..31, $adf_h2: 32..47, $adf_h3: 48..63, $adf_h4: 64..79, $adf_h5: 80..95, $adf_h6: 96..111 } + action_bus: { 16 : $adf_b0, 17 : $adf_b1, 18 : $adf_b2, 19 : $adf_b3, 64..65 : $adf_h4, 66..67 : $adf_h5, 68..69 : $adf_h6, 32..33 : $adf_h2, 34..35 : $adf_h3 } + exact_match _Chilson 2: + p4: { name: Chilson, size: 128, action_profile: Wakeman, disable_atomic_modify : true } + p4_param_order: + HillTop.Minturn.Grassflat: { type: exact, size: 7, full_size: 10, key_name: "Minturn.Grassflat" } + row: 0 + bus: 1 + column: 4 + stash: + row: [ 0 ] + col: [ 4 ] + unit: [ 0 ] + ways: + - [0, 1, 0x0, [0, 4]] + input_xbar: + exact group 1: { 64: HillTop.Minturn.Grassflat(0..6) } + hash 3: + 10..16: HillTop.Minturn.Grassflat(0..6) + hash group 0: + table: [3] + seed: 0x0 + format: { version(0): 112..115, meter_addr(0): 0..9, meter_pfe(0): 10..10, action_addr(0): 11..21 } + hit: [ _Sedan_0 ] + miss: _Sedan_0 + selector: _Chilson$selector.Wakeman_sel(meter_addr, meter_pfe, $DEFAULT) + selector_length: _Chilson$selector.Wakeman_sel($DEFAULT, $DEFAULT) + action: _Chilson$action_data.Wakeman(action_addr, $DEFAULT) + instruction: _Chilson($DEFAULT, $DEFAULT) + actions: + Froid(0, 3): + - p4_param_order: { Hector: 10 } + - default_action: { allowed: true } + - handle: 0x200000b3 + - next_table: 0 + - { Hector: $adf_h0(0..9) } + - or H34, Hector, H34 + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x200000b4 + - next_table: 0 + - { } + default_only_action: NoAction + selection _Chilson$selector.Wakeman_sel: + p4: { name: Wakeman_sel, size: 4 } + row: 15 + column: [ 1, 2 ] + maprams: [ 1, 2 ] + input_xbar: + exact group 2: { 0: HillTop.Lewiston.Staunton } + hash 4: + 0..50: slice(stripe(crc_rev(0x18005, 0x0, 0x0, 16, { 0: HillTop.Lewiston.Staunton })), 0..50) + hash group 2: + table: [4] + seed: 0x0 + mode: resilient 0 + non_linear: true + pool_sizes: [120] + action _Chilson$action_data.Wakeman: + p4: { name: Wakeman, size: 1024 } + row: 4 + column: 5 + vpns: [ 0 ] + home_row: + - 4 + format Froid: { $adf_h0: 0..15 } + action_bus: { 36..37 : $adf_h0 } + stateful _Chilson$salu.Wakeman_sel$salu: + p4: { name: Wakeman_sel$salu, size: 122880, hidden: true } + selection_table: _Chilson$selector.Wakeman_sel + row: 15 + column: [ 1, 2 ] + maprams: [ 1, 2 ] + format: { lo: 1 } + actions: + set_bit_at_alu$0: + - set_bit_at + clr_bit_at_alu$0: + - clr_bit_at + set_bit_alu$0: + - set_bit + clr_bit_alu$0: + - clr_bit + exact_match _Sedan_0 3: + p4: { name: Sedan, size: 20480, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Merrill: { type: exact, size: 16, full_size: 16, key_name: "RossFork.Merrill" } + row: [ 1, 0 ] + bus: [ 1, 0 ] + column: + - [ 4, 6 ] + - [ 2, 3 ] + stash: + row: [ 1 ] + col: [ 4 ] + unit: [ 0 ] + ways: + - [3, 0, 0x0, [1, 4]] + - [3, 1, 0x0, [1, 6]] + - [3, 2, 0x0, [0, 2]] + - [3, 3, 0x0, [0, 3]] + input_xbar: + exact group 2: { 64: HillTop.RossFork.Merrill } + hash 5: + 0..7: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(0..7) + 8..9: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(8..9) + 11..18: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(0..7) + 19: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(8) + 10: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(9) + 22..29: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(0..7) + 20..21: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(8..9) + 33..39: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(0..6) + 30: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(7) + 31..32: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(8..9) + hash group 3: + table: [5] + seed: 0x506b8ed1a4 + format: { action(0): 0..1, version(0): 112..115, match(0): 34..39, action(1): 2..3, version(1): 116..119, match(1): 42..47, action(2): 4..5, version(2): 120..123, match(2): 50..55, action(3): 6..7, version(3): 124..127, match(3): 58..63, action(4): 8..9, version(4): 16..19, match(4): 66..71 } + match: [ HillTop.RossFork.Merrill(10..15) ] + gateway: + name: cond-33 + input_xbar: + exact group 1: { 75: HillTop.Ovett.Hammond.0-0, 80: ig_intr_md_for_tm.copy_to_cpu, 93: HillTop.Ovett.Hematite, 101: HillTop.RossFork.Weyauwega, 109: HillTop.RossFork.Naruna.2-2, 115: HillTop.RossFork.Naruna.0-1 } + hash 3: + 44: HillTop.Ovett.Hammond.0-0 + 45: ig_intr_md_for_tm.copy_to_cpu + hash group 0: + table: [3] + seed: 0x0 + row: 0 + bus: 1 + unit: 0 + match: { 21: HillTop.RossFork.Weyauwega, 29: HillTop.Ovett.Hematite, 36: HillTop.Ovett.Hammond.0-0, 3: HillTop.RossFork.Naruna.0-1, 13: HillTop.RossFork.Naruna.2-2, 37: ig_intr_md_for_tm.copy_to_cpu } + 0b01******1*******0*******0********01: run_table + miss: _Lemont_0 + condition: + expression: "(HillTop.RossFork.Weyauwega == 0 && HillTop.Ovett.Hematite == 1 && HillTop.Ovett.Hammond & 1 == 1 && HillTop.RossFork.Naruna == 1 && ig_intr_md_for_tm.copy_to_cpu == 0)" + true: _Sedan_0 + false: _Lemont_0 + hit: [ [], _OldTown, _OldTown, _Casnovia_0 ] + miss: _OldTown + action: _Sedan_0$action_data($DIRECT, $DEFAULT) + instruction: _Sedan_0(action, $DEFAULT) + actions: + Bronwood(1, 4): + - p4_param_order: { Kaluaaha: 32, Calcasieu: 32, Cotter: 32 } + - default_action: { allowed: true } + - handle: 0x200000cf + - next_table: 1 + - { Calcasieu: $adf_f0(0..31), Kaluaaha: $adf_f1(0..31), Cotter.0-15: $adf_f2(0..15) } + - set HillTop.Maddock.Kaluaaha, Kaluaaha + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Cotter.0-15 + - set HillTop.RossFork.Boerne, 1 + - set HillTop.RossFork.Alamosa, 1 + Kinde(2, 6): + - p4_param_order: { Kaluaaha: 32, Calcasieu: 32, Hillside: 16, Wanamassa: 16, Cotter: 32 } + - default_action: { allowed: true } + - handle: 0x200000d0 + - next_table: 2 + - { Cotter.0-15: $adf_f0(0..15), Hillside: $adf_h1(0..15), Wanamassa: $adf_h2(0..15), Calcasieu: $adf_f2(0..31), Kaluaaha: $adf_f3(0..31) } + - set HillTop.Maddock.Kaluaaha, Kaluaaha + - set HillTop.Maddock.Calcasieu, Calcasieu + - set HillTop.RossFork.Bucktown(0..15), Cotter.0-15 + - set HillTop.RossFork.Boerne, 1 + - set HillTop.RossFork.Alamosa, 1 + - set HillTop.RossFork.Glenmora, Hillside + - set HillTop.RossFork.DonaAna, Wanamassa + Sequim(3, 0): + - default_action: { allowed: true } + - handle: 0x200000d1 + - next_table: 3 + - { } + default_action: Sequim + action _Sedan_0$action_data: + p4: { name: Sedan$action } + row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7 ] + word: [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - [ 3, 4, 5 ] + - 5 + - 5 + - 5 + - [ 2, 3, 4, 5 ] + - 5 + - [ 2, 3, 4, 5 ] + - 5 + - [ 2, 3, 4, 5 ] + vpns: + - [ 0, 1, 2 ] + - [ 3 ] + - [ 4 ] + - [ 5 ] + - [ 6, 7, 8, 9 ] + - [ 10 ] + - [ 11, 12, 13, 14 ] + - [ 15 ] + - [ 16, 17, 18, 19 ] + home_row: + - 15 + format Bronwood: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } + format Kinde: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_h2: 32..47, $adf_f2: 64..95, $adf_f3: 96..127 } + action_bus: { 74..75 : $adf_h1, 76..77 : $adf_h2, 104..107 : $adf_f2, 108..111 : $adf_f3, 72..75 : $adf_f0, 76..79 : $adf_f1 } + ternary_match _Lemont_0 8: + p4: { name: Lemont, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Ravena: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Ravena" } + HillTop.RossFork.Bradner: { type: ternary, size: 2, full_size: 2, key_name: "RossFork.Bradner" } + HillTop.RossFork.TroutRun: { type: ternary, size: 2, full_size: 2, key_name: "RossFork.TroutRun" } + HillTop.Wisdom.Piqua: { type: exact, size: 1, full_size: 1, key_name: "Wisdom.Piqua" } + HillTop.Wisdom.Morstein: { type: ternary, size: 1, full_size: 20, key_name: "Wisdom.Morstein", start_bit: 19 } + row: 4 + bus: 1 + column: 1 + input_xbar: + ternary group 6: { 4: HillTop.RossFork.Bradner, 11: HillTop.Wisdom.Morstein(19), 20: HillTop.RossFork.Ravena, 28: HillTop.Wisdom.Piqua, 38: HillTop.RossFork.TroutRun } + match: + - { group: 6, dirtcam: 0x155 } + hit: [ _OldTown ] + miss: _OldTown + indirect: _Lemont_0$tind + ternary_indirect _Lemont_0$tind: + row: 5 + bus: 0 + column: 4 + input_xbar: + ternary group 6: { 4: HillTop.RossFork.Bradner, 11: HillTop.Wisdom.Morstein(19), 20: HillTop.RossFork.Ravena, 28: HillTop.Wisdom.Piqua, 38: HillTop.RossFork.TroutRun } + format: { action: 0..0, immediate: 1..8 } + action_bus: { 0 : immediate(0..7) } + instruction: _Lemont_0$tind(action, $DEFAULT) + actions: + Frederika(0, 7): + - p4_param_order: { Blencoe: 8 } + - default_action: { allowed: true } + - handle: 0x200000db + - next_table: 0 + - { Blencoe: immediate(0..7) } + - set HillTop.Wisdom.Havana, 1 + - set HillTop.Wisdom.Blencoe, Blencoe + Saugatuck(1, 0): + - default_action: { allowed: true } + - handle: 0x200000dc + - next_table: 0 + - { } + NoAction(-1, 9): + - default_only_action: { allowed: true } + - handle: 0x200000dd + - next_table: 0 + - { } + default_only_action: NoAction + exact_match _Casnovia_0 4: + p4: { name: Casnovia, size: 4096, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Montross: { type: exact, size: 12, full_size: 12, key_name: "RossFork.Montross" } + HillTop.Maddock.Kaluaaha: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } + Millston.Grays.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Grays.Chevak" } + HillTop.RossFork.Brinklow: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Brinklow" } + row: [ 2, 1 ] + bus: [ 1, 0 ] + column: + - [ 4, 6 ] + - [ 2, 3 ] + stash: + row: [ 2 ] + col: [ 4 ] + unit: [ 0 ] + ways: + - [4, 0, 0x0, [2, 4]] + - [4, 1, 0x0, [2, 6]] + - [4, 2, 0x0, [1, 2]] + - [4, 3, 0x0, [1, 3]] + input_xbar: + exact group 3: { 0: HillTop.Maddock.Kaluaaha(0..7), 9: HillTop.RossFork.Brinklow, 24: HillTop.Maddock.Kaluaaha(24..31), 32: HillTop.RossFork.Montross(0..7), 40: HillTop.Maddock.Kaluaaha(8..23), 56: Millston.Grays.Chevak(8..15), 64: Millston.Grays.Chevak(0..7), 72: HillTop.RossFork.Montross(8..11) } + hash 6: + 6..9: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) + 0..4: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) ^ HillTop.RossFork.Brinklow(0..4) + 5: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) ^ HillTop.RossFork.Brinklow(7) + 10: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) + 17..19: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) + 11..15: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) ^ HillTop.RossFork.Brinklow(0..4) + 16: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) ^ HillTop.RossFork.Brinklow(7) + 20..21: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) + 28..29: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) + 22..26: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) ^ HillTop.RossFork.Brinklow(0..4) + 27: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) ^ HillTop.RossFork.Brinklow(7) + 30..32: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) + 39: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) + 33..37: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) ^ HillTop.RossFork.Brinklow(0..4) + 38: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) ^ HillTop.RossFork.Brinklow(7) + hash 7: + 0..5: random(Millston.Grays.Chevak(0..7)) + 6..9: random(Millston.Grays.Chevak(0..7)) ^ HillTop.RossFork.Montross(8..11) + 11..16: random(Millston.Grays.Chevak(0..7)) + 17..19: random(Millston.Grays.Chevak(0..7)) ^ HillTop.RossFork.Montross(8..10) + 10: random(Millston.Grays.Chevak(0..7)) ^ HillTop.RossFork.Montross(11) + 22..27: random(Millston.Grays.Chevak(0..7)) + 28..29: random(Millston.Grays.Chevak(0..7)) ^ HillTop.RossFork.Montross(8..9) + 20..21: random(Millston.Grays.Chevak(0..7)) ^ HillTop.RossFork.Montross(10..11) + 33..38: random(Millston.Grays.Chevak(0..7)) + 39: random(Millston.Grays.Chevak(0..7)) ^ HillTop.RossFork.Montross(8) + 30..32: random(Millston.Grays.Chevak(0..7)) ^ HillTop.RossFork.Montross(9..11) + hash group 4: + table: [6, 7] + seed: 0x67c3de1bef + format: { action(0): 0..1, immediate(0): 2..33, version(0): 112..115, match(0): [40..55, 38..39, 56..95 ] } + match: [ Millston.Grays.Chevak(0..7), Millston.Grays.Chevak(8..15), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(0..7), HillTop.Maddock.Kaluaaha(8..15), HillTop.Maddock.Kaluaaha(16..23), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7) ] + hit: [ _OldTown, _OldTown, _Sunbury_0 ] + miss: _OldTown + action_bus: { 100..103 : immediate(0..31) } + action: _Casnovia_0$action_data($DIRECT, $DEFAULT) + instruction: _Casnovia_0(action, $DEFAULT) + actions: + Garrison(0, 8): + - p4_param_order: { Kaluaaha: 32, Bratt: 32 } + - default_action: { allowed: true } + - handle: 0x200000d2 + - next_table: 0 + - { Kaluaaha: $adf_f0(0..31), Bratt.0-15: immediate(0..15) } + - set HillTop.Maddock.Kaluaaha, Kaluaaha + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Boerne, 1 + Dacono(1, 10): + - p4_param_order: { Kaluaaha: 32, Avondale: 16, Bratt: 32 } + - default_action: { allowed: true } + - handle: 0x200000d3 + - next_table: 1 + - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Kaluaaha: immediate(0..31) } + - set HillTop.RossFork.Glenmora, Avondale + - set HillTop.Maddock.Kaluaaha, Kaluaaha + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Boerne, 1 + Sequim(2, 0): + - default_action: { allowed: true } + - handle: 0x200000d4 + - next_table: 2 + - { } + default_action: Sequim + action _Casnovia_0$action_data: + p4: { name: Casnovia$action } + row: 7 + column: 1 + vpns: [ 0 ] + home_row: + - 7 + format Garrison: { $adf_f0: 0..31 } + format Dacono: { $adf_f0: 0..31, $adf_h1: 16..31 } + action_bus: { 42..43 : $adf_h1, 40..43 : $adf_f0 } + exact_match _Sunbury_0 5: + p4: { name: Sunbury, size: 1024, disable_atomic_modify : true } + p4_param_order: + HillTop.Maddock.Kaluaaha: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } + HillTop.RossFork.Brinklow: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Brinklow" } + Millston.Osyka.Noyes: { type: exact, size: 3, full_size: 8, key_name: "Osyka.Noyes" } + row: [ 3, 2 ] + bus: [ 1, 0 ] + column: + - [ 4, 6 ] + - [ 2, 3 ] + stash: + row: [ 3 ] + col: [ 4 ] + unit: [ 0 ] + ways: + - [5, 0, 0x0, [3, 4]] + - [5, 1, 0x0, [3, 6]] + - [5, 2, 0x0, [2, 2]] + - [5, 3, 0x0, [2, 3]] + input_xbar: + exact group 4: { 0: HillTop.Maddock.Kaluaaha(0..7), 9: HillTop.RossFork.Brinklow, 24: HillTop.Maddock.Kaluaaha(24..31), 32: Millston.Osyka.Noyes(0..2), 40: HillTop.Maddock.Kaluaaha(8..23) } + hash 8: + 0..5: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(0..5) + 6: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(7) + 7..9: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ Millston.Osyka.Noyes(0..2) + 11..16: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(0..5) + 17: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(7) + 18..19: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ Millston.Osyka.Noyes(0..1) + 10: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ Millston.Osyka.Noyes(2) + 22..27: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(0..5) + 28: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(7) + 29: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ Millston.Osyka.Noyes(0) + 20..21: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ Millston.Osyka.Noyes(1..2) + 33..38: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(0..5) + 39: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(7) + 30..32: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ Millston.Osyka.Noyes(0..2) + hash group 5: + table: [8] + seed: 0x9ee4d2fffa + format: { action(0): 0..0, immediate(0): 1..16, version(0): 112..115, match(0): [71..71, 32..63 ] } + match: [ HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(0..7), HillTop.Maddock.Kaluaaha(8..15), HillTop.Maddock.Kaluaaha(16..23), HillTop.Maddock.Kaluaaha(24..31) ] + hit: [ _OldTown, _Flaherty_0 ] + miss: _OldTown + action_bus: { 112..115 : immediate(0..15) } + action: _Sunbury_0$action_data($DIRECT, $DEFAULT) + instruction: _Sunbury_0(action, $DEFAULT) + actions: + Milano(0, 12): + - p4_param_order: { Kaluaaha: 32, Bratt: 32 } + - default_action: { allowed: true } + - handle: 0x200000d5 + - next_table: 0 + - { Kaluaaha: $adf_f0(0..31), Bratt.0-15: immediate(0..15) } + - set HillTop.Maddock.Kaluaaha, Kaluaaha + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Boerne, 1 + Sequim(1, 0): + - default_action: { allowed: true } + - handle: 0x200000d6 + - next_table: 1 + - { } + default_action: Sequim + idletime: + row: 0 + bus: 0 + column: 0 + precision: 1 + sweep_interval: 7 + notification: enable + per_flow_enable: false + action _Sunbury_0$action_data: + p4: { name: Sunbury$action } + row: 9 + column: 1 + vpns: [ 0 ] + home_row: + - 9 + format Milano: { $adf_f0: 0..31 } + action_bus: { 120..123 : $adf_f0 } + exact_match _Flaherty_0 6: + p4: { name: Flaherty, size: 10240, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Montross: { type: exact, size: 12, full_size: 12, key_name: "RossFork.Montross" } + HillTop.Maddock.Kaluaaha: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } + HillTop.RossFork.Brinklow: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Brinklow" } + row: [ 5, 6, 7 ] + bus: [ 0, 0, 0 ] + column: + - [ 2, 3 ] + - [ 2, 3 ] + - [ 2, 3 ] + stash: + row: [ 5, 6, 7 ] + col: [ 2, 2, 2 ] + unit: [ 0, 0, 0 ] + ways: + - [0, 2, 0x0, [7, 2], [6, 2], [5, 2]] + - [0, 3, 0x0, [7, 3], [6, 3], [5, 3]] + input_xbar: + exact group 5: { 0: HillTop.Maddock.Kaluaaha(0..7), 9: HillTop.RossFork.Brinklow, 24: HillTop.Maddock.Kaluaaha(24..31), 32: HillTop.RossFork.Montross(0..7), 40: HillTop.Maddock.Kaluaaha(8..23), 72: HillTop.RossFork.Montross(8..11) } + hash 10: + 26..29: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23)) + 20..24: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(0..4) + 25: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(7) + 30: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23)) + 37..39: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23)) + 31..35: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(0..4) + 36: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(7) + hash 11: + 26..29: HillTop.RossFork.Montross(8..11) + 37..39: HillTop.RossFork.Montross(8..10) + 30: HillTop.RossFork.Montross(11) + hash group 0: + table: [10, 11] + seed: 0x57fe600000 + format: { action(0): 1..1, immediate(0): 2..17, version(0): 112..115, match(0): 38..79, action(1): 0..0, immediate(1): 18..33, version(1): 244..247, match(1): [118..119, 80..111, 120..127 ], action(2): 129..129, immediate(2): 130..145, version(2): 240..243, match(2): 166..207, action(3): 128..128, immediate(3): 146..161, version(3): 372..375, match(3): [326..327, 208..239, 248..255 ], action(4): 256..256, immediate(4): 257..272, version(4): 368..371, match(4): 278..319 } + match: [ HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(0..7), HillTop.Maddock.Kaluaaha(8..15), HillTop.Maddock.Kaluaaha(16..23), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7) ] + hit: [ _OldTown, _Almota_0 ] + miss: _OldTown + action_bus: { 116..119 : immediate(0..15) } + action: _Flaherty_0$action_data($DIRECT, $DEFAULT) + instruction: _Flaherty_0(action, $DEFAULT) + actions: + Garrison(0, 14): + - p4_param_order: { Kaluaaha: 32, Bratt: 32 } + - default_action: { allowed: true } + - handle: 0x200000d7 + - next_table: 0 + - { Kaluaaha: $adf_f0(0..31), Bratt.0-15: immediate(0..15) } + - set HillTop.Maddock.Kaluaaha, Kaluaaha + - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 + - set HillTop.RossFork.Boerne, 1 + Sequim(1, 0): + - default_action: { allowed: true } + - handle: 0x200000d8 + - next_table: 1 + - { } + default_action: Sequim + action _Flaherty_0$action_data: + p4: { name: Flaherty$action } + row: 13 + column: [ 2, 3, 4 ] + vpns: [ 0, 1, 2 ] + home_row: + - 13 + format Garrison: { $adf_f0: 0..31 } + action_bus: { 80..83 : $adf_f0 } + ternary_match _Almota_0 7: + p4: { name: Almota, size: 1024, disable_atomic_modify : true } + p4_param_order: + HillTop.RossFork.Chaffee: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Chaffee" } + HillTop.RossFork.Brinklow: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Brinklow" } + HillTop.Maddock.Kaluaaha: { type: ternary, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } + HillTop.Maddock.Calcasieu: { type: ternary, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } + HillTop.RossFork.Chevak: { type: ternary, size: 16, full_size: 16, key_name: "RossFork.Chevak" } + HillTop.RossFork.Mendocino: { type: ternary, size: 16, full_size: 16, key_name: "RossFork.Mendocino" } + HillTop.RossFork.Ocoee: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } + HillTop.RossFork.Suttle: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Suttle" } + Millston.Osyka.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Osyka" } + Millston.Osyka.Noyes: { type: ternary, size: 8, full_size: 8, key_name: "Osyka.Noyes" } + row: [ 8, 9, 10, 11, 0, 1, 2, 3 ] + bus: [ 0, 0, 0, 0, 1, 1, 1, 1 ] + column: + - 0 + - 0 + - 0 + - 0 + - 1 + - 1 + - 1 + - 1 + input_xbar: + ternary group 0: { 0: HillTop.Maddock.Kaluaaha, 32: HillTop.RossFork.Chaffee } + ternary group 1: { 0: HillTop.RossFork.Mendocino, 16: HillTop.RossFork.Chevak, 38: Millston.Osyka.$valid } + ternary group 2: { 0: Millston.Osyka.Noyes, 8: HillTop.RossFork.Ocoee } + ternary group 3: { 1: HillTop.RossFork.Brinklow(0..6), 8: HillTop.Maddock.Calcasieu(16..31), 24: HillTop.Maddock.Calcasieu(0..15) } + byte group 0: { 0: HillTop.RossFork.Suttle } + byte group 3: { 0: HillTop.RossFork.Brinklow(7) } + match: + - { group: 0, byte_group: 0, byte_config: 0, dirtcam: 0x555 } + - { group: 1, dirtcam: 0x155 } + - { group: 2, byte_group: 3, byte_config: 0, dirtcam: 0x405 } + - { group: 3, dirtcam: 0x155 } + gateway: + name: cond-34 + input_xbar: + exact group 3: { 83: HillTop.Murphy.Standish, 94: HillTop.Murphy.Blairsden } + row: 1 + bus: 0 + unit: 0 + match: { 3: HillTop.Murphy.Standish, 14: HillTop.Murphy.Blairsden } + 0b*0**********0: run_table + miss: _OldTown + condition: + expression: "(HillTop.Murphy.Standish == 0 && HillTop.Murphy.Blairsden == 0)" + true: _Almota_0 + false: _OldTown + hit: [ [], _OldTown, _Lemont_0 ] + miss: _OldTown + indirect: _Almota_0$tind + ternary_indirect _Almota_0$tind: + row: 6 + bus: 0 + column: 4 + input_xbar: + ternary group 0: { 0: HillTop.Maddock.Kaluaaha, 32: HillTop.RossFork.Chaffee } + ternary group 1: { 0: HillTop.RossFork.Mendocino, 16: HillTop.RossFork.Chevak, 38: Millston.Osyka.$valid } + ternary group 2: { 0: Millston.Osyka.Noyes, 8: HillTop.RossFork.Ocoee } + ternary group 3: { 1: HillTop.RossFork.Brinklow(0..6), 8: HillTop.Maddock.Calcasieu(16..31), 24: HillTop.Maddock.Calcasieu(0..15) } + byte group 0: { 0: HillTop.RossFork.Suttle } + byte group 3: { 0: HillTop.RossFork.Brinklow(7) } + format: { action: 0..1, immediate: 2..21 } + action_bus: { 124..127 : immediate(0..19) } + instruction: _Almota_0$tind(action, $DEFAULT) + actions: + Peoria(1, 5): + - default_action: { allowed: true } + - handle: 0x200000d9 + - next_table: 1 + - { $constant0: immediate(0..19), $constant0: 511 } + - set HillTop.Wisdom.Havana, 1 + - set HillTop.Wisdom.Blencoe, HillTop.RossFork.Ankeny + - set HillTop.Wisdom.Morstein, $constant0 + Sequim(2, 0): + - default_action: { allowed: true } + - handle: 0x200000da + - next_table: 2 + - { } + default_action: Sequim +stage 10 ingress: + ternary_match _OldTown 1: + p4: { name: OldTown, size: 512, disable_atomic_modify : true } + p4_param_order: + Millston.Rainelle.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Rainelle" } + HillTop.Wisdom.Blencoe: { type: ternary, size: 8, full_size: 8, key_name: "Wisdom.Blencoe" } + HillTop.Wisdom.Havana: { type: ternary, size: 1, full_size: 1, key_name: "Wisdom.Havana" } + HillTop.RossFork.Pridgen: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Pridgen" } + HillTop.RossFork.Ocoee: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } + HillTop.RossFork.Chevak: { type: ternary, size: 16, full_size: 16, key_name: "RossFork.Chevak" } + HillTop.RossFork.Mendocino: { type: ternary, size: 16, full_size: 16, key_name: "RossFork.Mendocino" } + row: [ 8, 9 ] + bus: [ 0, 0 ] + column: + - 0 + - 0 + indirect_bus: 1 + input_xbar: + ternary group 8: { 0: HillTop.RossFork.Chevak(0..7), 8: HillTop.Wisdom.Blencoe, 16: HillTop.RossFork.Ocoee, 27: Millston.Rainelle.$valid } + ternary group 10: { 0: HillTop.RossFork.Mendocino(8..15), 8: HillTop.Wisdom.Havana, 23: HillTop.RossFork.Pridgen, 24: HillTop.RossFork.Mendocino(0..7), 32: HillTop.RossFork.Chevak(8..15) } + match: + - { group: 8, dirtcam: 0x55 } + - { group: 10, dirtcam: 0x155 } + hit: [ _Trevorton ] + miss: _Trevorton + action: _OldTown$action_data($DIRECT, $DEFAULT) + instruction: _OldTown($DEFAULT, $DEFAULT) + actions: + Lynne(0, 1): + - p4_param_order: { Pajaros: 5 } + - default_action: { allowed: true } + - handle: 0x200000e8 + - next_table: 0 + - { Pajaros: $adf_b0(0..4) } + - set HillTop.Edwards.Pajaros, Pajaros + default_action: Lynne + default_action_parameters: + Pajaros: "0x0" + action _OldTown$action_data: + p4: { name: OldTown$action } + row: 13 + column: 4 + vpns: [ 0 ] + home_row: + - 13 + format Lynne: { $adf_b0: 0..7 } + action_bus: { 2 : $adf_b0 } + exact_match _Trevorton 2: + p4: { name: Trevorton, size: 1024, disable_atomic_modify : true } + p4_param_order: + HillTop.Minturn.Whitewood: { type: exact, size: 10, full_size: 10, key_name: "Minturn.Whitewood" } + row: 4 + bus: 1 + column: 3 + stash: + row: [ 4 ] + col: [ 3 ] + unit: [ 0 ] + ways: + - [0, 0, 0x0, [4, 3]] + input_xbar: + exact group 0: { 0: HillTop.Minturn.Whitewood } + hash 0: + 0..7: HillTop.Minturn.Whitewood(0..7) + 8..9: HillTop.Minturn.Whitewood(8..9) + hash group 0: + table: [0] + seed: 0x0 + format: { action(0): 0..0, version(0): 112..115, meter_addr(0): 1..10, meter_pfe(0): 11..11 } + hit: [ _Ivanpah ] + miss: _Ivanpah + action_bus: { 3 : _Trevorton$meter..Lacombe color } + meter: _Trevorton$meter..Lacombe(meter_addr, meter_pfe, $DEFAULT) + meter_color : _Trevorton$meter..Lacombe(meter_addr, meter_pfe) + instruction: _Trevorton(action, $DEFAULT) + actions: + Clifton(0, 2): + - p4_param_order: { Kingsland: 32 } + - default_action: { allowed: true } + - handle: 0x200000de + - next_table: 0 + - { Kingsland: meter_addr } + - set HillTop.Minturn.Tilton, _Trevorton$meter..Lacombe color(0..1) + - _Trevorton$meter..Lacombe(2, Kingsland) + Eaton(1, 4): + - default_action: { allowed: true } + - handle: 0x200000df + - next_table: 0 + - set HillTop.Minturn.Tilton, 2 + default_action: Eaton + meter _Trevorton$meter..Lacombe: + p4: { name: Lacombe, size: 128 } + row: 15 + column: [ 2, 3 ] + maprams: [ 2, 3 ] + color_maprams: + row: 7 + bus: 0 + column: 0 + address: idletime + type: standard + count: bytes + per_flow_enable: meter_pfe + ternary_match _Ivanpah 3: + p4: { name: Ivanpah, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.Komatke.Monahans: { type: ternary, size: 1, full_size: 1, key_name: "Komatke.Monahans" } + HillTop.Moose.Monahans: { type: ternary, size: 1, full_size: 1, key_name: "Moose.Monahans" } + HillTop.RossFork.Ocoee: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } + HillTop.RossFork.Juniata: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Juniata" } + HillTop.RossFork.Brinkman: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Brinkman" } + HillTop.RossFork.Redden: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Redden" } + HillTop.Wisdom.Havana: { type: ternary, size: 1, full_size: 1, key_name: "Wisdom.Havana" } + HillTop.Ovett.Hammond: { type: ternary, size: 4, full_size: 4, key_name: "Ovett.Hammond" } + row: [ 10, 11 ] + bus: [ 0, 0 ] + column: + - 0 + - 0 + input_xbar: + ternary group 7: { 16: HillTop.Ovett.Hammond.1-3, 19: HillTop.Ovett.Hammond.0-0, 21: HillTop.Moose.Monahans, 28: HillTop.Komatke.Monahans, 35: HillTop.RossFork.Juniata } + ternary group 9: { 0: HillTop.RossFork.Ocoee, 8: HillTop.RossFork.Redden, 16: HillTop.Wisdom.Havana, 29: HillTop.RossFork.Brinkman } + match: + - { group: 7, dirtcam: 0x150 } + - { group: 9, dirtcam: 0x55 } + gateway: + name: cond-38 + input_xbar: + exact group 0: { 17: HillTop.Wisdom.Onycha } + row: 1 + bus: 0 + unit: 0 + match: { 1: HillTop.Wisdom.Onycha } + 0b****010: _Edinburgh + miss: run_table + condition: + expression: "(HillTop.Wisdom.Onycha != 2)" + true: _Ivanpah + false: _Edinburgh + hit: [ _Edinburgh ] + miss: _Edinburgh + indirect: _Ivanpah$tind + ternary_indirect _Ivanpah$tind: + row: 0 + bus: 0 + column: 2 + input_xbar: + ternary group 7: { 16: HillTop.Ovett.Hammond.1-3, 19: HillTop.Ovett.Hammond.0-0, 21: HillTop.Moose.Monahans, 28: HillTop.Komatke.Monahans, 35: HillTop.RossFork.Juniata } + ternary group 9: { 0: HillTop.RossFork.Ocoee, 8: HillTop.RossFork.Redden, 16: HillTop.Wisdom.Havana, 29: HillTop.RossFork.Brinkman } + format: { action: 0..2, immediate: 3..34 } + action_bus: { 64..65 : immediate(0..15), 66..67 : immediate(16..31) } + instruction: _Ivanpah$tind(action, $DEFAULT) + actions: + Langford(1, 3): + - p4_param_order: { Pinole: 1 } + - default_action: { allowed: true } + - handle: 0x200000e9 + - next_table: 0 + - { Pinole: immediate(0..0) } + - deposit-field H7(0..11), H1(0..11), H5 + - or H52, Pinole, H62 + Cowley(2, 5): + - p4_param_order: { Pinole: 1 } + - default_action: { allowed: true } + - handle: 0x200000ea + - next_table: 0 + - { Pinole: immediate(0..0) } + - set ig_intr_md_for_tm.mcast_grp_a, HillTop.Moose.Townville + - or H52, Pinole, H56 + Lackey(3, 6): + - p4_param_order: { Pinole: 1 } + - default_action: { allowed: true } + - handle: 0x200000eb + - next_table: 0 + - { Pinole: immediate(0..0), $constant0: immediate(16..31), $constant0: 4096 } + - add ig_intr_md_for_tm.mcast_grp_a, HillTop.Wisdom.Nenana, $constant0 + - set ig_intr_md_for_tm.copy_to_cpu, Pinole + Trion(4, 8): + - p4_param_order: { Pinole: 1 } + - default_action: { allowed: true } + - handle: 0x200000ec + - next_table: 0 + - { Pinole: immediate(0..0) } + - set ig_intr_md_for_tm.mcast_grp_a, 0 + - set ig_intr_md_for_tm.copy_to_cpu, Pinole + Baldridge(5, 10): + - p4_param_order: { Pinole: 1 } + - default_action: { allowed: true } + - handle: 0x200000ed + - next_table: 0 + - { Pinole: immediate(0..0) } + - deposit-field H7(12..15), 0, H2 + - or H52, Pinole, H52 + Carlson(6, 12): + - default_action: { allowed: true } + - handle: 0x200000ee + - next_table: 0 + - { $constant0: immediate(0..15), $constant0: 4096 } + - add ig_intr_md_for_tm.mcast_grp_a, HillTop.Wisdom.Nenana, $constant0 + - set ig_intr_md_for_tm.copy_to_cpu, 1 + - set HillTop.Wisdom.Blencoe, 26 + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x200000ef + - next_table: 0 + - { } + default_only_action: NoAction + exact_match _Edinburgh 4: + p4: { name: Edinburgh, size: 16384, disable_atomic_modify : true } + p4_param_order: + HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } + HillTop.Savery.Kaluaaha: { type: exact, size: 16, full_size: 16, key_name: "Savery.Kaluaaha" } + HillTop.Savery.Calcasieu: { type: exact, size: 16, full_size: 16, key_name: "Savery.Calcasieu" } + HillTop.Savery.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Savery.Chevak" } + HillTop.Savery.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Savery.Mendocino" } + HillTop.Savery.LasVegas: { type: exact, size: 8, full_size: 8, key_name: "Savery.LasVegas" } + HillTop.Savery.PineCity: { type: exact, size: 6, full_size: 6, key_name: "Savery.PineCity" } + HillTop.Savery.Exton: { type: exact, size: 8, full_size: 8, key_name: "Savery.Exton" } + HillTop.Savery.Noyes: { type: exact, size: 8, full_size: 8, key_name: "Savery.Noyes" } + HillTop.Savery.Peebles: { type: exact, size: 1, full_size: 1, key_name: "Savery.Peebles" } + row: [ 7, 6, 5, 4 ] + bus: [ 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 6, 7 ] + - [ 2, 3, 4, 6, 7 ] + - [ 2, 3, 4, 6, 7 ] + - 2 + stash: + row: [ 7 ] + col: [ 2 ] + unit: [ 0 ] + ways: + - [0, 1, 0xf, [7, 2], [7, 3], [7, 4], [7, 6], [7, 7], [6, 2], [6, 3], [6, 4], [6, 6], [6, 7], [5, 2], [5, 3], [5, 4], [5, 6], [5, 7], [4, 2]] + input_xbar: + exact group 1: { 0: HillTop.Savery.Chevak, 16: HillTop.Savery.Mendocino, 32: HillTop.Savery.Calcasieu, 48: HillTop.Savery.Kaluaaha, 68: HillTop.Bessie.Miranda, 86: HillTop.Savery.PineCity, 101: HillTop.Savery.Peebles, 104: HillTop.Savery.Noyes, 112: HillTop.Savery.LasVegas, 120: HillTop.Savery.Exton } + hash 2: + 10..19: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) + 40..43: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) + hash 3: + 10..13: random(HillTop.Savery.PineCity(5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(0..3) + 14..17: random(HillTop.Savery.PineCity(5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(4..7) + 18..19: random(HillTop.Savery.PineCity(5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(0..1) + 40..42: random(HillTop.Savery.PineCity(5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(2..4) + 43: random(HillTop.Savery.PineCity(5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.Peebles + hash group 0: + table: [2, 3] + seed: 0x10000068400 + format: { action(0): 0..0, version(0): 112..115, match(0): [32..111, 8..15, 3..3 ] } + match: [ HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton, HillTop.Savery.Chevak(0..7), HillTop.Savery.Chevak(8..15), HillTop.Savery.Mendocino(0..7), HillTop.Savery.Mendocino(8..15), HillTop.Savery.Calcasieu(0..7), HillTop.Savery.Calcasieu(8..15), HillTop.Savery.Kaluaaha(0..7), HillTop.Savery.Kaluaaha(8..15), HillTop.Savery.PineCity(5) ] + gateway: + name: cond-39 + input_xbar: + exact group 0: { 29: HillTop.Ovett.Hematite, 32: HillTop.RossFork.Yaurel } + row: 0 + bus: 1 + unit: 1 + match: { 0: HillTop.RossFork.Yaurel, 13: HillTop.Ovett.Hematite } + 0b**0************1: Newcomb_0 + miss: run_table + condition: + expression: "(HillTop.RossFork.Yaurel == 1 && HillTop.Ovett.Hematite == 0)" + true: Newcomb_0 + false: _Edinburgh + hit: [ cond-35 ] + miss: cond-35 + action: _Edinburgh$action_data($DIRECT, $DEFAULT) + instruction: _Edinburgh(action, $DEFAULT) + actions: + Unionvale(1, 7): + - p4_param_order: { Cornell: 32 } + - default_action: { allowed: true } + - handle: 0x200000f1 + - next_table: 0 + - { Cornell: $adf_f0(0..31) } + - maxu HillTop.Mausdale.Kenney, HillTop.Mausdale.Kenney, Cornell + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x200000f2 + - next_table: 0 + - { } + default_only_action: NoAction + action _Edinburgh$action_data: + p4: { name: Edinburgh$action } + row: [ 15, 14, 13 ] + word: [ 0, 0, 0 ] + column: + - [ 4, 5 ] + - 5 + - 5 + vpns: + - [ 0, 1 ] + - [ 2 ] + - [ 3 ] + home_row: + - 15 + format Unionvale: { $adf_f0: 0..31 } + action_bus: { 96..99 : $adf_f0 } + ternary_match Newcomb_0 5: + p4: { name: Newcomb, size: 1, disable_atomic_modify : true } + hit: [ cond-35 ] + miss: cond-35 + indirect: Newcomb_0$tind + ternary_indirect Newcomb_0$tind: + row: 2 + bus: 0 + format: { action: 0..0 } + instruction: Newcomb_0$tind(action, $DEFAULT) + actions: + Terry(0, 9): + - default_action: { allowed: true } + - handle: 0x200000f0 + - next_table: 0 + - set HillTop.Mausdale.Kenney, 0 + default_action: Terry + gateway cond-35 6: + name: cond-35 + input_xbar: + exact group 0: { 36: HillTop.Wisdom.Piqua, 46: HillTop.Murphy.Blairsden, 53: HillTop.RossFork.Weyauwega, 62: HillTop.RossFork.Tenino, 63: HillTop.RossFork.Pridgen, 64: HillTop.Wisdom.Havana, 75: HillTop.Murphy.Standish } + hash 0: + 44: HillTop.RossFork.Pridgen + 46: HillTop.Murphy.Blairsden + hash 1: + 45: HillTop.Murphy.Standish + hash group 0: + table: [0, 1] + seed: 0x0 + row: 4 + bus: 1 + unit: 0 + match: { 0: HillTop.Wisdom.Havana, 13: HillTop.RossFork.Weyauwega, 20: HillTop.Wisdom.Piqua, 30: HillTop.RossFork.Tenino, 36: HillTop.RossFork.Pridgen, 37: HillTop.Murphy.Standish, 38: HillTop.Murphy.Blairsden } + 0b000*****0*********0******0************0: _Felton + miss: _RockHill + condition: + expression: "(HillTop.Wisdom.Havana == 0 && HillTop.RossFork.Weyauwega == 0 && HillTop.Wisdom.Piqua == 0 && HillTop.RossFork.Tenino == 0 && HillTop.RossFork.Pridgen == 0 && HillTop.Murphy.Standish == 0 && HillTop.Murphy.Blairsden == 0)" + true: _Felton + false: _RockHill + ternary_match _Felton 7: + p4: { name: Felton, size: 1, disable_atomic_modify : true } + gateway: + name: cond-36 + input_xbar: + exact group 2: { 0: HillTop.Wisdom.Morstein, 25: HillTop.Wisdom.Onycha, 32: HillTop.RossFork.Quebrada, 57: HillTop.Wisdom.Westhoff } + hash 4: + 48..50: HillTop.Wisdom.Westhoff + hash group 0: + table: [4] + seed: 0x0 + row: 0 + bus: 0 + unit: 0 + match: { 0: HillTop.RossFork.Quebrada(0..7), 8: HillTop.RossFork.Quebrada(8..15), 16: HillTop.RossFork.Quebrada(16..19), 25: HillTop.Wisdom.Onycha, 40: HillTop.Wisdom.Westhoff } + xor: { 0: HillTop.Wisdom.Morstein(0..7), 8: HillTop.Wisdom.Morstein(8..15), 16: HillTop.Wisdom.Morstein(16..19) } + 0b***********************00000000000000000000: run_table + 0b101************001*************************: run_table + miss: _Arial + condition: + expression: "(HillTop.RossFork.Quebrada == HillTop.Wisdom.Morstein || HillTop.Wisdom.Onycha == 1 && HillTop.Wisdom.Westhoff == 5)" + true: _Felton + false: _Arial + hit: [ _RockHill ] + miss: _RockHill + indirect: _Felton$tind + ternary_indirect _Felton$tind: + row: 1 + bus: 1 + format: { action: 0..0 } + instruction: _Felton$tind(action, $DEFAULT) + actions: + Sedona(1, 11): + - default_action: { allowed: true } + - handle: 0x200000e0 + - next_table: 0 + - set HillTop.RossFork.Charco, 1 + default_action: Sedona + exact_match _Arial 8: + p4: { name: Arial, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.Wisdom.Morstein: { type: exact, size: 11, full_size: 20, key_name: "Wisdom.Morstein" } + row: 3 + bus: 0 + column: 2 + stash: + row: [ 3 ] + col: [ 2 ] + unit: [ 0 ] + ways: + - [0, 2, 0x0, [3, 2]] + input_xbar: + exact group 2: { 0: HillTop.Wisdom.Morstein(0..10) } + hash 4: + 20..26: random(HillTop.Wisdom.Morstein(7)) ^ HillTop.Wisdom.Morstein(0..6) + 27..29: random(HillTop.Wisdom.Morstein(7)) ^ HillTop.Wisdom.Morstein(8..10) + hash group 0: + table: [4] + seed: 0x30500000 + format: { action(0): 0..1, version(0): 112..115, match(0): 39..39 } + match: [ HillTop.Wisdom.Morstein(7) ] + gateway: + name: cond-37 + input_xbar: + exact group 2: { 11: HillTop.Wisdom.Morstein(11..19), 64: HillTop.Lamona.Whitefish } + row: 3 + bus: 0 + unit: 0 + match: { 16: HillTop.Lamona.Whitefish, 3: HillTop.Wisdom.Morstein(11..15), 8: HillTop.Wisdom.Morstein(16..19) } + 0b******10****000000111: run_table + miss: _RockHill + condition: + expression: "(HillTop.Lamona.Whitefish == 2 && HillTop.Wisdom.Morstein & 1046528 == 14336)" + true: _Arial + false: _RockHill + hit: [ _RockHill ] + miss: _RockHill + instruction: _Arial(action, $DEFAULT) + actions: + Swisshome(1, 0): + - default_action: { allowed: true } + - handle: 0x200000e1 + - next_table: 0 + Kotzebue(2, 13): + - default_action: { allowed: true } + - handle: 0x200000e2 + - next_table: 0 + - set HillTop.RossFork.Daphne, 1 + default_action: Swisshome +stage 11 ingress: + ternary_match _RockHill 0: + p4: { name: RockHill, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.Wisdom.Blencoe: { type: ternary, size: 8, full_size: 8, key_name: "Wisdom.Blencoe" } + HillTop.RossFork.Alamosa: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Alamosa" } + HillTop.RossFork.Boerne: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Boerne" } + HillTop.RossFork.Bucktown: { type: ternary, size: 16, full_size: 32, key_name: "RossFork.Bucktown" } + Millston.GlenAvon.$valid: { type: ternary, size: 1, full_size: 1, key_name: "GlenAvon" } + Millston.Brookneal.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Brookneal" } + Millston.Gotham.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Gotham" } + Millston.Brookneal.SoapLake: { type: ternary, size: 16, full_size: 16, key_name: "Brookneal.SoapLake" } + HillTop.Wisdom.Onycha: { type: ternary, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } + row: [ 0, 1 ] + bus: [ 1, 1 ] + column: + - 1 + - 1 + input_xbar: + ternary group 0: { 0: Millston.Brookneal.SoapLake, 17: HillTop.Wisdom.Onycha, 27: HillTop.RossFork.Alamosa, 32: HillTop.RossFork.Bucktown(0..7) } + ternary group 1: { 0: HillTop.RossFork.Boerne, 8: HillTop.Wisdom.Blencoe, 20: Millston.GlenAvon.$valid, 24: HillTop.RossFork.Bucktown(8..15) } + byte group 1: { 4: Millston.Gotham.$valid, 5: Millston.Brookneal.$valid } + match: + - { group: 0, byte_group: 1, byte_config: 1, dirtcam: 0x555 } + - { group: 1, dirtcam: 0x55 } + hit: [ _Lignite ] + miss: _Lignite + indirect: _RockHill$tind + ternary_indirect _RockHill$tind: + row: 5 + bus: 0 + column: 2 + input_xbar: + ternary group 0: { 0: Millston.Brookneal.SoapLake, 17: HillTop.Wisdom.Onycha, 27: HillTop.RossFork.Alamosa, 32: HillTop.RossFork.Bucktown(0..7) } + ternary group 1: { 0: HillTop.RossFork.Boerne, 8: HillTop.Wisdom.Blencoe, 20: Millston.GlenAvon.$valid, 24: HillTop.RossFork.Bucktown(8..15) } + byte group 1: { 4: Millston.Gotham.$valid, 5: Millston.Brookneal.$valid } + format: { action: 0..2 } + instruction: _RockHill$tind(action, $DEFAULT) + actions: + Swisshome(0, 0): + - default_action: { allowed: true } + - handle: 0x20000114 + - next_table: 0 + Olcott(1, 1): + - default_action: { allowed: true } + - handle: 0x20000115 + - next_table: 0 + - set Millston.GlenAvon.Kaluaaha, HillTop.Maddock.Kaluaaha + - set Millston.GlenAvon.Calcasieu, HillTop.Maddock.Calcasieu + Lefor(2, 2): + - default_action: { allowed: true } + - handle: 0x20000116 + - next_table: 0 + - set Millston.GlenAvon.Kaluaaha, HillTop.Maddock.Kaluaaha + - set Millston.GlenAvon.Calcasieu, HillTop.Maddock.Calcasieu + - set Millston.Grays.Chevak, HillTop.RossFork.Glenmora + - set Millston.Grays.Mendocino, HillTop.RossFork.DonaAna + - not W50, W50 + Volens(3, 4): + - default_action: { allowed: true } + - handle: 0x20000117 + - next_table: 0 + - set Millston.GlenAvon.Kaluaaha, HillTop.Maddock.Kaluaaha + - set Millston.GlenAvon.Calcasieu, HillTop.Maddock.Calcasieu + - set HillTop.RossFork.Bucktown, 0 + - set Millston.Grays.Chevak, HillTop.RossFork.Glenmora + - set Millston.Grays.Mendocino, HillTop.RossFork.DonaAna + - set W50(0..15), 4294967295 + Virgilina(4, 6): + - default_action: { allowed: true } + - handle: 0x20000118 + - next_table: 0 + - set Millston.Brookneal.SoapLake, 0 + - set HillTop.RossFork.Bucktown, 0 + - set Millston.GlenAvon.Kaluaaha, HillTop.Maddock.Kaluaaha + - set Millston.GlenAvon.Calcasieu, HillTop.Maddock.Calcasieu + - set Millston.Grays.Chevak, HillTop.RossFork.Glenmora + - set Millston.Grays.Mendocino, HillTop.RossFork.DonaAna + Dwight(5, 8): + - default_action: { allowed: true } + - handle: 0x20000119 + - next_table: 0 + - set HillTop.RossFork.Bucktown, 0 + - not W50, W50 + NoAction(-1, 3): + - default_only_action: { allowed: true } + - handle: 0x2000011a + - next_table: 0 + default_only_action: NoAction + hash_action _Lignite 1: + p4: { name: Lignite, size: 32768, disable_atomic_modify : true } + p4_param_order: + HillTop.Mausdale.Kenney: { type: exact, size: 15, full_size: 32, key_name: "Mausdale.Kenney" } + row: 0 + bus: 0 + hash_dist: + 0: { hash: 0, mask: 0x7fff, shift: 1 } + input_xbar: + exact group 0: { 0: HillTop.Mausdale.Kenney(0..14) } + hash 0: + 0..14: stripe(HillTop.Mausdale.Kenney(0..14)) + hash group 0: + table: [0] + seed: 0x0 + gateway: + name: _Lignite-gateway + row: 1 + bus: 0 + unit: 0 + 0x0: _Rhodell + miss: _Rhodell + condition: + expression: "true(always hit)" + true: _Rhodell + false: _Rhodell + next: [] + stats: _Lignite$stats.Encinitas(hash_dist 0, $DEFAULT) + instruction: _Lignite($DEFAULT, $DEFAULT) + actions: + Issaquah(0, 0): + - default_action: { allowed: true } + - handle: 0x20000107 + - next_table: 0 + - _Lignite$stats.Encinitas($DIRECT) + default_action: Issaquah + counter _Lignite$stats.Encinitas: + p4: { name: Encinitas, how_referenced: direct } + row: [ 13, 11 ] + column: + - [ 0, 1, 2, 3, 4, 5 ] + - [ 0, 1, 2 ] + maprams: + - [ 0, 1, 2, 3, 4, 5 ] + - [ 0, 1, 2 ] + count: packets + format: {packets(0): 96..127, packets(1): 64..95, packets(2): 32..63, packets(3): 0..31} + lrt: + - { threshold: 20036672, interval: 268435200 } + - { threshold: 20036672, interval: 268435200 } + - { threshold: 20036672, interval: 268435200 } + exact_match _Rhodell 2: + p4: { name: Rhodell, size: 2048, disable_atomic_modify : true } + p4_param_order: + HillTop.Minturn.Tilton: { type: exact, size: 1, full_size: 2, key_name: "Minturn.Tilton", start_bit: 1 } + HillTop.Minturn.Grassflat: { type: exact, size: 10, full_size: 10, key_name: "Minturn.Grassflat" } + row: 7 + bus: 1 + column: 4 + stash: + row: [ 7 ] + col: [ 4 ] + unit: [ 1 ] + ways: + - [1, 0, 0x0, [7, 4]] + input_xbar: + exact group 0: { 64: HillTop.Minturn.Grassflat, 81: HillTop.Minturn.Tilton(1) } + hash 1: + 0..6: HillTop.Minturn.Grassflat(0..6) + 7..8: HillTop.Minturn.Grassflat(8..9) + 9: HillTop.Minturn.Tilton(1) + hash group 1: + table: [1] + seed: 0x0 + format: { immediate(0): 0..9, version(0): 112..115, match(0): 39..39, immediate(1): 10..19, version(1): 116..119, match(1): 47..47 } + match: [ HillTop.Minturn.Grassflat(7) ] + hit: [ _Clarkdale ] + miss: _Clarkdale + action_bus: { 32..33 : immediate(0..9) } + instruction: _Rhodell($DEFAULT, $DEFAULT) + actions: + Ugashik(0, 5): + - p4_param_order: { Grassflat: 32 } + - default_action: { allowed: true } + - handle: 0x20000105 + - next_table: 0 + - { Grassflat.0-9: immediate(0..9) } + - set ig_intr_md_for_dprsr.mirror_type, 1 + - set HillTop.Minturn.Grassflat, Grassflat.0-9 + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x20000106 + - next_table: 0 + - { } + default_only_action: NoAction + ternary_match _Clarkdale 3: + p4: { name: Clarkdale, size: 1536, disable_atomic_modify : true } + p4_param_order: + HillTop.Tiburon.Arnold: { type: ternary, size: 7, full_size: 9, key_name: "Tiburon.Arnold" } + HillTop.Mausdale.Kenney: { type: ternary, size: 2, full_size: 32, key_name: "Mausdale.Kenney", start_bit: 15 } + HillTop.RossFork.Weyauwega: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Weyauwega" } + HillTop.RossFork.Lowes: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Lowes" } + HillTop.RossFork.Almedia: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Almedia" } + HillTop.RossFork.Chugwater: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Chugwater" } + HillTop.RossFork.Charco: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Charco" } + HillTop.RossFork.Uvalde: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Uvalde" } + HillTop.RossFork.Daphne: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Daphne" } + HillTop.RossFork.Naruna: { type: ternary, size: 1, full_size: 3, key_name: "RossFork.Naruna", start_bit: 2 } + HillTop.Wisdom.Morstein: { type: ternary, size: 20, full_size: 20, key_name: "Wisdom.Morstein" } + ig_intr_md_for_tm.mcast_grp_a: { type: ternary, size: 16, full_size: 16, key_name: "Freeny.mcast_grp_a" } + HillTop.Wisdom.Piqua: { type: ternary, size: 1, full_size: 1, key_name: "Wisdom.Piqua" } + HillTop.Wisdom.Havana: { type: ternary, size: 1, full_size: 1, key_name: "Wisdom.Havana" } + HillTop.RossFork.Level: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Level" } + HillTop.RossFork.Hulbert: { type: ternary, size: 2, full_size: 2, key_name: "RossFork.Hulbert" } + HillTop.Murphy.Blairsden: { type: ternary, size: 1, full_size: 1, key_name: "Murphy.Blairsden" } + HillTop.Murphy.Standish: { type: ternary, size: 1, full_size: 1, key_name: "Murphy.Standish" } + HillTop.RossFork.Algoa: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Algoa" } + ig_intr_md_for_tm.copy_to_cpu: { type: ternary, size: 1, full_size: 1, key_name: "Freeny.copy_to_cpu" } + HillTop.RossFork.Thayne: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Thayne" } + HillTop.RossFork.Pridgen: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Pridgen" } + HillTop.RossFork.Tenino: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Tenino" } + row: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + input_xbar: + ternary group 2: { 4: HillTop.RossFork.Hulbert, 8: HillTop.Wisdom.Morstein(0..7), 22: HillTop.Murphy.Blairsden, 24: ig_intr_md_for_tm.copy_to_cpu, 38: HillTop.RossFork.Tenino, 39: HillTop.RossFork.Pridgen } + ternary group 3: { 0: HillTop.Wisdom.Morstein(8..15), 8: HillTop.Mausdale.Kenney(16), 20: HillTop.RossFork.Almedia, 24: HillTop.Wisdom.Havana, 25: HillTop.RossFork.Algoa, 33: HillTop.RossFork.Uvalde } + ternary group 4: { 0: HillTop.Tiburon.Arnold(0..6), 8: ig_intr_md_for_tm.mcast_grp_a(8..15), 16: ig_intr_md_for_tm.mcast_grp_a(0..7), 29: HillTop.RossFork.Weyauwega, 30: HillTop.RossFork.Charco, 31: HillTop.RossFork.Daphne, 37: HillTop.RossFork.Naruna.2-2 } + ternary group 5: { 3: HillTop.Murphy.Standish, 4: HillTop.RossFork.Level, 5: HillTop.RossFork.Lowes, 6: HillTop.RossFork.Chugwater, 8: HillTop.RossFork.Thayne, 20: HillTop.Wisdom.Piqua } + byte group 0: { 7: HillTop.Mausdale.Kenney(15) } + byte group 3: { 0: HillTop.Wisdom.Morstein(16..19) } + match: + - { group: 2, byte_group: 0, byte_config: 1, dirtcam: 0x555 } + - { group: 3, dirtcam: 0x155 } + - { group: 4, byte_group: 3, byte_config: 0, dirtcam: 0x555 } + - { group: 5, dirtcam: 0x15 } + hit: [ _Talbert, _Talbert, _Luverne, _Luverne, _Luverne ] + miss: _Talbert + indirect: _Clarkdale$tind + counter _Clarkdale$stats.Herring: + p4: { name: Herring } + row: 1 + column: [ 0, 1 ] + maprams: [ 0, 1 ] + count: packets + format: {packets(0): 64..127, packets(1): 0..63} + ternary_indirect _Clarkdale$tind: + row: 4 + bus: 0 + column: 2 + input_xbar: + ternary group 2: { 4: HillTop.RossFork.Hulbert, 8: HillTop.Wisdom.Morstein(0..7), 22: HillTop.Murphy.Blairsden, 24: ig_intr_md_for_tm.copy_to_cpu, 38: HillTop.RossFork.Tenino, 39: HillTop.RossFork.Pridgen } + ternary group 3: { 0: HillTop.Wisdom.Morstein(8..15), 8: HillTop.Mausdale.Kenney(16), 20: HillTop.RossFork.Almedia, 24: HillTop.Wisdom.Havana, 25: HillTop.RossFork.Algoa, 33: HillTop.RossFork.Uvalde } + ternary group 4: { 0: HillTop.Tiburon.Arnold(0..6), 8: ig_intr_md_for_tm.mcast_grp_a(8..15), 16: ig_intr_md_for_tm.mcast_grp_a(0..7), 29: HillTop.RossFork.Weyauwega, 30: HillTop.RossFork.Charco, 31: HillTop.RossFork.Daphne, 37: HillTop.RossFork.Naruna.2-2 } + ternary group 5: { 3: HillTop.Murphy.Standish, 4: HillTop.RossFork.Level, 5: HillTop.RossFork.Lowes, 6: HillTop.RossFork.Chugwater, 8: HillTop.RossFork.Thayne, 20: HillTop.Wisdom.Piqua } + byte group 0: { 7: HillTop.Mausdale.Kenney(15) } + byte group 3: { 0: HillTop.Wisdom.Morstein(16..19) } + format: { action: 0..2 } + stats: _Clarkdale$stats.Herring($DIRECT, $DEFAULT) + instruction: _Clarkdale$tind(action, $DEFAULT) + actions: + Wattsburg(0, 0): + - default_action: { allowed: true } + - handle: 0x20000108 + - next_table: 0 + - _Clarkdale$stats.Herring($DIRECT) + DeBeque(1, 7): + - default_action: { allowed: true } + - handle: 0x20000109 + - next_table: 1 + - set ig_intr_md_for_tm.copy_to_cpu, 1 + - _Clarkdale$stats.Herring($DIRECT) + Plush(2, 9): + - default_action: { allowed: true } + - handle: 0x2000010a + - next_table: 2 + - set ig_intr_md_for_dprsr.drop_ctl(0..1), 3 + - _Clarkdale$stats.Herring($DIRECT) + Bethune(3, 10): + - default_action: { allowed: true } + - handle: 0x2000010b + - next_table: 3 + - set ig_intr_md_for_tm.copy_to_cpu, 1 + - set ig_intr_md_for_dprsr.drop_ctl(0..1), 3 + - _Clarkdale$stats.Herring($DIRECT) + Truro(4, 12): + - default_action: { allowed: true } + - handle: 0x2000010c + - next_table: 4 + - set ig_intr_md_for_dprsr.drop_ctl(0..1), 3 + - _Clarkdale$stats.Herring($DIRECT) + default_action: Wattsburg + exact_match _Talbert 4: + p4: { name: Talbert, size: 4096, disable_atomic_modify : true } + p4_param_order: + HillTop.Tiburon.Arnold: { type: exact, size: 7, full_size: 9, key_name: "Tiburon.Arnold" } + HillTop.Edwards.Pajaros: { type: exact, size: 5, full_size: 5, key_name: "Edwards.Pajaros" } + row: 7 + bus: 0 + column: [ 2, 3 ] + stash: + row: [ 7 ] + col: [ 2 ] + unit: [ 0 ] + ways: + - [1, 1, 0x1, [7, 2], [7, 3]] + input_xbar: + exact group 0: { 88: HillTop.Edwards.Pajaros, 96: HillTop.Tiburon.Arnold(0..6) } + hash 1: + 10..14: HillTop.Edwards.Pajaros + 15..19: HillTop.Tiburon.Arnold(0..4) + 40: HillTop.Tiburon.Arnold(5) + hash group 1: + table: [1] + seed: 0x0 + format: { action(0): 0..0, version(0): 112..115, counter_addr(0): 2..13, meter_addr(0): 14..25, meter_pfe(0): 26..26, match(0): 54..54, action(1): 1..1, version(1): 116..119, counter_addr(1): 27..38, meter_addr(1): 39..50, meter_pfe(1): 51..51, match(1): 62..62 } + match: [ HillTop.Tiburon.Arnold(6) ] + hit: [ _Luverne ] + miss: _Luverne + action_bus: { 3 : _Talbert$meter..Comobabi color } + stats: _Talbert$stats..PawCreek(counter_addr, $DEFAULT) + meter: _Talbert$meter..Comobabi(meter_addr, meter_pfe, $DEFAULT) + meter_color : _Talbert$meter..Comobabi(meter_addr, meter_pfe) + instruction: _Talbert(action, $DEFAULT) + actions: + Cornwall(0, 0): + - p4_param_order: { Langhorne: 32 } + - default_action: { allowed: true } + - handle: 0x2000010d + - next_table: 0 + - { Langhorne: counter_addr } + - _Talbert$stats..PawCreek(Langhorne) + Natalbany(1, 14): + - p4_param_order: { Langhorne: 32 } + - default_action: { allowed: true } + - handle: 0x2000010e + - next_table: 0 + - { Langhorne: counter_addr } + - set ig_intr_md_for_dprsr.drop_ctl, _Talbert$meter..Comobabi color(0..2) + - _Talbert$meter..Comobabi(2, Langhorne) + - _Talbert$stats..PawCreek(Langhorne) + NoAction(-1, 11): + - default_only_action: { allowed: true } + - handle: 0x2000010f + - next_table: 0 + default_only_action: NoAction + counter _Talbert$stats..PawCreek: + p4: { name: PawCreek, size: 4096 } + row: 9 + column: [ 0, 1, 2 ] + maprams: [ 0, 1, 2 ] + count: packets + format: {packets(0): 64..127, packets(1): 0..63} + meter _Talbert$meter..Comobabi: + p4: { name: Comobabi, size: 4096 } + row: [ 11, 9 ] + column: + - [ 3, 4, 5 ] + - [ 3, 4 ] + maprams: + - [ 3, 4, 5 ] + - [ 3, 4 ] + color_maprams: + row: 4 + bus: 0 + column: 5 + address: idletime + type: standard + green: 0 + yellow: 2 + red: 2 + count: bytes + per_flow_enable: meter_pfe + ternary_match _Luverne 5: + p4: { name: Luverne, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.Wisdom.Onycha: { type: ternary, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } + HillTop.Wisdom.Piqua: { type: ternary, size: 1, full_size: 1, key_name: "Wisdom.Piqua" } + HillTop.Lamona.Whitefish: { type: ternary, size: 2, full_size: 2, key_name: "Lamona.Whitefish" } + HillTop.Wisdom.Morstein: { type: ternary, size: 4, full_size: 20, key_name: "Wisdom.Morstein", start_bit: 16 } + ig_intr_md_for_tm.mcast_grp_a: { type: ternary, size: 4, full_size: 16, key_name: "Freeny.mcast_grp_a", start_bit: 12 } + row: 3 + bus: 1 + column: 1 + hash_dist: + 1: { hash: 0, mask: 0xffff, shift: 0 } + input_xbar: + ternary group 6: { 4: ig_intr_md_for_tm.mcast_grp_a(12..15), 8: HillTop.Wisdom.Morstein(16..19), 17: HillTop.Wisdom.Onycha, 24: HillTop.Lamona.Whitefish, 36: HillTop.Wisdom.Piqua } + exact group 0: { 16: HillTop.Wisdom.Morstein(16..19), 32: HillTop.Wisdom.Morstein(0..15) } + hash 0: + 16..31: stripe(HillTop.Wisdom.Morstein(0..15)) + hash group 0: + table: [0] + seed: 0x0 + match: + - { group: 6, dirtcam: 0x155 } + gateway: + name: cond-42 + input_xbar: + exact group 1: { 0: HillTop.Wisdom.Havana } + row: 0 + bus: 0 + unit: 0 + match: { 0: HillTop.Wisdom.Havana } + 0b*******0: run_table + miss: _Kingman + condition: + expression: "(HillTop.Wisdom.Havana == 0)" + true: _Luverne + false: _Kingman + hit: [ _Kingman ] + miss: _Kingman + indirect: _Luverne$tind + ternary_indirect _Luverne$tind: + row: 3 + bus: 0 + column: 2 + hash_dist: + 1: { hash: 0, mask: 0xffff, shift: 0 } + input_xbar: + ternary group 6: { 4: ig_intr_md_for_tm.mcast_grp_a(12..15), 8: HillTop.Wisdom.Morstein(16..19), 17: HillTop.Wisdom.Onycha, 24: HillTop.Lamona.Whitefish, 36: HillTop.Wisdom.Piqua } + exact group 0: { 16: HillTop.Wisdom.Morstein(16..19), 32: HillTop.Wisdom.Morstein(0..15) } + hash 0: + 16..31: stripe(HillTop.Wisdom.Morstein(0..15)) + hash group 0: + table: [0] + seed: 0x0 + format: { action: 0..2 } + action_bus: { 36..37 : hash_dist(1, lo) } + action: _Luverne$action_data($DIRECT, $DEFAULT) + instruction: _Luverne$tind(action, $DEFAULT) + actions: + Ragley(1, 13): + - p4_param_order: { Dunkerton: 16 } + - default_action: { allowed: true } + - handle: 0x20000110 + - next_table: 0 + - { Dunkerton: $adf_h0(0..15) } + - set ig_intr_md_for_tm.level1_exclusion_id, Dunkerton + - set ig_intr_md_for_tm.rid, ig_intr_md_for_tm.mcast_grp_a + Gunder(2, 15): + - p4_param_order: { Dunkerton: 16 } + - default_action: { allowed: true } + - handle: 0x20000111 + - next_table: 0 + - { Dunkerton: $adf_h0(0..15) } + - set ig_intr_md_for_tm.level1_exclusion_id, Dunkerton + - set ig_intr_md_for_tm.rid, ig_intr_md_for_tm.mcast_grp_a + Maury(3, 16): + - p4_param_order: { Dunkerton: 16 } + - default_action: { allowed: true } + - handle: 0x20000112 + - next_table: 0 + - { Dunkerton: $adf_h0(0..15) } + - set ig_intr_md_for_tm.rid, 65535 + - set ig_intr_md_for_tm.level1_exclusion_id, Dunkerton + Estrella(4, 18): + - default_action: { allowed: true } + - handle: 0x20000113 + - next_table: 0 + - { } + - set ig_intr_md_for_tm.rid, 65535 + - set ig_intr_md_for_tm.level1_exclusion_id, 0 + - set H7, hash_dist(1, 0..15) + default_action: Gunder + default_action_parameters: + Dunkerton: "0x0" + action _Luverne$action_data: + p4: { name: Luverne$action } + row: 12 + column: 4 + vpns: [ 0 ] + home_row: + - 12 + format Ragley: { $adf_h0: 0..15 } + format Gunder: { $adf_h0: 0..15 } + format Maury: { $adf_h0: 0..15 } + action_bus: { 40..41 : $adf_h0 } + ternary_match _Kingman 6: + p4: { name: Kingman, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.Wisdom.Havana: { type: exact, size: 1, full_size: 1, key_name: "Wisdom.Havana" } + HillTop.RossFork.ElVerano: { type: exact, size: 1, full_size: 1, key_name: "RossFork.ElVerano" } + HillTop.Lamona.Pachuta: { type: ternary, size: 1, full_size: 1, key_name: "Lamona.Pachuta" } + HillTop.Wisdom.Blencoe: { type: ternary, size: 8, full_size: 8, key_name: "Wisdom.Blencoe" } + Millston.Wondervu$0.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Wondervu$0" } + row: 4 + bus: 1 + column: 1 + input_xbar: + ternary group 7: { 1: Millston.Wondervu$0.$valid, 2: HillTop.RossFork.ElVerano, 8: HillTop.Wisdom.Havana, 16: HillTop.Lamona.Pachuta, 24: HillTop.Wisdom.Blencoe } + match: + - { group: 7, dirtcam: 0x55 } + hit: [ _Woolwine, _Willette_0, _Woolwine, _Willette_0, _Woolwine, _Willette_0 ] + miss: _Willette_0 + indirect: _Kingman$tind + ternary_indirect _Kingman$tind: + row: 2 + bus: 0 + column: 2 + input_xbar: + ternary group 7: { 1: Millston.Wondervu$0.$valid, 2: HillTop.RossFork.ElVerano, 8: HillTop.Wisdom.Havana, 16: HillTop.Lamona.Pachuta, 24: HillTop.Wisdom.Blencoe } + format: { action: 0..2, immediate: 3..16 } + action_bus: { 16 : immediate(0..7), 17 : immediate(8..13), 96..99 : immediate(0..13) } + instruction: _Kingman$tind(action, $DEFAULT) + actions: + Bigfork(0, 17): + - p4_param_order: { Rumson: 9, McKee: 5 } + - default_action: { allowed: true } + - handle: 0x200000f9 + - next_table: 0 + - { Rumson: immediate(0..8), McKee: immediate(9..13) } + - set HillTop.Wisdom.Miller, HillTop.Tiburon.Arnold + - set ig_intr_md_for_tm.ucast_egress_port, Rumson + - set ig_intr_md_for_tm.qid, McKee + - set HillTop.Wisdom.RioPecos, 0 + Punaluu(1, 19): + - p4_param_order: { Brownson: 5 } + - default_action: { allowed: true } + - handle: 0x200000fa + - next_table: 1 + - { Brownson.3-4: immediate(0..1) } + - set HillTop.Wisdom.Miller, HillTop.Tiburon.Arnold + - set ig_intr_md_for_tm.qid(3..4), Brownson.3-4 + - set HillTop.Wisdom.RioPecos, 0 + Linville(2, 20): + - p4_param_order: { Rumson: 9, McKee: 5 } + - default_action: { allowed: true } + - handle: 0x200000fb + - next_table: 2 + - { Rumson: immediate(0..8), McKee: immediate(9..13) } + - set HillTop.Wisdom.Miller, HillTop.Tiburon.Arnold + - set ig_intr_md_for_tm.ucast_egress_port, Rumson + - set ig_intr_md_for_tm.qid, McKee + - set HillTop.Wisdom.RioPecos, 1 + Kelliher(3, 22): + - p4_param_order: { Brownson: 5 } + - default_action: { allowed: true } + - handle: 0x200000fc + - next_table: 3 + - { Brownson.3-4: immediate(0..1) } + - set HillTop.Wisdom.Miller, HillTop.Tiburon.Arnold + - set ig_intr_md_for_tm.qid(3..4), Brownson.3-4 + - set HillTop.Wisdom.RioPecos, 1 + Hopeton(4, 24): + - p4_param_order: { Rumson: 9, McKee: 5 } + - default_action: { allowed: true } + - handle: 0x200000fd + - next_table: 4 + - { Rumson: immediate(0..8), McKee: immediate(9..13) } + - set HillTop.Wisdom.Miller, HillTop.Tiburon.Arnold + - set ig_intr_md_for_tm.ucast_egress_port, Rumson + - set ig_intr_md_for_tm.qid, McKee + - set HillTop.Wisdom.RioPecos, 1 + - set HillTop.RossFork.CeeVee, Millston.Wondervu$0.Bowden + Bernstein(5, 26): + - p4_param_order: { Brownson: 5 } + - default_action: { allowed: true } + - handle: 0x200000fe + - next_table: 5 + - { Brownson.3-4: immediate(0..1) } + - set HillTop.Wisdom.Miller, HillTop.Tiburon.Arnold + - set ig_intr_md_for_tm.qid(3..4), Brownson.3-4 + - set HillTop.Wisdom.RioPecos, 1 + - set HillTop.RossFork.CeeVee, Millston.Wondervu$0.Bowden + default_action: Kelliher + default_action_parameters: + Brownson: "0x0" + ternary_match _Willette_0 7: + p4: { name: Willette, size: 512, action_profile: Franktown, disable_atomic_modify : true } + p4_param_order: + HillTop.Wisdom.Morstein: { type: ternary, size: 20, full_size: 20, key_name: "Wisdom.Morstein" } + row: 5 + bus: 1 + column: 1 + input_xbar: + ternary group 8: { 0: HillTop.Wisdom.Morstein } + match: + - { group: 8, dirtcam: 0x15 } + hit: [ _Woolwine ] + miss: _Woolwine + indirect: _Willette_0$tind + selection _Willette_0$selector.Franktown_sel: + p4: { name: Franktown_sel, size: 4 } + row: 15 + column: [ 0, 1 ] + maprams: [ 0, 1 ] + input_xbar: + exact group 1: { 8: HillTop.Lewiston.Staunton(8..15), 16: HillTop.Lewiston.Staunton(0..7), 24: HillTop.Tiburon.Arnold(8), 32: HillTop.Tiburon.Arnold(0..7) } + hash 2: + 0..50: slice(stripe(crc_rev(0x18005, 0x0, 0x0, 25, { 0: HillTop.Lewiston.Staunton(0..7), 8: HillTop.Lewiston.Staunton(8..15), 16: HillTop.Tiburon.Arnold(0..7), 24: HillTop.Tiburon.Arnold(8) })), 0..50) + hash group 2: + table: [2] + seed: 0x0 + mode: resilient 0 + non_linear: true + pool_sizes: [120] + action _Willette_0$action_data.Franktown: + p4: { name: Franktown, size: 32768 } + row: [ 15, 14, 12, 10 ] + word: [ 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 5 ] + - 5 + - 5 + - [ 3, 4 ] + vpns: + - [ 0, 1, 2, 3 ] + - [ 4 ] + - [ 5 ] + - [ 6, 7 ] + home_row: + - [ 15, 10 ] + format Ihlen: { $adf_f0: 0..31 } + action_bus: { 104..107 : $adf_f0 } + stateful _Willette_0$salu.Franktown_sel$salu: + p4: { name: Franktown_sel$salu, size: 122880, hidden: true } + selection_table: _Willette_0$selector.Franktown_sel + row: 15 + column: [ 0, 1 ] + maprams: [ 0, 1 ] + format: { lo: 1 } + actions: + set_bit_at_alu$0: + - set_bit_at + clr_bit_at_alu$0: + - clr_bit_at + set_bit_alu$0: + - set_bit + clr_bit_alu$0: + - clr_bit + ternary_indirect _Willette_0$tind: + row: 1 + bus: 0 + column: 2 + input_xbar: + ternary group 8: { 0: HillTop.Wisdom.Morstein } + format: { action: 0..2, meter_addr: 3..12, meter_pfe: 13..13, action_addr: 14..29 } + selector: _Willette_0$selector.Franktown_sel(meter_addr, meter_pfe, $DEFAULT) + selector_length: _Willette_0$selector.Franktown_sel($DEFAULT, $DEFAULT) + action: _Willette_0$action_data.Franktown(action_addr, $DEFAULT) + instruction: _Willette_0$tind(action, $DEFAULT) + actions: + Ihlen(0, 23): + - p4_param_order: { Faulkton: 9 } + - default_action: { allowed: true } + - handle: 0x200000ff + - next_table: 0 + - { Faulkton: $adf_f0(0..8) } + - set ig_intr_md_for_tm.ucast_egress_port, Faulkton + - set HillTop.Wisdom.Waubun, 0 + Philmont(1, 27): + - default_action: { allowed: true } + - handle: 0x20000100 + - next_table: 0 + - { } + - set ig_intr_md_for_tm.ucast_egress_port, HillTop.Wisdom.Morstein(0..8) + - set HillTop.Wisdom.Waubun, HillTop.Wisdom.Morstein(9..14) + Twinsburg(2, 28): + - default_action: { allowed: true } + - handle: 0x20000101 + - next_table: 0 + - { } + - set W2(0..8), 4294967295 + ElCentro(3, 30): + - default_action: { allowed: true } + - handle: 0x20000102 + - next_table: 0 + - { } + - set W2(0..8), 4294967295 + Redvale(4, 0): + - default_action: { allowed: true } + - handle: 0x20000103 + - next_table: 0 + - { } + default_action: Twinsburg + ternary_match _Woolwine 8: + p4: { name: Woolwine, size: 1, disable_atomic_modify : true } + gateway: + name: cond-41 + input_xbar: + exact group 0: { 105: HillTop.Wisdom.Onycha, 113: Millston.Wondervu$0.$valid } + row: 7 + bus: 0 + unit: 0 + match: { 9: Millston.Wondervu$0.$valid, 1: HillTop.Wisdom.Onycha } + 0b******0********: END + 0o****2: END + miss: run_table + condition: + expression: "(Millston.Wondervu[0].$valid == 1 && HillTop.Wisdom.Onycha != 2)" + true: _Woolwine + false: END + hit: [ END ] + miss: END + indirect: _Woolwine$tind + ternary_indirect _Woolwine$tind: + row: 1 + bus: 1 + format: { action: 0..0 } + instruction: _Woolwine$tind(action, $DEFAULT) + actions: + Basye(1, 21): + - default_action: { allowed: true } + - handle: 0x20000104 + - next_table: 0 + - set Millston.Calabash.McCaulley.0-7, Millston.Wondervu$0.McCaulley.0-7 + - set Millston.Calabash.McCaulley.8-15, Millston.Wondervu$0.McCaulley.8-15 + - set Millston.Wondervu$0.$valid, 0 + default_action: Basye +stage 0 egress: + ternary_match _Mendoza 13: + p4: { name: Mendoza, size: 512, disable_atomic_modify : true } + p4_param_order: + eg_intr_md.egress_rid: { type: exact, size: 16, full_size: 16, key_name: "Sonoma.egress_rid" } + eg_intr_md.egress_port: { type: exact, size: 9, full_size: 9, key_name: "Sonoma.egress_port" } + row: 5 + bus: 0 + column: 0 + input_xbar: + ternary group 10: { 0: eg_intr_md.egress_port(8), 8: eg_intr_md.egress_rid, 24: eg_intr_md.egress_port(0..7) } + match: + - { group: 10, byte_config: 3, dirtcam: 0x55 } + gateway: + name: cond-43 + input_xbar: + exact group 6: { 0: Millston.Belgrade.$valid } + row: 0 + bus: 0 + unit: 0 + match: { 0: Millston.Belgrade.$valid } + 0b*******1: _Brookwood + miss: run_table + condition: + expression: "(Millston.Belgrade.$valid == 1 == 1)" + true: _Brookwood + false: _Mendoza + hit: [ _Protivin ] + miss: _Protivin + indirect: _Mendoza$tind + ternary_indirect _Mendoza$tind: + row: 0 + bus: 1 + column: 4 + input_xbar: + ternary group 10: { 0: eg_intr_md.egress_port(8), 8: eg_intr_md.egress_rid, 24: eg_intr_md.egress_port(0..7) } + format: { action: 0..1 } + action: _Mendoza$action_data($DIRECT, $DEFAULT) + instruction: _Mendoza$tind(action, $DEFAULT) + actions: + Kosmos(1, 1): + - default_action: { allowed: true } + - handle: 0x2000012b + - next_table: 0 + - { } + - set HillTop.Wisdom.Onycha, 0 + - set HillTop.Wisdom.Westhoff, 3 + Ironia(2, 2): + - p4_param_order: { BigFork: 8 } + - default_action: { allowed: true } + - handle: 0x2000012c + - next_table: 0 + - { BigFork: $adf_b0(0..7) } + - set HillTop.Wisdom.Blencoe, BigFork + - set HillTop.Wisdom.Lathrop, 1 + - set HillTop.Wisdom.Onycha, 0 + - set HillTop.Wisdom.Stratford, 1 + - set W28(1..4), 2 + Kenvil(3, 4): + - p4_param_order: { Rhine: 32, LaJara: 32, Exton: 8, PineCity: 6, Bammel: 16, Bowden: 12, Adona: 24, Connell: 24 } + - default_action: { allowed: true } + - handle: 0x2000012d + - next_table: 0 + - { Exton: $adf_b0(0..7), Adona.0-7: $adf_b1(0..7), Connell.0-7: $adf_b2(0..7), $constant0: $adf_h2(0..15), $constant0: 17, Bowden: $adf_h3(0..11), Connell.8-23: $adf_h8(0..15), Bammel: $adf_h9(0..15), $data0: $adf_h10(0..13), PineCity: $data0(0..5), $constant2: $data0(6..9), $constant2: 5, $constant1: $data0(10..13), $constant1: 4, Adona.8-23: $adf_h11(0..15), Rhine: $adf_f2(0..31), LaJara: $adf_f3(0..31) } + - set HillTop.Wisdom.Onycha, 0 + - set Millston.GlenAvon.$valid, 1 + - set Millston.GlenAvon.Ocoee, 47 + - set Millston.GlenAvon.Exton, Exton + - set Millston.GlenAvon.Kaluaaha, Rhine + - set Millston.GlenAvon.Calcasieu, LaJara + - add Millston.GlenAvon.Rexville, HillTop.Sonoma.Iberia, $constant0 + - set Millston.Broadwell.$valid, 1 + - set Millston.Broadwell.LasVegas, Bammel + - set HillTop.Wisdom.Bowden, Bowden + - set HillTop.Wisdom.Adona.0-7, Adona.0-7 + - set HillTop.Wisdom.Adona.8-23, Adona.8-23 + - set HillTop.Wisdom.Connell.0-7, Connell.0-7 + - set HillTop.Wisdom.Connell.8-23, Connell.8-23 + - set H81(2..15), $data0 + - set W16, 0 + - set W28(1..4), 4 + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x2000012e + - next_table: 0 + - { } + default_only_action: NoAction + action _Mendoza$action_data: + p4: { name: Mendoza$action } + row: [ 13, 9 ] + word: [ 0, 1 ] + column: + - 3 + - 1 + vpns: + - [ 0 ] + - [ 0 ] + home_row: + - 13 + - 9 + format Ironia: { $adf_b0: 0..7 } + format Kenvil: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_b2: 16..23, $adf_h2: 32..47, $adf_h3: 48..63, $adf_h8: 128..143, $adf_h9: 144..159, $adf_h10: 160..175, $adf_h11: 176..191, $adf_f2: 64..95, $adf_f3: 96..127 } + action_bus: { 16 : $adf_b0, 17 : $adf_b1, 18 : $adf_b2, 48..49 : $adf_h2, 50..51 : $adf_h3, 80..81 : $adf_h8, 82..83 : $adf_h9, 84..85 : $adf_h10, 86..87 : $adf_h11, 104..107 : $adf_f2, 108..111 : $adf_f3 } + exact_match _Brookwood 14: + p4: { name: Brookwood, size: 32768, disable_atomic_modify : true } + p4_param_order: + eg_intr_md.egress_rid: { type: exact, size: 16, full_size: 16, key_name: "Sonoma.egress_rid" } + row: [ 7, 3, 2 ] + bus: [ 0, 1, 0 ] + column: + - [ 2, 3, 4, 6 ] + - [ 4, 6 ] + - [ 2, 3, 4 ] + stash: + row: [ 2 ] + col: [ 2 ] + unit: [ 0 ] + ways: + - [5, 0, 0x1, [2, 2], [2, 3]] + - [5, 1, 0x2, [7, 2], [7, 3]] + - [5, 2, 0x4, [3, 4], [3, 6]] + - [5, 3, 0x8, [7, 4], [7, 6]] + - [5, 0, 0x0, [2, 4]] + input_xbar: + exact group 4: { 64: eg_intr_md.egress_rid } + hash 9: + 0..7: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(0..7) + 8..9: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(8..9) + 40: random(eg_intr_md.egress_rid(10..15)) + 11..18: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(0..7) + 19: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(8) + 10: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(9) + 41: random(eg_intr_md.egress_rid(10..15)) + 22..29: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(0..7) + 20..21: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(8..9) + 42: random(eg_intr_md.egress_rid(10..15)) + 33..39: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(0..6) + 30: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(7) + 31..32: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(8..9) + 43: random(eg_intr_md.egress_rid(10..15)) + hash group 5: + table: [9] + seed: 0x407ac5830f7 + format: { action(0): 0..0, immediate(0): 4..15, version(0): 112..115, match(0): 58..63, action(1): 1..1, immediate(1): 16..27, version(1): 116..119, match(1): 66..71, action(2): 2..2, immediate(2): 28..39, version(2): 120..123, match(2): 74..79, action(3): 3..3, immediate(3): 40..51, version(3): 124..127, match(3): 82..87 } + match: [ eg_intr_md.egress_rid(10..15) ] + gateway: + name: cond-44 + input_xbar: + exact group 4: { 64: eg_intr_md.egress_rid } + row: 2 + bus: 0 + unit: 0 + match: { 0: eg_intr_md.egress_rid(0..7), 8: eg_intr_md.egress_rid(8..15) } + 0x0000: _Bechyn + miss: run_table + condition: + expression: "(eg_intr_md.egress_rid != 0)" + true: _Brookwood + false: _Bechyn + hit: [ _Bechyn ] + miss: _Bechyn + action_bus: { 52..53 : immediate(0..11) } + instruction: _Brookwood(action, $DEFAULT) + actions: + Gwynn(1, 6): + - p4_param_order: { Rolla: 12 } + - default_action: { allowed: true } + - handle: 0x2000011f + - next_table: 0 + - { Rolla: immediate(0..11) } + - set HillTop.Wisdom.Nenana, Rolla + - set HillTop.Wisdom.Piqua, 1 + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x20000120 + - next_table: 0 + - { } + default_only_action: NoAction + exact_match _Bechyn 15: + p4: { name: Bechyn, size: 128, disable_atomic_modify : true } + p4_param_order: + eg_intr_md.egress_port: { type: exact, size: 9, full_size: 9, key_name: "Sonoma.egress_port" } + row: 1 + bus: 1 + column: 6 + stash: + row: [ 1 ] + col: [ 6 ] + unit: [ 0 ] + ways: + - [2, 2, 0x0, [1, 6]] + input_xbar: + exact group 3: { 32: eg_intr_md.egress_port } + hash 6: + 20..27: eg_intr_md.egress_port(0..7) + 28: eg_intr_md.egress_port(8) + hash group 2: + table: [6] + seed: 0x0 + format: { immediate(0): 0..9, version(0): 112..115 } + hit: [ _Pound ] + miss: _Pound + action_bus: { 56..57 : immediate(0..9) } + instruction: _Bechyn($DEFAULT, $DEFAULT) + actions: + DeRidder(0, 3): + - p4_param_order: { Heaton: 10 } + - default_action: { allowed: true } + - handle: 0x20000121 + - next_table: 0 + - { Heaton: immediate(0..9) } + - set HillTop.McCaskill.Grassflat, Heaton + default_action: DeRidder + default_action_parameters: + Heaton: "0x0" +stage 2 egress: + exact_match _Pound 8: + p4: { name: Pound, size: 4096, disable_atomic_modify : true } + p4_param_order: + eg_intr_md.egress_port: { type: exact, size: 7, full_size: 9, key_name: "Sonoma.egress_port" } + HillTop.Wisdom.Nenana: { type: exact, size: 12, full_size: 12, key_name: "Wisdom.Nenana" } + HillTop.Wisdom.Waubun: { type: exact, size: 6, full_size: 6, key_name: "Wisdom.Waubun" } + row: 1 + bus: 1 + column: [ 8, 9 ] + stash: + row: [ 1 ] + col: [ 8 ] + unit: [ 0 ] + ways: + - [3, 0, 0x0, [1, 8]] + - [3, 1, 0x0, [1, 9]] + input_xbar: + exact group 5: { 24: HillTop.Wisdom.Nenana(8..11), 34: HillTop.Wisdom.Waubun, 48: eg_intr_md.egress_port(0..6), 64: HillTop.Wisdom.Nenana(0..7) } + hash 10: + 0..3: random(eg_intr_md.egress_port(0..6)) ^ HillTop.Wisdom.Nenana(8..11) + 4..9: random(eg_intr_md.egress_port(0..6)) ^ HillTop.Wisdom.Waubun + 11..14: random(eg_intr_md.egress_port(0..6)) ^ HillTop.Wisdom.Nenana(8..11) + 15..19: random(eg_intr_md.egress_port(0..6)) ^ HillTop.Wisdom.Waubun(0..4) + 10: random(eg_intr_md.egress_port(0..6)) ^ HillTop.Wisdom.Waubun(5) + hash 11: + 0..9: random(HillTop.Wisdom.Nenana(0..7)) + 10..19: random(HillTop.Wisdom.Nenana(0..7)) + hash group 3: + table: [10, 11] + seed: 0x6acf0 + format: { action(0): 0..1, immediate(0): 4..15, version(0): 112..115, match(0): [40..46, 32..39 ], action(1): 2..3, immediate(1): 16..27, version(1): 116..119, match(1): [56..62, 48..55 ] } + match: [ eg_intr_md.egress_port(0..6), HillTop.Wisdom.Nenana(0..7) ] + hit: [ _MoonRun ] + miss: _MoonRun + action_bus: { 72..73 : immediate(0..11) } + instruction: _Pound(action, $DEFAULT) + actions: + Dundee(0, 1): + - p4_param_order: { Bowden: 12 } + - default_action: { allowed: true } + - handle: 0x20000128 + - next_table: 0 + - { Bowden: immediate(0..11) } + - set HillTop.Wisdom.Bowden, Bowden + RedBay(1, 2): + - p4_param_order: { Bowden: 12 } + - default_action: { allowed: true } + - handle: 0x20000129 + - next_table: 0 + - { Bowden: immediate(0..11) } + - set HillTop.Wisdom.Bowden, Bowden + - set HillTop.Wisdom.Weatherby, 1 + Tunis(2, 4): + - default_action: { allowed: true } + - handle: 0x2000012a + - next_table: 0 + - { } + - set HillTop.Wisdom.Bowden, HillTop.Wisdom.Nenana + default_action: Tunis +stage 4 egress: + exact_match _MoonRun 4: + p4: { name: MoonRun, size: 8192, disable_atomic_modify : true } + p4_param_order: + HillTop.Wisdom.Piqua: { type: exact, size: 1, full_size: 1, key_name: "Wisdom.Piqua" } + Millston.Maumee.$valid: { type: exact, size: 1, full_size: 1, key_name: "Maumee" } + Millston.GlenAvon.$valid: { type: exact, size: 1, full_size: 1, key_name: "GlenAvon" } + HillTop.Wisdom.Nenana: { type: exact, size: 12, full_size: 12, key_name: "Wisdom.Nenana" } + row: 0 + bus: 1 + column: [ 4, 6 ] + stash: + row: [ 0 ] + col: [ 4 ] + unit: [ 0 ] + ways: + - [0, 1, 0x0, [0, 4]] + - [0, 2, 0x0, [0, 6]] + input_xbar: + exact group 1: { 56: HillTop.Wisdom.Nenana(8..11), 67: Millston.GlenAvon.$valid, 73: Millston.Maumee.$valid, 80: HillTop.Wisdom.Nenana(0..7), 100: HillTop.Wisdom.Piqua } + hash 2: + 10..13: HillTop.Wisdom.Nenana(8..11) + 21..24: HillTop.Wisdom.Nenana(8..11) + hash 3: + 10..13: random(HillTop.Wisdom.Nenana(3..7)) + 14: random(HillTop.Wisdom.Nenana(3..7)) ^ Millston.GlenAvon.$valid + 15: random(HillTop.Wisdom.Nenana(3..7)) ^ Millston.Maumee.$valid + 16..18: random(HillTop.Wisdom.Nenana(3..7)) ^ HillTop.Wisdom.Nenana(0..2) + 19: random(HillTop.Wisdom.Nenana(3..7)) ^ HillTop.Wisdom.Piqua + 21..24: random(HillTop.Wisdom.Nenana(3..7)) + 25: random(HillTop.Wisdom.Nenana(3..7)) ^ Millston.GlenAvon.$valid + 26: random(HillTop.Wisdom.Nenana(3..7)) ^ Millston.Maumee.$valid + 27..29: random(HillTop.Wisdom.Nenana(3..7)) ^ HillTop.Wisdom.Nenana(0..2) + 20: random(HillTop.Wisdom.Nenana(3..7)) ^ HillTop.Wisdom.Piqua + hash group 0: + table: [2, 3] + seed: 0x393c5c00 + format: { immediate(0): 0..7, version(0): 112..115, match(0): 35..39, immediate(1): 8..15, version(1): 116..119, match(1): 43..47, immediate(2): 16..23, version(2): 120..123, match(2): 51..55, immediate(3): 24..31, version(3): 124..127, match(3): 59..63 } + match: [ HillTop.Wisdom.Nenana(3..7) ] + hit: [ _Monse ] + miss: _Monse + action_bus: { 0 : immediate(0..7) } + instruction: _MoonRun($DEFAULT, $DEFAULT) + actions: + GlenDean(0, 1): + - p4_param_order: { Buncombe: 8 } + - default_action: { allowed: true } + - handle: 0x20000125 + - next_table: 0 + - { Buncombe: immediate(0..7) } + - set HillTop.McGonigle.Buncombe, Buncombe + default_action: GlenDean + default_action_parameters: + Buncombe: "0x0" + ternary_match _Monse 5: + p4: { name: Monse, size: 8, disable_atomic_modify : true } + p4_param_order: + HillTop.Freeny.Dunedin: { type: exact, size: 3, full_size: 3, key_name: "Freeny.Dunedin" } + row: 6 + bus: 0 + column: 0 + indirect_bus: 3 + input_xbar: + ternary group 0: { 0: HillTop.Freeny.Dunedin } + match: + - { group: 0, byte_config: 3, dirtcam: 0x1 } + hit: [ Dyess_0 ] + miss: Dyess_0 + action: _Monse$action_data($DIRECT, $DEFAULT) + instruction: _Monse($DEFAULT, $DEFAULT) + actions: + Danbury(0, 2): + - p4_param_order: { PineCity: 6 } + - default_action: { allowed: true } + - handle: 0x2000011d + - next_table: 0 + - { PineCity: $adf_h0(0..5) } + - set HillTop.Edwards.Renick, PineCity + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x2000011e + - next_table: 0 + - { } + default_only_action: NoAction + action _Monse$action_data: + p4: { name: Monse$action } + row: 7 + column: 3 + vpns: [ 0 ] + home_row: + - 7 + format Danbury: { $adf_h0: 0..15 } + action_bus: { 40..41 : $adf_h0 } + ternary_match Dyess_0 6: + p4: { name: Dyess, size: 16, disable_atomic_modify : true } + p4_param_order: + HillTop.Wisdom.Dyess: { type: exact, size: 1, full_size: 1, key_name: "Wisdom.Dyess" } + Millston.GlenAvon.$valid: { type: exact, size: 1, full_size: 1, key_name: "GlenAvon" } + Millston.Maumee.$valid: { type: exact, size: 1, full_size: 1, key_name: "Maumee" } + row: 2 + bus: 0 + column: 0 + input_xbar: + ternary group 5: { 3: Millston.GlenAvon.$valid, 9: Millston.Maumee.$valid, 32: HillTop.Wisdom.Dyess } + match: + - { group: 5, byte_config: 3, dirtcam: 0x105 } + gateway: + name: cond-45 + input_xbar: + exact group 3: { 1: HillTop.Wisdom.Onycha } + row: 2 + bus: 1 + unit: 0 + match: { 1: HillTop.Wisdom.Onycha } + 0b****000: run_table + 0b****011: run_table + miss: _Lebanon + condition: + expression: "(HillTop.Wisdom.Onycha == 0 || HillTop.Wisdom.Onycha == 3)" + true: Dyess_0 + false: _Lebanon + hit: [ _Lebanon ] + miss: _Lebanon + indirect: Dyess_0$tind + ternary_indirect Dyess_0$tind: + row: 3 + bus: 0 + column: 5 + input_xbar: + ternary group 5: { 3: Millston.GlenAvon.$valid, 9: Millston.Maumee.$valid, 32: HillTop.Wisdom.Dyess } + format: { action: 0..1 } + instruction: Dyess_0$tind(action, $DEFAULT) + actions: + Daguao(1, 3): + - default_action: { allowed: true } + - handle: 0x20000122 + - next_table: 0 + - set Millston.GlenAvon.Ocoee(7..7), 0 + Ripley(2, 4): + - default_action: { allowed: true } + - handle: 0x20000123 + - next_table: 0 + - set Millston.Maumee.Dassel(7..7), 0 + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x20000124 + - next_table: 0 + default_only_action: NoAction + ternary_match _Lebanon 7: + p4: { name: Lebanon, size: 1024, disable_atomic_modify : true } + p4_param_order: + HillTop.McCaskill.Whitewood: { type: exact, size: 10, full_size: 10, key_name: "McCaskill.Whitewood" } + row: [ 3, 4 ] + bus: [ 0, 0 ] + column: + - 0 + - 0 + input_xbar: + ternary group 0: { 8: HillTop.McCaskill.Whitewood(8..9), 16: HillTop.McCaskill.Whitewood(0..7) } + match: + - { group: 0, byte_config: 3, dirtcam: 0x14 } + hit: [ _Protivin ] + miss: _Protivin + indirect: _Lebanon$tind + meter _Lebanon$meter..Slinger: + p4: { name: Slinger, size: 128 } + row: 15 + column: [ 3, 4 ] + maprams: [ 3, 4 ] + color_maprams: + row: 7 + bus: 0 + column: 0 + address: idletime + type: standard + count: bytes + per_flow_enable: meter_pfe + ternary_indirect _Lebanon$tind: + row: 2 + bus: 0 + column: 5 + input_xbar: + ternary group 0: { 8: HillTop.McCaskill.Whitewood(8..9), 16: HillTop.McCaskill.Whitewood(0..7) } + format: { action: 0..0, meter_addr: 1..10, meter_pfe: 11..11 } + action_bus: { 3 : _Lebanon$meter..Slinger color } + meter: _Lebanon$meter..Slinger(meter_addr, meter_pfe, $DEFAULT) + meter_color : _Lebanon$meter..Slinger(meter_addr, meter_pfe) + instruction: _Lebanon$tind(action, $DEFAULT) + actions: + Lovelady(0, 5): + - p4_param_order: { Kingsland: 32 } + - default_action: { allowed: true } + - handle: 0x20000126 + - next_table: 0 + - { Kingsland: meter_addr } + - set HillTop.McCaskill.Tilton, _Lebanon$meter..Slinger color(0..1) + - _Lebanon$meter..Slinger(2, Kingsland) + PellCity(1, 6): + - default_action: { allowed: true } + - handle: 0x20000127 + - next_table: 0 + - set HillTop.McCaskill.Tilton, 2 + default_action: PellCity + ternary_match _Protivin 8: + p4: { name: Protivin, size: 128, disable_atomic_modify : true } + p4_param_order: + eg_intr_md.egress_port: { type: exact, size: 9, full_size: 9, key_name: "Sonoma.egress_port" } + HillTop.Lamona.Pachuta: { type: exact, size: 1, full_size: 1, key_name: "Lamona.Pachuta" } + HillTop.Wisdom.RioPecos: { type: exact, size: 1, full_size: 1, key_name: "Wisdom.RioPecos" } + HillTop.Wisdom.Onycha: { type: exact, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } + row: 0 + bus: 0 + column: 0 + input_xbar: + ternary group 8: { 0: HillTop.Wisdom.RioPecos, 8: eg_intr_md.egress_port(8), 16: eg_intr_md.egress_port(0..7), 24: HillTop.Lamona.Pachuta, 33: HillTop.Wisdom.Onycha } + match: + - { group: 8, byte_config: 3, dirtcam: 0x155 } + hit: [ _Medart, _Ghent ] + miss: _Medart + indirect: _Protivin$tind + ternary_indirect _Protivin$tind: + row: 1 + bus: 0 + column: 5 + input_xbar: + ternary group 8: { 0: HillTop.Wisdom.RioPecos, 8: eg_intr_md.egress_port(8), 16: eg_intr_md.egress_port(0..7), 24: HillTop.Lamona.Pachuta, 33: HillTop.Wisdom.Onycha } + format: { action: 0..0, immediate: 1..2 } + action_bus: { 44..45 : immediate(0..1) } + instruction: _Protivin$tind(action, $DEFAULT) + actions: + Chappell(0, 7): + - p4_param_order: { Toklat: 2 } + - default_action: { allowed: true } + - handle: 0x2000012f + - next_table: 0 + - { Toklat: immediate(0..1) } + - set HillTop.Wisdom.Stratford, 1 + - set HillTop.Wisdom.Westhoff, 2 + - set HillTop.Wisdom.Toklat, Toklat + - set Millston.Hayfield.Aguilita, 0 + Sequim(1, 0): + - default_action: { allowed: true } + - handle: 0x20000130 + - next_table: 1 + - { } + default_action: Sequim + ternary_match _Ghent 9: + p4: { name: Ghent, size: 16, disable_atomic_modify : true } + p4_param_order: + HillTop.Wisdom.Onycha: { type: ternary, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } + HillTop.Wisdom.Westhoff: { type: exact, size: 3, full_size: 3, key_name: "Wisdom.Westhoff" } + HillTop.Wisdom.RioPecos: { type: ternary, size: 1, full_size: 1, key_name: "Wisdom.RioPecos" } + HillTop.Wisdom.Bennet: { type: ternary, size: 1, full_size: 32, key_name: "Wisdom.Bennet", start_bit: 16 } + HillTop.Wisdom.Bennet: { type: ternary, size: 1, full_size: 32, key_name: "Wisdom.Bennet", start_bit: 18 } + row: 1 + bus: 0 + column: 0 + input_xbar: + ternary group 8: { 0: HillTop.Wisdom.RioPecos, 1: HillTop.Wisdom.Westhoff, 33: HillTop.Wisdom.Onycha } + byte group 1: { 0: HillTop.Wisdom.Bennet.16-23(0), 2: HillTop.Wisdom.Bennet.16-23(2) } + match: + - { group: 8, byte_group: 1, byte_config: 0, dirtcam: 0x501 } + hit: [ _Medart ] + miss: _Medart + indirect: _Ghent$tind + ternary_indirect _Ghent$tind: + row: 0 + bus: 0 + column: 5 + input_xbar: + ternary group 8: { 0: HillTop.Wisdom.RioPecos, 1: HillTop.Wisdom.Westhoff, 33: HillTop.Wisdom.Onycha } + byte group 1: { 0: HillTop.Wisdom.Bennet.16-23(0), 2: HillTop.Wisdom.Bennet.16-23(2) } + format: { action: 0..2, immediate: 3..18 } + action_bus: { 100..103 : immediate(0..15) } + instruction: _Ghent$tind(action, $DEFAULT) + actions: + Westend(0, 8): + - p4_param_order: { Mendocino: 16, Scotland: 16, Addicks: 16 } + - default_action: { allowed: true } + - handle: 0x20000131 + - next_table: 0 + - { Addicks: immediate(0..15) } + - and W26, Addicks, W26 + Wyandanch(1, 10): + - p4_param_order: { RockPort: 32, Mendocino: 16, Scotland: 16, Addicks: 16 } + - default_action: { allowed: true } + - handle: 0x20000132 + - next_table: 0 + - { Addicks: immediate(0..15) } + - and W26, Addicks, W26 + Vananda(2, 12): + - p4_param_order: { RockPort: 32, Mendocino: 16, Scotland: 16, Addicks: 16 } + - default_action: { allowed: true } + - handle: 0x20000133 + - next_table: 0 + - { Addicks: immediate(0..15) } + - and W26, Addicks, W26 + Yorklyn(3, 0): + - p4_param_order: { Mendocino: 16, Scotland: 16 } + - default_action: { allowed: true } + - handle: 0x20000134 + - next_table: 0 + - { } + Botna(4, 9): + - p4_param_order: { Scotland: 16 } + - default_action: { allowed: true } + - handle: 0x20000135 + - next_table: 0 + - { } + NoAction(-1, 11): + - default_only_action: { allowed: true } + - handle: 0x20000136 + - next_table: 0 + - { } + default_only_action: NoAction + ternary_match _Medart 10: + p4: { name: Medart, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.Wisdom.Miller: { type: exact, size: 9, full_size: 9, key_name: "Wisdom.Miller" } + row: 5 + bus: 0 + column: 0 + indirect_bus: 1 + input_xbar: + ternary group 1: { 0: HillTop.Wisdom.Miller.8-8, 24: HillTop.Wisdom.Miller.0-7 } + match: + - { group: 1, byte_config: 3, dirtcam: 0x41 } + hit: [ _McDougal ] + miss: _McDougal + action: _Medart$action_data($DIRECT, $DEFAULT) + instruction: _Medart($DEFAULT, $DEFAULT) + actions: + Estero(0, 13): + - p4_param_order: { Inkom: 6, Gowanda: 10, BurrOak: 4, Gardena: 12 } + - default_action: { allowed: true } + - handle: 0x20000137 + - next_table: 0 + - { $data0: $adf_h0(0..15), Gardena: $data0(0..11), BurrOak: $data0(12..15), $data1: $adf_h1(0..15), Gowanda: $data1(0..9), Inkom: $data1(10..15) } + - set H31, $data0 + - set H72, $data1 + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x20000138 + - next_table: 0 + - { } + default_only_action: NoAction + action _Medart$action_data: + p4: { name: Medart$action } + row: 9 + column: 3 + vpns: [ 0 ] + home_row: + - 9 + format Estero: { $adf_h0: 0..15, $adf_h1: 16..31 } + action_bus: { 48..49 : $adf_h0, 50..51 : $adf_h1 } + hash_action _McDougal 11: + p4: { name: McDougal, size: 1, disable_atomic_modify : true } + row: 2 + bus: 1 + hash_dist: + 0: { hash: 2, mask: 0xfff, shift: 3 } + input_xbar: + exact group 3: { 8: eg_intr_md.egress_port(8), 16: eg_intr_md.egress_port(0..7), 32: eg_intr_md.egress_qid } + hash 6: + 0..4: stripe(eg_intr_md.egress_qid) + 5..11: stripe(eg_intr_md.egress_port(0..6)) + hash group 2: + table: [6] + seed: 0x0 + gateway: + name: _McDougal-gateway + row: 0 + bus: 0 + unit: 1 + 0x0: _Waseca + miss: _Waseca + condition: + expression: "true(always hit)" + true: _Waseca + false: _Waseca + next: [] + stats: _McDougal$stats..Tillicum(hash_dist 0, $DEFAULT) + instruction: _McDougal($DEFAULT, $DEFAULT) + actions: + Magazine(0, 0): + - default_action: { allowed: true } + - handle: 0x2000011c + - next_table: 0 + - _McDougal$stats..Tillicum($hash_dist) + default_action: Magazine + counter _McDougal$stats..Tillicum: + p4: { name: Tillicum, size: 4096 } + row: [ 13, 11 ] + column: + - [ 3, 4, 5 ] + - [ 3, 4 ] + maprams: + - [ 3, 4, 5 ] + - [ 3, 4 ] + count: packets_and_bytes + format: {packets(0): 0..63, bytes(0): 64..127} +stage 5 egress: + ternary_match _Waseca 9: + p4: { name: Waseca, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.Wisdom.Onycha: { type: exact, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } + HillTop.Wisdom.Westhoff: { type: exact, size: 3, full_size: 3, key_name: "Wisdom.Westhoff" } + HillTop.Wisdom.Piqua: { type: exact, size: 1, full_size: 1, key_name: "Wisdom.Piqua" } + Millston.GlenAvon.$valid: { type: ternary, size: 1, full_size: 1, key_name: "GlenAvon" } + Millston.Maumee.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Maumee" } + Millston.Ramos.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Ramos" } + Millston.Provencal.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Provencal" } + HillTop.Wisdom.Bennet: { type: ternary, size: 2, full_size: 32, key_name: "Wisdom.Bennet", start_bit: 18 } + row: [ 0, 1 ] + bus: [ 0, 0 ] + column: + - 0 + - 0 + input_xbar: + ternary group 4: { 17: HillTop.Wisdom.Onycha } + ternary group 5: { 3: Millston.GlenAvon.$valid, 4: Millston.Ramos.$valid, 9: Millston.Maumee.$valid, 17: Millston.Provencal.$valid, 33: HillTop.Wisdom.Westhoff, 36: HillTop.Wisdom.Piqua } + byte group 1: { 2: HillTop.Wisdom.Bennet.16-23(2..3) } + match: + - { group: 4, byte_group: 1, byte_config: 0, dirtcam: 0x410 } + - { group: 5, dirtcam: 0x115 } + hit: [ _Haugen ] + miss: _Haugen + indirect: _Waseca$tind + ternary_indirect _Waseca$tind: + row: 0 + bus: 0 + column: 2 + input_xbar: + ternary group 4: { 17: HillTop.Wisdom.Onycha } + ternary group 5: { 3: Millston.GlenAvon.$valid, 4: Millston.Ramos.$valid, 9: Millston.Maumee.$valid, 17: Millston.Provencal.$valid, 33: HillTop.Wisdom.Westhoff, 36: HillTop.Wisdom.Piqua } + byte group 1: { 2: HillTop.Wisdom.Bennet.16-23(2..3) } + format: { action: 0..5 } + action: _Waseca$action_data($DIRECT, $DEFAULT) + instruction: _Waseca$tind(action, $DEFAULT) + actions: + Durant(1, 1): + - p4_param_order: { Onamia: 24, Brule: 24 } + - default_action: { allowed: true } + - handle: 0x2000013b + - next_table: 0 + - { Brule.16-23: $adf_b0(0..7), Onamia.16-23: $adf_b1(0..7), Brule.0-15: $adf_h1(0..15), Onamia.0-15: $adf_h2(0..15) } + - set Millston.Calabash.Adona.0-7, HillTop.Wisdom.Adona.0-7 + - set Millston.Calabash.Adona.8-23, HillTop.Wisdom.Adona.8-23 + - set Millston.Calabash.Connell.0-7, HillTop.Wisdom.Connell.0-7 + - set Millston.Calabash.Connell.8-23, HillTop.Wisdom.Connell.8-23 + - set Millston.Calabash.Goldsboro.0-15, Onamia.0-15 + - set Millston.Calabash.Goldsboro.16-23, Onamia.16-23 + - set Millston.Calabash.Fabens.0-15, Brule.0-15 + - set Millston.Calabash.Fabens.16-23, Brule.16-23 + - add Millston.GlenAvon.Exton, Millston.GlenAvon.Exton, 255 + - set HillTop.Plains.Roachdale, 0 + - set HillTop.Plains.Miller, 0 + Kingsdale(2, 2): + - p4_param_order: { Onamia: 24, Brule: 24 } + - default_action: { allowed: true } + - handle: 0x2000013c + - next_table: 0 + - { Brule.16-23: $adf_b0(0..7), Onamia.16-23: $adf_b1(0..7), Brule.0-15: $adf_h1(0..15), Onamia.0-15: $adf_h2(0..15) } + - set Millston.Calabash.Adona.0-7, HillTop.Wisdom.Adona.0-7 + - set Millston.Calabash.Adona.8-23, HillTop.Wisdom.Adona.8-23 + - set Millston.Calabash.Connell.0-7, HillTop.Wisdom.Connell.0-7 + - set Millston.Calabash.Connell.8-23, HillTop.Wisdom.Connell.8-23 + - set Millston.Calabash.Goldsboro.0-15, Onamia.0-15 + - set Millston.Calabash.Goldsboro.16-23, Onamia.16-23 + - set Millston.Calabash.Fabens.0-15, Brule.0-15 + - set Millston.Calabash.Fabens.16-23, Brule.16-23 + - add Millston.Maumee.Bushland, Millston.Maumee.Bushland, 255 + - set HillTop.Plains.Roachdale, 0 + - set HillTop.Plains.Miller, 0 + Tekonsha(4, 4): + - default_action: { allowed: true } + - handle: 0x2000013d + - next_table: 0 + - { } + - set Millston.Calabash.Adona.0-7, HillTop.Wisdom.Adona.0-7 + - set Millston.Calabash.Adona.8-23, HillTop.Wisdom.Adona.8-23 + - set Millston.Calabash.Connell.0-7, HillTop.Wisdom.Connell.0-7 + - set Millston.Calabash.Connell.8-23, HillTop.Wisdom.Connell.8-23 + - set HillTop.Plains.Roachdale, 0 + - set HillTop.Plains.Miller, 0 + Clermont(6, 6): + - default_action: { allowed: true } + - handle: 0x2000013e + - next_table: 0 + - { } + - set Millston.Calabash.Adona.0-7, HillTop.Wisdom.Adona.0-7 + - set Millston.Calabash.Adona.8-23, HillTop.Wisdom.Adona.8-23 + - set Millston.Calabash.Connell.0-7, HillTop.Wisdom.Connell.0-7 + - set Millston.Calabash.Connell.8-23, HillTop.Wisdom.Connell.8-23 + - set HillTop.Plains.Roachdale, 0 + - set HillTop.Plains.Miller, 0 + Blanding(8, 8): + - default_action: { allowed: true } + - handle: 0x2000013f + - next_table: 0 + - { } + - set Millston.Wondervu$0.$valid, 1 + - set Millston.Wondervu$0.McCaulley, Millston.Calabash.McCaulley + - set Millston.Calabash.McCaulley, 33024 + - set HillTop.Plains.Roachdale, 0 + - set HillTop.Plains.Miller, 0 + - deposit-field H22(12..15), H20(4..7), H23 + Shelby(10, 10): + - default_action: { allowed: true } + - handle: 0x20000140 + - next_table: 0 + - { } + - set Millston.Hayfield.$valid, 1 + - set Millston.Hayfield.Lathrop, HillTop.Wisdom.Lathrop + - set Millston.Hayfield.Blencoe, HillTop.Wisdom.Blencoe + - set Millston.Hayfield.Harbor, HillTop.RossFork.Bicknell + - set HillTop.Plains.Roachdale, 0 + - set HillTop.Plains.Miller, 0 + - deposit-field H30(12..15), H23(12..15), H29 + Chambers(12, 12): + - default_action: { allowed: true } + - handle: 0x20000141 + - next_table: 0 + - { } + - set HillTop.Plains.Roachdale, 0 + - set HillTop.Plains.Miller, 0 + Ardenvoir(14, 14): + - p4_param_order: { Onamia: 24, Brule: 24 } + - default_action: { allowed: true } + - handle: 0x20000142 + - next_table: 0 + - { Brule.16-23: $adf_b0(0..7), Onamia.16-23: $adf_b1(0..7), Brule.0-15: $adf_h1(0..15), Onamia.0-15: $adf_h2(0..15) } + - set Millston.Calabash.$valid, 1 + - set Millston.Calabash.Adona.0-7, HillTop.Wisdom.Adona.0-7 + - set Millston.Calabash.Adona.8-23, HillTop.Wisdom.Adona.8-23 + - set Millston.Calabash.Connell.0-7, HillTop.Wisdom.Connell.0-7 + - set Millston.Calabash.Connell.8-23, HillTop.Wisdom.Connell.8-23 + - set Millston.Calabash.Goldsboro.0-15, Onamia.0-15 + - set Millston.Calabash.Goldsboro.16-23, Onamia.16-23 + - set Millston.Calabash.Fabens.0-15, Brule.0-15 + - set Millston.Calabash.Fabens.16-23, Brule.16-23 + - set Millston.Calabash.McCaulley, 2048 + - set HillTop.Plains.Roachdale, 0 + - set HillTop.Plains.Miller, 0 + Clinchco(16, 16): + - default_action: { allowed: true } + - handle: 0x20000143 + - next_table: 0 + - { } + - set Millston.Calabash.Adona.0-7, HillTop.Wisdom.Adona.0-7 + - set Millston.Calabash.Adona.8-23, HillTop.Wisdom.Adona.8-23 + - set Millston.Calabash.Connell.0-7, HillTop.Wisdom.Connell.0-7 + - set Millston.Calabash.Connell.8-23, HillTop.Wisdom.Connell.8-23 + - set HillTop.Plains.Roachdale, 0 + - set HillTop.Plains.Miller, 0 + Snook(18, 18): + - default_action: { allowed: true } + - handle: 0x20000144 + - next_table: 0 + - { } + - set Millston.Calabash.McCaulley, 2048 + - set Millston.Hayfield.$valid, 1 + - set Millston.Hayfield.Lathrop, HillTop.Wisdom.Lathrop + - set Millston.Hayfield.Blencoe, HillTop.Wisdom.Blencoe + - set Millston.Hayfield.Harbor, HillTop.RossFork.Bicknell + - set HillTop.Plains.Roachdale, 0 + - set HillTop.Plains.Miller, 0 + - deposit-field H30(12..15), H23(12..15), H29 + OjoFeliz(20, 20): + - default_action: { allowed: true } + - handle: 0x20000145 + - next_table: 0 + - { } + - set Millston.Calabash.McCaulley, 34525 + - set Millston.Hayfield.$valid, 1 + - set Millston.Hayfield.Lathrop, HillTop.Wisdom.Lathrop + - set Millston.Hayfield.Blencoe, HillTop.Wisdom.Blencoe + - set Millston.Hayfield.Harbor, HillTop.RossFork.Bicknell + - set HillTop.Plains.Roachdale, 0 + - set HillTop.Plains.Miller, 0 + - deposit-field H30(12..15), H23(12..15), H29 + Havertown(22, 22): + - p4_param_order: { Onamia: 24, Brule: 24 } + - default_action: { allowed: true } + - handle: 0x20000146 + - next_table: 0 + - { Brule.16-23: $adf_b0(0..7), Onamia.16-23: $adf_b1(0..7), Brule.0-15: $adf_h1(0..15), Onamia.0-15: $adf_h2(0..15) } + - set Millston.Calabash.Adona.0-7, HillTop.Wisdom.Adona.0-7 + - set Millston.Calabash.Adona.8-23, HillTop.Wisdom.Adona.8-23 + - set Millston.Calabash.Connell.0-7, HillTop.Wisdom.Connell.0-7 + - set Millston.Calabash.Connell.8-23, HillTop.Wisdom.Connell.8-23 + - set Millston.Calabash.Goldsboro.0-15, Onamia.0-15 + - set Millston.Calabash.Goldsboro.16-23, Onamia.16-23 + - set Millston.Calabash.Fabens.0-15, Brule.0-15 + - set Millston.Calabash.Fabens.16-23, Brule.16-23 + - set Millston.Calabash.McCaulley, 2048 + - add Millston.GlenAvon.Exton, Millston.GlenAvon.Exton, 255 + - set HillTop.Plains.Roachdale, 0 + - set HillTop.Plains.Miller, 0 + Napanoch(24, 24): + - p4_param_order: { Onamia: 24, Brule: 24 } + - default_action: { allowed: true } + - handle: 0x20000147 + - next_table: 0 + - { Brule.16-23: $adf_b0(0..7), Onamia.16-23: $adf_b1(0..7), Brule.0-15: $adf_h1(0..15), Onamia.0-15: $adf_h2(0..15) } + - set Millston.Calabash.Adona.0-7, HillTop.Wisdom.Adona.0-7 + - set Millston.Calabash.Adona.8-23, HillTop.Wisdom.Adona.8-23 + - set Millston.Calabash.Connell.0-7, HillTop.Wisdom.Connell.0-7 + - set Millston.Calabash.Connell.8-23, HillTop.Wisdom.Connell.8-23 + - set Millston.Calabash.Goldsboro.0-15, Onamia.0-15 + - set Millston.Calabash.Goldsboro.16-23, Onamia.16-23 + - set Millston.Calabash.Fabens.0-15, Brule.0-15 + - set Millston.Calabash.Fabens.16-23, Brule.16-23 + - set Millston.Calabash.McCaulley, 34525 + - add Millston.Maumee.Bushland, Millston.Maumee.Bushland, 255 + - set HillTop.Plains.Roachdale, 0 + - set HillTop.Plains.Miller, 0 + NoAction(-1, 26): + - default_only_action: { allowed: true } + - handle: 0x20000148 + - next_table: 0 + - { } + - set HillTop.Plains.Roachdale, 0 + - set HillTop.Plains.Miller, 0 + default_only_action: NoAction + action _Waseca$action_data: + p4: { name: Waseca$action } + row: 10 + column: 3 + vpns: [ 0 ] + home_row: + - 10 + format Durant: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_h1: 16..31, $adf_h2: 32..47 } + format Kingsdale: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_h1: 16..31, $adf_h2: 32..47 } + format Ardenvoir: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_h1: 16..31, $adf_h2: 32..47 } + format Havertown: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_h1: 16..31, $adf_h2: 32..47 } + format Napanoch: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_h1: 16..31, $adf_h2: 32..47 } + action_bus: { 0 : $adf_b0, 1 : $adf_b1, 74..75 : $adf_h1, 76..77 : $adf_h2 } + exact_match _Haugen 10: + p4: { name: Haugen, size: 512, disable_atomic_modify : true } + p4_param_order: + HillTop.Wisdom.Dolores: { type: exact, size: 2, full_size: 2, key_name: "Wisdom.Dolores" } + eg_intr_md.egress_port: { type: exact, size: 7, full_size: 9, key_name: "Sonoma.egress_port" } + row: 2 + bus: 1 + column: 11 + stash: + row: [ 2 ] + col: [ 11 ] + unit: [ 0 ] + ways: + - [4, 0, 0x0, [2, 11]] + input_xbar: + exact group 3: { 0: HillTop.Wisdom.Dolores, 16: eg_intr_md.egress_port(0..6) } + hash 6: + 0..1: HillTop.Wisdom.Dolores + 2..8: eg_intr_md.egress_port(0..6) + hash group 4: + table: [6] + seed: 0x0 + format: { action(0): 0..0, version(0): 112..115 } + gateway: + name: cond-46 + input_xbar: + exact group 4: { 1: HillTop.Wisdom.Westhoff, 4: HillTop.Wisdom.Piqua, 33: HillTop.Wisdom.Onycha } + row: 4 + bus: 1 + unit: 0 + match: { 20: HillTop.Wisdom.Piqua, 1: HillTop.Wisdom.Onycha, 9: HillTop.Wisdom.Westhoff } + 0b***0********000*****000: run_table + miss: _Papeton + condition: + expression: "(HillTop.Wisdom.Piqua == 0 && HillTop.Wisdom.Onycha == 0 && HillTop.Wisdom.Westhoff == 0)" + true: _Haugen + false: _Papeton + hit: [ _Papeton ] + miss: _Papeton + instruction: _Haugen(action, $DEFAULT) + actions: + Pearcy(1, 3): + - default_action: { allowed: true } + - handle: 0x20000139 + - next_table: 0 + - set eg_intr_md_for_dprsr.drop_ctl, 7 + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x2000013a + - next_table: 0 + default_only_action: NoAction + ternary_match _Papeton 11: + p4: { name: Papeton, size: 14, disable_atomic_modify : true } + p4_param_order: + HillTop.Wisdom.Westhoff: { type: ternary, size: 3, full_size: 3, key_name: "Wisdom.Westhoff" } + HillTop.Wisdom.Onycha: { type: ternary, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } + HillTop.Wisdom.Piqua: { type: ternary, size: 1, full_size: 1, key_name: "Wisdom.Piqua" } + Millston.GlenAvon.$valid: { type: ternary, size: 1, full_size: 1, key_name: "GlenAvon" } + Millston.Maumee.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Maumee" } + Millston.Ramos.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Ramos" } + Millston.Provencal.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Provencal" } + row: 9 + bus: 1 + column: 1 + input_xbar: + ternary group 8: { 3: Millston.GlenAvon.$valid, 4: Millston.Ramos.$valid, 9: Millston.Maumee.$valid, 17: Millston.Provencal.$valid, 33: HillTop.Wisdom.Westhoff, 36: HillTop.Wisdom.Piqua } + byte group 5: { 1: HillTop.Wisdom.Onycha } + match: + - { group: 8, byte_group: 5, byte_config: 0, dirtcam: 0x515 } + gateway: + name: cond-47 + input_xbar: + exact group 5: { 0: Millston.Belgrade.$valid, 8: HillTop.Wisdom.Stratford } + row: 7 + bus: 1 + unit: 0 + match: { 0: Millston.Belgrade.$valid, 8: HillTop.Wisdom.Stratford } + 0b*******0*******1: run_table + miss: _Astatula + condition: + expression: "(Millston.Belgrade.$valid == 1 == 1 && HillTop.Wisdom.Stratford == 0)" + true: _Papeton + false: _Astatula + hit: [ _Cropper ] + miss: _Cropper + indirect: _Papeton$tind + ternary_indirect _Papeton$tind: + row: 5 + bus: 0 + column: 2 + input_xbar: + ternary group 8: { 3: Millston.GlenAvon.$valid, 4: Millston.Ramos.$valid, 9: Millston.Maumee.$valid, 17: Millston.Provencal.$valid, 33: HillTop.Wisdom.Westhoff, 36: HillTop.Wisdom.Piqua } + byte group 5: { 1: HillTop.Wisdom.Onycha } + format: { action: 0..2 } + instruction: _Papeton$tind(action, $DEFAULT) + actions: + Ravenwood(1, 5): + - default_action: { allowed: true } + - handle: 0x20000151 + - next_table: 0 + - set Millston.GlenAvon.PineCity, HillTop.Edwards.PineCity + - set HillTop.Edwards.SomesBar, 0 + Poneto(2, 7): + - default_action: { allowed: true } + - handle: 0x20000152 + - next_table: 0 + - set Millston.Maumee.PineCity, HillTop.Edwards.PineCity + - set HillTop.Edwards.SomesBar, 0 + Lurton(3, 9): + - default_action: { allowed: true } + - handle: 0x20000153 + - next_table: 0 + - set Millston.Ramos.PineCity, HillTop.Edwards.PineCity + - set HillTop.Edwards.SomesBar, 0 + Quijotoa(4, 11): + - default_action: { allowed: true } + - handle: 0x20000154 + - next_table: 0 + - set Millston.Provencal.PineCity, HillTop.Edwards.PineCity + - set HillTop.Edwards.SomesBar, 0 + Frontenac(5, 13): + - default_action: { allowed: true } + - handle: 0x20000155 + - next_table: 0 + - set Millston.GlenAvon.PineCity, HillTop.Edwards.Renick + - set HillTop.Edwards.SomesBar, 0 + Gilman(6, 15): + - default_action: { allowed: true } + - handle: 0x20000156 + - next_table: 0 + - set Millston.GlenAvon.PineCity, HillTop.Edwards.Renick + - set Millston.Ramos.PineCity, HillTop.Edwards.PineCity + - set HillTop.Edwards.SomesBar, 0 + Kalaloch(7, 17): + - default_action: { allowed: true } + - handle: 0x20000157 + - next_table: 0 + - set Millston.GlenAvon.PineCity, HillTop.Edwards.Renick + - set Millston.Provencal.PineCity, HillTop.Edwards.PineCity + - set HillTop.Edwards.SomesBar, 0 + NoAction(-1, 19): + - default_only_action: { allowed: true } + - handle: 0x20000158 + - next_table: 0 + - set HillTop.Edwards.SomesBar, 0 + default_only_action: NoAction +stage 6 egress: + ternary_match _Cropper 6: + p4: { name: Cropper, size: 128, action_profile: Tulsa, disable_atomic_modify : true } + p4_param_order: + HillTop.McCaskill.Grassflat: { type: exact, size: 7, full_size: 10, key_name: "McCaskill.Grassflat" } + row: 7 + bus: 1 + column: 1 + input_xbar: + ternary group 0: { 32: HillTop.McCaskill.Grassflat(0..6) } + match: + - { group: 0, byte_config: 3, dirtcam: 0x100 } + hit: [ _Ranier ] + miss: _Ranier + indirect: _Cropper$tind + selection _Cropper$selector.Tulsa_sel: + p4: { name: Tulsa_sel, size: 4 } + row: 3 + column: [ 1, 2 ] + maprams: [ 1, 2 ] + input_xbar: + exact group 5: { 0: HillTop.Lewiston.Staunton } + hash 10: + 0..50: slice(stripe(crc_rev(0x18005, 0x0, 0x0, 16, { 0: HillTop.Lewiston.Staunton })), 0..50) + hash group 5: + table: [10] + seed: 0x0 + mode: resilient 0 + non_linear: true + pool_sizes: [120] + action _Cropper$action_data.Tulsa: + p4: { name: Tulsa, size: 1024 } + row: 0 + column: 4 + vpns: [ 0 ] + home_row: + - 0 + format Centre: { $adf_h0: 0..15 } + action_bus: { 52..53 : $adf_h0 } + stateful _Cropper$salu.Tulsa_sel$salu: + p4: { name: Tulsa_sel$salu, size: 122880, hidden: true } + selection_table: _Cropper$selector.Tulsa_sel + row: 3 + column: [ 1, 2 ] + maprams: [ 1, 2 ] + format: { lo: 1 } + actions: + set_bit_at_alu$0: + - set_bit_at + clr_bit_at_alu$0: + - clr_bit_at + set_bit_alu$0: + - set_bit + clr_bit_alu$0: + - clr_bit + ternary_indirect _Cropper$tind: + row: 0 + bus: 0 + column: 2 + input_xbar: + ternary group 0: { 32: HillTop.McCaskill.Grassflat(0..6) } + format: { meter_addr: 0..9, meter_pfe: 10..10, action_addr: 11..21 } + selector: _Cropper$selector.Tulsa_sel(meter_addr, meter_pfe, $DEFAULT) + selector_length: _Cropper$selector.Tulsa_sel($DEFAULT, $DEFAULT) + action: _Cropper$action_data.Tulsa(action_addr, $DEFAULT) + instruction: _Cropper$tind($DEFAULT, $DEFAULT) + actions: + Centre(0, 1): + - p4_param_order: { Hector: 10 } + - default_action: { allowed: true } + - handle: 0x2000014f + - next_table: 0 + - { Hector: $adf_h0(0..9) } + - or H19, Hector, H19 + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x20000150 + - next_table: 0 + - { } + default_only_action: NoAction + hash_action _Ranier 7: + p4: { name: Ranier, size: 1, disable_atomic_modify : true } + row: 1 + bus: 1 + hash_dist: + 3: { hash: 6, mask: 0x7ffff, shift: 0, expand: 0 } + input_xbar: + exact group 5: { 64: eg_intr_md.egress_port, 80: HillTop.Wisdom.Bowden } + hash 11: + 0..11: stripe(HillTop.Wisdom.Bowden) + 12..15: stripe(eg_intr_md.egress_port(0..3)) + 32..34: stripe(eg_intr_md.egress_port(4..6)) + hash group 6: + table: [11] + seed: 0x0 + gateway: + name: cond-50 + input_xbar: + exact group 6: { 1: HillTop.Wisdom.Onycha, 13: HillTop.Wisdom.Weatherby } + row: 0 + bus: 0 + unit: 0 + payload: 0x300001 + format: { action: 0..0, meter_addr: 1..19, meter_pfe: 20..20, meter_type: 21..23 } + match: { 1: HillTop.Wisdom.Onycha, 13: HillTop.Wisdom.Weatherby } + 0o****2: run_table + 0b**1************: run_table + miss: _Osakis + condition: + expression: "(HillTop.Wisdom.Onycha != 2 && HillTop.Wisdom.Weatherby == 0)" + true: _Osakis + false: _Charters + next: _Charters + action_bus: { 56..57 : _Ranier$salu..Nordland(0..15) } + stateful: _Ranier$salu..Nordland(hash_dist 3, $DEFAULT, $DEFAULT) + instruction: _Ranier(action, $DEFAULT) + actions: + Alnwick(1, 2): + - default_action: { allowed: true } + - handle: 0x2000014e + - next_table: 0 + - set HillTop.Stennett.Blairsden, _Ranier$salu..Nordland + - _Ranier$salu..Nordland(_Upalco, $hash_dist) + default_action: Alnwick + stateful _Ranier$salu..Nordland: + p4: { name: Nordland, size: 294912 } + row: 7 + column: [ 2, 3, 4, 5 ] + maprams: [ 2, 3, 4, 5 ] + format: { lo: 1 } + actions: + _Upalco: + - read_bit + - output alu_lo + set_bit_alu$0: + - set_bit + clr_bit_alu$0: + - clr_bit + hash_action _Osakis 8: + p4: { name: Osakis, size: 1, disable_atomic_modify : true } + row: 0 + bus: 0 + hash_dist: + 4: { hash: 6, mask: 0x7ffff, shift: 0, expand: 7 } + input_xbar: + exact group 5: { 64: eg_intr_md.egress_port, 80: HillTop.Wisdom.Bowden } + hash 11: + 16..27: stripe(HillTop.Wisdom.Bowden) + 28..31: stripe(eg_intr_md.egress_port(0..3)) + 39..41: stripe(eg_intr_md.egress_port(4..6)) + hash group 6: + table: [11] + seed: 0x0 + gateway: + name: _Osakis-gateway + row: 2 + bus: 0 + unit: 1 + 0x0: _Charters + miss: _Charters + condition: + expression: "true(always hit)" + true: _Charters + false: _Charters + next: [] + action_bus: { 2 : _Osakis$salu..Ontonagon(0..7) } + stateful: _Osakis$salu..Ontonagon(hash_dist 4, $DEFAULT, $DEFAULT) + instruction: _Osakis($DEFAULT, $DEFAULT) + actions: + Olivet(0, 3): + - default_action: { allowed: true } + - handle: 0x2000014d + - next_table: 0 + - set HillTop.Stennett.Standish, _Osakis$salu..Ontonagon + - _Osakis$salu..Ontonagon(_Ickesburg, $hash_dist) + default_action: Olivet + stateful _Osakis$salu..Ontonagon: + p4: { name: Ontonagon, size: 294912 } + row: 11 + column: [ 2, 3, 4, 5 ] + maprams: [ 2, 3, 4, 5 ] + format: { lo: 1 } + actions: + _Ickesburg: + - read_bitc + - output alu_lo + set_bit_alu$0: + - set_bit + clr_bit_alu$0: + - clr_bit + ternary_match _Charters 9: + p4: { name: Charters, size: 2048, disable_atomic_modify : true } + p4_param_order: + HillTop.McGonigle.Buncombe: { type: ternary, size: 8, full_size: 8, key_name: "McGonigle.Buncombe" } + Millston.GlenAvon.Kaluaaha: { type: ternary, size: 32, full_size: 32, key_name: "GlenAvon.Kaluaaha" } + Millston.GlenAvon.Calcasieu: { type: ternary, size: 32, full_size: 32, key_name: "GlenAvon.Calcasieu" } + Millston.GlenAvon.Ocoee: { type: ternary, size: 8, full_size: 8, key_name: "GlenAvon.Ocoee" } + Millston.Grays.Chevak: { type: ternary, size: 16, full_size: 16, key_name: "Grays.Chevak" } + Millston.Grays.Mendocino: { type: ternary, size: 16, full_size: 16, key_name: "Grays.Mendocino" } + Millston.Osyka.Noyes: { type: ternary, size: 8, full_size: 8, key_name: "Osyka.Noyes" } + HillTop.Bessie.Peebles: { type: ternary, size: 1, full_size: 1, key_name: "Bessie.Peebles" } + row: [ 6, 7, 8, 11, 10, 9, 0, 1, 2, 5, 4, 3 ] + bus: [ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 1 + - 1 + - 1 + - 1 + - 1 + - 1 + input_xbar: + ternary group 7: { 0: Millston.GlenAvon.Kaluaaha(24..31), 8: Millston.GlenAvon.Calcasieu(0..7), 16: Millston.GlenAvon.Kaluaaha(8..23), 32: Millston.GlenAvon.Calcasieu(24..31) } + ternary group 8: { 5: HillTop.Bessie.Peebles, 8: Millston.GlenAvon.Calcasieu(8..23), 24: Millston.Grays.Mendocino(8..15), 32: Millston.Grays.Mendocino(0..7) } + ternary group 9: { 0: Millston.Grays.Chevak, 16: HillTop.McGonigle.Buncombe, 24: Millston.GlenAvon.Ocoee, 32: Millston.Osyka.Noyes } + byte group 1: { 0: Millston.GlenAvon.Kaluaaha(0..7) } + match: + - { group: 7, byte_group: 1, byte_config: 0, dirtcam: 0x555 } + - { group: 8, byte_group: 1, byte_config: 1, dirtcam: 0x555 } + - { group: 9, byte_config: 3, dirtcam: 0x155 } + gateway: + name: cond-49 + input_xbar: + exact group 7: { 3: Millston.GlenAvon.$valid } + row: 3 + bus: 1 + unit: 0 + match: { 3: Millston.GlenAvon.$valid } + 0b****1: run_table + miss: _Keltys$st0 + condition: + expression: "(Millston.GlenAvon.$valid == 1)" + true: _Charters + false: _Keltys$st0 + hit: [ _Keltys$st0 ] + miss: _Keltys$st0 + indirect: _Charters$tind + counter _Charters$stats..Keller: + p4: { name: Keller } + row: 9 + column: [ 2, 3 ] + maprams: [ 2, 3 ] + count: packets + format: {packets(0): 64..127, packets(1): 0..63} + ternary_indirect _Charters$tind: + row: 2 + bus: 0 + column: 5 + input_xbar: + ternary group 7: { 0: Millston.GlenAvon.Kaluaaha(24..31), 8: Millston.GlenAvon.Calcasieu(0..7), 16: Millston.GlenAvon.Kaluaaha(8..23), 32: Millston.GlenAvon.Calcasieu(24..31) } + ternary group 8: { 5: HillTop.Bessie.Peebles, 8: Millston.GlenAvon.Calcasieu(8..23), 24: Millston.Grays.Mendocino(8..15), 32: Millston.Grays.Mendocino(0..7) } + ternary group 9: { 0: Millston.Grays.Chevak, 16: HillTop.McGonigle.Buncombe, 24: Millston.GlenAvon.Ocoee, 32: Millston.Osyka.Noyes } + byte group 1: { 0: Millston.GlenAvon.Kaluaaha(0..7) } + format: { action: 0..0 } + stats: _Charters$stats..Keller($DIRECT, $DEFAULT) + action: _Charters$action_data($DIRECT, $DEFAULT) + instruction: _Charters$tind(action, $DEFAULT) + actions: + Elysburg(1, 4): + - p4_param_order: { Cornell: 2 } + - default_action: { allowed: true } + - handle: 0x2000014b + - next_table: 0 + - { Cornell: $adf_b0(0..1) } + - set HillTop.Wisdom.DeGraff, Cornell + - _Charters$stats..Keller($DIRECT) + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x2000014c + - next_table: 0 + - { } + default_only_action: NoAction + action _Charters$action_data: + p4: { name: Charters$action } + row: 9 + column: 4 + vpns: [ 0 ] + home_row: + - 9 + format Elysburg: { $adf_b0: 0..7 } + action_bus: { 4 : $adf_b0 } +stage 9 egress: + ternary_match _Keltys$st0 9: + p4: { name: Keltys, size: 1024 } + p4_param_order: + HillTop.McGonigle.Buncombe: { type: ternary, size: 8, full_size: 8, key_name: "McGonigle.Buncombe" } + Millston.Maumee.Kaluaaha: { type: ternary, size: 128, full_size: 128, key_name: "Maumee.Kaluaaha" } + Millston.Maumee.Calcasieu: { type: ternary, size: 128, full_size: 128, key_name: "Maumee.Calcasieu" } + Millston.Maumee.Dassel: { type: ternary, size: 8, full_size: 8, key_name: "Maumee.Dassel" } + Millston.Grays.Chevak: { type: ternary, size: 16, full_size: 16, key_name: "Grays.Chevak" } + Millston.Grays.Mendocino: { type: ternary, size: 16, full_size: 16, key_name: "Grays.Mendocino" } + Millston.Osyka.Noyes: { type: ternary, size: 8, full_size: 8, key_name: "Osyka.Noyes" } + row: [ 0, 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + input_xbar: + ternary group 2: { 16: Millston.Osyka.Noyes } + ternary group 4: { 0: Millston.Maumee.Kaluaaha.0-31(16..23), 8: Millston.Maumee.Kaluaaha.32-63(24..31), 16: Millston.Maumee.Kaluaaha.32-63(0..23) } + ternary group 5: { 0: Millston.Maumee.Kaluaaha.64-95, 32: Millston.Maumee.Calcasieu.0-31(0..7) } + ternary group 7: { 0: Millston.Maumee.Calcasieu.0-31(24..31), 8: Millston.Maumee.Calcasieu.32-63(0..7), 16: Millston.Maumee.Calcasieu.0-31(8..23), 32: Millston.Maumee.Calcasieu.32-63(24..31) } + ternary group 8: { 0: Millston.Maumee.Kaluaaha.96-111, 16: Millston.Grays.Mendocino, 32: Millston.Grays.Chevak(0..7) } + ternary group 9: { 0: Millston.Maumee.Calcasieu.32-63(16..23), 8: Millston.Maumee.Calcasieu.64-95(24..31), 16: Millston.Maumee.Calcasieu.64-95(0..7), 24: Millston.Maumee.Calcasieu.32-63(8..15), 32: Millston.Maumee.Calcasieu.64-95(16..23) } + ternary group 10: { 0: Millston.Grays.Chevak(8..15), 8: Millston.Maumee.Kaluaaha.112-127, 24: HillTop.McGonigle.Buncombe, 32: Millston.Maumee.Dassel } + ternary group 11: { 0: Millston.Maumee.Calcasieu.64-95(8..15), 8: Millston.Maumee.Calcasieu.96-127(16..31), 24: Millston.Maumee.Calcasieu.96-127(0..15) } + byte group 1: { 0: Millston.Maumee.Kaluaaha.0-31(0..7) } + byte group 2: { 0: Millston.Maumee.Kaluaaha.0-31(24..31) } + byte group 4: { 0: Millston.Maumee.Kaluaaha.0-31(8..15) } + match: + - { group: 2, byte_group: 1, byte_config: 0, dirtcam: 0x410 } + - { group: 4, byte_group: 1, byte_config: 1, dirtcam: 0x555 } + - { group: 5, byte_group: 2, byte_config: 0, dirtcam: 0x555 } + - { group: 7, byte_group: 2, byte_config: 1, dirtcam: 0x555 } + - { group: 8, byte_group: 4, byte_config: 0, dirtcam: 0x555 } + - { group: 9, byte_group: 4, byte_config: 1, dirtcam: 0x555 } + - { group: 10, byte_config: 3, dirtcam: 0x155 } + - { group: 11, dirtcam: 0x155 } + gateway: + name: cond-48 + input_xbar: + exact group 3: { 105: Millston.Maumee.$valid } + row: 2 + bus: 1 + unit: 0 + match: { 1: Millston.Maumee.$valid } + 0b******1: run_table + miss: _Newsoms + condition: + expression: "(Millston.Maumee.$valid == 1)" + true: _Keltys$st0 + false: _Newsoms + hit: [ _Newsoms ] + miss: _Keltys$st1 + indirect: _Keltys$st0$tind + counter _Keltys$st0$stats..Kinter: + p4: { name: Kinter } + row: 13 + column: [ 0, 1 ] + maprams: [ 0, 1 ] + count: packets + format: {packets(0): 64..127, packets(1): 0..63} + ternary_indirect _Keltys$st0$tind: + row: 0 + bus: 0 + column: 5 + input_xbar: + ternary group 2: { 16: Millston.Osyka.Noyes } + ternary group 4: { 0: Millston.Maumee.Kaluaaha.0-31(16..23), 8: Millston.Maumee.Kaluaaha.32-63(24..31), 16: Millston.Maumee.Kaluaaha.32-63(0..23) } + ternary group 5: { 0: Millston.Maumee.Kaluaaha.64-95, 32: Millston.Maumee.Calcasieu.0-31(0..7) } + ternary group 7: { 0: Millston.Maumee.Calcasieu.0-31(24..31), 8: Millston.Maumee.Calcasieu.32-63(0..7), 16: Millston.Maumee.Calcasieu.0-31(8..23), 32: Millston.Maumee.Calcasieu.32-63(24..31) } + ternary group 8: { 0: Millston.Maumee.Kaluaaha.96-111, 16: Millston.Grays.Mendocino, 32: Millston.Grays.Chevak(0..7) } + ternary group 9: { 0: Millston.Maumee.Calcasieu.32-63(16..23), 8: Millston.Maumee.Calcasieu.64-95(24..31), 16: Millston.Maumee.Calcasieu.64-95(0..7), 24: Millston.Maumee.Calcasieu.32-63(8..15), 32: Millston.Maumee.Calcasieu.64-95(16..23) } + ternary group 10: { 0: Millston.Grays.Chevak(8..15), 8: Millston.Maumee.Kaluaaha.112-127, 24: HillTop.McGonigle.Buncombe, 32: Millston.Maumee.Dassel } + ternary group 11: { 0: Millston.Maumee.Calcasieu.64-95(8..15), 8: Millston.Maumee.Calcasieu.96-127(16..31), 24: Millston.Maumee.Calcasieu.96-127(0..15) } + byte group 1: { 0: Millston.Maumee.Kaluaaha.0-31(0..7) } + byte group 2: { 0: Millston.Maumee.Kaluaaha.0-31(24..31) } + byte group 4: { 0: Millston.Maumee.Kaluaaha.0-31(8..15) } + format: { action: 0..0 } + stats: _Keltys$st0$stats..Kinter($DIRECT, $DEFAULT) + action: _Keltys$st0$action_data($DIRECT, $DEFAULT) + instruction: _Keltys$st0$tind(action, $DEFAULT) + actions: + Elysburg(1, 1): + - p4_param_order: { Cornell: 2 } + - default_action: { allowed: true } + - handle: 0x20000149 + - next_table: 0 + - { Cornell: $adf_b0(0..1) } + - set HillTop.Wisdom.DeGraff, Cornell + - _Keltys$st0$stats..Kinter($DIRECT) + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x2000014a + - next_table: 0 + - { } + default_only_action: NoAction + action _Keltys$st0$action_data: + p4: { name: Keltys$action } + row: 5 + column: 1 + vpns: [ 0 ] + home_row: + - 5 + format Elysburg: { $adf_b0: 0..7 } + action_bus: { 2 : $adf_b0 } +stage 10 egress: + ternary_match _Keltys$st1 0: + p4: { name: Keltys, size: 1024 } + p4_param_order: + HillTop.McGonigle.Buncombe: { type: ternary, size: 8, full_size: 8, key_name: "McGonigle.Buncombe" } + Millston.Maumee.Kaluaaha: { type: ternary, size: 128, full_size: 128, key_name: "Maumee.Kaluaaha" } + Millston.Maumee.Calcasieu: { type: ternary, size: 128, full_size: 128, key_name: "Maumee.Calcasieu" } + Millston.Maumee.Dassel: { type: ternary, size: 8, full_size: 8, key_name: "Maumee.Dassel" } + Millston.Grays.Chevak: { type: ternary, size: 16, full_size: 16, key_name: "Grays.Chevak" } + Millston.Grays.Mendocino: { type: ternary, size: 16, full_size: 16, key_name: "Grays.Mendocino" } + Millston.Osyka.Noyes: { type: ternary, size: 8, full_size: 8, key_name: "Osyka.Noyes" } + row: [ 0, 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + indirect_bus: 2 + input_xbar: + ternary group 0: { 0: Millston.Maumee.Calcasieu.0-31, 32: Millston.Maumee.Calcasieu.32-63(0..7) } + ternary group 1: { 0: Millston.Maumee.Kaluaaha.0-31(16..31), 16: Millston.Maumee.Kaluaaha.32-63(0..23) } + ternary group 2: { 0: Millston.Maumee.Kaluaaha.32-63(24..31), 8: Millston.Maumee.Kaluaaha.64-95 } + ternary group 3: { 0: Millston.Maumee.Calcasieu.32-63(8..31), 24: Millston.Maumee.Calcasieu.64-95(0..15) } + ternary group 4: { 0: Millston.Maumee.Calcasieu.64-95(16..31), 16: Millston.Maumee.Calcasieu.96-127(0..23) } + ternary group 5: { 0: Millston.Maumee.Kaluaaha.96-111, 16: Millston.Grays.Mendocino(0..7), 24: Millston.Maumee.Calcasieu.96-127(24..31), 32: Millston.Grays.Chevak(0..7) } + ternary group 6: { 0: Millston.Grays.Mendocino(8..15), 8: Millston.Maumee.Kaluaaha.112-127(0..7), 16: Millston.Grays.Chevak(8..15), 24: HillTop.McGonigle.Buncombe, 32: Millston.Maumee.Kaluaaha.112-127(8..15) } + ternary group 7: { 0: Millston.Maumee.Dassel, 8: Millston.Osyka.Noyes } + byte group 0: { 0: Millston.Maumee.Kaluaaha.0-31(8..15) } + byte group 1: { 0: Millston.Maumee.Kaluaaha.0-31(0..7) } + match: + - { group: 0, byte_group: 0, byte_config: 0, dirtcam: 0x555 } + - { group: 1, byte_group: 0, byte_config: 1, dirtcam: 0x555 } + - { group: 2, byte_group: 1, byte_config: 0, dirtcam: 0x555 } + - { group: 3, byte_group: 1, byte_config: 1, dirtcam: 0x555 } + - { group: 4, byte_config: 3, dirtcam: 0x155 } + - { group: 5, dirtcam: 0x155 } + - { group: 6, dirtcam: 0x155 } + - { group: 7, dirtcam: 0x5 } + hit: [ _Newsoms ] + miss: _Newsoms + stats: _Keltys$st1$stats..Kinter($DIRECT, $DEFAULT) + action: _Keltys$st1$action_data($DIRECT, $DEFAULT) + instruction: _Keltys$st1($DEFAULT, $DEFAULT) + actions: + Elysburg(0, 1): + - p4_param_order: { Cornell: 2 } + - default_action: { allowed: true } + - handle: 0x20000149 + - next_table: 0 + - { Cornell: $adf_b0(0..1) } + - set HillTop.Wisdom.DeGraff, Cornell + - _Keltys$st1$stats..Kinter($DIRECT) + NoAction(-1, 0): + - default_only_action: { allowed: true } + - handle: 0x2000014a + - next_table: 0 + - { } + default_only_action: NoAction + counter _Keltys$st1$stats..Kinter: + p4: { name: Kinter } + row: 13 + column: [ 2, 3 ] + maprams: [ 2, 3 ] + count: packets + format: {packets(0): 64..127, packets(1): 0..63} + action _Keltys$st1$action_data: + p4: { name: Keltys$action } + row: 12 + column: 5 + vpns: [ 0 ] + home_row: + - 12 + format Elysburg: { $adf_b0: 0..7 } + action_bus: { 0 : $adf_b0 } +stage 11 egress: + ternary_match _Newsoms 9: + p4: { name: Newsoms, size: 512, disable_atomic_modify : true } + p4_param_order: + eg_intr_md.egress_port: { type: exact, size: 7, full_size: 9, key_name: "Sonoma.egress_port" } + HillTop.Stennett.Blairsden: { type: ternary, size: 1, full_size: 1, key_name: "Stennett.Blairsden" } + HillTop.Stennett.Standish: { type: ternary, size: 1, full_size: 1, key_name: "Stennett.Standish" } + HillTop.Edwards.SomesBar: { type: ternary, size: 1, full_size: 1, key_name: "Edwards.SomesBar" } + HillTop.Wisdom.DeGraff: { type: ternary, size: 2, full_size: 2, key_name: "Wisdom.DeGraff" } + row: 2 + bus: 1 + column: 1 + input_xbar: + ternary group 9: { 0: eg_intr_md.egress_port(0..6), 11: HillTop.Stennett.Blairsden, 20: HillTop.Stennett.Standish, 28: HillTop.Wisdom.DeGraff, 32: HillTop.Edwards.SomesBar } + match: + - { group: 9, dirtcam: 0x155 } + hit: [ _Astatula, _Hagewood_0 ] + miss: _Astatula + indirect: _Newsoms$tind + counter _Newsoms$stats.Corum: + p4: { name: Corum } + row: 5 + column: [ 0, 1 ] + maprams: [ 0, 1 ] + count: packets + format: {packets(0): 64..127, packets(1): 0..63} + ternary_indirect _Newsoms$tind: + row: 0 + bus: 0 + column: 2 + input_xbar: + ternary group 9: { 0: eg_intr_md.egress_port(0..6), 11: HillTop.Stennett.Blairsden, 20: HillTop.Stennett.Standish, 28: HillTop.Wisdom.DeGraff, 32: HillTop.Edwards.SomesBar } + format: { action: 0..0 } + stats: _Newsoms$stats.Corum($DIRECT, $DEFAULT) + instruction: _Newsoms$tind(action, $DEFAULT) + actions: + Nicollet(0, 1): + - default_action: { allowed: true } + - handle: 0x20000159 + - next_table: 0 + - set eg_intr_md_for_dprsr.drop_ctl, 7 + - _Newsoms$stats.Corum($DIRECT) + Fosston(1, 0): + - default_action: { allowed: true } + - handle: 0x2000015a + - next_table: 1 + - _Newsoms$stats.Corum($DIRECT) + default_action: Fosston + ternary_match _Hagewood_0 10: + p4: { name: Hagewood, size: 1, disable_atomic_modify : true } + gateway: + name: cond-51 + input_xbar: + exact group 1: { 40: HillTop.McCaskill.Grassflat(8..9), 48: HillTop.McCaskill.Grassflat(0..7), 58: HillTop.McCaskill.Tilton } + row: 6 + bus: 0 + unit: 0 + match: { 0: HillTop.McCaskill.Grassflat(0..7), 8: HillTop.McCaskill.Grassflat(8..9), 18: HillTop.McCaskill.Tilton } + 0b**************0000000000: _Astatula + 0b****00******************: run_table + miss: _Astatula + condition: + expression: "(HillTop.McCaskill.Grassflat != 0 && HillTop.McCaskill.Tilton == 0)" + true: _Hagewood_0 + false: _Astatula + hit: [ _Astatula ] + miss: _Astatula + indirect: _Hagewood_0$tind + ternary_indirect _Hagewood_0$tind: + row: 0 + bus: 1 + format: { action: 0..0 } + instruction: _Hagewood_0$tind(action, $DEFAULT) + actions: + Ozark(1, 2): + - default_action: { allowed: true } + - handle: 0x2000015b + - next_table: 0 + - set eg_intr_md_for_dprsr.mirror_type, 2 + - set HillTop.Plains.Miller, eg_intr_md.egress_port + default_action: Ozark + exact_match _Astatula 11: + p4: { name: Astatula, size: 128, disable_atomic_modify : true } + p4_param_order: + HillTop.Wisdom.Bowden: { type: exact, size: 12, full_size: 12, key_name: "Wisdom.Bowden" } + eg_intr_md.egress_port: { type: exact, size: 7, full_size: 9, key_name: "Sonoma.egress_port" } + HillTop.Wisdom.Weatherby: { type: exact, size: 1, full_size: 1, key_name: "Wisdom.Weatherby" } + row: 6 + bus: 0 + column: [ 2, 3 ] + stash: + row: [ 6 ] + col: [ 2 ] + unit: [ 0 ] + ways: + - [1, 2, 0x0, [6, 2]] + - [1, 3, 0x0, [6, 3]] + input_xbar: + exact group 1: { 64: eg_intr_md.egress_port(0..6), 72: HillTop.Wisdom.Bowden(8..11), 80: HillTop.Wisdom.Bowden(0..7), 93: HillTop.Wisdom.Weatherby } + hash 3: + 20..24: random(eg_intr_md.egress_port(5..6), HillTop.Wisdom.Bowden(0..7)) ^ eg_intr_md.egress_port(0..4) + 25..28: random(eg_intr_md.egress_port(5..6), HillTop.Wisdom.Bowden(0..7)) ^ HillTop.Wisdom.Bowden(8..11) + 29: random(eg_intr_md.egress_port(5..6), HillTop.Wisdom.Bowden(0..7)) ^ HillTop.Wisdom.Weatherby + 31..35: random(eg_intr_md.egress_port(5..6), HillTop.Wisdom.Bowden(0..7)) ^ eg_intr_md.egress_port(0..4) + 36..39: random(eg_intr_md.egress_port(5..6), HillTop.Wisdom.Bowden(0..7)) ^ HillTop.Wisdom.Bowden(8..11) + 30: random(eg_intr_md.egress_port(5..6), HillTop.Wisdom.Bowden(0..7)) ^ HillTop.Wisdom.Weatherby + hash group 1: + table: [3] + seed: 0xc2ae600000 + format: { action(0): 0..1, version(0): 112..115, match(0): [45..46, 32..39 ] } + match: [ eg_intr_md.egress_port(5..6), HillTop.Wisdom.Bowden(0..7) ] + gateway: + name: cond-52 + input_xbar: + exact group 2: { 1: HillTop.Wisdom.Westhoff, 8: HillTop.Wisdom.Stratford, 33: HillTop.Wisdom.Onycha } + row: 0 + bus: 1 + unit: 1 + match: { 16: HillTop.Wisdom.Stratford, 1: HillTop.Wisdom.Onycha, 9: HillTop.Wisdom.Westhoff } + 0b*******1***************: END + 0b********************010: END + 0b************011********: END + miss: run_table + condition: + expression: "(HillTop.Wisdom.Stratford == 0 && HillTop.Wisdom.Onycha != 2 && HillTop.Wisdom.Westhoff != 3)" + true: _Astatula + false: END + hit: [ END ] + miss: END + instruction: _Astatula(action, $DEFAULT) + actions: + Berlin(1, 0): + - default_action: { allowed: true } + - handle: 0x2000015c + - next_table: 0 + Ardsley(2, 3): + - default_action: { allowed: true } + - handle: 0x2000015d + - next_table: 0 + - set Millston.Wondervu$0.$valid, 1 + - set Millston.Wondervu$0.McCaulley, Millston.Calabash.McCaulley + - set Millston.Calabash.McCaulley, 33024 + - deposit-field H22(12..15), H20(4..7), H23 + default_action: Ardsley + +flexible_headers: [ + + { name: "Millston.Belgrade", + fields: [ + + { name: "Roachdale", slice: { start_bit: 0, bit_width: 8 } }, + { name: "Rugby", slice: { start_bit: 0, bit_width: 3 } }, + { name: "Davie", slice: { start_bit: 0, bit_width: 1 } }, + { name: "Cacao", slice: { start_bit: 0, bit_width: 4 } }, + { name: "Mankato", slice: { start_bit: 0, bit_width: 8 } }, + { name: "Virgil", slice: { start_bit: 0, bit_width: 24 } }, + { name: "Florin", slice: { start_bit: 0, bit_width: 24 } }, + { name: "Ronan", slice: { start_bit: 0, bit_width: 32 } }, + { name: "Corinth", slice: { start_bit: 0, bit_width: 16 } }, + { name: "__pad_0", slice: { start_bit: 0, bit_width: 4 } }, + { name: "Union", slice: { start_bit: 0, bit_width: 3 } }, + { name: "Rockport", slice: { start_bit: 0, bit_width: 1 } }, + { name: "__pad_1", slice: { start_bit: 0, bit_width: 25 } }, + { name: "Sudbury", slice: { start_bit: 0, bit_width: 6 } }, + { name: "Waipahu", slice: { start_bit: 0, bit_width: 1 } }, + { name: "Willard", slice: { start_bit: 0, bit_width: 3 } }, + { name: "Anacortes", slice: { start_bit: 0, bit_width: 1 } }, + { name: "Allgood", slice: { start_bit: 0, bit_width: 3 } }, + { name: "Shabbona", slice: { start_bit: 0, bit_width: 1 } }, + { name: "__pad_2", slice: { start_bit: 0, bit_width: 7 } }, + { name: "Freeburg", slice: { start_bit: 0, bit_width: 1 } }, + { name: "__pad_3", slice: { start_bit: 0, bit_width: 6 } }, + { name: "Selawik", slice: { start_bit: 0, bit_width: 2 } }, + { name: "__pad_4", slice: { start_bit: 0, bit_width: 10 } }, + { name: "Matheson", slice: { start_bit: 0, bit_width: 6 } }, + { name: "__pad_5", slice: { start_bit: 0, bit_width: 7 } }, + { name: "Chaska", slice: { start_bit: 0, bit_width: 9 } }, + { name: "__pad_6", slice: { start_bit: 0, bit_width: 4 } }, + { name: "Requa", slice: { start_bit: 0, bit_width: 12 } }, + { name: "__pad_7", slice: { start_bit: 0, bit_width: 4 } }, + { name: "Bayshore", slice: { start_bit: 0, bit_width: 12 } }, + { name: "__pad_8", slice: { start_bit: 0, bit_width: 4 } }, + { name: "Florien", slice: { start_bit: 0, bit_width: 12 } } ] + }, + { name: "HillTop.Plains", + fields: [ + + { name: "Roachdale", slice: { start_bit: 0, bit_width: 8 } }, + { name: "__pad_0", slice: { start_bit: 0, bit_width: 7 } }, + { name: "Miller", slice: { start_bit: 0, bit_width: 9 } } ] + }, + { name: "Plains_0", + fields: [ + + { name: "Roachdale", slice: { start_bit: 0, bit_width: 8 } }, + { name: "__pad_0", slice: { start_bit: 0, bit_width: 7 } }, + { name: "Miller", slice: { start_bit: 0, bit_width: 9 } } ] + }] + +primitives: "tcam_issue2.tofino/pipe//tcam_issue2.prim.json" +dynhash: "tcam_issue2.tofino/pipe//tcam_issue2.dynhash.json" diff --git a/backends/tofino/bf-asm/test/asm/p4c-4021.bfa b/backends/tofino/bf-asm/test/asm/p4c-4021.bfa new file mode 100644 index 00000000000..b3c4890c634 --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/p4c-4021.bfa @@ -0,0 +1,2381 @@ +version: + version: 1.0.1 + run_id: "1c65bbeecfecdbc9" + target: Tofino +phv ingress: + ig_intr_md.ingress_port: { stage 0..1: W1(16..24) } + ig_intr_md.ingress_mac_tstamp.0-31: { stage 0..1: W3 } + ig_intr_md.ingress_mac_tstamp.32-39: { stage 0..1: B5 } + ig_intr_md.ingress_mac_tstamp.40-47: { stage 0..1: W1(8..15) } + meta.mirror_session: H2(0..9) + meta.mac_timestamp: W2 + meta.pkt_type: B2 + hdr.bridge.rich_register: TB0 + hdr.bridge.pkt_type: TB9 + hdr.bridge.__pad_0: { stage 12: B3(4..7) } + hdr.bridge.rich_register_v: B3(3) + hdr.bridge.l23_rxtstmp_insert: B3(2) + hdr.bridge.l23_txtstmp_insert: B3(1) + hdr.bridge.l47_timestamp_insert: B3(0) + hdr.capture.seq_no: W0(8..31) + hdr.capture.reserved: W0(0..7) + hdr.capture.timestamp: TW0 + hdr.ethernet.dst_addr.0-31: TW9 + hdr.ethernet.dst_addr.32-47: TH20 + hdr.ethernet.src_addr.0-31: TW8 + hdr.ethernet.src_addr.32-47: TH19 + hdr.ethernet.ether_type: TH18 + hdr.vlan_tag.pcp: TW0(29..31) + hdr.vlan_tag.cfi: TW0(28) + hdr.vlan_tag.vid: TW0(16..27) + hdr.vlan_tag.ether_type: TW0(0..15) + hdr.ipv4.version: TW1(28..31) + hdr.ipv4.ihl: TW1(24..27) + hdr.ipv4.diffserv: TW1(16..23) + hdr.ipv4.total_len: TW1(0..15) + hdr.ipv4.identification: TH1 + hdr.ipv4.flags: TH0(13..15) + hdr.ipv4.frag_offset: TH0(0..12) + hdr.ipv4.ttl: TW3(24..31) + hdr.ipv4.protocol: TW3(16..23) + hdr.ipv4.hdr_checksum: TW3(0..15) + hdr.ipv4.src_addr: TW11 + hdr.ipv4.dst_addr: TW10 + hdr.tcp.src_port: TH5 + hdr.tcp.dst_port: TH4 + hdr.tcp.seq_no.0-15: TH14 + hdr.tcp.seq_no.16-31: TH15 + hdr.tcp.ack_no.0-15: TH12 + hdr.tcp.ack_no.16-31: TH13 + hdr.tcp.data_offset: TW2(28..31) + hdr.tcp.res: TW2(24..27) + hdr.tcp.flags: TW2(16..23) + hdr.tcp.window: TW2(0..15) + hdr.tcp.checksum: TH3 + hdr.tcp.urgent_ptr: TH2 + hdr.first_payload.signature_top: TW15 + hdr.first_payload.signature_bot: TW14 + hdr.first_payload.rx_timestamp: TW13 + hdr.first_payload.pgid: TW12 + hdr.first_payload.sequence.0-7: TB1 + hdr.first_payload.sequence.8-15: TB2 + hdr.first_payload.sequence.16-23: TB3 + hdr.first_payload.sequence.24-31: TB8 + hdr.first_payload.txtstamp.0-15: TH16 + hdr.first_payload.txtstamp.16-31: TH17 + hdr.udp.src_port: TH3 + hdr.udp.dst_port: TH2 + hdr.udp.hdr_length: TW2(16..31) + hdr.udp.checksum: TW2(0..15) + capture_port_1: { stage 1: W1(0..7) } + seq_no_0: { stage 1: H3 } + ig_intr_md_for_tm.ucast_egress_port: H0(0..8) + ig_intr_md_for_tm.mcast_grp_a: H1 + ig_intr_md_for_dprsr.drop_ctl: { stage 1..12: B1(0..2) } + ig_intr_md_for_dprsr.mirror_type: B0(0..2) + hdr.bridge.$valid: B4(0) + hdr.capture.$valid: B4(1) + hdr.ethernet.$valid: B4(2) + hdr.vlan_tag.$valid: B4(3) + hdr.ipv4.$valid: B4(4) + hdr.tcp.$valid: B4(5) + hdr.first_payload.$valid: B4(6) + hdr.udp.$valid: B4(7) +phv egress: + eg_intr_md_from_prsr.global_tstamp.0-31: { stage 0..10: W16 } + eg_intr_md_from_prsr.global_tstamp.32-47: { stage 0..10: TH33 } + eg_intr_md.egress_port: H24(0..8) + eg_intr_md.pkt_length: { stage 0..1: H16 } + meta.ing_port_mirror.pkt_type: { stage 0..10: B23 } + meta.ing_port_mirror.mac_timestamp: W17 + hdr.ethernet.dst_addr.0-31: TW16 + hdr.ethernet.dst_addr.32-47: TH32 + hdr.ethernet.src_addr.0-15: TH11 + hdr.ethernet.src_addr.16-23: TB6 + hdr.ethernet.src_addr.24-31: TB7 + hdr.ethernet.src_addr.32-47: TH31 + hdr.ethernet.ether_type: TH30 + meta.mirror_session: { stage 11..12: H16(0..9) } + meta.pkt_type: B17 + hdr.vlan_tag.pcp: TB4(5..7) + hdr.vlan_tag.cfi: TB4(4) + hdr.vlan_tag.vid.0-7: TB5 + hdr.vlan_tag.vid.8-11: TB4(0..3) + hdr.vlan_tag.ether_type: TH6 + hdr.ipv4.version: TW4(28..31) + hdr.ipv4.ihl: TW4(24..27) + hdr.ipv4.diffserv: TW4(16..23) + hdr.ipv4.total_len: TW4(0..15) + hdr.ipv4.identification: TW7(16..31) + hdr.ipv4.flags: TW7(13..15) + hdr.ipv4.frag_offset: TW7(0..12) + hdr.ipv4.ttl: TW6(24..31) + hdr.ipv4.protocol: TW6(16..23) + hdr.ipv4.hdr_checksum: TW6(0..15) + hdr.ipv4.src_addr: TW18 + hdr.ipv4.dst_addr: TW17 + hdr.tcp.src_port: TH10 + hdr.tcp.dst_port: TH9 + hdr.tcp.seq_no.0-15: TH24 + hdr.tcp.seq_no.16-31: TH25 + hdr.tcp.ack_no: TW19 + hdr.tcp.data_offset: TW5(28..31) + hdr.tcp.res: TW5(24..27) + hdr.tcp.flags: TW5(16..23) + hdr.tcp.window: TW5(0..15) + hdr.tcp.checksum: TH8 + hdr.tcp.urgent_ptr: TH7 + hdr.first_payload.signature_top: TW22 + hdr.first_payload.signature_bot: TW21 + hdr.first_payload.rx_timestamp: TW20 + hdr.first_payload.pgid.0-7: TB16 + hdr.first_payload.pgid.8-15: TB17 + hdr.first_payload.pgid.16-23: TB18 + hdr.first_payload.pgid.24-31: TB19 + hdr.first_payload.sequence.0-15: TH28 + hdr.first_payload.sequence.16-31: TH29 + hdr.first_payload.txtstamp.0-15: TH26 + hdr.first_payload.txtstamp.16-31: TH27 + hdr.udp.src_port: TH8 + hdr.udp.dst_port: TH7 + hdr.udp.hdr_length: TW5(16..31) + hdr.udp.checksum: TW5(0..15) + hdr.capture.seq_no.0-15: TH6 + hdr.capture.seq_no.16-23: TB4 + hdr.capture.reserved: B18 + hdr.capture.timestamp: W18 + update_register_portion: { stage 1: H17 } + update_register_capture_port: { stage 2..9: B20 } + update_register_padded_length: { stage 2..3: H16 } + update_register_negated_length: { stage 3: H18 } + update_register_load_length: { stage 3: H17 } + update_register_cap_length: { stage 0..4: H23 } + update_register_cap_length_0: { stage 0..5: H19 } + update_register_cap_length_1: { stage 0..6: H20 } + update_register_cap_length_2: { stage 0..7: H21 } + update_register_cap_length_3: { stage 0..8: H22 } + update_register_debt0: { stage 5..6: H16 } + update_register_debt1: { stage 6..7: H17 } + update_register_debt2: { stage 7..8: H16 } + update_register_debt3: { stage 8..9: H17 } + update_register_debt4: { stage 9: H16 } + update_register_reg0.0-3: { stage 0..7: B19(4..7) } + update_register_reg0.4-7: { stage 0..7: B21(4..7) } + update_register_reg1.0-3: { stage 8: B19(4..7) } + update_register_reg1.4-7: { stage 8: B21(4..7) } + update_register_reg2.0-3: { stage 9: B19(4..7) } + update_register_reg2.4-7: { stage 9: B21(4..7) } + rich_register_0.0-3: { stage 0..10: B19(0..3) } + rich_register_0.4-7: { stage 0..10: B21(0..3) } + eg_intr_md_for_dprsr.mirror_type: B16(0..2) + hdr.ethernet.$valid: B22(0) + hdr.vlan_tag.$valid: B22(1) + hdr.ipv4.$valid: B22(2) + hdr.tcp.$valid: B22(3) + hdr.first_payload.$valid: B22(4) + hdr.udp.$valid: B22(5) + hdr.capture.$valid: B22(6) +parser ingress: + start: $entry_point + init_zero: [ H2, W2, B2, TB0, B3, B4 ] + bitwise_or: [ TB9, B2, B4 ] + hdr_len_adj: 16 + states: + $entry_point: + *: + load: { byte1 : 12 } + buf_req: 13 + next: start + start: + match: [ byte1 ] + 0x*4: + 0..3: W1 + # - bit[7..15] -> W1 bit[24..16]: ingress::ig_intr_md.ingress_port + # - bit[16..23] -> W1 bit[15..8]: ingress::ig_intr_md.ingress_mac_tstamp[47:40].40-47 + 3: B5 # ingress::ig_intr_md.ingress_mac_tstamp[39:32].32-39 + 4..7: W3 # ingress::ig_intr_md.ingress_mac_tstamp[31:0].0-31 + B2: 1 # value 1 -> B2 bit[7..0]: ingress::meta.pkt_type + B4: 1 # value 1 -> B4 bit[0]: ingress::hdr.bridge.$valid + TB9: 1 # value 1 -> TB9 bit[7..0]: ingress::hdr.bridge.pkt_type + shift: 16 + buf_req: 16 + next: parse_capture_depth + 0x*5: + 0..3: W1 + # - bit[7..15] -> W1 bit[24..16]: ingress::ig_intr_md.ingress_port + # - bit[16..23] -> W1 bit[15..8]: ingress::ig_intr_md.ingress_mac_tstamp[47:40].40-47 + 3: B5 # ingress::ig_intr_md.ingress_mac_tstamp[39:32].32-39 + 4..7: W3 # ingress::ig_intr_md.ingress_mac_tstamp[31:0].0-31 + B2: 1 # value 1 -> B2 bit[7..0]: ingress::meta.pkt_type + B4: 1 # value 1 -> B4 bit[0]: ingress::hdr.bridge.$valid + TB9: 1 # value 1 -> TB9 bit[7..0]: ingress::hdr.bridge.pkt_type + shift: 16 + buf_req: 16 + next: parse_capture + 0x**: + 0..3: W1 + # - bit[7..15] -> W1 bit[24..16]: ingress::ig_intr_md.ingress_port + # - bit[16..23] -> W1 bit[15..8]: ingress::ig_intr_md.ingress_mac_tstamp[47:40].40-47 + 3: B5 # ingress::ig_intr_md.ingress_mac_tstamp[39:32].32-39 + 4..7: W3 # ingress::ig_intr_md.ingress_mac_tstamp[31:0].0-31 + B2: 1 # value 1 -> B2 bit[7..0]: ingress::meta.pkt_type + B4: 1 # value 1 -> B4 bit[0]: ingress::hdr.bridge.$valid + TB9: 1 # value 1 -> TB9 bit[7..0]: ingress::hdr.bridge.pkt_type + load: { half : 28..29 } + shift: 16 + buf_req: 30 + next: parse_ethernet + parse_capture_depth: + *: + 0..3: W0 + # - bit[0..23] -> W0 bit[31..8]: ingress::hdr.capture.seq_no + # - bit[24..31] -> W0 bit[7..0]: ingress::hdr.capture.reserved + 4..7: TW0 # ingress::hdr.capture.timestamp + B4: 2 # value 1 -> B4 bit[1]: ingress::hdr.capture.$valid + shift: 8 + buf_req: 8 + next: end + parse_capture: + *: + 0..3: W0 + # - bit[0..23] -> W0 bit[31..8]: ingress::hdr.capture.seq_no + # - bit[24..31] -> W0 bit[7..0]: ingress::hdr.capture.reserved + 4..7: TW0 # ingress::hdr.capture.timestamp + B4: 2 # value 1 -> B4 bit[1]: ingress::hdr.capture.$valid + B2: 3 # value 3 -> B2 bit[7..0]: ingress::meta.pkt_type + TB9: 5 # value 5 -> TB9 bit[7..0]: ingress::hdr.bridge.pkt_type + shift: 8 + buf_req: 8 + next: end + parse_ethernet: + match: [ half ] + 0x8100: + 0..1: TH20 # ingress::hdr.ethernet.dst_addr[47:32].32-47 + 2..5: TW9 # ingress::hdr.ethernet.dst_addr[31:0].0-31 + 6..7: TH19 # ingress::hdr.ethernet.src_addr[47:32].32-47 + 8..11: TW8 # ingress::hdr.ethernet.src_addr[31:0].0-31 + 12..13: TH18 # ingress::hdr.ethernet.ether_type + B4: 4 # value 1 -> B4 bit[2]: ingress::hdr.ethernet.$valid + load: { half : 16..17 } + shift: 14 + buf_req: 18 + next: parse_vlan_tag + 0x0800: + 0..1: TH20 # ingress::hdr.ethernet.dst_addr[47:32].32-47 + 2..5: TW9 # ingress::hdr.ethernet.dst_addr[31:0].0-31 + 6..7: TH19 # ingress::hdr.ethernet.src_addr[47:32].32-47 + 8..11: TW8 # ingress::hdr.ethernet.src_addr[31:0].0-31 + 12..13: TH18 # ingress::hdr.ethernet.ether_type + B4: 4 # value 1 -> B4 bit[2]: ingress::hdr.ethernet.$valid + load: { byte1 : 23 } + shift: 14 + buf_req: 24 + next: parse_ipv4 + 0x****: + 0..1: TH20 # ingress::hdr.ethernet.dst_addr[47:32].32-47 + 2..5: TW9 # ingress::hdr.ethernet.dst_addr[31:0].0-31 + 6..7: TH19 # ingress::hdr.ethernet.src_addr[47:32].32-47 + 8..11: TW8 # ingress::hdr.ethernet.src_addr[31:0].0-31 + 12..13: TH18 # ingress::hdr.ethernet.ether_type + B4: 4 # value 1 -> B4 bit[2]: ingress::hdr.ethernet.$valid + shift: 14 + buf_req: 14 + next: end + parse_vlan_tag: + match: [ half ] + 0x0800: + 0..3: TW0 + # - bit[0..2] -> TW0 bit[31..29]: ingress::hdr.vlan_tag.pcp + # - bit[3] -> TW0 bit[28]: ingress::hdr.vlan_tag.cfi + # - bit[4..15] -> TW0 bit[27..16]: ingress::hdr.vlan_tag.vid + # - bit[16..31] -> TW0 bit[15..0]: ingress::hdr.vlan_tag.ether_type + B4: 8 # value 1 -> B4 bit[3]: ingress::hdr.vlan_tag.$valid + load: { byte1 : 13 } + shift: 4 + buf_req: 14 + next: parse_ipv4 + 0x****: + 0..3: TW0 + # - bit[0..2] -> TW0 bit[31..29]: ingress::hdr.vlan_tag.pcp + # - bit[3] -> TW0 bit[28]: ingress::hdr.vlan_tag.cfi + # - bit[4..15] -> TW0 bit[27..16]: ingress::hdr.vlan_tag.vid + # - bit[16..31] -> TW0 bit[15..0]: ingress::hdr.vlan_tag.ether_type + B4: 8 # value 1 -> B4 bit[3]: ingress::hdr.vlan_tag.$valid + shift: 4 + buf_req: 4 + next: end + parse_ipv4: + match: [ byte1 ] + 0x06: + 0..3: TW1 + # - bit[0..3] -> TW1 bit[31..28]: ingress::hdr.ipv4.version + # - bit[4..7] -> TW1 bit[27..24]: ingress::hdr.ipv4.ihl + # - bit[8..15] -> TW1 bit[23..16]: ingress::hdr.ipv4.diffserv + # - bit[16..31] -> TW1 bit[15..0]: ingress::hdr.ipv4.total_len + 4..5: TH1 # ingress::hdr.ipv4.identification + 6..7: TH0 + # - bit[48..50] -> TH0 bit[15..13]: ingress::hdr.ipv4.flags + # - bit[51..63] -> TH0 bit[12..0]: ingress::hdr.ipv4.frag_offset + 8..11: TW3 + # - bit[64..71] -> TW3 bit[31..24]: ingress::hdr.ipv4.ttl + # - bit[72..79] -> TW3 bit[23..16]: ingress::hdr.ipv4.protocol + # - bit[80..95] -> TW3 bit[15..0]: ingress::hdr.ipv4.hdr_checksum + 12..15: TW11 # ingress::hdr.ipv4.src_addr + 16..19: TW10 # ingress::hdr.ipv4.dst_addr + B4: 16 # value 1 -> B4 bit[4]: ingress::hdr.ipv4.$valid + shift: 20 + buf_req: 20 + next: parseTcp + 0x11: + 0..3: TW1 + # - bit[0..3] -> TW1 bit[31..28]: ingress::hdr.ipv4.version + # - bit[4..7] -> TW1 bit[27..24]: ingress::hdr.ipv4.ihl + # - bit[8..15] -> TW1 bit[23..16]: ingress::hdr.ipv4.diffserv + # - bit[16..31] -> TW1 bit[15..0]: ingress::hdr.ipv4.total_len + 4..5: TH1 # ingress::hdr.ipv4.identification + 6..7: TH0 + # - bit[48..50] -> TH0 bit[15..13]: ingress::hdr.ipv4.flags + # - bit[51..63] -> TH0 bit[12..0]: ingress::hdr.ipv4.frag_offset + 8..11: TW3 + # - bit[64..71] -> TW3 bit[31..24]: ingress::hdr.ipv4.ttl + # - bit[72..79] -> TW3 bit[23..16]: ingress::hdr.ipv4.protocol + # - bit[80..95] -> TW3 bit[15..0]: ingress::hdr.ipv4.hdr_checksum + 12..15: TW11 # ingress::hdr.ipv4.src_addr + 16..19: TW10 # ingress::hdr.ipv4.dst_addr + B4: 16 # value 1 -> B4 bit[4]: ingress::hdr.ipv4.$valid + shift: 20 + buf_req: 20 + next: parseUdp + 0x**: + 0..3: TW1 + # - bit[0..3] -> TW1 bit[31..28]: ingress::hdr.ipv4.version + # - bit[4..7] -> TW1 bit[27..24]: ingress::hdr.ipv4.ihl + # - bit[8..15] -> TW1 bit[23..16]: ingress::hdr.ipv4.diffserv + # - bit[16..31] -> TW1 bit[15..0]: ingress::hdr.ipv4.total_len + 4..5: TH1 # ingress::hdr.ipv4.identification + 6..7: TH0 + # - bit[48..50] -> TH0 bit[15..13]: ingress::hdr.ipv4.flags + # - bit[51..63] -> TH0 bit[12..0]: ingress::hdr.ipv4.frag_offset + 8..11: TW3 + # - bit[64..71] -> TW3 bit[31..24]: ingress::hdr.ipv4.ttl + # - bit[72..79] -> TW3 bit[23..16]: ingress::hdr.ipv4.protocol + # - bit[80..95] -> TW3 bit[15..0]: ingress::hdr.ipv4.hdr_checksum + 12..15: TW11 # ingress::hdr.ipv4.src_addr + 16..19: TW10 # ingress::hdr.ipv4.dst_addr + B4: 16 # value 1 -> B4 bit[4]: ingress::hdr.ipv4.$valid + shift: 20 + buf_req: 20 + next: parseL23 + parseTcp: + *: + 0..1: TH5 # ingress::hdr.tcp.src_port + 2..3: TH4 # ingress::hdr.tcp.dst_port + 4..5: TH15 # ingress::hdr.tcp.seq_no[31:16].16-31 + 6..7: TH14 # ingress::hdr.tcp.seq_no[15:0].0-15 + 12..15: TW2 + # - bit[96..99] -> TW2 bit[31..28]: ingress::hdr.tcp.data_offset + # - bit[100..103] -> TW2 bit[27..24]: ingress::hdr.tcp.res + # - bit[104..111] -> TW2 bit[23..16]: ingress::hdr.tcp.flags + # - bit[112..127] -> TW2 bit[15..0]: ingress::hdr.tcp.window + 20..23: TW15 # ingress::hdr.first_payload.signature_top + 24..27: TW14 # ingress::hdr.first_payload.signature_bot + 28..31: TW13 # ingress::hdr.first_payload.rx_timestamp + B4: 96 + # - value 1 -> B4 bit[5]: ingress::hdr.tcp.$valid + # - value 1 -> B4 bit[6]: ingress::hdr.first_payload.$valid + shift: 8 + buf_req: 32 + next: parseTcp.$split_0 + parseTcp.$split_0: + *: + 0..1: TH13 # ingress::hdr.tcp.ack_no[31:16].16-31 + 2..3: TH12 # ingress::hdr.tcp.ack_no[15:0].0-15 + 8..9: TH3 # ingress::hdr.tcp.checksum + 10..11: TH2 # ingress::hdr.tcp.urgent_ptr + 24..27: TW12 # ingress::hdr.first_payload.pgid + 28: TB8 # ingress::hdr.first_payload.sequence[31:24].24-31 + 29: TB3 # ingress::hdr.first_payload.sequence[23:16].16-23 + 30: TB2 # ingress::hdr.first_payload.sequence[15:8].8-15 + 31: TB1 # ingress::hdr.first_payload.sequence[7:0].0-7 + shift: 32 + buf_req: 32 + next: parseTcp.$split_1 + parseTcp.$split_1: + *: + 0..1: TH17 # ingress::hdr.first_payload.txtstamp[31:16].16-31 + 2..3: TH16 # ingress::hdr.first_payload.txtstamp[15:0].0-15 + shift: 4 + buf_req: 4 + next: end + parseUdp: + *: + 0..1: TH3 # ingress::hdr.udp.src_port + 2..3: TH2 # ingress::hdr.udp.dst_port + 4..7: TW2 + # - bit[32..47] -> TW2 bit[31..16]: ingress::hdr.udp.hdr_length + # - bit[48..63] -> TW2 bit[15..0]: ingress::hdr.udp.checksum + 8..11: TW15 # ingress::hdr.first_payload.signature_top + 12..15: TW14 # ingress::hdr.first_payload.signature_bot + 16..19: TW13 # ingress::hdr.first_payload.rx_timestamp + 24: TB8 # ingress::hdr.first_payload.sequence[31:24].24-31 + 25: TB3 # ingress::hdr.first_payload.sequence[23:16].16-23 + 26: TB2 # ingress::hdr.first_payload.sequence[15:8].8-15 + 27: TB1 # ingress::hdr.first_payload.sequence[7:0].0-7 + 28..29: TH17 # ingress::hdr.first_payload.txtstamp[31:16].16-31 + 30..31: TH16 # ingress::hdr.first_payload.txtstamp[15:0].0-15 + shift: 20 + buf_req: 32 + next: parseUdp.$split_0 + parseUdp.$split_0: + *: + 0..3: TW12 # ingress::hdr.first_payload.pgid + B4: 192 + # - value 1 -> B4 bit[7]: ingress::hdr.udp.$valid + # - value 1 -> B4 bit[6]: ingress::hdr.first_payload.$valid + shift: 12 + buf_req: 12 + next: end + parseL23: + *: + 0..3: TW15 # ingress::hdr.first_payload.signature_top + 4..7: TW14 # ingress::hdr.first_payload.signature_bot + 8..11: TW13 # ingress::hdr.first_payload.rx_timestamp + 12..15: TW12 # ingress::hdr.first_payload.pgid + 16: TB8 # ingress::hdr.first_payload.sequence[31:24].24-31 + 17: TB3 # ingress::hdr.first_payload.sequence[23:16].16-23 + 18: TB2 # ingress::hdr.first_payload.sequence[15:8].8-15 + 19: TB1 # ingress::hdr.first_payload.sequence[7:0].0-7 + 20..21: TH17 # ingress::hdr.first_payload.txtstamp[31:16].16-31 + 22..23: TH16 # ingress::hdr.first_payload.txtstamp[15:0].0-15 + shift: 24 + buf_req: 24 + next: parseL23.$split_0 + parseL23.$split_0: + *: + B4: 64 # value 1 -> B4 bit[6]: ingress::hdr.first_payload.$valid + buf_req: 0 + next: end +deparser ingress: + dictionary: + TB0: B4(0) # ingress::hdr.bridge.rich_register if ingress::hdr.bridge.$valid + TB9: B4(0) # ingress::hdr.bridge.pkt_type if ingress::hdr.bridge.$valid + B3: B4(0) + # - bit[7..4]: ingress::hdr.bridge.__pad_0 if ingress::hdr.bridge.$valid + # - bit[3]: ingress::hdr.bridge.rich_register_v if ingress::hdr.bridge.$valid + # - bit[2]: ingress::hdr.bridge.l23_rxtstmp_insert if ingress::hdr.bridge.$valid + # - bit[1]: ingress::hdr.bridge.l23_txtstmp_insert if ingress::hdr.bridge.$valid + # - bit[0]: ingress::hdr.bridge.l47_timestamp_insert if ingress::hdr.bridge.$valid + W0: B4(1) + # - bit[31..8]: ingress::hdr.capture.seq_no if ingress::hdr.capture.$valid + # - bit[7..0]: ingress::hdr.capture.reserved if ingress::hdr.capture.$valid + TW0: B4(1) # ingress::hdr.capture.timestamp if ingress::hdr.capture.$valid + TH20: B4(2) # ingress::hdr.ethernet.dst_addr.32-47 if ingress::hdr.ethernet.$valid + TW9: B4(2) # ingress::hdr.ethernet.dst_addr.0-31 if ingress::hdr.ethernet.$valid + TH19: B4(2) # ingress::hdr.ethernet.src_addr.32-47 if ingress::hdr.ethernet.$valid + TW8: B4(2) # ingress::hdr.ethernet.src_addr.0-31 if ingress::hdr.ethernet.$valid + TH18: B4(2) # ingress::hdr.ethernet.ether_type if ingress::hdr.ethernet.$valid + TW0: B4(3) + # - bit[31..29]: ingress::hdr.vlan_tag.pcp if ingress::hdr.vlan_tag.$valid + # - bit[28]: ingress::hdr.vlan_tag.cfi if ingress::hdr.vlan_tag.$valid + # - bit[27..16]: ingress::hdr.vlan_tag.vid if ingress::hdr.vlan_tag.$valid + # - bit[15..0]: ingress::hdr.vlan_tag.ether_type if ingress::hdr.vlan_tag.$valid + TW1: B4(4) + # - bit[31..28]: ingress::hdr.ipv4.version if ingress::hdr.ipv4.$valid + # - bit[27..24]: ingress::hdr.ipv4.ihl if ingress::hdr.ipv4.$valid + # - bit[23..16]: ingress::hdr.ipv4.diffserv if ingress::hdr.ipv4.$valid + # - bit[15..0]: ingress::hdr.ipv4.total_len if ingress::hdr.ipv4.$valid + TH1: B4(4) # ingress::hdr.ipv4.identification if ingress::hdr.ipv4.$valid + TH0: B4(4) + # - bit[15..13]: ingress::hdr.ipv4.flags if ingress::hdr.ipv4.$valid + # - bit[12..0]: ingress::hdr.ipv4.frag_offset if ingress::hdr.ipv4.$valid + TW3: B4(4) + # - bit[31..24]: ingress::hdr.ipv4.ttl if ingress::hdr.ipv4.$valid + # - bit[23..16]: ingress::hdr.ipv4.protocol if ingress::hdr.ipv4.$valid + # - bit[15..0]: ingress::hdr.ipv4.hdr_checksum if ingress::hdr.ipv4.$valid + TW11: B4(4) # ingress::hdr.ipv4.src_addr if ingress::hdr.ipv4.$valid + TW10: B4(4) # ingress::hdr.ipv4.dst_addr if ingress::hdr.ipv4.$valid + TH5: B4(5) # ingress::hdr.tcp.src_port if ingress::hdr.tcp.$valid + TH4: B4(5) # ingress::hdr.tcp.dst_port if ingress::hdr.tcp.$valid + TH15: B4(5) # ingress::hdr.tcp.seq_no.16-31 if ingress::hdr.tcp.$valid + TH14: B4(5) # ingress::hdr.tcp.seq_no.0-15 if ingress::hdr.tcp.$valid + TH13: B4(5) # ingress::hdr.tcp.ack_no.16-31 if ingress::hdr.tcp.$valid + TH12: B4(5) # ingress::hdr.tcp.ack_no.0-15 if ingress::hdr.tcp.$valid + TW2: B4(5) + # - bit[31..28]: ingress::hdr.tcp.data_offset if ingress::hdr.tcp.$valid + # - bit[27..24]: ingress::hdr.tcp.res if ingress::hdr.tcp.$valid + # - bit[23..16]: ingress::hdr.tcp.flags if ingress::hdr.tcp.$valid + # - bit[15..0]: ingress::hdr.tcp.window if ingress::hdr.tcp.$valid + TH3: B4(5) # ingress::hdr.tcp.checksum if ingress::hdr.tcp.$valid + TH2: B4(5) # ingress::hdr.tcp.urgent_ptr if ingress::hdr.tcp.$valid + TH3: B4(7) # ingress::hdr.udp.src_port if ingress::hdr.udp.$valid + TH2: B4(7) # ingress::hdr.udp.dst_port if ingress::hdr.udp.$valid + TW2: B4(7) + # - bit[31..16]: ingress::hdr.udp.hdr_length if ingress::hdr.udp.$valid + # - bit[15..0]: ingress::hdr.udp.checksum if ingress::hdr.udp.$valid + TW15: B4(6) # ingress::hdr.first_payload.signature_top if ingress::hdr.first_payload.$valid + TW14: B4(6) # ingress::hdr.first_payload.signature_bot if ingress::hdr.first_payload.$valid + TW13: B4(6) # ingress::hdr.first_payload.rx_timestamp if ingress::hdr.first_payload.$valid + TW12: B4(6) # ingress::hdr.first_payload.pgid if ingress::hdr.first_payload.$valid + TB8: B4(6) # ingress::hdr.first_payload.sequence.24-31 if ingress::hdr.first_payload.$valid + TB3: B4(6) # ingress::hdr.first_payload.sequence.16-23 if ingress::hdr.first_payload.$valid + TB2: B4(6) # ingress::hdr.first_payload.sequence.8-15 if ingress::hdr.first_payload.$valid + TB1: B4(6) # ingress::hdr.first_payload.sequence.0-7 if ingress::hdr.first_payload.$valid + TH17: B4(6) # ingress::hdr.first_payload.txtstamp.16-31 if ingress::hdr.first_payload.$valid + TH16: B4(6) # ingress::hdr.first_payload.txtstamp.0-15 if ingress::hdr.first_payload.$valid + egress_unicast_port: H0(0..8) # bit[8..0]: ingress::ig_intr_md_for_tm.ucast_egress_port + drop_ctl: B1(0..2) # bit[2..0]: ingress::ig_intr_md_for_dprsr.drop_ctl + egress_multicast_group_0: + - H1 # ingress::ig_intr_md_for_tm.mcast_grp_a + mirror: + select: B0(0..2) # bit[2..0]: ingress::ig_intr_md_for_dprsr.mirror_type + 1: + - H2(0..9) # bit[9..0]: ingress::meta.mirror_session + - B2 # ingress::meta.pkt_type + - W2 # ingress::meta.mac_timestamp +parser egress: + start: $entry_point + init_zero: [ W16, TH33, B17, H23, H19, H20, H21, H22, B19, B21, B22 ] + bitwise_or: [ B22 ] + hdr_len_adj: 27 + meta_opt: 8191 + states: + $entry_point: + *: + 56..59: W16 # buffer mapped I/O: bit[448..479] -> W16 bit[31..0]: egress::eg_intr_md_from_prsr.global_tstamp[31:0].0-31 + 54..55: TH33 # buffer mapped I/O: bit[432..447] -> TH33 bit[15..0]: egress::eg_intr_md_from_prsr.global_tstamp[47:32].32-47 + intr_md: 48 + load: { byte1 : 27 } + buf_req: 28 + next: start + start: + match: [ byte1 ] + 0x02: + 0..1: H24 # bit[7..15] -> H24 bit[8..0]: egress::eg_intr_md.egress_port + 25..26: H16 # egress::eg_intr_md.pkt_length + intr_md: 25 + shift: 27 + buf_req: 27 + next: parse_mirror + 0x01: + 0..1: H24 # bit[7..15] -> H24 bit[8..0]: egress::eg_intr_md.egress_port + 25..26: H16 # egress::eg_intr_md.pkt_length + intr_md: 25 + shift: 27 + buf_req: 27 + next: parse_bridge + 0x03: + 0..1: H24 # bit[7..15] -> H24 bit[8..0]: egress::eg_intr_md.egress_port + 25..26: H16 # egress::eg_intr_md.pkt_length + intr_md: 25 + shift: 27 + buf_req: 27 + next: parse_capture + 0x05: + 0..1: H24 # bit[7..15] -> H24 bit[8..0]: egress::eg_intr_md.egress_port + 25..26: H16 # egress::eg_intr_md.pkt_length + intr_md: 25 + shift: 27 + buf_req: 27 + next: parse_capture_final + 0x**: + 0..1: H24 # bit[7..15] -> H24 bit[8..0]: egress::eg_intr_md.egress_port + 25..26: H16 # egress::eg_intr_md.pkt_length + intr_md: 25 + shift: 27 + buf_req: 27 + next: end + parse_mirror: + *: + 0: B23 # egress::meta.ing_port_mirror.pkt_type + 1..4: W17 # egress::meta.ing_port_mirror.mac_timestamp + 5..6: TH32 # egress::hdr.ethernet.dst_addr[47:32].32-47 + 7..10: TW16 # egress::hdr.ethernet.dst_addr[31:0].0-31 + 11..12: TH31 # egress::hdr.ethernet.src_addr[47:32].32-47 + 13: TB7 # egress::hdr.ethernet.src_addr[31:24].24-31 + 14: TB6 # egress::hdr.ethernet.src_addr[23:16].16-23 + 15..16: TH11 # egress::hdr.ethernet.src_addr[15:0].0-15 + 17..18: TH30 # egress::hdr.ethernet.ether_type + B22: 1 # value 1 -> B22 bit[0]: egress::hdr.ethernet.$valid + load: { half : 17..18 } + shift: 19 + buf_req: 19 + next: parse_mirror.$split_0 + parse_mirror.$split_0: + match: [ half ] + 0x8100: + B17: 1 # value 1 -> B17 bit[7..0]: egress::meta.pkt_type + load: { half : 2..3 } + buf_req: 4 + next: parse_vlan_tag + 0x0800: + B17: 1 # value 1 -> B17 bit[7..0]: egress::meta.pkt_type + buf_req: 0 + next: parse_ipv4 + 0x****: + B17: 1 # value 1 -> B17 bit[7..0]: egress::meta.pkt_type + buf_req: 0 + next: end + parse_vlan_tag: + match: [ half ] + 0x0800: + 0: TB4 + # - bit[0..2] -> TB4 bit[7..5]: egress::hdr.vlan_tag.pcp + # - bit[3] -> TB4 bit[4]: egress::hdr.vlan_tag.cfi + # - bit[4..7] -> TB4 bit[3..0]: egress::hdr.vlan_tag.vid[11:8].8-11 + 1: TB5 # egress::hdr.vlan_tag.vid[7:0].0-7 + 2..3: TH6 # egress::hdr.vlan_tag.ether_type + B22: 2 # value 1 -> B22 bit[1]: egress::hdr.vlan_tag.$valid + shift: 4 + buf_req: 4 + next: parse_ipv4 + 0x****: + 0: TB4 + # - bit[0..2] -> TB4 bit[7..5]: egress::hdr.vlan_tag.pcp + # - bit[3] -> TB4 bit[4]: egress::hdr.vlan_tag.cfi + # - bit[4..7] -> TB4 bit[3..0]: egress::hdr.vlan_tag.vid[11:8].8-11 + 1: TB5 # egress::hdr.vlan_tag.vid[7:0].0-7 + 2..3: TH6 # egress::hdr.vlan_tag.ether_type + B22: 2 # value 1 -> B22 bit[1]: egress::hdr.vlan_tag.$valid + shift: 4 + buf_req: 4 + next: end + parse_ipv4: + *: + 0..3: TW4 + # - bit[0..3] -> TW4 bit[31..28]: egress::hdr.ipv4.version + # - bit[4..7] -> TW4 bit[27..24]: egress::hdr.ipv4.ihl + # - bit[8..15] -> TW4 bit[23..16]: egress::hdr.ipv4.diffserv + # - bit[16..31] -> TW4 bit[15..0]: egress::hdr.ipv4.total_len + 4..7: TW7 + # - bit[32..47] -> TW7 bit[31..16]: egress::hdr.ipv4.identification + # - bit[48..50] -> TW7 bit[15..13]: egress::hdr.ipv4.flags + # - bit[51..63] -> TW7 bit[12..0]: egress::hdr.ipv4.frag_offset + 8..11: TW6 + # - bit[64..71] -> TW6 bit[31..24]: egress::hdr.ipv4.ttl + # - bit[72..79] -> TW6 bit[23..16]: egress::hdr.ipv4.protocol + # - bit[80..95] -> TW6 bit[15..0]: egress::hdr.ipv4.hdr_checksum + 12..15: TW18 # egress::hdr.ipv4.src_addr + B22: 4 # value 1 -> B22 bit[2]: egress::hdr.ipv4.$valid + load: { byte1 : 9 } + shift: 16 + buf_req: 16 + next: parse_ipv4.$split_0 + parse_ipv4.$split_0: + match: [ byte1 ] + 0x06: + 0..3: TW17 # egress::hdr.ipv4.dst_addr + shift: 4 + buf_req: 4 + next: parseTcp + 0x11: + 0..3: TW17 # egress::hdr.ipv4.dst_addr + shift: 4 + buf_req: 4 + next: parseUdp + 0x**: + 0..3: TW17 # egress::hdr.ipv4.dst_addr + shift: 4 + buf_req: 4 + next: parseL23 + parseTcp: + *: + 0..1: TH10 # egress::hdr.tcp.src_port + 2..3: TH9 # egress::hdr.tcp.dst_port + 4..5: TH25 # egress::hdr.tcp.seq_no[31:16].16-31 + 6..7: TH24 # egress::hdr.tcp.seq_no[15:0].0-15 + 8..11: TW19 # egress::hdr.tcp.ack_no + 12..15: TW5 + # - bit[96..99] -> TW5 bit[31..28]: egress::hdr.tcp.data_offset + # - bit[100..103] -> TW5 bit[27..24]: egress::hdr.tcp.res + # - bit[104..111] -> TW5 bit[23..16]: egress::hdr.tcp.flags + # - bit[112..127] -> TW5 bit[15..0]: egress::hdr.tcp.window + 20..23: TW22 # egress::hdr.first_payload.signature_top + 24..27: TW21 # egress::hdr.first_payload.signature_bot + B22: 24 + # - value 1 -> B22 bit[3]: egress::hdr.tcp.$valid + # - value 1 -> B22 bit[4]: egress::hdr.first_payload.$valid + shift: 16 + buf_req: 28 + next: parseTcp.$split_0 + parseTcp.$split_0: + *: + 0..1: TH8 # egress::hdr.tcp.checksum + 2..3: TH7 # egress::hdr.tcp.urgent_ptr + 12..15: TW20 # egress::hdr.first_payload.rx_timestamp + 16: TB19 # egress::hdr.first_payload.pgid[31:24].24-31 + 17: TB18 # egress::hdr.first_payload.pgid[23:16].16-23 + 18: TB17 # egress::hdr.first_payload.pgid[15:8].8-15 + 19: TB16 # egress::hdr.first_payload.pgid[7:0].0-7 + 20..21: TH29 # egress::hdr.first_payload.sequence[31:16].16-31 + 22..23: TH28 # egress::hdr.first_payload.sequence[15:0].0-15 + shift: 24 + buf_req: 24 + next: parseTcp.$split_1 + parseTcp.$split_1: + *: + 0..1: TH27 # egress::hdr.first_payload.txtstamp[31:16].16-31 + 2..3: TH26 # egress::hdr.first_payload.txtstamp[15:0].0-15 + shift: 4 + buf_req: 4 + next: end + parseUdp: + *: + 0..1: TH8 # egress::hdr.udp.src_port + 2..3: TH7 # egress::hdr.udp.dst_port + 4..7: TW5 + # - bit[32..47] -> TW5 bit[31..16]: egress::hdr.udp.hdr_length + # - bit[48..63] -> TW5 bit[15..0]: egress::hdr.udp.checksum + 8..11: TW22 # egress::hdr.first_payload.signature_top + 12..15: TW21 # egress::hdr.first_payload.signature_bot + 16..19: TW20 # egress::hdr.first_payload.rx_timestamp + 20: TB19 # egress::hdr.first_payload.pgid[31:24].24-31 + 21: TB18 # egress::hdr.first_payload.pgid[23:16].16-23 + 22: TB17 # egress::hdr.first_payload.pgid[15:8].8-15 + 23: TB16 # egress::hdr.first_payload.pgid[7:0].0-7 + 24..25: TH29 # egress::hdr.first_payload.sequence[31:16].16-31 + 26..27: TH28 # egress::hdr.first_payload.sequence[15:0].0-15 + shift: 28 + buf_req: 28 + next: parseUdp.$split_0 + parseUdp.$split_0: + *: + 0..1: TH27 # egress::hdr.first_payload.txtstamp[31:16].16-31 + 2..3: TH26 # egress::hdr.first_payload.txtstamp[15:0].0-15 + B22: 48 + # - value 1 -> B22 bit[5]: egress::hdr.udp.$valid + # - value 1 -> B22 bit[4]: egress::hdr.first_payload.$valid + shift: 4 + buf_req: 4 + next: end + parseL23: + *: + 0..3: TW22 # egress::hdr.first_payload.signature_top + 4..7: TW21 # egress::hdr.first_payload.signature_bot + 8..11: TW20 # egress::hdr.first_payload.rx_timestamp + 12: TB19 # egress::hdr.first_payload.pgid[31:24].24-31 + 13: TB18 # egress::hdr.first_payload.pgid[23:16].16-23 + 14: TB17 # egress::hdr.first_payload.pgid[15:8].8-15 + 15: TB16 # egress::hdr.first_payload.pgid[7:0].0-7 + 16..17: TH29 # egress::hdr.first_payload.sequence[31:16].16-31 + 18..19: TH28 # egress::hdr.first_payload.sequence[15:0].0-15 + 20..21: TH27 # egress::hdr.first_payload.txtstamp[31:16].16-31 + 22..23: TH26 # egress::hdr.first_payload.txtstamp[15:0].0-15 + shift: 24 + buf_req: 24 + next: parseL23.$split_0 + parseL23.$split_0: + *: + B22: 16 # value 1 -> B22 bit[4]: egress::hdr.first_payload.$valid + buf_req: 0 + next: end + parse_bridge: + *: + 3..4: TH32 # egress::hdr.ethernet.dst_addr[47:32].32-47 + 5..8: TW16 # egress::hdr.ethernet.dst_addr[31:0].0-31 + 9..10: TH31 # egress::hdr.ethernet.src_addr[47:32].32-47 + 11: TB7 # egress::hdr.ethernet.src_addr[31:24].24-31 + 12: TB6 # egress::hdr.ethernet.src_addr[23:16].16-23 + 13..14: TH11 # egress::hdr.ethernet.src_addr[15:0].0-15 + 15..16: TH30 # egress::hdr.ethernet.ether_type + B23: 1 # value 1 -> B23 bit[7..0]: egress::meta.ing_port_mirror.pkt_type + B17: 1 # value 1 -> B17 bit[7..0]: egress::meta.pkt_type + load: { half : 15..16 } + shift: 17 + buf_req: 17 + next: parse_bridge.$split_0 + parse_bridge.$split_0: + match: [ half ] + 0x8100: + B22: 1 # value 1 -> B22 bit[0]: egress::hdr.ethernet.$valid + load: { half : 2..3 } + buf_req: 4 + next: parse_vlan_tag + 0x0800: + B22: 1 # value 1 -> B22 bit[0]: egress::hdr.ethernet.$valid + buf_req: 0 + next: parse_ipv4 + 0x****: + B22: 1 # value 1 -> B22 bit[0]: egress::hdr.ethernet.$valid + buf_req: 0 + next: end + parse_capture: + *: + 0: B23 # egress::meta.ing_port_mirror.pkt_type + 1..4: W17 # egress::meta.ing_port_mirror.mac_timestamp + B22: 64 # value 1 -> B22 bit[6]: egress::hdr.capture.$valid + B17: 3 # value 3 -> B17 bit[7..0]: egress::meta.pkt_type + shift: 5 + buf_req: 5 + next: end + parse_capture_final: + *: + 3: TB4 # egress::hdr.capture.seq_no[23:16].16-23 + 4..5: TH6 # egress::hdr.capture.seq_no[15:0].0-15 + 6: B18 # egress::hdr.capture.reserved + 7..10: W18 # egress::hdr.capture.timestamp + B22: 64 # value 1 -> B22 bit[6]: egress::hdr.capture.$valid + B17: 5 # value 5 -> B17 bit[7..0]: egress::meta.pkt_type + shift: 11 + buf_req: 11 + next: end +deparser egress: + dictionary: + TB4: B22(6) # egress::hdr.capture.seq_no.16-23 if egress::hdr.capture.$valid + TH6: B22(6) # egress::hdr.capture.seq_no.0-15 if egress::hdr.capture.$valid + B18: B22(6) # egress::hdr.capture.reserved if egress::hdr.capture.$valid + W18: B22(6) # egress::hdr.capture.timestamp if egress::hdr.capture.$valid + TH32: B22(0) # egress::hdr.ethernet.dst_addr.32-47 if egress::hdr.ethernet.$valid + TW16: B22(0) # egress::hdr.ethernet.dst_addr.0-31 if egress::hdr.ethernet.$valid + TH31: B22(0) # egress::hdr.ethernet.src_addr.32-47 if egress::hdr.ethernet.$valid + TB7: B22(0) # egress::hdr.ethernet.src_addr.24-31 if egress::hdr.ethernet.$valid + TB6: B22(0) # egress::hdr.ethernet.src_addr.16-23 if egress::hdr.ethernet.$valid + TH11: B22(0) # egress::hdr.ethernet.src_addr.0-15 if egress::hdr.ethernet.$valid + TH30: B22(0) # egress::hdr.ethernet.ether_type if egress::hdr.ethernet.$valid + TB4: B22(1) + # - bit[7..5]: egress::hdr.vlan_tag.pcp if egress::hdr.vlan_tag.$valid + # - bit[4]: egress::hdr.vlan_tag.cfi if egress::hdr.vlan_tag.$valid + # - bit[3..0]: egress::hdr.vlan_tag.vid.8-11 if egress::hdr.vlan_tag.$valid + TB5: B22(1) # egress::hdr.vlan_tag.vid.0-7 if egress::hdr.vlan_tag.$valid + TH6: B22(1) # egress::hdr.vlan_tag.ether_type if egress::hdr.vlan_tag.$valid + TW4: B22(2) + # - bit[31..28]: egress::hdr.ipv4.version if egress::hdr.ipv4.$valid + # - bit[27..24]: egress::hdr.ipv4.ihl if egress::hdr.ipv4.$valid + # - bit[23..16]: egress::hdr.ipv4.diffserv if egress::hdr.ipv4.$valid + # - bit[15..0]: egress::hdr.ipv4.total_len if egress::hdr.ipv4.$valid + TW7: B22(2) + # - bit[31..16]: egress::hdr.ipv4.identification if egress::hdr.ipv4.$valid + # - bit[15..13]: egress::hdr.ipv4.flags if egress::hdr.ipv4.$valid + # - bit[12..0]: egress::hdr.ipv4.frag_offset if egress::hdr.ipv4.$valid + TW6: B22(2) + # - bit[31..24]: egress::hdr.ipv4.ttl if egress::hdr.ipv4.$valid + # - bit[23..16]: egress::hdr.ipv4.protocol if egress::hdr.ipv4.$valid + # - bit[15..0]: egress::hdr.ipv4.hdr_checksum if egress::hdr.ipv4.$valid + TW18: B22(2) # egress::hdr.ipv4.src_addr if egress::hdr.ipv4.$valid + TW17: B22(2) # egress::hdr.ipv4.dst_addr if egress::hdr.ipv4.$valid + TH10: B22(3) # egress::hdr.tcp.src_port if egress::hdr.tcp.$valid + TH9: B22(3) # egress::hdr.tcp.dst_port if egress::hdr.tcp.$valid + TH25: B22(3) # egress::hdr.tcp.seq_no.16-31 if egress::hdr.tcp.$valid + TH24: B22(3) # egress::hdr.tcp.seq_no.0-15 if egress::hdr.tcp.$valid + TW19: B22(3) # egress::hdr.tcp.ack_no if egress::hdr.tcp.$valid + TW5: B22(3) + # - bit[31..28]: egress::hdr.tcp.data_offset if egress::hdr.tcp.$valid + # - bit[27..24]: egress::hdr.tcp.res if egress::hdr.tcp.$valid + # - bit[23..16]: egress::hdr.tcp.flags if egress::hdr.tcp.$valid + # - bit[15..0]: egress::hdr.tcp.window if egress::hdr.tcp.$valid + TH8: B22(3) # egress::hdr.tcp.checksum if egress::hdr.tcp.$valid + TH7: B22(3) # egress::hdr.tcp.urgent_ptr if egress::hdr.tcp.$valid + TH8: B22(5) # egress::hdr.udp.src_port if egress::hdr.udp.$valid + TH7: B22(5) # egress::hdr.udp.dst_port if egress::hdr.udp.$valid + TW5: B22(5) + # - bit[31..16]: egress::hdr.udp.hdr_length if egress::hdr.udp.$valid + # - bit[15..0]: egress::hdr.udp.checksum if egress::hdr.udp.$valid + TW22: B22(4) # egress::hdr.first_payload.signature_top if egress::hdr.first_payload.$valid + TW21: B22(4) # egress::hdr.first_payload.signature_bot if egress::hdr.first_payload.$valid + TW20: B22(4) # egress::hdr.first_payload.rx_timestamp if egress::hdr.first_payload.$valid + TB19: B22(4) # egress::hdr.first_payload.pgid.24-31 if egress::hdr.first_payload.$valid + TB18: B22(4) # egress::hdr.first_payload.pgid.16-23 if egress::hdr.first_payload.$valid + TB17: B22(4) # egress::hdr.first_payload.pgid.8-15 if egress::hdr.first_payload.$valid + TB16: B22(4) # egress::hdr.first_payload.pgid.0-7 if egress::hdr.first_payload.$valid + TH29: B22(4) # egress::hdr.first_payload.sequence.16-31 if egress::hdr.first_payload.$valid + TH28: B22(4) # egress::hdr.first_payload.sequence.0-15 if egress::hdr.first_payload.$valid + TH27: B22(4) # egress::hdr.first_payload.txtstamp.16-31 if egress::hdr.first_payload.$valid + TH26: B22(4) # egress::hdr.first_payload.txtstamp.0-15 if egress::hdr.first_payload.$valid + egress_unicast_port: H24(0..8) # bit[8..0]: egress::eg_intr_md.egress_port + mirror: + select: B16(0..2) # bit[2..0]: egress::eg_intr_md_for_dprsr.mirror_type + 2: + - H16(0..9) # bit[9..0]: egress::meta.mirror_session + - B17 # egress::meta.pkt_type + - W17 # egress::meta.ing_port_mirror.mac_timestamp +stage 0 ingress: + phase0_match IngressParser.$PORT_METADATA: + p4: + name: IngressParser.$PORT_METADATA + size: 288 + preferred_match_type: exact + match_type: exact + size: 288 + p4_param_order: + ig_intr_md.ingress_port: { type: exact, size: 9 } + format: {port_signature: 32..63, port_type: 24..27, capture_port: 16..23} + constant_value: 0 + actions: + set_port_metadata: + - handle: 0x20000000 + - p4_param_order: { port_signature: 32, port_type: 4, capture_port: 8 } + exact_match setEgPortTbl_0 1: + p4: { name: Ingress.setEgPortTbl, size: 8 } + p4_param_order: + ig_intr_md.ingress_port: { type: exact, size: 9, full_size: 9 } + row: 7 + bus: 0 + column: 2 + stash: + row: [ 7 ] + col: [ 2 ] + unit: [ 0 ] + ways: + - [0, 0, 0x0, [7, 2]] + input_xbar: + exact group 0: { 16: ig_intr_md.ingress_port } + hash 0: + 0..7: ig_intr_md.ingress_port(0..7) + 8: ig_intr_md.ingress_port(8) + hash group 0: + table: [0] + seed: 0x0 + format: { action(0): 0..1, immediate(0): 2..10, version(0): 112..115 } + match_group_map: [ [ 0 ] ] + gateway: + name: cond-9 + input_xbar: + exact group 0: { 9: hdr.capture.$valid } + row: 0 + bus: 0 + unit: 0 + match: { 1: hdr.capture.$valid } + 0b******1: tbl_p4c2719l881 + miss: run_table + condition: + expression: "(hdr.capture.$valid == 1)" + true: tbl_p4c2719l881 + false: setEgPortTbl_0 + hit: [ ingressMirrorTbl_0 ] + miss: ingressMirrorTbl_0 + action_bus: { 32..33 : immediate(0..8) } + instruction: setEgPortTbl_0(action, $DEFAULT) + actions: + Ingress.setEgPort(1, 1): + - p4_param_order: { egress_port: 9 } + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000008 + - next_table: 0 + - { egress_port_2: immediate(0..8), egress_port: egress_port_2 } + - set ig_intr_md_for_tm.ucast_egress_port, egress_port + NoAction(2, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000009 + - next_table: 0 + - { } + default_action: NoAction + ternary_match tbl_p4c2719l881 2: + p4: { name: tbl_p4c2719l881, hidden: true } + gateway: + name: cond-10 + input_xbar: + exact group 0: { 32: meta.pkt_type } + row: 7 + bus: 0 + unit: 0 + match: { 0: meta.pkt_type } + 0x03: run_table + miss: tbl_p4c2719l886 + condition: + expression: "(meta.pkt_type == 3)" + true: tbl_p4c2719l881 + false: tbl_p4c2719l886 + hit: [ tbl_lookupCapturePort ] + miss: tbl_lookupCapturePort + indirect: tbl_p4c2719l881$tind + stateful tbl_p4c2719l881$salu.Ingress.sequence_no: + p4: { name: Ingress.sequence_no, size: 1 } + row: 15 + logical_bus: S + column: [ 0, 1 ] + maprams: [ 0, 1 ] + home_row: 15 + format: { lo: 16 } + actions: + update_seq_no_0: + - equ lo, lo, -2047 + - alu_a cmplo, lo, 0 + - add !cmplo, lo, lo, 1 + - output mem_lo + ternary_indirect tbl_p4c2719l881$tind: + row: 0 + bus: 1 + format: { action: 0..0, meter_addr: 1..10, meter_pfe: 11..11, meter_type: 12..14 } + action_bus: { 36..37 : tbl_p4c2719l881$salu.Ingress.sequence_no(0..15) } + stateful: tbl_p4c2719l881$salu.Ingress.sequence_no(meter_addr, meter_pfe, meter_type) + instruction: tbl_p4c2719l881$tind(action, $DEFAULT) + actions: + p4c2719l881(1, 2): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000002 + - next_table: 0 + - set seq_no_0, tbl_p4c2719l881$salu.Ingress.sequence_no + - tbl_p4c2719l881$salu.Ingress.sequence_no(update_seq_no_0, 0) + default_action: p4c2719l881 + ternary_match tbl_p4c2719l886 4: + p4: { name: tbl_p4c2719l886, hidden: true } + hit: [ ingressMirrorTbl_0 ] + miss: ingressMirrorTbl_0 + indirect: tbl_p4c2719l886$tind + ternary_indirect tbl_p4c2719l886$tind: + row: 1 + bus: 1 + format: { action: 0..0 } + instruction: tbl_p4c2719l886$tind(action, $DEFAULT) + actions: + p4c2719l886(0, 4): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000007 + - next_table: 0 + - set ig_intr_md_for_dprsr.drop_ctl, 1 + default_action: p4c2719l886 + ternary_match tbl_lookupCapturePort 3: + p4: { name: tbl_lookupCapturePort, hidden: true } + hit: [ setCaptureTbl_0 ] + miss: setCaptureTbl_0 + indirect: tbl_lookupCapturePort$tind + ternary_indirect tbl_lookupCapturePort$tind: + row: 0 + bus: 0 + format: { action: 0..0 } + instruction: tbl_lookupCapturePort$tind(action, $DEFAULT) + actions: + Ingress.lookupCapturePort(0, 3): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000001 + - next_table: 0 + - set capture_port_1, hdr.capture.reserved + default_action: Ingress.lookupCapturePort +stage 1 ingress: + dependency: match + ternary_match setCaptureTbl_0 1: + p4: { name: Ingress.setCaptureTbl, size: 8 } + p4_param_order: + capture_port_1: { type: ternary, size: 8, full_size: 8, key_name: "capture_port" } + row: 0 + bus: 0 + column: 0 + input_xbar: + ternary group 0: { 0: capture_port_1 } + match: + - { group: 0, byte_config: 3, dirtcam: 0x1 } + hit: [ insertOverheadTbl_0 ] + miss: insertOverheadTbl_0 + indirect: setCaptureTbl_0$tind + ternary_indirect setCaptureTbl_0$tind: + row: 0 + bus: 0 + column: 2 + input_xbar: + ternary group 0: { 0: capture_port_1 } + format: { action: 0..0, immediate: 1..9 } + action_bus: { 32..33 : immediate(0..8) } + instruction: setCaptureTbl_0$tind(action, $DEFAULT) + actions: + Ingress.setCaptureEgPort(0, 1): + - p4_param_order: { egress_port: 9 } + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000005 + - next_table: 0 + - { egress_port_3: immediate(0..8), egress_port: egress_port_3 } + - set ig_intr_md_for_tm.ucast_egress_port, egress_port + NoAction(1, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000006 + - next_table: 0 + - { } + default_action: NoAction + exact_match insertOverheadTbl_0 2: + p4: { name: Ingress.insertOverheadTbl, size: 2048 } + p4_param_order: + seq_no_0: { type: exact, size: 16, full_size: 16, key_name: "seq_no" } + row: 7 + bus: 0 + column: [ 2, 3, 4, 6 ] + stash: + row: [ 7 ] + col: [ 2 ] + unit: [ 0 ] + ways: + - [1, 0, 0x0, [7, 2]] + - [1, 1, 0x0, [7, 3]] + - [1, 2, 0x0, [7, 4]] + - [1, 3, 0x0, [7, 6]] + input_xbar: + exact group 0: { 64: seq_no_0 } + hash 1: + 0..7: random(seq_no_0(10..15)) ^ seq_no_0(0..7) + 8..9: random(seq_no_0(10..15)) ^ seq_no_0(8..9) + 11..18: random(seq_no_0(10..15)) ^ seq_no_0(0..7) + 19: random(seq_no_0(10..15)) ^ seq_no_0(8) + 10: random(seq_no_0(10..15)) ^ seq_no_0(9) + 22..29: random(seq_no_0(10..15)) ^ seq_no_0(0..7) + 20..21: random(seq_no_0(10..15)) ^ seq_no_0(8..9) + 33..39: random(seq_no_0(10..15)) ^ seq_no_0(0..6) + 30: random(seq_no_0(10..15)) ^ seq_no_0(7) + 31..32: random(seq_no_0(10..15)) ^ seq_no_0(8..9) + hash group 1: + table: [1] + seed: 0xc92687df45 + format: { immediate(0): 0..23, version(0): 112..115, match(0): 34..39 } + match: [ seq_no_0(10..15) ] + match_group_map: [ [ 0 ] ] + hit: [ ingressMirrorTbl_0 ] + miss: ingressMirrorTbl_0 + action_bus: { 96..99 : immediate(0..23) } + instruction: insertOverheadTbl_0($DEFAULT, $DEFAULT) + actions: + Ingress.insert_seq_no(0, 2): + - p4_param_order: { calculated_ov: 24 } + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000003 + - next_table: 0 + - { calculated_ov: immediate(0..23) } + - set hdr.capture.seq_no, calculated_ov + NoAction(-1, 0): + - hit_allowed: { allowed: false, reason: user_indicated_default_only } + - default_only_action: { allowed: true } + - handle: 0x20000004 + - next_table: 0 + - { } + default_only_action: NoAction + exact_match ingressMirrorTbl_0 3: + p4: { name: Ingress.ingressMirrorTbl, size: 1 } + p4_param_order: + ig_intr_md.ingress_port: { type: exact, size: 9, full_size: 9 } + row: 6 + bus: 0 + column: 2 + stash: + row: [ 6 ] + col: [ 2 ] + unit: [ 0 ] + ways: + - [0, 1, 0x0, [6, 2]] + hash_dist: + 0: { hash: 2, mask: 0xffff, shift: 0 } + 1: { hash: 2, mask: 0xffff, shift: 0 } + input_xbar: + exact group 0: { 16: ig_intr_md.ingress_port } + hash 0: + 10..17: ig_intr_md.ingress_port(0..7) + 18: ig_intr_md.ingress_port(8) + hash group 0: + table: [0] + seed: 0x0 + exact group 1: { 0: ig_intr_md.ingress_mac_tstamp.0-31(0..7), 8: ig_intr_md.ingress_mac_tstamp.40-47, 16: ig_intr_md.ingress_mac_tstamp.0-31(16..31), 32: ig_intr_md.ingress_mac_tstamp.32-39, 40: ig_intr_md.ingress_mac_tstamp.0-31(8..15) } + hash 2: + 0..7: ig_intr_md.ingress_mac_tstamp.0-31(0..7) + 8..15: ig_intr_md.ingress_mac_tstamp.0-31(8..15) + hash group 2: + table: [2] + seed: 0x0 + exact group 1: { 0: ig_intr_md.ingress_mac_tstamp.0-31(0..7), 8: ig_intr_md.ingress_mac_tstamp.40-47, 16: ig_intr_md.ingress_mac_tstamp.0-31(16..31), 32: ig_intr_md.ingress_mac_tstamp.32-39, 40: ig_intr_md.ingress_mac_tstamp.0-31(8..15) } + hash 2: + 16..31: ig_intr_md.ingress_mac_tstamp.0-31(16..31) + hash group 2: + table: [2] + seed: 0x0 + format: { action(0): 0..0, version(0): 112..115 } + match_group_map: [ [ 0 ] ] + hit: [ END ] + miss: END + action_bus: { 100..103 : hash_dist(0, 1) } + action: ingressMirrorTbl_0$action_data($DIRECT, $DEFAULT) + instruction: ingressMirrorTbl_0(action, $DEFAULT) + actions: + Ingress.set_mirror_session_capture(0, 3): + - p4_param_order: { mirror_session: 10 } + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x2000000a + - next_table: 0 + - { mirror_session_2: $adf_h0(0..9), mirror_session: mirror_session_2 } + - set ig_intr_md_for_dprsr.mirror_type, 1 + - set ig_intr_md_for_tm.mcast_grp_a, 0 + - set meta.mirror_session, mirror_session + - set meta.pkt_type, 3 + - set W2, hash_dist(0, 1, 0..31) + NoAction(1, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x2000000b + - next_table: 0 + - { } + default_action: NoAction + action ingressMirrorTbl_0$action_data: + p4: { name: Ingress.ingressMirrorTbl$action } + row: 14 + logical_bus: A + column: 5 + vpns: [ 0 ] + home_row: + - 14 + format Ingress.set_mirror_session_capture: { $adf_h0: 0..15 } + action_bus: { 36..37 : $adf_h0 } +stage 0 egress: + ternary_match tbl_update_register_partial_length 0: + p4: { name: tbl_update_register_partial_length, hidden: true } + gateway: + name: cond-11 + input_xbar: + exact group 0: { 6: hdr.capture.$valid } + row: 0 + bus: 1 + unit: 1 + match: { 6: hdr.capture.$valid } + 0b*1: run_table + miss: tbl_insert_capture + condition: + expression: "(hdr.capture.$valid == 1)" + true: tbl_update_register_partial_length + false: tbl_insert_capture + hit: [ update_register_captureLookupTbl ] + miss: update_register_captureLookupTbl + indirect: tbl_update_register_partial_length$tind + ternary_indirect tbl_update_register_partial_length$tind: + row: 1 + bus: 0 + format: { action: 0..0 } + instruction: tbl_update_register_partial_length$tind(action, $DEFAULT) + actions: + Egress.update_register.partial_length(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x2000000c + - next_table: 0 + - shru update_register_portion, eg_intr_md.pkt_length, 2 + default_action: Egress.update_register.partial_length +stage 1 egress: + dependency: action + exact_match update_register_captureLookupTbl 0: + p4: { name: Egress.update_register.captureLookupTbl, size: 32 } + p4_param_order: + eg_intr_md.egress_port: { type: exact, size: 9, full_size: 9, key_name: "inport" } + row: 7 + bus: 1 + column: 7 + stash: + row: [ 7 ] + col: [ 7 ] + unit: [ 1 ] + ways: + - [0, 0, 0x0, [7, 7]] + input_xbar: + exact group 0: { 0: eg_intr_md.egress_port } + hash 0: + 0..7: eg_intr_md.egress_port(0..7) + 8: eg_intr_md.egress_port(8) + hash group 0: + table: [0] + seed: 0x0 + format: { action(0): 0..0, version(0): 112..115, counter_addr(0): 1..10, counter_pfe(0): 11..11, meter_addr(0): 12..21, meter_pfe(0): 22..22 } + match_group_map: [ [ 0 ] ] + hit: [ tbl_update_register_negate_pad ] + miss: tbl_update_register_negate_pad + action_bus: { 0 : update_register_captureLookupTbl$salu.Egress.update_register.random_assign(0..7) } + stats: update_register_captureLookupTbl$stats.Egress.update_register.debug_stats(counter_addr, counter_pfe) + stateful: update_register_captureLookupTbl$salu.Egress.update_register.random_assign(meter_addr, meter_pfe, $DEFAULT) + instruction: update_register_captureLookupTbl(action, $DEFAULT) + actions: + Egress.update_register.lookupIndex(0, 1): + - p4_param_order: { port: 8 } + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x2000000d + - next_table: 0 + - { port: counter_addr } + - set update_register_capture_port, hdr.capture.reserved + - add update_register_padded_length, eg_intr_md.pkt_length, update_register_portion + - update_register_captureLookupTbl$stats.Egress.update_register.debug_stats(port) + Egress.update_register.lookupCapturePort(1, 2): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x2000000e + - next_table: 0 + - set update_register_capture_port, update_register_captureLookupTbl$salu.Egress.update_register.random_assign + - set update_register_padded_length, update_register_portion + - update_register_captureLookupTbl$salu.Egress.update_register.random_assign(update_register_random_assign_reg, 0) + default_action: Egress.update_register.lookupCapturePort + counter update_register_captureLookupTbl$stats.Egress.update_register.debug_stats: + p4: { name: Egress.update_register.debug_stats, size: 8 } + row: 13 + logical_bus: S + column: [ 0, 1 ] + maprams: [ 0, 1 ] + vpns: [ 0, 1 ] + home_row: 13 + count: packets + format: {packets(0): 64..127, packets(1): 0..63} + per_flow_enable: counter_pfe + stateful update_register_captureLookupTbl$salu.Egress.update_register.random_assign: + p4: { name: Egress.update_register.random_assign, size: 1 } + row: 15 + logical_bus: S + column: [ 2, 3 ] + maprams: [ 2, 3 ] + home_row: 15 + format: { lo: 8 } + actions: + update_register_random_assign_reg: + - equ lo, lo, -4 + - alu_a cmplo, lo, 0 + - add !cmplo, lo, lo, 1 + - output mem_lo +stage 2 egress: + dependency: action + ternary_match tbl_update_register_negate_pad 0: + p4: { name: tbl_update_register_negate_pad, hidden: true } + hit: [ update_register_LengthLookupTbl ] + miss: update_register_LengthLookupTbl + indirect: tbl_update_register_negate_pad$tind + ternary_indirect tbl_update_register_negate_pad$tind: + row: 0 + bus: 0 + format: { action: 0..0 } + instruction: tbl_update_register_negate_pad$tind(action, $DEFAULT) + actions: + Egress.update_register.negate_pad(0, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x2000000f + - next_table: 0 + - not update_register_negated_length, update_register_padded_length + - shl update_register_load_length, update_register_padded_length, 2 + default_action: Egress.update_register.negate_pad +stage 3 egress: + dependency: match + ternary_match update_register_LengthLookupTbl 0: + p4: { name: Egress.update_register.LengthLookupTbl, size: 32 } + p4_param_order: + meta.pkt_type: { type: exact, size: 8, full_size: 8, key_name: "pkt_type" } + update_register_capture_port: { type: ternary, size: 8, full_size: 8, key_name: "capture_port" } + row: 0 + bus: 0 + column: 0 + input_xbar: + ternary group 0: { 0: meta.pkt_type, 8: update_register_capture_port } + match: + - { group: 0, byte_config: 3, dirtcam: 0x5 } + hit: [ tbl_p4c2719l720 ] + miss: tbl_p4c2719l720 + context_json: + static_entries: + - priority: 0 + match_key_fields_values: + - field_name: pkt_type + value: "0x3" + - field_name: capture_port + value: "0x0" + mask: "0x7" + action_handle: 0x20000010 + is_default_entry: false + action_parameters_values: [] + - priority: 1 + match_key_fields_values: + - field_name: pkt_type + value: "0x3" + - field_name: capture_port + value: "0x1" + mask: "0x7" + action_handle: 0x20000011 + is_default_entry: false + action_parameters_values: [] + - priority: 2 + match_key_fields_values: + - field_name: pkt_type + value: "0x3" + - field_name: capture_port + value: "0x2" + mask: "0x7" + action_handle: 0x20000012 + is_default_entry: false + action_parameters_values: [] + - priority: 3 + match_key_fields_values: + - field_name: pkt_type + value: "0x3" + - field_name: capture_port + value: "0x3" + mask: "0x7" + action_handle: 0x20000013 + is_default_entry: false + action_parameters_values: [] + - priority: 4 + match_key_fields_values: + - field_name: pkt_type + value: "0x3" + - field_name: capture_port + value: "0x4" + mask: "0x7" + action_handle: 0x20000014 + is_default_entry: false + action_parameters_values: [] + - priority: 5 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x4" + mask: "0xFF" + action_handle: 0x20000018 + is_default_entry: false + action_parameters_values: [] + - priority: 6 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x3" + mask: "0xFF" + action_handle: 0x20000017 + is_default_entry: false + action_parameters_values: [] + - priority: 7 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x2" + mask: "0xFF" + action_handle: 0x20000016 + is_default_entry: false + action_parameters_values: [] + - priority: 8 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x1" + mask: "0xFF" + action_handle: 0x20000015 + is_default_entry: false + action_parameters_values: [] + - priority: 9 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x14" + mask: "0xFF" + action_handle: 0x2000001c + is_default_entry: false + action_parameters_values: [] + - priority: 10 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x13" + mask: "0xFF" + action_handle: 0x2000001b + is_default_entry: false + action_parameters_values: [] + - priority: 11 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x12" + mask: "0xFF" + action_handle: 0x2000001a + is_default_entry: false + action_parameters_values: [] + - priority: 12 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x10" + mask: "0xFF" + action_handle: 0x20000019 + is_default_entry: false + action_parameters_values: [] + - priority: 13 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x24" + mask: "0xFF" + action_handle: 0x20000020 + is_default_entry: false + action_parameters_values: [] + - priority: 14 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x23" + mask: "0xFF" + action_handle: 0x2000001f + is_default_entry: false + action_parameters_values: [] + - priority: 15 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x21" + mask: "0xFF" + action_handle: 0x2000001e + is_default_entry: false + action_parameters_values: [] + - priority: 16 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x20" + mask: "0xFF" + action_handle: 0x2000001d + is_default_entry: false + action_parameters_values: [] + - priority: 17 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x34" + mask: "0xFF" + action_handle: 0x20000024 + is_default_entry: false + action_parameters_values: [] + - priority: 18 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x32" + mask: "0xFF" + action_handle: 0x20000023 + is_default_entry: false + action_parameters_values: [] + - priority: 19 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x31" + mask: "0xFF" + action_handle: 0x20000022 + is_default_entry: false + action_parameters_values: [] + - priority: 20 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x30" + mask: "0xFF" + action_handle: 0x20000021 + is_default_entry: false + action_parameters_values: [] + - priority: 21 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x43" + mask: "0xFF" + action_handle: 0x20000028 + is_default_entry: false + action_parameters_values: [] + - priority: 22 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x42" + mask: "0xFF" + action_handle: 0x20000027 + is_default_entry: false + action_parameters_values: [] + - priority: 23 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x41" + mask: "0xFF" + action_handle: 0x20000026 + is_default_entry: false + action_parameters_values: [] + - priority: 24 + match_key_fields_values: + - field_name: pkt_type + value: "0x5" + - field_name: capture_port + value: "0x40" + mask: "0xFF" + action_handle: 0x20000025 + is_default_entry: false + action_parameters_values: [] + indirect: update_register_LengthLookupTbl$tind + ternary_indirect update_register_LengthLookupTbl$tind: + row: 0 + bus: 0 + column: 2 + input_xbar: + ternary group 0: { 0: meta.pkt_type, 8: update_register_capture_port } + format: { action: 0..5 } + instruction: update_register_LengthLookupTbl$tind(action, $DEFAULT) + actions: + Egress.update_register.capture_port_1(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000010 + - next_table: 0 + - set update_register_cap_length, update_register_load_length + - add update_register_cap_length_0, update_register_negated_length, 1 + - add update_register_cap_length_1, update_register_negated_length, 1 + - add update_register_cap_length_2, update_register_negated_length, 1 + - add update_register_cap_length_3, update_register_negated_length, 1 + Egress.update_register.capture_port_2(2, 2): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000011 + - next_table: 0 + - set update_register_cap_length_0, update_register_load_length + - add update_register_cap_length, update_register_negated_length, 1 + - add update_register_cap_length_1, update_register_negated_length, 1 + - add update_register_cap_length_2, update_register_negated_length, 1 + - add update_register_cap_length_3, update_register_negated_length, 1 + Egress.update_register.capture_port_3(4, 4): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000012 + - next_table: 0 + - set update_register_cap_length_1, update_register_load_length + - add update_register_cap_length_0, update_register_negated_length, 1 + - add update_register_cap_length, update_register_negated_length, 1 + - add update_register_cap_length_2, update_register_negated_length, 1 + - add update_register_cap_length_3, update_register_negated_length, 1 + Egress.update_register.capture_port_4(6, 6): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000013 + - next_table: 0 + - set update_register_cap_length_2, update_register_load_length + - add update_register_cap_length_0, update_register_negated_length, 1 + - add update_register_cap_length_1, update_register_negated_length, 1 + - add update_register_cap_length, update_register_negated_length, 1 + - add update_register_cap_length_3, update_register_negated_length, 1 + Egress.update_register.capture_port_5(8, 8): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000014 + - next_table: 0 + - set update_register_cap_length_3, update_register_load_length + - add update_register_cap_length_0, update_register_negated_length, 1 + - add update_register_cap_length_1, update_register_negated_length, 1 + - add update_register_cap_length_2, update_register_negated_length, 1 + - add update_register_cap_length, update_register_negated_length, 1 + Egress.update_register.comp_port_1_2(10, 10): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000015 + - next_table: 0 + - add update_register_cap_length, update_register_negated_length, 1 + - set update_register_cap_length_0, update_register_padded_length + - set update_register_cap_length_1, 0 + - set update_register_cap_length_2, 0 + - set update_register_cap_length_3, 0 + Egress.update_register.comp_port_1_3(12, 12): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000016 + - next_table: 0 + - add update_register_cap_length, update_register_negated_length, 1 + - set update_register_cap_length_0, 0 + - set update_register_cap_length_1, update_register_padded_length + - set update_register_cap_length_2, 0 + - set update_register_cap_length_3, 0 + Egress.update_register.comp_port_1_4(14, 14): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000017 + - next_table: 0 + - add update_register_cap_length, update_register_negated_length, 1 + - set update_register_cap_length_0, 0 + - set update_register_cap_length_1, 0 + - set update_register_cap_length_2, update_register_padded_length + - set update_register_cap_length_3, 0 + Egress.update_register.comp_port_1_5(16, 16): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000018 + - next_table: 0 + - add update_register_cap_length, update_register_negated_length, 1 + - set update_register_cap_length_0, 0 + - set update_register_cap_length_1, 0 + - set update_register_cap_length_2, 0 + - set update_register_cap_length_3, update_register_padded_length + Egress.update_register.comp_port_2_1(18, 18): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000019 + - next_table: 0 + - set update_register_cap_length, update_register_padded_length + - add update_register_cap_length_0, update_register_negated_length, 1 + - set update_register_cap_length_1, 0 + - set update_register_cap_length_2, 0 + - set update_register_cap_length_3, 0 + Egress.update_register.comp_port_2_3(20, 20): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x2000001a + - next_table: 0 + - set update_register_cap_length, 0 + - add update_register_cap_length_0, update_register_negated_length, 1 + - set update_register_cap_length_1, update_register_padded_length + - set update_register_cap_length_2, 0 + - set update_register_cap_length_3, 0 + Egress.update_register.comp_port_2_4(22, 22): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x2000001b + - next_table: 0 + - set update_register_cap_length, 0 + - add update_register_cap_length_0, update_register_negated_length, 1 + - set update_register_cap_length_1, 0 + - set update_register_cap_length_2, update_register_padded_length + - set update_register_cap_length_3, 0 + Egress.update_register.comp_port_2_5(24, 24): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x2000001c + - next_table: 0 + - set update_register_cap_length, 0 + - add update_register_cap_length_0, update_register_negated_length, 1 + - set update_register_cap_length_1, 0 + - set update_register_cap_length_2, 0 + - set update_register_cap_length_3, update_register_padded_length + Egress.update_register.comp_port_3_1(26, 26): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x2000001d + - next_table: 0 + - set update_register_cap_length, update_register_padded_length + - set update_register_cap_length_0, 0 + - add update_register_cap_length_1, update_register_negated_length, 1 + - set update_register_cap_length_2, 0 + - set update_register_cap_length_3, 0 + Egress.update_register.comp_port_3_2(28, 28): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x2000001e + - next_table: 0 + - set update_register_cap_length, 0 + - set update_register_cap_length_0, update_register_padded_length + - add update_register_cap_length_1, update_register_negated_length, 1 + - set update_register_cap_length_2, 0 + - set update_register_cap_length_3, 0 + Egress.update_register.comp_port_3_4(30, 30): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x2000001f + - next_table: 0 + - set update_register_cap_length, 0 + - set update_register_cap_length_0, 0 + - add update_register_cap_length_1, update_register_negated_length, 1 + - set update_register_cap_length_2, update_register_padded_length + - set update_register_cap_length_3, 0 + Egress.update_register.comp_port_3_5(32, 32): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000020 + - next_table: 0 + - set update_register_cap_length, 0 + - set update_register_cap_length_0, 0 + - add update_register_cap_length_1, update_register_negated_length, 1 + - set update_register_cap_length_2, 0 + - set update_register_cap_length_3, update_register_padded_length + Egress.update_register.comp_port_4_1(34, 34): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000021 + - next_table: 0 + - set update_register_cap_length, update_register_padded_length + - set update_register_cap_length_0, 0 + - set update_register_cap_length_1, 0 + - add update_register_cap_length_2, update_register_negated_length, 1 + - set update_register_cap_length_3, 0 + Egress.update_register.comp_port_4_2(36, 36): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000022 + - next_table: 0 + - set update_register_cap_length, 0 + - set update_register_cap_length_0, update_register_padded_length + - set update_register_cap_length_1, 0 + - add update_register_cap_length_2, update_register_negated_length, 1 + - set update_register_cap_length_3, 0 + Egress.update_register.comp_port_4_3(38, 38): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000023 + - next_table: 0 + - set update_register_cap_length, 0 + - set update_register_cap_length_0, 0 + - set update_register_cap_length_1, update_register_padded_length + - add update_register_cap_length_2, update_register_negated_length, 1 + - set update_register_cap_length_3, 0 + Egress.update_register.comp_port_4_5(40, 40): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000024 + - next_table: 0 + - set update_register_cap_length, 0 + - set update_register_cap_length_0, 0 + - set update_register_cap_length_1, 0 + - add update_register_cap_length_2, update_register_negated_length, 1 + - set update_register_cap_length_3, update_register_padded_length + Egress.update_register.comp_port_5_1(42, 42): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000025 + - next_table: 0 + - set update_register_cap_length, update_register_padded_length + - set update_register_cap_length_0, 0 + - set update_register_cap_length_1, 0 + - set update_register_cap_length_2, 0 + - add update_register_cap_length_3, update_register_negated_length, 1 + Egress.update_register.comp_port_5_2(44, 44): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000026 + - next_table: 0 + - set update_register_cap_length, 0 + - set update_register_cap_length_0, update_register_padded_length + - set update_register_cap_length_1, 0 + - set update_register_cap_length_2, 0 + - add update_register_cap_length_3, update_register_negated_length, 1 + Egress.update_register.comp_port_5_3(46, 46): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000027 + - next_table: 0 + - set update_register_cap_length, 0 + - set update_register_cap_length_0, 0 + - set update_register_cap_length_1, update_register_padded_length + - set update_register_cap_length_2, 0 + - add update_register_cap_length_3, update_register_negated_length, 1 + Egress.update_register.comp_port_5_4(48, 48): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000028 + - next_table: 0 + - set update_register_cap_length, 0 + - set update_register_cap_length_0, 0 + - set update_register_cap_length_1, 0 + - set update_register_cap_length_2, update_register_padded_length + - add update_register_cap_length_3, update_register_negated_length, 1 + NoAction(0, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000029 + - next_table: 0 + default_action: NoAction +stage 4 egress: + dependency: match + ternary_match tbl_p4c2719l720 0: + p4: { name: tbl_p4c2719l720, hidden: true } + hit: [ tbl_p4c2719l721 ] + miss: tbl_p4c2719l721 + indirect: tbl_p4c2719l720$tind + stateful tbl_p4c2719l720$salu.Egress.update_register.active_debt_reg0: + p4: { name: Egress.update_register.active_debt_reg0, size: 1 } + row: 15 + logical_bus: S + column: [ 0, 1 ] + maprams: [ 0, 1 ] + home_row: 15 + input_xbar: + exact group 0: { 64: update_register_cap_length } + data_bytemask: 3 + format: { lo: 16 } + initial_value: { lo: 4095 , hi: 0 } + actions: + update_register_increase_reg0: + - add lo, phv_lo, lo + - output mem_lo + ternary_indirect tbl_p4c2719l720$tind: + row: 0 + bus: 0 + format: { action: 0..0, meter_addr: 1..10 } + action_bus: { 32..33 : tbl_p4c2719l720$salu.Egress.update_register.active_debt_reg0(0..15) } + stateful: tbl_p4c2719l720$salu.Egress.update_register.active_debt_reg0(meter_addr, $DEFAULT, $DEFAULT) + instruction: tbl_p4c2719l720$tind(action, $DEFAULT) + actions: + p4c2719l720(0, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x2000002a + - next_table: 0 + - set update_register_debt0, tbl_p4c2719l720$salu.Egress.update_register.active_debt_reg0 + - tbl_p4c2719l720$salu.Egress.update_register.active_debt_reg0(update_register_increase_reg0, 0) + default_action: p4c2719l720 +stage 5 egress: + dependency: match + ternary_match tbl_p4c2719l721 0: + p4: { name: tbl_p4c2719l721, hidden: true } + hit: [ tbl_p4c2719l722 ] + miss: tbl_p4c2719l722 + indirect: tbl_p4c2719l721$tind + stateful tbl_p4c2719l721$salu.Egress.update_register.active_debt_reg1: + p4: { name: Egress.update_register.active_debt_reg1, size: 1 } + row: 15 + logical_bus: S + column: [ 0, 1 ] + maprams: [ 0, 1 ] + home_row: 15 + input_xbar: + exact group 0: { 64: update_register_debt0, 80: update_register_cap_length_0 } + data_bytemask: 15 + format: { lo: 16 } + initial_value: { lo: 4095 , hi: 0 } + actions: + update_register_increase_reg1: + - minu hi, phv_lo, lo + - add lo, phv_hi, lo + - output alu_hi + ternary_indirect tbl_p4c2719l721$tind: + row: 0 + bus: 0 + format: { action: 0..0, meter_addr: 1..10 } + action_bus: { 32..33 : tbl_p4c2719l721$salu.Egress.update_register.active_debt_reg1(0..15) } + stateful: tbl_p4c2719l721$salu.Egress.update_register.active_debt_reg1(meter_addr, $DEFAULT, $DEFAULT) + instruction: tbl_p4c2719l721$tind(action, $DEFAULT) + actions: + p4c2719l721(0, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x2000002b + - next_table: 0 + - set update_register_debt1, tbl_p4c2719l721$salu.Egress.update_register.active_debt_reg1 + - tbl_p4c2719l721$salu.Egress.update_register.active_debt_reg1(update_register_increase_reg1, 0) + default_action: p4c2719l721 +stage 6 egress: + dependency: match + ternary_match tbl_p4c2719l722 0: + p4: { name: tbl_p4c2719l722, hidden: true } + hit: [ tbl_p4c2719l732 ] + miss: tbl_p4c2719l732 + indirect: tbl_p4c2719l722$tind + stateful tbl_p4c2719l722$salu.Egress.update_register.active_debt_reg2: + p4: { name: Egress.update_register.active_debt_reg2, size: 1 } + row: 15 + logical_bus: S + column: [ 0, 1 ] + maprams: [ 0, 1 ] + home_row: 15 + input_xbar: + exact group 0: { 64: update_register_debt1, 80: update_register_cap_length_1 } + data_bytemask: 15 + format: { lo: 16 } + initial_value: { lo: 4095 , hi: 0 } + actions: + update_register_increase_reg2: + - minu hi, phv_lo, lo + - add lo, phv_hi, lo + - output alu_hi + ternary_indirect tbl_p4c2719l722$tind: + row: 0 + bus: 0 + format: { action: 0..0, meter_addr: 1..10 } + action_bus: { 32..33 : tbl_p4c2719l722$salu.Egress.update_register.active_debt_reg2(0..15) } + stateful: tbl_p4c2719l722$salu.Egress.update_register.active_debt_reg2(meter_addr, $DEFAULT, $DEFAULT) + instruction: tbl_p4c2719l722$tind(action, $DEFAULT) + actions: + p4c2719l722(0, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x2000002c + - next_table: 0 + - set update_register_debt2, tbl_p4c2719l722$salu.Egress.update_register.active_debt_reg2 + - tbl_p4c2719l722$salu.Egress.update_register.active_debt_reg2(update_register_increase_reg2, 0) + default_action: p4c2719l722 + ternary_match tbl_p4c2719l732 1: + p4: { name: tbl_p4c2719l732, hidden: true } + gateway: + name: cond-12 + input_xbar: + exact group 0: { 0: update_register_debt0, 64: update_register_debt1 } + row: 0 + bus: 0 + unit: 0 + match: { 0: update_register_debt1(0..7), 8: update_register_debt1(8..15) } + xor: { 0: update_register_debt0(0..7), 8: update_register_debt0(8..15) } + 0x0000: tbl_p4c2719l723 + miss: run_table + condition: + expression: "(update_register_debt1 == update_register_debt0)" + true: tbl_p4c2719l723 + false: tbl_p4c2719l732 + hit: [ tbl_p4c2719l723 ] + miss: tbl_p4c2719l723 + indirect: tbl_p4c2719l732$tind + ternary_indirect tbl_p4c2719l732$tind: + row: 0 + bus: 1 + format: { action: 0..0 } + instruction: tbl_p4c2719l732$tind(action, $DEFAULT) + actions: + p4c2719l732(1, 2): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x2000002f + - next_table: 0 + - set update_register_reg0.0-3, 1 + - set update_register_reg0.4-7, 0 + default_action: p4c2719l732 +stage 7 egress: + dependency: match + ternary_match tbl_p4c2719l723 0: + p4: { name: tbl_p4c2719l723, hidden: true } + hit: [ tbl_p4c2719l737 ] + miss: tbl_p4c2719l737 + indirect: tbl_p4c2719l723$tind + stateful tbl_p4c2719l723$salu.Egress.update_register.active_debt_reg3: + p4: { name: Egress.update_register.active_debt_reg3, size: 1 } + row: 15 + logical_bus: S + column: [ 0, 1 ] + maprams: [ 0, 1 ] + home_row: 15 + input_xbar: + exact group 0: { 64: update_register_debt2, 80: update_register_cap_length_2 } + data_bytemask: 15 + format: { lo: 16 } + initial_value: { lo: 4095 , hi: 0 } + actions: + update_register_increase_reg3: + - minu hi, phv_lo, lo + - add lo, phv_hi, lo + - output alu_hi + ternary_indirect tbl_p4c2719l723$tind: + row: 0 + bus: 1 + format: { action: 0..0, meter_addr: 1..10 } + action_bus: { 32..33 : tbl_p4c2719l723$salu.Egress.update_register.active_debt_reg3(0..15) } + stateful: tbl_p4c2719l723$salu.Egress.update_register.active_debt_reg3(meter_addr, $DEFAULT, $DEFAULT) + instruction: tbl_p4c2719l723$tind(action, $DEFAULT) + actions: + p4c2719l723(0, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x2000002d + - next_table: 0 + - set update_register_debt3, tbl_p4c2719l723$salu.Egress.update_register.active_debt_reg3 + - tbl_p4c2719l723$salu.Egress.update_register.active_debt_reg3(update_register_increase_reg3, 0) + default_action: p4c2719l723 + ternary_match tbl_p4c2719l737 1: + p4: { name: tbl_p4c2719l737, hidden: true } + gateway: + name: cond-13 + input_xbar: + exact group 0: { 0: update_register_debt1, 64: update_register_debt2 } + row: 0 + bus: 0 + unit: 0 + match: { 0: update_register_debt2(0..7), 8: update_register_debt2(8..15) } + xor: { 0: update_register_debt1(0..7), 8: update_register_debt1(8..15) } + 0x0000: run_table + miss: tbl_p4c2719l741 + condition: + expression: "(update_register_debt2 == update_register_debt1)" + true: tbl_p4c2719l737 + false: tbl_p4c2719l741 + hit: [ tbl_p4c2719l724 ] + miss: tbl_p4c2719l724 + indirect: tbl_p4c2719l737$tind + ternary_indirect tbl_p4c2719l737$tind: + row: 0 + bus: 0 + format: { action: 0..0 } + instruction: tbl_p4c2719l737$tind(action, $DEFAULT) + actions: + p4c2719l737(1, 2): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000030 + - next_table: 0 + - set update_register_reg1.0-3, update_register_reg0.0-3 + - set update_register_reg1.4-7, update_register_reg0.4-7 + default_action: p4c2719l737 + ternary_match tbl_p4c2719l741 2: + p4: { name: tbl_p4c2719l741, hidden: true } + hit: [ tbl_p4c2719l724 ] + miss: tbl_p4c2719l724 + indirect: tbl_p4c2719l741$tind + ternary_indirect tbl_p4c2719l741$tind: + row: 1 + bus: 0 + format: { action: 0..0 } + instruction: tbl_p4c2719l741$tind(action, $DEFAULT) + actions: + p4c2719l741(0, 4): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000031 + - next_table: 0 + - set update_register_reg1.0-3, 2 + - set update_register_reg1.4-7, 0 + default_action: p4c2719l741 +stage 8 egress: + dependency: match + ternary_match tbl_p4c2719l724 0: + p4: { name: tbl_p4c2719l724, hidden: true } + hit: [ tbl_p4c2719l746 ] + miss: tbl_p4c2719l746 + indirect: tbl_p4c2719l724$tind + stateful tbl_p4c2719l724$salu.Egress.update_register.active_debt_reg4: + p4: { name: Egress.update_register.active_debt_reg4, size: 1 } + row: 15 + logical_bus: S + column: [ 0, 1 ] + maprams: [ 0, 1 ] + home_row: 15 + input_xbar: + exact group 0: { 64: update_register_debt3, 80: update_register_cap_length_3 } + data_bytemask: 15 + format: { lo: 16 } + initial_value: { lo: 4095 , hi: 0 } + actions: + update_register_increase_reg4: + - minu hi, phv_lo, lo + - add lo, phv_hi, lo + - output alu_hi + ternary_indirect tbl_p4c2719l724$tind: + row: 0 + bus: 1 + format: { action: 0..0, meter_addr: 1..10 } + action_bus: { 32..33 : tbl_p4c2719l724$salu.Egress.update_register.active_debt_reg4(0..15) } + stateful: tbl_p4c2719l724$salu.Egress.update_register.active_debt_reg4(meter_addr, $DEFAULT, $DEFAULT) + instruction: tbl_p4c2719l724$tind(action, $DEFAULT) + actions: + p4c2719l724(0, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x2000002e + - next_table: 0 + - set update_register_debt4, tbl_p4c2719l724$salu.Egress.update_register.active_debt_reg4 + - tbl_p4c2719l724$salu.Egress.update_register.active_debt_reg4(update_register_increase_reg4, 0) + default_action: p4c2719l724 + ternary_match tbl_p4c2719l746 1: + p4: { name: tbl_p4c2719l746, hidden: true } + gateway: + name: cond-14 + input_xbar: + exact group 0: { 0: update_register_debt2, 64: update_register_debt3 } + row: 0 + bus: 0 + unit: 0 + match: { 0: update_register_debt3(0..7), 8: update_register_debt3(8..15) } + xor: { 0: update_register_debt2(0..7), 8: update_register_debt2(8..15) } + 0x0000: run_table + miss: tbl_p4c2719l750 + condition: + expression: "(update_register_debt3 == update_register_debt2)" + true: tbl_p4c2719l746 + false: tbl_p4c2719l750 + hit: [ tbl_update_register_map_last ] + miss: tbl_update_register_map_last + indirect: tbl_p4c2719l746$tind + ternary_indirect tbl_p4c2719l746$tind: + row: 0 + bus: 0 + format: { action: 0..0 } + instruction: tbl_p4c2719l746$tind(action, $DEFAULT) + actions: + p4c2719l746(1, 2): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000032 + - next_table: 0 + - set update_register_reg2.0-3, update_register_reg1.0-3 + - set update_register_reg2.4-7, update_register_reg1.4-7 + default_action: p4c2719l746 + ternary_match tbl_p4c2719l750 2: + p4: { name: tbl_p4c2719l750, hidden: true } + hit: [ tbl_update_register_map_last ] + miss: tbl_update_register_map_last + indirect: tbl_p4c2719l750$tind + ternary_indirect tbl_p4c2719l750$tind: + row: 1 + bus: 0 + format: { action: 0..0 } + instruction: tbl_p4c2719l750$tind(action, $DEFAULT) + actions: + p4c2719l750(0, 4): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000033 + - next_table: 0 + - set update_register_reg2.0-3, 3 + - set update_register_reg2.4-7, 0 + default_action: p4c2719l750 +stage 9 egress: + dependency: match + ternary_match tbl_update_register_map_last 0: + p4: { name: tbl_update_register_map_last, hidden: true } + gateway: + name: cond-15 + input_xbar: + exact group 0: { 0: update_register_debt3, 16: update_register_debt4 } + row: 0 + bus: 0 + unit: 0 + match: { 0: update_register_debt4(0..7), 8: update_register_debt4(8..15) } + xor: { 0: update_register_debt3(0..7), 8: update_register_debt3(8..15) } + 0x0000: run_table + miss: tbl_update_register_map_last_0 + condition: + expression: "(update_register_debt4 == update_register_debt3)" + true: tbl_update_register_map_last + false: tbl_update_register_map_last_0 + hit: [ tbl_insert_capture ] + miss: tbl_insert_capture + indirect: tbl_update_register_map_last$tind + ternary_indirect tbl_update_register_map_last$tind: + row: 0 + bus: 0 + format: { action: 0..0 } + instruction: tbl_update_register_map_last$tind(action, $DEFAULT) + actions: + Egress.update_register.map_last_2(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000034 + - next_table: 0 + - set rich_register_0.4-7, update_register_capture_port(0..3) + - set rich_register_0.0-3, update_register_reg2.0-3 + default_action: Egress.update_register.map_last_2 + ternary_match tbl_update_register_map_last_0 1: + p4: { name: tbl_update_register_map_last_0, hidden: true } + hit: [ tbl_insert_capture ] + miss: tbl_insert_capture + indirect: tbl_update_register_map_last_0$tind + ternary_indirect tbl_update_register_map_last_0$tind: + row: 0 + bus: 1 + format: { action: 0..0 } + instruction: tbl_update_register_map_last_0$tind(action, $DEFAULT) + actions: + Egress.update_register.map_last_4(0, 2): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000035 + - next_table: 0 + - set rich_register_0.4-7, update_register_capture_port(0..3) + - set rich_register_0.0-3, 4 + default_action: Egress.update_register.map_last_4 +stage 10 egress: + dependency: action + ternary_match tbl_insert_capture 0: + p4: { name: tbl_insert_capture, hidden: true } + gateway: + name: cond-16 + input_xbar: + exact group 0: { 0: meta.ing_port_mirror.pkt_type } + row: 7 + bus: 0 + unit: 0 + match: { 0: meta.ing_port_mirror.pkt_type } + 0x03: run_table + miss: egressCaptureTbl_0 + condition: + expression: "(meta.ing_port_mirror.pkt_type == 3)" + true: tbl_insert_capture + false: egressCaptureTbl_0 + hit: [ egressCaptureTbl_0 ] + miss: egressCaptureTbl_0 + indirect: tbl_insert_capture$tind + ternary_indirect tbl_insert_capture$tind: + row: 0 + bus: 0 + format: { action: 0..0 } + instruction: tbl_insert_capture$tind(action, $DEFAULT) + actions: + Egress.insert_capture(1, 1): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000036 + - next_table: 0 + - set hdr.capture.timestamp, meta.ing_port_mirror.mac_timestamp + - deposit-field B18(4..7), B21(0..3), B19 + default_action: Egress.insert_capture + exact_match egressCaptureTbl_0 1: + p4: { name: Egress.egressCaptureTbl, size: 64 } + p4_param_order: + eg_intr_md.egress_port: { type: exact, size: 9, full_size: 9 } + row: 7 + bus: 0 + column: 2 + stash: + row: [ 7 ] + col: [ 2 ] + unit: [ 0 ] + ways: + - [0, 0, 0x0, [7, 2]] + input_xbar: + exact group 0: { 8: eg_intr_md.egress_port(8), 16: eg_intr_md.egress_port(0..7) } + hash 0: + 0: eg_intr_md.egress_port(8) + 1..8: eg_intr_md.egress_port(0..7) + hash group 0: + table: [0] + seed: 0x0 + format: { action(0): 0..0, immediate(0): 1..10, version(0): 112..115 } + match_group_map: [ [ 0 ] ] + hit: [ END ] + miss: END + action_bus: { 32..33 : immediate(0..9) } + instruction: egressCaptureTbl_0(action, $DEFAULT) + actions: + Egress.set_mirror_session_capture(0, 2): + - p4_param_order: { mirror_session: 10 } + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000037 + - next_table: 0 + - { mirror_session_3: immediate(0..9), mirror_session: mirror_session_3 } + - set eg_intr_md_for_dprsr.mirror_type, 2 + - set meta.mirror_session, mirror_session + - set meta.pkt_type, 3 + - set meta.ing_port_mirror.mac_timestamp, eg_intr_md_from_prsr.global_tstamp.0-31 + NoAction(1, 0): + - hit_allowed: { allowed: true } + - default_action: { allowed: true } + - handle: 0x20000038 + - next_table: 0 + - { } + default_action: NoAction + +flexible_headers: [ + + { name: "hdr.bridge", + fields: [ + + { name: "rich_register", slice: { start_bit: 0, bit_width: 8 } }, + { name: "pkt_type", slice: { start_bit: 0, bit_width: 8 } }, + { name: "__pad_0", slice: { start_bit: 0, bit_width: 4 } }, + { name: "rich_register_v", slice: { start_bit: 0, bit_width: 1 } }, + { name: "l23_rxtstmp_insert", slice: { start_bit: 0, bit_width: 1 } }, + { name: "l23_txtstmp_insert", slice: { start_bit: 0, bit_width: 1 } }, + { name: "l47_timestamp_insert", slice: { start_bit: 0, bit_width: 1 } } ] + }, + { name: "meta.bridge", + fields: [ + + { name: "rich_register", slice: { start_bit: 0, bit_width: 8 } }, + { name: "pkt_type", slice: { start_bit: 0, bit_width: 8 } }, + { name: "__pad_0", slice: { start_bit: 0, bit_width: 4 } }, + { name: "rich_register_v", slice: { start_bit: 0, bit_width: 1 } }, + { name: "l23_rxtstmp_insert", slice: { start_bit: 0, bit_width: 1 } }, + { name: "l23_txtstmp_insert", slice: { start_bit: 0, bit_width: 1 } }, + { name: "l47_timestamp_insert", slice: { start_bit: 0, bit_width: 1 } } ] + }] diff --git a/backends/tofino/bf-asm/test/asm/parser_value_set.tfa b/backends/tofino/bf-asm/test/asm/parser_value_set.tfa new file mode 100644 index 00000000000..103da840f17 --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/parser_value_set.tfa @@ -0,0 +1,23 @@ +parser ingress: + start: state1 + multi_write: [ B0 ] + state1: + save: { byte0: 0, byte1: 1 } + shift: 2 + next: state2 + state2: + match: [ byte0 ] + value_set set1 5: + 0..3: W0 + B0: 1 + shift: 4 + next: end + 0x**: + next: state3 + state3: + match: [ byte1 ] + value_set set2 10: + 0..3: W1 + 4..7: W2 + B0: 2 + shift: 8 diff --git a/backends/tofino/bf-asm/test/asm/parser_zero_write.jba b/backends/tofino/bf-asm/test/asm/parser_zero_write.jba new file mode 100644 index 00000000000..77347bc0493 --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/parser_zero_write.jba @@ -0,0 +1,6 @@ +parser ingress: + start: + B0: 0 + H0: 0 + W0: 0 + next: end diff --git a/backends/tofino/bf-asm/test/asm/rng.tfa b/backends/tofino/bf-asm/test/asm/rng.tfa new file mode 100644 index 00000000000..a57dae5103b --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/rng.tfa @@ -0,0 +1,22 @@ +stage 0 ingress: + ternary_match test: + row: 11 + column: 0 + input_xbar: + group 0: { 0: W0 } + indirect: tind + ternary_indirect tind: + row: 0 + column: 2 + format: { action: 2, data: 8..15 } + action: atab(action) + action atab: + row: 15 + column: 0 + format: { misc : 8 } + actions: + act0: + - add B0, B0, rng(0, 0..7) + - add B1, B1, rng(0, 16..23) + act1: + - add H0, H0, rng(0, 0..15) diff --git a/backends/tofino/bf-asm/test/asm/stateful_multiple_output_error.tfa b/backends/tofino/bf-asm/test/asm/stateful_multiple_output_error.tfa new file mode 100644 index 00000000000..301a780a7f0 --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/stateful_multiple_output_error.tfa @@ -0,0 +1,348 @@ +version: 1.0.0 +phv ingress: + ipv4.version: R288(4..7) + ipv4.ihl: R288(0..3) + ipv4.diffserv: R289 + ipv4.totalLen: R320 + ipv4.identification: R321 + ipv4.flags: R322(13..15) + ipv4.fragOffset: R322(0..12) + ipv4.ttl: R256(24..31) + ipv4.protocol: R256(16..23) + ipv4.hdrChecksum: R256(0..15) + ipv4.srcAddr: R257 + ipv4.dstAddr: R258 + ethernet.dstAddr.40-47: R290 + ethernet.dstAddr.8-39: R259 + ethernet.dstAddr.0-7: R323(8..15) + ethernet.srcAddr.40-47: R323(0..7) + ethernet.srcAddr.32-39: R291 + ethernet.srcAddr.0-31: R264 + ethernet.etherType: R324 + ig_intr_md.resubmit_flag: R128(15) + ig_intr_md._pad1: R128(14) + ig_intr_md._pad2: R128(12..13) + ig_intr_md._pad3: R128(9..11) + ig_intr_md.ingress_port: R128(0..8) + meta.bfd_discriminator: R129 + meta.bfd_timeout_detected: R128(8..15) + meta.bfd_tx_or_rx: R65 + ig_intr_md_for_tm.drop_ctl: R66(5..7) + __md_ingress.__init_0: R128(8..15) + POV-ethernet: R64(0) + POV-ipv4: R64(1) + POV-metadata_bridge: R64(2) +phv egress: + ipv4.version: R292(4..7) + ipv4.ihl: R292(0..3) + ipv4.diffserv: R293 + ipv4.totalLen: R326 + ipv4.identification: R327 + ipv4.flags: R328(13..15) + ipv4.fragOffset: R328(0..12) + ipv4.ttl: R260(24..31) + ipv4.protocol: R260(16..23) + ipv4.hdrChecksum: R260(0..15) + ipv4.srcAddr: R261 + ipv4.dstAddr: R262 + ethernet.dstAddr.40-47: R294 + ethernet.dstAddr.8-39: R263 + ethernet.dstAddr.0-7: R329(8..15) + ethernet.srcAddr.40-47: R329(0..7) + ethernet.srcAddr.32-39: R295 + ethernet.srcAddr.0-31: R268 + ethernet.etherType: R330 + eg_intr_md._pad0: R144(9..15) + eg_intr_md.egress_port: R144(0..8) + eg_intr_md._pad7: R80(3..7) + eg_intr_md.egress_cos: R80(0..2) + POV-ethernet: R81(0) + POV-ipv4: R81(1) +parser ingress: + start: [Shim_start_state, Shim_start_state, Shim_start_state, Shim_start_state] + Shim_start_state 0: + 0x0: + next: POV_initialization + offset: 0 + buf_req: 0 + parse_ethernet 1: + match: half + 0x800: + next: END + shift: 20 + offset: 0 + buf_req: 20 + R64: 2 + 8..11: R256 + 12..15: ipv4.srcAddr + 16..19: ipv4.dstAddr + 0: R288 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: R322 + 0x****: + next: END + offset: 0 + buf_req: 0 + Ingress_intrinsic_metadata 3: + match: byte0 + 0b0*******: + next: Phase_0 + save: {byte0: 0} + shift: 8 + offset: 0 + buf_req: 8 + Phase_0 4: + match: byte0 + 0x**: + next: start$ + offset: 0 + buf_req: 0 + R64: 4 + POV_initialization 5: + 0x0: + next: Ingress_intrinsic_metadata + save: {byte0: 0} + shift: 8 + offset: 0 + buf_req: 8 + 0..1: R128 + start$ 6: + 0x0: + next: parse_ethernet + save: {half: 12..13} + shift: 14 + offset: 0 + buf_req: 14 + R64: 1 + 1..4: ethernet.dstAddr.8-39 + 8..11: ethernet.srcAddr.0-31 + 0: ethernet.dstAddr.40-47 + 7: ethernet.srcAddr.32-39 + 5..6: R323 + 12..13: ethernet.etherType + multi_write: [R64, meta.bfd_tx_or_rx, R128, meta.bfd_discriminator] + init_zero: [R64, meta.bfd_tx_or_rx, R128, meta.bfd_discriminator] + hdr_len_adj: 16 +deparser ingress: + pov: [R64] + dictionary: + - R64: POV-metadata_bridge + - ethernet.dstAddr.40-47: POV-ethernet + - ethernet.dstAddr.8-39: POV-ethernet + - R323: POV-ethernet + - ethernet.srcAddr.32-39: POV-ethernet + - ethernet.srcAddr.0-31: POV-ethernet + - ethernet.etherType: POV-ethernet + - R288: POV-ipv4 + - ipv4.diffserv: POV-ipv4 + - ipv4.totalLen: POV-ipv4 + - ipv4.identification: POV-ipv4 + - R322: POV-ipv4 + - R256: POV-ipv4 + - ipv4.srcAddr: POV-ipv4 + - ipv4.dstAddr: POV-ipv4 + drop_ctl: ig_intr_md_for_tm.drop_ctl +parser egress: + start: [Shim_start_state, Shim_start_state, Shim_start_state, Shim_start_state] + Shim_start_state 0: + 0x0: + next: POV_initialization + offset: 0 + buf_req: 0 + parse_ethernet 1: + match: half + 0x800: + next: END + shift: 20 + offset: 0 + buf_req: 20 + R81: 2 + 8..11: R260 + 12..15: ipv4.srcAddr + 16..19: ipv4.dstAddr + 0: R292 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: R328 + 0x****: + next: END + offset: 0 + buf_req: 0 + POV_skip 3: + 0x0: + next: start$ + offset: 0 + buf_req: 0 + Egress_intrinsic_metadata 4: + match: byte0 + 0x**: + next: POV_skip + shift: 1 + offset: 0 + buf_req: 1 + POV_initialization 5: + 0x0: + next: Egress_intrinsic_metadata + save: {byte0: 3} + shift: 3 + offset: 0 + buf_req: 4 + 2: R80 + 0..1: R144 + start$ 6: + 0x0: + next: parse_ethernet + save: {half: 12..13} + shift: 14 + offset: 0 + buf_req: 14 + R81: 1 + 1..4: ethernet.dstAddr.8-39 + 8..11: ethernet.srcAddr.0-31 + 0: ethernet.dstAddr.40-47 + 7: ethernet.srcAddr.32-39 + 5..6: R329 + 12..13: ethernet.etherType + multi_write: [R81] + init_zero: [R81] + hdr_len_adj: 3 + meta_opt: 1024 +deparser egress: + pov: [R81] + dictionary: + - ethernet.dstAddr.40-47: POV-ethernet + - ethernet.dstAddr.8-39: POV-ethernet + - R329: POV-ethernet + - ethernet.srcAddr.32-39: POV-ethernet + - ethernet.srcAddr.0-31: POV-ethernet + - ethernet.etherType: POV-ethernet + - R292: POV-ipv4 + - ipv4.diffserv: POV-ipv4 + - ipv4.totalLen: POV-ipv4 + - ipv4.identification: POV-ipv4 + - R328: POV-ipv4 + - R260: POV-ipv4 + - ipv4.srcAddr: POV-ipv4 + - ipv4.dstAddr: POV-ipv4 + egress_unicast_port: eg_intr_md.egress_port + ecos: eg_intr_md.egress_cos +stage 0 ingress: + exact_match bfd 0: + p4: + name: bfd + handle: 16777217 + size: 1024 + match_type: exact + row: 7 + bus: 0 + column: [2, 3, 4] + ways: + - [0, 0, 0, [7, 2]] + - [0, 1, 0, [7, 3]] + - [0, 2, 0, [7, 4]] + input_xbar: + group 0: {0: meta.bfd_discriminator, 16: meta.bfd_tx_or_rx} + hash 0: + 0: 0xa98401 + 1: 0xd3a002 + 2: 0xdcd404 + 3: 0xd03808 + 4: 0xdc0810 + 5: 0xe2420 + 6: 0x3ef440 + 7: 0x7d8c80 + 8: 0x127900 + 9: 0x30ee00 + 10: 0xf07a00 + 11: 0x545c01 + 12: 0x629402 + 13: 0x47b404 + 14: 0xa5fc08 + 15: 0xee4810 + 16: 0xf1b420 + 17: 0xd7b440 + 18: 0x62ec80 + 19: 0x122900 + 20: 0xe04500 + 21: 0xd10600 + 22: 0x338401 + 23: 0x7c0c02 + 24: 0x8d4c04 + 25: 0xc22c08 + 26: 0x17d010 + 27: 0x6c0820 + 28: 0xdc7440 + 29: 0x5cf880 + hash group 0: + table: 0 + seed: 0x17b88dac + table_counter: table_hit + stateful: bfd_cnt(state_ptr) + format: {action(0): 1, state_ptr(0): 23, match(0): [24..31, 34..39], version(0): 120..123} + match: [meta.bfd_tx_or_rx, meta.bfd_discriminator(10..15)] + next: check_needs + actions: + bfd_tx 0: + - 1 + - deposit-field meta.bfd_timeout_detected, A0(0..7), R128 + bfd_rx 1: + - 2 + - deposit-field meta.bfd_timeout_detected, 0, R128 + stateful bfd_cnt: + p4: + name: bfd_cnt + handle: 100663297 + size: 1024 + row: 15 + bus: 0 + column: [0, 1] + maprams: [0, 1] + global_binding: true + format: {lo: 8} + actions: + 0: + - grt.u lo, lo, -3 + - equ hi, 1 + - add lo, lo, 1 + - a hi, 1 + - output cmplo, alu_hi + - output !cmplo, alu_lo + 1: + - equ lo, 1 + - equ hi, 1 + - a lo, 0 +stage 1 ingress: + dependency: match + exact_match check_needs 0: + p4: + name: check_needs + handle: 16777218 + size: 256 + match_type: exact + row: 7 + bus: 0 + column: 2 + ways: + - [0, 0, 0, [7, 2]] + input_xbar: + group 0: {8: meta.bfd_timeout_detected} + hash 0: + 0..7: meta.bfd_timeout_detected + hash group 0: 0 + table_counter: table_hit + format: {action(0): 1, match(0): 8..15, version(0): 120..123} + match: [meta.bfd_timeout_detected] + next: END + actions: + drop_me 0: + - 1 + - deposit-field ig_intr_md_for_tm.drop_ctl, 1, R66 + on_miss 1: + - 0 +stage 6 ingress: + dependency: match +stage 6 egress: + dependency: match diff --git a/backends/tofino/bf-asm/test/asm/switch_l2_profile_tofino.tfa b/backends/tofino/bf-asm/test/asm/switch_l2_profile_tofino.tfa new file mode 100644 index 00000000000..3a381d8ddc9 --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/switch_l2_profile_tofino.tfa @@ -0,0 +1,5453 @@ +version: 1.0.0 +phv ingress: + standard_metadata.ingress_port: H14(0..8) + standard_metadata.egress_spec: H5(0..8) + standard_metadata.resubmit_flag: TW11(31) + $always_deparse: B9(7) + ingress_metadata.ingress_port: H15(0..8) + ingress_metadata.ifindex: H0 + ingress_metadata.egress_ifindex: H79 + ingress_metadata.port_type: H72(14..15) + ingress_metadata.bd: H3(0..13) + ingress_metadata.drop_flag: B61(6) + ingress_metadata.drop_reason: B8 + ingress_metadata.control_frame: B61(5) + ingress_metadata.bypass_lookups: H70 + ethernet.dstAddr.32-47: H10 + ethernet.dstAddr.16-31: H9 + ethernet.dstAddr.0-15: H8 + ethernet.srcAddr.32-47: H82 + ethernet.srcAddr.16-31: H81 + ethernet.srcAddr.0-15: H80 + ethernet.etherType: H86 + llc_header.dsap: TB10 + llc_header.ssap: TB9 + llc_header.control_: TB8 + snap_header.oui.16-23: TB2 + snap_header.oui.8-15: TB1 + snap_header.oui.0-7: TB0 + snap_header.type_: TH15 + vlan_tag_$0.pcp: H42(13..15) + vlan_tag_$0.cfi: H42(12) + vlan_tag_$0.vid: H42(0..11) + vlan_tag_$0.etherType: H87 + vlan_tag_$1.pcp: H32(13..15) + vlan_tag_$1.cfi: H32(12) + vlan_tag_$1.vid: H32(0..11) + vlan_tag_$1.etherType: H88 + ipv4.version: B49(4..7) + ipv4.ihl: B49(0..3) + ipv4.diffserv: B48 + ipv4.totalLen: H41 + ipv4.identification: H40 + ipv4.flags: H39(13..15) + ipv4.fragOffset: H39(0..12) + ipv4.ttl: B2 + ipv4.protocol: B4 + ipv4.hdrChecksum: H38 + ipv4.srcAddr: W10 + ipv4.dstAddr: W8 + icmp.typeCode: H67 + icmp.hdrChecksum: TH14 + l3_metadata.lkp_ip_type: H15(9..10) + l3_metadata.lkp_ip_version: B1(2..5) + l3_metadata.lkp_ip_proto: B5 + l3_metadata.lkp_ip_ttl: B3 + l3_metadata.lkp_l4_sport: H68 + l3_metadata.lkp_l4_dport: H64 + l3_metadata.lkp_outer_l4_sport: H69 + l3_metadata.lkp_outer_l4_dport: H65 + l3_metadata.rmac_group: H73(0..9) + l3_metadata.rmac_hit: B61(4) + l3_metadata.urpf_check_fail: B60(6) + l3_metadata.fib_hit: B60(5) + l3_metadata.same_bd_check: H4(0..13) + l3_metadata.nexthop_index: H91 + l3_metadata.routed: B60(4) + l3_metadata.l3_copy: B59(6) + ig_prsr_ctrl.priority: TW7(29..31) + tcp.srcPort: H67 + tcp.dstPort: H66 + tcp.seqNo: TW3 + tcp.ackNo: TW2 + tcp.dataOffset: TB6(4..7) + tcp.res: TB6(0..3) + tcp.flags: B15 + tcp.window: TH13 + tcp.checksum: TH12 + tcp.urgentPtr: TH11 + udp.srcPort: H67 + udp.dstPort: H66 + udp.length_: TH10 + udp.checksum: TH9 + ipv6.version: W12(28..31) + ipv6.trafficClass: W12(20..27) + ipv6.flowLabel: W12(0..19) + ipv6.payloadLen: H37 + ipv6.nextHdr: B14 + ipv6.hopLimit: B13 + ipv6.srcAddr.96-127: W7 + ipv6.srcAddr.64-95: W6 + ipv6.srcAddr.32-63: W5 + ipv6.srcAddr.0-31: W4 + ipv6.dstAddr.96-127: W3 + ipv6.dstAddr.64-95: W2 + ipv6.dstAddr.32-63: W1 + ipv6.dstAddr.0-31: W0 + tunnel_metadata.ingress_tunnel_type: B9(2..6) + tunnel_metadata.tunnel_terminate: B9(1) + tunnel_metadata.tunnel_if_check: B9(0) + inner_ipv4.version: B12(4..7) + inner_ipv4.ihl: B12(0..3) + inner_ipv4.diffserv: B11 + inner_ipv4.totalLen: H36 + inner_ipv4.identification: H35 + inner_ipv4.flags: H34(13..15) + inner_ipv4.fragOffset: H34(0..12) + inner_ipv4.ttl: B2 + inner_ipv4.protocol: B4 + inner_ipv4.hdrChecksum: H33 + inner_ipv4.srcAddr: W10 + inner_ipv4.dstAddr: W8 + ipv4_metadata.lkp_ipv4_sa: W11 + ipv4_metadata.lkp_ipv4_da: W9 + ipv4_metadata.ipv4_unicast_enabled: B59(5) + inner_icmp.typeCode: H67 + inner_icmp.hdrChecksum: TH8 + inner_tcp.srcPort: H67 + inner_tcp.dstPort: H66 + inner_tcp.seqNo: TW1 + inner_tcp.ackNo: TW0 + inner_tcp.dataOffset: TB5(4..7) + inner_tcp.res: TB5(0..3) + inner_tcp.flags: TB7 + inner_tcp.window: TH7 + inner_tcp.checksum: TH6 + inner_tcp.urgentPtr: TH5 + inner_udp.srcPort: H67 + inner_udp.dstPort: H66 + inner_udp.length_: TH4 + inner_udp.checksum: TH3 + fabric_header.packetType: TB4(5..7) + fabric_header.headerVersion: TB4(3..4) + fabric_header.packetVersion: TB4(1..2) + fabric_header.pad1: TB4(0) + fabric_header.fabricColor: TB3(5..7) + fabric_header.fabricQos: TB3(0..4) + fabric_header.dstDevice: B10 + fabric_header.dstPortOrGroup: H6 + fabric_header_cpu.egressQueue: B0(3..7) + fabric_header_cpu.txBypass: B0(2) + fabric_header_cpu.reserved: B0(0..1) + fabric_header_cpu.ingressPort: TH2 + fabric_header_cpu.ingressIfindex: TH1 + fabric_header_cpu.ingressBd: TH0 + fabric_header_cpu.reasonCode: H71 + fabric_payload_header.etherType: H89 + acl_metadata.acl_deny: B59(4) + acl_metadata.racl_deny: B58(6) + acl_metadata.acl_nexthop: H92 + acl_metadata.acl_nexthop_type: H73(14..15) + acl_metadata.acl_redirect: B58(5) + acl_metadata.racl_redirect: B58(4) + acl_metadata.if_label: H78 + acl_metadata.bd_label: H77 + acl_metadata.acl_stats_index: H75(0..13) + acl_metadata.ingress_src_port_range_id: B7 + acl_metadata.ingress_dst_port_range_id: B6 + l2_metadata.lkp_mac_sa.32-47: H85 + l2_metadata.lkp_mac_sa.16-31: H84 + l2_metadata.lkp_mac_sa.0-15: H83 + l2_metadata.lkp_mac_da.32-47: H13 + l2_metadata.lkp_mac_da.16-31: H12 + l2_metadata.lkp_mac_da.0-15: H11 + l2_metadata.lkp_pkt_type: H15(11..13) + l2_metadata.lkp_mac_type: H90 + l2_metadata.l2_nexthop: H93 + l2_metadata.l2_nexthop_type: H74(14..15) + l2_metadata.l2_redirect: B57(6) + l2_metadata.l2_src_miss: B57(5) + l2_metadata.l2_src_move: H1 + l2_metadata.stp_group: H72(0..9) + l2_metadata.stp_state: B63(4..6) + l2_metadata.bd_stats_idx: H7 + l2_metadata.learning_enabled: B57(4) + l2_metadata.port_vlan_mapping_miss: B56(6) + l2_metadata.same_if_check: H2 + ipv6_metadata.ipv6_unicast_enabled: H14(15) + ipv6_metadata.ipv6_src_is_link_local: H14(14) + multicast_metadata.mcast_route_hit: B56(5) + multicast_metadata.mcast_bridge_hit: B56(4) + multicast_metadata.igmp_snooping_enabled: B55(6) + multicast_metadata.mld_snooping_enabled: B55(5) + multicast_metadata.mcast_rpf_group: H74(0..13) + multicast_metadata.mcast_mode: H14(12..13) + egress_metadata.bypass: B1(0) + fabric_metadata.reason_code: H76 + nat_metadata.nat_hit: B55(4) + hash_metadata.hash1: H94 + hash_metadata.hash2: H95 + nexthop_metadata.nexthop_type: H75(14..15) + $learning: B62(0..2) + security_metadata.ipsg_check_fail: B54(6) + ethernet.$valid: B1(7) + fabric_header.$valid: B1(6) + fabric_header_cpu.$valid: B63(7) + fabric_payload_header.$valid: B62(7) + icmp.$valid: B61(7) + ig_prsr_ctrl.$valid: B60(7) + inner_icmp.$valid: B59(7) + inner_ipv4.$valid: B58(7) + inner_tcp.$valid: B57(7) + inner_udp.$valid: B56(7) + ipv4.$valid: B55(7) + ipv6.$valid: B54(7) + llc_header.$valid: B53(7) + snap_header.$valid: B52(7) + tcp.$valid: B51(7) + udp.$valid: B50(7) + vlan_tag_$0.$valid: H15(15) + vlan_tag_$1.$valid: H15(14) +phv egress: + standard_metadata.egress_port: H16(0..8) + ingress_metadata.ingress_port: H25(0..8) + ingress_metadata.ifindex: H26 + ingress_metadata.bd: H22(0..13) + l2_metadata.lkp_pkt_type: B22(2..4) + egress_metadata.bypass: B36(4) + egress_metadata.port_type: B21(3..4) + egress_metadata.bd: H23(0..13) + egress_metadata.routed: B18(6) + egress_metadata.ifindex: H48 + acl_metadata.acl_deny: H49(15) + fabric_metadata.fabric_header_present: B22(1) + fabric_metadata.reason_code: H28 + l3_metadata.nexthop_index: H31 + l3_metadata.l3_mtu_check: H30 + ethernet.dstAddr.32-47: TH29 + ethernet.dstAddr.16-31: TH28 + ethernet.dstAddr.0-15: TH27 + ethernet.srcAddr.32-47: TH26 + ethernet.srcAddr.16-31: TH25 + ethernet.srcAddr.0-15: TH24 + ethernet.etherType: H17 + llc_header.dsap: B31 + llc_header.ssap: B47 + llc_header.control_: B30 + snap_header.oui.16-23: TB18 + snap_header.oui.8-15: TB17 + snap_header.oui.0-7: TB16 + snap_header.type_: H63 + vlan_tag_$0.pcp: H51(13..15) + vlan_tag_$0.cfi: H51(12) + vlan_tag_$0.vid: H51(0..11) + vlan_tag_$0.etherType: H18 + vlan_tag_$1.pcp: H50(13..15) + vlan_tag_$1.cfi: H50(12) + vlan_tag_$1.vid: H50(0..11) + vlan_tag_$1.etherType: H19 + ipv4.version: B46(4..7) + ipv4.ihl: B46(0..3) + ipv4.diffserv: B45 + ipv4.totalLen: H62 + ipv4.identification: H61 + ipv4.flags: TH33(13..15) + ipv4.fragOffset: TH33(0..12) + ipv4.ttl: B29 + ipv4.protocol: B44 + ipv4.hdrChecksum: H60 + ipv4.srcAddr.16-31: TH31 + ipv4.srcAddr.0-15: TH30 + ipv4.dstAddr: TW31 + icmp.typeCode: H59 + icmp.hdrChecksum: H58 + tcp.srcPort: H57 + tcp.dstPort: H56 + tcp.seqNo: TW30 + tcp.ackNo: TW29 + tcp.dataOffset: B28(4..7) + tcp.res: B28(0..3) + tcp.flags: B43 + tcp.window: H55 + tcp.checksum: H54 + tcp.urgentPtr: H53 + udp.srcPort.8-15: TB31 + udp.srcPort.0-7: TB30 + udp.dstPort.8-15: TB29 + udp.dstPort.0-7: TB28 + udp.length_.8-15: TB27 + udp.length_.0-7: TB26 + udp.checksum.8-15: TB25 + udp.checksum.0-7: TB24 + ipv6.version: TW24(28..31) + ipv6.trafficClass: TW24(20..27) + ipv6.flowLabel: TW24(0..19) + ipv6.payloadLen.8-15: TB23 + ipv6.payloadLen.0-7: TB22 + ipv6.nextHdr: B27 + ipv6.hopLimit: B42 + ipv6.srcAddr.96-127: TW23 + ipv6.srcAddr.64-95: TW22 + ipv6.srcAddr.32-63: TW21 + ipv6.srcAddr.0-31: TW20 + ipv6.dstAddr.96-127: TW19 + ipv6.dstAddr.64-95: TW18 + ipv6.dstAddr.32-63: TW17 + ipv6.dstAddr.0-31: TW16 + inner_ipv4.version: B26(4..7) + inner_ipv4.ihl: B26(0..3) + inner_ipv4.diffserv: B41 + inner_ipv4.totalLen.8-15: TB21 + inner_ipv4.totalLen.0-7: TB20 + inner_ipv4.identification: TH47 + inner_ipv4.flags: TH32(13..15) + inner_ipv4.fragOffset: TH32(0..12) + inner_ipv4.ttl: B25 + inner_ipv4.protocol: B40 + inner_ipv4.hdrChecksum: TH46 + inner_ipv4.srcAddr: TW28 + inner_ipv4.dstAddr: TW27 + inner_icmp.typeCode: TH45 + inner_icmp.hdrChecksum: TH44 + inner_tcp.srcPort: TH43 + inner_tcp.dstPort: TH42 + inner_tcp.seqNo: TW26 + inner_tcp.ackNo: TW25 + inner_tcp.dataOffset: B24(4..7) + inner_tcp.res: B24(0..3) + inner_tcp.flags: B39 + inner_tcp.window: TH41 + inner_tcp.checksum: TH40 + inner_tcp.urgentPtr: TH39 + inner_udp.srcPort: TH38 + inner_udp.dstPort: TH37 + inner_udp.length_: TH36 + inner_udp.checksum: TH35 + fabric_header.packetType: B19(5..7) + fabric_header.headerVersion: B19(3..4) + fabric_header.packetVersion: B19(1..2) + fabric_header.pad1: B19(0) + fabric_header.fabricColor: TB19(5..7) + fabric_header.fabricQos: TB19(0..4) + fabric_header.dstDevice: B23 + fabric_header.dstPortOrGroup: TH34 + fabric_header_cpu.egressQueue: B38(3..7) + fabric_header_cpu.txBypass: B38(2) + fabric_header_cpu.reserved: B38(0..1) + fabric_header_cpu.ingressPort: H24 + fabric_header_cpu.ingressIfindex: H27 + fabric_header_cpu.ingressBd: H21 + fabric_header_cpu.reasonCode: H29 + fabric_payload_header.etherType: H20 + eg_intr_md.deflection_flag: B37(1) + eg_intr_md_from_parser_aux.clone_src: B17 + tunnel_metadata.egress_tunnel_type: B18(0..4) + tunnel_metadata.tunnel_index: H49(0..13) + tunnel_metadata.egress_header_count: H25(10..13) + multicast_metadata.replica: H25(15) + $mirror_id: B16 + $mirror: B37(2..4) + eg_intr_md.$valid: B18(7) + eg_intr_md_from_parser_aux.$valid: B22(7) + ethernet.$valid: B37(7) + fabric_header.$valid: B21(7) + fabric_header_cpu.$valid: B36(7) + fabric_payload_header.$valid: B20(7) + icmp.$valid: B35(7) + inner_icmp.$valid: B34(7) + inner_ipv4.$valid: B33(7) + inner_tcp.$valid: B32(7) + inner_udp.$valid: B22(6) + ipv4.$valid: B22(5) + ipv6.$valid: B37(6) + llc_header.$valid: B37(5) + snap_header.$valid: B21(6) + tcp.$valid: B21(5) + udp.$valid: B36(6) + vlan_tag_$0.$valid: B36(5) + vlan_tag_$1.$valid: B20(6) +parser ingress: + start: $ingress_metadata_shim + $ingress_metadata_shim: + match: [ 0 ] + 0b0*******: + $always_deparse: 1 + 0..3: TW11 + next: $ingress_metadata + 0b1*******: + $always_deparse: 1 + 0..3: TW11 + shift: 16 + next: start$ + $ingress_metadata: + 0x*: + 0..1: H14 + shift: 8 + next: $phase0 + $phase0: + 0x*: + next: $phase0_extract + $phase0_extract: + 0x*: + 0..1: ingress_metadata.ifindex + 2..3: H72 + shift: 8 + next: start$ + start$: + match: [ /* packet.lookahead>()[15:0]; */ ] + 0x*: + next: parse_ethernet + parse_ethernet: + match: [ 12..13 ] + 0o000***: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.0 + 0b00000*0*********: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.1 + 0x9000: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.2 + 0x8100: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.3 + 0x9100: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.4 + 0x8847: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.5 + 0x0800: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.6 + 0x86dd: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.7 + 0x0806: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.8 + 0x88cc: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.9 + 0x8809: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.10 + 0x*: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.11 + parse_ethernet.0: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: parse_llc_header + parse_llc_header: + match: [ 0, 1 ] + 0xaaaa: + 0: llc_header.dsap + 1: llc_header.ssap + 2: llc_header.control_ + llc_header.$valid: 1 + shift: 3 + next: parse_snap_header + 0xfefe: + 0: llc_header.dsap + 1: llc_header.ssap + 2: llc_header.control_ + llc_header.$valid: 1 + shift: 3 + next: parse_set_prio_med + 0x*: + 0: llc_header.dsap + 1: llc_header.ssap + 2: llc_header.control_ + llc_header.$valid: 1 + shift: 3 + next: end + parse_snap_header: + match: [ 3..4 ] + 0x8100: + 0: snap_header.oui.16-23 + 1: snap_header.oui.8-15 + 2: snap_header.oui.0-7 + 3..4: snap_header.type_ + snap_header.$valid: 1 + shift: 5 + next: parse_vlan + 0x9100: + 0: snap_header.oui.16-23 + 1: snap_header.oui.8-15 + 2: snap_header.oui.0-7 + 3..4: snap_header.type_ + snap_header.$valid: 1 + shift: 5 + next: parse_qinq + 0x8847: + 0: snap_header.oui.16-23 + 1: snap_header.oui.8-15 + 2: snap_header.oui.0-7 + 3..4: snap_header.type_ + snap_header.$valid: 1 + shift: 5 + next: end + 0x0800: + 0: snap_header.oui.16-23 + 1: snap_header.oui.8-15 + 2: snap_header.oui.0-7 + 3..4: snap_header.type_ + snap_header.$valid: 1 + shift: 5 + next: parse_ipv4 + 0x86dd: + 0: snap_header.oui.16-23 + 1: snap_header.oui.8-15 + 2: snap_header.oui.0-7 + 3..4: snap_header.type_ + snap_header.$valid: 1 + shift: 5 + next: parse_ipv6 + 0x0806: + 0: snap_header.oui.16-23 + 1: snap_header.oui.8-15 + 2: snap_header.oui.0-7 + 3..4: snap_header.type_ + snap_header.$valid: 1 + shift: 5 + next: parse_arp_rarp + 0x88cc: + 0: snap_header.oui.16-23 + 1: snap_header.oui.8-15 + 2: snap_header.oui.0-7 + 3..4: snap_header.type_ + snap_header.$valid: 1 + shift: 5 + next: parse_set_prio_high + 0x8809: + 0: snap_header.oui.16-23 + 1: snap_header.oui.8-15 + 2: snap_header.oui.0-7 + 3..4: snap_header.type_ + snap_header.$valid: 1 + shift: 5 + next: parse_set_prio_high + 0x*: + 0: snap_header.oui.16-23 + 1: snap_header.oui.8-15 + 2: snap_header.oui.0-7 + 3..4: snap_header.type_ + snap_header.$valid: 1 + shift: 5 + next: end + parse_vlan: + match: [ 2..3 ] + 0x8847: + 0..1: H42 + 2..3: vlan_tag_$0.etherType + vlan_tag_$0.$valid: 1 + shift: 4 + next: end + 0x0800: + 0..1: H42 + 2..3: vlan_tag_$0.etherType + vlan_tag_$0.$valid: 1 + shift: 4 + next: parse_ipv4 + 0x86dd: + 0..1: H42 + 2..3: vlan_tag_$0.etherType + vlan_tag_$0.$valid: 1 + shift: 4 + next: parse_ipv6 + 0x0806: + 0..1: H42 + 2..3: vlan_tag_$0.etherType + vlan_tag_$0.$valid: 1 + shift: 4 + next: parse_arp_rarp + 0x88cc: + 0..1: H42 + 2..3: vlan_tag_$0.etherType + vlan_tag_$0.$valid: 1 + shift: 4 + next: parse_set_prio_high + 0x8809: + 0..1: H42 + 2..3: vlan_tag_$0.etherType + vlan_tag_$0.$valid: 1 + shift: 4 + next: parse_set_prio_high + 0x*: + 0..1: H42 + 2..3: vlan_tag_$0.etherType + vlan_tag_$0.$valid: 1 + shift: 4 + next: end + parse_ipv4: + match: [ 6..7, 0, 9 ] + 0x0000501: + 0: B49 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: H39 + 8: ipv4.ttl + 9: ipv4.protocol + 10..11: ipv4.hdrChecksum + 12..15: ipv4.srcAddr + 16..19: ipv4.dstAddr + shift: 20 + next: parse_ipv4.0 + 0x0000506: + 0: B49 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: H39 + 8: ipv4.ttl + 9: ipv4.protocol + 10..11: ipv4.hdrChecksum + 12..15: ipv4.srcAddr + 16..19: ipv4.dstAddr + shift: 20 + next: parse_ipv4.1 + 0x0000511: + 0: B49 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: H39 + 8: ipv4.ttl + 9: ipv4.protocol + 10..11: ipv4.hdrChecksum + 12..15: ipv4.srcAddr + 16..19: ipv4.dstAddr + shift: 20 + next: parse_ipv4.2 + 0x0000002: + 0: B49 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: H39 + 8: ipv4.ttl + 9: ipv4.protocol + 10..11: ipv4.hdrChecksum + 12..15: ipv4.srcAddr + 16..19: ipv4.dstAddr + shift: 20 + next: parse_ipv4.3 + 0x0000058: + 0: B49 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: H39 + 8: ipv4.ttl + 9: ipv4.protocol + 10..11: ipv4.hdrChecksum + 12..15: ipv4.srcAddr + 16..19: ipv4.dstAddr + shift: 20 + next: parse_ipv4.4 + 0x0000059: + 0: B49 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: H39 + 8: ipv4.ttl + 9: ipv4.protocol + 10..11: ipv4.hdrChecksum + 12..15: ipv4.srcAddr + 16..19: ipv4.dstAddr + shift: 20 + next: parse_ipv4.5 + 0x0000067: + 0: B49 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: H39 + 8: ipv4.ttl + 9: ipv4.protocol + 10..11: ipv4.hdrChecksum + 12..15: ipv4.srcAddr + 16..19: ipv4.dstAddr + shift: 20 + next: parse_ipv4.6 + 0x0000070: + 0: B49 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: H39 + 8: ipv4.ttl + 9: ipv4.protocol + 10..11: ipv4.hdrChecksum + 12..15: ipv4.srcAddr + 16..19: ipv4.dstAddr + shift: 20 + next: parse_ipv4.7 + 0x*: + 0: B49 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: H39 + 8: ipv4.ttl + 9: ipv4.protocol + 10..11: ipv4.hdrChecksum + 12..15: ipv4.srcAddr + 16..19: ipv4.dstAddr + shift: 20 + next: parse_ipv4.8 + parse_ipv4.0: + 0x*: + ipv4.$valid: 1 + next: parse_icmp + parse_icmp: + match: [ 0..1 ] + 0o101***: + 0..1: icmp.typeCode + 2..3: icmp.hdrChecksum + icmp.$valid: 1 + l3_metadata.lkp_outer_l4_sport: 0 /* ingress::icmp.typeCode; */ + shift: 4 + next: parse_set_prio_med + 0b100001**********: + 0..1: icmp.typeCode + 2..3: icmp.hdrChecksum + icmp.$valid: 1 + l3_metadata.lkp_outer_l4_sport: 0 /* ingress::icmp.typeCode; */ + shift: 4 + next: parse_set_prio_med + 0x88**: + 0..1: icmp.typeCode + 2..3: icmp.hdrChecksum + icmp.$valid: 1 + l3_metadata.lkp_outer_l4_sport: 0 /* ingress::icmp.typeCode; */ + shift: 4 + next: parse_set_prio_med + 0x*: + 0..1: icmp.typeCode + 2..3: icmp.hdrChecksum + icmp.$valid: 1 + l3_metadata.lkp_outer_l4_sport: 0 /* ingress::icmp.typeCode; */ + shift: 4 + next: end + parse_set_prio_med: + 0x*: + ig_prsr_ctrl.priority: 3 + next: end + parse_ipv4.1: + 0x*: + ipv4.$valid: 1 + next: parse_tcp + parse_tcp: + match: [ 2..3 ] + 0x00b3: + 0..1: tcp.srcPort + 2..3: tcp.dstPort + 4..7: tcp.seqNo + 8..11: tcp.ackNo + 12: TB6 + 13: tcp.flags + 14..15: tcp.window + 16..17: tcp.checksum + shift: 18 + next: parse_tcp.0 + 0x027f: + 0..1: tcp.srcPort + 2..3: tcp.dstPort + 4..7: tcp.seqNo + 8..11: tcp.ackNo + 12: TB6 + 13: tcp.flags + 14..15: tcp.window + 16..17: tcp.checksum + shift: 18 + next: parse_tcp.1 + 0x*: + 0..1: tcp.srcPort + 2..3: tcp.dstPort + 4..7: tcp.seqNo + 8..11: tcp.ackNo + 12: TB6 + 13: tcp.flags + 14..15: tcp.window + 16..17: tcp.checksum + shift: 18 + next: parse_tcp.2 + parse_tcp.0: + 0x*: + 0..1: tcp.urgentPtr + tcp.$valid: 1 + l3_metadata.lkp_outer_l4_sport: 0 /* ingress::tcp.srcPort; */ + l3_metadata.lkp_outer_l4_dport: 0 /* ingress::tcp.dstPort; */ + shift: 2 + next: parse_set_prio_med + parse_tcp.1: + 0x*: + 0..1: tcp.urgentPtr + tcp.$valid: 1 + l3_metadata.lkp_outer_l4_sport: 0 /* ingress::tcp.srcPort; */ + l3_metadata.lkp_outer_l4_dport: 0 /* ingress::tcp.dstPort; */ + shift: 2 + next: parse_set_prio_med + parse_tcp.2: + 0x*: + 0..1: tcp.urgentPtr + tcp.$valid: 1 + l3_metadata.lkp_outer_l4_sport: 0 /* ingress::tcp.srcPort; */ + l3_metadata.lkp_outer_l4_dport: 0 /* ingress::tcp.dstPort; */ + shift: 2 + next: end + parse_ipv4.2: + 0x*: + ipv4.$valid: 1 + next: parse_udp + parse_udp: + match: [ 2..3 ] + 0x0043: + 0..1: udp.srcPort + 2..3: udp.dstPort + 4..5: udp.length_ + 6..7: udp.checksum + udp.$valid: 1 + shift: 9 + next: parse_udp.0 + 0x0044: + 0..1: udp.srcPort + 2..3: udp.dstPort + 4..5: udp.length_ + 6..7: udp.checksum + udp.$valid: 1 + shift: 9 + next: parse_udp.1 + 0x0222: + 0..1: udp.srcPort + 2..3: udp.dstPort + 4..5: udp.length_ + 6..7: udp.checksum + udp.$valid: 1 + shift: 9 + next: parse_udp.2 + 0x0223: + 0..1: udp.srcPort + 2..3: udp.dstPort + 4..5: udp.length_ + 6..7: udp.checksum + udp.$valid: 1 + shift: 9 + next: parse_udp.3 + 0x0208: + 0..1: udp.srcPort + 2..3: udp.dstPort + 4..5: udp.length_ + 6..7: udp.checksum + udp.$valid: 1 + shift: 9 + next: parse_udp.4 + 0x0209: + 0..1: udp.srcPort + 2..3: udp.dstPort + 4..5: udp.length_ + 6..7: udp.checksum + udp.$valid: 1 + shift: 9 + next: parse_udp.5 + 0x07c1: + 0..1: udp.srcPort + 2..3: udp.dstPort + 4..5: udp.length_ + 6..7: udp.checksum + udp.$valid: 1 + shift: 9 + next: parse_udp.6 + 0x18c7: + 0..1: udp.srcPort + 2..3: udp.dstPort + 4..5: udp.length_ + 6..7: udp.checksum + udp.$valid: 1 + shift: 9 + next: parse_udp.7 + 0x*: + 0..1: udp.srcPort + 2..3: udp.dstPort + 4..5: udp.length_ + 6..7: udp.checksum + udp.$valid: 1 + shift: 9 + next: parse_udp.8 + parse_udp.0: + 0x*: + l3_metadata.lkp_outer_l4_sport: 0 /* ingress::udp.srcPort; */ + l3_metadata.lkp_outer_l4_dport: 0 /* ingress::udp.dstPort; */ + # shift: -1 + next: parse_set_prio_med + parse_udp.1: + 0x*: + l3_metadata.lkp_outer_l4_sport: 0 /* ingress::udp.srcPort; */ + l3_metadata.lkp_outer_l4_dport: 0 /* ingress::udp.dstPort; */ + # shift: -1 + next: parse_set_prio_med + parse_udp.2: + 0x*: + l3_metadata.lkp_outer_l4_sport: 0 /* ingress::udp.srcPort; */ + l3_metadata.lkp_outer_l4_dport: 0 /* ingress::udp.dstPort; */ + # shift: -1 + next: parse_set_prio_med + parse_udp.3: + 0x*: + l3_metadata.lkp_outer_l4_sport: 0 /* ingress::udp.srcPort; */ + l3_metadata.lkp_outer_l4_dport: 0 /* ingress::udp.dstPort; */ + # shift: -1 + next: parse_set_prio_med + parse_udp.4: + 0x*: + l3_metadata.lkp_outer_l4_sport: 0 /* ingress::udp.srcPort; */ + l3_metadata.lkp_outer_l4_dport: 0 /* ingress::udp.dstPort; */ + # shift: -1 + next: parse_set_prio_med + parse_udp.5: + 0x*: + l3_metadata.lkp_outer_l4_sport: 0 /* ingress::udp.srcPort; */ + l3_metadata.lkp_outer_l4_dport: 0 /* ingress::udp.dstPort; */ + # shift: -1 + next: parse_set_prio_med + parse_udp.6: + 0x*: + l3_metadata.lkp_outer_l4_sport: 0 /* ingress::udp.srcPort; */ + l3_metadata.lkp_outer_l4_dport: 0 /* ingress::udp.dstPort; */ + # shift: -1 + next: parse_set_prio_med + parse_udp.7: + 0x*: + l3_metadata.lkp_outer_l4_sport: 0 /* ingress::udp.srcPort; */ + l3_metadata.lkp_outer_l4_dport: 0 /* ingress::udp.dstPort; */ + # shift: -1 + next: end + parse_udp.8: + 0x*: + l3_metadata.lkp_outer_l4_sport: 0 /* ingress::udp.srcPort; */ + l3_metadata.lkp_outer_l4_dport: 0 /* ingress::udp.dstPort; */ + # shift: -1 + next: end + parse_ipv4.3: + 0x*: + ipv4.$valid: 1 + next: parse_set_prio_med + parse_ipv4.4: + 0x*: + ipv4.$valid: 1 + next: parse_set_prio_med + parse_ipv4.5: + 0x*: + ipv4.$valid: 1 + next: parse_set_prio_med + parse_ipv4.6: + 0x*: + ipv4.$valid: 1 + next: parse_set_prio_med + parse_ipv4.7: + 0x*: + ipv4.$valid: 1 + next: parse_set_prio_med + parse_ipv4.8: + 0x*: + ipv4.$valid: 1 + next: end + parse_ipv6: + match: [ 6 ] + 0x3a: + 0..3: W12 + 4..5: ipv6.payloadLen + 6: ipv6.nextHdr + 7: ipv6.hopLimit + 8..11: ipv6.srcAddr.96-127 + 12..15: ipv6.srcAddr.64-95 + 16..19: ipv6.srcAddr.32-63 + shift: 20 + next: parse_ipv6.0 + 0x06: + 0..3: W12 + 4..5: ipv6.payloadLen + 6: ipv6.nextHdr + 7: ipv6.hopLimit + 8..11: ipv6.srcAddr.96-127 + 12..15: ipv6.srcAddr.64-95 + 16..19: ipv6.srcAddr.32-63 + shift: 20 + next: parse_ipv6.1 + 0x04: + 0..3: W12 + 4..5: ipv6.payloadLen + 6: ipv6.nextHdr + 7: ipv6.hopLimit + 8..11: ipv6.srcAddr.96-127 + 12..15: ipv6.srcAddr.64-95 + 16..19: ipv6.srcAddr.32-63 + shift: 20 + next: parse_ipv6.2 + 0x58: + 0..3: W12 + 4..5: ipv6.payloadLen + 6: ipv6.nextHdr + 7: ipv6.hopLimit + 8..11: ipv6.srcAddr.96-127 + 12..15: ipv6.srcAddr.64-95 + 16..19: ipv6.srcAddr.32-63 + shift: 20 + next: parse_ipv6.3 + 0x59: + 0..3: W12 + 4..5: ipv6.payloadLen + 6: ipv6.nextHdr + 7: ipv6.hopLimit + 8..11: ipv6.srcAddr.96-127 + 12..15: ipv6.srcAddr.64-95 + 16..19: ipv6.srcAddr.32-63 + shift: 20 + next: parse_ipv6.4 + 0x67: + 0..3: W12 + 4..5: ipv6.payloadLen + 6: ipv6.nextHdr + 7: ipv6.hopLimit + 8..11: ipv6.srcAddr.96-127 + 12..15: ipv6.srcAddr.64-95 + 16..19: ipv6.srcAddr.32-63 + shift: 20 + next: parse_ipv6.5 + 0x70: + 0..3: W12 + 4..5: ipv6.payloadLen + 6: ipv6.nextHdr + 7: ipv6.hopLimit + 8..11: ipv6.srcAddr.96-127 + 12..15: ipv6.srcAddr.64-95 + 16..19: ipv6.srcAddr.32-63 + shift: 20 + next: parse_ipv6.6 + 0x*: + 0..3: W12 + 4..5: ipv6.payloadLen + 6: ipv6.nextHdr + 7: ipv6.hopLimit + 8..11: ipv6.srcAddr.96-127 + 12..15: ipv6.srcAddr.64-95 + 16..19: ipv6.srcAddr.32-63 + shift: 20 + next: parse_ipv6.7 + parse_ipv6.0: + 0x*: + 0..3: ipv6.srcAddr.0-31 + 4..7: ipv6.dstAddr.96-127 + 8..11: ipv6.dstAddr.64-95 + 12..15: ipv6.dstAddr.32-63 + shift: 16 + next: parse_ipv6.0.0 + parse_ipv6.0.0: + 0x*: + 0..3: ipv6.dstAddr.0-31 + ipv6.$valid: 1 + shift: 4 + next: parse_icmp + parse_ipv6.1: + 0x*: + 0..3: ipv6.srcAddr.0-31 + 4..7: ipv6.dstAddr.96-127 + 8..11: ipv6.dstAddr.64-95 + 12..15: ipv6.dstAddr.32-63 + shift: 16 + next: parse_ipv6.1.0 + parse_ipv6.1.0: + 0x*: + 0..3: ipv6.dstAddr.0-31 + ipv6.$valid: 1 + shift: 4 + next: parse_tcp + parse_ipv6.2: + 0x*: + 0..3: ipv6.srcAddr.0-31 + 4..7: ipv6.dstAddr.96-127 + 8..11: ipv6.dstAddr.64-95 + 12..15: ipv6.dstAddr.32-63 + shift: 16 + next: parse_ipv6.2.0 + parse_ipv6.2.0: + 0x*: + 0..3: ipv6.dstAddr.0-31 + ipv6.$valid: 1 + shift: 4 + next: parse_ipv4_in_ip + parse_ipv4_in_ip: + 0x*: + tunnel_metadata.ingress_tunnel_type: 3 + next: parse_inner_ipv4 + parse_inner_ipv4: + match: [ 6..7, 0, 9 ] + 0x0000501: + 0: B12 + 1: inner_ipv4.diffserv + 2..3: inner_ipv4.totalLen + 4..5: inner_ipv4.identification + 6..7: H34 + 8: inner_ipv4.ttl + 9: inner_ipv4.protocol + 10..11: inner_ipv4.hdrChecksum + 12..15: inner_ipv4.srcAddr + 16..19: inner_ipv4.dstAddr + shift: 20 + next: parse_inner_ipv4.0 + 0x0000506: + 0: B12 + 1: inner_ipv4.diffserv + 2..3: inner_ipv4.totalLen + 4..5: inner_ipv4.identification + 6..7: H34 + 8: inner_ipv4.ttl + 9: inner_ipv4.protocol + 10..11: inner_ipv4.hdrChecksum + 12..15: inner_ipv4.srcAddr + 16..19: inner_ipv4.dstAddr + shift: 20 + next: parse_inner_ipv4.1 + 0x0000511: + 0: B12 + 1: inner_ipv4.diffserv + 2..3: inner_ipv4.totalLen + 4..5: inner_ipv4.identification + 6..7: H34 + 8: inner_ipv4.ttl + 9: inner_ipv4.protocol + 10..11: inner_ipv4.hdrChecksum + 12..15: inner_ipv4.srcAddr + 16..19: inner_ipv4.dstAddr + shift: 20 + next: parse_inner_ipv4.2 + 0x*: + 0: B12 + 1: inner_ipv4.diffserv + 2..3: inner_ipv4.totalLen + 4..5: inner_ipv4.identification + 6..7: H34 + 8: inner_ipv4.ttl + 9: inner_ipv4.protocol + 10..11: inner_ipv4.hdrChecksum + 12..15: inner_ipv4.srcAddr + 16..19: inner_ipv4.dstAddr + shift: 20 + next: parse_inner_ipv4.3 + parse_inner_ipv4.0: + 0x*: + inner_ipv4.$valid: 1 + ipv4_metadata.lkp_ipv4_sa: 0 /* ingress::inner_ipv4.srcAddr; */ + ipv4_metadata.lkp_ipv4_da: 0 /* ingress::inner_ipv4.dstAddr; */ + l3_metadata.lkp_ip_proto: 0 /* ingress::inner_ipv4.protocol; */ + l3_metadata.lkp_ip_ttl: 0 /* ingress::inner_ipv4.ttl; */ + next: parse_inner_icmp + parse_inner_icmp: + 0x*: + 0..1: inner_icmp.typeCode + 2..3: inner_icmp.hdrChecksum + inner_icmp.$valid: 1 + l3_metadata.lkp_l4_sport: 0 /* ingress::inner_icmp.typeCode; */ + shift: 4 + next: end + parse_inner_ipv4.1: + 0x*: + inner_ipv4.$valid: 1 + ipv4_metadata.lkp_ipv4_sa: 0 /* ingress::inner_ipv4.srcAddr; */ + ipv4_metadata.lkp_ipv4_da: 0 /* ingress::inner_ipv4.dstAddr; */ + l3_metadata.lkp_ip_proto: 0 /* ingress::inner_ipv4.protocol; */ + l3_metadata.lkp_ip_ttl: 0 /* ingress::inner_ipv4.ttl; */ + next: parse_inner_tcp + parse_inner_tcp: + 0x*: + 0..1: inner_tcp.srcPort + 2..3: inner_tcp.dstPort + 4..7: inner_tcp.seqNo + 8..11: inner_tcp.ackNo + 12: TB5 + 13: inner_tcp.flags + 14..15: inner_tcp.window + 16..17: inner_tcp.checksum + shift: 18 + next: parse_inner_tcp.0 + parse_inner_tcp.0: + 0x*: + 0..1: inner_tcp.urgentPtr + inner_tcp.$valid: 1 + l3_metadata.lkp_l4_sport: 0 /* ingress::inner_tcp.srcPort; */ + l3_metadata.lkp_l4_dport: 0 /* ingress::inner_tcp.dstPort; */ + shift: 2 + next: end + parse_inner_ipv4.2: + 0x*: + inner_ipv4.$valid: 1 + ipv4_metadata.lkp_ipv4_sa: 0 /* ingress::inner_ipv4.srcAddr; */ + ipv4_metadata.lkp_ipv4_da: 0 /* ingress::inner_ipv4.dstAddr; */ + l3_metadata.lkp_ip_proto: 0 /* ingress::inner_ipv4.protocol; */ + l3_metadata.lkp_ip_ttl: 0 /* ingress::inner_ipv4.ttl; */ + next: parse_inner_udp + parse_inner_udp: + 0x*: + 0..1: inner_udp.srcPort + 2..3: inner_udp.dstPort + 4..5: inner_udp.length_ + 6..7: inner_udp.checksum + inner_udp.$valid: 1 + shift: 9 + next: parse_inner_udp.0 + parse_inner_udp.0: + 0x*: + l3_metadata.lkp_l4_sport: 0 /* ingress::inner_udp.srcPort; */ + l3_metadata.lkp_l4_dport: 0 /* ingress::inner_udp.dstPort; */ + # shift: -1 + next: end + parse_inner_ipv4.3: + 0x*: + inner_ipv4.$valid: 1 + ipv4_metadata.lkp_ipv4_sa: 0 /* ingress::inner_ipv4.srcAddr; */ + ipv4_metadata.lkp_ipv4_da: 0 /* ingress::inner_ipv4.dstAddr; */ + l3_metadata.lkp_ip_proto: 0 /* ingress::inner_ipv4.protocol; */ + l3_metadata.lkp_ip_ttl: 0 /* ingress::inner_ipv4.ttl; */ + next: end + parse_ipv6.3: + 0x*: + 0..3: ipv6.srcAddr.0-31 + 4..7: ipv6.dstAddr.96-127 + 8..11: ipv6.dstAddr.64-95 + 12..15: ipv6.dstAddr.32-63 + shift: 16 + next: parse_ipv6.3.0 + parse_ipv6.3.0: + 0x*: + 0..3: ipv6.dstAddr.0-31 + ipv6.$valid: 1 + shift: 4 + next: parse_set_prio_med + parse_ipv6.4: + 0x*: + 0..3: ipv6.srcAddr.0-31 + 4..7: ipv6.dstAddr.96-127 + 8..11: ipv6.dstAddr.64-95 + 12..15: ipv6.dstAddr.32-63 + shift: 16 + next: parse_ipv6.4.0 + parse_ipv6.4.0: + 0x*: + 0..3: ipv6.dstAddr.0-31 + ipv6.$valid: 1 + shift: 4 + next: parse_set_prio_med + parse_ipv6.5: + 0x*: + 0..3: ipv6.srcAddr.0-31 + 4..7: ipv6.dstAddr.96-127 + 8..11: ipv6.dstAddr.64-95 + 12..15: ipv6.dstAddr.32-63 + shift: 16 + next: parse_ipv6.5.0 + parse_ipv6.5.0: + 0x*: + 0..3: ipv6.dstAddr.0-31 + ipv6.$valid: 1 + shift: 4 + next: parse_set_prio_med + parse_ipv6.6: + 0x*: + 0..3: ipv6.srcAddr.0-31 + 4..7: ipv6.dstAddr.96-127 + 8..11: ipv6.dstAddr.64-95 + 12..15: ipv6.dstAddr.32-63 + shift: 16 + next: parse_ipv6.6.0 + parse_ipv6.6.0: + 0x*: + 0..3: ipv6.dstAddr.0-31 + ipv6.$valid: 1 + shift: 4 + next: parse_set_prio_med + parse_ipv6.7: + 0x*: + 0..3: ipv6.srcAddr.0-31 + 4..7: ipv6.dstAddr.96-127 + 8..11: ipv6.dstAddr.64-95 + 12..15: ipv6.dstAddr.32-63 + shift: 16 + next: parse_ipv6.7.0 + parse_ipv6.7.0: + 0x*: + 0..3: ipv6.dstAddr.0-31 + ipv6.$valid: 1 + shift: 4 + next: end + parse_arp_rarp: + 0x*: + next: parse_set_prio_med + parse_set_prio_high: + 0x*: + ig_prsr_ctrl.priority: 5 + next: end + parse_qinq: + match: [ 2..3 ] + 0x8100: + 0..1: H42 + 2..3: vlan_tag_$0.etherType + vlan_tag_$0.$valid: 1 + shift: 4 + next: parse_qinq_vlan + 0x*: + 0..1: H42 + 2..3: vlan_tag_$0.etherType + vlan_tag_$0.$valid: 1 + shift: 4 + next: end + parse_qinq_vlan: + match: [ 2..3 ] + 0x8847: + 0..1: H32 + 2..3: vlan_tag_$1.etherType + vlan_tag_$1.$valid: 1 + shift: 4 + next: end + 0x0800: + 0..1: H32 + 2..3: vlan_tag_$1.etherType + vlan_tag_$1.$valid: 1 + shift: 4 + next: parse_ipv4 + 0x86dd: + 0..1: H32 + 2..3: vlan_tag_$1.etherType + vlan_tag_$1.$valid: 1 + shift: 4 + next: parse_ipv6 + 0x0806: + 0..1: H32 + 2..3: vlan_tag_$1.etherType + vlan_tag_$1.$valid: 1 + shift: 4 + next: parse_arp_rarp + 0x88cc: + 0..1: H32 + 2..3: vlan_tag_$1.etherType + vlan_tag_$1.$valid: 1 + shift: 4 + next: parse_set_prio_high + 0x8809: + 0..1: H32 + 2..3: vlan_tag_$1.etherType + vlan_tag_$1.$valid: 1 + shift: 4 + next: parse_set_prio_high + 0x*: + 0..1: H32 + 2..3: vlan_tag_$1.etherType + vlan_tag_$1.$valid: 1 + shift: 4 + next: end + parse_ethernet.1: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: parse_llc_header + parse_ethernet.2: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: parse_fabric_header + parse_fabric_header: + match: [ 0 ] + 0x5: + 0: TB4 + 1: TB3 + 2: fabric_header.dstDevice + 3..4: fabric_header.dstPortOrGroup + fabric_header.$valid: 1 + shift: 5 + next: parse_fabric_header_cpu + 0x*: + 0: TB4 + 1: TB3 + 2: fabric_header.dstDevice + 3..4: fabric_header.dstPortOrGroup + fabric_header.$valid: 1 + shift: 5 + next: end + parse_fabric_header_cpu: + match: [ 7..8 ] + 0x*: + 0: B0 + 1..2: fabric_header_cpu.ingressPort + 3..4: fabric_header_cpu.ingressIfindex + 5..6: fabric_header_cpu.ingressBd + 7..8: fabric_header_cpu.reasonCode + fabric_header_cpu.$valid: 1 + shift: 10 + next: parse_fabric_header_cpu.0 + parse_fabric_header_cpu.0: + 0x*: + ingress_metadata.bypass_lookups: 0 /* ingress::fabric_header_cpu.reasonCode; */ + # shift: -1 + next: parse_fabric_payload_header + parse_fabric_payload_header: + match: [ 0..1 ] + 0o000***: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: parse_llc_header + 0b00000*0*********: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: parse_llc_header + 0x8100: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: parse_vlan + 0x9100: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: parse_qinq + 0x8847: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: end + 0x0800: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: parse_ipv4 + 0x86dd: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: parse_ipv6 + 0x0806: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: parse_arp_rarp + 0x88cc: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: parse_set_prio_high + 0x8809: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: parse_set_prio_high + 0x*: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: end + parse_ethernet.3: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: parse_vlan + parse_ethernet.4: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: parse_qinq + parse_ethernet.5: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: end + parse_ethernet.6: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: parse_ipv4 + parse_ethernet.7: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: parse_ipv6 + parse_ethernet.8: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: parse_arp_rarp + parse_ethernet.9: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: parse_set_prio_high + parse_ethernet.10: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: parse_set_prio_high + parse_ethernet.11: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: end +deparser ingress: + dictionary: + ingress_metadata.ifindex: $always_deparse + H15: $always_deparse + H3: $always_deparse + B1: $always_deparse + B59: $always_deparse + fabric_metadata.reason_code: $always_deparse + l3_metadata.nexthop_index: $always_deparse + ethernet.dstAddr.32-47: ethernet.$valid + ethernet.dstAddr.16-31: ethernet.$valid + ethernet.dstAddr.0-15: ethernet.$valid + ethernet.srcAddr.32-47: ethernet.$valid + ethernet.srcAddr.16-31: ethernet.$valid + ethernet.srcAddr.0-15: ethernet.$valid + ethernet.etherType: ethernet.$valid + TB4: fabric_header.$valid + TB3: fabric_header.$valid + fabric_header.dstDevice: fabric_header.$valid + fabric_header.dstPortOrGroup: fabric_header.$valid + B0: fabric_header_cpu.$valid + fabric_header_cpu.ingressPort: fabric_header_cpu.$valid + fabric_header_cpu.ingressIfindex: fabric_header_cpu.$valid + fabric_header_cpu.ingressBd: fabric_header_cpu.$valid + fabric_header_cpu.reasonCode: fabric_header_cpu.$valid + fabric_payload_header.etherType: fabric_payload_header.$valid + llc_header.dsap: llc_header.$valid + llc_header.ssap: llc_header.$valid + llc_header.control_: llc_header.$valid + snap_header.oui.16-23: snap_header.$valid + snap_header.oui.8-15: snap_header.$valid + snap_header.oui.0-7: snap_header.$valid + snap_header.type_: snap_header.$valid + H42: vlan_tag_$0.$valid + vlan_tag_$0.etherType: vlan_tag_$0.$valid + H32: vlan_tag_$1.$valid + vlan_tag_$1.etherType: vlan_tag_$1.$valid + W12: ipv6.$valid + ipv6.payloadLen: ipv6.$valid + ipv6.nextHdr: ipv6.$valid + ipv6.hopLimit: ipv6.$valid + ipv6.srcAddr.96-127: ipv6.$valid + ipv6.srcAddr.64-95: ipv6.$valid + ipv6.srcAddr.32-63: ipv6.$valid + ipv6.srcAddr.0-31: ipv6.$valid + ipv6.dstAddr.96-127: ipv6.$valid + ipv6.dstAddr.64-95: ipv6.$valid + ipv6.dstAddr.32-63: ipv6.$valid + ipv6.dstAddr.0-31: ipv6.$valid + B12: inner_ipv4.$valid + inner_ipv4.diffserv: inner_ipv4.$valid + inner_ipv4.totalLen: inner_ipv4.$valid + inner_ipv4.identification: inner_ipv4.$valid + H34: inner_ipv4.$valid + inner_ipv4.ttl: inner_ipv4.$valid + inner_ipv4.protocol: inner_ipv4.$valid + inner_ipv4.hdrChecksum: inner_ipv4.$valid + inner_ipv4.srcAddr: inner_ipv4.$valid + inner_ipv4.dstAddr: inner_ipv4.$valid + inner_udp.srcPort: inner_udp.$valid + inner_udp.dstPort: inner_udp.$valid + inner_udp.length_: inner_udp.$valid + inner_udp.checksum: inner_udp.$valid + inner_tcp.srcPort: inner_tcp.$valid + inner_tcp.dstPort: inner_tcp.$valid + inner_tcp.seqNo: inner_tcp.$valid + inner_tcp.ackNo: inner_tcp.$valid + TB5: inner_tcp.$valid + inner_tcp.flags: inner_tcp.$valid + inner_tcp.window: inner_tcp.$valid + inner_tcp.checksum: inner_tcp.$valid + inner_tcp.urgentPtr: inner_tcp.$valid + inner_icmp.typeCode: inner_icmp.$valid + inner_icmp.hdrChecksum: inner_icmp.$valid + B49: ipv4.$valid + ipv4.diffserv: ipv4.$valid + ipv4.totalLen: ipv4.$valid + ipv4.identification: ipv4.$valid + H39: ipv4.$valid + ipv4.ttl: ipv4.$valid + ipv4.protocol: ipv4.$valid + ipv4.hdrChecksum: ipv4.$valid + ipv4.srcAddr: ipv4.$valid + ipv4.dstAddr: ipv4.$valid + udp.srcPort: udp.$valid + udp.dstPort: udp.$valid + udp.length_: udp.$valid + udp.checksum: udp.$valid + tcp.srcPort: tcp.$valid + tcp.dstPort: tcp.$valid + tcp.seqNo: tcp.$valid + tcp.ackNo: tcp.$valid + TB6: tcp.$valid + tcp.flags: tcp.$valid + tcp.window: tcp.$valid + tcp.checksum: tcp.$valid + tcp.urgentPtr: tcp.$valid + icmp.typeCode: icmp.$valid + icmp.hdrChecksum: icmp.$valid + egress_unicast_port: standard_metadata.egress_spec + learning: + 0: [ $learning, H3, l2_metadata.lkp_mac_sa.32-47, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.0-15, ingress_metadata.ifindex ] + select: $learning +parser egress: + start: $egress_metadata_shim + $egress_metadata_shim: + 0x*: + 0..1: H16 + shift: 2 + next: $bridge_metadata_extract + $bridge_metadata_extract: + 0x*: + 0..1: ingress_metadata.ifindex + 2..3: H25 + shift: 4 + next: $bridge_metadata_extract.0 + $bridge_metadata_extract.0: + 0x*: + 0: B22 + shift: 1 + next: $bridge_metadata_extract.1 + $bridge_metadata_extract.1: + 0x*: + 0..1: H22 + shift: 2 + next: $bridge_metadata_extract.2 + $bridge_metadata_extract.2: + 0x*: + 0: B36 + shift: 1 + next: $bridge_metadata_extract.3 + $bridge_metadata_extract.3: + 0x*: + 0..1: H49 + shift: 1 + next: $bridge_metadata_extract.4 + $bridge_metadata_extract.4: + 0x*: + 0..1: fabric_metadata.reason_code + 2..3: l3_metadata.nexthop_index + shift: 4 + next: start$ + start$: + match: [ /* packet.lookahead>()[15:0]; */ ] + 0x*: + next: parse_ethernet + parse_ethernet: + match: [ 12..13 ] + 0o000***: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.0 + 0b00000*0*********: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.1 + 0x9000: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.2 + 0x8100: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.3 + 0x9100: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.4 + 0x8847: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.5 + 0x0800: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.6 + 0x86dd: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.7 + 0x0806: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.8 + 0x88cc: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.9 + 0x8809: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.10 + 0x*: + 0..1: ethernet.dstAddr.32-47 + 2..3: ethernet.dstAddr.16-31 + 4..5: ethernet.dstAddr.0-15 + 6..7: ethernet.srcAddr.32-47 + shift: 8 + next: parse_ethernet.11 + parse_ethernet.0: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: parse_llc_header + parse_llc_header: + match: [ 0, 1 ] + 0xaaaa: + 0: llc_header.dsap + 1: llc_header.ssap + 2: llc_header.control_ + llc_header.$valid: 1 + shift: 3 + next: parse_snap_header + 0xfefe: + 0: llc_header.dsap + 1: llc_header.ssap + 2: llc_header.control_ + llc_header.$valid: 1 + shift: 3 + next: end + 0x*: + 0: llc_header.dsap + 1: llc_header.ssap + 2: llc_header.control_ + llc_header.$valid: 1 + shift: 3 + next: end + parse_snap_header: + match: [ 3..4 ] + 0x8100: + 0: snap_header.oui.16-23 + 1: snap_header.oui.8-15 + 2: snap_header.oui.0-7 + 3..4: snap_header.type_ + snap_header.$valid: 1 + shift: 5 + next: parse_vlan + 0x9100: + 0: snap_header.oui.16-23 + 1: snap_header.oui.8-15 + 2: snap_header.oui.0-7 + 3..4: snap_header.type_ + snap_header.$valid: 1 + shift: 5 + next: parse_qinq + 0x8847: + 0: snap_header.oui.16-23 + 1: snap_header.oui.8-15 + 2: snap_header.oui.0-7 + 3..4: snap_header.type_ + snap_header.$valid: 1 + shift: 5 + next: end + 0x0800: + 0: snap_header.oui.16-23 + 1: snap_header.oui.8-15 + 2: snap_header.oui.0-7 + 3..4: snap_header.type_ + snap_header.$valid: 1 + shift: 5 + next: parse_ipv4 + 0x86dd: + 0: snap_header.oui.16-23 + 1: snap_header.oui.8-15 + 2: snap_header.oui.0-7 + 3..4: snap_header.type_ + snap_header.$valid: 1 + shift: 5 + next: parse_ipv6 + 0x0806: + 0: snap_header.oui.16-23 + 1: snap_header.oui.8-15 + 2: snap_header.oui.0-7 + 3..4: snap_header.type_ + snap_header.$valid: 1 + shift: 5 + next: end + 0x88cc: + 0: snap_header.oui.16-23 + 1: snap_header.oui.8-15 + 2: snap_header.oui.0-7 + 3..4: snap_header.type_ + snap_header.$valid: 1 + shift: 5 + next: end + 0x8809: + 0: snap_header.oui.16-23 + 1: snap_header.oui.8-15 + 2: snap_header.oui.0-7 + 3..4: snap_header.type_ + snap_header.$valid: 1 + shift: 5 + next: end + 0x*: + 0: snap_header.oui.16-23 + 1: snap_header.oui.8-15 + 2: snap_header.oui.0-7 + 3..4: snap_header.type_ + snap_header.$valid: 1 + shift: 5 + next: end + parse_vlan: + match: [ 2..3 ] + 0x8847: + 0..1: H51 + 2..3: vlan_tag_$0.etherType + vlan_tag_$0.$valid: 1 + shift: 4 + next: end + 0x0800: + 0..1: H51 + 2..3: vlan_tag_$0.etherType + vlan_tag_$0.$valid: 1 + shift: 4 + next: parse_ipv4 + 0x86dd: + 0..1: H51 + 2..3: vlan_tag_$0.etherType + vlan_tag_$0.$valid: 1 + shift: 4 + next: parse_ipv6 + 0x0806: + 0..1: H51 + 2..3: vlan_tag_$0.etherType + vlan_tag_$0.$valid: 1 + shift: 4 + next: end + 0x88cc: + 0..1: H51 + 2..3: vlan_tag_$0.etherType + vlan_tag_$0.$valid: 1 + shift: 4 + next: end + 0x8809: + 0..1: H51 + 2..3: vlan_tag_$0.etherType + vlan_tag_$0.$valid: 1 + shift: 4 + next: end + 0x*: + 0..1: H51 + 2..3: vlan_tag_$0.etherType + vlan_tag_$0.$valid: 1 + shift: 4 + next: end + parse_ipv4: + match: [ 6..7, 0, 9 ] + 0x0000501: + 0: B46 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: TH33 + 8: ipv4.ttl + 9: ipv4.protocol + 10..11: ipv4.hdrChecksum + shift: 12 + next: parse_ipv4.0 + 0x0000506: + 0: B46 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: TH33 + 8: ipv4.ttl + 9: ipv4.protocol + 10..11: ipv4.hdrChecksum + shift: 12 + next: parse_ipv4.1 + 0x0000511: + 0: B46 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: TH33 + 8: ipv4.ttl + 9: ipv4.protocol + 10..11: ipv4.hdrChecksum + shift: 12 + next: parse_ipv4.2 + 0x0000002: + 0: B46 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: TH33 + 8: ipv4.ttl + 9: ipv4.protocol + 10..11: ipv4.hdrChecksum + shift: 12 + next: parse_ipv4.3 + 0x0000058: + 0: B46 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: TH33 + 8: ipv4.ttl + 9: ipv4.protocol + 10..11: ipv4.hdrChecksum + shift: 12 + next: parse_ipv4.4 + 0x0000059: + 0: B46 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: TH33 + 8: ipv4.ttl + 9: ipv4.protocol + 10..11: ipv4.hdrChecksum + shift: 12 + next: parse_ipv4.5 + 0x0000067: + 0: B46 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: TH33 + 8: ipv4.ttl + 9: ipv4.protocol + 10..11: ipv4.hdrChecksum + shift: 12 + next: parse_ipv4.6 + 0x0000070: + 0: B46 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: TH33 + 8: ipv4.ttl + 9: ipv4.protocol + 10..11: ipv4.hdrChecksum + shift: 12 + next: parse_ipv4.7 + 0x*: + 0: B46 + 1: ipv4.diffserv + 2..3: ipv4.totalLen + 4..5: ipv4.identification + 6..7: TH33 + 8: ipv4.ttl + 9: ipv4.protocol + 10..11: ipv4.hdrChecksum + shift: 12 + next: parse_ipv4.8 + parse_ipv4.0: + 0x*: + 0..1: ipv4.srcAddr.16-31 + 2..3: ipv4.srcAddr.0-15 + 4..7: ipv4.dstAddr + ipv4.$valid: 1 + shift: 8 + next: parse_icmp + parse_icmp: + match: [ 0..1 ] + 0o101***: + 0..1: icmp.typeCode + 2..3: icmp.hdrChecksum + icmp.$valid: 1 + shift: 4 + next: end + 0b100001**********: + 0..1: icmp.typeCode + 2..3: icmp.hdrChecksum + icmp.$valid: 1 + shift: 4 + next: end + 0x88**: + 0..1: icmp.typeCode + 2..3: icmp.hdrChecksum + icmp.$valid: 1 + shift: 4 + next: end + 0x*: + 0..1: icmp.typeCode + 2..3: icmp.hdrChecksum + icmp.$valid: 1 + shift: 4 + next: end + parse_ipv4.1: + 0x*: + 0..1: ipv4.srcAddr.16-31 + 2..3: ipv4.srcAddr.0-15 + 4..7: ipv4.dstAddr + ipv4.$valid: 1 + shift: 8 + next: parse_tcp + parse_tcp: + match: [ 2..3 ] + 0x00b3: + 0..1: tcp.srcPort + 2..3: tcp.dstPort + 4..7: tcp.seqNo + 8..11: tcp.ackNo + 12: B28 + 13: tcp.flags + 14..15: tcp.window + 16..17: tcp.checksum + shift: 18 + next: parse_tcp.0 + 0x027f: + 0..1: tcp.srcPort + 2..3: tcp.dstPort + 4..7: tcp.seqNo + 8..11: tcp.ackNo + 12: B28 + 13: tcp.flags + 14..15: tcp.window + 16..17: tcp.checksum + shift: 18 + next: parse_tcp.1 + 0x*: + 0..1: tcp.srcPort + 2..3: tcp.dstPort + 4..7: tcp.seqNo + 8..11: tcp.ackNo + 12: B28 + 13: tcp.flags + 14..15: tcp.window + 16..17: tcp.checksum + shift: 18 + next: parse_tcp.2 + parse_tcp.0: + 0x*: + 0..1: tcp.urgentPtr + tcp.$valid: 1 + shift: 2 + next: end + parse_tcp.1: + 0x*: + 0..1: tcp.urgentPtr + tcp.$valid: 1 + shift: 2 + next: end + parse_tcp.2: + 0x*: + 0..1: tcp.urgentPtr + tcp.$valid: 1 + shift: 2 + next: end + parse_ipv4.2: + 0x*: + 0..1: ipv4.srcAddr.16-31 + 2..3: ipv4.srcAddr.0-15 + 4..7: ipv4.dstAddr + ipv4.$valid: 1 + shift: 8 + next: parse_udp + parse_udp: + match: [ 2..3 ] + 0x0043: + 0: udp.srcPort.8-15 + 1: udp.srcPort.0-7 + 2: udp.dstPort.8-15 + 3: udp.dstPort.0-7 + shift: 4 + next: parse_udp.0 + 0x0044: + 0: udp.srcPort.8-15 + 1: udp.srcPort.0-7 + 2: udp.dstPort.8-15 + 3: udp.dstPort.0-7 + shift: 4 + next: parse_udp.1 + 0x0222: + 0: udp.srcPort.8-15 + 1: udp.srcPort.0-7 + 2: udp.dstPort.8-15 + 3: udp.dstPort.0-7 + shift: 4 + next: parse_udp.2 + 0x0223: + 0: udp.srcPort.8-15 + 1: udp.srcPort.0-7 + 2: udp.dstPort.8-15 + 3: udp.dstPort.0-7 + shift: 4 + next: parse_udp.3 + 0x0208: + 0: udp.srcPort.8-15 + 1: udp.srcPort.0-7 + 2: udp.dstPort.8-15 + 3: udp.dstPort.0-7 + shift: 4 + next: parse_udp.4 + 0x0209: + 0: udp.srcPort.8-15 + 1: udp.srcPort.0-7 + 2: udp.dstPort.8-15 + 3: udp.dstPort.0-7 + shift: 4 + next: parse_udp.5 + 0x07c1: + 0: udp.srcPort.8-15 + 1: udp.srcPort.0-7 + 2: udp.dstPort.8-15 + 3: udp.dstPort.0-7 + shift: 4 + next: parse_udp.6 + 0x18c7: + 0: udp.srcPort.8-15 + 1: udp.srcPort.0-7 + 2: udp.dstPort.8-15 + 3: udp.dstPort.0-7 + shift: 4 + next: parse_udp.7 + 0x*: + 0: udp.srcPort.8-15 + 1: udp.srcPort.0-7 + 2: udp.dstPort.8-15 + 3: udp.dstPort.0-7 + shift: 4 + next: parse_udp.8 + parse_udp.0: + 0x*: + 0: udp.length_.8-15 + 1: udp.length_.0-7 + 2: udp.checksum.8-15 + 3: udp.checksum.0-7 + shift: 4 + next: parse_udp.0.0 + parse_udp.0.0: + 0x*: + udp.$valid: 1 + next: end + parse_udp.1: + 0x*: + 0: udp.length_.8-15 + 1: udp.length_.0-7 + 2: udp.checksum.8-15 + 3: udp.checksum.0-7 + shift: 4 + next: parse_udp.1.0 + parse_udp.1.0: + 0x*: + udp.$valid: 1 + next: end + parse_udp.2: + 0x*: + 0: udp.length_.8-15 + 1: udp.length_.0-7 + 2: udp.checksum.8-15 + 3: udp.checksum.0-7 + shift: 4 + next: parse_udp.2.0 + parse_udp.2.0: + 0x*: + udp.$valid: 1 + next: end + parse_udp.3: + 0x*: + 0: udp.length_.8-15 + 1: udp.length_.0-7 + 2: udp.checksum.8-15 + 3: udp.checksum.0-7 + shift: 4 + next: parse_udp.3.0 + parse_udp.3.0: + 0x*: + udp.$valid: 1 + next: end + parse_udp.4: + 0x*: + 0: udp.length_.8-15 + 1: udp.length_.0-7 + 2: udp.checksum.8-15 + 3: udp.checksum.0-7 + shift: 4 + next: parse_udp.4.0 + parse_udp.4.0: + 0x*: + udp.$valid: 1 + next: end + parse_udp.5: + 0x*: + 0: udp.length_.8-15 + 1: udp.length_.0-7 + 2: udp.checksum.8-15 + 3: udp.checksum.0-7 + shift: 4 + next: parse_udp.5.0 + parse_udp.5.0: + 0x*: + udp.$valid: 1 + next: end + parse_udp.6: + 0x*: + 0: udp.length_.8-15 + 1: udp.length_.0-7 + 2: udp.checksum.8-15 + 3: udp.checksum.0-7 + shift: 4 + next: parse_udp.6.0 + parse_udp.6.0: + 0x*: + udp.$valid: 1 + next: end + parse_udp.7: + 0x*: + 0: udp.length_.8-15 + 1: udp.length_.0-7 + 2: udp.checksum.8-15 + 3: udp.checksum.0-7 + shift: 4 + next: parse_udp.7.0 + parse_udp.7.0: + 0x*: + udp.$valid: 1 + next: end + parse_udp.8: + 0x*: + 0: udp.length_.8-15 + 1: udp.length_.0-7 + 2: udp.checksum.8-15 + 3: udp.checksum.0-7 + shift: 4 + next: parse_udp.8.0 + parse_udp.8.0: + 0x*: + udp.$valid: 1 + next: end + parse_ipv4.3: + 0x*: + 0..1: ipv4.srcAddr.16-31 + 2..3: ipv4.srcAddr.0-15 + 4..7: ipv4.dstAddr + ipv4.$valid: 1 + shift: 8 + next: end + parse_ipv4.4: + 0x*: + 0..1: ipv4.srcAddr.16-31 + 2..3: ipv4.srcAddr.0-15 + 4..7: ipv4.dstAddr + ipv4.$valid: 1 + shift: 8 + next: end + parse_ipv4.5: + 0x*: + 0..1: ipv4.srcAddr.16-31 + 2..3: ipv4.srcAddr.0-15 + 4..7: ipv4.dstAddr + ipv4.$valid: 1 + shift: 8 + next: end + parse_ipv4.6: + 0x*: + 0..1: ipv4.srcAddr.16-31 + 2..3: ipv4.srcAddr.0-15 + 4..7: ipv4.dstAddr + ipv4.$valid: 1 + shift: 8 + next: end + parse_ipv4.7: + 0x*: + 0..1: ipv4.srcAddr.16-31 + 2..3: ipv4.srcAddr.0-15 + 4..7: ipv4.dstAddr + ipv4.$valid: 1 + shift: 8 + next: end + parse_ipv4.8: + 0x*: + 0..1: ipv4.srcAddr.16-31 + 2..3: ipv4.srcAddr.0-15 + 4..7: ipv4.dstAddr + ipv4.$valid: 1 + shift: 8 + next: end + parse_ipv6: + match: [ 6 ] + 0x3a: + 0..3: TW24 + 4: ipv6.payloadLen.8-15 + 5: ipv6.payloadLen.0-7 + 6: ipv6.nextHdr + 7: ipv6.hopLimit + 8..11: ipv6.srcAddr.96-127 + 12..15: ipv6.srcAddr.64-95 + 16..19: ipv6.srcAddr.32-63 + shift: 20 + next: parse_ipv6.0 + 0x06: + 0..3: TW24 + 4: ipv6.payloadLen.8-15 + 5: ipv6.payloadLen.0-7 + 6: ipv6.nextHdr + 7: ipv6.hopLimit + 8..11: ipv6.srcAddr.96-127 + 12..15: ipv6.srcAddr.64-95 + 16..19: ipv6.srcAddr.32-63 + shift: 20 + next: parse_ipv6.1 + 0x04: + 0..3: TW24 + 4: ipv6.payloadLen.8-15 + 5: ipv6.payloadLen.0-7 + 6: ipv6.nextHdr + 7: ipv6.hopLimit + 8..11: ipv6.srcAddr.96-127 + 12..15: ipv6.srcAddr.64-95 + 16..19: ipv6.srcAddr.32-63 + shift: 20 + next: parse_ipv6.2 + 0x58: + 0..3: TW24 + 4: ipv6.payloadLen.8-15 + 5: ipv6.payloadLen.0-7 + 6: ipv6.nextHdr + 7: ipv6.hopLimit + 8..11: ipv6.srcAddr.96-127 + 12..15: ipv6.srcAddr.64-95 + 16..19: ipv6.srcAddr.32-63 + shift: 20 + next: parse_ipv6.3 + 0x59: + 0..3: TW24 + 4: ipv6.payloadLen.8-15 + 5: ipv6.payloadLen.0-7 + 6: ipv6.nextHdr + 7: ipv6.hopLimit + 8..11: ipv6.srcAddr.96-127 + 12..15: ipv6.srcAddr.64-95 + 16..19: ipv6.srcAddr.32-63 + shift: 20 + next: parse_ipv6.4 + 0x67: + 0..3: TW24 + 4: ipv6.payloadLen.8-15 + 5: ipv6.payloadLen.0-7 + 6: ipv6.nextHdr + 7: ipv6.hopLimit + 8..11: ipv6.srcAddr.96-127 + 12..15: ipv6.srcAddr.64-95 + 16..19: ipv6.srcAddr.32-63 + shift: 20 + next: parse_ipv6.5 + 0x70: + 0..3: TW24 + 4: ipv6.payloadLen.8-15 + 5: ipv6.payloadLen.0-7 + 6: ipv6.nextHdr + 7: ipv6.hopLimit + 8..11: ipv6.srcAddr.96-127 + 12..15: ipv6.srcAddr.64-95 + 16..19: ipv6.srcAddr.32-63 + shift: 20 + next: parse_ipv6.6 + 0x*: + 0..3: TW24 + 4: ipv6.payloadLen.8-15 + 5: ipv6.payloadLen.0-7 + 6: ipv6.nextHdr + 7: ipv6.hopLimit + 8..11: ipv6.srcAddr.96-127 + 12..15: ipv6.srcAddr.64-95 + 16..19: ipv6.srcAddr.32-63 + shift: 20 + next: parse_ipv6.7 + parse_ipv6.0: + 0x*: + 0..3: ipv6.srcAddr.0-31 + 4..7: ipv6.dstAddr.96-127 + 8..11: ipv6.dstAddr.64-95 + 12..15: ipv6.dstAddr.32-63 + shift: 16 + next: parse_ipv6.0.0 + parse_ipv6.0.0: + 0x*: + 0..3: ipv6.dstAddr.0-31 + ipv6.$valid: 1 + shift: 4 + next: parse_icmp + parse_ipv6.1: + 0x*: + 0..3: ipv6.srcAddr.0-31 + 4..7: ipv6.dstAddr.96-127 + 8..11: ipv6.dstAddr.64-95 + 12..15: ipv6.dstAddr.32-63 + shift: 16 + next: parse_ipv6.1.0 + parse_ipv6.1.0: + 0x*: + 0..3: ipv6.dstAddr.0-31 + ipv6.$valid: 1 + shift: 4 + next: parse_tcp + parse_ipv6.2: + 0x*: + 0..3: ipv6.srcAddr.0-31 + 4..7: ipv6.dstAddr.96-127 + 8..11: ipv6.dstAddr.64-95 + 12..15: ipv6.dstAddr.32-63 + shift: 16 + next: parse_ipv6.2.0 + parse_ipv6.2.0: + 0x*: + 0..3: ipv6.dstAddr.0-31 + ipv6.$valid: 1 + shift: 4 + next: parse_ipv4_in_ip + parse_ipv4_in_ip: + 0x*: + next: parse_inner_ipv4 + parse_inner_ipv4: + match: [ 6..7, 0, 9 ] + 0x0000501: + 0: B26 + 1: inner_ipv4.diffserv + 2: inner_ipv4.totalLen.8-15 + 3: inner_ipv4.totalLen.0-7 + 4..5: inner_ipv4.identification + 6..7: TH32 + shift: 8 + next: parse_inner_ipv4.0 + 0x0000506: + 0: B26 + 1: inner_ipv4.diffserv + 2: inner_ipv4.totalLen.8-15 + 3: inner_ipv4.totalLen.0-7 + 4..5: inner_ipv4.identification + 6..7: TH32 + shift: 8 + next: parse_inner_ipv4.1 + 0x0000511: + 0: B26 + 1: inner_ipv4.diffserv + 2: inner_ipv4.totalLen.8-15 + 3: inner_ipv4.totalLen.0-7 + 4..5: inner_ipv4.identification + 6..7: TH32 + shift: 8 + next: parse_inner_ipv4.2 + 0x*: + 0: B26 + 1: inner_ipv4.diffserv + 2: inner_ipv4.totalLen.8-15 + 3: inner_ipv4.totalLen.0-7 + 4..5: inner_ipv4.identification + 6..7: TH32 + shift: 8 + next: parse_inner_ipv4.3 + parse_inner_ipv4.0: + 0x*: + 0: inner_ipv4.ttl + 1: inner_ipv4.protocol + 2..3: inner_ipv4.hdrChecksum + 4..7: inner_ipv4.srcAddr + 8..11: inner_ipv4.dstAddr + inner_ipv4.$valid: 1 + shift: 12 + next: parse_inner_icmp + parse_inner_icmp: + 0x*: + 0..1: inner_icmp.typeCode + 2..3: inner_icmp.hdrChecksum + inner_icmp.$valid: 1 + shift: 4 + next: end + parse_inner_ipv4.1: + 0x*: + 0: inner_ipv4.ttl + 1: inner_ipv4.protocol + 2..3: inner_ipv4.hdrChecksum + 4..7: inner_ipv4.srcAddr + 8..11: inner_ipv4.dstAddr + inner_ipv4.$valid: 1 + shift: 12 + next: parse_inner_tcp + parse_inner_tcp: + 0x*: + 0..1: inner_tcp.srcPort + 2..3: inner_tcp.dstPort + 4..7: inner_tcp.seqNo + 8..11: inner_tcp.ackNo + 12: B24 + 13: inner_tcp.flags + 14..15: inner_tcp.window + 16..17: inner_tcp.checksum + shift: 18 + next: parse_inner_tcp.0 + parse_inner_tcp.0: + 0x*: + 0..1: inner_tcp.urgentPtr + inner_tcp.$valid: 1 + shift: 2 + next: end + parse_inner_ipv4.2: + 0x*: + 0: inner_ipv4.ttl + 1: inner_ipv4.protocol + 2..3: inner_ipv4.hdrChecksum + 4..7: inner_ipv4.srcAddr + 8..11: inner_ipv4.dstAddr + inner_ipv4.$valid: 1 + shift: 12 + next: parse_inner_udp + parse_inner_udp: + 0x*: + 0..1: inner_udp.srcPort + 2..3: inner_udp.dstPort + 4..5: inner_udp.length_ + 6..7: inner_udp.checksum + inner_udp.$valid: 1 + shift: 8 + next: end + parse_inner_ipv4.3: + 0x*: + 0: inner_ipv4.ttl + 1: inner_ipv4.protocol + 2..3: inner_ipv4.hdrChecksum + 4..7: inner_ipv4.srcAddr + 8..11: inner_ipv4.dstAddr + inner_ipv4.$valid: 1 + shift: 12 + next: end + parse_ipv6.3: + 0x*: + 0..3: ipv6.srcAddr.0-31 + 4..7: ipv6.dstAddr.96-127 + 8..11: ipv6.dstAddr.64-95 + 12..15: ipv6.dstAddr.32-63 + shift: 16 + next: parse_ipv6.3.0 + parse_ipv6.3.0: + 0x*: + 0..3: ipv6.dstAddr.0-31 + ipv6.$valid: 1 + shift: 4 + next: end + parse_ipv6.4: + 0x*: + 0..3: ipv6.srcAddr.0-31 + 4..7: ipv6.dstAddr.96-127 + 8..11: ipv6.dstAddr.64-95 + 12..15: ipv6.dstAddr.32-63 + shift: 16 + next: parse_ipv6.4.0 + parse_ipv6.4.0: + 0x*: + 0..3: ipv6.dstAddr.0-31 + ipv6.$valid: 1 + shift: 4 + next: end + parse_ipv6.5: + 0x*: + 0..3: ipv6.srcAddr.0-31 + 4..7: ipv6.dstAddr.96-127 + 8..11: ipv6.dstAddr.64-95 + 12..15: ipv6.dstAddr.32-63 + shift: 16 + next: parse_ipv6.5.0 + parse_ipv6.5.0: + 0x*: + 0..3: ipv6.dstAddr.0-31 + ipv6.$valid: 1 + shift: 4 + next: end + parse_ipv6.6: + 0x*: + 0..3: ipv6.srcAddr.0-31 + 4..7: ipv6.dstAddr.96-127 + 8..11: ipv6.dstAddr.64-95 + 12..15: ipv6.dstAddr.32-63 + shift: 16 + next: parse_ipv6.6.0 + parse_ipv6.6.0: + 0x*: + 0..3: ipv6.dstAddr.0-31 + ipv6.$valid: 1 + shift: 4 + next: end + parse_ipv6.7: + 0x*: + 0..3: ipv6.srcAddr.0-31 + 4..7: ipv6.dstAddr.96-127 + 8..11: ipv6.dstAddr.64-95 + 12..15: ipv6.dstAddr.32-63 + shift: 16 + next: parse_ipv6.7.0 + parse_ipv6.7.0: + 0x*: + 0..3: ipv6.dstAddr.0-31 + ipv6.$valid: 1 + shift: 4 + next: end + parse_qinq: + match: [ 2..3 ] + 0x8100: + 0..1: H51 + 2..3: vlan_tag_$0.etherType + vlan_tag_$0.$valid: 1 + shift: 4 + next: parse_qinq_vlan + 0x*: + 0..1: H51 + 2..3: vlan_tag_$0.etherType + vlan_tag_$0.$valid: 1 + shift: 4 + next: end + parse_qinq_vlan: + match: [ 2..3 ] + 0x8847: + 0..1: H50 + 2..3: vlan_tag_$1.etherType + vlan_tag_$1.$valid: 1 + shift: 4 + next: end + 0x0800: + 0..1: H50 + 2..3: vlan_tag_$1.etherType + vlan_tag_$1.$valid: 1 + shift: 4 + next: parse_ipv4 + 0x86dd: + 0..1: H50 + 2..3: vlan_tag_$1.etherType + vlan_tag_$1.$valid: 1 + shift: 4 + next: parse_ipv6 + 0x0806: + 0..1: H50 + 2..3: vlan_tag_$1.etherType + vlan_tag_$1.$valid: 1 + shift: 4 + next: end + 0x88cc: + 0..1: H50 + 2..3: vlan_tag_$1.etherType + vlan_tag_$1.$valid: 1 + shift: 4 + next: end + 0x8809: + 0..1: H50 + 2..3: vlan_tag_$1.etherType + vlan_tag_$1.$valid: 1 + shift: 4 + next: end + 0x*: + 0..1: H50 + 2..3: vlan_tag_$1.etherType + vlan_tag_$1.$valid: 1 + shift: 4 + next: end + parse_ethernet.1: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: parse_llc_header + parse_ethernet.2: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: parse_fabric_header + parse_fabric_header: + match: [ 0 ] + 0x5: + 0: B19 + 1: TB19 + 2: fabric_header.dstDevice + 3..4: fabric_header.dstPortOrGroup + fabric_header.$valid: 1 + shift: 5 + next: parse_fabric_header_cpu + 0x*: + 0: B19 + 1: TB19 + 2: fabric_header.dstDevice + 3..4: fabric_header.dstPortOrGroup + fabric_header.$valid: 1 + shift: 5 + next: end + parse_fabric_header_cpu: + match: [ 7..8 ] + 0x*: + 0: B38 + 1..2: fabric_header_cpu.ingressPort + 3..4: fabric_header_cpu.ingressIfindex + 5..6: fabric_header_cpu.ingressBd + 7..8: fabric_header_cpu.reasonCode + fabric_header_cpu.$valid: 1 + shift: 9 + next: parse_fabric_payload_header + parse_fabric_payload_header: + match: [ 0..1 ] + 0o000***: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: parse_llc_header + 0b00000*0*********: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: parse_llc_header + 0x8100: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: parse_vlan + 0x9100: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: parse_qinq + 0x8847: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: end + 0x0800: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: parse_ipv4 + 0x86dd: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: parse_ipv6 + 0x0806: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: end + 0x88cc: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: end + 0x8809: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: end + 0x*: + 0..1: fabric_payload_header.etherType + fabric_payload_header.$valid: 1 + shift: 2 + next: end + parse_ethernet.3: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: parse_vlan + parse_ethernet.4: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: parse_qinq + parse_ethernet.5: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: end + parse_ethernet.6: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: parse_ipv4 + parse_ethernet.7: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: parse_ipv6 + parse_ethernet.8: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: end + parse_ethernet.9: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: end + parse_ethernet.10: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: end + parse_ethernet.11: + 0x*: + 0..1: ethernet.srcAddr.16-31 + 2..3: ethernet.srcAddr.0-15 + 4..5: ethernet.etherType + ethernet.$valid: 1 + shift: 6 + next: end +deparser egress: + dictionary: + ethernet.dstAddr.32-47: ethernet.$valid + ethernet.dstAddr.16-31: ethernet.$valid + ethernet.dstAddr.0-15: ethernet.$valid + ethernet.srcAddr.32-47: ethernet.$valid + ethernet.srcAddr.16-31: ethernet.$valid + ethernet.srcAddr.0-15: ethernet.$valid + ethernet.etherType: ethernet.$valid + B19: fabric_header.$valid + TB19: fabric_header.$valid + fabric_header.dstDevice: fabric_header.$valid + fabric_header.dstPortOrGroup: fabric_header.$valid + B38: fabric_header_cpu.$valid + fabric_header_cpu.ingressPort: fabric_header_cpu.$valid + fabric_header_cpu.ingressIfindex: fabric_header_cpu.$valid + fabric_header_cpu.ingressBd: fabric_header_cpu.$valid + fabric_header_cpu.reasonCode: fabric_header_cpu.$valid + fabric_payload_header.etherType: fabric_payload_header.$valid + llc_header.dsap: llc_header.$valid + llc_header.ssap: llc_header.$valid + llc_header.control_: llc_header.$valid + snap_header.oui.16-23: snap_header.$valid + snap_header.oui.8-15: snap_header.$valid + snap_header.oui.0-7: snap_header.$valid + snap_header.type_: snap_header.$valid + H51: vlan_tag_$0.$valid + vlan_tag_$0.etherType: vlan_tag_$0.$valid + H51: vlan_tag_$0.$valid + vlan_tag_$0.etherType: vlan_tag_$0.$valid + H50: vlan_tag_$1.$valid + vlan_tag_$1.etherType: vlan_tag_$1.$valid + B46: ipv4.$valid + ipv4.diffserv: ipv4.$valid + ipv4.totalLen: ipv4.$valid + ipv4.identification: ipv4.$valid + TH33: ipv4.$valid + ipv4.ttl: ipv4.$valid + ipv4.protocol: ipv4.$valid + ipv4.hdrChecksum: ipv4.$valid + ipv4.srcAddr.16-31: ipv4.$valid + ipv4.srcAddr.0-15: ipv4.$valid + ipv4.dstAddr: ipv4.$valid + udp.srcPort.8-15: udp.$valid + udp.srcPort.0-7: udp.$valid + udp.dstPort.8-15: udp.$valid + udp.dstPort.0-7: udp.$valid + udp.length_.8-15: udp.$valid + udp.length_.0-7: udp.$valid + udp.checksum.8-15: udp.$valid + udp.checksum.0-7: udp.$valid + TW24: ipv6.$valid + ipv6.payloadLen.8-15: ipv6.$valid + ipv6.payloadLen.0-7: ipv6.$valid + ipv6.nextHdr: ipv6.$valid + ipv6.hopLimit: ipv6.$valid + ipv6.srcAddr.96-127: ipv6.$valid + ipv6.srcAddr.64-95: ipv6.$valid + ipv6.srcAddr.32-63: ipv6.$valid + ipv6.srcAddr.0-31: ipv6.$valid + ipv6.dstAddr.96-127: ipv6.$valid + ipv6.dstAddr.64-95: ipv6.$valid + ipv6.dstAddr.32-63: ipv6.$valid + ipv6.dstAddr.0-31: ipv6.$valid + tcp.srcPort: tcp.$valid + tcp.dstPort: tcp.$valid + tcp.seqNo: tcp.$valid + tcp.ackNo: tcp.$valid + B28: tcp.$valid + tcp.flags: tcp.$valid + tcp.window: tcp.$valid + tcp.checksum: tcp.$valid + tcp.urgentPtr: tcp.$valid + icmp.typeCode: icmp.$valid + icmp.hdrChecksum: icmp.$valid + B26: inner_ipv4.$valid + inner_ipv4.diffserv: inner_ipv4.$valid + inner_ipv4.totalLen.8-15: inner_ipv4.$valid + inner_ipv4.totalLen.0-7: inner_ipv4.$valid + inner_ipv4.identification: inner_ipv4.$valid + TH32: inner_ipv4.$valid + inner_ipv4.ttl: inner_ipv4.$valid + inner_ipv4.protocol: inner_ipv4.$valid + inner_ipv4.hdrChecksum: inner_ipv4.$valid + inner_ipv4.srcAddr: inner_ipv4.$valid + inner_ipv4.dstAddr: inner_ipv4.$valid + inner_icmp.typeCode: inner_icmp.$valid + inner_icmp.hdrChecksum: inner_icmp.$valid + inner_tcp.srcPort: inner_tcp.$valid + inner_tcp.dstPort: inner_tcp.$valid + inner_tcp.seqNo: inner_tcp.$valid + inner_tcp.ackNo: inner_tcp.$valid + B24: inner_tcp.$valid + inner_tcp.flags: inner_tcp.$valid + inner_tcp.window: inner_tcp.$valid + inner_tcp.checksum: inner_tcp.$valid + inner_tcp.urgentPtr: inner_tcp.$valid + inner_udp.srcPort: inner_udp.$valid + inner_udp.dstPort: inner_udp.$valid + inner_udp.length_: inner_udp.$valid + inner_udp.checksum: inner_udp.$valid + egress_unicast_port: standard_metadata.egress_port + mirror: + 0: [ $mirror, $mirror_id, H22, ingress_metadata.ifindex, fabric_metadata.reason_code, H25 ] + 1: [ $mirror, $mirror_id, H22, ingress_metadata.ifindex, fabric_metadata.reason_code, H25 ] + 2: [ $mirror, $mirror_id, H22, ingress_metadata.ifindex, fabric_metadata.reason_code, H25 ] + 3: [ $mirror, $mirror_id, H22, ingress_metadata.ifindex, fabric_metadata.reason_code, H25 ] + select: $mirror +stage 0 ingress: + phase0_match ingress_port_mapping: + p4: + name: ingress_port_mapping + size: 288 + preferred_match_type: exact + match_type: exact + size: 288 + width: 1 + format: {ifindex: 48..63, port_type: 46..47} + constant_value: 0 + exact_match _switch_config_params_0 0: + p4: { name: switch_config_params, size: 1 } + row: 0 + bus: 0 + column: [ ] + next: _validate_outer_ethernet_0 + action_bus: { } + actions: + set_config_parameters: + - p4_param_order: {enable_dod: 1, enable_flowlet: 8, switch_id: 32 } + - { $constant0: immediate(0..8), $constant0: 511 } + - set ingress_metadata.ingress_port, standard_metadata.ingress_port + - set l2_metadata.same_if_check, ingress_metadata.ifindex + - set standard_metadata.egress_spec, $constant0 + NoAction: + - { } + default_action: NoAction + ternary_match _validate_outer_ethernet_0 1: + p4: { name: validate_outer_ethernet, size: 64 } + p4_param_order: + ethernet.srcAddr: { type: ternary, size: 48} + ethernet.dstAddr: { type: ternary, size: 48} + vlan_tag_$0.$valid: { type: exact, size: 1} + vlan_tag_$1.$valid: { type: exact, size: 1} + row: [ 0, 1, 2 ] + bus: [ 0, 0, 0 ] + column: + - 0 + - 0 + - 0 + input_xbar: + group 0: { 0: ethernet.dstAddr.0-15, 16: ethernet.dstAddr.16-31, 32: ethernet.dstAddr.32-47(0..7) } + group 1: { 0: ethernet.srcAddr.0-15(0..7), 8: ethernet.dstAddr.32-47(8..15), 16: ethernet.srcAddr.16-31(0..7), 24: ethernet.srcAddr.0-15(8..15), 32: ethernet.srcAddr.32-47(0..7), 43: vlan_tag_$0.$valid } + group 2: { 0: ethernet.srcAddr.16-31(8..15), 16: ethernet.srcAddr.32-47(8..15), 38: vlan_tag_$1.$valid } + next: _adjust_lkp_fields_0 + action_bus: { } + indirect: _validate_outer_ethernet_0$tind + ternary_indirect _validate_outer_ethernet_0$tind: + row: 0 + bus: 0 + column: 2 + format: { action: 8..13, immediate: 0..7} + actions: + malformed_outer_ethernet_packet: + - p4_param_order: {drop_reason: 8 } + - { drop_reason: immediate(0..7) } + - set ingress_metadata.drop_flag, 1 + - set ingress_metadata.drop_reason, drop_reason + set_valid_outer_unicast_packet_untagged: + - { } + - set l2_metadata.lkp_pkt_type, 1 + - set l2_metadata.lkp_mac_type, ethernet.etherType + set_valid_outer_unicast_packet_single_tagged: + - { } + - set l2_metadata.lkp_pkt_type, 1 + - set l2_metadata.lkp_mac_type, vlan_tag_$0.etherType + set_valid_outer_unicast_packet_double_tagged: + - { } + - set l2_metadata.lkp_pkt_type, 1 + - set l2_metadata.lkp_mac_type, vlan_tag_$1.etherType + set_valid_outer_unicast_packet_qinq_tagged: + - { } + - set l2_metadata.lkp_pkt_type, 1 + - set l2_metadata.lkp_mac_type, ethernet.etherType + set_valid_outer_multicast_packet_untagged: + - { } + - set l2_metadata.lkp_pkt_type, 2 + - set l2_metadata.lkp_mac_type, ethernet.etherType + set_valid_outer_multicast_packet_single_tagged: + - { } + - set l2_metadata.lkp_pkt_type, 2 + - set l2_metadata.lkp_mac_type, vlan_tag_$0.etherType + set_valid_outer_multicast_packet_double_tagged: + - { } + - set l2_metadata.lkp_pkt_type, 2 + - set l2_metadata.lkp_mac_type, vlan_tag_$1.etherType + set_valid_outer_multicast_packet_qinq_tagged: + - { } + - set l2_metadata.lkp_pkt_type, 2 + - set l2_metadata.lkp_mac_type, ethernet.etherType + set_valid_outer_broadcast_packet_untagged: + - { } + - set l2_metadata.lkp_pkt_type, 4 + - set l2_metadata.lkp_mac_type, ethernet.etherType + set_valid_outer_broadcast_packet_single_tagged: + - { } + - set l2_metadata.lkp_pkt_type, 4 + - set l2_metadata.lkp_mac_type, vlan_tag_$0.etherType + set_valid_outer_broadcast_packet_double_tagged: + - { } + - set l2_metadata.lkp_pkt_type, 4 + - set l2_metadata.lkp_mac_type, vlan_tag_$1.etherType + set_valid_outer_broadcast_packet_qinq_tagged: + - { } + - set l2_metadata.lkp_pkt_type, 4 + - set l2_metadata.lkp_mac_type, ethernet.etherType + NoAction: + - { } + default_action: NoAction + exact_match _adjust_lkp_fields_0 2: + p4: { name: adjust_lkp_fields } + p4_param_order: + ipv4.$valid: { type: exact, size: 1} + ipv6.$valid: { type: exact, size: 1} + row: 2 + bus: 0 + column: [ 2, 3, 4 ] + ways: + - [0, 0, 0x0, [2, 2]] + - [0, 1, 0x0, [2, 3]] + - [0, 2, 0x0, [2, 4]] + input_xbar: + group 0: { 7: ipv4.$valid, 15: ipv6.$valid } + hash 0: + 0..9: stripe(ipv4.$valid, ipv6.$valid) + 10..19: stripe(ipv4.$valid, ipv6.$valid) + 20..29: stripe(ipv4.$valid, ipv6.$valid) + hash group 0: + table: [0] + format: { action(0): 0..1, version(0): 112..115 } + next: _port_vlan_mapping_0 + actions: + non_ip_lkp: + - set l2_metadata.lkp_mac_da.0-15, ethernet.dstAddr.0-15 + - set l2_metadata.lkp_mac_da.16-31, ethernet.dstAddr.16-31 + - set l2_metadata.lkp_mac_da.32-47, ethernet.dstAddr.32-47 + - set l2_metadata.lkp_mac_sa.0-15, ethernet.srcAddr.0-15 + - set l2_metadata.lkp_mac_sa.16-31, ethernet.srcAddr.16-31 + - set l2_metadata.lkp_mac_sa.32-47, ethernet.srcAddr.32-47 + ipv4_lkp: + - set ipv4_metadata.lkp_ipv4_sa, ipv4.srcAddr + - set ipv4_metadata.lkp_ipv4_da, ipv4.dstAddr + - set l3_metadata.lkp_ip_proto, ipv4.protocol + - set l3_metadata.lkp_ip_ttl, ipv4.ttl + - set l3_metadata.lkp_l4_sport, l3_metadata.lkp_outer_l4_sport + - set l3_metadata.lkp_l4_dport, l3_metadata.lkp_outer_l4_dport + - set l2_metadata.lkp_mac_da.0-15, ethernet.dstAddr.0-15 + - set l2_metadata.lkp_mac_da.16-31, ethernet.dstAddr.16-31 + - set l2_metadata.lkp_mac_da.32-47, ethernet.dstAddr.32-47 + - set l2_metadata.lkp_mac_sa.0-15, ethernet.srcAddr.0-15 + - set l2_metadata.lkp_mac_sa.16-31, ethernet.srcAddr.16-31 + - set l2_metadata.lkp_mac_sa.32-47, ethernet.srcAddr.32-47 + NoAction: + - 0 + default_action: NoAction + exact_match _port_vlan_mapping_0 4: + p4: { name: port_vlan_mapping, size: 32768, action_profile: bd_action_profile } + p4_param_order: + ingress_metadata.ifindex: { type: exact, size: 16} + vlan_tag_$0.$valid: { type: exact, size: 1} + vlan_tag_$0.vid: { type: exact, size: 12} + vlan_tag_$1.$valid: { type: exact, size: 1} + vlan_tag_$1.vid: { type: exact, size: 12} + row: [ 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + ways: + - [2, 0, 0x7, [7, 2], [7, 3], [7, 4], [7, 6], [7, 7], [7, 8], [7, 9], [7, 10]] + - [2, 1, 0x38, [6, 2], [6, 3], [6, 4], [6, 6], [6, 7], [6, 8], [6, 9], [6, 10]] + - [2, 2, 0x1c0, [5, 2], [5, 3], [5, 4], [5, 6], [5, 7], [5, 8], [5, 9], [5, 10]] + - [2, 3, 0xe00, [4, 2], [4, 3], [4, 4], [4, 6], [4, 7], [4, 8], [4, 9], [4, 10]] + input_xbar: + group 1: { 0: ingress_metadata.ifindex, 16: vlan_tag_$0.vid(0..7), 31: vlan_tag_$0.$valid, 32: vlan_tag_$1.vid(0..7), 40: vlan_tag_$0.vid(8..11), 62: vlan_tag_$1.$valid, 72: vlan_tag_$1.vid(8..11) } + hash 2: + 0..9: random(ingress_metadata.ifindex, vlan_tag_$0.vid(0..7), vlan_tag_$1.vid(3..7)) ^ stripe(vlan_tag_$0.$valid, vlan_tag_$1.vid(0..2), vlan_tag_$0.vid(8..11), vlan_tag_$1.$valid) + 10..19: random(ingress_metadata.ifindex, vlan_tag_$0.vid(0..7), vlan_tag_$1.vid(3..7)) ^ stripe(vlan_tag_$0.$valid, vlan_tag_$1.vid(0..2), vlan_tag_$0.vid(8..11), vlan_tag_$1.$valid) + 20..29: random(ingress_metadata.ifindex, vlan_tag_$0.vid(0..7), vlan_tag_$1.vid(3..7)) ^ stripe(vlan_tag_$0.$valid, vlan_tag_$1.vid(0..2), vlan_tag_$0.vid(8..11), vlan_tag_$1.$valid) + 30..39: random(ingress_metadata.ifindex, vlan_tag_$0.vid(0..7), vlan_tag_$1.vid(3..7)) ^ stripe(vlan_tag_$0.$valid, vlan_tag_$1.vid(0..2), vlan_tag_$0.vid(8..11), vlan_tag_$1.$valid) + 40..51: random(ingress_metadata.ifindex, vlan_tag_$0.vid(0..7), vlan_tag_$1.vid(3..7)) ^ stripe(vlan_tag_$0.$valid, vlan_tag_$1.vid(0..2), vlan_tag_$0.vid(8..11), vlan_tag_$1.$valid) + hash 3: + 0..9: stripe(vlan_tag_$1.vid(8..11)) + 10..19: stripe(vlan_tag_$1.vid(8..11)) + 20..29: stripe(vlan_tag_$1.vid(8..11)) + 30..39: stripe(vlan_tag_$1.vid(8..11)) + 40..51: stripe(vlan_tag_$1.vid(8..11)) + hash group 2: + table: [2, 3] + format: { action(0): 15..16, version(0): 112..115, action_addr(0): 0..14, match(0): [40..47, 32..39, 48..55, 59..63 ] } + match: [ ingress_metadata.ifindex, vlan_tag_$0.vid(0..7), vlan_tag_$1.vid(3..7) ] + next: _ingress_port_properties_0 + action: _port_vlan_mapping_0$act_prof..bd_action_profile(action, action_addr) + default_action: NoAction + action _port_vlan_mapping_0$act_prof..bd_action_profile: + row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4 ] + column: + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - [ 3, 4, 5 ] + - 5 + - [ 3, 4, 5 ] + - 5 + home_row: [ 15, 5 ] + format set_bd_properties: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_b2: 16..23, $adf_h0: 32..47, $adf_h1: 48..63, $adf_h2: 64..79, $adf_h3: 80..95, $adf_h4: 96..111, $adf_h5: 112..127 } + action_bus: { 16 : $adf_b0, 17 : $adf_b1, 18 : $adf_b2, 64..65 : $adf_h2, 66..67 : $adf_h3, 68..69 : $adf_h4, 70..71 : $adf_h5, 40..41 : $adf_h0, 42..43 : $adf_h1 } + actions: + set_bd_properties: + - p4_param_order: {bd: 14, vrf: 14, stp_group: 10, learning_enabled: 1, bd_label: 16, stats_idx: 16, rmac_group: 10, ipv4_unicast_enabled: 1, ipv6_unicast_enabled: 1, ipv4_urpf_mode: 2, ipv6_urpf_mode: 2, igmp_snooping_enabled: 1, mld_snooping_enabled: 1, ipv4_multicast_enabled: 1, ipv6_multicast_enabled: 1, mrpf_group: 14, ipv4_mcast_key: 14, ipv4_mcast_key_type: 1, ipv6_mcast_key: 14, ipv6_mcast_key_type: 1, ingress_rid: 16 } + - { $data0: $adf_b0, igmp_snooping_enabled: $data0(6..6), mld_snooping_enabled: $data0(5..5), learning_enabled: $adf_b1, ipv4_unicast_enabled: $adf_b2, bd: $adf_h0, stats_idx: $adf_h1, ipv6_unicast_enabled: $adf_h2, stp_group: $adf_h3, rmac_group: $adf_h4, bd_label: $adf_h5 } + - set ingress_metadata.bd, bd + - set acl_metadata.bd_label, bd_label + - set l2_metadata.stp_group, stp_group + - set l2_metadata.bd_stats_idx, stats_idx + - set l2_metadata.learning_enabled, learning_enabled + - set ipv4_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled + - set ipv6_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled + - set l3_metadata.rmac_group, rmac_group + - set B55(5..6), $data0(5..6) + port_vlan_mapping_miss: + - { } + - set l2_metadata.port_vlan_mapping_miss, 1 + NoAction: + - { } + exact_match _ingress_port_properties_0 6: + p4: { name: ingress_port_properties, size: 288 } + p4_param_order: + standard_metadata.ingress_port: { type: exact, size: 9} + row: 3 + bus: 0 + column: [ 2, 3, 4 ] + ways: + - [4, 0, 0x0, [3, 2]] + - [4, 1, 0x0, [3, 3]] + - [4, 2, 0x0, [3, 4]] + input_xbar: + group 2: { 64: standard_metadata.ingress_port } + hash 5: + 0..9: random(standard_metadata.ingress_port(1..7)) ^ stripe(standard_metadata.ingress_port(0), standard_metadata.ingress_port(8)) + 10..19: random(standard_metadata.ingress_port(1..7)) ^ stripe(standard_metadata.ingress_port(0), standard_metadata.ingress_port(8)) + 20..29: random(standard_metadata.ingress_port(1..7)) ^ stripe(standard_metadata.ingress_port(0), standard_metadata.ingress_port(8)) + hash group 4: + table: [5] + format: { action(0): 16..16, immediate(0): 0..15, version(0): 112..115, match(0): 33..39 } + match: [ standard_metadata.ingress_port(1..7) ] + next: _compute_ipv4_hashes_0 + action_bus: { } + actions: + set_ingress_port_properties: + - p4_param_order: {if_label: 16, exclusion_id: 9, qos_group: 5, tc_qos_group: 5, tc: 8, color: 2, trust_dscp: 1, trust_pcp: 1 } + - { if_label: immediate(0..15) } + - set acl_metadata.if_label, if_label + NoAction: + - { } + default_action: NoAction +stage 1 ingress: + exact_match _compute_ipv4_hashes_0 0: + p4: { name: compute_ipv4_hashes } + p4_param_order: + ethernet.$valid: { type: exact, size: 1} + row: 0 + bus: 0 + column: [ 2, 3, 4 ] + ways: + - [0, 0, 0x0, [0, 2]] + - [0, 1, 0x0, [0, 3]] + - [0, 2, 0x0, [0, 4]] + hash_dist: + 2: {hash: 1, mask: 0xffff, shift: 0} + 1: {hash: 1, mask: 0xffff, shift: 0} + input_xbar: + group 0: { 7: ethernet.$valid } + hash 0: + 0..9: stripe(ethernet.$valid) + 10..19: stripe(ethernet.$valid) + 20..29: stripe(ethernet.$valid) + hash group 0: + table: [0] + exact group 1: { 0: ipv4_metadata.lkp_ipv4_da, 32: ipv4_metadata.lkp_ipv4_sa, 64: l3_metadata.lkp_l4_dport, 80: l3_metadata.lkp_l4_sport, 96: l3_metadata.lkp_ip_proto } + hash 2: + 32..47: stripe(crc(0x8fdb, ipv4_metadata.lkp_ipv4_da, ipv4_metadata.lkp_ipv4_sa)) + hash 3: + 32..47: stripe(crc(0x8fdb, l3_metadata.lkp_l4_dport, l3_metadata.lkp_l4_sport, l3_metadata.lkp_ip_proto)) + hash group 1: + table: [2, 3] + exact group 2: { 0: ipv4_metadata.lkp_ipv4_da, 32: ipv4_metadata.lkp_ipv4_sa, 64: l2_metadata.lkp_mac_da.0-15, 80: l2_metadata.lkp_mac_da.16-31, 96: l2_metadata.lkp_mac_da.32-47, 112: l2_metadata.lkp_mac_sa.0-15 } + exact group 3: { 0: l2_metadata.lkp_mac_sa.16-31, 16: l2_metadata.lkp_mac_sa.32-47, 32: l3_metadata.lkp_l4_dport, 48: l3_metadata.lkp_l4_sport, 64: l3_metadata.lkp_ip_proto } + hash 4: + 16..31: stripe(crc(0x8fdb, ipv4_metadata.lkp_ipv4_da, ipv4_metadata.lkp_ipv4_sa)) + hash 5: + 16..31: stripe(crc(0x8fdb, l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47, l2_metadata.lkp_mac_sa.0-15)) + hash 6: + 16..31: stripe(crc(0x8fdb, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47, l3_metadata.lkp_l4_dport, l3_metadata.lkp_l4_sport)) + hash 7: + 16..31: stripe(crc(0x8fdb, l3_metadata.lkp_ip_proto)) + hash group 1: + table: [4, 5, 6, 7] + format: { action(0): 0..0, version(0): 112..115 } + gateway: + input_xbar: + group 0: { 15: inner_ipv4.$valid, 23: ipv4.$valid, 25: tunnel_metadata.tunnel_terminate } + hash 0: + 40: inner_ipv4.$valid + 41: ipv4.$valid + hash group 0: + table: [0] + row: 1 + bus: 1 + match: { 1: tunnel_metadata.tunnel_terminate, 32: inner_ipv4.$valid, 33: ipv4.$valid } + 0b1*******************************0: run_table + 0b*1******************************1: run_table + miss: _compute_non_ip_hashes_0 + next: _fabric_ingress_dst_lkp + actions: + compute_lkp_ipv4_hash: + - set hash_metadata.hash1, hash_dist(2, 1) + - set hash_metadata.hash2, hash_dist(2, 1) + NoAction: + - 0 + default_action: NoAction + exact_match _compute_non_ip_hashes_0 1: + p4: { name: compute_non_ip_hashes } + p4_param_order: + ethernet.$valid: { type: exact, size: 1} + row: 1 + bus: 1 + column: [ 6, 7, 8 ] + ways: + - [2, 0, 0x0, [1, 6]] + - [2, 1, 0x0, [1, 7]] + - [2, 2, 0x0, [1, 8]] + hash_dist: + 0: {hash: 1, mask: 0xffff, shift: 0} + input_xbar: + group 0: { 71: ethernet.$valid } + hash 1: + 0..9: stripe(ethernet.$valid) + 10..19: stripe(ethernet.$valid) + 20..29: stripe(ethernet.$valid) + hash group 2: + table: [1] + exact group 4: { 0: ingress_metadata.ifindex, 16: l2_metadata.lkp_mac_da.0-15, 32: l2_metadata.lkp_mac_da.16-31, 48: l2_metadata.lkp_mac_da.32-47, 64: l2_metadata.lkp_mac_sa.0-15, 80: l2_metadata.lkp_mac_sa.16-31, 96: l2_metadata.lkp_mac_sa.32-47, 112: l2_metadata.lkp_mac_type } + hash 8: + 0..15: stripe(crc(0x8fdb, ingress_metadata.ifindex, l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47)) + hash 9: + 0..15: stripe(crc(0x8fdb, l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47, l2_metadata.lkp_mac_type)) + hash group 1: + table: [8, 9] + format: { action(0): 0..0, version(0): 112..115 } + next: _fabric_ingress_dst_lkp + actions: + compute_lkp_non_ip_hash: + - set hash_metadata.hash2, hash_dist(0) + NoAction: + - 0 + default_action: NoAction + exact_match _fabric_ingress_dst_lkp 2: + p4: { name: fabric_ingress_dst_lkp } + p4_param_order: + fabric_header.dstDevice: { type: exact, size: 8} + row: 1 + bus: 0 + column: [ 2, 3, 4 ] + ways: + - [3, 0, 0x0, [1, 2]] + - [3, 1, 0x0, [1, 3]] + - [3, 2, 0x0, [1, 4]] + input_xbar: + group 5: { 0: fabric_header.dstDevice } + hash 10: + 0..9: random(fabric_header.dstDevice(2..7)) ^ stripe(fabric_header.dstDevice(0..1)) + 10..19: random(fabric_header.dstDevice(2..7)) ^ stripe(fabric_header.dstDevice(0..1)) + 20..29: random(fabric_header.dstDevice(2..7)) ^ stripe(fabric_header.dstDevice(0..1)) + hash group 3: + table: [10] + format: { action(0): 0..1, version(0): 112..115, match(0): 34..39 } + match: [ fabric_header.dstDevice(2..7) ] + gateway: + input_xbar: + group 0: { 46: ingress_metadata.port_type } + row: 1 + bus: 0 + match: { 6: ingress_metadata.port_type } + 0x0: rmac + miss: run_table + next: rmac + actions: + nop: + - 0 + terminate_cpu_packet: + - set standard_metadata.egress_spec, fabric_header.dstPortOrGroup + - set egress_metadata.bypass, fabric_header_cpu.txBypass + - set ethernet.etherType, fabric_payload_header.etherType + NoAction: + - 0 + default_action: NoAction + exact_match rmac 3: + p4: { name: rmac, size: 512 } + p4_param_order: + l3_metadata.rmac_group: { type: exact, size: 10} + l2_metadata.lkp_mac_da: { type: exact, size: 48} + row: [ 0, 2 ] + bus: [ 1, 1 ] + column: + - [ 6, 7 ] + - 11 + ways: + - [4, 0, 0x0, [2, 11]] + - [4, 1, 0x0, [0, 6]] + - [4, 2, 0x0, [0, 7]] + input_xbar: + group 5: { 64: l2_metadata.lkp_mac_da.0-15, 80: l2_metadata.lkp_mac_da.16-31, 96: l2_metadata.lkp_mac_da.32-47, 112: l3_metadata.rmac_group } + hash 11: + 0..9: random(l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47, l3_metadata.rmac_group(1..7)) ^ stripe(l3_metadata.rmac_group(0), l3_metadata.rmac_group(8..9)) + 10..19: random(l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47, l3_metadata.rmac_group(1..7)) ^ stripe(l3_metadata.rmac_group(0), l3_metadata.rmac_group(8..9)) + 20..29: random(l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47, l3_metadata.rmac_group(1..7)) ^ stripe(l3_metadata.rmac_group(0), l3_metadata.rmac_group(8..9)) + hash group 4: + table: [11] + format: { action(0): 0..1, version(0): 112..115, match(0): [56..63, 32..39, 64..71, 40..47, 72..79, 48..55, 80..87 ] } + match: [ l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47, l3_metadata.rmac_group(0..7) ] + gateway: + input_xbar: + group 0: { 46: ingress_metadata.port_type } + row: 0 + bus: 1 + match: { 6: ingress_metadata.port_type } + 0x1: _compute_other_hashes_0 + miss: run_table + next: _validate_packet_0 + actions: + rmac_hit: + - set l3_metadata.rmac_hit, 1 + rmac_miss: + - set l3_metadata.rmac_hit, 0 + NoAction: + - 0 + default_action: NoAction + ternary_match _validate_packet_0 4: + p4: { name: validate_packet, size: 64 } + p4_param_order: + l2_metadata.lkp_mac_sa: { type: ternary, size: 48} + l2_metadata.lkp_mac_da: { type: ternary, size: 48} + l3_metadata.lkp_ip_type: { type: ternary, size: 2} + l3_metadata.lkp_ip_ttl: { type: ternary, size: 8} + l3_metadata.lkp_ip_version: { type: ternary, size: 4} + ipv4_metadata.lkp_ipv4_sa: { type: ternary, size: 8} + row: [ 0, 1, 2, 3 ] + bus: [ 0, 0, 0, 0 ] + column: + - 0 + - 0 + - 0 + - 0 + input_xbar: + group 0: { 0: ipv4_metadata.lkp_ipv4_sa, 32: l2_metadata.lkp_mac_da.0-15(0..7), 41: l3_metadata.lkp_ip_type } + group 1: { 0: l2_metadata.lkp_mac_da.16-31(0..7), 8: l2_metadata.lkp_mac_da.0-15(8..15), 16: l2_metadata.lkp_mac_da.32-47(0..7), 24: l2_metadata.lkp_mac_da.16-31(8..15), 32: l2_metadata.lkp_mac_sa.0-15(0..7) } + group 2: { 0: l2_metadata.lkp_mac_da.32-47(8..15), 8: l2_metadata.lkp_mac_sa.16-31(0..7), 16: l2_metadata.lkp_mac_sa.0-15(8..15), 24: l2_metadata.lkp_mac_sa.32-47(0..7), 32: l2_metadata.lkp_mac_sa.16-31(8..15) } + group 3: { 0: l2_metadata.lkp_mac_sa.32-47(8..15), 8: l3_metadata.lkp_ip_ttl, 18: l3_metadata.lkp_ip_version } + gateway: + input_xbar: + group 5: { 8: ingress_metadata.bypass_lookups(8..15), 16: ingress_metadata.bypass_lookups(0..7), 30: ingress_metadata.drop_flag } + row: 0 + bus: 0 + match: { 0: ingress_metadata.bypass_lookups(0..7), 8: ingress_metadata.bypass_lookups(8..15), 22: ingress_metadata.drop_flag } + 0b*0***************0******: run_table + miss: _smac_0.1 + next: _smac_0.1 + action_bus: { } + indirect: _validate_packet_0$tind + ternary_indirect _validate_packet_0$tind: + row: 0 + bus: 0 + column: 5 + format: { action: 8..10, immediate: 0..7} + actions: + nop: + - { } + set_unicast: + - { } + - set l2_metadata.lkp_pkt_type, 1 + set_unicast_and_ipv6_src_is_link_local: + - { } + - set l2_metadata.lkp_pkt_type, 1 + - set ipv6_metadata.ipv6_src_is_link_local, 1 + set_multicast: + - { } + - set l2_metadata.lkp_pkt_type, 2 + - add l2_metadata.bd_stats_idx, l2_metadata.bd_stats_idx, 1 + set_multicast_and_ipv6_src_is_link_local: + - { } + - set l2_metadata.lkp_pkt_type, 2 + - set ipv6_metadata.ipv6_src_is_link_local, 1 + - add l2_metadata.bd_stats_idx, l2_metadata.bd_stats_idx, 1 + set_broadcast: + - { } + - set l2_metadata.lkp_pkt_type, 4 + - add l2_metadata.bd_stats_idx, l2_metadata.bd_stats_idx, 2 + set_malformed_packet: + - p4_param_order: {drop_reason: 8 } + - { drop_reason: immediate(0..7) } + - set ingress_metadata.drop_flag, 1 + - set ingress_metadata.drop_reason, drop_reason + NoAction: + - { } + default_action: NoAction + exact_match _smac_0.1 5: + p4: { name: smac, size: 440000 } + p4_param_order: + ingress_metadata.bd: { type: exact, size: 14} + l2_metadata.lkp_mac_sa: { type: exact, size: 48} + row: [ 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10, 11 ] + ways: + - [5, 0, 0x7, [7, 2], [7, 3], [7, 4], [7, 6], [7, 7], [7, 8], [7, 9], [7, 10]] + - [5, 1, 0x38, [7, 11], [6, 2], [6, 3], [6, 4], [6, 6], [6, 7], [6, 8], [6, 9]] + - [5, 2, 0x1c0, [6, 10], [6, 11], [5, 2], [5, 3], [5, 4], [5, 6], [5, 7], [5, 8]] + - [5, 3, 0xe00, [5, 9], [5, 10], [5, 11], [4, 2], [4, 3], [4, 4], [4, 6], [4, 7]] + - [5, 0, 0x7, [4, 8], [4, 9], [4, 10], [4, 11], [3, 2], [3, 3], [3, 4], [3, 6]] + - [5, 1, 0x38, [3, 7], [3, 8], [3, 9], [3, 10], [3, 11], [2, 2], [2, 3], [2, 4]] + - [5, 2, 0xc0, [2, 6], [2, 7], [2, 8], [2, 9]] + - [5, 3, 0x0, [2, 10]] + input_xbar: + group 6: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_sa.0-15, 32: l2_metadata.lkp_mac_sa.16-31, 48: l2_metadata.lkp_mac_sa.32-47 } + hash 12: + 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..3)) + 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..3)) + 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..3)) + 30..39: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..3)) + 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..3)) + hash group 5: + table: [12] + format: { action(0): 0..1, version(0): 112..115, match(0): [56..71, 32..39, 72..79, 40..47, 4..7, 48..55 ], action(1): 2..3, version(1): 116..119, match(1): [104..111, 8..15, 80..87, 16..23, 88..95, 28..31, 96..103 ] } + match: [ ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(4..15) ] + gateway: + input_xbar: + group 0: { 32: ingress_metadata.bypass_lookups(0..7), 46: ingress_metadata.port_type, 56: ingress_metadata.bypass_lookups(8..15) } + row: 2 + bus: 0 + match: { 0: ingress_metadata.bypass_lookups(0..7), 8: ingress_metadata.bypass_lookups(8..15), 22: ingress_metadata.port_type } + 0b00**************0*******: run_table + miss: _dmac_0.1 + hit: _dmac_0.1 + miss: _smac_0.2 + action: _smac_0.1$action + default_action: NoAction + action _smac_0.1$action: + p4: { name: _smac_0$action } + row: [ 14, 12, 10, 8, 6, 4, 3, 2, 1 ] + column: + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - [ 3, 4, 5 ] + - 5 + - [ 2, 3, 4, 5 ] + home_row: [ 14, 4 ] + format smac_hit: { $adf_h0: 0..15 } + action_bus: { 32..33 : $adf_h0 } + actions: + nop: + - { } + smac_miss: + - { } + - set l2_metadata.l2_src_miss, 1 + smac_hit: + - p4_param_order: {ifindex: 16 } + - { ifindex: $adf_h0 } + - xor l2_metadata.l2_src_move, ingress_metadata.ifindex, ifindex + NoAction: + - { } +stage 2 ingress: + exact_match _smac_0.2 0: + p4: { name: smac, size: 440000 } + p4_param_order: + ingress_metadata.bd: { type: exact, size: 14} + l2_metadata.lkp_mac_sa: { type: exact, size: 48} + row: [ 0, 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + ways: + - [0, 0, 0xf, [7, 2], [7, 3], [7, 4], [7, 6], [7, 7], [7, 8], [7, 9], [7, 10], [6, 2], [6, 3], [6, 4], [6, 6], [6, 7], [6, 8], [6, 9], [6, 10]] + - [0, 1, 0xf0, [5, 2], [5, 3], [5, 4], [5, 6], [5, 7], [5, 8], [5, 9], [5, 10], [4, 2], [4, 3], [4, 4], [4, 6], [4, 7], [4, 8], [4, 9], [4, 10]] + - [0, 2, 0xf00, [3, 2], [3, 3], [3, 4], [3, 6], [3, 7], [3, 8], [3, 9], [3, 10], [2, 2], [2, 3], [2, 4], [2, 6], [2, 7], [2, 8], [2, 9], [2, 10]] + - [1, 0, 0xf, [1, 2], [1, 3], [1, 4], [1, 6], [1, 7], [1, 8], [1, 9], [1, 10], [0, 2], [0, 3], [0, 4], [0, 6], [0, 7], [0, 8], [0, 9], [0, 10]] + input_xbar: + group 0: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_sa.0-15, 32: l2_metadata.lkp_mac_sa.16-31, 48: l2_metadata.lkp_mac_sa.32-47 } + group 1: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_sa.0-15, 32: l2_metadata.lkp_mac_sa.16-31, 48: l2_metadata.lkp_mac_sa.32-47 } + hash 0: + 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) + 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) + 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) + 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) + hash group 0: + table: [0] + hash 2: + 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) + 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) + 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) + 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) + hash group 1: + table: [2] + format: { action(0): 0..1, version(0): 120..123, match(0): [56..71, 32..39, 72..79, 40..47, 24..31, 48..55 ], action(1): 2..3, version(1): 124..127, match(1): [104..111, 8..15, 80..87, 16..23, 88..95, 112..119, 96..103 ] } + match: [ ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47 ] + hit: _dmac_0.1 + miss: _smac_0.3 + action: _smac_0.2$action + default_action: NoAction + action _smac_0.2$action: + p4: { name: _smac_0$action } + row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ] + column: + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + home_row: [ 15, 5 ] + format smac_hit: { $adf_h0: 0..15 } + action_bus: { 32..33 : $adf_h0 } + actions: + nop: + - { } + smac_miss: + - { } + - set l2_metadata.l2_src_miss, 1 + smac_hit: + - p4_param_order: {ifindex: 16 } + - { ifindex: $adf_h0 } + - xor l2_metadata.l2_src_move, ingress_metadata.ifindex, ifindex + NoAction: + - { } +stage 3 ingress: + exact_match _smac_0.3 0: + p4: { name: smac, size: 440000 } + p4_param_order: + ingress_metadata.bd: { type: exact, size: 14} + l2_metadata.lkp_mac_sa: { type: exact, size: 48} + row: [ 0, 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + ways: + - [0, 0, 0xf, [7, 2], [7, 3], [7, 4], [7, 6], [7, 7], [7, 8], [7, 9], [7, 10], [6, 2], [6, 3], [6, 4], [6, 6], [6, 7], [6, 8], [6, 9], [6, 10]] + - [0, 1, 0xf0, [5, 2], [5, 3], [5, 4], [5, 6], [5, 7], [5, 8], [5, 9], [5, 10], [4, 2], [4, 3], [4, 4], [4, 6], [4, 7], [4, 8], [4, 9], [4, 10]] + - [0, 2, 0xf00, [3, 2], [3, 3], [3, 4], [3, 6], [3, 7], [3, 8], [3, 9], [3, 10], [2, 2], [2, 3], [2, 4], [2, 6], [2, 7], [2, 8], [2, 9], [2, 10]] + - [1, 0, 0xf, [1, 2], [1, 3], [1, 4], [1, 6], [1, 7], [1, 8], [1, 9], [1, 10], [0, 2], [0, 3], [0, 4], [0, 6], [0, 7], [0, 8], [0, 9], [0, 10]] + input_xbar: + group 0: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_sa.0-15, 32: l2_metadata.lkp_mac_sa.16-31, 48: l2_metadata.lkp_mac_sa.32-47 } + group 1: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_sa.0-15, 32: l2_metadata.lkp_mac_sa.16-31, 48: l2_metadata.lkp_mac_sa.32-47 } + hash 0: + 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) + 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) + 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) + 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) + hash group 0: + table: [0] + hash 2: + 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) + 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) + 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) + 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) + hash group 1: + table: [2] + format: { action(0): 0..1, version(0): 120..123, match(0): [56..71, 32..39, 72..79, 40..47, 24..31, 48..55 ], action(1): 2..3, version(1): 124..127, match(1): [104..111, 8..15, 80..87, 16..23, 88..95, 112..119, 96..103 ] } + match: [ ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47 ] + hit: _dmac_0.1 + miss: _smac_0.4 + action: _smac_0.3$action + default_action: NoAction + action _smac_0.3$action: + p4: { name: _smac_0$action } + row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ] + column: + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + home_row: [ 15, 5 ] + format smac_hit: { $adf_h0: 0..15 } + action_bus: { 32..33 : $adf_h0 } + actions: + nop: + - { } + smac_miss: + - { } + - set l2_metadata.l2_src_miss, 1 + smac_hit: + - p4_param_order: {ifindex: 16 } + - { ifindex: $adf_h0 } + - xor l2_metadata.l2_src_move, ingress_metadata.ifindex, ifindex + NoAction: + - { } +stage 4 ingress: + exact_match _smac_0.4 0: + p4: { name: smac, size: 440000 } + p4_param_order: + ingress_metadata.bd: { type: exact, size: 14} + l2_metadata.lkp_mac_sa: { type: exact, size: 48} + row: [ 0, 4, 5, 6, 7 ] + bus: [ 1, 0, 0, 0, 0 ] + column: + - [ 8, 9 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + ways: + - [0, 0, 0x7, [7, 2], [7, 3], [7, 4], [7, 6], [7, 7], [7, 8], [7, 9], [7, 10]] + - [0, 1, 0x38, [6, 2], [6, 3], [6, 4], [6, 6], [6, 7], [6, 8], [6, 9], [6, 10]] + - [0, 2, 0x1c0, [5, 2], [5, 3], [5, 4], [5, 6], [5, 7], [5, 8], [5, 9], [5, 10]] + - [0, 3, 0xe00, [4, 2], [4, 3], [4, 4], [4, 6], [4, 7], [4, 8], [4, 9], [4, 10]] + - [0, 0, 0x1, [0, 8], [0, 9]] + input_xbar: + group 0: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_sa.0-15, 32: l2_metadata.lkp_mac_sa.16-31, 48: l2_metadata.lkp_mac_sa.32-47 } + hash 0: + 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..4)) + 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..4)) + 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..4)) + 30..39: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..4)) + 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..4)) + hash group 0: + table: [0] + format: { action(0): 0..1, version(0): 112..115, match(0): [56..71, 32..39, 72..79, 40..47, 5..7, 48..55 ], action(1): 2..3, version(1): 116..119, match(1): [104..111, 8..15, 80..87, 16..23, 88..95, 29..31, 96..103 ] } + match: [ ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(5..15) ] + next: _dmac_0.1 + action: _smac_0.4$action + default_action: NoAction + action _smac_0.4$action: + p4: { name: _smac_0$action } + row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7 ] + column: + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + home_row: 15 + format smac_hit: { $adf_h0: 0..15 } + action_bus: { 32..33 : $adf_h0 } + actions: + nop: + - { } + smac_miss: + - { } + - set l2_metadata.l2_src_miss, 1 + smac_hit: + - p4_param_order: {ifindex: 16 } + - { ifindex: $adf_h0 } + - xor l2_metadata.l2_src_move, ingress_metadata.ifindex, ifindex + NoAction: + - { } + exact_match _dmac_0.1 1: + p4: { name: dmac, size: 440000 } + p4_param_order: + ingress_metadata.bd: { type: exact, size: 14} + l2_metadata.lkp_mac_da: { type: exact, size: 48} + row: [ 0, 1, 2, 3 ] + bus: [ 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 6, 7 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + ways: + - [1, 0, 0x3, [3, 2], [3, 3], [3, 4], [3, 6]] + - [1, 1, 0xc, [3, 7], [3, 8], [3, 9], [3, 10]] + - [1, 2, 0x30, [2, 2], [2, 3], [2, 4], [2, 6]] + - [1, 3, 0xc0, [2, 7], [2, 8], [2, 9], [2, 10]] + - [1, 0, 0x3, [1, 2], [1, 3], [1, 4], [1, 6]] + - [1, 1, 0xc, [1, 7], [1, 8], [1, 9], [1, 10]] + - [1, 2, 0x30, [0, 2], [0, 3], [0, 4], [0, 6]] + - [1, 3, 0x0, [0, 7]] + input_xbar: + group 1: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_da.0-15, 32: l2_metadata.lkp_mac_da.16-31, 48: l2_metadata.lkp_mac_da.32-47 } + hash 2: + 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..3)) + 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..3)) + 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..3)) + 30..39: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..3)) + 40..47: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..3)) + hash group 1: + table: [2] + format: { action(0): 0..2, version(0): 112..115, match(0): [56..71, 32..39, 72..79, 40..47, 28..31, 48..55 ], action(1): 3..5, version(1): 120..123, match(1): [104..111, 8..15, 80..87, 16..23, 88..95, 116..119, 96..103 ] } + match: [ ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(4..15) ] + gateway: + input_xbar: + group 0: { 64: ingress_metadata.bypass_lookups } + row: 0 + bus: 1 + match: { 0: ingress_metadata.bypass_lookups(0..7), 8: ingress_metadata.bypass_lookups(8..15) } + 0b***************0: run_table + miss: cond-8 + hit: cond-8 + miss: _dmac_0.2 + action: _dmac_0.1$action + default_action: NoAction + action _dmac_0.1$action: + p4: { name: _dmac_0$action } + row: [ 6, 5, 4, 3, 2, 1, 0 ] + column: + - 5 + - 5 + - 5 + - 5 + - 5 + - [ 4, 5 ] + - 5 + home_row: 6 + format dmac_hit: { $adf_h0: 0..15 } + format dmac_redirect_nexthop: { $adf_h0: 0..15 } + format dmac_redirect_ecmp: { $adf_h0: 0..15 } + action_bus: { 36..37 : $adf_h0 } + actions: + nop: + - { } + dmac_hit: + - p4_param_order: {ifindex: 16 } + - { ifindex: $adf_h0 } + - set ingress_metadata.egress_ifindex, ifindex + - xor l2_metadata.same_if_check, l2_metadata.same_if_check, ifindex + dmac_multicast_hit: + - p4_param_order: {mc_index: 16 } + - { } + dmac_miss: + - { } + - set ingress_metadata.egress_ifindex, 65535 + dmac_redirect_nexthop: + - p4_param_order: {nexthop_index: 16 } + - { nexthop_index: $adf_h0 } + - set l2_metadata.l2_redirect, 1 + - set l2_metadata.l2_nexthop, nexthop_index + - set l2_metadata.l2_nexthop_type, 0 + dmac_redirect_ecmp: + - p4_param_order: {ecmp_index: 16 } + - { ecmp_index: $adf_h0 } + - set l2_metadata.l2_redirect, 1 + - set l2_metadata.l2_nexthop, ecmp_index + - set l2_metadata.l2_nexthop_type, 1 + dmac_drop: + - { } + - invalidate standard_metadata.egress_spec + NoAction: + - { } +stage 5 ingress: + exact_match _dmac_0.2 0: + p4: { name: dmac, size: 440000 } + p4_param_order: + ingress_metadata.bd: { type: exact, size: 14} + l2_metadata.lkp_mac_da: { type: exact, size: 48} + row: [ 0, 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + ways: + - [0, 0, 0xf, [7, 2], [7, 3], [7, 4], [7, 6], [7, 7], [7, 8], [7, 9], [7, 10], [6, 2], [6, 3], [6, 4], [6, 6], [6, 7], [6, 8], [6, 9], [6, 10]] + - [0, 1, 0xf0, [5, 2], [5, 3], [5, 4], [5, 6], [5, 7], [5, 8], [5, 9], [5, 10], [4, 2], [4, 3], [4, 4], [4, 6], [4, 7], [4, 8], [4, 9], [4, 10]] + - [0, 2, 0xf00, [3, 2], [3, 3], [3, 4], [3, 6], [3, 7], [3, 8], [3, 9], [3, 10], [2, 2], [2, 3], [2, 4], [2, 6], [2, 7], [2, 8], [2, 9], [2, 10]] + - [1, 0, 0xf, [1, 2], [1, 3], [1, 4], [1, 6], [1, 7], [1, 8], [1, 9], [1, 10], [0, 2], [0, 3], [0, 4], [0, 6], [0, 7], [0, 8], [0, 9], [0, 10]] + input_xbar: + group 0: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_da.0-15, 32: l2_metadata.lkp_mac_da.16-31, 48: l2_metadata.lkp_mac_da.32-47 } + group 1: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_da.0-15, 32: l2_metadata.lkp_mac_da.16-31, 48: l2_metadata.lkp_mac_da.32-47 } + hash 0: + 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) + 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) + 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) + 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) + hash group 0: + table: [0] + hash 2: + 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) + 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) + 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) + 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) + hash group 1: + table: [2] + format: { action(0): 0..2, version(0): 120..123, match(0): [56..71, 32..39, 72..79, 40..47, 24..31, 48..55 ], action(1): 3..5, version(1): 124..127, match(1): [104..111, 8..15, 80..87, 16..23, 88..95, 112..119, 96..103 ] } + match: [ ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47 ] + hit: cond-8 + miss: _dmac_0.3 + action: _dmac_0.2$action + default_action: NoAction + action _dmac_0.2$action: + p4: { name: _dmac_0$action } + row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ] + column: + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + home_row: [ 15, 5 ] + format dmac_hit: { $adf_h0: 0..15 } + format dmac_redirect_nexthop: { $adf_h0: 0..15 } + format dmac_redirect_ecmp: { $adf_h0: 0..15 } + action_bus: { 32..33 : $adf_h0 } + actions: + nop: + - { } + dmac_hit: + - p4_param_order: {ifindex: 16 } + - { ifindex: $adf_h0 } + - set ingress_metadata.egress_ifindex, ifindex + - xor l2_metadata.same_if_check, l2_metadata.same_if_check, ifindex + dmac_multicast_hit: + - p4_param_order: {mc_index: 16 } + - { } + dmac_miss: + - { } + - set ingress_metadata.egress_ifindex, 65535 + dmac_redirect_nexthop: + - p4_param_order: {nexthop_index: 16 } + - { nexthop_index: $adf_h0 } + - set l2_metadata.l2_redirect, 1 + - set l2_metadata.l2_nexthop, nexthop_index + - set l2_metadata.l2_nexthop_type, 0 + dmac_redirect_ecmp: + - p4_param_order: {ecmp_index: 16 } + - { ecmp_index: $adf_h0 } + - set l2_metadata.l2_redirect, 1 + - set l2_metadata.l2_nexthop, ecmp_index + - set l2_metadata.l2_nexthop_type, 1 + dmac_drop: + - { } + - invalidate standard_metadata.egress_spec + NoAction: + - { } +stage 6 ingress: + exact_match _dmac_0.3 0: + p4: { name: dmac, size: 440000 } + p4_param_order: + ingress_metadata.bd: { type: exact, size: 14} + l2_metadata.lkp_mac_da: { type: exact, size: 48} + row: [ 0, 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + - [ 2, 3, 4, 6, 7, 8, 9, 10 ] + ways: + - [0, 0, 0xf, [7, 2], [7, 3], [7, 4], [7, 6], [7, 7], [7, 8], [7, 9], [7, 10], [6, 2], [6, 3], [6, 4], [6, 6], [6, 7], [6, 8], [6, 9], [6, 10]] + - [0, 1, 0xf0, [5, 2], [5, 3], [5, 4], [5, 6], [5, 7], [5, 8], [5, 9], [5, 10], [4, 2], [4, 3], [4, 4], [4, 6], [4, 7], [4, 8], [4, 9], [4, 10]] + - [0, 2, 0xf00, [3, 2], [3, 3], [3, 4], [3, 6], [3, 7], [3, 8], [3, 9], [3, 10], [2, 2], [2, 3], [2, 4], [2, 6], [2, 7], [2, 8], [2, 9], [2, 10]] + - [1, 0, 0xf, [1, 2], [1, 3], [1, 4], [1, 6], [1, 7], [1, 8], [1, 9], [1, 10], [0, 2], [0, 3], [0, 4], [0, 6], [0, 7], [0, 8], [0, 9], [0, 10]] + input_xbar: + group 0: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_da.0-15, 32: l2_metadata.lkp_mac_da.16-31, 48: l2_metadata.lkp_mac_da.32-47 } + group 1: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_da.0-15, 32: l2_metadata.lkp_mac_da.16-31, 48: l2_metadata.lkp_mac_da.32-47 } + hash 0: + 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) + 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) + 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) + 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) + hash group 0: + table: [0] + hash 2: + 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) + 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) + 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) + 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) + hash group 1: + table: [2] + format: { action(0): 0..2, version(0): 120..123, match(0): [56..71, 32..39, 72..79, 40..47, 24..31, 48..55 ], action(1): 3..5, version(1): 124..127, match(1): [104..111, 8..15, 80..87, 16..23, 88..95, 112..119, 96..103 ] } + match: [ ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47 ] + hit: cond-8 + miss: _dmac_0.4 + action: _dmac_0.3$action + default_action: NoAction + action _dmac_0.3$action: + p4: { name: _dmac_0$action } + row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ] + column: + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + - 5 + home_row: [ 15, 5 ] + format dmac_hit: { $adf_h0: 0..15 } + format dmac_redirect_nexthop: { $adf_h0: 0..15 } + format dmac_redirect_ecmp: { $adf_h0: 0..15 } + action_bus: { 32..33 : $adf_h0 } + actions: + nop: + - { } + dmac_hit: + - p4_param_order: {ifindex: 16 } + - { ifindex: $adf_h0 } + - set ingress_metadata.egress_ifindex, ifindex + - xor l2_metadata.same_if_check, l2_metadata.same_if_check, ifindex + dmac_multicast_hit: + - p4_param_order: {mc_index: 16 } + - { } + dmac_miss: + - { } + - set ingress_metadata.egress_ifindex, 65535 + dmac_redirect_nexthop: + - p4_param_order: {nexthop_index: 16 } + - { nexthop_index: $adf_h0 } + - set l2_metadata.l2_redirect, 1 + - set l2_metadata.l2_nexthop, nexthop_index + - set l2_metadata.l2_nexthop_type, 0 + dmac_redirect_ecmp: + - p4_param_order: {ecmp_index: 16 } + - { ecmp_index: $adf_h0 } + - set l2_metadata.l2_redirect, 1 + - set l2_metadata.l2_nexthop, ecmp_index + - set l2_metadata.l2_nexthop_type, 1 + dmac_drop: + - { } + - invalidate standard_metadata.egress_spec + NoAction: + - { } +stage 7 ingress: + exact_match _dmac_0.4 0: + p4: { name: dmac, size: 440000 } + p4_param_order: + ingress_metadata.bd: { type: exact, size: 14} + l2_metadata.lkp_mac_da: { type: exact, size: 48} + row: [ 0, 1, 2, 3, 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - [ 2, 3 ] + - [ 2, 3, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 6, 7, 8, 9, 10, 11 ] + - [ 2, 3, 6, 7, 8, 9, 10, 11 ] + ways: + - [0, 0, 0x7, [7, 2], [7, 3], [7, 6], [7, 7], [7, 8], [7, 9], [7, 10], [7, 11]] + - [0, 1, 0x38, [6, 2], [6, 3], [6, 6], [6, 7], [6, 8], [6, 9], [6, 10], [6, 11]] + - [0, 2, 0x1c0, [5, 2], [5, 3], [5, 6], [5, 7], [5, 8], [5, 9], [5, 10], [5, 11]] + - [0, 3, 0xe00, [4, 2], [4, 3], [4, 6], [4, 7], [4, 8], [4, 9], [4, 10], [4, 11]] + - [0, 0, 0x7, [3, 2], [3, 3], [3, 6], [3, 7], [3, 8], [3, 9], [3, 10], [3, 11]] + - [0, 1, 0x38, [2, 2], [2, 3], [2, 6], [2, 7], [2, 8], [2, 9], [2, 10], [2, 11]] + - [0, 2, 0x1c0, [1, 2], [1, 3], [1, 6], [1, 7], [1, 8], [1, 9], [1, 10], [1, 11]] + - [0, 3, 0x200, [0, 2], [0, 3]] + input_xbar: + group 0: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_da.0-15, 32: l2_metadata.lkp_mac_da.16-31, 48: l2_metadata.lkp_mac_da.32-47 } + hash 0: + 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..4)) + 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..4)) + 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..4)) + 30..39: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..4)) + 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..4)) + hash group 0: + table: [0] + format: { action(0): 0..2, version(0): 112..115, match(0): [56..71, 32..39, 72..79, 40..47, 29..31, 48..55 ], action(1): 3..5, version(1): 120..123, match(1): [104..111, 8..15, 80..87, 16..23, 88..95, 117..119, 96..103 ] } + match: [ ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(5..15) ] + next: cond-8 + action: _dmac_0.4$action + default_action: NoAction + action _dmac_0.4$action: + p4: { name: _dmac_0$action } + row: [ 14, 12, 10, 8, 6, 4, 2, 1, 0 ] + column: + - [ 4, 5 ] + - 5 + - 5 + - [ 4, 5 ] + - [ 4, 5 ] + - [ 4, 5 ] + - 5 + - [ 3, 4, 5 ] + - 5 + home_row: [ 14, 4 ] + format dmac_hit: { $adf_h0: 0..15 } + format dmac_redirect_nexthop: { $adf_h0: 0..15 } + format dmac_redirect_ecmp: { $adf_h0: 0..15 } + action_bus: { 32..33 : $adf_h0 } + actions: + nop: + - { } + dmac_hit: + - p4_param_order: {ifindex: 16 } + - { ifindex: $adf_h0 } + - set ingress_metadata.egress_ifindex, ifindex + - xor l2_metadata.same_if_check, l2_metadata.same_if_check, ifindex + dmac_multicast_hit: + - p4_param_order: {mc_index: 16 } + - { } + dmac_miss: + - { } + - set ingress_metadata.egress_ifindex, 65535 + dmac_redirect_nexthop: + - p4_param_order: {nexthop_index: 16 } + - { nexthop_index: $adf_h0 } + - set l2_metadata.l2_redirect, 1 + - set l2_metadata.l2_nexthop, nexthop_index + - set l2_metadata.l2_nexthop_type, 0 + dmac_redirect_ecmp: + - p4_param_order: {ecmp_index: 16 } + - { ecmp_index: $adf_h0 } + - set l2_metadata.l2_redirect, 1 + - set l2_metadata.l2_nexthop, ecmp_index + - set l2_metadata.l2_nexthop_type, 1 + dmac_drop: + - { } + - invalidate standard_metadata.egress_spec + NoAction: + - { } + gateway cond-8 1: + input_xbar: + group 0: { 89: l3_metadata.lkp_ip_type } + row: 1 + bus: 1 + match: { 1: l3_metadata.lkp_ip_type } + 0b*****00: _mac_acl_0 + miss: cond-10 + ternary_match _mac_acl_0 2: + p4: { name: mac_acl, size: 128 } + p4_param_order: + acl_metadata.if_label: { type: ternary, size: 16} + acl_metadata.bd_label: { type: ternary, size: 16} + l2_metadata.lkp_mac_sa: { type: ternary, size: 48} + l2_metadata.lkp_mac_da: { type: ternary, size: 48} + l2_metadata.lkp_mac_type: { type: ternary, size: 16} + row: [ 0, 1, 2, 3 ] + bus: [ 0, 0, 0, 0 ] + column: + - 0 + - 0 + - 0 + - 0 + input_xbar: + group 0: { 0: acl_metadata.bd_label, 16: acl_metadata.if_label, 32: l2_metadata.lkp_mac_da.0-15(0..7), 40: l2_metadata.lkp_mac_da.32-47(8..15) } + group 1: { 0: l2_metadata.lkp_mac_da.16-31(0..7), 8: l2_metadata.lkp_mac_da.0-15(8..15), 16: l2_metadata.lkp_mac_da.32-47(0..7), 24: l2_metadata.lkp_mac_da.16-31(8..15), 32: l2_metadata.lkp_mac_sa.0-15(0..7) } + group 2: { 0: l2_metadata.lkp_mac_sa.0-15(8..15), 8: l2_metadata.lkp_mac_sa.16-31, 24: l2_metadata.lkp_mac_sa.32-47 } + group 3: { 0: l2_metadata.lkp_mac_type(8..15), 8: l2_metadata.lkp_mac_type(0..7) } + gateway: + input_xbar: + group 0: { 64: ingress_metadata.bypass_lookups } + row: 1 + bus: 0 + match: { 0: ingress_metadata.bypass_lookups(0..7), 8: ingress_metadata.bypass_lookups(8..15) } + 0b*************0**: run_table + miss: _compute_other_hashes_0 + next: _compute_other_hashes_0 + indirect: _mac_acl_0$tind + ternary_indirect _mac_acl_0$tind: + row: 0 + bus: 0 + column: 4 + format: { action: 0..2} + action: _mac_acl_0$action + default_action: NoAction + action _mac_acl_0$action: + p4: { name: _mac_acl_0$action } + row: 10 + column: 4 + home_row: 10 + format acl_deny: { $adf_h1: 32..47, $adf_h2: 48..63 } + format acl_permit: { $adf_h1: 32..47, $adf_h2: 48..63 } + format acl_redirect_nexthop: { $adf_h0: 16..31, $adf_h1: 32..47, $adf_h2: 48..63 } + format acl_redirect_ecmp: { $adf_h0: 16..31, $adf_h1: 32..47, $adf_h2: 48..63 } + action_bus: { 66..67 : $adf_h0, 68..69 : $adf_h1, 70..71 : $adf_h2 } + actions: + nop: + - { } + acl_deny: + - p4_param_order: {acl_stats_index: 14, acl_meter_index: 16, acl_copy_reason: 16, nat_mode: 2, ingress_cos: 8, tc: 8, color: 8 } + - { acl_stats_index: $adf_h1, acl_copy_reason: $adf_h2 } + - set acl_metadata.acl_deny, 1 + - set acl_metadata.acl_stats_index, acl_stats_index + - set fabric_metadata.reason_code, acl_copy_reason + acl_permit: + - p4_param_order: {acl_stats_index: 14, acl_meter_index: 16, acl_copy_reason: 16, nat_mode: 2, ingress_cos: 8, tc: 8, color: 8 } + - { acl_stats_index: $adf_h1, acl_copy_reason: $adf_h2 } + - set acl_metadata.acl_stats_index, acl_stats_index + - set fabric_metadata.reason_code, acl_copy_reason + acl_redirect_nexthop: + - p4_param_order: {nexthop_index: 16, acl_stats_index: 14, acl_meter_index: 16, acl_copy_reason: 16, nat_mode: 2, ingress_cos: 8, tc: 8, color: 8 } + - { acl_stats_index: $adf_h0, acl_copy_reason: $adf_h1, nexthop_index: $adf_h2 } + - set acl_metadata.acl_redirect, 1 + - set acl_metadata.acl_nexthop, nexthop_index + - set acl_metadata.acl_nexthop_type, 0 + - set acl_metadata.acl_stats_index, acl_stats_index + - set fabric_metadata.reason_code, acl_copy_reason + acl_redirect_ecmp: + - p4_param_order: {ecmp_index: 16, acl_stats_index: 14, acl_meter_index: 16, acl_copy_reason: 16, nat_mode: 2, ingress_cos: 8, tc: 8, color: 8 } + - { acl_stats_index: $adf_h0, acl_copy_reason: $adf_h1, ecmp_index: $adf_h2 } + - set acl_metadata.acl_redirect, 1 + - set acl_metadata.acl_nexthop, ecmp_index + - set acl_metadata.acl_nexthop_type, 1 + - set acl_metadata.acl_stats_index, acl_stats_index + - set fabric_metadata.reason_code, acl_copy_reason + NoAction: + - { } + gateway cond-10 3: + input_xbar: + group 0: { 64: ingress_metadata.bypass_lookups } + row: 0 + bus: 1 + match: { 0: ingress_metadata.bypass_lookups(0..7), 8: ingress_metadata.bypass_lookups(8..15) } + 0b*************0**: _ip_acl_0 + miss: _compute_other_hashes_0 + ternary_match _ip_acl_0 4: + p4: { name: ip_acl, size: 128 } + p4_param_order: + acl_metadata.if_label: { type: ternary, size: 16} + acl_metadata.bd_label: { type: ternary, size: 16} + ipv4_metadata.lkp_ipv4_sa: { type: ternary, size: 32} + ipv4_metadata.lkp_ipv4_da: { type: ternary, size: 32} + l3_metadata.lkp_ip_proto: { type: ternary, size: 8} + acl_metadata.ingress_src_port_range_id: { type: exact, size: 8} + acl_metadata.ingress_dst_port_range_id: { type: exact, size: 8} + tcp.flags: { type: ternary, size: 8} + l3_metadata.lkp_ip_ttl: { type: ternary, size: 8} + row: [ 4, 5, 6, 7 ] + bus: [ 0, 0, 0, 0 ] + column: + - 0 + - 0 + - 0 + - 0 + input_xbar: + group 3: { 16: acl_metadata.if_label(8..15), 24: acl_metadata.ingress_dst_port_range_id, 32: acl_metadata.ingress_src_port_range_id } + group 4: { 0: ipv4_metadata.lkp_ipv4_da(16..31), 16: ipv4_metadata.lkp_ipv4_da(0..15), 32: ipv4_metadata.lkp_ipv4_sa(16..23), 40: acl_metadata.bd_label(8..15) } + group 5: { 0: ipv4_metadata.lkp_ipv4_sa(0..15), 16: acl_metadata.bd_label(0..7), 24: ipv4_metadata.lkp_ipv4_sa(24..31), 32: acl_metadata.if_label(0..7) } + group 6: { 0: l3_metadata.lkp_ip_proto, 8: l3_metadata.lkp_ip_ttl, 16: tcp.flags } + gateway: + input_xbar: + group 0: { 89: l3_metadata.lkp_ip_type } + row: 0 + bus: 0 + match: { 1: l3_metadata.lkp_ip_type } + 0b*****01: run_table + miss: _compute_other_hashes_0 + next: _compute_other_hashes_0 + indirect: _ip_acl_0$tind + ternary_indirect _ip_acl_0$tind: + row: 1 + bus: 0 + column: 4 + format: { action: 0..2} + action: _ip_acl_0$action + default_action: NoAction + action _ip_acl_0$action: + p4: { name: _ip_acl_0$action } + row: 12 + column: 4 + home_row: 12 + format acl_deny: { $adf_h1: 32..47, $adf_h2: 48..63 } + format acl_permit: { $adf_h1: 32..47, $adf_h2: 48..63 } + format acl_redirect_nexthop: { $adf_h0: 16..31, $adf_h1: 32..47, $adf_h2: 48..63 } + format acl_redirect_ecmp: { $adf_h0: 16..31, $adf_h1: 32..47, $adf_h2: 48..63 } + action_bus: { 74..75 : $adf_h0, 76..77 : $adf_h1, 78..79 : $adf_h2 } + actions: + nop: + - { } + acl_deny: + - p4_param_order: {acl_stats_index: 14, acl_meter_index: 16, acl_copy_reason: 16, nat_mode: 2, ingress_cos: 8, tc: 8, color: 8 } + - { acl_stats_index: $adf_h1, acl_copy_reason: $adf_h2 } + - set acl_metadata.acl_deny, 1 + - set acl_metadata.acl_stats_index, acl_stats_index + - set fabric_metadata.reason_code, acl_copy_reason + acl_permit: + - p4_param_order: {acl_stats_index: 14, acl_meter_index: 16, acl_copy_reason: 16, nat_mode: 2, ingress_cos: 8, tc: 8, color: 8 } + - { acl_stats_index: $adf_h1, acl_copy_reason: $adf_h2 } + - set acl_metadata.acl_stats_index, acl_stats_index + - set fabric_metadata.reason_code, acl_copy_reason + acl_redirect_nexthop: + - p4_param_order: {nexthop_index: 16, acl_stats_index: 14, acl_meter_index: 16, acl_copy_reason: 16, nat_mode: 2, ingress_cos: 8, tc: 8, color: 8 } + - { acl_stats_index: $adf_h0, acl_copy_reason: $adf_h1, nexthop_index: $adf_h2 } + - set acl_metadata.acl_redirect, 1 + - set acl_metadata.acl_nexthop, nexthop_index + - set acl_metadata.acl_nexthop_type, 0 + - set acl_metadata.acl_stats_index, acl_stats_index + - set fabric_metadata.reason_code, acl_copy_reason + acl_redirect_ecmp: + - p4_param_order: {ecmp_index: 16, acl_stats_index: 14, acl_meter_index: 16, acl_copy_reason: 16, nat_mode: 2, ingress_cos: 8, tc: 8, color: 8 } + - { acl_stats_index: $adf_h0, acl_copy_reason: $adf_h1, ecmp_index: $adf_h2 } + - set acl_metadata.acl_redirect, 1 + - set acl_metadata.acl_nexthop, ecmp_index + - set acl_metadata.acl_nexthop_type, 1 + - set acl_metadata.acl_stats_index, acl_stats_index + - set fabric_metadata.reason_code, acl_copy_reason + NoAction: + - { } + exact_match _compute_other_hashes_0 5: + p4: { name: compute_other_hashes } + p4_param_order: + hash_metadata.hash1: { type: exact, size: 16} + row: 0 + bus: 1 + column: [ 6, 7, 8 ] + ways: + - [1, 0, 0x0, [0, 6]] + - [1, 1, 0x0, [0, 7]] + - [1, 2, 0x0, [0, 8]] + input_xbar: + group 0: { 80: hash_metadata.hash1(0..7), 104: hash_metadata.hash1(8..15) } + hash 1: + 0..9: random(hash_metadata.hash1(10..15)) ^ stripe(hash_metadata.hash1(0..7), hash_metadata.hash1(8..9)) + 10..19: random(hash_metadata.hash1(10..15)) ^ stripe(hash_metadata.hash1(0..7), hash_metadata.hash1(8..9)) + 20..29: random(hash_metadata.hash1(10..15)) ^ stripe(hash_metadata.hash1(0..7), hash_metadata.hash1(8..9)) + hash group 1: + table: [1] + format: { action(0): 0..1, version(0): 112..115, match(0): 34..39 } + match: [ hash_metadata.hash1(10..15) ] + next: _spanning_tree_0 + actions: + computed_two_hashes: + - 0 + computed_one_hash: + - set hash_metadata.hash1, hash_metadata.hash2 + NoAction: + - 0 + default_action: NoAction +stage 8 ingress: + exact_match _spanning_tree_0 0: + p4: { name: spanning_tree, size: 4096 } + p4_param_order: + ingress_metadata.ifindex: { type: exact, size: 16} + l2_metadata.stp_group: { type: exact, size: 10} + row: [ 5, 6 ] + bus: [ 0, 0 ] + column: + - 2 + - [ 2, 3, 4 ] + ways: + - [0, 0, 0x0, [6, 2]] + - [0, 1, 0x0, [6, 3]] + - [0, 2, 0x0, [6, 4]] + - [0, 3, 0x0, [5, 2]] + input_xbar: + group 0: { 0: ingress_metadata.ifindex, 16: l2_metadata.stp_group } + hash 0: + 0..9: random(ingress_metadata.ifindex, l2_metadata.stp_group(1..7)) ^ stripe(l2_metadata.stp_group(0), l2_metadata.stp_group(8..9)) + 10..19: random(ingress_metadata.ifindex, l2_metadata.stp_group(1..7)) ^ stripe(l2_metadata.stp_group(0), l2_metadata.stp_group(8..9)) + 20..29: random(ingress_metadata.ifindex, l2_metadata.stp_group(1..7)) ^ stripe(l2_metadata.stp_group(0), l2_metadata.stp_group(8..9)) + 30..39: random(ingress_metadata.ifindex, l2_metadata.stp_group(1..7)) ^ stripe(l2_metadata.stp_group(0), l2_metadata.stp_group(8..9)) + hash group 0: + table: [0] + format: { action(0): 7..7, immediate(0): 0..6, version(0): 112..115, match(0): [40..47, 32..39, 48..55 ] } + match: [ ingress_metadata.ifindex, l2_metadata.stp_group(0..7) ] + gateway: + input_xbar: + group 0: { 16: l2_metadata.stp_group, 46: ingress_metadata.port_type } + row: 1 + bus: 0 + match: { 0: l2_metadata.stp_group(0..7), 8: l2_metadata.stp_group(8..9), 22: ingress_metadata.port_type } + 0b******00********00000000: _ingress_bd_stats_2 + 0b00**********************: run_table + miss: _ingress_bd_stats_2 + next: _ingress_bd_stats_2 + action_bus: { } + actions: + set_stp_state: + - p4_param_order: {stp_state: 3 } + - { stp_state: immediate(0..6) } + - set l2_metadata.stp_state, stp_state + NoAction: + - { } + default_action: NoAction + hash_action _ingress_bd_stats_2 1: + p4: { name: ingress_bd_stats, size: 16384 } + row: 0 + bus: 0 + column: [ ] + hash_dist: + 0: {hash: 1, mask: 0xffff, shift: 3} + input_xbar: + exact group 0: { 64: l2_metadata.bd_stats_idx } + hash 1: + 0..15: l2_metadata.bd_stats_idx + hash group 1: + table: [1] + gateway: + input_xbar: + group 0: { 46: ingress_metadata.port_type } + row: 0 + bus: 1 + payload: 1 + match: { 6: ingress_metadata.port_type } + 0x1: run_table + miss: _fwd_result_0 + next: cond-18 + stats: _ingress_bd_stats_2$counter..ingress_bd_stats(hash_dist 0) + actions: + update_ingress_bd_stats: + - 0 + NoAction: + - 0 + default_action: NoAction + counter _ingress_bd_stats_2$counter..ingress_bd_stats: + p4: { name: ingress_bd_stats } + row: [ 9, 7 ] + column: + - [ 0, 1, 2, 3, 4, 5 ] + - 0 + maprams: + - [ 0, 1, 2, 3, 4, 5 ] + - 0 + count: packets_and_bytes + format: {packets(0): 85..101, bytes(0): 102..126, packets(1): 42..58, bytes(1): 59..83, packets(2): 0..16, bytes(2): 17..41} + ternary_match _fwd_result_0 2: + p4: { name: fwd_result, size: 512 } + p4_param_order: + l2_metadata.l2_redirect: { type: ternary, size: 1} + acl_metadata.acl_redirect: { type: ternary, size: 1} + acl_metadata.racl_redirect: { type: ternary, size: 1} + l3_metadata.rmac_hit: { type: ternary, size: 1} + l3_metadata.fib_hit: { type: ternary, size: 1} + nat_metadata.nat_hit: { type: ternary, size: 1} + l2_metadata.lkp_pkt_type: { type: ternary, size: 3} + l3_metadata.lkp_ip_type: { type: ternary, size: 2} + multicast_metadata.igmp_snooping_enabled: { type: ternary, size: 1} + multicast_metadata.mld_snooping_enabled: { type: ternary, size: 1} + multicast_metadata.mcast_route_hit: { type: ternary, size: 1} + multicast_metadata.mcast_bridge_hit: { type: ternary, size: 1} + multicast_metadata.mcast_rpf_group: { type: ternary, size: 14} + multicast_metadata.mcast_mode: { type: ternary, size: 2} + row: [ 0, 1, 2 ] + bus: [ 0, 0, 0 ] + column: + - 0 + - 0 + - 0 + input_xbar: + group 0: { 0: multicast_metadata.mcast_rpf_group(0..7), 9: l3_metadata.lkp_ip_type, 21: acl_metadata.acl_redirect, 28: multicast_metadata.mcast_mode, 36: acl_metadata.racl_redirect, 43: l2_metadata.lkp_pkt_type } + group 1: { 6: l2_metadata.l2_redirect, 8: multicast_metadata.mcast_rpf_group(8..13), 21: l3_metadata.fib_hit, 28: l3_metadata.rmac_hit, 38: multicast_metadata.igmp_snooping_enabled } + group 2: { 4: multicast_metadata.mcast_bridge_hit, 13: multicast_metadata.mcast_route_hit, 21: multicast_metadata.mld_snooping_enabled, 28: nat_metadata.nat_hit } + gateway: + input_xbar: + group 0: { 32: ingress_metadata.bypass_lookups(0..7), 56: ingress_metadata.bypass_lookups(8..15) } + row: 0 + bus: 0 + match: { 0: ingress_metadata.bypass_lookups(0..7), 8: ingress_metadata.bypass_lookups(8..15) } + 0x**ff: _acl_stats_2 + miss: run_table + next: _acl_stats_2 + action_bus: { } + indirect: _fwd_result_0$tind + ternary_indirect _fwd_result_0$tind: + row: 0 + bus: 0 + column: 2 + format: { action: 9..11, immediate: 0..8} + actions: + nop: + - { } + set_l2_redirect_action: + - { } + - set l3_metadata.nexthop_index, l2_metadata.l2_nexthop + - set nexthop_metadata.nexthop_type, l2_metadata.l2_nexthop_type + - set ingress_metadata.egress_ifindex, 0 + set_fib_redirect_action: + - { } + - set l3_metadata.nexthop_index, 0 + - set nexthop_metadata.nexthop_type, 0 + - set l3_metadata.routed, 1 + - set fabric_metadata.reason_code, 535 + set_cpu_redirect_action: + - { $constant0: immediate(0..8), $constant0: 64 } + - set l3_metadata.routed, 0 + - set standard_metadata.egress_spec, $constant0 + - set ingress_metadata.egress_ifindex, 0 + set_acl_redirect_action: + - { } + - set l3_metadata.nexthop_index, acl_metadata.acl_nexthop + - set nexthop_metadata.nexthop_type, acl_metadata.acl_nexthop_type + - set ingress_metadata.egress_ifindex, 0 + set_racl_redirect_action: + - { } + - set l3_metadata.nexthop_index, 0 + - set nexthop_metadata.nexthop_type, 0 + - set l3_metadata.routed, 1 + - set ingress_metadata.egress_ifindex, 0 + NoAction: + - { } + default_action: NoAction + hash_action _acl_stats_2 3: + p4: { name: acl_stats, size: 128 } + row: 1 + bus: 0 + column: [ ] + hash_dist: + 1: {hash: 1, mask: 0x3fff, shift: 3} + input_xbar: + exact group 0: { 80: acl_metadata.acl_stats_index } + hash 1: + 16..29: acl_metadata.acl_stats_index + hash group 1: + table: [1] + gateway: + row: 2 + bus: 0 + 0x0: _ecmp_group_0 + miss: _ecmp_group_0 + next: _ecmp_group_0 + stats: _acl_stats_2$counter..acl_stats(hash_dist 1) + actions: + acl_stats_update: + - 0 + NoAction: + - 0 + default_action: NoAction + counter _acl_stats_2$counter..acl_stats: + p4: { name: acl_stats } + row: 5 + column: [ 0, 1 ] + maprams: [ 0, 1 ] + count: packets_and_bytes + format: {packets(0): 85..101, bytes(0): 102..126, packets(1): 42..58, bytes(1): 59..83, packets(2): 0..16, bytes(2): 17..41} +stage 9 ingress: + exact_match _ecmp_group_0 0: + p4: { name: ecmp_group, size: 1024, action_profile: ecmp_action_profile } + p4_param_order: + l3_metadata.nexthop_index: { type: exact, size: 16} + row: 7 + bus: 0 + column: [ 2, 3, 4 ] + ways: + - [0, 0, 0x0, [7, 2]] + - [0, 1, 0x0, [7, 3]] + - [0, 2, 0x0, [7, 4]] + input_xbar: + group 0: { 0: l3_metadata.nexthop_index } + hash 0: + 0..9: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) + 10..19: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) + 20..29: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) + hash group 0: + table: [0] + format: { action(0): 26..27, version(0): 112..115, meter_addr(0): 0..9, meter_pfe(0): 10..10, action_addr(0): 11..25, match(0): 34..39 } + match: [ l3_metadata.nexthop_index(10..15) ] + gateway: + input_xbar: + group 0: { 30: nexthop_metadata.nexthop_type } + row: 0 + bus: 0 + match: { 6: nexthop_metadata.nexthop_type } + 0x1: run_table + miss: _nexthop_0 + next: _learn_notify_0 + action: _ecmp_group_0$act_prof..ecmp_action_profile(action, action_addr) + selector: _ecmp_group_0$act_sel..ecmp_action_profile(meter_addr) + default_action: NoAction + action _ecmp_group_0$act_prof..ecmp_action_profile: + row: [ 11, 10 ] + column: + - [ 1, 2, 3, 4, 5 ] + - [ 2, 3, 4 ] + home_row: 11 + format set_ecmp_nexthop_details: { $adf_b0: 0..7, $adf_h0: 16..31, $adf_h1: 32..47, $adf_h2: 48..63 } + format set_ecmp_nexthop_details_for_post_routed_flood: { $adf_h1: 32..47, $adf_h2: 48..63 } + action_bus: { 0 : $adf_b0, 66..67 : $adf_h0, 68..69 : $adf_h1, 70..71 : $adf_h2 } + actions: + nop: + - { } + set_ecmp_nexthop_details: + - p4_param_order: {ifindex: 16, bd: 14, nhop_index: 16, tunnel: 1 } + - { $data0: $adf_b0, $constant0: $data0(0..0), $constant0: 0, tunnel: $data0(0..0), bd: $adf_h0, ifindex: $adf_h1, nhop_index: $adf_h2 } + - set ingress_metadata.egress_ifindex, ifindex + - set l3_metadata.nexthop_index, nhop_index + - xor l3_metadata.same_bd_check, ingress_metadata.bd, bd + - xor l2_metadata.same_if_check, l2_metadata.same_if_check, ifindex + - xor tunnel_metadata.tunnel_if_check, $constant0, tunnel + set_ecmp_nexthop_details_for_post_routed_flood: + - p4_param_order: {bd: 14, uuc_mc_index: 16, nhop_index: 16 } + - { bd: $adf_h1, nhop_index: $adf_h2 } + - set l3_metadata.nexthop_index, nhop_index + - set ingress_metadata.egress_ifindex, 0 + - xor l3_metadata.same_bd_check, ingress_metadata.bd, bd + NoAction: + - { } + selection _ecmp_group_0$act_sel..ecmp_action_profile: + p4: { name: ecmp_action_profile } + row: 15 + column: [ 4, 5 ] + maprams: [ 4, 5 ] + input_xbar: + group 0: { 64: hash_metadata.hash1 } + hash 1: + 0..13: random(hash_metadata.hash1) + hash group 1: + table: [1] + mode: fair 0 + per_flow_enable: meter_pfe + non_linear: true + pool_sizes: [4, 120] + exact_match _nexthop_0 1: + p4: { name: nexthop, size: 16384 } + p4_param_order: + l3_metadata.nexthop_index: { type: exact, size: 16} + row: 6 + bus: 0 + column: [ 2, 3, 4, 6 ] + ways: + - [2, 0, 0x0, [6, 2]] + - [2, 1, 0x0, [6, 3]] + - [2, 2, 0x0, [6, 4]] + - [2, 3, 0x0, [6, 6]] + input_xbar: + group 1: { 0: l3_metadata.nexthop_index } + hash 2: + 0..9: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) + 10..19: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) + 20..29: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) + 30..39: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) + hash group 2: + table: [2] + format: { action(0): 0..1, version(0): 112..115, match(0): 34..39, action(1): 2..3, version(1): 116..119, match(1): 42..47, action(2): 4..5, version(2): 120..123, match(2): 50..55, action(3): 6..7, version(3): 124..127, match(3): 58..63 } + match: [ l3_metadata.nexthop_index(10..15) ] + next: _learn_notify_0 + action: _nexthop_0$action + default_action: NoAction + action _nexthop_0$action: + p4: { name: _nexthop_0$action } + row: [ 14, 13, 12, 11 ] + column: + - 5 + - [ 1, 2, 3, 4, 5 ] + - 5 + - 0 + home_row: 14 + format set_nexthop_details: { $adf_b0: 0..7, $adf_h0: 32..47, $adf_h1: 48..63 } + format set_nexthop_details_for_post_routed_flood: { $adf_h1: 48..63 } + action_bus: { 2 : $adf_b0, 32..33 : $adf_h0, 34..35 : $adf_h1 } + actions: + nop: + - { } + set_nexthop_details: + - p4_param_order: {ifindex: 16, bd: 14, tunnel: 1 } + - { $data0: $adf_b0, $constant0: $data0(0..0), $constant0: 0, tunnel: $data0(0..0), bd: $adf_h0, ifindex: $adf_h1 } + - set ingress_metadata.egress_ifindex, ifindex + - xor l3_metadata.same_bd_check, ingress_metadata.bd, bd + - xor l2_metadata.same_if_check, l2_metadata.same_if_check, ifindex + - xor tunnel_metadata.tunnel_if_check, $constant0, tunnel + set_nexthop_details_for_post_routed_flood: + - p4_param_order: {bd: 14, uuc_mc_index: 16 } + - { bd: $adf_h1 } + - set ingress_metadata.egress_ifindex, 0 + - xor l3_metadata.same_bd_check, ingress_metadata.bd, bd + NoAction: + - { } + ternary_match _learn_notify_0 3: + p4: { name: learn_notify, size: 512 } + p4_param_order: + l2_metadata.l2_src_miss: { type: ternary, size: 1} + l2_metadata.l2_src_move: { type: ternary, size: 16} + l2_metadata.stp_state: { type: ternary, size: 3} + row: 0 + bus: 0 + column: 0 + input_xbar: + group 0: { 0: l2_metadata.l2_src_move, 21: l2_metadata.l2_src_miss, 28: l2_metadata.stp_state } + gateway: + input_xbar: + group 0: { 20: l2_metadata.learning_enabled } + row: 0 + bus: 1 + match: { 4: l2_metadata.learning_enabled } + 0b***1: run_table + miss: _lag_group_0 + next: _lag_group_0 + indirect: _learn_notify_0$tind + ternary_indirect _learn_notify_0$tind: + row: 0 + bus: 0 + column: 2 + format: { action: 0..1} + actions: + nop: + - 0 + generate_learn_notify: + - set $learning, 1 + NoAction: + - 0 + default_action: NoAction +stage 10 ingress: + exact_match _lag_group_0 0: + p4: { name: lag_group, size: 1024, action_profile: lag_action_profile } + p4_param_order: + ingress_metadata.egress_ifindex: { type: exact, size: 16} + row: 6 + bus: 1 + column: [ 3, 4, 6 ] + ways: + - [0, 0, 0x0, [6, 3]] + - [0, 1, 0x0, [6, 4]] + - [0, 2, 0x0, [6, 6]] + input_xbar: + group 0: { 0: ingress_metadata.egress_ifindex } + hash 0: + 0..9: random(ingress_metadata.egress_ifindex(10..15)) ^ stripe(ingress_metadata.egress_ifindex(0..7), ingress_metadata.egress_ifindex(8..9)) + 10..19: random(ingress_metadata.egress_ifindex(10..15)) ^ stripe(ingress_metadata.egress_ifindex(0..7), ingress_metadata.egress_ifindex(8..9)) + 20..29: random(ingress_metadata.egress_ifindex(10..15)) ^ stripe(ingress_metadata.egress_ifindex(0..7), ingress_metadata.egress_ifindex(8..9)) + hash group 0: + table: [0] + format: { action(0): 22..23, version(0): 112..115, meter_addr(0): 0..9, meter_pfe(0): 10..10, action_addr(0): 11..21, match(0): 34..39 } + match: [ ingress_metadata.egress_ifindex(10..15) ] + gateway: + input_xbar: + group 0: { 0: ingress_metadata.egress_ifindex } + row: 1 + bus: 0 + match: { 0: ingress_metadata.egress_ifindex(0..7), 8: ingress_metadata.egress_ifindex(8..15) } + 0x**ff: cond-18 + miss: run_table + next: cond-18 + action: _lag_group_0$act_prof..lag_action_profile(action, action_addr) + selector: _lag_group_0$act_sel..lag_action_profile(meter_addr) + default_action: NoAction + action _lag_group_0$act_prof..lag_action_profile: + row: 14 + column: 5 + home_row: 14 + format set_lag_port: { $adf_h0: 0..15 } + action_bus: { 32..33 : $adf_h0 } + actions: + set_lag_miss: + - { } + set_lag_port: + - p4_param_order: {port: 9 } + - { port: $adf_h0 } + - set standard_metadata.egress_spec, port + NoAction: + - { } + selection _lag_group_0$act_sel..lag_action_profile: + p4: { name: lag_action_profile } + row: 15 + column: [ 4, 5 ] + maprams: [ 4, 5 ] + input_xbar: + group 0: { 64: hash_metadata.hash2 } + hash 1: + 0..13: random(hash_metadata.hash2) + hash group 1: + table: [1] + mode: fair 0 + per_flow_enable: meter_pfe + non_linear: true + pool_sizes: [4, 120] + gateway cond-18 1: + input_xbar: + group 0: { 30: ingress_metadata.port_type } + row: 0 + bus: 1 + match: { 6: ingress_metadata.port_type } + 0x1: END + miss: _system_acl_0 +stage 11 ingress: + ternary_match _system_acl_0 0: + p4: { name: system_acl, size: 512 } + p4_param_order: + acl_metadata.if_label: { type: ternary, size: 16} + acl_metadata.bd_label: { type: ternary, size: 16} + ingress_metadata.ifindex: { type: ternary, size: 16} + l2_metadata.lkp_mac_type: { type: ternary, size: 16} + l2_metadata.port_vlan_mapping_miss: { type: ternary, size: 1} + security_metadata.ipsg_check_fail: { type: ternary, size: 1} + acl_metadata.acl_deny: { type: ternary, size: 1} + acl_metadata.racl_deny: { type: ternary, size: 1} + l3_metadata.urpf_check_fail: { type: ternary, size: 1} + ingress_metadata.drop_flag: { type: ternary, size: 1} + l3_metadata.l3_copy: { type: ternary, size: 1} + l3_metadata.rmac_hit: { type: ternary, size: 1} + l3_metadata.routed: { type: ternary, size: 1} + ipv6_metadata.ipv6_src_is_link_local: { type: ternary, size: 1} + l2_metadata.same_if_check: { type: ternary, size: 16} + tunnel_metadata.tunnel_if_check: { type: ternary, size: 1} + l3_metadata.same_bd_check: { type: ternary, size: 14} + l3_metadata.lkp_ip_ttl: { type: ternary, size: 8} + l2_metadata.stp_state: { type: ternary, size: 3} + ingress_metadata.control_frame: { type: ternary, size: 1} + ipv4_metadata.ipv4_unicast_enabled: { type: ternary, size: 1} + ipv6_metadata.ipv6_unicast_enabled: { type: ternary, size: 1} + ingress_metadata.egress_ifindex: { type: ternary, size: 16} + fabric_metadata.reason_code: { type: ternary, size: 16} + row: [ 0, 1, 2, 3, 4, 5 ] + bus: [ 0, 0, 0, 0, 0, 0 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + input_xbar: + group 0: { 0: acl_metadata.bd_label, 16: acl_metadata.if_label, 32: fabric_metadata.reason_code(0..7) } + group 1: { 0: ingress_metadata.egress_ifindex(0..7), 8: fabric_metadata.reason_code(8..15), 16: ingress_metadata.ifindex(0..7), 24: ingress_metadata.egress_ifindex(8..15), 32: l2_metadata.lkp_mac_type(0..7), 42: ipv6_metadata.ipv6_src_is_link_local } + group 2: { 0: ingress_metadata.ifindex(8..15), 8: l2_metadata.same_if_check(0..7), 23: ipv6_metadata.ipv6_unicast_enabled, 24: l3_metadata.same_bd_check(0..7), 32: l2_metadata.lkp_mac_type(8..15) } + group 3: { 0: l2_metadata.same_if_check(8..15), 12: acl_metadata.acl_deny, 16: l3_metadata.same_bd_check(8..13), 30: acl_metadata.racl_deny, 37: ingress_metadata.control_frame, 42: ingress_metadata.drop_flag } + group 4: { 5: ipv4_metadata.ipv4_unicast_enabled, 14: l2_metadata.port_vlan_mapping_miss, 20: l2_metadata.stp_state, 30: l3_metadata.l3_copy, 32: l3_metadata.lkp_ip_ttl } + group 5: { 4: l3_metadata.rmac_hit, 12: l3_metadata.routed, 22: l3_metadata.urpf_check_fail, 30: security_metadata.ipsg_check_fail, 32: tunnel_metadata.tunnel_if_check } + gateway: + input_xbar: + group 0: { 0: ingress_metadata.bypass_lookups } + row: 0 + bus: 0 + match: { 0: ingress_metadata.bypass_lookups(0..7), 8: ingress_metadata.bypass_lookups(8..15) } + 0b**********0*****: run_table + miss: END + next: _drop_stats_4 + action_bus: { } + indirect: _system_acl_0$tind + counter _system_acl_0$counter..drop_stats: + p4: { name: drop_stats } + row: 13 + column: [ 0, 1 ] + maprams: [ 0, 1 ] + count: packets + format: {packets(0): 106..126, packets(1): 85..105, packets(2): 64..84, packets(3): 42..62, packets(4): 21..41, packets(5): 0..20} + per_flow_enable: counter_pfe + ternary_indirect _system_acl_0$tind: + row: 0 + bus: 0 + column: 2 + format: { action: 27..29, immediate: 11..26, counter_addr: 0..9, counter_pfe: 10..10} + stats: _system_acl_0$counter..drop_stats(counter_addr) + actions: + nop: + - { } + redirect_to_cpu: + - p4_param_order: {qid: 5, meter_id: 8, icos: 3 } + - { } + - invalidate standard_metadata.egress_spec + redirect_to_cpu_with_reason: + - p4_param_order: {reason_code: 16, qid: 5, meter_id: 8, icos: 3 } + - { reason_code: immediate(0..15) } + - set fabric_metadata.reason_code, reason_code + - invalidate standard_metadata.egress_spec + copy_to_cpu: + - p4_param_order: {qid: 5, meter_id: 8, icos: 3 } + - { } + copy_to_cpu_with_reason: + - p4_param_order: {reason_code: 16, qid: 5, meter_id: 8, icos: 3 } + - { reason_code: immediate(0..15) } + - set fabric_metadata.reason_code, reason_code + drop_packet: + - { } + - invalidate standard_metadata.egress_spec + drop_packet_with_reason: + - p4_param_order: {drop_reason: 32 } + - { } + - { drop_reason: counter_addr } + - invalidate standard_metadata.egress_spec + NoAction: + - { } + default_action: NoAction + hash_action _drop_stats_4 1: + p4: { name: drop_stats, size: 256 } + row: 0 + bus: 0 + column: [ ] + hash_dist: + 0: {hash: 0, mask: 0xff, shift: 3} + input_xbar: + exact group 0: { 16: ingress_metadata.drop_reason } + hash 0: + 0..7: ingress_metadata.drop_reason + hash group 0: + table: [0] + gateway: + input_xbar: + group 0: { 70: ingress_metadata.drop_flag } + row: 0 + bus: 1 + payload: 1 + match: { 6: ingress_metadata.drop_flag } + 0b*1: END + miss: run_table + next: END + stats: _drop_stats_4$counter..drop_stats_2(hash_dist 0) + actions: + drop_stats_update: + - 0 + NoAction: + - 0 + default_action: NoAction + counter _drop_stats_4$counter..drop_stats_2: + p4: { name: drop_stats_2 } + row: 9 + column: [ 0, 1 ] + maprams: [ 0, 1 ] + count: packets + format: {packets(0): 106..126, packets(1): 85..105, packets(2): 64..84, packets(3): 42..62, packets(4): 21..41, packets(5): 0..20} +stage 0 egress: + exact_match egress_port_mapping 3: + p4: { name: egress_port_mapping, size: 288 } + p4_param_order: + standard_metadata.egress_port: { type: exact, size: 9} + row: 2 + bus: 1 + column: [ 6, 7, 8 ] + ways: + - [1, 0, 0x0, [2, 6]] + - [1, 1, 0x0, [2, 7]] + - [1, 2, 0x0, [2, 8]] + input_xbar: + group 0: { 64: standard_metadata.egress_port } + hash 1: + 0..9: random(standard_metadata.egress_port(1..7)) ^ stripe(standard_metadata.egress_port(0), standard_metadata.egress_port(8)) + 10..19: random(standard_metadata.egress_port(1..7)) ^ stripe(standard_metadata.egress_port(0), standard_metadata.egress_port(8)) + 20..29: random(standard_metadata.egress_port(1..7)) ^ stripe(standard_metadata.egress_port(0), standard_metadata.egress_port(8)) + hash group 1: + table: [1] + format: { action(0): 0..1, immediate(0): 2..22, version(0): 112..115, match(0): 33..39 } + match: [ standard_metadata.egress_port(1..7) ] + gateway: + input_xbar: + group 0: { 17: eg_intr_md.deflection_flag, 28: egress_metadata.bypass } + row: 0 + bus: 1 + match: { 1: eg_intr_md.deflection_flag, 12: egress_metadata.bypass } + 0b***0**********0: run_table + miss: _egress_system_acl_0 + hit: [ _vlan_decap_0, _tunnel_encap_process_outer_0, _tunnel_encap_process_outer_0, _tunnel_encap_process_outer_0 ] + miss: _tunnel_encap_process_outer_0 + action_bus: { } + actions: + egress_port_type_normal: + - p4_param_order: {ifindex: 16, qos_group: 5, if_label: 16 } + - { ifindex: immediate(0..15) } + - set egress_metadata.port_type, 0 + - set egress_metadata.ifindex, ifindex + egress_port_type_fabric: + - p4_param_order: {ifindex: 16 } + - { ifindex: immediate(0..15), $constant0: immediate(16..20), $constant0: 15 } + - set egress_metadata.port_type, 1 + - set egress_metadata.ifindex, ifindex + - set tunnel_metadata.egress_tunnel_type, $constant0 + egress_port_type_cpu: + - p4_param_order: {ifindex: 16 } + - { ifindex: immediate(0..15), $constant0: immediate(16..20), $constant0: 16 } + - set egress_metadata.port_type, 2 + - set egress_metadata.ifindex, ifindex + - set tunnel_metadata.egress_tunnel_type, $constant0 + NoAction: + - { } + default_action: NoAction + exact_match _vlan_decap_0 5: + p4: { name: vlan_decap, size: 256 } + p4_param_order: + vlan_tag_$0.$valid: { type: exact, size: 1} + vlan_tag_$1.$valid: { type: exact, size: 1} + row: 3 + bus: 1 + column: [ 6, 7, 8 ] + ways: + - [3, 0, 0x0, [3, 6]] + - [3, 1, 0x0, [3, 7]] + - [3, 2, 0x0, [3, 8]] + input_xbar: + group 2: { 5: vlan_tag_$0.$valid, 14: vlan_tag_$1.$valid } + hash 4: + 0..9: stripe(vlan_tag_$0.$valid, vlan_tag_$1.$valid) + 10..19: stripe(vlan_tag_$0.$valid, vlan_tag_$1.$valid) + 20..29: stripe(vlan_tag_$0.$valid, vlan_tag_$1.$valid) + hash group 3: + table: [4] + format: { action(0): 0..1, version(0): 112..115 } + gateway: + input_xbar: + group 1: { 48: eg_intr_md_from_parser_aux.clone_src } + row: 0 + bus: 0 + match: { 0: eg_intr_md_from_parser_aux.clone_src } + 0x00: run_table + miss: _rewrite_0 + next: _rewrite_0 + actions: + nop: + - 0 + remove_vlan_single_tagged: + - set ethernet.etherType, vlan_tag_$0.etherType + remove_vlan_double_tagged: + - set ethernet.etherType, vlan_tag_$1.etherType + NoAction: + - 0 + default_action: NoAction + exact_match _rewrite_0 7: + p4: { name: rewrite, size: 16384 } + p4_param_order: + l3_metadata.nexthop_index: { type: exact, size: 16} + row: 1 + bus: 0 + column: [ 2, 3, 4, 6 ] + ways: + - [5, 0, 0x0, [1, 2]] + - [5, 1, 0x0, [1, 3]] + - [5, 2, 0x0, [1, 4]] + - [5, 3, 0x0, [1, 6]] + input_xbar: + group 3: { 0: l3_metadata.nexthop_index } + hash 6: + 0..9: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) + 10..19: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) + 20..29: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) + 30..39: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) + hash group 5: + table: [6] + format: { action(0): 0..1, version(0): 112..115, match(0): 34..39, action(1): 2..3, version(1): 116..119, match(1): 42..47, action(2): 4..5, version(2): 120..123, match(2): 50..55, action(3): 6..7, version(3): 124..127, match(3): 58..63 } + match: [ l3_metadata.nexthop_index(10..15) ] + gateway: + input_xbar: + group 1: { 64: l3_metadata.nexthop_index(0..7), 86: egress_metadata.routed, 88: l3_metadata.nexthop_index(8..15) } + row: 1 + bus: 0 + match: { 22: egress_metadata.routed, 0: l3_metadata.nexthop_index(0..7), 8: l3_metadata.nexthop_index(8..15) } + 0b*0**********************: run_table + 0x00**00: _egress_bd_stats_2 + miss: run_table + next: _egress_bd_stats_2 + actions: + nop: + - 0 + set_l2_rewrite: + - set egress_metadata.bd, ingress_metadata.bd + NoAction: + - 0 + default_action: NoAction +stage 8 egress: + exact_match _egress_bd_stats_2 4: + p4: { name: egress_bd_stats, size: 16384 } + p4_param_order: + egress_metadata.bd: { type: exact, size: 14} + l2_metadata.lkp_pkt_type: { type: exact, size: 3} + row: [ 3, 4 ] + bus: [ 1, 0 ] + column: + - 4 + - [ 2, 3, 4 ] + ways: + - [2, 0, 0x0, [4, 2]] + - [2, 1, 0x0, [4, 3]] + - [2, 2, 0x0, [4, 4]] + - [2, 3, 0x0, [3, 4]] + input_xbar: + group 1: { 0: egress_metadata.bd, 18: l2_metadata.lkp_pkt_type } + hash 2: + 0..9: random(egress_metadata.bd(1..7)) ^ stripe(egress_metadata.bd(0), egress_metadata.bd(8..13), l2_metadata.lkp_pkt_type) + 10..19: random(egress_metadata.bd(1..7)) ^ stripe(egress_metadata.bd(0), egress_metadata.bd(8..13), l2_metadata.lkp_pkt_type) + 20..29: random(egress_metadata.bd(1..7)) ^ stripe(egress_metadata.bd(0), egress_metadata.bd(8..13), l2_metadata.lkp_pkt_type) + 30..39: random(egress_metadata.bd(1..7)) ^ stripe(egress_metadata.bd(0), egress_metadata.bd(8..13), l2_metadata.lkp_pkt_type) + hash group 2: + table: [2] + format: { action(0): 0..0, version(0): 112..115, match(0): 33..39, action(1): 1..1, version(1): 116..119, match(1): 41..47, action(2): 2..2, version(2): 120..123, match(2): 49..55, action(3): 3..3, version(3): 124..127, match(3): 57..63 } + match: [ egress_metadata.bd(1..7) ] + next: _egress_bd_map_0 + stats: _egress_bd_stats_2$counter..egress_bd_stats + actions: + nop: + - 0 + NoAction: + - 0 + default_action: NoAction + counter _egress_bd_stats_2$counter..egress_bd_stats: + p4: { name: egress_bd_stats } + row: [ 13, 11 ] + column: + - [ 0, 1, 2, 3, 4, 5 ] + - 0 + maprams: + - [ 0, 1, 2, 3, 4, 5 ] + - 0 + count: packets_and_bytes + format: {packets(0): 85..101, bytes(0): 102..126, packets(1): 42..58, bytes(1): 59..83, packets(2): 0..16, bytes(2): 17..41} + exact_match _egress_bd_map_0 5: + p4: { name: egress_bd_map, size: 16384 } + p4_param_order: + egress_metadata.bd: { type: exact, size: 14} + row: [ 3, 5 ] + bus: [ 0, 1 ] + column: + - [ 2, 3 ] + - [ 3, 4 ] + ways: + - [3, 0, 0x0, [5, 3]] + - [3, 1, 0x0, [5, 4]] + - [3, 2, 0x0, [3, 2]] + - [3, 3, 0x0, [3, 3]] + input_xbar: + group 1: { 64: egress_metadata.bd } + hash 3: + 0..9: random(egress_metadata.bd(4..7)) ^ stripe(egress_metadata.bd(0..3), egress_metadata.bd(8..13)) + 10..19: random(egress_metadata.bd(4..7)) ^ stripe(egress_metadata.bd(0..3), egress_metadata.bd(8..13)) + 20..29: random(egress_metadata.bd(4..7)) ^ stripe(egress_metadata.bd(0..3), egress_metadata.bd(8..13)) + 30..39: random(egress_metadata.bd(4..7)) ^ stripe(egress_metadata.bd(0..3), egress_metadata.bd(8..13)) + hash group 3: + table: [3] + format: { action(0): 0..1, version(0): 112..115, match(0): 36..39, action(1): 2..3, version(1): 116..119, match(1): 44..47, action(2): 4..5, version(2): 120..123, match(2): 52..55, action(3): 6..7, version(3): 124..127, match(3): 60..63 } + match: [ egress_metadata.bd(4..7) ] + next: _tunnel_encap_process_outer_0 + actions: + nop: + - 0 + set_egress_bd_properties: + - p4_param_order: {smac_idx: 9, nat_mode: 2, bd_label: 16 } + - 0 + NoAction: + - 0 + default_action: NoAction + exact_match _tunnel_encap_process_outer_0 6: + p4: { name: tunnel_encap_process_outer, size: 256 } + p4_param_order: + tunnel_metadata.egress_tunnel_type: { type: exact, size: 5} + tunnel_metadata.egress_header_count: { type: exact, size: 4} + multicast_metadata.replica: { type: exact, size: 1} + row: 7 + bus: 0 + column: [ 2, 3, 4 ] + ways: + - [4, 0, 0x0, [7, 2]] + - [4, 1, 0x0, [7, 3]] + - [4, 2, 0x0, [7, 4]] + input_xbar: + group 2: { 0: tunnel_metadata.egress_tunnel_type, 15: multicast_metadata.replica, 26: tunnel_metadata.egress_header_count } + hash 4: + 0..9: stripe(tunnel_metadata.egress_tunnel_type, multicast_metadata.replica, tunnel_metadata.egress_header_count) + 10..19: stripe(tunnel_metadata.egress_tunnel_type, multicast_metadata.replica, tunnel_metadata.egress_header_count) + 20..29: stripe(tunnel_metadata.egress_tunnel_type, multicast_metadata.replica, tunnel_metadata.egress_header_count) + hash group 4: + table: [4] + format: { action(0): 14..15, immediate(0): 0..13, version(0): 112..115 } + gateway: + input_xbar: + group 1: { 25: fabric_metadata.fabric_header_present, 32: tunnel_metadata.egress_tunnel_type } + row: 1 + bus: 1 + match: { 0: tunnel_metadata.egress_tunnel_type, 9: fabric_metadata.fabric_header_present } + 0b***********00000: _egress_vlan_xlate_0 + 0b******0*********: run_table + miss: _egress_vlan_xlate_0 + next: _tunnel_rewrite_0 + action_bus: { } + actions: + nop: + - { } + fabric_rewrite: + - p4_param_order: {tunnel_index: 14 } + - { tunnel_index: immediate(0..13) } + - set tunnel_metadata.tunnel_index, tunnel_index + NoAction: + - { } + default_action: NoAction +stage 9 egress: + exact_match _tunnel_rewrite_0 2: + p4: { name: tunnel_rewrite, size: 16384 } + p4_param_order: + tunnel_metadata.tunnel_index: { type: exact, size: 14} + row: 7 + bus: 1 + column: [ 6, 7, 8, 9 ] + ways: + - [3, 0, 0x0, [7, 6]] + - [3, 1, 0x0, [7, 7]] + - [3, 2, 0x0, [7, 8]] + - [3, 3, 0x0, [7, 9]] + input_xbar: + group 1: { 64: tunnel_metadata.tunnel_index } + hash 3: + 0..9: random(tunnel_metadata.tunnel_index(4..7)) ^ stripe(tunnel_metadata.tunnel_index(0..3), tunnel_metadata.tunnel_index(8..13)) + 10..19: random(tunnel_metadata.tunnel_index(4..7)) ^ stripe(tunnel_metadata.tunnel_index(0..3), tunnel_metadata.tunnel_index(8..13)) + 20..29: random(tunnel_metadata.tunnel_index(4..7)) ^ stripe(tunnel_metadata.tunnel_index(0..3), tunnel_metadata.tunnel_index(8..13)) + 30..39: random(tunnel_metadata.tunnel_index(4..7)) ^ stripe(tunnel_metadata.tunnel_index(0..3), tunnel_metadata.tunnel_index(8..13)) + hash group 3: + table: [3] + format: { action(0): 32..33, immediate(0): 0..7, version(0): 112..115, match(0): 44..47, action(1): 34..35, immediate(1): 8..15, version(1): 116..119, match(1): 52..55, action(2): 36..37, immediate(2): 16..23, version(2): 120..123, match(2): 60..63, action(3): 38..39, immediate(3): 24..31, version(3): 124..127, match(3): 68..71 } + match: [ tunnel_metadata.tunnel_index(4..7) ] + next: _egress_vlan_xlate_0 + action_bus: { } + actions: + nop: + - { } + cpu_rx_rewrite: + - { $data0: immediate(0..7), $constant0: $data0(3..4), $constant0: 0, $constant1: $data0(1..2), $constant1: 0, $constant2: $data0(0..0), $constant2: 0, $constant3: $data0(5..7), $constant3: 5 } + - set fabric_header_cpu.ingressPort, ingress_metadata.ingress_port + - set fabric_header_cpu.ingressIfindex, ingress_metadata.ifindex + - set fabric_header_cpu.ingressBd, ingress_metadata.bd + - set fabric_header_cpu.reasonCode, fabric_metadata.reason_code + - set fabric_payload_header.etherType, ethernet.etherType + - set ethernet.etherType, 36864 + - set B19, $data0 + NoAction: + - { } + default_action: NoAction +stage 10 egress: + exact_match _egress_vlan_xlate_0 2: + p4: { name: egress_vlan_xlate, size: 32768 } + p4_param_order: + egress_metadata.ifindex: { type: exact, size: 16} + egress_metadata.bd: { type: exact, size: 14} + row: [ 6, 7 ] + bus: [ 0, 0 ] + column: + - 2 + - [ 2, 3, 4, 6, 7, 8, 9 ] + ways: + - [2, 0, 0x1, [7, 2], [7, 3]] + - [2, 1, 0x2, [7, 4], [7, 6]] + - [2, 2, 0x4, [7, 7], [7, 8]] + - [2, 3, 0x8, [7, 9], [6, 2]] + input_xbar: + group 1: { 0: egress_metadata.bd, 16: egress_metadata.ifindex } + hash 2: + 0..9: random(egress_metadata.bd(0..7), egress_metadata.ifindex(5..15)) ^ stripe(egress_metadata.bd(8..13), egress_metadata.ifindex(0..4)) + 10..19: random(egress_metadata.bd(0..7), egress_metadata.ifindex(5..15)) ^ stripe(egress_metadata.bd(8..13), egress_metadata.ifindex(0..4)) + 20..29: random(egress_metadata.bd(0..7), egress_metadata.ifindex(5..15)) ^ stripe(egress_metadata.bd(8..13), egress_metadata.ifindex(0..4)) + 30..39: random(egress_metadata.bd(0..7), egress_metadata.ifindex(5..15)) ^ stripe(egress_metadata.bd(8..13), egress_metadata.ifindex(0..4)) + 40..43: random(egress_metadata.bd(0..7), egress_metadata.ifindex(5..15)) ^ stripe(egress_metadata.bd(8..13), egress_metadata.ifindex(0..4)) + hash group 2: + table: [2] + format: { action(0): 0..1, version(0): 112..115, match(0): [40..47, 101..103, 32..39 ], action(1): 2..3, version(1): 116..119, match(1): [56..63, 109..111, 48..55 ], action(2): 4..5, version(2): 120..123, match(2): [72..79, 13..15, 64..71 ], action(3): 6..7, version(3): 124..127, match(3): [88..95, 21..23, 80..87 ] } + match: [ egress_metadata.bd(0..7), egress_metadata.ifindex(5..15) ] + gateway: + input_xbar: + group 0: { 19: egress_metadata.port_type } + row: 0 + bus: 0 + match: { 3: egress_metadata.port_type } + 0b***00: run_table + miss: _egress_system_acl_0 + next: _egress_system_acl_0 + action: _egress_vlan_xlate_0$action + default_action: NoAction + action _egress_vlan_xlate_0$action: + p4: { name: _egress_vlan_xlate_0$action } + row: [ 13, 12, 11 ] + column: + - [ 1, 2, 3, 4, 5 ] + - 5 + - [ 0, 1 ] + home_row: 13 + format set_egress_packet_vlan_tagged: { $adf_h1: 16..31 } + format set_egress_packet_vlan_double_tagged: { $adf_h0: 0..15, $adf_h1: 16..31 } + action_bus: { 36..37 : $adf_h0, 38..39 : $adf_h1 } + actions: + set_egress_packet_vlan_untagged: + - { } + set_egress_packet_vlan_tagged: + - p4_param_order: {vlan_id: 12 } + - { vlan_id: $adf_h1 } + - set vlan_tag_$0.etherType, ethernet.etherType + - set vlan_tag_$0.vid, vlan_id + - set ethernet.etherType, 33024 + set_egress_packet_vlan_double_tagged: + - p4_param_order: {s_tag: 12, c_tag: 12 } + - { c_tag: $adf_h0, s_tag: $adf_h1 } + - set vlan_tag_$1.etherType, ethernet.etherType + - set vlan_tag_$1.vid, c_tag + - set vlan_tag_$0.etherType, 33024 + - set vlan_tag_$0.vid, s_tag + - set ethernet.etherType, 37120 + NoAction: + - { } + ternary_match _egress_system_acl_0 3: + p4: { name: egress_system_acl, size: 128 } + p4_param_order: + fabric_metadata.reason_code: { type: ternary, size: 16} + standard_metadata.egress_port: { type: ternary, size: 9} + eg_intr_md.deflection_flag: { type: ternary, size: 1} + l3_metadata.l3_mtu_check: { type: ternary, size: 16} + acl_metadata.acl_deny: { type: ternary, size: 1} + row: [ 0, 1 ] + bus: [ 0, 0 ] + column: + - 0 + - 0 + input_xbar: + group 0: { 0: fabric_metadata.reason_code(0..7), 15: acl_metadata.acl_deny, 16: l3_metadata.l3_mtu_check(0..7), 24: fabric_metadata.reason_code(8..15), 32: standard_metadata.egress_port(0..7) } + group 1: { 1: eg_intr_md.deflection_flag, 8: l3_metadata.l3_mtu_check(8..15), 24: standard_metadata.egress_port(8) } + gateway: + input_xbar: + group 0: { 36: egress_metadata.bypass } + row: 1 + bus: 1 + match: { 4: egress_metadata.bypass } + 0b***0: run_table + miss: END + next: END + action_bus: { } + indirect: _egress_system_acl_0$tind + ternary_indirect _egress_system_acl_0$tind: + row: 0 + bus: 0 + column: 2 + format: { action: 16..18, immediate: 0..15} + actions: + nop: + - { } + drop_packet: + - { } + - invalidate standard_metadata.egress_port + egress_copy_to_cpu: + - { } + - set $mirror_id, 250 + - set $mirror, 1 + egress_redirect_to_cpu: + - { } + - set $mirror_id, 250 + - set $mirror, 2 + - invalidate standard_metadata.egress_port + egress_copy_to_cpu_with_reason: + - p4_param_order: {reason_code: 16 } + - { reason_code: immediate(0..15) } + - set fabric_metadata.reason_code, reason_code + - set $mirror_id, 250 + - set $mirror, 3 + egress_redirect_to_cpu_with_reason: + - p4_param_order: {reason_code: 16 } + - { reason_code: immediate(0..15) } + - set fabric_metadata.reason_code, reason_code + - set $mirror_id, 250 + - set $mirror, 4 + - invalidate standard_metadata.egress_port + egress_mirror_coal_hdr: + - p4_param_order: {session_id: 8, id: 8 } + - { } + NoAction: + - { } + default_action: NoAction diff --git a/backends/tofino/bf-asm/test/asm/table_action_alias.tfa b/backends/tofino/bf-asm/test/asm/table_action_alias.tfa new file mode 100644 index 00000000000..01b6f4248b3 --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/table_action_alias.tfa @@ -0,0 +1,66 @@ +version: 1.0.0 +phv ingress: + standard_metadata.egress_spec: H0(0..8) + data.f1: W0 + data.n1: B0(4..7) + data.n2: B0(0..3) + data.$valid: B47(7) +phv egress: + standard_metadata.egress_port: H16(0..8) +parser ingress: + start: $ingress_metadata_shim + $ingress_metadata_shim: + 0x*: + shift: 16 + next: start$ + start$: + 0x*: + 0..3: data.f1 + 4: B0 + data.$valid: 1 + shift: 5 + next: end +deparser ingress: + dictionary: + data.f1: data.$valid + B0: data.$valid + egress_unicast_port: standard_metadata.egress_spec +parser egress: + start: $egress_metadata_shim + $egress_metadata_shim: + 0x*: + 0..1: H16 + shift: 2 + next: end +deparser egress: + dictionary: {} + egress_unicast_port: standard_metadata.egress_port +stage 0 ingress: + exact_match test1 0: + p4: { name: test1 } + row: 7 + bus: 0 + column: [ 2, 3, 4 ] + ways: + - [0, 0, 0x0, [7, 2]] + - [0, 1, 0x0, [7, 3]] + - [0, 2, 0x0, [7, 4]] + input_xbar: + group 0: { 0: data.f1 } + hash 0: + 0..9: random(data.f1(0..15), data.f1(18..23)) ^ stripe(data.f1(16..17), data.f1(24..31)) + 10..19: random(data.f1(0..15), data.f1(18..23)) ^ stripe(data.f1(16..17), data.f1(24..31)) + 20..29: random(data.f1(0..15), data.f1(18..23)) ^ stripe(data.f1(16..17), data.f1(24..31)) + hash group 0: + table: [0] + format: { action(0): 8..8, immediate(0): 0..7, version(0): 112..115, match(0): [32..47, 50..55 ] } + match: [ data.f1(0..15), data.f1(18..23) ] + next: END + actions: + set_nibbles: + - { $data0: immediate(0..7) } + - set B0, $data0 + - { param1.0-3: $data0(4..7), param2.0-3: $data0(0..3) } + NoAction: + - { } + default_action: NoAction diff --git a/backends/tofino/bf-asm/test/asm/table_alias_fields_error.tfa b/backends/tofino/bf-asm/test/asm/table_alias_fields_error.tfa new file mode 100644 index 00000000000..5940f502b0c --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/table_alias_fields_error.tfa @@ -0,0 +1,66 @@ +version: 1.0.0 +phv ingress: + standard_metadata.egress_spec: H0(0..8) + data.f1: W0 + data.n1: B0(4..7) + data.n2: B0(0..3) + data.$valid: B47(7) +phv egress: + standard_metadata.egress_port: H16(0..8) +parser ingress: + start: $ingress_metadata_shim + $ingress_metadata_shim: + 0x*: + shift: 16 + next: start$ + start$: + 0x*: + 0..3: data.f1 + 4: B0 + data.$valid: 1 + shift: 5 + next: end +deparser ingress: + dictionary: + data.f1: data.$valid + B0: data.$valid + egress_unicast_port: standard_metadata.egress_spec +parser egress: + start: $egress_metadata_shim + $egress_metadata_shim: + 0x*: + 0..1: H16 + shift: 2 + next: end +deparser egress: + dictionary: {} + egress_unicast_port: standard_metadata.egress_port +stage 0 ingress: + exact_match test1 0: + p4: { name: test1 } + row: 7 + bus: 0 + column: [ 2, 3, 4 ] + ways: + - [0, 0, 0x0, [7, 2]] + - [0, 1, 0x0, [7, 3]] + - [0, 2, 0x0, [7, 4]] + input_xbar: + group 0: { 0: data.f1 } + hash 0: + 0..9: random(data.f1(0..15), data.f1(18..23)) ^ stripe(data.f1(16..17), data.f1(24..31)) + 10..19: random(data.f1(0..15), data.f1(18..23)) ^ stripe(data.f1(16..17), data.f1(24..31)) + 20..29: random(data.f1(0..15), data.f1(18..23)) ^ stripe(data.f1(16..17), data.f1(24..31)) + hash group 0: + table: [0] + format: { action(0): 8..8, immediate(0): 0..7, version(0): 112..115, match(0): [32..47, 50..55 ] } + match: [ data.f1(0..15), data.f1(18..23) ] + next: END + actions: + set_nibbles: + - { $data0: immediate(0..3) } + - set B0, $data0 + - { param1.0-3: $data0(4..7), param2.0-3: $data0(0..3) } + NoAction: + - { } + default_action: NoAction diff --git a/backends/tofino/bf-asm/test/asm/tor.tfa b/backends/tofino/bf-asm/test/asm/tor.tfa new file mode 100644 index 00000000000..75e26a49239 --- /dev/null +++ b/backends/tofino/bf-asm/test/asm/tor.tfa @@ -0,0 +1,1587 @@ +version: 1.0.0 +phv ingress: + standard_metadata.ingress_port: H13(0..8) + standard_metadata.egress_spec: H0(0..8) + $bridge-metadata: B63(6) + packet_out.egress_physical_port: H1(0..8) + packet_out.submit_to_ingress: H13(15) + ethernet.dst_addr.32-47: H5 + ethernet.dst_addr.16-31: H4 + ethernet.dst_addr.0-15: H3 + ethernet.src_addr.32-47: H8 + ethernet.src_addr.16-31: H7 + ethernet.src_addr.0-15: H6 + ethernet.ether_type: H82 + vlan_tag$0.pcp: H15(13..15) + vlan_tag$0.cfi: H15(12) + vlan_tag$0.vid: H15(0..11) + vlan_tag$0.ether_type: H81 + vlan_tag$1.pcp: TH3(13..15) + vlan_tag$1.cfi: TH3(12) + vlan_tag$1.vid: TH3(0..11) + vlan_tag$1.ether_type: H80 + ipv4_base.version: TB1(4..7) + ipv4_base.ihl: TB1(0..3) + ipv4_base.diffserv: B5 + ipv4_base.total_len: TH18 + ipv4_base.identification: TH17 + ipv4_base.flags: H14(13..15) + ipv4_base.frag_offset: H14(0..12) + ipv4_base.ttl: B0 + ipv4_base.protocol: B7 + ipv4_base.hdr_checksum: TH16 + ipv4_base.src_addr: W10 + ipv4_base.dst_addr: W12 + tcp.src_port: H11 + tcp.dst_port: H9 + tcp.seq_no: TW2 + tcp.ack_no: TW1 + tcp.data_offset: TB0(4..7) + tcp.res: TB0(0..3) + tcp.flags: TB4 + tcp.window: TH15 + tcp.checksum: TH14 + tcp.urgent_ptr: TH13 + local_metadata.vrf_id: W11 + local_metadata.class_id: B3 + local_metadata.skip_egress: B63(6) + local_metadata.egress_spec_at_punt_match: H2(0..8) + local_metadata.color: B47(5..6) + local_metadata.l4_src_port: H12 + local_metadata.l4_dst_port: H10 + local_metadata.icmp_code: B2 + udp.src_port: H11 + udp.dst_port: H9 + udp.hdr_length: TH12 + udp.checksum: TH11 + ipv6_base.version: W8(28..31) + ipv6_base.traffic_class: W8(20..27) + ipv6_base.flow_label: W8(0..19) + ipv6_base.payload_length: TH10 + ipv6_base.next_header: B6 + ipv6_base.hop_limit: B4 + ipv6_base.src_addr.96-127: W3 + ipv6_base.src_addr.64-95: W2 + ipv6_base.src_addr.32-63: W1 + ipv6_base.src_addr.0-31: W0 + ipv6_base.dst_addr.96-127: W7 + ipv6_base.dst_addr.64-95: W6 + ipv6_base.dst_addr.32-63: W5 + ipv6_base.dst_addr.0-31: W4 + arp.hw_type: TH9 + arp.proto_type: TH8 + arp.hw_addr_len: TB3 + arp.proto_addr_len: TB2 + arp.opcode: TH7 + arp.sender_hw_addr.32-47: TH6 + arp.sender_hw_addr.16-31: TH5 + arp.sender_hw_addr.0-15: TH4 + arp.sender_proto_addr: TW0 + arp.target_hw_addr.32-47: TH2 + arp.target_hw_addr.16-31: TH1 + arp.target_hw_addr.0-15: TH0 + arp.target_proto_addr: W9 + hasExited: B63(6) + $mirror_id: B1 + $mirror: B15(4..6) + arp.$valid: B15(7) + ethernet.$valid: B47(7) + ipv4_base.$valid: B63(7) + ipv6_base.$valid: B14(7) + packet_out.$valid: B46(7) + tcp.$valid: B45(7) + udp.$valid: B62(7) + vlan_tag$0.$valid: B61(7) + vlan_tag$1.$valid: B13(7) +phv egress: + standard_metadata.ingress_port: H19(0..8) + standard_metadata.egress_spec: H22(0..8) + standard_metadata.egress_port: H16(0..8) + local_metadata.skip_egress: B31(6) + local_metadata.egress_spec_at_punt_match: H17(0..8) + local_metadata.l4_dst_port: H21 + packet_out.egress_physical_port: TH27(0..8) + packet_out.submit_to_ingress: TW27(31) + ethernet.dst_addr.32-47: TH30 + ethernet.dst_addr.16-31: TH29 + ethernet.dst_addr.0-15: TH28 + ethernet.src_addr.32-47: TH26 + ethernet.src_addr.16-31: TH25 + ethernet.src_addr.0-15: TH24 + ethernet.ether_type: H26 + vlan_tag$0.pcp: TH32(13..15) + vlan_tag$0.cfi: TH32(12) + vlan_tag$0.vid: TH32(0..11) + vlan_tag$0.ether_type: H25 + vlan_tag$1.pcp: TH31(13..15) + vlan_tag$1.cfi: TH31(12) + vlan_tag$1.vid: TH31(0..11) + vlan_tag$1.ether_type: H24 + ipv4_base.version: TB16(4..7) + ipv4_base.ihl: TB16(0..3) + ipv4_base.diffserv: TB19 + ipv4_base.total_len: TH40 + ipv4_base.identification: TH39 + ipv4_base.flags: H23(13..15) + ipv4_base.frag_offset: H23(0..12) + ipv4_base.ttl: TB18 + ipv4_base.protocol: B17 + ipv4_base.hdr_checksum: TH38 + ipv4_base.src_addr: TW26 + ipv4_base.dst_addr: TW25 + udp.src_port: TH37 + udp.dst_port: TH36 + udp.hdr_length: TH35 + udp.checksum: TH34 + ipv6_base.version: TW24(28..31) + ipv6_base.traffic_class: TW24(20..27) + ipv6_base.flow_label: TW24(0..19) + ipv6_base.payload_length: TH33 + ipv6_base.next_header: B16 + ipv6_base.hop_limit: TB17 + ipv6_base.src_addr.96-127: TW23 + ipv6_base.src_addr.64-95: TW22 + ipv6_base.src_addr.32-63: TW21 + ipv6_base.src_addr.0-31: TW20 + ipv6_base.dst_addr.96-127: TW19 + ipv6_base.dst_addr.64-95: TW18 + ipv6_base.dst_addr.32-63: TW17 + ipv6_base.dst_addr.0-31: TW16 + hasExited_0: H22(15) + ethernet.$valid: B31(7) + ipv4_base.$valid: B30(7) + ipv6_base.$valid: B29(7) + packet_out.$valid: B28(7) + udp.$valid: B27(7) + vlan_tag$0.$valid: B26(7) + vlan_tag$1.$valid: B25(7) +parser ingress: + start: $ingress_metadata_shim + $ingress_metadata_shim: + 0x*: + 0..1: H13 + shift: 16 + next: $bridge-metadata + save: { half:0..1 } + $bridge-metadata: + 0x*: + $bridge-metadata: 1 + next: start$ + start$: + match: [ half ] + 0x0fd: + next: parse_cpu_header + 0x*: + next: parse_ethernet + parse_cpu_header: + 0x*: + 0..1: H1 + 2..3: H13 + packet_out.$valid: 1 + shift: 2 + next: parse_ethernet + parse_ethernet: + match: [ 12..13 ] + 0x8100: + 0..1: ethernet.dst_addr.32-47 + 2..3: ethernet.dst_addr.16-31 + 4..5: ethernet.dst_addr.0-15 + 6..7: ethernet.src_addr.32-47 + shift: 8 + next: parse_ethernet.0 + 0x9100: + 0..1: ethernet.dst_addr.32-47 + 2..3: ethernet.dst_addr.16-31 + 4..5: ethernet.dst_addr.0-15 + 6..7: ethernet.src_addr.32-47 + shift: 8 + next: parse_ethernet.1 + 0x9200: + 0..1: ethernet.dst_addr.32-47 + 2..3: ethernet.dst_addr.16-31 + 4..5: ethernet.dst_addr.0-15 + 6..7: ethernet.src_addr.32-47 + shift: 8 + next: parse_ethernet.2 + 0x9300: + 0..1: ethernet.dst_addr.32-47 + 2..3: ethernet.dst_addr.16-31 + 4..5: ethernet.dst_addr.0-15 + 6..7: ethernet.src_addr.32-47 + shift: 8 + next: parse_ethernet.3 + 0x0800: + 0..1: ethernet.dst_addr.32-47 + 2..3: ethernet.dst_addr.16-31 + 4..5: ethernet.dst_addr.0-15 + 6..7: ethernet.src_addr.32-47 + shift: 8 + next: parse_ethernet.4 + 0x86dd: + 0..1: ethernet.dst_addr.32-47 + 2..3: ethernet.dst_addr.16-31 + 4..5: ethernet.dst_addr.0-15 + 6..7: ethernet.src_addr.32-47 + shift: 8 + next: parse_ethernet.5 + 0x0806: + 0..1: ethernet.dst_addr.32-47 + 2..3: ethernet.dst_addr.16-31 + 4..5: ethernet.dst_addr.0-15 + 6..7: ethernet.src_addr.32-47 + shift: 8 + next: parse_ethernet.6 + 0x*: + 0..1: ethernet.dst_addr.32-47 + 2..3: ethernet.dst_addr.16-31 + 4..5: ethernet.dst_addr.0-15 + 6..7: ethernet.src_addr.32-47 + shift: 8 + next: parse_ethernet.7 + parse_ethernet.0: + 0x*: + 0..1: ethernet.src_addr.16-31 + 2..3: ethernet.src_addr.0-15 + 4..5: ethernet.ether_type + ethernet.$valid: 1 + shift: 6 + next: parse_vlan + parse_vlan: + match: [ 2..3 ] + 0x8100: + 0..1: H15 + 2..3: vlan_tag$0.ether_type + vlan_tag$0.$valid: 1 + shift: 4 + next: parse_vlan.0 + 0x9100: + 0..1: H15 + 2..3: vlan_tag$0.ether_type + vlan_tag$0.$valid: 1 + shift: 4 + next: parse_vlan.5 + 0x9200: + 0..1: H15 + 2..3: vlan_tag$0.ether_type + vlan_tag$0.$valid: 1 + shift: 4 + next: parse_vlan.10 + 0x9300: + 0..1: H15 + 2..3: vlan_tag$0.ether_type + vlan_tag$0.$valid: 1 + shift: 4 + next: parse_vlan.15 + 0x0800: + 0..1: H15 + 2..3: vlan_tag$0.ether_type + vlan_tag$0.$valid: 1 + shift: 4 + next: parse_ipv4 + 0x86dd: + 0..1: H15 + 2..3: vlan_tag$0.ether_type + vlan_tag$0.$valid: 1 + shift: 4 + next: parse_ipv6 + 0x*: + 0..1: H15 + 2..3: vlan_tag$0.ether_type + vlan_tag$0.$valid: 1 + shift: 4 + next: end + parse_vlan.0: + match: [ 2..3 ] + 0x8100: + next: end + 0x9100: + next: end + 0x9200: + next: end + 0x9300: + next: end + 0x0800: + 0..1: TH3 + 2..3: vlan_tag$1.ether_type + vlan_tag$1.$valid: 1 + shift: 4 + next: parse_ipv4 + 0x86dd: + 0..1: TH3 + 2..3: vlan_tag$1.ether_type + vlan_tag$1.$valid: 1 + shift: 4 + next: parse_ipv6 + 0x*: + next: end + parse_ipv4: + match: [ /* ingress::ipv4_base.frag_offset ++ ingress::ipv4_base.protocol; */ ] + 0x000001: + 0: TB1 + 1: ipv4_base.diffserv + 2..3: ipv4_base.total_len + 4..5: ipv4_base.identification + 6..7: H14 + 8: ipv4_base.ttl + 9: ipv4_base.protocol + 10..11: ipv4_base.hdr_checksum + 12..15: ipv4_base.src_addr + 16..19: ipv4_base.dst_addr + shift: 20 + next: parse_ipv4.0 + 0x000006: + 0: TB1 + 1: ipv4_base.diffserv + 2..3: ipv4_base.total_len + 4..5: ipv4_base.identification + 6..7: H14 + 8: ipv4_base.ttl + 9: ipv4_base.protocol + 10..11: ipv4_base.hdr_checksum + 12..15: ipv4_base.src_addr + 16..19: ipv4_base.dst_addr + shift: 20 + next: parse_ipv4.1 + 0x000011: + 0: TB1 + 1: ipv4_base.diffserv + 2..3: ipv4_base.total_len + 4..5: ipv4_base.identification + 6..7: H14 + 8: ipv4_base.ttl + 9: ipv4_base.protocol + 10..11: ipv4_base.hdr_checksum + 12..15: ipv4_base.src_addr + 16..19: ipv4_base.dst_addr + shift: 20 + next: parse_ipv4.2 + 0x*: + 0: TB1 + 1: ipv4_base.diffserv + 2..3: ipv4_base.total_len + 4..5: ipv4_base.identification + 6..7: H14 + 8: ipv4_base.ttl + 9: ipv4_base.protocol + 10..11: ipv4_base.hdr_checksum + 12..15: ipv4_base.src_addr + 16..19: ipv4_base.dst_addr + shift: 20 + next: parse_ipv4.3 + parse_ipv4.0: + 0x*: + ipv4_base.$valid: 1 + next: end + parse_ipv4.1: + 0x*: + ipv4_base.$valid: 1 + next: parse_tcp + parse_tcp: + 0x*: + 0..1: tcp.src_port + 2..3: tcp.dst_port + 4..7: tcp.seq_no + 8..11: tcp.ack_no + 12: TB0 + 13: tcp.flags + 14..15: tcp.window + 16..17: tcp.checksum + shift: 18 + next: parse_tcp.0 + parse_tcp.0: + 0x*: + 0..1: tcp.urgent_ptr + tcp.$valid: 1 + local_metadata.l4_src_port: 0 /* ingress::tcp.src_port; */ + local_metadata.l4_dst_port: 0 /* ingress::tcp.dst_port; */ + shift: 2 + next: end + parse_ipv4.2: + 0x*: + ipv4_base.$valid: 1 + next: parse_udp + parse_udp: + 0x*: + 0..1: udp.src_port + 2..3: udp.dst_port + 4..5: udp.hdr_length + 6..7: udp.checksum + udp.$valid: 1 + shift: 9 + next: parse_udp.0 + parse_udp.0: + 0x*: + local_metadata.l4_src_port: 0 /* ingress::udp.src_port; */ + local_metadata.l4_dst_port: 0 /* ingress::udp.dst_port; */ + # shift: -1 + next: end + parse_ipv4.3: + 0x*: + ipv4_base.$valid: 1 + next: end + parse_ipv6: + match: [ 6 ] + 0x3a: + 0..3: W8 + 4..5: ipv6_base.payload_length + 6: ipv6_base.next_header + 7: ipv6_base.hop_limit + 8..11: ipv6_base.src_addr.96-127 + 12..15: ipv6_base.src_addr.64-95 + 16..19: ipv6_base.src_addr.32-63 + shift: 20 + next: parse_ipv6.0 + 0x06: + 0..3: W8 + 4..5: ipv6_base.payload_length + 6: ipv6_base.next_header + 7: ipv6_base.hop_limit + 8..11: ipv6_base.src_addr.96-127 + 12..15: ipv6_base.src_addr.64-95 + 16..19: ipv6_base.src_addr.32-63 + shift: 20 + next: parse_ipv6.1 + 0x11: + 0..3: W8 + 4..5: ipv6_base.payload_length + 6: ipv6_base.next_header + 7: ipv6_base.hop_limit + 8..11: ipv6_base.src_addr.96-127 + 12..15: ipv6_base.src_addr.64-95 + 16..19: ipv6_base.src_addr.32-63 + shift: 20 + next: parse_ipv6.2 + 0x*: + 0..3: W8 + 4..5: ipv6_base.payload_length + 6: ipv6_base.next_header + 7: ipv6_base.hop_limit + 8..11: ipv6_base.src_addr.96-127 + 12..15: ipv6_base.src_addr.64-95 + 16..19: ipv6_base.src_addr.32-63 + shift: 20 + next: parse_ipv6.3 + parse_ipv6.0: + 0x*: + 0..3: ipv6_base.src_addr.0-31 + 4..7: ipv6_base.dst_addr.96-127 + 8..11: ipv6_base.dst_addr.64-95 + 12..15: ipv6_base.dst_addr.32-63 + shift: 16 + next: parse_ipv6.0.0 + parse_ipv6.0.0: + 0x*: + 0..3: ipv6_base.dst_addr.0-31 + ipv6_base.$valid: 1 + shift: 4 + next: end + parse_ipv6.1: + 0x*: + 0..3: ipv6_base.src_addr.0-31 + 4..7: ipv6_base.dst_addr.96-127 + 8..11: ipv6_base.dst_addr.64-95 + 12..15: ipv6_base.dst_addr.32-63 + shift: 16 + next: parse_ipv6.1.0 + parse_ipv6.1.0: + 0x*: + 0..3: ipv6_base.dst_addr.0-31 + ipv6_base.$valid: 1 + shift: 4 + next: parse_tcp + parse_ipv6.2: + 0x*: + 0..3: ipv6_base.src_addr.0-31 + 4..7: ipv6_base.dst_addr.96-127 + 8..11: ipv6_base.dst_addr.64-95 + 12..15: ipv6_base.dst_addr.32-63 + shift: 16 + next: parse_ipv6.2.0 + parse_ipv6.2.0: + 0x*: + 0..3: ipv6_base.dst_addr.0-31 + ipv6_base.$valid: 1 + shift: 4 + next: parse_udp + parse_ipv6.3: + 0x*: + 0..3: ipv6_base.src_addr.0-31 + 4..7: ipv6_base.dst_addr.96-127 + 8..11: ipv6_base.dst_addr.64-95 + 12..15: ipv6_base.dst_addr.32-63 + shift: 16 + next: parse_ipv6.3.0 + parse_ipv6.3.0: + 0x*: + 0..3: ipv6_base.dst_addr.0-31 + ipv6_base.$valid: 1 + shift: 4 + next: end + parse_vlan.5: + match: [ 2..3 ] + 0x8100: + next: end + 0x9100: + next: end + 0x9200: + next: end + 0x9300: + next: end + 0x0800: + 0..1: TH3 + 2..3: vlan_tag$1.ether_type + vlan_tag$1.$valid: 1 + shift: 4 + next: parse_ipv4 + 0x86dd: + 0..1: TH3 + 2..3: vlan_tag$1.ether_type + vlan_tag$1.$valid: 1 + shift: 4 + next: parse_ipv6 + 0x*: + next: end + parse_vlan.10: + match: [ 2..3 ] + 0x8100: + next: end + 0x9100: + next: end + 0x9200: + next: end + 0x9300: + next: end + 0x0800: + 0..1: TH3 + 2..3: vlan_tag$1.ether_type + vlan_tag$1.$valid: 1 + shift: 4 + next: parse_ipv4 + 0x86dd: + 0..1: TH3 + 2..3: vlan_tag$1.ether_type + vlan_tag$1.$valid: 1 + shift: 4 + next: parse_ipv6 + 0x*: + next: end + parse_vlan.15: + match: [ 2..3 ] + 0x8100: + next: end + 0x9100: + next: end + 0x9200: + next: end + 0x9300: + next: end + 0x0800: + 0..1: TH3 + 2..3: vlan_tag$1.ether_type + vlan_tag$1.$valid: 1 + shift: 4 + next: parse_ipv4 + 0x86dd: + 0..1: TH3 + 2..3: vlan_tag$1.ether_type + vlan_tag$1.$valid: 1 + shift: 4 + next: parse_ipv6 + 0x*: + next: end + parse_ethernet.1: + 0x*: + 0..1: ethernet.src_addr.16-31 + 2..3: ethernet.src_addr.0-15 + 4..5: ethernet.ether_type + ethernet.$valid: 1 + shift: 6 + next: parse_vlan + parse_ethernet.2: + 0x*: + 0..1: ethernet.src_addr.16-31 + 2..3: ethernet.src_addr.0-15 + 4..5: ethernet.ether_type + ethernet.$valid: 1 + shift: 6 + next: parse_vlan + parse_ethernet.3: + 0x*: + 0..1: ethernet.src_addr.16-31 + 2..3: ethernet.src_addr.0-15 + 4..5: ethernet.ether_type + ethernet.$valid: 1 + shift: 6 + next: parse_vlan + parse_ethernet.4: + 0x*: + 0..1: ethernet.src_addr.16-31 + 2..3: ethernet.src_addr.0-15 + 4..5: ethernet.ether_type + ethernet.$valid: 1 + shift: 6 + next: parse_ipv4 + parse_ethernet.5: + 0x*: + 0..1: ethernet.src_addr.16-31 + 2..3: ethernet.src_addr.0-15 + 4..5: ethernet.ether_type + ethernet.$valid: 1 + shift: 6 + next: parse_ipv6 + parse_ethernet.6: + 0x*: + 0..1: ethernet.src_addr.16-31 + 2..3: ethernet.src_addr.0-15 + 4..5: ethernet.ether_type + ethernet.$valid: 1 + shift: 6 + next: parse_arp + parse_arp: + 0x*: + 0..1: arp.hw_type + 2..3: arp.proto_type + 4: arp.hw_addr_len + 5: arp.proto_addr_len + 6..7: arp.opcode + 8..9: arp.sender_hw_addr.32-47 + shift: 10 + next: parse_arp.0 + parse_arp.0: + 0x*: + 0..1: arp.sender_hw_addr.16-31 + 2..3: arp.sender_hw_addr.0-15 + 4..7: arp.sender_proto_addr + 8..9: arp.target_hw_addr.32-47 + 10..11: arp.target_hw_addr.16-31 + shift: 12 + next: parse_arp.0.0 + parse_arp.0.0: + 0x*: + 0..1: arp.target_hw_addr.0-15 + 2..5: arp.target_proto_addr + arp.$valid: 1 + shift: 6 + next: end + parse_ethernet.7: + 0x*: + 0..1: ethernet.src_addr.16-31 + 2..3: ethernet.src_addr.0-15 + 4..5: ethernet.ether_type + ethernet.$valid: 1 + shift: 6 + next: end +deparser ingress: + dictionary: + H0: $bridge-metadata + B63: $bridge-metadata + H2: $bridge-metadata + local_metadata.l4_dst_port: $bridge-metadata + ethernet.dst_addr.32-47: ethernet.$valid + ethernet.dst_addr.16-31: ethernet.$valid + ethernet.dst_addr.0-15: ethernet.$valid + ethernet.src_addr.32-47: ethernet.$valid + ethernet.src_addr.16-31: ethernet.$valid + ethernet.src_addr.0-15: ethernet.$valid + ethernet.ether_type: ethernet.$valid + H15: vlan_tag$0.$valid + vlan_tag$0.ether_type: vlan_tag$0.$valid + TH3: vlan_tag$1.$valid + vlan_tag$1.ether_type: vlan_tag$1.$valid + TB1: ipv4_base.$valid + ipv4_base.diffserv: ipv4_base.$valid + ipv4_base.total_len: ipv4_base.$valid + ipv4_base.identification: ipv4_base.$valid + H14: ipv4_base.$valid + ipv4_base.ttl: ipv4_base.$valid + ipv4_base.protocol: ipv4_base.$valid + ipv4_base.hdr_checksum: ipv4_base.$valid + ipv4_base.src_addr: ipv4_base.$valid + ipv4_base.dst_addr: ipv4_base.$valid + W8: ipv6_base.$valid + ipv6_base.payload_length: ipv6_base.$valid + ipv6_base.next_header: ipv6_base.$valid + ipv6_base.hop_limit: ipv6_base.$valid + ipv6_base.src_addr.96-127: ipv6_base.$valid + ipv6_base.src_addr.64-95: ipv6_base.$valid + ipv6_base.src_addr.32-63: ipv6_base.$valid + ipv6_base.src_addr.0-31: ipv6_base.$valid + ipv6_base.dst_addr.96-127: ipv6_base.$valid + ipv6_base.dst_addr.64-95: ipv6_base.$valid + ipv6_base.dst_addr.32-63: ipv6_base.$valid + ipv6_base.dst_addr.0-31: ipv6_base.$valid + arp.hw_type: arp.$valid + arp.proto_type: arp.$valid + arp.hw_addr_len: arp.$valid + arp.proto_addr_len: arp.$valid + arp.opcode: arp.$valid + arp.sender_hw_addr.32-47: arp.$valid + arp.sender_hw_addr.16-31: arp.$valid + arp.sender_hw_addr.0-15: arp.$valid + arp.sender_proto_addr: arp.$valid + arp.target_hw_addr.32-47: arp.$valid + arp.target_hw_addr.16-31: arp.$valid + arp.target_hw_addr.0-15: arp.$valid + arp.target_proto_addr: arp.$valid + tcp.src_port: tcp.$valid + tcp.dst_port: tcp.$valid + tcp.seq_no: tcp.$valid + tcp.ack_no: tcp.$valid + TB0: tcp.$valid + tcp.flags: tcp.$valid + tcp.window: tcp.$valid + tcp.checksum: tcp.$valid + tcp.urgent_ptr: tcp.$valid + udp.src_port: udp.$valid + udp.dst_port: udp.$valid + udp.hdr_length: udp.$valid + udp.checksum: udp.$valid + egress_unicast_port: standard_metadata.egress_spec + mirror: + 0: [ $mirror, $mirror_id, H13 ] + select: $mirror +parser egress: + start: $egress_metadata_shim + $egress_metadata_shim: + 0x*: + 0..1: H16 + shift: 2 + next: $bridge-metadata + save: { half:0..1 } + $bridge-metadata: + 0x*: + 0..1: H22 + 2: B31 + 3..4: H17 + 5..6: local_metadata.l4_dst_port + shift: 7 + next: start$ + start$: + match: [ half ] + 0x0fd: + next: parse_cpu_header + 0x*: + next: parse_ethernet + parse_cpu_header: + 0x*: + 0..1: TH27 + 2..5: TW27 + packet_out.$valid: 1 + shift: 2 + next: parse_ethernet + parse_ethernet: + match: [ 12..13 ] + 0x8100: + 0..1: ethernet.dst_addr.32-47 + 2..3: ethernet.dst_addr.16-31 + 4..5: ethernet.dst_addr.0-15 + 6..7: ethernet.src_addr.32-47 + shift: 8 + next: parse_ethernet.0 + 0x9100: + 0..1: ethernet.dst_addr.32-47 + 2..3: ethernet.dst_addr.16-31 + 4..5: ethernet.dst_addr.0-15 + 6..7: ethernet.src_addr.32-47 + shift: 8 + next: parse_ethernet.1 + 0x9200: + 0..1: ethernet.dst_addr.32-47 + 2..3: ethernet.dst_addr.16-31 + 4..5: ethernet.dst_addr.0-15 + 6..7: ethernet.src_addr.32-47 + shift: 8 + next: parse_ethernet.2 + 0x9300: + 0..1: ethernet.dst_addr.32-47 + 2..3: ethernet.dst_addr.16-31 + 4..5: ethernet.dst_addr.0-15 + 6..7: ethernet.src_addr.32-47 + shift: 8 + next: parse_ethernet.3 + 0x0800: + 0..1: ethernet.dst_addr.32-47 + 2..3: ethernet.dst_addr.16-31 + 4..5: ethernet.dst_addr.0-15 + 6..7: ethernet.src_addr.32-47 + shift: 8 + next: parse_ethernet.4 + 0x86dd: + 0..1: ethernet.dst_addr.32-47 + 2..3: ethernet.dst_addr.16-31 + 4..5: ethernet.dst_addr.0-15 + 6..7: ethernet.src_addr.32-47 + shift: 8 + next: parse_ethernet.5 + 0x0806: + next: end + 0x*: + next: end + parse_ethernet.0: + 0x*: + 0..1: ethernet.src_addr.16-31 + 2..3: ethernet.src_addr.0-15 + 4..5: ethernet.ether_type + ethernet.$valid: 1 + shift: 6 + next: parse_vlan + parse_vlan: + match: [ 2..3 ] + 0x8100: + 0..1: TH32 + 2..3: vlan_tag$0.ether_type + vlan_tag$0.$valid: 1 + shift: 4 + next: parse_vlan.0 + 0x9100: + 0..1: TH32 + 2..3: vlan_tag$0.ether_type + vlan_tag$0.$valid: 1 + shift: 4 + next: parse_vlan.5 + 0x9200: + 0..1: TH32 + 2..3: vlan_tag$0.ether_type + vlan_tag$0.$valid: 1 + shift: 4 + next: parse_vlan.10 + 0x9300: + 0..1: TH32 + 2..3: vlan_tag$0.ether_type + vlan_tag$0.$valid: 1 + shift: 4 + next: parse_vlan.15 + 0x0800: + 0..1: TH32 + 2..3: vlan_tag$0.ether_type + vlan_tag$0.$valid: 1 + shift: 4 + next: parse_ipv4 + 0x86dd: + 0..1: TH32 + 2..3: vlan_tag$0.ether_type + vlan_tag$0.$valid: 1 + shift: 4 + next: parse_ipv6 + 0x*: + next: end + parse_vlan.0: + match: [ 2..3 ] + 0x8100: + next: end + 0x9100: + next: end + 0x9200: + next: end + 0x9300: + next: end + 0x0800: + 0..1: TH31 + 2..3: vlan_tag$1.ether_type + vlan_tag$1.$valid: 1 + shift: 4 + next: parse_ipv4 + 0x86dd: + 0..1: TH31 + 2..3: vlan_tag$1.ether_type + vlan_tag$1.$valid: 1 + shift: 4 + next: parse_ipv6 + 0x*: + next: end + parse_ipv4: + match: [ /* egress::ipv4_base.frag_offset ++ egress::ipv4_base.protocol; */ ] + 0x000001: + next: end + 0x000006: + next: end + 0x000011: + 0: TB16 + 1: ipv4_base.diffserv + 2..3: ipv4_base.total_len + 4..5: ipv4_base.identification + 6..7: H23 + 8: ipv4_base.ttl + 9: ipv4_base.protocol + 10..11: ipv4_base.hdr_checksum + 12..15: ipv4_base.src_addr + 16..19: ipv4_base.dst_addr + shift: 20 + next: parse_ipv4.0 + 0x*: + next: end + parse_ipv4.0: + 0x*: + ipv4_base.$valid: 1 + next: parse_udp + parse_udp: + 0x*: + 0..1: udp.src_port + 2..3: udp.dst_port + 4..5: udp.hdr_length + 6..7: udp.checksum + udp.$valid: 1 + shift: 8 + next: end + parse_ipv6: + match: [ 6 ] + 0x3a: + next: end + 0x06: + next: end + 0x11: + 0..3: TW24 + 4..5: ipv6_base.payload_length + 6: ipv6_base.next_header + 7: ipv6_base.hop_limit + 8..11: ipv6_base.src_addr.96-127 + 12..15: ipv6_base.src_addr.64-95 + 16..19: ipv6_base.src_addr.32-63 + shift: 20 + next: parse_ipv6.0 + 0x*: + next: end + parse_ipv6.0: + 0x*: + 0..3: ipv6_base.src_addr.0-31 + 4..7: ipv6_base.dst_addr.96-127 + 8..11: ipv6_base.dst_addr.64-95 + 12..15: ipv6_base.dst_addr.32-63 + shift: 16 + next: parse_ipv6.0.0 + parse_ipv6.0.0: + 0x*: + 0..3: ipv6_base.dst_addr.0-31 + ipv6_base.$valid: 1 + shift: 4 + next: parse_udp + parse_vlan.5: + match: [ 2..3 ] + 0x8100: + next: end + 0x9100: + next: end + 0x9200: + next: end + 0x9300: + next: end + 0x0800: + 0..1: TH31 + 2..3: vlan_tag$1.ether_type + vlan_tag$1.$valid: 1 + shift: 4 + next: parse_ipv4 + 0x86dd: + 0..1: TH31 + 2..3: vlan_tag$1.ether_type + vlan_tag$1.$valid: 1 + shift: 4 + next: parse_ipv6 + 0x*: + next: end + parse_vlan.10: + match: [ 2..3 ] + 0x8100: + next: end + 0x9100: + next: end + 0x9200: + next: end + 0x9300: + next: end + 0x0800: + 0..1: TH31 + 2..3: vlan_tag$1.ether_type + vlan_tag$1.$valid: 1 + shift: 4 + next: parse_ipv4 + 0x86dd: + 0..1: TH31 + 2..3: vlan_tag$1.ether_type + vlan_tag$1.$valid: 1 + shift: 4 + next: parse_ipv6 + 0x*: + next: end + parse_vlan.15: + match: [ 2..3 ] + 0x8100: + next: end + 0x9100: + next: end + 0x9200: + next: end + 0x9300: + next: end + 0x0800: + 0..1: TH31 + 2..3: vlan_tag$1.ether_type + vlan_tag$1.$valid: 1 + shift: 4 + next: parse_ipv4 + 0x86dd: + 0..1: TH31 + 2..3: vlan_tag$1.ether_type + vlan_tag$1.$valid: 1 + shift: 4 + next: parse_ipv6 + 0x*: + next: end + parse_ethernet.1: + 0x*: + 0..1: ethernet.src_addr.16-31 + 2..3: ethernet.src_addr.0-15 + 4..5: ethernet.ether_type + ethernet.$valid: 1 + shift: 6 + next: parse_vlan + parse_ethernet.2: + 0x*: + 0..1: ethernet.src_addr.16-31 + 2..3: ethernet.src_addr.0-15 + 4..5: ethernet.ether_type + ethernet.$valid: 1 + shift: 6 + next: parse_vlan + parse_ethernet.3: + 0x*: + 0..1: ethernet.src_addr.16-31 + 2..3: ethernet.src_addr.0-15 + 4..5: ethernet.ether_type + ethernet.$valid: 1 + shift: 6 + next: parse_vlan + parse_ethernet.4: + 0x*: + 0..1: ethernet.src_addr.16-31 + 2..3: ethernet.src_addr.0-15 + 4..5: ethernet.ether_type + ethernet.$valid: 1 + shift: 6 + next: parse_ipv4 + parse_ethernet.5: + 0x*: + 0..1: ethernet.src_addr.16-31 + 2..3: ethernet.src_addr.0-15 + 4..5: ethernet.ether_type + ethernet.$valid: 1 + shift: 6 + next: parse_ipv6 +deparser egress: + dictionary: + ethernet.dst_addr.32-47: ethernet.$valid + ethernet.dst_addr.16-31: ethernet.$valid + ethernet.dst_addr.0-15: ethernet.$valid + ethernet.src_addr.32-47: ethernet.$valid + ethernet.src_addr.16-31: ethernet.$valid + ethernet.src_addr.0-15: ethernet.$valid + ethernet.ether_type: ethernet.$valid + TH32: vlan_tag$0.$valid + vlan_tag$0.ether_type: vlan_tag$0.$valid + TH31: vlan_tag$1.$valid + vlan_tag$1.ether_type: vlan_tag$1.$valid + TB16: ipv4_base.$valid + ipv4_base.diffserv: ipv4_base.$valid + ipv4_base.total_len: ipv4_base.$valid + ipv4_base.identification: ipv4_base.$valid + H23: ipv4_base.$valid + ipv4_base.ttl: ipv4_base.$valid + ipv4_base.protocol: ipv4_base.$valid + ipv4_base.hdr_checksum: ipv4_base.$valid + ipv4_base.src_addr: ipv4_base.$valid + ipv4_base.dst_addr: ipv4_base.$valid + TW24: ipv6_base.$valid + ipv6_base.payload_length: ipv6_base.$valid + ipv6_base.next_header: ipv6_base.$valid + ipv6_base.hop_limit: ipv6_base.$valid + ipv6_base.src_addr.96-127: ipv6_base.$valid + ipv6_base.src_addr.64-95: ipv6_base.$valid + ipv6_base.src_addr.32-63: ipv6_base.$valid + ipv6_base.src_addr.0-31: ipv6_base.$valid + ipv6_base.dst_addr.96-127: ipv6_base.$valid + ipv6_base.dst_addr.64-95: ipv6_base.$valid + ipv6_base.dst_addr.32-63: ipv6_base.$valid + ipv6_base.dst_addr.0-31: ipv6_base.$valid + udp.src_port: udp.$valid + udp.dst_port: udp.$valid + udp.hdr_length: udp.$valid + udp.checksum: udp.$valid + egress_unicast_port: standard_metadata.egress_port +stage 0 ingress: + exact_match tbl_act 0: + p4: { name: tbl_act } + row: 0 + bus: 1 + column: [ ] + next: cond-1 + actions: + act_1: + - set hasExited, 0 + default_action: act_1 + gateway cond-1 2: + input_xbar: + group 0: { 7: packet_out.$valid } + hash 0: + 40: packet_out.$valid + hash group 0: + table: [0] + row: 0 + bus: 0 + match: { 32: packet_out.$valid } + 0x1: tbl_act_0 + miss: vrf_vrf_classifier_table_0 +stage 1 ingress: + exact_match tbl_act_0 0: + p4: { name: tbl_act_0 } + row: 1 + bus: 0 + column: [ ] + gateway: + input_xbar: + group 0: { 15: packet_out.submit_to_ingress } + row: 1 + bus: 1 + match: { 7: packet_out.submit_to_ingress } + 0x0: run_table + miss: tbl_act_1 + next: tbl_act_1 + action_bus: { } + actions: + act: + - { $data0: immediate(0..6), $constant0: $data0(6..6), $constant0: 1, $constant1: $data0(6..6), $constant1: 1 } + - set standard_metadata.egress_spec, packet_out.egress_physical_port + - set B63(6..6), $data0(6..6) + default_action: act + exact_match tbl_act_1 2: + p4: { name: tbl_act_1 } + row: 0 + bus: 0 + column: [ ] + gateway: + input_xbar: + group 0: { 22: hasExited } + row: 0 + bus: 1 + match: { 6: hasExited } + 0b*0: run_table + miss: vrf_vrf_classifier_table_0 + next: vrf_vrf_classifier_table_0 + actions: + act_0: + - 0 + default_action: act_0 + ternary_match vrf_vrf_classifier_table_0 3: + p4: { name: vrf.vrf_classifier_table } + row: [ 0, 1, 2, 3, 4, 5 ] + bus: [ 0, 0, 0, 0, 0, 0 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + input_xbar: + group 0: { 0: ipv4_base.dst_addr, 32: ipv6_base.dst_addr.0-31(0..7), 40: standard_metadata.ingress_port(8) } + group 1: { 0: ipv6_base.dst_addr.0-31(16..31), 16: ipv6_base.dst_addr.32-63(0..7), 24: ipv6_base.dst_addr.0-31(8..15), 32: ipv6_base.dst_addr.32-63(16..23) } + group 2: { 0: ipv6_base.dst_addr.32-63(24..31), 8: ipv6_base.dst_addr.64-95(0..7), 16: ipv6_base.dst_addr.32-63(8..15), 24: ipv6_base.dst_addr.64-95(16..31), 40: ethernet.ether_type(0..7) } + group 3: { 0: ipv6_base.dst_addr.64-95(8..15), 8: ipv6_base.dst_addr.96-127(16..31), 24: ipv6_base.dst_addr.96-127(0..15) } + group 4: { 4: ipv6_base.traffic_class, 16: ethernet.src_addr.0-15(0..7), 24: ethernet.ether_type(8..15), 32: ethernet.src_addr.16-31(0..7), 40: ethernet.src_addr.32-47(8..15) } + group 5: { 0: ethernet.src_addr.32-47(0..7), 8: ethernet.src_addr.0-15(8..15), 16: standard_metadata.ingress_port(0..7), 24: ethernet.src_addr.16-31(8..15), 32: ipv4_base.diffserv } + gateway: + input_xbar: + group 0: { 22: hasExited } + row: 0 + bus: 0 + match: { 6: hasExited } + 0b*0: run_table + miss: END + next: class_id_class_id_assignment_table_0 + action: vrf_vrf_classifier_table_0$action + default_action: vrf.set_vrf + default_action_parameters: + vrf_id: 0 + action vrf_vrf_classifier_table_0$action: + p4: { name: vrf_vrf_classifier_table_0$action } + row: 14 + column: 5 + home_row: 14 + format vrf.set_vrf: { $adf_f0: 0..31 } + action_bus: { 96..99 : $adf_f0 } + actions: + vrf.set_vrf: + - { vrf_id: $adf_f0 } + - set local_metadata.vrf_id, vrf_id + ternary_match class_id_class_id_assignment_table_0 4: + p4: { name: class_id.class_id_assignment_table } + row: [ 6, 7, 8, 9, 10, 11 ] + bus: [ 0, 0, 0, 0, 0, 0 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + input_xbar: + group 2: { 0: ipv6_base.dst_addr.32-63(24..31), 8: ipv6_base.dst_addr.64-95(0..7), 16: ipv6_base.dst_addr.32-63(8..15), 24: ipv6_base.dst_addr.64-95(16..31), 40: ethernet.ether_type(0..7) } + group 3: { 0: ipv6_base.dst_addr.64-95(8..15), 8: ipv6_base.dst_addr.96-127(16..31), 24: ipv6_base.dst_addr.96-127(0..15) } + group 8: { 0: ipv4_base.dst_addr, 32: ipv6_base.dst_addr.0-31(0..7) } + group 9: { 0: ipv6_base.dst_addr.0-31(16..31), 16: ipv6_base.dst_addr.32-63(0..7), 24: ipv6_base.dst_addr.0-31(8..15), 32: ipv6_base.dst_addr.32-63(16..23), 41: vlan_tag$0.pcp } + group 10: { 0: ethernet.ether_type(8..15), 8: local_metadata.l4_dst_port, 24: local_metadata.l4_src_port, 40: ipv6_base.next_header } + group 11: { 0: vlan_tag$0.vid(8..11), 8: vlan_tag$0.vid(0..7), 16: ipv4_base.protocol, 24: ipv4_base.ttl, 32: ipv6_base.hop_limit } + next: l3_fwd_l3_routing_classifier_table_0 + action: class_id_class_id_assignment_table_0$action + default_action: class_id.set_class_id + default_action_parameters: + class_id_value: 0 + action class_id_class_id_assignment_table_0$action: + p4: { name: class_id_class_id_assignment_table_0$action } + row: 15 + column: 0 + home_row: 15 + format class_id.set_class_id: { $adf_b0: 0..7 } + action_bus: { 2 : $adf_b0 } + actions: + class_id.set_class_id: + - { class_id_value: $adf_b0 } + - set local_metadata.class_id, class_id_value + exact_match l3_fwd_l3_routing_classifier_table_0 5: + p4: { name: l3_fwd.l3_routing_classifier_table } + row: 7 + bus: 0 + column: [ 2, 3, 4 ] + ways: + - [0, 0, 0x0, [7, 2]] + - [0, 1, 0x0, [7, 3]] + - [0, 2, 0x0, [7, 4]] + input_xbar: + group 0: { 24: ethernet.dst_addr.0-15(8..15), 32: ethernet.dst_addr.0-15(0..7), 40: ethernet.dst_addr.16-31(8..15), 48: ethernet.dst_addr.16-31(0..7), 56: ethernet.dst_addr.32-47(8..15), 64: ethernet.dst_addr.32-47(0..7) } + hash 0: + 0..9: random(ethernet.dst_addr.0-15(8..15), ethernet.dst_addr.0-15(0..7), ethernet.dst_addr.16-31(8..15), ethernet.dst_addr.16-31(2..7), ethernet.dst_addr.32-47(8..15)) ^ stripe(ethernet.dst_addr.16-31(0..1)) + 10..19: random(ethernet.dst_addr.0-15(8..15), ethernet.dst_addr.0-15(0..7), ethernet.dst_addr.16-31(8..15), ethernet.dst_addr.16-31(2..7), ethernet.dst_addr.32-47(8..15)) ^ stripe(ethernet.dst_addr.16-31(0..1)) + 20..29: random(ethernet.dst_addr.0-15(8..15), ethernet.dst_addr.0-15(0..7), ethernet.dst_addr.16-31(8..15), ethernet.dst_addr.16-31(2..7), ethernet.dst_addr.32-47(8..15)) ^ stripe(ethernet.dst_addr.16-31(0..1)) + hash 1: + 0..9: stripe(ethernet.dst_addr.32-47(0..7)) + 10..19: stripe(ethernet.dst_addr.32-47(0..7)) + 20..29: stripe(ethernet.dst_addr.32-47(0..7)) + hash group 0: + table: [0, 1] + format: { version(0): 112..115, match(0): [56..63, 32..39, 66..71, 40..55 ] } + match: [ ethernet.dst_addr.0-15, ethernet.dst_addr.16-31(2..15), ethernet.dst_addr.32-47(8..15) ] + hit: l3_fwd_l3_ipv4_override_table_0 + miss: punt_punt_table_0 + actions: + NoAction: + - 0 + default_action: NoAction +stage 2 ingress: + ternary_match l3_fwd_l3_ipv4_override_table_0 0: + p4: { name: l3_fwd.l3_ipv4_override_table, action_profile: l3_fwd.wcmp_action_profile } + row: 2 + bus: 0 + column: 0 + input_xbar: + group 0: { 0: ipv4_base.dst_addr } + gateway: + input_xbar: + group 1: { 7: ipv4_base.$valid } + hash 2: + 40: ipv4_base.$valid + hash group 1: + table: [2] + row: 5 + bus: 0 + match: { 32: ipv4_base.$valid } + 0x1: run_table + miss: punt_punt_table_0 + hit: tbl_act_2 + miss: l3_fwd_l3_ipv4_vrf_table_0 + indirect: l3_fwd_l3_ipv4_override_table_0$tind + ternary_indirect l3_fwd_l3_ipv4_override_table_0$tind: + row: 0 + bus: 0 + column: 2 + format: { action: 27..27, action_ptr: 0..9, select_ptr: 17} + action: l3_fwd_l3_ipv4_fallback_table_0$act_prof.l3_fwd.wcmp_action_profile(action, action_ptr) + selector: l3_fwd_l3_ipv4_fallback_table_0$act_sel.l3_fwd.wcmp_action_profile(select_ptr) + default_action: NoAction + ternary_match l3_fwd_l3_ipv4_vrf_table_0 1: + p4: { name: l3_fwd.l3_ipv4_vrf_table, action_profile: l3_fwd.wcmp_action_profile } + row: [ 0, 1 ] + bus: [ 0, 0 ] + column: + - 0 + - 0 + input_xbar: + group 0: { 0: ipv4_base.dst_addr, 32: local_metadata.vrf_id(0..7) } + group 1: { 0: local_metadata.vrf_id(16..31), 24: local_metadata.vrf_id(8..15) } + hit: tbl_act_2 + miss: l3_fwd_l3_ipv4_fallback_table_0 + indirect: l3_fwd_l3_ipv4_vrf_table_0$tind + ternary_indirect l3_fwd_l3_ipv4_vrf_table_0$tind: + row: 1 + bus: 0 + column: 2 + format: { action: 27..27, action_ptr: 0..9, select_ptr: 17} + action: l3_fwd_l3_ipv4_fallback_table_0$act_prof.l3_fwd.wcmp_action_profile(action, action_ptr) + selector: l3_fwd_l3_ipv4_fallback_table_0$act_sel.l3_fwd.wcmp_action_profile(select_ptr) + default_action: NoAction + ternary_match l3_fwd_l3_ipv4_fallback_table_0 2: + p4: { name: l3_fwd.l3_ipv4_fallback_table, action_profile: l3_fwd.wcmp_action_profile } + row: 3 + bus: 0 + column: 0 + input_xbar: + group 0: { 0: ipv4_base.dst_addr } + next: tbl_act_2 + indirect: l3_fwd_l3_ipv4_fallback_table_0$tind + action l3_fwd_l3_ipv4_fallback_table_0$act_prof.l3_fwd.wcmp_action_profile: + row: 15 + column: 2 + home_row: 15 + format l3_fwd.set_nexthop: { $adf_h0: 16..31, $adf_h1: 32..47, $adf_h2: 48..63, $adf_h3: 64..79, $adf_h4: 80..95, $adf_h5: 96..111, $adf_h6: 112..127 } + action_bus: { 32..33 : $adf_h3, 34..35 : $adf_h4, 36..37 : $adf_h5, 38..39 : $adf_h6, 42..43 : $adf_h0, 44..45 : $adf_h1, 46..47 : $adf_h2 } + actions: + l3_fwd.set_nexthop: + - { port: $adf_h0, dmac.0-15: $adf_h1, dmac.16-31: $adf_h2, dmac.32-47: $adf_h3, smac.0-15: $adf_h4, smac.16-31: $adf_h5, smac.32-47: $adf_h6 } + - set standard_metadata.egress_spec, port + - add ipv4_base.ttl, ipv4_base.ttl, 255 + - set ethernet.dst_addr.0-15, dmac.0-15 + - set ethernet.dst_addr.16-31, dmac.16-31 + - set ethernet.dst_addr.32-47, dmac.32-47 + - set ethernet.src_addr.0-15, smac.0-15 + - set ethernet.src_addr.16-31, smac.16-31 + - set ethernet.src_addr.32-47, smac.32-47 + NoAction: + - { } + selection l3_fwd_l3_ipv4_fallback_table_0$act_sel.l3_fwd.wcmp_action_profile: + p4: { name: l3_fwd.wcmp_action_profile } + row: 15 + column: [ 0, 1 ] + maprams: [ 0, 1 ] + input_xbar: + group 0: { 0: ipv4_base.dst_addr, 32: ipv4_base.src_addr, 64: local_metadata.l4_dst_port, 80: local_metadata.l4_src_port, 96: ipv4_base.protocol } + hash 0: + 0..50: random(ipv4_base.dst_addr, ipv4_base.src_addr) + hash 1: + 0..50: random(local_metadata.l4_dst_port, local_metadata.l4_src_port, ipv4_base.protocol) + hash group 0: + table: [0, 1] + mode: fair 0 + ternary_indirect l3_fwd_l3_ipv4_fallback_table_0$tind: + row: 2 + bus: 0 + column: 2 + format: { action: 27..27, action_ptr: 0..9, select_ptr: 17} + action: l3_fwd_l3_ipv4_fallback_table_0$act_prof.l3_fwd.wcmp_action_profile(action, action_ptr) + selector: l3_fwd_l3_ipv4_fallback_table_0$act_sel.l3_fwd.wcmp_action_profile(select_ptr) + default_action: NoAction +stage 3 ingress: + exact_match tbl_act_2 0: + p4: { name: tbl_act_2 } + row: 0 + bus: 0 + column: [ ] + gateway: + input_xbar: + group 0: { 0: ipv4_base.ttl } + row: 0 + bus: 0 + match: { 0: ipv4_base.ttl } + 0x00: run_table + miss: punt_punt_table_0 + next: punt_punt_table_0 + actions: + act_2: + - invalidate standard_metadata.egress_spec + default_action: act_2 +stage 4 ingress: + ternary_match punt_punt_table_0 0: + p4: { name: punt.punt_table } + row: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + column: + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + input_xbar: + group 0: { 0: arp.target_proto_addr, 32: ipv4_base.dst_addr(0..7), 40: standard_metadata.egress_spec(8) } + group 1: { 0: ipv4_base.dst_addr(16..31), 16: ipv4_base.src_addr(0..7), 24: ipv4_base.dst_addr(8..15), 32: ipv4_base.src_addr(16..23) } + group 2: { 0: ipv4_base.src_addr(24..31), 8: ipv6_base.dst_addr.0-31(0..7), 16: ipv4_base.src_addr(8..15), 24: ipv6_base.dst_addr.0-31(16..31), 40: ipv6_base.dst_addr.64-95(0..7) } + group 3: { 0: ipv6_base.dst_addr.0-31(8..15), 8: ipv6_base.dst_addr.32-63(16..31), 24: ipv6_base.dst_addr.32-63(0..15) } + group 4: { 0: ipv6_base.dst_addr.64-95(16..31), 16: ipv6_base.dst_addr.96-127(0..7), 24: ipv6_base.dst_addr.64-95(8..15), 32: ipv6_base.dst_addr.96-127(16..23), 40: ipv6_base.src_addr.0-31(24..31) } + group 5: { 0: ipv6_base.src_addr.0-31(0..7), 8: ipv6_base.dst_addr.96-127(8..15), 16: ipv6_base.src_addr.0-31(16..23), 24: ipv6_base.dst_addr.96-127(24..31), 32: ipv6_base.src_addr.32-63(0..7) } + group 6: { 0: ipv6_base.src_addr.0-31(8..15), 8: ipv6_base.src_addr.32-63(16..31), 24: ipv6_base.src_addr.64-95(0..7), 32: ipv6_base.src_addr.32-63(8..15), 40: ipv6_base.src_addr.96-127(16..23) } + group 7: { 0: ipv6_base.src_addr.64-95(24..31), 8: ipv6_base.src_addr.96-127(0..7), 16: ipv6_base.src_addr.64-95(8..23), 32: ipv6_base.src_addr.96-127(24..31) } + group 8: { 0: local_metadata.vrf_id(0..7), 8: ipv6_base.src_addr.96-127(8..15), 20: ipv6_base.traffic_class, 32: ethernet.ether_type } + group 9: { 0: local_metadata.vrf_id(16..31), 16: standard_metadata.egress_spec(0..7), 24: local_metadata.vrf_id(8..15), 32: standard_metadata.ingress_port(0..7) } + group 10: { 0: standard_metadata.ingress_port(8), 8: vlan_tag$0.vid(0..7), 21: vlan_tag$0.pcp, 24: ipv4_base.diffserv, 32: vlan_tag$0.vid(8..11), 40: local_metadata.icmp_code } + group 11: { 0: ipv4_base.protocol, 8: ipv4_base.ttl, 16: ipv6_base.hop_limit, 24: ipv6_base.next_header, 32: local_metadata.class_id } + next: tbl_act_3 + action_bus: { } + indirect: punt_punt_table_0$tind + meter punt_punt_table_0$meter.punt.ingress_port_meter: + p4: { name: punt.ingress_port_meter } + row: 15 + column: [ 0, 1 ] + maprams: [ 0, 1 ] + color_maprams: + row: 7 + bus: 0 + column: 2 + type: standard + count: bytes + counter punt_punt_table_0$counter.punt.punt_packet_counter: + p4: { name: punt.punt_packet_counter } + row: 13 + column: [ 0, 1 ] + maprams: [ 0, 1 ] + count: packets + format: {packets(0): 106..126, packets(1): 85..105, packets(2): 64..84, packets(3): 42..62, packets(4): 21..41, packets(5): 0..20} + ternary_indirect punt_punt_table_0$tind: + row: 0 + bus: 0 + column: 2 + format: { action: 9..10, immediate: 0..8} + meter: punt_punt_table_0$meter.punt.ingress_port_meter + stats: punt_punt_table_0$counter.punt.punt_packet_counter + actions: + punt.set_queue_and_clone_to_cpu: + - { } + - set local_metadata.egress_spec_at_punt_match, standard_metadata.egress_spec + # - set $mirror_id, 1024 + - set $mirror, 1 + punt.set_queue_and_send_to_cpu: + - { $constant0: immediate(0..8), $constant0: 253 } + - set local_metadata.egress_spec_at_punt_match, standard_metadata.egress_spec + - set standard_metadata.egress_spec, $constant0 + NoAction: + - { } + default_action: NoAction +stage 5 ingress: + exact_match tbl_act_3 0: + p4: { name: tbl_act_3 } + row: 0 + bus: 0 + column: [ ] + gateway: + input_xbar: + group 0: { 5: local_metadata.color } + row: 0 + bus: 0 + match: { 5: local_metadata.color } + 0b*00: END + miss: run_table + next: END + actions: + act_3: + - invalidate standard_metadata.egress_spec + default_action: act_3 +stage 0 egress: + exact_match tbl_act_4 1: + p4: { name: tbl_act_4 } + row: 0 + bus: 0 + column: [ ] + next: tbl_packetio_egress_encap_packet_in_header + actions: + act_4: + - set hasExited_0, 0 + default_action: act_4 + exact_match tbl_packetio_egress_encap_packet_in_header 3: + p4: { name: tbl_packetio_egress_encap_packet_in_header } + row: 1 + bus: 0 + column: [ ] + gateway: + input_xbar: + group 0: { 8: standard_metadata.egress_port(8), 16: standard_metadata.egress_port(0..7) } + row: 0 + bus: 1 + match: { 0: standard_metadata.egress_port(0..7), 8: standard_metadata.egress_port(8) } + 0x**fd: run_table + miss: tbl_act_5 + next: tbl_act_5 + actions: + packetio_egress.encap_packet_in_header: + - 0 + default_action: packetio_egress.encap_packet_in_header +stage 1 egress: + exact_match tbl_act_5 1: + p4: { name: tbl_act_5 } + row: 0 + bus: 1 + column: [ ] + gateway: + input_xbar: + group 0: { 6: local_metadata.skip_egress } + row: 1 + bus: 0 + match: { 6: local_metadata.skip_egress } + 0b*1: run_table + miss: cond-10 + next: cond-10 + actions: + act_5: + - set hasExited_0, 1 + default_action: act_5 +stage 2 egress: + gateway cond-10 3: + input_xbar: + group 0: { 111: hasExited_0 } + row: 0 + bus: 0 + match: { 7: hasExited_0 } + 0x0: spoof_protection_dhcp_spoof_protection_table_0 + miss: END + exact_match spoof_protection_dhcp_spoof_protection_table_0 4: + p4: { name: spoof_protection.dhcp_spoof_protection_table } + row: [ 5, 6, 7 ] + bus: [ 0, 0, 0 ] + column: + - 2 + - 2 + - 2 + ways: + - [1, 0, 0x0, [7, 2]] + - [1, 1, 0x0, [6, 2]] + - [1, 2, 0x0, [5, 2]] + input_xbar: + group 1: { 8: local_metadata.l4_dst_port(8..15), 16: local_metadata.l4_dst_port(0..7), 24: standard_metadata.egress_spec(8), 32: standard_metadata.egress_spec(0..7) } + hash 2: + 0..9: random(local_metadata.l4_dst_port(8..15), local_metadata.l4_dst_port(1..7)) ^ stripe(local_metadata.l4_dst_port(0), standard_metadata.egress_spec(8), standard_metadata.egress_spec(0..7)) + 10..19: random(local_metadata.l4_dst_port(8..15), local_metadata.l4_dst_port(1..7)) ^ stripe(local_metadata.l4_dst_port(0), standard_metadata.egress_spec(8), standard_metadata.egress_spec(0..7)) + 20..29: random(local_metadata.l4_dst_port(8..15), local_metadata.l4_dst_port(1..7)) ^ stripe(local_metadata.l4_dst_port(0), standard_metadata.egress_spec(8), standard_metadata.egress_spec(0..7)) + hash group 1: + table: [2] + format: { action(0): 1, version(0): 112..115, match(0): [41..47, 32..39 ] } + match: [ local_metadata.l4_dst_port(1..15) ] + gateway: + input_xbar: + group 2: { 7: udp.$valid } + hash 4: + 40: udp.$valid + hash group 2: + table: [4] + row: 0 + bus: 1 + match: { 32: udp.$valid } + 0x1: run_table + miss: END + next: END + actions: + spoof_protection.drop_packet: + - invalidate standard_metadata.egress_port + NoAction: + - 0 + default_action: NoAction diff --git a/backends/tofino/bf-asm/test/bfas_lookup_test/__init__.py b/backends/tofino/bf-asm/test/bfas_lookup_test/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_cases.py b/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_cases.py new file mode 100644 index 00000000000..fb0f38a6f99 --- /dev/null +++ b/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_cases.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 + +# The test line is a list of input data in following forma: +# * Input BFA file to translate, relative from this folder (string) +# * BFA parameters (list) +# * Expected results (dictionary) +# - name of the inspected match (string) +# - results for 8 and 16 bit extractions where the first one is for 8 bit +# and second one for 16 bit extractions (tuple) +# + +TEST_LIST = [ + ["../asm/network_tap.bfa", [], { + "ingress,parse_inner_ipv6": (68, 30), + "ingress,parse_ipv6.$split_1": (56, 18), + "ingress,parse_inner_tcp": (72, 34), + "ingress,parse_volte,0x6*": (68, 28), + "egress,parse_gtp_base,0x01****": (60, 36), + "egress,parse_imsi": (64, 38), + "egress,parse_volte,0x6*": (60, 36), + "egress,parse_inner_tcp": (64, 44), + "egress,parse_inner_ipv6": (64, 40), + "egress,parse_ipv6": (32, 18), + "egress,parse_mpls_bos,0x6*": (52, 26)}], +] diff --git a/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_test.py b/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_test.py new file mode 100755 index 00000000000..40013374d1d --- /dev/null +++ b/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_test.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 + +import os +import shlex +import subprocess +import pdb +import pprint +import sys +import traceback +import re + +import bfas_lookup_cases + +# Path to the stability test folder +BFAS_LOOKUP_TEST_PATH = os.path.dirname(os.path.realpath(__file__)) +# Relative path to the bfas folder +BFAS_REL_PATH = os.path.join(BFAS_LOOKUP_TEST_PATH, "../../../build/bf-asm") +# Absolute path to the bfas folder +BFAS_ABS_PATH = os.path.abspath(BFAS_REL_PATH) +# Path to the bfas file +BFAS_TOOL_ABS = os.path.join(BFAS_ABS_PATH, "bfas") + + +class MatchCompareException(Exception): + def __init__(self, expected, received): + # Build the error message + err_msg = "Expected and received results are not same!\n" + err_msg += "\t* 8 bit - {} (expected), {} (received)\n".format(expected[0], received[0]) + err_msg += "\t* 16 bit - {} (expected), {} (received)\n".format(expected[1], received[1]) + super().__init__(err_msg) + + +def run_bfas_translation(bfa_file, bfa_options, log_file): + """ + Run the bfas tool with enabled verbose and file logging. + + Parameters: + * bfa_file - file to process + * bfa_options - list of additional options which will be extended + with logging into a logfile + * log_file - file we want to log into + """ + try: + bfa_command = [BFAS_TOOL_ABS, "-v", "-v", "-v", "-v", "-l", log_file] + bfa_options + [bfa_file] + cmd_concat = ' '.join(bfa_command) + p = subprocess.Popen(cmd_concat, shell=True) + p.wait() + ret_code = p.returncode + if ret_code != 0: + print("Return code: {}".format(ret_code)) + sys.exit(ret_code) + except Exception: + print("error invoking {}".format(bfa_command), file=sys.stderr) + print(traceback.format_exc(), file=sys.stderr) + sys.exit(1) + + +def parse_results(log_file): + """ + Parse the log file and return the dictionary in the form of: + * key - name of the match + * value - tuple with 8 bit extractions (index 0) and 16 bit extractions (index 1) + """ + if not os.path.exists(log_file): + raise RuntimeError("Log file {} doesn't exists!".format(log_file)) + + ret = {} + logf = open(log_file, 'r') + while True: + # Analyze the file line by line + line = logf.readline() + if line == "": + break + + matchobj = re.match(r"INFO: Used extractors for (.*) - 8bit:([0-9]+), 16bit:([0-9]+)", line) + if not matchobj: + continue + + match = matchobj.group(1) + ext8 = int(matchobj.group(2)) + ext16 = int(matchobj.group(3)) + ret[match] = (ext8, ext16) + logf.close() + return ret + + +def run_test(): + # Name of the file with bfas log file + log_file_path = os.path.join(BFAS_ABS_PATH, "bfas_translation.log") + try: + print("Starting the BFAS test of cache lookup test for Tofino ") + for test in bfas_lookup_cases.TEST_LIST: + bfa_file = os.path.join(BFAS_LOOKUP_TEST_PATH, test[0]) + bfa_options = test[1] + expected_results = test[2] + # Run the translation, parse output data and check results + run_bfas_translation(bfa_file, bfa_options, log_file_path) + translation_results = parse_results(log_file_path) + + # Check that both dictionaries contains same keys + same_key_set = set(expected_results.keys()) == set(translation_results.keys()) + if not same_key_set: + raise RuntimeError("Key sets are not same:\n\tExpected: {}\n\tReceived{}".format( + expected_results.keys(), translation_results.keys())) + + # Iterate over the dictionary and check results + for match, values in expected_results.items(): + if translation_results[match] != values: + raise MatchCompareException(values, translation_results[match]) + + # Cleanup of generated files between runs + os.remove(log_file_path) + + files_to_remove = ["context.json", "mau.gfm.log", "tofino.bin"] + for f in files_to_remove: + os.remove(os.path.join(BFAS_LOOKUP_TEST_PATH, f)) + + print("All tests passed!") + except Exception: + print(traceback.format_exc(), file=sys.stderr) + sys.exit(1) + + +if __name__ == "__main__": + run_test() + sys.exit(0) diff --git a/backends/tofino/bf-asm/test/checksum1.p4 b/backends/tofino/bf-asm/test/checksum1.p4 new file mode 100644 index 00000000000..2d132ecea02 --- /dev/null +++ b/backends/tofino/bf-asm/test/checksum1.p4 @@ -0,0 +1,120 @@ +parser start { + return parse_ethernet; +} + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header ethernet_t ethernet; +#define ETHERTYPE_IPV4 0x0800 +#define ETHERTYPE_IPV6 0x86dd + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + ETHERTYPE_IPV4 : parse_ipv4; + ETHERTYPE_IPV6 : parse_ipv6; + default: ingress; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} +header ipv4_t ipv4; +field_list ipv4_checksum_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_checksum { + input { + ipv4_checksum_list; + } + algorithm : csum16; + output_width : 16; +} + +calculated_field ipv4.hdrChecksum { + verify ipv4_checksum; + update ipv4_checksum; +} + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +header_type ipv6_t { + fields { + version : 4; + trafficClass : 8; + flowLabel : 20; + payloadLen : 16; + nextHdr : 8; + hopLimit : 8; + srcAddr : 128; + dstAddr : 128; + } +} +header ipv6_t ipv6; + +parser parse_ipv6 { + extract(ipv6); + return ingress; +} + +action do_setup() { +} + +table setup { + reads { ethernet: valid; } + actions { do_setup; } +} + +action drop() { +} +action forward(to) { + modify_field(ethernet.dstAddr, to); + add_to_field(ipv4.ttl, -1); +} + +table route { + reads { ipv4.dstAddr : ternary; } + actions { + drop; + forward; + } +} + +control ingress { + apply(setup); + apply(route); +} diff --git a/backends/tofino/bf-asm/test/counter1.p4 b/backends/tofino/bf-asm/test/counter1.p4 new file mode 100644 index 00000000000..b81579347a9 --- /dev/null +++ b/backends/tofino/bf-asm/test/counter1.p4 @@ -0,0 +1,44 @@ +/* + * Simple stat program. + * Direct mapped, that does not go across stages + */ + +header_type ethernet_t { + fields { + dstAddr : 48; + } +} +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return ingress; +} +action act(idx) { + modify_field(ethernet.dstAddr, idx); +} +table tab1 { + reads { + ethernet.dstAddr : exact; + } + actions { + act; + } + size: 128; +} + +counter cnt { + type: packets; + direct: tab1; + +} +control ingress { + apply(tab1); +} +control egress { + +} diff --git a/backends/tofino/bf-asm/test/counter2.p4 b/backends/tofino/bf-asm/test/counter2.p4 new file mode 100644 index 00000000000..4879b5a208e --- /dev/null +++ b/backends/tofino/bf-asm/test/counter2.p4 @@ -0,0 +1,44 @@ +/* + * Simple stat program. + * Direct mapped, that does not go across stages + */ + +header_type ethernet_t { + fields { + dstAddr : 48; + } +} +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return ingress; +} +action act(idx) { + modify_field(ethernet.dstAddr, idx); +} +table tab1 { + reads { + ethernet.dstAddr : ternary; + } + actions { + act; + } + size: 128; +} + +counter cnt { + type: packets; + direct: tab1; + +} +control ingress { + apply(tab1); +} +control egress { + +} diff --git a/backends/tofino/bf-asm/test/counter3.p4 b/backends/tofino/bf-asm/test/counter3.p4 new file mode 100644 index 00000000000..652e75c96cb --- /dev/null +++ b/backends/tofino/bf-asm/test/counter3.p4 @@ -0,0 +1,53 @@ +/* + * Simple stat program. + * Statically mapped, that should be optimized away by the compiler + * because there isn't a count primitive in any of the actions + * + */ + +header_type ethernet_t { + fields { + dstAddr : 48; + } +} +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return ingress; +} +action act(idx) { + modify_field(ethernet.dstAddr, idx); +} +table tab1 { + reads { + ethernet.dstAddr : exact; + } + actions { + act; + } + size: 128; +} + +counter cnt { + type: packets; + direct: tab1; +} + +counter cnt2 { + type: bytes; + direct: tab1; + + +} + +control ingress { + apply(tab1); +} +control egress { + +} diff --git a/backends/tofino/bf-asm/test/counter4.p4 b/backends/tofino/bf-asm/test/counter4.p4 new file mode 100644 index 00000000000..ac0315b1f95 --- /dev/null +++ b/backends/tofino/bf-asm/test/counter4.p4 @@ -0,0 +1,45 @@ +/* + * Simple program, just a direct mapped RAM + */ + +header_type ethernet_t { + fields { + dstAddr : 48; + } +} +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return ingress; +} +action act(idx) { + modify_field(ethernet.dstAddr, idx); + count(cntDum, idx); +} +table tab1 { + reads { + ethernet.dstAddr : exact; + } + actions { + act; + } + size: 70000; +} + +counter cntDum { + type: packets; + static: tab1; + instance_count: 200; + +} +control ingress { + apply(tab1); +} +control egress { + +} diff --git a/backends/tofino/bf-asm/test/counter5.p4 b/backends/tofino/bf-asm/test/counter5.p4 new file mode 100644 index 00000000000..79cdda0a20d --- /dev/null +++ b/backends/tofino/bf-asm/test/counter5.p4 @@ -0,0 +1,44 @@ +/* + * Simple program, just a direct mapped RAM + */ + +header_type ethernet_t { + fields { + dstAddr : 48; + } +} +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return ingress; +} +action act(idx) { + count(cntDum, idx); +} +table tab1 { + reads { + ethernet.dstAddr : exact; + } + actions { + act; + } + size: 160000; +} + +counter cntDum { + type: packets; + static: tab1; + instance_count: 70000; + min_width:64; +} +control ingress { + apply(tab1); +} +control egress { + +} diff --git a/backends/tofino/bf-asm/test/ctx_json b/backends/tofino/bf-asm/test/ctx_json new file mode 120000 index 00000000000..12eb7e788bb --- /dev/null +++ b/backends/tofino/bf-asm/test/ctx_json @@ -0,0 +1 @@ +../../glass/p4c_tofino/target/tofino/ctx_json \ No newline at end of file diff --git a/backends/tofino/bf-asm/test/ctxt_json_ignore b/backends/tofino/bf-asm/test/ctxt_json_ignore new file mode 100644 index 00000000000..e5ab774017e --- /dev/null +++ b/backends/tofino/bf-asm/test/ctxt_json_ignore @@ -0,0 +1,94 @@ +# FIXME -- need to figure out what should be in these and implement it +EntryFormatNode +HashJsonNode +ParserInfo +ProgramInfo +ContextJsonNode[2] +ContextJsonNode[3] +ContextJsonNode[4] + +actions +action_pack_format_map +action_parameter_map +action_to_constant_mapping +action_to_immediate_mapping +action_to_next_table_mapping +action_to_perform +ap_bind_indirect_res_to_match +bound_to_stateful_table +bound_to_selection_table +color_address_extract +color_aware_per_flow_enable_address_type_bit_position +constant_name_to_value +default_address_bits_provided +default_next_table +default_next_table_modifiable +default_only_action +enable_per_flow_enable +enable_sps_scrambling +entry_list +field_list +gateway_fields +hash_algorithm +hash_distribution_usage +hash_distribution_usage_for_pre_color +hash_output_width +hash_polynomial +hash_way_number +include_idletime +indirect +lpf_or_red_field +match_entry_vpns +match_fields_type_dictionary +match_group_resource_allocation +match_key_fields +max_port_pool_size +memory_units_depth +memory_units_width +min_port_pool_size +number_entries_with_ranges +number_hash_ways +number_selection_groups +pack_format_length +p4_meter_tables +p4_parameters +p4_primitives +p4_stateful_tables +#p4_statistics_tables +pack_format_length +per_flow_enable_bit_position +port_pool_sizes +pre_color_field +ram_enable_dictionary +range_field +reference_dictionary +result_field +saturating +selection_fields +stage_action_parameter_map +stage_gateway_table +#stage_idletime_table +stage_primitives +stage_table_type_handle +stage_table_type_handle_type +stash_resource_allocation +statistics_precision +sweep_interval +table_type +ternary_mode +timeout +uses_range +vliw_resource_allocation +way_match_group_map +& 0xff000000 == 0x21000000 +override_meter_addr_pfe +override_stat_addr_pfe +override_stateful_addr_pfe +override_meter_addr +override_meter_full_addr +override_stat_addr +override_stat_full_addr +override_stateful_addr +override_stateful_full_addr +all_hash_calculations +dynamic_selection diff --git a/backends/tofino/bf-asm/test/ctxt_json_ignore_new b/backends/tofino/bf-asm/test/ctxt_json_ignore_new new file mode 100644 index 00000000000..be242af4ef3 --- /dev/null +++ b/backends/tofino/bf-asm/test/ctxt_json_ignore_new @@ -0,0 +1,9 @@ +build_date +compiler_version +learn_quanta +parser +phv_allocation +hash_bits +hash_function_id +handle +action_handle diff --git a/backends/tofino/bf-asm/test/exact_match0.p4 b/backends/tofino/bf-asm/test/exact_match0.p4 new file mode 100644 index 00000000000..56eb381b7b0 --- /dev/null +++ b/backends/tofino/bf-asm/test/exact_match0.p4 @@ -0,0 +1,35 @@ +#include + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } + +table test1 { + reads { + data.f1 : exact; + } + actions { + noop; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/exact_match1.p4 b/backends/tofino/bf-asm/test/exact_match1.p4 new file mode 100644 index 00000000000..4403dd7c715 --- /dev/null +++ b/backends/tofino/bf-asm/test/exact_match1.p4 @@ -0,0 +1,40 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setb1(val, port) { + modify_field(data.b1, val); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +table test1 { + reads { + data.f1 : exact; + } + actions { + setb1; + noop; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/exact_match1.stf b/backends/tofino/bf-asm/test/exact_match1.stf new file mode 100644 index 00000000000..6f504e3fb28 --- /dev/null +++ b/backends/tofino/bf-asm/test/exact_match1.stf @@ -0,0 +1,11 @@ + +add test1 0 data.f1:0x01010101 setb1(val:0x7f, port:2) +add test1 1 data.f1:0x02020202 setb1(val:7, port:3) +add test1 2 data.f1:0x03030303 setb1(val:0, port:4) + +expect 2 01010101 ******** ******** ******** 7f 66 +expect 3 02020202 ******** ******** ******** 07 66 +expect 4 03030303 ******** ******** ******** 00 66 +packet 0 01010101 00000202 00000303 00000404 55 66 77 88 +packet 1 02020202 00000303 00000404 00000404 55 66 77 88 +packet 2 03030303 00000303 00000404 00000404 55 66 77 88 diff --git a/backends/tofino/bf-asm/test/exact_match2.p4 b/backends/tofino/bf-asm/test/exact_match2.p4 new file mode 100644 index 00000000000..4184e360847 --- /dev/null +++ b/backends/tofino/bf-asm/test/exact_match2.p4 @@ -0,0 +1,41 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setb1(val, port) { + modify_field(data.b1, val); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +table test1 { + reads { + data.f1 : exact; + } + actions { + setb1; + noop; + } + size: 10000; +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/exact_match3.p4 b/backends/tofino/bf-asm/test/exact_match3.p4 new file mode 100644 index 00000000000..7cc330c4253 --- /dev/null +++ b/backends/tofino/bf-asm/test/exact_match3.p4 @@ -0,0 +1,41 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setb1(val, port) { + modify_field(data.b1, val); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +table test1 { + reads { + data.f1 : exact; + } + actions { + setb1; + noop; + } + size: 300000; +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/exact_match4.p4 b/backends/tofino/bf-asm/test/exact_match4.p4 new file mode 100644 index 00000000000..85a1c3dcd1c --- /dev/null +++ b/backends/tofino/bf-asm/test/exact_match4.p4 @@ -0,0 +1,42 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type data_t { + fields { + f1 : 128; + f2 : 128; + f3 : 128; + f4 : 128; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setb1(val, port) { + modify_field(data.b1, val); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +table test1 { + reads { + data.f1 : exact; + data.f2 : exact; + data.f3 : exact; + } + actions { + setb1; + noop; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/exact_match5.p4 b/backends/tofino/bf-asm/test/exact_match5.p4 new file mode 100644 index 00000000000..27df288f04e --- /dev/null +++ b/backends/tofino/bf-asm/test/exact_match5.p4 @@ -0,0 +1,43 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type data_t { + fields { + f1 : 128; + f2 : 128; + f3 : 128; + f4 : 128; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setb1(val, port) { + modify_field(data.b1, val); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +table test1 { + reads { + data.f1 : exact; + data.f2 : exact; + data.f3 : exact; + } + actions { + setb1; + noop; + } + size: 50000; +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/exact_match6.p4 b/backends/tofino/bf-asm/test/exact_match6.p4 new file mode 100644 index 00000000000..4c1c5c53b8a --- /dev/null +++ b/backends/tofino/bf-asm/test/exact_match6.p4 @@ -0,0 +1,43 @@ + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +header_type meta_t { + fields { + sum : 32; + } +} +metadata meta_t meta; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action addf2() { add(meta.sum, data.f2, 100); } + +table test1 { + reads { + data.f1 : exact; + } + actions { + addf2; + noop; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/exact_match7.p4 b/backends/tofino/bf-asm/test/exact_match7.p4 new file mode 100644 index 00000000000..eacc3338259 --- /dev/null +++ b/backends/tofino/bf-asm/test/exact_match7.p4 @@ -0,0 +1,41 @@ + +header_type data_t { + fields { + x1 : 3; + f1 : 7; + x2 : 6; + f2 : 32; + x3 : 5; + f3 : 20; + x4 : 7; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setb1(val) { modify_field(data.b1, val); } + +table test1 { + reads { + data.f1 : exact; + data.f3 : exact; + } + actions { + setb1; + noop; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/exact_match8.p4 b/backends/tofino/bf-asm/test/exact_match8.p4 new file mode 100644 index 00000000000..12ebf762f6d --- /dev/null +++ b/backends/tofino/bf-asm/test/exact_match8.p4 @@ -0,0 +1,54 @@ + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setb1(val) { modify_field(data.b1, val); } +action setb2(val) { modify_field(data.b2, val); } +action setb3(val) { modify_field(data.b3, val); } +action setb4(val) { modify_field(data.b4, val); } +action setb12(v1, v2) { modify_field(data.b1, v1); modify_field(data.b2, v2); } +action setb13(v1, v2) { modify_field(data.b1, v1); modify_field(data.b3, v2); } +action setb14(v1, v2) { modify_field(data.b1, v1); modify_field(data.b4, v2); } +action setb23(v1, v2) { modify_field(data.b2, v1); modify_field(data.b3, v2); } +action setb24(v1, v2) { modify_field(data.b2, v1); modify_field(data.b4, v2); } +action setb34(v1, v2) { modify_field(data.b3, v1); modify_field(data.b4, v2); } + +table test1 { + reads { + data.f1 : exact; + } + actions { + noop; + setb1; + setb2; + setb3; + setb4; + setb12; + setb13; + setb14; + setb23; + setb24; + setb34; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/exact_match9.p4 b/backends/tofino/bf-asm/test/exact_match9.p4 new file mode 100644 index 00000000000..b03da0ae6a1 --- /dev/null +++ b/backends/tofino/bf-asm/test/exact_match9.p4 @@ -0,0 +1,44 @@ + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setb1(val) { modify_field(data.b1, val); } +action setb2(val) { modify_field(data.b2, val); } +action setb3(val) { modify_field(data.b3, val); } +action setb4(val) { modify_field(data.b4, val); } + +table test1 { + reads { + data.f1 : exact; + } + actions { + noop; + setb1; + setb2; + setb3; + setb4; + } +} + +control ingress { + if (data.f2 != 0) { + apply(test1); + } +} diff --git a/backends/tofino/bf-asm/test/exact_match_valid1.p4 b/backends/tofino/bf-asm/test/exact_match_valid1.p4 new file mode 100644 index 00000000000..970a24629c0 --- /dev/null +++ b/backends/tofino/bf-asm/test/exact_match_valid1.p4 @@ -0,0 +1,44 @@ +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; +header data_t data2; + +parser start { + extract(data); + return select(data.f2) { + 0xf0000000 mask 0xf0000000 : parse_data2; + default : ingress; + } +} +parser parse_data2 { + extract(data2); + return ingress; +} + +action noop() { } +action setb1(val) { modify_field(data2.b1, val); } + +table test1 { + reads { + data : valid; + data2 : valid; + } + actions { + setb1; + noop; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/expected_failures.txt b/backends/tofino/bf-asm/test/expected_failures.txt new file mode 100644 index 00000000000..415da9ad345 --- /dev/null +++ b/backends/tofino/bf-asm/test/expected_failures.txt @@ -0,0 +1,41 @@ +- current compiler failures on some tests. + +parser1.p4 compile +parser2.p4 compile +parser_dc_full.p4 compile +port_vlan_mapping.p4 compile +- glass fails to unroll parser loop properly (new problem with 3.3?) + +action_chain1.p4 bfas +- asm gen fails to include 'next' field in ternary indirect + +counter4.p4 mismatch +- compiler duplicates data on ixbar and programs byteswizzle to inconsistently + pull from either copy; assembler always pulls from first. + +counter5.p4 mismatch +- synth2port fabric is different -- not clear if it is a bug or where + +hash_index5.p4 mismatch +- control of stats table is different + +exact_match3.p4 mismatch +- vpn lsb encoding swapped (not a bug -- either way is fine) +- asm chooses different home rows for action table that needs multiple + (compiler should specify in asm output) + +exact_match5.p4 mismatch +- compiler duplicates data across ixbar groups and programs vh_xbar_select to + pull from either copy; assembler always pulls from first. + +hash_index2.p4 mismatch +hash_index3.p4 mismatch +- compiler fails to produce asm code for default action + +meter_test1.p4 mismatch +- vpn lsb encoding swapped (not a bug -- either way is fine) +- synth2port fabric is different -- not clear if it is a bug or where +- idletime missing from asm? + +mac_rewrite.p4 bfas +- glass generates invalid slice of immediate for action_bus. diff --git a/backends/tofino/bf-asm/test/gateway1.p4 b/backends/tofino/bf-asm/test/gateway1.p4 new file mode 100644 index 00000000000..3821cde68d0 --- /dev/null +++ b/backends/tofino/bf-asm/test/gateway1.p4 @@ -0,0 +1,48 @@ +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setb1(val) { modify_field(data.b1, val); } + +table test1 { + reads { + data.f1 : exact; + } + actions { + setb1; + noop; + } +} +table test2 { + reads { + data.f2 : exact; + } + actions { + setb1; + noop; + } +} + +control ingress { + if (data.b2 == 1) { + apply(test1); + } else { + apply(test2); + } +} diff --git a/backends/tofino/bf-asm/test/gateway2.p4 b/backends/tofino/bf-asm/test/gateway2.p4 new file mode 100644 index 00000000000..9faa6bb7be2 --- /dev/null +++ b/backends/tofino/bf-asm/test/gateway2.p4 @@ -0,0 +1,48 @@ +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setb1(val) { modify_field(data.b1, val); } + +table test1 { + reads { + data.f1 : exact; + } + actions { + setb1; + noop; + } +} +table test2 { + reads { + data.f2 : exact; + } + actions { + setb1; + noop; + } +} + +control ingress { + if (data.b2 == data.b3 and data.b4 == 10) { + apply(test1); + } else { + apply(test2); + } +} diff --git a/backends/tofino/bf-asm/test/gateway3.p4 b/backends/tofino/bf-asm/test/gateway3.p4 new file mode 100644 index 00000000000..7b32b429044 --- /dev/null +++ b/backends/tofino/bf-asm/test/gateway3.p4 @@ -0,0 +1,51 @@ + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setb1(val) { modify_field(data.b1, val); } + +table test1 { + reads { + data.f1 : exact; + } + actions { + setb1; + noop; + } +} +table test2 { + reads { + data.f2 : exact; + } + actions { + setb1; + noop; + } +} + +control ingress { + if (data.b2 == data.b3 and data.b4 == 10) { + if (data.b1 == data.b2) { + apply(test1); + } + } else { if (data.b1 != data.b2) { + apply(test2); + } } +} diff --git a/backends/tofino/bf-asm/test/gateway4.p4 b/backends/tofino/bf-asm/test/gateway4.p4 new file mode 100644 index 00000000000..4cc8c677372 --- /dev/null +++ b/backends/tofino/bf-asm/test/gateway4.p4 @@ -0,0 +1,62 @@ + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; +header_type data2_t { + fields { + x1 : 8; + x2 : 8; + } +} +header data2_t data2; + +parser start { + extract(data); + return select(data.b1) { + 0x01 : parse_data2; + default : ingress; + } +} + +parser parse_data2 { + extract(data2); + return ingress; +} + +action noop() { } +action setb1(val) { modify_field(data.b1, val); } + +table test1 { + reads { + data.f1 : exact; + } + actions { + setb1; + noop; + } +} +table test2 { + reads { + data.f2 : exact; + } + actions { + setb1; + noop; + } +} + +control ingress { + if (valid(data2)) { + apply(test1); } + apply(test2); +} diff --git a/backends/tofino/bf-asm/test/gateway5.p4 b/backends/tofino/bf-asm/test/gateway5.p4 new file mode 100644 index 00000000000..ea40aa542c1 --- /dev/null +++ b/backends/tofino/bf-asm/test/gateway5.p4 @@ -0,0 +1,54 @@ +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + x1 : 2; + pad0 : 3; + x2 : 2; + pad1 : 5; + x3 : 1; + pad2 : 2; + skip : 32; + x4 : 1; + x5 : 1; + pad3 : 6; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setf4(val) { modify_field(data.f4, val); } + +table test1 { + reads { + data.f1 : exact; + } + actions { + setf4; + noop; + } +} +table test2 { + reads { + data.f2 : exact; + } + actions { + setf4; + noop; + } +} + +control ingress { + if (data.x1 == 1 and data.x4 == 0) { + apply(test1); + } else { + apply(test2); + } +} diff --git a/backends/tofino/bf-asm/test/gateway6.p4 b/backends/tofino/bf-asm/test/gateway6.p4 new file mode 100644 index 00000000000..79b0114a759 --- /dev/null +++ b/backends/tofino/bf-asm/test/gateway6.p4 @@ -0,0 +1,48 @@ +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setb1(val) { modify_field(data.b1, val); } + +table test1 { + reads { + data.f1 : exact; + } + actions { + setb1; + noop; + } +} +table test2 { + reads { + data.f2 : exact; + } + actions { + setb1; + noop; + } +} + +control ingress { + if (1 == (15 & data.b2)) { + apply(test1); + } else { + apply(test2); + } +} diff --git a/backends/tofino/bf-asm/test/gateway7.p4 b/backends/tofino/bf-asm/test/gateway7.p4 new file mode 100644 index 00000000000..d1aec5c6802 --- /dev/null +++ b/backends/tofino/bf-asm/test/gateway7.p4 @@ -0,0 +1,48 @@ +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setb1(val) { modify_field(data.b1, val); } + +table test1 { + reads { + data.f1 : exact; + } + actions { + setb1; + noop; + } +} +table test2 { + reads { + data.f2 : exact; + } + actions { + setb1; + noop; + } +} + +control ingress { + if (data.b2 > 50) { + apply(test1); + } else { + apply(test2); + } +} diff --git a/backends/tofino/bf-asm/test/hash_index0.p4 b/backends/tofino/bf-asm/test/hash_index0.p4 new file mode 100644 index 00000000000..a134f631824 --- /dev/null +++ b/backends/tofino/bf-asm/test/hash_index0.p4 @@ -0,0 +1,36 @@ +#include + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action setf1(val) { modify_field(data.f1, val); } + +table test1 { + reads { + data.b1 : exact; + } + actions { + setf1; + } + size : 256; +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/hash_index1.p4 b/backends/tofino/bf-asm/test/hash_index1.p4 new file mode 100644 index 00000000000..60b67fa6744 --- /dev/null +++ b/backends/tofino/bf-asm/test/hash_index1.p4 @@ -0,0 +1,38 @@ +#include + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action setf1(val) { modify_field(data.f1, val); } + +table test1 { + reads { + data.b1 : exact; + } + actions { + setf1; + } + size : 256; +} + +control ingress { + if (data.b2 == 4) { + apply(test1); + } +} diff --git a/backends/tofino/bf-asm/test/hash_index2.p4 b/backends/tofino/bf-asm/test/hash_index2.p4 new file mode 100644 index 00000000000..2fdb0d00f89 --- /dev/null +++ b/backends/tofino/bf-asm/test/hash_index2.p4 @@ -0,0 +1,51 @@ +#include + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action setf1(val) { modify_field(data.f1, val); } +action setf2(val) { modify_field(data.f2, val); } +action setf3(val) { modify_field(data.f3, val); } + +@pragma use_hash_action 1 +table test1 { + reads { + data.b1 : exact; + } + actions { + setf1; + } + default_action : setf1(0); + size : 256; +} + +table test2 { + reads { + data.f1 : ternary; + } + actions { + setf2; + setf3; + } +} + +control ingress { + apply(test1); + apply(test2); +} diff --git a/backends/tofino/bf-asm/test/hash_index3.p4 b/backends/tofino/bf-asm/test/hash_index3.p4 new file mode 100644 index 00000000000..f506cc186af --- /dev/null +++ b/backends/tofino/bf-asm/test/hash_index3.p4 @@ -0,0 +1,63 @@ +#include + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action setf1(val) { modify_field(data.f1, val); } +action setf2(val) { modify_field(data.f2, val); } +action setf3(val) { modify_field(data.f3, val); } + +@pragma use_hash_action 1 +table test1 { + reads { + data.b1 : exact; + } + actions { + setf1; + } + default_action : setf1(0); + size : 256; +} + +table test2 { + reads { + data.f2 : ternary; + } + actions { + setf3; + } +} + +table test3 { + reads { + data.f4 : ternary; + } + actions { + setf3; + } +} + +control ingress { + if (data.b2 == 10) { + apply(test1); + } else { + apply(test2); + } + apply(test3); +} diff --git a/backends/tofino/bf-asm/test/hash_index5.p4 b/backends/tofino/bf-asm/test/hash_index5.p4 new file mode 100644 index 00000000000..553b33cd737 --- /dev/null +++ b/backends/tofino/bf-asm/test/hash_index5.p4 @@ -0,0 +1,37 @@ +#include + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action countb2(val) { count(simple, data.b2); } + +counter simple { + type : packets; + instance_count : 256; +} + +table test1 { + actions { + countb2; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/instruct1.p4 b/backends/tofino/bf-asm/test/instruct1.p4 new file mode 100644 index 00000000000..e0f12c83018 --- /dev/null +++ b/backends/tofino/bf-asm/test/instruct1.p4 @@ -0,0 +1,61 @@ + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; +header_type data2_t { + fields { + x1 : 16; + x2 : 16; + } +} +header data2_t hdr1; +header data2_t hdr2; + +parser start { + extract(data); + return select(data.b1) { + 0x00: parse_data2; + default: ingress; + } +} +parser parse_data2 { + extract(hdr1); + return select(hdr1.x1) { + 1 mask 1: parse_hdr2; + default: ingress; + } +} +parser parse_hdr2 { + extract(hdr2); + return ingress; +} + +action noop() { } +action decap() { + copy_header(hdr1, hdr2); + remove_header(hdr2); +} + +table test1 { + reads { + data.f1 : exact; + } + actions { + decap; + noop; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/instruct2.p4 b/backends/tofino/bf-asm/test/instruct2.p4 new file mode 100644 index 00000000000..52eed14e2db --- /dev/null +++ b/backends/tofino/bf-asm/test/instruct2.p4 @@ -0,0 +1,39 @@ +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action do_xor() { bit_xor(data.b1, data.b2, data.b3); } +action do_and() { bit_and(data.b2, data.b3, data.b4); } +action do_or() { bit_or(data.b4, data.b3, data.b1); } +action do_add() { add(data.b3, data.b1, data.b2); } + +table test1 { + reads { + data.f1 : exact; + } + actions { + do_add; + do_and; + do_or; + do_xor; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/instruct3.p4 b/backends/tofino/bf-asm/test/instruct3.p4 new file mode 100644 index 00000000000..e8f0396137a --- /dev/null +++ b/backends/tofino/bf-asm/test/instruct3.p4 @@ -0,0 +1,34 @@ + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + x1 : 2; + x2 : 2; + x3 : 2; + x4 : 2; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setx() { modify_field(data.x2, 2); modify_field(data.x4,1); } + +table test1 { + reads { + data.f1 : exact; + } + actions { + setx; + noop; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/instruct4.p4 b/backends/tofino/bf-asm/test/instruct4.p4 new file mode 100644 index 00000000000..f4babaf63d4 --- /dev/null +++ b/backends/tofino/bf-asm/test/instruct4.p4 @@ -0,0 +1,35 @@ +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setf4() { modify_field(data.f4, 0x70a50); } + +table test1 { + reads { + data.f1 : exact; + } + actions { + setf4; + noop; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/instruct5.p4 b/backends/tofino/bf-asm/test/instruct5.p4 new file mode 100644 index 00000000000..de60a960474 --- /dev/null +++ b/backends/tofino/bf-asm/test/instruct5.p4 @@ -0,0 +1,56 @@ + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; +header_type data2_t { + fields { + x1 : 16; + x2 : 16; + } +} +header data2_t extra[4]; + +parser start { + extract(data); + return select(data.b1) { + 0x00: parse_extra; + default: ingress; + } +} +parser parse_extra { + extract(extra[next]); + return select(latest.x1) { + 1 mask 1: parse_extra; + default: ingress; + } +} + +action noop() { } +action push1() { push(extra, 1); } +action push2() { push(extra, 2); } + + +table test1 { + reads { + data.f1 : exact; + } + actions { + noop; + push1; + push2; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/internal/brig/expected_failures.txt b/backends/tofino/bf-asm/test/internal/brig/expected_failures.txt new file mode 100644 index 00000000000..cde3422c8a6 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/brig/expected_failures.txt @@ -0,0 +1,2 @@ +test_config_123_meter_2.p4 bfas +- missing color_maprams diff --git a/backends/tofino/bf-asm/test/internal/brig/test_config_123_meter_2.p4 b/backends/tofino/bf-asm/test/internal/brig/test_config_123_meter_2.p4 new file mode 100644 index 00000000000..490c6f499af --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/brig/test_config_123_meter_2.p4 @@ -0,0 +1,118 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + color_0 : 8; + pad_0 : 24; + pad_1 : 160; + pad_2 : 24; + color_1 : 8; + pad_3 : 24; + + lpf : 16; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +meter meter_0 { + type : bytes; + //static : table_0; + direct : table_0; + result : pkt.color_0; // Over-loading the meaning of result to be the input and output + //instance_count : 500; + //implementation : red; +} + + +meter meter_1 { + type : bytes; + static : table_1; + //direct : table_1; + result : pkt.color_1; + instance_count : 4097; +} + + +action action_0(param0){ + //modify_field(pkt.field_f_16, param0); + //execute_meter(meter_0, 7, pkt.color_0); +} + + +action action_1(param0){ + //modify_field(pkt.field_g_16, param0); + execute_meter(meter_1, 7, pkt.color_1); +} + + +action do_nothing(){ + no_op(); +// drop(); +} + + + +//@pragma include_idletime 1 +@pragma pa_solitare meter_result.color_0, meter_result.color_1 +@pragma include_stash 1 +@pragma action_default_only do_nothing +table table_0 { + reads { + pkt.field_e_16 : ternary; + pkt.color_0 : exact; //HACK + pkt.color_1 : exact; //HACK + pkt.lpf : exact; //HACK + } + actions { + action_0; + //do_nothing; + } + size : 6000; +} + + +//@pragma include_idletime 1 +@pragma idletime_two_way_notification 1 +@pragma include_stash 1 +table table_1 { + reads { + pkt.field_e_16: exact; + } + actions { + do_nothing; + action_1; + } + size : 32768; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_1); +} diff --git a/backends/tofino/bf-asm/test/internal/brig/test_config_223_simple_set_metadata.p4 b/backends/tofino/bf-asm/test/internal/brig/test_config_223_simple_set_metadata.p4 new file mode 100644 index 00000000000..d940d02eb15 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/brig/test_config_223_simple_set_metadata.p4 @@ -0,0 +1,82 @@ +// #include "tofino/intrinsic_metadata.p4" + +header_type zero_byte_t { + fields { + a : 8; + } +} + +header_type one_byte_t { + fields { + a : 8; + } +} + +header_type meta_t { + fields { + a : 32; + b : 8; + c : 5; + d : 3; + } +} + +header zero_byte_t zero; +header one_byte_t one; +metadata meta_t meta; + +parser start { + return zerob; +} + +parser zerob { + extract(zero); + return select(zero.a) { + 0 : oneb; + default : twob; + } +} + + +parser oneb { + extract(one); + set_metadata(meta.b, latest.a); + set_metadata(meta.a, 0x7); + set_metadata(meta.c, 1); + set_metadata(meta.d, 2); //current(8, 1)); + return ingress; +} + +parser twob { + extract(one); + set_metadata(meta.c, 2); + return ingress; +} + + +action do_nothing(){} + +action action_0(p){ + add(one.a, one.a, 1); + add(meta.a, meta.a, p); +} + + +table table_i0 { + reads { + one.a : ternary; + meta.a : exact; + meta.b : exact; + meta.c : exact; + meta.d : exact; + } + actions { + do_nothing; + action_0; + } + size : 512; +} + +control ingress { + apply(table_i0); +} diff --git a/backends/tofino/bf-asm/test/internal/debug_issue_1_invalid_action_pack_format.p4 b/backends/tofino/bf-asm/test/internal/debug_issue_1_invalid_action_pack_format.p4 new file mode 100644 index 00000000000..bb8d5c9a5a1 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/debug_issue_1_invalid_action_pack_format.p4 @@ -0,0 +1,84 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + + +action nop(){ + no_op(); +} + +action mod_mac_adr(egress_port, srcmac, dstmac) { + //modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + + +@pragma immediate 1 +table tcam_tbl_stage_2 { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + mod_mac_adr; + } +} + + +control ingress{ + apply(tcam_tbl_stage_2); +} diff --git a/backends/tofino/bf-asm/test/internal/debug_issue_2_action_data_bus.PRAGMA b/backends/tofino/bf-asm/test/internal/debug_issue_2_action_data_bus.PRAGMA new file mode 100644 index 00000000000..c31981eb8a0 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/debug_issue_2_action_data_bus.PRAGMA @@ -0,0 +1,610 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm: csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + //modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop_ipv4(egress_port /*,srcmac, dstmac*/) { + hop(ipv4.ttl, egress_port); +// modify_field(ethernet.srcAddr, srcmac); +// modify_field(ethernet.dstAddr, dstmac); +} + +action drop_ipv4 () { + drop(); +} + +action next_hop_ipv4(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + //modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action ig_drop() { +// modify_field(routing_metadata.drop, 1); + add_to_field(ipv4.ttl, -1); + //modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); +} + +action mod_mac_adr(egress_port, srcmac, dstmac) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + //modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action udp_hdr_add (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + add_header(udp); + modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); + add_to_field(ipv4.totalLen, 8); +} + +action tcp_hdr_rm (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + remove_header(tcp); + modify_field(ipv4.protocol, 0); +// add_to_field(ipv4.totalLen, -20); +// modify_field(ipv4.totalLen, 66); +} + +action modify_tcp_dst_port(dstPort) { + modify_field(tcp.dstPort, dstPort); +} + +action modify_tcp_dst_port_1(dstPort, egress_port) { + modify_field(tcp.dstPort, dstPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ipv4.srcAddr, ipAddr); + modify_field(ethernet.dstAddr, dstAddr); + modify_field(tcp.dstPort, tcpPort); +} + +action custom_action_2(egress_port, ipAddr, tcpPort) +{ + modify_field(ipv4.srcAddr, ipAddr); + modify_field(tcp.dstPort, tcpPort); + hop(ipv4.ttl, egress_port); +} + +action custom_action_3(egress_port, dstAddr, dstIp) +{ + modify_field(ipv4.dstAddr, dstIp); + modify_field(ethernet.dstAddr, dstAddr); + hop(ipv4.ttl, egress_port); +} + +action modify_l2 (egress_port, srcAddr, dstAddr) { + // Trying for 128 bit action data + hop(ipv4.ttl, egress_port); + //modify_field(ethernet.srcAddr, srcAddr); + modify_field(ethernet.dstAddr, dstAddr); +} + +action switching_action_1(egress_port/*, vlan_id */) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + //modify_field(vlan_tag.vlan_id, vlan_id); +} + +@pragma immediate 1 +table ipv4_routing { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + hop_ipv4; + drop_ipv4; + } +} + +table ipv4_routing_exm_ways_3_pack_5 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + modify_tcp_dst_port_1; + } +} + + +table ipv4_routing_exm_ways_3_pack_3 { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + custom_action_1; + } +} + +table ipv4_routing_exm_ways_4_pack_3_stage_1 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma immediate 1 +table ipv4_routing_stage_1 { + reads { + ipv4.dstAddr : lpm; + ipv4.srcAddr : exact; + } + actions { + nop; + hop_ipv4; + } + size : 1024; +} + +@pragma immediate 1 +table tcam_tbl_stage_2 { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + mod_mac_adr; + } +} + +table ipv4_routing_exm_ways_4_pack_7_stage_2 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + tcp.dstPort : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +table ipv4_routing_exm_ways_3_pack_7_stage_2 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + +table ipv4_routing_exm_ways_5_pack_3_stage_3 { + reads { + ipv4.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma immediate 1 +table udp_add_tbl_stage_3 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + udp_hdr_add; + } +} + +table ipv4_routing_exm_ways_6_pack_3_stage_4 { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + + +@pragma immediate 1 +table tcp_rm_tbl_stage_4 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + tcp_hdr_rm; + } +} + +table ipv4_routing_exm_ways_3_pack_4_stage_5 { + reads { + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + modify_tcp_dst_port_1; + } +} + +table switching_exm_ways_3_pack_6_stage_5 { + reads { + ethernet.dstAddr : exact; + vlan_tag.vlan_id : exact; + } + actions { + nop; + switching_action_1; + } +} + +table ipv4_routing_exm_ways_4_pack_4_stage_6 { + reads { + ethernet.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_exm_ways_4_pack_6_stage_6 { + reads { + ethernet.srcAddr : exact; + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_exm_ways_5_pack_4_stage_7 { + reads { + ipv4.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + +table ipv4_routing_exm_ways_5_pack_6_stage_7 { + reads { + ipv4.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +table ipv4_routing_exm_ways_4_pack_5_stage_8 { + reads { + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.srcPort : exact; + tcp.dstPort : exact; + } + actions { + nop; + custom_action_2; + } +} + + +table ipv4_routing_exm_ways_5_pack_5_stage_9 { + reads { + ipv4.dstAddr : exact; + ethernet.srcAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + + +table ipv4_routing_exm_ways_6_pack_5_stage_10 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + custom_action_2; + } +} + +table ipv4_routing_exm_ways_5_pack_7_stage_10 { + reads { + ethernet.srcAddr : exact; + ipv4.dstAddr : exact; + } + actions { + nop; + tcp_hdr_rm; + } +} + +@pragma immediate 1 +table tcam_adt_deep_stage_10 { + reads { + ethernet.srcAddr : ternary; + ethernet.dstAddr : ternary; + ipv4.srcAddr : ternary; + ipv4.dstAddr : ternary; + } + actions { + nop; + modify_l2; + } + size : 2048; +} + +table ipv4_routing_exm_stage_11 { + reads { + ethernet.srcAddr : exact; + ethernet.dstAddr : exact; + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + custom_action_2; + } +} + +table ipv4_routing_exm_ways_6_pack_6_stage_11 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + +table ipv4_routing_exm_ways_6_pack_4_stage_11 { + reads { + ipv4.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + + +/* Main control flow */ +control ingress { + /* A general principle : Always keep the exact match tables ahead of the + * ternary tables in the same stage, except first stage. Logic relating to next-table + * will cause the Tofino model not to launch a lookup on th exact match + * tables if the order is reversed. + */ + apply(ipv4_routing); +/// apply(ipv4_routing_exm_ways_3_pack_5); +/// apply(ipv4_routing_exm_ways_3_pack_3); +/// apply(ipv4_routing_exm_ways_4_pack_3_stage_1); + apply(ipv4_routing_stage_1); + apply(tcam_tbl_stage_2); +/// apply(ipv4_routing_exm_ways_4_pack_7_stage_2); +/// apply(ipv4_routing_exm_ways_3_pack_7_stage_2); +/// apply(ipv4_routing_exm_ways_5_pack_3_stage_3); + /* Gateway not yet supported */ +// if (ipv4.protocol == 0) { + apply(udp_add_tbl_stage_3); +// } + apply(ipv4_routing_exm_ways_6_pack_3_stage_4); +// if (valid(tcp)) { + apply(tcp_rm_tbl_stage_4); +// } + apply(ipv4_routing_exm_ways_3_pack_4_stage_5); + apply(switching_exm_ways_3_pack_6_stage_5); + apply(ipv4_routing_exm_ways_4_pack_4_stage_6); + apply(ipv4_routing_exm_ways_4_pack_6_stage_6); + apply(ipv4_routing_exm_ways_5_pack_4_stage_7); + apply(ipv4_routing_exm_ways_5_pack_6_stage_7); + apply(ipv4_routing_exm_ways_4_pack_5_stage_8); + apply(ipv4_routing_exm_ways_5_pack_5_stage_9); + apply(ipv4_routing_exm_ways_6_pack_5_stage_10); + apply(tcam_adt_deep_stage_10); + //apply(ipv4_routing_exm_ways_6_pack_6_stage_11); + apply(ipv4_routing_exm_ways_6_pack_4_stage_11); +} + +action eg_drop() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); + modify_field(eg_intr_md.egress_port, 0); +} + +action permit() { +} + +table egress_acl { + reads { + routing_metadata.drop: ternary; + } + actions { + permit; + eg_drop; + } +} + + +control egress { +// apply(egress_acl); +} diff --git a/backends/tofino/bf-asm/test/internal/debug_issue_3_7_way_table.p4 b/backends/tofino/bf-asm/test/internal/debug_issue_3_7_way_table.p4 new file mode 100644 index 00000000000..4d5d569cb10 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/debug_issue_3_7_way_table.p4 @@ -0,0 +1,82 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + + +action nop(){ + no_op(); +} + +action mod_mac_adr(dstmac) { + modify_field(ethernet.dstAddr, dstmac); +} + + +@pragma ways 7 +table table_0 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + mod_mac_adr; + } +} + + +control ingress{ + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/debug_issue_4_small_exact_match_key.p4 b/backends/tofino/bf-asm/test/internal/debug_issue_4_small_exact_match_key.p4 new file mode 100644 index 00000000000..b57539b97bf --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/debug_issue_4_small_exact_match_key.p4 @@ -0,0 +1,81 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + + +action nop(){ + no_op(); +} + +action mod_mac_adr(dstmac) { + modify_field(ethernet.dstAddr, dstmac); +} + + +table table_0 { + reads { + ipv4.hdrChecksum : exact; + } + actions { + nop; + mod_mac_adr; + } +} + + +control ingress{ + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/dileep.p4 b/backends/tofino/bf-asm/test/internal/dileep.p4 new file mode 100644 index 00000000000..5de7d6a65f8 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/dileep.p4 @@ -0,0 +1,290 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm: csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop_ipv4(egress_port /*,srcmac, dstmac*/) { + hop(ipv4.ttl, egress_port); +// modify_field(ethernet.srcAddr, srcmac); +// modify_field(ethernet.dstAddr, dstmac); +} + +action next_hop_ipv4(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action ig_drop() { +// modify_field(routing_metadata.drop, 1); + add_to_field(ipv4.ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); +} + +action mod_mac_adr(egress_port, srcmac, dstmac) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action udp_hdr_add (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + add_header(udp); + modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); + add_to_field(ipv4.totalLen, 8); +} + +action tcp_hdr_rm (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + remove_header(tcp); + modify_field(ipv4.protocol, 0); +// add_to_field(ipv4.totalLen, -20); +// modify_field(ipv4.totalLen, 66); +} + +table ipv4_routing { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + hop_ipv4; + } +} + +table ipv4_routing_exm_stage_5 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } + + size : 28672; +} + +table ipv4_routing_exm_stage_6 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } + + size : 8192; +} + +table ipv4_routing_stage_1 { + reads { + ipv4.dstAddr : lpm; + ipv4.srcAddr : exact; + } + actions { + nop; + hop_ipv4; + } + size : 1024; +} + +table tcam_tbl_stage_2 { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + mod_mac_adr; + } +} + +table udp_add_tbl_stage_3 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + udp_hdr_add; + } +} + +table tcp_rm_tbl_stage_4 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + tcp_hdr_rm; + } +} + +/* Main control flow */ +control ingress { + apply(ipv4_routing); + apply(ipv4_routing_stage_1); + apply(tcam_tbl_stage_2); + /* Gateway not yet supported */ +// if (ipv4.protocol == 0) { + apply(udp_add_tbl_stage_3); +// } +// if (valid(tcp)) { + apply(tcp_rm_tbl_stage_4); +// } + apply(ipv4_routing_exm_stage_5); + apply(ipv4_routing_exm_stage_6); +} + +action eg_drop() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); + modify_field(eg_intr_md.egress_port, 0); +} + +action permit() { +} + +table egress_acl { + reads { + routing_metadata.drop: ternary; + } + actions { + permit; + eg_drop; + } +} + +control egress { +// apply(egress_acl); +} diff --git a/backends/tofino/bf-asm/test/internal/dileep10.p4 b/backends/tofino/bf-asm/test/internal/dileep10.p4 new file mode 100644 index 00000000000..510c7c77132 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/dileep10.p4 @@ -0,0 +1,186 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm: csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action custom_action_3(egress_port, dstAddr, dstIp) +{ + modify_field(ipv4.dstAddr, dstIp); + modify_field(ethernet.dstAddr, dstAddr); + hop(ipv4.ttl, egress_port); +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +@pragma stage 2 + +table exm_3ways_32k { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + tcp.srcPort : exact; + tcp.dstPort : exact; + } + actions { + nop; + custom_action_3; + } + + size : 32768; +} + +control ingress { + apply(exm_3ways_32k); +} diff --git a/backends/tofino/bf-asm/test/internal/dileep11.p4 b/backends/tofino/bf-asm/test/internal/dileep11.p4 new file mode 100644 index 00000000000..e5d95ade07a --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/dileep11.p4 @@ -0,0 +1,183 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm: csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action next_hop_ipv4(egress_port, srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + + +@pragma stage 6 +@pragma ways 4 +@pragma pack 4 +table ipv4_routing_exm_ways_4_pack_4_stage_6 { + reads { + ethernet.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + + +control ingress { + apply(ipv4_routing_exm_ways_4_pack_4_stage_6); +} diff --git a/backends/tofino/bf-asm/test/internal/dileep12.p4 b/backends/tofino/bf-asm/test/internal/dileep12.p4 new file mode 100644 index 00000000000..2fa4f419c37 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/dileep12.p4 @@ -0,0 +1,449 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type ipv6_t { + fields { + version : 4; + trafficClass : 8; + flowLabel : 20; + payloadLen : 16; + nextHdr : 8; + hopLimit : 8; + srcAddr : 128; + dstAddr : 128; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + 0x86dd : parse_ipv6; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; +header ipv6_t ipv6; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +parser parse_ipv6 { + extract(ipv6); + return select(latest.nextHdr) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default : ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm : csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action egress_port(egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop_ipv4(egress_port /*,srcmac, dstmac*/) { + hop(ipv4.ttl, egress_port); +// modify_field(ethernet.srcAddr, srcmac); +// modify_field(ethernet.dstAddr, dstmac); +} + +action drop_ipv4 () { + drop(); +} + +action next_hop_ipv4(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action next_hop_ipv6(egress_port ,srcmac, dstmac) { + hop(ipv6.hopLimit, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action ig_drop() { +// modify_field(routing_metadata.drop, 1); + add_to_field(ipv4.ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); +} + +action mod_mac_addr(egress_port, srcmac, dstmac) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action udp_hdr_add (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + add_header(udp); + modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); + add_to_field(ipv4.totalLen, 8); +} + +action tcp_hdr_rm (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + remove_header(tcp); + modify_field(ipv4.protocol, 0); +// add_to_field(ipv4.totalLen, -20); +// modify_field(ipv4.totalLen, 66); +} + +action modify_tcp_dst_port(dstPort) { + modify_field(tcp.dstPort, dstPort); +} + +action modify_tcp_dst_port_1(dstPort, egress_port) { + modify_field(tcp.dstPort, dstPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ipv4.srcAddr, ipAddr); + modify_field(ethernet.dstAddr, dstAddr); + modify_field(tcp.dstPort, tcpPort); +} + +action custom_action_2(egress_port, ipAddr, tcpPort) +{ + modify_field(ipv4.srcAddr, ipAddr); + modify_field(tcp.dstPort, tcpPort); + hop(ipv4.ttl, egress_port); +} + +action custom_action_3(egress_port, dstAddr, dstIp) +{ + modify_field(ipv4.dstAddr, dstIp); + modify_field(ethernet.dstAddr, dstAddr); + hop(ipv4.ttl, egress_port); +} + +action custom_action_4(egress_port, dstPort, srcPort) +{ + modify_field(tcp.dstPort, dstPort); + modify_field(tcp.srcPort, srcPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_5(dstPort, srcPort) +{ + modify_field(tcp.dstPort, dstPort); + modify_field(tcp.srcPort, srcPort); +} + +action switching_action_1(egress_port/*, vlan_id */) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + //modify_field(vlan_tag.vlan_id, vlan_id); +} + +action nhop_set(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action nhop_set_1(port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +@pragma stage 0 +@pragma pack 5 +@pragma ways 5 + +table exm_5ways_5Entries { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_3; + } + + size : 25600; +} + +@pragma stage 1 +@pragma pack 5 +@pragma ways 6 + +table exm_6ways_5Entries { + reads { + ethernet.dstAddr : exact; + ipv4.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + next_hop_ipv4; + } + size : 30720; +} + +@pragma stage 2 +@pragma pack 6 +@pragma ways 4 + +table exm_4ways_6Entries { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + custom_action_1; + } + size : 24576; +} + +@pragma stage 3 +@pragma pack 6 +@pragma ways 5 + +table exm_5ways_6Entries { + reads { + ethernet.dstAddr : exact; + } + actions { + nop; + custom_action_2; + } + size : 30720; +} + +@pragma stage 4 +@pragma pack 6 +@pragma ways 6 + +table exm_6ways_6Entries { + reads { + ethernet.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + mod_mac_addr; + } + size : 36864; +} + +@pragma stage 5 +@pragma pack 7 +@pragma ways 3 + +table exm_3ways_7Entries { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } + size : 21504; +} + +@pragma stage 6 +@pragma pack 8 +@pragma ways 4 + +table exm_4ways_8Entries { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + modify_tcp_dst_port_1; + } + size : 32768; +} + + +/* Main control flow */ +control ingress { + /* A general principle : Always keep the exact match tables ahead of the + * ternary tables in the same stage, except first stage. Logic relating to next-table + * will cause the Tofino model not to launch a lookup on th exact match + * tables if the order is reversed. + */ + + apply(exm_5ways_5Entries); + apply(exm_6ways_5Entries); + apply(exm_4ways_6Entries); + + apply(exm_5ways_6Entries); + + apply(exm_6ways_6Entries); + apply(exm_3ways_7Entries); + apply(exm_4ways_8Entries); + +} + +action eg_drop() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); + modify_field(eg_intr_md.egress_port, 0); +} + +action permit() { +} + +table egress_acl { + reads { + routing_metadata.drop: ternary; + } + actions { + permit; + eg_drop; + } +} + +control egress { +// apply(egress_acl); +} diff --git a/backends/tofino/bf-asm/test/internal/dileep2.p4 b/backends/tofino/bf-asm/test/internal/dileep2.p4 new file mode 100644 index 00000000000..023d5d975d5 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/dileep2.p4 @@ -0,0 +1,329 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm: csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop_ipv4(egress_port /*,srcmac, dstmac*/) { + hop(ipv4.ttl, egress_port); +// modify_field(ethernet.srcAddr, srcmac); +// modify_field(ethernet.dstAddr, dstmac); +} + +action next_hop_ipv4(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action ig_drop() { +// modify_field(routing_metadata.drop, 1); + add_to_field(ipv4.ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); +} + +action mod_mac_adr(egress_port, srcmac, dstmac) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action udp_hdr_add (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + add_header(udp); + modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); + add_to_field(ipv4.totalLen, 8); +} + +action tcp_hdr_rm (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + remove_header(tcp); + modify_field(ipv4.protocol, 0); +// add_to_field(ipv4.totalLen, -20); +// modify_field(ipv4.totalLen, 66); +} + +table ipv4_routing { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + hop_ipv4; + } +} + +table ipv4_routing_exm_ways_3_pack_3 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_exm_ways_4_pack_3_stage_1 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_stage_1 { + reads { + ipv4.dstAddr : lpm; + ipv4.srcAddr : exact; + } + actions { + nop; + hop_ipv4; + } + size : 1024; +} + +table tcam_tbl_stage_2 { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + mod_mac_adr; + } +} + +table ipv4_routing_exm_ways_4_pack_7_stage_2 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_exm_ways_5_pack_3_stage_3 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table udp_add_tbl_stage_3 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + udp_hdr_add; + } +} + +table ipv4_routing_exm_ways_6_pack_3_stage_4 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table tcp_rm_tbl_stage_4 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + tcp_hdr_rm; + } +} + +table ipv4_routing_exm_ways_3_pack_4_stage_5 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +/* Main control flow */ +control ingress { + apply(ipv4_routing); + apply(ipv4_routing_exm_ways_3_pack_3); + apply(ipv4_routing_exm_ways_4_pack_3_stage_1); + apply(ipv4_routing_stage_1); + apply(tcam_tbl_stage_2); + apply(ipv4_routing_exm_ways_4_pack_7_stage_2); + apply(ipv4_routing_exm_ways_5_pack_3_stage_3); + /* Gateway not yet supported */ +// if (ipv4.protocol == 0) { + apply(udp_add_tbl_stage_3); +// } +// if (valid(tcp)) { + apply(tcp_rm_tbl_stage_4); +// } + apply(ipv4_routing_exm_ways_6_pack_3_stage_4); + apply(ipv4_routing_exm_ways_3_pack_4_stage_5); +} + +action eg_drop() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); + modify_field(eg_intr_md.egress_port, 0); +} + +action permit() { +} + +table egress_acl { + reads { + routing_metadata.drop: ternary; + } + actions { + permit; + eg_drop; + } +} + +control egress { +// apply(egress_acl); +} diff --git a/backends/tofino/bf-asm/test/internal/dileep3.p4 b/backends/tofino/bf-asm/test/internal/dileep3.p4 new file mode 100644 index 00000000000..019e78359f9 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/dileep3.p4 @@ -0,0 +1,358 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm: csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop_ipv4(egress_port /*,srcmac, dstmac*/) { + hop(ipv4.ttl, egress_port); +// modify_field(ethernet.srcAddr, srcmac); +// modify_field(ethernet.dstAddr, dstmac); +} + +action next_hop_ipv4(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action ig_drop() { +// modify_field(routing_metadata.drop, 1); + add_to_field(ipv4.ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); +} + +action mod_mac_adr(egress_port, srcmac, dstmac) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action udp_hdr_add (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + add_header(udp); + modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); + add_to_field(ipv4.totalLen, 8); +} + +action tcp_hdr_rm (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + remove_header(tcp); + modify_field(ipv4.protocol, 0); +// add_to_field(ipv4.totalLen, -20); +// modify_field(ipv4.totalLen, 66); +} + +action modify_tcp_dst_port(dstPort) { + modify_field(tcp.dstPort, dstPort); +} + +table ipv4_routing { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + hop_ipv4; + } +} + +table ipv4_routing_exm_ways_3_pack_5 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + hop_ipv4; + } +} + +table ipv4_routing_exm_ways_3_pack_3 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_exm_ways_4_pack_3_stage_1 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_stage_1 { + reads { + ipv4.dstAddr : lpm; + ipv4.srcAddr : exact; + } + actions { + nop; + hop_ipv4; + } + size : 1024; +} + +table tcam_tbl_stage_2 { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + mod_mac_adr; + } +} + +table ipv4_routing_exm_ways_4_pack_7_stage_2 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_exm_ways_5_pack_3_stage_3 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table udp_add_tbl_stage_3 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + udp_hdr_add; + } +} + +table ipv4_routing_exm_ways_6_pack_3_stage_4 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table tcp_rm_tbl_stage_4 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + tcp_hdr_rm; + } +} + +table ipv4_routing_exm_ways_3_pack_4_stage_5 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_exm_ways_4_pack_4_stage_6 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_exm_ways_5_pack_4_stage_7 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_exm_ways_6_pack_4_stage_8 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +/* Main control flow */ +control ingress { + apply(ipv4_routing_exm_ways_3_pack_5); +} + +action eg_drop() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); + modify_field(eg_intr_md.egress_port, 0); +} + +action permit() { +} + +table egress_acl { + reads { + routing_metadata.drop: ternary; + } + actions { + permit; + eg_drop; + } +} + +control egress { +// apply(egress_acl); +} diff --git a/backends/tofino/bf-asm/test/internal/dileep4.p4 b/backends/tofino/bf-asm/test/internal/dileep4.p4 new file mode 100644 index 00000000000..e581e0a79dc --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/dileep4.p4 @@ -0,0 +1,412 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm: csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop_ipv4(egress_port /*,srcmac, dstmac*/) { + hop(ipv4.ttl, egress_port); +// modify_field(ethernet.srcAddr, srcmac); +// modify_field(ethernet.dstAddr, dstmac); +} + +action drop_ipv4 () { + drop(); +} + +action next_hop_ipv4(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action ig_drop() { +// modify_field(routing_metadata.drop, 1); + add_to_field(ipv4.ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); +} + +action mod_mac_adr(egress_port, srcmac, dstmac) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action udp_hdr_add (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + add_header(udp); + modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); + add_to_field(ipv4.totalLen, 8); +} + +action tcp_hdr_rm (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + remove_header(tcp); + modify_field(ipv4.protocol, 0); +// add_to_field(ipv4.totalLen, -20); +// modify_field(ipv4.totalLen, 66); +} + +action modify_tcp_dst_port(dstPort) { + modify_field(tcp.dstPort, dstPort); +} + +action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ipv4.srcAddr, ipAddr); + modify_field(ethernet.dstAddr, dstAddr); + modify_field(tcp.dstPort, tcpPort); +} + +action custom_action_2(egress_port, ipAddr, tcpPort) +{ + modify_field(ipv4.srcAddr, ipAddr); + modify_field(tcp.dstPort, tcpPort); + hop(ipv4.ttl, egress_port); +} + +table ipv4_routing { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + hop_ipv4; + drop_ipv4; + } +} + +table ipv4_routing_exm_ways_3_pack_5 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + modify_tcp_dst_port; + } +} + +table ipv4_routing_exm_ways_3_pack_3 { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + custom_action_1; + } +} + +table ipv4_routing_exm_ways_4_pack_3_stage_1 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_stage_1 { + reads { + ipv4.dstAddr : lpm; + ipv4.srcAddr : exact; + } + actions { + nop; + hop_ipv4; + } + size : 1024; +} + +table tcam_tbl_stage_2 { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + mod_mac_adr; + } +} + +table ipv4_routing_exm_ways_4_pack_7_stage_2 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + tcp.dstPort : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +table ipv4_routing_exm_ways_5_pack_3_stage_3 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table udp_add_tbl_stage_3 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + udp_hdr_add; + } +} + +table ipv4_routing_exm_ways_6_pack_3_stage_4 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table tcp_rm_tbl_stage_4 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + tcp_hdr_rm; + } +} + +table ipv4_routing_exm_ways_3_pack_4_stage_5 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_exm_ways_4_pack_4_stage_6 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_exm_ways_5_pack_4_stage_7 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_exm_ways_6_pack_4_stage_8 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +/* Main control flow */ +control ingress { + /* A general principle : Always keep the exact match tables ahead of the + * ternary tables in the same stage, except first stage. Logic relating to next-table + * will cause the Tofino model not to launch a lookup on th exact match + * tables if the order is reversed. + */ + apply(ipv4_routing); + apply(ipv4_routing_exm_ways_3_pack_5); + apply(ipv4_routing_exm_ways_3_pack_3); + apply(ipv4_routing_exm_ways_4_pack_3_stage_1); + apply(ipv4_routing_stage_1); + apply(tcam_tbl_stage_2); + apply(ipv4_routing_exm_ways_4_pack_7_stage_2); + apply(ipv4_routing_exm_ways_5_pack_3_stage_3); + /* Gateway not yet supported */ +// if (ipv4.protocol == 0) { + apply(udp_add_tbl_stage_3); +// } + apply(ipv4_routing_exm_ways_6_pack_3_stage_4); +// if (valid(tcp)) { + apply(tcp_rm_tbl_stage_4); +// } + /* Commenting this out, because of a compiler issue */ + //apply(ipv4_routing_exm_ways_3_pack_4_stage_5); + /* Commenting this out, because of a compiler issue */ + //apply(ipv4_routing_exm_ways_4_pack_4_stage_6); + /* Commenting this out, because of a compiler issue */ + //apply(ipv4_routing_exm_ways_5_pack_4_stage_7); + /* Commenting this out, because of a compiler issue */ + //apply(ipv4_routing_exm_ways_6_pack_4_stage_8); +} + +action eg_drop() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); + modify_field(eg_intr_md.egress_port, 0); +} + +action permit() { +} + +table egress_acl { + reads { + routing_metadata.drop: ternary; + } + actions { + permit; + eg_drop; + } +} + +control egress { +// apply(egress_acl); +} diff --git a/backends/tofino/bf-asm/test/internal/dileep5.PRAGMA b/backends/tofino/bf-asm/test/internal/dileep5.PRAGMA new file mode 100644 index 00000000000..ef5eeb8311f --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/dileep5.PRAGMA @@ -0,0 +1,487 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + vlan_id : 12; + pri : 3; + cfi : 1; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm: csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop_ipv4(egress_port /*,srcmac, dstmac*/) { + hop(ipv4.ttl, egress_port); +// modify_field(ethernet.srcAddr, srcmac); +// modify_field(ethernet.dstAddr, dstmac); +} + +action drop_ipv4 () { + drop(); +} + +action next_hop_ipv4(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action ig_drop() { +// modify_field(routing_metadata.drop, 1); + add_to_field(ipv4.ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); +} + +action mod_mac_adr(egress_port, srcmac, dstmac) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action udp_hdr_add (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + add_header(udp); + modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); + add_to_field(ipv4.totalLen, 8); +} + +action tcp_hdr_rm (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + remove_header(tcp); + modify_field(ipv4.protocol, 0); +// add_to_field(ipv4.totalLen, -20); +// modify_field(ipv4.totalLen, 66); +} + +action modify_tcp_dst_port(dstPort) { + modify_field(tcp.dstPort, dstPort); +} + +action modify_tcp_dst_port_1(dstPort, egress_port) { + modify_field(tcp.dstPort, dstPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ipv4.srcAddr, ipAddr); + modify_field(ethernet.dstAddr, dstAddr); + modify_field(tcp.dstPort, tcpPort); +} + +action custom_action_2(egress_port, ipAddr, tcpPort) +{ + modify_field(ipv4.srcAddr, ipAddr); + modify_field(tcp.dstPort, tcpPort); + hop(ipv4.ttl, egress_port); +} + +action custom_action_3(egress_port, dstAddr, dstIp) +{ + modify_field(ipv4.dstAddr, dstIp); + modify_field(ethernet.dstAddr, dstAddr); + hop(ipv4.ttl, egress_port); +} + +table ipv4_routing { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + hop_ipv4; + drop_ipv4; + } +} + +table ipv4_routing_exm_ways_3_pack_5 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + modify_tcp_dst_port_1; + } +} + + +table ipv4_routing_exm_ways_3_pack_3 { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + custom_action_1; + } +} + +table ipv4_routing_exm_ways_4_pack_3_stage_1 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_stage_1 { + reads { + ipv4.dstAddr : lpm; + ipv4.srcAddr : exact; + } + actions { + nop; + hop_ipv4; + } + size : 1024; +} + +table tcam_tbl_stage_2 { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + mod_mac_adr; + } +} + +table ipv4_routing_exm_ways_4_pack_7_stage_2 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + tcp.dstPort : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +table ipv4_routing_exm_ways_5_pack_3_stage_3 { + reads { + ipv4.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table udp_add_tbl_stage_3 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + udp_hdr_add; + } +} + +table ipv4_routing_exm_ways_6_pack_3_stage_4 { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table tcp_rm_tbl_stage_4 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + tcp_hdr_rm; + } +} + +table ipv4_routing_exm_ways_3_pack_4_stage_5 { + reads { + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + modify_tcp_dst_port_1; + } +} + +table ipv4_routing_exm_ways_4_pack_4_stage_6 { + reads { + ethernet.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_exm_ways_5_pack_4_stage_7 { + reads { + ipv4.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + +table ipv4_routing_exm_ways_4_pack_5_stage_8 { + reads { + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.srcPort : exact; + tcp.dstPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +table ipv4_routing_exm_ways_5_pack_5_stage_9 { + reads { + ipv4.dstAddr : exact; + ethernet.srcAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_exm_ways_6_pack_4_stage_9 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_exm_ways_6_pack_5_stage_10 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + custom_action_2; + } +} + +/* Main control flow */ +control ingress { + /* A general principle : Always keep the exact match tables ahead of the + * ternary tables in the same stage, except first stage. Logic relating to next-table + * will cause the Tofino model not to launch a lookup on th exact match + * tables if the order is reversed. + */ + apply(ipv4_routing); + apply(ipv4_routing_exm_ways_3_pack_5); + apply(ipv4_routing_exm_ways_3_pack_3); + apply(ipv4_routing_exm_ways_4_pack_3_stage_1); + apply(ipv4_routing_stage_1); + apply(tcam_tbl_stage_2); + apply(ipv4_routing_exm_ways_4_pack_7_stage_2); + apply(ipv4_routing_exm_ways_5_pack_3_stage_3); + /* Gateway not yet supported */ +// if (ipv4.protocol == 0) { + apply(udp_add_tbl_stage_3); +// } + apply(ipv4_routing_exm_ways_6_pack_3_stage_4); +// if (valid(tcp)) { + apply(tcp_rm_tbl_stage_4); +// } + apply(ipv4_routing_exm_ways_3_pack_4_stage_5); + apply(ipv4_routing_exm_ways_4_pack_4_stage_6); + apply(ipv4_routing_exm_ways_5_pack_4_stage_7); + apply(ipv4_routing_exm_ways_4_pack_5_stage_8); + apply(ipv4_routing_exm_ways_5_pack_5_stage_9); + apply(ipv4_routing_exm_ways_6_pack_5_stage_10); + //apply(ipv4_routing_exm_ways_6_pack_4_stage_9); +} + +action eg_drop() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); + modify_field(eg_intr_md.egress_port, 0); +} + +action permit() { +} + +table egress_acl { + reads { + routing_metadata.drop: ternary; + } + actions { + permit; + eg_drop; + } +} + +control egress { +// apply(egress_acl); +} diff --git a/backends/tofino/bf-asm/test/internal/dileep6.PHV_BUG b/backends/tofino/bf-asm/test/internal/dileep6.PHV_BUG new file mode 100644 index 00000000000..7aa6836be1c --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/dileep6.PHV_BUG @@ -0,0 +1,592 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm: csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop_ipv4(egress_port /*,srcmac, dstmac*/) { + hop(ipv4.ttl, egress_port); +// modify_field(ethernet.srcAddr, srcmac); +// modify_field(ethernet.dstAddr, dstmac); +} + +action drop_ipv4 () { + drop(); +} + +action next_hop_ipv4(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action ig_drop() { +// modify_field(routing_metadata.drop, 1); + add_to_field(ipv4.ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); +} + +action mod_mac_adr(egress_port, srcmac, dstmac) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action udp_hdr_add (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + add_header(udp); + modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); + add_to_field(ipv4.totalLen, 8); +} + +action tcp_hdr_rm (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + remove_header(tcp); + modify_field(ipv4.protocol, 0); +// add_to_field(ipv4.totalLen, -20); +// modify_field(ipv4.totalLen, 66); +} + +action modify_tcp_dst_port(dstPort) { + modify_field(tcp.dstPort, dstPort); +} + +action modify_tcp_dst_port_1(dstPort, egress_port) { + modify_field(tcp.dstPort, dstPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ipv4.srcAddr, ipAddr); + modify_field(ethernet.dstAddr, dstAddr); + modify_field(tcp.dstPort, tcpPort); +} + +action custom_action_2(egress_port, ipAddr, tcpPort) +{ + modify_field(ipv4.srcAddr, ipAddr); + modify_field(tcp.dstPort, tcpPort); + hop(ipv4.ttl, egress_port); +} + +action custom_action_3(egress_port, dstAddr, dstIp) +{ + modify_field(ipv4.dstAddr, dstIp); + modify_field(ethernet.dstAddr, dstAddr); + hop(ipv4.ttl, egress_port); +} + +action switching_action_1(egress_port/*, vlan_id */) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + //modify_field(vlan_tag.vlan_id, vlan_id); +} + +table ipv4_routing { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + hop_ipv4; + drop_ipv4; + } +} + +table ipv4_routing_exm_ways_3_pack_5 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + modify_tcp_dst_port_1; + } +} + + +table ipv4_routing_exm_ways_3_pack_3 { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + custom_action_1; + } +} + +table ipv4_routing_exm_ways_4_pack_3_stage_1 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_stage_1 { + reads { + ipv4.dstAddr : lpm; + ipv4.srcAddr : exact; + } + actions { + nop; + hop_ipv4; + } + size : 1024; +} + +table tcam_tbl_stage_2 { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + mod_mac_adr; + } +} + +table ipv4_routing_exm_ways_4_pack_7_stage_2 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + tcp.dstPort : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +table ipv4_routing_exm_ways_3_pack_7_stage_2 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + +table ipv4_routing_exm_ways_5_pack_3_stage_3 { + reads { + ipv4.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table udp_add_tbl_stage_3 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + udp_hdr_add; + } +} + +table ipv4_routing_exm_ways_6_pack_3_stage_4 { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + + +table tcp_rm_tbl_stage_4 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + tcp_hdr_rm; + } +} + +table ipv4_routing_exm_ways_3_pack_4_stage_5 { + reads { + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + modify_tcp_dst_port_1; + } +} + +table switching_exm_ways_3_pack_6_stage_5 { + reads { + ethernet.dstAddr : exact; + vlan_tag.vlan_id : exact; + } + actions { + nop; + switching_action_1; + } +} + +table ipv4_routing_exm_ways_4_pack_4_stage_6 { + reads { + ethernet.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_exm_ways_4_pack_6_stage_6 { + reads { + ethernet.srcAddr : exact; + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_exm_ways_5_pack_4_stage_7 { + reads { + ipv4.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + +table ipv4_routing_exm_ways_5_pack_6_stage_7 { + reads { + ipv4.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +table ipv4_routing_exm_ways_4_pack_5_stage_8 { + reads { + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.srcPort : exact; + tcp.dstPort : exact; + } + actions { + nop; + custom_action_2; + } +} + + +table ipv4_routing_exm_ways_5_pack_5_stage_9 { + reads { + ipv4.dstAddr : exact; + ethernet.srcAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_exm_ways_6_pack_4_stage_9 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +table ipv4_routing_exm_ways_6_pack_5_stage_10 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + custom_action_2; + } +} + +table ipv4_routing_exm_ways_5_pack_7_stage_10 { + reads { + ethernet.srcAddr : exact; + ipv4.dstAddr : exact; + } + actions { + nop; + tcp_hdr_rm; + } +} + +table ipv4_routing_exm_stage_11 { + reads { + ethernet.srcAddr : exact; + ethernet.dstAddr : exact; + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + custom_action_2; + } +} + +table ipv4_routing_exm_ways_6_pack_6_stage_11 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + + +/* Main control flow */ +control ingress { + /* A general principle : Always keep the exact match tables ahead of the + * ternary tables in the same stage, except first stage. Logic relating to next-table + * will cause the Tofino model not to launch a lookup on th exact match + * tables if the order is reversed. + */ + apply(ipv4_routing); + apply(ipv4_routing_exm_ways_3_pack_5); + apply(ipv4_routing_exm_ways_3_pack_3); + apply(ipv4_routing_exm_ways_4_pack_3_stage_1); + apply(ipv4_routing_stage_1); + apply(tcam_tbl_stage_2); + apply(ipv4_routing_exm_ways_4_pack_7_stage_2); + apply(ipv4_routing_exm_ways_3_pack_7_stage_2); + apply(ipv4_routing_exm_ways_5_pack_3_stage_3); + /* Gateway not yet supported */ +// if (ipv4.protocol == 0) { + apply(udp_add_tbl_stage_3); +// } + apply(ipv4_routing_exm_ways_6_pack_3_stage_4); +// if (valid(tcp)) { + apply(tcp_rm_tbl_stage_4); +// } + apply(ipv4_routing_exm_ways_3_pack_4_stage_5); + apply(switching_exm_ways_3_pack_6_stage_5); + apply(ipv4_routing_exm_ways_4_pack_4_stage_6); + apply(ipv4_routing_exm_ways_4_pack_6_stage_6); + apply(ipv4_routing_exm_ways_5_pack_4_stage_7); + apply(ipv4_routing_exm_ways_5_pack_6_stage_7); + apply(ipv4_routing_exm_ways_4_pack_5_stage_8); + apply(ipv4_routing_exm_ways_5_pack_5_stage_9); + apply(ipv4_routing_exm_ways_6_pack_5_stage_10); + //apply(ipv4_routing_exm_ways_6_pack_6_stage_11); + //apply(ipv4_routing_exm_stage_11); + //apply(ipv4_routing_exm_ways_6_pack_4_stage_9); +} + +action eg_drop() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); + modify_field(eg_intr_md.egress_port, 0); +} + +action permit() { +} + +table egress_acl { + reads { + routing_metadata.drop: ternary; + } + actions { + permit; + eg_drop; + } +} + +table exm_5ways_7Entries { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + +control egress { +// apply(egress_acl); + apply(exm_5ways_7Entries); +} diff --git a/backends/tofino/bf-asm/test/internal/dileep7-b.p4 b/backends/tofino/bf-asm/test/internal/dileep7-b.p4 new file mode 100644 index 00000000000..13985acb68b --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/dileep7-b.p4 @@ -0,0 +1,577 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm: csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop_ipv4(egress_port /*,srcmac, dstmac*/) { + hop(ipv4.ttl, egress_port); +// modify_field(ethernet.srcAddr, srcmac); +// modify_field(ethernet.dstAddr, dstmac); +} + +action drop_ipv4 () { + drop(); +} + +action next_hop_ipv4(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action ig_drop() { +// modify_field(routing_metadata.drop, 1); + add_to_field(ipv4.ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); +} + +action mod_mac_addr(egress_port, srcmac, dstmac) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action udp_hdr_add (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + add_header(udp); + modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); + add_to_field(ipv4.totalLen, 8); +} + +action tcp_hdr_rm (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + remove_header(tcp); + modify_field(ipv4.protocol, 0); +// add_to_field(ipv4.totalLen, -20); +// modify_field(ipv4.totalLen, 66); +} + +action modify_tcp_dst_port(dstPort) { + modify_field(tcp.dstPort, dstPort); +} + +action modify_tcp_dst_port_1(dstPort, egress_port) { + modify_field(tcp.dstPort, dstPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ipv4.srcAddr, ipAddr); + modify_field(ethernet.dstAddr, dstAddr); + modify_field(tcp.dstPort, tcpPort); +} + +action custom_action_2(egress_port, ipAddr, tcpPort) +{ + modify_field(ipv4.srcAddr, ipAddr); + modify_field(tcp.dstPort, tcpPort); + hop(ipv4.ttl, egress_port); +} + +action custom_action_3(egress_port, dstAddr, dstIp) +{ + modify_field(ipv4.dstAddr, dstIp); + modify_field(ethernet.dstAddr, dstAddr); + hop(ipv4.ttl, egress_port); +} + +action switching_action_1(egress_port/*, vlan_id */) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + //modify_field(vlan_tag.vlan_id, vlan_id); +} + +@pragma stage 0 +@pragma pack 7 +@pragma ways 5 + +table exm_5ways_7Entries { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + +@pragma pack 8 +@pragma ways 4 + +table exm_4ways_8Entries { + reads { + ipv4.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_3; + } +} + +@pragma ways 5 +@pragma pack 8 + +table exm_5ways_8Entries { + reads { + tcp.dstPort : exact; + } + actions { + nop; + tcp_hdr_rm; + } +} + +@pragma ways 3 +@pragma pack 1 + +table exm_3ways_1Entries { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma ways 4 +@pragma pack 1 + +table exm_4ways_1Entries { + reads { + ipv4.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + custom_action_2; + } +} + + +@pragma ways 6 +@pragma pack 7 + +table exm_6ways_7Entries_stage_1 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma ways 3 +@pragma pack 8 + +table exm_3ways_8Entries_stage_1 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + custom_action_2; + } +} + + + +@pragma ways 6 +@pragma pack 8 + +table exm_6ways_8Entries_stage_2 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + mod_mac_addr; + } +} + +@pragma pack 4 +@pragma ways 2 + +table exm_2ways_4Entries_stage_2 { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 5 +@pragma ways 2 + +table exm_2ways_5Entries_stage_2 { + reads { + tcp.srcPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +@pragma pack 6 +@pragma ways 2 + +table exm_2ways_6Entries_stage_2 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + +@pragma pack 1 +@pragma ways 5 + +table exm_5ways_1Entries_stage_2 { + reads { + ethernet.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_3; + } +} + +@pragma pack 1 +@pragma ways 6 + +table exm_6ways_1Entries_stage_2 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + tcp.dstPort : exact; + tcp.srcPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 7 +@pragma ways 2 + +table exm_2ways_7Entries_stage_3 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 8 +@pragma ways 2 + +table exm_2ways_8Entries_stage_3 { + reads { + tcp.dstPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 1 +@pragma ways 6 + +table exm_6ways_1Entries_stage_3 { + reads { + ethernet.dstAddr : exact; + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 2 +@pragma ways 3 + +table exm_3ways_2Entries_stage_3 { + reads { + ipv4.srcAddr : exact; + ipv4.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 2 +@pragma ways 4 + +table exm_4ways_2Entries_stage_4 { + reads { + ipv4.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 2 +@pragma ways 5 + +table exm_5ways_2Entries_stage_4 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + custom_action_3; + } +} + +@pragma pack 2 +@pragma ways 6 + +table exm_6ways_2Entries_stage_4 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + custom_action_2; + } +} + + +/* Main control flow */ +control ingress { + /* A general principle : Always keep the exact match tables ahead of the + * ternary tables in the same stage, except first stage. Logic relating to next-table + * will cause the Tofino model not to launch a lookup on th exact match + * tables if the order is reversed. + */ +/* + apply(exm_5ways_7Entries); + //apply(exm_4ways_8Entries); + apply(exm_5ways_8Entries); + apply(exm_3ways_1Entries); + apply(exm_4ways_1Entries); + apply(exm_6ways_7Entries_stage_1); + apply(exm_3ways_8Entries_stage_1); + apply(exm_6ways_8Entries_stage_2); + apply(exm_2ways_4Entries_stage_2); + apply(exm_2ways_5Entries_stage_2); + apply(exm_2ways_6Entries_stage_2); +*/ + apply(exm_5ways_1Entries_stage_2); +/* + apply(exm_2ways_7Entries_stage_3); + //apply(exm_2ways_8Entries_stage_3); + apply(exm_6ways_1Entries_stage_3); + apply(exm_3ways_2Entries_stage_3); + apply(exm_4ways_2Entries_stage_4); + apply(exm_5ways_2Entries_stage_4); + apply(exm_6ways_2Entries_stage_4); +*/ +} + +action eg_drop() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); + modify_field(eg_intr_md.egress_port, 0); +} + +action permit() { +} + +table egress_acl { + reads { + routing_metadata.drop: ternary; + } + actions { + permit; + eg_drop; + } +} + +control egress { +// apply(egress_acl); +} diff --git a/backends/tofino/bf-asm/test/internal/dileep7.PRAGMA b/backends/tofino/bf-asm/test/internal/dileep7.PRAGMA new file mode 100644 index 00000000000..d82e658d9fe --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/dileep7.PRAGMA @@ -0,0 +1,573 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm: csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop_ipv4(egress_port /*,srcmac, dstmac*/) { + hop(ipv4.ttl, egress_port); +// modify_field(ethernet.srcAddr, srcmac); +// modify_field(ethernet.dstAddr, dstmac); +} + +action drop_ipv4 () { + drop(); +} + +action next_hop_ipv4(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action ig_drop() { +// modify_field(routing_metadata.drop, 1); + add_to_field(ipv4.ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); +} + +action mod_mac_addr(egress_port, srcmac, dstmac) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action udp_hdr_add (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + add_header(udp); + modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); + add_to_field(ipv4.totalLen, 8); +} + +action tcp_hdr_rm (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + remove_header(tcp); + modify_field(ipv4.protocol, 0); +// add_to_field(ipv4.totalLen, -20); +// modify_field(ipv4.totalLen, 66); +} + +action modify_tcp_dst_port(dstPort) { + modify_field(tcp.dstPort, dstPort); +} + +action modify_tcp_dst_port_1(dstPort, egress_port) { + modify_field(tcp.dstPort, dstPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ipv4.srcAddr, ipAddr); + modify_field(ethernet.dstAddr, dstAddr); + modify_field(tcp.dstPort, tcpPort); +} + +action custom_action_2(egress_port, ipAddr, tcpPort) +{ + modify_field(ipv4.srcAddr, ipAddr); + modify_field(tcp.dstPort, tcpPort); + hop(ipv4.ttl, egress_port); +} + +action custom_action_3(egress_port, dstAddr, dstIp) +{ + modify_field(ipv4.dstAddr, dstIp); + modify_field(ethernet.dstAddr, dstAddr); + hop(ipv4.ttl, egress_port); +} + +action switching_action_1(egress_port/*, vlan_id */) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + //modify_field(vlan_tag.vlan_id, vlan_id); +} + +@pragma stage 0 +@pragma pack 7 +@pragma ways 5 + +table exm_5ways_7Entries { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + +@pragma pack 8 +@pragma ways 4 + +table exm_4ways_8Entries { + reads { + ipv4.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_3; + } +} + +@pragma ways 5 +@pragma pack 8 + +table exm_5ways_8Entries { + reads { + tcp.dstPort : exact; + } + actions { + nop; + tcp_hdr_rm; + } +} + +@pragma ways 3 +@pragma pack 1 + +table exm_3ways_1Entries { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma ways 4 +@pragma pack 1 + +table exm_4ways_1Entries { + reads { + ipv4.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + custom_action_2; + } +} + + +@pragma ways 6 +@pragma pack 7 + +table exm_6ways_7Entries_stage_1 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma ways 3 +@pragma pack 8 + +table exm_3ways_8Entries_stage_1 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + custom_action_2; + } +} + + + +@pragma ways 6 +@pragma pack 8 + +table exm_6ways_8Entries_stage_2 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + mod_mac_addr; + } +} + +@pragma pack 4 +@pragma ways 2 + +table exm_2ways_4Entries_stage_2 { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 5 +@pragma ways 2 + +table exm_2ways_5Entries_stage_2 { + reads { + tcp.srcPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +@pragma pack 6 +@pragma ways 2 + +table exm_2ways_6Entries_stage_2 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + +@pragma pack 1 +@pragma ways 5 + +table exm_5ways_1Entries_stage_2 { + reads { + ethernet.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_3; + } +} + +@pragma pack 1 +@pragma ways 6 + +table exm_6ways_1Entries_stage_2 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + tcp.dstPort : exact; + tcp.srcPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 7 +@pragma ways 2 + +table exm_2ways_7Entries_stage_3 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 8 +@pragma ways 2 + +table exm_2ways_8Entries_stage_3 { + reads { + tcp.dstPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 1 +@pragma ways 6 + +table exm_6ways_1Entries_stage_3 { + reads { + ethernet.dstAddr : exact; + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 2 +@pragma ways 3 + +table exm_3ways_2Entries_stage_3 { + reads { + ipv4.srcAddr : exact; + ipv4.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 2 +@pragma ways 4 + +table exm_4ways_2Entries_stage_4 { + reads { + ipv4.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 2 +@pragma ways 5 + +table exm_5ways_2Entries_stage_4 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + custom_action_3; + } +} + +@pragma pack 2 +@pragma ways 6 + +table exm_6ways_2Entries_stage_4 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + custom_action_2; + } +} + + +/* Main control flow */ +control ingress { + /* A general principle : Always keep the exact match tables ahead of the + * ternary tables in the same stage, except first stage. Logic relating to next-table + * will cause the Tofino model not to launch a lookup on th exact match + * tables if the order is reversed. + */ + apply(exm_5ways_7Entries); + //apply(exm_4ways_8Entries); + apply(exm_5ways_8Entries); + apply(exm_3ways_1Entries); + apply(exm_4ways_1Entries); + apply(exm_6ways_7Entries_stage_1); + apply(exm_3ways_8Entries_stage_1); + apply(exm_6ways_8Entries_stage_2); + apply(exm_2ways_4Entries_stage_2); + apply(exm_2ways_5Entries_stage_2); + apply(exm_2ways_6Entries_stage_2); + apply(exm_5ways_1Entries_stage_2); + apply(exm_2ways_7Entries_stage_3); + //apply(exm_2ways_8Entries_stage_3); + apply(exm_6ways_1Entries_stage_3); + apply(exm_3ways_2Entries_stage_3); + apply(exm_4ways_2Entries_stage_4); + apply(exm_5ways_2Entries_stage_4); + apply(exm_6ways_2Entries_stage_4); +} + +action eg_drop() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); + modify_field(eg_intr_md.egress_port, 0); +} + +action permit() { +} + +table egress_acl { + reads { + routing_metadata.drop: ternary; + } + actions { + permit; + eg_drop; + } +} + +control egress { +// apply(egress_acl); +} diff --git a/backends/tofino/bf-asm/test/internal/dileep8.p4 b/backends/tofino/bf-asm/test/internal/dileep8.p4 new file mode 100644 index 00000000000..b6f5b75530f --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/dileep8.p4 @@ -0,0 +1,593 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm: csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop_ipv4(egress_port /*,srcmac, dstmac*/) { + hop(ipv4.ttl, egress_port); +// modify_field(ethernet.srcAddr, srcmac); +// modify_field(ethernet.dstAddr, dstmac); +} + +action drop_ipv4 () { + drop(); +} + +action next_hop_ipv4(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action ig_drop() { +// modify_field(routing_metadata.drop, 1); + add_to_field(ipv4.ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); +} + +action mod_mac_addr(egress_port, srcmac, dstmac) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action udp_hdr_add (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + add_header(udp); + modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); + add_to_field(ipv4.totalLen, 8); +} + +action tcp_hdr_rm (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + remove_header(tcp); + modify_field(ipv4.protocol, 0); +// add_to_field(ipv4.totalLen, -20); +// modify_field(ipv4.totalLen, 66); +} + +action modify_tcp_dst_port(dstPort) { + modify_field(tcp.dstPort, dstPort); +} + +action modify_tcp_dst_port_1(dstPort, egress_port) { + modify_field(tcp.dstPort, dstPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ipv4.srcAddr, ipAddr); + modify_field(ethernet.dstAddr, dstAddr); + modify_field(tcp.dstPort, tcpPort); +} + +action custom_action_2(egress_port, ipAddr, tcpPort) +{ + modify_field(ipv4.srcAddr, ipAddr); + modify_field(tcp.dstPort, tcpPort); + hop(ipv4.ttl, egress_port); +} + +action custom_action_3(egress_port, dstAddr, dstIp) +{ + modify_field(ipv4.dstAddr, dstIp); + modify_field(ethernet.dstAddr, dstAddr); + hop(ipv4.ttl, egress_port); +} + +action switching_action_1(egress_port/*, vlan_id */) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + //modify_field(vlan_tag.vlan_id, vlan_id); +} + +@pragma stage 0 +@pragma pack 7 +@pragma ways 5 + +table exm_5ways_7Entries { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + +@pragma pack 8 +@pragma ways 4 + +table exm_4ways_8Entries { + reads { + ipv4.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_3; + } +} + +@pragma ways 5 +@pragma pack 8 + +table exm_5ways_8Entries { + reads { + tcp.dstPort : exact; + } + actions { + nop; + tcp_hdr_rm; + } +} + +@pragma ways 3 +@pragma pack 1 + +table exm_3ways_1Entries { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma ways 4 +@pragma pack 1 + +table exm_4ways_1Entries { + reads { + ipv4.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + custom_action_2; + } +} + + +@pragma ways 6 +@pragma pack 7 + +table exm_6ways_7Entries_stage_1 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma ways 3 +@pragma pack 8 + +table exm_3ways_8Entries_stage_1 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + custom_action_2; + } +} + + + +@pragma ways 5 //Not enough memory to allocate all action entries +@pragma pack 8 + +table exm_6ways_8Entries_stage_2 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + mod_mac_addr; + } +} + + + + + +@pragma pack 1 +@pragma ways 6 + +table exm_6ways_1Entries_stage_2 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + tcp.dstPort : exact; + tcp.srcPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 7 +@pragma ways 2 + +table exm_2ways_7Entries_stage_3 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 8 +@pragma ways 2 + +table exm_2ways_8Entries_stage_3 { + reads { + tcp.dstPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 1 +@pragma ways 6 + +table exm_6ways_1Entries_stage_3 { + reads { + ethernet.dstAddr : exact; + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 2 +@pragma ways 3 + +table exm_3ways_2Entries_stage_3 { + reads { + ipv4.srcAddr : exact; + ipv4.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 2 +@pragma ways 4 + +table exm_4ways_2Entries_stage_4 { + reads { + ipv4.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 2 +@pragma ways 5 + +table exm_5ways_2Entries_stage_4 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + custom_action_3; + } +} + +@pragma pack 2 +@pragma ways 6 + +table exm_6ways_2Entries_stage_4 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + custom_action_2; + } +} + +@pragma pack 4 +@pragma ways 2 + +table exm_2ways_4Entries_stage_5 { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 5 +@pragma ways 2 + +table exm_2ways_5Entries_stage_5 { + reads { + tcp.srcPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +@pragma ways 4 + +table exm_4ways_16k_stage_5 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } + + size : 16384; +} + +@pragma pack 6 +@pragma ways 2 + +table exm_2ways_6Entries_stage_6 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + +@pragma pack 1 +@pragma ways 5 +table exm_5ways_1Entries_stage_6 { + reads { + ethernet.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_3; + } +} + +/* Main control flow */ +control ingress { + /* A general principle : Always keep the exact match tables ahead of the + * ternary tables in the same stage, except first stage. Logic relating to next-table + * will cause the Tofino model not to launch a lookup on th exact match + * tables if the order is reversed. + */ + apply(exm_5ways_7Entries); + //apply(exm_4ways_8Entries); + //apply(exm_5ways_8Entries); + apply(exm_3ways_1Entries); + apply(exm_4ways_1Entries); + apply(exm_6ways_7Entries_stage_1); + //apply(exm_3ways_8Entries_stage_1); + apply(exm_6ways_8Entries_stage_2); + apply(exm_2ways_7Entries_stage_3); + //apply(exm_2ways_8Entries_stage_3); + apply(exm_6ways_1Entries_stage_3); + apply(exm_3ways_2Entries_stage_3); + apply(exm_4ways_2Entries_stage_4); + apply(exm_5ways_2Entries_stage_4); + apply(exm_6ways_2Entries_stage_4); + //apply(exm_2ways_4Entries_stage_5); + //apply(exm_2ways_5Entries_stage_5); + apply(exm_4ways_16k_stage_5); + //apply(exm_2ways_6Entries_stage_6); + //apply(exm_5ways_1Entries_stage_6); +} + +action eg_drop() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); + modify_field(eg_intr_md.egress_port, 0); +} + +action permit() { +} + +table egress_acl { + reads { + routing_metadata.drop: ternary; + } + actions { + permit; + eg_drop; + } +} + +control egress { +// apply(egress_acl); +} diff --git a/backends/tofino/bf-asm/test/internal/dileep9.PRAGMA b/backends/tofino/bf-asm/test/internal/dileep9.PRAGMA new file mode 100644 index 00000000000..f5c1c60f086 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/dileep9.PRAGMA @@ -0,0 +1,188 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm: csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action custom_action_3(egress_port, dstAddr, dstIp) +{ + modify_field(ipv4.dstAddr, dstIp); + modify_field(ethernet.dstAddr, dstAddr); + hop(ipv4.ttl, egress_port); +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + + +@pragma stage 0 +@pragma pack 7 +@pragma ways 5 +table exm_5ways_7Entries { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + custom_action_3; + } + size : 35840; +} + +control ingress { + /* A general principle : Always keep the exact match tables ahead of the + * ternary tables in the same stage, except first stage. Logic relating to next-table + * will cause the Tofino model not to launch a lookup on th exact match + * tables if the order is reversed. + */ + apply(exm_5ways_7Entries); +} diff --git a/backends/tofino/bf-asm/test/internal/google-tor/lag.p4 b/backends/tofino/bf-asm/test/internal/google-tor/lag.p4 new file mode 100644 index 00000000000..da634c3fa59 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/google-tor/lag.p4 @@ -0,0 +1,48 @@ +// lag.p4 + +//----------------------------------- +// LAG egress port selection +//----------------------------------- + +action set_lag_egress_port(port) { + modify_field(standard_metadata.egress_spec, port); +} + +field_list lag_hash_fields { + ethernet.dstAddr; + ethernet.srcAddr; + ethernet.etherType; + standard_metadata.ingress_port; +} + +field_list_calculation lag_hash { + input { + lag_hash_fields; + } + algorithm : crc16; + output_width : 14; +} + +action_selector lag_selector { + selection_key : lag_hash; + selection_mode : fair; +} + +action_profile lag_action_profile { + actions { + set_lag_egress_port; + } + dynamic_action_selection: lag_selector; +} + +table lag_resolve_table { + reads { + standard_metadata.egress_spec: exact; + } + action_profile: lag_action_profile; +} + +control lag_handling { + apply(lag_resolve_table); +} + diff --git a/backends/tofino/bf-asm/test/internal/google-tor/tor.p4 b/backends/tofino/bf-asm/test/internal/google-tor/tor.p4 new file mode 100644 index 00000000000..9cdbb026840 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/google-tor/tor.p4 @@ -0,0 +1,672 @@ +// Copyright (c) 2016, Google Inc. +// +// P4 specification for a ToR (top-of-rack) switch. +// Status: WORK IN PROGRESS +// Note: This code has not been tested and is expected to contain bugs. + +//------------------------------------------------------------------------------ +// Global defines +//------------------------------------------------------------------------------ + +#define CPU_PORT 64 +#define INITIAL_CPU_PACKET_OFFSET 64 + +#define ARP_REASON 1 + +#define ETHERTYPE_VLAN 0x8100, 0x9100, 0x9200, 0x9300 +#define ETHERTYPE_IPV4 0x0800 +#define ETHERTYPE_IPV6 0x86dd +#define ETHERTYPE_ARP 0x0806 +#define ETHERTYPE_ND 0x6007 +#define ETHERTYPE_LLDP 0x88CC + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 +#define IP_PROTOCOLS_ICMP 1 +#define IP_PROTOCOLS_ICMPv6 58 + +#define DEFAULT_VRF0 0 + +#define L2_VLAN 4050 +#define VLAN_DEPTH 2 + +#define CPU_MIRROR_SESSION_ID 1024 + +#define PORT_COUNT 256 + +#ifdef P4_EXPLICIT_LAG +#include "lag.p4" +#endif + +//------------------------------------------------------------------------------ +// Protocol Header Definitions +//------------------------------------------------------------------------------ + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_base_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr : 32; + } +} + +// Fixed ipv6 header +header_type ipv6_base_t { + fields { + version : 4; + traffic_class : 8; + flowLabel : 20; + payloadLength : 16; + nextHeader : 8; + hopLimit : 8; + srcAddr : 128; + dstAddr : 128; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 4; + flags : 8; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +// Same for both ip v4 and v6 +header_type icmp_header_t { + fields { + icmpType: 8; + code: 8; + checksum: 16; + } +} + +header_type vlan_tag_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + +header_type arp_t { + fields { + hwType : 16; + protoType : 16; + hwAddrLen : 8; + protoAddrLen : 8; + opcode : 16; + hwSrcAddr : 48; + protoSrcAddr : 32; + hwDstAddr : 48; + protoDstAddr : 32; + } +} + +//------------------------------------------------------------------------------ +// Internal Header Definitions +//------------------------------------------------------------------------------ + +header_type cpu_header_t { + fields { + zeros : 64; + reason : 16; + port : 32; + } +} + +//------------------------------------------------------------------------------ +// Metadata Header and Field List Definitions +//------------------------------------------------------------------------------ + +// Local meta-data for each packet being processed. +header_type local_metadata_t { + fields { + vrf_id : 32; + class_id: 8; // Dst traffic class ID (IPSP) + qid: 5; // CPU COS queue ID + ingress_meter_index: 16; // per-port ingress rate-limiting (IPSP) + color: 2; + l4SrcPort: 16; + l4DstPort: 16; + icmp_code: 8; + reason: 8; // Reason to drop to CPU + src_mac: 48; + } +} + +// Field List for packets destined to CPU. +field_list cpu_info { + local_metadata.reason; + standard_metadata.ingress_port; +} + +//------------------------------------------------------------------------------ +// Headers and Metadata Declarations +//------------------------------------------------------------------------------ + +header ethernet_t ethernet; +header ipv4_base_t ipv4_base; +header ipv6_base_t ipv6_base; +header icmp_header_t icmp_header; +header tcp_t tcp; +header udp_t udp; +header vlan_tag_t vlan_tag[VLAN_DEPTH]; +header arp_t arp; + +header cpu_header_t cpu_header; + +metadata local_metadata_t local_metadata; + +//------------------------------------------------------------------------------ +// Parsers +//------------------------------------------------------------------------------ + +// Start with ethernet always. +parser start { + return select(current(0, INITIAL_CPU_PACKET_OFFSET)) { + 0 : parse_cpu_header; + default: parse_ethernet; + } +} + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + ETHERTYPE_VLAN: parse_vlan; + ETHERTYPE_IPV4: parse_ipv4; + ETHERTYPE_IPV6: parse_ipv6; + ETHERTYPE_ARP: parse_arp; + default: ingress; + } +} + +parser parse_vlan { + extract(vlan_tag[next]); + return select(latest.etherType) { + ETHERTYPE_VLAN : parse_vlan; + ETHERTYPE_IPV4 : parse_ipv4; + ETHERTYPE_IPV6 : parse_ipv6; + default: ingress; + } +} + +parser parse_ipv4 { + extract(ipv4_base); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_ICMP : parse_icmp; + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +parser parse_ipv6 { + extract(ipv6_base); + return select(ipv6_base.nextHeader) { + IP_PROTOCOLS_ICMPv6: parse_icmp; + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +parser parse_tcp { + extract(tcp); + // Normalize TCP port metadata to common port metadata + set_metadata(local_metadata.l4SrcPort, latest.srcPort); + set_metadata(local_metadata.l4DstPort, latest.dstPort); + return ingress; +} + +parser parse_udp { + extract(udp); + // Normalize UDP port metadata to common port metadata + set_metadata(local_metadata.l4SrcPort, latest.srcPort); + set_metadata(local_metadata.l4DstPort, latest.dstPort); + return ingress; +} + +parser parse_icmp { + extract(icmp_header); + return ingress; +} + +parser parse_arp { + extract(arp); + return ingress; +} + +parser parse_cpu_header { + extract(cpu_header); + return parse_ethernet; +} + +//------------------------------------------------------------------------------ +// Actions +//------------------------------------------------------------------------------ + +// Do nothing action. +action nop() { +} + +// Drops the packet. +action drop_packet() { + drop(); +} + +// TODO(wmohsin): Confirm this use-case. +// Sets the ’special' L2 Vlan that we allow (every other L2 packet forwarding is +// disabled). +action set_l2_vlan() { + modify_field(vlan_tag[0].vid, L2_VLAN); + modify_field(vlan_tag[0].etherType, 0x8100); +} + +action set_class_id(class_id) { + modify_field(local_metadata.class_id, class_id); +} + +action set_vrf(vrf_id) { + modify_field(local_metadata.vrf_id, vrf_id); +} + +action set_ecmp_nexthop_info_port(port, smac, dmac) { + modify_field(standard_metadata.egress_spec, port); + modify_field(ethernet.srcAddr, smac); + modify_field(ethernet.dstAddr, dmac); +} + +//----------------------------------- +// Send/Copy to CPU in a given queue +//----------------------------------- + +action set_queue_and_copy_to_cpu(qid, reason) { + modify_field(local_metadata.qid, qid); + modify_field(local_metadata.reason, reason); + clone_ingress_pkt_to_egress(CPU_MIRROR_SESSION_ID, cpu_info); +} + +action set_queue_and_send_to_cpu(qid, reason) { + modify_field(local_metadata.qid, qid); + add_header(cpu_header); + modify_field(cpu_header.reason, reason); + modify_field(cpu_header.port, standard_metadata.ingress_port); + modify_field(standard_metadata.egress_spec, CPU_PORT); +} + +//------------------------------------------------------------------------------ +// Receive from CPU +//------------------------------------------------------------------------------ + +action set_egress_port_and_decap_cpu_header() { + modify_field(standard_metadata.egress_spec, cpu_header.port); + remove_header(cpu_header); +} + +action meter_packet(meter_index) { + modify_field(local_metadata.ingress_meter_index, meter_index); + execute_meter(ingress_port_meter, meter_index, local_metadata.color); +} + +action meter_deny() { + drop(); +} + +action meter_permit() { +} + +//------------------------------------------------------------------------------ +// Tables and Control Flows +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Packet Classification +//------------------------------------------------------------------------------ + +table class_id_assignment_table { + reads { + ethernet.etherType: exact; + + ipv4_base.ttl: ternary; + ipv6_base.hopLimit: ternary; + ipv4_base.dstAddr: ternary; + ipv6_base.dstAddr: ternary; + ipv4_base.protocol: exact; + ipv6_base.nextHeader: exact; + + local_metadata.l4SrcPort: exact; + local_metadata.l4DstPort: exact; + + vlan_tag[0].vid: exact; + vlan_tag[0].pcp: exact; + } + actions { + set_class_id; + } + default_action: set_class_id(0); +} + +//----------------------------------- +// Map traffic to a particular VRF +//----------------------------------- + +table vrf_classifier_table { + reads { + ethernet.etherType : exact; + ethernet.srcAddr : exact; + ethernet.dstAddr : exact; + standard_metadata.ingress_port: exact; + } + actions { + set_vrf; + } + default_action: set_vrf(DEFAULT_VRF0); +} + +//------------------------------------------------------------------------------ +// L3 Routing (My MAC check) +//------------------------------------------------------------------------------ + +// Drops packets that do not need to be part of L3 forwarding. +// Equivalent of BCM MY_STATION table ? +table l3_routing_classifier_table { + reads { + ethernet.dstAddr : exact; + } + actions { + nop; + drop_packet; + } + default_action: drop_packet(); +} + +//------------------------------------------------------------------------------ +// IPv4 and IPv6 L3 Forwarding +//------------------------------------------------------------------------------ + +//----------------------------------- +// IPv4 L3 Forwarding +//----------------------------------- + +table l3_ipv4_override_table { + reads { + ipv4_base.dstAddr : lpm; + } + action_profile: ecmp_action_profile; +} + +table l3_ipv4_vrf_table { + reads { + local_metadata.vrf_id: exact; + ipv4_base.dstAddr : lpm; + } + action_profile: ecmp_action_profile; +} + +table l3_ipv4_fallback_table { + reads { + ipv4_base.dstAddr : lpm; + } + action_profile: ecmp_action_profile; +} + +// LPM forwarding for IPV4 packets. +control ingress_ipv4_l3_forwarding { + apply(l3_ipv4_override_table) { + miss { + apply(l3_ipv4_vrf_table) { + miss { + apply(l3_ipv4_fallback_table); + } + } + } + } +} + +//----------------------------------- +// IPv6 L3 Forwarding +//----------------------------------- + +table l3_ipv6_override_table { + reads { + ipv6_base.dstAddr : lpm; + } + action_profile: ecmp_action_profile; +} + +table l3_ipv6_vrf_table { + reads { + local_metadata.vrf_id: exact; + ipv6_base.dstAddr : lpm; + } + action_profile: ecmp_action_profile; +} + +table l3_ipv6_fallback_table { + reads { + ipv6_base.dstAddr : lpm; + } + action_profile: ecmp_action_profile; +} + + +//----------------------------------- +// L3 ECMP nexthop selection +//----------------------------------- + +field_list l3_ip_hash_fields { + ipv6_base.dstAddr; + ipv6_base.srcAddr; + ipv6_base.flowLabel; + ipv4_base.dstAddr; + ipv4_base.srcAddr; + ipv4_base.protocol; + local_metadata.l4SrcPort; + local_metadata.l4DstPort; +} + +field_list_calculation ecmp_hash { + input { + l3_ip_hash_fields; + } + algorithm : crc16; + output_width : 14; +} + +action_selector ecmp_selector { + selection_key : ecmp_hash; + selection_mode : fair; +} + +action_profile ecmp_action_profile { + actions { + set_ecmp_nexthop_info_port; + } + dynamic_action_selection: ecmp_selector; +} + +// LPM forwarding for IPV6 packets. +control ingress_ipv6_l3_forwarding { + apply(l3_ipv6_override_table) { + miss { + apply(l3_ipv6_vrf_table) { + miss { + apply(l3_ipv6_fallback_table); + } + } + } + } +} + +//----------------------------------- +// IPv4/v6 L3 Forwarding +//----------------------------------- + +// Controls LPM forwarding. +control ingress_lpm_forwarding { + if (valid(ipv4_base)) { + ingress_ipv4_l3_forwarding(); + } else { + if (valid(ipv6_base)) { + ingress_ipv6_l3_forwarding(); + } + } +#ifdef P4_EXPLICIT_LAG + lag_handling(); +#endif +} + +// Combined punt table. +// TODO(wmohsin): target_egress_port in punted packet-io. +table punt_table { + reads { + standard_metadata.ingress_port: ternary; + standard_metadata.egress_spec: ternary; + + ethernet.etherType: ternary; + + ipv4_base: valid; + ipv6_base: valid; + ipv4_base.diffserv: ternary; + ipv6_base.traffic_class: ternary; + ipv4_base.ttl: ternary; + ipv6_base.hopLimit: ternary; + ipv4_base.srcAddr: ternary; + ipv4_base.dstAddr: ternary; + ipv6_base.srcAddr: ternary; + ipv6_base.dstAddr: ternary; + ipv4_base.protocol: ternary; + ipv6_base.nextHeader: ternary; + + arp.protoDstAddr: ternary; + local_metadata.icmp_code: ternary; + + vlan_tag[0].vid: ternary; + vlan_tag[0].pcp: ternary; + + local_metadata.class_id: ternary; + local_metadata.vrf_id: ternary; + } + actions { + set_queue_and_copy_to_cpu; + set_queue_and_send_to_cpu; + } +} + +table process_cpu_header { + actions { + set_egress_port_and_decap_cpu_header; + } + default_action: set_egress_port_and_decap_cpu_header(); +} + +//------------------------------------------------------------------------------ +// Meters +//------------------------------------------------------------------------------ + +// TODO(wmohsin): Evaluate this being direct: ingress_port_meter_table +meter ingress_port_meter { + type : bytes; + instance_count : PORT_COUNT; +} + +// Per-port ingress packet rate limiting. +table ingress_port_meter_table { + reads { + standard_metadata.ingress_port: exact; + standard_metadata.egress_spec: exact; + ethernet.etherType: exact; + ipv4_base.dstAddr: ternary; + arp.protoDstAddr: ternary; + local_metadata.class_id: exact; + } + actions { + meter_packet; + } +} + +//----------------------------------- +// Meter Stats +//----------------------------------- + +counter meter_stats { + type : packets; + direct : ingress_port_meter_policy_table; +} + +table ingress_port_meter_policy_table { + reads { + local_metadata.color : exact; + local_metadata.ingress_meter_index : exact; + } + + actions { + meter_permit; + meter_deny; + } +} + +//----------------------------------- +// Meter Control Flow +//----------------------------------- + +control process_punt_packets { + apply(punt_table); + apply(ingress_port_meter_table) { + hit { + apply(ingress_port_meter_policy_table); + } + } +} + +control ingress { + if (valid(cpu_header)) { + apply(process_cpu_header); + } else { + apply(class_id_assignment_table); + apply(vrf_classifier_table); + apply(l3_routing_classifier_table); + ingress_lpm_forwarding(); + process_punt_packets(); + } +} + +control egress { +} + diff --git a/backends/tofino/bf-asm/test/internal/test_7_storm_control.p4 b/backends/tofino/bf-asm/test/internal/test_7_storm_control.p4 new file mode 100644 index 00000000000..d7f8aa6c6fd --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_7_storm_control.p4 @@ -0,0 +1,140 @@ + + +header_type ingress_metadata_t { + fields { + bd : 16; + vrf : 12; + v6_vrf : 12; + ipv4_term : 1; + ipv6_term : 1; + igmp_snoop : 1; + tunnel_term : 1; + tunnel_vni : 32; + ing_meter : 16; + i_lif : 16; + i_tunnel_lif : 16; + o_lif : 16; + if_acl_label : 16; + + route_acl_label : 16; + + bd_flags : 16; + stp_instance : 8; + route : 1; + inner_route : 1; + l2_miss : 1; + l3_lpm_miss : 1; + mc_index : 16; + inner_mc_index : 16; + nhop : 16; + ecmp_index : 10; + + ecmp_offset : 14; + + nsh_value : 16; + lag_index : 8; + + lag_port : 15; + lag_offset : 14; + + flood : 1; + learn_type : 1; + learn_mac : 48; + learn_ipv4 : 32; + mcast_drop : 1; + drop_2 : 1; + drop_1 : 1; + drop_0 : 1; + drop_reason : 8; + copy_to_cpu : 1; + mirror_sesion_id: 10; + urpf : 1; + urpf_mode: 2; + urpf_strict: 16; + ingress_bypass: 1; + ipv4_dstaddr_24b: 24; + nhop_index: 16; + + if_drop : 1; + route_drop : 1; + + ipv4_dest : 32; + eth_dstAddr : 48; + eth_srcAddr : 48; + ipv4_ttl : 8; + dcsp : 3; + buffer_qos : 3; + ip_srcPort : 16; + ip_dstPort : 16; + + + mcast_pkt : 1; + inner_mcast_pkt : 1; + + if_copy_to_cpu : 1; + if_nhop : 16; + if_port : 9; + if_ecmp_index : 10; + if_lag_index : 8; + route_copy_to_cpu : 1; + route_nhop : 16; + route_port : 9; + route_ecmp_index : 10; + route_lag_index : 8; + + tun_type : 8; + nat_enable : 1; + + nat_source_index : 13; + nat_dest_index : 13; + + } +} + + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header ethernet_t ethernet; +metadata ingress_metadata_t ingress_metadata; + +parser start { + return parse_ethernet; +} + +parser parse_ethernet { + extract(ethernet); + return ingress; +} + + + +action no_action(){ + no_op(); +} + +action ing_meter_set(meter_) { + modify_field(ingress_metadata.ing_meter, meter_); +} + +table storm_control { + reads { + ingress_metadata.bd : exact; + ethernet.dstAddr : ternary; + } + actions { + no_action; + ing_meter_set; + } + size : 8192; +} + + +control ingress { + apply(storm_control); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_100_hash_action.p4 b/backends/tofino/bf-asm/test/internal/test_config_100_hash_action.p4 new file mode 100644 index 00000000000..470d9e08ab9 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_100_hash_action.p4 @@ -0,0 +1,105 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + color_0 : 8; + } +} + +header_type meta_t { + fields { + field_17 : 17; + pad_15 : 15; + } +} + +parser start { + return parse_pkt; +} + +header pkt_t pkt; +metadata meta_t meta; + +parser parse_pkt { + extract(pkt); + return ingress; +} + + +action action_0(param0){ + modify_field(pkt.field_c_32, param0); +} + +action action_1(param0){ + modify_field(pkt.field_f_16, param0); +} + +action action_2(){ + count(simple_stats, meta.field_17); +} + +action do_nothing(){ + no_op(); +} + +counter simple_stats { + type : packets; + instance_count : 32768; +} + +@pragma action_default_only do_nothing +table table_0 { + reads { + pkt.field_i_8 : exact; + } + actions { + do_nothing; + action_0; + } + size : 256; +} + +@pragma include_idletime 1 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 1 +table table_1 { + reads { + pkt.field_g_16 : exact; + } + actions { + action_1; + } + size : 65536; +} + +table table_2 { + actions { + action_2; + } +} + +/* Main control flow */ + +control ingress { + if (valid(pkt)){ + apply(table_0); + apply(table_1); + apply(table_2); + } +} + + diff --git a/backends/tofino/bf-asm/test/internal/test_config_101_switch_msdc.p4 b/backends/tofino/bf-asm/test/internal/test_config_101_switch_msdc.p4 new file mode 100644 index 00000000000..527a1f52667 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_101_switch_msdc.p4 @@ -0,0 +1,3838 @@ +# 1 "p4src/switch.p4" +# 1 "" +# 1 "/usr/include/stdc-predef.h" 1 3 4 +# 1 "" 2 +# 1 "p4src/switch.p4" + +# 1 "/home/john/ws/p4f/submodules/p4c-tofino/p4c_tofino/target/tofino/p4_lib/tofino/intrinsic_metadata.p4" 1 +# 11 "/home/john/ws/p4f/submodules/p4c-tofino/p4c_tofino/target/tofino/p4_lib/tofino/intrinsic_metadata.p4" +header_type ingress_parser_control_signals { + fields { + priority : 3; + } +} + +@pragma not_deparsed ingress +@pragma not_deparsed egress +@pragma pa_gress ingress ig_prsr_ctrl +header ingress_parser_control_signals ig_prsr_ctrl; + + + +header_type ingress_intrinsic_metadata_t { + fields { + + resubmit_flag : 1; + + + _pad1 : 1; + + _pad2 : 2; + + _pad3 : 3; + + ingress_port : 9; + + + ingress_mac_tstamp : 48; + + } +} + +@pragma dont_trim +@pragma not_deparsed ingress +@pragma not_deparsed egress +@pragma pa_gress ingress ig_intr_md +@pragma pa_no_tagalong ingress ig_intr_md.ingress_port +header ingress_intrinsic_metadata_t ig_intr_md; + + + +header_type generator_metadata_t { + fields { + + app_id : 16; + + batch_id: 16; + + instance_id: 16; + } +} + +@pragma not_deparsed ingress +@pragma not_deparsed egress +header generator_metadata_t ig_pg_md; + + + + +header_type ingress_intrinsic_metadata_from_parser_aux_t { + fields { + ingress_global_tstamp : 48; + + + ingress_global_ver : 32; + + + ingress_parser_err : 16; + + } +} + +@pragma pa_fragment ingress ig_intr_md_from_parser_aux.ingress_parser_err +@pragma pa_atomic ingress ig_intr_md_from_parser_aux.ingress_parser_err +@pragma not_deparsed ingress +@pragma not_deparsed egress +@pragma pa_gress ingress ig_intr_md_from_parser_aux +header ingress_intrinsic_metadata_from_parser_aux_t ig_intr_md_from_parser_aux; + + + + +header_type ingress_intrinsic_metadata_for_tm_t { + fields { + + + + + _pad2 : 7; + ucast_egress_port : 9; + + + _pad3 : 7; + bypass_egress : 1; + + + _pad4 : 3; + qid : 5; + + + _pad5 : 7; + deflect_on_drop : 1; + + + + _pad6 : 5; + ingress_cos : 3; + + + + _pad7 : 6; + packet_color : 2; + + + + _pad8 : 7; + copy_to_cpu : 1; + + + _pad9 : 5; + icos_for_copy_to_cpu : 3; + + + + mcast_grp_a : 16; + + + + mcast_grp_b : 16; + + + _pad10 : 3; + level1_mcast_hash : 13; + + + + + + _pad11 : 3; + level2_mcast_hash : 13; + + + + + + level1_exclusion_id : 16; + + + + _pad12 : 7; + level2_exclusion_id : 9; + + + + rid : 16; + + + _pad13 : 7; + disable_ucast_cutthru : 1; + + + _pad14 : 7; + enable_mcast_cutthru : 1; + + } +} + + + + + + +@pragma pa_no_tagalong ingress ig_intr_md_for_tm.mcast_grp_a +@pragma pa_no_tagalong ingress ig_intr_md_for_tm.mcast_grp_b + + +@pragma pa_fragment ingress ig_intr_md_for_tm._pad2 +@pragma pa_atomic ingress ig_intr_md_for_tm.ucast_egress_port +@pragma pa_fragment ingress ig_intr_md_for_tm._pad2 +@pragma pa_fragment ingress ig_intr_md_for_tm._pad3 +@pragma pa_fragment ingress ig_intr_md_for_tm._pad4 +@pragma pa_fragment ingress ig_intr_md_for_tm._pad5 +@pragma pa_fragment ingress ig_intr_md_for_tm._pad6 +@pragma pa_fragment ingress ig_intr_md_for_tm._pad7 +@pragma pa_fragment ingress ig_intr_md_for_tm._pad8 +@pragma pa_fragment ingress ig_intr_md_for_tm._pad9 +@pragma pa_atomic ingress ig_intr_md_for_tm.mcast_grp_a +@pragma pa_fragment ingress ig_intr_md_for_tm.mcast_grp_a +@pragma pa_atomic ingress ig_intr_md_for_tm.mcast_grp_b +@pragma pa_fragment ingress ig_intr_md_for_tm.mcast_grp_b +@pragma pa_atomic ingress ig_intr_md_for_tm.level1_mcast_hash +@pragma pa_fragment ingress ig_intr_md_for_tm._pad10 +@pragma pa_atomic ingress ig_intr_md_for_tm.level2_mcast_hash +@pragma pa_fragment ingress ig_intr_md_for_tm._pad11 +@pragma pa_atomic ingress ig_intr_md_for_tm.level1_exclusion_id +@pragma pa_fragment ingress ig_intr_md_for_tm.level1_exclusion_id +@pragma pa_atomic ingress ig_intr_md_for_tm.level2_exclusion_id +@pragma pa_fragment ingress ig_intr_md_for_tm._pad12 +@pragma pa_atomic ingress ig_intr_md_for_tm.rid +@pragma pa_fragment ingress ig_intr_md_for_tm.rid +@pragma pa_fragment ingress ig_intr_md_for_tm._pad13 +@pragma pa_fragment ingress ig_intr_md_for_tm._pad14 +@pragma not_deparsed ingress +@pragma not_deparsed egress +@pragma pa_gress ingress ig_intr_md_for_tm +header ingress_intrinsic_metadata_for_tm_t ig_intr_md_for_tm; + + +header_type ingress_intrinsic_metadata_for_mirror_buffer_t { + fields { + _pad1 : 6; + ingress_mirror_id : 10; + + + } +} + +@pragma dont_trim +@pragma pa_gress ingress ig_intr_md_for_mb +@pragma pa_atomic ingress ig_intr_md_for_mb.ingress_mirror_id +@pragma pa_no_tagalong ingress ig_intr_md_for_mb.ingress_mirror_id +@pragma not_deparsed ingress +@pragma not_deparsed egress +header ingress_intrinsic_metadata_for_mirror_buffer_t ig_intr_md_for_mb; + + +header_type egress_intrinsic_metadata_t { + fields { + + egress_port : 16; + + + _pad1: 5; + enq_qdepth : 19; + + + _pad2: 6; + enq_congest_stat : 2; + + + enq_tstamp : 32; + + + _pad3: 5; + deq_qdepth : 19; + + + _pad4: 6; + deq_congest_stat : 2; + + + app_pool_congest_stat : 8; + + + + deq_timedelta : 32; + + + egress_rid : 16; + + + _pad5: 7; + egress_rid_first : 1; + + + _pad6: 3; + egress_qid : 5; + + + _pad7: 5; + egress_cos : 3; + + + _pad8: 7; + deflection_flag : 1; + + + pkt_length : 16; + } +} + +@pragma dont_trim +@pragma not_deparsed ingress +@pragma not_deparsed egress +@pragma pa_gress egress eg_intr_md +@pragma pa_no_tagalong egress eg_intr_md.egress_port +@pragma pa_no_tagalong egress eg_intr_md.egress_cos +header egress_intrinsic_metadata_t eg_intr_md; + + + +header_type egress_intrinsic_metadata_from_parser_aux_t { + fields { + egress_global_tstamp : 48; + + + egress_global_ver : 32; + + + egress_parser_err : 16; + + + } +} + +@pragma pa_fragment egress eg_intr_md_from_parser_aux.egress_parser_err +@pragma pa_atomic egress eg_intr_md_from_parser_aux.egress_parser_err +@pragma not_deparsed ingress +@pragma not_deparsed egress +@pragma pa_gress egress eg_intr_md_from_parser_aux +header egress_intrinsic_metadata_from_parser_aux_t eg_intr_md_from_parser_aux; +# 353 "/home/john/ws/p4f/submodules/p4c-tofino/p4c_tofino/target/tofino/p4_lib/tofino/intrinsic_metadata.p4" +header_type egress_intrinsic_metadata_for_mirror_buffer_t { + fields { + _pad1 : 6; + egress_mirror_id : 10; + + + coalesce_flush: 1; + coalesce_length: 7; + + + + } +} + +@pragma dont_trim +@pragma pa_gress egress eg_intr_md_for_mb +@pragma pa_atomic egress eg_intr_md_for_mb.egress_mirror_id +@pragma pa_no_tagalong ingress ig_intr_md.coalesce_length +@pragma pa_no_tagalong ingress ig_intr_md.coalesce_flush +@pragma pa_fragment ingress eg_intr_md_for_mb.coalesce_flush +@pragma not_deparsed ingress +@pragma not_deparsed egress +header egress_intrinsic_metadata_for_mirror_buffer_t eg_intr_md_for_mb; + + + + +header_type egress_intrinsic_metadata_for_output_port_t { + fields { + + _pad1 : 7; + capture_tstamp_on_tx : 1; + + + + _pad2 : 7; + update_delay_on_tx : 1; +# 400 "/home/john/ws/p4f/submodules/p4c-tofino/p4c_tofino/target/tofino/p4_lib/tofino/intrinsic_metadata.p4" + _pad3 : 7; + force_tx_error : 1; + } +} + +@pragma pa_fragment egress eg_intr_md_for_oport._pad2 +@pragma pa_fragment egress eg_intr_md_for_oport._pad3 +@pragma not_deparsed ingress +@pragma not_deparsed egress +@pragma pa_gress egress eg_intr_md_for_oport +header egress_intrinsic_metadata_for_output_port_t eg_intr_md_for_oport; +# 3 "p4src/switch.p4" 2 + + + + +# 1 "p4src/includes/p4features.h" 1 +# 8 "p4src/switch.p4" 2 +# 1 "p4src/includes/headers.p4" 1 +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type llc_header_t { + fields { + dsap : 8; + ssap : 8; + control_ : 8; + } +} + +header_type snap_header_t { + fields { + oui : 24; + type_ : 16; + } +} + +header_type roce_header_t { + fields { + ib_grh : 320; + ib_bth : 96; + } +} + +header_type roce_v2_header_t { + fields { + ib_bth : 96; + } +} + +header_type fcoe_header_t { + fields { + version : 4; + type_ : 4; + sof : 8; + rsvd1 : 32; + ts_upper : 32; + ts_lower : 32; + size_ : 32; + eof : 8; + rsvd2 : 24; + } +} + +header_type vlan_tag_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + +header_type vlan_tag_3b_t { + fields { + pcp : 3; + cfi : 1; + vid : 4; + etherType : 16; + } +} +header_type vlan_tag_5b_t { + fields { + pcp : 3; + cfi : 1; + vid : 20; + etherType : 16; + } +} + +header_type ieee802_1ah_t { + fields { + pcp : 3; + dei : 1; + uca : 1; + reserved : 3; + i_sid : 24; + } +} + +header_type mpls_t { + fields { + label : 20; + exp : 3; + bos : 1; + ttl : 8; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type ipv6_t { + fields { + version : 4; + trafficClass : 8; + flowLabel : 20; + payloadLen : 16; + nextHdr : 8; + hopLimit : 8; + srcAddr : 128; + dstAddr : 128; + } +} + +header_type icmp_t { + fields { + type_ : 8; + code : 8; + hdrChecksum : 16; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 4; + flags : 8; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + length_ : 16; + checksum : 16; + } +} + +header_type sctp_t { + fields { + srcPort : 16; + dstPort : 16; + verifTag : 32; + checksum : 32; + } +} + +header_type gre_t { + fields { + C : 1; + R : 1; + K : 1; + S : 1; + s : 1; + recurse : 3; + flags : 5; + ver : 3; + proto : 16; + } +} + +header_type nvgre_t { + fields { + tni : 24; + reserved : 8; + } +} + + +header_type erspan_header_v1_t { + fields { + version : 4; + vlan : 12; + priority : 6; + span_id : 10; + direction : 8; + truncated: 8; + } +} + + +header_type erspan_header_v2_t { + fields { + version : 4; + vlan : 12; + priority : 6; + span_id : 10; + unknown7 : 32; + } +} + +header_type ipsec_esp_t { + fields { + spi : 32; + seqNo : 32; + } +} + +header_type ipsec_ah_t { + fields { + nextHdr : 8; + length_ : 8; + zero : 16; + spi : 32; + seqNo : 32; + } +} + +header_type arp_rarp_t { + fields { + hwType : 16; + protoType : 16; + hwAddrLen : 8; + protoAddrLen : 8; + opcode : 16; + } +} + +header_type arp_rarp_ipv4_t { + fields { + srcHwAddr : 48; + srcProtoAddr : 32; + dstHwAddr : 48; + dstProtoAddr : 32; + } +} + +header_type eompls_t { + fields { + zero : 4; + reserved : 12; + seqNo : 16; + } +} + +header_type vxlan_t { + fields { + flags : 8; + reserved : 24; + vni : 24; + reserved2 : 8; + } +} + +header_type nsh_t { + fields { + oam : 1; + context : 1; + flags : 6; + reserved : 8; + protoType: 16; + spath : 24; + sindex : 8; + } +} + +header_type nsh_context_t { + fields { + network_platform : 32; + network_shared : 32; + service_platform : 32; + service_shared : 32; + } +} + + + + +header_type genv_t { + fields { + ver : 2; + optLen : 6; + oam : 1; + critical : 1; + reserved : 6; + protoType : 16; + vni : 24; + reserved2 : 8; + } +} + + + + + +header_type genv_opt_A_t { + fields { + optClass : 16; + optType : 8; + reserved : 3; + optLen : 5; + data : 32; + } +} + + + + +header_type genv_opt_B_t { + fields { + optClass : 16; + optType : 8; + reserved : 3; + optLen : 5; + data : 64; + } +} + + + + +header_type genv_opt_C_t { + fields { + optClass : 16; + optType : 8; + reserved : 3; + optLen : 5; + data : 32; + } +} + +header_type trill_t { + fields { + version : 2; + reserved : 2; + multiDestination : 1; + optLength : 5; + hopCount : 6; + egressRbridge : 16; + ingressRbridge : 16; + } +} + +header_type lisp_t { + fields { + flags : 8; + nonce : 24; + lsbsInstanceId : 32; + } +} + +header_type vntag_t { + fields { + direction : 1; + pointer : 1; + destVif : 14; + looped : 1; + reserved : 1; + version : 2; + srcVif : 12; + } +} + +header_type bfd_t { + fields { + version : 3; + diag : 5; + state : 2; + p : 1; + f : 1; + c : 1; + a : 1; + d : 1; + m : 1; + detectMult : 8; + len : 8; + myDiscriminator : 32; + yourDiscriminator : 32; + desiredMinTxInterval : 32; + requiredMinRxInterval : 32; + requiredMinEchoRxInterval : 32; + } +} + +header_type sflow_t { + fields { + version : 32; + ipVersion : 32; + ipAddress : 32; + subAgentId : 32; + seqNumber : 32; + uptime : 32; + numSamples : 32; + } +} + +header_type sflow_internal_ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type sflow_sample_t { + fields { + enterprise : 20; + format : 12; + sampleLength : 32; + seqNumer : 32; + srcIdClass : 8; + srcIdIndex : 24; + samplingRate : 32; + samplePool : 32; + numDrops : 32; + inputIfindex : 32; + outputIfindex : 32; + numFlowRecords : 32; + } +} + +header_type sflow_record_t { + fields { + enterprise : 20; + format : 12; + flowDataLength : 32; + headerProtocol : 32; + frameLength : 32; + bytesRemoved : 32; + headerSize : 32; + } +} +# 451 "p4src/includes/headers.p4" +header_type fabric_header_internal_t { + fields { + packetType : 3; + pad1 : 5; + ingress_tunnel_type : 8; + egress_bd : 16; + nexthop_index : 16; + lkp_mac_type : 16; + routed : 1; + outer_routed : 1; + tunnel_terminate : 1; + header_count : 4; + pad2 : 1; + + + + + } +} + +header_type fabric_header_t { + fields { + packetType : 3; + headerVersion : 2; + packetVersion : 2; + pad1 : 1; + + fabricColor : 3; + fabricQos : 5; + + dstDevice : 8; + dstPort : 16; + } +} + +header_type fabric_header_unicast_t { + fields { + headerCount : 4; + tunnelTerminate : 1; + routed : 1; + outerRouted : 1; + pad : 1; + ingressTunnelType : 8; + egressBd : 16; + lkpMacType : 16; + nexthopIndex : 16; + } +} + +header_type fabric_header_multicast_t { + fields { + tunnelTerminate : 1; + routed : 1; + outerRouted : 1; + pad1 : 5; + ingressTunnelType : 8; + egressBd : 16; + lkpMacType : 16; + + mcastGrpA : 16; + mcastGrpB : 16; + ingressRid : 16; + l1ExclusionId : 16; + l2ExclusionId : 9; + pad2 : 7; + l1McastHash : 13; + pad3 : 3; + l2McastHash : 13; + pad4 : 3; + } +} + +header_type fabric_header_mirror_t { + fields { + rewriteIndex : 16; + egressPort : 10; + egressQueue : 5; + pad : 1; + } +} + +header_type fabric_header_control_t { + fields { + egressPort : 10; + egressQueue : 5; + pad : 1; + type_ : 1; + dir : 1; + redirectToCpu : 1; + forwardingBypass : 1; + aclBypass : 1; + reserved : 3; + } +} + +header_type fabric_header_cpu_t { + fields { + reserved : 11; + egressQueue : 5; + port : 16; + } +} + +header_type fabric_payload_header_t { + fields { + etherType : 16; + } +} +# 9 "p4src/switch.p4" 2 +# 1 "p4src/includes/parser.p4" 1 + + + +parser start { + set_metadata(ingress_metadata.drop_0, 0); + return parse_ethernet; +} +# 71 "p4src/includes/parser.p4" +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0 mask 0xfe00: parse_llc_header; + 0 mask 0xfa00: parse_llc_header; + 0x9000 : parse_fabric_header; + 0x8100, 0x9100 : parse_vlan; 0x8847 : parse_mpls; 0x0800 : parse_ipv4; 0x86dd : parse_ipv6; 0x0806 : parse_arp_rarp; 0x8035 : parse_arp_rarp; 0x8915 : parse_roce; 0x8906 : parse_fcoe; 0x8926 : parse_vntag; 0x88cc : parse_set_prio_high; 0x8809 : parse_set_prio_high; default: ingress; + } +} + +header llc_header_t llc_header; + +parser parse_llc_header { + extract(llc_header); + return select(llc_header.dsap, llc_header.ssap) { + 0xAAAA : parse_snap_header; + 0xFEFE : parse_set_prio_med; + default: ingress; + } +} + +header snap_header_t snap_header; + +parser parse_snap_header { + extract(snap_header); + return select(latest.type_) { + 0x8100, 0x9100 : parse_vlan; 0x8847 : parse_mpls; 0x0800 : parse_ipv4; 0x86dd : parse_ipv6; 0x0806 : parse_arp_rarp; 0x8035 : parse_arp_rarp; 0x8915 : parse_roce; 0x8906 : parse_fcoe; 0x8926 : parse_vntag; 0x88cc : parse_set_prio_high; 0x8809 : parse_set_prio_high; default: ingress; + } +} + +header roce_header_t roce; + +parser parse_roce { + extract(roce); + return ingress; +} + +header fcoe_header_t fcoe; + +parser parse_fcoe { + extract(fcoe); + return ingress; +} + + +header vlan_tag_t vlan_tag_[2]; +header vlan_tag_3b_t vlan_tag_3b[2]; +header vlan_tag_5b_t vlan_tag_5b[2]; + +parser parse_vlan { + extract(vlan_tag_[next]); + return select(latest.etherType) { + 0x8100, 0x9100 : parse_vlan; 0x8847 : parse_mpls; 0x0800 : parse_ipv4; 0x86dd : parse_ipv6; 0x0806 : parse_arp_rarp; 0x8035 : parse_arp_rarp; 0x8915 : parse_roce; 0x8906 : parse_fcoe; 0x8926 : parse_vntag; 0x88cc : parse_set_prio_high; 0x8809 : parse_set_prio_high; default: ingress; + } +} + + + +header mpls_t mpls[3]; + + +parser parse_mpls { + extract(mpls[next]); + return select(latest.bos) { + 0 : parse_mpls; + 1 : parse_mpls_bos; + default: ingress; + } +} + +parser parse_mpls_bos { +# 158 "p4src/includes/parser.p4" + return select(current(0, 4)) { + 0x4 : parse_mpls_inner_ipv4; + 0x6 : parse_mpls_inner_ipv6; + default: parse_eompls; + } + +} + +parser parse_mpls_inner_ipv4 { + set_metadata(tunnel_metadata.ingress_tunnel_type, 6); + return parse_inner_ipv4; +} + +parser parse_mpls_inner_ipv6 { + set_metadata(tunnel_metadata.ingress_tunnel_type, 6); + return parse_inner_ipv6; +} + +parser parse_vpls { + return ingress; +} + +parser parse_pw { + return ingress; +} +# 206 "p4src/includes/parser.p4" +header ipv4_t ipv4; + +field_list ipv4_checksum_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_checksum { + input { + ipv4_checksum_list; + } + algorithm : csum16; + output_width : 16; +} + +calculated_field ipv4.hdrChecksum { + + verify ipv4_checksum; + update ipv4_checksum; + + + + +} + +parser parse_ipv4 { + extract(ipv4); + set_metadata(ingress_metadata.ipv4_dstaddr_24b, latest.dstAddr); + return select(latest.fragOffset, latest.ihl, latest.protocol) { + 0x501 : parse_icmp; + 0x506 : parse_tcp; + 0x511 : parse_udp; + 0x52f : parse_gre; + 0x504 : parse_inner_ipv4; + 0x529 : parse_inner_ipv6; + 2 : parse_set_prio_med; + 88 : parse_set_prio_med; + 89 : parse_set_prio_med; + 103 : parse_set_prio_med; + 112 : parse_set_prio_med; + default: ingress; + } +} + +header ipv6_t ipv6; + +parser parse_ipv6 { + extract(ipv6); + set_metadata(ipv6_metadata.lkp_ipv6_sa, latest.srcAddr); + set_metadata(ipv6_metadata.lkp_ipv6_da, latest.dstAddr); + return select(latest.nextHdr) { + 58 : parse_icmp; + 6 : parse_tcp; + 17 : parse_udp; + 47 : parse_gre; + 4 : parse_inner_ipv4; + 41 : parse_inner_ipv6; + + 88 : parse_set_prio_med; + 89 : parse_set_prio_med; + 103 : parse_set_prio_med; + 112 : parse_set_prio_med; + + default: ingress; + } +} + +header icmp_t icmp; + +parser parse_icmp { + extract(icmp); + set_metadata(ingress_metadata.lkp_icmp_type, latest.type_); + set_metadata(ingress_metadata.lkp_icmp_code, latest.code); + return select(latest.type_) { + + 0x82 mask 0xfe : parse_set_prio_med; + 0x84 mask 0xfc : parse_set_prio_med; + 0x88 : parse_set_prio_med; + default: ingress; + } +} + + + + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + set_metadata(ingress_metadata.lkp_l4_sport, latest.srcPort); + set_metadata(ingress_metadata.lkp_l4_dport, latest.dstPort); + return select(latest.dstPort) { + 179 : parse_set_prio_med; + 639 : parse_set_prio_med; + default: ingress; + } +} +# 327 "p4src/includes/parser.p4" +header udp_t udp; + +header roce_v2_header_t roce_v2; + +parser parse_roce_v2 { + extract(roce_v2); + return ingress; +} + +parser parse_udp { + extract(udp); + set_metadata(ingress_metadata.lkp_l4_sport, latest.srcPort); + set_metadata(ingress_metadata.lkp_l4_dport, latest.dstPort); + return select(latest.dstPort) { + 4789 : parse_vxlan; + 6081: parse_geneve; + 4791: parse_roce_v2; + + + + + + 67 : parse_set_prio_med; + 68 : parse_set_prio_med; + 546 : parse_set_prio_med; + 547 : parse_set_prio_med; + 520 : parse_set_prio_med; + 521 : parse_set_prio_med; + 1985 : parse_set_prio_med; + default: ingress; + } +} + +header sctp_t sctp; + +parser parse_sctp { + extract(sctp); + return ingress; +} + + + + + +header gre_t gre; + +parser parse_gre { + extract(gre); + return select(latest.C, latest.R, latest.K, latest.S, latest.s, + latest.recurse, latest.flags, latest.ver, latest.proto) { + 0x20006558 : parse_nvgre; + 0x0800 : parse_gre_ipv4; + 0x86dd : parse_gre_ipv6; + 0x88BE : parse_erspan_v1; + 0x22EB : parse_erspan_v2; + + + + default: ingress; + } +} + +parser parse_gre_ipv4 { + set_metadata(tunnel_metadata.ingress_tunnel_type, 2); + return parse_inner_ipv4; +} + +parser parse_gre_ipv6 { + set_metadata(tunnel_metadata.ingress_tunnel_type, 2); + return parse_inner_ipv6; +} + +header nvgre_t nvgre; +header ethernet_t inner_ethernet; + +header ipv4_t inner_ipv4; +header ipv6_t inner_ipv6; +header ipv4_t outer_ipv4; +header ipv6_t outer_ipv6; + +field_list inner_ipv4_checksum_list { + inner_ipv4.version; + inner_ipv4.ihl; + inner_ipv4.diffserv; + inner_ipv4.totalLen; + inner_ipv4.identification; + inner_ipv4.flags; + inner_ipv4.fragOffset; + inner_ipv4.ttl; + inner_ipv4.protocol; + inner_ipv4.srcAddr; + inner_ipv4.dstAddr; +} + +field_list_calculation inner_ipv4_checksum { + input { + inner_ipv4_checksum_list; + } + algorithm : csum16; + output_width : 16; +} + +calculated_field inner_ipv4.hdrChecksum { + + verify inner_ipv4_checksum; + update inner_ipv4_checksum; + + + + +} + +header udp_t outer_udp; + +parser parse_nvgre { + extract(nvgre); + set_metadata(tunnel_metadata.ingress_tunnel_type, 4); + set_metadata(tunnel_metadata.tunnel_vni, latest.tni); + return parse_inner_ethernet; +} + +header erspan_header_v1_t erspan_v1_header; + +parser parse_erspan_v1 { + extract(erspan_v1_header); + return ingress; +} + +header erspan_header_v2_t erspan_v2_header; + +parser parse_erspan_v2 { + extract(erspan_v2_header); + return ingress; +} + + + +header arp_rarp_t arp_rarp; + +parser parse_arp_rarp { + extract(arp_rarp); + return select(latest.protoType) { + 0x0800 : parse_arp_rarp_ipv4; + default: ingress; + } +} + +header arp_rarp_ipv4_t arp_rarp_ipv4; + +parser parse_arp_rarp_ipv4 { + extract(arp_rarp_ipv4); + return parse_set_prio_med; +} + +header eompls_t eompls; + +parser parse_eompls { + + set_metadata(tunnel_metadata.ingress_tunnel_type, 5); + return parse_inner_ethernet; +} + +header vxlan_t vxlan; + +parser parse_vxlan { + extract(vxlan); + set_metadata(tunnel_metadata.ingress_tunnel_type, 1); + set_metadata(tunnel_metadata.tunnel_vni, latest.vni); + return parse_inner_ethernet; +} + +header genv_t genv; + +parser parse_geneve { + extract(genv); + set_metadata(tunnel_metadata.tunnel_vni, latest.vni); + set_metadata(tunnel_metadata.ingress_tunnel_type, 3); + return select(genv.ver, genv.optLen, genv.protoType) { + 0x6558 : parse_inner_ethernet; + 0x0800 : parse_inner_ipv4; + 0x86dd : parse_inner_ipv6; + default : ingress; + } +} + +header nsh_t nsh; +header nsh_context_t nsh_context; + +parser parse_nsh { + extract(nsh); + extract(nsh_context); + return select(nsh.protoType) { + 0x0800 : parse_inner_ipv4; + 0x86dd : parse_inner_ipv6; + 0x6558 : parse_inner_ethernet; + default : ingress; + } +} + +header lisp_t lisp; + +parser parse_lisp { + extract(lisp); + return select(current(0, 4)) { + 0x4 : parse_inner_ipv4; + 0x6 : parse_inner_ipv6; + default : ingress; + } +} + +parser parse_inner_ipv4 { + extract(inner_ipv4); + return select(latest.fragOffset, latest.ihl, latest.protocol) { + 0x501 : parse_inner_icmp; + 0x506 : parse_inner_tcp; + 0x511 : parse_inner_udp; + default: ingress; + } +} + +header icmp_t inner_icmp; + +parser parse_inner_icmp { + extract(inner_icmp); + set_metadata(ingress_metadata.lkp_inner_icmp_type, latest.type_); + set_metadata(ingress_metadata.lkp_inner_icmp_code, latest.code); + return ingress; +} + +header tcp_t inner_tcp; + +parser parse_inner_tcp { + extract(inner_tcp); + set_metadata(ingress_metadata.lkp_inner_l4_sport, latest.srcPort); + set_metadata(ingress_metadata.lkp_inner_l4_dport, latest.dstPort); + return ingress; +} + +header udp_t inner_udp; + +parser parse_inner_udp { + extract(inner_udp); + set_metadata(ingress_metadata.lkp_inner_l4_sport, latest.srcPort); + set_metadata(ingress_metadata.lkp_inner_l4_dport, latest.dstPort); + return ingress; +} + +header sctp_t inner_sctp; + +parser parse_inner_sctp { + extract(inner_sctp); + return ingress; +} + +parser parse_inner_ipv6 { + extract(inner_ipv6); + return select(latest.nextHdr) { + 58 : parse_inner_icmp; + 6 : parse_inner_tcp; + 17 : parse_inner_udp; + default: ingress; + } +} + +parser parse_inner_ethernet { + extract(inner_ethernet); + return select(latest.etherType) { + 0x0800 : parse_inner_ipv4; + 0x86dd : parse_inner_ipv6; + default: ingress; + } +} + +header trill_t trill; + +parser parse_trill { + extract(trill); + return parse_inner_ethernet; +} + +header vntag_t vntag; + +parser parse_vntag { + extract(vntag); + return parse_inner_ethernet; +} + +header bfd_t bfd; + +parser parse_bfd { + extract(bfd); + return parse_set_prio_max; +} + +header sflow_t sflow; +header sflow_internal_ethernet_t sflow_internal_ethernet; +header sflow_sample_t sflow_sample; +header sflow_record_t sflow_record; + +parser parse_sflow { + extract(sflow); + return ingress; +} + +parser parse_bf_internal_sflow { + extract(sflow_internal_ethernet); + extract(sflow_sample); + extract(sflow_record); + return ingress; +} + +header fabric_header_t fabric_header; +header fabric_header_unicast_t fabric_header_unicast; +header fabric_header_multicast_t fabric_header_multicast; +header fabric_header_mirror_t fabric_header_mirror; +header fabric_header_control_t fabric_header_control; +header fabric_header_cpu_t fabric_header_cpu; +header fabric_payload_header_t fabric_payload_header; + +parser parse_fabric_header { + return select(current(0, 3)) { + 1 : parse_internal_fabric_header; + default : parse_external_fabric_header; + } +} + +parser parse_internal_fabric_header { + + + + + return ingress; + +} + +parser parse_external_fabric_header { + extract(fabric_header); + return select(latest.packetType) { + 2 : parse_fabric_header_unicast; + 3 : parse_fabric_header_multicast; + 4 : parse_fabric_header_mirror; + 5 : parse_fabric_header_control; + 6 : parse_fabric_header_cpu; + default : ingress; + } +} + +parser parse_fabric_header_unicast { + extract(fabric_header_unicast); + return parse_fabric_payload_header; +} + +parser parse_fabric_header_multicast { + extract(fabric_header_multicast); + return parse_fabric_payload_header; +} + +parser parse_fabric_header_mirror { + extract(fabric_header_mirror); + return parse_fabric_payload_header; +} + +parser parse_fabric_header_control { + extract(fabric_header_control); + return parse_fabric_payload_header; +} + +parser parse_fabric_header_cpu { + extract(fabric_header_cpu); + set_metadata(ig_intr_md_for_tm.ucast_egress_port, latest.port); + return parse_fabric_payload_header; +} + +parser parse_fabric_payload_header { + extract(fabric_payload_header); + return select(latest.etherType) { + 0 mask 0xfe00: parse_llc_header; + 0 mask 0xfa00: parse_llc_header; + 0x8100, 0x9100 : parse_vlan; 0x8847 : parse_mpls; 0x0800 : parse_ipv4; 0x86dd : parse_ipv6; 0x0806 : parse_arp_rarp; 0x8035 : parse_arp_rarp; 0x8915 : parse_roce; 0x8906 : parse_fcoe; 0x8926 : parse_vntag; 0x88cc : parse_set_prio_high; 0x8809 : parse_set_prio_high; default: ingress; + } +} +# 718 "p4src/includes/parser.p4" +parser parse_set_prio_med { + set_metadata(ig_prsr_ctrl.priority, 3); + return ingress; +} + +parser parse_set_prio_high { + set_metadata(ig_prsr_ctrl.priority, 5); + return ingress; +} + +parser parse_set_prio_max { + set_metadata(ig_prsr_ctrl.priority, 7); + return ingress; +} +# 10 "p4src/switch.p4" 2 +# 1 "p4src/includes/sizes.p4" 1 +# 11 "p4src/switch.p4" 2 +# 1 "p4src/includes/defines.p4" 1 +# 12 "p4src/switch.p4" 2 + + +header_type ingress_metadata_t { + fields { + lkp_l4_sport : 16; + lkp_l4_dport : 16; + lkp_inner_l4_sport : 16; + lkp_inner_l4_dport : 16; + + lkp_icmp_type : 8; + lkp_icmp_code : 8; + lkp_inner_icmp_type : 8; + lkp_inner_icmp_code : 8; + + ifindex : 16; + vrf : 2; + + outer_bd : 16; + outer_dscp : 8; + + src_is_link_local : 1; + bd : 16; + uuc_mc_index : 16; + umc_mc_index : 16; + bcast_mc_index : 16; + + if_label : 16; + bd_label : 16; + + ipsg_check_fail : 1; + + mirror_session_id : 10; + + marked_cos : 3; + marked_dscp : 8; + marked_exp : 3; + + egress_ifindex : 16; + same_bd_check : 16; + + ipv4_dstaddr_24b : 24; + drop_0 : 1; + drop_reason : 8; + control_frame: 1; + } +} + +header_type egress_metadata_t { + fields { + payload_length : 16; + smac_idx : 9; + bd : 16; + inner_replica : 1; + replica : 1; + mac_da : 48; + routed : 1; + same_bd_check : 16; + + header_count: 4; + + drop_reason : 8; + egress_bypass : 1; + fabric_bypass : 1; + drop_exception : 8; + } +} + +metadata ingress_metadata_t ingress_metadata; +metadata egress_metadata_t egress_metadata; + +# 1 "p4src/port.p4" 1 + +action set_valid_outer_unicast_packet_untagged() { + modify_field(l2_metadata.lkp_pkt_type, 1); + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); + add_i_fabric_header(ethernet.etherType); +} + +action set_valid_outer_unicast_packet_single_tagged() { + modify_field(l2_metadata.lkp_pkt_type, 1); + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); + add_i_fabric_header(vlan_tag_[0].etherType); +} + +action set_valid_outer_unicast_packet_double_tagged() { + modify_field(l2_metadata.lkp_pkt_type, 1); + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); + add_i_fabric_header(vlan_tag_[1].etherType); +} + +action set_valid_outer_unicast_packet_qinq_tagged() { + modify_field(l2_metadata.lkp_pkt_type, 1); + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); + add_i_fabric_header(ethernet.etherType); +} + +action set_valid_outer_multicast_packet_untagged() { + modify_field(l2_metadata.lkp_pkt_type, 2); + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); + add_i_fabric_header(ethernet.etherType); +} + +action set_valid_outer_multicast_packet_single_tagged() { + modify_field(l2_metadata.lkp_pkt_type, 2); + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); + add_i_fabric_header(vlan_tag_[0].etherType); +} + +action set_valid_outer_multicast_packet_double_tagged() { + modify_field(l2_metadata.lkp_pkt_type, 2); + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); + add_i_fabric_header(vlan_tag_[1].etherType); +} + +action set_valid_outer_multicast_packet_qinq_tagged() { + modify_field(l2_metadata.lkp_pkt_type, 2); + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); + add_i_fabric_header(ethernet.etherType); +} + +action set_valid_outer_broadcast_packet_untagged() { + modify_field(l2_metadata.lkp_pkt_type, 4); + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); + add_i_fabric_header(ethernet.etherType); +} + +action set_valid_outer_broadcast_packet_single_tagged() { + modify_field(l2_metadata.lkp_pkt_type, 4); + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); + add_i_fabric_header(vlan_tag_[0].etherType); +} + +action set_valid_outer_broadcast_packet_double_tagged() { + modify_field(l2_metadata.lkp_pkt_type, 4); + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); + add_i_fabric_header(vlan_tag_[1].etherType); +} + +action set_valid_outer_broadcast_packet_qinq_tagged() { + modify_field(l2_metadata.lkp_pkt_type, 4); + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); + add_i_fabric_header(ethernet.etherType); +} + +table validate_outer_ethernet { + reads { + ethernet.dstAddr : ternary; + vlan_tag_[0] : valid; + vlan_tag_[1] : valid; + } + actions { + set_valid_outer_unicast_packet_untagged; + set_valid_outer_unicast_packet_single_tagged; + set_valid_outer_unicast_packet_double_tagged; + set_valid_outer_unicast_packet_qinq_tagged; + set_valid_outer_multicast_packet_untagged; + set_valid_outer_multicast_packet_single_tagged; + set_valid_outer_multicast_packet_double_tagged; + set_valid_outer_multicast_packet_qinq_tagged; + set_valid_outer_broadcast_packet_untagged; + set_valid_outer_broadcast_packet_single_tagged; + set_valid_outer_broadcast_packet_double_tagged; + set_valid_outer_broadcast_packet_qinq_tagged; + } + size : 64; +} + +control validate_outer_ethernet_header { + apply(validate_outer_ethernet); +} +action set_ifindex(ifindex, if_label, exclusion_id) { + modify_field(ingress_metadata.ifindex, ifindex); + modify_field(ig_intr_md_for_tm.level2_exclusion_id, exclusion_id); + modify_field(ingress_metadata.if_label, if_label); +} + +table port_mapping { + reads { + ig_intr_md.ingress_port : exact; + } + actions { + set_ifindex; + } + size : 288; +} + +control process_port_mapping { + apply(port_mapping); +} + +action set_bd_ipv4_mcast_switch_ipv6_mcast_switch_flags(bd, vrf, + rmac_group, mrpf_group, + bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, + ipv4_unicast_enabled, ipv6_unicast_enabled, + ipv4_multicast_mode, ipv6_multicast_mode, + igmp_snooping_enabled, mld_snooping_enabled, + ipv4_urpf_mode, ipv6_urpf_mode, + stp_group, exclusion_id, stats_idx) { + modify_field(ingress_metadata.vrf, vrf); + modify_field(ingress_metadata.bd, bd); + modify_field(ingress_metadata.outer_bd, bd); + modify_field(multicast_metadata.outer_ipv4_mcast_key_type, 0); + modify_field(multicast_metadata.outer_ipv4_mcast_key, bd); + modify_field(multicast_metadata.outer_ipv6_mcast_key_type, 0); + modify_field(multicast_metadata.outer_ipv6_mcast_key, bd); + + modify_field(ipv4_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); + modify_field(ipv6_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled); + modify_field(multicast_metadata.ipv4_multicast_mode, ipv4_multicast_mode); + modify_field(multicast_metadata.ipv6_multicast_mode, ipv6_multicast_mode); + modify_field(multicast_metadata.igmp_snooping_enabled, igmp_snooping_enabled); + modify_field(multicast_metadata.mld_snooping_enabled, mld_snooping_enabled); + modify_field(ipv4_metadata.ipv4_urpf_mode, ipv4_urpf_mode); + modify_field(ipv6_metadata.ipv6_urpf_mode, ipv6_urpf_mode); + modify_field(l3_metadata.rmac_group, rmac_group); + modify_field(multicast_metadata.bd_mrpf_group, mrpf_group); + modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); + modify_field(ingress_metadata.umc_mc_index, umc_mc_index); + modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); + modify_field(ingress_metadata.bd_label, bd_label); + modify_field(l2_metadata.stp_group, stp_group); + modify_field(ig_intr_md_for_tm.level1_exclusion_id, exclusion_id); + modify_field(l2_metadata.bd_stats_idx, stats_idx); +} + +action set_bd_ipv4_mcast_switch_ipv6_mcast_route_flags(bd, vrf, + rmac_group, mrpf_group, + bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, + ipv4_unicast_enabled, ipv6_unicast_enabled, + ipv4_multicast_mode, ipv6_multicast_mode, + igmp_snooping_enabled, mld_snooping_enabled, + ipv4_urpf_mode, ipv6_urpf_mode, + stp_group, exclusion_id, stats_idx) { + modify_field(ingress_metadata.vrf, vrf); + modify_field(ingress_metadata.bd, bd); + modify_field(ingress_metadata.outer_bd, bd); + modify_field(multicast_metadata.outer_ipv4_mcast_key_type, 0); + modify_field(multicast_metadata.outer_ipv4_mcast_key, bd); + modify_field(multicast_metadata.outer_ipv6_mcast_key_type, 1); + modify_field(multicast_metadata.outer_ipv6_mcast_key, vrf); + + modify_field(ipv4_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); + modify_field(ipv6_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled); + modify_field(multicast_metadata.ipv4_multicast_mode, ipv4_multicast_mode); + modify_field(multicast_metadata.ipv6_multicast_mode, ipv6_multicast_mode); + modify_field(multicast_metadata.igmp_snooping_enabled, igmp_snooping_enabled); + modify_field(multicast_metadata.mld_snooping_enabled, mld_snooping_enabled); + modify_field(ipv4_metadata.ipv4_urpf_mode, ipv4_urpf_mode); + modify_field(ipv6_metadata.ipv6_urpf_mode, ipv6_urpf_mode); + modify_field(l3_metadata.rmac_group, rmac_group); + modify_field(multicast_metadata.bd_mrpf_group, mrpf_group); + modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); + modify_field(ingress_metadata.umc_mc_index, umc_mc_index); + modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); + modify_field(ingress_metadata.bd_label, bd_label); + modify_field(l2_metadata.stp_group, stp_group); + modify_field(ig_intr_md_for_tm.level1_exclusion_id, exclusion_id); + modify_field(l2_metadata.bd_stats_idx, stats_idx); +} + +action set_bd_ipv4_mcast_route_ipv6_mcast_switch_flags(bd, vrf, + rmac_group, mrpf_group, + bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, + ipv4_unicast_enabled, ipv6_unicast_enabled, + ipv4_multicast_mode, ipv6_multicast_mode, + igmp_snooping_enabled, mld_snooping_enabled, + ipv4_urpf_mode, ipv6_urpf_mode, + stp_group, exclusion_id, stats_idx) { + modify_field(ingress_metadata.vrf, vrf); + modify_field(ingress_metadata.bd, bd); + modify_field(ingress_metadata.outer_bd, bd); + modify_field(multicast_metadata.outer_ipv4_mcast_key_type, 1); + modify_field(multicast_metadata.outer_ipv4_mcast_key, vrf); + modify_field(multicast_metadata.outer_ipv6_mcast_key_type, 0); + modify_field(multicast_metadata.outer_ipv6_mcast_key, bd); + + modify_field(ipv4_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); + modify_field(ipv6_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled); + modify_field(multicast_metadata.ipv4_multicast_mode, ipv4_multicast_mode); + modify_field(multicast_metadata.ipv6_multicast_mode, ipv6_multicast_mode); + modify_field(multicast_metadata.igmp_snooping_enabled, igmp_snooping_enabled); + modify_field(multicast_metadata.mld_snooping_enabled, mld_snooping_enabled); + modify_field(ipv4_metadata.ipv4_urpf_mode, ipv4_urpf_mode); + modify_field(ipv6_metadata.ipv6_urpf_mode, ipv6_urpf_mode); + modify_field(l3_metadata.rmac_group, rmac_group); + modify_field(multicast_metadata.bd_mrpf_group, mrpf_group); + modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); + modify_field(ingress_metadata.umc_mc_index, umc_mc_index); + modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); + modify_field(ingress_metadata.bd_label, bd_label); + modify_field(l2_metadata.stp_group, stp_group); + modify_field(ig_intr_md_for_tm.level1_exclusion_id, exclusion_id); + modify_field(l2_metadata.bd_stats_idx, stats_idx); +} + +action set_bd_ipv4_mcast_route_ipv6_mcast_route_flags(bd, vrf, + rmac_group, mrpf_group, + bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, + ipv4_unicast_enabled, ipv6_unicast_enabled, + ipv4_multicast_mode, ipv6_multicast_mode, + igmp_snooping_enabled, mld_snooping_enabled, + ipv4_urpf_mode, ipv6_urpf_mode, + stp_group, exclusion_id, stats_idx) { + modify_field(ingress_metadata.vrf, vrf); + modify_field(ingress_metadata.bd, bd); + modify_field(ingress_metadata.outer_bd, bd); + modify_field(multicast_metadata.outer_ipv4_mcast_key_type, 1); + modify_field(multicast_metadata.outer_ipv4_mcast_key, vrf); + modify_field(multicast_metadata.outer_ipv6_mcast_key_type, 1); + modify_field(multicast_metadata.outer_ipv6_mcast_key, vrf); + + modify_field(ipv4_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); + modify_field(ipv6_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled); + modify_field(multicast_metadata.ipv4_multicast_mode, ipv4_multicast_mode); + modify_field(multicast_metadata.ipv6_multicast_mode, ipv6_multicast_mode); + modify_field(multicast_metadata.igmp_snooping_enabled, igmp_snooping_enabled); + modify_field(multicast_metadata.mld_snooping_enabled, mld_snooping_enabled); + modify_field(ipv4_metadata.ipv4_urpf_mode, ipv4_urpf_mode); + modify_field(ipv6_metadata.ipv6_urpf_mode, ipv6_urpf_mode); + modify_field(l3_metadata.rmac_group, rmac_group); + modify_field(multicast_metadata.bd_mrpf_group, mrpf_group); + modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); + modify_field(ingress_metadata.umc_mc_index, umc_mc_index); + modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); + modify_field(ingress_metadata.bd_label, bd_label); + modify_field(l2_metadata.stp_group, stp_group); + modify_field(ig_intr_md_for_tm.level1_exclusion_id, exclusion_id); + modify_field(l2_metadata.bd_stats_idx, stats_idx); +} + +action set_bd(bd, vrf, rmac_group, + bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, + ipv4_unicast_enabled, + igmp_snooping_enabled, + stp_group, exclusion_id, stats_idx) { + modify_field(ingress_metadata.vrf, vrf); + modify_field(ipv4_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); + modify_field(multicast_metadata.igmp_snooping_enabled, igmp_snooping_enabled); + modify_field(l3_metadata.rmac_group, rmac_group); + modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); + modify_field(ingress_metadata.umc_mc_index, umc_mc_index); + modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); + modify_field(ingress_metadata.bd_label, bd_label); + modify_field(ingress_metadata.bd, bd); + modify_field(ingress_metadata.outer_bd, bd); + modify_field(l2_metadata.stp_group, stp_group); + modify_field(ig_intr_md_for_tm.level1_exclusion_id, exclusion_id); + modify_field(l2_metadata.bd_stats_idx, stats_idx); +} + +action_profile bd_action_profile { + actions { + set_bd; + set_bd_ipv4_mcast_switch_ipv6_mcast_switch_flags; + set_bd_ipv4_mcast_switch_ipv6_mcast_route_flags; + set_bd_ipv4_mcast_route_ipv6_mcast_switch_flags; + set_bd_ipv4_mcast_route_ipv6_mcast_route_flags; + } + size : 16384; +} + +table port_vlan_mapping { + reads { + ingress_metadata.ifindex : exact; + vlan_tag_[0] : valid; + vlan_tag_[0].vid : exact; + vlan_tag_[1] : valid; + vlan_tag_[1].vid : exact; + } + + action_profile: bd_action_profile; + size : 32768; +} + +control process_port_vlan_mapping { + apply(port_vlan_mapping); +} + + +counter ingress_bd_stats { + type : packets_and_bytes; + instance_count : 16384; +} + +action update_ingress_bd_stats() { + count(ingress_bd_stats, l2_metadata.bd_stats_idx); +} + +table ingress_bd_stats { + actions { + update_ingress_bd_stats; + } + size : 64; +} + + +control process_ingress_bd_stats { + apply(ingress_bd_stats); +} + +field_list lag_hash_fields { + l2_metadata.lkp_mac_sa; + l2_metadata.lkp_mac_da; + i_fabric_header.lkp_mac_type; + ipv4_metadata.lkp_ipv4_sa; + ipv4_metadata.lkp_ipv4_da; + l3_metadata.lkp_ip_proto; + ingress_metadata.lkp_l4_sport; + ingress_metadata.lkp_l4_dport; +} + +field_list_calculation lag_hash { + input { + lag_hash_fields; + } + algorithm : crc16; + output_width : 8; +} + +action_selector lag_selector { + selection_key : lag_hash; +} + + + + + + + +action set_lag_port(port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + + +action_profile lag_action_profile { + actions { + nop; + set_lag_port; + } + size : 1024; + dynamic_action_selection : lag_selector; +} + +table lag_group { + reads { + ingress_metadata.egress_ifindex : exact; + } + action_profile: lag_action_profile; + size : 1024; +} + +control process_lag { + apply(lag_group); +} + +action set_egress_packet_vlan_tagged(vlan_id) { + add_header(vlan_tag_[0]); + modify_field(vlan_tag_[0].etherType, ethernet.etherType); + modify_field(vlan_tag_[0].vid, vlan_id); + modify_field(ethernet.etherType, 0x8100); +} + +action set_egress_packet_vlan_untagged() { +} + +table egress_vlan_xlate { + reads { + eg_intr_md.egress_port : exact; + egress_metadata.bd : exact; + } + actions { + set_egress_packet_vlan_tagged; + set_egress_packet_vlan_untagged; + } + size : 32768; +} + +control process_vlan_xlate { + apply(egress_vlan_xlate); +} +# 83 "p4src/switch.p4" 2 +# 1 "p4src/l2.p4" 1 +header_type l2_metadata_t { + fields { + lkp_pkt_type : 3; + lkp_mac_sa : 48; + lkp_mac_da : 48; + + l2_nexthop : 16; + l2_nexthop_type : 1; + l2_redirect : 1; + l2_src_miss : 1; + l2_src_move : 16; + stp_group: 10; + stp_state : 3; + bd_stats_idx : 16; + } +} + +metadata l2_metadata_t l2_metadata; +# 37 "p4src/l2.p4" +control process_spanning_tree { + + + + + +} +# 117 "p4src/l2.p4" +control process_mac { + + + + +} +# 149 "p4src/l2.p4" +control process_mac_learning { + + + +} + +action set_unicast() { +} + +action set_unicast_and_ipv6_src_is_link_local() { + modify_field(ingress_metadata.src_is_link_local, 1); +} + +action set_multicast() { + add_to_field(l2_metadata.bd_stats_idx, 1); +} + +action set_ip_multicast() { + modify_field(multicast_metadata.ip_multicast, 1); + add_to_field(l2_metadata.bd_stats_idx, 1); +} + +action set_ip_multicast_and_ipv6_src_is_link_local() { + modify_field(multicast_metadata.ip_multicast, 1); + modify_field(ingress_metadata.src_is_link_local, 1); + add_to_field(l2_metadata.bd_stats_idx, 1); +} + +action set_broadcast() { + add_to_field(l2_metadata.bd_stats_idx, 2); +} + +table validate_packet { + reads { + l2_metadata.lkp_mac_da : ternary; + + + + } + actions { + nop; + set_unicast; + set_unicast_and_ipv6_src_is_link_local; + set_multicast; + set_ip_multicast; + set_ip_multicast_and_ipv6_src_is_link_local; + set_broadcast; + } + size : 64; +} + +control process_validate_packet { + apply(validate_packet); +} + + +action rewrite_unicast_mac(smac) { + modify_field(ethernet.srcAddr, smac); + modify_field(ethernet.dstAddr, egress_metadata.mac_da); +} + +action rewrite_multicast_mac(smac) { + modify_field(ethernet.srcAddr, smac); + modify_field(ethernet.dstAddr, 0x01005E000000); + + + + add_to_field(ipv4.ttl, -1); +} + +table mac_rewrite { + reads { + egress_metadata.smac_idx : exact; + ipv4.dstAddr : ternary; + } + actions { + nop; + rewrite_unicast_mac; + rewrite_multicast_mac; + } + size : 512; +} + +control process_mac_rewrite { + if (i_fabric_header.routed == 1) { + apply(mac_rewrite); + } +} +# 286 "p4src/l2.p4" +control process_replication { +# 296 "p4src/l2.p4" +} + +action set_egress_bd_properties(nat_mode) { + modify_field(nat_metadata.egress_nat_mode, nat_mode); +} + +table egress_bd_map { + reads { + i_fabric_header.egress_bd : exact; + } + actions { + nop; + set_egress_bd_properties; + } + size : 16384; +} + +control process_egress_bd { + apply(egress_bd_map); +} + +action vlan_decap_nop() { + modify_field(ethernet.etherType, i_fabric_header.lkp_mac_type); +} + +action remove_vlan_single_tagged() { + remove_header(vlan_tag_[0]); + modify_field(ethernet.etherType, i_fabric_header.lkp_mac_type); +} + +action remove_vlan_double_tagged() { + remove_header(vlan_tag_[0]); + remove_header(vlan_tag_[1]); + modify_field(ethernet.etherType, i_fabric_header.lkp_mac_type); +} + +action remove_vlan_qinq_tagged() { + remove_header(vlan_tag_[0]); + remove_header(vlan_tag_[1]); + modify_field(ethernet.etherType, i_fabric_header.lkp_mac_type); +} + +table vlan_decap { + reads { + egress_metadata.drop_exception : exact; + vlan_tag_[0] : valid; + vlan_tag_[1] : valid; + } + actions { + vlan_decap_nop; + remove_vlan_single_tagged; + remove_vlan_double_tagged; + remove_vlan_qinq_tagged; + } + size: 256; +} + +control process_vlan_decap { + apply(vlan_decap); +} +# 84 "p4src/switch.p4" 2 +# 1 "p4src/l3.p4" 1 + + + + + header_type l3_metadata_t { + fields { + lkp_ip_type : 2; + lkp_ip_proto : 8; + lkp_ip_tc : 8; + lkp_ip_ttl : 8; + rmac_group : 10; + rmac_hit : 1; + urpf_mode : 2; + urpf_hit : 1; + urpf_check_fail :1; + urpf_bd_group : 16; + fib_hit : 1; + fib_nexthop : 16; + fib_nexthop_type : 1; + } + } + + metadata l3_metadata_t l3_metadata; + +action fib_hit_nexthop(nexthop_index) { + modify_field(l3_metadata.fib_hit, 1); + modify_field(l3_metadata.fib_nexthop, nexthop_index); + modify_field(l3_metadata.fib_nexthop_type, 0); +} + +action fib_hit_ecmp(ecmp_index) { + modify_field(l3_metadata.fib_hit, 1); + modify_field(l3_metadata.fib_nexthop, ecmp_index); + modify_field(l3_metadata.fib_nexthop_type, 1); +} + +action rmac_hit() { + modify_field(l3_metadata.rmac_hit, 1); + modify_field(ingress_metadata.egress_ifindex, 64); + modify_field(ig_intr_md_for_tm.mcast_grp_a, 0); + modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); + + + +} + +action rmac_miss() { + modify_field(l3_metadata.rmac_hit, 0); +} + +table rmac { + reads { + l3_metadata.rmac_group : exact; + l2_metadata.lkp_mac_da : exact; + } + actions { + rmac_hit; + rmac_miss; + } + size : 512; +} +# 85 "p4src/l3.p4" +control process_urpf_bd { + + + + + + +} +# 117 "p4src/l3.p4" +control process_mtu { + + + +} +# 85 "p4src/switch.p4" 2 +# 1 "p4src/ipv4.p4" 1 +# 18 "p4src/ipv4.p4" + header_type ipv4_metadata_t { + fields { + lkp_ipv4_sa : 32; + lkp_ipv4_da : 32; + ipv4_unicast_enabled : 1; + ipv4_urpf_mode : 2; + + fib_hit_exm_prefix_length_32 : 1; + fib_nexthop_exm_prefix_length_32 :10; + fib_nexthop_type_exm_prefix_length_32 : 1; + + fib_hit_exm_prefix_length_31 : 1; + fib_nexthop_exm_prefix_length_31 :10; + fib_nexthop_type_exm_prefix_length_31 : 1; + + fib_hit_exm_prefix_length_30 : 1; + fib_nexthop_exm_prefix_length_30 :10; + fib_nexthop_type_exm_prefix_length_30 : 1; + + fib_hit_exm_prefix_length_29 : 1; + fib_nexthop_exm_prefix_length_29 :10; + fib_nexthop_type_exm_prefix_length_29 : 1; + + fib_hit_exm_prefix_length_28 : 1; + fib_nexthop_exm_prefix_length_28 :10; + fib_nexthop_type_exm_prefix_length_28 : 1; + + fib_hit_exm_prefix_length_27 : 1; + fib_nexthop_exm_prefix_length_27 :10; + fib_nexthop_type_exm_prefix_length_27 : 1; + + fib_hit_exm_prefix_length_26 : 1; + fib_nexthop_exm_prefix_length_26 :10; + fib_nexthop_type_exm_prefix_length_26 : 1; + + fib_hit_exm_prefix_length_25 : 1; + fib_nexthop_exm_prefix_length_25 :10; + fib_nexthop_type_exm_prefix_length_25 : 1; + + fib_hit_exm_prefix_length_24 : 1; + fib_nexthop_exm_prefix_length_24 :10; + fib_nexthop_type_exm_prefix_length_24 : 1; + + fib_hit_exm_prefix_length_23 : 1; + fib_nexthop_exm_prefix_length_23 :10; + fib_nexthop_type_exm_prefix_length_23 : 1; + + fib_hit_lpm_prefix_range_22_to_0 : 1; + fib_nexthop_lpm_prefix_range_22_to_0 :10; + fib_nexthop_type_lpm_prefix_range_22_to_0 : 1; + + } + } + +metadata ipv4_metadata_t ipv4_metadata; + + + +action set_valid_outer_ipv4_packet() { + modify_field(l3_metadata.lkp_ip_type, 1); + modify_field(ipv4_metadata.lkp_ipv4_sa, ipv4.srcAddr); + modify_field(ipv4_metadata.lkp_ipv4_da, ipv4.dstAddr); + modify_field(l3_metadata.lkp_ip_proto, ipv4.protocol); + modify_field(l3_metadata.lkp_ip_tc, ipv4.diffserv); + modify_field(l3_metadata.lkp_ip_ttl, ipv4.ttl); +} + +action set_malformed_outer_ipv4_packet() { +} + +table validate_outer_ipv4_packet { + reads { + ipv4.version : exact; + ipv4.ihl : exact; + ipv4.ttl : exact; + ipv4.srcAddr : ternary; + ipv4.dstAddr : ternary; + } + actions { + set_valid_outer_ipv4_packet; + set_malformed_outer_ipv4_packet; + } + size : 64; +} + + +control validate_outer_ipv4_header { + + apply(validate_outer_ipv4_packet); + +} + + + +action fib_hit_exm_prefix_length_32_nexthop(nexthop_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_32, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_32, + nexthop_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_32, + 0); +} + +action fib_hit_exm_prefix_length_31_nexthop(nexthop_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_31, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_31, + nexthop_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_31, + 0); +} + +action fib_hit_exm_prefix_length_30_nexthop(nexthop_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_30, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_30, + nexthop_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_30, + 0); +} + +action fib_hit_exm_prefix_length_29_nexthop(nexthop_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_29, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_29, + nexthop_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_29, + 0); +} + +action fib_hit_exm_prefix_length_28_nexthop(nexthop_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_28, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_28, + nexthop_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_28, + 0); +} + +action fib_hit_exm_prefix_length_27_nexthop(nexthop_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_27, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_27, + nexthop_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_27, + 0); +} + +action fib_hit_exm_prefix_length_26_nexthop(nexthop_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_26, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_26, + nexthop_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_26, + 0); +} + +action fib_hit_exm_prefix_length_25_nexthop(nexthop_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_25, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_25, + nexthop_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_25, + 0); +} + +action fib_hit_exm_prefix_length_24_nexthop(nexthop_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_24, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_24, + nexthop_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_24, + 0); +} + +action fib_hit_exm_prefix_length_23_nexthop(nexthop_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_23, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_23, + nexthop_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_23, + 0); +} + +action fib_hit_lpm_prefix_range_22_to_0_nexthop(nexthop_index) { + modify_field(ipv4_metadata.fib_hit_lpm_prefix_range_22_to_0, 1); + modify_field(ipv4_metadata.fib_nexthop_lpm_prefix_range_22_to_0, + nexthop_index); + modify_field(ipv4_metadata.fib_nexthop_type_lpm_prefix_range_22_to_0, + 0); +} + +action fib_hit_exm_prefix_length_32_ecmp(ecmp_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_32, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_32, ecmp_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_32, + 1); +} + +action fib_hit_exm_prefix_length_31_ecmp(ecmp_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_31, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_31, ecmp_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_31, + 1); +} + +action fib_hit_exm_prefix_length_30_ecmp(ecmp_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_30, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_30, ecmp_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_30, + 1); +} + +action fib_hit_exm_prefix_length_29_ecmp(ecmp_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_29, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_29, ecmp_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_29, + 1); +} + +action fib_hit_exm_prefix_length_28_ecmp(ecmp_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_28, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_28, ecmp_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_28, + 1); +} + +action fib_hit_exm_prefix_length_27_ecmp(ecmp_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_27, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_27, ecmp_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_27, + 1); +} + +action fib_hit_exm_prefix_length_26_ecmp(ecmp_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_26, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_26, ecmp_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_26, + 1); +} + +action fib_hit_exm_prefix_length_25_ecmp(ecmp_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_25, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_25, ecmp_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_25, + 1); +} + +action fib_hit_exm_prefix_length_24_ecmp(ecmp_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_24, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_24, ecmp_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_24, + 1); +} + +action fib_hit_exm_prefix_length_23_ecmp(ecmp_index) { + modify_field(ipv4_metadata.fib_hit_exm_prefix_length_23, 1); + modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_23, ecmp_index); + modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_23, + 1); +} + +action fib_hit_lpm_prefix_range_22_to_0_ecmp(ecmp_index) { + modify_field(ipv4_metadata.fib_hit_lpm_prefix_range_22_to_0, 1); + modify_field(ipv4_metadata.fib_nexthop_lpm_prefix_range_22_to_0, + ecmp_index); + modify_field(ipv4_metadata.fib_nexthop_type_lpm_prefix_range_22_to_0, + 1); +} + +table ipv4_fib_exm_prefix_length_32 { + reads { + ingress_metadata.vrf : exact; + ipv4_metadata.lkp_ipv4_da : exact; + } + actions { + on_miss; + fib_hit_exm_prefix_length_32_nexthop; + fib_hit_exm_prefix_length_32_ecmp; + } + size : 19200; +} + +table ipv4_fib_exm_prefix_length_31 { + reads { + ingress_metadata.vrf : exact; + ipv4_metadata.lkp_ipv4_da mask 0xFFFFFFFE: exact; + } + actions { + on_miss; + fib_hit_exm_prefix_length_31_nexthop; + fib_hit_exm_prefix_length_31_ecmp; + } + size : 1024; +} + +table ipv4_fib_exm_prefix_length_30 { + reads { + ingress_metadata.vrf : exact; + ipv4_metadata.lkp_ipv4_da mask 0xFFFFFFFC: exact; + } + actions { + on_miss; + fib_hit_exm_prefix_length_30_nexthop; + fib_hit_exm_prefix_length_30_ecmp; + } + size : 23040; +} + +table ipv4_fib_exm_prefix_length_29 { + reads { + ingress_metadata.vrf : exact; + ipv4_metadata.lkp_ipv4_da mask 0xFFFFFFF8 : exact; + } + actions { + on_miss; + fib_hit_exm_prefix_length_29_nexthop; + fib_hit_exm_prefix_length_29_ecmp; + } + size : 15360; +} + +table ipv4_fib_exm_prefix_length_28 { + reads { + ingress_metadata.vrf : exact; + ipv4_metadata.lkp_ipv4_da mask 0xFFFFFFF0 : exact; + } + actions { + on_miss; + fib_hit_exm_prefix_length_28_nexthop; + fib_hit_exm_prefix_length_28_ecmp; + } + size : 30720; +} + +table ipv4_fib_exm_prefix_length_27 { + reads { + ingress_metadata.vrf : exact; + ipv4_metadata.lkp_ipv4_da mask 0xFFFFFFE0 : exact; + } + actions { + on_miss; + fib_hit_exm_prefix_length_27_nexthop; + fib_hit_exm_prefix_length_27_ecmp; + } + size : 7680; +} + +table ipv4_fib_exm_prefix_length_26 { + reads { + ingress_metadata.vrf : exact; + ipv4_metadata.lkp_ipv4_da mask 0xFFFFFFC0 : exact; + } + actions { + on_miss; + fib_hit_exm_prefix_length_26_nexthop; + fib_hit_exm_prefix_length_26_ecmp; + } + size : 7680; +} + +table ipv4_fib_exm_prefix_length_25 { + reads { + ingress_metadata.vrf : exact; + ipv4_metadata.lkp_ipv4_da mask 0xFFFFFF80 : exact; + } + actions { + on_miss; + fib_hit_exm_prefix_length_25_nexthop; + fib_hit_exm_prefix_length_25_ecmp; + } + size : 3840; +} + +table ipv4_fib_exm_prefix_length_24 { + reads { + ingress_metadata.vrf : exact; + ipv4_metadata.lkp_ipv4_da mask 0xFFFFFF00 : exact; + } + actions { + on_miss; + fib_hit_exm_prefix_length_24_nexthop; + fib_hit_exm_prefix_length_24_ecmp; + } + size : 38400; +} + +table ipv4_fib_exm_prefix_length_23 { + reads { + ingress_metadata.vrf : exact; + ipv4_metadata.lkp_ipv4_da mask 0xFFFFFE00 : exact; + } + actions { + on_miss; + fib_hit_exm_prefix_length_23_nexthop; + fib_hit_exm_prefix_length_23_ecmp; + } + size : 30720; +} + +table ipv4_fib_lpm_prefix_range_22_to_0 { + reads { + ingress_metadata.vrf : exact; + ipv4_metadata.lkp_ipv4_da : lpm; + } + actions { + on_miss; + fib_hit_lpm_prefix_range_22_to_0_nexthop; + fib_hit_lpm_prefix_range_22_to_0_ecmp; + } + size : 512; +} +# 449 "p4src/ipv4.p4" +control process_ipv4_fib { + + + + apply(ipv4_fib_exm_prefix_length_32); + apply(ipv4_fib_exm_prefix_length_31); + apply(ipv4_fib_exm_prefix_length_30); + apply(ipv4_fib_exm_prefix_length_29); + apply(ipv4_fib_exm_prefix_length_28); + apply(ipv4_fib_exm_prefix_length_27); + apply(ipv4_fib_exm_prefix_length_26); + apply(ipv4_fib_exm_prefix_length_25); + apply(ipv4_fib_exm_prefix_length_24); + apply(ipv4_fib_exm_prefix_length_23); + apply(ipv4_fib_lpm_prefix_range_22_to_0); +# 472 "p4src/ipv4.p4" +} +# 506 "p4src/ipv4.p4" +control process_ipv4_urpf { +# 517 "p4src/ipv4.p4" +} +# 86 "p4src/switch.p4" 2 +# 1 "p4src/ipv6.p4" 1 +# 11 "p4src/ipv6.p4" +header_type ipv6_metadata_t { + fields { + lkp_ipv6_sa : 128; + lkp_ipv6_da : 128; + ipv6_unicast_enabled : 1; + ipv6_urpf_mode : 2; + + fib_hit_exm_prefix_length_128 : 1; + fib_nexthop_exm_prefix_length_128 : 16; + fib_nexthop_type_exm_prefix_length_128 : 1; + + fib_hit_lpm_prefix_range_127_to_65 : 1; + fib_nexthop_lpm_prefix_range_127_to_65 : 16; + fib_nexthop_type_lpm_prefix_range_127_to_65 : 1; + + fib_hit_exm_prefix_length_64 : 1; + fib_nexthop_exm_prefix_length_64 : 16; + fib_nexthop_type_exm_prefix_length_64 : 1; + + fib_hit_lpm_prefix_range_63_to_0 : 1; + fib_nexthop_lpm_prefix_range_63_to_0 : 16; + fib_nexthop_type_lpm_prefix_range_63_to_0 : 1; + + } +} +metadata ipv6_metadata_t ipv6_metadata; +# 67 "p4src/ipv6.p4" +control validate_outer_ipv6_header { + + + +} +# 233 "p4src/ipv6.p4" +control process_ipv6_fib { +# 249 "p4src/ipv6.p4" +} +# 284 "p4src/ipv6.p4" +control process_ipv6_urpf { +# 295 "p4src/ipv6.p4" +} +# 87 "p4src/switch.p4" 2 +# 1 "p4src/tunnel.p4" 1 + + + +header_type tunnel_metadata_t { + fields { + ingress_tunnel_type : 8; + tunnel_vni : 24; + mpls_enabled : 1; + mpls_label: 20; + mpls_exp: 3; + mpls_ttl: 8; + egress_tunnel_type : 8; + tunnel_index: 14; + tunnel_src_index : 9; + tunnel_smac_index : 9; + tunnel_dst_index : 14; + tunnel_dmac_index : 14; + vnid : 24; + } +} +metadata tunnel_metadata_t tunnel_metadata; +# 107 "p4src/tunnel.p4" +control process_ipv4_vtep { + + + + + + + +} + +control process_ipv6_vtep { + + + + + + + +} +# 302 "p4src/tunnel.p4" +control process_tunnel { + + + +} +# 346 "p4src/tunnel.p4" +control validate_mpls_header { + + + +} +# 440 "p4src/tunnel.p4" +control process_mpls { + + + +} +# 747 "p4src/tunnel.p4" +control process_tunnel_decap { +# 757 "p4src/tunnel.p4" +} +# 1316 "p4src/tunnel.p4" +control process_tunnel_encap { +# 1333 "p4src/tunnel.p4" +} +# 88 "p4src/switch.p4" 2 +# 1 "p4src/acl.p4" 1 + + + +header_type acl_metadata_t { + fields { + acl_deny : 1; + racl_deny : 1; + acl_nexthop : 16; + racl_nexthop : 16; + acl_nexthop_type : 1; + racl_nexthop_type : 1; + acl_redirect : 1; + racl_redirect : 1; + } +} + +metadata acl_metadata_t acl_metadata; +# 78 "p4src/acl.p4" +control process_mac_acl { + + + + + +} +# 170 "p4src/acl.p4" +control process_ip_acl { +# 184 "p4src/acl.p4" +} +# 227 "p4src/acl.p4" +control process_qos { + + + + + +} + + +action racl_log() { +} + +action racl_deny() { + modify_field(acl_metadata.racl_deny, 1); +} + +action racl_permit() { +} + +action racl_set_nat_mode(nat_mode) { + modify_field(nat_metadata.ingress_nat_mode, nat_mode); +} + +action racl_redirect_nexthop(nexthop_index) { + modify_field(acl_metadata.racl_redirect, 1); + modify_field(acl_metadata.racl_nexthop, nexthop_index); + modify_field(acl_metadata.racl_nexthop_type, 0); +} + +action racl_redirect_ecmp(ecmp_index) { + modify_field(acl_metadata.racl_redirect, 1); + modify_field(acl_metadata.racl_nexthop, ecmp_index); + modify_field(acl_metadata.racl_nexthop_type, 1); +} +# 296 "p4src/acl.p4" +control process_ipv4_racl { + + + + + +} +# 330 "p4src/acl.p4" +control process_ipv6_racl { + + + + + +} + +field_list mirror_info { + ingress_metadata.ifindex; + ingress_metadata.drop_reason; + l3_metadata.lkp_ip_ttl; +} + +action negative_mirror(clone_spec, drop_reason) { + modify_field(ingress_metadata.drop_reason, drop_reason); + clone_ingress_pkt_to_egress(clone_spec, mirror_info); + drop(); +} + +action redirect_to_cpu() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 64); + modify_field(ig_intr_md_for_tm.mcast_grp_a, 0); + modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); + + + +} + +action copy_to_cpu() { + clone_ingress_pkt_to_egress(250); +} + +action drop_packet() { + drop(); +} + +table system_acl { + reads { + ingress_metadata.if_label : ternary; + ingress_metadata.bd_label : ternary; + + + ipv4_metadata.lkp_ipv4_sa : ternary; + ipv4_metadata.lkp_ipv4_da : ternary; + l3_metadata.lkp_ip_proto : ternary; + + + l2_metadata.lkp_mac_sa : ternary; + l2_metadata.lkp_mac_da : ternary; + i_fabric_header.lkp_mac_type : ternary; + + + ingress_metadata.ipsg_check_fail : ternary; + acl_metadata.acl_deny : ternary; + acl_metadata.racl_deny: ternary; + l3_metadata.urpf_check_fail : ternary; + + + + + + i_fabric_header.routed : ternary; + ingress_metadata.src_is_link_local : ternary; + ingress_metadata.same_bd_check : ternary; + l3_metadata.lkp_ip_ttl : ternary; + l2_metadata.stp_state : ternary; + ingress_metadata.control_frame: ternary; + ipv4_metadata.ipv4_unicast_enabled : ternary; + + + ig_intr_md_for_tm.ucast_egress_port : ternary; + } + actions { + nop; + redirect_to_cpu; + copy_to_cpu; + drop_packet; + negative_mirror; + } + size : 512; +} + +control process_system_acl { + apply(system_acl); +} +# 452 "p4src/acl.p4" +control process_egress_acl { + + + +} +# 89 "p4src/switch.p4" 2 +# 1 "p4src/nat.p4" 1 +header_type nat_metadata_t { + fields { + ingress_nat_mode : 2; + egress_nat_mode : 2; + nat_nexthop : 16; + nat_hit : 1; + nat_rewrite_index : 16; + } +} + +metadata nat_metadata_t nat_metadata; +# 79 "p4src/nat.p4" +control process_nat { +# 94 "p4src/nat.p4" +} +# 109 "p4src/nat.p4" +control process_egress_nat { +# 118 "p4src/nat.p4" +} +# 90 "p4src/switch.p4" 2 +# 1 "p4src/multicast.p4" 1 +header_type multicast_metadata_t { + fields { + outer_ipv4_mcast_key_type : 1; + outer_ipv4_mcast_key : 8; + outer_ipv6_mcast_key_type : 1; + outer_ipv6_mcast_key : 8; + outer_mcast_route_hit : 1; + outer_mcast_mode : 2; + ip_multicast : 1; + mcast_route_hit : 1; + mcast_bridge_hit : 1; + ipv4_multicast_mode : 2; + ipv6_multicast_mode : 2; + igmp_snooping_enabled : 1; + mld_snooping_enabled : 1; + bd_mrpf_group : 16; + mcast_rpf_group : 16; + mcast_mode : 2; + multicast_route_mc_index : 16; + multicast_bridge_mc_index : 16; + } +} + +metadata multicast_metadata_t multicast_metadata; +# 45 "p4src/multicast.p4" +control process_outer_multicast_rpf { +# 54 "p4src/multicast.p4" +} +# 145 "p4src/multicast.p4" +control process_outer_ipv4_multicast { +# 156 "p4src/multicast.p4" +} +# 192 "p4src/multicast.p4" +control process_outer_ipv6_multicast { +# 203 "p4src/multicast.p4" +} + +control process_outer_multicast { +# 216 "p4src/multicast.p4" +} +# 244 "p4src/multicast.p4" +control process_multicast_rpf { + + + + + + + +} +# 350 "p4src/multicast.p4" +control process_ipv4_multicast { +# 368 "p4src/multicast.p4" +} +# 427 "p4src/multicast.p4" +control process_ipv6_multicast { +# 444 "p4src/multicast.p4" +} + +control process_multicast { +# 459 "p4src/multicast.p4" +} +# 91 "p4src/switch.p4" 2 +# 1 "p4src/nexthop.p4" 1 + + + +header_type nexthop_metadata_t { + fields { + nexthop_type : 1; + } +} + +metadata nexthop_metadata_t nexthop_metadata; + +action set_l2_redirect_action() { + modify_field(i_fabric_header.nexthop_index, l2_metadata.l2_nexthop); + modify_field(nexthop_metadata.nexthop_type, + l2_metadata.l2_nexthop_type); +} + +action set_acl_redirect_action() { + modify_field(i_fabric_header.nexthop_index, acl_metadata.acl_nexthop); + modify_field(nexthop_metadata.nexthop_type, + acl_metadata.acl_nexthop_type); +} + +action set_racl_redirect_action() { + modify_field(i_fabric_header.nexthop_index, acl_metadata.racl_nexthop); + modify_field(nexthop_metadata.nexthop_type, + acl_metadata.racl_nexthop_type); + modify_field(i_fabric_header.routed, 1); +} + +action set_fib_redirect_action() { + modify_field(i_fabric_header.nexthop_index, l3_metadata.fib_nexthop); + modify_field(nexthop_metadata.nexthop_type, + l3_metadata.fib_nexthop_type); + modify_field(i_fabric_header.routed, 1); + modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); + + + +} + +action set_nat_redirect_action() { + modify_field(i_fabric_header.nexthop_index, nat_metadata.nat_nexthop); + modify_field(nexthop_metadata.nexthop_type, 0); + modify_field(i_fabric_header.routed, 1); +} + +action set_multicast_route_action() { + modify_field(ig_intr_md_for_tm.mcast_grp_b, + multicast_metadata.multicast_route_mc_index); + + + +} + +action set_multicast_bridge_action() { + modify_field(ig_intr_md_for_tm.mcast_grp_b, + multicast_metadata.multicast_bridge_mc_index); + + + +} + + + +action set_fib_exm_prefix_length_32_redirect_action() { + + modify_field(nexthop_metadata.nexthop_type, + ipv4_metadata.fib_nexthop_type_exm_prefix_length_32); + modify_field(i_fabric_header.routed, 1); + modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); + + + +} + +action set_fib_exm_prefix_length_31_redirect_action() { + + modify_field(nexthop_metadata.nexthop_type, + ipv4_metadata.fib_nexthop_type_exm_prefix_length_31); + modify_field(i_fabric_header.routed, 1); + modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); + + + +} + +action set_fib_exm_prefix_length_30_redirect_action() { + + modify_field(nexthop_metadata.nexthop_type, + ipv4_metadata.fib_nexthop_type_exm_prefix_length_30); + modify_field(i_fabric_header.routed, 1); + modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); + + + +} + +action set_fib_exm_prefix_length_29_redirect_action() { + + modify_field(nexthop_metadata.nexthop_type, + ipv4_metadata.fib_nexthop_type_exm_prefix_length_29); + modify_field(i_fabric_header.routed, 1); + modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); + + + +} + +action set_fib_exm_prefix_length_28_redirect_action() { + + modify_field(nexthop_metadata.nexthop_type, + ipv4_metadata.fib_nexthop_type_exm_prefix_length_28); + modify_field(i_fabric_header.routed, 1); + modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); + + + +} + +action set_fib_exm_prefix_length_27_redirect_action() { + + modify_field(nexthop_metadata.nexthop_type, + ipv4_metadata.fib_nexthop_type_exm_prefix_length_27); + modify_field(i_fabric_header.routed, 1); + modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); + + + +} + +action set_fib_exm_prefix_length_26_redirect_action() { + + modify_field(nexthop_metadata.nexthop_type, + ipv4_metadata.fib_nexthop_type_exm_prefix_length_26); + modify_field(i_fabric_header.routed, 1); + modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); + + + +} + +action set_fib_exm_prefix_length_25_redirect_action() { + + modify_field(nexthop_metadata.nexthop_type, + ipv4_metadata.fib_nexthop_type_exm_prefix_length_25); + modify_field(i_fabric_header.routed, 1); + modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); + + + +} + +action set_fib_exm_prefix_length_24_redirect_action() { + + modify_field(nexthop_metadata.nexthop_type, + ipv4_metadata.fib_nexthop_type_exm_prefix_length_24); + modify_field(i_fabric_header.routed, 1); + modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); + + + +} + +action set_fib_exm_prefix_length_23_redirect_action() { + + modify_field(nexthop_metadata.nexthop_type, + ipv4_metadata.fib_nexthop_type_exm_prefix_length_23); + modify_field(i_fabric_header.routed, 1); + modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); + + + +} + +action set_fib_lpm_prefix_range_22_to_0_redirect_action() { + + modify_field(nexthop_metadata.nexthop_type, + ipv4_metadata.fib_nexthop_type_lpm_prefix_range_22_to_0); + modify_field(i_fabric_header.routed, 1); + modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); + + + +} +# 239 "p4src/nexthop.p4" +table fwd_result { + reads { +# 263 "p4src/nexthop.p4" + ipv4_metadata.fib_hit_exm_prefix_length_32 : ternary; + ipv4_metadata.fib_hit_exm_prefix_length_31 : ternary; + ipv4_metadata.fib_hit_exm_prefix_length_30 : ternary; + ipv4_metadata.fib_hit_exm_prefix_length_29 : ternary; + ipv4_metadata.fib_hit_exm_prefix_length_28 : ternary; + ipv4_metadata.fib_hit_exm_prefix_length_27 : ternary; + ipv4_metadata.fib_hit_exm_prefix_length_26 : ternary; + ipv4_metadata.fib_hit_exm_prefix_length_25 : ternary; + ipv4_metadata.fib_hit_exm_prefix_length_24 : ternary; + ipv4_metadata.fib_hit_exm_prefix_length_23 : ternary; + ipv4_metadata.fib_hit_lpm_prefix_range_22_to_0 : ternary; +# 282 "p4src/nexthop.p4" + } + actions { + nop; + set_l2_redirect_action; + set_acl_redirect_action; + set_racl_redirect_action; + set_fib_redirect_action; + set_nat_redirect_action; + + + + + + + set_fib_exm_prefix_length_32_redirect_action; + set_fib_exm_prefix_length_31_redirect_action; + set_fib_exm_prefix_length_30_redirect_action; + set_fib_exm_prefix_length_29_redirect_action; + set_fib_exm_prefix_length_28_redirect_action; + set_fib_exm_prefix_length_27_redirect_action; + set_fib_exm_prefix_length_26_redirect_action; + set_fib_exm_prefix_length_25_redirect_action; + set_fib_exm_prefix_length_24_redirect_action; + set_fib_exm_prefix_length_23_redirect_action; + set_fib_lpm_prefix_range_22_to_0_redirect_action; +# 315 "p4src/nexthop.p4" + } + size : 512; +} + +control process_merge_results { + apply(fwd_result); +} + +field_list l3_hash_fields { + ipv4_metadata.lkp_ipv4_sa; + ipv4_metadata.lkp_ipv4_da; + l3_metadata.lkp_ip_proto; + ingress_metadata.lkp_l4_sport; + ingress_metadata.lkp_l4_dport; +} + +field_list_calculation ecmp_hash { + input { + l3_hash_fields; + } + algorithm : crc16; + output_width : 10; +} + +action_selector ecmp_selector { + selection_key : ecmp_hash; +} + +action_profile ecmp_action_profile { + actions { + nop; + set_ecmp_nexthop_details; + set_ecmp_nexthop_details_for_post_routed_flood; + } + size : 16384; + dynamic_action_selection : ecmp_selector; +} + +table ecmp_group { + reads { + i_fabric_header.nexthop_index : exact; + } + action_profile: ecmp_action_profile; + size : 1024; +} + +action set_nexthop_details(ifindex, bd) { + modify_field(ingress_metadata.egress_ifindex, ifindex); + modify_field(i_fabric_header.egress_bd, bd); + bit_xor(ingress_metadata.same_bd_check, ingress_metadata.bd, bd); +} + +action set_ecmp_nexthop_details(ifindex, bd, nhop_index) { + modify_field(ingress_metadata.egress_ifindex, ifindex); + modify_field(i_fabric_header.egress_bd, bd); + modify_field(i_fabric_header.nexthop_index, nhop_index); + bit_xor(ingress_metadata.same_bd_check, ingress_metadata.bd, bd); +} + + + + + +action set_nexthop_details_for_post_routed_flood(bd, uuc_mc_index) { + modify_field(ig_intr_md_for_tm.mcast_grp_b, uuc_mc_index); + modify_field(i_fabric_header.egress_bd, bd); + bit_xor(ingress_metadata.same_bd_check, ingress_metadata.bd, bd); + + + +} + +action set_ecmp_nexthop_details_for_post_routed_flood(bd, uuc_mc_index, + nhop_index) { + modify_field(ig_intr_md_for_tm.mcast_grp_b, uuc_mc_index); + modify_field(i_fabric_header.egress_bd, bd); + modify_field(i_fabric_header.nexthop_index, nhop_index); + bit_xor(ingress_metadata.same_bd_check, ingress_metadata.bd, bd); + + + +} + +table nexthop { + reads { + i_fabric_header.nexthop_index : exact; + } + actions { + nop; + set_nexthop_details; + set_nexthop_details_for_post_routed_flood; + } + size : 1024; +} + +control process_nexthop { + if (nexthop_metadata.nexthop_type == 1) { + + apply(ecmp_group); + } else { + + apply(nexthop); + } +} +# 92 "p4src/switch.p4" 2 +# 1 "p4src/rewrite.p4" 1 +action set_l2_rewrite() { + modify_field(egress_metadata.routed, 0); + modify_field(egress_metadata.bd, i_fabric_header.egress_bd); +} + +action set_ipv4_unicast_rewrite(smac_idx, dmac) { + modify_field(egress_metadata.smac_idx, smac_idx); + modify_field(egress_metadata.mac_da, dmac); + modify_field(egress_metadata.routed, 1); + add_to_field(ipv4.ttl, -1); + modify_field(egress_metadata.bd, i_fabric_header.egress_bd); +} + +action set_ipv6_unicast_rewrite(smac_idx, dmac) { + modify_field(egress_metadata.smac_idx, smac_idx); + modify_field(egress_metadata.mac_da, dmac); + modify_field(egress_metadata.routed, 1); + add_to_field(ipv6.hopLimit, -1); + modify_field(egress_metadata.bd, i_fabric_header.egress_bd); +} + +action set_ipv4_vxlan_rewrite(outer_bd, tunnel_index, smac_idx, dmac) { + modify_field(egress_metadata.bd, outer_bd); + modify_field(egress_metadata.smac_idx, smac_idx); + modify_field(egress_metadata.mac_da, dmac); + modify_field(tunnel_metadata.tunnel_index, tunnel_index); + modify_field(tunnel_metadata.egress_tunnel_type, 1); +} + +action set_ipv6_vxlan_rewrite(outer_bd, tunnel_index, smac_idx, dmac) { + modify_field(egress_metadata.bd, outer_bd); + modify_field(egress_metadata.smac_idx, smac_idx); + modify_field(egress_metadata.mac_da, dmac); + modify_field(tunnel_metadata.tunnel_index, tunnel_index); + modify_field(tunnel_metadata.egress_tunnel_type, 2); +} + +action set_ipv4_geneve_rewrite(outer_bd, tunnel_index, smac_idx, dmac) { + modify_field(egress_metadata.bd, outer_bd); + modify_field(egress_metadata.smac_idx, smac_idx); + modify_field(egress_metadata.mac_da, dmac); + modify_field(tunnel_metadata.tunnel_index, tunnel_index); + modify_field(tunnel_metadata.egress_tunnel_type, 3); +} + +action set_ipv6_geneve_rewrite(outer_bd, tunnel_index, smac_idx, dmac) { + modify_field(egress_metadata.bd, outer_bd); + modify_field(egress_metadata.smac_idx, smac_idx); + modify_field(egress_metadata.mac_da, dmac); + modify_field(tunnel_metadata.tunnel_index, tunnel_index); + modify_field(tunnel_metadata.egress_tunnel_type, 4); +} + +action set_ipv4_nvgre_rewrite(outer_bd, tunnel_index, smac_idx, dmac) { + modify_field(egress_metadata.bd, outer_bd); + modify_field(egress_metadata.smac_idx, smac_idx); + modify_field(egress_metadata.mac_da, dmac); + modify_field(tunnel_metadata.tunnel_index, tunnel_index); + modify_field(tunnel_metadata.egress_tunnel_type, 5); +} + +action set_ipv6_nvgre_rewrite(outer_bd, tunnel_index, smac_idx, dmac) { + modify_field(egress_metadata.bd, outer_bd); + modify_field(egress_metadata.smac_idx, smac_idx); + modify_field(egress_metadata.mac_da, dmac); + modify_field(tunnel_metadata.tunnel_index, tunnel_index); + modify_field(tunnel_metadata.egress_tunnel_type, 6); +} + +action set_ipv4_erspan_v2_rewrite(outer_bd, tunnel_index, smac_idx, dmac) { + modify_field(egress_metadata.bd, outer_bd); + modify_field(egress_metadata.smac_idx, smac_idx); + modify_field(egress_metadata.mac_da, dmac); + modify_field(tunnel_metadata.tunnel_index, tunnel_index); + modify_field(tunnel_metadata.egress_tunnel_type, 7); +} + +action set_ipv6_erspan_v2_rewrite(outer_bd, tunnel_index, smac_idx, dmac) { + modify_field(egress_metadata.bd, outer_bd); + modify_field(egress_metadata.smac_idx, smac_idx); + modify_field(egress_metadata.mac_da, dmac); + modify_field(tunnel_metadata.tunnel_index, tunnel_index); + modify_field(tunnel_metadata.egress_tunnel_type, 8); +} +# 135 "p4src/rewrite.p4" +table rewrite { + reads { + i_fabric_header.nexthop_index : exact; + } + actions { + nop; + set_l2_rewrite; + set_ipv4_unicast_rewrite; +# 175 "p4src/rewrite.p4" + } + size : 1024; +} + +control process_rewrite { + apply(rewrite); +} +# 93 "p4src/switch.p4" 2 +# 1 "p4src/security.p4" 1 + + + +header_type security_metadata_t { + fields { + storm_control_color : 1; + ipsg_enabled : 1; + } +} + +metadata security_metadata_t security_metadata; +# 38 "p4src/security.p4" +control process_storm_control { + + + +} +# 75 "p4src/security.p4" +control process_ip_sourceguard { +# 86 "p4src/security.p4" +} +# 94 "p4src/switch.p4" 2 +# 1 "p4src/fabric.p4" 1 + + + +metadata fabric_header_internal_t i_fabric_header; + + +action add_i_fabric_header(etherType) { + + + + + + + modify_field(i_fabric_header.ingress_tunnel_type, + tunnel_metadata.ingress_tunnel_type); + modify_field(i_fabric_header.lkp_mac_type, etherType); + + + +} +# 135 "p4src/fabric.p4" +control process_fabric_ingress { + + + +} +# 267 "p4src/fabric.p4" +control process_fabric_lag { + + + +} + +action cpu_tx_rewrite() { + modify_field(ethernet.etherType, fabric_payload_header.etherType); + remove_header(fabric_header); + remove_header(fabric_header_cpu); + remove_header(fabric_payload_header); + modify_field(egress_metadata.fabric_bypass, 1); +} + +action cpu_rx_rewrite() { + add_header(fabric_header); + add_header(fabric_header_cpu); + modify_field(fabric_header.headerVersion, 0); + modify_field(fabric_header.packetVersion, 0); + modify_field(fabric_header.pad1, 0); + modify_field(fabric_header.packetType, 6); + modify_field(fabric_header_cpu.port, ig_intr_md.ingress_port); + modify_field(egress_metadata.fabric_bypass, 1); + + + + add_header(fabric_payload_header); + modify_field(fabric_payload_header.etherType, ethernet.etherType); + modify_field(ethernet.etherType, 0x9000); + +} + + + + + + + +table fabric_rewrite { + reads { + eg_intr_md.egress_port : ternary; + ig_intr_md.ingress_port : ternary; + } + actions { + nop; + cpu_tx_rewrite; + cpu_rx_rewrite; + + + + } + size : 512; +} + +control process_fabric_egress { + apply(fabric_rewrite); +} + +action strip_i_fabric_header() { + remove_header(i_fabric_header); + remove_header(fabric_payload_header); +} + +table egress_i_fabric_rewrite { + reads { + i_fabric_header : valid; + } + actions { + strip_i_fabric_header; + } +} + +control process_i_fabric_egress { + + + +} +# 95 "p4src/switch.p4" 2 +# 1 "p4src/egress_filter.p4" 1 +# 40 "p4src/egress_filter.p4" +control process_egress_filter { +# 51 "p4src/egress_filter.p4" +} +# 96 "p4src/switch.p4" 2 + +action nop() { +} + +action on_miss() { +} + +control ingress { + + if (valid(fabric_header)) { + + + process_fabric_ingress(); + } else { + + + validate_outer_ethernet_header(); + + + if (valid(ipv4)) { + validate_outer_ipv4_header(); + } else { + if (valid(ipv6)) { + validate_outer_ipv6_header(); + } + } + + if (valid(mpls[0])) { + validate_mpls_header(); + } + + + + + + + process_port_mapping(); + + process_storm_control(); + + + process_port_vlan_mapping(); + process_spanning_tree(); + process_ip_sourceguard(); +# 182 "p4src/switch.p4" + process_validate_packet(); + + + process_mac(); + + + if (l3_metadata.lkp_ip_type == 0) { + process_mac_acl(); + } else { + process_ip_acl(); + } + + process_qos(); + + apply(rmac) { + rmac_miss { + process_multicast(); + } + default { + if ((l3_metadata.lkp_ip_type == 1) and + (ipv4_metadata.ipv4_unicast_enabled == 1)) { + + process_ipv4_racl(); + process_nat(); + + process_ipv4_urpf(); + process_ipv4_fib(); + + } else { + if ((l3_metadata.lkp_ip_type == 2) and + (ipv6_metadata.ipv6_unicast_enabled == 1)) { + + + process_ipv6_racl(); + process_ipv6_urpf(); + process_ipv6_fib(); + } + } + process_urpf_bd(); + } + } + + + + + + + process_merge_results(); + + + process_nexthop(); + + + process_ingress_bd_stats(); + + + process_lag(); + + + process_mac_learning(); + } + + + process_fabric_lag(); + + + process_system_acl(); +} + +control egress { + + if (egress_metadata.egress_bypass == 0) { + + + process_fabric_egress(); + + if (egress_metadata.fabric_bypass == 0) { + + process_replication(); + + process_vlan_decap(); + + + process_tunnel_decap(); + + + process_egress_bd(); + + process_egress_nat(); + + + process_rewrite(); + + + process_mac_rewrite(); + + + process_tunnel_encap(); + + process_mtu(); + + + process_vlan_xlate(); + + + process_egress_filter(); + + + process_egress_acl(); + + + process_i_fabric_egress(); + } + } +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_102_clone.NOT_READY b/backends/tofino/bf-asm/test/internal/test_config_102_clone.NOT_READY new file mode 100644 index 00000000000..3940590adf9 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_102_clone.NOT_READY @@ -0,0 +1,97 @@ +#include +#include +#include + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +parser start { + return select(current(0,1)) { + 0 mask 0: abc; + default: ingress; + } +} + +parser abc { + extract(ethernet); + return ingress; +} +header ethernet_t ethernet; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +header_type metadata_h { + fields { + foo : 8; + } +} +metadata metadata_h m; + +field_list mirror_list { + m.foo; +} + +action ingr_action () { + clone_i2e(5, mirror_list); +} +action ingr_action2 () { + clone_i2e(6); +} + +action egr_action () { + clone_e2e(7, mirror_list); +} +action egr_action2 () { + clone_e2e(8); +} + + +table ingr_null_table { + reads { + ig_intr_md_from_parser_aux.ingress_parser_err : exact; + } + actions { + ingr_action; + ingr_action2; + } +} + +table egr_null_table { + reads { + eg_intr_md_from_parser_aux.egress_parser_err : exact; + ethernet.dstAddr : exact; + m.foo : exact; + } + actions { + egr_action; + egr_action2; + } +} + + +control ingress { + apply(ingr_null_table); +} + +control egress { + apply(egr_null_table); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_102_clone.p4 b/backends/tofino/bf-asm/test/internal/test_config_102_clone.p4 new file mode 100644 index 00000000000..3940590adf9 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_102_clone.p4 @@ -0,0 +1,97 @@ +#include +#include +#include + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +parser start { + return select(current(0,1)) { + 0 mask 0: abc; + default: ingress; + } +} + +parser abc { + extract(ethernet); + return ingress; +} +header ethernet_t ethernet; + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +header_type metadata_h { + fields { + foo : 8; + } +} +metadata metadata_h m; + +field_list mirror_list { + m.foo; +} + +action ingr_action () { + clone_i2e(5, mirror_list); +} +action ingr_action2 () { + clone_i2e(6); +} + +action egr_action () { + clone_e2e(7, mirror_list); +} +action egr_action2 () { + clone_e2e(8); +} + + +table ingr_null_table { + reads { + ig_intr_md_from_parser_aux.ingress_parser_err : exact; + } + actions { + ingr_action; + ingr_action2; + } +} + +table egr_null_table { + reads { + eg_intr_md_from_parser_aux.egress_parser_err : exact; + ethernet.dstAddr : exact; + m.foo : exact; + } + actions { + egr_action; + egr_action2; + } +} + + +control ingress { + apply(ingr_null_table); +} + +control egress { + apply(egr_null_table); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_103_first_phase_0.p4 b/backends/tofino/bf-asm/test/internal/test_config_103_first_phase_0.p4 new file mode 100644 index 00000000000..81322c48749 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_103_first_phase_0.p4 @@ -0,0 +1,129 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + color_0 : 8; + } +} + +header_type meta_t { + fields { + field_a0_1 : 1; + field_a1_1 : 1; + field_a2_1 : 1; + field_a3_1 : 1; + field_b_4 : 4; + field_c_4 : 4; + field_d_4 : 4; + field_e_4 : 4; + field_f_4 : 4; + field_g_4 : 4; + field_h0_1 : 1; + field_h1_1 : 1; + field_h2_1 : 1; + field_h3_1 : 1; + } +} + +parser start { + return parse_pkt; +} + +header pkt_t pkt; +metadata meta_t meta; + +parser parse_pkt { + extract(pkt); + return ingress; +} + + +action action_0(param0, param1, param2, param3, param4, param5){ + modify_field(meta.field_a0_1, 0); + modify_field(meta.field_a1_1, param0); + modify_field(meta.field_a2_1, 1); + modify_field(meta.field_a3_1, param1); + modify_field(meta.field_b_4, 9); + modify_field(meta.field_c_4, param2); + modify_field(meta.field_d_4, 6); + modify_field(meta.field_e_4, 10); + modify_field(meta.field_f_4, 15, 0xf); + modify_field(meta.field_g_4, param3); + modify_field(meta.field_h0_1, param4); + modify_field(meta.field_h1_1, 0); + modify_field(meta.field_h2_1, param5); + modify_field(meta.field_h3_1, 1); +} + +action action_1(param0){ + modify_field(pkt.field_f_16, param0); +} + +action do_nothing(){ + no_op(); +} + +table table_0 { + reads { + ig_intr_md.ingress_port : exact; + } + actions { + action_0; + } + size : 128; +} + +@pragma include_idletime 1 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 1 +table table_1 { + reads { + pkt.field_g_16 : exact; + pkt.color_0 : exact; + + meta.field_a0_1 : exact; + meta.field_a1_1 : exact; + meta.field_a2_1 : exact; + meta.field_a3_1 : exact; + + meta.field_b_4 : exact; + meta.field_c_4 : exact; + meta.field_d_4 : exact; + meta.field_e_4 : exact; + meta.field_f_4 : exact; + meta.field_g_4 : exact; + + meta.field_h0_1 : exact; + meta.field_h1_1 : exact; + meta.field_h2_1 : exact; + meta.field_h3_1 : exact; + + } + actions { + action_1; + } + size : 65536; +} + +/* Main control flow */ + +control ingress { + if (0 == ig_intr_md.resubmit_flag){ + apply(table_0); + apply(table_1); + } +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_10_new_crossbar_allocation.p4 b/backends/tofino/bf-asm/test/internal/test_config_10_new_crossbar_allocation.p4 new file mode 100644 index 00000000000..04d6ca8c5a6 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_10_new_crossbar_allocation.p4 @@ -0,0 +1,120 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +action action_0(){ + modify_field(ipv4.diffserv, 1); +} + +action action_1() { + modify_field(ipv4.totalLen, 2); +} + +action action_2() { + modify_field(ipv4.identification, 3); +} + +action action_3(param_3) { + modify_field(ipv4.ttl, param_3); +} + +action action_4(param_4) { + modify_field(ipv4.protocol, param_4); +} + +action do_nothing(){ + no_op(); +} + + +table table_0 { + reads { + ethernet.etherType : ternary; + ethernet.srcAddr mask 0xffffffff00: ternary; + } + actions { + action_0; + do_nothing; + } + max_size : 1024; +} + +@pragma ways 6 +@pragma pack 3 +table table_1 { + reads { + ipv4.srcAddr : exact; + ipv4.dstAddr : exact; + ipv4.fragOffset : exact; + ethernet.srcAddr : exact; + ethernet.dstAddr : exact; + //ipv4.dstAddr mask 0xffff0000 : ternary; + //ethernet.srcAddr : ternary; + //ethernet.dstAddr : ternary; + } + actions { + action_1; + do_nothing; + } + max_size : 40960; +} + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_1); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_114_simple_drop.p4 b/backends/tofino/bf-asm/test/internal/test_config_114_simple_drop.p4 new file mode 100644 index 00000000000..33985ed7a05 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_114_simple_drop.p4 @@ -0,0 +1,71 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + + field_e : 32; + field_f : 32; + field_g : 32; + field_h : 32; + field_i : 32; + field_j : 32; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action nop(){ + no_op(); +} + +action action_0(){ + drop(); +} + +action action_1(){ + drop(); +} + +table table_0 { + reads { + pkt.field_b : exact; + } + actions { + action_0; + nop; + } + size : 256000; +} + +table table_1 { + reads { + pkt.field_d : exact; + } + actions { + action_1; + nop; + } +} + + +control ingress { + apply(table_0); +} + +control egress { + apply(table_1); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_115_hash_parity_groups.p4 b/backends/tofino/bf-asm/test/internal/test_config_115_hash_parity_groups.p4 new file mode 100644 index 00000000000..693c57ae23b --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_115_hash_parity_groups.p4 @@ -0,0 +1,103 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_m_32 : 32; + field_n_32 : 32; + } +} + + +parser start { + return parse_pkt; +} + +header pkt_t pkt; + +parser parse_pkt { + extract(pkt); + return ingress; +} + + +action do_nothing(){ + no_op(); +} + +table table_0 { + reads { + pkt.field_a_32 : exact; + pkt.field_b_32 : exact; + pkt.field_c_32 : exact; + pkt.field_d_32 : exact; + pkt.field_e_16 : exact; + } + actions { + do_nothing; + } + size : 4096; +} + +table table_1 { + reads { + pkt.field_i_8 : exact; + pkt.field_j_8 : exact; + pkt.field_k_8 : exact; + } + actions { + do_nothing; + } + size : 4096; +} + +table table_2 { + reads { + pkt.field_a_32 : exact; + pkt.field_b_32 : exact; + pkt.field_c_32 : exact; + pkt.field_d_32 : exact; + pkt.field_e_16 : exact; + pkt.field_j_8 : exact; +/* + pkt.field_c_32 : exact; + pkt.field_n_32 : exact; + pkt.field_f_16 : exact; + pkt.field_g_16 : exact; + pkt.field_h_16 : exact; + pkt.field_i_8 : exact; + pkt.field_k_8 : exact; + pkt.field_j_8 : exact; +*/ + } + actions { + do_nothing; + } +} + +/* Main control flow */ + +control ingress { + if (valid(pkt)){ + apply(table_0); + apply(table_1); + apply(table_2); + } +} + + diff --git a/backends/tofino/bf-asm/test/internal/test_config_116_predication_with_condition.p4 b/backends/tofino/bf-asm/test/internal/test_config_116_predication_with_condition.p4 new file mode 100644 index 00000000000..3a8a97e22c8 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_116_predication_with_condition.p4 @@ -0,0 +1,109 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_m_32 : 32; + field_n_32 : 32; + } +} + + +parser start { + return parse_pkt; +} + +header pkt_t pkt; + +parser parse_pkt { + extract(pkt); + return ingress; +} + +action action_0(param0){ + modify_field(pkt.field_f_16, param0); +} + +action action_1(param0){ + modify_field(pkt.field_f_16, param0); +} + +action action_2(param0){ + modify_field(pkt.field_f_16, param0); +} + +action do_nothing(){ + no_op(); +} + +action do_nothing_1(){ +} + +table table_0 { + reads { + pkt.field_a_32 : exact; + } + actions { + do_nothing; + action_0; + } + size : 4096; +} + +table table_1 { + reads { + pkt.field_b_32 : exact; + } + actions { + do_nothing_1; + action_1; + } + size : 4096; +} + +table table_2 { + reads { + pkt.field_b_32 : exact; + } + actions { + do_nothing; + action_2; + } + size : 4096; +} + + +/* Main control flow */ + +control ingress { + apply(table_0){ + do_nothing { + if (valid(pkt)){ + apply(table_1){ + do_nothing_1 { + if(valid(pkt)){ + apply(table_2); + } + } + } + } + } + } +} + + diff --git a/backends/tofino/bf-asm/test/internal/test_config_117_first_tcam_range.p4 b/backends/tofino/bf-asm/test/internal/test_config_117_first_tcam_range.p4 new file mode 100644 index 00000000000..93a2504d488 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_117_first_tcam_range.p4 @@ -0,0 +1,68 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_m_32 : 32; + field_n_32 : 32; + } +} + + +parser start { + return parse_pkt; +} + +header pkt_t pkt; + +parser parse_pkt { + extract(pkt); + return ingress; +} + +action action_0(){ + modify_field(pkt.field_f_16, 1); +} + +action do_nothing(){ + no_op(); +} + +action do_nothing_1(){ +} + +table table_0 { + reads { + pkt.field_e_16 : range; + pkt.field_f_16 : exact; + } + actions { + do_nothing; + action_0; + } + size : 1024; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} + + diff --git a/backends/tofino/bf-asm/test/internal/test_config_118_tcam_range_2.p4 b/backends/tofino/bf-asm/test/internal/test_config_118_tcam_range_2.p4 new file mode 100644 index 00000000000..82c6b6703bb --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_118_tcam_range_2.p4 @@ -0,0 +1,88 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_m_32 : 32; + field_n_32 : 32; + + field_o_4 : 4; + field_p_4 : 4; + } +} + + +parser start { + return parse_pkt; +} + +header pkt_t pkt; + +parser parse_pkt { + extract(pkt); + return ingress; +} + +action action_0(){ + modify_field(pkt.field_g_16, 1); +} + +action action_1(){ + modify_field(pkt.field_h_16, 1); +} + +action do_nothing(){ + no_op(); +} + +action do_nothing_1(){ +} + +table table_0 { + reads { + pkt.field_o_4 : range; + pkt.field_f_16 : exact; + } + actions { + do_nothing; + action_0; + } + size : 1024; +} + +table table_1 { + reads { + pkt.field_p_4 : range; + pkt.field_f_16 : exact; + } + actions { + do_nothing; + action_1; + } + size : 1024; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_1); +} + + diff --git a/backends/tofino/bf-asm/test/internal/test_config_119_tcam_range_3.p4 b/backends/tofino/bf-asm/test/internal/test_config_119_tcam_range_3.p4 new file mode 100644 index 00000000000..495e3a68996 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_119_tcam_range_3.p4 @@ -0,0 +1,88 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_m_32 : 32; + field_n_32 : 32; + + field_o_12 : 12; + field_p_12 : 12; + } +} + + +parser start { + return parse_pkt; +} + +header pkt_t pkt; + +parser parse_pkt { + extract(pkt); + return ingress; +} + +action action_0(){ + modify_field(pkt.field_g_16, 1); +} + +action action_1(){ + modify_field(pkt.field_h_16, 1); +} + +action do_nothing(){ + no_op(); +} + +action do_nothing_1(){ +} + +table table_0 { + reads { + pkt.field_o_12 : range; + pkt.field_f_16 : exact; + } + actions { + do_nothing; + action_0; + } + size : 1024; +} + +table table_1 { + reads { + pkt.field_p_12 : range; + pkt.field_f_16 : exact; + } + actions { + do_nothing; + action_1; + } + size : 1024; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_1); +} + + diff --git a/backends/tofino/bf-asm/test/internal/test_config_11_simple_gateway_table.p4 b/backends/tofino/bf-asm/test/internal/test_config_11_simple_gateway_table.p4 new file mode 100644 index 00000000000..00ae5b66dd5 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_11_simple_gateway_table.p4 @@ -0,0 +1,121 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +action action_0(){ + modify_field(ipv4.diffserv, 1); +} + +action action_1() { + modify_field(ipv4.totalLen, 2); +} + +action action_2() { + modify_field(ipv4.ttl, 3); +} + +action do_nothing(){ + no_op(); +} + + +table table_0 { + reads { + ethernet.etherType : lpm; + //ethernet.srcAddr : exact; + } + actions { + action_0; + do_nothing; + } + max_size : 1024; +} + +table table_1 { + reads { + ipv4.srcAddr : exact; + ipv4.dstAddr : exact; + } + actions { + action_1; + do_nothing; + } + max_size : 16384; +} + +table table_2 { + reads { + ipv4.srcAddr : exact; + } + actions { + action_2; + do_nothing; + } + max_size : 4096; +} + +/* Main control flow */ + +control ingress { + + if (ethernet.etherType == 0x0800){ + //if (ipv4.version == 4){ + apply(table_0); + } + + + if (valid(ipv4)){ + apply(table_1); + } + + + if (ethernet.etherType == ipv4.totalLen){ + apply(table_2); + } + +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_120_tcam_range_4.p4 b/backends/tofino/bf-asm/test/internal/test_config_120_tcam_range_4.p4 new file mode 100644 index 00000000000..21264a5088c --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_120_tcam_range_4.p4 @@ -0,0 +1,88 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_m_32 : 32; + field_n_32 : 32; + + field_o_4 : 4; + field_p_16 : 12; + } +} + + +parser start { + return parse_pkt; +} + +header pkt_t pkt; + +parser parse_pkt { + extract(pkt); + return ingress; +} + +action action_0(){ + modify_field(pkt.field_g_16, 1); +} + +action action_1(){ + modify_field(pkt.field_h_16, 1); +} + +action do_nothing(){ + no_op(); +} + +action do_nothing_1(){ +} + +table table_0 { + reads { + pkt.field_o_4 : range; + pkt.field_f_16 : exact; + } + actions { + do_nothing; + action_0; + } + size : 1024; +} + +table table_1 { + reads { + pkt.field_p_16 : range; + pkt.field_f_16 : exact; + } + actions { + do_nothing; + action_1; + } + size : 1024; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_1); +} + + diff --git a/backends/tofino/bf-asm/test/internal/test_config_121_tcam_range_5.p4 b/backends/tofino/bf-asm/test/internal/test_config_121_tcam_range_5.p4 new file mode 100644 index 00000000000..8f3de5840fd --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_121_tcam_range_5.p4 @@ -0,0 +1,88 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_m_32 : 32; + field_n_32 : 32; + + field_o_17 : 17; + field_p_15 : 15; + } +} + + +parser start { + return parse_pkt; +} + +header pkt_t pkt; + +parser parse_pkt { + extract(pkt); + return ingress; +} + +action action_0(){ + modify_field(pkt.field_g_16, 1); +} + +action action_1(){ + modify_field(pkt.field_h_16, 1); +} + +action do_nothing(){ + no_op(); +} + +action do_nothing_1(){ +} + +table table_0 { + reads { + pkt.field_o_17 : range; + pkt.field_f_16 : exact; + } + actions { + do_nothing; + action_0; + } + size : 1024; +} + +table table_1 { + reads { + pkt.field_p_15 : range; + pkt.field_f_16 : exact; + } + actions { + do_nothing; + action_1; + } + size : 1024; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_1); +} + + diff --git a/backends/tofino/bf-asm/test/internal/test_config_122_tcam_range_6.p4 b/backends/tofino/bf-asm/test/internal/test_config_122_tcam_range_6.p4 new file mode 100644 index 00000000000..c07a362641d --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_122_tcam_range_6.p4 @@ -0,0 +1,70 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_m_32 : 32; + field_n_32 : 32; + } +} + + +parser start { + return parse_pkt; +} + +header pkt_t pkt; + +parser parse_pkt { + extract(pkt); + return ingress; +} + +action action_0(){ + modify_field(pkt.field_f_16, 1); +} + +action do_nothing(){ + no_op(); +} + +action do_nothing_1(){ +} + +@pragma entries_with_ranges 64 +table table_0 { + reads { + pkt.field_e_16 : range; + pkt.field_f_16 : range; + pkt.field_g_16 : exact; + } + actions { + do_nothing; + action_0; + } + size : 512; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} + + diff --git a/backends/tofino/bf-asm/test/internal/test_config_123_meter_2.p4 b/backends/tofino/bf-asm/test/internal/test_config_123_meter_2.p4 new file mode 100644 index 00000000000..490c6f499af --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_123_meter_2.p4 @@ -0,0 +1,118 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + color_0 : 8; + pad_0 : 24; + pad_1 : 160; + pad_2 : 24; + color_1 : 8; + pad_3 : 24; + + lpf : 16; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +meter meter_0 { + type : bytes; + //static : table_0; + direct : table_0; + result : pkt.color_0; // Over-loading the meaning of result to be the input and output + //instance_count : 500; + //implementation : red; +} + + +meter meter_1 { + type : bytes; + static : table_1; + //direct : table_1; + result : pkt.color_1; + instance_count : 4097; +} + + +action action_0(param0){ + //modify_field(pkt.field_f_16, param0); + //execute_meter(meter_0, 7, pkt.color_0); +} + + +action action_1(param0){ + //modify_field(pkt.field_g_16, param0); + execute_meter(meter_1, 7, pkt.color_1); +} + + +action do_nothing(){ + no_op(); +// drop(); +} + + + +//@pragma include_idletime 1 +@pragma pa_solitare meter_result.color_0, meter_result.color_1 +@pragma include_stash 1 +@pragma action_default_only do_nothing +table table_0 { + reads { + pkt.field_e_16 : ternary; + pkt.color_0 : exact; //HACK + pkt.color_1 : exact; //HACK + pkt.lpf : exact; //HACK + } + actions { + action_0; + //do_nothing; + } + size : 6000; +} + + +//@pragma include_idletime 1 +@pragma idletime_two_way_notification 1 +@pragma include_stash 1 +table table_1 { + reads { + pkt.field_e_16: exact; + } + actions { + do_nothing; + action_1; + } + size : 32768; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_1); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_124_meter_3.p4 b/backends/tofino/bf-asm/test/internal/test_config_124_meter_3.p4 new file mode 100644 index 00000000000..bb2bc26cace --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_124_meter_3.p4 @@ -0,0 +1,113 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + color_0 : 8; + pad_0 : 24; + pad_1 : 16; + pad_2 : 24; + color_1 : 8; + pad_3 : 24; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +meter meter_0 { + type : bytes; + //static : table_0; + direct : table_0; + result : pkt.color_0; + //instance_count : 500; +} + + +meter meter_1 { + type : bytes; + static : table_1; + //direct : table_1; + result : pkt.color_1; + instance_count : 500; +} + + +action action_0(param0){ + //modify_field(pkt.field_f_16, param0); + //execute_meter(meter_0, 7, pkt.color_0); +} + + +action action_1(param0){ + //modify_field(pkt.field_g_16, param0); + execute_meter(meter_1, 7, pkt.color_1); +} + + +action do_nothing(){ + no_op(); +// drop(); +} + + + +//@pragma include_idletime 1 +@pragma pa_solitare meter_result.color_0, meter_result.color_1 +//@pragma include_stash 1 +table table_0 { + reads { + pkt.field_e_16 : ternary; + pkt.color_0 : exact; //HACK + pkt.color_1 : exact; //HACK + } + actions { + action_0; +// do_nothing; + } + size : 6000; +} + + +//@pragma include_idletime 1 +@pragma idletime_two_way_notification 1 +//@pragma include_stash 1 +table table_1 { + reads { + pkt.field_e_16: exact; + } + actions { + do_nothing; + action_1; + } + size : 32768; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_1); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_125_meter_pre_color.p4 b/backends/tofino/bf-asm/test/internal/test_config_125_meter_pre_color.p4 new file mode 100644 index 00000000000..ce09b191a27 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_125_meter_pre_color.p4 @@ -0,0 +1,112 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + color_0 : 4; + pad_0 : 4; + color_1 : 8; + + pre_color_0 : 8; + pre_color_1 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +meter meter_0 { + type : bytes; + //static : table_0; + direct : table_0; + result : pkt.color_0; + pre_color : pkt.pre_color_0; + //instance_count : 500; +} + + +meter meter_1 { + type : bytes; + static : table_1; + //direct : table_1; + result : pkt.color_1; + instance_count : 500; +} + + +action action_0(param0){ + //modify_field(pkt.field_f_16, param0); + //execute_meter(meter_0, 7, pkt.color_0); +} + + +action action_1(param0){ + //modify_field(pkt.field_g_16, param0); + execute_meter(meter_1, 7, pkt.color_1, pkt.pre_color_1); +} + + +action do_nothing(){ + no_op(); +} + + +// @pragma include_stash 1 +table table_0 { + reads { + pkt.field_e_16 : ternary; + pkt.color_0 : exact; //HACK + pkt.color_1 : exact; //HACK + pkt.pre_color_0 : exact; //HACK + pkt.pre_color_1 : exact; //HACK + } + actions { + action_0; +// do_nothing; + } + size : 6000; +} + + +//@pragma include_idletime 1 +@pragma idletime_two_way_notification 1 +// @pragma include_stash 1 +table table_1 { + reads { + pkt.field_e_16: exact; + } + actions { + do_nothing; + action_1; + } + size : 32768; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_1); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_126_meter_pre_color_2.p4 b/backends/tofino/bf-asm/test/internal/test_config_126_meter_pre_color_2.p4 new file mode 100644 index 00000000000..09b0daa741d --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_126_meter_pre_color_2.p4 @@ -0,0 +1,114 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + color_0 : 4; + pad_0 : 4; + color_1 : 8; + pre_color_0 : 4; + pad_1 : 4; + pre_color_1 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +meter meter_0 { + type : bytes; + //static : table_0; + direct : table_0; + result : pkt.color_0; + pre_color : pkt.pre_color_0; + //instance_count : 500; +} + + +meter meter_1 { + type : bytes; + static : table_1; + //direct : table_1; + result : pkt.color_1; + instance_count : 500; +} + + +action action_0(param0){ + //modify_field(pkt.field_f_16, param0); + //execute_meter(meter_0, 7, pkt.color_0); +} + + +action action_1(param0){ + //modify_field(pkt.field_g_16, param0); + execute_meter(meter_1, 7, pkt.color_1, pkt.pre_color_1); +} + + +action do_nothing(){ + no_op(); +} + + +// @pragma include_stash 1 +table table_0 { + reads { + pkt.field_e_16 : ternary; + pkt.color_0 : exact; //HACK + pkt.color_1 : exact; //HACK + pkt.pre_color_0 : exact; //HACK + pkt.pre_color_1 : exact; //HACK + } + actions { + action_0; +// do_nothing; + } + size : 6000; +} + + +//@pragma include_idletime 1 +@pragma idletime_two_way_notification 1 +// @pragma include_stash 1 +table table_1 { + reads { + pkt.field_e_16: exact; + } + actions { + do_nothing; + action_1; + } + size : 32768; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} +control egress { + apply(table_1); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_127_meter_pre_color_3.p4 b/backends/tofino/bf-asm/test/internal/test_config_127_meter_pre_color_3.p4 new file mode 100644 index 00000000000..7b280174053 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_127_meter_pre_color_3.p4 @@ -0,0 +1,160 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + color_0 : 4; + pad_0 : 4; + color_1 : 8; + color_2 : 8; + pad_2 : 32; + color_3 : 8; + + pre_color_0 : 4; + pad_1 : 4; + pre_color_1 : 8; + pre_color_2 : 8; + pre_color_3 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +meter meter_0 { + type : bytes; + //static : table_0; + direct : table_0; + result : pkt.color_0; + pre_color : pkt.pre_color_0; + //instance_count : 500; +} + + +meter meter_1 { + type : bytes; + static : table_1; + //direct : table_1; + result : pkt.color_1; + instance_count : 500; +} + +meter meter_2 { + type : bytes; + direct : table_2; + result : pkt.color_2; + pre_color : pkt.pre_color_2; +} + +meter meter_3 { + type : bytes; + direct : table_3; + result : pkt.color_3; + pre_color : pkt.pre_color_3; +} + + +action action_0(param0){ + //modify_field(pkt.field_f_16, param0); + //execute_meter(meter_0, 7, pkt.color_0); +} + + +action action_1(param0){ + //modify_field(pkt.field_g_16, param0); + execute_meter(meter_1, 7, pkt.color_1, pkt.pre_color_1); +} + + +action do_nothing(){ + no_op(); +} + + +// @pragma include_stash 1 +table table_0 { + reads { + pkt.field_e_16 : ternary; + pkt.color_0 : exact; //HACK + pkt.color_1 : exact; //HACK + pkt.color_2 : exact; //HACK + pkt.color_3 : exact; //HACK + pkt.pre_color_0 : exact; //HACK + pkt.pre_color_1 : exact; //HACK + pkt.pre_color_2 : exact; //HACK + pkt.pre_color_3 : exact; //HACK + } + actions { + action_0; +// do_nothing; + } + size : 1024; +} + + +//@pragma include_idletime 1 +@pragma idletime_two_way_notification 1 +// @pragma include_stash 1 +table table_1 { + reads { + pkt.field_e_16: exact; + } + actions { + do_nothing; + action_1; + } + size : 32768; +} + +table table_2 { + reads { + pkt.field_e_16: ternary; + } + actions { + do_nothing; + } + size : 512; +} + +table table_3 { + reads { + pkt.field_e_16: ternary; + } + actions { + do_nothing; + } + size : 512; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_2); + apply(table_3); +} +control egress { + apply(table_1); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_128_table_placement_bug.p4 b/backends/tofino/bf-asm/test/internal/test_config_128_table_placement_bug.p4 new file mode 100644 index 00000000000..662e40b6161 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_128_table_placement_bug.p4 @@ -0,0 +1,101 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + color_0 : 4; + pad_0 : 4; + color_1 : 8; + color_2 : 8; + color_3 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +action action_0(param0){ + modify_field(pkt.field_f_16, param0); +} + + +action action_1(param0){ + modify_field(pkt.field_g_16, param0); +} + + +action do_nothing(){ + no_op(); +} + +table table_0 { + reads { + pkt.field_e_16 : ternary; + } + actions { + action_0; + do_nothing; + } + size : 1024; +} + +//@pragma no_versioning 1 +table table_1 { + reads { + pkt.field_e_16: exact; + pkt.field_f_16 mask 0xfffc : exact; + } + actions { + action_1; + do_nothing; + + } + size : 1024; +} + +table table_2 { + reads { + pkt.field_i_8: ternary; + } + actions { + do_nothing; + + } + size : 256; +} + + +/* Main control flow */ + +control ingress { + if (valid(pkt)){ + apply(table_0); + } else { + apply(table_1) { + action_1 { + apply(table_2); + } + } + } +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_12_no_overhead.p4 b/backends/tofino/bf-asm/test/internal/test_config_12_no_overhead.p4 new file mode 100644 index 00000000000..bb118c77605 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_12_no_overhead.p4 @@ -0,0 +1,72 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +action action_0(){ + modify_field(ipv4.diffserv, 1); +} + + +table table_0 { + reads { + ethernet.etherType : exact; + } + actions { + action_0; + } + max_size : 1024; +} + +/* Main control flow */ + +control ingress { + + if (ethernet.etherType == 0x0800){ + apply(table_0); + } +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_130_test_default_action.p4 b/backends/tofino/bf-asm/test/internal/test_config_130_test_default_action.p4 new file mode 100644 index 00000000000..435bef62abc --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_130_test_default_action.p4 @@ -0,0 +1,115 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + color_0 : 4; + pad_0 : 4; + color_1 : 8; + color_2 : 8; + color_3 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +action action_0(param0){ + modify_field(pkt.field_f_16, param0); +} + + +action action_1(param0){ + modify_field(pkt.field_g_16, param0); +} + +action action_2(param0){ + modify_field(pkt.field_h_16, param0); +} + + +action do_nothing_0(){ + no_op(); +} + +action do_nothing_1(){ + no_op(); +} + +action do_nothing_2(){ + no_op(); +} + +table table_0 { + reads { + pkt.field_e_16 : ternary; + } + actions { + action_0; + do_nothing_0; + } + size : 1024; +} + +table table_1 { + reads { + pkt.field_e_16: exact; + pkt.field_f_16 mask 0xffff : exact; + } + actions { + //action_1; + do_nothing_1; + + } + default_action : action_1(0xf); + size : 1024; +} + +table table_2 { + reads { + pkt.field_i_8: ternary; + } + actions { + action_2; + do_nothing_2; + + } + default_action : do_nothing_2; + size : 256; +} + + +/* Main control flow */ + +control ingress { + if (valid(pkt)){ + apply(table_0); + } else { + apply(table_1) { + do_nothing_1 { + apply(table_2); + } + } + } +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_132_meter_pre_color_4.p4 b/backends/tofino/bf-asm/test/internal/test_config_132_meter_pre_color_4.p4 new file mode 100644 index 00000000000..093fec76b9e --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_132_meter_pre_color_4.p4 @@ -0,0 +1,172 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/wred_blackbox.p4" +#include "tofino/lpf_blackbox.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + color_0 : 4; + pad_0 : 4; + color_1 : 8; + color_2 : 8; + pad_2 : 32; + color_3 : 8; + + pre_color_0 : 4; + pad_1 : 4; + pre_color_1 : 8; + pre_color_2 : 8; + pre_color_3 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; + //return ACCEPT; +} + +@pragma meter_per_flow_enable 1 +meter meter_0 { + type : bytes; + static : table_0; + //direct : table_0; + result : pkt.color_0; + //pre_color : pkt.pre_color_0; + instance_count : 500; +} + + +@pragma meter_per_flow_enable 1 +@pragma meter_pre_color_aware_per_flow_enable 1 +meter meter_1 { + type : bytes; + static : table_1; + //direct : table_1; + result : pkt.color_1; + instance_count : 500; +} + +blackbox wred meter_2 { + wred_input: pkt.pre_color_2; + direct : table_2; + drop_value : 127; + no_drop_value : 63; +} + + +blackbox lpf meter_3 { + filter_input : pkt.pre_color_3; + direct : table_3; +} + + +action action_0(param0){ + //modify_field(pkt.field_f_16, param0); + execute_meter(meter_0, 7, pkt.color_0, pkt.pre_color_0); +} + + +action action_1(param0){ + //modify_field(pkt.field_g_16, param0); + execute_meter(meter_1, 7, pkt.color_1, pkt.pre_color_1); +} + + +action do_nothing(){ + no_op(); +} + +action do_nothing_2(){ + meter_2.execute(pkt.pre_color_2); +} + +action do_nothing_3(){ + meter_3.execute(pkt.color_3); +} + + +@pragma include_stash 1 +table table_0 { + reads { + pkt.field_e_16 : ternary; + pkt.color_0 : exact; //HACK + pkt.color_1 : exact; //HACK + pkt.color_2 : exact; //HACK + pkt.color_3 : exact; //HACK + pkt.pre_color_0 : exact; //HACK + pkt.pre_color_1 : exact; //HACK + pkt.pre_color_2 : exact; //HACK + pkt.pre_color_3 : exact; //HACK + } + actions { + action_0; +// do_nothing; + } + size : 1024; +} + + +//@pragma include_idletime 1 +@pragma idletime_two_way_notification 1 +@pragma include_stash 1 +table table_1 { + reads { + pkt.field_e_16: exact; + } + actions { + do_nothing; + action_1; + } + size : 32768; +} + +table table_2 { + reads { + pkt.field_e_16: ternary; + } + actions { + do_nothing_2; + } + size : 512; +} + +table table_3 { + reads { + pkt.field_e_16: ternary; + } + actions { + do_nothing_3; + } + size : 512; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_2); + apply(table_3); +} +control egress { + apply(table_1); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_134_stage_deps.p4 b/backends/tofino/bf-asm/test/internal/test_config_134_stage_deps.p4 new file mode 100644 index 00000000000..662a12d61a5 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_134_stage_deps.p4 @@ -0,0 +1,120 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + color_0 : 8; + } +} + +parser start { + return parse_pkt; +} + +header pkt_t pkt; + +parser parse_pkt { + extract(pkt); + return ingress; +} + + +action action_a(param0, param1, param2){ + modify_field(pkt.field_e_16, param0); + modify_field(pkt.field_f_16, param1); + modify_field(pkt.field_g_16, param2); +} + +action action_b(param0){ + modify_field(pkt.field_f_16, param0); +} + +action action_c(param0){ + modify_field(pkt.field_f_16, param0); +} + +action action_d(){ + no_op(); +} + +action action_e(){ + no_op(); +} + +table table_a { + reads { + pkt.field_a_32 : exact; + } + actions { + action_a; + } + size : 256; +} + +table table_b { + reads { + pkt.field_a_32 : exact; + } + actions { + action_b; + } + size : 256; +} + +table table_c { + reads { + pkt.field_a_32 : exact; + } + actions { + action_c; + } + size : 256; +} + +@pragma stage 3 +table table_d { + reads { + pkt.field_e_16 : exact; + } + actions { + action_d; + } + size : 256; +} + +@pragma stage 4 +table table_e { + reads { + pkt.field_g_16 : exact; + } + actions { + action_e; + } + size : 256; +} + + +/* Main control flow */ + +control ingress { + apply(table_a); + apply(table_b); + apply(table_c); + apply(table_d); + apply(table_e); +} + + diff --git a/backends/tofino/bf-asm/test/internal/test_config_135_tcam_range_7.p4 b/backends/tofino/bf-asm/test/internal/test_config_135_tcam_range_7.p4 new file mode 100644 index 00000000000..6d2b9f2188f --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_135_tcam_range_7.p4 @@ -0,0 +1,71 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_m_32 : 32; + field_n_32 : 32; + + field_o_10 : 10; + field_p_6 : 6; + } +} + + +parser start { + return parse_pkt; +} + +header pkt_t pkt; + +parser parse_pkt { + extract(pkt); + return ingress; +} + +action action_0(){ + modify_field(pkt.field_f_16, 1); +} + +action do_nothing(){ + no_op(); +} + +action do_nothing_1(){ +} + +@pragma entries_with_ranges 64 +table table_0 { + reads { + pkt.field_o_10 : range; + pkt.field_g_16 : exact; + } + actions { + do_nothing; + action_0; + } + size : 1024; +} + +/* Main control flow */ + +control ingress { + apply(table_0); +} + + diff --git a/backends/tofino/bf-asm/test/internal/test_config_136_tcam_error_detection.p4 b/backends/tofino/bf-asm/test/internal/test_config_136_tcam_error_detection.p4 new file mode 100644 index 00000000000..f0106c45264 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_136_tcam_error_detection.p4 @@ -0,0 +1,73 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_m_32 : 32; + field_n_32 : 32; + + field_o_10 : 10; + field_p_6 : 6; + } +} + + +parser start { + return parse_pkt; +} + +header pkt_t pkt; + +parser parse_pkt { + extract(pkt); + return ingress; +} + +action action_0(){ + modify_field(pkt.field_f_16, 1); +} + +action do_nothing(){ + no_op(); +} + +action do_nothing_1(){ +} + +@pragma entries_with_ranges 64 +@pragma tcam_error_detect 1 +table table_0 { + reads { + pkt.field_o_10 : range; + pkt.field_g_16 : exact; + pkt.field_h_16 : exact; + } + actions { + do_nothing; + action_0; + } + size : 1024; +} + +/* Main control flow */ + +control ingress { + apply(table_0); +} + + diff --git a/backends/tofino/bf-asm/test/internal/test_config_137_tcam_error_detection_2.p4 b/backends/tofino/bf-asm/test/internal/test_config_137_tcam_error_detection_2.p4 new file mode 100644 index 00000000000..16be2673158 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_137_tcam_error_detection_2.p4 @@ -0,0 +1,131 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_m_32 : 32; + field_n_32 : 32; + + field_o_10 : 10; + field_p_6 : 6; + } +} + + +parser start { + return parse_pkt; +} + +header pkt_t pkt; + +parser parse_pkt { + extract(pkt); + return ingress; +} + +action action_0(){ + modify_field(pkt.field_f_16, 1); +} + +action do_nothing(){ + no_op(); +} + +action do_nothing_1(){ +} + +table table_a { + reads { + pkt.field_a_32 : ternary; + } + actions { + do_nothing; + } + size : 512; +} + +table table_b { + reads { + pkt.field_b_32 : ternary; + } + actions { + do_nothing; + } + size : 512; +} + +table table_c { + reads { + pkt.field_c_32 : ternary; + } + actions { + do_nothing; + } + size : 512; +} + +table table_d { + reads { + pkt.field_d_32 : ternary; + } + actions { + do_nothing; + } + size : 512; +} + + +@pragma entries_with_ranges 64 +@pragma tcam_error_detect 1 +table table_e { + reads { + pkt.field_o_10 : range; + pkt.field_g_16 : exact; + pkt.field_h_16 : exact; + } + actions { + do_nothing; + action_0; + } + size : 1024; +} + +@pragma tcam_error_detect 1 +table table_f { + reads { + pkt.field_g_16 : ternary; + } + actions { + do_nothing; + } + size : 1024; +} + +/* Main control flow */ + +// Should fit in one stage +control ingress { + apply(table_a); + apply(table_b); + apply(table_c); + apply(table_d); + apply(table_e); + apply(table_f); +} + + diff --git a/backends/tofino/bf-asm/test/internal/test_config_138_tcam_error_detection_3.p4 b/backends/tofino/bf-asm/test/internal/test_config_138_tcam_error_detection_3.p4 new file mode 100644 index 00000000000..29cb55d5843 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_138_tcam_error_detection_3.p4 @@ -0,0 +1,147 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_m_32 : 32; + field_n_32 : 32; + + field_o_10 : 10; + field_p_6 : 6; + } +} + + +parser start { + return parse_pkt; +} + +header pkt_t pkt; + +parser parse_pkt { + extract(pkt); + return ingress; +} + +action action_0(){ + modify_field(pkt.field_f_16, 1); +} + +action do_nothing(){ + no_op(); +} + +action do_nothing_1(){ +} + +table table_z { + reads { + pkt.field_l_8 : ternary; + } + actions { + do_nothing; + } + size : 512; +} + + +table table_a { + reads { + pkt.field_a_32 : ternary; + } + actions { + do_nothing; + } + size : 512; +} + +table table_b { + reads { + pkt.field_b_32 : ternary; + } + actions { + do_nothing; + } + size : 512; +} + +table table_c { + reads { + pkt.field_c_32 : ternary; + } + actions { + do_nothing; + } + size : 512; +} + +table table_d { + reads { + pkt.field_d_32 : ternary; + } + actions { + do_nothing; + } + size : 512; +} + + +@pragma entries_with_ranges 64 +@pragma tcam_error_detect 1 +table table_e { + reads { + pkt.field_o_10 : range; + pkt.field_g_16 : exact; + pkt.field_h_16 : exact; + } + actions { + do_nothing; + action_0; + } + size : 1024; +} + +@pragma tcam_error_detect 1 +table table_f { + reads { + pkt.field_g_16 : ternary; + } + actions { + do_nothing; + } + size : 1024; +} + +/* Main control flow */ + +// Should fit in two stages +control ingress { + apply(table_z); + apply(table_a); + apply(table_b); + apply(table_c); + apply(table_d); + apply(table_e); + apply(table_f); +} + + + + + + diff --git a/backends/tofino/bf-asm/test/internal/test_config_139_tcam_error_detection_4.p4 b/backends/tofino/bf-asm/test/internal/test_config_139_tcam_error_detection_4.p4 new file mode 100644 index 00000000000..cdb411333c9 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_139_tcam_error_detection_4.p4 @@ -0,0 +1,140 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_m_32 : 32; + field_n_32 : 32; + + field_o_10 : 10; + field_p_6 : 6; + } +} + + +parser start { + return parse_pkt; +} + +header pkt_t pkt; + +parser parse_pkt { + extract(pkt); + return ingress; +} + +action action_0(){ + modify_field(pkt.field_f_16, 1); +} + +action do_nothing(){ + no_op(); +} + +action do_nothing_1(){ +} + +action count_it(){ + count(simple_stats, pkt.field_h_16); +} + +counter simple_stats { + type : packets; + instance_count : 16384; +} + +table table_a { + actions { + count_it; + } +} + +table table_b { + reads { + pkt.field_b_32 : ternary; + } + actions { + do_nothing; + } + size : 512; +} + +table table_c { + reads { + pkt.field_c_32 : ternary; + } + actions { + do_nothing; + } + size : 512; +} + +table table_d { + reads { + pkt.field_d_32 : ternary; + } + actions { + do_nothing; + } + size : 512; +} + + +@pragma entries_with_ranges 64 +@pragma tcam_error_detect 1 +table table_e { + reads { + pkt.field_o_10 : range; + pkt.field_g_16 : exact; + pkt.field_h_16 : exact; + } + actions { + do_nothing; + action_0; + } + size : 1024; +} + +@pragma tcam_error_detect 1 +table table_f { + reads { + pkt.field_g_16 : ternary; + } + actions { + do_nothing; + } + size : 1024; +} + +/* Main control flow */ + +// Should fit in one stages +control ingress { + apply(table_a); + apply(table_b); + apply(table_c); + apply(table_d); + apply(table_e); + apply(table_f); +} + + + + + + diff --git a/backends/tofino/bf-asm/test/internal/test_config_13_first_selection.p4 b/backends/tofino/bf-asm/test/internal/test_config_13_first_selection.p4 new file mode 100644 index 00000000000..41464660316 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_13_first_selection.p4 @@ -0,0 +1,152 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + + blah1 : 32; + blah2 : 8; + blah3 : 64; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + + +field_list first_field_list { + ipv4.blah1; + ipv4.blah2; + ipv4.blah3; +} + + +field_list_calculation first_hash { + input { + first_field_list; + } + algorithm : random; + output_width : 72; +} + + +action big_action(param0, param1, param2/*, param3*/){ + modify_field(ipv4.dstAddr, param0); + modify_field(ipv4.srcAddr, param1); + modify_field(ethernet.dstAddr, param2); + //modify_field(ethernet.srcAddr, param3); +} + +action action_0(param0){ + modify_field(ipv4.hdrChecksum, param0); +} + +action action_select(base, hash_size){ + modify_field_with_hash_based_offset(ipv4.blah2, base, first_hash, hash_size); +} + +action do_nothing(){ + no_op(); +} + +@pragma immediate 0 +@pragma selector_max_group_size 121 +table test_select { + reads { + ethernet.etherType : exact; + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + action_profile : some_action_profile; + size : 8192; +} + +action_profile some_action_profile { + actions { + action_0; + big_action; + do_nothing; + } + size : 512; + dynamic_action_selection : some_selector ; +} + +action_selector some_selector { + selection_key : first_hash; + selection_mode : resilient; +} + + + +/* +table table_select { + reads { + ethernet.etherType : exact; + } + actions { + do_nothing; + action_0; + //big_action; + } + max_size : 2048; +} +*/ + +table table_group { + reads { + ipv4.blah1 : ternary; + } + actions { + action_select; + } +} + + +/* Main control flow */ + +control ingress { + + apply(test_select); + + apply(table_group); +// apply(table_select); + +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_140_table_counter.p4 b/backends/tofino/bf-asm/test/internal/test_config_140_table_counter.p4 new file mode 100644 index 00000000000..e2c6ffdb2f6 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_140_table_counter.p4 @@ -0,0 +1,103 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + color_0 : 4; + pad_0 : 4; + color_1 : 8; + color_2 : 8; + color_3 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +action action_0(param0){ + modify_field(pkt.field_f_16, param0); +} + +action action_1(param0){ + modify_field(pkt.field_g_16, param0); +} + +action action_2(param0){ + modify_field(pkt.field_h_16, param0); +} + + +action do_nothing(){ + no_op(); +} + +@pragma table_counter gateway_hit +table table_0 { + reads { + pkt.field_e_16 : ternary; + } + actions { + do_nothing; + } + size : 4096; +} + +@pragma table_counter table_miss +table table_1 { + reads { + pkt.field_e_16: exact; + pkt.field_f_16 mask 0xffff : exact; + } + actions { + do_nothing; + + } + default_action : action_1(0xf); + size : 16384; +} + +@pragma table_counter table_hit +table table_2 { + reads { + pkt.field_f_16: ternary; + } + actions { + do_nothing; + + } + default_action : do_nothing; + size : 2048; +} + + +/* Main control flow */ + +control ingress { + if (valid(pkt)){ + apply(table_0); + } else { + apply(table_1); + } + apply(table_2); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_142_stateful_bfd.p4 b/backends/tofino/bf-asm/test/internal/test_config_142_stateful_bfd.p4 new file mode 100644 index 00000000000..c8bc7973b08 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_142_stateful_bfd.p4 @@ -0,0 +1,103 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + } +} + +header_type bfd_t { + fields { + bfd_tx_or_rx : 8; + bfd_discriminator : 8; + } +} + +header_type sample_t { + fields { + a : 8 ; + b : 8 ; + } +} + + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; +metadata bfd_t bfd_md; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +register bfd_cnt{ + /* + width : 8; + */ + layout : sample_t; + direct : bfd; + /* instance_count : 16384; */ +} + +/* +stateful_alu bfd_cnt_rx_alu { + register: bfd_cnt; + update_lo_1_value: 0; +} +stateful_alu bfd_cnt_tx_alu { + register: bfd_cnt; + condition_a: register > 3; + update_hi_1_value: 1; + update_lo_1_value: register + 1; + output_predicate: a; + output_expr: new_hi; + output_dst: egress_md.bfd_timeout_detected; +} +*/ + +action bfd_rx() { + /* execute_stateful_alu(bfd_cnt_rx_alu); */ +} + +action bfd_tx() { + /* execute_stateful_alu(bfd_cnt_tx_alu); */ +} + + +table bfd { + reads { + bfd_md.bfd_tx_or_rx : exact; + bfd_md.bfd_discriminator : exact; + } + actions { + bfd_rx; + bfd_tx; + } + size : 16384; +} + + + +/* Main control flow */ + +control ingress { + apply(bfd); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_143_packing_constants.p4 b/backends/tofino/bf-asm/test/internal/test_config_143_packing_constants.p4 new file mode 100644 index 00000000000..e971cc85ff7 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_143_packing_constants.p4 @@ -0,0 +1,80 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_bit_7 : 1; + field_i_bit_6 : 1; + field_i_bit_5 : 1; + field_i_bit_4 : 1; + field_i_bit_3 : 1; + field_i_bit_2 : 1; + field_i_bit_1 : 1; + field_i_bit_0 : 1; + + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +action set_hi(){ + modify_field(pkt.field_i_bit_7, 1); + modify_field(pkt.field_i_bit_6, 0); + modify_field(pkt.field_i_bit_5, 1); +} + +action set_mid(){ + modify_field(pkt.field_i_bit_5, 1); + modify_field(pkt.field_i_bit_4, 0); + modify_field(pkt.field_i_bit_3, 1); +} + +action set_lo(){ + modify_field(pkt.field_i_bit_2, 1); + modify_field(pkt.field_i_bit_1, 0); + modify_field(pkt.field_i_bit_0, 1); +} + + + +table table_0 { + reads { + pkt.field_a_32 : ternary; + } + actions { + set_hi; + set_mid; + set_lo; + } + size : 512; +} + + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_144_recirculate.p4 b/backends/tofino/bf-asm/test/internal/test_config_144_recirculate.p4 new file mode 100644 index 00000000000..d65cdfcc40e --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_144_recirculate.p4 @@ -0,0 +1,56 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +action action_0(port){ + recirculate(port); + //recirculate(15); +} + +table table_0 { + reads { + pkt.field_a_32 : ternary; + ig_intr_md_for_tm.ucast_egress_port : exact; + } + actions { + action_0; + } + size : 512; +} + + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_145_shift_primitives.p4 b/backends/tofino/bf-asm/test/internal/test_config_145_shift_primitives.p4 new file mode 100644 index 00000000000..fe9a5b620c6 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_145_shift_primitives.p4 @@ -0,0 +1,69 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +action action_0(){ + shift_left(pkt.field_i_8, pkt.field_j_8, 2); +} + +action action_1(){ + shift_left(pkt.field_i_8, 1, 2); +} + +action action_2(){ + shift_right(pkt.field_i_8, pkt.field_j_8, 5); +} + +action action_3(){ + shift_right(pkt.field_i_8, 128, 5); +} + +table table_0 { + reads { + pkt.field_a_32 : ternary; + } + actions { + action_0; + action_1; + action_2; + action_3; + } + size : 512; +} + + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_146_two_drops.p4 b/backends/tofino/bf-asm/test/internal/test_config_146_two_drops.p4 new file mode 100644 index 00000000000..85786e7c71f --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_146_two_drops.p4 @@ -0,0 +1,69 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +action action_0() { + drop(); +} + +action action_1() { + drop(); +} + +table table_0 { + reads { + pkt.field_a_32 : ternary; + } + actions { + action_0; + } + size : 512; +} + +table table_1 { + reads { + pkt.field_b_32 : ternary; + } + actions { + action_1; + } + size : 512; +} + + + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_1); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_147_subtract_primitive.p4 b/backends/tofino/bf-asm/test/internal/test_config_147_subtract_primitive.p4 new file mode 100644 index 00000000000..841db063e04 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_147_subtract_primitive.p4 @@ -0,0 +1,69 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +action action_0() { + subtract(pkt.field_a_32, pkt.field_a_32, pkt.field_b_32); +} + +action action_1() { + subtract(pkt.field_i_8, pkt.field_j_8, pkt.field_k_8); +} + +table table_0 { + reads { + pkt.field_a_32 : ternary; + } + actions { + action_0; + } + size : 512; +} + +table table_1 { + reads { + pkt.field_b_32 : ternary; + } + actions { + action_1; + } + size : 512; +} + + + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_1); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_148_action_profile.p4 b/backends/tofino/bf-asm/test/internal/test_config_148_action_profile.p4 new file mode 100644 index 00000000000..8128238bb98 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_148_action_profile.p4 @@ -0,0 +1,67 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +action do_nothing(){ + no_op(); +} + +action action_0(param0) { + subtract(pkt.field_a_32, param0, pkt.field_a_32); +} + +action action_1() { + subtract(pkt.field_i_8, pkt.field_j_8, pkt.field_k_8); +} + +table table_0 { + reads { + pkt.field_a_32 : exact; + } + action_profile: table_0_action_profile; + size : 3072; +} + +action_profile table_0_action_profile { + actions { + do_nothing; + action_0; + action_1; + } + size : 3072; +} + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_149_signed_and_saturating_add_sub.p4 b/backends/tofino/bf-asm/test/internal/test_config_149_signed_and_saturating_add_sub.p4 new file mode 100644 index 00000000000..990739a4cd1 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_149_signed_and_saturating_add_sub.p4 @@ -0,0 +1,85 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_signed : 32 (signed); + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_sat : 16 (saturating); + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_signed_sat : 8 (signed, saturating); + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +//signed +action action_0() { + add(pkt.field_a_signed, pkt.field_a_signed, pkt.field_b_32); +} + +//saturating +action action_1() { + add_to_field(pkt.field_e_sat, pkt.field_f_16); +} + +//signed and saturating +action action_2() { + add(pkt.field_i_signed_sat, pkt.field_i_signed_sat, pkt.field_j_8); +} + +//signed +action action_3() { + subtract(pkt.field_a_signed, pkt.field_a_signed, pkt.field_b_32); +} + +//saturating +action action_4() { + subtract(pkt.field_e_sat, pkt.field_e_sat, pkt.field_f_16); +} + +//signed and saturating +action action_5() { + subtract(pkt.field_i_signed_sat, pkt.field_i_signed_sat, pkt.field_j_8); +} + + +table table_0 { + reads { + pkt.field_c_32 : ternary; + } + actions { + action_0; + action_1; + action_2; + action_3; + action_4; + action_5; + } + size : 512; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_14_auto_immediate_action_data.p4 b/backends/tofino/bf-asm/test/internal/test_config_14_auto_immediate_action_data.p4 new file mode 100644 index 00000000000..80433917856 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_14_auto_immediate_action_data.p4 @@ -0,0 +1,97 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + + +field_list first_field_list { + ipv4.protocol; + ipv4.srcAddr; +} + + +field_list_calculation first_hash { + input { + first_field_list; + } + algorithm : crc16; + output_width : 16; +} + +action big_action(param0, param1, param2, param3){ + modify_field(ipv4.dstAddr, param0); + modify_field(ipv4.srcAddr, param1); + modify_field(ethernet.dstAddr, param2); + modify_field(ethernet.srcAddr, param3); +} + +action action_0(){ + modify_field(ipv4.hdrChecksum, 1); +} + +action do_nothing(){ + no_op(); +} + +@pragma immediate 1 +table table_0 { + reads { + ipv4.dstAddr : exact ; + } + actions { + action_0; +// big_action; + do_nothing; + } +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_150_action_bus_allocation.p4 b/backends/tofino/bf-asm/test/internal/test_config_150_action_bus_allocation.p4 new file mode 100644 index 00000000000..e47869fff7a --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_150_action_bus_allocation.p4 @@ -0,0 +1,90 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_signed : 32 (signed); + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_sat : 16 (saturating); + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_signed_sat : 8 (signed, saturating); + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +action action_0(param0){ + add(pkt.field_a_signed, pkt.field_a_signed, param0); +} + +action action_1(param0) { + add_to_field(pkt.field_e_sat, param0); +} + +action action_2(param0) { + add(pkt.field_i_signed_sat, pkt.field_i_signed_sat, param0); +} + +action action_3(param0) { + modify_field(pkt.field_c_32, param0); +} + +action action_4(param0) { + modify_field(pkt.field_g_16, param0); +} + +action action_5(param0) { + modify_field(pkt.field_k_8, param0); +} + + +table table_0 { + reads { + pkt.field_c_32 : ternary; + } + actions { + action_0; + action_1; + action_2; + } + size : 512; +} + +table table_1 { + reads { + pkt.field_d_32 : ternary; + } + actions { + action_3; + action_4; + action_5; + } + size : 512; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_1); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_151_action_bus_allocation_2.p4 b/backends/tofino/bf-asm/test/internal/test_config_151_action_bus_allocation_2.p4 new file mode 100644 index 00000000000..3d7c664fb84 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_151_action_bus_allocation_2.p4 @@ -0,0 +1,84 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_signed : 32 (signed); + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_sat : 16 (saturating); + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_signed_sat : 8 (signed, saturating); + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +action action_0(param0){ + modify_field(pkt.field_b_32, param0, 0x0ff00000); +} + +action action_1(param0){ + modify_field(pkt.field_c_32, param0, 0x000ff000); +} + +action action_2(param0){ + modify_field(pkt.field_d_32, param0, 0x0ff0); +} + +table table_0 { + reads { + pkt.field_h_16 : ternary; + } + actions { + action_0; + } + size : 512; +} + +table table_1 { + reads { + pkt.field_h_16 : ternary; + } + actions { + action_1; + } + size : 512; +} + +table table_2 { + reads { + pkt.field_h_16 : ternary; + } + actions { + action_2; + } + size : 512; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_1); + apply(table_2); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_152_stateful_simple_cntr.p4 b/backends/tofino/bf-asm/test/internal/test_config_152_stateful_simple_cntr.p4 new file mode 100644 index 00000000000..b15b1ce5ea3 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_152_stateful_simple_cntr.p4 @@ -0,0 +1,72 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +register stateful_cntr{ + width : 16; + /* direct : match_cntr; */ + instance_count : 8192; +} + + +blackbox stateful_alu cntr { + reg: stateful_cntr; + update_lo_1_value: register_lo + 1; +} + + +action cnt() { + cntr.execute_stateful_alu(); +} + +action do_nothing(){} + +table match_cntr { + reads { + pkt.field_a_32 : exact; + } + actions { + cnt; + do_nothing; + } + size : 16384; +} + + + +/* Main control flow */ + +control ingress { + apply(match_cntr); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_153_stateful_simple_cntr_with_output.p4 b/backends/tofino/bf-asm/test/internal/test_config_153_stateful_simple_cntr_with_output.p4 new file mode 100644 index 00000000000..93032cd2278 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_153_stateful_simple_cntr_with_output.p4 @@ -0,0 +1,91 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + } +} + +header_type meta_t { + fields { + count_value : 16; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; +metadata meta_t meta; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +register stateful_cntr{ + width : 16; + direct : match_cntr; + /* instance_count : 8192; */ +} + + +blackbox stateful_alu cntr { + reg: stateful_cntr; + update_lo_1_value: register_lo + 1; + output_value : alu_lo; + output_dst : meta.count_value; +} + + +action cnt(/* param0 */) { + cntr.execute_stateful_alu(); + /* modify_field(pkt.field_e_16, param0); */ +} + +action do_nothing(){} + +/* @pragma immediate 0 */ +table match_cntr { + reads { + pkt.field_a_32 : exact; + } + actions { + cnt; + } + size : 16384; +} + +table dummy { + reads { + meta.count_value : exact; + } + actions { + do_nothing; + } +} + + +/* Main control flow */ + +control ingress { + apply(match_cntr); + apply(dummy); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_154_stateful_sampling.p4 b/backends/tofino/bf-asm/test/internal/test_config_154_stateful_sampling.p4 new file mode 100644 index 00000000000..6fdea7f3435 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_154_stateful_sampling.p4 @@ -0,0 +1,85 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + } +} + +header_type meta_t { + fields { + needs_sampling : 8 (signed, saturating); + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; +metadata meta_t meta; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +register flow_cnt { + width : 8; + direct : match_tbl; + /* instance_count : 65536; */ +} + +blackbox stateful_alu sampler_alu { + reg: flow_cnt; + condition_lo: register_lo == 10; /* sample limit */ + update_lo_1_predicate: condition_lo; + update_lo_1_value: 1; + update_lo_2_predicate: not condition_lo; + update_lo_2_value: register_lo + 1; + output_predicate: condition_lo; + output_value : alu_lo; + output_dst : meta.needs_sampling; +} + +action sample(){ + sampler_alu.execute_stateful_alu(); +} + +action do_nothing(){} + +table match_tbl { + reads { + pkt.field_a_32 : ternary; + meta.needs_sampling : exact; /* hack to ensure phv puts it in mau space */ + } + actions { + sample; + } + size : 8192; +} + + + + +/* Main control flow */ + +control ingress { + apply(match_tbl); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_155_stateful_3_alus.p4 b/backends/tofino/bf-asm/test/internal/test_config_155_stateful_3_alus.p4 new file mode 100644 index 00000000000..7e91def8360 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_155_stateful_3_alus.p4 @@ -0,0 +1,139 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + } +} + +header_type meta_t { + fields { + count_value : 16; + needs_sampling : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; +metadata meta_t meta; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +register stateful_cntr_1{ + width : 16; + direct : match_cntr_1; + /* instance_count : 8192; */ +} + +register stateful_cntr_2{ + width : 16; + direct : match_cntr_2; + /* instance_count : 8192; */ +} + +register flow_cnt { + width : 8; + direct : match_flow; + /* instance_count : 65536; */ +} + +blackbox stateful_alu cntr_1 { + reg: stateful_cntr_1; + update_lo_1_value: register_lo + 1; +} + +blackbox stateful_alu cntr_2 { + reg: stateful_cntr_2; + update_lo_1_value: register_lo + 1; + output_value : alu_lo; + output_dst : meta.count_value; +} + +blackbox stateful_alu sampler_alu { + reg: flow_cnt; + condition_lo: register_lo == 10; /* sample limit */ + update_lo_1_predicate: condition_lo; + update_lo_1_value: 1; + update_lo_2_predicate: not condition_lo; + update_lo_2_value: register_lo + 1; + output_predicate: condition_lo; + output_value : alu_lo; + output_dst : meta.needs_sampling; +} + + +action cnt_1() { + cntr_1.execute_stateful_alu(); +} + +action cnt_2() { + cntr_2.execute_stateful_alu(); +} + +action sample(){ + sampler_alu.execute_stateful_alu(); +} + +@pragma table_counter disabled +table match_cntr_1 { + reads { + pkt.field_a_32 : exact; + } + actions { + cnt_1; + } + size : 16384; +} + +table match_cntr_2 { + reads { + pkt.field_a_32 : exact; + pkt.field_j_8 : exact; + meta.count_value : exact; + } + actions { + cnt_2; + } + size : 16384; +} + +table match_flow { + reads { + pkt.field_a_32 : ternary; + meta.needs_sampling : exact; /* hack to ensure phv puts it in mau space */ + } + actions { + sample; + } + size : 8192; +} + +/* Main control flow */ + +control ingress { + apply(match_cntr_1); + apply(match_cntr_2); + apply(match_flow); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_156_indirect_stateful_cntr.p4 b/backends/tofino/bf-asm/test/internal/test_config_156_indirect_stateful_cntr.p4 new file mode 100644 index 00000000000..e351f842d4f --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_156_indirect_stateful_cntr.p4 @@ -0,0 +1,107 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + } +} + +header_type meta_t { + fields { + count_value : 16; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; +metadata meta_t meta; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +register stateful_cntr{ + width : 16; + /* direct : match_cntr; */ + instance_count : 8192; +} + + +blackbox stateful_alu cntr { + reg: stateful_cntr; + update_lo_1_value: register_lo + 1; + output_value : alu_lo; + output_dst : meta.count_value; + initial_register_lo_value : 1; +} + +/* +blackbox stateful_alu cntr2 { + reg: stateful_cntr; + update_lo_1_value: register_lo + 2; + output_value : alu_lo; + output_dst : meta.count_value; + initial_register_lo_value : 1; +} +*/ + +action cnt(/* param0 */) { + cntr.execute_stateful_alu(); + /* modify_field(pkt.field_e_16, param0); */ +} + +/* +action cnt2(){ + cntr2.execute_stateful_alu(); +} +*/ + +action do_nothing(){} + +/* @pragma immediate 0 */ +table match_cntr { + reads { + pkt.field_a_32 : exact; + } + actions { + cnt; + } + size : 16384; +} + +table dummy { + reads { + meta.count_value : exact; + } + actions { + do_nothing; + } +} + + +/* Main control flow */ + +control ingress { + apply(match_cntr); + apply(dummy); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_157_random_number_generator.p4 b/backends/tofino/bf-asm/test/internal/test_config_157_random_number_generator.p4 new file mode 100644 index 00000000000..22db9116f55 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_157_random_number_generator.p4 @@ -0,0 +1,75 @@ +#include "tofino/intrinsic_metadata.p4" + + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +action action_0(param0){ + modify_field_rng_uniform(pkt.field_a_32, 0, 65535); + modify_field(pkt.field_e_16, param0); +} + +action action_1(){ + modify_field_rng_uniform(pkt.field_d_32, 0, 0xffffff); +} + +action do_nothing(){} + +table table_0 { + reads { + pkt.field_b_32 : ternary; + } + actions { + action_0; + do_nothing; + } + size : 512; +} + +table table_1 { + reads { + pkt.field_c_32 : ternary; + } + actions { + action_1; + do_nothing; + } + size : 512; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_1); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_158_share_vliw.p4 b/backends/tofino/bf-asm/test/internal/test_config_158_share_vliw.p4 new file mode 100644 index 00000000000..deae036f0bf --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_158_share_vliw.p4 @@ -0,0 +1,81 @@ +#include "tofino/intrinsic_metadata.p4" + + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +action action_0(){ + add(pkt.field_a_32, pkt.field_b_32, pkt.field_c_32); + modify_field(pkt.field_j_8, 3); +} + +action action_1(){ + subtract(pkt.field_a_32, pkt.field_b_32, pkt.field_c_32); + shift_left(pkt.field_e_16, pkt.field_e_16, 5); +} + +action do_nothing(){ no_op();} + +table table_0 { + reads { + pkt.field_b_32 : ternary; + } + actions { + action_0; + action_1; + do_nothing; + } + size : 512; +} + +table table_1 { + reads { + pkt.field_c_32 : ternary; + } + actions { + action_0; + action_1; + do_nothing; + } + size : 512; +} + + +/* Main control flow */ + +control ingress { + if (pkt.field_i_8 == 1){ + apply(table_0); + } else { + apply(table_1); + } +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_159_stateful_using_phv_field.p4 b/backends/tofino/bf-asm/test/internal/test_config_159_stateful_using_phv_field.p4 new file mode 100644 index 00000000000..149e68edcaa --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_159_stateful_using_phv_field.p4 @@ -0,0 +1,90 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_16 : 16; + field_j_16 : 16; + field_k_8 : 8; + field_l_8 : 8; + + } +} + +header_type meta_t { + fields { + needs_sampling : 16 (signed, saturating); + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; +metadata meta_t meta; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +@pragma stateful_table_counter table_hit +register flow_cnt { + width : 16; + direct : match_tbl; + /* instance_count : 65536; */ +} + +blackbox stateful_alu sampler_alu { + reg: flow_cnt; + condition_hi: pkt.field_i_16 == 3; /* testing */ + condition_lo: register_lo == 10; /* sample limit */ + update_lo_1_predicate: condition_lo; + update_lo_1_value: 1; + update_lo_2_predicate: not condition_lo; + update_lo_2_value: register_lo + 1; + update_hi_1_value: pkt.field_j_16 + 2; + output_predicate: condition_lo; + output_value : alu_lo; + output_dst : meta.needs_sampling; +} + +action sample(){ + sampler_alu.execute_stateful_alu(); +} + +action do_nothing(){} + +table match_tbl { + reads { + pkt.field_a_32 : ternary; + pkt.field_i_16 : exact; /* hack */ + pkt.field_j_16 : exact; /* hack */ + meta.needs_sampling : exact; /* hack to ensure phv puts it in mau space */ + } + actions { + sample; + } + size : 4096; +} + + + + +/* Main control flow */ + +control ingress { + apply(match_tbl); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_15_wide_key.p4 b/backends/tofino/bf-asm/test/internal/test_config_15_wide_key.p4 new file mode 100644 index 00000000000..34c0fe1a645 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_15_wide_key.p4 @@ -0,0 +1,93 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + + +field_list first_field_list { + ipv4.protocol; + ipv4.srcAddr; +} + + +field_list_calculation first_hash { + input { + first_field_list; + } + algorithm : crc16; + output_width : 16; +} + +action action_0(param0){ + modify_field(ipv4.hdrChecksum, param0); +} + +action do_nothing(){ + no_op(); +} + +//@pragma stage 2 +table table_0 { + reads { + ipv4.dstAddr : exact ; + ipv4.srcAddr : exact ; + ethernet.dstAddr : exact ; + ethernet.srcAddr : exact ; + ipv4.protocol : exact ; + } + actions { + action_0; + do_nothing; + } +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_160_stateful_single_bit_mode.p4 b/backends/tofino/bf-asm/test/internal/test_config_160_stateful_single_bit_mode.p4 new file mode 100644 index 00000000000..d197d18151f --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_160_stateful_single_bit_mode.p4 @@ -0,0 +1,127 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 1; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_16 : 16; + field_j_16 : 16; + field_k_8 : 8; + field_l_8 : 8; + + from_pkt_gen : 1; + pad_0 : 7; + } +} + +header_type meta_t { + fields { + live_port : 1 (signed, saturating); + pad_0 : 7; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; +metadata meta_t meta; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +@pragma stateful_table_counter table_hit +register port_liveness_update { + width : 1; + /* direct : port_liveness_update_match_tbl; */ + instance_count : 65536; +} + +blackbox stateful_alu make_port_live { + reg: port_liveness_update; + selector_binding: selector_match_tbl; + update_lo_1_value: clr_bit; + output_value : alu_lo; + output_dst : meta.live_port; +} + +action port_alive(){ + make_port_live.execute_stateful_alu(); +} + +action action_0(param_0){ + modify_field(pkt.field_b_32, param_0); +} + +action do_nothing(){} + + +field_list selector_fields { + pkt.field_c_32; + pkt.field_d_32; +} + +field_list_calculation selector_hash { + input { + selector_fields; + } + algorithm : crc16; + output_width : 16; +} + + +action_selector some_selector { + selection_key : selector_hash; + selection_mode : fair; +} + +action_profile selector_match_tbl_action_profile { + actions { + action_0; + } + size : 1024; + dynamic_action_selection : some_selector; +} + + +table selector_match_tbl { + reads { + pkt.field_a_32 : ternary; + } + action_profile: selector_match_tbl_action_profile; + size : 4096; +} + +table port_liveness_update_match_tbl { + reads { + pkt.field_k_8 : ternary; + meta.live_port : exact; /* HACK */ + } + actions { + port_alive; + } + size : 1024; +} + +/* Main control flow */ + +control ingress { + if (pkt.from_pkt_gen == 0){ + apply(selector_match_tbl); + } else { + apply(port_liveness_update_match_tbl); + } +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_161_new_primitives.p4 b/backends/tofino/bf-asm/test/internal/test_config_161_new_primitives.p4 new file mode 100644 index 00000000000..ce3ffc15811 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_161_new_primitives.p4 @@ -0,0 +1,123 @@ +#include "tofino/intrinsic_metadata.p4" + + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32 (signed); + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_x_32 : 32 (signed); + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +action action_0(){ + bit_nor(pkt.field_a_32, pkt.field_b_32, pkt.field_c_32); +} +action action_1(param0){ + bit_nand(pkt.field_a_32, param0, pkt.field_c_32); +} +action action_2(param0){ + bit_xnor(pkt.field_a_32, pkt.field_b_32, param0); +} +action action_3(){ + bit_not(pkt.field_a_32, pkt.field_d_32); +} +action action_4(param0){ + min(pkt.field_a_32, pkt.field_d_32, param0); +} +action action_5(param0){ + max(pkt.field_a_32, param0, pkt.field_d_32); +} +action action_6(){ + min(pkt.field_b_32, pkt.field_d_32, 7); +} +action action_7(param0){ + max(pkt.field_b_32, param0, pkt.field_d_32); +} +action action_8(param0){ + max(pkt.field_x_32, pkt.field_x_32, param0); +} +action action_9(){ + shift_right(pkt.field_x_32, pkt.field_x_32, 7); +} + +action action_10(param0){ + //bit_andca(pkt.field_a_32, pkt.field_a_32, param0); + bit_andca(pkt.field_a_32, param0, pkt.field_a_32); +} + +action action_11(param0){ + //bit_andcb(pkt.field_a_32, pkt.field_a_32, param0); + bit_andcb(pkt.field_a_32, param0, pkt.field_a_32); +} + +action action_12(param0){ + //bit_orca(pkt.field_a_32, pkt.field_a_32, param0); + bit_orca(pkt.field_a_32, param0, pkt.field_a_32); +} + +action action_13(param0){ + //bit_orcb(pkt.field_a_32, pkt.field_a_32, param0); + bit_orcb(pkt.field_a_32, param0, pkt.field_a_32); +} + +action do_nothing(){} + +table table_0 { + reads { + pkt.field_a_32 : ternary; + pkt.field_b_32 : ternary; + pkt.field_c_32 : ternary; + pkt.field_d_32 : ternary; + pkt.field_g_16 : ternary; + pkt.field_h_16 : ternary; + } + actions { + action_0; + action_1; + action_2; + action_3; + action_4; + action_5; + action_6; + action_7; + action_8; + action_9; + action_10; + action_11; + action_12; + action_13; + do_nothing; + } + size : 512; +} + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_162_add_header_init.p4 b/backends/tofino/bf-asm/test/internal/test_config_162_add_header_init.p4 new file mode 100644 index 00000000000..e14a64a86dd --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_162_add_header_init.p4 @@ -0,0 +1,80 @@ +#include "tofino/intrinsic_metadata.p4" + + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32 (signed); + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_x_32 : 32 (signed); + } +} + +header_type to_add_t { + fields { + field_one : 16; + field_two : 8; + field_three : 32; + field_four : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; +header to_add_t to_add; + +parser parse_ethernet { + extract(pkt); + return select(pkt.field_i_8){ + 1 : parse_to_add; + default: ingress; + } +} + +parser parse_to_add { + extract(to_add); + return ingress; +} + +action action_0(){ + add_header(to_add); + modify_field(to_add.field_two, 15); +} + +action do_nothing(){} + +table table_0 { + reads { + pkt.field_a_32 : ternary; + to_add.field_one : exact; + to_add.field_three : exact; + to_add.field_four : exact; + } + actions { + action_0; + do_nothing; + } + size : 512; +} + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_163_stateful_table_math_unit.p4 b/backends/tofino/bf-asm/test/internal/test_config_163_stateful_table_math_unit.p4 new file mode 100644 index 00000000000..6b84ade4ec5 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_163_stateful_table_math_unit.p4 @@ -0,0 +1,92 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + } +} + +header_type meta_t { + fields { + count_value : 16; + needs_sampling : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; +metadata meta_t meta; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +register stateful_cntr_1{ + width : 32; + direct : match_cntr_1; + //attributes: signed, saturating; + /* instance_count : 8192; */ +} + +blackbox stateful_alu cntr_1 { + reg: stateful_cntr_1; + condition_lo: pkt.field_e_16 == 7; + update_lo_1_predicate: condition_lo; + update_lo_1_value: register_lo + 1; + update_lo_2_predicate: not condition_lo; + update_lo_2_value: register_hi ^ math_unit; + + math_unit_input: pkt.field_f_16; + math_unit_output_scale: 4; + math_unit_exponent_shift: -1; + math_unit_exponent_invert: True; + math_unit_lookup_table: 0xf 14 13 0xc 0x0b 10 9 8 7 6 5 4 3 2 1 0; + + output_predicate: condition_lo; + output_value : alu_lo; + output_dst : meta.needs_sampling; +} + +action cnt_1() { + /* cntr_1.execute_stateful_alu(pkt.field_i_8); */ + cntr_1.execute_stateful_alu(); +} + +table match_cntr_1 { + reads { + pkt.field_a_32 : exact; + pkt.field_e_16 : exact; + pkt.field_f_16 : exact; + meta.needs_sampling: exact; + } + actions { + cnt_1; + } + size : 16384; +} + +/* Main control flow */ + +control ingress { + apply(match_cntr_1); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_164_stateful_deterministic_sampling.p4 b/backends/tofino/bf-asm/test/internal/test_config_164_stateful_deterministic_sampling.p4 new file mode 100644 index 00000000000..9575811c3fd --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_164_stateful_deterministic_sampling.p4 @@ -0,0 +1,115 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type meta_t { + fields { + needs_sampling : 8; + } +} + +header ethernet_t ethernet; +header ipv4_t ipv4; +metadata meta_t meta; + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x0800 : parse_ipv4; + default : ingress; + } +} + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +register flow_cnt { + width : 8; + direct : ipv4_fib; +} + +blackbox stateful_alu sampler_alu { + reg: flow_cnt; + condition_lo: register_lo == 100; + update_lo_1_predicate: condition_lo; + update_lo_1_value: 0; + + update_lo_2_predicate: not condition_lo; + update_lo_2_value: register_lo + 1; + update_hi_1_value: 1; + + output_predicate: condition_lo; + output_value : alu_hi; + output_dst : meta.needs_sampling; +} + +action on_miss() { } + +action drop_me(){ + drop(); +} + +action ipv4_fib_hit() { + sampler_alu.execute_stateful_alu(); +} + +table ipv4_fib { + reads { + /* l3_metadata.vrf : exact; */ + ipv4.dstAddr : exact; + } + actions { + ipv4_fib_hit; + } + default_action: on_miss; + size : 1024; +} + +table check_needs { + reads { + meta.needs_sampling : exact; + } + actions { + drop_me; + on_miss; + } +} + +/* Main control flow */ + +control ingress { + apply(ipv4_fib); + apply(check_needs); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_165_stateful_bfd_failure_detection.p4 b/backends/tofino/bf-asm/test/internal/test_config_165_stateful_bfd_failure_detection.p4 new file mode 100644 index 00000000000..871a7db48da --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_165_stateful_bfd_failure_detection.p4 @@ -0,0 +1,125 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type meta_t { + fields { + bfd_timeout_detected : 8; + bfd_tx_or_rx : 8; + bfd_discriminator : 16; + } +} + +header ethernet_t ethernet; +header ipv4_t ipv4; +metadata meta_t meta; + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x0800 : parse_ipv4; + default : ingress; + } +} + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +register bfd_cnt { + width : 8; + /* direct : bfd; */ + instance_count : 1024; +} + +blackbox stateful_alu bfd_cnt_rx_alu { + reg: bfd_cnt; + update_lo_1_value : 0; +} + +blackbox stateful_alu bfd_cnt_tx_alu { + reg: bfd_cnt; + condition_lo: register_lo > 3; + + update_hi_1_value : 1; + update_lo_1_value : register_lo + 1; + + output_predicate: condition_lo; + output_value : alu_hi; + output_dst : meta.bfd_timeout_detected; +} + +action on_miss() { } + +action drop_me(){ + drop(); +} + +action bfd_rx() { + bfd_cnt_rx_alu.execute_stateful_alu(); +} + +action bfd_tx() { + bfd_cnt_tx_alu.execute_stateful_alu(); +} + + +table bfd { + reads { + meta.bfd_tx_or_rx : exact; + meta.bfd_discriminator : exact; + } + actions { + bfd_rx; + bfd_tx; + } + size : 1024; +} + +table check_needs { + reads { + meta.bfd_timeout_detected : exact; + } + actions { + drop_me; + on_miss; + } +} + +/* Main control flow */ + +control ingress { + apply(bfd); + apply(check_needs); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_166_stateful_generic_counter.p4 b/backends/tofino/bf-asm/test/internal/test_config_166_stateful_generic_counter.p4 new file mode 100644 index 00000000000..2bb1d3f08f2 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_166_stateful_generic_counter.p4 @@ -0,0 +1,96 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type meta_t { + fields { + encap_decap_size : 16; + } +} + +header ethernet_t ethernet; +header ipv4_t ipv4; +metadata meta_t meta; + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x0800 : parse_ipv4; + default : ingress; + } +} + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +register cntr { + width : 64; + instance_count : 8192; +} + +blackbox stateful_alu counter_alu { + reg: cntr; + condition_hi: register_lo < 0; + condition_lo: register_lo + meta.encap_decap_size < 0; + + update_hi_1_predicate: condition_hi and not condition_lo; + update_hi_1_value: register_hi + 1; + + update_hi_2_predicate: not condition_hi and condition_lo; + update_hi_2_value: register_hi - 1; + + update_lo_1_value : register_lo + meta.encap_decap_size; +} + +action increment_counter() { + counter_alu.execute_stateful_alu(); +} + +table packet_offset_counting { + reads { + meta.encap_decap_size : exact; /* hack to get allocated */ + ig_intr_md.ingress_port : exact; + } + actions { + increment_counter; + } + size : 1024; +} + +/* Main control flow */ + +control ingress { + apply(packet_offset_counting); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_167_stateful_flowlet_switching.p4 b/backends/tofino/bf-asm/test/internal/test_config_167_stateful_flowlet_switching.p4 new file mode 100644 index 00000000000..ecd86a811b5 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_167_stateful_flowlet_switching.p4 @@ -0,0 +1,144 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 4; + flags : 8; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type flowlet_state_layout { + fields { + padding : 16; + flowlet_next_hop : 16; + flowlet_last_time_seen : 32; + } +} + +header_type meta_t { + fields { + next_hop : 16; + tstamp : 32; + } +} + +header ethernet_t ethernet; +header ipv4_t ipv4; +header tcp_t tcp; +metadata meta_t meta; + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x0800 : parse_ipv4; + default : ingress; + } +} + +parser parse_ipv4 { + extract(ipv4); + return select(ipv4.protocol){ + 0x06 : parse_tcp; + default : ingress; + } +} + +parser parse_tcp { + extract(tcp); + return ingress; +} + +field_list hash_fields_5_tuple { + ipv4.srcAddr; + ipv4.dstAddr; + ipv4.protocol; + tcp.srcPort; + tcp.dstPort; +} + +field_list_calculation hash_id { + input { hash_fields_5_tuple; } + algorithm : crc32; + output_width : 16; +} + + +register flowlet_state { + layout : flowlet_state_layout; + instance_count : 65536; +} + +blackbox stateful_alu flowlet_state_alu { + reg: flowlet_state; + + condition_lo: meta.tstamp - register_lo > 20000; + + update_hi_1_predicate: condition_lo; + update_hi_1_value: register_hi; + + update_lo_1_value: meta.tstamp; + + output_value: alu_hi; + output_dst: meta.next_hop; +} + +action get_flowlet_next_hop() { + flowlet_state_alu.execute_stateful_alu(); +} + +table flowlet_next_hop { + reads { /* HACK, because actually want to use hash result to index */ + meta.next_hop : ternary; + meta.tstamp: exact; + } + actions { + get_flowlet_next_hop; + } + size : 1024; +} + +/* Main control flow */ + +control ingress { + apply(flowlet_next_hop); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_168_meter_bug.p4 b/backends/tofino/bf-asm/test/internal/test_config_168_meter_bug.p4 new file mode 100644 index 00000000000..ccf39b541cb --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_168_meter_bug.p4 @@ -0,0 +1,89 @@ +#include "tofino/intrinsic_metadata.p4" +//#include "tofino/stateful_alu_blackbox.p4" + + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + + +header ethernet_t ethernet; +header ipv4_t ipv4; + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x0800 : parse_ipv4; + default : ingress; + } +} + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + + +meter exm_meter2 { + type : bytes; + direct : table_0; + result : ipv4.diffserv; +} + + +action nop() { +} + +action action_0(){ + modify_field(ipv4.ttl, 4); +} + +action action_1(){ + modify_field(ipv4.ttl, 5); +} + + +table table_0 { + reads { + ipv4.srcAddr : exact; + ipv4.dstAddr : exact; + ipv4.diffserv : exact; /* hack */ + } + actions { + action_0; + action_1; + nop; + } +} + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_169_stateful_sflow_sequence.p4 b/backends/tofino/bf-asm/test/internal/test_config_169_stateful_sflow_sequence.p4 new file mode 100644 index 00000000000..e030a838ece --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_169_stateful_sflow_sequence.p4 @@ -0,0 +1,195 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 4; + flags : 8; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type meta_t { + fields { + sflow_sample_seq_no : 32; + sflow_src : 16; + } +} + +header_type sflowHdr_t { + fields { + seq_num : 16; + num_samples : 16; + temp : 16 (saturating); + drops : 16; + } +} + + +header ethernet_t ethernet; +header ipv4_t ipv4; +header tcp_t tcp; +metadata meta_t meta; +metadata sflowHdr_t sflowHdr; + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x0800 : parse_ipv4; + default : ingress; + } +} + +parser parse_ipv4 { + extract(ipv4); + return select(ipv4.protocol){ + 0x06 : parse_tcp; + default : ingress; + } +} + +parser parse_tcp { + extract(tcp); + return ingress; +} + + +register sflow_state_seq_num { + width : 32; + direct : sflow_seq_num; +} + +blackbox stateful_alu seq_num_gen { + reg: sflow_state_seq_num; + + update_lo_1_value: register_lo + 1; + update_hi_1_value: register_lo; + + output_value: alu_hi; + output_dst: meta.sflow_sample_seq_no; +} + + +register sflow_state_exp_seq_num { + width : 32; + direct : sflow_verify_seq_no_step_2; +} + +blackbox stateful_alu sflow_exp_seq_num { + reg: sflow_state_exp_seq_num; + + update_hi_1_value: sflowHdr.seq_num - register_lo; + update_lo_1_value: sflowHdr.temp; + + output_value: alu_hi; + output_dst: sflowHdr.drops; +} + + +action get_sflow_seq_num(){ + seq_num_gen.execute_stateful_alu(); +} + +action calc_next_seq_num() { + add(sflowHdr.temp, sflowHdr.seq_num, sflowHdr.num_samples); +} + +action chk_sflow_seq_num() { + sflow_exp_seq_num.execute_stateful_alu(); +} + +action drop_me(){ + drop(); +} + +action do_nothing(){} + + +table sflow_seq_num { + reads { + meta.sflow_src: exact; + meta.sflow_sample_seq_no : exact; /* HACK */ + } + actions { + get_sflow_seq_num; + } + size : 1024; +} + +table sflow_verify_seq_no_step_1 { + actions { + calc_next_seq_num; + } + size : 512; +} + +@pragma stage 1 /* Provided dependency graph is incorrect */ +table sflow_verify_seq_no_step_2 { + reads { + meta.sflow_src : exact; + } + actions { + chk_sflow_seq_num; + } + size : 16384; +} + +table sflow_verify_seq_no_step_3 { + reads { + sflowHdr.drops : ternary; + } + actions { + drop_me; + do_nothing; + } + size : 512; +} + + + +/* Main control flow */ + +control ingress { + apply(sflow_seq_num); + apply(sflow_verify_seq_no_step_1); + apply(sflow_verify_seq_no_step_2); + apply(sflow_verify_seq_no_step_3); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_16_action_packing_multi_entry_with_pad.p4 b/backends/tofino/bf-asm/test/internal/test_config_16_action_packing_multi_entry_with_pad.p4 new file mode 100644 index 00000000000..393a97e76ed --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_16_action_packing_multi_entry_with_pad.p4 @@ -0,0 +1,79 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + + +action action_0(param0){ + modify_field(ipv4.hdrChecksum, param0); +} + +action action_1(param0, param1){ + modify_field(ipv4.diffserv, param0); + modify_field(ipv4.ttl, param1); +} + +action do_nothing(){ + no_op(); +} + +table table_0 { + reads { + ipv4.dstAddr : exact ; + } + actions { + action_0; + action_1; + } +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_170_stateful_selection_table_update.p4 b/backends/tofino/bf-asm/test/internal/test_config_170_stateful_selection_table_update.p4 new file mode 100644 index 00000000000..bd5fbb9b834 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_170_stateful_selection_table_update.p4 @@ -0,0 +1,167 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 4; + flags : 8; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type meta_t { + fields { + egress_ifindex : 16; + instance_id : 16; + down_port : 1; + from_packet_generator : 1; + padding : 6; + } +} + + +header ethernet_t ethernet; +header ipv4_t ipv4; +header tcp_t tcp; +metadata meta_t meta; + + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x0800 : parse_ipv4; + default : ingress; + } +} + +parser parse_ipv4 { + extract(ipv4); + return select(ipv4.protocol){ + 0x06 : parse_tcp; + default : ingress; + } +} + +parser parse_tcp { + extract(tcp); + return ingress; +} + +field_list lag_hash_fields { + ethernet.srcAddr; + ethernet.dstAddr; + ipv4.srcAddr; + ipv4.dstAddr; + ipv4.protocol; + tcp.srcPort; + tcp.dstPort; +} + +field_list_calculation lag_hash { + input { lag_hash_fields; } + algorithm : crc16; + output_width : 14; +} + +action_selector lag_selector { + selection_key : lag_hash; + /* selection_map : lag_mbrs; */ +} +action set_lag_port(port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action_profile lag_action_profile { + actions { + set_lag_port; + } + size : 1024; + dynamic_action_selection : lag_selector; +} + + +register lag_mbrs { + width : 1; + instance_count : 1; +} + +blackbox stateful_alu port_status_alu { + reg: lag_mbrs; + selector_binding: lag_group; + update_lo_1_value: clr_bit; +} + +action set_mbr_down(){ + port_status_alu.execute_stateful_alu(); +} + +action drop_packet(){ + drop(); +} + + +table lag_group { + reads { + meta.egress_ifindex : exact; + } + action_profile: lag_action_profile; +} + +table lag_group_fast_update { + reads { + meta.down_port : exact; + meta.instance_id : exact; + } + actions { + set_mbr_down; + drop_packet; + } +} + +/* Main control flow */ + +control ingress { + if (meta.from_packet_generator == 0){ + apply(lag_group); + } else { + apply(lag_group_fast_update); + } +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_171_stateful_conga.p4 b/backends/tofino/bf-asm/test/internal/test_config_171_stateful_conga.p4 new file mode 100644 index 00000000000..dd752649729 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_171_stateful_conga.p4 @@ -0,0 +1,175 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 4; + flags : 8; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type meta_t { + fields { + next_hop : 8; + dst_tor_id : 8; + is_conga_packet : 1 ; + padding : 7; + } +} + +header_type conga_meta_t { + fields { + next_hop : 8; + util : 8; + } +} + +header_type conga_state_layout { + fields { + next_hop : 8; + utilization : 8; + } +} + + +header ethernet_t ethernet; +header ipv4_t ipv4; +header tcp_t tcp; +metadata meta_t meta; +metadata conga_meta_t conga_meta; + + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x0800 : parse_ipv4; + default : ingress; + } +} + +parser parse_ipv4 { + extract(ipv4); + return select(ipv4.protocol){ + 0x06 : parse_tcp; + default : ingress; + } +} + +parser parse_tcp { + extract(tcp); + return ingress; +} + + + +register conga_state { + layout : conga_state_layout; + instance_count : 256; +} + +blackbox stateful_alu conga_alu { + reg: conga_state; + update_lo_1_value: register_hi; + output_value: alu_lo; + output_dst: meta.next_hop; +} + +blackbox stateful_alu conga_update_alu { + reg: conga_state; + + condition_hi: register_lo > conga_meta.util; + condition_lo: register_hi == conga_meta.next_hop; + + update_hi_1_predicate: condition_hi; + update_hi_1_value: conga_meta.next_hop; + + update_lo_1_predicate: condition_hi or condition_lo; + update_lo_1_value: conga_meta.util; + + output_value: alu_hi; + output_dst: meta.next_hop; +} + +action get_preferred_next_hop(){ + conga_alu.execute_stateful_alu(); +} + +action update_preferred_next_hop(){ + conga_update_alu.execute_stateful_alu(); +} + + +table conga_rd_next_hop_table { + reads { + meta.dst_tor_id : exact; + } + actions { + get_preferred_next_hop; + } + size : 256; +} + +table conga_wr_next_hop_table { + reads { + meta.dst_tor_id : exact; + meta.next_hop : exact; /* HACK */ + conga_meta.next_hop : exact; /* HACK */ + conga_meta.util : exact; /* HACK */ + } + actions { + update_preferred_next_hop; + } + size : 256; +} + + + +/* Main control flow */ + +control ingress { + if (meta.is_conga_packet == 1){ + apply(conga_wr_next_hop_table); + } else { + apply(conga_rd_next_hop_table); + } + +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_172_stateful_heavy_hitter.p4 b/backends/tofino/bf-asm/test/internal/test_config_172_stateful_heavy_hitter.p4 new file mode 100644 index 00000000000..aba3f4acdcf --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_172_stateful_heavy_hitter.p4 @@ -0,0 +1,262 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 4; + flags : 8; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type meta_t { + fields { + is_not_heavy_hitter : 1; + padding : 7; + + pad_1 : 4; + hash_1 : 12; + pad_2 : 4; + hash_2 : 12; + //pad_3 : 4; + hash_3 : 32; + } +} + + + +header ethernet_t ethernet; +header ipv4_t ipv4; +header tcp_t tcp; +metadata meta_t meta; + + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x0800 : parse_ipv4; + default : ingress; + } +} + +parser parse_ipv4 { + extract(ipv4); + return select(ipv4.protocol){ + 0x06 : parse_tcp; + default : ingress; + } +} + +parser parse_tcp { + extract(tcp); + return ingress; +} + +field_list fields_for_hash { ipv4.srcAddr; } + +field_list_calculation hash_1 { + input { fields_for_hash; } + algorithm : crc16; + output_width : 12; +} + +field_list_calculation hash_2 { + input { fields_for_hash; } + algorithm : crc16_msb; + output_width : 12; +} + +field_list_calculation hash_3 { + input { fields_for_hash; } + algorithm : identity; + output_width : 32; +} + +register sketch_cnt_1 { + width: 32; + direct: heavy_hitter_tbl_1; +} + +register sketch_cnt_2 { + width: 32; + direct: heavy_hitter_tbl_2; +} + +register sketch_cnt_3 { + width: 32; + direct: heavy_hitter_tbl_3; +} + +blackbox stateful_alu sketch_cnt_alu_1 { + reg: sketch_cnt_1; + + condition_hi: register_lo > 10000000; + condition_lo: register_lo < 50000000; + + update_lo_1_value: register_lo + 1; + update_hi_1_value: 1; + + output_predicate: not condition_hi or not condition_lo; + output_value: alu_hi; + output_dst: meta.is_not_heavy_hitter; /* TODO: make reduction or */ +} + +blackbox stateful_alu sketch_cnt_alu_2 { + reg: sketch_cnt_2; + + condition_hi: register_lo > 10000000; + condition_lo: register_lo < 50000000; + + update_lo_1_value: register_lo + 1; + update_hi_1_value: 1; + + output_predicate: not condition_hi or not condition_lo; + output_value: alu_hi; + output_dst: meta.is_not_heavy_hitter; /* TODO: make reduction or */ +} + +blackbox stateful_alu sketch_cnt_alu_3 { + reg: sketch_cnt_3; + + condition_hi: register_lo > 10000000; + condition_lo: register_lo < 50000000; + + update_lo_1_value: register_lo + 1; + update_hi_1_value: 1; + + output_predicate: not condition_hi or not condition_lo; + output_value: alu_hi; + output_dst: meta.is_not_heavy_hitter; /* TODO: make reduction or */ +} + +action run_alu_1(){ + sketch_cnt_alu_1.execute_stateful_alu(); +} + +action run_alu_2(){ + sketch_cnt_alu_2.execute_stateful_alu(); +} + +action run_alu_3(){ + sketch_cnt_alu_3.execute_stateful_alu(); +} + +action set_hash_1_and_2(){ + modify_field_with_hash_based_offset(meta.hash_1, 0, hash_1, 4096); + modify_field_with_hash_based_offset(meta.hash_2, 0, hash_2, 4096); +} + +action set_hash_3(){ + modify_field_with_hash_based_offset(meta.hash_3, 0, hash_3, 4294967296);//4096); +} + +action drop_me(){ + drop(); +} + +action do_nothing(){} + + +table set_hashes_1_and_2_tbl { + actions { + set_hash_1_and_2; + } + size : 256; +} + +table set_hash_3_tbl { + actions { + set_hash_3; + } + size : 256; +} + +table heavy_hitter_tbl_1 { + reads { + meta.hash_1 : exact; + } + actions { + run_alu_1; + } +} + +table heavy_hitter_tbl_2 { + reads { + meta.hash_2 : exact; + } + actions { + run_alu_2; + } +} + +table heavy_hitter_tbl_3 { + reads { + meta.hash_3 : exact; + } + actions { + run_alu_3; + } +} + + +table react { + reads { + meta.is_not_heavy_hitter : exact; + } + actions { + drop_me; + do_nothing; + } +} + + +/* Main control flow */ + +control ingress { + apply(set_hashes_1_and_2_tbl); + apply(set_hash_3_tbl); + + apply(heavy_hitter_tbl_1); + apply(heavy_hitter_tbl_2); + apply(heavy_hitter_tbl_3); + + apply(react); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_173_stateful_bloom_filter.p4 b/backends/tofino/bf-asm/test/internal/test_config_173_stateful_bloom_filter.p4 new file mode 100644 index 00000000000..aa617f64b68 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_173_stateful_bloom_filter.p4 @@ -0,0 +1,259 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 4; + flags : 8; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type meta_t { + fields { + pad_1 : 6; + hash_1 : 18; + pad_2 : 6; + hash_2 : 18; + pad_3 : 6; + hash_3 : 18; + + pad_4 : 7; + is_not_member : 1; + } +} + +header ethernet_t ethernet; +header ipv4_t ipv4; +header tcp_t tcp; +metadata meta_t meta; + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x0800 : parse_ipv4; + default : ingress; + } +} + +parser parse_ipv4 { + extract(ipv4); + return select(ipv4.protocol){ + 0x06 : parse_tcp; + default : ingress; + } +} + +parser parse_tcp { + extract(tcp); + return ingress; +} + +field_list fields_for_hash { + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation hash_1 { + input { fields_for_hash; } + algorithm: random; + output_width: 18; +} + +field_list_calculation hash_2 { + input { fields_for_hash; } + algorithm: crc32; + output_width: 18; +} + +field_list_calculation hash_3 { + input { fields_for_hash; } + algorithm: identity; + output_width: 18; +} + + +register bloom_filter_1 { + width : 1; + direct : bloom_filter_membership_1; +} + +register bloom_filter_2 { + width : 1; + direct : bloom_filter_membership_2; +} + +register bloom_filter_3 { + width : 1; + direct : bloom_filter_membership_3; +} + +blackbox stateful_alu bloom_filter_alu_1 { + reg: bloom_filter_1; + + update_lo_1_value: set_bitc; + + output_value: alu_lo; + output_dst: meta.is_not_member; /* Want reduction OR */ +} + +blackbox stateful_alu bloom_filter_alu_2 { + reg: bloom_filter_2; + + update_lo_1_value: set_bitc; + + output_value: alu_lo; + output_dst: meta.is_not_member; /* Want reduction OR */ +} + +blackbox stateful_alu bloom_filter_alu_3 { + reg: bloom_filter_3; + + update_lo_1_value: set_bitc; + + output_value: alu_lo; + output_dst: meta.is_not_member; /* Want reduction OR */ +} + +action run_bloom_filter_1(){ + bloom_filter_alu_1.execute_stateful_alu(); +} +action run_bloom_filter_2(){ + bloom_filter_alu_2.execute_stateful_alu(); +} +action run_bloom_filter_3(){ + bloom_filter_alu_3.execute_stateful_alu(); +} + +action set_hash_1(){ + modify_field_with_hash_based_offset(meta.hash_1, 0, hash_1, 262144); +} +action set_hash_2(){ + modify_field_with_hash_based_offset(meta.hash_2, 0, hash_2, 262144); +} +action set_hash_3(){ + modify_field_with_hash_based_offset(meta.hash_3, 0, hash_3, 262144); +} + + + + +action drop_me(){ + drop(); +} + +action do_nothing(){} + + +table set_hash_1_tbl { + actions { + set_hash_1; + } + size : 256; +} + +table set_hash_2_tbl { + actions { + set_hash_2; + } + size : 1; +} + +table set_hash_3_tbl { + actions { + set_hash_3; + } + size : 1; +} + +table bloom_filter_membership_1 { + reads { + meta.hash_1 : exact; + } + actions { + run_bloom_filter_1; + } + size : 262144; +} + +table bloom_filter_membership_2 { + reads { + meta.hash_2 : exact; + } + actions { + run_bloom_filter_2; + } + size : 262144; +} + +table bloom_filter_membership_3 { + reads { + meta.hash_3 : exact; + } + actions { + run_bloom_filter_3; + } + size : 262144; +} + +table react { + reads { + meta.is_not_member : exact; + } + actions { + drop_me; + do_nothing; + } +} + +/* Main control flow */ + +control ingress { + apply(set_hash_1_tbl); + apply(set_hash_2_tbl); + apply(set_hash_3_tbl); + + apply(bloom_filter_membership_1); + apply(bloom_filter_membership_2); + apply(bloom_filter_membership_3); + + apply(react); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_175_match_table_with_no_key.p4 b/backends/tofino/bf-asm/test/internal/test_config_175_match_table_with_no_key.p4 new file mode 100644 index 00000000000..9c4cc3856f1 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_175_match_table_with_no_key.p4 @@ -0,0 +1,70 @@ + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32 (signed); + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_x_32 : 32 (signed); + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +action action_0(){ + bit_nor(pkt.field_a_32, pkt.field_b_32, pkt.field_c_32); +} +action action_1(param0){ + bit_orca(pkt.field_b_32, param0, pkt.field_c_32); +} + +action do_nothing(){} + +table table_0 { + actions { + action_0; + } +} + +table table_1 { + actions { + action_1; + } +} + +table table_2 { + actions { + do_nothing; + } +} + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_1); + if (pkt.field_i_8 == 0){ + apply(table_2); + } +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_176_extend_crc16.p4 b/backends/tofino/bf-asm/test/internal/test_config_176_extend_crc16.p4 new file mode 100644 index 00000000000..a21db0274ec --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_176_extend_crc16.p4 @@ -0,0 +1,77 @@ + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32 (signed); + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_x_32 : 32 (signed); + } +} + +header_type meta_t { + fields { + hash_1 : 16; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; +metadata meta_t meta; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +field_list fields_for_hash { + pkt.field_c_32; + pkt.field_d_32; +} + +field_list_calculation hash_1 { + input { fields_for_hash; } + algorithm: crc16; + output_width: 16; +} + + +action action_0(){ + //modify_field_with_hash_based_offset(meta.hash_1, 0, hash_1, 65536); //16 + modify_field_with_hash_based_offset(meta.hash_1, 0, hash_1, 16777216); //24 + //modify_field_with_hash_based_offset(meta.hash_1, 0, hash_1, 4294967296); //32 +} + +action do_nothing(){} + +table table_0 { + reads { + pkt.field_g_16 : ternary; + } + actions { + action_0; + do_nothing; + } +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_177_meter_test.p4 b/backends/tofino/bf-asm/test/internal/test_config_177_meter_test.p4 new file mode 100644 index 00000000000..9e792a4efe0 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_177_meter_test.p4 @@ -0,0 +1,90 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + color_0 : 8; + pad_0 : 24; + pad_1 : 160; + pad_2 : 24; + color_1 : 8; + pad_3 : 24; + + lpf : 16; + } +} + +header_type meta_t { + fields { + color_0 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; +metadata meta_t meta; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +meter meter_0 { + type : bytes; + direct : table_0; + result : pkt.color_0; + //static : table_0; + //instance_count : 500; +} + +action action_0(param0){ + //execute_meter(meter_0, 7, pkt.color_0); +} + +action action_1(param0){ + //execute_meter(meter_0, 0, pkt.color_1); +} + +action do_nothing(){ + no_op(); +} + + +table table_0 { + reads { + pkt.field_e_16 : ternary; + pkt.color_0 : exact; /* HACK */ + pkt.color_1 : exact; /* HACK */ + //meta.color_0 : exact; + } + actions { + action_0; + action_1; + do_nothing; + } + size : 6000; +} + + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_178_hash_action.p4 b/backends/tofino/bf-asm/test/internal/test_config_178_hash_action.p4 new file mode 100644 index 00000000000..28121778867 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_178_hash_action.p4 @@ -0,0 +1,69 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + color_0 : 8; + pad_0 : 24; + pad_1 : 160; + pad_2 : 24; + color_1 : 8; + pad_3 : 24; + + lpf : 16; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +meter meter_0 { + type : bytes; + static : table_0; + instance_count : 500; +} + +action action_0(param0){ + modify_field(pkt.field_a_32, param0); +} + + + +table table_0 { + reads { + pkt.field_i_8 : exact; + } + actions { + action_0; + } + size : 256; +} + + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_179_check_if_sequential_action_used.p4 b/backends/tofino/bf-asm/test/internal/test_config_179_check_if_sequential_action_used.p4 new file mode 100644 index 00000000000..57bbaab3046 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_179_check_if_sequential_action_used.p4 @@ -0,0 +1,79 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + color_0 : 8; + pad_0 : 24; + pad_1 : 160; + pad_2 : 24; + color_1 : 8; + pad_3 : 24; + + lpf : 16; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +action action_0(param0){ + modify_field(pkt.field_a_32, param0); + drop(); + add(pkt.field_b_32, pkt.field_a_32, 2); +} + +action action_1(param0){ + drop(); + add(pkt.field_b_32, pkt.field_a_32, 2); + modify_field(pkt.field_a_32, param0); +} + +action action_2(param0){ + drop(); + modify_field(pkt.field_a_32, param0); + add(pkt.field_b_32, pkt.field_c_32, pkt.field_a_32); +} + + + +table table_0 { + reads { + pkt.field_i_8 : exact; + } + actions { + //action_0; + action_1; + //action_2; + } + size : 256; +} + + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_17_action_packing_wide_with_pad.p4 b/backends/tofino/bf-asm/test/internal/test_config_17_action_packing_wide_with_pad.p4 new file mode 100644 index 00000000000..c770b5f80de --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_17_action_packing_wide_with_pad.p4 @@ -0,0 +1,82 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + + +action action_0(param0, param1, param2, param3){ + modify_field(ethernet.dstAddr, param0); + modify_field(ethernet.srcAddr, param1); + modify_field(ipv4.dstAddr, param2); + modify_field(ipv4.srcAddr, param3); +} + +action action_1(param0, param1){ + modify_field(ipv4.diffserv, param0); + modify_field(ipv4.ttl, param1); +} + +action do_nothing(){ + no_op(); +} + +table table_0 { + reads { + ipv4.dstAddr : exact ; + } + actions { + action_0; + action_1; + } +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_180_first_proxy_hash.p4 b/backends/tofino/bf-asm/test/internal/test_config_180_first_proxy_hash.p4 new file mode 100644 index 00000000000..536a672021e --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_180_first_proxy_hash.p4 @@ -0,0 +1,74 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + color_0 : 8; + pad_0 : 24; + pad_1 : 160; + pad_2 : 24; + color_1 : 8; + pad_3 : 24; + + lpf : 16; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +action action_0(param0, param1){ + modify_field(pkt.field_c_32, param0); + modify_field(pkt.field_g_16, param1); +} + +action action_1(){ + drop(); +} + + +//@pragma immediate 0 +@pragma proxy_hash_width 24 +@pragma proxy_hash_algorithm crc16_extend +table table_0 { + reads { + pkt.field_a_32 : exact; + pkt.field_b_32 : exact; + pkt.field_e_16 : exact; + pkt.field_f_16 : exact; + } + actions { + action_0; + action_1; + } + size : 16384; +} + + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_181_first_alg_tcam.p4 b/backends/tofino/bf-asm/test/internal/test_config_181_first_alg_tcam.p4 new file mode 100644 index 00000000000..51069ad36a9 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_181_first_alg_tcam.p4 @@ -0,0 +1,161 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 4; + flags : 8; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + + +header_type meta_t { + fields { + partition_index : 11; + pad_0 : 9; + vrf : 12; + } +} + + +header ethernet_t ethernet; +header ipv4_t ipv4; +header tcp_t tcp; +metadata meta_t meta; + + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x0800 : parse_ipv4; + default : ingress; + } +} + +parser parse_ipv4 { + extract(ipv4); + return select(ipv4.protocol){ + 0x06 : parse_tcp; + default : ingress; + } +} + +parser parse_tcp { + extract(tcp); + return ingress; +} + + +action set_partition_index(idx){ + modify_field(meta.partition_index, idx); +} + +action ipv4_lpm_hit(){ + subtract(ipv4.ttl, ipv4.ttl, 1); +} + +action lpm_miss(){ + drop(); +} + +action do_nothing(){ } +action do_nothing_2(){} + +table ipv4_lpm_partition { + reads { + meta.vrf: exact; + ipv4.dstAddr: lpm; + } + actions { + set_partition_index; + } + size : 1024; +} + +/* @pragma atcam_number_partitions 1024 */ +@pragma atcam_partition_index meta.partition_index +table ipv4_alg_tcam { + reads { + meta.partition_index: exact; + meta.vrf: exact; + ipv4.dstAddr: lpm; + } + actions { + ipv4_lpm_hit; + lpm_miss; + } + /* size : 8192; */ + size: 65536; + /* size : 262144; */ +} + +table table_n { + reads { + ipv4.dstAddr : exact; + } + actions { + do_nothing; + do_nothing_2; + } +} + +table table_x { + reads { + ipv4.dstAddr : ternary; + } + actions { + do_nothing; + } +} + +/* Main control flow */ + +control ingress { + apply(ipv4_lpm_partition); + apply(ipv4_alg_tcam) { + lpm_miss { + apply(table_n) { + do_nothing_2 { + apply(table_x); + } + } + } + } +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_182_warp_primitive.p4 b/backends/tofino/bf-asm/test/internal/test_config_182_warp_primitive.p4 new file mode 100644 index 00000000000..a9fb3740e91 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_182_warp_primitive.p4 @@ -0,0 +1,81 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type meta_t { + fields { + a : 16; + b : 16; + c : 16; + d : 16; + } +} + + +header ethernet_t ethernet; +metadata meta_t meta; + + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return ingress; +} + +action action_0(){ + bypass_egress(); + //mark_for_drop(); +} + +action action_1(){ + drop(); +} + +action action_2(){ + //exit(); +} + +table table_0 { + reads { + ethernet.dstAddr: exact; + } + actions { + action_0; + action_1; + } + size : 1024; +} + +table table_1 { + reads { + ethernet.dstAddr: exact; + } + actions { + action_2; + } +} + +table table_2 { + reads { + ethernet.dstAddr: exact; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); + apply(table_1); + apply(table_2); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_183_sample_e2e.p4 b/backends/tofino/bf-asm/test/internal/test_config_183_sample_e2e.p4 new file mode 100644 index 00000000000..d28e7ac56f5 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_183_sample_e2e.p4 @@ -0,0 +1,58 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type meta_t { + fields { + a : 16; + b : 16; + c : 16; + d : 16; + } +} + + +header ethernet_t ethernet; +metadata meta_t meta; + + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return ingress; +} + +action action_0(){ + sample_e2e(1, 7); +} + +action action_1(){ +} + + +table table_0 { + reads { + ethernet.dstAddr: exact; + } + actions { + action_0; + action_1; + } + size : 1024; +} + +control ingress { } + +control egress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_184_stateful_bug1.p4 b/backends/tofino/bf-asm/test/internal/test_config_184_stateful_bug1.p4 new file mode 100644 index 00000000000..3a020990a5f --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_184_stateful_bug1.p4 @@ -0,0 +1,103 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + blah : 16; + } +} + +header_type meta_t { + fields { + a : 16; + b : 16; + c : 16; + d : 16; + } +} + + +header ethernet_t ethernet; +metadata meta_t meta; + + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return ingress; +} + +action action_0(){ + sampling_alu.execute_stateful_alu(); +} + +action action_1(){ +} + + +register sampling_cntr { + width : 32; + static: table_0; + instance_count : 139264; /* Fills 34 + 1 spare RAMs (max size - 1) */ +} + +/* Note the extra complexity of this ALU program is required so that if C2C was + * already set (by the bloom filter) it will stay set even if this ALU says not + * to sample. */ +blackbox stateful_alu sampling_alu { + reg: sampling_cntr; + initial_register_lo_value: 1; + condition_lo: register_lo >= 10; + condition_hi: ig_intr_md_for_tm.copy_to_cpu != 0; + update_lo_1_predicate: condition_lo; + update_lo_1_value: 1; + update_lo_2_predicate: not condition_lo; + update_lo_2_value: register_lo + 1; + update_hi_1_value: 1; + output_predicate: condition_lo or condition_hi; + output_value : alu_hi; + output_dst : ig_intr_md_for_tm.copy_to_cpu; +} + +field_list bf_hash_fields { + ethernet.dstAddr; + ethernet.etherType; +} + +field_list_calculation bf_hash_1 { + input { bf_hash_fields; } + algorithm: random; + output_width: 16; +} + +action action_7(){ + modify_field_with_hash_based_offset(ethernet.blah, 0, bf_hash_1, 262144); +} + + +table table_0 { + reads { + ethernet.dstAddr: exact; + } + actions { + action_0; + action_1; + } + size : 1024; +} + +table table_1 { + actions { action_7; } +} + +control ingress { + apply(table_0); + apply(table_1); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_185_first_lpf.p4 b/backends/tofino/bf-asm/test/internal/test_config_185_first_lpf.p4 new file mode 100644 index 00000000000..2d259ae4c9d --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_185_first_lpf.p4 @@ -0,0 +1,105 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/lpf_blackbox.p4" +#include "tofino/wred_blackbox.p4" +#include "tofino/meter_blackbox.p4" + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + blah0 : 16; + blah1 : 8; + blah2 : 8; + } +} + +header_type meta_t { + fields { + a : 16; + b : 16; + c : 16; + d : 16; + } +} + + +header ethernet_t ethernet; +metadata meta_t meta; + + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return ingress; +} + +action action_0(){ + my_lpf.execute(ethernet.blah0); +} + +action do_nothing(){} + +action action_1(){ + my_wred.execute(ethernet.blah1); +} + +action action_2(){ + my_meter.execute(ethernet.blah2); +} + +blackbox lpf my_lpf { + filter_input : ethernet.etherType; + direct : table_0; +} + +blackbox wred my_wred { + wred_input : ethernet.etherType; + direct : table_1; +} + +blackbox meter my_meter { + type : bytes; + direct : table_2; +} + +table table_0 { + reads { + ethernet.dstAddr: exact; + } + actions { + action_0; + //do_nothing; + } + size : 1024; +} + +table table_1 { + reads { + ethernet.dstAddr: exact; + } + actions { + action_1; + } + size : 1024; +} + +table table_2 { + reads { + ethernet.dstAddr: exact; + } + actions { + action_2; + } + size : 1024; +} + +control ingress { + apply(table_0); + apply(table_1); + apply(table_2); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_186_hlir_modify.p4 b/backends/tofino/bf-asm/test/internal/test_config_186_hlir_modify.p4 new file mode 100644 index 00000000000..8c6803b1383 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_186_hlir_modify.p4 @@ -0,0 +1,89 @@ + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + blah0 : 16; + blah1 : 8; + blah2 : 8; + } +} + +header_type meta_t { + fields { + a : 16; + b : 16; + c : 16; + d : 16; + + e : 32; + f : 32; + g : 32; + h : 32; + + i : 8; + j : 8; + k : 8; + l : 8; + } +} + + +header ethernet_t ethernet; +metadata meta_t meta; + + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return ingress; +} + +action action_0(blah1, blah2, blah3){ + modify_field(meta.a, blah1); + modify_field(meta.b, blah2); + modify_field(meta.c, blah3); +} + +action action_1(){ + modify_field(meta.e, 7); + modify_field(meta.f, 8); + modify_field(meta.g, 2097151); /* 2**21 - 1 */ + modify_field(meta.h, -1); +} + +action do_nothing(){} + + +table table_0 { + reads { + ethernet.dstAddr: exact; + } + actions { + action_0; + do_nothing; + } + size : 1024; +} + +@pragma immediate 0 +table table_1 { + reads { + ethernet.dstAddr: exact; + } + actions { + action_1; + do_nothing; + } + size : 1024; +} + +control ingress { + apply(table_0); + apply(table_1); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_187_proxy_hash_2.p4 b/backends/tofino/bf-asm/test/internal/test_config_187_proxy_hash_2.p4 new file mode 100644 index 00000000000..821e2e9ceb6 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_187_proxy_hash_2.p4 @@ -0,0 +1,61 @@ + +/* Sample P4 program */ +header_type pkt_t { + fields { + srcAddr : 32; + dstAddr : 32; + protocol : 8; + srcPort : 16; + dstPort : 16; + + blah : 16; + + a : 32; + b : 32; + c : 32; + d : 32; + + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +action set_dip(){ + modify_field(pkt.blah, 8); +} + +action nop(){ +} + +@pragma proxy_hash_width 24 +table exm_proxy_hash { + reads { + pkt.srcAddr : exact; + pkt.dstAddr : exact; + pkt.protocol : exact; + pkt.srcPort : exact; + pkt.dstPort : exact; + } + actions { + nop; + set_dip; + } + size : 400000; +} + + +/* Main control flow */ + +control ingress { + apply(exm_proxy_hash); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_188_action_data_overflow.p4 b/backends/tofino/bf-asm/test/internal/test_config_188_action_data_overflow.p4 new file mode 100644 index 00000000000..125a4e9a0f0 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_188_action_data_overflow.p4 @@ -0,0 +1,59 @@ + +/* Sample P4 program */ +header_type pkt_t { + fields { + srcAddr : 32; + dstAddr : 32; + protocol : 8; + srcPort : 16; + dstPort : 16; + + a : 32; + b : 32; + c : 32; + d : 32; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +action action_0(param0, param1, param2, param3, param4){ + modify_field(pkt.a, param0); + modify_field(pkt.b, param1); + modify_field(pkt.c, param2); + //modify_field(pkt.d, param3); + //modify_field(pkt.dstPort, param4); +} + +action nop(){ +} + +@pragma immediate 0 +table table_0 { + reads { + pkt.srcPort : exact; + pkt.dstPort : ternary; + } + actions { + nop; + action_0; + } + size : 4098; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_189_stat_with_lrt.p4 b/backends/tofino/bf-asm/test/internal/test_config_189_stat_with_lrt.p4 new file mode 100644 index 00000000000..5d64e167fb1 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_189_stat_with_lrt.p4 @@ -0,0 +1,62 @@ + +/* Sample P4 program */ +header_type pkt_t { + fields { + srcAddr : 32; + dstAddr : 32; + protocol : 8; + srcPort : 16; + dstPort : 16; + + a : 32; + b : 32; + c : 32; + d : 32; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +action action_0(param0, param1, param2, param3, param4){ + modify_field(pkt.a, param0); +} + +action nop(){ +} + +@pragma lrt_enable 1 +counter counter_0 { + type: packets; + direct: table_0; + min_width: 32; +} + +@pragma immediate 0 +table table_0 { + reads { + pkt.srcPort : exact; + pkt.dstPort : ternary; + } + actions { + nop; + action_0; + } + size : 4096; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_18_first_bit_xor.p4 b/backends/tofino/bf-asm/test/internal/test_config_18_first_bit_xor.p4 new file mode 100644 index 00000000000..77b95538782 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_18_first_bit_xor.p4 @@ -0,0 +1,100 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type blah_t { + fields { + a : 32; + b : 32; + c : 32; + d : 32; + e : 16; + f : 16; + g : 16; + h : 16; + i : 8; + j : 8; + k : 8; + l : 8; + } +} + + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return parse_blah; +} + +header blah_t blah; + +parser parse_blah { + extract(blah); + return ingress; +} + + + +action action_0(param0){ + bit_xor(blah.a, blah.b, param0); +} + +action do_nothing(){ + no_op(); +} + +table table_0 { + reads { + ipv4.dstAddr : exact ; + } + actions { + action_0; + do_nothing; + } +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_190_modify_with_expr.p4 b/backends/tofino/bf-asm/test/internal/test_config_190_modify_with_expr.p4 new file mode 100644 index 00000000000..3ceed9971b3 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_190_modify_with_expr.p4 @@ -0,0 +1,69 @@ + +/* Sample P4 program */ +header_type pkt_t { + fields { + srcAddr : 32; + dstAddr : 32; + protocol : 8; + srcPort : 16; + dstPort : 16; + + a : 32; + b : 32; + c : 32; + d : 32; + + e : 16; + f : 16; + g : 16; + h : 16; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +action action_0(param0, param1, param2){ + modify_field(pkt.a, pkt.b + 2); + modify_field(pkt.b, 3 - pkt.b); + modify_field(pkt.c, pkt.c >> 3); + modify_field(pkt.d, pkt.d << 7); + + modify_field(pkt.e, param0 | pkt.e); + modify_field(pkt.f, pkt.f & param1); + modify_field(pkt.g, pkt.g ^ 0xfff); + modify_field(pkt.h, ~param2); + + +} + +action nop(){ +} + +table table_0 { + reads { + pkt.srcPort : exact; + pkt.dstPort : ternary; + } + actions { + nop; + action_0; + } + size : 4096; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_191_invalidate.p4 b/backends/tofino/bf-asm/test/internal/test_config_191_invalidate.p4 new file mode 100644 index 00000000000..73d88f57580 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_191_invalidate.p4 @@ -0,0 +1,64 @@ + +/* Sample P4 program */ +header_type pkt_t { + fields { + srcAddr : 32; + dstAddr : 32; + protocol : 8; + srcPort : 16; + dstPort : 16; + + a : 32; + b : 32; + c : 32; + d : 32; + + e : 16; + f : 16; + g : 16; + h : 16; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +action action_0(){ + invalidate(144); +} + +action action_1(){ + invalidate(pkt.a); +} + +action nop(){ +} + +table table_0 { + reads { + pkt.srcPort : exact; + pkt.dstPort : ternary; + } + actions { + nop; + action_0; + action_1; + } + size : 4096; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_192_stateful_driven_by_hash.p4 b/backends/tofino/bf-asm/test/internal/test_config_192_stateful_driven_by_hash.p4 new file mode 100644 index 00000000000..3343228020b --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_192_stateful_driven_by_hash.p4 @@ -0,0 +1,300 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + + +/* ----------------------------------------- */ +field_list f_em_direct { + pkt.field_a_32; + pkt.field_b_32; +} + +field_list_calculation h_em_direct { + input { + f_em_direct; + } + algorithm : random; + output_width : 12; +} + +register r_em_direct { + width : 16; + static : t_em_direct; + instance_count : 2048; +} + +blackbox stateful_alu b_em_direct { + reg: r_em_direct; + update_lo_1_value: register_lo + 1; + output_value : alu_lo; + output_dst : pkt.field_e_16; +} + +action a_em_direct(){ + b_em_direct.execute_stateful_alu_from_hash(h_em_direct); +} + +table t_em_direct { + reads { + pkt.field_a_32 : exact; + } + + actions { + a_em_direct; + } + size : 4096; +} + +/* ----------------------------------------- */ +field_list f_em_indirect { + pkt.field_a_32; + pkt.field_b_32; +} + +field_list_calculation h_em_indirect { + input { + f_em_indirect; + } + algorithm : random; + output_width : 13; +} + +register r_em_indirect { + width : 16; + instance_count: 8192; +} + +blackbox stateful_alu b_em_indirect { + reg: r_em_indirect; + update_lo_1_value: register_lo + 5; + output_value : alu_lo; + output_dst : pkt.field_f_16; +} + +action a_em_indirect(){ + b_em_indirect.execute_stateful_alu_from_hash(h_em_indirect); +} + +table t_em_indirect { + reads { + pkt.field_a_32 : exact; + } + + actions { + a_em_indirect; + do_nothing; + } + size : 2048; +} + + +/* ----------------------------------------- */ +field_list f_t_direct { + pkt.field_a_32; + pkt.field_b_32; +} + +field_list_calculation h_t_direct { + input { + f_t_direct; + } + algorithm : random; + output_width : 12; +} + +register r_t_direct { + width : 16; + static : t_t_direct; + instance_count : 3072; +} + +blackbox stateful_alu b_t_direct { + reg: r_t_direct; + update_lo_1_value: register_lo + 1; + output_value : alu_lo; + output_dst : pkt.field_g_16; +} + +action a_t_direct(){ + b_t_direct.execute_stateful_alu_from_hash(h_t_direct); +} + +table t_t_direct { + reads { + pkt.field_a_32 : ternary; + } + + actions { + a_t_direct; + } + size : 4096; +} + + +/* ----------------------------------------- */ +field_list f_t_indirect { + pkt.field_a_32; + pkt.field_b_32; +} + +field_list_calculation h_t_indirect { + input { + f_t_indirect; + } + algorithm : random; + output_width : 13; +} + +register r_t_indirect { + width : 16; + instance_count: 8192; +} + +blackbox stateful_alu b_t_indirect { + reg: r_t_indirect; + update_lo_1_value: register_lo + 5; + output_value : alu_lo; + output_dst : pkt.field_h_16; +} + +action a_t_indirect(){ + b_t_indirect.execute_stateful_alu_from_hash(h_t_indirect); +} + +table t_t_indirect { + reads { + pkt.field_a_32 : ternary; + } + + actions { + a_t_indirect; + do_nothing; + } + size : 2048; +} + + +/* ----------------------------------------- */ +field_list f_no_key { + pkt.field_a_32; + pkt.field_b_32; +} + +field_list_calculation h_no_key { + input { + f_no_key; + } + algorithm : random; + output_width : 16; +} + +register r_no_key { + width : 16; + static: t_no_key; + instance_count : 1024; +} + +blackbox stateful_alu b_no_key { + reg: r_no_key; + update_lo_1_value: register_lo + 5; + output_value : alu_lo; + output_dst : pkt.field_i_8; +} + +action a_no_key(){ + b_no_key.execute_stateful_alu_from_hash(h_no_key); +} + +table t_no_key { + actions { + a_no_key; + } + size : 1024; +} + + +/* ----------------------------------------- */ +field_list f_hash_act { + pkt.field_a_32; + pkt.field_b_32; +} + +field_list_calculation h_hash_act { + input { + f_hash_act; + } + algorithm : random; + output_width : 10; +} + +register r_hash_act { + width : 8; + static: t_hash_act; + instance_count : 256; +} + +blackbox stateful_alu b_hash_act { + reg: r_hash_act; + update_lo_1_value: register_lo + 5; + output_value : alu_lo; + output_dst : pkt.field_j_8; +} + +action a_hash_act(){ + b_hash_act.execute_stateful_alu_from_hash(h_hash_act); +} + +table t_hash_act { + reads { + pkt.field_d_32 mask 0x3ff : exact; + } + actions { + a_hash_act; + } + size : 1024; +} + +action do_nothing(){} + +/* Main control flow */ + +control ingress { + apply(t_em_direct); + apply(t_em_indirect); + apply(t_t_direct); + apply(t_t_indirect); + apply(t_no_key); + apply(t_hash_act); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_193_indirect_stats_no_reads.p4 b/backends/tofino/bf-asm/test/internal/test_config_193_indirect_stats_no_reads.p4 new file mode 100644 index 00000000000..7256ce7ae0d --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_193_indirect_stats_no_reads.p4 @@ -0,0 +1,64 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +counter cntr_0 { + type: packets; + instance_count: 500; + //min_width: 32; +} + +action do_nothing(){} + +action action_0() { + count(cntr_0, pkt.field_i_8); +} + + +table table_0 { + actions { + action_0; + } + //size : 256; +} + + + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_194_same_action_param.p4 b/backends/tofino/bf-asm/test/internal/test_config_194_same_action_param.p4 new file mode 100644 index 00000000000..38661288548 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_194_same_action_param.p4 @@ -0,0 +1,103 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; +/* + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_m_16 : 16; +*/ + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +action do_nothing(){} + +/* +action action_0(param_0) { + bit_xor(pkt.field_f_16, pkt.field_g_16, param_0); + modify_field(pkt.field_e_16, param_0); +} + +@pragma immediate 0 +table table_0 { + reads { + pkt.field_l_8 : ternary; + + pkt.field_a_32 : ternary; + pkt.field_b_32 : exact; + pkt.field_c_32 : exact; + pkt.field_e_16 : exact; + + } + actions { + action_0; + } + size : 256; +} +*/ +action action_1(param_1){ + bit_xor(pkt.field_a_32, pkt.field_a_32, param_1); + modify_field(pkt.field_b_32, param_1); +} + + +@pragma immediate 0 +table table_1 { + reads { + pkt.field_a_32 mask 0xff: ternary; + } + actions { + action_1; + } + size : 256; +} + +action drop_me(){ + drop(); +} + +table table_e { + reads { + pkt.field_a_32: ternary; + } + actions { + do_nothing; + drop_me; + } + size : 512; +} + +control ingress { + //apply(table_0); + apply(table_1); +} + +control egress { + apply(table_e); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_195_stateful_predicate_output.p4 b/backends/tofino/bf-asm/test/internal/test_config_195_stateful_predicate_output.p4 new file mode 100644 index 00000000000..9b127554a3c --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_195_stateful_predicate_output.p4 @@ -0,0 +1,96 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + } +} + +header_type meta_t { + fields { + pred_4 : 4; + pad_4 : 4; + pad_6 : 6; + comb_pred_1 : 1; + pad_1 : 1; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; +metadata meta_t meta; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +register r_pred { + width : 8; + static : t_pred; + instance_count : 1024; +} + +blackbox stateful_alu b_pred { + reg: r_pred; + condition_lo : 1; + update_lo_1_value: register_lo + 1; + + //output_predicate : condition_lo; + output_value : predicate; + output_dst : meta.pred_4; +} + +blackbox stateful_alu b_comb_pred { + reg: r_pred; + condition_lo : register_lo > 0; + update_lo_1_value: register_lo + 2; + + output_predicate : condition_lo; + output_value : combined_predicate; + output_dst : meta.comb_pred_1; +} + +action a_pred(idx){ + b_pred.execute_stateful_alu(idx); +} + +action a_comb_pred(idx){ + b_comb_pred.execute_stateful_alu(idx); +} + +table t_pred { + reads { + pkt.field_a_32 : lpm; + } + + actions { + a_pred; + a_comb_pred; + } + size : 512; +} + +control ingress { + apply(t_pred); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_196_hit_miss.p4 b/backends/tofino/bf-asm/test/internal/test_config_196_hit_miss.p4 new file mode 100644 index 00000000000..813b851b571 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_196_hit_miss.p4 @@ -0,0 +1,119 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_m_16 : 16; + + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +action do_nothing(){} + +action action_0(param_0) { + bit_xor(pkt.field_f_16, pkt.field_g_16, param_0); + modify_field(pkt.field_e_16, param_0); +} + +@pragma immediate 0 +table table_0 { + reads { + pkt.field_l_8 : ternary; + + pkt.field_a_32 : ternary; + pkt.field_b_32 : exact; + pkt.field_c_32 : exact; + pkt.field_e_16 : exact; + + } + actions { + action_0; + drop_me; + do_nothing; + } + size : 256; +} + +action action_1(param_1){ + bit_xor(pkt.field_a_32, pkt.field_a_32, param_1); + modify_field(pkt.field_b_32, param_1); +} + + +@pragma immediate 0 +table table_1 { + reads { + pkt.field_a_32 mask 0xff: ternary; + } + actions { + action_1; + } + size : 256; +} + +table table_2 { + reads { + pkt.field_b_32 : exact; + } + actions { + action_1; + drop_me; + } +} + +action drop_me(){ + drop(); +} + +table table_e { + reads { + pkt.field_a_32: ternary; + } + actions { + do_nothing; + drop_me; + } + size : 512; +} + +control ingress { + + apply(table_0) { + hit { + apply(table_1); + apply(table_2); + } + } + apply(table_e); +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_197_default_next_table.p4 b/backends/tofino/bf-asm/test/internal/test_config_197_default_next_table.p4 new file mode 100644 index 00000000000..1e8a25e0a09 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_197_default_next_table.p4 @@ -0,0 +1,109 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_m_16 : 16; + + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +action do_nothing(){} + +action action_0(param_0) { + modify_field(pkt.field_e_16, param_0); +} + +table table_0 { + reads { + pkt.field_l_8 : ternary; + + pkt.field_a_32 : ternary; + pkt.field_b_32 : exact; + pkt.field_c_32 : exact; + pkt.field_e_16 : exact; + + } + actions { + action_0; + action_1; + drop_me; + do_nothing; + } + size : 256; +} + +action action_1(param_1){ + modify_field(pkt.field_b_32, param_1); +} + + +table table_1 { + reads { + pkt.field_a_32 mask 0xff: ternary; + } + actions { + do_nothing; + } + size : 256; +} + +table table_2 { + actions { + do_nothing; + } +} + +action drop_me(){ + drop(); +} + +table table_3 { + reads { + pkt.field_a_32: ternary; + } + actions { + do_nothing; + } + size : 512; +} + +control ingress { + apply(table_0) { + action_0 { + apply(table_1); + } + action_1 { + apply(table_2); + } + } + apply(table_3); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_198_shared_action_profile.p4 b/backends/tofino/bf-asm/test/internal/test_config_198_shared_action_profile.p4 new file mode 100644 index 00000000000..096f17954b9 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_198_shared_action_profile.p4 @@ -0,0 +1,92 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +action do_nothing(){ + no_op(); +} + +action action_0(param0) { + modify_field(pkt.field_a_32, param0); +} + +action action_1(param1) { + modify_field(pkt.field_b_32, param1); +} + +table table_0 { + reads { + pkt.field_a_32 : ternary; + } + action_profile: shared_action_profile; + size : 2048; +} + +table table_1 { + reads { + pkt.field_b_32 : ternary; + } + action_profile: shared_action_profile; + size : 2048; +} + +action_profile shared_action_profile { + actions { + do_nothing; + action_0; + action_1; + } + size : 1024; +} + +//@pragma stage 0 +table table_2 { + reads { + pkt.field_a_32 : exact; + } + actions { + do_nothing; + } +} + +/* Main control flow */ + +control ingress { + + if (pkt.field_i_8 == 0){ + apply(table_0); + } else { + apply(table_1); + } + + apply(table_2); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_199_stateful_constant_index.p4 b/backends/tofino/bf-asm/test/internal/test_config_199_stateful_constant_index.p4 new file mode 100644 index 00000000000..b6e4d42a5e2 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_199_stateful_constant_index.p4 @@ -0,0 +1,67 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + blah : 16; + + x : 32; + y : 32; + z : 32; + } +} + +header ethernet_t ethernet; + + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return ingress; +} + +action action_0(){ + sampling_alu.execute_stateful_alu(8191); +} + +action action_1(){ +} + +register sampling_cntr { + width : 32; + static: table_0; + instance_count : 8192; +} + +blackbox stateful_alu sampling_alu { + reg: sampling_cntr; + condition_lo: 1; + update_lo_1_predicate: condition_lo; + update_lo_1_value: register_lo + 1; + output_predicate: condition_lo; + output_value : alu_lo; + output_dst : ethernet.x; +} + +@pragma ways 1 +table table_0 { + reads { + ethernet.blah: exact; + } + actions { + action_0; + //action_1; + } + size : 1024; +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_19_immediate_but_no_action_data_table.p4 b/backends/tofino/bf-asm/test/internal/test_config_19_immediate_but_no_action_data_table.p4 new file mode 100644 index 00000000000..0b8cb5553d4 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_19_immediate_but_no_action_data_table.p4 @@ -0,0 +1,76 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + + + +action action_0(param0){ + modify_field(ipv4.hdrChecksum, param0); +} + +action do_nothing(){ + no_op(); +} + +@pragma immediate 1 +table table_0 { + reads { + ipv4.dstAddr : exact ; + } + actions { + action_0; + do_nothing; + } +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_1_ternary_match_crossbar.p4 b/backends/tofino/bf-asm/test/internal/test_config_1_ternary_match_crossbar.p4 new file mode 100644 index 00000000000..1421b5f661c --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_1_ternary_match_crossbar.p4 @@ -0,0 +1,51 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type my_test_config_1_t { + fields { + a_32 : 32; + b_8 : 8; + c_8 : 8; + d_16 : 16; + e_32 : 32; + } +} + + +header my_test_config_1_t my_test_config_1; + +parser start{ + return parse_my_test_config_1; +} + +parser parse_my_test_config_1{ + extract(my_test_config_1); + return ingress; +} + +action modify_b(my_param){ + modify_field(my_test_config_1.b_8, my_param); +} + +action just_no_op(){ + no_op(); +} + + +table my_test_config_1_table { + reads { + my_test_config_1.a_32 : lpm; + my_test_config_1.e_32 : ternary; + //my_test_config_1.d_16 : ternary; + my_test_config_1.b_8 mask 0xf0: ternary; + my_test_config_1.c_8 : ternary; + } + actions { + modify_b; + just_no_op; + } + max_size : 2048; +} + +control ingress { + apply(my_test_config_1_table); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_200_counter_constant_index.p4 b/backends/tofino/bf-asm/test/internal/test_config_200_counter_constant_index.p4 new file mode 100644 index 00000000000..d8bf6b3f4ad --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_200_counter_constant_index.p4 @@ -0,0 +1,63 @@ + +/* Sample P4 program */ +header_type pkt_t { + fields { + srcAddr : 32; + dstAddr : 32; + protocol : 8; + srcPort : 16; + dstPort : 16; + + a : 32; + b : 32; + c : 32; + d : 32; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +action action_0(param0, param1, param2, param3, param4){ + count(counter_0, 2047); + modify_field(pkt.a, param0); +} + +action nop(){ +} + + +counter counter_0 { + type: packets_and_bytes; + static: table_0; + instance_count: 2048; + min_width: 32; +} + +table table_0 { + reads { + pkt.srcPort : exact; + pkt.dstPort : ternary; + } + actions { + //nop; + action_0; + } + size : 4096; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_201_meter_constant_index.p4 b/backends/tofino/bf-asm/test/internal/test_config_201_meter_constant_index.p4 new file mode 100644 index 00000000000..afcc162adba --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_201_meter_constant_index.p4 @@ -0,0 +1,109 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/lpf_blackbox.p4" +#include "tofino/wred_blackbox.p4" +#include "tofino/meter_blackbox.p4" + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + blah0 : 16; + blah1 : 8; + blah2 : 8; + } +} + +header_type meta_t { + fields { + a : 16; + b : 16; + c : 16; + d : 16; + } +} + + +header ethernet_t ethernet; +metadata meta_t meta; + + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return ingress; +} + +action action_0(){ + my_lpf.execute(ethernet.blah0, 1023); +} + +action do_nothing(){} + +action action_1(){ + my_wred.execute(ethernet.blah1, 1022); +} + +action action_2(){ + my_meter.execute(ethernet.blah2, 3071); +} + +blackbox lpf my_lpf { + filter_input : ethernet.etherType; + static : table_0; + instance_count: 1024; +} + +blackbox wred my_wred { + wred_input : ethernet.etherType; + instance_count: 1024; + drop_value : 127; + no_drop_value : 63; +} + +blackbox meter my_meter { + type : bytes; + instance_count: 3072; +} + +table table_0 { + //reads { + // ethernet.dstAddr: exact; + //} + actions { + action_0; + } + size : 1024; +} + +table table_1 { + reads { + ethernet.dstAddr: exact; + } + actions { + action_1; + } + size : 1024; +} + +table table_2 { + reads { + ethernet.dstAddr: exact; + } + actions { + action_2; + } + size : 1024; +} + +control ingress { + if (ethernet.blah1 == 2){ + apply(table_0); + } + apply(table_1); + apply(table_2); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_202_write_same_byte.p4 b/backends/tofino/bf-asm/test/internal/test_config_202_write_same_byte.p4 new file mode 100644 index 00000000000..4f6702ba896 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_202_write_same_byte.p4 @@ -0,0 +1,67 @@ +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + field_m_4 : 4; + field_n_4 : 4; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +action action_0(param0) { + modify_field(pkt.field_m_4, param0); +} + +action action_1(param1) { + modify_field(pkt.field_n_4, param1); +} + +table table_0 { + reads { + pkt.field_a_32 : ternary; + } + actions { + action_0; + } + size : 1024; +} + +table table_1 { + reads { + pkt.field_b_32 : ternary; + } + actions { + action_1; + } + size : 1024; +} + + +control ingress { + apply(table_0); + apply(table_1); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_203_first_reduction_or.p4 b/backends/tofino/bf-asm/test/internal/test_config_203_first_reduction_or.p4 new file mode 100644 index 00000000000..7f256fe2e47 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_203_first_reduction_or.p4 @@ -0,0 +1,144 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + } +} + +header_type meta_t { + fields { + result_8 : 8; + result_8_2 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; +metadata meta_t meta; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +register reg_0 { + width : 8; + static : table_0; + instance_count : 1024; +} + +register reg_1 { + width : 8; + static : table_1; + instance_count : 1024; +} + + +register reg_2 { + width : 8; + static : table_2; + instance_count : 1024; +} + +blackbox stateful_alu alu_0 { + reg: reg_0; + condition_lo : 1; + update_lo_1_value: 15; + + output_value : alu_lo; + output_dst : meta.result_8; + reduction_or_group: or_group_1; +} + +blackbox stateful_alu alu_1 { + reg: reg_1; + condition_lo : 1; + update_lo_1_value: 0x30; + + output_value : alu_lo; + output_dst : meta.result_8; + reduction_or_group: or_group_1; +} + +blackbox stateful_alu alu_2 { + reg: reg_2; + condition_lo : 1; + update_lo_1_value: 0xc0; + + output_value : alu_lo; + output_dst : meta.result_8; + reduction_or_group: or_group_1; +} + +action action_0(idx){ + /* modify_field(pkt.field_c_32, 0); */ + alu_0.execute_stateful_alu(idx); +} + +action action_1(idx){ + alu_1.execute_stateful_alu(idx); +} + +action action_2(idx){ + alu_2.execute_stateful_alu(idx); +} + +table table_0 { + reads { + pkt.field_a_32 : lpm; + } + + actions { + action_0; + } + size : 512; +} + +table table_1 { + reads { + pkt.field_b_32 : lpm; + } + + actions { + action_1; + } + size : 512; +} + +table table_2 { + reads { + pkt.field_c_32 : lpm; + } + + actions { + action_2; + } + size : 512; +} + +control ingress { + apply(table_0); + apply(table_1); + apply(table_2); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_204_no_tables_in_stage0.p4 b/backends/tofino/bf-asm/test/internal/test_config_204_no_tables_in_stage0.p4 new file mode 100644 index 00000000000..1643b18b238 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_204_no_tables_in_stage0.p4 @@ -0,0 +1,75 @@ + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +action action_0(){ + modify_field(pkt.field_l_8, 2); +} + +action action_1(){ + modify_field(pkt.field_k_8, 5); +} + +@pragma stage 2 +table table_0 { + reads { + pkt.field_a_32 : lpm; + } + + actions { + action_0; + } + size : 512; +} + +@pragma stage 1 +table table_1 { + reads { + pkt.field_b_32 : lpm; + } + + actions { + action_1; + } + size : 512; +} + +control ingress { + apply(table_0); +} + +control egress { + if (pkt.field_i_8 == 3) { + apply(table_1); + } +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_205_modify_field_from_hash.p4 b/backends/tofino/bf-asm/test/internal/test_config_205_modify_field_from_hash.p4 new file mode 100644 index 00000000000..1ed4b3ee5f0 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_205_modify_field_from_hash.p4 @@ -0,0 +1,90 @@ + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + +field_list simple_fields { + pkt.field_e_16; + pkt.field_f_16; +} + + +field_list_calculation simple_hash { + input { simple_fields; } + algorithm : identity_lsb; + output_width : 31; +} + +field_list_calculation simple_hash_2 { + input { simple_fields; } + algorithm : identity_msb; + output_width : 31; +} + + +action common_action(){ + modify_field_with_hash_based_offset(pkt.field_b_32, 0, simple_hash, 2147483648); +} + +action action_0(){ + common_action(); + modify_field(pkt.field_k_8, 0); +} + +action action_1(){ + common_action(); + modify_field(pkt.field_k_8, 1); +} + +action action_2(){ + common_action(); + modify_field(pkt.field_k_8, 2); + //modify_field_with_hash_based_offset(pkt.field_c_32, 0, simple_hash_2, 2147483648); +} + +table table_0 { + reads { + pkt.field_a_32 : lpm; + } + + actions { + action_0; + action_1; + action_2; + } + size : 512; +} + + +control ingress { + apply(table_0); +} + diff --git a/backends/tofino/bf-asm/test/internal/test_config_206_stateful_logging.p4 b/backends/tofino/bf-asm/test/internal/test_config_206_stateful_logging.p4 new file mode 100644 index 00000000000..b512618a57d --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_206_stateful_logging.p4 @@ -0,0 +1,70 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + blah : 16; + } +} + +header_type meta_t { + fields { + a : 16; + b : 16; + c : 16; + d : 16; + } +} + + +header ethernet_t ethernet; +metadata meta_t meta; + + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return ingress; +} + +register logging_reg { + width : 16; + static: table_0; + instance_count : 16384; +} + +blackbox stateful_alu logging_alu { + reg: logging_reg; + update_lo_1_value: ethernet.blah; + stateful_logging_mode : table_hit; +} + +action action_0(){ + drop(); + logging_alu.execute_stateful_log(); +} + +action action_1(){ } /* Note that stateful logging is still performed here. */ + +table table_0 { + reads { + ethernet.dstAddr: exact; + } + actions { + action_0; + action_1; + } + size : 1024; +} + + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_207_not_gateway.p4 b/backends/tofino/bf-asm/test/internal/test_config_207_not_gateway.p4 new file mode 100644 index 00000000000..e8af9c2ce25 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_207_not_gateway.p4 @@ -0,0 +1,61 @@ + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +action action_0(){ + modify_field(pkt.field_k_8, 0); +} + +action action_1(){ + modify_field(pkt.field_k_8, 1); +} + +table table_0 { + reads { + pkt.field_a_32 : lpm; + } + + actions { + action_0; + action_1; + } + size : 512; +} + + +control ingress { + if (not valid(pkt)){ + apply(table_0); + } +} + diff --git a/backends/tofino/bf-asm/test/internal/test_config_208_table_no_key.p4 b/backends/tofino/bf-asm/test/internal/test_config_208_table_no_key.p4 new file mode 100644 index 00000000000..2710e8036cb --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_208_table_no_key.p4 @@ -0,0 +1,51 @@ + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +action action_0(param0){ + modify_field(pkt.field_k_8, param0); +} + +table table_0 { + actions { + action_0; + } +} + + +control ingress { + //if (pkt.field_i_8 == 1){ + apply(table_0); + //} +} + diff --git a/backends/tofino/bf-asm/test/internal/test_config_209_pack_hash_dist.p4 b/backends/tofino/bf-asm/test/internal/test_config_209_pack_hash_dist.p4 new file mode 100644 index 00000000000..7bcd47f21b5 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_209_pack_hash_dist.p4 @@ -0,0 +1,137 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + + } +} + +header_type meta_t { + fields { + result_8 : 8; + result_8_2 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; +metadata meta_t meta; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +register reg_0 { + width : 8; + static : table_0; + instance_count : 131072; +} + +register reg_1 { + width : 8; + static : table_1; + instance_count : 131072; +} + +blackbox stateful_alu alu_0 { + reg: reg_0; + condition_lo : 1; + update_lo_1_value: 15; + + output_value : alu_lo; + output_dst : meta.result_8; + reduction_or_group: or_group_1; +} + +blackbox stateful_alu alu_1 { + reg: reg_1; + condition_lo : 1; + update_lo_1_value: 0x30; + + output_value : alu_lo; + output_dst : meta.result_8; + reduction_or_group: or_group_1; +} + +field_list fl_0 { + pkt.field_a_32; + pkt.field_b_32; +} + +field_list_calculation hash0 { + input { + fl_0; + } + algorithm : random; + output_width : 17; +} + +field_list fl_1 { + pkt.field_c_32; + pkt.field_d_32; + pkt.field_e_16; +} + +field_list_calculation hash1 { + input { + fl_1; + } + algorithm : random; + output_width : 17; +} + +action action_0(){ + alu_0.execute_stateful_alu_from_hash(hash0); +} + +action action_1(){ + alu_1.execute_stateful_alu_from_hash(hash1); +} + +table table_0 { + reads { + pkt.field_a_32 : lpm; + } + + actions { + action_0; + } + size : 512; +} + +table table_1 { + reads { + pkt.field_b_32 : lpm; + } + + actions { + action_1; + } + size : 512; +} + +control ingress { + apply(table_0); + apply(table_1); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_20_table_dependencies.p4 b/backends/tofino/bf-asm/test/internal/test_config_20_table_dependencies.p4 new file mode 100644 index 00000000000..ada3a758cdb --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_20_table_dependencies.p4 @@ -0,0 +1,131 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +action action_0(){ + modify_field(ipv4.diffserv, 1); +} + +action action_1() { + modify_field(ipv4.totalLen, 2); +} + +action action_2() { + modify_field(ipv4.identification, 3); +} + +action action_3(){ + modify_field(ipv4.identification, 4); +} + + +action do_nothing(){ + no_op(); +} + + +table table_0 { + reads { + ethernet.etherType : lpm; + ipv4.diffserv : exact; + } + actions { + action_0; + do_nothing; + } + max_size : 1024; +} + +table table_1 { + reads { + ipv4.srcAddr : exact; + ipv4.dstAddr : exact; + } + actions { + action_1; + do_nothing; + } + max_size : 16384; +} + +table table_2 { + reads { + ipv4.srcAddr : exact; + ipv4.totalLen : exact; + } + actions { + action_2; + do_nothing; + } + max_size : 4096; +} + +table table_3 { + reads { + ipv4.srcAddr : exact; + } + actions { + action_3; + } + max_size : 2048; +} + + +/* Main control flow */ + +control ingress { + + apply(table_0); + apply(table_1); + + if (valid(ipv4)){ + apply(table_2); + } + + apply(table_3); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_21_tcam_vpns.p4 b/backends/tofino/bf-asm/test/internal/test_config_21_tcam_vpns.p4 new file mode 100644 index 00000000000..0eb86e69974 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_21_tcam_vpns.p4 @@ -0,0 +1,76 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +action action_0(param0){ + modify_field(ipv4.diffserv, param0); +} + +action action_1(param1) { + modify_field(ipv4.totalLen, param1); +} + + +@pragma immediate 1 +table table_0 { + reads { + ipv4.srcAddr : lpm; + } + actions { + action_0; + action_1; + } + max_size : 8192; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_22_direct_mapped_exact.p4 b/backends/tofino/bf-asm/test/internal/test_config_22_direct_mapped_exact.p4 new file mode 100644 index 00000000000..246b8506332 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_22_direct_mapped_exact.p4 @@ -0,0 +1,92 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type vlan_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + 0x8100: parse_vlan; + default: ingress; + } +} + +header ipv4_t ipv4; +header vlan_t vlan; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +parser parse_vlan { + extract(vlan); + return ingress; +} + + +action action_0(param0){ + modify_field(ipv4.diffserv, param0); +} + +action action_1(param1) { + modify_field(ipv4.totalLen, param1); +} + + +table table_0 { + reads { + vlan.vid : exact; + } + actions { + action_0; + action_1; + } + max_size : 8192; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_23_same_container_modified.p4 b/backends/tofino/bf-asm/test/internal/test_config_23_same_container_modified.p4 new file mode 100644 index 00000000000..768ae76192d --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_23_same_container_modified.p4 @@ -0,0 +1,95 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type vlan_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + 0x8100: parse_vlan; + default: ingress; + } +} + +header ipv4_t ipv4; +header vlan_t vlan; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +parser parse_vlan { + extract(vlan); + return ingress; +} + + +action action_0(my_param0, my_param1){ + modify_field(ipv4.protocol, my_param0, 0xF8); + modify_field(ipv4.ttl, my_param1); + //modify_field(ipv4.totalLen, ipv4.hdrChecksum); + //modify_field(ipv4.protocol, ipv4.ttl); +} + +action action_1(my_param2) { + modify_field(ipv4.totalLen, ipv4.totalLen); +} + + +table table_0 { + reads { + ipv4.srcAddr : exact; + } + actions { + action_0; + action_1; + } + max_size : 4096; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_24_action_entries_pragma.p4 b/backends/tofino/bf-asm/test/internal/test_config_24_action_entries_pragma.p4 new file mode 100644 index 00000000000..2826c6e17c9 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_24_action_entries_pragma.p4 @@ -0,0 +1,87 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type vlan_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + 0x8100: parse_vlan; + default: ingress; + } +} + +header ipv4_t ipv4; +header vlan_t vlan; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +parser parse_vlan { + extract(vlan); + return ingress; +} + + +action action_0(my_param0, my_param1){ + modify_field(ipv4.ttl, my_param1); +} + +@pragma action_entries 1024 +table table_0 { + reads { + ipv4.srcAddr : exact; + } + actions { + action_0; + } + max_size : 4096; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_25_no_reads_for_table.p4 b/backends/tofino/bf-asm/test/internal/test_config_25_no_reads_for_table.p4 new file mode 100644 index 00000000000..5179d856d13 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_25_no_reads_for_table.p4 @@ -0,0 +1,83 @@ + +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type vlan_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + 0x8100: parse_vlan; + default: ingress; + } +} + +header ipv4_t ipv4; +header vlan_t vlan; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +parser parse_vlan { + extract(vlan); + return ingress; +} + + +action action_0(my_param0, my_param1){ + modify_field(ethernet.dstAddr, 0xcba987654321); +} + +table table_0 { + actions { + action_0; + } +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_26_direct_add_primitive.p4 b/backends/tofino/bf-asm/test/internal/test_config_26_direct_add_primitive.p4 new file mode 100644 index 00000000000..04c56621683 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_26_direct_add_primitive.p4 @@ -0,0 +1,88 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type vlan_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + 0x8100: parse_vlan; + default: ingress; + } +} + +header ipv4_t ipv4; +header vlan_t vlan; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +parser parse_vlan { + extract(vlan); + return ingress; +} + + +action action_0(my_param_0){ + add(vlan.etherType, vlan.etherType, my_param_0); + //add(ethernet.etherType, ethernet.etherType, my_param_0); + //add(ipv4.diffserv, ipv4.diffserv, -1); +} + +table table_0 { + reads { + ipv4.srcAddr : lpm; + } + actions { + action_0; + } + max_size : 1024; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_2_action_data_table_sizing.p4 b/backends/tofino/bf-asm/test/internal/test_config_2_action_data_table_sizing.p4 new file mode 100644 index 00000000000..5b19bfde64e --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_2_action_data_table_sizing.p4 @@ -0,0 +1,66 @@ +#include "tofino/intrinsic_metadata.p4" + + +header_type my_test_config_1_t { + fields { + a_32 : 32; + b_8 : 8; + c_8 : 8; + d_16 : 16; + e_32 : 32; + f_32 : 32; + g_32 : 32; + h_32 : 32; + i_32 : 32; + j_16 : 16; + k_16 : 16; + l_16 : 16; + m_16 : 16; + } +} + + +header my_test_config_1_t my_test_config_1; + +parser start{ + return parse_my_test_config_1; +} + +parser parse_my_test_config_1 { + extract(my_test_config_1); + return ingress; +} + +action action_160(param_1_32, param_2_32, param_3_32, param_4_32, param_5_16, param_6_8){ + modify_field(my_test_config_1.a_32, param_1_32); + modify_field(my_test_config_1.e_32, param_2_32); + modify_field(my_test_config_1.f_32, param_3_32); + //modify_field(my_test_config_1.g_32, param_4_32); + modify_field(my_test_config_1.m_16, param_5_16); + modify_field(my_test_config_1.c_8, param_6_8); +} + +action action_8(param_1_8){ + modify_field(my_test_config_1.b_8, param_1_8); +} + + +table my_test_config_1_table { + reads { + my_test_config_1.a_32 : lpm; + my_test_config_1.e_32 : ternary; + //my_test_config_1.d_16 : ternary; + my_test_config_1.b_8 mask 0xf0: ternary; + my_test_config_1.c_8 : ternary; + } + + actions { + action_160; + action_8; + } + max_size : 1024; +} + +control ingress { + apply(my_test_config_1_table); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_30_action_data_imm_param.p4 b/backends/tofino/bf-asm/test/internal/test_config_30_action_data_imm_param.p4 new file mode 100644 index 00000000000..f663a3938ff --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_30_action_data_imm_param.p4 @@ -0,0 +1,87 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type vlan_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + 0x8100: parse_vlan; + default: ingress; + } +} + +header ipv4_t ipv4; +header vlan_t vlan; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +parser parse_vlan { + extract(vlan); + return ingress; +} + + +action action_0(my_param0){ + modify_field(ipv4.protocol, 0xA5); + modify_field(ipv4.ttl, my_param0); +} + +table table_0 { + reads { + ipv4.srcAddr : exact; + } + actions { + action_0; + } + max_size : 4096; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_31_action_data_imm_imm.p4 b/backends/tofino/bf-asm/test/internal/test_config_31_action_data_imm_imm.p4 new file mode 100644 index 00000000000..a7ed086f43c --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_31_action_data_imm_imm.p4 @@ -0,0 +1,87 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type vlan_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + 0x8100: parse_vlan; + default: ingress; + } +} + +header ipv4_t ipv4; +header vlan_t vlan; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +parser parse_vlan { + extract(vlan); + return ingress; +} + + +action action_0(){ + modify_field(ipv4.protocol, 0xA5); + modify_field(ipv4.ttl, 0x81); +} + +table table_0 { + reads { + ipv4.srcAddr : exact; + } + actions { + action_0; + } + max_size : 4096; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_32_action_data_imm_param_imm.p4 b/backends/tofino/bf-asm/test/internal/test_config_32_action_data_imm_param_imm.p4 new file mode 100644 index 00000000000..2cf49cf723b --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_32_action_data_imm_param_imm.p4 @@ -0,0 +1,44 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_a : 4; + field_b : 8; + field_c : 4; + field_d : 32; + field_e : 32; + } +} + + +header test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(test.field_a, 2); + modify_field(test.field_b, my_param_0); + modify_field(test.field_c, 15); +} + + +table table_0 { + reads { + test.field_e : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_33_action_data_paramx3.p4 b/backends/tofino/bf-asm/test/internal/test_config_33_action_data_paramx3.p4 new file mode 100644 index 00000000000..f8ed7850a14 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_33_action_data_paramx3.p4 @@ -0,0 +1,44 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_a : 4; + field_b : 8; + field_c : 4; + field_d : 32; + field_e : 32; + } +} + + +header test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test); + return ingress; +} + + +action action_0(my_param_0, my_param_1, my_param_2){ + modify_field(test.field_a, my_param_0); + modify_field(test.field_b, my_param_1); + modify_field(test.field_c, my_param_2); +} + + +table table_0 { + reads { + test.field_e : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_34_action_data_1_bit_params.p4 b/backends/tofino/bf-asm/test/internal/test_config_34_action_data_1_bit_params.p4 new file mode 100644 index 00000000000..0f1e2ee5897 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_34_action_data_1_bit_params.p4 @@ -0,0 +1,114 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_0 : 1; + field_1 : 1; + field_2 : 1; + field_3 : 1; + field_4 : 1; + field_5 : 1; + field_6 : 1; + field_7 : 1; + field_8 : 1; + field_9 : 1; + field_10 : 1; + field_11 : 1; + field_12 : 1; + field_13 : 1; + field_14 : 1; + field_15 : 1; + field_16 : 1; + field_17 : 1; + field_18 : 1; + field_19 : 1; + field_20 : 1; + field_21 : 1; + field_22 : 1; + field_23 : 1; + field_24 : 1; + field_25 : 1; + field_26 : 1; + field_27 : 1; + field_28 : 1; + field_29 : 1; + field_30 : 1; + field_31 : 1; + + field_a : 32; + field_b : 32; + } +} + + +header test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test); + return ingress; +} + + +action action_0(my_param_0, my_param_1, my_param_2, + my_param_3, my_param_4, my_param_5, + my_param_6, my_param_7, my_param_8, + my_param_9, my_param_10, my_param_11, + my_param_12, my_param_13, my_param_14, + my_param_15, my_param_16, my_param_17, + my_param_18, my_param_19, my_param_20, + my_param_21, my_param_22, my_param_23, + my_param_24, my_param_25, my_param_26, + my_param_27, my_param_28, my_param_29, + my_param_30, my_param_31){ + + modify_field(test.field_0, my_param_0); + modify_field(test.field_1, my_param_1); + modify_field(test.field_2, my_param_2); + modify_field(test.field_3, my_param_3); + modify_field(test.field_4, my_param_4); + modify_field(test.field_5, my_param_5); + modify_field(test.field_6, my_param_6); + modify_field(test.field_7, my_param_7); + modify_field(test.field_8, my_param_8); + modify_field(test.field_9, my_param_9); + modify_field(test.field_10, my_param_10); + modify_field(test.field_11, my_param_11); + modify_field(test.field_12, my_param_12); + modify_field(test.field_13, my_param_13); + modify_field(test.field_14, my_param_14); + modify_field(test.field_15, my_param_15); + modify_field(test.field_16, my_param_16); + modify_field(test.field_17, my_param_17); + modify_field(test.field_18, my_param_18); + modify_field(test.field_19, my_param_19); + modify_field(test.field_20, my_param_20); + modify_field(test.field_21, my_param_21); + modify_field(test.field_22, my_param_22); + modify_field(test.field_23, my_param_23); + modify_field(test.field_24, my_param_24); + modify_field(test.field_25, my_param_25); + modify_field(test.field_26, my_param_26); + modify_field(test.field_27, my_param_27); + modify_field(test.field_28, my_param_28); + modify_field(test.field_29, my_param_29); + modify_field(test.field_30, my_param_30); + modify_field(test.field_31, my_param_31); +} + + +table table_0 { + reads { + test.field_a : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_35_action_data_1_bit_params_and_imms.p4 b/backends/tofino/bf-asm/test/internal/test_config_35_action_data_1_bit_params_and_imms.p4 new file mode 100644 index 00000000000..b26ffb0af0e --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_35_action_data_1_bit_params_and_imms.p4 @@ -0,0 +1,113 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_0 : 1; + field_1 : 1; + field_2 : 1; + field_3 : 1; + field_4 : 1; + field_5 : 1; + field_6 : 1; + field_7 : 1; + field_8 : 1; + field_9 : 1; + field_10 : 1; + field_11 : 1; + field_12 : 1; + field_13 : 1; + field_14 : 1; + field_15 : 1; + field_16 : 1; + field_17 : 1; + field_18 : 1; + field_19 : 1; + field_20 : 1; + field_21 : 1; + field_22 : 1; + field_23 : 1; + field_24 : 1; + field_25 : 1; + field_26 : 1; + field_27 : 1; + field_28 : 1; + field_29 : 1; + field_30 : 1; + field_31 : 1; + + field_a : 32; + field_b : 32; + } +} + + +header test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test); + return ingress; +} + + +action action_0(my_param_0, my_param_1, my_param_2, + my_param_4, my_param_5, + my_param_6, my_param_7, my_param_8, + my_param_10, my_param_11, + my_param_12, my_param_13, my_param_14, + my_param_16, my_param_17, + my_param_18, my_param_19, my_param_20, + my_param_21, my_param_22, my_param_23, + my_param_25, my_param_26, + my_param_27, my_param_28, + my_param_31){ + + modify_field(test.field_0, my_param_0); + modify_field(test.field_1, my_param_1); + modify_field(test.field_2, my_param_2); + modify_field(test.field_3, 0); + modify_field(test.field_4, my_param_4); + modify_field(test.field_5, my_param_5); + modify_field(test.field_6, my_param_6); + modify_field(test.field_7, my_param_7); + modify_field(test.field_8, my_param_8); + modify_field(test.field_9, 1); + modify_field(test.field_10, my_param_10); + modify_field(test.field_11, my_param_11); + modify_field(test.field_12, my_param_12); + modify_field(test.field_13, my_param_13); + modify_field(test.field_14, my_param_14); + modify_field(test.field_15, 1); + modify_field(test.field_16, my_param_16); + modify_field(test.field_17, my_param_17); + modify_field(test.field_18, my_param_18); + modify_field(test.field_19, my_param_19); + modify_field(test.field_20, my_param_20); + modify_field(test.field_21, my_param_21); + modify_field(test.field_22, my_param_22); + modify_field(test.field_23, my_param_23); + modify_field(test.field_24, 0); + modify_field(test.field_25, my_param_25); + modify_field(test.field_26, my_param_26); + modify_field(test.field_27, my_param_27); + modify_field(test.field_28, my_param_28); + modify_field(test.field_29, 1); + modify_field(test.field_30, 1); + modify_field(test.field_31, my_param_31); +} + +table table_0 { + reads { + test.field_a : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_36_action_data_field_param.p4 b/backends/tofino/bf-asm/test/internal/test_config_36_action_data_field_param.p4 new file mode 100644 index 00000000000..c0a91ae1107 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_36_action_data_field_param.p4 @@ -0,0 +1,43 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_a : 4; + field_b : 8; + field_c : 4; + field_d : 32; + field_e : 32; + } +} + + +header test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(test.field_a, test.field_c); + modify_field(test.field_e, my_param_0); +} + + +table table_0 { + reads { + test.field_e : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_37_action_data_field_field.p4 b/backends/tofino/bf-asm/test/internal/test_config_37_action_data_field_field.p4 new file mode 100644 index 00000000000..cb12ae45526 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_37_action_data_field_field.p4 @@ -0,0 +1,46 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_a : 4; + field_b : 8; + field_c : 4; + field_d : 4; + field_e : 8; + field_f : 4; + + field_g : 32; + field_h : 32; + } +} + + +header test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(test.field_a, test.field_f); +} + + +table table_0 { + reads { + test.field_e : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_38_action_data_field_same_container.p4 b/backends/tofino/bf-asm/test/internal/test_config_38_action_data_field_same_container.p4 new file mode 100644 index 00000000000..091dd479fef --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_38_action_data_field_same_container.p4 @@ -0,0 +1,46 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_a : 4; + field_b : 4; + field_c : 4; + field_d : 4; + field_e : 8; + field_f : 4; + + field_g : 32; + field_h : 32; + } +} + + +header test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(test.field_a, test.field_b); +} + + +table table_0 { + reads { + test.field_e : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_39_action_data_add_to_field.p4 b/backends/tofino/bf-asm/test/internal/test_config_39_action_data_add_to_field.p4 new file mode 100644 index 00000000000..608c81cb541 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_39_action_data_add_to_field.p4 @@ -0,0 +1,46 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_a : 8; + field_b : 4; + field_c : 4; + field_d : 4; + field_e : 8; + field_f : 4; + + field_g : 32; + field_h : 32; + } +} + + +header test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test); + return ingress; +} + + +action action_0(){ + add_to_field(test.field_a, -1); +} + + +table table_0 { + reads { + test.field_e : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_3_add_to_field.PHV_BUG b/backends/tofino/bf-asm/test/internal/test_config_3_add_to_field.PHV_BUG new file mode 100644 index 00000000000..5f6e8a7ee39 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_3_add_to_field.PHV_BUG @@ -0,0 +1,74 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type my_test_config_1_t { + fields { + a_32 : 32; + b_8 : 8; + c_8 : 8; + d_16 : 16; + e_32 : 32; + f_32 : 32; + g_32 : 32; + h_32 : 32; + i_32 : 32; + j_16 : 16; + k_16 : 16; + l_16 : 16; + m_16 : 16; + n_4 : 4; + o_1 : 1; + p_3 : 3; + } +} + + +header my_test_config_1_t my_test_config_1; + +parser start{ + return parse_my_test_config_1; +} + +parser parse_my_test_config_1 { + extract(my_test_config_1); + return ingress; +} + +action action_add_constant(){ + add_to_field(my_test_config_1.b_8, -1); +} + +action action_add_param(param_1_16){ + add_to_field(my_test_config_1.j_16, param_1_16); +} + +action action_add_field(){ + add_to_field(my_test_config_1.b_8, my_test_config_1.b_8); +} + +action drop_me(){ + drop(); +} + +action set_flag(){ + modify_field(my_test_config_1.o_1, 1); +} + + +table my_test_config_1_table { + reads { + my_test_config_1.a_32 : lpm; + } + + actions { + action_add_constant; + action_add_param; + action_add_field; + drop_me; + set_flag; + } + max_size : 1024; +} + +control ingress { + apply(my_test_config_1_table); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_40_action_data_bit_xor.p4 b/backends/tofino/bf-asm/test/internal/test_config_40_action_data_bit_xor.p4 new file mode 100644 index 00000000000..6c6102b688a --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_40_action_data_bit_xor.p4 @@ -0,0 +1,46 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_a : 32; + field_b : 4; + field_c : 4; + field_d : 4; + field_e : 8; + field_f : 4; + + field_g : 32; + field_h : 32; + } +} + + +header test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test); + return ingress; +} + + +action action_0(){ + bit_xor(test.field_a, test.field_a, 0x74); +} + + +table table_0 { + reads { + test.field_e : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_41_action_data_remove_header.p4 b/backends/tofino/bf-asm/test/internal/test_config_41_action_data_remove_header.p4 new file mode 100644 index 00000000000..47cb94c1c9a --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_41_action_data_remove_header.p4 @@ -0,0 +1,46 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_a : 8; + field_b : 4; + field_c : 4; + field_d : 4; + field_e : 8; + field_f : 4; + + field_g : 32; + field_h : 32; + } +} + + +header test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test); + return ingress; +} + + +action action_0(){ + remove_header(test); +} + + +table table_0 { + reads { + test.field_e : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_42_action_data_add_header.p4 b/backends/tofino/bf-asm/test/internal/test_config_42_action_data_add_header.p4 new file mode 100644 index 00000000000..25c48d47b58 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_42_action_data_add_header.p4 @@ -0,0 +1,45 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_a : 8; + field_b : 4; + field_c : 4; + field_d : 4; + field_e : 8; + field_f : 4; + + field_g : 32; + field_h : 32; + } +} + +header test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test); + return ingress; +} + + +action action_0(){ + add_header(test); +} + + +table table_0 { + reads { + test.field_e : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_43_action_data_drop.PHV_BUG b/backends/tofino/bf-asm/test/internal/test_config_43_action_data_drop.PHV_BUG new file mode 100644 index 00000000000..2d7008cc27e --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_43_action_data_drop.PHV_BUG @@ -0,0 +1,46 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_a : 32; + field_b : 4; + field_c : 4; + field_d : 4; + field_e : 8; + field_f : 4; + + field_g : 32; + field_h : 32; + } +} + + +header test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test); + return ingress; +} + + +action action_0(){ + drop(); +} + + +table table_0 { + reads { + test.field_e : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_44_action_data_immediate.p4 b/backends/tofino/bf-asm/test/internal/test_config_44_action_data_immediate.p4 new file mode 100644 index 00000000000..471b3971a88 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_44_action_data_immediate.p4 @@ -0,0 +1,47 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_a : 32; + field_b : 4; + field_c : 4; + field_d : 4; + field_e : 8; + field_f : 4; + + field_g : 32; + field_h : 32; + } +} + + +header test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test); + return ingress; +} + + +action action_0(my_param_0, my_param_1){ + modify_field(test.field_b, my_param_0); + modify_field(test.field_c, my_param_1); +} + +@pragma immediate 1 +table table_0 { + reads { + test.field_e : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_45_action_data_immediate_param_and_constant.p4 b/backends/tofino/bf-asm/test/internal/test_config_45_action_data_immediate_param_and_constant.p4 new file mode 100644 index 00000000000..9b280cd1d51 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_45_action_data_immediate_param_and_constant.p4 @@ -0,0 +1,49 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_a : 32; + field_b : 4; + field_c : 4; + field_d : 4; + field_e : 8; + field_f : 4; + + field_g : 32; + field_h : 32; + } +} + + +header test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test); + return ingress; +} + + +action action_0(my_param_0, my_param_1, my_param_2){ + modify_field(test.field_b, my_param_0); + modify_field(test.field_c, 0xc); + modify_field(test.field_d, my_param_1); + modify_field(test.field_f, my_param_2); +} + +@pragma immediate 1 +table table_0 { + reads { + test.field_e : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_46_action_data_big_constant.p4 b/backends/tofino/bf-asm/test/internal/test_config_46_action_data_big_constant.p4 new file mode 100644 index 00000000000..fa607db1cb1 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_46_action_data_big_constant.p4 @@ -0,0 +1,87 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type vlan_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + 0x8100: parse_vlan; + default: ingress; + } +} + +header ipv4_t ipv4; +header vlan_t vlan; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +parser parse_vlan { + extract(vlan); + return ingress; +} + + +action action_0(my_param0, my_param1){ + modify_field(ethernet.dstAddr, 0xcba987654321); +} + +@pragma immediate 1 +table table_0 { + reads { + ipv4.srcAddr : lpm; + } + actions { + action_0; + } + max_size : 1024; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_47_action_data_big_constant_immediate.p4 b/backends/tofino/bf-asm/test/internal/test_config_47_action_data_big_constant_immediate.p4 new file mode 100644 index 00000000000..fa607db1cb1 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_47_action_data_big_constant_immediate.p4 @@ -0,0 +1,87 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type vlan_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + 0x8100: parse_vlan; + default: ingress; + } +} + +header ipv4_t ipv4; +header vlan_t vlan; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +parser parse_vlan { + extract(vlan); + return ingress; +} + + +action action_0(my_param0, my_param1){ + modify_field(ethernet.dstAddr, 0xcba987654321); +} + +@pragma immediate 1 +table table_0 { + reads { + ipv4.srcAddr : lpm; + } + actions { + action_0; + } + max_size : 1024; +} + + +/* Main control flow */ + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_48_action_data_bit_masked_set.p4 b/backends/tofino/bf-asm/test/internal/test_config_48_action_data_bit_masked_set.p4 new file mode 100644 index 00000000000..781bdc0bd6c --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_48_action_data_bit_masked_set.p4 @@ -0,0 +1,44 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_a : 2; + field_b : 2; + field_c : 2; + field_d : 2; + field_e : 32; + field_f : 32; + } +} + + +header test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test); + return ingress; +} + + +action action_0(my_param_0, my_param_1){ + modify_field(test.field_a, my_param_0); + modify_field(test.field_c, my_param_1); +} + + +table table_0 { + reads { + test.field_e : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_49_action_data_bit_masked_set_immediate.p4 b/backends/tofino/bf-asm/test/internal/test_config_49_action_data_bit_masked_set_immediate.p4 new file mode 100644 index 00000000000..602a6e16a7f --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_49_action_data_bit_masked_set_immediate.p4 @@ -0,0 +1,50 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + field_e : 16; + field_f : 16; + field_g : 16; + field_h : 16; + field_i : 2; + field_j : 2; + field_k : 2; + field_l : 2; + } +} + + +header test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test); + return ingress; +} + + +action action_0(my_param_0, my_param_1){ + modify_field(test.field_i, my_param_0); + modify_field(test.field_k, my_param_1); +} + +@pragma immediate 1 +table table_0 { + reads { + test.field_e : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_4_modify_field.p4 b/backends/tofino/bf-asm/test/internal/test_config_4_modify_field.p4 new file mode 100644 index 00000000000..e78d5b43469 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_4_modify_field.p4 @@ -0,0 +1,65 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type my_test_config_1_t { + fields { + a_32 : 32; + b_8 : 8; + c_8 : 8; + d_16 : 16; + e_32 : 32; + f_32 : 32; + g_32 : 32; + h_32 : 32; + i_32 : 32; + j_16 : 16; + k_16 : 16; + l_16 : 16; + m_16 : 16; + n_4 : 4; + o_1 : 1; + p_3 : 3; + } +} + + +header my_test_config_1_t my_test_config_1; + +parser start{ + return parse_my_test_config_1; +} + +parser parse_my_test_config_1 { + extract(my_test_config_1); + return ingress; +} + +action modify_from_constant(){ + modify_field(my_test_config_1.e_32, 3); +} + +action modify_from_field(){ + modify_field(my_test_config_1.h_32, my_test_config_1.g_32); +} + + +action modify_from_param(param1_32){ + modify_field(my_test_config_1.f_32, param1_32); +} + + +table my_test_config_1_table { + reads { + my_test_config_1.a_32 : lpm; + } + + actions { + modify_from_constant; + modify_from_field; + modify_from_param; + } + max_size : 1024; +} + +control ingress { + apply(my_test_config_1_table); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_50_action_data_different_size_fields.p4 b/backends/tofino/bf-asm/test/internal/test_config_50_action_data_different_size_fields.p4 new file mode 100644 index 00000000000..13da225d720 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_50_action_data_different_size_fields.p4 @@ -0,0 +1,44 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + field_e : 16; + field_f : 16; + field_g : 16; + field_h : 16; + } +} + + +header test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test); + return ingress; +} + + +action action_0(){ + modify_field(test.field_a, test.field_e); +} + +table table_0 { + reads { + test.field_b : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_51_action_data_same_parameter_used_multiple.p4 b/backends/tofino/bf-asm/test/internal/test_config_51_action_data_same_parameter_used_multiple.p4 new file mode 100644 index 00000000000..0c597fa4d22 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_51_action_data_same_parameter_used_multiple.p4 @@ -0,0 +1,51 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + field_e : 16; + field_f : 16; + field_g : 16; + field_h : 16; + } +} + + +header test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(test.field_a, my_param_0); + modify_field(test.field_c, my_param_0); +} + +action action_1(){ + no_op(); +} + +@pragma action_entries 200 +table table_0 { + reads { + test.field_b : ternary; + } + actions { + action_0; + action_1; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_52_copy_header.p4 b/backends/tofino/bf-asm/test/internal/test_config_52_copy_header.p4 new file mode 100644 index 00000000000..7c7c7012849 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_52_copy_header.p4 @@ -0,0 +1,45 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_a : 8; + field_b : 16; + field_c : 8; + field_d : 32; + field_e : 16; + field_f : 16; + } +} + + +header test_t test_dest; +header test_t test_src; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test_dest); + extract(test_src); + return ingress; +} + + +action action_0(){ + copy_header(test_dest, test_src); +} + + +table table_0 { + reads { + test_src.field_e : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_53_ternary_swizzle.p4 b/backends/tofino/bf-asm/test/internal/test_config_53_ternary_swizzle.p4 new file mode 100644 index 00000000000..cb522a6f84f --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_53_ternary_swizzle.p4 @@ -0,0 +1,43 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type test_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + field_e : 32; + } +} + + +header test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(test); + return ingress; +} + + +action action_0(){ + modify_field(test.field_a, 2); +} + + +table table_0 { + reads { + test.field_a : ternary; + test.field_b mask 0xff00 : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_54_modify_field_different_size.PHV_BUG b/backends/tofino/bf-asm/test/internal/test_config_54_modify_field_different_size.PHV_BUG new file mode 100644 index 00000000000..e5eb489d96d --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_54_modify_field_different_size.PHV_BUG @@ -0,0 +1,51 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + } +} + +header_type test_t { + fields { + + field_a_8 : 8; + field_a_16 : 16; + + field_d_8 : 8; + field_d_16 : 16; + + } +} + +header pkt_t pkt; +metadata test_t test; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(){ + modify_field(test.field_a_8, test.field_a_16); + modify_field(test.field_d_16, test.field_d_8); +} + + +table table_0 { + reads { + pkt.field_a : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_55_generate_digest.p4 b/backends/tofino/bf-asm/test/internal/test_config_55_generate_digest.p4 new file mode 100644 index 00000000000..5cfd98e2b13 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_55_generate_digest.p4 @@ -0,0 +1,42 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +field_list tcp_digest { + pkt.field_a; +} + + +action action_0(){ + generate_digest(0, tcp_digest); +} + + +table table_0 { + reads { + pkt.field_a : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_56_iterate_through_packing.p4 b/backends/tofino/bf-asm/test/internal/test_config_56_iterate_through_packing.p4 new file mode 100644 index 00000000000..85088974408 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_56_iterate_through_packing.p4 @@ -0,0 +1,39 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + field_b : 32; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0, my_param_1){ + modify_field(pkt.field_a, my_param_0); + modify_field(pkt.field_b, my_param_1); +} + + +table table_0 { + reads { + pkt.field_a : exact; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_57_tcam_with_44_bits_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_57_tcam_with_44_bits_no_version.p4 new file mode 100644 index 00000000000..e04305a484f --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_57_tcam_with_44_bits_no_version.p4 @@ -0,0 +1,41 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 4; + field_b : 12; + field_c : 16; + field_d : 32; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 0 +table table_0 { + reads { + pkt.field_b : ternary; + pkt.field_d : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_58_tcam_with_40_bits.p4 b/backends/tofino/bf-asm/test/internal/test_config_58_tcam_with_40_bits.p4 new file mode 100644 index 00000000000..bb7c1f4c2e1 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_58_tcam_with_40_bits.p4 @@ -0,0 +1,41 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 8; + field_b : 8; + field_c : 16; + field_d : 32; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 0 +table table_0 { + reads { + pkt.field_b : ternary; + pkt.field_d : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_59_tcam_with_44_bits_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_59_tcam_with_44_bits_and_version.p4 new file mode 100644 index 00000000000..e04305a484f --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_59_tcam_with_44_bits_and_version.p4 @@ -0,0 +1,41 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 4; + field_b : 12; + field_c : 16; + field_d : 32; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 0 +table table_0 { + reads { + pkt.field_b : ternary; + pkt.field_d : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_5_sram_allocation.p4 b/backends/tofino/bf-asm/test/internal/test_config_5_sram_allocation.p4 new file mode 100644 index 00000000000..4cd64b34c8b --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_5_sram_allocation.p4 @@ -0,0 +1,69 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type my_test_config_1_t { + fields { + a_32 : 32; + b_8 : 8; + c_8 : 8; + d_16 : 16; + e_32 : 32; + f_32 : 32; + g_32 : 32; + h_32 : 32; + i_32 : 32; + j_16 : 16; + k_16 : 16; + l_16 : 16; + m_16 : 16; + n_4 : 4; + o_1 : 1; + p_3 : 3; + } +} + + +header my_test_config_1_t my_test_config_1; + +parser start{ + return parse_my_test_config_1; +} + +parser parse_my_test_config_1 { + extract(my_test_config_1); + return ingress; +} + +action set_flag(){ + modify_field(my_test_config_1.o_1, 1); +} + +action do_nothing(){ + no_op(); +} + +table test_exact_table { + reads { + //my_test_config_1.a_32 : exact; + //my_test_config_1.a_32 mask 0xff0fff0f: exact; + //my_test_config_1.p_3 : valid; + + my_test_config_1.a_32 : exact; + my_test_config_1.e_32 : exact; + my_test_config_1.f_32 : exact; + my_test_config_1.g_32 : exact; + my_test_config_1.h_32 : exact; + my_test_config_1.i_32 : exact; + + + } + + actions { + set_flag; + do_nothing; + } + max_size : 16384; +} + +control ingress { + apply(test_exact_table); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_60_tcam_with_44_and_no_version_high_nibble.p4 b/backends/tofino/bf-asm/test/internal/test_config_60_tcam_with_44_and_no_version_high_nibble.p4 new file mode 100644 index 00000000000..1163dfbac57 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_60_tcam_with_44_and_no_version_high_nibble.p4 @@ -0,0 +1,41 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 12; + field_b : 4; + field_c : 16; + field_d : 32; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 1 +table table_0 { + reads { + pkt.field_a : ternary; + pkt.field_d : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_61_tcam_with_44_bits_and_no_version_low_nibble.p4 b/backends/tofino/bf-asm/test/internal/test_config_61_tcam_with_44_bits_and_no_version_low_nibble.p4 new file mode 100644 index 00000000000..761aff8036c --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_61_tcam_with_44_bits_and_no_version_low_nibble.p4 @@ -0,0 +1,41 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 4; + field_b : 12; + field_c : 16; + field_d : 32; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 1 +table table_0 { + reads { + pkt.field_b : ternary; + pkt.field_d : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_62_tcam_with_48_bits_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_62_tcam_with_48_bits_and_version.p4 new file mode 100644 index 00000000000..38979e77e58 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_62_tcam_with_48_bits_and_version.p4 @@ -0,0 +1,41 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 8; + field_b : 16; + field_c : 16; + field_d : 32; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 0 +table table_0 { + reads { + pkt.field_b : ternary; + pkt.field_d : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_63_tcam_with_48_bits_and_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_63_tcam_with_48_bits_and_no_version.p4 new file mode 100644 index 00000000000..55d4cc9497f --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_63_tcam_with_48_bits_and_no_version.p4 @@ -0,0 +1,41 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 8; + field_b : 16; + field_c : 16; + field_d : 32; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 1 +table table_0 { + reads { + pkt.field_b : ternary; + pkt.field_d : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_64_tcam_with_84_bits_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_64_tcam_with_84_bits_and_version.p4 new file mode 100644 index 00000000000..e04305a484f --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_64_tcam_with_84_bits_and_version.p4 @@ -0,0 +1,41 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 4; + field_b : 12; + field_c : 16; + field_d : 32; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 0 +table table_0 { + reads { + pkt.field_b : ternary; + pkt.field_d : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_64_tcam_with_84_bits_high_nibble_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_64_tcam_with_84_bits_high_nibble_and_version.p4 new file mode 100644 index 00000000000..e23b199f462 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_64_tcam_with_84_bits_high_nibble_and_version.p4 @@ -0,0 +1,45 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 12; + field_b : 4; + field_c : 16; + field_d : 32; + field_e : 32; + field_f : 8; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 0 +table table_0 { + reads { + pkt.field_a : ternary; + pkt.field_d : ternary; + pkt.field_e : ternary; + pkt.field_f : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_65_tcam_with_84_bits_low_nibble_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_65_tcam_with_84_bits_low_nibble_and_version.p4 new file mode 100644 index 00000000000..9ebba80b73d --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_65_tcam_with_84_bits_low_nibble_and_version.p4 @@ -0,0 +1,45 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 4; + field_b : 12; + field_c : 16; + field_d : 32; + field_e : 32; + field_f : 8; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 0 +table table_0 { + reads { + pkt.field_b : ternary; + pkt.field_d : ternary; + pkt.field_e : ternary; + pkt.field_f : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_66_tcam_with_84_bits_high_nibble_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_66_tcam_with_84_bits_high_nibble_no_version.p4 new file mode 100644 index 00000000000..d2bc060c8bc --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_66_tcam_with_84_bits_high_nibble_no_version.p4 @@ -0,0 +1,45 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 12; + field_b : 4; + field_c : 16; + field_d : 32; + field_e : 32; + field_f : 8; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 1 +table table_0 { + reads { + pkt.field_a : ternary; + pkt.field_d : ternary; + pkt.field_e : ternary; + pkt.field_f : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_67_tcam_with_84_bits_low_nibble_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_67_tcam_with_84_bits_low_nibble_no_version.p4 new file mode 100644 index 00000000000..8de0a0fcf37 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_67_tcam_with_84_bits_low_nibble_no_version.p4 @@ -0,0 +1,45 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 4; + field_b : 12; + field_c : 16; + field_d : 32; + field_e : 32; + field_f : 8; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 1 +table table_0 { + reads { + pkt.field_b : ternary; + pkt.field_d : ternary; + pkt.field_e : ternary; + pkt.field_f : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_68_tcam_with_88_bits_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_68_tcam_with_88_bits_and_version.p4 new file mode 100644 index 00000000000..bff51acb4d8 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_68_tcam_with_88_bits_and_version.p4 @@ -0,0 +1,45 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 8; + field_b : 16; + field_c : 16; + field_d : 32; + field_e : 32; + field_f : 8; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 0 +table table_0 { + reads { + pkt.field_b : ternary; + pkt.field_d : ternary; + pkt.field_e : ternary; + pkt.field_f : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_69_tcam_with_88_bits_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_69_tcam_with_88_bits_no_version.p4 new file mode 100644 index 00000000000..0e8c6b60d7c --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_69_tcam_with_88_bits_no_version.p4 @@ -0,0 +1,45 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 8; + field_b : 16; + field_c : 16; + field_d : 32; + field_e : 32; + field_f : 8; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 1 +table table_0 { + reads { + pkt.field_b : ternary; + pkt.field_d : ternary; + pkt.field_e : ternary; + pkt.field_f : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_6_sram_and_tcam_allocation.p4 b/backends/tofino/bf-asm/test/internal/test_config_6_sram_and_tcam_allocation.p4 new file mode 100644 index 00000000000..fa0f38693e3 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_6_sram_and_tcam_allocation.p4 @@ -0,0 +1,131 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +action ig_drop() { + modify_field(routing_metadata.drop, 1); +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(standard_metadata.egress_port, egress_port); +} + +action do_nothing(){ + no_op(); +} + +action l3_set_index(index) { + modify_field( ipv4.diffserv, index); +} + +action hop_ipv4(srcmac, srcip, dstmac, egress_port){ + hop(ipv4.ttl, egress_port); + modify_field(ipv4.srcAddr, srcip); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +table ipv4_routing { + reads { + ipv4.dstAddr : lpm; + ipv4.srcAddr : exact; + } + actions { + ig_drop; + hop_ipv4; + } + max_size : 2048; +} + +table host_ip { + reads { + ipv4.dstAddr : exact; + } + actions { + do_nothing; + l3_set_index; + } + max_size : 16384; +} + + +/* Main control flow */ +control ingress { + apply(ipv4_routing); + apply(host_ip); +} + +action eg_drop() { + modify_field(standard_metadata.egress_spec, 0); +} + +action permit() { +} + +table egress_acl { + reads { + routing_metadata.drop: ternary; + } + actions { + eg_drop; + permit; + } +} + +control egress { + apply(egress_acl); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_70_tcam_with_128_bits_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_70_tcam_with_128_bits_and_version.p4 new file mode 100644 index 00000000000..3798f18b9a4 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_70_tcam_with_128_bits_and_version.p4 @@ -0,0 +1,43 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 0 +table table_0 { + reads { + pkt.field_a : ternary; + pkt.field_b : ternary; + pkt.field_c : ternary; + pkt.field_d : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_71_tcam_with_128_bits_and_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_71_tcam_with_128_bits_and_no_version.p4 new file mode 100644 index 00000000000..4e060d03f93 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_71_tcam_with_128_bits_and_no_version.p4 @@ -0,0 +1,43 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 1 +table table_0 { + reads { + pkt.field_a : ternary; + pkt.field_b : ternary; + pkt.field_c : ternary; + pkt.field_d : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_72_tcam_with_172_bits_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_72_tcam_with_172_bits_and_version.p4 new file mode 100644 index 00000000000..9ce7c42ad21 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_72_tcam_with_172_bits_and_version.p4 @@ -0,0 +1,45 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + field_e : 32; + + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 0 +table table_0 { + reads { + pkt.field_a : ternary; + pkt.field_b : ternary; + pkt.field_c : ternary; + pkt.field_d : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_72_tcam_with_172_bits_high_nibble_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_72_tcam_with_172_bits_high_nibble_and_version.p4 new file mode 100644 index 00000000000..667cf30b457 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_72_tcam_with_172_bits_high_nibble_and_version.p4 @@ -0,0 +1,48 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + field_e : 32; + field_f : 12; + field_g : 4; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 0 +table table_0 { + reads { + pkt.field_a : ternary; + pkt.field_b : ternary; + pkt.field_c : ternary; + pkt.field_d : ternary; + pkt.field_e : ternary; + pkt.field_f : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_73_tcam_with_172_bits_low_nibble_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_73_tcam_with_172_bits_low_nibble_and_version.p4 new file mode 100644 index 00000000000..f6511c668c0 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_73_tcam_with_172_bits_low_nibble_and_version.p4 @@ -0,0 +1,48 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + field_e : 32; + field_f : 4; + field_g : 12; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 0 +table table_0 { + reads { + pkt.field_a : ternary; + pkt.field_b : ternary; + pkt.field_c : ternary; + pkt.field_d : ternary; + pkt.field_e : ternary; + pkt.field_g : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_74_tcam_with_172_bits_low_nibble_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_74_tcam_with_172_bits_low_nibble_no_version.p4 new file mode 100644 index 00000000000..b9c776c48f5 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_74_tcam_with_172_bits_low_nibble_no_version.p4 @@ -0,0 +1,48 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + field_e : 32; + field_f : 4; + field_g : 12; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 1 +table table_0 { + reads { + pkt.field_a : ternary; + pkt.field_b : ternary; + pkt.field_c : ternary; + pkt.field_d : ternary; + pkt.field_e : ternary; + pkt.field_g : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_75_tcam_with_176_bits_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_75_tcam_with_176_bits_no_version.p4 new file mode 100644 index 00000000000..1f51a058ece --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_75_tcam_with_176_bits_no_version.p4 @@ -0,0 +1,47 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + field_e : 32; + field_f : 16; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 1 +table table_0 { + reads { + pkt.field_a : ternary; + pkt.field_b : ternary; + pkt.field_c : ternary; + pkt.field_d : ternary; + pkt.field_e : ternary; + pkt.field_f : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_76_tcam_with_176_bits_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_76_tcam_with_176_bits_and_version.p4 new file mode 100644 index 00000000000..993c5db41de --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_76_tcam_with_176_bits_and_version.p4 @@ -0,0 +1,47 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + field_e : 32; + field_f : 16; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 0 +table table_0 { + reads { + pkt.field_a : ternary; + pkt.field_b : ternary; + pkt.field_c : ternary; + pkt.field_d : ternary; + pkt.field_e : ternary; + pkt.field_f : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_77_tcam_with_216_bits_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_77_tcam_with_216_bits_and_version.p4 new file mode 100644 index 00000000000..0bcd316d9b5 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_77_tcam_with_216_bits_and_version.p4 @@ -0,0 +1,51 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + field_e : 32; + field_f : 32; + field_g : 16; + field_h : 8; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 0 +table table_0 { + reads { + pkt.field_a : ternary; + pkt.field_b : ternary; + pkt.field_c : ternary; + pkt.field_d : ternary; + pkt.field_e : ternary; + pkt.field_f : ternary; + pkt.field_g : ternary; + pkt.field_h : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_78_tcam_with_220_bits_high_nibble_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_78_tcam_with_220_bits_high_nibble_and_version.p4 new file mode 100644 index 00000000000..65239c86c03 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_78_tcam_with_220_bits_high_nibble_and_version.p4 @@ -0,0 +1,56 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + field_e : 32; + field_f : 32; + field_g : 16; + field_h : 12; + field_i : 4; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0, my_param_1, my_param_2, my_param_3, my_param_4){ + modify_field(pkt.field_c, my_param_0); + //modify_field(pkt.field_d, my_param_1); + modify_field(pkt.field_g, my_param_2); + modify_field(pkt.field_i, my_param_3); + //modify_field(pkt.field_a, my_param_4); +} + +@pragma no_versioning 0 +table table_0 { + reads { + pkt.field_a : ternary; + pkt.field_b : ternary; + pkt.field_c : ternary; + pkt.field_d : ternary; + pkt.field_e : ternary; + pkt.field_f : ternary; + pkt.field_g : ternary; + pkt.field_h : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_79_tcam_with_220_bits_high_nibble_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_79_tcam_with_220_bits_high_nibble_no_version.p4 new file mode 100644 index 00000000000..ce5de789db0 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_79_tcam_with_220_bits_high_nibble_no_version.p4 @@ -0,0 +1,52 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + field_e : 32; + field_f : 32; + field_g : 16; + field_h : 12; + field_i : 4; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 1 +table table_0 { + reads { + pkt.field_a : ternary; + pkt.field_b : ternary; + pkt.field_c : ternary; + pkt.field_d : ternary; + pkt.field_e : ternary; + pkt.field_f : ternary; + pkt.field_g : ternary; + pkt.field_h : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_80_tcam_with_220_bits_low_nibble_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_80_tcam_with_220_bits_low_nibble_no_version.p4 new file mode 100644 index 00000000000..c687d0041ba --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_80_tcam_with_220_bits_low_nibble_no_version.p4 @@ -0,0 +1,52 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + field_e : 32; + field_f : 32; + field_g : 16; + field_i : 4; + field_h : 12; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +@pragma no_versioning 1 +table table_0 { + reads { + pkt.field_a : ternary; + pkt.field_b : ternary; + pkt.field_c : ternary; + pkt.field_d : ternary; + pkt.field_e : ternary; + pkt.field_f : ternary; + pkt.field_g : ternary; + pkt.field_h : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_81_indirect_action_data_default.p4 b/backends/tofino/bf-asm/test/internal/test_config_81_indirect_action_data_default.p4 new file mode 100644 index 00000000000..588560e5c3e --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_81_indirect_action_data_default.p4 @@ -0,0 +1,60 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + field_e : 32; + field_f : 32; + field_g : 16; + field_h : 12; + field_i : 4; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(){ + no_op(); +} + +action action_1(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +action action_2(my_param_0, my_param_1, my_param_2, my_param_3){ + modify_field(pkt.field_a, my_param_0); + modify_field(pkt.field_b, my_param_1); + modify_field(pkt.field_c, my_param_2); + modify_field(pkt.field_d, my_param_3); +} + + +@pragma action_entries 100 +table table_0 { + reads { + pkt.field_a : ternary; + } + actions { + action_0; + action_1; + action_2; + } + min_size : 2049; +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_82_param_sharing.p4 b/backends/tofino/bf-asm/test/internal/test_config_82_param_sharing.p4 new file mode 100644 index 00000000000..9f81dd87db9 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_82_param_sharing.p4 @@ -0,0 +1,78 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 4; + field_b : 4; + field_c : 4; + field_d : 4; + field_e : 4; + field_f : 4; + field_g : 4; + field_h : 4; + + field_i : 4; + field_j : 4; + field_k : 4; + field_l : 4; + field_m : 4; + field_n : 4; + field_o : 4; + field_p : 4; + + field_q : 32; + field_r : 32; + + field_s : 16; + field_t : 16; + field_u : 16; + field_v : 16; + + field_w : 8; + field_x : 8; + field_y : 8; + field_z : 8; + + + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(){ + no_op(); +} + +action action_1(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +action action_2(my_param_0, my_param_1){ + modify_field(pkt.field_a, my_param_0); + modify_field(pkt.field_i, my_param_1); +} + +table table_0 { + reads { + pkt.field_b : ternary; + } + actions { + action_0; + action_1; + action_2; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_83_no_immediate_when_indirect_action_table.p4 b/backends/tofino/bf-asm/test/internal/test_config_83_no_immediate_when_indirect_action_table.p4 new file mode 100644 index 00000000000..1eb9b09dcb6 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_83_no_immediate_when_indirect_action_table.p4 @@ -0,0 +1,53 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 16; + field_b : 16; + field_c : 16; + field_d : 16; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(){ + no_op(); +} + +action action_1(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +action action_2(my_param_0, my_param_1){ + modify_field(pkt.field_a, my_param_0); + modify_field(pkt.field_d, my_param_1); +} + +//@pragma immediate 0 +@pragma action_entries 1024 +table table_0 { + reads { + pkt.field_b : ternary; + } + actions { + action_0; + action_1; + action_2; + } + size : 2048; +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_84_simple_wide_exact_match.p4 b/backends/tofino/bf-asm/test/internal/test_config_84_simple_wide_exact_match.p4 new file mode 100644 index 00000000000..6d60cefbd1c --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_84_simple_wide_exact_match.p4 @@ -0,0 +1,53 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + + field_e : 32; + field_f : 32; + field_g : 32; + field_h : 32; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action action_0(){ + no_op(); +} + +action action_1(my_param_0){ + modify_field(pkt.field_c, my_param_0); +} + +table table_0 { + reads { + pkt.field_a : exact; + pkt.field_b : exact; + pkt.field_c : exact; + pkt.field_d : exact; + pkt.field_e : exact; + } + actions { + action_0; + action_1; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_85_table_ordering.p4 b/backends/tofino/bf-asm/test/internal/test_config_85_table_ordering.p4 new file mode 100644 index 00000000000..fb412ff6f79 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_85_table_ordering.p4 @@ -0,0 +1,126 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + + field_e : 32; + field_f : 32; + field_g : 32; + field_h : 32; + field_i : 32; + field_j : 32; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action nop(){ + no_op(); +} + +action action_0(my_param_0, my_param_4){ + modify_field(pkt.field_a, my_param_0); + modify_field(pkt.field_g, my_param_4); +} + +action action_1(my_param_1){ + modify_field(pkt.field_c, my_param_1); +} + +action action_2(my_param_2){ + modify_field(pkt.field_e, my_param_2); +} + +action action_3(my_param_3){ + modify_field(pkt.field_i, my_param_3); +} + +action action_4(my_param_4){ + modify_field(pkt.field_j, my_param_4); +} + +@pragma immediate 0 +table table_0 { + reads { + pkt.field_b : exact; + } + actions { + action_0; + nop; + } + size : 256000; +} + +table table_1 { + reads { + pkt.field_d : exact; + } + actions { + action_1; + nop; + } +} + +table table_2 { + reads { + pkt.field_f : exact; + } + actions { + action_2; + nop; + } +} + +table table_3 { + reads { + pkt.field_h : exact; + } + actions { + action_3; + nop; + } +} + + +table table_4 { + reads { + pkt.field_e : exact; + } + actions { + action_4; + nop; + } +} + + + +control ingress { + apply(table_0){ + nop { + apply(table_1); + } + } + + if (valid(pkt)){ + apply(table_2); + } else { + apply(table_3); + } + + apply(table_4); + +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_86_multiple_action_widths_for_indirect_action.p4 b/backends/tofino/bf-asm/test/internal/test_config_86_multiple_action_widths_for_indirect_action.p4 new file mode 100644 index 00000000000..7009c772d57 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_86_multiple_action_widths_for_indirect_action.p4 @@ -0,0 +1,95 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 8; + field_b : 8; + field_c : 16; + field_d : 16; + + field_e : 32; + field_f : 32; + field_g : 32; + field_h : 32; + field_i : 32; + field_j : 32; + field_k : 32; + field_l : 32; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action nop(){ + no_op(); +} + +//8 +action action_0(my_param_a){ + modify_field(pkt.field_a, my_param_a); +} + +//16 +action action_1(my_param_c){ + modify_field(pkt.field_c, my_param_c); +} + +//32 +action action_2(my_param_e){ + modify_field(pkt.field_e, my_param_e); +} + +//64 +action action_3(my_param_f, my_param_g){ + modify_field(pkt.field_f, my_param_f); + modify_field(pkt.field_g, my_param_g); +} + +//128 +action action_4(my_param_h, my_param_i, my_param_j, my_param_k){ + modify_field(pkt.field_h, my_param_h); + modify_field(pkt.field_i, my_param_i); + modify_field(pkt.field_j, my_param_j); + modify_field(pkt.field_k, my_param_k); +} + +//160 +action action_5(my_param_h, my_param_i, my_param_j, my_param_k, my_param_l){ + modify_field(pkt.field_h, my_param_h); + modify_field(pkt.field_i, my_param_i); + modify_field(pkt.field_j, my_param_j); + modify_field(pkt.field_k, my_param_k); + modify_field(pkt.field_l, my_param_l); +} + + +@pragma immediate 0 +@pragma action_entries 1024 +table table_0 { + reads { + pkt.field_b : exact; + } + actions { + action_0; + action_1; + action_2; + action_3; + action_4; + action_5; + } + size : 4096; +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_87_share_parameter_for_different_containers.p4 b/backends/tofino/bf-asm/test/internal/test_config_87_share_parameter_for_different_containers.p4 new file mode 100644 index 00000000000..b7f4830cea1 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_87_share_parameter_for_different_containers.p4 @@ -0,0 +1,59 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a : 32; + field_b : 32; + field_c : 32; + field_d : 32; + + field_e : 16; + field_f : 16; + field_g : 16; + field_h : 16; + + field_i : 8; + field_j : 8; + field_k : 8; + field_l : 8; + } +} + +header pkt_t pkt; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action nop(){ + no_op(); +} + +action action_0(my_only_param){ + modify_field(pkt.field_a, my_only_param); + modify_field(pkt.field_e, my_only_param); + modify_field(pkt.field_i, my_only_param); + +} + + +@pragma immediate 0 +table table_0 { + reads { + pkt.field_b : exact; + } + actions { + action_0; + } + size : 1024; +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_88_testing_action_data_allocation_3.p4 b/backends/tofino/bf-asm/test/internal/test_config_88_testing_action_data_allocation_3.p4 new file mode 100644 index 00000000000..0893bc91ee5 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_88_testing_action_data_allocation_3.p4 @@ -0,0 +1,192 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +header_type meta_t { + fields { + meta_a_32 : 32; + meta_b_32 : 32; + meta_c_32 : 32; + meta_d_32 : 32; + } +} + + +header pkt_t pkt; +metadata meta_t meta; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action nop(){ + no_op(); +} + +//Simple Actions + +action action_0(param_a_32){ + modify_field(pkt.field_a_32, param_a_32); +} + +action action_1(param_e_16){ + modify_field(pkt.field_e_16, param_e_16); +} + +action action_2(param_i_8){ + modify_field(pkt.field_i_8, param_i_8); +} + +//Adjacent Actions + +action action_3(param_b_32){ + modify_field(pkt.field_b_32, param_b_32, 0xffffafff); +} + +action action_4(param_f_16){ + modify_field(pkt.field_f_16, param_f_16, 0xfaff); +} + +action action_5(param_j_8){ + modify_field(pkt.field_j_8, param_j_8, 0xaa); +} + + +//Long Actions + + +action action_6(param_c_32, param_g_16, param_k_8){ + modify_field(pkt.field_c_32, param_c_32); + modify_field(pkt.field_g_16, param_g_16); + modify_field(pkt.field_k_8, param_k_8); +} + +action action_7(param_c_32, param_d_32, param_h_16, param_l_8, param_a_32, param_e_16){ + modify_field(pkt.field_c_32, param_c_32); + modify_field(pkt.field_d_32, param_d_32); + modify_field(pkt.field_h_16, param_h_16); + modify_field(pkt.field_l_8, param_l_8); + modify_field(pkt.field_a_32, param_a_32, 0xffcf); + modify_field(pkt.field_e_16, param_e_16, 0xfcff); +} + +action action_8(param_i_8, param_j_8, param_k_8){ + modify_field(pkt.field_i_8, param_i_8); + modify_field(pkt.field_j_8, param_j_8); + modify_field(pkt.field_k_8, param_k_8); +} + +action action_9(param_e_16, param_f_16, param_g_16){ + modify_field(pkt.field_e_16, param_e_16); + modify_field(pkt.field_f_16, param_f_16); + modify_field(pkt.field_g_16, param_g_16); +} + +action action_10(param_a_32, param_b_32, param_c_32, param_d_32){ + modify_field(pkt.field_a_32, param_a_32); + modify_field(pkt.field_b_32, param_b_32); + modify_field(pkt.field_c_32, param_c_32); + modify_field(pkt.field_d_32, param_d_32); +} + +action action_11(param_a_32, param_b_32, param_c_32, param_e_16, param_f_16, + param_g_16, param_i_8, param_j_8, param_k_8, param_l_8){ + modify_field(pkt.field_a_32, param_a_32); + modify_field(pkt.field_b_32, param_b_32); + modify_field(pkt.field_c_32, param_c_32); + modify_field(pkt.field_e_16, param_e_16); + modify_field(pkt.field_f_16, param_f_16); + modify_field(pkt.field_g_16, param_g_16); + modify_field(pkt.field_i_8, param_i_8); + modify_field(pkt.field_j_8, param_j_8); + modify_field(pkt.field_k_8, param_k_8); + modify_field(pkt.field_l_8, param_l_8); +} + +action action_12(param_a_32, param_b_32, param_c_32, param_i_8, param_j_8, param_k_8, param_l_8){ + modify_field(pkt.field_a_32, param_a_32, 0xffcf); + modify_field(pkt.field_b_32, param_b_32, 0xfcff); + modify_field(pkt.field_c_32, param_c_32); + modify_field(pkt.field_i_8, param_i_8); + modify_field(pkt.field_j_8, param_j_8); + modify_field(pkt.field_k_8, param_k_8); + modify_field(pkt.field_l_8, param_l_8); +} + +action action_13(param_a_32, param_b_32, param_c_32, param_e_16, param_f_16, param_g_16, param_h_16){ + modify_field(pkt.field_a_32, param_a_32, 0xffcf); + modify_field(pkt.field_b_32, param_b_32, 0xfcff); + + modify_field(pkt.field_c_32, param_c_32); + + modify_field(pkt.field_e_16, param_e_16); + modify_field(pkt.field_f_16, param_f_16); + modify_field(pkt.field_g_16, param_g_16); + modify_field(pkt.field_h_16, param_h_16); +} + +action action_14(param_a_32, param_b_32, param_c_32, param_d_32, + param_meta_a_32){ //, param_meta_b_32, param_meta_c_32){ + modify_field(pkt.field_a_32, param_a_32, 0xffcf); + modify_field(pkt.field_b_32, param_b_32, 0xfcff); + modify_field(pkt.field_c_32, param_c_32); + modify_field(pkt.field_d_32, param_d_32); + modify_field(meta.meta_a_32, param_meta_a_32); +} + +action action_15(){ +} + +//@pragma immediate 0 +@pragma action_entries 512 +table table_0 { + reads { + pkt.field_b_32 : exact; + } + actions { + action_0; + action_1; + action_2; + action_3; + action_4; + action_5; + action_6; + action_7; + action_8; + action_9; + action_10; + action_11; + action_12; + action_13; + action_14; + action_15; + } + size : 1024; +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_89_testing_action_data_allocation_3_with_partial_ram.p4 b/backends/tofino/bf-asm/test/internal/test_config_89_testing_action_data_allocation_3_with_partial_ram.p4 new file mode 100644 index 00000000000..7735fde20a7 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_89_testing_action_data_allocation_3_with_partial_ram.p4 @@ -0,0 +1,121 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +header_type meta_t { + fields { + meta_a_32 : 32; + meta_b_32 : 32; + meta_c_32 : 32; + meta_d_32 : 32; + } +} + + +header pkt_t pkt; +metadata meta_t meta; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action nop(){ + no_op(); +} + +//Simple Actions + +action action_0(param_a_32){ + modify_field(pkt.field_a_32, param_a_32); +} + +action action_1(param_e_16){ + modify_field(pkt.field_e_16, param_e_16); +} + +action action_2(param_i_8){ + modify_field(pkt.field_i_8, param_i_8); +} + + +// Partial field modifications + +action action_3(param_a_32){ + modify_field(pkt.field_a_32, param_a_32, 0xffff); +} + +action action_4(param_e_16){ + modify_field(pkt.field_e_16, param_e_16, 0xff); +} + +action action_5(param_a_32, param_e_16){ + modify_field(pkt.field_a_32, param_a_32, 0xffff0000); + modify_field(pkt.field_e_16, param_e_16, 0xff); +} + +action action_6(param_b_32, param_f_16){ + modify_field(pkt.field_b_32, param_b_32, 0xfff00000); + modify_field(pkt.field_f_16, param_f_16, 0xff00); +} + + +action action_15(){ +} + +@pragma immediate 0 +table table_0 { + reads { + pkt.field_b_32 : exact; + } + actions { +/* + action_0; + action_1; + action_2; + action_3; + action_4; + action_5; + action_6; +*/ +/* + + action_7; + action_8; + action_9; + action_10; + action_11; + action_12; + action_13; + action_14; +*/ + action_15; + } + size : 1024; +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_8_next_table.BUG b/backends/tofino/bf-asm/test/internal/test_config_8_next_table.BUG new file mode 100644 index 00000000000..1c6d976c57e --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_8_next_table.BUG @@ -0,0 +1,175 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +action action_0(){ + modify_field(ipv4.diffserv, 1); +} + +action action_1() { + modify_field(ipv4.totalLen, 2); +} + +action action_2() { + modify_field(ipv4.identification, 3); +} + +action action_3(param_3) { + modify_field(ipv4.ttl, param_3); +} + +action action_4(param_4) { + modify_field(ipv4.protocol, param_4); +} + +action do_nothing(){ + no_op(); +} + + +table table_0_ways_6_pack_3 { + reads { + ethernet.etherType : exact; + } + actions { + action_0; + do_nothing; + } + max_size : 4096; +} + +table table_1 { + reads { + ipv4.srcAddr : exact; + } + actions { + action_1; + do_nothing; + } + max_size : 4096; +} + +table table_2 { + reads { + ipv4.dstAddr : exact; + } + actions { + action_2; + do_nothing; + } + max_size : 4096; +} + +table table_3 { + reads { + ipv4.srcAddr : exact; + ipv4.dstAddr : exact; + } + actions { + action_3; + do_nothing; + } + max_size : 4096; +} + +table table_4 { + reads { + ethernet.dstAddr : exact; + } + actions { + action_4; + do_nothing; + } + max_size : 4096; +} + + + +/* Main control flow */ + +control ingress { + apply(table_0_ways_6_pack_3){ + hit { + apply(table_1); + } + miss { + if (valid(ipv4)){ + apply(table_2); + if (valid(ethernet)){ + apply(table_3); + } + } + } + } + apply(table_4); +} + + +/* +control ingress { + apply(table_0){ + action_0 { + apply(table_1); + } + do_nothing { + if (valid(ipv4)){ + apply(table_2); + } + } + } + apply(table_4); +} +*/ diff --git a/backends/tofino/bf-asm/test/internal/test_config_90_testing_action_data_allocation_3_with_fields_in_overhead.p4 b/backends/tofino/bf-asm/test/internal/test_config_90_testing_action_data_allocation_3_with_fields_in_overhead.p4 new file mode 100644 index 00000000000..fe5734e052c --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_90_testing_action_data_allocation_3_with_fields_in_overhead.p4 @@ -0,0 +1,121 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +header_type meta_t { + fields { + meta_a_32 : 32; + meta_b_32 : 32; + meta_c_32 : 32; + meta_d_32 : 32; + } +} + + +header pkt_t pkt; +metadata meta_t meta; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action nop(){ + no_op(); +} + +//Simple Actions + +action action_0(param_a_32){ + modify_field(pkt.field_a_32, param_a_32, 0xfff00000); +} + +action action_1(param_e_16){ + modify_field(pkt.field_e_16, param_e_16); +} + +action action_2(param_i_8){ + modify_field(pkt.field_i_8, param_i_8); +} + + +// Partial field modifications + +action action_3(param_a_32){ + modify_field(pkt.field_a_32, param_a_32, 0xffff); +} + +action action_4(param_e_16){ + modify_field(pkt.field_e_16, param_e_16, 0xff); +} + +action action_5(param_a_32, param_e_16){ + modify_field(pkt.field_a_32, param_a_32, 0xffff0000); + modify_field(pkt.field_e_16, param_e_16, 0xff); +} + +action action_6(param_b_32, param_f_16){ + modify_field(pkt.field_b_32, param_b_32, 0xfff00000); + modify_field(pkt.field_f_16, param_f_16, 0xff00); +} + + +action action_15(){ +} + +table table_0 { + reads { + pkt.field_b_32 : exact; + } + actions { + action_0; + action_1; + action_2; +/* + action_3; + + action_4; + action_5; + action_6; + +/* + + action_7; + action_8; + action_9; + action_10; + action_11; + action_12; + action_13; + action_14; +*/ + action_15; + } + size : 1024; +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_91_gateway_with_split_table.p4 b/backends/tofino/bf-asm/test/internal/test_config_91_gateway_with_split_table.p4 new file mode 100644 index 00000000000..a54bfaab5dc --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_91_gateway_with_split_table.p4 @@ -0,0 +1,77 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +header_type meta_t { + fields { + meta_a_32 : 32; + meta_b_32 : 32; + meta_c_32 : 32; + meta_d_32 : 32; + } +} + + +header pkt_t pkt; +metadata meta_t meta; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action nop(){ + no_op(); +} + +//Simple Actions + +action action_0(param_a_32){ + modify_field(pkt.field_a_32, param_a_32); +} + + +action action_15(){ +} + +table table_0 { + reads { + pkt.field_a_32 : exact; + pkt.field_b_32 : exact; + pkt.field_c_32 : exact; + pkt.field_e_16 : exact; + } + actions { + action_0; + action_15; + } + size : 200000; +} + +control ingress { + if (valid(pkt)){ + apply(table_0); + } +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_92_bit_xor_10_bits.p4 b/backends/tofino/bf-asm/test/internal/test_config_92_bit_xor_10_bits.p4 new file mode 100644 index 00000000000..8d8f8295127 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_92_bit_xor_10_bits.p4 @@ -0,0 +1,56 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_16 : 16; + } +} + +header_type meta_t { + fields { + field_a_10 : 10; + field_b_10 : 10; + } +} + +header pkt_t pkt; +metadata meta_t meta; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + return ingress; +} + + +action nop(){ + no_op(); +} + +action action_0(){ + bit_xor(meta.field_a_10, meta.field_a_10, meta.field_b_10); +} + + +action action_15(){ +} + +//@pragma pa_atomic ingress meta.field_a_10 meta.field_b_10 +table table_0 { + reads { + pkt.field_a_32 : ternary; + } + actions { + action_0; + action_15; + } + size : 1024; +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_93_push_and_pop.p4 b/backends/tofino/bf-asm/test/internal/test_config_93_push_and_pop.p4 new file mode 100644 index 00000000000..48e29ed3fd6 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_93_push_and_pop.p4 @@ -0,0 +1,71 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +header_type tags_t { + fields { + field_a_8 : 8; + field_b_12 : 12; + field_c_4 : 4; + field_d_8 : 8; + } +} + + + +header pkt_t pkt; +header tags_t tags[5]; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + extract(tags[0]); + return ingress; +} + + +action nop(){ + no_op(); +} + +action push_action(){ + push(tags, 3); +} + +action pop_action(){ + pop(tags, 4); +} +table table_0 { + reads { + pkt.field_a_32 : exact; + } + actions { + push_action; + pop_action; + } + size : 1024; +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_94_action_constant_alignment.p4 b/backends/tofino/bf-asm/test/internal/test_config_94_action_constant_alignment.p4 new file mode 100644 index 00000000000..009888d79a6 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_94_action_constant_alignment.p4 @@ -0,0 +1,75 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type pkt_t { + fields { + + field_x_12 : 12; + field_x_4 : 4; + field_x_16 : 16; + + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +header_type tags_t { + fields { + field_a_8 : 8; + field_b_12 : 12; + field_c_4 : 4; + field_d_8 : 8; + } +} + + + +header pkt_t pkt; +header tags_t tags[5]; + +parser start { + return parse_test; +} + +parser parse_test { + extract(pkt); + extract(tags[0]); + return ingress; +} + + +action nop(){ + no_op(); +} + +action action_0(){ + modify_field(pkt.field_x_12, 0xfff); + modify_field(pkt.field_x_4, 0); +} + + +@pragma immediate 0 +table table_0 { + reads { + pkt.field_a_32 : ternary; + } + actions { + action_0; + } + size : 1024; +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_95_first_meter_table.NOT_READY b/backends/tofino/bf-asm/test/internal/test_config_95_first_meter_table.NOT_READY new file mode 100644 index 00000000000..ebd7b10780b --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_95_first_meter_table.NOT_READY @@ -0,0 +1,105 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + color_0 : 8; + color_1 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +meter meter_0 { + type : bytes; + static : table_0; + result : pkt.color_0; + instance_count : 7000; +} + + +meter meter_1 { + type : bytes; + static : table_1; + result : pkt.color_1; + instance_count : 500; +} + + +action action_0(param0){ + //modify_field(pkt.field_f_16, param0); + execute_meter(meter_0, 7, pkt.color_0); +} + + +action action_1(param0){ + //modify_field(pkt.field_g_16, param0); + execute_meter(meter_1, 7, pkt.color_1); +} + + +action do_nothing(){ + no_op(); +// drop(); +} + + + +@pragma include_idletime 1 +@pragma pa_solitare meter_result.color_0, meter_result.color_1 +@pragma include_stash 1 +table table_0 { + reads { + pkt.field_e_16 : ternary; + pkt.color_0 : exact; //HACK + pkt.color_1 : exact; //HACK + } + actions { + action_0; +// do_nothing; + } + size : 7000; +} + + +@pragma include_idletime 1 +@pragma idletime_two_way_notification 1 +table table_1 { + reads { + pkt.field_e_16: exact; + } + actions { +// do_nothing; + action_1; + } +} + + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_1); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_96_hash_data.p4 b/backends/tofino/bf-asm/test/internal/test_config_96_hash_data.p4 new file mode 100644 index 00000000000..1352506b7fb --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_96_hash_data.p4 @@ -0,0 +1,171 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_28 : 28; + field_a2_4 : 4; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +parser start { + return parse_pkt; +} + +header pkt_t pkt; + +parser parse_pkt { + extract(pkt); + return ingress; +} + + + + +field_list field_list_0 { + pkt.field_a_28; + pkt.field_b_32; + pkt.field_i_8; +} + +field_list field_list_1 { + pkt.field_c_32; + pkt.field_g_16; + pkt.field_h_16; + pkt.field_k_8; +} + +field_list field_list_2 { + pkt.field_d_32; + pkt.field_l_8; + pkt.field_c_32; + pkt.field_e_16; + pkt.field_f_16; +} + +field_list_calculation hash_0 { + input { + field_list_0; + } + algorithm : crc32; + output_width : 32; +} + +field_list_calculation hash_1 { + input { + field_list_1; + } + algorithm : crc16; + output_width : 16; +} + +field_list_calculation hash_2 { + input { + field_list_2; + } + algorithm : random; + output_width : 72; +} + +action action_0(param0){ + modify_field(pkt.field_e_16, param0); + modify_field_with_hash_based_offset(pkt.field_a_28, 0, hash_0, 16384); +} + +action action_1(){ + modify_field_with_hash_based_offset(pkt.field_l_8, 0, hash_1, 256); +} + +action action_2(param0){ + modify_field(pkt.field_h_16, param0); +} + + +action do_nothing(){ + no_op(); +} + + +@pragma include_idletime 1 +@pragma idletime_precision 1 +table table_0 { + reads { + pkt.field_a_28 : exact; + } + actions { + action_0; + } +} + + +@pragma ways 8 +@pragma include_idletime 1 +table table_1 { + reads { + pkt.field_c_32 : exact; + pkt.field_d_32 : exact; + + pkt.field_f_16 : exact; + pkt.field_g_16 : exact; + pkt.field_h_16 : exact; + } + actions { + action_1; + do_nothing; + } + size : 2048; +} + +@pragma selector_max_group_size 121 +@pragma include_idletime 1 +@pragma idletime_sweep_interval 12 +table table_2 { + reads { + pkt.field_b_32 : ternary;//exact; + } + action_profile : table_2_action_profile; + size : 2048; +} + +action_profile table_2_action_profile { + actions { + action_2; + do_nothing; + } + size : 512; + dynamic_action_selection : table_2_selector; +} + +action_selector table_2_selector { + selection_key : hash_2; +} + + + +/* Main control flow */ + +control ingress { + if (valid(pkt)){ + apply(table_0); + } + + if (valid(pkt)){ + apply(table_1); + } + + + apply(table_2); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_97_unrelated_tables.p4 b/backends/tofino/bf-asm/test/internal/test_config_97_unrelated_tables.p4 new file mode 100644 index 00000000000..0709ae4eefe --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_97_unrelated_tables.p4 @@ -0,0 +1,94 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_28 : 28; + field_a2_4 : 4; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +parser start { + return parse_pkt; +} + +header pkt_t pkt; + +parser parse_pkt { + extract(pkt); + return ingress; +} + + +action action_0(param0){ + modify_field(pkt.field_b_32, param0); +} + +action action_1(param0){ + modify_field(pkt.field_c_32, param0); +} + +action action_2(param0){ + modify_field(pkt.field_d_32, param0); +} + +action do_nothing(){ + no_op(); +} + +table table_0 { + reads { + pkt.field_e_16 : exact; + } + actions { + action_0; + } + size : 200000; +} + +table table_1 { + reads { + pkt.field_f_16 : exact; + } + actions { + action_1; + } +} + +table table_2 { + reads { + pkt.field_g_16 : exact; + } + actions { + action_2; + } +} + + +/* Main control flow */ + +control ingress { + if (valid(pkt)){ + apply(table_0); + apply(table_1); + } +/* + if (valid(pkt)){ + apply(table_1); + } +*/ + apply(table_2); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_98_multiple_control_flow.p4 b/backends/tofino/bf-asm/test/internal/test_config_98_multiple_control_flow.p4 new file mode 100644 index 00000000000..b4b2f8779b9 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_98_multiple_control_flow.p4 @@ -0,0 +1,103 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_28 : 28; + field_a2_4 : 4; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +parser start { + return parse_pkt; +} + +header pkt_t pkt; + +parser parse_pkt { + extract(pkt); + return ingress; +} + + +action action_0(param0){ + modify_field(pkt.field_b_32, param0); +} + +action action_1(param0){ + modify_field(pkt.field_c_32, param0); +} + +action action_2(param0){ + modify_field(pkt.field_d_32, param0); +} + +action do_nothing(){ + no_op(); +} + +table table_0 { + reads { + pkt.field_e_16 : exact; + } + actions { + action_0; + } +} + +table table_1 { + reads { + pkt.field_f_16 : exact; + } + actions { + action_1; + } +} + +table table_2 { + reads { + pkt.field_g_16 : exact; + } + actions { + action_2; + } +} + +table table_3 { + reads { + pkt.field_g_16 : exact; + } + actions { + do_nothing; + } +} + +/* Main control flow */ + +control ingress { + apply(table_0); + pipe_0(); +} + +control pipe_0 { + apply(table_1); +// pipe_1(); +} + +control egress { + apply(table_2); + apply(table_3); +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_99_share_exact_match_key.p4 b/backends/tofino/bf-asm/test/internal/test_config_99_share_exact_match_key.p4 new file mode 100644 index 00000000000..6f9e0141cc2 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_99_share_exact_match_key.p4 @@ -0,0 +1,91 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + field_k_8 : 8; + field_l_8 : 8; + } +} + +parser start { + return parse_pkt; +} + +header pkt_t pkt; + +parser parse_pkt { + extract(pkt); + return ingress; +} + + +action action_0(param0){ + modify_field(pkt.field_d_32, param0); +} + +action action_1(param0){ + modify_field(pkt.field_h_16, param0); +} + +action do_nothing(){ + no_op(); +} + +table table_0 { + reads { + pkt.field_a_32 : ternary; + pkt.field_b_32 : exact; + pkt.field_e_16 : exact; + pkt.field_f_16 : exact; + pkt.field_i_8 : exact; + } + actions { + action_0; + } + size : 512; + //size : 4096; +} + +@pragma include_idletime 1 +table table_1 { + reads { + pkt.field_a_32 : exact; + pkt.field_e_16 : exact; + pkt.field_b_32 : exact; + pkt.field_f_16 : exact; + //pkt.field_i_8 : exact; + + pkt.field_c_32 : exact; + pkt.field_g_16 : exact; + pkt.field_j_8 : exact; + pkt.field_k_8 : exact; + + } + actions { + action_1; + } + size : 1024; + //size : 8192; +} + +/* Main control flow */ + +control ingress { + if (valid(pkt)){ + apply(table_0); + apply(table_1); + } +} diff --git a/backends/tofino/bf-asm/test/internal/test_config_9_no_ternary_indirection.p4 b/backends/tofino/bf-asm/test/internal/test_config_9_no_ternary_indirection.p4 new file mode 100644 index 00000000000..057a337355a --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_config_9_no_ternary_indirection.p4 @@ -0,0 +1,92 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +action action_0(param_0){ + modify_field(ipv4.diffserv, param_0); +} + +action action_1(){ + modify_field(ipv4.totalLen, 1); +} + +table table_0 { + reads { + ethernet.etherType : ternary; + } + actions { + action_0; + } + max_size : 4096; +} + +table table_1 { + reads { + ethernet.etherType : ternary; + } + actions { + action_1; + } + max_size : 4096; +} + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_1); +} + diff --git a/backends/tofino/bf-asm/test/internal/test_tp_1_one_table_spill.p4 b/backends/tofino/bf-asm/test/internal/test_tp_1_one_table_spill.p4 new file mode 100644 index 00000000000..9e746eb9546 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/test_tp_1_one_table_spill.p4 @@ -0,0 +1,104 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +action action_0(param0){ + modify_field(ipv4.diffserv, param0); +} + +action action_1(param1){ + modify_field(ipv4.hdrChecksum, param1); +} + +action action_e(param2, param_3){ + modify_field(ipv4.diffserv, param2); + modify_field(ipv4.hdrChecksum, param_3); +} + +table table_0 { + reads { + ipv4.dstAddr: lpm; + } + actions { + action_0; + action_1; + } + //max_size : 32768; +} + +table table_1 { + reads { + ipv4.dstAddr: exact; + ipv4.protocol: exact; + } + actions { + action_1; + } +} + +table table_e { + reads { + ipv4.srcAddr: exact; + ipv4.diffserv: exact; + } + actions { + action_e; + } +} + +/* Main control flow */ + +control ingress { + apply(table_0); + apply(table_1); +} + + +control egress { + apply(table_e); +} diff --git a/backends/tofino/bf-asm/test/internal/vk_basic_ipv4.PHV_BUG b/backends/tofino/bf-asm/test/internal/vk_basic_ipv4.PHV_BUG new file mode 100644 index 00000000000..b0ca5faf362 --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/vk_basic_ipv4.PHV_BUG @@ -0,0 +1,629 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm: csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop_ipv4(egress_port /*,srcmac, dstmac*/) { + hop(ipv4.ttl, egress_port); +// modify_field(ethernet.srcAddr, srcmac); +// modify_field(ethernet.dstAddr, dstmac); +} + +action drop_ipv4 () { + drop(); +} + +action next_hop_ipv4(egress_port, srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action mod_mac_adr(egress_port, srcmac, dstmac) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action udp_hdr_add (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + add_header(udp); + modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); + add_to_field(ipv4.totalLen, 8); +} + +action udp_set_dest(port) { + modify_field(udp.dstPort, port); +} +action udp_set_src(port) { + modify_field(udp.srcPort, port); +} + +action tcp_hdr_rm (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + remove_header(tcp); + modify_field(ipv4.protocol, 0); +// add_to_field(ipv4.totalLen, -20); +// modify_field(ipv4.totalLen, 66); +} + +action modify_tcp_dst_port_1(dstPort, egress_port) { + modify_field(tcp.dstPort, dstPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ipv4.srcAddr, ipAddr); + modify_field(ethernet.dstAddr, dstAddr); + modify_field(tcp.dstPort, tcpPort); +} + +action custom_action_2(egress_port, ipAddr, tcpPort) +{ + modify_field(ipv4.srcAddr, ipAddr); + modify_field(tcp.dstPort, tcpPort); + hop(ipv4.ttl, egress_port); +} + +action custom_action_3(egress_port, dstAddr, dstIp) +{ + modify_field(ipv4.dstAddr, dstIp); + modify_field(ethernet.dstAddr, dstAddr); + hop(ipv4.ttl, egress_port); +} + +action modify_l2 (egress_port, srcAddr, dstAddr) { + // Trying for 128 bit action data + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcAddr); + modify_field(ethernet.dstAddr, dstAddr); +} + + + +@pragma immediate 1 +@pragma stage 0 +table ig_udp { + reads { + ethernet : valid; + ipv4 : valid; + udp : valid; + udp.dstPort : ternary; + } + actions { + nop; + udp_set_dest; + } +} +@pragma immediate 1 +@pragma stage 0 +table eg_udp { + reads { + ethernet : valid; + ipv4 : valid; + udp : valid; + udp.srcPort : exact; + } + actions { + nop; + udp_set_src; + } +} + +@pragma immediate 1 +@pragma stage 0 +table ipv4_routing { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + hop_ipv4; + drop_ipv4; + } +} + +@pragma immediate 1 +@pragma stage 0 +@pragma ways 3 +@pragma pack 5 +table ipv4_routing_exm_ways_3_pack_5 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + modify_tcp_dst_port_1; + } +} + + +@pragma immediate 1 +@pragma stage 1 +@pragma ways 3 +@pragma pack 3 +table ipv4_routing_exm_ways_3_pack_3 { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + custom_action_1; + } +} + +@pragma immediate 1 +@pragma stage 1 +@pragma ways 4 +@pragma pack 3 +table ipv4_routing_exm_ways_4_pack_3_stage_1 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma immediate 1 +@pragma stage 1 +table ipv4_routing_stage_1 { + reads { + ipv4.dstAddr : lpm; + ipv4.srcAddr : exact; + } + actions { + nop; + hop_ipv4; + } + size : 1024; +} + +@pragma stage 2 +table tcam_tbl_stage_2 { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + mod_mac_adr; + } +} + +@pragma stage 2 +@pragma ways 4 +@pragma pack 7 +table ipv4_routing_exm_ways_4_pack_7_stage_2 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + tcp.dstPort : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +@pragma immediate 1 +@pragma stage 3 +@pragma ways 5 +@pragma pack 3 +table ipv4_routing_exm_ways_5_pack_3_stage_3 { + reads { + ipv4.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma immediate 1 +@pragma stage 3 +table udp_add_tbl_stage_3 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + udp_hdr_add; + } +} + +@pragma immediate 1 +@pragma stage 4 +@pragma ways 6 +@pragma pack 3 +table ipv4_routing_exm_ways_6_pack_3_stage_4 { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + + +@pragma immediate 1 +@pragma stage 4 +table tcp_rm_tbl_stage_4 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + tcp_hdr_rm; + } +} + +@pragma immediate 1 +@pragma stage 5 +@pragma ways 3 +@pragma pack 4 +table ipv4_routing_exm_ways_3_pack_4_stage_5 { + reads { + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + modify_tcp_dst_port_1; + } +} + +@pragma stage 6 +@pragma ways 4 +@pragma pack 4 +table ipv4_routing_exm_ways_4_pack_4_stage_6 { + reads { + ethernet.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma immediate 1 +@pragma stage 7 +@pragma ways 5 +@pragma pack 4 +table ipv4_routing_exm_ways_5_pack_4_stage_7 { + reads { + ipv4.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + +@pragma immediate 1 +@pragma stage 8 +table tcam_adt_deep_stage_8 { + reads { + ethernet.srcAddr : ternary; + ethernet.dstAddr : ternary; + ipv4.srcAddr : ternary; + ipv4.dstAddr : ternary; + } + actions { + nop; + modify_l2; + } + size : 2048; +} + +@pragma stage 8 +@pragma ways 4 +@pragma pack 5 +table ipv4_routing_exm_ways_4_pack_5_stage_8 { + reads { + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.srcPort : exact; + tcp.dstPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +@pragma stage 9 +table ipv4_routing_select { + reads { + ipv4.dstAddr: lpm; + } + action_profile : ecmp_action_profile; + size : 512; +} + +field_list ecmp_hash_fields { + ipv4.srcAddr; + ipv4.dstAddr; + ipv4.identification; + ipv4.protocol; +} + +field_list_calculation ecmp_hash { + input { + ecmp_hash_fields; + } + algorithm : crc16; + output_width : 10; +} + +action_profile ecmp_action_profile { + actions { + nhop_set; + nop; + } + size : 1024; + // optional + dynamic_action_selection : ecmp_selector; +} + +action_selector ecmp_selector { + selection_key : ecmp_hash; // take a field_list_calculation only + // optional + selection_mode : resilient; // “resilient” or “non-resilient” +} + +action nhop_set(port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +@pragma stage 10 +table tcam_indirect_action { + reads { + ethernet.srcAddr : ternary; + ethernet.dstAddr : ternary; + ethernet.etherType: exact; + ipv4.srcAddr : ternary; + ipv4.dstAddr : ternary; + ipv4.protocol : exact; + ipv4.version : exact; + } + action_profile : indirect_action_profile; + size : 3072; +} + +action modify_ip_id(port, id, srcAddr, dstAddr) { + modify_field(ipv4.identification, id); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); + modify_field(ethernet.srcAddr, srcAddr); + modify_field(ethernet.dstAddr, dstAddr); +} + +action_profile indirect_action_profile { + actions { + nop; + modify_ip_id; + } + size : 2048; +} + +@pragma stage 11 +@pragma ways 6 +@pragma pack 4 +table ipv4_routing_exm_ways_6_pack_4_stage_11 { + reads { + ipv4.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + + +/* Main control flow */ +control ingress { + /* A general principle : Always keep the exact match tables ahead of the + * ternary tables in the same stage, except first stage. Logic relating to next-table + * will cause the Tofino model not to launch a lookup on th exact match + * tables if the order is reversed. + */ + apply(ig_udp); + apply(ipv4_routing); + apply(ipv4_routing_exm_ways_3_pack_5); + apply(ipv4_routing_exm_ways_3_pack_3); + apply(ipv4_routing_exm_ways_4_pack_3_stage_1); + apply(ipv4_routing_stage_1); + apply(tcam_tbl_stage_2); + apply(ipv4_routing_exm_ways_4_pack_7_stage_2); + apply(ipv4_routing_exm_ways_5_pack_3_stage_3); + /* Gateway not yet supported */ +// if (ipv4.protocol == 0) { + apply(udp_add_tbl_stage_3); +// } + apply(ipv4_routing_exm_ways_6_pack_3_stage_4); +// if (valid(tcp)) { + apply(tcp_rm_tbl_stage_4); +// } + apply(ipv4_routing_exm_ways_3_pack_4_stage_5); + apply(ipv4_routing_exm_ways_4_pack_4_stage_6); + apply(ipv4_routing_exm_ways_5_pack_4_stage_7); + apply(tcam_adt_deep_stage_8); + apply(ipv4_routing_exm_ways_4_pack_5_stage_8); + // Stage 9 - Please use caution before adding any more tables in stage 9 + // Poor man's selector may not work + apply(ipv4_routing_select); + // Stage 10 + apply(tcam_indirect_action); + // Stage 11 +} + +control egress { + apply(eg_udp); + apply(ipv4_routing_exm_ways_6_pack_4_stage_11); +} diff --git a/backends/tofino/bf-asm/test/internal/vk_basic_ipv4_20150706.p4 b/backends/tofino/bf-asm/test/internal/vk_basic_ipv4_20150706.p4 new file mode 100644 index 00000000000..991f3d2fd0f --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/vk_basic_ipv4_20150706.p4 @@ -0,0 +1,707 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + learn_meta_1:20; + learn_meta_2:24; + learn_meta_3:25; + learn_meta_4:10; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm : csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +field_list learn_1 { + ipv4.ihl; + ipv4.protocol; + ipv4.srcAddr; + ethernet.srcAddr; + ethernet.dstAddr; + ipv4.fragOffset; + ipv4.identification; + routing_metadata.learn_meta_1; + routing_metadata.learn_meta_4; +} + +action learn_1 (learn_meta_1, learn_meta_4) { + generate_digest(FLOW_LRN_DIGEST_RCVR, learn_1); + modify_field(routing_metadata.learn_meta_1, learn_meta_1); + modify_field(routing_metadata.learn_meta_4, learn_meta_4); +} + +field_list learn_2 { + ipv4.ihl; + ipv4.identification; + ipv4.protocol; + ipv4.srcAddr; + ethernet.srcAddr; + ethernet.dstAddr; + ipv4.fragOffset; + routing_metadata.learn_meta_2; + routing_metadata.learn_meta_3; +} + +action learn_2 (learn_meta_2, learn_meta_3) { + generate_digest(FLOW_LRN_DIGEST_RCVR, learn_2); + modify_field(routing_metadata.learn_meta_2, learn_meta_2); + modify_field(routing_metadata.learn_meta_3, learn_meta_3); +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop_ipv4(egress_port /*,srcmac, dstmac*/) { + hop(ipv4.ttl, egress_port); +// modify_field(ethernet.srcAddr, srcmac); +// modify_field(ethernet.dstAddr, dstmac); +} + +action drop_ipv4 () { + drop(); +} + +action next_hop_ipv4(egress_port, srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action mod_mac_adr(egress_port, srcmac, dstmac) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action udp_hdr_add (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + add_header(udp); + modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); + add_to_field(ipv4.totalLen, 8); +} + +action udp_set_dest(port) { + modify_field(udp.dstPort, port); +} +action udp_set_src(port) { + modify_field(udp.srcPort, port); +} + +action tcp_hdr_rm (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + remove_header(tcp); + modify_field(ipv4.protocol, 0); +// add_to_field(ipv4.totalLen, -20); +// modify_field(ipv4.totalLen, 66); +} + +action modify_tcp_dst_port_1(dstPort, egress_port) { + modify_field(tcp.dstPort, dstPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ipv4.srcAddr, ipAddr); + modify_field(ethernet.dstAddr, dstAddr); + modify_field(tcp.dstPort, tcpPort); +} + +action custom_action_2(egress_port, ipAddr, tcpPort) +{ + modify_field(ipv4.srcAddr, ipAddr); + modify_field(tcp.dstPort, tcpPort); + hop(ipv4.ttl, egress_port); +} + +action custom_action_3(egress_port, dstAddr, dstIp) +{ + modify_field(ipv4.dstAddr, dstIp); + modify_field(ethernet.dstAddr, dstAddr); + hop(ipv4.ttl, egress_port); +} + +action modify_l2 (egress_port, srcAddr, dstAddr, tcp_sport, tcp_dport) { + // Trying for >128 bit action data + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcAddr); + modify_field(ethernet.dstAddr, dstAddr); + modify_field(tcp.dstPort, tcp_dport); + modify_field(tcp.srcPort, tcp_sport); +} + +@pragma immediate 1 +@pragma stage 0 +table ig_udp { + reads { + ethernet : valid; + ipv4 : valid; + udp : valid; + udp.dstPort : ternary; + } + actions { + nop; + udp_set_dest; + } +} +@pragma immediate 1 +@pragma stage 0 +table eg_udp { + reads { + ethernet : valid; + ipv4 : valid; + udp : valid; + udp.srcPort : exact; + } + actions { + nop; + udp_set_src; + } +} + +@pragma immediate 1 +@pragma stage 0 +table ipv4_routing { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + hop_ipv4; + drop_ipv4; + learn_1; + learn_2; + } + size : 512; +} + +@pragma immediate 1 +@pragma stage 0 +@pragma ways 3 +@pragma pack 5 +table ipv4_routing_exm_ways_3_pack_5 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + modify_tcp_dst_port_1; + } +} + + +@pragma immediate 1 +@pragma stage 1 +@pragma ways 3 +@pragma pack 3 +table ipv4_routing_exm_ways_3_pack_3 { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + custom_action_1; + } +} + +@pragma immediate 1 +@pragma stage 1 +@pragma ways 4 +@pragma pack 3 +table ipv4_routing_exm_ways_4_pack_3_stage_1 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma immediate 1 +@pragma stage 1 +table ipv4_routing_stage_1 { + reads { + ipv4.dstAddr : lpm; + ipv4.srcAddr : exact; + } + actions { + nop; + hop_ipv4; + } + size : 1024; +} + +@pragma stage 2 +table tcam_tbl_stage_2 { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + mod_mac_adr; + } +} + +@pragma stage 2 +@pragma ways 4 +@pragma pack 7 +table ipv4_routing_exm_ways_4_pack_7_stage_2 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + tcp.dstPort : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +@pragma immediate 1 +@pragma stage 3 +@pragma ways 5 +@pragma pack 3 +table ipv4_routing_exm_ways_5_pack_3_stage_3 { + reads { + ipv4.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma immediate 1 +@pragma stage 3 +table udp_add_tbl_stage_3 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + udp_hdr_add; + } +} + +@pragma immediate 1 +@pragma stage 4 +@pragma ways 6 +@pragma pack 3 +table ipv4_routing_exm_ways_6_pack_3_stage_4 { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + + +@pragma immediate 1 +@pragma stage 4 +table tcp_rm_tbl_stage_4 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + tcp_hdr_rm; + } +} + +@pragma immediate 1 +@pragma stage 5 +@pragma ways 3 +@pragma pack 4 +table ipv4_routing_exm_ways_3_pack_4_stage_5 { + reads { + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + modify_tcp_dst_port_1; + } +} + +@pragma stage 6 +@pragma ways 4 +@pragma pack 4 +table ipv4_routing_exm_ways_4_pack_4_stage_6 { + reads { + ethernet.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma immediate 1 +@pragma stage 7 +@pragma ways 5 +@pragma pack 4 +table ipv4_routing_exm_ways_5_pack_4_stage_7 { + reads { + ipv4.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + +@pragma immediate 1 +@pragma stage 8 +table tcam_adt_deep_stage_8 { + reads { + ethernet.srcAddr : ternary; + ethernet.dstAddr : ternary; + ipv4.srcAddr : ternary; + ipv4.dstAddr : ternary; + } + actions { + nop; + modify_l2; + } + size : 3072; +} + +@pragma stage 8 +@pragma ways 4 +@pragma pack 5 +table ipv4_routing_exm_ways_4_pack_5_stage_8 { + reads { + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.srcPort : exact; + tcp.dstPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +@pragma stage 9 +table ipv4_routing_select { + reads { + ipv4.dstAddr: lpm; + } + action_profile : ecmp_action_profile; + size : 512; +} + +field_list ecmp_hash_fields { + ipv4.srcAddr; + ipv4.dstAddr; + ipv4.identification; + ipv4.protocol; +} + +field_list_calculation ecmp_hash { + input { + ecmp_hash_fields; + } + algorithm : crc16; + output_width : 10; +} + +action_profile ecmp_action_profile { + actions { + nhop_set; + nop; + } + size : 1024; + // optional + dynamic_action_selection : ecmp_selector; +} + +action_selector ecmp_selector { + selection_key : ecmp_hash; // take a field_list_calculation only + // optional + selection_mode : resilient; // “resilient” or “non-resilient” +} + +action nhop_set(port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +@pragma stage 10 +table tcam_indirect_action { + reads { + ethernet.srcAddr : ternary; + ethernet.dstAddr : ternary; + ethernet.etherType: exact; + ipv4.srcAddr : ternary; + ipv4.dstAddr : ternary; + ipv4.protocol : exact; + ipv4.version : exact; + } + action_profile : indirect_action_profile; + size : 2048; +} + +action modify_ip_id(port, id, srcAddr, dstAddr) { + modify_field(ipv4.identification, id); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); + modify_field(ethernet.srcAddr, srcAddr); + modify_field(ethernet.dstAddr, dstAddr); +} + +action_profile indirect_action_profile { + actions { + nop; + modify_ip_id; + } + size : 1500; +} + +@pragma stage 11 +@pragma ways 6 +@pragma pack 4 +table ipv4_routing_exm_ways_6_pack_4_stage_11 { + reads { + ipv4.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma stage 5 +table tcam_range { + reads { + ipv4.dstAddr : ternary; + tcp.dstPort : range; + } + actions { + nop; + hop_ipv4; + } + size : 1024; +} + + +/* Main control flow */ +control ingress { +#if 0 + /* A general principle : Always keep the exact match tables ahead of the + * ternary tables in the same stage, except first stage. Logic relating to next-table + * will cause the Tofino model not to launch a lookup on th exact match + * tables if the order is reversed. + */ + apply(ig_udp); + apply(ipv4_routing); + apply(ipv4_routing_exm_ways_3_pack_5); + apply(ipv4_routing_exm_ways_3_pack_3); + apply(ipv4_routing_exm_ways_4_pack_3_stage_1); + apply(ipv4_routing_stage_1); + apply(tcam_tbl_stage_2); + apply(ipv4_routing_exm_ways_4_pack_7_stage_2); + apply(ipv4_routing_exm_ways_5_pack_3_stage_3); + /* Gateway not yet supported */ +// if (ipv4.protocol == 0) { + apply(udp_add_tbl_stage_3); +// } + apply(ipv4_routing_exm_ways_6_pack_3_stage_4); +// if (valid(tcp)) { + apply(tcp_rm_tbl_stage_4); +// } + apply(ipv4_routing_exm_ways_3_pack_4_stage_5); + apply(ipv4_routing_exm_ways_4_pack_4_stage_6); + apply(ipv4_routing_exm_ways_5_pack_4_stage_7); + apply(tcam_adt_deep_stage_8); + apply(ipv4_routing_exm_ways_4_pack_5_stage_8); + // Stage 9 - Please use caution before adding any more tables in stage 9 + // Poor man's selector may not work + apply(ipv4_routing_select); + // Stage 10 + apply(tcam_indirect_action); + // Stage 11 +#endif + apply(tcam_range); +} + +control egress { + apply(eg_udp); + // Commenting out since modify of egress port is not possible in egress +// apply(ipv4_routing_exm_ways_6_pack_4_stage_11); +} + diff --git a/backends/tofino/bf-asm/test/internal/vk_basic_ipv4_subset.p4 b/backends/tofino/bf-asm/test/internal/vk_basic_ipv4_subset.p4 new file mode 100644 index 00000000000..8f193301d8d --- /dev/null +++ b/backends/tofino/bf-asm/test/internal/vk_basic_ipv4_subset.p4 @@ -0,0 +1,189 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm: csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +@pragma stage 10 +table tcam_indirect_action { + reads { + ethernet.srcAddr : ternary; + ethernet.dstAddr : ternary; + ethernet.etherType: exact; + ipv4.srcAddr : ternary; + ipv4.dstAddr : ternary; + ipv4.protocol : exact; + ipv4.version : exact; + } + action_profile : indirect_action_profile; + size : 2048; +} + +action modify_ip_id(port, id, srcAddr, dstAddr) { + modify_field(ipv4.identification, id); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); + modify_field(ethernet.srcAddr, srcAddr); + modify_field(ethernet.dstAddr, dstAddr); +} + +action_profile indirect_action_profile { + actions { + nop; + modify_ip_id; + } + size : 2048; +} + +/* Main control flow */ +control ingress { + if (valid(ipv4)){ + apply(tcam_indirect_action); + } +} + diff --git a/backends/tofino/bf-asm/test/jdiff.sh b/backends/tofino/bf-asm/test/jdiff.sh new file mode 100755 index 00000000000..26274e046d0 --- /dev/null +++ b/backends/tofino/bf-asm/test/jdiff.sh @@ -0,0 +1,84 @@ +#!/bin/bash + +curdir=`pwd` +json_diff_file="json_diff.txt" + +TRY_BINDIRS=" + $PWD + $PWD/.. + $PWD/../* + $TESTDIR/.. + $TESTDIR/../* +" + +function findbin () { + found="" + if [ -x "$BUILDDIR/$1" ]; then + echo $BUILDDIR/$1 + return + fi + for d in $TRY_BINDIRS; do + if [ -x "$d/$1" ]; then + if [ -z "$found" -o "$d/$1" -nt "$found" ]; then + found="$(cd $d; pwd -P)/$1" + fi + fi + done + if [ -z "$found" ]; then + echo >&2 "Can't find $1 executable" + echo false + exit + else + echo $found + fi +} + +if [ ! -x "$JSON_DIFF" ]; then + JSON_DIFF=$(findbin json_diff) +fi + +if [ -z "$1" ] || [ -z "$2" ]; then + echo "Please specify 2 dirs to diff" + exit 1 +fi + +dir1=$(readlink -f "$1") +dir2=$(readlink -f "$2") +echo "Comparing dir1 vs dir2" +echo "dir1="$dir1 +echo "dir2="$dir2 + +> $json_diff_file +for f1 in $dir1/*.cfg.json*; do + f=$(basename $f1) + f2="$dir2/${f1##*/}" + if [ ! -r $f2 ]; then + ext="${f2##*.}" + if [ "$ext" = "gz" ]; then + f2=${f2%.*} + else + f2="$f2.gz" + fi + fi + if [ ! -r $f2 ]; then + echo "Cannot read file $f2" + continue + fi + echo "Comparing file $(basename $f1) vs $(basename $f2)" + if zcmp -s $f1 $f2; then + continue + elif [ "$f1" = "$dir1/regs.pipe.cfg.json" ]; then + $JSON_DIFF -i mau $f1 $f2 + if [ $? -gt 128 ]; then + echo "***json_diff crashed" + fi + continue + fi + $JSON_DIFF $f1 $f2 >> $json_diff_file +done + +if [ -r $dir1/context.json ]; then + { $JSON_DIFF $CTXT_DIFFARGS $dir1/context.json $dir2/context.json; + if [ $? -gt 128 ]; then echo "***json_diff crashed"; fi; } >> \ + $json_diff_file +fi diff --git a/backends/tofino/bf-asm/test/mac_rewrite.p4 b/backends/tofino/bf-asm/test/mac_rewrite.p4 new file mode 100644 index 00000000000..4d700ede2ab --- /dev/null +++ b/backends/tofino/bf-asm/test/mac_rewrite.p4 @@ -0,0 +1,149 @@ +parser start { + return parse_ethernet; +} + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header ethernet_t ethernet; +#define ETHERTYPE_IPV4 0x0800 +#define ETHERTYPE_IPV6 0x86dd + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + ETHERTYPE_IPV4 : parse_ipv4; + ETHERTYPE_IPV6 : parse_ipv6; + default: ingress; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} +header ipv4_t ipv4; +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +header_type ipv6_t { + fields { + version : 4; + trafficClass : 8; + flowLabel : 20; + payloadLen : 16; + nextHdr : 8; + hopLimit : 8; + srcAddr : 128; + dstAddr : 128; + } +} +header ipv6_t ipv6; + +parser parse_ipv6 { + extract(ipv6); + return ingress; +} + +header_type egress_metadata_t { + fields { + payload_length : 16; /* payload length for tunnels */ + smac_idx : 9; /* index into source mac table */ + bd : 16; /* egress inner bd */ + inner_replica : 1; /* is copy is due to inner replication */ + replica : 1; /* is this a replica */ + mac_da : 48; /* final mac da */ + routed : 1; /* is this replica routed */ + same_bd_check : 16; /* ingress bd xor egress bd */ + + header_count: 4; /* Number of headers */ + + drop_reason : 8; /* drop reason for negative mirroring */ + egress_bypass : 1; /* skip the entire egress pipeline */ + drop_exception : 8; /* MTU check fail, .. */ + } +} +metadata egress_metadata_t egress_metadata; + +action do_setup(idx, routed) { + modify_field(egress_metadata.mac_da, ethernet.dstAddr); + modify_field(egress_metadata.smac_idx, idx); + modify_field(egress_metadata.routed, routed); +} + +table setup { + reads { ethernet: valid; } + actions { do_setup; } +} + +control ingress { + apply(setup); + process_mac_rewrite(); +} + +action nop() { } + +action rewrite_ipv4_unicast_mac(smac) { + modify_field(ethernet.srcAddr, smac); + modify_field(ethernet.dstAddr, egress_metadata.mac_da); + add_to_field(ipv4.ttl, -1); +} + +action rewrite_ipv4_multicast_mac(smac) { + modify_field(ethernet.srcAddr, smac); + modify_field(ethernet.dstAddr, 0x01005E000000, 0xFFFFFF800000); + add_to_field(ipv4.ttl, -1); +} + +action rewrite_ipv6_unicast_mac(smac) { + modify_field(ethernet.srcAddr, smac); + modify_field(ethernet.dstAddr, egress_metadata.mac_da); + add_to_field(ipv6.hopLimit, -1); +} + +action rewrite_ipv6_multicast_mac(smac) { + modify_field(ethernet.srcAddr, smac); + modify_field(ethernet.dstAddr, 0x333300000000, 0xFFFF00000000); + add_to_field(ipv6.hopLimit, -1); +} + +table mac_rewrite { + reads { + egress_metadata.smac_idx : exact; + ipv4 : valid; + ipv6 : valid; + } + actions { + nop; + rewrite_ipv4_unicast_mac; + rewrite_ipv4_multicast_mac; + rewrite_ipv6_unicast_mac; + rewrite_ipv6_multicast_mac; + } + size : 512; +} + +control process_mac_rewrite { + if (egress_metadata.routed == 1) { + apply(mac_rewrite); + } +} diff --git a/backends/tofino/bf-asm/test/mau/01-FlexCounter.p4 b/backends/tofino/bf-asm/test/mau/01-FlexCounter.p4 new file mode 100644 index 00000000000..f67bf1b1358 --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/01-FlexCounter.p4 @@ -0,0 +1,89 @@ +#ifdef __TARGET_TOFINO__ +#include +#include +#include +#else +#include "includes/tofino.p4" +#endif + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + ethertype : 16; + } +} + +header_type vlan_tag_t { + fields { + prio : 3; + cfi : 1; + vlan_id : 12; + } +} + +header ethernet_t ethernet; +header vlan_tag_t vlan_tag; + +parser start { + extract(ethernet); + return select(latest.ethertype) { + 0x8100 : parse_vlan_tag; + default: ingress; + } +} + +parser parse_vlan_tag { + extract(vlan_tag); + return ingress; +} + +@pragma pa_solitary md.flex_counter_offset + +header_type metadata_t { + fields { + flex_counter_index : 13; + } +} + +metadata metadata_t md; + +counter flex_counter { + type : packets; + instance_count : 8192; +} + +action set_flex_counter_index(flex_counter_base) { + add(md.flex_counter_index, flex_counter_base, vlan_tag.prio); +} + +action update_flex_counter() { + count(flex_counter, md.flex_counter_index); +} + +table vlan { + reads { + vlan_tag.vlan_id : exact; + } + actions { + set_flex_counter_index; + } + size : 4096; +} + +table update_counters { + actions { + update_flex_counter; + } +} + +control ingress { + apply(vlan) { + hit { + apply(update_counters); + } + } +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/mau/02-FlexCounterActionProfile.p4 b/backends/tofino/bf-asm/test/mau/02-FlexCounterActionProfile.p4 new file mode 100644 index 00000000000..6e3f02fc254 --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/02-FlexCounterActionProfile.p4 @@ -0,0 +1,101 @@ +#ifdef __TARGET_TOFINO__ +#include +#include +#include +#else +#include "includes/tofino.p4" +#endif + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + ethertype : 16; + } +} + +header_type vlan_tag_t { + fields { + prio : 3; + cfi : 1; + vlan_id : 12; + } +} + +header ethernet_t ethernet; +header vlan_tag_t vlan_tag; + +parser start { + extract(ethernet); + return select(latest.ethertype) { + 0x8100 : parse_vlan_tag; + default: ingress; + } +} + +parser parse_vlan_tag { + extract(vlan_tag); + return ingress; +} + +@pragma pa_solitary md.flex_counter_offset + +header_type metadata_t { + fields { + flex_counter_index : 13; + } +} + +metadata metadata_t md; + +counter flex_counter { + type : packets; + instance_count : 8192; +} + +action set_flex_counter_index(flex_counter_base) { + add(md.flex_counter_index, flex_counter_base, vlan_tag.prio); +} + +action update_flex_counter(flex_counter_index) { + count(flex_counter, flex_counter_index); +} + +field_list vlan_prio_fields { + vlan_tag.prio; +} + +field_list_calculation vlan_prio_calc { + input { + vlan_prio_fields; + } + algorithm : identity_lsb; + output_width : 3; +} + +action_selector vlan_prio_sel { + selection_key : vlan_prio_calc; +} + +action_profile vlan_flex_counter_profile { + actions { + update_flex_counter; + } + size : 8; + dynamic_action_selection : vlan_prio_sel; +} + +table vlan { + reads { + vlan_tag.vlan_id : exact; + } + action_profile: vlan_flex_counter_profile; + size : 4096; +} + +control ingress { + apply(vlan); +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/mau/02-FullPHV1.p4 b/backends/tofino/bf-asm/test/mau/02-FullPHV1.p4 new file mode 100644 index 00000000000..44ce6a957e4 --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/02-FullPHV1.p4 @@ -0,0 +1,766 @@ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + ethertype : 16; + } +} + +header ethernet_t ethernet; + +header_type m_t { + fields { + field_8_01 : 8; + field_8_02 : 8; + field_8_03 : 8; + field_8_04 : 8; + field_8_05 : 8; + field_8_06 : 8; + field_8_07 : 8; + field_8_08 : 8; + field_8_09 : 8; + field_8_10 : 8; + field_8_11 : 8; + field_8_12 : 8; + field_8_13 : 8; + field_8_14 : 8; + field_8_15 : 8; + field_8_16 : 8; + field_8_17 : 8; + field_8_18 : 8; + field_8_19 : 8; + field_8_20 : 8; + field_8_21 : 8; + field_8_22 : 8; + field_8_23 : 8; + field_8_24 : 8; + field_8_25 : 8; + field_8_26 : 8; + field_8_27 : 8; + field_8_28 : 8; + field_8_29 : 8; + field_8_30 : 8; + field_8_31 : 8; + field_8_32 : 8; + field_8_33 : 8; + field_8_34 : 8; + field_8_35 : 8; + field_8_36 : 8; + field_8_37 : 8; + field_8_38 : 8; + field_8_39 : 8; + field_8_40 : 8; + field_8_41 : 8; + field_8_42 : 8; + field_8_43 : 8; + field_8_44 : 8; + field_8_45 : 8; + field_8_46 : 8; + field_8_47 : 8; + field_8_48 : 8; + field_8_49 : 8; + field_8_50 : 8; + field_8_51 : 8; + field_8_52 : 8; + field_8_53 : 8; + field_8_54 : 8; + field_8_55 : 8; + field_8_56 : 8; + field_8_57 : 8; + field_8_58 : 8; + field_8_59 : 8; + field_8_60 : 8; + field_8_61 : 8; + field_8_62 : 8; + field_8_63 : 8; + field_8_64 : 8; + + field_16_01 : 16; + field_16_02 : 16; + field_16_03 : 16; + field_16_04 : 16; + field_16_05 : 16; + field_16_06 : 16; + field_16_07 : 16; + field_16_08 : 16; + field_16_09 : 16; + field_16_10 : 16; + field_16_11 : 16; + field_16_12 : 16; + field_16_13 : 16; + field_16_14 : 16; + field_16_15 : 16; + field_16_16 : 16; + field_16_17 : 16; + field_16_18 : 16; + field_16_19 : 16; + field_16_20 : 16; + field_16_21 : 16; + field_16_22 : 16; + field_16_23 : 16; + field_16_24 : 16; + field_16_25 : 16; + field_16_26 : 16; + field_16_27 : 16; + field_16_28 : 16; + field_16_29 : 16; + field_16_30 : 16; + field_16_31 : 16; + field_16_32 : 16; + field_16_33 : 16; + field_16_34 : 16; + field_16_35 : 16; + field_16_36 : 16; + field_16_37 : 16; + field_16_38 : 16; + field_16_39 : 16; + field_16_40 : 16; + field_16_41 : 16; + field_16_42 : 16; + field_16_43 : 16; + field_16_44 : 16; + field_16_45 : 16; + field_16_46 : 16; + field_16_47 : 16; + field_16_48 : 16; + field_16_49 : 16; + field_16_50 : 16; + field_16_51 : 16; + field_16_52 : 16; + field_16_53 : 16; + field_16_54 : 16; + field_16_55 : 16; + field_16_56 : 16; + field_16_57 : 16; + field_16_58 : 16; + field_16_59 : 16; + field_16_60 : 16; + field_16_61 : 16; + field_16_62 : 16; + field_16_63 : 16; + field_16_64 : 16; + field_16_65 : 16; + field_16_66 : 16; + field_16_67 : 16; + field_16_68 : 16; + field_16_69 : 16; + field_16_70 : 16; + field_16_71 : 16; + field_16_72 : 16; + field_16_73 : 16; + field_16_74 : 16; + field_16_75 : 16; + field_16_76 : 16; + field_16_77 : 16; + field_16_78 : 16; + field_16_79 : 16; + field_16_80 : 16; + field_16_81 : 16; + field_16_82 : 16; + field_16_83 : 16; + field_16_84 : 16; + field_16_85 : 16; + field_16_86 : 16; + field_16_87 : 16; + field_16_88 : 16; + field_16_89 : 16; + field_16_90 : 16; + field_16_91 : 16; + field_16_92 : 16; + field_16_93 : 16; + field_16_94 : 16; + field_16_95 : 16; + field_16_96 : 16; + + field_32_01 : 32; + field_32_02 : 32; + field_32_03 : 32; + field_32_04 : 32; + field_32_05 : 32; + field_32_06 : 32; + field_32_07 : 32; + field_32_08 : 32; + field_32_09 : 32; + field_32_10 : 32; + field_32_11 : 32; + field_32_12 : 32; + field_32_13 : 32; + field_32_14 : 32; + field_32_15 : 32; + field_32_16 : 32; + field_32_17 : 32; + field_32_18 : 32; + field_32_19 : 32; + field_32_20 : 32; + field_32_21 : 32; + field_32_22 : 32; + field_32_23 : 32; + field_32_24 : 32; + field_32_25 : 32; + field_32_26 : 32; + field_32_27 : 32; + field_32_28 : 32; + field_32_29 : 32; + field_32_30 : 32; + field_32_31 : 32; + field_32_32 : 32; + field_32_33 : 32; + field_32_34 : 32; + field_32_35 : 32; + field_32_36 : 32; + field_32_37 : 32; + field_32_38 : 32; + field_32_39 : 32; + field_32_40 : 32; + field_32_41 : 32; + field_32_42 : 32; + field_32_43 : 32; + field_32_44 : 32; + field_32_45 : 32; + field_32_46 : 32; + field_32_47 : 32; + field_32_48 : 32; + field_32_49 : 32; + field_32_50 : 32; + field_32_51 : 32; + field_32_52 : 32; + field_32_53 : 32; + field_32_54 : 32; + field_32_55 : 32; + field_32_56 : 32; + field_32_57 : 32; + field_32_58 : 32; + field_32_59 : 32; + field_32_60 : 32; + field_32_61 : 32; + field_32_62 : 32; + field_32_63 : 32; + field_32_64 : 32; + } +} + +metadata m_t m; + +parser start { + extract(ethernet); + return ingress; +} + +action a1() { + modify_field(m.field_8_01, 1); + modify_field(m.field_8_02, 2); + modify_field(m.field_8_03, 3); + modify_field(m.field_8_04, 4); + modify_field(m.field_8_05, 5); + modify_field(m.field_8_06, 6); + modify_field(m.field_8_07, 7); + modify_field(m.field_8_08, 8); + modify_field(m.field_8_09, 9); + modify_field(m.field_8_10, 10); + modify_field(m.field_8_11, 11); + modify_field(m.field_8_12, 12); + modify_field(m.field_8_13, 13); + modify_field(m.field_8_14, 14); + modify_field(m.field_8_15, 15); + modify_field(m.field_8_16, 16); + modify_field(m.field_8_17, 17); + modify_field(m.field_8_18, 18); + modify_field(m.field_8_19, 19); + modify_field(m.field_8_20, 20); + modify_field(m.field_8_21, 21); + modify_field(m.field_8_22, 22); + modify_field(m.field_8_23, 23); + modify_field(m.field_8_24, 24); + modify_field(m.field_8_25, 25); + modify_field(m.field_8_26, 26); + modify_field(m.field_8_27, 27); + modify_field(m.field_8_28, 28); + modify_field(m.field_8_29, 29); + modify_field(m.field_8_30, 30); + modify_field(m.field_8_31, 31); + modify_field(m.field_8_32, 32); + modify_field(m.field_8_33, 33); + modify_field(m.field_8_34, 34); + modify_field(m.field_8_35, 35); + modify_field(m.field_8_36, 36); + modify_field(m.field_8_37, 37); + modify_field(m.field_8_38, 38); + modify_field(m.field_8_39, 39); + modify_field(m.field_8_40, 40); + modify_field(m.field_8_41, 41); + modify_field(m.field_8_42, 42); + modify_field(m.field_8_43, 43); + modify_field(m.field_8_44, 44); + modify_field(m.field_8_45, 45); + modify_field(m.field_8_46, 46); + modify_field(m.field_8_47, 47); + modify_field(m.field_8_48, 48); + modify_field(m.field_8_49, 49); + modify_field(m.field_8_50, 50); + modify_field(m.field_8_51, 51); + modify_field(m.field_8_52, 52); + modify_field(m.field_8_53, 53); + modify_field(m.field_8_54, 54); + modify_field(m.field_8_55, 55); + modify_field(m.field_8_56, 56); + modify_field(m.field_8_57, 57); + modify_field(m.field_8_58, 58); + modify_field(m.field_8_59, 59); + modify_field(m.field_8_60, 60); + modify_field(m.field_8_61, 61); + modify_field(m.field_8_62, 62); + modify_field(m.field_8_63, 63); + modify_field(m.field_8_64, 64); + + modify_field(m.field_16_01, 1); + modify_field(m.field_16_02, 2); + modify_field(m.field_16_03, 3); + modify_field(m.field_16_04, 4); + modify_field(m.field_16_05, 5); + modify_field(m.field_16_06, 6); + modify_field(m.field_16_07, 7); + modify_field(m.field_16_08, 8); + modify_field(m.field_16_09, 9); + modify_field(m.field_16_10, 10); + modify_field(m.field_16_11, 11); + modify_field(m.field_16_12, 12); + modify_field(m.field_16_13, 13); + modify_field(m.field_16_14, 14); + modify_field(m.field_16_15, 15); + modify_field(m.field_16_16, 16); + modify_field(m.field_16_17, 17); + modify_field(m.field_16_18, 18); + modify_field(m.field_16_19, 19); + modify_field(m.field_16_20, 20); + modify_field(m.field_16_21, 21); + modify_field(m.field_16_22, 22); + modify_field(m.field_16_23, 23); + modify_field(m.field_16_24, 24); + modify_field(m.field_16_25, 25); + modify_field(m.field_16_26, 26); + modify_field(m.field_16_27, 27); + modify_field(m.field_16_28, 28); + modify_field(m.field_16_29, 29); + modify_field(m.field_16_30, 30); + modify_field(m.field_16_31, 31); + modify_field(m.field_16_32, 32); + modify_field(m.field_16_33, 33); + modify_field(m.field_16_34, 34); + modify_field(m.field_16_35, 35); + modify_field(m.field_16_36, 36); + modify_field(m.field_16_37, 37); + modify_field(m.field_16_38, 38); + modify_field(m.field_16_39, 39); + modify_field(m.field_16_40, 40); + modify_field(m.field_16_41, 41); + modify_field(m.field_16_42, 42); + modify_field(m.field_16_43, 43); + modify_field(m.field_16_44, 44); + modify_field(m.field_16_45, 45); + modify_field(m.field_16_46, 46); + modify_field(m.field_16_47, 47); + modify_field(m.field_16_48, 48); + modify_field(m.field_16_49, 49); + modify_field(m.field_16_50, 50); + modify_field(m.field_16_51, 51); + modify_field(m.field_16_52, 52); + modify_field(m.field_16_53, 53); + modify_field(m.field_16_54, 54); + modify_field(m.field_16_55, 55); + modify_field(m.field_16_56, 56); + modify_field(m.field_16_57, 57); + modify_field(m.field_16_58, 58); + modify_field(m.field_16_59, 59); + modify_field(m.field_16_60, 60); + modify_field(m.field_16_61, 61); + modify_field(m.field_16_62, 62); + modify_field(m.field_16_63, 63); + modify_field(m.field_16_64, 64); + modify_field(m.field_16_65, 65); + modify_field(m.field_16_66, 66); + modify_field(m.field_16_67, 67); + modify_field(m.field_16_68, 68); + modify_field(m.field_16_69, 69); + modify_field(m.field_16_70, 70); + modify_field(m.field_16_71, 71); + modify_field(m.field_16_72, 72); + modify_field(m.field_16_73, 73); + modify_field(m.field_16_74, 74); + modify_field(m.field_16_75, 75); + modify_field(m.field_16_76, 76); + modify_field(m.field_16_77, 77); + modify_field(m.field_16_78, 78); + modify_field(m.field_16_79, 79); + modify_field(m.field_16_80, 80); + modify_field(m.field_16_81, 81); + modify_field(m.field_16_82, 82); + modify_field(m.field_16_83, 83); + modify_field(m.field_16_84, 84); + modify_field(m.field_16_85, 85); + modify_field(m.field_16_86, 86); + modify_field(m.field_16_87, 87); + modify_field(m.field_16_88, 88); + modify_field(m.field_16_89, 89); + modify_field(m.field_16_90, 90); + modify_field(m.field_16_91, 91); + modify_field(m.field_16_92, 92); + modify_field(m.field_16_93, 93); + modify_field(m.field_16_94, 94); + modify_field(m.field_16_95, 95); + modify_field(m.field_16_96, 96); + + modify_field(m.field_32_01, 1); + modify_field(m.field_32_02, 2); + modify_field(m.field_32_03, 3); + modify_field(m.field_32_04, 4); + modify_field(m.field_32_05, 5); + modify_field(m.field_32_06, 6); + modify_field(m.field_32_07, 7); + modify_field(m.field_32_08, 8); + modify_field(m.field_32_09, 9); + modify_field(m.field_32_10, 10); + modify_field(m.field_32_11, 11); + modify_field(m.field_32_12, 12); + modify_field(m.field_32_13, 13); + modify_field(m.field_32_14, 14); + modify_field(m.field_32_15, 15); + modify_field(m.field_32_16, 16); + modify_field(m.field_32_17, 17); + modify_field(m.field_32_18, 18); + modify_field(m.field_32_19, 19); + modify_field(m.field_32_20, 20); + modify_field(m.field_32_21, 21); + modify_field(m.field_32_22, 22); + modify_field(m.field_32_23, 23); + modify_field(m.field_32_24, 24); + modify_field(m.field_32_25, 25); + modify_field(m.field_32_26, 26); + modify_field(m.field_32_27, 27); + modify_field(m.field_32_28, 28); + modify_field(m.field_32_29, 29); + modify_field(m.field_32_30, 30); + modify_field(m.field_32_31, 31); + modify_field(m.field_32_32, 32); + modify_field(m.field_32_33, 33); + modify_field(m.field_32_34, 34); + modify_field(m.field_32_35, 35); + modify_field(m.field_32_36, 36); + modify_field(m.field_32_37, 37); + modify_field(m.field_32_38, 38); + modify_field(m.field_32_39, 39); +#if 0 + modify_field(m.field_32_40, 40); + modify_field(m.field_32_41, 41); + modify_field(m.field_32_42, 42); + modify_field(m.field_32_43, 43); + modify_field(m.field_32_44, 44); + modify_field(m.field_32_45, 45); + modify_field(m.field_32_46, 46); + modify_field(m.field_32_47, 47); + modify_field(m.field_32_48, 48); + modify_field(m.field_32_49, 49); + modify_field(m.field_32_50, 50); + modify_field(m.field_32_51, 51); + modify_field(m.field_32_52, 52); + modify_field(m.field_32_53, 53); + modify_field(m.field_32_54, 54); + modify_field(m.field_32_55, 55); + modify_field(m.field_32_56, 56); + modify_field(m.field_32_57, 57); + modify_field(m.field_32_58, 58); + modify_field(m.field_32_59, 59); + modify_field(m.field_32_60, 60); + modify_field(m.field_32_61, 61); + modify_field(m.field_32_62, 62); + modify_field(m.field_32_63, 63); + modify_field(m.field_32_64, 64); +#endif +} + +table t1 { + actions { + a1; + } +} + +action a2_1() { + modify_field(m.field_16_01, 1); + modify_field(m.field_16_02, 2); + modify_field(m.field_16_03, 3); + modify_field(m.field_16_04, 4); + modify_field(m.field_16_05, 5); + modify_field(m.field_16_06, 6); + modify_field(m.field_16_07, 7); + modify_field(m.field_16_08, 8); + modify_field(m.field_16_09, 9); + modify_field(m.field_16_10, 10); + modify_field(m.field_16_11, 11); + modify_field(m.field_16_12, 12); + modify_field(m.field_16_13, 13); + modify_field(m.field_16_14, 14); + modify_field(m.field_16_15, 15); + modify_field(m.field_16_16, 16); + modify_field(m.field_16_17, 17); + modify_field(m.field_16_18, 18); + modify_field(m.field_16_19, 19); + modify_field(m.field_16_20, 20); + modify_field(m.field_16_21, 21); + modify_field(m.field_16_22, 22); + modify_field(m.field_16_23, 23); + modify_field(m.field_16_24, 24); + modify_field(m.field_16_25, 25); + modify_field(m.field_16_26, 26); + modify_field(m.field_16_27, 27); + modify_field(m.field_16_28, 28); + modify_field(m.field_16_29, 29); + modify_field(m.field_16_30, 30); + modify_field(m.field_16_31, 31); + modify_field(m.field_16_32, 32); + modify_field(m.field_16_33, 33); + modify_field(m.field_16_34, 34); + modify_field(m.field_16_35, 35); + modify_field(m.field_16_36, 36); + modify_field(m.field_16_37, 37); + modify_field(m.field_16_38, 38); + modify_field(m.field_16_39, 39); + modify_field(m.field_16_40, 40); + modify_field(m.field_16_41, 41); + modify_field(m.field_16_42, 42); + modify_field(m.field_16_43, 43); + modify_field(m.field_16_44, 44); + modify_field(m.field_16_45, 45); + modify_field(m.field_16_46, 46); + modify_field(m.field_16_47, 47); + modify_field(m.field_16_48, 48); +} + +table t2_1 { + reads { + m.field_8_01 : exact; + m.field_8_02 : exact; + m.field_8_03 : exact; + m.field_8_04 : exact; + m.field_8_05 : exact; + m.field_8_06 : exact; + m.field_8_07 : exact; + m.field_8_08 : exact; + m.field_8_09 : exact; + m.field_8_10 : exact; + m.field_8_11 : exact; + m.field_8_12 : exact; + m.field_8_13 : exact; + m.field_8_14 : exact; + m.field_8_15 : exact; + m.field_8_16 : exact; + m.field_8_17 : exact; + m.field_8_18 : exact; + m.field_8_19 : exact; + m.field_8_20 : exact; + m.field_8_21 : exact; + m.field_8_22 : exact; + m.field_8_23 : exact; + m.field_8_24 : exact; + m.field_8_25 : exact; + m.field_8_26 : exact; + m.field_8_27 : exact; + m.field_8_28 : exact; + m.field_8_29 : exact; + m.field_8_30 : exact; + m.field_8_31 : exact; + m.field_8_32 : exact; + m.field_8_33 : exact; + m.field_8_34 : exact; + m.field_8_35 : exact; + m.field_8_36 : exact; + m.field_8_37 : exact; + m.field_8_38 : exact; + m.field_8_39 : exact; + m.field_8_40 : exact; + m.field_8_41 : exact; + m.field_8_42 : exact; + m.field_8_43 : exact; + m.field_8_44 : exact; + m.field_8_45 : exact; + m.field_8_46 : exact; + m.field_8_47 : exact; + m.field_8_48 : exact; + m.field_8_49 : exact; + m.field_8_50 : exact; + m.field_8_51 : exact; + m.field_8_52 : exact; + m.field_8_53 : exact; + m.field_8_54 : exact; + m.field_8_55 : exact; + m.field_8_56 : exact; + m.field_8_57 : exact; + m.field_8_58 : exact; + m.field_8_59 : exact; + m.field_8_60 : exact; + m.field_8_61 : exact; + m.field_8_62 : exact; + m.field_8_63 : exact; + m.field_8_64 : exact; + } + actions { + a2_1; + } +} + +action a2_2() { + modify_field(m.field_16_49, 49); + modify_field(m.field_16_50, 50); + modify_field(m.field_16_51, 51); + modify_field(m.field_16_52, 52); + modify_field(m.field_16_53, 53); + modify_field(m.field_16_54, 54); + modify_field(m.field_16_55, 55); + modify_field(m.field_16_56, 56); + modify_field(m.field_16_57, 57); + modify_field(m.field_16_58, 58); + modify_field(m.field_16_59, 59); + modify_field(m.field_16_60, 60); + modify_field(m.field_16_61, 61); + modify_field(m.field_16_62, 62); + modify_field(m.field_16_63, 63); +} + +table t2_2 { + reads { + m.field_32_01 : exact; + m.field_32_02 : exact; + m.field_32_03 : exact; + m.field_32_04 : exact; + m.field_32_05 : exact; + m.field_32_06 : exact; + m.field_32_07 : exact; + m.field_32_08 : exact; + m.field_32_09 : exact; + m.field_32_10 : exact; + m.field_32_11 : exact; + m.field_32_12 : exact; + m.field_32_13 : exact; + m.field_32_14 : exact; + m.field_32_15 : exact; + m.field_32_16 : exact; + } + actions { + a2_2; + } +} + +action a2_3() { + modify_field(m.field_16_65, 65); + modify_field(m.field_16_66, 66); + modify_field(m.field_16_67, 67); + modify_field(m.field_16_68, 68); + modify_field(m.field_16_69, 69); + modify_field(m.field_16_70, 70); + modify_field(m.field_16_71, 71); + modify_field(m.field_16_72, 72); + modify_field(m.field_16_73, 73); + modify_field(m.field_16_74, 74); + modify_field(m.field_16_75, 75); + modify_field(m.field_16_76, 76); + modify_field(m.field_16_77, 77); + modify_field(m.field_16_78, 78); + modify_field(m.field_16_79, 79); +} + +table t2_3 { + reads { + m.field_32_17 : ternary; + m.field_32_18 : ternary; + m.field_32_19 : ternary; + m.field_32_20 : ternary; + m.field_32_21 : ternary; + m.field_32_22 : ternary; + m.field_32_23 : ternary; + m.field_32_24 : ternary; + m.field_32_25 : ternary; + m.field_32_26 : ternary; + m.field_32_27 : ternary; + m.field_32_28 : ternary; + m.field_32_29 : ternary; + m.field_32_30 : ternary; + m.field_32_31 : ternary; + m.field_32_32 : ternary; + } + actions { + a2_3; + } +} + +action a3_1() { + modify_field(m.field_16_80, 80); + modify_field(m.field_16_81, 81); + modify_field(m.field_16_82, 82); + modify_field(m.field_16_83, 83); + modify_field(m.field_16_84, 84); + modify_field(m.field_16_85, 85); + modify_field(m.field_16_86, 86); + modify_field(m.field_16_87, 87); + modify_field(m.field_16_88, 88); + modify_field(m.field_16_89, 89); + modify_field(m.field_16_90, 90); + modify_field(m.field_16_91, 91); + modify_field(m.field_16_92, 92); + modify_field(m.field_16_93, 93); + modify_field(m.field_16_94, 94); + modify_field(m.field_16_95, 95); + modify_field(m.field_16_96, 96); +} + +table t3_1 { + reads { + m.field_32_33 : exact; + m.field_32_34 : exact; + m.field_32_35 : exact; + m.field_32_36 : exact; + m.field_32_37 : exact; + m.field_32_38 : exact; + m.field_32_39 : exact; + m.field_32_40 : exact; + m.field_32_41 : exact; + m.field_32_42 : exact; + m.field_32_43 : exact; + m.field_32_44 : exact; + m.field_32_45 : exact; + m.field_32_46 : exact; + m.field_32_47 : exact; + m.field_32_48 : exact; + m.field_32_49 : exact; +#if 0 + m.field_32_50 : exact; + m.field_32_51 : exact; + m.field_32_52 : exact; + m.field_32_53 : exact; + m.field_32_54 : exact; + m.field_32_55 : exact; + m.field_32_56 : exact; + m.field_32_57 : exact; + m.field_32_58 : exact; + m.field_32_59 : exact; + m.field_32_60 : exact; + m.field_32_61 : exact; + m.field_32_62 : exact; + m.field_32_63 : exact; + m.field_32_64 : exact; +#endif + } + actions { + a3_1; + } +} + +control ingress { + apply(t1); + + apply(t2_1); + apply(t2_2); + apply(t2_3); + + apply(t3_1); +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/mau/04-FieldProblem.p4 b/backends/tofino/bf-asm/test/mau/04-FieldProblem.p4 new file mode 100644 index 00000000000..138615c8950 --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/04-FieldProblem.p4 @@ -0,0 +1,91 @@ +header_type vag_t { + fields { + f1 : 8; + f2 : 16; + f3 : 32; + } +} + +header vag_t vag; + +parser start { + extract(vag); + return ingress; +} + +header_type ingress_metadata_t { + fields { + f1 : 8; + f2 : 16; + f3 : 32; + } +} + +metadata ingress_metadata_t ing_metadata; + +action nop() { +} + +action set_f1(f1) { + modify_field(ing_metadata.f1, f1); +} + +action set_f2(f2) { + modify_field(ing_metadata.f2, f2); +} + +action set_f3(f3) { + modify_field(ing_metadata.f3, f3); +} + +table i_t1 { + reads { + vag.f1 : exact; + } + actions { + nop; + set_f1; + } + size : 1024; +} + +table i_t2 { + reads { + vag.f2 : exact; + } + actions { + nop; + set_f2; + } + size : 1024; +} + +table i_t3 { + reads { + vag.f3 : exact; + } + actions { + nop; + set_f3; + } + size : 1024; +} + +control ingress { + apply(i_t1); +// apply(i_t2); +// apply(i_t3); +} + +table e_t1 { + reads { + vag.f1 : exact; + } + actions { + nop; + } +} + +control egress { + apply(e_t1); +} diff --git a/backends/tofino/bf-asm/test/mau/07-MacAddrCheck.p4 b/backends/tofino/bf-asm/test/mau/07-MacAddrCheck.p4 new file mode 100644 index 00000000000..076136de13c --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/07-MacAddrCheck.p4 @@ -0,0 +1,52 @@ +#ifdef __TARGET_TOFINO__ +#include +#include +#include +#else +#include "includes/tofino.p4" +#endif + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + ethertype : 16; + } +} + +header ethernet_t ethernet; + +parser start { + extract(ethernet); + return ingress; +} + +header_type ingress_metadata_t { + fields { + drop : 1; + } +} + +metadata ingress_metadata_t ing_metadata; + +action nop() { +} + +action ing_drop() { + drop(); +} + +table bad_mac_drop { + actions { + ing_drop; + } +} + +control ingress { + if (ethernet.srcAddr == ethernet.dstAddr) { + apply(bad_mac_drop); + } +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/mau/08-MacAddrCheck1.p4 b/backends/tofino/bf-asm/test/mau/08-MacAddrCheck1.p4 new file mode 100644 index 00000000000..49b8e6d5375 --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/08-MacAddrCheck1.p4 @@ -0,0 +1,55 @@ +#ifdef __TARGET_TOFINO__ +#include +#include +#include +#else +#include "includes/tofino.p4" +#endif + +header_type ethernet_t { + fields { + dstAddr16 : 16; + dstAddr32 : 32; + srcAddr16 : 16; + srcAddr32 : 32; + ethertype : 16; + } +} + +header ethernet_t ethernet; + +parser start { + extract(ethernet); + return ingress; +} + +header_type ingress_metadata_t { + fields { + drop : 1; + } +} + +metadata ingress_metadata_t ing_metadata; + +action nop() { +} + +action ing_drop() { + drop(); +} + +table bad_mac_drop { + actions { + ing_drop; + } +} + +control ingress { + if ((ethernet.srcAddr16 == ethernet.dstAddr16) and + (ethernet.srcAddr32 == ethernet.dstAddr32)) { + apply(bad_mac_drop); + } +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/mau/08-MultiProtocolIfElse.p4 b/backends/tofino/bf-asm/test/mau/08-MultiProtocolIfElse.p4 new file mode 100644 index 00000000000..53ea59195d7 --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/08-MultiProtocolIfElse.p4 @@ -0,0 +1,199 @@ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type ipv6_t { + fields { + version : 4; + trafficClass : 8; + flowLabel : 20; + payloadLen : 16; + nextHdr : 8; + hopLimit : 8; + srcAddr : 128; + dstAddr : 128; + } +} + +header_type icmp_t { + fields { + typeCode : 16; + hdrChecksum : 16; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 4; + flags : 8; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + length_ : 16; + checksum : 16; + } +} + +header ethernet_t ethernet; +header vlan_tag_t vlan_tag; +header ipv4_t ipv4; +header ipv6_t ipv6; +header tcp_t tcp; +header udp_t udp; +header icmp_t icmp; + +parser start { + extract(ethernet); + return select(latest.etherType) { + 0x8100, 0x9100 : parse_vlan_tag; + 0x0800 : parse_ipv4; + 0x86DD : parse_ipv6; + default : ingress; + } +} + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x0800 : parse_ipv4; + 0x86DD : parse_ipv6; + default : ingress; + } +} + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.ihl, latest.protocol) { + 0x0000501 mask 0x0000fff : parse_icmp; + 0x0000506 mask 0x0000fff : parse_tcp; + 0x0000511 mask 0x0000fff : parse_udp; + default : ingress; + } +} + +parser parse_ipv6 { + extract(ipv6); + return select(latest.nextHdr) { + 0x01 : parse_icmp; + 0x06 : parse_tcp; + 0x11 : parse_udp; + default : ingress; + } +} + +parser parse_icmp { + extract(icmp); + return ingress; +} + +parser parse_tcp { + extract(tcp); + return ingress; +} + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type ingress_metadata_t { + fields { + drop : 1; + egress_port : 8; + packet_type : 4; + } +} + +metadata ingress_metadata_t ing_metadata; + +action nop() { +} + +action set_egress_port(egress_port) { + modify_field(ing_metadata.egress_port, egress_port); +} + +table ipv4_match { + reads { + ipv4.srcAddr : exact; + } + actions { + nop; + set_egress_port; + } +} + +table ipv6_match { + reads { + ipv6.srcAddr : exact; + } + actions { + nop; + set_egress_port; + } +} + +table l2_match { + reads { + ethernet.srcAddr : exact; + } + actions { + nop; + set_egress_port; + } +} + +control ingress { + if (ethernet.etherType == 0x0800) { + apply(ipv4_match); + } else if (ethernet.etherType == 0x86DD) { + apply(ipv6_match); + } else { + apply(l2_match); + } +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/mau/09-MacAddrCheck2.p4 b/backends/tofino/bf-asm/test/mau/09-MacAddrCheck2.p4 new file mode 100644 index 00000000000..07f0b7ca8d8 --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/09-MacAddrCheck2.p4 @@ -0,0 +1,56 @@ +#ifdef __TARGET_TOFINO__ +#include +#include +#include +#else +#include "includes/tofino.p4" +#endif + +header_type ethernet_t { + fields { + dstAddr16 : 16; + dstAddr32 : 32; + srcAddr16 : 16; + srcAddr32 : 32; + ethertype : 16; + } +} + +header ethernet_t ethernet; + +parser start { + extract(ethernet); + return ingress; +} + +header_type ingress_metadata_t { + fields { + drop : 1; + } +} + +metadata ingress_metadata_t ing_metadata; + +action nop() { +} + +action ing_drop() { + drop(); +} + +table bad_mac_drop { + actions { + ing_drop; + } +} + +control ingress { + if (ethernet.srcAddr16 == ethernet.dstAddr16) { + if (ethernet.srcAddr32 == ethernet.dstAddr32) { + apply(bad_mac_drop); + } + } +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/mau/10-AssignChooseSource.p4 b/backends/tofino/bf-asm/test/mau/10-AssignChooseSource.p4 new file mode 100644 index 00000000000..af678b9e46e --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/10-AssignChooseSource.p4 @@ -0,0 +1,100 @@ +#ifdef __TARGET_TOFINO__ +#include +#include +#include +#else +#include "includes/tofino.p4" +#endif + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + ethertype : 16; + } +} + +header ethernet_t ethernet; + +parser start { + extract(ethernet); + return ingress; +} + +header_type ingress_metadata_t { + fields { + flag : 1; + tmp1 : 9; + tmp2 : 9; + egress_port : 9; + } +} + +metadata ingress_metadata_t ing_metadata; + +action set_ingress_port_props(port_type) { + modify_field(ing_metadata.flag, port_type); +} + +table ingress_port_map { + reads { + ig_intr_md.ingress_port : exact; + } + actions { + set_ingress_port_props; + } + size : 288; +} + +action assign_egress_interfaces(value1, value2) { + modify_field(ing_metadata.tmp1, value1); + modify_field(ing_metadata.tmp2, value2); +} + +table dmac { + reads { + ethernet.dstAddr : exact; + } + actions { + assign_egress_interfaces; + } +} + +action assign_egress1_action() { + modify_field(ing_metadata.egress_port, ing_metadata.tmp1); +} + +table assign_egress1 { + actions { + assign_egress1_action; + } +} + +action assign_egress2_action() { + modify_field(ing_metadata.egress_port, ing_metadata.tmp2); +} + +table assign_egress2 { + actions { + assign_egress2_action; + } +} + +control ingress { + if (ig_intr_md.resubmit_flag == 0) { + apply(ingress_port_map); + + apply(dmac) { + assign_egress_interfaces { + if (ing_metadata.flag == 1) { + apply(assign_egress1); + } else { + apply(assign_egress2); + } + } + } + } +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/mau/12-Counters.p4 b/backends/tofino/bf-asm/test/mau/12-Counters.p4 new file mode 100644 index 00000000000..8aaa3513ae9 --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/12-Counters.p4 @@ -0,0 +1,49 @@ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + ethertype : 16; + } +} + +header ethernet_t ethernet; + +parser start { + extract(ethernet); + return ingress; +} + +counter c1 { + type : packets; + instance_count : 1024; +} + +action count_c1_1() { + count(c1, 1); +} + +table t1 { + reads { + ethernet.dstAddr : exact; + } + actions { + count_c1_1; + } +} + +table t2 { + reads { + ethernet.srcAddr : exact; + } + actions { + count_c1_1; + } +} + +control ingress { + apply(t1); + apply(t2); +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/mau/12-SmallToBigFieldWithMask8.p4 b/backends/tofino/bf-asm/test/mau/12-SmallToBigFieldWithMask8.p4 new file mode 100644 index 00000000000..dc3ed584a2f --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/12-SmallToBigFieldWithMask8.p4 @@ -0,0 +1,59 @@ +#ifdef __TARGET_TOFINO__ +#include +#include +#include +#else +#include "includes/tofino.p4" +#endif + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + ethertype : 16; + } +} + +header ethernet_t ethernet; + +parser start { + extract(ethernet); + return ingress; +} + +header_type m1_t { + fields { + f1 : 16; + } +} + +metadata m1_t m1; + +action a1(p1) { + modify_field(m1.f1, p1); +} + +action a2() { + modify_field(ethernet.dstAddr, m1.f1, 0xfffF); + //modify_field(ethernet.dstAddr, m1.f1); +} + +table t1 { + actions { + a1; + } +} + +table t2 { + actions { + a2; + } +} + +control ingress { + apply(t1); + apply(t2); +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/mau/14-Counter.p4 b/backends/tofino/bf-asm/test/mau/14-Counter.p4 new file mode 100644 index 00000000000..eb6d310df68 --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/14-Counter.p4 @@ -0,0 +1,36 @@ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + ethertype : 16; + } +} + +header ethernet_t ethernet; + +parser start { + extract(ethernet); + return ingress; +} + +counter c1 { + type : packets; + instance_count : 1024; +} + +action count_c1_1() { + count(c1, 1); +} + +table t1 { + actions { + count_c1_1; + } +} + +control ingress { + apply(t1); +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/mau/15-MultiProtocolIfElseMinimal.p4 b/backends/tofino/bf-asm/test/mau/15-MultiProtocolIfElseMinimal.p4 new file mode 100644 index 00000000000..3581d584761 --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/15-MultiProtocolIfElseMinimal.p4 @@ -0,0 +1,107 @@ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header ethernet_t ethernet; +header vlan_tag_t vlan_tag; +header ipv4_t ipv4; + +parser start { + extract(ethernet); + return select(latest.etherType) { + 0x8100, 0x9100 : parse_vlan_tag; + 0x0800 : parse_ipv4; + default : ingress; + } +} + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x0800 : parse_ipv4; + default : ingress; + } +} + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +header_type ingress_metadata_t { + fields { + drop : 1; + egress_port : 8; + packet_type : 4; + } +} + +metadata ingress_metadata_t ing_metadata; + +action nop() { +} + +action set_egress_port(egress_port) { + modify_field(ing_metadata.egress_port, egress_port); +} + +table ipv4_match { + reads { + ipv4.srcAddr : exact; + } + actions { + nop; + set_egress_port; + } +} + +table l2_match { + reads { + ethernet.srcAddr : exact; + } + actions { + nop; + set_egress_port; + } +} + +control ingress { + if (ethernet.etherType == 0x0800) { + apply(ipv4_match); + } else { + apply(l2_match); + } +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/mau/16-NoHeaders.p4 b/backends/tofino/bf-asm/test/mau/16-NoHeaders.p4 new file mode 100644 index 00000000000..c409c7cc2ca --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/16-NoHeaders.p4 @@ -0,0 +1,19 @@ +parser start { + return ingress; +} + +action a1() { +} + +table t1 { + actions { + a1; + } +} + +control ingress { + apply(t1); +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/mau/19-SimpleTrill.p4 b/backends/tofino/bf-asm/test/mau/19-SimpleTrill.p4 new file mode 100644 index 00000000000..db1c61cff2c --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/19-SimpleTrill.p4 @@ -0,0 +1,94 @@ +#ifdef __TARGET_TOFINO__ +#include +#include +#include +#else +#include "includes/tofino.p4" +#endif + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + ethertype : 16; + } +} + +header ethernet_t outer_ethernet; +header ethernet_t inner_ethernet; + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vid : 12; + ethertype : 16; + } +} + +header vlan_tag_t vlan_tag; + +header_type trill_t { + fields { + version : 2; + reserved : 2; + multiDestination : 1; + optLength : 5; + hopCount : 6; + egressRbridge : 16; + ingressRbridge : 16; + } +} + +header trill_t trill; + +parser start { + extract(outer_ethernet); + return select(latest.ethertype) { + 0x8100 : parse_vlan_tag; + 0x2222 : parse_trill; + default : ingress; + } +} + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.ethertype) { + 0x2222 : parse_trill; + default : ingress; + } +} + +parser parse_trill { + extract(trill); + extract(inner_ethernet); + return ingress; +} + +/* + * TRILL Forwarding Table + */ +action forward_trill(new_mac_da, new_mac_sa, new_vlan_id, new_port) { + modify_field(outer_ethernet.dstAddr, new_mac_da); + modify_field(outer_ethernet.srcAddr, new_mac_sa); + modify_field(vlan_tag.vid, new_vlan_id); + modify_field(ig_intr_md_for_tm.ucast_egress_port, new_port); + add_to_field(trill.hopCount, -1); +} + +table trill_forward { + reads { + trill.egressRbridge : exact; + } + actions { + forward_trill; + } +} + +control ingress { + apply(trill_forward); +} + + +control egress { +} diff --git a/backends/tofino/bf-asm/test/mau/20-SimpleTrillTwoStep.p4 b/backends/tofino/bf-asm/test/mau/20-SimpleTrillTwoStep.p4 new file mode 100644 index 00000000000..77399460f4f --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/20-SimpleTrillTwoStep.p4 @@ -0,0 +1,115 @@ +#ifdef __TARGET_TOFINO__ +#include +#include +#include +#else +#include "includes/tofino.p4" +#endif + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + ethertype : 16; + } +} + +header ethernet_t outer_ethernet; +header ethernet_t inner_ethernet; + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vid : 12; + ethertype : 16; + } +} + +header vlan_tag_t vlan_tag; + +header_type trill_t { + fields { + version : 2; + reserved : 2; + multiDestination : 1; + optLength : 5; + hopCount : 6; + egressRbridge : 16; + ingressRbridge : 16; + } +} + +header trill_t trill; + +header_type my_metadata_t { + fields { + hopCount : 6 (saturating); + } +} + +metadata my_metadata_t m; + +parser start { + extract(outer_ethernet); + return select(latest.ethertype) { + 0x8100 : parse_vlan_tag; + 0x2222 : parse_trill; + default : ingress; + } +} + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.ethertype) { + 0x2222 : parse_trill; + default : ingress; + } +} + +parser parse_trill { + extract(trill); + //set_metadata(m.hopCount, trill.hopCount); + extract(inner_ethernet); + return ingress; +} + +/* + * TRILL Forwarding Table + */ +action forward_trill(new_mac_da, new_mac_sa, new_vlan_id, new_port) { + modify_field(outer_ethernet.dstAddr, new_mac_da); + modify_field(outer_ethernet.srcAddr, new_mac_sa); + modify_field(vlan_tag.vid, new_vlan_id); + modify_field(ig_intr_md_for_tm.ucast_egress_port, new_port); + add(m.hopCount, trill.hopCount, -1); + //add_to_field(m.hopCount, -1); +} + +table trill_forward { + reads { + trill.egressRbridge : exact; + } + actions { + forward_trill; + } +} + +action copy_hopCount() { + modify_field(trill.hopCount, m.hopCount); +} + +table fix_trill_header { + actions { + copy_hopCount; + } +} + +control ingress { + apply(trill_forward); + apply(fix_trill_header); +} + + +control egress { +} diff --git a/backends/tofino/bf-asm/test/mau/22-BigToSmallFieldWithMask8.p4 b/backends/tofino/bf-asm/test/mau/22-BigToSmallFieldWithMask8.p4 new file mode 100644 index 00000000000..34eca7f4a9b --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/22-BigToSmallFieldWithMask8.p4 @@ -0,0 +1,58 @@ +#ifdef __TARGET_TOFINO__ +#include +#include +#include +#else +#include "includes/tofino.p4" +#endif + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + ethertype : 16; + } +} + +header ethernet_t ethernet; + +parser start { + extract(ethernet); + return ingress; +} + +header_type m1_t { + fields { + f1 : 60; + } +} + +metadata m1_t m1; + +action a1(p1) { + modify_field(m1.f1, p1); +} + +action a2() { + modify_field(ethernet.dstAddr, m1.f1, 0xFF); +} + +table t1 { + actions { + a1; + } +} + +table t2 { + actions { + a2; + } +} + +control ingress { + apply(t1); + apply(t2); +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/mau/22-SimpleTrillThreeStep.p4 b/backends/tofino/bf-asm/test/mau/22-SimpleTrillThreeStep.p4 new file mode 100644 index 00000000000..0cc862aa562 --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/22-SimpleTrillThreeStep.p4 @@ -0,0 +1,124 @@ +#ifdef __TARGET_TOFINO__ +#include +#include +#include +#else +#include "includes/tofino.p4" +#endif + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + ethertype : 16; + } +} + +header ethernet_t outer_ethernet; +header ethernet_t inner_ethernet; + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vid : 12; + ethertype : 16; + } +} + +header vlan_tag_t vlan_tag; + +header_type trill_t { + fields { + version : 2; + reserved : 2; + multiDestination : 1; + optLength : 5; + hopCount : 6; + egressRbridge : 16; + ingressRbridge : 16; + } +} + +header trill_t trill; + +header_type my_metadata_t { + fields { + hopCount : 6; + } +} + +metadata my_metadata_t m; + +parser start { + extract(outer_ethernet); + return select(latest.ethertype) { + 0x8100 : parse_vlan_tag; + 0x2222 : parse_trill; + default : ingress; + } +} + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.ethertype) { + 0x2222 : parse_trill; + default : ingress; + } +} + +parser parse_trill { + extract(trill); + extract(inner_ethernet); + return ingress; +} + +/* + * TRILL Forwarding Table + */ +action forward_trill(new_mac_da, new_mac_sa, new_vlan_id, new_port) { + modify_field(outer_ethernet.dstAddr, new_mac_da); + modify_field(outer_ethernet.srcAddr, new_mac_sa); + modify_field(vlan_tag.vid, new_vlan_id); + modify_field(ig_intr_md_for_tm.ucast_egress_port, new_port); + add_to_field(m.hopCount, -1); +} + +table trill_forward { + reads { + trill.egressRbridge : exact; + } + actions { + forward_trill; + } +} + +action do_copy_hopCount_to_m() { + bit_and(m.hopCount, trill.hopCount, 0x3f); +} + +table copy_hopCount_to_m { + actions { + do_copy_hopCount_to_m; + } +} + +action do_copy_hopCount_from_m() { + modify_field(trill.hopCount, m.hopCount); +} + +table copy_hopCount_from_m { + actions { + do_copy_hopCount_from_m; + } +} + +control ingress { + apply(copy_hopCount_to_m); + apply(trill_forward); + apply(copy_hopCount_from_m); +} + + +control egress { +} diff --git a/backends/tofino/bf-asm/test/mau/action_params.p4 b/backends/tofino/bf-asm/test/mau/action_params.p4 new file mode 100644 index 00000000000..3f185f0814f --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/action_params.p4 @@ -0,0 +1,136 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type pkt_t { + fields { + field_a_32 : 32; + field_b_32 : 32; + field_c_32 : 32; + field_d_32 : 32; + + field_e_16 : 16; + field_f_16 : 16; + field_g_16 : 16; + field_h_16 : 16; + field_i_16 : 16; + field_j_16 : 16; + field_k_16 : 16; + + field_i_8 : 8; + field_j_8 : 8; + color_0 : 4; + pad_0 : 4; + color_1 : 8; + color_2 : 8; + color_3 : 8; + } +} + +parser start { + return parse_ethernet; +} + +header pkt_t pkt; + +parser parse_ethernet { + extract(pkt); + return ingress; +} + + +action action_0(param0){ + modify_field(pkt.field_f_16, param0); +} + +//action action_1(param0){ +// modify_field(pkt.field_g_16, param0); +//} + +action action_1(param0, param1, param2){ + modify_field(pkt.field_g_16, param0); + modify_field(pkt.field_i_16, param1); + modify_field(pkt.field_j_16, param2); +} + +//action action_2(param0){ +// modify_field(pkt.field_h_16, param0); +//} + +action action_2(param0, param1, param2){ + modify_field(pkt.field_h_16, param0); + modify_field(pkt.field_i_16, param1); + modify_field(pkt.field_j_16, param2); +} + +action action_3(param0){ + modify_field(pkt.field_k_16, param0); +} + + +action do_nothing(){ + no_op(); +} + +@pragma table_counter gateway_hit +table table_0 { + reads { + pkt.field_e_16 : ternary; + } + actions { + do_nothing; + } + size : 4096; +} + +@pragma table_counter table_miss +table table_1 { + reads { + pkt.field_e_16: exact; + pkt.field_f_16 mask 0xffff : exact; + } + actions { + do_nothing; + + } + default_action : action_1(0xffff,0xdead,0xbeef); + //default_action : action_1(0xf); + size : 16384; +} + +@pragma table_counter table_hit +table table_2 { + reads { + pkt.field_f_16: ternary; + } + actions { + do_nothing; + + } + //default_action: do_nothing; + default_action : action_2(0x1111, 0x2222, 0x3333); + size : 2048; +} + +table table_3 { + reads { + pkt.field_k_16: ternary; + } + actions { + do_nothing; + + } + default_action : action_3(0xf); + size : 2048; +} + +/* Main control flow */ + +control ingress { + if (valid(pkt)){ + apply(table_0); + } else { + apply(table_1); + } + apply(table_2); + apply(table_3); +} diff --git a/backends/tofino/bf-asm/test/mau/basic_ipv4_selection.p4 b/backends/tofino/bf-asm/test/mau/basic_ipv4_selection.p4 new file mode 100644 index 00000000000..6e72baf4428 --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/basic_ipv4_selection.p4 @@ -0,0 +1,215 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +header_type ingress_metadata_t { + fields { + port: 16; + } +} + +metadata ingress_metadata_t /*metadata*/ ingress_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm: csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + + +/* Main control flow */ +control ingress { + apply(ipv4_routing_select_2); +} + + +control egress { +// apply(egress_acl); +} + +field_list ecmp_hash_fields { + ipv4.srcAddr; + ipv4.dstAddr; + ipv4.identification; + ipv4.protocol; +} + + +field_list_calculation ecmp_hash { + input { + ecmp_hash_fields; + } + algorithm : crc16; + output_width : 14; +} + + +table ipv4_routing_select_2 { + reads { + ipv4.dstAddr: lpm; + } + action_profile : ecmp_action_profile; + size : 512; +} + +action_profile ecmp_action_profile { + actions { + nhop_set; + nop; + } + size : 4096; + // optional + dynamic_action_selection : ecmp_selector; +} + +action_selector ecmp_selector { + selection_key : ecmp_hash; // take a field_list_calculation only + // optional + selection_mode : fair; // “resilient” or “non-resilient” +} + +action nhop_set(port) { + modify_field(ipv4.identification, port); +} diff --git a/backends/tofino/bf-asm/test/mau/do_nothing.p4 b/backends/tofino/bf-asm/test/mau/do_nothing.p4 new file mode 100644 index 00000000000..66208821fe0 --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/do_nothing.p4 @@ -0,0 +1,36 @@ +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return ingress; +} + +action action_0(){ + no_op(); +} + +table table_0 { + reads { + ethernet.etherType : ternary; + } + actions { + action_0; + } +} + +control ingress { + apply(table_0); +} diff --git a/backends/tofino/bf-asm/test/mau/expected_failures.txt b/backends/tofino/bf-asm/test/mau/expected_failures.txt new file mode 100644 index 00000000000..bde2b0e514e --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/expected_failures.txt @@ -0,0 +1,111 @@ +test_config_96_hash_data.p4 bfas + - incorrect asm code for hash_action+counter +test_config_101_switch_msdc.p4 compile + - compiler uses tcam byte swizzler to duplicate 8-bit phv, rather than just loading it directly +test_config_120_tcam_range_4.p4 mismatch + - compiler uses tcam byte swizzler to duplicate 8-bit phv, rather than just loading it directly +test_config_132_meter_pre_color_4.p4 bfas + - compiler uses tcam byte swizzler to duplicate 8-bit phv, rather than just loading it directly +test_config_136_tcam_error_detection.p4 mismatch +test_config_137_tcam_error_detection_2.p4 mismatch +test_config_138_tcam_error_detection_3.p4 mismatch +test_config_139_tcam_error_detection_4.p4 mismatch + +14-Counter.p4 bfas +- invalid asm refers to stat_ptr but doesn't define it. + +test_config_91_gateway_with_split_table.p4 mismatch +- action table split at 8 rows instead of 10? + +debug_issue_3_7_way_table.p4 mismatch +dileep.p4 mismatch +dileep2.p4 mismatch +dileep4.p4 mismatch +test_config_85_table_ordering.p4 mismatch +test_config_97_unrelated_tables.p4 mismatch +test_config_103_first_phase_0.p4 mismatch +- data duplicated on ixbar; assembler always uses first copy in byteswizzle + +12-SmallToBigFieldWithMask8.p4 mismatch +22-BigToSmallFieldWithMask8.p4 mismatch +action_params.p4 mismatch +test_config_114_simple_drop.p4 mismatch +test_config_130_test_default_action.p4 mismatch +test_config_140_table_counter.p4 mismatch +test_config_182_warp_primitive.p4 mismatch +test_config_208_table_no_key.p4 mismatch +test_config_25_no_reads_for_table.p4 mismatch +- missing default_action.allowed_to_be_default_action in context.json + +- uncharacterized failures (FIXME) +01-FlexCounter.p4 compile +02-FlexCounterActionProfile.p4 compile +07-MacAddrCheck.p4 compile +08-MacAddrCheck1.p4 compile +12-Counters.p4 compile +19-SimpleTrill.p4 compile +22-SimpleTrillThreeStep.p4 compile + +dileep10.p4 mismatch +dileep11.p4 mismatch +dileep12.p4 mismatch +dileep8.p4 mismatch +test_config_10_new_crossbar_allocation.p4 compile +test_config_13_first_selection.p4 compile +test_config_78_tcam_with_220_bits_high_nibble_and_version.p4 mismatch +test_config_93_push_and_pop.p4 compile +test_config_100_hash_action.p4 bfas +test_config_123_meter_2.p4 bfas +test_config_124_meter_3.p4 bfas +test_config_125_meter_pre_color.p4 bfas +test_config_126_meter_pre_color_2.p4 bfas +test_config_127_meter_pre_color_3.p4 bfas +test_config_142_stateful_bfd.p4 compile +test_config_148_action_profile.p4 mismatch +test_config_152_stateful_simple_cntr.p4 mismatch +test_config_153_stateful_simple_cntr_with_output.p4 mismatch +test_config_154_stateful_sampling.p4 mismatch +test_config_155_stateful_3_alus.p4 mismatch +test_config_156_indirect_stateful_cntr.p4 mismatch +test_config_157_random_number_generator.p4 bfas +test_config_159_stateful_using_phv_field.p4 mismatch +test_config_160_stateful_single_bit_mode.p4 mismatch +test_config_161_new_primitives.p4 mismatch +test_config_163_stateful_table_math_unit.p4 mismatch +test_config_164_stateful_deterministic_sampling.p4 mismatch +test_config_165_stateful_bfd_failure_detection.p4 mismatch +test_config_166_stateful_generic_counter.p4 mismatch +test_config_167_stateful_flowlet_switching.p4 compile +test_config_168_meter_bug.p4 mismatch +test_config_169_stateful_sflow_sequence.p4 bfas +test_config_170_stateful_selection_table_update.p4 mismatch +test_config_171_stateful_conga.p4 compile +test_config_172_stateful_heavy_hitter.p4 bfas +test_config_173_stateful_bloom_filter.p4 compile +test_config_175_match_table_with_no_key.p4 mismatch +test_config_177_meter_test.p4 bfas +test_config_180_first_proxy_hash.p4 mismatch +test_config_181_first_alg_tcam.p4 bfas +test_config_183_sample_e2e.p4 compile +test_config_184_stateful_bug1.p4 bfas +test_config_185_first_lpf.p4 mismatch +test_config_187_proxy_hash_2.p4 mismatch +test_config_189_stat_with_lrt.p4 mismatch +test_config_190_modify_with_expr.p4 compile +test_config_191_invalidate.p4 mismatch +test_config_192_stateful_driven_by_hash.p4 bfas +test_config_193_indirect_stats_no_reads.p4 bfas +test_config_195_stateful_predicate_output.p4 mismatch +test_config_196_hit_miss.p4 mismatch +test_config_197_default_next_table.p4 mismatch +test_config_198_shared_action_profile.p4 mismatch +test_config_199_stateful_constant_index.p4 bfas +test_config_200_counter_constant_index.p4 mismatch +test_config_201_meter_constant_index.p4 bfas +test_config_203_first_reduction_or.p4 mismatch +test_config_204_no_tables_in_stage0.p4 mismatch +test_config_205_modify_field_from_hash.p4 compile +test_config_206_stateful_logging.p4 bfas +test_config_209_pack_hash_dist.p4 mismatch +vk_basic_ipv4_20150706.p4 mismatch +vk_basic_ipv4_subset.p4 mismatch diff --git a/backends/tofino/bf-asm/test/mau/instruct1.p4 b/backends/tofino/bf-asm/test/mau/instruct1.p4 new file mode 100644 index 00000000000..e0f12c83018 --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/instruct1.p4 @@ -0,0 +1,61 @@ + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; +header_type data2_t { + fields { + x1 : 16; + x2 : 16; + } +} +header data2_t hdr1; +header data2_t hdr2; + +parser start { + extract(data); + return select(data.b1) { + 0x00: parse_data2; + default: ingress; + } +} +parser parse_data2 { + extract(hdr1); + return select(hdr1.x1) { + 1 mask 1: parse_hdr2; + default: ingress; + } +} +parser parse_hdr2 { + extract(hdr2); + return ingress; +} + +action noop() { } +action decap() { + copy_header(hdr1, hdr2); + remove_header(hdr2); +} + +table test1 { + reads { + data.f1 : exact; + } + actions { + decap; + noop; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/mau/selector1.p4 b/backends/tofino/bf-asm/test/mau/selector1.p4 new file mode 100644 index 00000000000..6482f718ab2 --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/selector1.p4 @@ -0,0 +1,60 @@ +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +field_list sel_fields { + data.f1; + data.f2; + data.f3; + data.f4; +} + +field_list_calculation sel_hash { + input { + sel_fields; + } + algorithm : crc16; + output_width : 16; +} + +action_selector sel { + selection_key : sel_hash; + selection_mode : fair; +} + +action noop(param0) { modify_field(data.b1, param0); } + +action_profile sel_profile { + actions { + noop; + } + size : 16384; + dynamic_action_selection : sel; +} + +table test1 { + reads { + data.b1 : exact; + } + action_profile : sel_profile; + size : 1024; +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/mau/ternary_match0.p4 b/backends/tofino/bf-asm/test/mau/ternary_match0.p4 new file mode 100644 index 00000000000..df0c0f900c0 --- /dev/null +++ b/backends/tofino/bf-asm/test/mau/ternary_match0.p4 @@ -0,0 +1,34 @@ + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } + +table test1 { + reads { + data.f1 : ternary; + } + actions { + noop; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/meter_test1.p4 b/backends/tofino/bf-asm/test/meter_test1.p4 new file mode 100644 index 00000000000..26af0800d1b --- /dev/null +++ b/backends/tofino/bf-asm/test/meter_test1.p4 @@ -0,0 +1,69 @@ +header_type data_t { + fields { + f1 : 32; + f2 : 32; + h1 : 16; + h2 : 16; + h3 : 16; + h4 : 16; + h5 : 16; + h6 : 16; + color_1 : 8; + color_2 : 8; + } +} + +header data_t data; +parser start { + extract (data); + return ingress; +} + +action h1_3(val1, val2, val3) { + modify_field(data.h1, val1); + modify_field(data.h2, val2); + modify_field(data.h3, val3); +} + +action h4_6(val4, val5, val6, port) { + modify_field(data.h4, val4); + modify_field(data.h5, val5); + modify_field(data.h6, val6); + modify_field(standard_metadata.egress_spec, port); +} + + +meter meter_1 { + type : bytes; + direct : test1; + result : data.color_1; +} + +meter meter_2 { + type : bytes; + direct : test2; + result : data.color_2; +} + +table test1 { + reads { + data.f1 : exact; + } actions { + h1_3; + } + size : 6000; +} + +table test2 { + reads { + data.f2 : exact; + } actions { + h4_6; + } + size : 10000; +} + +control ingress { + apply(test1); + apply(test2); +} diff --git a/backends/tofino/bf-asm/test/parser1.p4 b/backends/tofino/bf-asm/test/parser1.p4 new file mode 100644 index 00000000000..8cc97cb8313 --- /dev/null +++ b/backends/tofino/bf-asm/test/parser1.p4 @@ -0,0 +1,154 @@ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + +header_type mpls_t { + fields { + label : 20; + tc : 3; + bos : 1; + ttl : 8; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +parser start { + return parse_ethernet; +} + +#define ETHERTYPE_CPU 0x9000, 0x010c +#define ETHERTYPE_VLAN 0x8100, 0x9100, 0x9200, 0x9300 +#define ETHERTYPE_MPLS 0x8847 +#define ETHERTYPE_IPV4 0x0800 +#define ETHERTYPE_IPV6 0x86dd +#define ETHERTYPE_ARP 0x0806 +#define ETHERTYPE_RARP 0x8035 +#define ETHERTYPE_NSH 0x894f +#define ETHERTYPE_ETHERNET 0x6558 +#define ETHERTYPE_ROCE 0x8915 +#define ETHERTYPE_FCOE 0x8906 +/* missing: vlan_3b, vlan_5b, ieee802_1q, ieee802_1ad */ + +#define IPV4_MULTICAST_MAC 0x01005E +#define IPV6_MULTICAST_MAC 0x3333 + +/* Tunnel types */ +#define TUNNEL_TYPE_NONE 0 +#define TUNNEL_TYPE_VXLAN 1 +#define TUNNEL_TYPE_GRE 2 +#define TUNNEL_TYPE_GENEVE 3 +#define TUNNEL_TYPE_NVGRE 4 +#define TUNNEL_TYPE_MPLS 5 + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + ETHERTYPE_VLAN : parse_vlan; + ETHERTYPE_MPLS : parse_mpls; + ETHERTYPE_IPV4 : parse_ipv4; + default: ingress; + } +} + +#define VLAN_DEPTH 2 +header vlan_tag_t vlan_tag_[VLAN_DEPTH]; + +parser parse_vlan { + extract(vlan_tag_[next]); + return select(latest.etherType) { + ETHERTYPE_VLAN : parse_vlan; + ETHERTYPE_MPLS : parse_mpls; + ETHERTYPE_IPV4 : parse_ipv4; + default: ingress; + } +} + +#define MPLS_DEPTH 3 +/* all the tags but the last one */ +header mpls_t mpls[MPLS_DEPTH]; + +/* last mpls tag in the stack */ +header mpls_t mpls_bos; + +/* TODO: this will be optimized when pushed to the chip ? */ + +parser parse_mpls { + return select(current(23, 1)) { + 0 : parse_mpls_not_bos; + 1 : parse_mpls_bos; + default: ingress; + } +} + +parser parse_mpls_not_bos { + extract(mpls[next]); + return parse_mpls; +} + +parser parse_mpls_bos { + extract(mpls_bos); + return select(current(0, 4)) { + 0x4 : parse_ipv4; + default : ingress; + } +} + +#define IP_PROTOCOLS_ICMP 1 +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 +#define IP_PROTOCOLS_GRE 47 +#define IP_PROTOCOLS_IPSEC_ESP 50 +#define IP_PROTOCOLS_IPSEC_AH 51 +#define IP_PROTOCOLS_ICMPV6 58 +#define IP_PROTOCOLS_SCTP 132 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +action do_noop() { } + +table do_nothing { + reads { + ethernet.dstAddr : exact; + } + actions { + do_noop; + } +} + +control ingress { apply(do_nothing); } diff --git a/backends/tofino/bf-asm/test/parser2.p4 b/backends/tofino/bf-asm/test/parser2.p4 new file mode 100644 index 00000000000..575c533cc66 --- /dev/null +++ b/backends/tofino/bf-asm/test/parser2.p4 @@ -0,0 +1,255 @@ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + +header_type mpls_t { + fields { + label : 20; + tc : 3; + bos : 1; + ttl : 8; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type ipv6_t { + fields { + version : 4; + trafficClass : 8; + flowLabel : 20; + payloadLen : 16; + nextHdr : 8; + hopLimit : 8; + srcAddr : 128; + dstAddr : 128; + } +} + +header_type icmp_t { + fields { + type_ : 8; + code : 8; + hdrChecksum : 16; + } +} + +header_type icmpv6_t { + fields { + type_ : 8; + code : 8; + hdrChecksum : 16; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 4; + flags : 8; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + length_ : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +#define ETHERTYPE_CPU 0x9000, 0x010c +#define ETHERTYPE_VLAN 0x8100, 0x9100, 0x9200, 0x9300 +#define ETHERTYPE_MPLS 0x8847 +#define ETHERTYPE_IPV4 0x0800 +#define ETHERTYPE_IPV6 0x86dd +#define ETHERTYPE_ARP 0x0806 +#define ETHERTYPE_RARP 0x8035 +#define ETHERTYPE_NSH 0x894f +#define ETHERTYPE_ETHERNET 0x6558 +#define ETHERTYPE_ROCE 0x8915 +#define ETHERTYPE_FCOE 0x8906 +/* missing: vlan_3b, vlan_5b, ieee802_1q, ieee802_1ad */ + +#define IPV4_MULTICAST_MAC 0x01005E +#define IPV6_MULTICAST_MAC 0x3333 + +/* Tunnel types */ +#define TUNNEL_TYPE_NONE 0 +#define TUNNEL_TYPE_VXLAN 1 +#define TUNNEL_TYPE_GRE 2 +#define TUNNEL_TYPE_GENEVE 3 +#define TUNNEL_TYPE_NVGRE 4 +#define TUNNEL_TYPE_MPLS 5 + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + ETHERTYPE_VLAN : parse_vlan; + ETHERTYPE_MPLS : parse_mpls; + ETHERTYPE_IPV4 : parse_ipv4; + ETHERTYPE_IPV6 : parse_ipv6; + default: ingress; + } +} + +#define VLAN_DEPTH 2 +header vlan_tag_t vlan_tag_[VLAN_DEPTH]; + +parser parse_vlan { + extract(vlan_tag_[next]); + return select(latest.etherType) { + ETHERTYPE_VLAN : parse_vlan; + ETHERTYPE_MPLS : parse_mpls; + ETHERTYPE_IPV4 : parse_ipv4; + ETHERTYPE_IPV6 : parse_ipv6; + default: ingress; + } +} + +#define MPLS_DEPTH 3 +/* all the tags but the last one */ +header mpls_t mpls[MPLS_DEPTH]; + +/* last mpls tag in the stack */ +header mpls_t mpls_bos; + +/* TODO: this will be optimized when pushed to the chip ? */ + +parser parse_mpls { + return select(current(23, 1)) { + 0 : parse_mpls_not_bos; + 1 : parse_mpls_bos; + default: ingress; + } +} + +parser parse_mpls_not_bos { + extract(mpls[next]); + return parse_mpls; +} + +parser parse_mpls_bos { + extract(mpls_bos); + return select(current(0, 4)) { + 0x4 : parse_ipv4; + 0x6 : parse_ipv6; + default : ingress; + } +} + +#define IP_PROTOCOLS_ICMP 1 +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 +#define IP_PROTOCOLS_GRE 47 +#define IP_PROTOCOLS_IPSEC_ESP 50 +#define IP_PROTOCOLS_IPSEC_AH 51 +#define IP_PROTOCOLS_ICMPV6 58 +#define IP_PROTOCOLS_SCTP 132 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_ICMP : parse_icmp; + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header ipv6_t ipv6; + +parser parse_ipv6 { + extract(ipv6); + return select(latest.nextHdr) { + IP_PROTOCOLS_ICMPV6 : parse_icmpv6; + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header icmp_t icmp; + +parser parse_icmp { + extract(icmp); + return ingress; +} + +header icmpv6_t icmpv6; + +parser parse_icmpv6 { + extract(icmpv6); + return ingress; +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +action do_noop() { } + +table do_nothing { + reads { + ethernet.dstAddr : exact; + } + actions { + do_noop; + } +} + +control ingress { apply(do_nothing); } diff --git a/backends/tofino/bf-asm/test/parser3.p4 b/backends/tofino/bf-asm/test/parser3.p4 new file mode 100644 index 00000000000..fd743ba43ae --- /dev/null +++ b/backends/tofino/bf-asm/test/parser3.p4 @@ -0,0 +1,63 @@ + +header_type data1_t { + fields { + f1 : 32; + x1 : 2; + x2 : 4; + x3 : 4; + x4 : 4; + x5 : 2; + x6 : 5; + x7 : 2; + x8 : 1; + } +} +header data1_t data1; +header_type data2_t { + fields { + a1 : 8; + a2 : 4; + a3 : 4; + a4 : 8; + a5 : 4; + a6 : 4; + } +} +header data2_t data2; +#if 0 +header_type data3_t { + fields { + b1 : 13; + b2 : 3; + } +} +header data3_t data3; +#endif + +parser start { + extract(data1); + return select(data1.x3, data1.x1, data1.x7) { + 0xe4: parse_data2; + default: ingress; + } +} + +parser parse_data2 { + extract(data2); + return ingress; +} + +action noop() { } + +table test1 { + reads { + data1.f1 : exact; + } + actions { + noop; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/parser_dc_full.p4 b/backends/tofino/bf-asm/test/parser_dc_full.p4 new file mode 100644 index 00000000000..6c33dcf0139 --- /dev/null +++ b/backends/tofino/bf-asm/test/parser_dc_full.p4 @@ -0,0 +1,959 @@ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type snap_header_t { + fields { + dsap : 8; + ssap : 8; + control_ : 8; + oui : 24; + type_ : 16; + } +} + +header_type roce_header_t { + fields { + ib_grh : 320; + ib_bth : 96; + } +} + +header_type roce_v2_header_t { + fields { + ib_bth : 96; + } +} + +header_type fcoe_header_t { + fields { + version : 4; + type_ : 4; + sof : 8; + rsvd1 : 32; + ts_upper : 32; + ts_lower : 32; + size_ : 32; + eof : 8; + rsvd2 : 24; + } +} + +header_type cpu_header_t { + fields { + qid : 3; + pad : 1; + reason_code : 12; + rxhash : 16; + bridge_domain : 16; + ingress_lif : 16; + egress_lif : 16; + lu_bypass_ingress : 1; + lu_bypass_egress : 1; + pad1 : 14; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + +header_type vlan_tag_3b_t { + fields { + pcp : 3; + cfi : 1; + vid : 4; + etherType : 16; + } +} +header_type vlan_tag_5b_t { + fields { + pcp : 3; + cfi : 1; + vid : 20; + etherType : 16; + } +} + +header_type ieee802_1ah_t { + fields { + pcp : 3; + dei : 1; + uca : 1; + reserved : 3; + i_sid : 24; + } +} + +header_type mpls_t { + fields { + label : 20; + tc : 3; + bos : 1; + ttl : 8; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type ipv6_t { + fields { + version : 4; + trafficClass : 8; + flowLabel : 20; + payloadLen : 16; + nextHdr : 8; + hopLimit : 8; + srcAddr : 128; + dstAddr : 128; + } +} + +header_type icmp_t { + fields { + type_ : 8; + code : 8; + hdrChecksum : 16; + } +} + +header_type icmpv6_t { + fields { + type_ : 8; + code : 8; + hdrChecksum : 16; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 4; + flags : 8; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + length_ : 16; + checksum : 16; + } +} + +header_type sctp_t { + fields { + srcPort : 16; + dstPort : 16; + verifTag : 32; + checksum : 32; + } +} + +header_type gre_t { + fields { + C : 1; + R : 1; + K : 1; + S : 1; + s : 1; + recurse : 3; + flags : 5; + ver : 3; + proto : 16; + } +} + +header_type nvgre_t { + fields { + tni : 24; + reserved : 8; + } +} + +/* 8 bytes */ +header_type erspan_header_v1_t { + fields { + version : 4; + vlan : 12; + priority : 6; + span_id : 10; + direction : 8; + truncated: 8; + } +} + +/* 8 bytes */ +header_type erspan_header_v2_t { + fields { + version : 4; + vlan : 12; + priority : 6; + span_id : 10; + unknown7 : 32; + } +} + +header_type ipsec_esp_t { + fields { + spi : 32; + seqNo : 32; + } +} + +header_type ipsec_ah_t { + fields { + nextHdr : 8; + length_ : 8; + zero : 16; + spi : 32; + seqNo : 32; + } +} + +header_type arp_rarp_t { + fields { + hwType : 16; + protoType : 16; + hwAddrLen : 8; + protoAddrLen : 8; + opcode : 16; + } +} + +header_type arp_rarp_ipv4_t { + fields { + srcHwAddr : 48; + srcProtoAddr : 32; + dstHwAddr : 48; + dstProtoAddr : 32; + } +} + +header_type eompls_t { + fields { + zero : 4; + reserved : 12; + seqNo : 16; + } +} + +header_type vxlan_t { + fields { + flags : 8; + reserved : 24; + vni : 24; + reserved2 : 8; + } +} + +header_type nsh_t { + fields { + oam : 1; + context : 1; + flags : 6; + reserved : 8; + protoType: 16; + spath : 24; + sindex : 8; + } +} + +header_type nsh_context_t { + fields { + network_platform : 32; + network_shared : 32; + service_platform : 32; + service_shared : 32; + } +} + +/* GENEVE HEADERS + 3 possible options with known type, known length */ + +header_type genv_t { + fields { + ver : 2; + optLen : 6; + oam : 1; + critical : 1; + reserved : 6; + protoType : 16; + vni : 24; + reserved2 : 8; + } +} + +#define GENV_OPTION_A_TYPE 0x000001 +/* TODO: Would it be convenient to have some kind of sizeof macro ? */ +#define GENV_OPTION_A_LENGTH 2 /* in bytes */ + +header_type genv_opt_A_t { + fields { + optClass : 16; + optType : 8; + reserved : 3; + optLen : 5; + data : 32; + } +} + +#define GENV_OPTION_B_TYPE 0x000002 +#define GENV_OPTION_B_LENGTH 3 /* in bytes */ + +header_type genv_opt_B_t { + fields { + optClass : 16; + optType : 8; + reserved : 3; + optLen : 5; + data : 64; + } +} + +#define GENV_OPTION_C_TYPE 0x000003 +#define GENV_OPTION_C_LENGTH 2 /* in bytes */ + +header_type genv_opt_C_t { + fields { + optClass : 16; + optType : 8; + reserved : 3; + optLen : 5; + data : 32; + } +} +parser start { + return parse_input_port; +} + +header_type input_port_hdr_t { + fields { + port : 16; + } +} + +header input_port_hdr_t input_port_hdr; + +parser parse_input_port { + extract (input_port_hdr); + return parse_ethernet; +} + +#define ETHERTYPE_CPU 0x9000, 0x010c +#define ETHERTYPE_VLAN 0x8100, 0x9100, 0x9200, 0x9300 +#define ETHERTYPE_MPLS 0x8847 +#define ETHERTYPE_IPV4 0x0800 +#define ETHERTYPE_IPV6 0x86dd +#define ETHERTYPE_ARP 0x0806 +#define ETHERTYPE_RARP 0x8035 +#define ETHERTYPE_NSH 0x894f +#define ETHERTYPE_ETHERNET 0x6558 +#define ETHERTYPE_ROCE 0x8915 +#define ETHERTYPE_FCOE 0x8906 +/* missing: vlan_3b, vlan_5b, ieee802_1q, ieee802_1ad */ + +#define IPV4_MULTICAST_MAC 0x01005E +#define IPV6_MULTICAST_MAC 0x3333 + +/* Tunnel types */ +#define TUNNEL_TYPE_NONE 0 +#define TUNNEL_TYPE_VXLAN 1 +#define TUNNEL_TYPE_GRE 2 +#define TUNNEL_TYPE_GENEVE 3 +#define TUNNEL_TYPE_NVGRE 4 +#define TUNNEL_TYPE_MPLS 5 + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0 mask 0xf800: parse_snap_header; /* < 1536 */ + ETHERTYPE_CPU : parse_cpu_header; + ETHERTYPE_VLAN : parse_vlan; + ETHERTYPE_MPLS : parse_mpls; + ETHERTYPE_IPV4 : parse_ipv4; + ETHERTYPE_IPV6 : parse_ipv6; + ETHERTYPE_ARP : parse_arp_rarp; + ETHERTYPE_RARP : parse_arp_rarp; + ETHERTYPE_NSH : parse_nsh; + ETHERTYPE_ROCE: parse_roce; + ETHERTYPE_FCOE: parse_fcoe; + default: ingress; + } +} + +header snap_header_t snap_header; + +parser parse_snap_header { + extract(snap_header); + return ingress; +} + +header roce_header_t roce; + +parser parse_roce { + extract(roce); + return ingress; +} + +header fcoe_header_t fcoe; + +parser parse_fcoe { + extract(fcoe); + return ingress; +} + +header cpu_header_t cpu_header; + +parser parse_cpu_header { + extract(cpu_header); + return select(latest.etherType) { + 0 mask 0xf800: parse_snap_header; /* < 1536 */ + ETHERTYPE_VLAN : parse_vlan; + ETHERTYPE_MPLS : parse_mpls; + ETHERTYPE_IPV4 : parse_ipv4; + ETHERTYPE_IPV6 : parse_ipv6; + ETHERTYPE_ARP : parse_arp_rarp; + ETHERTYPE_RARP : parse_arp_rarp; + ETHERTYPE_NSH : parse_nsh; + ETHERTYPE_ROCE: parse_roce; + ETHERTYPE_FCOE: parse_fcoe; + default: ingress; + } +} + +#define VLAN_DEPTH 2 +header vlan_tag_t vlan_tag_[VLAN_DEPTH]; +header vlan_tag_3b_t vlan_tag_3b[VLAN_DEPTH]; +header vlan_tag_5b_t vlan_tag_5b[VLAN_DEPTH]; + +parser parse_vlan { + extract(vlan_tag_[next]); + return select(latest.etherType) { + ETHERTYPE_VLAN : parse_vlan; + ETHERTYPE_MPLS : parse_mpls; + ETHERTYPE_IPV4 : parse_ipv4; + ETHERTYPE_IPV6 : parse_ipv6; + ETHERTYPE_ARP : parse_arp_rarp; + ETHERTYPE_RARP : parse_arp_rarp; + default: ingress; + } +} + +#define MPLS_DEPTH 3 +/* all the tags but the last one */ +header mpls_t mpls[MPLS_DEPTH]; + +/* last mpls tag in the stack */ +header mpls_t mpls_bos; + +/* TODO: this will be optimized when pushed to the chip ? */ + +parser parse_mpls { + return select(current(23, 1)) { + 0 : parse_mpls_not_bos; + 1 : parse_mpls_bos; + default: ingress; + } +} + +parser parse_mpls_not_bos { + extract(mpls[next]); + return parse_mpls; +} + +parser parse_mpls_bos { + extract(mpls_bos); + return select(current(0, 4)) { + 0x4 : parse_inner_ipv4; + 0x6 : parse_inner_ipv6; + default : parse_eompls; + } +} + +#define IP_PROTOCOLS_ICMP 1 +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 +#define IP_PROTOCOLS_GRE 47 +#define IP_PROTOCOLS_IPSEC_ESP 50 +#define IP_PROTOCOLS_IPSEC_AH 51 +#define IP_PROTOCOLS_ICMPV6 58 +#define IP_PROTOCOLS_SCTP 132 + +header ipv4_t ipv4; + +field_list ipv4_checksum_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_checksum { + input { + ipv4_checksum_list; + } + algorithm : csum16; + output_width : 16; +} + +calculated_field ipv4.hdrChecksum { +#ifdef __TARGET_TOFINO__ + verify ipv4_checksum; + update ipv4_checksum; +#else + verify ipv4_checksum if(ipv4.ihl == 5); + update ipv4_checksum if(ipv4.ihl == 5); +#endif +} + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_ICMP : parse_icmp; + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + IP_PROTOCOLS_GRE : parse_gre; +// IP_PROTOCOLS_SCTP : parse_sctp; + default: ingress; + } +} + +header ipv6_t ipv6; + +parser parse_ipv6 { + extract(ipv6); + return select(latest.nextHdr) { + IP_PROTOCOLS_ICMPV6 : parse_icmpv6; + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + IP_PROTOCOLS_GRE : parse_gre; +// IP_PROTOCOLS_SCTP : parse_sctp; + default: ingress; + } +} + +header icmp_t icmp; + +parser parse_icmp { + extract(icmp); + return ingress; +} + +header icmpv6_t icmpv6; + +parser parse_icmpv6 { + extract(icmpv6); + return ingress; +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +#define UDP_PORT_VXLAN 4789 +#define UDP_PORT_GENV 6081 +// Check IANA UDP port number + #define UDP_PORT_ROCE_V2 1021 + +header udp_t udp; + +header roce_v2_header_t roce_v2; + +parser parse_roce_v2 { + extract(roce_v2); + return ingress; +} + +parser parse_udp { + extract(udp); + return select(latest.dstPort) { + UDP_PORT_VXLAN : parse_vxlan; + UDP_PORT_GENV: parse_geneve; + UDP_PORT_ROCE_V2: parse_roce_v2; + default: ingress; + } +} + +header sctp_t sctp; + +parser parse_sctp { + extract(sctp); + return ingress; +} + + +#define GRE_PROTOCOLS_NVGRE 0x6558 +#define GRE_PROTOCOLS_GRE 0x6559 +#define GRE_PROTOCOLS_ERSPAN_V1 0x88BE +#define GRE_PROTOCOLS_ERSPAN_V2 0x22EB + +#define GRE_DEPTH 2 + +//header gre_t gre[GRE_DEPTH]; +header gre_t gre; + +#if 0 +header_type gre_opt_t { + fields { + key : 32; + } +} + +header gre_opt_t gre_opt; + +parser parse_gre_key { + extract(gre_opt); + return ingress; +} +parser parse_gre_key2 { + extract(gre_opt); + extract(gre_opt); + return ingress; +} +parser parse_gre_key22 { + extract(gre_opt); + extract(gre_opt); + return ingress; +} +parser parse_gre_opt1 { + extract(gre_opt); + return ingress; +} +parser parse_gre_opt2 { + extract(gre_opt); + extract(gre_opt); + return ingress; +} +parser parse_gre_opt3 { + extract(gre_opt); + extract(gre_opt); + extract(gre_opt); + return ingress; +} + +parser parse_gre_opts { + return select(latest.C, latest.S, latest.K) { + 1 mask 0x0000 : parse_gre_key; + 2 mask 0x0000 : parse_gre_opt1; + 3 mask 0x0000 : parse_gre_key2; + 4 mask 0x0000 : parse_gre_opt1; + 5 mask 0x0000 : parse_gre_key22; + 6 mask 0x0000 : parse_gre_opt2; + 7 mask 0x0000 : parse_gre_opt3; + default: ingress; + } +} +#endif + +parser parse_gre { + extract(gre); +// parse_gre_opts; + return select(latest.K, latest.proto) { + GRE_PROTOCOLS_NVGRE : parse_nvgre; +// GRE_PROTOCOLS_GRE : parse_gre; + GRE_PROTOCOLS_ERSPAN_V1 : parse_erspan_v1; + GRE_PROTOCOLS_ERSPAN_V2 : parse_erspan_v2; + ETHERTYPE_NSH : parse_nsh; + default: ingress; + } +} + +header nvgre_t nvgre; +header ethernet_t inner_ethernet; + +header ipv4_t inner_ipv4; +header ipv6_t inner_ipv6; +header ipv4_t outer_ipv4; +header ipv6_t outer_ipv6; + +field_list inner_ipv4_checksum_list { + inner_ipv4.version; + inner_ipv4.ihl; + inner_ipv4.diffserv; + inner_ipv4.totalLen; + inner_ipv4.identification; + inner_ipv4.flags; + inner_ipv4.fragOffset; + inner_ipv4.ttl; + inner_ipv4.protocol; + inner_ipv4.srcAddr; + inner_ipv4.dstAddr; +} + +field_list_calculation inner_ipv4_checksum { + input { + inner_ipv4_checksum_list; + } + algorithm : csum16; + output_width : 16; +} + +calculated_field inner_ipv4.hdrChecksum { +#ifdef __TARGET_TOFINO__ + verify inner_ipv4_checksum; + update inner_ipv4_checksum; +#else + verify inner_ipv4_checksum if(valid(ipv4)); + update inner_ipv4_checksum if(valid(ipv4)); +#endif +} + +header udp_t outer_udp; + +parser parse_nvgre { + extract(nvgre); + return parse_inner_ethernet; +} + +header erspan_header_v1_t erspan_v1_header; + +parser parse_erspan_v1 { + extract(erspan_v1_header); + return ingress; +} + +header erspan_header_v2_t erspan_v2_header; + +parser parse_erspan_v2 { + extract(erspan_v2_header); + return ingress; +} + +#define ARP_PROTOTYPES_ARP_RARP_IPV4 0x0800 + +header arp_rarp_t arp_rarp; + +parser parse_arp_rarp { + extract(arp_rarp); + return select(latest.protoType) { + ARP_PROTOTYPES_ARP_RARP_IPV4 : parse_arp_rarp_ipv4; + default: ingress; + } +} + +header arp_rarp_ipv4_t arp_rarp_ipv4; + +parser parse_arp_rarp_ipv4 { + extract(arp_rarp_ipv4); + return ingress; +} + +header eompls_t eompls; + +parser parse_eompls { + extract(eompls); + extract(inner_ethernet); + return ingress; +} + +header vxlan_t vxlan; + +parser parse_vxlan { + extract(vxlan); + return parse_inner_ethernet; +} + +header genv_t genv; + +header genv_opt_A_t genv_opt_A; +header genv_opt_B_t genv_opt_B; +header genv_opt_C_t genv_opt_C; + +parser parse_geneve { + extract(genv); + /* + counter_init(counter_1, latest.optLen); + return select(latest.optLen) { + 0 : parse_genv_inner; + default : parse_genv_opts; + } + */ + return parse_genv_inner; +} + +#if 0 + +parser parse_genv_opts { + /* switching on combined class and type */ + return select(current(0, 24)) { + GENV_OPTION_A_TYPE: parse_genv_opt_A; + GENV_OPTION_B_TYPE: parse_genv_opt_B; + GENV_OPTION_C_TYPE: parse_genv_opt_C; + } +} + +parser parse_genv_opt_A { + extract(genv_opt_A); + counter_decrement(counter_1, GENV_OPTION_A_LENGTH); + return select(counter_1) { + 0 : parse_genv_inner; + default : parse_genv_opts; + } +} + +parser parse_genv_opt_B { + extract(genv_opt_B); + counter_decrement(counter_1, GENV_OPTION_B_LENGTH); + return select(counter_1) { + 0 : parse_genv_inner; + default : parse_genv_opts; + } +} + +parser parse_genv_opt_C { + extract(genv_opt_C); + counter_decrement(counter_1, GENV_OPTION_C_LENGTH); + return select(counter_1) { + 0 : parse_genv_inner; + default : parse_genv_opts; + } +} +#endif + +parser parse_genv_inner { + return select(genv.protoType) { + ETHERTYPE_ETHERNET : parse_inner_ethernet; + ETHERTYPE_IPV4 : parse_inner_ipv4; + ETHERTYPE_IPV6 : parse_inner_ipv6; + default : ingress; + } +} + +header nsh_t nsh; +header nsh_context_t nsh_context; + +parser parse_nsh { + extract(nsh); + extract(nsh_context); + return select(nsh.protoType) { + ETHERTYPE_IPV4 : parse_inner_ipv4; + ETHERTYPE_IPV6 : parse_inner_ipv6; + ETHERTYPE_ETHERNET : parse_inner_ethernet; + default: ingress; + } +} + +parser parse_inner_ipv4 { + extract(inner_ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_ICMP : parse_inner_icmp; + IP_PROTOCOLS_TCP : parse_inner_tcp; + IP_PROTOCOLS_UDP : parse_inner_udp; +// IP_PROTOCOLS_SCTP : parse_inner_sctp; + default: ingress; + } +} + +header icmp_t inner_icmp; + +parser parse_inner_icmp { + extract(inner_icmp); + return ingress; +} + +header tcp_t inner_tcp; + +parser parse_inner_tcp { + extract(inner_tcp); + return ingress; +} + +header udp_t inner_udp; + +parser parse_inner_udp { + extract(inner_udp); + return ingress; +} + +header sctp_t inner_sctp; + +parser parse_inner_sctp { + extract(inner_sctp); + return ingress; +} + +parser parse_inner_ipv6 { + extract(inner_ipv6); + return select(latest.nextHdr) { + IP_PROTOCOLS_ICMPV6 : parse_inner_icmpv6; + IP_PROTOCOLS_TCP : parse_inner_tcp; + IP_PROTOCOLS_UDP : parse_inner_udp; +// IP_PROTOCOLS_SCTP : parse_inner_sctp; + default: ingress; + } +} + +header icmpv6_t inner_icmpv6; + +parser parse_inner_icmpv6 { + extract(inner_icmpv6); + return ingress; +} + +parser parse_inner_ethernet { + extract(inner_ethernet); + return select(latest.etherType) { + ETHERTYPE_IPV4 : parse_inner_ipv4; + ETHERTYPE_IPV6 : parse_inner_ipv6; + default: ingress; + } +} + +action do_noop() { } + +table do_nothing { + reads { + ethernet.dstAddr : exact; + } + actions { + do_noop; + } +} + +control ingress { apply(do_nothing); } diff --git a/backends/tofino/bf-asm/test/port_vlan_mapping.p4 b/backends/tofino/bf-asm/test/port_vlan_mapping.p4 new file mode 100644 index 00000000000..5c01dfc1d20 --- /dev/null +++ b/backends/tofino/bf-asm/test/port_vlan_mapping.p4 @@ -0,0 +1,1415 @@ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type snap_header_t { + fields { + dsap : 8; + ssap : 8; + control_ : 8; + oui : 24; + type_ : 16; + } +} + +header_type roce_header_t { + fields { + ib_grh : 320; + ib_bth : 96; + } +} + +header_type roce_v2_header_t { + fields { + ib_bth : 96; + } +} + +header_type fcoe_header_t { + fields { + version : 4; + type_ : 4; + sof : 8; + rsvd1 : 32; + ts_upper : 32; + ts_lower : 32; + size_ : 32; + eof : 8; + rsvd2 : 24; + } +} + +header_type cpu_header_t { + fields { + qid : 3; + pad : 1; + reason_code : 12; + rxhash : 16; + bridge_domain : 16; + ingress_lif : 16; + egress_lif : 16; + lu_bypass_ingress : 1; + lu_bypass_egress : 1; + pad1 : 14; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + +header_type vlan_tag_3b_t { + fields { + pcp : 3; + cfi : 1; + vid : 4; + etherType : 16; + } +} +header_type vlan_tag_5b_t { + fields { + pcp : 3; + cfi : 1; + vid : 20; + etherType : 16; + } +} + +header_type ieee802_1ah_t { + fields { + pcp : 3; + dei : 1; + uca : 1; + reserved : 3; + i_sid : 24; + } +} + +header_type mpls_t { + fields { + label : 20; + tc : 3; + bos : 1; + ttl : 8; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type ipv6_t { + fields { + version : 4; + trafficClass : 8; + flowLabel : 20; + payloadLen : 16; + nextHdr : 8; + hopLimit : 8; + srcAddr : 128; + dstAddr : 128; + } +} + +header_type icmp_t { + fields { + type_ : 8; + code : 8; + hdrChecksum : 16; + } +} + +header_type icmpv6_t { + fields { + type_ : 8; + code : 8; + hdrChecksum : 16; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 4; + flags : 8; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + length_ : 16; + checksum : 16; + } +} + +header_type sctp_t { + fields { + srcPort : 16; + dstPort : 16; + verifTag : 32; + checksum : 32; + } +} + +header_type gre_t { + fields { + C : 1; + R : 1; + K : 1; + S : 1; + s : 1; + recurse : 3; + flags : 5; + ver : 3; + proto : 16; + } +} + +header_type nvgre_t { + fields { + tni : 24; + reserved : 8; + } +} + +/* 8 bytes */ +header_type erspan_header_v1_t { + fields { + version : 4; + vlan : 12; + priority : 6; + span_id : 10; + direction : 8; + truncated: 8; + } +} + +/* 8 bytes */ +header_type erspan_header_v2_t { + fields { + version : 4; + vlan : 12; + priority : 6; + span_id : 10; + unknown7 : 32; + } +} + +header_type ipsec_esp_t { + fields { + spi : 32; + seqNo : 32; + } +} + +header_type ipsec_ah_t { + fields { + nextHdr : 8; + length_ : 8; + zero : 16; + spi : 32; + seqNo : 32; + } +} + +header_type arp_rarp_t { + fields { + hwType : 16; + protoType : 16; + hwAddrLen : 8; + protoAddrLen : 8; + opcode : 16; + } +} + +header_type arp_rarp_ipv4_t { + fields { + srcHwAddr : 48; + srcProtoAddr : 32; + dstHwAddr : 48; + dstProtoAddr : 32; + } +} + +header_type eompls_t { + fields { + zero : 4; + reserved : 12; + seqNo : 16; + } +} + +header_type vxlan_t { + fields { + flags : 8; + reserved : 24; + vni : 24; + reserved2 : 8; + } +} + +header_type nsh_t { + fields { + oam : 1; + context : 1; + flags : 6; + reserved : 8; + protoType: 16; + spath : 24; + sindex : 8; + } +} + +header_type nsh_context_t { + fields { + network_platform : 32; + network_shared : 32; + service_platform : 32; + service_shared : 32; + } +} + +/* GENEVE HEADERS + 3 possible options with known type, known length */ + +header_type genv_t { + fields { + ver : 2; + optLen : 6; + oam : 1; + critical : 1; + reserved : 6; + protoType : 16; + vni : 24; + reserved2 : 8; + } +} + +#define GENV_OPTION_A_TYPE 0x000001 +/* TODO: Would it be convenient to have some kind of sizeof macro ? */ +#define GENV_OPTION_A_LENGTH 2 /* in bytes */ + +header_type genv_opt_A_t { + fields { + optClass : 16; + optType : 8; + reserved : 3; + optLen : 5; + data : 32; + } +} + +#define GENV_OPTION_B_TYPE 0x000002 +#define GENV_OPTION_B_LENGTH 3 /* in bytes */ + +header_type genv_opt_B_t { + fields { + optClass : 16; + optType : 8; + reserved : 3; + optLen : 5; + data : 64; + } +} + +#define GENV_OPTION_C_TYPE 0x000003 +#define GENV_OPTION_C_LENGTH 2 /* in bytes */ + +header_type genv_opt_C_t { + fields { + optClass : 16; + optType : 8; + reserved : 3; + optLen : 5; + data : 32; + } +} +parser start { + return parse_input_port; +} + +header_type input_port_hdr_t { + fields { + port : 16; + } +} + +header input_port_hdr_t input_port_hdr; + +parser parse_input_port { + extract (input_port_hdr); + return parse_ethernet; +} + +#define ETHERTYPE_CPU 0x9000, 0x010c +#define ETHERTYPE_VLAN 0x8100, 0x9100, 0x9200, 0x9300 +#define ETHERTYPE_MPLS 0x8847 +#define ETHERTYPE_IPV4 0x0800 +#define ETHERTYPE_IPV6 0x86dd +#define ETHERTYPE_ARP 0x0806 +#define ETHERTYPE_RARP 0x8035 +#define ETHERTYPE_NSH 0x894f +#define ETHERTYPE_ETHERNET 0x6558 +#define ETHERTYPE_ROCE 0x8915 +#define ETHERTYPE_FCOE 0x8906 +/* missing: vlan_3b, vlan_5b, ieee802_1q, ieee802_1ad */ + +#define IPV4_MULTICAST_MAC 0x01005E +#define IPV6_MULTICAST_MAC 0x3333 + +/* Tunnel types */ +#define TUNNEL_TYPE_NONE 0 +#define TUNNEL_TYPE_VXLAN 1 +#define TUNNEL_TYPE_GRE 2 +#define TUNNEL_TYPE_GENEVE 3 +#define TUNNEL_TYPE_NVGRE 4 +#define TUNNEL_TYPE_MPLS 5 + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0 mask 0xf800: parse_snap_header; /* < 1536 */ + ETHERTYPE_CPU : parse_cpu_header; + ETHERTYPE_VLAN : parse_vlan; + ETHERTYPE_MPLS : parse_mpls; + ETHERTYPE_IPV4 : parse_ipv4; + ETHERTYPE_IPV6 : parse_ipv6; + ETHERTYPE_ARP : parse_arp_rarp; + ETHERTYPE_RARP : parse_arp_rarp; + ETHERTYPE_NSH : parse_nsh; + ETHERTYPE_ROCE: parse_roce; + ETHERTYPE_FCOE: parse_fcoe; + default: ingress; + } +} + +header snap_header_t snap_header; + +parser parse_snap_header { + extract(snap_header); + return ingress; +} + +header roce_header_t roce; + +parser parse_roce { + extract(roce); + return ingress; +} + +header fcoe_header_t fcoe; + +parser parse_fcoe { + extract(fcoe); + return ingress; +} + +header cpu_header_t cpu_header; + +parser parse_cpu_header { + extract(cpu_header); + return select(latest.etherType) { + 0 mask 0xf800: parse_snap_header; /* < 1536 */ + ETHERTYPE_VLAN : parse_vlan; + ETHERTYPE_MPLS : parse_mpls; + ETHERTYPE_IPV4 : parse_ipv4; + ETHERTYPE_IPV6 : parse_ipv6; + ETHERTYPE_ARP : parse_arp_rarp; + ETHERTYPE_RARP : parse_arp_rarp; + ETHERTYPE_NSH : parse_nsh; + ETHERTYPE_ROCE: parse_roce; + ETHERTYPE_FCOE: parse_fcoe; + default: ingress; + } +} + +#define VLAN_DEPTH 2 +header vlan_tag_t vlan_tag_[VLAN_DEPTH]; +header vlan_tag_3b_t vlan_tag_3b[VLAN_DEPTH]; +header vlan_tag_5b_t vlan_tag_5b[VLAN_DEPTH]; + +parser parse_vlan { + extract(vlan_tag_[next]); + return select(latest.etherType) { + ETHERTYPE_VLAN : parse_vlan; + ETHERTYPE_MPLS : parse_mpls; + ETHERTYPE_IPV4 : parse_ipv4; + ETHERTYPE_IPV6 : parse_ipv6; + ETHERTYPE_ARP : parse_arp_rarp; + ETHERTYPE_RARP : parse_arp_rarp; + default: ingress; + } +} + +#define MPLS_DEPTH 3 +/* all the tags but the last one */ +header mpls_t mpls[MPLS_DEPTH]; + +/* last mpls tag in the stack */ +header mpls_t mpls_bos; + +/* TODO: this will be optimized when pushed to the chip ? */ + +parser parse_mpls { + return select(current(23, 1)) { + 0 : parse_mpls_not_bos; + 1 : parse_mpls_bos; + default: ingress; + } +} + +parser parse_mpls_not_bos { + extract(mpls[next]); + return parse_mpls; +} + +parser parse_mpls_bos { + extract(mpls_bos); + return select(current(0, 4)) { + 0x4 : parse_inner_ipv4; + 0x6 : parse_inner_ipv6; + default : parse_eompls; + } +} + +#define IP_PROTOCOLS_ICMP 1 +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 +#define IP_PROTOCOLS_GRE 47 +#define IP_PROTOCOLS_IPSEC_ESP 50 +#define IP_PROTOCOLS_IPSEC_AH 51 +#define IP_PROTOCOLS_ICMPV6 58 +#define IP_PROTOCOLS_SCTP 132 + +header ipv4_t ipv4; + +field_list ipv4_checksum_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_checksum { + input { + ipv4_checksum_list; + } + algorithm : csum16; + output_width : 16; +} + +calculated_field ipv4.hdrChecksum { +#ifdef __TARGET_TOFINO__ + verify ipv4_checksum; + update ipv4_checksum; +#else + verify ipv4_checksum if(ipv4.ihl == 5); + update ipv4_checksum if(ipv4.ihl == 5); +#endif +} + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_ICMP : parse_icmp; + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + IP_PROTOCOLS_GRE : parse_gre; +// IP_PROTOCOLS_SCTP : parse_sctp; + default: ingress; + } +} + +header ipv6_t ipv6; + +parser parse_ipv6 { + extract(ipv6); + return select(latest.nextHdr) { + IP_PROTOCOLS_ICMPV6 : parse_icmpv6; + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + IP_PROTOCOLS_GRE : parse_gre; +// IP_PROTOCOLS_SCTP : parse_sctp; + default: ingress; + } +} + +header icmp_t icmp; + +parser parse_icmp { + extract(icmp); + return ingress; +} + +header icmpv6_t icmpv6; + +parser parse_icmpv6 { + extract(icmpv6); + return ingress; +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +#define UDP_PORT_VXLAN 4789 +#define UDP_PORT_GENV 6081 +// Check IANA UDP port number + #define UDP_PORT_ROCE_V2 1021 + +header udp_t udp; + +header roce_v2_header_t roce_v2; + +parser parse_roce_v2 { + extract(roce_v2); + return ingress; +} + +parser parse_udp { + extract(udp); + return select(latest.dstPort) { + UDP_PORT_VXLAN : parse_vxlan; + UDP_PORT_GENV: parse_geneve; + UDP_PORT_ROCE_V2: parse_roce_v2; + default: ingress; + } +} + +header sctp_t sctp; + +parser parse_sctp { + extract(sctp); + return ingress; +} + + +#define GRE_PROTOCOLS_NVGRE 0x6558 +#define GRE_PROTOCOLS_GRE 0x6559 +#define GRE_PROTOCOLS_ERSPAN_V1 0x88BE +#define GRE_PROTOCOLS_ERSPAN_V2 0x22EB + +#define GRE_DEPTH 2 + +//header gre_t gre[GRE_DEPTH]; +header gre_t gre; + +#if 0 +header_type gre_opt_t { + fields { + key : 32; + } +} + +header gre_opt_t gre_opt; + +parser parse_gre_key { + extract(gre_opt); + return ingress; +} +parser parse_gre_key2 { + extract(gre_opt); + extract(gre_opt); + return ingress; +} +parser parse_gre_key22 { + extract(gre_opt); + extract(gre_opt); + return ingress; +} +parser parse_gre_opt1 { + extract(gre_opt); + return ingress; +} +parser parse_gre_opt2 { + extract(gre_opt); + extract(gre_opt); + return ingress; +} +parser parse_gre_opt3 { + extract(gre_opt); + extract(gre_opt); + extract(gre_opt); + return ingress; +} + +parser parse_gre_opts { + return select(latest.C, latest.S, latest.K) { + 1 mask 0x0000 : parse_gre_key; + 2 mask 0x0000 : parse_gre_opt1; + 3 mask 0x0000 : parse_gre_key2; + 4 mask 0x0000 : parse_gre_opt1; + 5 mask 0x0000 : parse_gre_key22; + 6 mask 0x0000 : parse_gre_opt2; + 7 mask 0x0000 : parse_gre_opt3; + default: ingress; + } +} +#endif + +parser parse_gre { + extract(gre); +// parse_gre_opts; + return select(latest.K, latest.proto) { + GRE_PROTOCOLS_NVGRE : parse_nvgre; +// GRE_PROTOCOLS_GRE : parse_gre; + GRE_PROTOCOLS_ERSPAN_V1 : parse_erspan_v1; + GRE_PROTOCOLS_ERSPAN_V2 : parse_erspan_v2; + ETHERTYPE_NSH : parse_nsh; + default: ingress; + } +} + +header nvgre_t nvgre; +header ethernet_t inner_ethernet; + +header ipv4_t inner_ipv4; +header ipv6_t inner_ipv6; +header ipv4_t outer_ipv4; +header ipv6_t outer_ipv6; + +field_list inner_ipv4_checksum_list { + inner_ipv4.version; + inner_ipv4.ihl; + inner_ipv4.diffserv; + inner_ipv4.totalLen; + inner_ipv4.identification; + inner_ipv4.flags; + inner_ipv4.fragOffset; + inner_ipv4.ttl; + inner_ipv4.protocol; + inner_ipv4.srcAddr; + inner_ipv4.dstAddr; +} + +field_list_calculation inner_ipv4_checksum { + input { + inner_ipv4_checksum_list; + } + algorithm : csum16; + output_width : 16; +} + +calculated_field inner_ipv4.hdrChecksum { +#ifdef __TARGET_TOFINO__ + verify inner_ipv4_checksum; + update inner_ipv4_checksum; +#else + verify inner_ipv4_checksum if(valid(ipv4)); + update inner_ipv4_checksum if(valid(ipv4)); +#endif +} + +header udp_t outer_udp; + +parser parse_nvgre { + extract(nvgre); + return parse_inner_ethernet; +} + +header erspan_header_v1_t erspan_v1_header; + +parser parse_erspan_v1 { + extract(erspan_v1_header); + return ingress; +} + +header erspan_header_v2_t erspan_v2_header; + +parser parse_erspan_v2 { + extract(erspan_v2_header); + return ingress; +} + +#define ARP_PROTOTYPES_ARP_RARP_IPV4 0x0800 + +header arp_rarp_t arp_rarp; + +parser parse_arp_rarp { + extract(arp_rarp); + return select(latest.protoType) { + ARP_PROTOTYPES_ARP_RARP_IPV4 : parse_arp_rarp_ipv4; + default: ingress; + } +} + +header arp_rarp_ipv4_t arp_rarp_ipv4; + +parser parse_arp_rarp_ipv4 { + extract(arp_rarp_ipv4); + return ingress; +} + +header eompls_t eompls; + +parser parse_eompls { + extract(eompls); + extract(inner_ethernet); + return ingress; +} + +header vxlan_t vxlan; + +parser parse_vxlan { + extract(vxlan); + return parse_inner_ethernet; +} + +header genv_t genv; + +header genv_opt_A_t genv_opt_A; +header genv_opt_B_t genv_opt_B; +header genv_opt_C_t genv_opt_C; + +parser parse_geneve { + extract(genv); + /* + counter_init(counter_1, latest.optLen); + return select(latest.optLen) { + 0 : parse_genv_inner; + default : parse_genv_opts; + } + */ + return parse_genv_inner; +} + +#if 0 + +parser parse_genv_opts { + /* switching on combined class and type */ + return select(current(0, 24)) { + GENV_OPTION_A_TYPE: parse_genv_opt_A; + GENV_OPTION_B_TYPE: parse_genv_opt_B; + GENV_OPTION_C_TYPE: parse_genv_opt_C; + } +} + +parser parse_genv_opt_A { + extract(genv_opt_A); + counter_decrement(counter_1, GENV_OPTION_A_LENGTH); + return select(counter_1) { + 0 : parse_genv_inner; + default : parse_genv_opts; + } +} + +parser parse_genv_opt_B { + extract(genv_opt_B); + counter_decrement(counter_1, GENV_OPTION_B_LENGTH); + return select(counter_1) { + 0 : parse_genv_inner; + default : parse_genv_opts; + } +} + +parser parse_genv_opt_C { + extract(genv_opt_C); + counter_decrement(counter_1, GENV_OPTION_C_LENGTH); + return select(counter_1) { + 0 : parse_genv_inner; + default : parse_genv_opts; + } +} +#endif + +parser parse_genv_inner { + return select(genv.protoType) { + ETHERTYPE_ETHERNET : parse_inner_ethernet; + ETHERTYPE_IPV4 : parse_inner_ipv4; + ETHERTYPE_IPV6 : parse_inner_ipv6; + default : ingress; + } +} + +header nsh_t nsh; +header nsh_context_t nsh_context; + +parser parse_nsh { + extract(nsh); + extract(nsh_context); + return select(nsh.protoType) { + ETHERTYPE_IPV4 : parse_inner_ipv4; + ETHERTYPE_IPV6 : parse_inner_ipv6; + ETHERTYPE_ETHERNET : parse_inner_ethernet; + default: ingress; + } +} + +parser parse_inner_ipv4 { + extract(inner_ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_ICMP : parse_inner_icmp; + IP_PROTOCOLS_TCP : parse_inner_tcp; + IP_PROTOCOLS_UDP : parse_inner_udp; +// IP_PROTOCOLS_SCTP : parse_inner_sctp; + default: ingress; + } +} + +header icmp_t inner_icmp; + +parser parse_inner_icmp { + extract(inner_icmp); + return ingress; +} + +header tcp_t inner_tcp; + +parser parse_inner_tcp { + extract(inner_tcp); + return ingress; +} + +header udp_t inner_udp; + +parser parse_inner_udp { + extract(inner_udp); + return ingress; +} + +header sctp_t inner_sctp; + +parser parse_inner_sctp { + extract(inner_sctp); + return ingress; +} + +parser parse_inner_ipv6 { + extract(inner_ipv6); + return select(latest.nextHdr) { + IP_PROTOCOLS_ICMPV6 : parse_inner_icmpv6; + IP_PROTOCOLS_TCP : parse_inner_tcp; + IP_PROTOCOLS_UDP : parse_inner_udp; +// IP_PROTOCOLS_SCTP : parse_inner_sctp; + default: ingress; + } +} + +header icmpv6_t inner_icmpv6; + +parser parse_inner_icmpv6 { + extract(inner_icmpv6); + return ingress; +} + +parser parse_inner_ethernet { + extract(inner_ethernet); + return select(latest.etherType) { + ETHERTYPE_IPV4 : parse_inner_ipv4; + ETHERTYPE_IPV6 : parse_inner_ipv6; + default: ingress; + } +} + +#define VALIDATE_PACKET_TABLE_SIZE 64 +#define PORTMAP_TABLE_SIZE 288 +#define STORM_CONTROL_TABLE_SIZE 256 +#define STORM_CONTROL_METER_TABLE_SIZE 256 +#define PORT_VLAN_TABLE_SIZE 32768 +#define OUTER_BD_TABLE_SIZE 256 +#define OUTER_ROUTER_MAC_TABLE_SIZE 256 +#define DEST_TUNNEL_TABLE_SIZE 512 +#define SRC_TUNNEL_TABLE_SIZE 16384 +#define OUTER_MULTICAST_STAR_G_TABLE_SIZE 512 +#define OUTER_MULTICAST_S_G_TABLE_SIZE 1024 +#define VNID_MAPPING_TABLE_SIZE 16384 +#define BD_TABLE_SIZE 16384 +#define OUTER_MCAST_RPF_TABLE_SIZE 512 +#define MPLS_TABLE_SIZE 4096 +#define VALIDATE_MPLS_TABLE_SIZE 512 + +#define ROUTER_MAC_TABLE_SIZE 512 +#define DMAC_TABLE_SIZE 65536 +#define SMAC_TABLE_SIZE 65536 +#define IPSG_TABLE_SIZE 8192 +#define IPSG_PERMIT_SPECIAL_TABLE_SIZE 512 +#define INGRESS_MIRROR_ACL_TABLE_SIZE 512 +#define INGRESS_MAC_ACL_TABLE_SIZE 512 +#define INGRESS_IP_ACL_TABLE_SIZE 1024 +#define INGRESS_IPV6_ACL_TABLE_SIZE 512 +#define INGRESS_QOS_ACL_TABLE_SIZE 512 +#define INGRESS_IP_RACL_TABLE_SIZE 1024 +#define INGRESS_IPV6_RACL_TABLE_SIZE 256 +#define IP_NAT_TABLE_SIZE 4096 + +#define IPV4_LPM_TABLE_SIZE 8192 +#define IPV6_LPM_TABLE_SIZE 2048 +#define IPV4_HOST_TABLE_SIZE 65536 +#define IPV6_HOST_TABLE_SIZE 16384 + +#define IPV4_MULTICAST_STAR_G_TABLE_SIZE 2048 +#define IPV4_MULTICAST_S_G_TABLE_SIZE 4096 +#define IPV6_MULTICAST_STAR_G_TABLE_SIZE 512 +#define IPV6_MULTICAST_S_G_TABLE_SIZE 512 +#define MCAST_RPF_TABLE_SIZE 32768 + +#define FWD_RESULT_TABLE_SIZE 512 +#define URPF_GROUP_TABLE_SIZE 32768 +#define ECMP_GROUP_TABLE_SIZE 1024 +#define ECMP_SELECT_TABLE_SIZE 16384 +#define NEXTHOP_TABLE_SIZE 49152 +#ifdef HARLYN +#define LAG_GROUP_TABLE_SIZE 4096 +#else +#define LAG_GROUP_TABLE_SIZE 1024 +#endif +#define LAG_SELECT_TABLE_SIZE 1024 +#define SYSTEM_ACL_SIZE 1024 +#define LEARN_NOTIFY_TABLE_SIZE 512 + +#define MAC_REWRITE_TABLE_SIZE 512 +#define EGRESS_VNID_MAPPING_TABLE_SIZE 16384 +#define EGRESS_BD_MAPPING_TABLE_SIZE 16384 +#define REPLICA_TYPE_TABLE_SIZE 16 +#define RID_TABLE_SIZE 65536 +#define TUNNEL_DECAP_TABLE_SIZE 512 +#define IP_MTU_TABLE_SIZE 512 +#define EGRESS_SYSTEM_ACL_TABLE_SIZE 512 +#define EGRESS_VLAN_XLATE_TABLE_SIZE 32768 +#define SPANNING_TREE_TABLE_SIZE 4096 +#define CPU_REWRITE_TABLE_SIZE 512 +#define EGRESS_ACL_TABLE_SIZE 2048 +#define VLAN_DECAP_TABLE_SIZE 256 +#define TUNNEL_HEADER_TABLE_SIZE 256 +#define TUNNEL_REWRITE_TABLE_SIZE 16384 +#define TUNNEL_SMAC_REWRITE_TABLE_SIZE 512 +#define TUNNEL_DMAC_REWRITE_TABLE_SIZE 16384 + +/* Boolean */ +#define FALSE 0 +#define TRUE 1 + +/* Packet types */ +#define L2_UNICAST 1 +#define L2_MULTICAST 2 +#define L2_BROADCAST 4 + +#define STORM_CONTROL_COLOR_GREEN 0 +#define STORM_CONTROL_COLOR_RED 1 + +/* IP types */ +#define IPTYPE_NONE 0 +#define IPTYPE_IPV4 1 +#define IPTYPE_IPV6 2 + +/* Multicast modes */ +#define MCAST_MODE_NONE 0 +#define MCAST_MODE_SM 1 +#define MCAST_MODE_BIDIR 2 + +#define OUTER_MCAST_KEY_TYPE_BD 0 +#define OUTER_MCAST_KEY_TYPE_VRF 1 + +/* URPF modes */ +#define URPF_MODE_NONE 0 +#define URPF_MODE_LOOSE 1 +#define URPF_MODE_STRICT 2 + +/* NAT modes */ +#define NAT_MODE_NONE 0 +#define NAT_MODE_INSIDE 1 +#define NAT_MODE_OUTSIDE 2 + +/* Egress tunnel types */ +#define EGRESS_TUNNEL_TYPE_NONE 0 +#define EGRESS_TUNNEL_TYPE_IPV4_VXLAN 1 +#define EGRESS_TUNNEL_TYPE_IPV6_VXLAN 2 +#define EGRESS_TUNNEL_TYPE_IPV4_GENEVE 3 +#define EGRESS_TUNNEL_TYPE_IPV6_GENEVE 4 +#define EGRESS_TUNNEL_TYPE_IPV4_NVGRE 5 +#define EGRESS_TUNNEL_TYPE_IPV6_NVGRE 6 +#define EGRESS_TUNNEL_TYPE_IPV4_ERSPANV2 7 +#define EGRESS_TUNNEL_TYPE_IPV6_ERSPANV2 8 +#define EGRESS_TUNNEL_TYPE_IPV4_GRE 9 +#define EGRESS_TUNNEL_TYPE_IPV6_GRE 10 +#define EGRESS_TUNNEL_TYPE_IPV4_IP 11 +#define EGRESS_TUNNEL_TYPE_IPV6_IP 12 +#define EGRESS_TUNNEL_TYPE_MPLS_L2VPN 13 +#define EGRESS_TUNNEL_TYPE_MPLS_L3VPN 14 + +#define VRF_BIT_WIDTH 12 +#define BD_BIT_WIDTH 16 +#define ECMP_BIT_WIDTH 10 +#define LAG_BIT_WIDTH 8 +#define IFINDEX_BIT_WIDTH 16 + +#define STP_GROUP_NONE 0 + +#define CPU_PORT_ID 64 +#define CPU_MIRROR_SESSION_ID 250 + +/* Learning Receivers */ +#ifndef HARLYN +#define MAC_LEARN_RECEIVER 1024 +#else +#define MAC_LEARN_RECEIVER 0 +#endif + +/* Nexthop Type */ +#define NEXTHOP_TYPE_SIMPLE 0 +#define NEXTHOP_TYPE_ECMP 1 + +/* METADATA */ +header_type ingress_metadata_t { + fields { + lkp_pkt_type : 3; + lkp_mac_sa : 48; + lkp_mac_da : 48; + lkp_mac_type : 16; + lkp_ip_type : 2; + lkp_ipv4_sa : 32; + lkp_ipv4_da : 32; + lkp_ipv6_sa : 128; + lkp_ipv6_da : 128; + lkp_ip_proto : 8; + lkp_ip_tc : 8; + lkp_ip_ttl : 8; + + lkp_l4_sport : 16; + lkp_l4_dport : 16; + lkp_inner_l4_sport : 16; + lkp_inner_l4_dport : 16; + + lkp_icmp_type : 8; + lkp_icmp_code : 8; + lkp_inner_icmp_type : 8; + lkp_inner_icmp_code : 8; + + l3_length : 16; /* l3 length */ + + ifindex : IFINDEX_BIT_WIDTH; /* input interface index - MSB bit lag*/ + vrf : VRF_BIT_WIDTH; /* VRF */ + +#ifdef HARLYN + tunnel_type : 8; /* tunnel type from parser */ +#else + tunnel_type : 4; /* tunnel type from parser */ +#endif + tunnel_terminate : 1; /* should tunnel be terminated */ + tunnel_vni : 24; /* tunnel id */ + src_vtep_miss : 1; /* src vtep lookup failed */ + + outer_bd : 8; /* outer BD */ + outer_ipv4_mcast_key_type : 1; /* 0 bd, 1 vrf */ + outer_ipv4_mcast_key : 8; /* bd or vrf value */ + outer_ipv6_mcast_key_type : 1; /* 0 bd, 1 vrf */ + outer_ipv6_mcast_key : 8; /* bd or vrf value */ + outer_mcast_route_hit : 1; /* hit in the outer multicast table */ + outer_mcast_mode : 2; /* multicast mode from route */ + outer_dscp : 8; /* outer dscp */ + outer_ttl : 8; /* outer ttl */ + outer_routed : 1; /* is outer packet routed */ + + l2_multicast : 1; /* packet is l2 multicast */ + ip_multicast : 1; /* packet is ip multicast */ + src_is_link_local : 1; /* source is link local address */ + bd : BD_BIT_WIDTH; /* inner BD */ + ipsg_enabled : 1; /* is ip source guard feature enabled */ + ipv4_unicast_enabled : 1; /* is ipv4 unicast routing enabled on BD */ + ipv6_unicast_enabled : 1; /* is ipv6 unicast routing enabled on BD */ + ipv4_multicast_mode : 2; /* ipv4 multicast mode BD */ + ipv6_multicast_mode : 2; /* ipv6 multicast mode BD */ + igmp_snooping_enabled : 1; /* is IGMP snooping enabled on BD */ + mld_snooping_enabled : 1; /* is MLD snooping enabled on BD */ + mpls_enabled : 1; /* is mpls enabled on BD */ + mpls_label: 20; /* Mpls label */ + mpls_exp: 3; /* Mpls Traffic Class */ + mpls_ttl: 8; /* Mpls Ttl */ + ipv4_urpf_mode : 2; /* 0: none, 1: strict, 3: loose */ + ipv6_urpf_mode : 2; /* 0: none, 1: strict, 3: loose */ + urpf_mode : 2; /* urpf mode for current lookup */ + nat_mode : 2; /* 0: none, 1: inside, 2: outside */ + rmac_group : 10; /* Rmac group, for rmac indirection */ + rmac_hit : 1; /* dst mac is the router's mac */ + mcast_route_hit : 1; /* hit in the multicast route table */ + mcast_bridge_hit : 1; /* hit in the multicast bridge table */ + bd_mrpf_group : BD_BIT_WIDTH; /* rpf group from bd lookup */ + mcast_rpf_group : BD_BIT_WIDTH; /* rpf group from mcast lookup */ + mcast_mode : 2; /* multicast mode from route */ + uuc_mc_index : 16; /* unknown unicast multicast index */ + umc_mc_index : 16; /* unknown multicast multicast index */ + bcast_mc_index : 16; /* broadcast multicast index */ + multicast_route_mc_index : 16; /* multicast index from mfib */ + multicast_bridge_mc_index : 16; /* multicast index from igmp/mld snoop */ + storm_control_color : 1; /* 0 : pass, 1 : fail */ + urpf_hit : 1; /* hit in urpf table */ + urpf_check_fail :1; /* urpf check failed */ + urpf_bd_group : BD_BIT_WIDTH; /* urpf bd group */ + routed : 1; /* is packet routed */ + + if_label : 16; /* if label for acls */ + bd_label : 16; /* bd label for acls */ + + l2_src_miss : 1; /* l2 source miss */ + l2_src_move : IFINDEX_BIT_WIDTH; /* l2 source interface mis-match */ + ipsg_check_fail : 1; /* ipsg check failed */ + acl_deny : 1; /* ifacl/vacl deny action */ + racl_deny : 1; /* racl deny action */ + l2_redirect : 1; /* l2 redirect action */ + acl_redirect : 1; /* ifacl/vacl redirect action */ + racl_redirect : 1; /* racl redirect action */ + fib_hit : 1; /* fib hit */ + nat_hit : 1; /* fwd and rewrite info from nat */ + + mirror_session_id : 10; /* mirror session id */ + + l2_nexthop : 16; /* next hop from l2 */ + acl_nexthop : 16; /* next hop from ifacl/vacl */ + racl_nexthop : 16; /* next hop from racl */ + fib_nexthop : 16; /* next hop from fib */ + nat_nexthop : 16; /* next hop from nat */ + l2_nexthop_type : 1; /* ecmp or nexthop */ + acl_nexthop_type : 1; /* ecmp or nexthop */ + racl_nexthop_type : 1; /* ecmp or nexthop */ + fib_nexthop_type : 1; /* ecmp or nexthop */ + nexthop_index : 16; /* final next hop index */ + nexthop_type : 1; /* final next hop index type */ + nat_rewrite_index : 16; /* NAT rewrite index */ + + marked_cos : 3; /* marked vlan cos value */ + marked_dscp : 8; /* marked dscp value */ + marked_exp : 3; /* marked exp value */ + ttl : 8; /* update ttl */ + +#ifndef HARLYN + egress_ifindex : IFINDEX_BIT_WIDTH; /* egress interface index */ +#else + egress_ifindex : 32; /* egress interface index */ +#endif + egress_bd : BD_BIT_WIDTH; /* egress BD */ + same_bd_check : BD_BIT_WIDTH; /* ingress bd xor egress bd */ + + ingress_bypass : 1; /* skip the entire ingress pipeline */ + ipv4_dstaddr_24b : 24; /* first 24b of ipv4 dst addr */ + drop_0 : 1; /* dummy */ + drop_reason : 8; /* drop reason for negative mirroring */ + stp_group: 10; /* spanning tree group id */ + stp_state : 3; /* spanning tree port state */ + control_frame: 1; /* control frame */ + header_count: 4; /* Number of headers */ + } +} + +metadata ingress_metadata_t ingress_metadata; + +table port_vlan_mapping { + reads { + ingress_metadata.ifindex : exact; + vlan_tag_[0] : valid; + vlan_tag_[0].vid : exact; + vlan_tag_[1] : valid; + vlan_tag_[1].vid : exact; + } + + action_profile: outer_bd_action_profile; + size : PORT_VLAN_TABLE_SIZE; +} + +action set_outer_bd_ipv4_mcast_switch_ipv6_mcast_switch_flags(bd, vrf, + rmac_group, mrpf_group, + bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, + ipv4_unicast_enabled, ipv6_unicast_enabled, + ipv4_multicast_mode, ipv6_multicast_mode, + igmp_snooping_enabled, mld_snooping_enabled, + ipv4_urpf_mode, ipv6_urpf_mode, stp_group) { + modify_field(ingress_metadata.vrf, vrf); + modify_field(ingress_metadata.bd, bd); + modify_field(ingress_metadata.outer_bd, bd); + modify_field(ingress_metadata.outer_ipv4_mcast_key_type, OUTER_MCAST_KEY_TYPE_BD); + modify_field(ingress_metadata.outer_ipv4_mcast_key, bd); + modify_field(ingress_metadata.outer_ipv6_mcast_key_type, OUTER_MCAST_KEY_TYPE_BD); + modify_field(ingress_metadata.outer_ipv6_mcast_key, bd); + + modify_field(ingress_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); + modify_field(ingress_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled); + modify_field(ingress_metadata.ipv4_multicast_mode, ipv4_multicast_mode); + modify_field(ingress_metadata.ipv6_multicast_mode, ipv6_multicast_mode); + modify_field(ingress_metadata.igmp_snooping_enabled, igmp_snooping_enabled); + modify_field(ingress_metadata.mld_snooping_enabled, mld_snooping_enabled); + modify_field(ingress_metadata.ipv4_urpf_mode, ipv4_urpf_mode); + modify_field(ingress_metadata.ipv6_urpf_mode, ipv6_urpf_mode); + modify_field(ingress_metadata.rmac_group, rmac_group); + modify_field(ingress_metadata.bd_mrpf_group, mrpf_group); + modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); + modify_field(ingress_metadata.umc_mc_index, umc_mc_index); + modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); + modify_field(ingress_metadata.bd_label, bd_label); + modify_field(ingress_metadata.stp_group, stp_group); +} + +action set_outer_bd_ipv4_mcast_switch_ipv6_mcast_route_flags(bd, vrf, + rmac_group, mrpf_group, + bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, + ipv4_unicast_enabled, ipv6_unicast_enabled, + ipv4_multicast_mode, ipv6_multicast_mode, + igmp_snooping_enabled, mld_snooping_enabled, + ipv4_urpf_mode, ipv6_urpf_mode, stp_group) { + modify_field(ingress_metadata.vrf, vrf); + modify_field(ingress_metadata.bd, bd); + modify_field(ingress_metadata.outer_bd, bd); + modify_field(ingress_metadata.outer_ipv4_mcast_key_type, OUTER_MCAST_KEY_TYPE_BD); + modify_field(ingress_metadata.outer_ipv4_mcast_key, bd); + modify_field(ingress_metadata.outer_ipv6_mcast_key_type, OUTER_MCAST_KEY_TYPE_VRF); + modify_field(ingress_metadata.outer_ipv6_mcast_key, vrf); + + modify_field(ingress_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); + modify_field(ingress_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled); + modify_field(ingress_metadata.ipv4_multicast_mode, ipv4_multicast_mode); + modify_field(ingress_metadata.ipv6_multicast_mode, ipv6_multicast_mode); + modify_field(ingress_metadata.igmp_snooping_enabled, igmp_snooping_enabled); + modify_field(ingress_metadata.mld_snooping_enabled, mld_snooping_enabled); + modify_field(ingress_metadata.ipv4_urpf_mode, ipv4_urpf_mode); + modify_field(ingress_metadata.ipv6_urpf_mode, ipv6_urpf_mode); + modify_field(ingress_metadata.rmac_group, rmac_group); + modify_field(ingress_metadata.bd_mrpf_group, mrpf_group); + modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); + modify_field(ingress_metadata.umc_mc_index, umc_mc_index); + modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); + modify_field(ingress_metadata.bd_label, bd_label); + modify_field(ingress_metadata.stp_group, stp_group); +} + +action set_outer_bd_ipv4_mcast_route_ipv6_mcast_switch_flags(bd, vrf, + rmac_group, mrpf_group, + bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, + ipv4_unicast_enabled, ipv6_unicast_enabled, + ipv4_multicast_mode, ipv6_multicast_mode, + igmp_snooping_enabled, mld_snooping_enabled, + ipv4_urpf_mode, ipv6_urpf_mode, stp_group) { + modify_field(ingress_metadata.vrf, vrf); + modify_field(ingress_metadata.bd, bd); + modify_field(ingress_metadata.outer_bd, bd); + modify_field(ingress_metadata.outer_ipv4_mcast_key_type, OUTER_MCAST_KEY_TYPE_VRF); + modify_field(ingress_metadata.outer_ipv4_mcast_key, vrf); + modify_field(ingress_metadata.outer_ipv6_mcast_key_type, OUTER_MCAST_KEY_TYPE_BD); + modify_field(ingress_metadata.outer_ipv6_mcast_key, bd); + + modify_field(ingress_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); + modify_field(ingress_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled); + modify_field(ingress_metadata.ipv4_multicast_mode, ipv4_multicast_mode); + modify_field(ingress_metadata.ipv6_multicast_mode, ipv6_multicast_mode); + modify_field(ingress_metadata.igmp_snooping_enabled, igmp_snooping_enabled); + modify_field(ingress_metadata.mld_snooping_enabled, mld_snooping_enabled); + modify_field(ingress_metadata.ipv4_urpf_mode, ipv4_urpf_mode); + modify_field(ingress_metadata.ipv6_urpf_mode, ipv6_urpf_mode); + modify_field(ingress_metadata.rmac_group, rmac_group); + modify_field(ingress_metadata.bd_mrpf_group, mrpf_group); + modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); + modify_field(ingress_metadata.umc_mc_index, umc_mc_index); + modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); + modify_field(ingress_metadata.bd_label, bd_label); + modify_field(ingress_metadata.stp_group, stp_group); +} + +action set_outer_bd_ipv4_mcast_route_ipv6_mcast_route_flags(bd, vrf, + rmac_group, mrpf_group, + bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, + ipv4_unicast_enabled, ipv6_unicast_enabled, + ipv4_multicast_mode, ipv6_multicast_mode, + igmp_snooping_enabled, mld_snooping_enabled, + ipv4_urpf_mode, ipv6_urpf_mode, stp_group) { + modify_field(ingress_metadata.vrf, vrf); + modify_field(ingress_metadata.bd, bd); + modify_field(ingress_metadata.outer_bd, bd); + modify_field(ingress_metadata.outer_ipv4_mcast_key_type, OUTER_MCAST_KEY_TYPE_VRF); + modify_field(ingress_metadata.outer_ipv4_mcast_key, vrf); + modify_field(ingress_metadata.outer_ipv6_mcast_key_type, OUTER_MCAST_KEY_TYPE_VRF); + modify_field(ingress_metadata.outer_ipv6_mcast_key, vrf); + + modify_field(ingress_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); + modify_field(ingress_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled); + modify_field(ingress_metadata.ipv4_multicast_mode, ipv4_multicast_mode); + modify_field(ingress_metadata.ipv6_multicast_mode, ipv6_multicast_mode); + modify_field(ingress_metadata.igmp_snooping_enabled, igmp_snooping_enabled); + modify_field(ingress_metadata.mld_snooping_enabled, mld_snooping_enabled); + modify_field(ingress_metadata.ipv4_urpf_mode, ipv4_urpf_mode); + modify_field(ingress_metadata.ipv6_urpf_mode, ipv6_urpf_mode); + modify_field(ingress_metadata.rmac_group, rmac_group); + modify_field(ingress_metadata.bd_mrpf_group, mrpf_group); + modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); + modify_field(ingress_metadata.umc_mc_index, umc_mc_index); + modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); + modify_field(ingress_metadata.bd_label, bd_label); + modify_field(ingress_metadata.stp_group, stp_group); +} + +action set_bd(outer_vlan_bd, vrf, rmac_group, + bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, + ipv4_unicast_enabled, + igmp_snooping_enabled, stp_group) { + modify_field(ingress_metadata.vrf, vrf); + modify_field(ingress_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); + modify_field(ingress_metadata.igmp_snooping_enabled, igmp_snooping_enabled); + modify_field(ingress_metadata.rmac_group, rmac_group); + modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); + modify_field(ingress_metadata.umc_mc_index, umc_mc_index); + modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); + modify_field(ingress_metadata.bd_label, bd_label); + modify_field(ingress_metadata.bd, outer_vlan_bd); + modify_field(ingress_metadata.stp_group, stp_group); +} + +action_profile outer_bd_action_profile { + actions { + /* + * This is the default miss action if the outer bd is not found in this + * table. + */ + set_bd; + set_outer_bd_ipv4_mcast_switch_ipv6_mcast_switch_flags; + set_outer_bd_ipv4_mcast_switch_ipv6_mcast_route_flags; + set_outer_bd_ipv4_mcast_route_ipv6_mcast_switch_flags; + set_outer_bd_ipv4_mcast_route_ipv6_mcast_route_flags; + } + size : OUTER_BD_TABLE_SIZE; +} + +control ingress { + + apply(port_vlan_mapping); + +} diff --git a/backends/tofino/bf-asm/test/proxy_hash1.p4 b/backends/tofino/bf-asm/test/proxy_hash1.p4 new file mode 100644 index 00000000000..685fb7ab4c2 --- /dev/null +++ b/backends/tofino/bf-asm/test/proxy_hash1.p4 @@ -0,0 +1,109 @@ +header_type ethernet_t { + fields { + dst_addr : 48; // width in bits + src_addr : 48; + ethertype : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr : 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 4; + flags : 8; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + length_ : 16; + checksum : 16; + } +} + +header ethernet_t ethernet; +header ipv4_t ipv4; +header tcp_t tcp; +header udp_t udp; + +// Start with ethernet always. +parser start { + return ethernet; +} + +parser ethernet { + extract(ethernet); // Start with the ethernet header + return select(ethernet.ethertype) { + 0x800: ipv4; +// default: ingress; + } +} + +parser ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + //1 : icmp; + 6 : tcp; + 17 : udp; + default: ingress; + } +} + +parser tcp { + extract(tcp); + return ingress; +} + +parser udp { + extract(udp); + return ingress; +} + +action nop() {} +action set_dip() {} + +@pragma proxy_hash_width 24 +table exm_proxy_hash { + reads { + ipv4.srcAddr : exact; + ipv4.dstAddr : exact; + ipv4.protocol : exact; + tcp.srcPort : exact; + tcp.dstPort : exact; + } + actions { + nop; + set_dip; + } + size : 131072; +} + +control ingress { + apply(exm_proxy_hash); +} diff --git a/backends/tofino/bf-asm/test/ptf/action_spec_format.p4 b/backends/tofino/bf-asm/test/ptf/action_spec_format.p4 new file mode 100644 index 00000000000..aa093aa4e5e --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/action_spec_format.p4 @@ -0,0 +1,464 @@ +#include +#include + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm : csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +meter exm_meter1 { + type : bytes; + static : exm_tbl_act_spec_format_1; + result : ipv4.diffserv; + instance_count : 500; +} + +counter exm_cntr1 { + type : packets; + direct : exm_tbl_act_spec_format_1; +} + +meter exm_meter2 { + type : bytes; + direct : exm_tbl_act_spec_format_2; + result : ipv4.diffserv; +} + +counter exm_cntr2 { + type : packets; + static : exm_tbl_act_spec_format_2; + instance_count : 500; +} + +meter exm_meter3 { + type : bytes; + static : exm_tbl_act_spec_format_3; + result : ipv4.diffserv; + instance_count : 500; +} + +counter exm_cntr3 { + type : packets; + static : exm_tbl_act_spec_format_3; + instance_count : 500; +} + +//meter exm_meter4 { +// type : bytes; +// direct : exm_tbl_act_spec_format_4; +// result : ipv4.diffserv; +//} +// +//counter exm_cntr4 { +// type : packets; +// direct : exm_tbl_act_spec_format_4; +//} + +meter tcam_meter1 { + type : bytes; + static : tcam_tbl_act_spec_format_1; + result : ipv4.diffserv; + instance_count : 500; +} + +counter tcam_cntr1 { + type : packets; + direct : tcam_tbl_act_spec_format_1; +} + +meter tcam_meter2 { + type : bytes; + direct : tcam_tbl_act_spec_format_2; + result : ipv4.diffserv; +} + +counter tcam_cntr2 { + type : packets; + static : tcam_tbl_act_spec_format_2; + instance_count : 500; +} + +meter tcam_meter3 { + type : bytes; + static : tcam_tbl_act_spec_format_3; + result : ipv4.diffserv; + instance_count : 500; +} + +counter tcam_cntr3 { + type : packets; + static : tcam_tbl_act_spec_format_3; + instance_count : 500; +} + +//meter tcam_meter4 { +// type : bytes; +// direct : tcam_tbl_act_spec_format_4; +// result : ipv4.diffserv; +//} +// +//counter tcam_cntr4 { +// type : packets; +// direct : tcam_tbl_act_spec_format_4; +//} + +action nop() { +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action next_hop_ipv4(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action next_hop_ipv4_meters_1(egress_port ,srcmac, dstmac, meter_idx) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); + execute_meter(exm_meter1, meter_idx, ipv4.diffserv); +} + +action next_hop_ipv4_stats_2(egress_port ,srcmac, dstmac, stat_idx) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); + count(exm_cntr2, stat_idx); +} + +action next_hop_ipv4_stats_meters_3(egress_port ,srcmac, dstmac, meter_idx, stat_idx) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); + count(exm_cntr3, stat_idx); + execute_meter(exm_meter3, meter_idx, ipv4.diffserv); +} + +action next_hop_ipv4_stats_3(egress_port ,srcmac, dstmac, stat_idx) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); + count(exm_cntr3, stat_idx); +} + +action next_hop_ipv4_meters_3(egress_port ,srcmac, dstmac, meter_idx) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); + execute_meter(exm_meter3, meter_idx, ipv4.diffserv); +} + +action tcam_next_hop_ipv4_meters_1(egress_port ,srcmac, dstmac, meter_idx) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); + execute_meter(tcam_meter1, meter_idx, ipv4.diffserv); +} + +action tcam_next_hop_ipv4_stats_2(egress_port ,srcmac, dstmac, stat_idx) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); + count(tcam_cntr2, stat_idx); +} + +action tcam_next_hop_ipv4_stats_meters_3(egress_port ,srcmac, dstmac, meter_idx, stat_idx) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); + count(tcam_cntr3, stat_idx); + execute_meter(tcam_meter3, meter_idx, ipv4.diffserv); +} + +action tcam_next_hop_ipv4_stats_3(egress_port ,srcmac, dstmac, stat_idx) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); + count(tcam_cntr3, stat_idx); +} + +action tcam_next_hop_ipv4_meters_3(egress_port ,srcmac, dstmac, meter_idx) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); + execute_meter(tcam_meter3, meter_idx, ipv4.diffserv); +} + +/* Exact match table referring to meter table indirectly for one action + * And directly referring to a stats table. + */ + +table exm_tbl_act_spec_format_1 { + reads { + ipv4.srcAddr : exact; + ipv4.dstAddr : exact; + } + actions { + next_hop_ipv4_meters_1; + next_hop_ipv4; + } + default_action: nop(); +} + +/* Exact match table referring to stat table indirectly for one action + * And directly referring to a meter table + */ + +table exm_tbl_act_spec_format_2 { + reads { + ipv4.srcAddr : exact; + ipv4.dstAddr : exact; + } + actions { + next_hop_ipv4_stats_2; + next_hop_ipv4; + } + default_action: nop(); +} + +/* Exact match table referring to stat table and meter table indirectly with + * all combinations across four actions. + */ + +table exm_tbl_act_spec_format_3 { + reads { + ipv4.srcAddr : exact; + ipv4.dstAddr : exact; + } + actions { + next_hop_ipv4_stats_meters_3; + next_hop_ipv4_stats_3; + next_hop_ipv4_meters_3; + next_hop_ipv4; + } + default_action: nop(); +} + +/* Exact match table referring to a stat table and meter table directly */ + +table exm_tbl_act_spec_format_4 { + reads { + ipv4.srcAddr : exact; + ipv4.dstAddr : exact; + } + actions { + next_hop_ipv4; + } + default_action: nop(); +} + +/* TCAM table referring to meter table indirectly for one action + * And directly referring to a stats table. + */ + +table tcam_tbl_act_spec_format_1 { + reads { + ipv4.srcAddr : lpm; + ipv4.dstAddr : exact; + } + actions { + tcam_next_hop_ipv4_meters_1; + next_hop_ipv4; + } + default_action: nop(); +} + +/* TCAM table referring to stat table indirectly for one action + * And directly referring to a meter table + */ + +table tcam_tbl_act_spec_format_2 { + reads { + ipv4.srcAddr : lpm; + ipv4.dstAddr : exact; + } + actions { + tcam_next_hop_ipv4_stats_2; + next_hop_ipv4; + } + default_action: nop(); +} + +/* TCAM table referring to stat table and meter table indirectly with + * all combinations across four actions. + */ + +table tcam_tbl_act_spec_format_3 { + reads { + ipv4.srcAddr : lpm; + ipv4.dstAddr : exact; + } + actions { + tcam_next_hop_ipv4_stats_meters_3; + tcam_next_hop_ipv4_stats_3; + tcam_next_hop_ipv4_meters_3; + next_hop_ipv4; + } + default_action: nop(); +} + +/* TCAM table referring to a stat table and meter table directly */ + +table tcam_tbl_act_spec_format_4 { + reads { + ipv4.srcAddr : lpm; + ipv4.dstAddr : exact; + } + actions { + next_hop_ipv4; + nop; + } + default_action: nop(); +} + + +control ingress { + apply(exm_tbl_act_spec_format_2); + apply(tcam_tbl_act_spec_format_2); + apply(exm_tbl_act_spec_format_1); + apply(exm_tbl_act_spec_format_3); + apply(tcam_tbl_act_spec_format_1); + apply(tcam_tbl_act_spec_format_3); + //apply(exm_tbl_act_spec_format_4); +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/ptf/alpm_test.p4 b/backends/tofino/bf-asm/test/ptf/alpm_test.p4 new file mode 100644 index 00000000000..fb2bb8b6d2a --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/alpm_test.p4 @@ -0,0 +1,173 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 4; + flags : 8; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + + +header_type meta_t { + fields { + pad_0 : 4; + vrf : 12; + } +} + + +header ethernet_t ethernet; +header ipv4_t ipv4; +header tcp_t tcp; +metadata meta_t meta; + + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x0800 : parse_ipv4; + default : ingress; + } +} + +parser parse_ipv4 { + extract(ipv4); + return select(ipv4.protocol){ + 0x06 : parse_tcp; + default : ingress; + } +} + +parser parse_tcp { + extract(tcp); + return ingress; +} + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm : csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action ipv4_lpm_hit(egress_port) { + hop(ipv4.ttl, egress_port); +} + +action lpm_miss(){ + drop(); +} + +action nop() {} + +@pragma alpm 1 +table ipv4_alpm { + reads { + meta.vrf: exact; + ipv4.dstAddr: lpm; + } + actions { + ipv4_lpm_hit; + lpm_miss; + nop; + } + size: 8192; +} + +@pragma alpm 1 +@pragma alpm_partitions 1024 +@pragma alpm_subtrees_per_partition 4 +table ipv4_alpm_large { + reads { + meta.vrf: exact; + ipv4.dstAddr: lpm; + } + actions { + ipv4_lpm_hit; + lpm_miss; + nop; + } + size: 200000; +} + +@pragma alpm 1 +table ipv4_alpm_idle { + reads { + ipv4.dstAddr: lpm; + } + actions { + ipv4_lpm_hit; + nop; + } + size: 8192; + support_timeout: true; +} + +/* Main control flow */ +control ingress { + apply(ipv4_alpm); + apply(ipv4_alpm_large); + apply(ipv4_alpm_idle); +} diff --git a/backends/tofino/bf-asm/test/ptf/basic_ipv4.p4 b/backends/tofino/bf-asm/test/ptf/basic_ipv4.p4 new file mode 100644 index 00000000000..2d80e912300 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/basic_ipv4.p4 @@ -0,0 +1,866 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header_type md_t { + fields { + sport:16; + dport:16; + } +} + +metadata md_t md; + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + set_metadata(md.sport, latest.srcPort); + set_metadata(md.dport, latest.dstPort); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + set_metadata(md.sport, latest.srcPort); + set_metadata(md.dport, latest.dstPort); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + learn_meta_1:20; + learn_meta_2:24; + learn_meta_3:25; + learn_meta_4:10; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +header_type range_metadata_t { + fields { + src_range_index : 16; + dest_range_index : 16; + } +} + +metadata range_metadata_t range_mdata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm : csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +field_list learn_1 { + ipv4.ihl; + ipv4.protocol; + ipv4.srcAddr; + ethernet.srcAddr; + ethernet.dstAddr; + ipv4.fragOffset; + ipv4.identification; + routing_metadata.learn_meta_1; + routing_metadata.learn_meta_4; +} + +action learn_1 (learn_meta_1, learn_meta_4) { + generate_digest(FLOW_LRN_DIGEST_RCVR, learn_1); + modify_field(routing_metadata.learn_meta_1, learn_meta_1); + modify_field(routing_metadata.learn_meta_4, learn_meta_4); +} + +field_list learn_2 { + ipv4.ihl; + ipv4.identification; + ipv4.protocol; + ipv4.srcAddr; + ethernet.srcAddr; + ethernet.dstAddr; + ipv4.fragOffset; + routing_metadata.learn_meta_2; + routing_metadata.learn_meta_3; +} + +action learn_2 (learn_meta_2, learn_meta_3) { + generate_digest(FLOW_LRN_DIGEST_RCVR, learn_2); + modify_field(routing_metadata.learn_meta_2, learn_meta_2); + modify_field(routing_metadata.learn_meta_3, learn_meta_3); +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop_ipv4(egress_port /*,srcmac, dstmac*/) { + hop(ipv4.ttl, egress_port); +// modify_field(ethernet.srcAddr, srcmac); +// modify_field(ethernet.dstAddr, dstmac); +} + +action set_srange_mdata(index) { + modify_field(range_mdata.src_range_index, index); +} + +action set_drange_mdata(index) { + modify_field(range_mdata.dest_range_index, index); +} + +action drop_ipv4 () { + drop(); +} + +action next_hop_ipv4(egress_port, srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action mod_mac_adr(egress_port, srcmac, dstmac) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action udp_hdr_add (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + add_header(udp); + modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); + add_to_field(ipv4.totalLen, 8); +} + +action udp_set_dest(port) { + modify_field(udp.dstPort, port); +} +action udp_set_src(port) { + modify_field(udp.srcPort, port); +} +action tcp_set_src_dest(sport, dport) { + modify_field(tcp.srcPort, sport); + modify_field(tcp.dstPort, dport); +} + +action tcp_hdr_rm (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + remove_header(tcp); + modify_field(ipv4.protocol, 0); +// add_to_field(ipv4.totalLen, -20); +// modify_field(ipv4.totalLen, 66); +} + +action modify_tcp_dst_port_1(dstPort, egress_port) { + modify_field(tcp.dstPort, dstPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ipv4.srcAddr, ipAddr); + modify_field(ethernet.dstAddr, dstAddr); + modify_field(tcp.dstPort, tcpPort); +} + +action custom_action_2(egress_port, ipAddr, tcpPort) +{ + modify_field(ipv4.srcAddr, ipAddr); + modify_field(tcp.dstPort, tcpPort); + hop(ipv4.ttl, egress_port); +} + +action custom_action_3(egress_port, dstAddr, dstIp) +{ + modify_field(ipv4.dstAddr, dstIp); + modify_field(ethernet.dstAddr, dstAddr); + hop(ipv4.ttl, egress_port); +} + +action modify_l2 (egress_port, srcAddr, dstAddr, tcp_sport, tcp_dport) { + // Trying for >128 bit action data + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcAddr); + modify_field(ethernet.dstAddr, dstAddr); + modify_field(tcp.dstPort, tcp_dport); + modify_field(tcp.srcPort, tcp_sport); +} + +@pragma command_line --no-dead-code-elimination +@pragma immediate 1 +@pragma stage 0 +table ig_udp { + reads { + ethernet : valid; + ipv4 : valid; + udp : valid; + udp.dstPort : ternary; + } + actions { + nop; + udp_set_dest; + } +} +@pragma immediate 1 +@pragma stage 0 +table eg_udp { + reads { + ethernet : valid; + ipv4 : valid; + udp : valid; + udp.srcPort : exact; + } + actions { + nop; + udp_set_src; + } +} +table ig_udp_ternary_valid { + reads { + ethernet : valid; + ipv4.valid : exact; + udp.valid : ternary; + md.dport : ternary; + } + actions { + nop; + udp_set_dest; + tcp_set_src_dest; + } +} + +@pragma immediate 1 +@pragma stage 0 +table ipv4_routing { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + hop_ipv4; + drop_ipv4; + learn_1; + learn_2; + } + size : 512; +} + +@pragma immediate 1 +@pragma stage 0 +@pragma ways 3 +@pragma pack 5 +table ipv4_routing_exm_ways_3_pack_5 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + modify_tcp_dst_port_1; + } +} + + +@pragma immediate 1 +@pragma stage 1 +@pragma ways 3 +@pragma pack 3 +table ipv4_routing_exm_ways_3_pack_3 { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + custom_action_1; + } +} + +@pragma immediate 1 +@pragma stage 1 +@pragma ways 4 +@pragma pack 3 +table ipv4_routing_exm_ways_4_pack_3_stage_1 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma immediate 1 +@pragma stage 1 +table ipv4_routing_stage_1 { + reads { + ipv4.dstAddr : lpm; + ipv4.srcAddr : exact; + } + actions { + nop; + hop_ipv4; + } + size : 1024; +} + +@pragma stage 2 +table tcam_tbl_stage_2 { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + mod_mac_adr; + } +} + +@pragma stage 2 +@pragma ways 4 +@pragma pack 7 +table ipv4_routing_exm_ways_4_pack_7_stage_2 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + tcp.dstPort : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +@pragma immediate 1 +@pragma stage 3 +@pragma ways 5 +@pragma pack 3 +table ipv4_routing_exm_ways_5_pack_3_stage_3 { + reads { + ipv4.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma immediate 1 +@pragma stage 3 +table udp_add_tbl_stage_3 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + udp_hdr_add; + } +} + +@pragma immediate 1 +@pragma stage 4 +@pragma ways 6 +@pragma pack 3 +table ipv4_routing_exm_ways_6_pack_3_stage_4 { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + + +@pragma immediate 1 +@pragma stage 4 +table tcp_rm_tbl_stage_4 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + tcp_hdr_rm; + } +} + +@pragma immediate 1 +@pragma stage 5 +@pragma ways 3 +@pragma pack 4 +table ipv4_routing_exm_ways_3_pack_4_stage_5 { + reads { + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + modify_tcp_dst_port_1; + } +} + +@pragma stage 6 +@pragma ways 4 +@pragma pack 4 +table ipv4_routing_exm_ways_4_pack_4_stage_6 { + reads { + ethernet.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma immediate 1 +@pragma stage 7 +@pragma ways 5 +@pragma pack 4 +table ipv4_routing_exm_ways_5_pack_4_stage_7 { + reads { + ipv4.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + +@pragma immediate 1 +@pragma stage 8 +table tcam_adt_deep_stage_8 { + reads { + ethernet.srcAddr : ternary; + ethernet.dstAddr : ternary; + ipv4.srcAddr : ternary; + ipv4.dstAddr : ternary; + } + actions { + nop; + modify_l2; + } + size : 3072; +} + +@pragma stage 8 +@pragma ways 4 +@pragma pack 5 +table ipv4_routing_exm_ways_4_pack_5_stage_8 { + reads { + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.srcPort : exact; + tcp.dstPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +@pragma stage 9 +table ipv4_routing_select { + reads { + ipv4.dstAddr: lpm; + } + action_profile : ecmp_action_profile; + size : 512; +} + +field_list ecmp_hash_fields { + ipv4.srcAddr; + ipv4.dstAddr; + ipv4.identification; + ipv4.protocol; +} + +field_list_calculation ecmp_hash { + input { + ecmp_hash_fields; + } +#if defined(BMV2TOFINO) + algorithm : xxh64; +#else + algorithm : random; +#endif + output_width : 64; +} + +action_profile ecmp_action_profile { + actions { + nhop_set; + nop; + } + size : 1024; + // optional + dynamic_action_selection : ecmp_selector; +} + +action_selector ecmp_selector { + selection_key : ecmp_hash; // take a field_list_calculation only + // optional + selection_mode : resilient; // “resilient” or “non-resilient” +} + +action nhop_set(port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +@pragma stage 10 +table tcam_indirect_action { + reads { + ethernet.srcAddr : ternary; + ethernet.dstAddr : ternary; + ethernet.etherType: exact; + ipv4.srcAddr : ternary; + ipv4.dstAddr : ternary; + ipv4.protocol : exact; + ipv4.version : exact; + } + action_profile : indirect_action_profile; + size : 2048; +} + +action modify_ip_id(port, id, srcAddr, dstAddr) { + modify_field(ipv4.identification, id); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); + modify_field(ethernet.srcAddr, srcAddr); + modify_field(ethernet.dstAddr, dstAddr); +} + +action_profile indirect_action_profile { + actions { + nop; + modify_ip_id; + } + size : 1500; +} + +@pragma stage 11 +@pragma ways 6 +@pragma pack 4 +table ipv4_routing_exm_ways_6_pack_4_stage_11 { + reads { + ipv4.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma stage 5 +table tcam_range { + reads { + ipv4.dstAddr : ternary; + tcp.dstPort : range; + } + actions { + nop; + hop_ipv4; + } + size : 1024; +} + +@pragma stage 5 +table tcam_range_ternary_valid { + reads { + tcp.valid : ternary; + ipv4.dstAddr : ternary; + md.dport : range; + } + actions { + nop; + hop_ipv4; + } + size : 1024; +} + +@pragma stage 6 +@pragma entries_with_ranges 1 +table tcam_range_2_fields { + reads { + ipv4.dstAddr : ternary; + tcp.dstPort : range; + tcp.srcPort : range; + } + actions { + nop; + hop_ipv4; + } + size : 1024; +} + +@pragma stage 7 +table src_non_overlap_range_table{ + reads { + tcp.srcPort : range; + } + actions { + nop; + set_srange_mdata; + } + size : 1024; +} + +@pragma stage 7 +table dest_non_overlap_range_table{ + reads { + tcp.dstPort : range; + } + actions { + nop; + set_drange_mdata; + } + size : 1024; +} + +@pragma stage 11 +@pragma entries_with_ranges 1 +table match_range_table{ + reads { + range_mdata.src_range_index : ternary; + range_mdata.dest_range_index : ternary; + tcp.srcPort : range; + tcp.dstPort : range; + ipv4.dstAddr : ternary; + ipv4.srcAddr : ternary; + } + actions { + nop; + hop_ipv4; + } + size : 1024; +} + +action set_mgid() { + modify_field(ig_intr_md_for_tm.mcast_grp_a, 0xAAAA); + modify_field(ig_intr_md_for_tm.mcast_grp_b, 0x5555); +} +action clr_mgid() { + bit_andca(ig_intr_md_for_tm.mcast_grp_a, ig_intr_md_for_tm.mcast_grp_a, ig_intr_md_for_tm.mcast_grp_a); + bit_andca(ig_intr_md_for_tm.mcast_grp_b, ig_intr_md_for_tm.mcast_grp_b, ig_intr_md_for_tm.mcast_grp_b); +} +@pragma stage 10 +table no_key_1 { + actions { + set_mgid; + } +} +@pragma stage 11 +table no_key_2 { + actions { + clr_mgid; + } +} + +/* Main control flow */ +control ingress { + /* A general principle : Always keep the exact match tables ahead of the + * ternary tables in the same stage, except first stage. Logic relating to next-table + * will cause the Tofino model not to launch a lookup on th exact match + * tables if the order is reversed. + */ + // stage 0 + apply(ig_udp); + apply(ig_udp_ternary_valid); + apply(ipv4_routing); + apply(ipv4_routing_exm_ways_3_pack_5); + // stage 1 + apply(ipv4_routing_exm_ways_3_pack_3); + apply(ipv4_routing_exm_ways_4_pack_3_stage_1); + apply(ipv4_routing_stage_1); + // stage 2 + apply(tcam_tbl_stage_2); + apply(ipv4_routing_exm_ways_4_pack_7_stage_2); + // stage 3 + apply(ipv4_routing_exm_ways_5_pack_3_stage_3); + /* Gateway not yet supported */ +// if (ipv4.protocol == 0) { + apply(udp_add_tbl_stage_3); +// } + + // stage 4 + apply(ipv4_routing_exm_ways_6_pack_3_stage_4); +// if (valid(tcp)) { + apply(tcp_rm_tbl_stage_4); +// } + + // stage 5 + apply(ipv4_routing_exm_ways_3_pack_4_stage_5); + apply(tcam_range); + apply(tcam_range_ternary_valid); + // stage 6 + apply(ipv4_routing_exm_ways_4_pack_4_stage_6); + apply(tcam_range_2_fields); + // stage 7 + apply(ipv4_routing_exm_ways_5_pack_4_stage_7); + apply(src_non_overlap_range_table); + apply(dest_non_overlap_range_table); + // stage 8 + apply(tcam_adt_deep_stage_8); + apply(ipv4_routing_exm_ways_4_pack_5_stage_8); + // Stage 9 + apply(ipv4_routing_select); + // Stage 10 + apply(tcam_indirect_action); + apply(no_key_1); + // Stage 11 + apply(match_range_table); + apply(no_key_2); +} + +control egress { + apply(eg_udp); + // Commenting out since modify of egress port is not possible in egress +// apply(ipv4_routing_exm_ways_6_pack_4_stage_11); +} + diff --git a/backends/tofino/bf-asm/test/ptf/basic_ipv4_selector.p4 b/backends/tofino/bf-asm/test/ptf/basic_ipv4_selector.p4 new file mode 100644 index 00000000000..841d5641bba --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/basic_ipv4_selector.p4 @@ -0,0 +1,269 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header_type md_t { + fields { + sport:16; + dport:16; + } +} + +metadata md_t md; + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + set_metadata(md.sport, latest.srcPort); + set_metadata(md.dport, latest.dstPort); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + set_metadata(md.sport, latest.srcPort); + set_metadata(md.dport, latest.dstPort); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + learn_meta_1:20; + learn_meta_2:24; + learn_meta_3:25; + learn_meta_4:10; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +header_type range_metadata_t { + fields { + src_range_index : 16; + dest_range_index : 16; + } +} + +metadata range_metadata_t range_mdata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm : csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action udp_set_src(port) { + modify_field(udp.srcPort, port); +} + +action nop() { +} + +@pragma command_line --no-dead-code-elimination +table ipv4_routing_select { + reads { + ipv4.dstAddr: lpm; + } + action_profile : ecmp_action_profile; + size : 512; +} + +field_list ecmp_hash_fields { + ipv4.srcAddr; + ipv4.dstAddr; + ipv4.identification; + ipv4.protocol; +} + +field_list_calculation ecmp_hash { + input { + ecmp_hash_fields; + } +#if defined(BMV2TOFINO) + algorithm : xxh64; +#else + algorithm : random; +#endif + output_width : 64; +} + +action_profile ecmp_action_profile { + actions { + nhop_set; + nop; + } + size : 1024; + // optional + dynamic_action_selection : ecmp_selector; +} + +action_selector ecmp_selector { + selection_key : ecmp_hash; // take a field_list_calculation only + // optional + selection_mode : resilient; // “resilient” or “non-resilient” +} + +action nhop_set(port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +table eg_udp { + reads { + ethernet : valid; + ipv4 : valid; + udp : valid; + udp.srcPort : exact; + } + actions { + nop; + udp_set_src; + } +} + + +control ingress { + apply(ipv4_routing_select); +} + +control egress { + apply(eg_udp); +} + diff --git a/backends/tofino/bf-asm/test/ptf/basic_switching.p4 b/backends/tofino/bf-asm/test/ptf/basic_switching.p4 new file mode 100644 index 00000000000..0fd3e4a375e --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/basic_switching.p4 @@ -0,0 +1,79 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// This is P4 sample source for basic_switching + +#include "includes/headers.p4" +#include "includes/parser.p4" +#include +#include + +action set_egr(egress_spec) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_spec); +} + +action nop() { +} + +action _drop() { + drop(); +} + +table forward { + reads { + ethernet.dstAddr : exact; + } + actions { + set_egr; nop; + } +} + +#if 0 +// VLAN based forwarding +table vlan_map { + reads { + ig_intr_md.ingress_port: exact; + vlan.vid : exact; + } + actions { + set_egr; + } +} + +#endif + +table acl { + reads { + ethernet.dstAddr : ternary; + ethernet.srcAddr : ternary; + } + actions { + nop; + _drop; + } +} + +control ingress { + apply(forward); +#if 0 + apply(vlan_map); +#endif +} + +control egress { + apply(acl); +} + diff --git a/backends/tofino/bf-asm/test/ptf/dkm.p4 b/backends/tofino/bf-asm/test/ptf/dkm.p4 new file mode 100644 index 00000000000..413ead4cb47 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/dkm.p4 @@ -0,0 +1,214 @@ +#include +#include +#include + +#define VLAN_DEPTH 2 +#define ETHERTYPE_VLAN 0x8100 +#define ETHERTYPE_IPV4 0x0800 + + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr : 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl :3; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type metadata_t { + fields { + table_hit : 1; + table_id : 8; + } +} + +header ethernet_t ethernet; +header vlan_tag_t vlan_tag; +header ipv4_t ipv4; +header tcp_t tcp; +metadata metadata_t md; + +parser start { + return parse_ethernet; +} + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan; + default : ingress; + } +} + +parser parse_vlan { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default: ingress; + } +} + +parser parse_ipv4 { + extract(ipv4); + return select (latest.protocol) { + 6 : parse_tcp; + default: ingress; + } +} + +parser parse_tcp { + extract(tcp); + return ingress; +} + +action switch_to_dest_port (dport) { + modify_field(md.table_hit, 1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, dport); +} + +action switch_to_miss_port(miss_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, miss_port); +} + +action nop() { +} + + +/* + * Exm tables covering following scenarios are implemented/Tested using this p4. + * - Multiple match spec packed in one sram RAM word. + * - Multiple match spec packed in more than one sram RAM word. + * - More than 1 way. + * - Table spaning more than 1 stage. + */ + + + +@pragma stage 0 +@pragma ways 3 +@pragma pack 2 +@pragma dynamic_table_key_masks 1 +table l2_stage0_ways_3_pack_2 { + reads { + ethernet.srcAddr : exact; + ethernet.dstAddr : exact; + } + actions { + switch_to_dest_port; + } + size : 1024; +} + + +@pragma stage 1 +@pragma ways 6 +@pragma pack 2 +@pragma dynamic_table_key_masks 1 +table l2_stage1_ways_6_pack_2 { + reads { + ethernet.srcAddr : exact; + ethernet.dstAddr : exact; + } + actions { + switch_to_dest_port; + } + size : 1024; +} + + +@pragma stage 2 +@pragma ways 6 +@pragma pack 3 +@pragma dynamic_table_key_masks 1 +table l2_stage2_ways_6_pack_3 { + reads { + ethernet.srcAddr : exact; + ethernet.dstAddr : exact; + } + actions { + switch_to_dest_port; + } + size : 1024; +} + +@pragma ways 6 +@pragma pack 3 +@pragma dynamic_table_key_masks 1 +table l2_multistage_ways_6_pack_3 { + reads { + ethernet.srcAddr : exact; + ethernet.dstAddr : exact; + } + actions { + switch_to_dest_port; + } + size: 64000; +} + + + +table miss_check { + reads { + md.table_hit : exact; + } + actions { + switch_to_miss_port; + } + size : 1; +} + + + +control ingress { + apply(l2_stage0_ways_3_pack_2); + apply(l2_stage1_ways_6_pack_2); + apply(l2_stage2_ways_6_pack_3); + apply(l2_multistage_ways_6_pack_3); + apply(miss_check); +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/ptf/drivers_test.p4 b/backends/tofino/bf-asm/test/ptf/drivers_test.p4 new file mode 100644 index 00000000000..3be6e1a4423 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/drivers_test.p4 @@ -0,0 +1,477 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "tofino/intrinsic_metadata.p4" +#include "tofino/constants.p4" +#include "p4features.h" + +#if defined(STATEFUL_DIRECT) || defined(STATEFUL_INDIRECT) +#include "tofino/stateful_alu_blackbox.p4" +#endif + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type ipv6_t { + fields { + version : 4; + trafficClass : 8; + flowLabel : 20; + payloadLen : 16; + nextHdr : 8; + hopLimit : 8; + srcAddr : 128; + dstAddr : 128; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + 0x86dd : parse_ipv6; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; +header ipv6_t ipv6; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +parser parse_ipv6 { + extract(ipv6); + return select(latest.nextHdr) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default : ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm : csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +#if defined(STATS_DIRECT) || defined(STATS_INDIRECT) +counter cntr { + type : packets; +#ifdef STATS_DIRECT + direct : match_tbl; +#elif defined(STATS_INDIRECT) +// static : match_tbl; + instance_count : STATS_COUNT; +#endif +} +#endif + +#if defined(METER_DIRECT) || defined(METER_INDIRECT) +meter mtr { + type : bytes; +#ifdef METER_DIRECT + direct : match_tbl; +// result : ig_intr_md_for_tm.packet_color; + result : ipv4.diffserv; +#elif defined(METER_INDIRECT) +// static : match_tbl; +// result : ig_intr_md_for_tm.packet_color; +// result : ipv4.diffserv; + instance_count : METER_COUNT; +#endif +} +#endif + +#if defined(STATEFUL_DIRECT) +register r { + width : 32; + direct : match_tbl; +} +blackbox stateful_alu r_alu { + reg: r; + initial_register_lo_value: 1; + update_lo_1_value: register_lo + 1; +} +#endif + +#if defined(STATEFUL_INDIRECT) +register r { + width : 32; + instance_count: STATEFUL_COUNT; +} +blackbox stateful_alu r_alu1 { + reg: r; + initial_register_lo_value: 1; + update_lo_1_value: register_lo + 1; +} +blackbox stateful_alu r_alu2 { + reg: r; + initial_register_lo_value: 1; + update_lo_1_value: register_lo + 100; +} +blackbox stateful_alu r_alu3 { + reg: r; + initial_register_lo_value: 1; + update_lo_1_value: register_lo + 1234; +} +blackbox stateful_alu r_alu4 { + reg: r; + initial_register_lo_value: 1; + update_lo_1_value: register_lo + 333; +} +#endif + + +action tcp_sport_modify (sPort, port) { + modify_field(tcp.srcPort, sPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +#ifdef STATEFUL_DIRECT + r_alu.execute_stateful_alu(); +#endif +} + +action tcp_dport_modify (dPort, port +#ifdef STATEFUL_INDIRECT + , stful_idx +#endif + ) { + modify_field(tcp.dstPort, dPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +#ifdef STATEFUL_INDIRECT + r_alu1.execute_stateful_alu(stful_idx); +#endif +#ifdef STATEFUL_DIRECT + r_alu.execute_stateful_alu(); +#endif +} + +action ipsa_modify (ipsa, port +#ifdef STATS_INDIRECT + ,stat_idx +#endif +#ifdef METER_INDIRECT + , meter_idx +#endif +#ifdef STATEFUL_INDIRECT + , stful_idx +#endif + ) { + modify_field(ipv4.srcAddr, ipsa); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +#ifdef STATS_INDIRECT + count(cntr, stat_idx); +#endif +#ifdef METER_INDIRECT +// execute_meter(mtr, meter_idx, ig_intr_md_for_tm.packet_color); + execute_meter(mtr, meter_idx, ipv4.diffserv); +#endif +#ifdef STATEFUL_INDIRECT + r_alu1.execute_stateful_alu(stful_idx); +#endif +#ifdef STATEFUL_DIRECT + r_alu.execute_stateful_alu(); +#endif +} + +action ipda_modify (ipda, port +#ifdef STATEFUL_INDIRECT + , stful_idx +#endif + ) { + modify_field(ipv4.dstAddr, ipda); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +#ifdef STATEFUL_INDIRECT + r_alu2.execute_stateful_alu(stful_idx); +#endif +#ifdef STATEFUL_DIRECT + r_alu.execute_stateful_alu(); +#endif +} + +action ipds_modify(ds, port +#ifdef STATEFUL_INDIRECT + , stful_idx +#endif + ) { + modify_field(ipv4.diffserv, ds); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +#ifdef STATEFUL_INDIRECT + r_alu3.execute_stateful_alu(stful_idx); +#endif +#ifdef STATEFUL_DIRECT + r_alu.execute_stateful_alu(); +#endif +} + +action ipttl_modify(ttl, port +#ifdef STATEFUL_INDIRECT + , stful_idx +#endif + ) { + modify_field(ipv4.ttl, ttl); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +#ifdef STATEFUL_INDIRECT + r_alu4.execute_stateful_alu(stful_idx); +#endif +#ifdef STATEFUL_DIRECT + r_alu.execute_stateful_alu(); +#endif +} + +#ifdef SELECTOR_INDIRECT +field_list ecmp_hash_fields { + ipv4.srcAddr; + ipv4.dstAddr; + ipv4.identification; + ipv4.protocol; +} + +field_list_calculation ecmp_hash { + input { + ecmp_hash_fields; + } + algorithm : random; + output_width : 72; +} + +action_selector ecmp_selector { + selection_key : ecmp_hash; // take a field_list_calculation only + // optional + selection_mode : resilient; // “resilient” or “non-resilient” +} +#endif + +#ifdef ACTION_INDIRECT +#ifdef STATS_INDIRECT +@pragma bind_indirect_res_to_match cntr +#endif +#ifdef METER_INDIRECT +@pragma bind_indirect_res_to_match mtr +#endif +#ifdef STATEFUL_INDIRECT +@pragma bind_indirect_res_to_match r +#endif +action_profile selector_profile { + actions { + tcp_sport_modify; + tcp_dport_modify; + ipsa_modify; + ipda_modify; + ipds_modify; + ipttl_modify; + } + size : ACTION_COUNT; +#ifdef SELECTOR_INDIRECT + dynamic_action_selection : ecmp_selector; +#endif +} +#endif + +#ifdef MATCH_EXM +#if MATCH_COUNT > 40000 +@pragma stage 0 8192 +@pragma stage 1 6144 +@pragma stage 2 8192 +@pragma stage 3 6144 +@pragma stage 4 8192 +@pragma stage 5 6144 +@pragma stage 6 8192 +@pragma stage 7 6144 +@pragma stage 8 8192 +@pragma stage 9 6144 +@pragma stage 10 8192 +@pragma stage 11 +#endif +#endif +#ifdef MATCH_ATCAM +@pragma atcam_partition_index vlan_tag.vlan_id +#endif +#ifdef MATCH_ALPM +@pragma alpm 1 +#endif +#ifdef SELECTOR_INDIRECT +@pragma selector_max_group_size 20 +@pragma selector_num_max_groups SELECTOR_COUNT +#endif +table match_tbl { + reads { +#ifdef MATCH_EXM + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + ipv4.protocol : exact; + ethernet.dstAddr : exact; +#elif defined(MATCH_TCAM) + ipv4.dstAddr:ternary; +#elif defined(MATCH_ATCAM) + ipv4.dstAddr : ternary; + vlan_tag.vlan_id : exact; +#elif defined(MATCH_ALPM) + ipv4.dstAddr : lpm; + vlan_tag.vlan_id : exact; +#endif + } +#ifdef ACTION_INDIRECT + action_profile : selector_profile; +#elif defined(ACTION_DIRECT) + actions { + tcp_sport_modify; + tcp_dport_modify; + ipsa_modify; + ipda_modify; + ipds_modify; + ipttl_modify; + } +#endif + size : MATCH_COUNT; +#ifdef SUPPORT_IDLE + support_timeout: true; +#endif +} + +/* Main control flow */ +control ingress { + apply(match_tbl); +} + +control egress { +} + diff --git a/backends/tofino/bf-asm/test/ptf/easy.p4 b/backends/tofino/bf-asm/test/ptf/easy.p4 new file mode 100644 index 00000000000..6b5cd0dda55 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/easy.p4 @@ -0,0 +1,32 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header ethernet_t ethernet; + +parser start { + return parse_ethernet; +} + +parser parse_ethernet { + extract(ethernet); + return ingress; +} + +action nop() { } + +action do() { modify_field(ig_intr_md_for_tm.ucast_egress_port, 2); } + +table t { + reads { ig_intr_md.ingress_port : exact; } + actions { nop; do; } + default_action : do(); +} + +control ingress { apply(t); } diff --git a/backends/tofino/bf-asm/test/ptf/easy_ternary.p4 b/backends/tofino/bf-asm/test/ptf/easy_ternary.p4 new file mode 100644 index 00000000000..56fa427edd0 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/easy_ternary.p4 @@ -0,0 +1,32 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header ethernet_t ethernet; + +parser start { + return parse_ethernet; +} + +parser parse_ethernet { + extract(ethernet); + return ingress; +} + +action nop() { } + +action do(val) { modify_field(ig_intr_md_for_tm.ucast_egress_port, val); } + +table t { + reads { ethernet.etherType : lpm; } + actions { nop; do; } + default_action : nop(); +} + +control ingress { apply(t); } diff --git a/backends/tofino/bf-asm/test/ptf/ecmp_pi.p4 b/backends/tofino/bf-asm/test/ptf/ecmp_pi.p4 new file mode 100644 index 00000000000..40b969d1381 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/ecmp_pi.p4 @@ -0,0 +1,221 @@ +/* Copyright 2013-present Barefoot Networks, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +parser start { + return parse_ethernet; +} + +#define ETHERTYPE_IPV4 0x0800 + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + ETHERTYPE_IPV4 : parse_ipv4; + default: ingress; + } +} + +header ipv4_t ipv4; + +field_list ipv4_checksum_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_checksum { + input { + ipv4_checksum_list; + } + algorithm : csum16; + output_width : 16; +} + +calculated_field ipv4.hdrChecksum { + verify ipv4_checksum; + update ipv4_checksum; +} + +#define IP_PROTOCOLS_TCP 6 + +parser parse_ipv4 { + extract(ipv4); + return select(latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + default: ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + + +action _drop() { + drop(); +} + +header_type routing_metadata_t { + fields { + nhop_ipv4 : 32; + } +} + +metadata routing_metadata_t routing_metadata; + +action set_nhop(nhop_ipv4, port) { + modify_field(routing_metadata.nhop_ipv4, nhop_ipv4); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); + add_to_field(ipv4.ttl, -1); +} + +#define ECMP_BIT_WIDTH 16 +#define ECMP_GROUP_TABLE_SIZE 1024 +#define ECMP_SELECT_TABLE_SIZE 16384 + +field_list l3_hash_fields { + ipv4.srcAddr; + ipv4.dstAddr; + ipv4.protocol; + tcp.srcPort; + tcp.dstPort; +} + +field_list_calculation ecmp_hash { + input { + l3_hash_fields; + } + algorithm : crc16; + output_width : ECMP_BIT_WIDTH; +} + +table ecmp_group { + reads { + ipv4.dstAddr : lpm; + } + action_profile: ecmp_action_profile; + size : ECMP_GROUP_TABLE_SIZE; +} + +action_selector ecmp_selector { + selection_key : ecmp_hash; +} + +action_profile ecmp_action_profile { + actions { + _drop; + set_nhop; + } + size : ECMP_SELECT_TABLE_SIZE; + dynamic_action_selection : ecmp_selector; +} + +action set_dmac(dmac) { + modify_field(ethernet.dstAddr, dmac); +} + +table forward { + reads { + routing_metadata.nhop_ipv4 : exact; + } + actions { + set_dmac; + _drop; + } + size: 512; +} + +action rewrite_mac(smac) { + modify_field(ethernet.srcAddr, smac); +} + +table send_frame { + reads { + eg_intr_md.egress_port: exact; + } + actions { + rewrite_mac; + _drop; + } + size: 256; +} + +control ingress { + if(valid(ipv4) and ipv4.ttl != 0) { + apply(ecmp_group); + apply(forward); + } +} + +control egress { + apply(send_frame); +} diff --git a/backends/tofino/bf-asm/test/ptf/emulation.p4 b/backends/tofino/bf-asm/test/ptf/emulation.p4 new file mode 100644 index 00000000000..765936d6a66 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/emulation.p4 @@ -0,0 +1,202 @@ +#include +#include +#include + +#define VLAN_DEPTH 2 +#define ETHERTYPE_VLAN 0x8100 +#define ETHERTYPE_IPV4 0x0800 + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + + +header ethernet_t ethernet; +header vlan_tag_t vlan_tag_; + +parser start { + return parse_ethernet; +} + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + ETHERTYPE_VLAN : parse_vlan; + default : ingress; + } +} + +parser parse_vlan { + extract(vlan_tag_); + return ingress; +} + + +action dmac_miss(flood_mc_index) { + modify_field(ig_intr_md_for_tm.mcast_grp_a, flood_mc_index); +} + +action dmac_unicast_hit(egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action dmac_multicast_hit(mc_index) { + modify_field(ig_intr_md_for_tm.mcast_grp_a, mc_index); + modify_field(ig_intr_md_for_tm.enable_mcast_cutthru, 1); +} + +action dmac_uc_mc_hit(egress_port, mc_index) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ig_intr_md_for_tm.mcast_grp_a, mc_index); + modify_field(ig_intr_md_for_tm.enable_mcast_cutthru, 1); +} + +table dmac { + reads { + ethernet.dstAddr : exact; + } + actions { + dmac_miss; + dmac_unicast_hit; + dmac_multicast_hit; + dmac_uc_mc_hit; + } + size : 4096; +} + +action qos_miss() { + modify_field(ig_intr_md_for_tm.ingress_cos, 0); + modify_field(ig_intr_md_for_tm.qid, 0); +} + +action qos_hit_eg_bypass_no_mirror(qid, color) { + modify_field(ig_intr_md_for_tm.ingress_cos, 1); + modify_field(ig_intr_md_for_tm.qid, qid); + bypass_egress(); +#ifndef SINGLE_STAGE + modify_field(ig_intr_md_for_tm.packet_color, color); +#else + modify_field(ig_intr_md_for_tm._pad5, color); +#endif /* !SINGLE_STAGE */ +} + +action qos_hit_no_eg_bypass_no_mirror(qid, color) { + modify_field(ig_intr_md_for_tm.ingress_cos, 1); + modify_field(ig_intr_md_for_tm.qid, qid); +#ifndef SINGLE_STAGE + modify_field(ig_intr_md_for_tm.packet_color, color); +#else + modify_field(ig_intr_md_for_tm._pad5, color); +#endif /* !SINGLE_STAGE */ +} + +action qos_hit_eg_bypass_i2e_mirror(qid, mirror_id) { + modify_field(ig_intr_md_for_tm.ingress_cos, 1); + modify_field(ig_intr_md_for_tm.qid, qid); + bypass_egress(); + clone_ingress_pkt_to_egress(mirror_id); +} + +action qos_hit_e2e_mirror(qid, mirror_id) { + clone_egress_pkt_to_egress(mirror_id); +} + + +table ingress_qos { + reads { + vlan_tag_: valid; + vlan_tag_.vid : exact; + } + actions { + qos_miss; + qos_hit_eg_bypass_i2e_mirror; + qos_hit_eg_bypass_no_mirror; + qos_hit_no_eg_bypass_no_mirror; + } + size : 8192; +} + +action do_resubmit() { + resubmit(); +} + +table resubmit_tbl { + actions { do_resubmit; } +} + +action do_deflect_on_drop() { + modify_field(ig_intr_md_for_tm.deflect_on_drop, 1); +} + +table deflect_on_drop_tbl { + actions { do_deflect_on_drop; } +} + +action do_recirc() { + recirculate(68); + invalidate(ig_intr_md_for_tm.mcast_grp_a); +} + +action noop() { + no_op(); +} + +table recirc_tbl { + reads { + ig_intr_md.ingress_port : exact; + } + actions { + do_recirc; + noop; + } +} + + +table egress_qos { + reads { + vlan_tag_: valid; + vlan_tag_.vid : exact; + } + actions { + qos_hit_e2e_mirror; + } + size : 8192; +} + + + +control ingress { + apply(dmac); + apply(ingress_qos); +#ifndef SINGLE_STAGE + if (0 == ig_intr_md.resubmit_flag and + 1 == vlan_tag_.pcp) { + apply(resubmit_tbl); + } else + if (2 == vlan_tag_.pcp) { + apply(deflect_on_drop_tbl); + } else + if (3 == vlan_tag_.pcp) { + apply(recirc_tbl); + } +#endif /* !SINGLE_STAGE */ +} + +control egress { + if (pkt_is_not_mirrored) { + apply(egress_qos); + } +} diff --git a/backends/tofino/bf-asm/test/ptf/exm_direct.p4 b/backends/tofino/bf-asm/test/ptf/exm_direct.p4 new file mode 100644 index 00000000000..32962153718 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/exm_direct.p4 @@ -0,0 +1,723 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "tofino_exm.p4" +#include "tofino/intrinsic_metadata.p4" +#include "tofino/constants.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type ipv6_t { + fields { + version : 4; + trafficClass : 8; + flowLabel : 20; + payloadLen : 16; + nextHdr : 8; + hopLimit : 8; + srcAddr : 128; + dstAddr : 128; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + 0x86dd : parse_ipv6; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; +header ipv6_t ipv6; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +parser parse_ipv6 { + extract(ipv6); + return select(latest.nextHdr) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default : ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm : csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action egress_port(egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop_ipv4(egress_port /*,srcmac, dstmac*/) { + hop(ipv4.ttl, egress_port); +// modify_field(ethernet.srcAddr, srcmac); +// modify_field(ethernet.dstAddr, dstmac); +} + +action drop_ipv4 () { + drop(); +} + +action next_hop_ipv4(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action next_hop_ipv6(egress_port ,srcmac, dstmac) { + hop(ipv6.hopLimit, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action ig_drop() { +// modify_field(routing_metadata.drop, 1); + add_to_field(ipv4.ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); +} + +action mod_mac_addr(egress_port, srcmac, dstmac) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action udp_hdr_add (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + add_header(udp); + modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); + add_to_field(ipv4.totalLen, 8); +} + +action tcp_hdr_rm (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + remove_header(tcp); + modify_field(ipv4.protocol, 0); +// add_to_field(ipv4.totalLen, -20); +// modify_field(ipv4.totalLen, 66); +} + +action modify_tcp_dst_port(dstPort) { + modify_field(tcp.dstPort, dstPort); +} + +action modify_tcp_dst_port_1(dstPort, egress_port) { + modify_field(tcp.dstPort, dstPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ipv4.srcAddr, ipAddr); + modify_field(ethernet.dstAddr, dstAddr); + modify_field(tcp.dstPort, tcpPort); +} + +action custom_action_2(egress_port, ipAddr, tcpPort) +{ + modify_field(ipv4.srcAddr, ipAddr); + modify_field(tcp.dstPort, tcpPort); + hop(ipv4.ttl, egress_port); +} + +action custom_action_3(egress_port, dstAddr, dstIp) +{ + modify_field(ipv4.dstAddr, dstIp); + modify_field(ethernet.dstAddr, dstAddr); + hop(ipv4.ttl, egress_port); +} + +action custom_action_4(egress_port, dstPort, srcPort) +{ + modify_field(tcp.dstPort, dstPort); + modify_field(tcp.srcPort, srcPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_5(dstPort, srcPort) +{ + modify_field(tcp.dstPort, dstPort); + modify_field(tcp.srcPort, srcPort); +} + +action switching_action_1(egress_port/*, vlan_id */) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + //modify_field(vlan_tag.vlan_id, vlan_id); +} + +action nhop_set(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action nhop_set_1(port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +@pragma command_line --no-dead-code-elimination +@pragma stage 0 +@pragma pack 5 +@pragma ways 5 +table exm_5ways_5Entries { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_3; + } + + size : 25600; +} + +@pragma stage 1 +@pragma pack 5 +@pragma ways 6 + +table exm_6ways_5Entries { + reads { + ethernet.dstAddr : exact; + ipv4.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + next_hop_ipv4; + } + size : 30720; +} + +@pragma stage 2 +@pragma pack 6 +@pragma ways 4 + +table exm_4ways_6Entries { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + custom_action_1; + } + size : 24576; +} + +@pragma stage 3 +@pragma pack 6 +@pragma ways 5 + +table exm_5ways_6Entries { + reads { + ethernet.dstAddr : exact; + } + actions { + nop; + custom_action_2; + } + size : 30720; +} + +@pragma stage 4 +@pragma pack 6 +@pragma ways 6 + +table exm_6ways_6Entries { + reads { + ethernet.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + mod_mac_addr; + } + size : 36864; +} + +@pragma stage 5 +@pragma pack 7 +@pragma ways 3 + +table exm_3ways_7Entries { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } + size : 21504; +} + +@pragma stage 6 +@pragma pack 8 +@pragma ways 4 + +table exm_4ways_8Entries { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + modify_tcp_dst_port_1; + } + size : 32768; +} + +field_list ecmp_hash_fields { + ipv4.srcAddr; + ipv4.dstAddr; + ipv4.identification; + ipv4.protocol; +} + +field_list_calculation ecmp_hash { + input { + ecmp_hash_fields; + } +#if defined(BMV2TOFINO) + algorithm : xxh64; +#else + algorithm : random; +#endif + output_width : 72; +} + +@pragma stage 7 +@pragma selector_max_group_size 119040 +//@pragma selector_max_group_size 200 +table tcp_port_select { + reads { + ipv4.dstAddr: lpm; + } + action_profile : tcp_port_action_profile; + size : 512; +} + +action_profile tcp_port_action_profile { + actions { + tcp_port_modify; + nop; + } + size : 131072; +// size : 1024; + dynamic_action_selection : ecmp_selector; +} + +action_selector ecmp_selector { + selection_key : ecmp_hash; // take a field_list_calculation only + // optional + selection_mode : resilient; // “resilient” or “non-resilient” +} + +@pragma stage 8 +//@pragma selector_max_group_size 119040 +@pragma selector_max_group_size 100 +table tcp_port_select_exm { + reads { + ipv4.dstAddr: exact; + } + action_profile : tcp_port_action_profile_exm; + size : 512; +} + +action_profile tcp_port_action_profile_exm { + actions { + tcp_port_modify; + nop; + } +// size : 131072; + size : 2048; + dynamic_action_selection : fair_selector; +} + +action_selector fair_selector { + selection_key : ecmp_hash; // take a field_list_calculation only + // optional + selection_mode : non_resilient; // “resilient” or “non-resilient” +} + +action tcp_port_modify(sPort, port) { + modify_field(tcp.srcPort, sPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +@pragma immediate 1 +@pragma stage 9 +@pragma include_idletime 1 +@pragma idletime_precision 2 +table idle_tcam_2 { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + hop_ipv4; + } + size : 512; + support_timeout: true; +} + +@pragma immediate 1 +@pragma stage 9 +@pragma include_idletime 1 +@pragma idletime_precision 6 +table idle_tcam_6 { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + hop_ipv4; + } + size : 512; + support_timeout: true; +} + +@pragma immediate 1 +@pragma stage 9 +@pragma include_idletime 1 +@pragma idletime_precision 3 +@pragma idletime_per_flow_idletime 0 +table idle_tcam_3d { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + hop_ipv4; + } + size : 512; + support_timeout: true; +} + +@pragma immediate 1 +@pragma stage 9 +@pragma include_idletime 1 +@pragma idletime_precision 6 +@pragma idletime_per_flow_idletime 0 +table idle_tcam_6d { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + hop_ipv4; + } + size : 512; + support_timeout: true; +} + +@pragma stage 9 +@pragma pack 1 +@pragma ways 4 +table exm_movereg { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } + size : 4096; +} + +counter exm_cnt { + type : packets; + direct : exm_movereg; +} + +@pragma immediate 1 +@pragma stage 10 +@pragma include_idletime 1 +@pragma idletime_precision 1 +table idle_tcam_1 { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + hop_ipv4; + } + size : 512; + support_timeout: true; +} + +@pragma immediate 1 +@pragma stage 10 +@pragma include_idletime 1 +@pragma idletime_precision 2 +table idle_2 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + hop_ipv4; + } + size : 1024; + support_timeout: true; +} + +@pragma immediate 1 +@pragma stage 10 +@pragma include_idletime 1 +@pragma idletime_precision 3 +table idle_3 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + hop_ipv4; + } + size : 1024; + support_timeout: true; +} + +@pragma immediate 1 +@pragma stage 10 +@pragma include_idletime 1 +@pragma idletime_precision 6 +table idle_6 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + hop_ipv4; + } + size : 1024; + support_timeout: true; +} + +@pragma immediate 1 +@pragma stage 11 +@pragma include_idletime 1 +@pragma idletime_precision 3 +table idle_tcam_3 { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + hop_ipv4; + } + size : 12288; + support_timeout: true; +} + + +/* Main control flow */ +control ingress { + /* A general principle : Always keep the exact match tables ahead of the + * ternary tables in the same stage, except first stage. Logic relating to next-table + * will cause the Tofino model not to launch a lookup on th exact match + * tables if the order is reversed. + */ + apply(exm_5ways_5Entries); + apply(exm_6ways_5Entries); + apply(exm_4ways_6Entries); + apply(exm_5ways_6Entries); + apply(exm_6ways_6Entries); + apply(exm_3ways_7Entries); + apply(exm_4ways_8Entries); + //Stage 7 + apply(tcp_port_select); + // Stage 8 + apply(tcp_port_select_exm); + // Stage 9 + apply(idle_tcam_2); + apply(idle_tcam_6); + apply(idle_tcam_3d); + apply(idle_tcam_6d); + apply(exm_movereg); + //Stage 10 + apply(idle_tcam_1); + apply(idle_2); + apply(idle_3); + apply(idle_6); + //Stage 11 + apply(idle_tcam_3); +} + +action eg_drop() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); + modify_field(intrinsic_metadata.egress_port, 0); +} + +action permit() { +} + +table egress_acl { + reads { + routing_metadata.drop: ternary; + } + actions { + permit; + eg_drop; + } +} + +control egress { +// apply(egress_acl); +} diff --git a/backends/tofino/bf-asm/test/ptf/exm_direct_1.p4 b/backends/tofino/bf-asm/test/ptf/exm_direct_1.p4 new file mode 100644 index 00000000000..236d0ebfd2b --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/exm_direct_1.p4 @@ -0,0 +1,780 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "tofino.p4" +#include "tofino/intrinsic_metadata.p4" +#include "tofino/constants.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type ipv6_t { + fields { + version : 4; + trafficClass : 8; + flowLabel : 20; + payloadLen : 16; + nextHdr : 8; + hopLimit : 8; + srcAddr : 128; + dstAddr : 128; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + 0x86dd : parse_ipv6; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; +header ipv6_t ipv6; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +parser parse_ipv6 { + extract(ipv6); + return select(latest.nextHdr) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default : ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm : csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action egress_port(egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop_ipv4(egress_port /*,srcmac, dstmac*/) { + hop(ipv4.ttl, egress_port); +// modify_field(ethernet.srcAddr, srcmac); +// modify_field(ethernet.dstAddr, dstmac); +} + +action drop_ipv4 () { + drop(); +} + +action next_hop_ipv4(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action next_hop_ipv6(egress_port ,srcmac, dstmac) { + hop(ipv6.hopLimit, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action ig_drop() { +// modify_field(routing_metadata.drop, 1); + add_to_field(ipv4.ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); +} + +action mod_mac_addr(egress_port, dstmac) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ethernet.dstAddr, dstmac); +} + +action udp_hdr_add (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + add_header(udp); + modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); + add_to_field(ipv4.totalLen, 8); +} + +action tcp_hdr_rm (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + remove_header(tcp); + modify_field(ipv4.protocol, 0); +// add_to_field(ipv4.totalLen, -20); +// modify_field(ipv4.totalLen, 66); +} + +action modify_tcp_dst_port(dstPort) { + modify_field(tcp.dstPort, dstPort); +} + +action modify_tcp_dst_port_1(dstPort, egress_port) { + modify_field(tcp.dstPort, dstPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ipv4.srcAddr, ipAddr); + modify_field(ethernet.dstAddr, dstAddr); + modify_field(tcp.dstPort, tcpPort); +} + +action custom_action_2(egress_port, ipAddr, tcpPort) +{ + modify_field(ipv4.srcAddr, ipAddr); + modify_field(tcp.dstPort, tcpPort); + hop(ipv4.ttl, egress_port); +} + +action custom_action_3(egress_port, dstAddr, dstIp) +{ + modify_field(ipv4.dstAddr, dstIp); + modify_field(ethernet.dstAddr, dstAddr); + hop(ipv4.ttl, egress_port); +} + +action custom_action_4(egress_port, dstPort, srcPort) +{ + modify_field(tcp.dstPort, dstPort); + modify_field(tcp.srcPort, srcPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_5(dstPort, srcPort) +{ + modify_field(tcp.dstPort, dstPort); + modify_field(tcp.srcPort, srcPort); +} + +action switching_action_1(egress_port/*, vlan_id */) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + //modify_field(vlan_tag.vlan_id, vlan_id); +} + + +@pragma command_line --no-dead-code-elimination +@pragma pack 7 +@pragma ways 5 +table exm_5ways_7Entries { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + custom_action_3; + } + size : 35840; +} + + + +@pragma stage 0 +@pragma pack 2 + +table exm_6ways_2Entries { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + modify_tcp_dst_port; + } + size : 12288; +} + +@pragma stage 0 +@pragma ways 3 +@pragma pack 1 + +table exm_3ways_1Entries { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } + size : 3072; +} + + +@pragma stage 1 +@pragma ways 4 +@pragma pack 1 + +table exm_4ways_1Entries { + reads { + ipv4.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + custom_action_2; + } + size : 4096; +} + +@pragma stage 2 +@pragma pack 1 +@pragma ways 5 + +table exm_5ways_1Entries { + reads { + ethernet.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_3; + } + + size : 5120; +} + + +@pragma stage 3 +@pragma ways 6 +@pragma pack 7 + +table exm_6ways_7Entries { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } + size : 43008; +} + +@pragma stage 4 +@pragma pack 8 + +table exm_deep_32k { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + custom_action_3; + } + + size : 32768; +} + +@pragma stage 5 +@pragma pack 8 + +table exm_deep_64k { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + modify_tcp_dst_port_1; + } + + size : 65536; +} + +@pragma stage 6 +@pragma pack 1 +@pragma ways 6 + +table exm_6ways_1Entries { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + tcp.dstPort : exact; + tcp.srcPort : exact; + } + actions { + nop; + next_hop_ipv4; + } + size : 6144; +} + +@pragma stage 7 +@pragma pack 2 +@pragma ways 5 + +table exm_5ways_2Entries { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + custom_action_4; + } + + size : 10240; +} + +@pragma stage 8 +@pragma pack 2 +@pragma ways 4 + +table exm_4ways_2Entries { + reads { + ipv4.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + next_hop_ipv4; + } + + size : 8192; +} + +@pragma stage 8 +@pragma pack 2 +@pragma ways 3 + +table exm_3ways_2Entries { + reads { + ipv4.srcAddr : exact; + ipv4.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + custom_action_5; + } + + size : 6144; +} + +@pragma stage 9 + +table exm_wide_key { + reads { + ipv4.srcAddr : exact; + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + tcp.dstPort : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_1; + } + + size : 2048; +} + +@pragma stage 10 +@pragma ways 6 +@pragma pack 8 + +table exm_6ways_8Entries { + reads { + ethernet.dstAddr : exact; + } + actions { + nop; + mod_mac_addr; + } + + size : 49152; +} + +@pragma stage 11 +@pragma ways 5 +@pragma pack 8 + +table exm_5ways_8Entries { + reads { + tcp.dstPort : exact; + } + actions { + nop; + tcp_hdr_rm; + } + + size: 40960; +} + +@pragma ways 3 +@pragma pack 8 + +table exm_3ways_8Entries_stage_1 { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + custom_action_2; + } +} + +@pragma pack 7 +@pragma ways 2 + +table exm_2ways_7Entries_stage_3 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + ipv4.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 8 +@pragma ways 2 + +table exm_2ways_8Entries_stage_3 { + reads { + tcp.dstPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + + + + + +@pragma pack 4 +@pragma ways 2 + +table exm_2ways_4Entries_stage_5 { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma pack 5 +@pragma ways 2 + +table exm_2ways_5Entries_stage_5 { + reads { + tcp.srcPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +@pragma ways 4 +table exm_4ways_16k_stage_5 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } + + size : 16384; +} + +@pragma pack 6 +@pragma ways 2 + +table exm_2ways_6Entries_stage_6 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + + +@pragma ways 5 +table exm_5ways_16k_stage_7 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + tcp.srcPort : exact; + tcp.dstPort : exact; + } + actions { + nop; + next_hop_ipv4; + } + + size : 16384; +} + +@pragma ways 6 +table exm_6ways_32k_stage_8 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + tcp.srcPort : exact; + tcp.dstPort : exact; + } + actions { + nop; + next_hop_ipv4; + } + + size : 32768; +} + +@pragma ways 2 +@pragma pack 2 + +table exm_2ways_32k_stage_9 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + tcp.srcPort : exact; + tcp.dstPort : exact; + } + actions { + nop; + custom_action_3; + } + + size : 32768; +} + +@pragma pack 8 +@pragma ways 4 + +table exm_4ways_8Entries { + reads { + ipv4.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_3; + } +} + + +/* Main control flow */ +control ingress { + /* A general principle : Always keep the exact match tables ahead of the + * ternary tables in the same stage, except first stage. Logic relating to next-table + * will cause the Tofino model not to launch a lookup on th exact match + * tables if the order is reversed. + */ + apply(exm_5ways_7Entries); + apply(exm_6ways_2Entries); + //apply(exm_4ways_8Entries); + apply(exm_3ways_1Entries); + apply(exm_4ways_1Entries); + apply(exm_5ways_1Entries); + apply(exm_6ways_7Entries); + apply(exm_deep_32k); + apply(exm_deep_64k); + apply(exm_6ways_1Entries); + apply(exm_5ways_2Entries); + apply(exm_4ways_2Entries); + apply(exm_3ways_2Entries); + apply(exm_wide_key); + apply(exm_6ways_8Entries); + apply(exm_5ways_8Entries); + ////apply(exm_3ways_8Entries_stage_1); + //apply(exm_2ways_7Entries_stage_3); + ////apply(exm_2ways_8Entries_stage_3); + //apply(exm_2ways_4Entries_stage_5); + //apply(exm_2ways_5Entries_stage_5); + //apply(exm_2ways_6Entries_stage_6); +} + +action eg_drop() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); + modify_field(intrinsic_metadata.egress_port, 0); +} + +action permit() { +} + +table egress_acl { + reads { + routing_metadata.drop: ternary; + } + actions { + permit; + eg_drop; + } +} + +control egress { +// apply(egress_acl); +} + diff --git a/backends/tofino/bf-asm/test/ptf/exm_indirect_1.p4 b/backends/tofino/bf-asm/test/ptf/exm_indirect_1.p4 new file mode 100644 index 00000000000..90e2113ee0d --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/exm_indirect_1.p4 @@ -0,0 +1,893 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "tofino.p4" +#include "tofino/intrinsic_metadata.p4" +#include "tofino/constants.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type ipv6_t { + fields { + version : 4; + trafficClass : 8; + flowLabel : 20; + payloadLen : 16; + nextHdr : 8; + hopLimit : 8; + srcAddr : 128; + dstAddr : 128; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + 0x86dd : parse_ipv6; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; +header ipv6_t ipv6; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +parser parse_ipv6 { + extract(ipv6); + return select(latest.nextHdr) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default : ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm : csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action egress_port(egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop_ipv4(egress_port /*,srcmac, dstmac*/) { + hop(ipv4.ttl, egress_port); +// modify_field(ethernet.srcAddr, srcmac); +// modify_field(ethernet.dstAddr, dstmac); +} + +action drop_ipv4 () { + drop(); +} + +action next_hop_ipv4(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action next_hop_ipv6(egress_port ,srcmac, dstmac) { + hop(ipv6.hopLimit, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action ig_drop() { +// modify_field(routing_metadata.drop, 1); + add_to_field(ipv4.ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); +} + +action mod_mac_addr(egress_port, srcmac, dstmac) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action udp_hdr_add (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + add_header(udp); + modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); + add_to_field(ipv4.totalLen, 8); +} + +action tcp_hdr_rm (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + remove_header(tcp); + modify_field(ipv4.protocol, 0); +// add_to_field(ipv4.totalLen, -20); +// modify_field(ipv4.totalLen, 66); +} + +action modify_tcp_dst_port(dstPort) { + modify_field(tcp.dstPort, dstPort); +} + +action modify_tcp_dst_port_1(dstPort, egress_port) { + modify_field(tcp.dstPort, dstPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ipv4.srcAddr, ipAddr); + modify_field(ethernet.dstAddr, dstAddr); + modify_field(tcp.dstPort, tcpPort); +} + +action custom_action_2(egress_port, ipAddr, tcpPort) +{ + modify_field(ipv4.srcAddr, ipAddr); + modify_field(tcp.dstPort, tcpPort); + hop(ipv4.ttl, egress_port); +} + +action custom_action_3(egress_port, dstAddr, dstIp) +{ + modify_field(ipv4.dstAddr, dstIp); + modify_field(ethernet.dstAddr, dstAddr); + hop(ipv4.ttl, egress_port); +} + +action custom_action_4(egress_port, dstPort, srcPort) +{ + modify_field(tcp.dstPort, dstPort); + modify_field(tcp.srcPort, srcPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_5(dstPort, srcPort) +{ + modify_field(tcp.dstPort, dstPort); + modify_field(tcp.srcPort, srcPort); +} + +action switching_action_1(egress_port/*, vlan_id */) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + //modify_field(vlan_tag.vlan_id, vlan_id); +} + +action nhop_set(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action nhop_set_1(port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action hash_action(value) { + modify_field(ipv4.ttl, value); +} + +action hash_action2(value) { + modify_field(vlan_tag.pri, value); +} + +action_profile custom_action_3_profile { + actions { + nop; + custom_action_3; + egress_port; + } + size : 1024; +} + +action_profile next_hop_ipv4_profile { + actions { + nop; + next_hop_ipv4; + } + + size : 2048; +} + +action_profile next_hop_ipv4_1_profile { + actions { + nop; + next_hop_ipv4; + } + + size : 2048; +} + +action_profile custom_action_1_profile { + actions { + nop; + custom_action_1; + } + size : 2048; +} + +action_profile custom_action_2_profile { + actions { + nop; + custom_action_2; + } + size : 2048; +} + +action_profile mod_mac_addr_profile { + actions { + nop; + mod_mac_addr; + } + size : 1024; +} + +action_profile modify_tcp_dst_port_1_profile { + actions { + nop; + modify_tcp_dst_port_1; + } + size : 1024; +} + +@pragma command_line --no-dead-code-elimination +@pragma stage 0 +@pragma pack 5 +@pragma ways 5 +table exm_5ways_5Entries { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + tcp.srcPort : exact; + } + + action_profile : custom_action_3_profile; + + size : 25600; +} + +@pragma stage 1 +@pragma pack 5 +@pragma ways 6 + +table exm_6ways_5Entries { + reads { + ethernet.dstAddr : exact; + ipv4.dstAddr : exact; + tcp.dstPort : exact; + } + + action_profile : next_hop_ipv4_profile; + + size : 30720; +} + +@pragma stage 2 +@pragma pack 6 +@pragma ways 4 + +table exm_4ways_6Entries { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + + action_profile : custom_action_1_profile; + + size : 24576; +} + +@pragma stage 3 +@pragma pack 6 +@pragma ways 5 + +table exm_5ways_6Entries { + reads { + ethernet.dstAddr : exact; + } + + action_profile : custom_action_2_profile; + + size : 30720; +} + +@pragma stage 4 +@pragma pack 6 +@pragma ways 6 + +table exm_6ways_6Entries { + reads { + ethernet.dstAddr : exact; + tcp.srcPort : exact; + } + + action_profile : mod_mac_addr_profile; + + size : 36864; +} + +@pragma stage 5 +@pragma pack 7 +@pragma ways 3 + +table exm_3ways_7Entries { + reads { + ipv4.dstAddr : exact; + } + + action_profile : next_hop_ipv4_1_profile; + + size : 21504; +} + +@pragma stage 6 +@pragma pack 8 +@pragma ways 4 + +table exm_4ways_8Entries { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + + action_profile : modify_tcp_dst_port_1_profile; + + size : 32768; +} + +@pragma stage 7 + +table exm_ipv4_routing { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + + action_profile : next_hop_profile; + + size : 32768; +} + +action_profile next_hop_profile { + actions { + nhop_set; + nop; + } +size : 4096; +} + +field_list ecmp_hash_fields { + ipv4.srcAddr; + ipv4.dstAddr; + ipv4.identification; + ipv4.protocol; +} + +field_list_calculation ecmp_hash { + input { + ecmp_hash_fields; + } +#if defined(BMV2TOFINO) + algorithm : xxh64; +#else + algorithm : random; +#endif + output_width : 64; +} + +@pragma stage 8 +table ipv4_routing_select { + reads { + ipv4.dstAddr: exact; + } + action_profile : ecmp_action_profile; +} + +@pragma stage 8 +table ipv4_routing_select_iter { + reads { + ipv4.dstAddr: exact; + } + action_profile : ecmp_action_profile_iter; +} + +@pragma stage 9 +table stat_tbl_indirect_pkt_64bit { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + act; + } + + size : 2048; +} + +@pragma stage 9 +table stat_tbl_indirect_pkt_32bit { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + act2; + } + + size : 2048; +} + +@pragma stage 9 +table stat_tbl_indirect_pkt_byte_64bit { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + act5; + } + + size : 2048; +} + +@pragma stage 10 +table stat_tbl_direct_pkt_64bit { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + act1; + } + + size : 2048; +} + +@pragma stage 10 +table stat_tbl_direct_pkt_32bit { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + act4; + } + + size : 2048; +} + +@pragma stage 11 +table stat_tbl_direct_pkt_byte_64bit { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + act1; + } + + size : 2048; +} + +@pragma stage 11 +table stat_tbl_direct_pkt_byte_32bit { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + act1; + } + + size : 2048; +} + +table stat_tcam_direct_pkt_64bit { + reads { + ipv4.dstAddr : lpm; + } + actions { + egr_act1; + } + + size : 2048; +} + +@pragma stage 11 +table hash_action_exm { + reads { + ipv4.ttl : exact; + ipv4 : valid; + } + actions { + hash_action; + } + default_action : hash_action(33); + size : 512; +} + +@pragma stage 11 +table hash_action2_exm { + reads { + vlan_tag.vlan_id : exact; + vlan_tag.pri : exact; + } + actions { + hash_action2; + } + default_action : hash_action2(1); + size : 32768; +} + +header_type l3_metadata_t { + fields { + vrf : 24; + fib_hit : 1; + fib_nexthop : 16; + fib_nexthop_type : 1; + } +} + +metadata l3_metadata_t l3_metadata; + +action fib_hit_nexthop(nexthop_index) { + modify_field(l3_metadata.fib_hit, 1); + modify_field(l3_metadata.fib_nexthop, nexthop_index); + modify_field(l3_metadata.fib_nexthop_type, 0); +} + +action fib_hit_ecmp(ecmp_index) { + modify_field(l3_metadata.fib_hit, 1); + modify_field(l3_metadata.fib_nexthop, ecmp_index); + modify_field(l3_metadata.fib_nexthop_type, 1); +} + +table duplicate_check_exm_immediate_action { + reads { + l3_metadata.vrf : exact; + ipv4.dstAddr : exact; + } + actions { + nop; + fib_hit_nexthop; + fib_hit_ecmp; + } + + size : 2048; +} + +action act(idx, egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + count(cntDum, idx); +} + +action act1(egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action egr_act1(tcp_sport) { + modify_field(tcp.srcPort, tcp_sport); +} + +action act4(egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action act2(idx, egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + count(cntDum3, idx); +} + +action act5(idx, egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + count(cntDum6, idx); +} + +counter cntDum { + type : packets; + static : stat_tbl_indirect_pkt_64bit; + instance_count : 256; +} + +counter cntDum3 { + type : packets; + static : stat_tbl_indirect_pkt_32bit; + instance_count : 256; +} + +counter cntDum1 { + type : packets; + direct : stat_tbl_direct_pkt_64bit; +} + +counter cntDum2 { + type : packets; + direct : stat_tbl_direct_pkt_32bit; + min_width : 20; +} + +counter cntDum4 { + type : packets_and_bytes; + direct : stat_tbl_direct_pkt_byte_64bit; +} + +counter cntDum5 { + type : packets_and_bytes; + direct : stat_tbl_direct_pkt_byte_32bit; + min_width : 20; +} + +counter cntDum6 { + type : packets_and_bytes; + static : stat_tbl_indirect_pkt_byte_64bit; + instance_count : 256; +} + +counter egr_cntDum1 { + type : packets; + direct : stat_tcam_direct_pkt_64bit; +} + +action_profile ecmp_action_profile { + actions { + nop; + nhop_set_1; + } + size : 1024; + // optional + dynamic_action_selection : ecmp_selector; +} + +action_profile ecmp_action_profile_iter { + actions { + nop; + nhop_set_1; + } + size : 1024; + // optional + dynamic_action_selection : ecmp_selector; +} + +action_selector ecmp_selector { + selection_key : ecmp_hash; // take a field_list_calculation only + // optional + selection_mode : resilient; // “resilient” or “non-resilient” +} + +action set_ucast_dest(dest) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, dest); +} + +@pragma stage 11 +table exm_txn_test { + reads { + ig_intr_md.ingress_port : exact; + } + actions { + set_ucast_dest; + } + size : 256; +} + +/* Main control flow */ +control ingress { + /* A general principle : Always keep the exact match tables ahead of the + * ternary tables in the same stage, except first stage. Logic relating to next-table + * will cause the Tofino model not to launch a lookup on th exact match + * tables if the order is reversed. + */ + apply(exm_5ways_5Entries); + apply(exm_6ways_5Entries); + apply(exm_4ways_6Entries); + apply(exm_5ways_6Entries); + apply(exm_6ways_6Entries); + apply(exm_3ways_7Entries); + apply(exm_4ways_8Entries); + apply(exm_ipv4_routing); /* Explicitly managed action data entries */ + apply(ipv4_routing_select); + apply(ipv4_routing_select_iter); + apply(stat_tbl_indirect_pkt_64bit); + apply(stat_tbl_indirect_pkt_32bit); + apply(stat_tbl_indirect_pkt_byte_64bit); + apply(stat_tbl_direct_pkt_64bit); + apply(stat_tbl_direct_pkt_32bit); + apply(stat_tbl_direct_pkt_byte_64bit); + apply(stat_tbl_direct_pkt_byte_32bit); + /* Hash-action tables are always executed. Using gateway condition + of tcp-srcport to prevent all tests from hitting this condition + */ + if (tcp.srcPort == 9000) { + apply(hash_action_exm); + apply(hash_action2_exm); + } + apply(exm_txn_test); +} + +action eg_drop() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); + modify_field(intrinsic_metadata.egress_port, 0); +} + +action permit() { +} + +table egress_acl { + reads { + routing_metadata.drop: ternary; + } + actions { + permit; + eg_drop; + } +} + +action action1() { + add_to_field(ipv4.ttl, -1); +} + +table exm_txn_test1 { + reads { + ipv4.dstAddr : exact; + } + actions { + action1; + } + size : 4096; +} + +control egress { + apply(stat_tcam_direct_pkt_64bit); + apply(duplicate_check_exm_immediate_action); + apply(exm_txn_test1); +// apply(egress_acl); +} + diff --git a/backends/tofino/bf-asm/test/ptf/exm_smoke_test.p4 b/backends/tofino/bf-asm/test/ptf/exm_smoke_test.p4 new file mode 100644 index 00000000000..45bfec06352 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/exm_smoke_test.p4 @@ -0,0 +1,766 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "tofino.p4" +#include "tofino/intrinsic_metadata.p4" +#include "tofino/constants.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type ipv6_t { + fields { + version : 4; + trafficClass : 8; + flowLabel : 20; + payloadLen : 16; + nextHdr : 8; + hopLimit : 8; + srcAddr : 128; + dstAddr : 128; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + 0x86dd : parse_ipv6; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; +header ipv6_t ipv6; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +parser parse_ipv6 { + extract(ipv6); + return select(latest.nextHdr) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default : ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm : csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action egress_port(egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop_ipv4(egress_port /*,srcmac, dstmac*/) { + hop(ipv4.ttl, egress_port); +// modify_field(ethernet.srcAddr, srcmac); +// modify_field(ethernet.dstAddr, dstmac); +} + +action drop_ipv4 () { + drop(); +} + +action next_hop_ipv4(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action next_hop_ipv6(egress_port ,srcmac, dstmac) { + hop(ipv6.hopLimit, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action ig_drop() { +// modify_field(routing_metadata.drop, 1); + add_to_field(ipv4.ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); +} + +action mod_mac_addr(egress_port, srcmac, dstmac) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action udp_hdr_add (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + add_header(udp); + modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); + add_to_field(ipv4.totalLen, 8); +} + +action tcp_hdr_rm (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + remove_header(tcp); + modify_field(ipv4.protocol, 0); +// add_to_field(ipv4.totalLen, -20); +// modify_field(ipv4.totalLen, 66); +} + +action modify_tcp_dst_port(dstPort) { + modify_field(tcp.dstPort, dstPort); +} + +action modify_tcp_dst_port_1(dstPort, egress_port) { + modify_field(tcp.dstPort, dstPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ipv4.srcAddr, ipAddr); + modify_field(ethernet.dstAddr, dstAddr); + modify_field(tcp.dstPort, tcpPort); +} + +action custom_action_2(egress_port, ipAddr, tcpPort) +{ + modify_field(ipv4.srcAddr, ipAddr); + modify_field(tcp.dstPort, tcpPort); + hop(ipv4.ttl, egress_port); +} + +action custom_action_3(egress_port, dstAddr, dstIp) +{ + modify_field(ipv4.dstAddr, dstIp); + modify_field(ethernet.dstAddr, dstAddr); + hop(ipv4.ttl, egress_port); +} + +action custom_action_4(egress_port, dstPort, srcPort) +{ + modify_field(tcp.dstPort, dstPort); + modify_field(tcp.srcPort, srcPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_5(dstPort, srcPort) +{ + modify_field(tcp.dstPort, dstPort); + modify_field(tcp.srcPort, srcPort); +} + +action switching_action_1(egress_port/*, vlan_id */) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + //modify_field(vlan_tag.vlan_id, vlan_id); +} + +action_profile custom_action_3_profile { + actions { + nop; + egress_port; + custom_action_3; + } + size : 2048; +} + +action_profile custom_action_4_profile { + actions { + nop; + custom_action_4; + } + size : 1024; +} + +action_profile custom_action_5_profile { + actions { + nop; + custom_action_5; + } + size : 1024; +} + +action_profile custom_action_3_1_profile { + actions { + nop; + custom_action_3; + } + size : 1024; +} + +action_profile custom_action_3_2_profile { + actions { + nop; + custom_action_3; + } + size : 1024; +} + +action_profile modify_tcp_dst_port_profile { + actions { + nop; + modify_tcp_dst_port; + } + size : 1024; +} + +action_profile modify_tcp_dst_port_1_profile { + actions { + nop; + modify_tcp_dst_port_1; + } + size : 2048; +} + +action_profile next_hop_ipv4_profile { + actions { + nop; + next_hop_ipv4; + } + + size : 1024; +} + +action_profile next_hop_ipv4_1_profile { + actions { + nop; + next_hop_ipv4; + } + + size : 1024; +} + +action_profile next_hop_ipv4_2_profile { + actions { + nop; + next_hop_ipv4; + } + + size : 1024; +} + +action_profile next_hop_ipv4_3_profile { + actions { + nop; + next_hop_ipv4; + } + + size : 1024; +} + +action_profile custom_action_1_profile { + actions { + nop; + custom_action_1; + } + size : 1024; +} + +action_profile custom_action_2_profile { + actions { + nop; + custom_action_2; + } + size : 2048; +} + +action_profile mod_mac_addr_profile { + actions { + nop; + mod_mac_addr; + } + size : 2048; +} + +action_profile tcp_hdr_rm_profile { + actions { + nop; + tcp_hdr_rm; + } + size : 2048; +} + +@pragma command_line --no-dead-code-elimination +@pragma pack 7 +@pragma ways 5 +table exm_5ways_7Entries { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + + action_profile : custom_action_3_profile; + + size : 35840; +} + + + +@pragma stage 0 +@pragma pack 2 +@pragma ways 6 + +table exm_6ways_2Entries { + reads { + ipv4.dstAddr : exact; + } + + action_profile : modify_tcp_dst_port_profile; + + size : 12288; +} + +@pragma stage 0 +@pragma ways 3 +@pragma pack 1 + +table exm_3ways_1Entries { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + + action_profile : next_hop_ipv4_profile; + + size : 3072; +} + + +@pragma stage 1 +@pragma ways 4 +@pragma pack 1 + +table exm_4ways_1Entries { + reads { + ipv4.dstAddr : exact; + tcp.dstPort : exact; + } + + action_profile : custom_action_2_profile; + + size : 4096; +} + +@pragma stage 2 +@pragma pack 1 +@pragma ways 5 + +table exm_5ways_1Entries { + reads { + ethernet.dstAddr : exact; + tcp.srcPort : exact; + } + + action_profile : custom_action_3_1_profile; + + size : 5120; +} + + +@pragma stage 3 +@pragma ways 6 +@pragma pack 7 + +table exm_6ways_7Entries { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + + action_profile : next_hop_ipv4_1_profile; + + size : 43008; +} + +@pragma stage 4 +@pragma pack 8 + +table exm_deep_32k { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + + action_profile : custom_action_3_2_profile; + + size : 32768; +} + +@pragma stage 5 +@pragma pack 8 + +table exm_deep_64k { + reads { + ipv4.dstAddr : exact; + } + + action_profile : modify_tcp_dst_port_1_profile; + + size : 65536; +} + +@pragma stage 6 +@pragma pack 1 +@pragma ways 6 + +table exm_6ways_1Entries { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + tcp.dstPort : exact; + tcp.srcPort : exact; + } + + action_profile : next_hop_ipv4_2_profile; + + size : 6144; +} + +@pragma stage 7 +@pragma pack 2 +@pragma ways 5 + +table exm_5ways_2Entries { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + tcp.dstPort : exact; + } + + action_profile : custom_action_4_profile; + + size : 10240; +} + +@pragma stage 8 +@pragma pack 2 +@pragma ways 4 + +table exm_4ways_2Entries { + reads { + ipv4.dstAddr : exact; + tcp.srcPort : exact; + } + + action_profile : next_hop_ipv4_3_profile; + + size : 8192; +} + +@pragma stage 8 +@pragma pack 2 +@pragma ways 3 + +table exm_3ways_2Entries { + reads { + ipv4.srcAddr : exact; + ipv4.dstAddr : exact; + tcp.dstPort : exact; + } + + action_profile : custom_action_5_profile; + + size : 6144; +} + +@pragma stage 9 + +table exm_wide_key { + reads { + ipv4.srcAddr : exact; + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + tcp.dstPort : exact; + tcp.srcPort : exact; + } + + action_profile : custom_action_1_profile; + + size : 2048; +} + +@pragma stage 10 +@pragma ways 6 +@pragma pack 8 + +table exm_6ways_8Entries { + reads { + ethernet.dstAddr : exact; + } + + action_profile : mod_mac_addr_profile; + + size : 49152; +} + +@pragma stage 11 +@pragma ways 5 +@pragma pack 8 + +table exm_5ways_8Entries { + reads { + tcp.dstPort : exact; + } + + action_profile : tcp_hdr_rm_profile; + + size: 40960; +} + +@pragma pack 5 +@pragma ways 2 + +table exm_2ways_5Entries_stage_5 { + reads { + tcp.srcPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +@pragma ways 4 +table exm_4ways_16k_stage_5 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } + + size : 16384; +} + +@pragma pack 6 +@pragma ways 2 + +table exm_2ways_6Entries_stage_6 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + +@pragma pack 8 +@pragma ways 4 + +table exm_4ways_8Entries { + reads { + ipv4.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_3; + } +} + + +/* Main control flow */ +control ingress { + /* A general principle : Always keep the exact match tables ahead of the + * ternary tables in the same stage, except first stage. Logic relating to next-table + * will cause the Tofino model not to launch a lookup on th exact match + * tables if the order is reversed. + */ + apply(exm_5ways_7Entries); + apply(exm_6ways_2Entries); + //apply(exm_4ways_8Entries); + apply(exm_3ways_1Entries); + apply(exm_4ways_1Entries); + apply(exm_5ways_1Entries); + apply(exm_6ways_7Entries); + apply(exm_deep_32k); + apply(exm_deep_64k); + apply(exm_6ways_1Entries); + apply(exm_5ways_2Entries); + apply(exm_4ways_2Entries); + apply(exm_3ways_2Entries); + apply(exm_wide_key); + apply(exm_6ways_8Entries); + apply(exm_5ways_8Entries); + ////apply(exm_3ways_8Entries_stage_1); + //apply(exm_2ways_7Entries_stage_3); + ////apply(exm_2ways_8Entries_stage_3); + //apply(exm_2ways_4Entries_stage_5); + //apply(exm_2ways_5Entries_stage_5); + //apply(exm_2ways_6Entries_stage_6); +} + +action eg_drop() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); + modify_field(intrinsic_metadata.egress_port, 0); +} + +action permit() { +} + +table egress_acl { + reads { + routing_metadata.drop: ternary; + } + actions { + permit; + eg_drop; + } +} + +control egress { +// apply(egress_acl); +} + diff --git a/backends/tofino/bf-asm/test/ptf/fast_reconfig.p4 b/backends/tofino/bf-asm/test/ptf/fast_reconfig.p4 new file mode 100644 index 00000000000..ac93b004d1f --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/fast_reconfig.p4 @@ -0,0 +1,279 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags_resv : 1; + flags_df : 1; + flags_mf : 1; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type ingress_metadata_t { + fields { + ifid : 32; /* Logical Interface ID */ + brid : 16; /* Bridging Domain ID */ + vrf : 16; + l3 : 1; /* Set if routed */ + } +} + +metadata ingress_metadata_t ing_md; +header ethernet_t ethernet; +header ipv4_t ipv4; +header vlan_tag_t vlan_tag; + + +parser start { + return parse_ethernet; +} + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags_resv; + ipv4.flags_df; + ipv4.flags_mf; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm : csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + + + + + + + +/****************************************************************************** + * + * Table: ing_port + * Key: Incoming physical port number + * Top VLAN tag + * + * Maps the physical port to a logical port and also invalidates the egress + * unicast port and MGID intrinsic metadatas. + * + *****************************************************************************/ +action set_ifid(ifid) { + modify_field(ing_md.ifid, ifid); + /* Set the destination port to an invalid value. */ + modify_field(ig_intr_md_for_tm.ucast_egress_port, 0x1FF); +} + +table ing_port { + reads { + ig_intr_md.ingress_port : exact; + vlan_tag : valid; + vlan_tag.vlan_id : exact; + } + actions { + set_ifid; + } +} + + +/****************************************************************************** + * + * Table: ing_src_ifid + * Key: Logical interface id + * + * Assigns ingress interface specific metadata: iRID, XID, YID, and brid. + * Also sets the hash values used for multicast replication. + * + *****************************************************************************/ +action set_src_ifid_md(rid, yid, brid, h1, h2) { + modify_field(ig_intr_md_for_tm.rid, rid); + modify_field(ig_intr_md_for_tm.level2_exclusion_id, yid); + modify_field(ing_md.brid, brid); + modify_field(ig_intr_md_for_tm.level1_mcast_hash, h1); + modify_field(ig_intr_md_for_tm.level2_mcast_hash, h2); +} + +table ing_src_ifid { + reads { + ing_md.ifid : exact; + } + actions { + set_src_ifid_md; + } +} + + +/****************************************************************************** + * + * Table: ing_dmac + * Key: Bridging domain and DMAC + * + * Will either setup the packet to L2 flood, L2 switch or route. + * + *****************************************************************************/ +action flood() { + modify_field(ig_intr_md_for_tm.mcast_grp_a, ing_md.brid); +} +action switch(egr_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egr_port); +} +action route(vrf) { + modify_field(ing_md.l3, 1); + modify_field(ing_md.vrf, vrf); +} +table ing_dmac { + reads { + ing_md.brid : exact; + ethernet.dstAddr : exact; + } + actions { + flood; + switch; + route; + } +} + + +/****************************************************************************** + * + * Table: ing_ipv4_mcast + * Key: IPv4 addresses and VRF + * + * Will assign MGID and XID + * + *****************************************************************************/ +action mcast_route(xid, mgid1, mgid2) { + modify_field(ig_intr_md_for_tm.level1_exclusion_id, xid); + modify_field(ig_intr_md_for_tm.mcast_grp_a, mgid1); + modify_field(ig_intr_md_for_tm.mcast_grp_b, mgid2); + add_to_field(ipv4.ttl, -1); +} +table ing_ipv4_mcast { + reads { + ing_md.vrf : exact; + ipv4.srcAddr : ternary; + ipv4.dstAddr : ternary; + } + actions { + mcast_route; + } +} + + +control ingress { + apply(ing_port); + apply(ing_src_ifid); + apply(ing_dmac); + if (ing_md.l3 == 1) { + apply(ing_ipv4_mcast); + } +} + + +/****************************************************************************** + * + * Table: egr_encode + * Key: None + * + * Encodes metadata generated by the multicast replication into the packet. + * + *****************************************************************************/ +action do_egr_encode() { + modify_field(ipv4.identification, eg_intr_md.egress_rid); + modify_field(ipv4.diffserv, eg_intr_md.egress_rid_first); +} +table egr_encode { + actions { + do_egr_encode; + } +} + + +control egress { + if (valid(ipv4)) { + apply(egr_encode); + } +} + + diff --git a/backends/tofino/bf-asm/test/ptf/fr_test.p4 b/backends/tofino/bf-asm/test/ptf/fr_test.p4 new file mode 100644 index 00000000000..173e664f671 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/fr_test.p4 @@ -0,0 +1,635 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "tofino/intrinsic_metadata.p4" +#include "tofino/constants.p4" +#include "tofino/stateful_alu_blackbox.p4" + + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} +header ethernet_t ethernet; + +parser start { + return parse_ethernet; +} +parser parse_ethernet { + extract(ethernet); + return ingress; +} + +header_type md_t { + fields { + run_eg : 1; + run_t1 : 1; + run_t2 : 1; + key0 : 32; + t1_hit : 1; + t2_hit : 1; + } +} +metadata md_t md; + +/* Resources for the egress table. */ +counter cntr { + type : packets_and_bytes; + instance_count : 29696; +} +meter mtr { + type : packets; + instance_count : 4096; +} + +/* Resources for the ingress tables. */ +register reg_0 { + width : 32; + instance_count : 36864; +} +blackbox stateful_alu reg_alu_0 { + reg: reg_0; + update_lo_1_value: register_lo + 1; + initial_register_lo_value: 100; +} +register reg_1 { + width : 32; + instance_count : 36864; +} +blackbox stateful_alu reg_alu_1 { + reg: reg_1; + update_lo_1_value: register_lo + 1; + initial_register_lo_value: 100; +} +register reg_2 { + width : 32; + instance_count : 36864; +} +blackbox stateful_alu reg_alu_2 { + reg: reg_2; + update_lo_1_value: register_lo + 1; + initial_register_lo_value: 100; +} +register reg_3 { + width : 32; + instance_count : 36864; +} +blackbox stateful_alu reg_alu_3 { + reg: reg_3; + update_lo_1_value: register_lo + 1; + initial_register_lo_value: 100; +} +register reg_4 { + width : 32; + instance_count : 36864; +} +blackbox stateful_alu reg_alu_4 { + reg: reg_4; + update_lo_1_value: register_lo + 1; + initial_register_lo_value: 100; +} +register reg_5 { + width : 32; + instance_count : 36864; +} +blackbox stateful_alu reg_alu_5 { + reg: reg_5; + update_lo_1_value: register_lo + 1; + initial_register_lo_value: 100; +} +register reg_6 { + width : 32; + instance_count : 36864; +} +blackbox stateful_alu reg_alu_6 { + reg: reg_6; + update_lo_1_value: register_lo + 1; + initial_register_lo_value: 100; +} +register reg_7 { + width : 32; + instance_count : 36864; +} +blackbox stateful_alu reg_alu_7 { + reg: reg_7; + update_lo_1_value: register_lo + 1; + initial_register_lo_value: 100; +} +register reg_8 { + width : 32; + instance_count : 36864; +} +blackbox stateful_alu reg_alu_8 { + reg: reg_8; + update_lo_1_value: register_lo + 1; + initial_register_lo_value: 100; +} +register reg_9 { + width : 32; + instance_count : 36864; +} +blackbox stateful_alu reg_alu_9 { + reg: reg_9; + update_lo_1_value: register_lo + 1; + initial_register_lo_value: 100; +} +register reg_10 { + width : 32; + instance_count : 36864; +} +blackbox stateful_alu reg_alu_10 { + reg: reg_10; + update_lo_1_value: register_lo + 1; + initial_register_lo_value: 100; +} + +meter ing_mtr { + type : packets; + instance_count : 10240; +} + +table t0 { + reads { ig_intr_md.ingress_port : exact; } + actions { set_md; } + size : 288; +} +action set_md(run_eg, run_t1, run_t2, key0) { + modify_field(md.run_eg, run_eg); + modify_field(md.run_t1, run_t1); + modify_field(md.run_t2, run_t2); + modify_field(md.key0, key0); +} + +@pragma ways 4 +@pragma pack 1 +@pragma immediate 0 +@pragma idletime_precision 2 +table t1_0 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + ethernet.etherType : exact; + md.key0 : exact; + } + actions { t1a_0; } + size: 8000; + support_timeout: true; +} +action t1a_0(etype) { + modify_field(md.t1_hit, 1); + modify_field(ethernet.etherType, etype); +} +@pragma ways 4 +@pragma pack 1 +table t2_0 { + reads { + md.key0 : exact; + } + actions { t2a_0; } + size: 7168; +} +action t2a_0(reg_index) { + modify_field(md.t2_hit, 1); + add(md.key0, md.key0, 1); + reg_alu_0.execute_stateful_alu(reg_index); +} + +@pragma ways 4 +@pragma pack 1 +@pragma immediate 0 +@pragma idletime_precision 2 +table t1_1 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + ethernet.etherType : exact; + md.key0 : exact; + } + actions { t1a_1; } + size: 8000; + support_timeout: true; +} +action t1a_1(etype) { + modify_field(md.t1_hit, 1); + modify_field(ethernet.etherType, etype); +} +@pragma ways 4 +@pragma pack 1 +table t2_1 { + reads { + md.key0 : exact; + } + actions { t2a_1; } + size: 7168; +} +action t2a_1(reg_index) { + modify_field(md.t2_hit, 1); + add(md.key0, md.key0, 1); + reg_alu_1.execute_stateful_alu(reg_index); +} + +@pragma ways 4 +@pragma pack 1 +@pragma immediate 0 +@pragma idletime_precision 2 +table t1_2 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + ethernet.etherType : exact; + md.key0 : exact; + } + actions { t1a_2; } + size: 8000; + support_timeout: true; +} +action t1a_2(etype) { + modify_field(md.t1_hit, 1); + modify_field(ethernet.etherType, etype); +} +@pragma ways 4 +@pragma pack 1 +table t2_2 { + reads { + md.key0 : exact; + } + actions { t2a_2; } + size: 7168; +} +action t2a_2(reg_index) { + modify_field(md.t2_hit, 1); + add(md.key0, md.key0, 1); + reg_alu_2.execute_stateful_alu(reg_index); +} + +@pragma ways 4 +@pragma pack 1 +@pragma immediate 0 +@pragma idletime_precision 2 +table t1_3 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + ethernet.etherType : exact; + md.key0 : exact; + } + actions { t1a_3; } + size: 8000; + support_timeout: true; +} +action t1a_3(etype) { + modify_field(md.t1_hit, 1); + modify_field(ethernet.etherType, etype); +} +@pragma ways 4 +@pragma pack 1 +table t2_3 { + reads { + md.key0 : exact; + } + actions { t2a_3; } + size: 7168; +} +action t2a_3(reg_index) { + modify_field(md.t2_hit, 1); + add(md.key0, md.key0, 1); + reg_alu_3.execute_stateful_alu(reg_index); +} + +@pragma ways 4 +@pragma pack 1 +@pragma immediate 0 +@pragma idletime_precision 2 +table t1_4 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + ethernet.etherType : exact; + md.key0 : exact; + } + actions { t1a_4; } + size: 8000; + support_timeout: true; +} +action t1a_4(etype) { + modify_field(md.t1_hit, 1); + modify_field(ethernet.etherType, etype); +} +@pragma ways 4 +@pragma pack 1 +table t2_4 { + reads { + md.key0 : exact; + } + actions { t2a_4; } + size: 7168; +} +action t2a_4(reg_index) { + modify_field(md.t2_hit, 1); + add(md.key0, md.key0, 1); + reg_alu_4.execute_stateful_alu(reg_index); +} + +@pragma ways 4 +@pragma pack 1 +@pragma immediate 0 +@pragma idletime_precision 2 +table t1_5 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + ethernet.etherType : exact; + md.key0 : exact; + } + actions { t1a_5; } + size: 8000; + support_timeout: true; +} +action t1a_5(etype) { + modify_field(md.t1_hit, 1); + modify_field(ethernet.etherType, etype); +} +@pragma ways 4 +@pragma pack 1 +table t2_5 { + reads { + md.key0 : exact; + } + actions { t2a_5; } + size: 7168; +} +action t2a_5(reg_index) { + modify_field(md.t2_hit, 1); + add(md.key0, md.key0, 1); + reg_alu_5.execute_stateful_alu(reg_index); +} + +@pragma ways 4 +@pragma pack 1 +@pragma immediate 0 +@pragma idletime_precision 2 +table t1_6 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + ethernet.etherType : exact; + md.key0 : exact; + } + actions { t1a_6; } + size: 8000; + support_timeout: true; +} +action t1a_6(etype) { + modify_field(md.t1_hit, 1); + modify_field(ethernet.etherType, etype); +} +@pragma ways 4 +@pragma pack 1 +table t2_6 { + reads { + md.key0 : exact; + } + actions { t2a_6; } + size: 7168; +} +action t2a_6(reg_index) { + modify_field(md.t2_hit, 1); + add(md.key0, md.key0, 1); + reg_alu_6.execute_stateful_alu(reg_index); +} + +@pragma ways 4 +@pragma pack 1 +@pragma immediate 0 +@pragma idletime_precision 2 +table t1_7 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + ethernet.etherType : exact; + md.key0 : exact; + } + actions { t1a_7; } + size: 8000; + support_timeout: true; +} +action t1a_7(etype) { + modify_field(md.t1_hit, 1); + modify_field(ethernet.etherType, etype); +} +@pragma ways 4 +@pragma pack 1 +table t2_7 { + reads { + md.key0 : exact; + } + actions { t2a_7; } + size: 7168; +} +action t2a_7(reg_index) { + modify_field(md.t2_hit, 1); + add(md.key0, md.key0, 1); + reg_alu_7.execute_stateful_alu(reg_index); +} + +@pragma ways 4 +@pragma pack 1 +@pragma immediate 0 +@pragma idletime_precision 2 +table t1_8 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + ethernet.etherType : exact; + md.key0 : exact; + } + actions { t1a_8; } + size: 8000; + support_timeout: true; +} +action t1a_8(etype) { + modify_field(md.t1_hit, 1); + modify_field(ethernet.etherType, etype); +} +@pragma ways 4 +@pragma pack 1 +table t2_8 { + reads { + md.key0 : exact; + } + actions { t2a_8; } + size: 7168; +} +action t2a_8(reg_index) { + modify_field(md.t2_hit, 1); + add(md.key0, md.key0, 1); + reg_alu_8.execute_stateful_alu(reg_index); +} + +@pragma ways 4 +@pragma pack 1 +@pragma immediate 0 +@pragma idletime_precision 2 +table t1_9 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + ethernet.etherType : exact; + md.key0 : exact; + } + actions { t1a_9; } + size: 8000; + support_timeout: true; +} +action t1a_9(etype) { + modify_field(md.t1_hit, 1); + modify_field(ethernet.etherType, etype); +} +@pragma ways 4 +@pragma pack 1 +table t2_9 { + reads { + md.key0 : exact; + } + actions { t2a_9; } + size: 7168; +} +action t2a_9(reg_index) { + modify_field(md.t2_hit, 1); + add(md.key0, md.key0, 1); + reg_alu_9.execute_stateful_alu(reg_index); +} + +@pragma ways 4 +@pragma pack 1 +@pragma immediate 0 +@pragma idletime_precision 2 +table t1_10 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + ethernet.etherType : exact; + md.key0 : exact; + } + actions { t1a_10; } + size: 8000; + support_timeout: true; +} +action t1a_10(etype) { + modify_field(md.t1_hit, 1); + modify_field(ethernet.etherType, etype); +} +@pragma ways 4 +@pragma pack 1 +table t2_10 { + reads { + md.key0 : exact; + } + actions { t2a_10; } + size: 7168; +} +action t2a_10(reg_index) { + modify_field(md.t2_hit, 1); + add(md.key0, md.key0, 1); + reg_alu_10.execute_stateful_alu(reg_index); +} + +table t3 { + reads { + ethernet.dstAddr : exact; + ethernet.srcAddr : exact; + ethernet.etherType : exact; + } + actions { t3a; } + size : 24000; +} +action t3a(meter_index) { + execute_meter(ing_mtr, meter_index, ig_intr_md_for_tm.packet_color); +} + +table set_dest { + actions { set_egr_port; } + default_action: set_egr_port; + size : 1; +} +action set_egr_port() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, ig_intr_md.ingress_port); +} +table set_drop { + actions { drop_pkt; } + default_action: drop_pkt; + size : 1; +} +action drop_pkt() { + drop(); +} + +table egr_tbl { + reads { md.key0 : ternary; } + actions { egr_tbl_action; } + size: 147456; +} +action egr_tbl_action(cntr_index, meter_index) { + count(cntr, cntr_index); + execute_meter(mtr, meter_index, ig_intr_md_for_tm.packet_color); +} + + + + +control ingress { + if (0 == ig_intr_md.resubmit_flag) { + apply(t0); + } + if (1 == md.run_t1) { apply(t1_0); } + if (1 == md.run_t2) { apply(t2_0); } + if (1 == md.run_t1) { apply(t1_1); } + if (1 == md.run_t2) { apply(t2_1); } + if (1 == md.run_t1) { apply(t1_2); } + if (1 == md.run_t2) { apply(t2_2); } + if (1 == md.run_t1) { apply(t1_3); } + if (1 == md.run_t2) { apply(t2_3); } + if (1 == md.run_t1) { apply(t1_4); } + if (1 == md.run_t2) { apply(t2_4); } + if (1 == md.run_t1) { apply(t1_5); } + if (1 == md.run_t2) { apply(t2_5); } + if (1 == md.run_t1) { apply(t1_6); } + if (1 == md.run_t2) { apply(t2_6); } + if (1 == md.run_t1) { apply(t1_7); } + if (1 == md.run_t2) { apply(t2_7); } + if (1 == md.run_t1) { apply(t1_8); } + if (1 == md.run_t2) { apply(t2_8); } + if (1 == md.run_t1) { apply(t1_9); } + if (1 == md.run_t2) { apply(t2_9); } + if (1 == md.run_t1) { apply(t1_10); } + if (1 == md.run_t2) { apply(t2_10); } + + if (md.t1_hit == 1 or md.t2_hit == 1 or (md.run_t1 == 0 and md.run_t2 == 0)) { + apply(set_dest); + } else { + apply(set_drop); + } + + apply(t3); +} + +control egress { + if (1 == md.run_eg) { apply(egr_tbl); } +} + diff --git a/backends/tofino/bf-asm/test/ptf/includes/headers.p4 b/backends/tofino/bf-asm/test/ptf/includes/headers.p4 new file mode 100644 index 00000000000..5842e002dc2 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/includes/headers.p4 @@ -0,0 +1,41 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Template headers.p4 file for basic_switching +// Edit this file as needed for your P4 program + +// Here's an ethernet header to get started. + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header ethernet_t ethernet; + +header_type vlan_tag_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + +header vlan_tag_t vlan; diff --git a/backends/tofino/bf-asm/test/ptf/includes/parser.p4 b/backends/tofino/bf-asm/test/ptf/includes/parser.p4 new file mode 100644 index 00000000000..dc5ac2de9e6 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/includes/parser.p4 @@ -0,0 +1,46 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Template parser.p4 file for basic_switching +// Edit this file as needed for your P4 program + +// This parses an ethernet header + +parser start { + return parse_ethernet; +} + +#define ETHERTYPE_VLAN 0x8100 +#define ETHERTYPE_IPV4 0x0800 + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + ETHERTYPE_VLAN : parse_vlan; +// ETHERTYPE_IPV4 : parse_ipv4; + default: ingress; + } +} + +parser parse_vlan { + extract(vlan); + return select(latest.etherType) { +// ETHERTYPE_VLAN : parse_vlan; +// ETHERTYPE_IPV4 : parse_ipv4; + default: ingress; + } +} + diff --git a/backends/tofino/bf-asm/test/ptf/iterator.p4 b/backends/tofino/bf-asm/test/ptf/iterator.p4 new file mode 100644 index 00000000000..8d1248b3d8c --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/iterator.p4 @@ -0,0 +1,195 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "tofino/intrinsic_metadata.p4" + +action n() {} +action N(x) {modify_field(ig_intr_md_for_tm.rid, x);} + +table p0 { + reads { + ig_intr_md.ingress_port : exact; + } + actions {N;} + size: 288; +} +table exm { + reads { + ig_intr_md.ingress_port : exact; + } + actions {n;} +} +table tcam { + reads { + ig_intr_md.ingress_port : ternary; + } + actions {n;} +} +@pragma use_hash_action 1 +table ha { + reads { + ig_intr_md.ingress_port : exact; + } + actions {n;} + default_action : n(); + size: 512; +} +counter ha_cntr { + type: packets; + direct: ha; +} + +@pragma alpm 1 +table alpm { + reads { + ig_intr_md.ingress_port : lpm; + } + actions {n;} +} + +/* + * Shared Counter + */ +counter cntr { + type: packets_and_bytes; + instance_count: 1000; + min_width : 32; +} + +/* + * Shared Selection Table w/ Counter + */ +action a(x) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, x); +} +action b(x,i) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, x); + count(cntr, i); +} +action c(x) { + a(x); + count(cntr, 1); +} +action d(x,y,i) { + modify_field(ipv6.srcAddr, x); + modify_field(ipv6.flowLabel, y); + count(cntr, i); +} +action e() { + count(cntr, 0); +} +action_profile sel_ap { + actions { a;b;c;d;e; } + dynamic_action_selection : sel_as; +} +action_selector sel_as { + selection_key : sel_as_hash; +} +field_list_calculation sel_as_hash { + input { sel_as_hash_fields; } + algorithm : crc32; + output_width : 29; +} +field_list sel_as_hash_fields { + ethernet.dstAddr; + ethernet.srcAddr; +} + +table exm_sel { + reads { + ipv6.valid : exact; + ipv6.srcAddr : exact; + ipv6.dstAddr : exact; + } + action_profile : sel_ap; +} +table tcam_sel { + reads { + ipv6.valid : exact; + ipv6.srcAddr : exact; + ipv6.dstAddr : lpm; + } + action_profile : sel_ap; +} + +/* + * Shared Indirect Action w/ Counter + */ +action_profile ap { + actions { a;b;c;d;e; } +} +table exm_ap { + reads { + ipv6.valid : exact; + ipv6.srcAddr : exact; + ipv6.dstAddr : exact; + } + action_profile : ap; +} +table tcam_ap { + reads { + ipv6.valid : exact; + ipv6.srcAddr : exact; + ipv6.dstAddr : lpm; + } + action_profile : ap; +} + + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} +header_type ipv6_t { + fields { + version : 4; + trafficClass : 8; + flowLabel : 20; + payloadLen : 16; + nextHdr : 8; + hopLimit : 8; + srcAddr : 128; + dstAddr : 128; + } +} +header ethernet_t ethernet; +header ipv6_t ipv6; +parser start { + extract(ethernet); + extract(ipv6); + return ingress; +} +control ingress { + if (0 == ig_intr_md.resubmit_flag) { + apply(p0); + } + apply(exm); + apply(tcam); + apply(ha); + apply(alpm); + if (ig_intr_md.ingress_port == 0) { + apply(exm_sel); + } else if (ig_intr_md.ingress_port == 1) { + apply(tcam_sel); + } else if (ig_intr_md.ingress_port == 2) { + apply(exm_ap); + } else if (ig_intr_md.ingress_port == 3) { + apply(tcam_ap); + } +} diff --git a/backends/tofino/bf-asm/test/ptf/mau_mem_test.p4 b/backends/tofino/bf-asm/test/ptf/mau_mem_test.p4 new file mode 100644 index 00000000000..dc41ffa437e --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/mau_mem_test.p4 @@ -0,0 +1,294 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + default: ingress; + } +} + +header ethernet_t ethernet; + +action action_0(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_1(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_2(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_3(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_4(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_5(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_6(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_7(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_8(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_9(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_10(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_11(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +counter counter_ingress { + type : packets; + instance_count : 512; +} + +action ingress_action(){ + count(counter_ingress, ig_intr_md.ingress_port); +} + +counter counter_egress { + type : packets; + instance_count : 512; +} +action egress_action(){ + count(counter_egress, eg_intr_md.egress_port); +} + +action do_nothing(){} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_0 +table simple_table_0 { + reads { + ethernet.srcAddr mask 0xFFFF : exact; + } + actions { + action_0; + do_nothing; + } + size : 65536; +} + +@pragma stage_0 +table simple_table_ingress { + actions { + ingress_action; + } +} + +//@pragma use_hash_action 1 +table simple_table_egress { + actions { + egress_action; + } +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_1 +table simple_table_1 { + reads { + ethernet.srcAddr mask 0xFFFF : exact; + } + actions { + action_1; + do_nothing; + } + size : 65536; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_2 +table simple_table_2 { + reads { + ethernet.srcAddr mask 0xFFFF : exact; + } + actions { + action_2; + do_nothing; + } + size : 65536; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_3 +table simple_table_3 { + reads { + ethernet.srcAddr mask 0xFFFF : exact; + } + actions { + action_3; + do_nothing; + } + size : 65536; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_4 +table simple_table_4 { + reads { + ethernet.srcAddr mask 0xFFFF : exact; + } + actions { + action_4; + do_nothing; + } + size : 65536; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_5 +table simple_table_5 { + reads { + ethernet.srcAddr mask 0xFFFF : exact; + } + actions { + action_5; + do_nothing; + } + size : 65536; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_6 +table simple_table_6 { + reads { + ethernet.srcAddr mask 0xFFFF : exact; + } + actions { + action_6; + do_nothing; + } + size : 65536; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_7 +table simple_table_7 { + reads { + ethernet.srcAddr mask 0xFFFF : exact; + } + actions { + action_7; + do_nothing; + } + size : 65536; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_8 +table simple_table_8 { + reads { + ethernet.srcAddr mask 0xFFFF : exact; + } + actions { + action_8; + do_nothing; + } + size : 65536; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_9 +table simple_table_9 { + reads { + ethernet.srcAddr mask 0xFFFF : exact; + } + actions { + action_9; + do_nothing; + } + size : 65536; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_10 +table simple_table_10 { + reads { + ethernet.srcAddr mask 0xFFFF : exact; + } + actions { + action_10; + do_nothing; + } + size : 65536; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_11 +table simple_table_11 { + reads { + ethernet.srcAddr mask 0xFFFF : exact; + } + actions { + action_11; + do_nothing; + } + size : 65536; +} + +control ingress { + if (ethernet.etherType == 0) apply(simple_table_0); + if (ethernet.etherType == 1) apply(simple_table_1); + if (ethernet.etherType == 2) apply(simple_table_2); + if (ethernet.etherType == 3) apply(simple_table_3); + if (ethernet.etherType == 4) apply(simple_table_4); + if (ethernet.etherType == 5) apply(simple_table_5); + if (ethernet.etherType == 6) apply(simple_table_6); + if (ethernet.etherType == 7) apply(simple_table_7); + if (ethernet.etherType == 8) apply(simple_table_8); + if (ethernet.etherType == 9) apply(simple_table_9); + if (ethernet.etherType == 10) apply(simple_table_10); + if (ethernet.etherType == 11) apply(simple_table_11); + apply(simple_table_ingress); +} + +control egress { + apply(simple_table_egress); +} + diff --git a/backends/tofino/bf-asm/test/ptf/mau_tcam_test.p4 b/backends/tofino/bf-asm/test/ptf/mau_tcam_test.p4 new file mode 100644 index 00000000000..e0f370e915d --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/mau_tcam_test.p4 @@ -0,0 +1,282 @@ +#include "tofino/intrinsic_metadata.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +parser start { + return parse_ethernet; +} + + +parser parse_ethernet { + extract(ethernet); + return select(ethernet.etherType) { + default: ingress; + } +} + +header ethernet_t ethernet; + +action action_0(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_1(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_2(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_3(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_4(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_5(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_6(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_7(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_8(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_9(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_10(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action action_11(port){ + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +counter counter_ingress { + type : packets; + instance_count : 512; +} + +action ingress_action(){ + count(counter_ingress, ig_intr_md.ingress_port); +} + +counter counter_egress { + type : packets; + instance_count : 512; +} +action egress_action(){ + count(counter_egress, eg_intr_md.egress_port); +} + +action do_nothing(){} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_0 +table simple_table_0 { + reads { + ethernet.srcAddr mask 0x1FFF : ternary; + } + actions { + action_0; + } + size : 8192; +} + +@pragma stage_0 +table simple_table_ingress { + actions { + ingress_action; + } +} + +//@pragma use_hash_action 1 +table simple_table_egress { + actions { + egress_action; + } +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_1 +table simple_table_1 { + reads { + ethernet.srcAddr mask 0x1FFF : ternary; + } + actions { + action_1; + } + size : 8192; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_2 +table simple_table_2 { + reads { + ethernet.srcAddr mask 0x1FFF : ternary; + } + actions { + action_2; + } + size : 8192; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_3 +table simple_table_3 { + reads { + ethernet.srcAddr mask 0x1FFF : ternary; + } + actions { + action_3; + } + size : 8192; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_4 +table simple_table_4 { + reads { + ethernet.srcAddr mask 0x1FFF : ternary; + } + actions { + action_4; + } + size : 8192; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_5 +table simple_table_5 { + reads { + ethernet.srcAddr mask 0x1FFF : ternary; + } + actions { + action_5; + } + size : 8192; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_6 +table simple_table_6 { + reads { + ethernet.srcAddr mask 0x1FFF : ternary; + } + actions { + action_6; + } + size : 8192; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_7 +table simple_table_7 { + reads { + ethernet.srcAddr mask 0x1FFF : ternary; + } + actions { + action_7; + } + size : 8192; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_8 +table simple_table_8 { + reads { + ethernet.srcAddr mask 0x1FFF : ternary; + } + actions { + action_8; + } + size : 8192; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_9 +table simple_table_9 { + reads { + ethernet.srcAddr mask 0x1FFF : ternary; + } + actions { + action_9; + } + size : 8192; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_10 +table simple_table_10 { + reads { + ethernet.srcAddr mask 0x1FFF : ternary; + } + actions { + action_10; + } + size : 8192; +} + +@pragma use_identity_hash 1 +@pragma immediate 0 +@pragma stage_11 +table simple_table_11 { + reads { + ethernet.srcAddr mask 0x1FFF : ternary; + } + actions { + action_11; + } + size : 8192; +} + +control ingress { + if (ethernet.etherType == 0) apply(simple_table_0); + if (ethernet.etherType == 1) apply(simple_table_1); + if (ethernet.etherType == 2) apply(simple_table_2); + if (ethernet.etherType == 3) apply(simple_table_3); + if (ethernet.etherType == 4) apply(simple_table_4); + if (ethernet.etherType == 5) apply(simple_table_5); + if (ethernet.etherType == 6) apply(simple_table_6); + if (ethernet.etherType == 7) apply(simple_table_7); + if (ethernet.etherType == 8) apply(simple_table_8); + if (ethernet.etherType == 9) apply(simple_table_9); + if (ethernet.etherType == 10) apply(simple_table_10); + if (ethernet.etherType == 11) apply(simple_table_11); + apply(simple_table_ingress); +} + +control egress { + apply(simple_table_egress); +} + diff --git a/backends/tofino/bf-asm/test/ptf/mau_test.p4 b/backends/tofino/bf-asm/test/ptf/mau_test.p4 new file mode 100644 index 00000000000..cfae09e6c77 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/mau_test.p4 @@ -0,0 +1,1285 @@ +#include +#include "tofino/stateful_alu_blackbox.p4" +#include "tofino/lpf_blackbox.p4" + +#define VLAN_DEPTH 2 +#define ETHERTYPE_VLAN 0x8100 +#define ETHERTYPE_IPV4 0x0800 + +header_type metadata_t { + fields { + stats_key : 32; + m1_clr : 8; + m1_idx : 32; + m1_drop : 1; + drop_it : 1; + count_it : 2; + resubmit_for_meter_test : 1; + dummy : 1; + mr_clr : 8; + e3_meter : 8; + t3_meter : 8; + e4_meter : 8; + t4_meter : 8; + e5_lpf : 32; + t5_lpf : 32; + e6_lpf : 32; + t6_lpf : 32; + e5_lpf_tmp1 : 32; + t5_lpf_tmp1 : 32; + e6_lpf_tmp1 : 32; + t6_lpf_tmp1 : 32; + e5_lpf_tmp2 : 32; + t5_lpf_tmp2 : 32; + e6_lpf_tmp2 : 32; + t6_lpf_tmp2 : 32; + + e1_stful : 32; + t1_stful : 32; + mr1_fail : 32; + + etherType_hi : 16; + } +} +header_type ethernet_t { + /* Source address is split into two fields as a hack to work around a + * compiler limitation with gateway tables. SrcAddr is used in a gateway + * table but with a mask so really only the masked bits need to be in the + * gateway but the compiler thinks all 48 bits should go in and complains. + * Split the field so that it will "fit" in a gateway. */ + fields { + dstAddr : 48; + srcAddrHi : 16; + srcAddr : 32; + etherType : 16; + } +} + +header_type move_reg_key_t { + fields { + hi : 8; + lo : 8; + } +} +@pragma pa_fragment egress mrk.hi +@pragma pa_fragment egress mrk.lo +header move_reg_key_t mrk; + +metadata metadata_t md; + +@pragma pa_fragment egress ethernet.etherType +header ethernet_t ethernet; + +parser start { + return parse_ethernet; +} + +parser parse_ethernet { + extract(ethernet); + + return select(latest.etherType) { + 0xCCC1 : stat_tag_one; + 0xCCC2 : stat_tag_two; + 0xCCC3 : stat_tag_three; + 0xDEAD : drop_tag; + default : get_move_reg_key; + } +} + +parser stat_tag_one { + set_metadata(md.count_it, 1); + return ingress; +} +parser stat_tag_two { + set_metadata(md.count_it, 2); + return ingress; +} +parser stat_tag_three { + set_metadata(md.count_it, 3); + return ingress; +} +parser drop_tag { + set_metadata(md.drop_it, 1); + return ingress; +} +parser get_move_reg_key { + extract(mrk); + return ingress; +} + + +/* + * Simple table to set packet destination. + */ +action set_dest() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, ig_intr_md.ingress_port); + shift_right(md.etherType_hi, ethernet.etherType, 8); +} +table dest { + actions { set_dest; } +} + + +register mrk_hi_reg { + width : 16; + instance_count : 1024; +} +register mrk_lo_reg { + width : 16; + instance_count : 1024; +} +blackbox stateful_alu set_mrk_hi_alu { + reg: mrk_hi_reg; + update_lo_1_value: md.etherType_hi; + output_value: alu_lo; + output_dst: mrk.hi; +} +blackbox stateful_alu set_mrk_lo_alu { + reg: mrk_lo_reg; + update_lo_1_value: ethernet.etherType & 0xFF; + output_value: alu_lo; + output_dst: mrk.lo; +} +action do_set_mrk_hi() { + set_mrk_hi_alu.execute_stateful_alu(0); +} +action do_set_mrk_lo() { + set_mrk_lo_alu.execute_stateful_alu(0); +} +@pragma stage 1 +table set_mrk_hi { + actions {do_set_mrk_hi;} +} +@pragma stage 0 +table set_mrk_lo { + actions {do_set_mrk_lo;} +} + +/* + * Counter test, 2 ingress and 2 egress counter tables. + */ + +table stats_resubmit { + reads { ethernet.etherType : ternary; } + actions { nothing; do_resubmit; } + default_action: nothing; +} +register stats_key_reg { + width : 64; + instance_count : 2048; +} +blackbox stateful_alu stats_key_alu3 { + /* Register hi: Counts 0..X then resets back to 0. X represents the number + * of back to back packets which should go to the same stats entry. + * Register lo: The stats key, range is 0-11 so there are 12 keys total, it + * will only increment every X packets (i.e. when register_lo resets). + */ + reg: stats_key_reg; + condition_hi: register_hi >= 2; + condition_lo: register_lo >= 11; + update_hi_1_predicate: not condition_hi; + update_hi_1_value: register_hi + 1; + update_hi_2_predicate: condition_hi; + update_hi_2_value: 0; + + update_lo_1_predicate: condition_hi and not condition_lo; + update_lo_1_value: register_lo + 1; + update_lo_2_predicate: condition_lo; + update_lo_2_value: 0; + + output_value: register_lo; + output_dst: md.stats_key; +} +blackbox stateful_alu stats_key_alu1 { + /* Same as stats_key_alu3 but uses a larger space for the output key. */ + reg: stats_key_reg; + condition_hi: register_hi >= 2; + condition_lo: register_lo >= 2099; + update_hi_1_predicate: not condition_hi; + update_hi_1_value: register_hi + 1; + update_hi_2_predicate: condition_hi; + update_hi_2_value: 0; + + update_lo_1_predicate: condition_hi and not condition_lo; + update_lo_1_value: register_lo + 1; + update_lo_2_predicate: condition_lo; + update_lo_2_value: 100; + + output_value: register_lo; + output_dst: md.stats_key; + + initial_register_lo_value: 100; +} +action do_set_stats_key1() { + stats_key_alu1.execute_stateful_alu(0); +} +action do_set_stats_key2() { + modify_field(md.stats_key, 0xFFFFFFFF); +} +action do_set_stats_key3() { + stats_key_alu3.execute_stateful_alu(1); +} +table set_stats_key1 { + actions { do_set_stats_key1; } +} +table set_stats_key2 { + actions { do_set_stats_key2; } +} +table set_stats_key3 { + actions { do_set_stats_key3; } +} + + +@pragma lrt_enable 1 +//@pragma lrt_scale 64 +counter ig_cntr_1 { + type : packets_and_bytes; + instance_count : 32768; + min_width : 32; +} +@pragma lrt_enable 1 +//@pragma lrt_scale 65 +counter ig_cntr_2 { + type : packets_and_bytes; + instance_count : 4096; + min_width : 32; +} +@pragma lrt_enable 1 +//@pragma lrt_scale 64 +counter eg_cntr_1 { + type : packets_and_bytes; + instance_count : 32768; + min_width : 32; +} +@pragma lrt_enable 1 +//@pragma lrt_scale 65 +counter eg_cntr_2 { + type : packets_and_bytes; + instance_count : 4096; + min_width : 32; +} +counter ig_cntr_3 { + type : packets_and_bytes; + instance_count : 16384; +} +counter ig_cntr_4 { + type : packets; + instance_count : 2048; +} +counter eg_cntr_3 { + type : packets_and_bytes; + instance_count : 16384; +} +counter eg_cntr_4 { + type : packets; + instance_count : 2048; +} + + +@pragma stage 1 +table ig_stat_1 { + reads { md.stats_key : exact; } + actions { inc_ig_cntr_1; } + size : 4096; +} + +@pragma stage 1 +table ig_stat_2 { + reads { md.stats_key : exact; } + actions { inc_ig_cntr_2; } + size : 4096; +} + +@pragma stage 1 +table eg_stat_1 { + reads { md.stats_key : exact; } + actions { inc_eg_cntr_1; } + size : 4096; +} + +@pragma stage 1 +table eg_stat_2 { + reads { md.stats_key : exact; } + actions { inc_eg_cntr_2; } + size : 4096; +} + +@pragma stage 6 +table ig_stat_3 { + reads { md.stats_key mask 0xFFF : exact; } + actions { inc_ig_cntr_3; } + size : 4096; +} + +@pragma stage 6 +table ig_stat_4 { + reads { md.stats_key mask 0xFFF : exact; } + actions { inc_ig_cntr_4; } + size : 4096; +} + +@pragma stage 6 +table eg_stat_3 { + reads { md.stats_key mask 0xFFF : exact; } + actions { inc_eg_cntr_3; } + size : 4096; +} + +@pragma stage 6 +table eg_stat_4 { + reads { md.stats_key mask 0xFFF : exact; } + actions { inc_eg_cntr_4; } + size : 4096; +} + +action inc_ig_cntr_1(cntr_index) { + count(ig_cntr_1, cntr_index); +} +action inc_ig_cntr_2(cntr_index) { + count(ig_cntr_2, cntr_index); +} +action inc_ig_cntr_3(cntr_index) { + count(ig_cntr_3, cntr_index); +} +action inc_ig_cntr_4(cntr_index) { + count(ig_cntr_4, cntr_index); +} +action inc_eg_cntr_1(cntr_index) { + count(eg_cntr_1, cntr_index); +} +action inc_eg_cntr_2(cntr_index) { + count(eg_cntr_2, cntr_index); +} +action inc_eg_cntr_3(cntr_index) { + count(eg_cntr_3, cntr_index); +} +action inc_eg_cntr_4(cntr_index) { + count(eg_cntr_4, cntr_index); +} + + +/* + * Idletime test, 16 idletime tables in a mix of 1 and 3 bit mode + */ + +action nothing() {} +@pragma stage 2 +@pragma include_idletime 1 +@pragma idletime_precision 3 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 1 +table ig_idle_1 { reads { ethernet.srcAddr mask 0x3FFF : exact; } actions { nothing; } size : 18432; support_timeout: true;} +@pragma stage 2 +@pragma include_idletime 1 +@pragma idletime_precision 3 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 1 +table ig_idle_2 { reads { ethernet.srcAddr mask 0x3FFF : exact; } actions { nothing; } size : 8192; support_timeout: true;} +@pragma stage 2 +@pragma include_idletime 1 +@pragma idletime_precision 3 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 1 +table ig_idle_3 { reads { ethernet.srcAddr mask 0x3FFF : exact; } actions { nothing; } size : 8192; support_timeout: true;} +@pragma stage 2 +@pragma include_idletime 1 +@pragma idletime_precision 3 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 1 +table ig_idle_4 { reads { ethernet.srcAddr mask 0x3FFF : exact; } actions { nothing; } size : 8192; support_timeout: true;} +@pragma stage 2 +@pragma include_idletime 1 +@pragma idletime_precision 3 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 1 +table ig_idle_5 { reads { ethernet.srcAddr mask 0x3FFF : exact; } actions { nothing; } size : 8192; support_timeout: true;} +@pragma stage 2 +@pragma include_idletime 1 +@pragma idletime_precision 3 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 1 +table ig_idle_6 { reads { ethernet.srcAddr mask 0x3FFF : exact; } actions { nothing; } size : 8192; support_timeout: true;} +@pragma stage 2 +@pragma include_idletime 1 +@pragma idletime_precision 3 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 1 +table ig_idle_7 { reads { ethernet.srcAddr mask 0x3FFF : exact; } actions { nothing; } size : 8192; support_timeout: true;} +@pragma stage 2 +@pragma include_idletime 1 +@pragma idletime_precision 3 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 1 +table ig_idle_8 { reads { ethernet.srcAddr mask 0x3FFF : exact; } actions { nothing; } size : 8192; support_timeout: true;} +@pragma stage 2 +@pragma include_idletime 1 +@pragma idletime_precision 3 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 0 +table ig_idle_9 { reads { ethernet.srcAddr mask 0x3FFF : ternary; } actions { nothing; } size : 1536; support_timeout: true;} +@pragma stage 2 +@pragma include_idletime 1 +@pragma idletime_precision 3 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 0 +table ig_idle_10 { reads { ethernet.srcAddr mask 0x3FFF : ternary; } actions { nothing; } size : 1536; support_timeout: true;} +@pragma stage 2 +@pragma include_idletime 1 +@pragma idletime_precision 3 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 0 +table ig_idle_11 { reads { ethernet.srcAddr mask 0x3FFF : ternary; } actions { nothing; } size : 1536; support_timeout: true;} +@pragma stage 2 +@pragma include_idletime 1 +@pragma idletime_precision 3 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 0 +table ig_idle_12 { reads { ethernet.srcAddr mask 0x3FFF : ternary; } actions { nothing; } size : 1536; support_timeout: true;} +@pragma stage 2 +@pragma include_idletime 1 +@pragma idletime_precision 3 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 0 +table ig_idle_13 { reads { ethernet.srcAddr mask 0x3FFF : ternary; } actions { nothing; } size : 1536; support_timeout: true;} +@pragma stage 2 +@pragma include_idletime 1 +@pragma idletime_precision 3 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 0 +table ig_idle_14 { reads { ethernet.srcAddr mask 0x3FFF : ternary; } actions { nothing; } size : 1536; support_timeout: true;} +@pragma stage 2 +@pragma include_idletime 1 +@pragma idletime_precision 3 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 0 +table ig_idle_15 { reads { ethernet.srcAddr mask 0x3FFF : ternary; } actions { nothing; } size : 1536; support_timeout: true;} +@pragma stage 2 +@pragma include_idletime 1 +@pragma idletime_precision 3 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 0 +table ig_idle_16 { reads { ethernet.srcAddr mask 0xFFFF : ternary; } actions { nothing; } size : 1536; support_timeout: true;} + + +@pragma stage 3 +@pragma include_idletime 1 +@pragma idletime_precision 1 +table eg_idle_1 { reads { ethernet.srcAddr mask 0xFFFF : exact; } actions { nothing; } size : 131072; support_timeout: true;} +@pragma stage 3 +@pragma include_idletime 1 +@pragma idletime_precision 1 +table eg_idle_2 { reads { ethernet.srcAddr mask 0xFFFF : exact; } actions { nothing; } size : 65536; support_timeout: true;} +@pragma stage 3 +@pragma include_idletime 1 +@pragma idletime_precision 1 +table eg_idle_3 { reads { ethernet.srcAddr mask 0xFFFF : exact; } actions { nothing; } size : 65536; support_timeout: true;} +@pragma stage 3 +@pragma include_idletime 1 +@pragma idletime_precision 1 +table eg_idle_4 { reads { ethernet.srcAddr mask 0xFFFF : exact; } actions { nothing; } size : 65536; support_timeout: true;} + + +action mark_meter_resubmit() { + modify_field(md.resubmit_for_meter_test, 1); +} +table ig_meter_resubmit { + actions {mark_meter_resubmit;} +} +action set_m1_clr() { + modify_field(md.m1_clr, ethernet.etherType, 0x03); +} +table ig_m1_color { + actions { set_m1_clr; } +} +@pragma meter_per_flow_enable 1 +@pragma meter_pre_color_aware_per_flow_enable 1 +@pragma meter_sweep_interval 0 +meter m1 { + type : bytes; + static : ig_m1; + pre_color : md.m1_clr; + instance_count : 20480; +} + +action m1(index) { + execute_meter(m1, index, md.m1_clr, md.m1_clr); + modify_field(md.m1_idx, index); +} + +@pragma stage 4 +table ig_m1 { reads {ethernet.dstAddr mask 0xFFFF00000000 : exact;} actions {m1; nothing;} size: 1024;} + +counter ig_m1_cntr { + type : bytes; + direct : ig_m1_cnt; +} +table ig_m1_cnt { reads { md.m1_idx: exact; md.m1_clr: exact; } actions { nothing; } size:1024; } + +action m1_tag_for_drop() { + modify_field(md.m1_drop, 1); +} +table ig_meter_test_discard { + actions { m1_tag_for_drop; } +} + + + +/****************************************************************************** +* * +* Selection Test * +* * +******************************************************************************/ + +register sel_tbl_reg { + width : 1; + instance_count : 131072; +} +blackbox stateful_alu stateful_selection_alu { + reg: sel_tbl_reg; + selector_binding: sel_tbl; + update_lo_1_value: clr_bit; +} +@pragma action_default_only nothing +@pragma stage 5 +table sel_tbl { + reads { ethernet.dstAddr : ternary; } + action_profile: sel_tbl_ap; + //default_action: nothing; + size : 1; +} +action set_egr_port(p) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, p); +} +action_profile sel_tbl_ap { + actions { set_egr_port; nothing; } + size : 1024; + dynamic_action_selection : sel_tbl_as; +} +action_selector sel_tbl_as { + selection_key: sel_tbl_hash; + selection_mode: resilient; +} +field_list_calculation sel_tbl_hash { + input { sel_tbl_fields; } +#if defined(BMV2TOFINO) + algorithm : xxh64; +#else + algorithm: random; +#endif + output_width: 51; +} +field_list sel_tbl_fields { + ethernet.dstAddr; + ethernet.etherType; +} + +action update_stful_sel_tbl(index) { + stateful_selection_alu.execute_stateful_alu(index); +} +@pragma stage 5 +table dummy_tbl { + reads { ethernet.dstAddr : exact; } + actions { update_stful_sel_tbl; } + size : 1; +} + +register sel_res_reg { + width : 16; + instance_count : 64; +} +blackbox stateful_alu sel_res_alu { + reg: sel_res_reg; + update_lo_1_value: ig_intr_md_for_tm.ucast_egress_port; +} +field_list sel_res_hash_fields { + ethernet.dstAddr; +} +field_list_calculation sel_res_hash { + input { sel_res_hash_fields; } + algorithm: identity; + output_width: 6; +} +action log_egr_port() { + sel_res_alu.execute_stateful_alu_from_hash(sel_res_hash); +} +table sel_res { + reads { + ethernet.dstAddr : ternary; + } + actions { log_egr_port; nothing; } + default_action: nothing; + size : 64; +} + +action do_resubmit() { + resubmit(); +} +table resubmit_2_tbl { + actions { do_resubmit; } +} +action drop_it() { mark_for_drop(); } +@pragma stage 1 +table eg_discard { + actions { drop_it; } +} + +/****************************************************************************** +* * +* move reg * +* * +******************************************************************************/ +#define MR1 0 +#define MR1_NEXT 10 +#define MR2 9 +#define MR3 10 +#define MR4 10 +#define MR5 8 +#define MR6 8 +#define MR_VERIFY_SETUP 10 +#define MR_VERIFY 11 + +@pragma idletime_precision 1 +@pragma stage MR1 +table t1 { + reads { ethernet.etherType : ternary; } + actions { t1_action; } + support_timeout: true; +} +@pragma lrt_enable 0 +@pragma lrt_scale 154 +counter t1_cntr { + type : packets; + direct: t1; + min_width : 64; +} +register t1_reg { + width: 64; + direct: t1; + attributes: signed; +} +blackbox stateful_alu t1_alu { + reg: t1_reg; + condition_lo: register_lo != ethernet.etherType; + update_hi_1_value: register_hi + 1; + update_lo_1_predicate: condition_lo; + update_lo_1_value: 0; + output_value: register_hi; + output_dst: md.t1_stful; +} +action t1_action() { + t1_alu.execute_stateful_alu(); +} + + +@pragma idletime_precision 1 +@pragma stage MR1 +@pragma pack 1 +@pragma ways 4 +@pragma random_seed 1027 +table e1 { + reads { mrk.lo : exact; mrk.hi : exact; } + actions { e1_action; } + size: 4096; + support_timeout: true; +} +@pragma lrt_enable 0 +@pragma lrt_scale 154 +counter e1_cntr { + type : packets; + direct: e1; + min_width : 64; +} +register e1_reg { + width: 64; + direct: e1; + attributes: signed; +} +blackbox stateful_alu e1_alu { + reg: e1_reg; + condition_lo: register_lo != ethernet.etherType; + update_hi_1_value: register_hi + 1; + update_lo_1_predicate: condition_lo; + update_lo_1_value: 0; + output_value: register_hi; + output_dst: md.e1_stful; +} +action e1_action() { + e1_alu.execute_stateful_alu(); +} + + +@pragma stage MR1_NEXT +table mr1_verify { + actions {mr1_verify_fail;} +} +action mr1_verify_fail() { + modify_field(md.mr1_fail, 1); +} + + +@pragma idletime_precision 3 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 1 +@pragma stage MR2 +table t2 { + reads { ethernet.etherType : ternary; } + actions { t2_action; } + support_timeout: true; +} +@pragma lrt_enable 0 +@pragma lrt_scale 15811 +counter t2_cntr { + type : packets; + direct : t2; + min_width : 32; +} +register t2_reg { + width: 32; + direct: t2; +} +blackbox stateful_alu t2_alu { + reg: t2_reg; + condition_lo: register_lo != ethernet.etherType; + update_hi_1_value: register_hi + 1; + update_lo_1_predicate: condition_lo; + update_lo_1_value: 0; +} +action t2_action() { + t2_alu.execute_stateful_alu(); +} + +@pragma idletime_precision 3 +@pragma idletime_two_way_notification 1 +@pragma idletime_per_flow_idletime 1 +@pragma stage MR2 +@pragma pack 1 +@pragma ways 4 +@pragma random_seed 1027 +table e2 { + reads { mrk.lo : exact; mrk.hi : exact; } + actions { e2_action; } + size: 4096; + support_timeout: true; +} +@pragma lrt_enable 0 +@pragma lrt_scale 15811 +counter e2_cntr { + type : packets; + direct : e2; + min_width : 32; +} +register e2_reg { + width: 32; + direct: e2; +} +blackbox stateful_alu e2_alu { + reg: e2_reg; + condition_lo: register_lo != ethernet.etherType; + update_hi_1_value: register_hi + 1; + update_lo_1_predicate: condition_lo; + update_lo_1_value: 0; +} +action e2_action() { + e2_alu.execute_stateful_alu(); +} + + +@pragma stage 0 +table eg_mr_meter_clr_setup { + actions { setup_mr_meter_clr; } +} +action setup_mr_meter_clr() { + modify_field(md.mr_clr, ethernet.dstAddr, 3); +} + +@pragma stage MR3 +table t3 { + reads { ethernet.etherType : ternary; } + actions { t3_action; } +} +@pragma lrt_enable 0 +@pragma lrt_scale 154 +counter t3_cntr { + type : bytes; + direct : t3; + min_width : 64; +} +@pragma meter_sweep_interval 0 +meter t3_meter { + type: bytes; + direct: t3; + result: md.t3_meter; + pre_color : md.mr_clr; +} +action t3_action() {} + +@pragma stage MR3 +@pragma pack 1 +@pragma ways 4 +@pragma random_seed 1027 +table e3 { + reads { mrk.lo : exact; mrk.hi : exact; } + actions { e3_action; } + size: 4096; +} +@pragma lrt_enable 0 +@pragma lrt_scale 154 +counter e3_cntr { + type : bytes; + direct : e3; + min_width : 64; +} +@pragma meter_sweep_interval 0 +meter e3_meter { + type: bytes; + direct: e3; + result: md.e3_meter; + pre_color : md.mr_clr; +} +action e3_action() {} + + + + +@pragma stage MR4 +table t4 { + reads { ethernet.etherType : ternary; } + actions { t4_action; } +} +@pragma lrt_enable 0 +@pragma lrt_scale 15811 +counter t4_cntr { + type : packets; + direct : t4; + //min_width : 32; +} +@pragma meter_sweep_interval 0 +meter t4_meter { + type: packets; + direct: t4; + result: md.t4_meter; + pre_color : md.mr_clr; +} +action t4_action() {} + +@pragma stage MR4 +@pragma pack 1 +@pragma ways 4 +@pragma random_seed 1027 +table e4 { + reads { mrk.lo : exact; mrk.hi : exact; } + actions { e4_action; } + size: 4096; +} +@pragma lrt_enable 0 +@pragma lrt_scale 15811 +counter e4_cntr { + type : packets; + direct : e4; + //min_width : 32; +} +@pragma meter_sweep_interval 0 +meter e4_meter { + type: packets; + direct: e4; + result: md.e4_meter; + pre_color : md.mr_clr; +} +action e4_action() {} + + + + + +@pragma stage MR5 +table t5 { + reads { ethernet.etherType : ternary; } + actions { t5_action; } +} +@pragma lrt_enable 0 +@pragma lrt_scale 154 +counter t5_cntr { + type : bytes; + direct : t5; + min_width : 32; +} +blackbox lpf t5_lpf { + filter_input: ethernet.srcAddr; + direct: t5; +} +//action t5_action() { } +action t5_action() { t5_lpf.execute(md.t5_lpf); } + +@pragma stage MR5 +@pragma pack 1 +@pragma ways 4 +@pragma random_seed 1027 +table e5 { + reads { mrk.lo : exact; mrk.hi : exact; } + actions { e5_action; } + size: 4096; +} +@pragma lrt_enable 0 +@pragma lrt_scale 154 +counter e5_cntr { + type : bytes; + direct : e5; + min_width : 32; +} +blackbox lpf e5_lpf { + filter_input: ethernet.srcAddr; + direct: e5; +} +//action e5_action() { } +action e5_action() { e5_lpf.execute(md.e5_lpf); } + + + + +@pragma stage MR6 +table t6 { + reads { ethernet.etherType : ternary; } + actions { t6_action; } +} +@pragma lrt_enable 0 +@pragma lrt_scale 15811 +counter t6_cntr { + type : packets; + direct : t6; + //min_width : 32; +} +blackbox lpf t6_lpf { + filter_input: ethernet.srcAddr; + direct: t6; +} +//action t6_action() { } +action t6_action() { t6_lpf.execute(md.t6_lpf); } + +@pragma stage MR6 +@pragma pack 1 +@pragma ways 4 +@pragma random_seed 1027 +table e6 { + reads { mrk.lo : exact; mrk.hi : exact; } + actions { e6_action; } + size: 4096; +} +@pragma lrt_enable 0 +@pragma lrt_scale 15811 +counter e6_cntr { + type : packets; + direct : e6; + //min_width : 32; +} +blackbox lpf e6_lpf { + filter_input: ethernet.srcAddr; + direct: e6; +} +//action e6_action() { } +action e6_action() { e6_lpf.execute(md.e6_lpf); } + + +@pragma stage MR_VERIFY_SETUP +table mr_verify_setup { + actions { mr_verify_setup_action; } +} +action mr_verify_setup_action() { + shift_right(md.t5_lpf_tmp1, md.t5_lpf, 4); + shift_right(md.t5_lpf_tmp2, md.t5_lpf, 8); + shift_right(md.e5_lpf_tmp1, md.e5_lpf, 4); + shift_right(md.e5_lpf_tmp2, md.e5_lpf, 8); + shift_right(md.t6_lpf_tmp1, md.t6_lpf, 4); + shift_right(md.t6_lpf_tmp2, md.t6_lpf, 8); + shift_right(md.e6_lpf_tmp1, md.e6_lpf, 4); + shift_right(md.e6_lpf_tmp2, md.e6_lpf, 8); +} + +counter v3_cntr { + type : bytes; + direct : v3; +} +@pragma stage MR_VERIFY +table v3 { + reads { ethernet.etherType : exact; } + actions { nothing; } +} +counter v4_cntr { + type : packets; + direct : v4; +} +@pragma stage MR_VERIFY +table v4 { + reads { ethernet.etherType : exact; } + actions { nothing; } +} +counter v5_cntr { + type : bytes; + direct : v5; +} +@pragma stage MR_VERIFY +table v5 { + reads { ethernet.etherType : exact; } + actions { nothing; } +} +counter v6_cntr { + type : packets; + direct : v6; +} +@pragma stage MR_VERIFY +table v6 { + reads { ethernet.etherType : exact; } + actions { nothing; } +} + + +register vp5_reg { + width: 64; + direct: vp5; +} +blackbox stateful_alu vp5_alu { + reg: vp5_reg; + condition_lo: register_lo == 0xFFFFFFFF; + update_hi_1_predicate: condition_lo; + update_hi_1_value: register_hi + 1; + update_lo_1_value: register_lo + 1; +} +action vp5_action() { + vp5_alu.execute_stateful_alu(); +} +@pragma stage MR_VERIFY +table vp5 { + reads { ethernet.etherType : exact; } + actions { vp5_action; } +} +register vp6_reg { + width: 64; + direct: vp6; +} +blackbox stateful_alu vp6_alu { + reg: vp6_reg; + condition_lo: register_lo == 0xFFFFFFFF; + update_hi_1_predicate: condition_lo; + update_hi_1_value: register_hi + 1; + update_lo_1_value: register_lo + 1; +} +action vp6_action() { + vp6_alu.execute_stateful_alu(); +} +@pragma stage MR_VERIFY +table vp6 { + reads { ethernet.etherType : exact; } + actions { vp6_action; } +} +register vpp5_reg { + width: 64; + direct: vpp5; +} +blackbox stateful_alu vpp5_alu { + reg: vpp5_reg; + condition_lo: register_lo == 0xFFFFFFFF; + update_hi_1_predicate: condition_lo; + update_hi_1_value: register_hi + 1; + update_lo_1_value: register_lo + 1; +} +action vpp5_action() { + vpp5_alu.execute_stateful_alu(); +} +@pragma stage MR_VERIFY +table vpp5 { + reads { ethernet.etherType : exact; } + actions { vpp5_action; } +} +register vpp6_reg { + width: 64; + direct: vpp6; +} +blackbox stateful_alu vpp6_alu { + reg: vpp6_reg; + condition_lo: register_lo == 0xFFFFFFFF; + update_hi_1_predicate: condition_lo; + update_hi_1_value: register_hi + 1; + update_lo_1_value: register_lo + 1; +} +action vpp6_action() { + vpp6_alu.execute_stateful_alu(); +} +@pragma stage MR_VERIFY +table vpp6 { + reads { ethernet.etherType : exact; } + actions { vpp6_action; } +} + + +/* +t1 : TCAM with idle-1 and stats-bytes and stateful-64bit +t2 : TCAM with idle-3 and stats-packets and stateful-32bit +t3 : TCAM with meter and stats-bytes +t4 : TCAM with meter and stats-packets +t5 : TCAM with LPF and stats-bytes +t6 : TCAM with LPF and stats-packets + +e1 : EXM with idle-1 and stats-bytes and stateful-64bit +e2 : EXM with idle-3 and stats-packets and stateful-32bit +e3 : EXM with meter and stats-bytes +e4 : EXM with meter and stats-packets +e5 : EXM with LPF and stats-bytes +e6 : EXM with LPF and stats-packets +*/ + + +action eg_dummy_action() { + modify_field(md.t3_meter, md.t3_meter); + modify_field(md.e3_meter, md.e3_meter); + modify_field(md.t4_meter, md.t4_meter); + modify_field(md.e4_meter, md.e4_meter); + modify_field(md.t5_lpf, md.t5_lpf); + modify_field(md.e5_lpf, md.e5_lpf); + modify_field(md.t6_lpf, md.t6_lpf); + modify_field(md.e6_lpf, md.e6_lpf); + modify_field(md.mr_clr, md.mr_clr); + modify_field(mrk.hi, 0x30); + modify_field(mrk.lo, 0x30); +} +@pragma stage 11 +table eg_dummy { + actions { eg_dummy_action; } +} + + +control ingress { + apply(dest); + apply(set_mrk_lo); + + if (0 == ig_intr_md.resubmit_flag and 0 == md.drop_it) { + apply(stats_resubmit); + } + if (1 == md.count_it) { + apply(set_stats_key1); + } else if (2 == md.count_it) { + apply(set_stats_key2); + } else if (3 == md.count_it) { + apply(set_stats_key3); + } + + if (1 == (ethernet.srcAddr & 1) and 0 == ig_intr_md.resubmit_flag and 0 == md.drop_it) { + apply(ig_meter_resubmit); + } + + apply(set_mrk_hi); + + if (1 == md.count_it or 2 == md.count_it or 3 == md.count_it) { + apply(ig_stat_1); + apply(ig_stat_2); + } + + apply(ig_idle_1); + apply(ig_idle_2); + apply(ig_idle_3); + apply(ig_idle_4); + apply(ig_idle_5); + apply(ig_idle_6); + apply(ig_idle_7); + apply(ig_idle_8); + apply(ig_idle_9); + apply(ig_idle_10); + apply(ig_idle_11); + apply(ig_idle_12); + apply(ig_idle_13); + apply(ig_idle_14); + apply(ig_idle_15); + apply(ig_idle_16); + + if (1 == md.resubmit_for_meter_test and 0 == ig_intr_md.resubmit_flag) { + apply(resubmit_2_tbl); + } else { + apply(ig_m1_color); + apply(ig_m1) { + hit { + apply(ig_m1_cnt); + if (md.m1_clr == 3) { + apply(ig_meter_test_discard); + } + } + } + } + + if (0 == md.dummy) { + apply(sel_tbl) { + hit { apply(sel_res); } + miss { + apply(ig_stat_3); + apply(ig_stat_4); + } + } + } else { + apply(dummy_tbl); + } +} + +control egress { + apply(t1); + apply(e1); + + apply(eg_mr_meter_clr_setup); + + if (1 == md.count_it or 2 == md.count_it or 3 == md.count_it or md.m1_drop == 1) { + apply(eg_stat_1); + apply(eg_stat_2); + //apply(eg_discard); + } + + apply(eg_idle_1); + apply(eg_idle_2); + apply(eg_idle_3); + apply(eg_idle_4); + + apply(eg_stat_3); + apply(eg_stat_4); + + apply(t5); + apply(e5); + apply(t6); + apply(e6); + + apply(t2); + apply(e2); + + if (md.t1_stful != md.e1_stful) { + apply(mr1_verify); + } + + apply(t3); + apply(e3); + apply(t4); + apply(e4); + + apply(mr_verify_setup); + + if (md.t3_meter == md.e3_meter) { + apply(v3); + } + if (md.t4_meter == md.e4_meter) { + apply(v4); + } + if (md.t5_lpf == md.e5_lpf) { + apply(v5); + } + if (md.t6_lpf == md.e6_lpf) { + apply(v6); + } + if (md.t5_lpf_tmp1 == md.e5_lpf_tmp1) { + apply(vp5); + } + if (md.t5_lpf_tmp2 == md.e5_lpf_tmp2) { + apply(vpp5); + } + if (md.t6_lpf_tmp1 == md.e6_lpf_tmp1) { + apply(vp6); + } + if (md.t6_lpf_tmp2 == md.e6_lpf_tmp2) { + apply(vpp6); + } + apply(eg_dummy); +} + + diff --git a/backends/tofino/bf-asm/test/ptf/meters.p4 b/backends/tofino/bf-asm/test/ptf/meters.p4 new file mode 100644 index 00000000000..1f37d1ccd2d --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/meters.p4 @@ -0,0 +1,447 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "tofino.p4" +#include "tofino/intrinsic_metadata.p4" +#include "tofino/constants.p4" +#include "tofino/lpf_blackbox.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type ipv6_t { + fields { + version : 4; + trafficClass : 8; + flowLabel : 20; + payloadLen : 16; + nextHdr : 8; + hopLimit : 8; + srcAddr : 128; + dstAddr : 128; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + 0x86dd : parse_ipv6; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; +header ipv6_t ipv6; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +parser parse_ipv6 { + extract(ipv6); + return select(latest.nextHdr) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default : ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm : csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action next_hop_ipv4(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + + +action next_hop_ipv6(egress_port ,srcmac, dstmac) { + hop(ipv6.hopLimit, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +meter meter_0 { + type : bytes; + static : meter_tbl; + result : ipv4.diffserv; + instance_count : 500; +} + +meter meter_1 { + type : bytes; + direct : meter_tbl_direct; + result : ipv4.diffserv; +} + + +@pragma meter_pre_color_aware_per_flow_enable 1 +meter meter_2 { + type : bytes; + static : meter_tbl_color_aware_indirect; + result : ipv4.diffserv; + pre_color : ipv4.diffserv; + instance_count : 500; +} + +meter meter_3 { + type : bytes; + direct : meter_tbl_color_aware_direct; + result : ipv4.diffserv; + pre_color : ipv4.diffserv; +} + +blackbox lpf meter_lpf { + filter_input : ipv4.srcAddr; + instance_count : 500; +} + + +blackbox lpf meter_lpf_tcam { + filter_input : ipv4.srcAddr; + static : match_tbl_tcam_lpf; + instance_count : 500; +} + +blackbox lpf meter_lpf_direct { + filter_input : ipv4.srcAddr; + direct : match_tbl_lpf_direct; +} + +blackbox lpf meter_lpf_tcam_direct { + filter_input : ipv4.srcAddr; + direct : match_tbl_tcam_lpf_direct; +} + +action meter_action (egress_port, srcmac, dstmac, idx) { + next_hop_ipv4(egress_port, srcmac, dstmac); + execute_meter(meter_0, idx, ipv4.diffserv); +} + +action meter_action_color_aware (egress_port, srcmac, dstmac, idx) { + next_hop_ipv4(egress_port, srcmac, dstmac); + execute_meter(meter_2, idx, ipv4.diffserv, ipv4.diffserv); +} + +action count_color(color_idx) { + count(colorCntr, color_idx); +} + +action next_hop_ipv4_lpf(egress_port ,srcmac, dstmac, lpf_idx) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); + meter_lpf.execute(ipv4.srcAddr, lpf_idx); +} + +action next_hop_ipv4_direct_lpf(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); + meter_lpf_direct.execute(ipv4.srcAddr); +} + +action next_hop_ipv4_lpf_tcam(egress_port ,srcmac, dstmac, lpf_idx) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); + meter_lpf_tcam.execute(ipv4.srcAddr, lpf_idx); +} + +action next_hop_ipv4_lpf_direct_tcam(egress_port ,srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); + meter_lpf_tcam_direct.execute(ipv4.srcAddr); +} + +counter colorCntr { + type : packets; + static : color_match; + instance_count : 100; +} + +@pragma command_line --no-dead-code-elimination +@pragma stage 1 +table meter_tbl { + reads { + ipv4.dstAddr : exact; + } + actions { + nop; + meter_action; + } +} + +@pragma stage 0 +table meter_tbl_direct { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma stage 2 +table meter_tbl_color_aware_indirect { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + meter_action_color_aware; + } +} + + +@pragma stage 3 +table meter_tbl_color_aware_direct { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + next_hop_ipv4; + } + default_action : nop(); +} + +@pragma stage 4 +table match_tbl_lpf { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + next_hop_ipv4_lpf; + } + default_action : nop(); +} + +@pragma stage 4 +table match_tbl_tcam_lpf { + reads { + ipv4.dstAddr : ternary; + ipv4.srcAddr : ternary; + } + actions { + next_hop_ipv4_lpf_tcam; + } + default_action : nop(); +} + + +@pragma stage 5 +table match_tbl_lpf_direct { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + next_hop_ipv4_direct_lpf; + } + default_action : nop(); +} + +@pragma stage 5 +table match_tbl_tcam_lpf_direct { + reads { + ipv4.dstAddr : ternary; + ipv4.srcAddr : ternary; + } + actions { + next_hop_ipv4_lpf_direct_tcam; + } + default_action : nop(); +} + + +@pragma stage 11 +table color_match { + reads { + ethernet.dstAddr: exact; + ipv4.diffserv: exact; + } + actions { + count_color; + } + size : 256; +} + + +/* Main control flow */ +control ingress { + /* A general principle : Always keep the exact match tables ahead of the + * ternary tables in the same stage, except first stage. Logic relating to next-table + * will cause the Tofino model not to launch a lookup on th exact match + * tables if the order is reversed. + */ + apply(meter_tbl_direct); + apply(meter_tbl); + apply(meter_tbl_color_aware_indirect); + apply(meter_tbl_color_aware_direct); + apply(match_tbl_lpf); + apply(match_tbl_tcam_lpf); + apply(match_tbl_lpf_direct); + apply(match_tbl_tcam_lpf_direct); + apply(color_match); +} + +control egress { + +} + diff --git a/backends/tofino/bf-asm/test/ptf/multi_device.p4 b/backends/tofino/bf-asm/test/ptf/multi_device.p4 new file mode 100644 index 00000000000..1b5b3491b91 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/multi_device.p4 @@ -0,0 +1,692 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + learn_meta_1:20; + learn_meta_2:24; + learn_meta_3:25; + learn_meta_4:10; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm : csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +field_list learn_1 { + ipv4.ihl; + ipv4.protocol; + ipv4.srcAddr; + ethernet.srcAddr; + ethernet.dstAddr; + ipv4.fragOffset; + ipv4.identification; + routing_metadata.learn_meta_1; + routing_metadata.learn_meta_4; +} + +action learn_1 (learn_meta_1, learn_meta_4) { + generate_digest(FLOW_LRN_DIGEST_RCVR, learn_1); + modify_field(routing_metadata.learn_meta_1, learn_meta_1); + modify_field(routing_metadata.learn_meta_4, learn_meta_4); +} + +field_list learn_2 { + ipv4.ihl; + ipv4.identification; + ipv4.protocol; + ipv4.srcAddr; + ethernet.srcAddr; + ethernet.dstAddr; + ipv4.fragOffset; + routing_metadata.learn_meta_2; + routing_metadata.learn_meta_3; +} + +action learn_2 (learn_meta_2, learn_meta_3) { + generate_digest(FLOW_LRN_DIGEST_RCVR, learn_2); + modify_field(routing_metadata.learn_meta_2, learn_meta_2); + modify_field(routing_metadata.learn_meta_3, learn_meta_3); +} + +action hop(ttl, egress_port) { + add_to_field(ttl, -1); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action hop_ipv4(egress_port /*,srcmac, dstmac*/) { + hop(ipv4.ttl, egress_port); +// modify_field(ethernet.srcAddr, srcmac); +// modify_field(ethernet.dstAddr, dstmac); +} + +action drop_ipv4 () { + drop(); +} + +action next_hop_ipv4(egress_port, srcmac, dstmac) { + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action mod_mac_adr(egress_port, srcmac, dstmac) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ethernet.srcAddr, srcmac); + modify_field(ethernet.dstAddr, dstmac); +} + +action udp_hdr_add (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + add_header(udp); + modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); + add_to_field(ipv4.totalLen, 8); +} + +action udp_set_dest(port) { + modify_field(udp.dstPort, port); +} +action udp_set_src(port) { + modify_field(udp.srcPort, port); +} + +action tcp_hdr_rm (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + remove_header(tcp); + modify_field(ipv4.protocol, 0); +// add_to_field(ipv4.totalLen, -20); +// modify_field(ipv4.totalLen, 66); +} + +action modify_tcp_dst_port_1(dstPort, egress_port) { + modify_field(tcp.dstPort, dstPort); + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) +{ + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ipv4.srcAddr, ipAddr); + modify_field(ethernet.dstAddr, dstAddr); + modify_field(tcp.dstPort, tcpPort); +} + +action custom_action_2(egress_port, ipAddr, tcpPort) +{ + modify_field(ipv4.srcAddr, ipAddr); + modify_field(tcp.dstPort, tcpPort); + hop(ipv4.ttl, egress_port); +} + +action custom_action_3(egress_port, dstAddr, dstIp) +{ + modify_field(ipv4.dstAddr, dstIp); + modify_field(ethernet.dstAddr, dstAddr); + hop(ipv4.ttl, egress_port); +} + +action modify_l2 (egress_port, srcAddr, dstAddr, tcp_sport, tcp_dport) { + // Trying for >128 bit action data + hop(ipv4.ttl, egress_port); + modify_field(ethernet.srcAddr, srcAddr); + modify_field(ethernet.dstAddr, dstAddr); + modify_field(tcp.dstPort, tcp_dport); + modify_field(tcp.srcPort, tcp_sport); +} + +@pragma command_line --no-dead-code-elimination +@pragma immediate 1 +@pragma stage 0 +table ig_udp { + reads { + ethernet : valid; + ipv4 : valid; + udp : valid; + udp.dstPort : ternary; + } + actions { + nop; + udp_set_dest; + } +} +@pragma immediate 1 +@pragma stage 0 +table eg_udp { + reads { + ethernet : valid; + ipv4 : valid; + udp : valid; + udp.srcPort : exact; + } + actions { + nop; + udp_set_src; + } +} + +@pragma immediate 1 +@pragma stage 0 +table ipv4_routing { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + hop_ipv4; + drop_ipv4; + learn_1; + learn_2; + } + size : 512; +} + +@pragma immediate 1 +@pragma stage 0 +@pragma ways 3 +@pragma pack 5 +table ipv4_routing_exm_ways_3_pack_5 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + modify_tcp_dst_port_1; + } +} + + +@pragma immediate 1 +@pragma stage 1 +@pragma ways 3 +@pragma pack 3 +table ipv4_routing_exm_ways_3_pack_3 { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + custom_action_1; + } +} + +@pragma immediate 1 +@pragma stage 1 +@pragma ways 4 +@pragma pack 3 +table ipv4_routing_exm_ways_4_pack_3_stage_1 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma immediate 1 +@pragma stage 1 +table ipv4_routing_stage_1 { + reads { + ipv4.dstAddr : lpm; + ipv4.srcAddr : exact; + } + actions { + nop; + hop_ipv4; + } + size : 1024; +} + +@pragma stage 2 +table tcam_tbl_stage_2 { + reads { + ipv4.dstAddr : lpm; + } + actions { + nop; + mod_mac_adr; + } +} + +@pragma stage 2 +@pragma ways 4 +@pragma pack 7 +table ipv4_routing_exm_ways_4_pack_7_stage_2 { + reads { + ipv4.dstAddr : exact; + ipv4.srcAddr : exact; + tcp.dstPort : exact; + tcp.srcPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +@pragma immediate 1 +@pragma stage 3 +@pragma ways 5 +@pragma pack 3 +table ipv4_routing_exm_ways_5_pack_3_stage_3 { + reads { + ipv4.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma immediate 1 +@pragma stage 3 +table udp_add_tbl_stage_3 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + udp_hdr_add; + } +} + +@pragma immediate 1 +@pragma stage 4 +@pragma ways 6 +@pragma pack 3 +table ipv4_routing_exm_ways_6_pack_3_stage_4 { + reads { + ipv4.dstAddr : exact; + ethernet.dstAddr : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + + +@pragma immediate 1 +@pragma stage 4 +table tcp_rm_tbl_stage_4 { + reads { + ethernet.srcAddr : ternary; + } + actions { + nop; + tcp_hdr_rm; + } +} + +@pragma immediate 1 +@pragma stage 5 +@pragma ways 3 +@pragma pack 4 +table ipv4_routing_exm_ways_3_pack_4_stage_5 { + reads { + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + modify_tcp_dst_port_1; + } +} + +@pragma stage 6 +@pragma ways 4 +@pragma pack 4 +table ipv4_routing_exm_ways_4_pack_4_stage_6 { + reads { + ethernet.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.srcPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + +@pragma immediate 1 +@pragma stage 7 +@pragma ways 5 +@pragma pack 4 +table ipv4_routing_exm_ways_5_pack_4_stage_7 { + reads { + ipv4.dstAddr : exact; + ethernet.srcAddr : exact; + } + actions { + nop; + custom_action_3; + } +} + +@pragma immediate 1 +@pragma stage 8 +table tcam_adt_deep_stage_8 { + reads { + ethernet.srcAddr : ternary; + ethernet.dstAddr : ternary; + ipv4.srcAddr : ternary; + ipv4.dstAddr : ternary; + } + actions { + nop; + modify_l2; + } + size : 3072; +} + +@pragma stage 8 +@pragma ways 4 +@pragma pack 5 +table ipv4_routing_exm_ways_4_pack_5_stage_8 { + reads { + ipv4.srcAddr : exact; + ethernet.dstAddr : exact; + tcp.srcPort : exact; + tcp.dstPort : exact; + } + actions { + nop; + custom_action_2; + } +} + +@pragma stage 9 +table ipv4_routing_select { + reads { + ipv4.dstAddr: lpm; + } + action_profile : ecmp_action_profile; + size : 512; +} + +field_list ecmp_hash_fields { + ipv4.srcAddr; + ipv4.dstAddr; + ipv4.identification; + ipv4.protocol; +} + +field_list_calculation ecmp_hash { + input { + ecmp_hash_fields; + } + algorithm : crc16; + output_width : 14; +} + +action_profile ecmp_action_profile { + actions { + nhop_set; + nop; + } + size : 1024; + // optional + dynamic_action_selection : ecmp_selector; +} + +action_selector ecmp_selector { + selection_key : ecmp_hash; // take a field_list_calculation only + // optional + selection_mode : fair; // “resilient” or “non-resilient” +} + +action nhop_set(port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +@pragma stage 10 +table tcam_indirect_action { + reads { + ethernet.srcAddr : ternary; + ethernet.dstAddr : ternary; + ethernet.etherType: exact; + ipv4.srcAddr : ternary; + ipv4.dstAddr : ternary; + ipv4.protocol : exact; + ipv4.version : exact; + } + action_profile : indirect_action_profile; + size : 2048; +} + +action modify_ip_id(port, id, srcAddr, dstAddr) { + modify_field(ipv4.identification, id); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); + modify_field(ethernet.srcAddr, srcAddr); + modify_field(ethernet.dstAddr, dstAddr); +} + +action_profile indirect_action_profile { + actions { + nop; + modify_ip_id; + } + size : 1500; +} + +@pragma stage 11 +@pragma ways 6 +@pragma pack 4 +table ipv4_routing_exm_ways_6_pack_4_stage_11 { + reads { + ipv4.dstAddr : exact; + tcp.dstPort : exact; + } + actions { + nop; + next_hop_ipv4; + } +} + + +/* Main control flow */ +control ingress { + /* A general principle : Always keep the exact match tables ahead of the + * ternary tables in the same stage, except first stage. Logic relating to next-table + * will cause the Tofino model not to launch a lookup on th exact match + * tables if the order is reversed. + */ + apply(ig_udp); + apply(ipv4_routing); + apply(ipv4_routing_exm_ways_3_pack_5); + apply(ipv4_routing_exm_ways_3_pack_3); + apply(ipv4_routing_exm_ways_4_pack_3_stage_1); + apply(ipv4_routing_stage_1); + apply(tcam_tbl_stage_2); + apply(ipv4_routing_exm_ways_4_pack_7_stage_2); + apply(ipv4_routing_exm_ways_5_pack_3_stage_3); + /* Gateway not yet supported */ +// if (ipv4.protocol == 0) { + apply(udp_add_tbl_stage_3); +// } + apply(ipv4_routing_exm_ways_6_pack_3_stage_4); +// if (valid(tcp)) { + apply(tcp_rm_tbl_stage_4); +// } + apply(ipv4_routing_exm_ways_3_pack_4_stage_5); + apply(ipv4_routing_exm_ways_4_pack_4_stage_6); + apply(ipv4_routing_exm_ways_5_pack_4_stage_7); + apply(tcam_adt_deep_stage_8); + apply(ipv4_routing_exm_ways_4_pack_5_stage_8); + // Stage 9 - Please use caution before adding any more tables in stage 9 + // Poor man's selector may not work + apply(ipv4_routing_select); + // Stage 10 + apply(tcam_indirect_action); + // Stage 11 +} + +control egress { + apply(eg_udp); + // Commenting out since modify of egress port is not possible in egress +// apply(ipv4_routing_exm_ways_6_pack_4_stage_11); +} + diff --git a/backends/tofino/bf-asm/test/ptf/multicast_scale.p4 b/backends/tofino/bf-asm/test/ptf/multicast_scale.p4 new file mode 100644 index 00000000000..f28e6dc0cf2 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/multicast_scale.p4 @@ -0,0 +1,120 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include "tofino/stateful_alu_blackbox.p4" +#include + +header_type ethernet_t { + fields { + dmac : 48; + smac : 48; + etype : 16; + } +} +header ethernet_t ethernet; + +parser start { + extract(ethernet); + return ingress; +} + + + + + +action set_general_md(rid, xid, yid, h1, h2) { + modify_field(ig_intr_md_for_tm.rid, rid); + modify_field(ig_intr_md_for_tm.level1_exclusion_id, xid); + modify_field(ig_intr_md_for_tm.level2_exclusion_id, yid); + modify_field(ig_intr_md_for_tm.level1_mcast_hash, h1); + modify_field(ig_intr_md_for_tm.level2_mcast_hash, h2); +} +action mcast_1(mgid, rid, xid, yid, h1, h2) { + modify_field(ig_intr_md_for_tm.mcast_grp_a, mgid); + set_general_md(rid, xid, yid, h1, h2); +} +action mcast_2(mgid, rid, xid, yid, h1, h2) { + modify_field(ig_intr_md_for_tm.mcast_grp_b, mgid); + set_general_md(rid, xid, yid, h1, h2); +} +action mcast_both(mgid1, mgid2, rid, xid, yid, h1, h2) { + modify_field(ig_intr_md_for_tm.mcast_grp_a, mgid1); + modify_field(ig_intr_md_for_tm.mcast_grp_b, mgid2); + set_general_md(rid, xid, yid, h1, h2); +} + +table ing { + reads { + ig_intr_md.ingress_port mask 0x7f : exact; + ethernet.dmac : exact; + } + actions { + mcast_1; + mcast_2; + mcast_both; + } + size: 65536; // Enough to assign 64k MGIDs +} + + +action on_miss() { count(cntr, 1); drop();} + +action log_only() { + salu.execute_stateful_alu(); + count(cntr, 0); + drop(); +} + +counter cntr { + type: packets; + instance_count: 2; + min_width: 64; +} +register log { + width : 16; + direct: egr; +} +blackbox stateful_alu salu { + reg: log; + condition_lo: eg_intr_md.egress_rid_first == 1; + update_lo_1_predicate: condition_lo; + update_lo_1_value: register_lo + 0x100; + update_lo_2_predicate: not condition_lo; + update_lo_2_value: register_lo + 1; +} + +table egr { + reads { + eg_intr_md.egress_port mask 0x7f : exact; + eg_intr_md.egress_rid : exact; + } + actions { + log_only; + } + default_action: on_miss; + size: 1048576; // Enough for 16384 RIDs on 64 ports +} + +control ingress { + apply(ing); +} + +control egress { + apply(egr); +} + + diff --git a/backends/tofino/bf-asm/test/ptf/multicast_test.p4 b/backends/tofino/bf-asm/test/ptf/multicast_test.p4 new file mode 100644 index 00000000000..ac93b004d1f --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/multicast_test.p4 @@ -0,0 +1,279 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags_resv : 1; + flags_df : 1; + flags_mf : 1; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type ingress_metadata_t { + fields { + ifid : 32; /* Logical Interface ID */ + brid : 16; /* Bridging Domain ID */ + vrf : 16; + l3 : 1; /* Set if routed */ + } +} + +metadata ingress_metadata_t ing_md; +header ethernet_t ethernet; +header ipv4_t ipv4; +header vlan_tag_t vlan_tag; + + +parser start { + return parse_ethernet; +} + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags_resv; + ipv4.flags_df; + ipv4.flags_mf; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm : csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + + + + + + + +/****************************************************************************** + * + * Table: ing_port + * Key: Incoming physical port number + * Top VLAN tag + * + * Maps the physical port to a logical port and also invalidates the egress + * unicast port and MGID intrinsic metadatas. + * + *****************************************************************************/ +action set_ifid(ifid) { + modify_field(ing_md.ifid, ifid); + /* Set the destination port to an invalid value. */ + modify_field(ig_intr_md_for_tm.ucast_egress_port, 0x1FF); +} + +table ing_port { + reads { + ig_intr_md.ingress_port : exact; + vlan_tag : valid; + vlan_tag.vlan_id : exact; + } + actions { + set_ifid; + } +} + + +/****************************************************************************** + * + * Table: ing_src_ifid + * Key: Logical interface id + * + * Assigns ingress interface specific metadata: iRID, XID, YID, and brid. + * Also sets the hash values used for multicast replication. + * + *****************************************************************************/ +action set_src_ifid_md(rid, yid, brid, h1, h2) { + modify_field(ig_intr_md_for_tm.rid, rid); + modify_field(ig_intr_md_for_tm.level2_exclusion_id, yid); + modify_field(ing_md.brid, brid); + modify_field(ig_intr_md_for_tm.level1_mcast_hash, h1); + modify_field(ig_intr_md_for_tm.level2_mcast_hash, h2); +} + +table ing_src_ifid { + reads { + ing_md.ifid : exact; + } + actions { + set_src_ifid_md; + } +} + + +/****************************************************************************** + * + * Table: ing_dmac + * Key: Bridging domain and DMAC + * + * Will either setup the packet to L2 flood, L2 switch or route. + * + *****************************************************************************/ +action flood() { + modify_field(ig_intr_md_for_tm.mcast_grp_a, ing_md.brid); +} +action switch(egr_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egr_port); +} +action route(vrf) { + modify_field(ing_md.l3, 1); + modify_field(ing_md.vrf, vrf); +} +table ing_dmac { + reads { + ing_md.brid : exact; + ethernet.dstAddr : exact; + } + actions { + flood; + switch; + route; + } +} + + +/****************************************************************************** + * + * Table: ing_ipv4_mcast + * Key: IPv4 addresses and VRF + * + * Will assign MGID and XID + * + *****************************************************************************/ +action mcast_route(xid, mgid1, mgid2) { + modify_field(ig_intr_md_for_tm.level1_exclusion_id, xid); + modify_field(ig_intr_md_for_tm.mcast_grp_a, mgid1); + modify_field(ig_intr_md_for_tm.mcast_grp_b, mgid2); + add_to_field(ipv4.ttl, -1); +} +table ing_ipv4_mcast { + reads { + ing_md.vrf : exact; + ipv4.srcAddr : ternary; + ipv4.dstAddr : ternary; + } + actions { + mcast_route; + } +} + + +control ingress { + apply(ing_port); + apply(ing_src_ifid); + apply(ing_dmac); + if (ing_md.l3 == 1) { + apply(ing_ipv4_mcast); + } +} + + +/****************************************************************************** + * + * Table: egr_encode + * Key: None + * + * Encodes metadata generated by the multicast replication into the packet. + * + *****************************************************************************/ +action do_egr_encode() { + modify_field(ipv4.identification, eg_intr_md.egress_rid); + modify_field(ipv4.diffserv, eg_intr_md.egress_rid_first); +} +table egr_encode { + actions { + do_egr_encode; + } +} + + +control egress { + if (valid(ipv4)) { + apply(egr_encode); + } +} + + diff --git a/backends/tofino/bf-asm/test/ptf/p4features.h b/backends/tofino/bf-asm/test/ptf/p4features.h new file mode 100644 index 00000000000..cf4ff426b95 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/p4features.h @@ -0,0 +1,8 @@ +#define MATCH_ATCAM +#define MATCH_COUNT 50000 +#define STATS_INDIRECT +#define STATS_COUNT 18000 +#define STATEFUL_INDIRECT +#define STATEFUL_COUNT 40000 +#define ACTION_DIRECT +#define ACTION_COUNT 50000 diff --git a/backends/tofino/bf-asm/test/ptf/parser_intr_md.p4 b/backends/tofino/bf-asm/test/ptf/parser_intr_md.p4 new file mode 100644 index 00000000000..5d45dbc11ae --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/parser_intr_md.p4 @@ -0,0 +1,129 @@ +// Test program for enhancement to use ig_intr_md in the parser for branching +// Compiler-216 + +#ifdef __TARGET_TOFINO__ +#include +#include +#include +#include +#endif + +#define ETHERTYPE_IPV4 0x0800 + +@pragma parser_value_set_size 2 +parser_value_set pvs_server_port; +@pragma parser_value_set_size 2 +parser_value_set pvs_fabric_port; + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} +header ethernet_t ethernet; + +header_type fabric_header_t { + fields { + packetType : 3; + headerVersion : 2; + packetVersion : 2; + pad1 : 1; + + fabricColor : 3; + fabricQos : 5; + + dstDevice : 8; + dstPortOrGroup : 16; + } +} +header fabric_header_t fabric_header; +#define ETHERTYPE_BF_PKTGEN 0x9001 +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} +header ipv4_t ipv4; + +parser start { + //return select(ig_intr_md._pad2, ig_intr_md.ingress_port) { + return select(ig_intr_md.ingress_port) { +#ifdef PVS + //pvs_server_port : parse_ethernet; + pvs_fabric_port : parse_fabric_header; +#else + 0x0000 mask 0x0001 : parse_ethernet; + 0x0001 mask 0x0001 : parse_fabric_header; +#endif + default : parse_ethernet; + } +} + +parser parse_fabric_header { + extract(ethernet); + extract(fabric_header); + return ingress; +} + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x0800: parse_ipv4; + default: ingress; + } +} + +parser parse_pktgen_header { + extract(pktgen_generic); + return ingress; +} + +parser parse_ipv4 { + extract(ipv4); + return ingress; +} + +// Tables +action fwd_to_fabric() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 3); +} + +action fwd_to_server() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 4); +} + +action fwd_drop() { + drop(); +} + +table fwd_packet { + // all ip packets received from server ports are sent to port 3 + // all fabric packets received from fabric ports are sent to server port 4 + reads { + ipv4 : valid; + fabric_header : valid; + } + actions { + fwd_to_fabric; + fwd_to_server; + fwd_drop; + } + size : 4; +} + +control ingress { + apply(fwd_packet); +} diff --git a/backends/tofino/bf-asm/test/ptf/pcie_pkt_test.p4 b/backends/tofino/bf-asm/test/ptf/pcie_pkt_test.p4 new file mode 100644 index 00000000000..f5a90ed1dce --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/pcie_pkt_test.p4 @@ -0,0 +1,30 @@ +#include +#include + +parser start { + return ingress; +} + +action set_md(eg_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, eg_port); +} + +table port_tbl { + reads { + ig_intr_md.ingress_port : exact; + } + actions { + set_md; + } + size : 288; +} + + +control ingress { + if (0 == ig_intr_md.resubmit_flag) { + apply(port_tbl); + } +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/ptf/pctr.p4 b/backends/tofino/bf-asm/test/ptf/pctr.p4 new file mode 100644 index 00000000000..5602d112cc4 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/pctr.p4 @@ -0,0 +1,226 @@ +#include + +#define _parser_counter_ ig_prsr_ctrl.parser_counter + +#define ETHERTYPE_IPV4 0x0800 +#define ETHERTYPE_IPV6 0x86dd + +#define IP_PROTOCOLS_SR 43 +#define SRH_MAX_SEGMENTS 9 + +#define IPV4_OPTION_EOL_VALUE 0x00 +#define IPV4_OPTION_NOP_VALUE 0x01 +#define IPV4_OPTION_ADDRESS_EXTENSION 0x93 + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +// End of Option List +header_type ipv4_option_EOL_t { + fields { + value : 8; + } +} + +// No operation +header_type ipv4_option_NOP_t { + fields { + value : 8; + } +} + +header_type ipv4_option_addr_ext_t { + fields { + value : 8; + len : 8; + src_ext : 32; + dst_ext : 32; + } +} + +header_type ipv6_t { + fields { + version : 4; + trafficClass : 8; + flowLabel : 20; + payloadLen : 16; + nextHdr : 8; + hopLimit : 8; + srcAddr : 128; + dstAddr : 128; + } +} + +header_type ipv6_srh_t { + fields { + nextHdr : 8; + hdrExtLen : 8; + routingType : 8; + segLeft : 8; + firstSeg : 8; + flags : 16; + reserved : 8; + } +} + +header_type ipv6_srh_segment_t { + fields { + sid : 128; + } +} + +header ethernet_t ethernet; +header ipv4_t ipv4; +@pragma header_ordering ipv4_option_addr_ext ipv4_option_NOP ipv4_option_EOL +header ipv4_option_EOL_t ipv4_option_EOL; +header ipv4_option_NOP_t ipv4_option_NOP; +header ipv4_option_addr_ext_t ipv4_option_addr_ext; +header ipv6_t ipv6; +header ipv6_srh_t ipv6_srh; +header ipv6_srh_segment_t ipv6_srh_seg_list[SRH_MAX_SEGMENTS]; +header ipv6_srh_segment_t active_segment; + + +parser start { + return parse_ethernet; +} + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + ETHERTYPE_IPV4 : parse_ipv4; + ETHERTYPE_IPV6 : parse_ipv6; + } +} + +parser parse_ipv4 { + extract(ipv4); + // Little bit hacky. This shouldve been ipv4.ihl * 4 - 20. Extra -1 is to + // get rid of the effect of version (0x0100) + set_metadata(_parser_counter_, ipv4.ihl * 4 - 21); + return select(ipv4.ihl) { + 0x05 : ingress; + default : parse_ipv4_options; + } +} + +parser parse_ipv4_options { + // match on byte counter and option value + return select(_parser_counter_, current(0, 8)) { + 0x0000 mask 0xff00 : ingress; + 0x0000 mask 0x00ff : parse_ipv4_option_eol; + 0x0001 mask 0x00ff : parse_ipv4_option_nop; + 0x0093 mask 0x00ff : parse_ipv4_option_addr_ext; + } +} + +parser parse_ipv4_option_eol { + extract(ipv4_option_EOL); + set_metadata(_parser_counter_, _parser_counter_ - 1); + return parse_ipv4_options; +} + +parser parse_ipv4_option_nop { + extract(ipv4_option_NOP); + set_metadata(_parser_counter_, _parser_counter_ - 1); + return parse_ipv4_options; +} + +parser parse_ipv4_option_addr_ext { + extract(ipv4_option_addr_ext); + // security option must have length 11 bytes + set_metadata(_parser_counter_, _parser_counter_ - 10); + return parse_ipv4_options; +} + +parser parse_ipv6 { + extract(ipv6); + return select(latest.nextHdr) { + IP_PROTOCOLS_SR : parse_ipv6_srh; + } +} + +parser parse_ipv6_srh { + extract(ipv6_srh); + set_metadata(_parser_counter_, ipv6_srh.segLeft); + return parse_ipv6_srh_seg_list; +} + +parser parse_ipv6_srh_seg_list { + return select(_parser_counter_) { + 0x00 : parse_ipv6_srh_active_segment; + default : parse_ipv6_srh_segment; + } +} + +parser parse_ipv6_srh_segment { + extract(ipv6_srh_seg_list[next]); + set_metadata(_parser_counter_, _parser_counter_ - 1); + return parse_ipv6_srh_seg_list; +} + +parser parse_ipv6_srh_active_segment { + extract(active_segment); + return ingress; +} + +action rewrite_ipv6_and_set_egress_port() { + modify_field(ipv6.dstAddr, active_segment.sid); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); +} + +action set_egress_port() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); +} + +table sr_lookup { + actions { + rewrite_ipv6_and_set_egress_port; + } +} + +table ipv4_option_lookup { + reads { + ipv4_option_NOP : valid; + ipv4_option_EOL : valid; + ipv4_option_addr_ext : valid; + } + actions { + set_egress_port; + } +} + +control ingress { + if (valid(ipv6_srh)) { + apply(sr_lookup); + } + if (valid(ipv4)) { + apply(ipv4_option_lookup); + } +} + +control egress { + +} diff --git a/backends/tofino/bf-asm/test/ptf/perf_test.p4 b/backends/tofino/bf-asm/test/ptf/perf_test.p4 new file mode 100644 index 00000000000..efc3fcd376a --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/perf_test.p4 @@ -0,0 +1,245 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "tofino.p4" +#include "tofino/intrinsic_metadata.p4" +#include "tofino/constants.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type ipv6_t { + fields { + version : 4; + trafficClass : 8; + flowLabel : 20; + payloadLen : 16; + nextHdr : 8; + hopLimit : 8; + srcAddr : 128; + dstAddr : 128; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +header_type l3_metadata_t { + fields { + vrf : 24; + fib_hit : 1; + fib_nexthop : 16; + fib_nexthop_type : 1; + } +} + +metadata l3_metadata_t l3_metadata; + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + 0x86dd : parse_ipv6; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; +header ipv6_t ipv6; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +parser parse_ipv6 { + extract(ipv6); + return select(latest.nextHdr) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default : ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm : csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action fib_hit_nexthop(nexthop_index) { + modify_field(l3_metadata.fib_hit, 1); + modify_field(l3_metadata.fib_nexthop, nexthop_index); + modify_field(l3_metadata.fib_nexthop_type, 0); +} + +action fib_hit_ecmp(ecmp_index) { + modify_field(l3_metadata.fib_hit, 1); + modify_field(l3_metadata.fib_nexthop, ecmp_index); + modify_field(l3_metadata.fib_nexthop_type, 1); +} + +@pragma command_line --no-dead-code-elimination +table perf_exm_immediate_action { + reads { + l3_metadata.vrf : exact; + ipv4.dstAddr : exact; + } + actions { + nop; + fib_hit_nexthop; + fib_hit_ecmp; + } + + size : 1000000; +} + +/* Main control flow */ +control ingress { + /* A general principle : Always keep the exact match tables ahead of the + * ternary tables in the same stage, except first stage. Logic relating to next-table + * will cause the Tofino model not to launch a lookup on th exact match + * tables if the order is reversed. + */ + apply(perf_exm_immediate_action); +} + +control egress { + +} diff --git a/backends/tofino/bf-asm/test/ptf/perf_test_alpm.p4 b/backends/tofino/bf-asm/test/ptf/perf_test_alpm.p4 new file mode 100644 index 00000000000..9f2b3fcc7b6 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/perf_test_alpm.p4 @@ -0,0 +1,217 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "tofino.p4" +#include "tofino/intrinsic_metadata.p4" +#include "tofino/constants.p4" + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +header_type l3_metadata_t { + fields { + vrf : 24; + fib_hit : 1; + fib_nexthop : 16; + fib_nexthop_type : 1; + } +} + +metadata l3_metadata_t l3_metadata; + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type routing_metadata_t { + fields { + drop: 1; + } +} + +metadata routing_metadata_t /*metadata*/ routing_metadata; + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm : csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +action nop() { +} + +action fib_hit_nexthop(nexthop_index) { + modify_field(l3_metadata.fib_hit, 1); + modify_field(l3_metadata.fib_nexthop, nexthop_index); + modify_field(l3_metadata.fib_nexthop_type, 0); +} + +action fib_hit_ecmp(ecmp_index) { + modify_field(l3_metadata.fib_hit, 1); + modify_field(l3_metadata.fib_nexthop, ecmp_index); + modify_field(l3_metadata.fib_nexthop_type, 1); +} + +@pragma command_line --no-dead-code-elimination +@pragma alpm 1 +table perf_alpm_immediate_action { + reads { + l3_metadata.vrf : exact; + ipv4.dstAddr : lpm; + } + actions { + nop; + fib_hit_nexthop; + fib_hit_ecmp; + } + + size : 130000; +} + +/* Main control flow */ +control ingress { + apply(perf_alpm_immediate_action); +} + +control egress { + +} diff --git a/backends/tofino/bf-asm/test/ptf/pgrs.p4 b/backends/tofino/bf-asm/test/ptf/pgrs.p4 new file mode 100644 index 00000000000..65fe93f8c65 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/pgrs.p4 @@ -0,0 +1,309 @@ + +#ifdef __TARGET_TOFINO__ +#include +#include +#include +#include "tofino/stateful_alu_blackbox.p4" +#else +#include "includes/tofino.p4" +#include "includes/pktgen_headers.p4" +#endif +@pragma pa_alias ingress ig_intr_md.ingress_port ingress_metadata.ingress_port + +header_type pktgen_header_t { + fields { + id : 8; + } + +} + +header pktgen_header_t pgen_header; + +parser start { + extract(pgen_header); + return select(latest.id) { + 0x00 mask 0x1F: pktgen_port_down; // Pipe 0, App 0 + 0x01 mask 0x1F: pktgen_timer; // App 1 + 0x02 mask 0x1F: pktgen_recirc; // App 2 + 0x03 mask 0x1F: pktgen_timer; // App 3 + 0x04 mask 0x1F: pktgen_timer; // App 4 + 0x05 mask 0x1F: pktgen_timer; // App 5 + 0x06 mask 0x1F: pktgen_timer; // App 6 + 0x07 mask 0x1F: pktgen_timer; // App 7 + 0x08 mask 0x1F: pktgen_timer; // Pipe 1, App 0 + 0x09 mask 0x1F: pktgen_port_down; // App 1 + 0x0A mask 0x1F: pktgen_timer; // App 2 + 0x0B mask 0x1F: pktgen_recirc; // App 3 + 0x0C mask 0x1F: pktgen_timer; // App 4 + 0x0D mask 0x1F: pktgen_timer; // App 5 + 0x0E mask 0x1F: pktgen_timer; // App 6 + 0x0F mask 0x1F: pktgen_timer; // App 7 + 0x10 mask 0x1F: pktgen_timer; // Pipe 2, App 0 + 0x11 mask 0x1F: pktgen_timer; // App 1 + 0x12 mask 0x1F: pktgen_port_down; // App 2 + 0x13 mask 0x1F: pktgen_timer; // App 3 + 0x14 mask 0x1F: pktgen_recirc; // App 4 + 0x15 mask 0x1F: pktgen_timer; // App 5 + 0x16 mask 0x1F: pktgen_timer; // App 6 + 0x17 mask 0x1F: pktgen_timer; // App 7 + 0x18 mask 0x1F: pktgen_timer; // Pipe 3, App 0 + 0x19 mask 0x1F: pktgen_timer; // App 1 + 0x1A mask 0x1F: pktgen_timer; // App 2 + 0x1B mask 0x1F: pktgen_port_down; // App 3 + 0x1C mask 0x1F: pktgen_timer; // App 4 + 0x1D mask 0x1F: pktgen_recirc; // App 5 + 0x1E mask 0x1F: pktgen_timer; // App 6 + 0x1F mask 0x1F: pktgen_timer; // App 7 + default: ingress; + } +} + +parser pktgen_timer { + set_metadata(ig_md.pktgen_type, 0); + return pktgen_done; +} +parser pktgen_port_down { + set_metadata(ig_md.pktgen_type, 2); + return pktgen_done; +} +parser pktgen_recirc { + set_metadata(ig_md.pktgen_type, 3); + return pktgen_done; +} +parser pktgen_done { + return ingress; +} + + +header_type ig_md_t { + fields { + skip_lkups : 1; + pktgen_port : 1; + pktgen_type : 2; + test_recirc : 1; + pfe_override_test : 1; + } +} +metadata ig_md_t ig_md; + +action set_md(eg_port, skip, pktgen_port, test_recirc, mgid1, mgid2, pfe) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, eg_port); + modify_field(ig_md.skip_lkups, skip); + modify_field(ig_md.pktgen_port, pktgen_port); + modify_field(ig_md.test_recirc, test_recirc); + modify_field(ig_intr_md_for_tm.mcast_grp_a, mgid1); + modify_field(ig_intr_md_for_tm.mcast_grp_b, mgid2); + modify_field(ig_md.pfe_override_test, pfe); +} + +table port_tbl { + reads { + ig_intr_md.ingress_port : exact; + } + actions { + set_md; + } + size : 288; +} + + +action timer_ok() { +#ifndef __TARGET_TOFINO__ + modify_field(eg_intr_md.enq_congest_stat, 1024); + +#endif +} +action timer_nok() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 6); +} +table pg_verify_timer { + reads { + ig_intr_md.ingress_port : exact; + } + actions { + timer_ok; + timer_nok; + } +} + +action port_down_ok() { +} +action port_down_nok() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 6); +} +table pg_verify_port_down { + reads { + ig_intr_md.ingress_port : exact; + } + actions { + port_down_ok; + port_down_nok; + } +} + +action recirc_ok() { +} +action recirc_nok() { + modify_field(ig_intr_md_for_tm.ucast_egress_port, 6); +} +table pg_verify_recirc { + reads { + ig_intr_md.ingress_port : exact; + } + actions { + recirc_ok; + recirc_nok; + } +} + +action local_recirc(local_port) { +#ifdef __TARGET_TOFINO__ + recirculate( local_port ); +#endif +} +table do_local_recirc { + actions { local_recirc; } +} + +table eg_tcam_or_exm { + reads { ig_intr_md.ingress_port : exact; } + actions { + do_tcam; + do_exm; + } + size : 2; +} +action do_tcam() {} +action do_exm() {} +header_type pfe_md_t { + fields { + a:16; + } +} +metadata pfe_md_t pfe_md; +counter c1 { + type : packets; + instance_count : 500; +} +counter c2 { + type : packets; + instance_count : 500; +} +register r1 { + width : 32; + instance_count : 500; +} +register r2 { + width : 32; + instance_count : 500; +} +blackbox stateful_alu alu1 { + reg: r1; + update_lo_1_value: register_lo + 1; +} +blackbox stateful_alu alu2 { + reg: r2; + update_lo_1_value: register_lo + 1; +} +action a1() { +} +action a2(cntr_index) { + count(c1, cntr_index); +} +action a3() { + count(c2, ig_intr_md.ingress_port); +} +action a4() { + count(c1, 12); +} +action a5(stful_index) { + alu1.execute_stateful_alu(stful_index); +} +action a6() { + alu2.execute_stateful_alu(ig_intr_md.ingress_port); +} +action a7() { + alu1.execute_stateful_alu(12); +} + +table t1 { + reads { ig_intr_md.ingress_port : ternary; } + actions { a1; a2; a4; } + size : 5; +} +table t2 { + reads { ig_intr_md.ingress_port : ternary; } + actions { a1; a3; } + size : 5; +} +table t4 { + reads { ig_intr_md.ingress_port : ternary; } + actions { a1; a5; a7; } + size : 5; +} +table t5 { + reads { ig_intr_md.ingress_port : ternary; } + actions { a1; a6; } + size : 5; +} +table e1 { + reads { ig_intr_md.ingress_port : exact; } + actions { a1; a2; a4; } + size : 5; +} +table e2 { + reads { ig_intr_md.ingress_port : exact; } + actions { a1; a3; } + size : 5; +} +table e4 { + reads { ig_intr_md.ingress_port : exact; } + actions { a1; a5; a7; } + size : 5; +} +table e5 { + reads { ig_intr_md.ingress_port : exact; } + actions { a1; a6; } + size : 5; +} +control ingress { + //if (0 == ig_intr_md.resubmit_flag) { + apply(port_tbl); + //} + if (ig_md.skip_lkups == 0) { + if (ig_md.pktgen_port == 1) { + if (ig_md.pktgen_type == 0) { + apply( pg_verify_timer ); + } + if (ig_md.pktgen_type == 2) { + apply( pg_verify_port_down ); + } + if (ig_md.pktgen_type == 3) { + apply( pg_verify_recirc ); + } + } + if (ig_md.pfe_override_test == 1) { + apply(eg_tcam_or_exm) { + do_tcam { + apply(t1); + apply(t2); + apply(t4); + apply(t5); + } + do_exm { + apply(e1); + apply(e2); + apply(e4); + apply(e5); + } + } + } + } else { + if (ig_md.test_recirc == 1) { + apply( do_local_recirc ); + } + } +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/ptf/pktgen_headers.p4 b/backends/tofino/bf-asm/test/ptf/pktgen_headers.p4 new file mode 100644 index 00000000000..f03a97fc66d --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/pktgen_headers.p4 @@ -0,0 +1,57 @@ + +/******************************************************************************** + * Packet Generator Header Definition for Tofino * + *******************************************************************************/ + +#ifndef _TOFINO_LIB_PKTGEN_HEADERS +#define _TOFINO_LIB_PKTGEN_HEADERS 1 + +header_type pktgen_generic_header_t { + fields { + _pad0 : 3; + app_id : 3; + pipe_id : 2; + key_msb : 8; // Only valid for recirc triggers. + batch_id : 16; // Overloaded to port# or lsbs of key for port down and + // recirc triggers. + packet_id : 16; + } +} +header pktgen_generic_header_t pktgen_generic; + +header_type pktgen_timer_header_t { + fields { + _pad0 : 3; + app_id : 3; + pipe_id : 2; + _pad1 : 8; + batch_id : 16; + packet_id : 16; + } +} +header pktgen_timer_header_t pktgen_timer; + +header_type pktgen_port_down_header_t { + fields { + _pad0 : 3; + app_id : 3; + pipe_id : 2; + _pad1 : 15; + port_num : 9; + packet_id : 16; + } +} +header pktgen_port_down_header_t pktgen_port_down; + +header_type pktgen_recirc_header_t { + fields { + _pad0 : 3; + app_id : 3; + pipe_id : 2; + key : 24; + packet_id : 16; + } +} +header pktgen_recirc_header_t pktgen_recirc; + +#endif diff --git a/backends/tofino/bf-asm/test/ptf/pvs.p4 b/backends/tofino/bf-asm/test/ptf/pvs.p4 new file mode 100644 index 00000000000..31d88b55888 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/pvs.p4 @@ -0,0 +1,160 @@ +#include +#include +#include + +#define VLAN_DEPTH 2 +#define ETHERTYPE_VLAN 0x8100 +#define ETHERTYPE_IPV4 0x0800 + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pcp : 3; + cfi : 1; + vid : 12; + etherType : 16; + } +} + +header_type new_tag_24t { + fields { + t24_f1_6b : 6; + t24_f2_12b : 12; + t24_f3_14b : 14; + } +} + +header_type new_tag_32t { + fields { + t32_f1_16b : 16; + t32_f2_16b : 16; + } +} + +header_type new_tag_48t { + fields { + t48_f1_16b : 16; + t48_f2_32b : 32; + } +} + +header_type new_tag_64t { + fields { + t64_f1_48b : 48; + t64_f2_16b : 16; + } +} + +header ethernet_t ethernet; +header vlan_tag_t vlan_tag_; +header new_tag_24t new_tag24_; +header new_tag_32t new_tag32_; +header new_tag_48t new_tag48_; +header new_tag_64t new_tag64_; +header new_tag_64t new_tag64_2_; + +parser start { + return parse_ethernet; +} + +@pragma parser_value_set_size 5 +parser_value_set pvs1; +@pragma parser_value_set_size 7 +parser_value_set pvs2; +@pragma parser_value_set_size 9 +parser_value_set pvs3; +@pragma parser_value_set_size 2 +parser_value_set pvs4; +@pragma parser_value_set_size 5 +parser_value_set pvs5; + + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + pvs2 : parse_vlan; + default : ingress; + } +} + +parser parse_vlan { + extract(vlan_tag_); + return ingress; +} + + +// Example of using PVS along with constant select value +parser parse_hdr_pvs1 { + extract(new_tag24_); + return select(latest.t24_f1_6b, latest.t24_f3_14b) { + pvs3 : parse_hdr_pvs3; + 199: parse_hdr_pvs4; + default: ingress; + } +} + +parser parse_hdr_pvs2 { + extract(new_tag32_); + return ingress; +} + +parser parse_hdr_pvs3 { + extract(new_tag48_); + return select(latest.t48_f2_32b) { + pvs4: parse_hdr_pvs4; + default: ingress; + } +} + +parser parse_hdr_pvs4 { + extract(new_tag64_); + // Expected to get compile error when branch condition value is > 32bits + //return select(latest.t64_f1_48b) { + // 6700: parse_hdr_pvs5; + // default: ingress; + //} + return ingress; +} + +parser parse_hdr_pvs5 { + extract(new_tag64_2_); + return ingress; +} + + +action vlan_miss(egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +action vlan_hit(egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +table vlan { + reads { + vlan_tag_.vid: exact; + } + actions { + vlan_miss; + vlan_hit; + } + size : 512; +} + + +action noop() { + no_op(); +} + + +control ingress { + apply(vlan); +} + diff --git a/backends/tofino/bf-asm/test/ptf/range.p4 b/backends/tofino/bf-asm/test/ptf/range.p4 new file mode 100644 index 00000000000..84d66721b2c --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/range.p4 @@ -0,0 +1,185 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/constants.p4" + +/* Headers */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type ipv6_t { + fields { + version : 4; + trafficClass : 8; + flowLabel : 20; + payloadLen : 16; + nextHdr : 8; + hopLimit : 8; + srcAddr : 128; + dstAddr : 128; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + 0x86dd : parse_ipv6; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; +header ipv6_t ipv6; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +parser parse_ipv6 { + extract(ipv6); + return select(latest.nextHdr) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default : ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +header_type bit9_t { + fields { + gauche : 1; + tartly : 9; + } +} +metadata bit9_t bit9; + +/* Actions */ +action nop() { +} + +action set_val(val) { + modify_field(bit9.tartly, val); +} + +table range_set { + reads { + ipv4.srcAddr : exact; + } + actions { + set_val; + } +} + +action set_egress(port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} +/* Tables */ +table bit9_match { + reads { + bit9.gauche : ternary; + bit9.tartly : range; + } + actions { + set_egress; + } + size : 1024; +} + +/* Controls */ +control ingress { + apply(range_set); + apply(bit9_match); +} diff --git a/backends/tofino/bf-asm/test/ptf/resubmit.p4 b/backends/tofino/bf-asm/test/ptf/resubmit.p4 new file mode 100644 index 00000000000..c78ad7e8a23 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/resubmit.p4 @@ -0,0 +1,129 @@ + +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* + * This sample program hightlights the use of resubmit on Tofino + * Not tested on BM (v1 or v2). + */ + +#ifdef __TARGET_TOFINO__ +#include +#endif + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header ethernet_t ethernet; + +parser start { + extract(ethernet); + return ingress; +} + + +header_type test_metadata_t { + fields { + field_A: 8; + field_B: 8; + field_C: 16; + } +} + +metadata test_metadata_t test_metadata; + +field_list resubmit_fields { + test_metadata.field_A; + test_metadata.field_C; +} + +action nop() { + +} + +/* + * Processing regular packet + */ + +action do_resubmit_with_fields() { + modify_field(test_metadata.field_C, 0x1234); + resubmit(resubmit_fields); +} + +action do_resubmit() { +#if defined(BMV2TOFINO) + resubmit_no_fields(); +#else + resubmit(); +#endif +} + + +table l2_resubmit { + reads { + ethernet.dstAddr: exact; + } + actions { + nop; + do_resubmit; + do_resubmit_with_fields; + } + size : 512; +} + +/* + * Processing resubmitted packet + */ + +action nhop_set(port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action nhop_set_with_type(port) { + modify_field(ethernet.etherType, test_metadata.field_C); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +table l2_nhop { + reads { + ethernet.dstAddr: exact; + } + actions { + nop; + nhop_set; + nhop_set_with_type; + } + size : 512; +} + +/* Main control flow */ +control ingress { + if (0 == ig_intr_md.resubmit_flag) { + apply(l2_resubmit); + } else { + apply(l2_nhop); + } +} + +control egress { + +} + diff --git a/backends/tofino/bf-asm/test/ptf/smoke_large_tbls.p4 b/backends/tofino/bf-asm/test/ptf/smoke_large_tbls.p4 new file mode 100644 index 00000000000..84c26ea6eb3 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/smoke_large_tbls.p4 @@ -0,0 +1,253 @@ +#include +#include +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +field_list ipv4_field_list { + ipv4.version; + ipv4.ihl; + ipv4.diffserv; + ipv4.totalLen; + ipv4.identification; + ipv4.flags; + ipv4.fragOffset; + ipv4.ttl; + ipv4.protocol; + ipv4.srcAddr; + ipv4.dstAddr; +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +field_list_calculation ipv4_chksum_calc { + input { + ipv4_field_list; + } + algorithm : csum16; + output_width: 16; +} + +calculated_field ipv4.hdrChecksum { + update ipv4_chksum_calc; +} + +counter dummy_cntr { + type : packets; + direct : idle_stats_tbl; +} + +action drop_count (count_idx) { + //count(dummy_cntr, count_idx); + drop(); +} + +action nop() { +} + +action set_egress (egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); +} + +@pragma command_line --no-dead-code-elimination +table idle_stats_tbl { + reads { + ethernet.dstAddr : ternary; + ethernet.srcAddr : ternary; + ethernet.etherType : ternary; + vlan_tag.pri : ternary; + vlan_tag.cfi : ternary; + vlan_tag.vlan_id : ternary; + vlan_tag.etherType : ternary; + ipv4.version : ternary; + ipv4.ihl : ternary; + ipv4.diffserv : ternary; + ipv4.totalLen : ternary; + ipv4.identification : ternary; + ipv4.flags : ternary; + ipv4.fragOffset : ternary; + ipv4.ttl : ternary; + ipv4.protocol : ternary; + ipv4.hdrChecksum : ternary; + ipv4.dstAddr : lpm; + ipv4.srcAddr : ternary; + tcp.srcPort : ternary; + tcp.dstPort : ternary; + tcp.seqNo : ternary; + tcp.ackNo : ternary; + tcp.dataOffset : ternary; + tcp.res : ternary; + tcp.ecn : ternary; + tcp.ctrl : ternary; + tcp.window : ternary; + tcp.checksum : ternary; + tcp.urgentPtr : ternary; + udp.srcPort : ternary; + udp.dstPort : ternary; + udp.hdr_length : ternary; + } + actions { + set_egress; + nop; + } + size : 2048; + support_timeout: true; +} + +@pragma pack 2 +@pragma ways 4 +@pragma atcam_partition_index vlan_tag.vlan_id +//@pragma atcam_number_partitions 1024 +table atcam_tbl { + reads { + tcp.valid : ternary; + vlan_tag.vlan_id : exact; + ipv4.dstAddr : ternary; + } + actions { + set_egress; + nop; + } + size: 500000; +} + +action set_ip_id (ip_id, egress_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); + modify_field(ipv4.identification, ip_id); +} + +action_profile atcam_action_profile { + actions { + set_ip_id; + nop; + } + size : 65536; +} + +@pragma atcam_partition_index vlan_tag.vlan_id +//@pragma atcam_number_partitions 1024 +table atcam_indirect_tbl { + reads { + vlan_tag.vlan_id : exact; + ipv4.srcAddr : ternary; + } + action_profile : atcam_action_profile; + size: 100000; +} + +control ingress { + apply(idle_stats_tbl); + apply(atcam_tbl); + apply(atcam_indirect_tbl); +} + +control egress { +} + diff --git a/backends/tofino/bf-asm/test/ptf/stats_pi.p4 b/backends/tofino/bf-asm/test/ptf/stats_pi.p4 new file mode 100644 index 00000000000..51e60a2f816 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/stats_pi.p4 @@ -0,0 +1,171 @@ +/* Copyright 2013-present Barefoot Networks, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type meta_t { + fields { + f8 : 8; + f16 : 16; + f20 : 20; + f24 : 24; + f32 : 32; + f48 : 48; + f64 : 64; + } +} + +metadata meta_t meta; +header ethernet_t ethernet; + +parser start { + return parse_ethernet; +} + +parser parse_ethernet { + extract(ethernet); + return ingress; +} + +action no_op() { } + +action actionA(param, port) { + modify_field(meta.f32, param); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action actionB(port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +table ExactOne { + reads { + ethernet.dstAddr : exact; + } + actions { + actionA; actionB; no_op; + } + size: 512; +} + +counter ExactOne_counter { + type : packets; + direct : ExactOne; +} + +meter ExactOne_meter { + type : bytes; + direct : ExactOne; + result : meta.f8; +} + +meter MeterA { + type : packets; + instance_count : 1024; +} + +action _MeterAAction() { + execute_meter(MeterA, 16, meta.f8); +} + +table _MeterATable { + reads { + ethernet.dstAddr : exact; + } + actions { + _MeterAAction; + } + size: 512; +} + +counter CounterA { + type : packets; + instance_count : 1024; +} + +action _CounterAAction1(idx) { + count(CounterA, idx); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 3); +} + +action _CounterAAction2() { + count(CounterA, 37); + modify_field(ig_intr_md_for_tm.ucast_egress_port, 3); +} + +table _CounterATable { + reads { + ethernet.dstAddr : exact; + } + actions { + _CounterAAction1; _CounterAAction2; + } + size: 512; +} + +// an indirect table to test indirect resource management + +field_list hash_fields { ethernet.srcAddr; } +field_list_calculation hash { + input { hash_fields; } + algorithm : crc16; + output_width : 16; +} + +table IndirectTable { + reads { ethernet.dstAddr : exact; } + action_profile : ActionProf; + size : 1024; +} + +counter CounterB { + type : packets; + instance_count : 64; +} + +action indirectAction(idx, port) { + count(CounterB, idx); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +action_profile ActionProf { + actions { indirectAction; } + size : 128; + dynamic_action_selection : Selector; +} + +action_selector Selector { + selection_key : hash; +} + +control ingress { + apply(ExactOne); + apply(_MeterATable); + apply(_CounterATable); + apply(IndirectTable); +} + +control egress { + +} diff --git a/backends/tofino/bf-asm/test/ptf/stful.p4 b/backends/tofino/bf-asm/test/ptf/stful.p4 new file mode 100644 index 00000000000..b29954ac924 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/stful.p4 @@ -0,0 +1,932 @@ +#include "tofino/intrinsic_metadata.p4" +#include "tofino/stateful_alu_blackbox.p4" +#include "tofino/pktgen_headers.p4" + + +/* + * TCAM EXM No Tbl + * Direct Addressed egr_port ifid XXX + * Indirect Addressed next_hop sip_sampler + * Hash Addressed flowlet bloom filter + * Logging Addressed + */ +header_type ethernet_t { + fields { + dmac : 48; + smac : 48; + ethertype : 16; + } +} +header ethernet_t ethernet; + +header_type ipv4_t { + fields { + ver : 4; + len : 4; + diffserv : 8; + totalLen : 16; + id : 16; + flags : 3; + offset : 13; + ttl : 8; + proto : 8; + csum : 16; + sip : 32; + dip : 32; + } +} +header ipv4_t ipv4; + +header_type tcp_t { + fields { + sPort : 16; + dPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} +header tcp_t tcp; + +header_type udp_t { + fields { + sPort : 16; + dPort : 16; + hdr_length : 16; + checksum : 16; + } +} +header udp_t udp; + +header_type user_metadata_t { + fields { + ifid : 16; + egr_ifid : 16; + timestamp : 48; + offset : 32 (signed); + bf_tmp_1 : 1; + bf_tmp_2 : 1; + bf_tmp_3 : 1; + flowlet_hash_input : 8; + nh_id : 16; + flowlet_temp : 15; + flowlet_ts : 32; + lag_tbl_bit_index : 17; + ecmp_tbl_bit_index: 17; + pkt_gen_pkt : 1; + recirc_pkt : 1; + one_bit_val_1 : 1; + one_bit_val_2 : 1; + } +} +@pragma pa_solitary ingress md.flowlet_temp +metadata user_metadata_t md; + +header_type recirc_header_t { + fields { + tag : 4; // Must be 0xF + rtype : 4; // 0: TDB, 1: pktgen port down, 2:pktgen recirc, 3:TDB, ... + pad : 8; + key : 16; + } +} +header recirc_header_t recirc_hdr; + +parser start { + return select( current(0,8) ) { + 0x01 mask 0xE7: parse_pkt_gen_port_down; // Pipe x, App 1 + 0x02 mask 0xE7: parse_pkt_gen_recirc; // Pipe x, App 2 + 0x03 mask 0xE7: parse_pkt_gen_hw_clr; // Pipex, App 3 + 0xF0 mask 0xF0: parse_recirc_pkt; + default: parse_ethernet; + } +} + +#define RECIRC_TYPE_PG_PORT_DOWN 1 +#define RECIRC_TYPE_PG_RECIRC 2 + +parser parse_recirc_pkt { + extract(recirc_hdr); + set_metadata(md.recirc_pkt, 1); + return select(latest.rtype) { + RECIRC_TYPE_PG_PORT_DOWN : parse_pkt_gen_port_down; + RECIRC_TYPE_PG_RECIRC : parse_recirc_trigger_pkt; + default: ingress; + } +} +parser parse_ethernet { + extract(ethernet); + return select(latest.ethertype) { + 0x0800 : parse_ipv4; + } +} +parser parse_ipv4 { + extract(ipv4); + return select(latest.proto) { + 6 : parse_tcp; + 17: parse_udp; + } +} +parser parse_tcp { + extract(tcp); + return ingress; +} +parser parse_udp { + extract(udp); + return ingress; +} + +parser parse_pkt_gen_port_down { + extract(pktgen_port_down); + set_metadata(md.pkt_gen_pkt, 1); + return ingress; +} + +parser parse_pkt_gen_recirc { + extract(pktgen_recirc); + set_metadata(md.pkt_gen_pkt, 1); + return ingress; +} + +parser parse_pkt_gen_hw_clr { + extract(pktgen_generic); + set_metadata(md.pkt_gen_pkt, 1); + return ingress; +} + +parser parse_recirc_trigger_pkt { + return parse_ethernet; +} + + + + +/****************************************************************************** + * + * Ingress Port Table + * + *****************************************************************************/ +action set_ifid(ifid) { + modify_field(md.ifid, ifid); +} + +@pragma --metadata-overlay False +table ing_port { + reads { ig_intr_md.ingress_port : exact; } + actions { set_ifid; } + size : 288; +} + +/****************************************************************************** + * + * Test one bit reads + * + *****************************************************************************/ +register ob1 { + width : 1; + instance_count: 1000; +} +register ob2 { + width : 1; + instance_count: 1000; +} +blackbox stateful_alu one_bit_alu_1 { + reg: ob1; + output_value: register_lo; + output_dst: md.one_bit_val_1; +} +blackbox stateful_alu one_bit_alu_2 { + reg: ob2; + update_lo_1_value: read_bit; + output_value: alu_lo; + output_dst: md.one_bit_val_2; +} +table one_bit_read_1 { + actions { run_one_bit_read_1; } + default_action: run_one_bit_read_1; + size : 1; +} +table one_bit_read_2 { + actions { run_one_bit_read_2; } + default_action: run_one_bit_read_2; + size : 1; +} +action run_one_bit_read_1() { one_bit_alu_1.execute_stateful_alu(1); } +action run_one_bit_read_2() { one_bit_alu_2.execute_stateful_alu(2); } +table undrop { + actions {do_undrop;} + default_action: do_undrop; + size: 1; +} +action do_undrop() { + modify_field(ig_intr_md_for_tm.drop_ctl, 0); + modify_field(ig_intr_md_for_tm.ucast_egress_port, ig_intr_md.ingress_port); +} + +/****************************************************************************** + * + * IFID Table + * - Runs a stateful table to increment a signed saturating counter + * + *****************************************************************************/ +register ifid_cntr { + width: 16; + direct: ifid; + attributes: signed, saturating; +} +blackbox stateful_alu ifid_cntr_alu { + reg: ifid_cntr; + update_lo_1_value: register_lo + ipv4.ttl; +} +action set_ifid_based_params(ts, offset) { + run_ifid_cntr(); + modify_field(md.timestamp, ts); + modify_field(md.offset, offset); +} +action drop_it() { + run_ifid_cntr(); + mark_for_drop(); +} +action run_ifid_cntr() { + ifid_cntr_alu.execute_stateful_alu(); +} +table ifid { + reads { md.ifid : exact; } + actions { + set_ifid_based_params; + drop_it; + } + size : 25000; +} + +/****************************************************************************** + * + * Bloom Filter Table + * - Will set the C2C flag for packets not part of the filter + * - Will add the packet to the filter + * + *****************************************************************************/ + +/* Field list describing which fields contribute to the bloom filter hash. */ +field_list bf_hash_fields { + ipv4.proto; + ipv4.sip; + ipv4.dip; + tcp.sPort; + tcp.dPort; +} + +/* Three hash functions for the filter, just using random hash functions right + * now. */ +field_list_calculation bf_hash_1 { + input { bf_hash_fields; } +#ifdef BMV2TOFINO + algorithm: crc32; +#else + algorithm: random; +#endif + output_width: 18; +} +field_list_calculation bf_hash_2 { + input { bf_hash_fields; } +#ifdef BMV2TOFINO + algorithm: crc16; +#else + algorithm: random; +#endif + output_width: 18; +} +field_list_calculation bf_hash_3 { + input { bf_hash_fields; } +#ifdef BMV2TOFINO + algorithm: csum16; +#else + algorithm: random; +#endif + output_width: 18; +} + +field_list bf_clr_hash_fields { + pktgen_generic.batch_id; + pktgen_generic.packet_id; +} +field_list_calculation bf_clr_hash { + input { bf_clr_hash_fields; } + algorithm: identity; + output_width: 18; +} + +/* Three registers implementing the bloom filter. Each register takes 3 RAMs; + * each RAM has 128k entries so two RAMs to make 256k plus a third RAM as the + * spare, so 9 RAMs total. */ +register bloom_filter_1 { + width : 1; + instance_count : 262144; +} +register bloom_filter_2 { + width : 1; + instance_count : 262144; +} +register bloom_filter_3 { + width : 1; + instance_count : 262144; +} + +/* Three stateful ALU blackboxes running the bloom filter. + * Note there is no reduction-OR support yet so each ALU outputs to a separate + * metadata temp variable. + * Output is 1 if the packet is not in the filter and 0 if it is in. */ +blackbox stateful_alu bloom_filter_alu_1 { + reg: bloom_filter_1; + update_lo_1_value: set_bitc; + output_value: alu_lo; + output_dst: md.bf_tmp_1; +} +blackbox stateful_alu bloom_filter_alu_2 { + reg: bloom_filter_2; + update_lo_1_value: set_bitc; + output_value: alu_lo; + output_dst: md.bf_tmp_2; +} +blackbox stateful_alu bloom_filter_alu_3 { + reg: bloom_filter_3; + update_lo_1_value: set_bitc; + output_value: alu_lo; + output_dst: md.bf_tmp_3; +} +blackbox stateful_alu clr_bloom_filter_alu_1 { + reg: bloom_filter_1; + update_lo_1_value: clr_bit; +} +blackbox stateful_alu clr_bloom_filter_alu_2 { + reg: bloom_filter_2; + update_lo_1_value: clr_bit; +} +blackbox stateful_alu clr_bloom_filter_alu_3 { + reg: bloom_filter_3; + update_lo_1_value: clr_bit; +} + +/* Note that we need additional actions here to OR the bloom filter results + * into a single result. */ +action check_bloom_filter_1() { + bloom_filter_alu_1.execute_stateful_alu_from_hash(bf_hash_1); +} +action check_bloom_filter_2() { + bloom_filter_alu_2.execute_stateful_alu_from_hash(bf_hash_2); +} +action check_bloom_filter_3() { + bloom_filter_alu_3.execute_stateful_alu_from_hash(bf_hash_3); +} +action bloom_filter_mark_sample() { + modify_field(ig_intr_md_for_tm.copy_to_cpu, 1); +} +action clear_bloom_filter_1() { + clr_bloom_filter_alu_1.execute_stateful_alu_from_hash(bf_clr_hash); +} +action clear_bloom_filter_2() { + clr_bloom_filter_alu_2.execute_stateful_alu_from_hash(bf_clr_hash); +} +action clear_bloom_filter_3() { + clr_bloom_filter_alu_3.execute_stateful_alu_from_hash(bf_clr_hash); +} + +@pragma stage 0 +table bloom_filter_1 { + actions { check_bloom_filter_1; } + size : 1; +} +@pragma stage 1 +table bloom_filter_2 { + actions { check_bloom_filter_2; } + size : 1; +} +@pragma stage 1 +table bloom_filter_3 { + actions { check_bloom_filter_3; } + size : 1; +} +@pragma stage 0 +table clr_bloom_filter_1 { + actions { clear_bloom_filter_1; } + size : 1; +} +@pragma stage 1 +table clr_bloom_filter_2 { + actions { clear_bloom_filter_2; } + size : 1; +} +@pragma stage 1 +table clr_bloom_filter_3 { + actions { clear_bloom_filter_3; } + size : 1; +} +action drop_clearing_packet() { drop(); } +table drop_bloom_filter_clear { + actions { drop_clearing_packet; } + size : 1; +} + +/* Extra tables to run an action to mark a packet for sampling. + * This will be removed once the compiler supports the reduction-OR + * operation. */ +table bloom_filter_sample { + actions { bloom_filter_mark_sample; } + size : 1; +} + + +/****************************************************************************** + * + * Sampling Table + * - Sample, with C2C, every Nth packet from a particular IPv4 source. + * - Note that multiple IPv4 sources can share the same stateful entry to + * - sample the Nth packet from a group of sources. + * + *****************************************************************************/ +register sampling_cntr { + width : 32; + static: sip_sampler; + instance_count : 143360; // Fills 35 + 1 spare RAMs (max size) +} + +/* Note the extra complexity of this ALU program is required so that if C2C was + * already set (by the bloom filter) it will stay set even if this ALU says not + * to sample. */ +blackbox stateful_alu sampling_alu { + reg: sampling_cntr; + initial_register_lo_value: 1; + condition_lo: register_lo >= 10; + condition_hi: ig_intr_md_for_tm.copy_to_cpu != 0; + update_lo_1_predicate: condition_lo; + update_lo_1_value: 1; + update_lo_2_predicate: not condition_lo; + update_lo_2_value: register_lo + 1; + update_hi_1_value: 1; + output_predicate: condition_lo or condition_hi; + output_value : alu_hi; + output_dst : ig_intr_md_for_tm.copy_to_cpu; +} +action sample(index) { + sampling_alu.execute_stateful_alu(index); +} +action no_sample() {} +table sip_sampler { + reads { ipv4.sip : exact; } + actions { + sample; + no_sample; + } + size : 85000; +} + + +/****************************************************************************** + * + * Flowlet Table + * - Generate an extra 8 bit field to influence action profile selection. + * - Ideally the timestamp should come from the "global timestamp" intrinsic + * metadata however that is difficult to control from a test script, instead + * a dummy timestamp will be used. + * + *****************************************************************************/ +/* Field list describing which fields contribute to the flowlet hash. */ +field_list flowlet_hash_fields { + ipv4.proto; + ipv4.sip; + ipv4.dip; + tcp.sPort; + tcp.dPort; +} +field_list_calculation flowlet_hash { + input { flowlet_hash_fields; } + algorithm: crc16; + output_width: 15; +} + +register flowlet_state { + width : 64; + instance_count : 32768; +} + +/* Flowlet lifetime is 50 microseconds. Use 0xFFFF as un-initialized value + * to signal no next hop has been stored yet. */ +blackbox stateful_alu flowlet_alu { + reg: flowlet_state; + condition_hi: register_hi != 65535; + condition_lo: md.flowlet_ts - register_lo > 50000; + update_hi_1_predicate: condition_hi or condition_lo; + update_hi_1_value: md.nh_id; + update_lo_2_value: md.flowlet_ts; + output_value: alu_hi; + output_dst: md.nh_id; + initial_register_hi_value: 65535; + initial_register_lo_value: 60000; +} + +action set_flowlet_hash_and_ts() { + modify_field_with_hash_based_offset(md.flowlet_temp, 0, flowlet_hash, 32768); + modify_field(md.flowlet_ts, md.timestamp); +} +table flowlet_prepare { + actions { set_flowlet_hash_and_ts; } + size : 1; +} +action run_flowlet_alu() { + flowlet_alu.execute_stateful_alu(md.flowlet_temp); +} +table flowlet_next_hop { + actions { run_flowlet_alu; } + size : 1; +} + + +/****************************************************************************** + * + * IPv4 Route Table + * + *****************************************************************************/ +action set_next_hop(nh) { + modify_field(md.nh_id, nh); +} +action set_ecmp(ecmp_id) { + modify_field(md.nh_id, ecmp_id); +} +table ipv4_route { + reads { ipv4.dip : lpm; } + actions { + set_next_hop; + set_ecmp; + } + size : 512; +} + +/****************************************************************************** + * + * Next Hop ECMP Table + * + *****************************************************************************/ +field_list next_hop_ecmp_hash_fields { + ipv4.proto; + ipv4.sip; + ipv4.dip; + tcp.sPort; + tcp.dPort; + md.flowlet_hash_input; +} +field_list_calculation next_hop_ecmp_hash { + input { next_hop_ecmp_hash_fields; } + algorithm : crc32; + output_width : 29; +} +register next_hop_ecmp_reg { + width : 1; + instance_count : 131072; +} +blackbox stateful_alu next_hop_ecmp_alu { + reg: next_hop_ecmp_reg; + selector_binding: next_hop_ecmp; + update_lo_1_value: clr_bit; +} +action_selector next_hop_ecmp_selector { + selection_key: next_hop_ecmp_hash; + selection_mode: fair; +} +action_profile next_hop_ecmp_ap { + actions { set_next_hop; } + size : 4096; + dynamic_action_selection : next_hop_ecmp_selector; +} +@pragma stage 6 +@pragma selector_max_group_size 200 +table next_hop_ecmp { + reads { md.nh_id : exact; } + action_profile : next_hop_ecmp_ap; + size : 4096; +} +field_list ecmp_index_identity_hash_fields { + md.ecmp_tbl_bit_index; +} +field_list_calculation ecmp_index_identity_hash { + input { ecmp_index_identity_hash_fields; } + algorithm: identity; + output_width: 17; +} +action set_mbr_down() { + next_hop_ecmp_alu.execute_stateful_alu_from_hash(ecmp_index_identity_hash); + drop(); +} +@pragma stage 6 +table next_hop_ecmp_fast_update { + actions { + set_mbr_down; + } + size : 1; +} + +@pragma stage 5 +table make_key_ecmp_fast_update { + reads { + pktgen_recirc.key mask 0xFFFF : exact; + pktgen_recirc.packet_id : exact; + } + actions { + set_ecmp_fast_update_key; + drop_ecmp_update_pkt; + } + default_action: drop_ecmp_update_pkt; + size : 16384; +} +action set_ecmp_fast_update_key(key) { + modify_field(md.ecmp_tbl_bit_index, key); +} +action drop_ecmp_update_pkt() { + drop(); +} + +/****************************************************************************** + * + * Next Hop Table + * - Uses a register to do useless operations to test multiple instructions + * on a stateful ALU. + * + *****************************************************************************/ +register scratch { + width: 16; + static: next_hop; + instance_count: 4096; +} +blackbox stateful_alu scratch_alu_add { + reg: scratch; + update_lo_1_value: register_lo + md.nh_id; +} +blackbox stateful_alu scratch_alu_sub { + reg: scratch; + update_lo_1_value: md.nh_id - register_lo; +} +blackbox stateful_alu scratch_alu_zero { + reg: scratch; + update_lo_1_value: 0; +} +blackbox stateful_alu scratch_alu_invert { + reg: scratch; + update_lo_1_value: ~register_lo; +} + +action set_egr_ifid(ifid) { + modify_field(md.egr_ifid, ifid); +} +action scratch_add(index, ifid) { + set_egr_ifid(ifid); + scratch_alu_add.execute_stateful_alu(index); +} +action scratch_sub(index, ifid) { + set_egr_ifid(ifid); + scratch_alu_sub.execute_stateful_alu(index); +} +action scratch_zero(index, ifid) { + set_egr_ifid(ifid); + scratch_alu_zero.execute_stateful_alu(index); +} +action scratch_invert(index, ifid) { + set_egr_ifid(ifid); + scratch_alu_invert.execute_stateful_alu(index); +} +action next_hop_down(mgid) { + add_header(recirc_hdr); + modify_field(recirc_hdr.tag, 0xF); + modify_field(recirc_hdr.rtype, RECIRC_TYPE_PG_RECIRC); + modify_field(recirc_hdr.pad, 0); + modify_field(recirc_hdr.key, md.nh_id); + modify_field(ig_intr_md_for_tm.mcast_grp_b, mgid); +} +table next_hop { + reads { md.nh_id : ternary; } + actions { + set_egr_ifid; + scratch_add; + scratch_sub; + scratch_zero; + scratch_invert; + next_hop_down; + } + size: 4096; +} + + +/****************************************************************************** + * + * Egress Ifid Table + * + *****************************************************************************/ +register lag_reg { + width : 1; + instance_count : 131072; +} +blackbox stateful_alu lag_alu { + reg: lag_reg; + selector_binding: egr_ifid; + update_lo_1_value: clr_bit; +} +@pragma seletor_num_max_groups 128 +@pragma selector_max_group_size 1200 +table egr_ifid { + reads {md.egr_ifid : exact;} + action_profile : lag_ap; + size : 16384; +} +action_profile lag_ap { + actions { set_egr_port; } + size : 4096; + dynamic_action_selection : lag_as; +} +action_selector lag_as { + selection_key: lag_hash; + selection_mode: resilient; +} +field_list_calculation lag_hash { + input { lag_fields; } +#ifdef BMV2TOFINO + algorithm: xxh64; +#else + algorithm: random; +#endif + output_width: 66; +} +field_list lag_fields { + ipv4.proto; + ipv4.sip; + ipv4.dip; + tcp.sPort; + tcp.dPort; + ig_intr_md.ingress_port; +} +action set_egr_port(port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +@pragma stage 7 +table egr_ifid_fast_update_make_key { + reads { + pktgen_port_down.port_num : exact; + pktgen_port_down.packet_id : exact; + } + actions { + set_lag_fast_update_key; + drop_ifid_update_pkt; + } + default_action: drop_ifid_update_pkt; + size : 16384; +} +action set_lag_fast_update_key(key) { + modify_field(md.lag_tbl_bit_index, key); +} +@pragma stage 8 +table egr_ifid_fast_update { + actions { + set_lag_mbr_down; + } + size : 1; +} +field_list lag_index_identity_hash_fields { + md.lag_tbl_bit_index; +} +field_list_calculation lag_index_identity_hash { + input { lag_index_identity_hash_fields; } + algorithm: identity; + output_width: 17; +} +action set_lag_mbr_down() { + lag_alu.execute_stateful_alu_from_hash(lag_index_identity_hash); + drop(); +} +action drop_ifid_update_pkt() { + drop(); +} + +/****************************************************************************** + * + * Egress Port Table + * + *****************************************************************************/ +register port_cntr { + width: 64; + direct: egr_port; + attributes: signed; +} +blackbox stateful_alu counter_alu { + reg: port_cntr; + condition_hi: register_lo < 0; + condition_lo: register_lo + md.offset < 0; + + update_hi_1_predicate: condition_hi and not condition_lo; + update_hi_1_value: register_hi + 1; + update_hi_2_predicate: not condition_hi and condition_lo; + update_hi_2_value: register_hi - 1; + + update_lo_1_value: register_lo + md.offset; +} + +action set_dest(port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); + counter_alu.execute_stateful_alu(); +} +table egr_port { + reads { md.egr_ifid : ternary; } + actions { set_dest; } + size : 16384; +} + + +control ingress { + if (0 == ig_intr_md.resubmit_flag) { + apply(ing_port); + } + if (0 == md.recirc_pkt and 0 == md.pkt_gen_pkt) { + apply( ifid ) { + drop_it { + apply(one_bit_read_1); + apply(one_bit_read_2); + if (md.one_bit_val_1 == 1 and md.one_bit_val_2 == 1) { + apply(undrop); + } + } + default { + apply(bloom_filter_1); + apply(bloom_filter_2); + apply(bloom_filter_3); + if ((md.bf_tmp_1 != 0) or (md.bf_tmp_2 != 0) or (md.bf_tmp_3 != 0)) { + apply(bloom_filter_sample); + } + + apply(sip_sampler); + + apply(flowlet_prepare); + apply(ipv4_route) { + set_ecmp { + apply(next_hop_ecmp); + //apply(flowlet_next_hop); + } + } + + apply(next_hop); + + apply(egr_ifid) { + miss { + apply(egr_port); + } + } + } + } + } else if (0 == md.recirc_pkt and 1 == md.pkt_gen_pkt) { + pgen_pass_1_ctrl_flow(); + } else if (1 == md.recirc_pkt and 0 == md.pkt_gen_pkt) { + recirc_trigger_pkt_ctrl_flow(); + } else if (1 == md.recirc_pkt and 1 == md.pkt_gen_pkt) { + pgen_pass_2_ctrl_flow(); + } +} + +control recirc_trigger_pkt_ctrl_flow { + /* Nothing to do let it go to the deparser and be dropped. */ +} + +@pragma stage 8 +table prepare_for_recirc { + reads { pktgen_port_down.app_id : exact; } + actions {prepare_for_recirc;} + size : 7; +} +action prepare_for_recirc(rtype, mgid) { + add_header(recirc_hdr); + modify_field(recirc_hdr.tag, 0xF); + modify_field(recirc_hdr.rtype, rtype); + modify_field(ig_intr_md_for_tm.mcast_grp_b, mgid); +} +control pgen_pass_1_ctrl_flow { + if ( valid(pktgen_generic) ) { + apply( clr_bloom_filter_1 ); + apply( clr_bloom_filter_2 ); + apply( clr_bloom_filter_3 ); + } else if ( valid(pktgen_recirc) ) { + apply(make_key_ecmp_fast_update); + apply(next_hop_ecmp_fast_update); + } else { + apply(prepare_for_recirc); + } +} + +control pgen_pass_2_ctrl_flow { + if (recirc_hdr.rtype == RECIRC_TYPE_PG_RECIRC) { + + } else if (recirc_hdr.rtype == RECIRC_TYPE_PG_PORT_DOWN) { + apply(egr_ifid_fast_update_make_key); + apply(egr_ifid_fast_update); + } +} diff --git a/backends/tofino/bf-asm/test/ptf/tofino.p4 b/backends/tofino/bf-asm/test/ptf/tofino.p4 new file mode 100644 index 00000000000..31890f6df19 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/tofino.p4 @@ -0,0 +1,145 @@ +/******************************************************************************* + * Intrinsic Metadata Definition for Tofino * + ******************************************************************************/ + +header_type ingress_parser_control_signals { + fields { + priority : 3; // set packet priority + } +} +metadata ingress_parser_control_signals ig_prsr_ctrl; + +header_type ingress_intrinsic_metadata_t { + fields { + resubmit_flag : 1; // flag distinguishing original packets + // from resubmitted packets. + + ingress_port : 9; // ingress physical port id. + + ingress_global_tstamp : 48; // global timestamp (ns) taken upon + // arrival at ingress. + + lf_field_list : 32; // hack for learn filter. + } +} +metadata ingress_intrinsic_metadata_t ig_intr_md; + +header_type ingress_intrinsic_metadata_for_tm_t { + fields { + ucast_egress_port : 9; // egress port for unicast packets. + + mcast_grp_a : 16; // 1st multicast group (i.e., tree) id; + // a tree can have two levels. must be + // presented to TM for multicast. + + mcast_grp_b : 16; // 2nd multicast group (i.e., tree) id; + // a tree can have two levels. + + level1_mcast_hash : 13; // source of entropy for multicast + // replication-tree level1 (i.e., L3 + // replication). must be presented to TM + // for L3 dynamic member selection + // (e.g., ECMP) for multicast. + + level2_mcast_hash : 13; // source of entropy for multicast + // replication-tree level2 (i.e., L2 + // replication). must be presented to TM + // for L2 dynamic member selection + // (e.g., LAG) for nested multicast. + + level1_exclusion_id : 16; // exclusion id for multicast + // replication-tree level1. used for + // pruning. + + level2_exclusion_id : 9; // exclusion id for multicast + // replication-tree level2. used for + // pruning. + + rid : 16; // L3 replication id for multicast. + // used for pruning. + deflect_on_drop : 1; // flag indicating whether a packet can + // be deflected by TM on congestion drop + } +} + +metadata ingress_intrinsic_metadata_for_tm_t ig_intr_md_for_tm; + +header_type egress_intrinsic_metadata_t { + fields { + egress_port : 16; // egress port id. + + enq_qdepth : 19; // queue depth at the packet enqueue + // time. + + enq_congest_stat : 2; // queue congestion status at the packet + // enqueue time. + + enq_tstamp : 32; // time snapshot taken when the packet + // is enqueued (in nsec). + + deq_qdepth : 19; // queue depth at the packet dequeue + // time. + + deq_congest_stat : 2; // queue congestion status at the packet + // dequeue time. + + app_pool_congest_stat : 8; // dequeue-time application-pool + // congestion status. 2bits per + // pool. + + deq_timedelta : 32; // time delta between the packet's + // enqueue and dequeue time. + + egress_rid : 16; // L3 replication id for multicast + // packets. + + egress_rid_first : 1; // flag indicating the first replica for + // the given multicast group. + + egress_qid : 5; // egress (physical) queue id via which + // this packet was served. + + egress_cos : 3; // egress cos (eCoS) value. + + deflection_flag : 1; // flag indicating whether a packet is + // deflected due to deflect_on_drop. + } +} + +metadata egress_intrinsic_metadata_t eg_intr_md; + +/* primitive/library function extensions */ + +action deflect_on_drop() { + modify_field(ig_intr_md_for_tm.deflect_on_drop, 1); +} + +#define _ingress_global_tstamp_ ig_intr_md.ingress_global_tstamp + +header_type egress_intrinsic_metadata_from_parser_aux_t { + fields { + clone_src : 8; + egress_global_tstamp: 48; + } +} +metadata egress_intrinsic_metadata_from_parser_aux_t eg_intr_md_from_parser_aux; + +#define PKT_INSTANCE_TYPE_NORMAL 0 +#define PKT_INSTANCE_TYPE_INGRESS_CLONE 1 +#define PKT_INSTANCE_TYPE_EGRESS_CLONE 2 +#define PKT_INSTANCE_TYPE_COALESCED 3 +#define PKT_INSTANCE_TYPE_INGRESS_RECIRC 4 +#define PKT_INSTANCE_TYPE_REPLICATION 5 +#define PKT_INSTANCE_TYPE_RESUBMIT 6 + +// XXX check other types RECIRC etc and exclude those +#define pkt_is_mirrored \ + ((standard_metadata.instance_type != PKT_INSTANCE_TYPE_NORMAL) and \ + (standard_metadata.instance_type != PKT_INSTANCE_TYPE_REPLICATION)) +#define pkt_is_not_mirrored \ + ((standard_metadata.instance_type == PKT_INSTANCE_TYPE_NORMAL) or \ + (standard_metadata.instance_type == PKT_INSTANCE_TYPE_REPLICATION)) +#define pkt_is_i2e_mirrored \ + (standard_metadata.instance_type == PKT_INSTANCE_TYPE_INGRESS_CLONE) +#define pkt_is_e2e_mirrored \ + (standard_metadata.instance_type == PKT_INSTANCE_TYPE_EGRESS_CLONE) diff --git a/backends/tofino/bf-asm/test/ptf/tofino/constants.p4 b/backends/tofino/bf-asm/test/ptf/tofino/constants.p4 new file mode 100644 index 00000000000..c4540219da4 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/tofino/constants.p4 @@ -0,0 +1,52 @@ +// This file is to be kept in precise sync with constants.py + +#ifndef _TOFINO_LIB_CONSTANTS +#define _TOFINO_LIB_CONSTANTS 1 + +///////////////////////////////////////////////////////////// +// Parser hardware error codes +#define PARSER_ERROR_OK 0x0000 +#define PARSER_ERROR_NO_TCAM 0x0001 +#define PARSER_ERROR_PARTIAL_HDR 0x0002 +#define PARSER_ERROR_CTR_RANGE 0x0004 +#define PARSER_ERROR_TIMEOUT_USER 0x0008 +#define PARSER_ERROR_TIMEOUT_HW 0x0010 +#define PARSER_ERROR_SRC_EXT 0x0020 +#define PARSER_ERROR_DST_CONT 0x0040 +#define PARSER_ERROR_PHV_OWNER 0x0080 +#define PARSER_ERROR_MULTIWRITE 0x0100 +#define PARSER_ERROR_ARAM_SBE 0x0200 +#define PARSER_ERROR_ARAM_MBE 0x0400 +#define PARSER_ERROR_FCS 0x0800 +#define PARSER_ERROR_CSUM 0x1000 + +#define PARSER_ERROR_ARRAY_OOB 0xC000 +///////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////// +// Digest receivers +#define FLOW_LRN_DIGEST_RCVR 0 + +#define RECIRCULATE_DIGEST_RCVR 90 +#define RESUBMIT_DIGEST_RCVR 91 +#define CLONE_I2I_DIGEST_RCVR 92 +#define CLONE_E2I_DIGEST_RCVR 93 +#define CLONE_I2E_DIGEST_RCVR 94 +#define CLONE_E2E_DIGEST_RCVR 95 +///////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////// +// Clone soruces +// (to be used with eg_intr_md_from_parser_aux.clone_src) +#define NOT_CLONED 0 +#define CLONED_FROM_INGRESS 1 +#define CLONED_FROM_EGRESS 3 +#define COALESCED 5 +///////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Default priorities +#define PARSER_DEF_PRI 0 +#define PARSER_THRESH_PRI 3 + +#endif diff --git a/backends/tofino/bf-asm/test/ptf/tofino/intrinsic_metadata.p4 b/backends/tofino/bf-asm/test/ptf/tofino/intrinsic_metadata.p4 new file mode 100644 index 00000000000..0cf5f384985 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/tofino/intrinsic_metadata.p4 @@ -0,0 +1,445 @@ +/******************************************************************************** + * Intrinsic Metadata Definition for Tofino * + *******************************************************************************/ + +#ifndef _TOFINO_LIB_INTRINSIC_METADATA +#define _TOFINO_LIB_INTRINSIC_METADATA 1 + +/* Control signals for the Ingress Parser during parsing (not used in or + passed to the MAU) */ +header_type ingress_parser_control_signals { + fields { + priority : 3; // set packet priority + _pad1 : 5; + parser_counter : 8; // parser counter + } +} + +@pragma not_deparsed ingress +@pragma not_deparsed egress +@pragma pa_intrinsic_header ingress ig_prsr_ctrl +header ingress_parser_control_signals ig_prsr_ctrl; + + +/* Produced by Ingress Parser */ +header_type ingress_intrinsic_metadata_t { + fields { + + resubmit_flag : 1; // flag distinguising original packets + // from resubmitted packets. + + _pad1 : 1; + + _pad2 : 2; // packet version; irrelevant for s/w. + + _pad3 : 3; + + ingress_port : 9; // ingress physical port id. + // this field is passed to the deparser + + ingress_mac_tstamp : 48; // ingress IEEE 1588 timestamp (in nsec) + // taken at the ingress MAC. + } +} + +@pragma dont_trim +@pragma not_deparsed ingress +@pragma not_deparsed egress +@pragma pa_intrinsic_header ingress ig_intr_md +@pragma pa_mandatory_intrinsic_field ingress ig_intr_md.ingress_port +header ingress_intrinsic_metadata_t ig_intr_md; + + +/* Produced by Packet Generator */ +header_type generator_metadata_t { + fields { + + app_id : 16; // packet-generation session (app) id + + batch_id: 16; // batch id + + instance_id: 16; // instance (packet) id + } +} + +@pragma not_deparsed ingress +@pragma not_deparsed egress +header generator_metadata_t ig_pg_md; + + +/* Produced by Ingress Parser-Auxiliary */ +header_type ingress_intrinsic_metadata_from_parser_aux_t { + fields { + ingress_global_tstamp : 48; // global timestamp (ns) taken upon + // arrival at ingress. + + ingress_global_ver : 32; // global version number taken upon + // arrival at ingress. + + ingress_parser_err : 16; // error flags indicating error(s) + // encountered at ingress parser. + } +} + +@pragma pa_fragment ingress ig_intr_md_from_parser_aux.ingress_parser_err +@pragma pa_atomic ingress ig_intr_md_from_parser_aux.ingress_parser_err +@pragma not_deparsed ingress +@pragma not_deparsed egress +@pragma pa_intrinsic_header ingress ig_intr_md_from_parser_aux +header ingress_intrinsic_metadata_from_parser_aux_t ig_intr_md_from_parser_aux; + + +/* Consumed by Ingress Deparser for Traffic Manager (TM) */ +header_type ingress_intrinsic_metadata_for_tm_t { + fields { + + // The ingress physical port id is passed to the TM directly from + // ig_intr_md.ingress_port + + _pad1 : 7; + ucast_egress_port : 9; // egress port for unicast packets. must + // be presented to TM for unicast. + + // --------------------- + + drop_ctl : 3; // disable packet replication: + // - bit 0 disables unicast, + // multicast, and resubmit + // - bit 1 disables copy-to-cpu + // - bit 2 disables mirroring + bypass_egress : 1; // request flag for the warp mode + // (egress bypass). + deflect_on_drop : 1; // request for deflect on drop. must be + // presented to TM to enable deflection + // upon drop. + + ingress_cos : 3; // ingress cos (iCoS) for PG mapping, + // ingress admission control, PFC, + // etc. + + // --------------------- + + qid : 5; // egress (logical) queue id into which + // this packet will be deposited. + icos_for_copy_to_cpu : 3; // ingress cos for the copy to CPU. must + // be presented to TM if copy_to_cpu == + // 1. + + // --------------------- + + _pad2: 3; + + copy_to_cpu : 1; // request for copy to cpu. + + packet_color : 2; // packet color (G,Y,R) that is + // typically derived from meters and + // used for color-based tail dropping. + + disable_ucast_cutthru : 1; // disable cut-through forwarding for + // unicast. + enable_mcast_cutthru : 1; // enable cut-through forwarding for + // multicast. + + // --------------------- + + mcast_grp_a : 16; // 1st multicast group (i.e., tree) id; + // a tree can have two levels. must be + // presented to TM for multicast. + + // --------------------- + + mcast_grp_b : 16; // 2nd multicast group (i.e., tree) id; + // a tree can have two levels. + + // --------------------- + + _pad3 : 3; + level1_mcast_hash : 13; // source of entropy for multicast + // replication-tree level1 (i.e., L3 + // replication). must be presented to TM + // for L3 dynamic member selection + // (e.g., ECMP) for multicast. + + // --------------------- + + _pad4 : 3; + level2_mcast_hash : 13; // source of entropy for multicast + // replication-tree level2 (i.e., L2 + // replication). must be presented to TM + // for L2 dynamic member selection + // (e.g., LAG) for nested multicast. + + // --------------------- + + level1_exclusion_id : 16; // exclusion id for multicast + // replication-tree level1. used for + // pruning. + + // --------------------- + + _pad5 : 7; + level2_exclusion_id : 9; // exclusion id for multicast + // replication-tree level2. used for + // pruning. + + // --------------------- + + rid : 16; // L3 replication id for multicast. + // used for pruning. + + + } +} + +@pragma pa_atomic ingress ig_intr_md_for_tm.ucast_egress_port + +@pragma pa_fragment ingress ig_intr_md_for_tm.drop_ctl +@pragma pa_fragment ingress ig_intr_md_for_tm.qid +@pragma pa_fragment ingress ig_intr_md_for_tm._pad2 + +@pragma pa_atomic ingress ig_intr_md_for_tm.mcast_grp_a +@pragma pa_fragment ingress ig_intr_md_for_tm.mcast_grp_a +@pragma pa_mandatory_intrinsic_field ingress ig_intr_md_for_tm.mcast_grp_a + +@pragma pa_atomic ingress ig_intr_md_for_tm.mcast_grp_b +@pragma pa_fragment ingress ig_intr_md_for_tm.mcast_grp_b +@pragma pa_mandatory_intrinsic_field ingress ig_intr_md_for_tm.mcast_grp_b + +@pragma pa_atomic ingress ig_intr_md_for_tm.level1_mcast_hash +@pragma pa_fragment ingress ig_intr_md_for_tm._pad3 + +@pragma pa_atomic ingress ig_intr_md_for_tm.level2_mcast_hash +@pragma pa_fragment ingress ig_intr_md_for_tm._pad4 + +@pragma pa_atomic ingress ig_intr_md_for_tm.level1_exclusion_id +@pragma pa_fragment ingress ig_intr_md_for_tm.level1_exclusion_id + +@pragma pa_atomic ingress ig_intr_md_for_tm.level2_exclusion_id +@pragma pa_fragment ingress ig_intr_md_for_tm._pad5 + +@pragma pa_atomic ingress ig_intr_md_for_tm.rid +@pragma pa_fragment ingress ig_intr_md_for_tm.rid + +@pragma not_deparsed ingress +@pragma not_deparsed egress +@pragma pa_intrinsic_header ingress ig_intr_md_for_tm +@pragma dont_trim +@pragma pa_mandatory_intrinsic_field ingress ig_intr_md_for_tm.drop_ctl +header ingress_intrinsic_metadata_for_tm_t ig_intr_md_for_tm; + +/* Consumed by Mirror Buffer */ +header_type ingress_intrinsic_metadata_for_mirror_buffer_t { + fields { + _pad1 : 6; + ingress_mirror_id : 10; // ingress mirror id. must be presented + // to mirror buffer for mirrored + // packets. + } +} + +@pragma dont_trim +@pragma pa_intrinsic_header ingress ig_intr_md_for_mb +@pragma pa_atomic ingress ig_intr_md_for_mb.ingress_mirror_id +@pragma pa_mandatory_intrinsic_field ingress ig_intr_md_for_mb.ingress_mirror_id +@pragma not_deparsed ingress +@pragma not_deparsed egress +header ingress_intrinsic_metadata_for_mirror_buffer_t ig_intr_md_for_mb; + +/* Produced by TM */ +header_type egress_intrinsic_metadata_t { + fields { + + _pad0 : 7; + egress_port : 9; // egress port id. + // this field is passed to the deparser + + _pad1: 5; + enq_qdepth : 19; // queue depth at the packet enqueue + // time. + + _pad2: 6; + enq_congest_stat : 2; // queue congestion status at the packet + // enqueue time. + + enq_tstamp : 32; // time snapshot taken when the packet + // is enqueued (in nsec). + + _pad3: 5; + deq_qdepth : 19; // queue depth at the packet dequeue + // time. + + _pad4: 6; + deq_congest_stat : 2; // queue congestion status at the packet + // dequeue time. + + app_pool_congest_stat : 8; // dequeue-time application-pool + // congestion status. 2bits per + // pool. + + deq_timedelta : 32; // time delta between the packet's + // enqueue and dequeue time. + + egress_rid : 16; // L3 replication id for multicast + // packets. + + _pad5: 7; + egress_rid_first : 1; // flag indicating the first replica for + // the given multicast group. + + _pad6: 3; + egress_qid : 5; // egress (physical) queue id via which + // this packet was served. + + _pad7: 5; + egress_cos : 3; // egress cos (eCoS) value. + // this field is passed to the deparser + + _pad8: 7; + deflection_flag : 1; // flag indicating whether a packet is + // deflected due to deflect_on_drop. + + pkt_length : 16; // Packet length, in bytes + } +} + +@pragma dont_trim +@pragma not_deparsed ingress +@pragma not_deparsed egress +@pragma pa_intrinsic_header egress eg_intr_md + +@pragma pa_atomic egress eg_intr_md.egress_port +@pragma pa_fragment egress eg_intr_md._pad1 +@pragma pa_fragment egress eg_intr_md._pad7 +@pragma pa_fragment egress eg_intr_md._pad8 +@pragma pa_mandatory_intrinsic_field egress eg_intr_md.egress_port +@pragma pa_mandatory_intrinsic_field egress eg_intr_md.egress_cos + +header egress_intrinsic_metadata_t eg_intr_md; + +/* Produced by Egress Parser-Auxiliary */ +header_type egress_intrinsic_metadata_from_parser_aux_t { + fields { + egress_global_tstamp : 48; // global time stamp (ns) taken at the + // egress pipe. + + egress_global_ver : 32; // global version number taken at the + // egress pipe. + + egress_parser_err : 16; // error flags indicating error(s) + // encountered at egress + // parser. + + clone_digest_id : 4; // value indicating the digest ID, + // based on the field list ID. + + clone_src : 4; // value indicating whether or not a + // packet is a cloned copy + // (see #defines in constants.p4) + + coalesce_sample_count : 8; // if clone_src indicates this packet + // is coalesced, the number of samples + // taken from other packets + } +} + +@pragma pa_fragment egress eg_intr_md_from_parser_aux.coalesce_sample_count +@pragma pa_fragment egress eg_intr_md_from_parser_aux.clone_src +@pragma pa_fragment egress eg_intr_md_from_parser_aux.egress_parser_err +@pragma pa_atomic egress eg_intr_md_from_parser_aux.egress_parser_err +@pragma not_deparsed ingress +@pragma not_deparsed egress +@pragma pa_intrinsic_header egress eg_intr_md_from_parser_aux +header egress_intrinsic_metadata_from_parser_aux_t eg_intr_md_from_parser_aux; + + +/* Consumed by Egress Deparser */ +// egress_port and egress_cos are passed to the deparser directly from the +// eg_intr_md header instance. The following commented out header is a +// stand-alone definition of this data: +/* +header_type egress_intrinsic_metadata_for_deparser_t { + fields { + + egress_port : 16; // egress port id. must be presented to + // egress deparser for every packet, or + // the packet will be dropped by egress + // deparser. + + egress_cos : 8; // egress cos (eCoS) value. must be + // presented to egress buffer for every + // lossless-class packet. + } +} + +@pragma pa_atomic egress eg_intr_md_for_deparser.egress_port +@pragma pa_fragment egress eg_intr_md_for_deparser.egress_cos +@pragma not_deparsed ingress +@pragma not_deparsed egress +header egress_intrinsic_metadata_for_deparser_t eg_intr_md_for_deparser; +*/ + +/* Consumed by Mirror Buffer */ +header_type egress_intrinsic_metadata_for_mirror_buffer_t { + fields { + _pad1 : 6; + egress_mirror_id : 10; // egress mirror id. must be presented to + // mirror buffer for mirrored packets. + + coalesce_flush: 1; // flush the coalesced mirror buffer + coalesce_length: 7; // the number of bytes in the current + // packet to collect in the mirror + // buffer + } +} + +@pragma dont_trim +@pragma pa_intrinsic_header egress eg_intr_md_for_mb +@pragma pa_atomic egress eg_intr_md_for_mb.egress_mirror_id +@pragma pa_fragment egress eg_intr_md_for_mb.coalesce_flush +@pragma pa_mandatory_intrinsic_field egress eg_intr_md_for_mb.egress_mirror_id +@pragma pa_mandatory_intrinsic_field egress eg_intr_md_for_mb.coalesce_flush +@pragma pa_mandatory_intrinsic_field egress eg_intr_md_for_mb.coalesce_length +@pragma not_deparsed ingress +@pragma not_deparsed egress +header egress_intrinsic_metadata_for_mirror_buffer_t eg_intr_md_for_mb; + + +/* Consumed by Egress MAC (port) */ +header_type egress_intrinsic_metadata_for_output_port_t { + fields { + + _pad1 : 2; + capture_tstamp_on_tx : 1; // request for packet departure + // timestamping at egress MAC for IEEE + // 1588. consumed by h/w (egress MAC). + update_delay_on_tx : 1; // request for PTP delay (elapsed time) + // update at egress MAC for IEEE 1588 + // Transparent Clock. consumed by h/w + // (egress MAC). when this is enabled, + // the egress pipeline must prepend a + // custom header composed of in front of the + // Ethernet header. + force_tx_error : 1; // force a hardware transmission error + + drop_ctl : 3; // disable packet replication: + // - bit 0 disables unicast, + // multicast, and resubmit + // - bit 1 disables copy-to-cpu + // - bit 2 disables mirroring + // TODO: which of these actually apply + // for egress? + + } +} + +@pragma dont_trim +@pragma pa_mandatory_intrinsic_field egress eg_intr_md_for_oport.drop_ctl +@pragma not_deparsed ingress +@pragma not_deparsed egress +@pragma pa_intrinsic_header egress eg_intr_md_for_oport +header egress_intrinsic_metadata_for_output_port_t eg_intr_md_for_oport; + +#endif diff --git a/backends/tofino/bf-asm/test/ptf/tofino/lpf_blackbox.p4 b/backends/tofino/bf-asm/test/ptf/tofino/lpf_blackbox.p4 new file mode 100644 index 00000000000..79977705fe7 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/tofino/lpf_blackbox.p4 @@ -0,0 +1,53 @@ +/***************************************************************************/ + +blackbox_type lpf { + + attribute filter_input { + /* Reference to the input field to compute the filter on. + The maximum input bit width supported is 32 bits. */ + type: bit<0>; + } + + attribute direct { + /* Mutually exclusive with 'static' attribute. + Must be a match table reference */ + type: table; + optional; + } + + attribute static { + /* Mutually exclusive with 'direct' attribute. + Must be a table reference */ + type: table; + optional; + } + + attribute instance_count { + /* Mutually exclusive with 'direct' attribute. */ + type: int; + optional; + } + + + /* + Execute the low pass filter for a given cell in the array and writes + the result to the output parameter. + If the low pass filter is direct, then 'index' is ignored as the table + entry determines which cell to reference. + + Callable from: + - Actions + + Parameters: + - destination: A field reference to store the low pass filter state. + The maximum output bit width is 32 bits. + - index: Optional. The offset in the low pass filter array to update. Necessary + unless the low pass filter is declared as direct, in which case it should + not be present. + */ + method execute (out bit<0> destination, optional in int index){ + reads {filter_input} + } +} + +/***************************************************************************/ diff --git a/backends/tofino/bf-asm/test/ptf/tofino/meter_blackbox.p4 b/backends/tofino/bf-asm/test/ptf/tofino/meter_blackbox.p4 new file mode 100644 index 00000000000..58f3a671921 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/tofino/meter_blackbox.p4 @@ -0,0 +1,83 @@ +/***************************************************************************/ + +blackbox_type meter { + + attribute type { + /* Must be either: + bytes + packets */ + type: string; + } + + attribute direct { + /* Mutually exclusive with 'static' attribute. + Must be a match table reference */ + type: table; + optional; + } + + attribute static { + /* Mutually exclusive with 'direct' attribute. + Must be a table reference */ + type: table; + optional; + } + + attribute instance_count { + /* Mutually exclusive with 'direct' attribute. */ + type: int; + optional; + } + + attribute green_value { + /* An 8-bit value that can be output if the packet is to be marked as green. + The default value is 0. */ + type: int; + optional; + } + attribute yellow_value { + /* An 8-bit value that can be output if the packet is to be marked as yellow. + The default value is 1. */ + type: int; + optional; + } + attribute red_value { + /* An 8-bit value that can be output if the packet is to be marked as red. + The default value is 3. */ + type: int; + optional; + } + + /* + Execute the metering operation for a given cell in the array. If + the meter is direct, then 'index' is ignored as the table + entry determines which cell to reference. The length of the packet + is implicitly passed to the meter. The state of meter is updated + and the meter returns information (a 'color') which is stored in + 'destination'. If the parent header of 'destination' is not valid, + the meter state is updated, but resulting output is discarded. + + Callable from: + - Actions + + Parameters: + - destination: A field reference to store the low pass filter state. + The maximum output bit width is 32 bits. + - index: Optional. The offset in the low pass filter array to update. Necessary + unless the low pass filter is declared as direct, in which case it should + not be present. + */ + method execute (out bit<0> destination, optional in int index){} + + /* Same as execute, but the precolor attribute specifies the minimum color the packet + may be tagged with. + Pre-color encoding (which is not programmable): + 0 = green + 1 = yellow + 2 = yellow + 3 = red + */ + method execute_with_pre_color (out bit<0> destination, in bit<0> precolor, optional in int index){} +} + +/***************************************************************************/ diff --git a/backends/tofino/bf-asm/test/ptf/tofino/pktgen_headers.p4 b/backends/tofino/bf-asm/test/ptf/tofino/pktgen_headers.p4 new file mode 100644 index 00000000000..3f739dfc403 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/tofino/pktgen_headers.p4 @@ -0,0 +1,57 @@ + +/******************************************************************************** + * Packet Generator Header Definition for Tofino * + *******************************************************************************/ + +#ifndef _TOFINO_LIB_PKTGEN_HEADERS +#define _TOFINO_LIB_PKTGEN_HEADERS 1 + +header_type pktgen_generic_header_t { + fields { + _pad0 : 3; + pipe_id : 2; + app_id : 3; + key_msb : 8; // Only valid for recirc triggers. + batch_id : 16; // Overloaded to port# or lsbs of key for port down and + // recirc triggers. + packet_id : 16; + } +} +header pktgen_generic_header_t pktgen_generic; + +header_type pktgen_timer_header_t { + fields { + _pad0 : 3; + pipe_id : 2; + app_id : 3; + _pad1 : 8; + batch_id : 16; + packet_id : 16; + } +} +header pktgen_timer_header_t pktgen_timer; + +header_type pktgen_port_down_header_t { + fields { + _pad0 : 3; + pipe_id : 2; + app_id : 3; + _pad1 : 15; + port_num : 9; + packet_id : 16; + } +} +header pktgen_port_down_header_t pktgen_port_down; + +header_type pktgen_recirc_header_t { + fields { + _pad0 : 3; + pipe_id : 2; + app_id : 3; + key : 24; + packet_id : 16; + } +} +header pktgen_recirc_header_t pktgen_recirc; + +#endif diff --git a/backends/tofino/bf-asm/test/ptf/tofino/primitives.p4 b/backends/tofino/bf-asm/test/ptf/tofino/primitives.p4 new file mode 100644 index 00000000000..9f7c4ed0266 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/tofino/primitives.p4 @@ -0,0 +1,26 @@ +#ifndef _TOFINO_LIB_PRIMITIVES +#define _TOFINO_LIB_PRIMITIVES 1 + +///////////////////////////////////////////////////////////// +// Primitive aliases + +#define clone_i2e clone_ingress_pkt_to_egress +#define clone_e2e clone_egress_pkt_to_egress + +action deflect_on_drop(enable_dod) { + modify_field(ig_intr_md_for_tm.deflect_on_drop, enable_dod); +} + +#define _ingress_global_tstamp_ ig_intr_md_from_parser_aux.ingress_global_tstamp + +#define _parser_counter_ ig_prsr_ctrl.parser_counter + +#define pkt_is_mirrored (eg_intr_md_from_parser_aux.clone_src != NOT_CLONED) +#define pkt_is_not_mirrored (eg_intr_md_from_parser_aux.clone_src == NOT_CLONED) + +#define pkt_is_i2e_mirrored (eg_intr_md_from_parser_aux.clone_src == CLONED_FROM_INGRESS) +#define pkt_is_e2e_mirrored (eg_intr_md_from_parser_aux.clone_src == CLONED_FROM_EGRESS) +#define pkt_is_coalesced (eg_intr_md_from_parser_aux.clone_src == COALESCED) +#define pkt_is_not_coalesced (eg_intr_md_from_parser_aux.clone_src != COALESCED) + +#endif diff --git a/backends/tofino/bf-asm/test/ptf/tofino/stateful_alu_blackbox.p4 b/backends/tofino/bf-asm/test/ptf/tofino/stateful_alu_blackbox.p4 new file mode 100644 index 00000000000..8ac0e09ecee --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/tofino/stateful_alu_blackbox.p4 @@ -0,0 +1,276 @@ +/***************************************************************************/ + +blackbox_type stateful_alu { + + attribute reg { + /* Reference to the register table description. */ + type: register; + } + + attribute selector_binding { + /* Bind this stateful ALU to the selector used by the specified match table. */ + type: table; + optional; + } + + attribute initial_register_lo_value { + /* The initial value to use for the stateful memory cell. Used in dual-width mode as the + low half initial value. In single-width mode, this is the initial value of the entire memory cell. + */ + type: int; + optional; + } + + attribute initial_register_hi_value { + /* The initial value to use for the stateful memory cell. Only relevant in dual-width mode to + specify the high half initial value. + */ + type: int; + optional; + } + + attribute condition_hi { + /* Condition associated with cmp hi unit. + An expression that can be transformed into the form: + memory +/- phv - constant operation 0 + */ + type: expression; + expression_local_variables {register_lo, register_hi} + optional; + } + + attribute condition_lo { + /* Condition associated with cmp lo unit. + An expression that can be transformed into the form: + memory +/- phv - constant operation 0 + */ + type: expression; + expression_local_variables {register_lo, register_hi} + optional; + } + + + attribute update_lo_1_predicate { + /* Condition expression associated with running ALU 1 lo. */ + type: expression; + expression_local_variables {condition_lo, condition_hi} + optional; + } + + attribute update_lo_1_value { + /* Expression computed in ALU 1 lo. + In single-bit mode, this ALU can only perform single_bit instructions, which perform the following: + + +-------------------+---------------------------------------------------------------------------------+ + | Operation Name | Description | + +-------------------+---------------------------------------------------------------------------------+ + | set_bit | Sets the specified bit to 1, outputs the previous bit value. | + +-------------------+---------------------------------------------------------------------------------+ + | set_bitc | Sets the specified bit to 1, outputs the complement of the previous bit value. | + +-------------------+---------------------------------------------------------------------------------+ + | clr_bit | Sets the specified bit to 0, outputs the previous bit value. | + +-------------------+---------------------------------------------------------------------------------+ + | clr_bitc | Sets the specified bit to 0, outputs the complement of the previous bit value. | + +-------------------+---------------------------------------------------------------------------------+ + | read_bit | Does not modify specified bit, outputs current bit value. | + +-------------------+---------------------------------------------------------------------------------+ + | read_bitc | Does not modify specified bit, outputs complement of the current bit value. | + +-------------------+---------------------------------------------------------------------------------+ + + */ + type: expression; + expression_local_variables {register_lo, register_hi, + set_bit, set_bitc, clr_bit, clr_bitc, read_bit, read_bitc} + optional; + } + + attribute update_lo_2_predicate { + /* Condition expression associated with running ALU 2 lo. */ + type: expression; + expression_local_variables {condition_lo, condition_hi} + optional; + } + + attribute update_lo_2_value { + /* Expression computed in ALU 2 lo. */ + type: expression; + expression_local_variables {register_lo, register_hi, math_unit} + optional; + } + + attribute update_hi_1_predicate { + /* Condition expression associated with running ALU 1 hi. */ + type: expression; + expression_local_variables {condition_lo, condition_hi} + optional; + } + + attribute update_hi_1_value { + /* Expression computed in ALU 1 hi. */ + type: expression; + expression_local_variables {register_lo, register_hi} + optional; + } + + attribute update_hi_2_predicate { + /* Condition expression associated with running ALU 2 hi. */ + type: expression; + expression_local_variables {condition_lo, condition_hi} + optional; + } + + attribute update_hi_2_value { + /* Expression computed in ALU 2 hi. */ + type: expression; + expression_local_variables {register_lo, register_hi} + optional; + } + + attribute output_predicate { + /* Condition expression associated with outputting result to action data bus. + Allowed references are 'condition_lo' and 'condition_hi'. + Allowed operations are 'and', 'or', and 'not'. + */ + type: expression; + expression_local_variables {condition_lo, condition_hi} + optional; + } + + attribute output_value { + /* Output result expression. + Allowed references are 'alu_lo', 'alu_hi', 'register_lo', 'register_hi', + 'predicate', and 'combined_predicate'. + In the case of 'register_lo' and 'register_hi', these are the values + fetched from memory on this access, not the value to be written back + computed by the ALU(s). + */ + type: expression; + expression_local_variables {alu_lo, alu_hi, register_lo, register_hi, predicate, combined_predicate} + optional; + } + + attribute output_dst { + /* Optional field to write the stateful result to. */ + type: bit<0>; + optional; + } + + attribute math_unit_input { + /* Specification of the math unit's input. + This attribute must be defined if a math_unit is referenced in 'update_lo_2_value'. + */ + type: expression; + expression_local_variables {register_lo, register_hi} + optional; + } + attribute math_unit_output_scale { + /* Specification of the math unit's output scale. + This is a 6-bit signed number added to the exponent, which shifts the output result. + The default value is 0. + */ + type: int; + optional; + } + attribute math_unit_exponent_shift { + /* Specification of the math unit's exponent shift. + Supported shift values are -1, 0, and 1. The default value is 0. + This value controls the shifting of the input data exponent. + With an exponent shift of -1, the math unit normalization is 2-bit resolution. + Otherwise, the math unit normalization is 1-bit resolution. + */ + type: int; + optional; + } + attribute math_unit_exponent_invert { + /* Specifies whether the math unit should invert the computed exponent. + By default, the exponent is not inverted. Allowed values are True and False. + Inverting allows reciprocal exponents, e.g. 1/x, 1/x**2, or 1/sqrt(x) + */ + type: string; + optional; + } + + attribute math_unit_lookup_table { + /* Specifies the math unit's lookup table values. + There are 16 8-bit values that can be looked up. + This attribute must be defined if a math_unit is referenced in 'update_lo_2_value'. + Input is specified with the most significant byte appearing first in the string. + For example: + 0x0f 0x0e 0x0d 0x0c 0x0b 0x0a 9 8 7 6 5 4 3 2 1 0; + */ + type: string; + optional; + } + + attribute reduction_or_group { + /* Specifies that the output value to be written belongs to a group of stateful ALU + outputs that are all OR'd together. Using a reduction OR group breaks what + would normally be considered a dependency. + A typical use case is to perform a membership check in, e.g., a Bloom filter. + For example, n unique hash functions may be used to check for membership in + n unique registers. If any of the hashed locations are active, + the member is active. + */ + type: string; + optional; + } + + attribute stateful_logging_mode { + /* Specify that stateful logging should be performed. + Stateful logging writes a result to consecutive addresses in a register based on the mode + of logging being performed. + Allowed values are: + table_hit - performing logging if the match table hits and is predicated on. + table_miss - performing logging if the match table misses and is predicated on. + gateway_inhibit - performing logging if the gateway table inhibits a match table and is predicated on. + address - any time the table is predicated on. + */ + type: string; + optional; + } + + /* + Executes this stateful alu instance. + + If output_dst is defined, this writes the output_value to a destination field. + + output_dst = output_value + + Callable from: + - Actions + + Parameters: + - index: The offset into the stateful register to access. + May be a constant or an address provided by the run time. + */ + method execute_stateful_alu(optional in bit<0> index){ + reads {condition_hi, condition_lo, + update_lo_1_predicate, update_lo_1_value, + update_lo_2_predicate, update_lo_2_value, + update_hi_1_predicate, update_hi_1_value, + update_hi_2_predicate, update_hi_2_value, + math_unit_input} + writes {output_dst} + } + + method execute_stateful_alu_from_hash(in field_list_calculation hash_field_list){ + reads {condition_hi, condition_lo, + update_lo_1_predicate, update_lo_1_value, + update_lo_2_predicate, update_lo_2_value, + update_hi_1_predicate, update_hi_1_value, + update_hi_2_predicate, update_hi_2_value, + math_unit_input} + writes {output_dst} + } + + method execute_stateful_log(){ + reads {condition_hi, condition_lo, + update_lo_1_predicate, update_lo_1_value, + update_lo_2_predicate, update_lo_2_value, + update_hi_1_predicate, update_hi_1_value, + update_hi_2_predicate, update_hi_2_value, + math_unit_input} + } +} + +/***************************************************************************/ diff --git a/backends/tofino/bf-asm/test/ptf/tofino/wred_blackbox.p4 b/backends/tofino/bf-asm/test/ptf/tofino/wred_blackbox.p4 new file mode 100644 index 00000000000..9ca9a475bcb --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/tofino/wred_blackbox.p4 @@ -0,0 +1,64 @@ +/***************************************************************************/ + +blackbox_type wred { + + attribute wred_input { + /* Reference to the input field to compute the moving average on. + The maximum input bit width supported is 32 bits. */ + type: bit<0>; + } + + attribute direct { + /* Mutually exclusive with 'static' attribute. + Must be a match table reference */ + type: table; + optional; + } + + attribute static { + /* Mutually exclusive with 'direct' attribute. + Must be a table reference */ + type: table; + optional; + } + + attribute instance_count { + /* Mutually exclusive with 'direct' attribute. */ + type: int; + optional; + } + + attribute drop_value { + /* Specifies the lower bound for which the computed moving average should result in a drop. */ + type: int; + optional; + } + + attribute no_drop_value { + /* Specifies the upper bound for which the computed moving average should not result in a drop. */ + type: int; + optional; + } + + /* + Execute the moving average for a given cell in the array and writes + the result to the output parameter. + If the wred is direct, then 'index' is ignored as the table + entry determines which cell to reference. + + Callable from: + - Actions + + Parameters: + - destination: A field reference to store the moving average state. + The maximum output bit width is 8 bits. + - index: Optional. The offset in the wred array to update. Necessary + unless the wred is declared as direct, in which case it should + not be present. + */ + method execute (out bit<0> destination, optional in int index){ + reads {wred_input} + } +} + +/***************************************************************************/ diff --git a/backends/tofino/bf-asm/test/ptf/tofino_diag.p4 b/backends/tofino/bf-asm/test/ptf/tofino_diag.p4 new file mode 100644 index 00000000000..de7577496e1 --- /dev/null +++ b/backends/tofino/bf-asm/test/ptf/tofino_diag.p4 @@ -0,0 +1,158 @@ +#include +#include + +/* Sample P4 program */ +header_type ethernet_t { + fields { + dstAddr : 48; + srcAddr : 48; + etherType : 16; + } +} + +header_type vlan_tag_t { + fields { + pri : 3; + cfi : 1; + vlan_id : 12; + etherType : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr: 32; + } +} + +header_type tcp_t { + fields { + srcPort : 16; + dstPort : 16; + seqNo : 32; + ackNo : 32; + dataOffset : 4; + res : 3; + ecn : 3; + ctrl : 6; + window : 16; + checksum : 16; + urgentPtr : 16; + } +} + +header_type udp_t { + fields { + srcPort : 16; + dstPort : 16; + hdr_length : 16; + checksum : 16; + } +} + +parser start { + return parse_ethernet; +} + +header ethernet_t ethernet; + +parser parse_ethernet { + extract(ethernet); + return select(latest.etherType) { + 0x8100 : parse_vlan_tag; + 0x800 : parse_ipv4; + default: ingress; + } +} + +#define IP_PROTOCOLS_TCP 6 +#define IP_PROTOCOLS_UDP 17 + +header ipv4_t ipv4; + +parser parse_ipv4 { + extract(ipv4); + return select(latest.fragOffset, latest.protocol) { + IP_PROTOCOLS_TCP : parse_tcp; + IP_PROTOCOLS_UDP : parse_udp; + default: ingress; + } +} + +header vlan_tag_t vlan_tag; + +parser parse_vlan_tag { + extract(vlan_tag); + return select(latest.etherType) { + 0x800 : parse_ipv4; + default : ingress; + } +} + +header tcp_t tcp; + +parser parse_tcp { + extract(tcp); + return ingress; +} + +header udp_t udp; + +parser parse_udp { + extract(udp); + return ingress; +} + +counter dummy_cntr { + type : packets; + static : idle_stats_tbl; + instance_count : 256; +} + +action drop_count (count_idx) { + count(dummy_cntr, count_idx); + drop(); +} + +table idle_stats_tbl { + reads { + ipv4.dstAddr : exact; + } + actions { + drop_count; + } + support_timeout: true; +} + +action set_egress_port (eg_port) { + modify_field(ig_intr_md_for_tm.ucast_egress_port, eg_port); +} + +table snake_test { + reads { + ig_intr_md.ingress_port : exact; + } + actions { + set_egress_port; + } + size : 512; +} + +control ingress { +// apply(idle_stats_tbl); + apply(snake_test); +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/runtests b/backends/tofino/bf-asm/test/runtests new file mode 100755 index 00000000000..ec5b1004b76 --- /dev/null +++ b/backends/tofino/bf-asm/test/runtests @@ -0,0 +1,703 @@ +#!/bin/bash + +fast=false +brig=false +glass=false +outdir=false +verbose=false +diff=false +link=false +clean=false +skip_ctxtjson=false +TIME=false +# parallel make arguments +PARALLEL=1 +TOKEN_READ=0 +TOKEN_WRITE=0 + +shopt -s nullglob +set -o pipefail + +TESTDIR=$(cd $(dirname $0); pwd -P) + +prev_mflag="" +for mflag in $MAKEFLAGS; do + case $mflag in + n) exit 0 + ;; + -j[1-9]|-j[1-9][0-9]) + PARALLEL=${mflag#-j} + ;; + [1-9]|[1-9][0-9]) + if [ "$prev_mflag" = "-j" ]; then + PARALLEL=${mflag} + fi + ;; + --jobserver-*=*) + fds=${mflag/*=/} + vec=(${fds/,/ }) + if eval "command >&${vec[1]}" 2>/dev/null; then + TOKEN_READ=${vec[0]} + TOKEN_WRITE=${vec[1]} + else + echo >&2 "invalid --jobserver, assuming -j1 -- must use '+' in Makefile rule" + fi + ;; + esac + prev_mflag=$mflag +done + +while expr "$1" : - >/dev/null; do + case $1 in + -f) fast=true + ;; + -c) clean=true + ;; + -b) brig=true + ;; + -g) glass=true + ;; + -l) link=true + ;; + -t) + TIME=true + ;; + -d) + diff=true + ;; + -j) + shift + if [[ $1 =~ ^[0-9]+$ ]]; then + PARALLEL=$1 + else + echo >&2 "invalid number -j $1" + fi + ;; + -j[1-9]|-j[1-9][0-9]) + PARALLEL=${1#-j} + ;; + -o) + shift + outdir=true + odir=$1 + ;; + -v) + verbose=true + ;; + --skip_ctxtjson) + skip_ctxtjson=true + ;; + -*) + echo >&2 "unknown argument $1" + ;; + esac + shift +done + +# If neither '-b' or '-g' specified run for both brig and glass as default case +# unless just -d specified -- then just run glass to do json_diff comparisons +if ! $brig && ! $glass; then + glass=true; + if ! $diff; then + brig=true; + fi +fi + +#glsc_args="--placement-order ingress_before_egress --libpd --placement secret" +#glsc_args="--verbose 2 -vl 2 -S -G --placement-order ingress_before_egress --no-bin --new_ctx_json" +glsc_args="--verbose 2 -vl 2 --gen_asm --gen_json --placement-order ingress_before_egress" + +trap 'release_all_tokens; exit' 2 + +if [ $# -eq 0 ]; then + set *.p4 +fi + +count=$# + +rm -rf faillog.txt +FAILLOG=$(pwd -P)/faillog.txt + +echo -n "Test run started at " >$FAILLOG +date >> $FAILLOG + +TRY_BINDIRS=" +" + +function searchdir () { + found="" + if [ -x "$BUILDDIR/$1" ]; then + echo $BUILDDIR/$1 + return + fi + for d in $TRY_BINDIRS; do + if [[ $2 ]]; then + if [ -d "$d/$2" ]; then + for f in $(find -L $d/$2 -executable -type f -name $1); do + if [ "$f" -nt "$found" ]; then + found="$f" + fi + done + if [ -n "$found" ]; then + break; + fi + fi + else + for f in $(find -L $d -executable -type f -name $1); do + if [ "$f" -nt "$found" ]; then + found="$f" + fi + done + if [ -n "$found" ]; then + break; + fi + fi + done + if [ -z "$found" ]; then + found=$(which $1) + fi + if [ -z "$found" ]; then + echo >&2 "Can't find $1 executable" + echo false + else + echo $found + fi +} + +function findexec () { + evarref=\$"$1" + evalue=`eval "expr \"$evarref\" "` + if [ ! -x "$evalue" ]; then + e=$(searchdir $2 $4) + eval "${1}=${e}" + evalue=`eval "expr \"$evarref\" "` + if [ -x "$evalue" ]; then + echo "Using $evalue" + else + #echo >&2 "Can't find $3 executable" + eval "${1}=false" + fi + fi +} + +#FINDFUNC PARAM EXECUTABLE NAME OPTIONAL SEARCH DIR PREFIX +findexec GLSC "shell.py" "glass" "" +findexec BRIG "p4c-barefoot" "brig" "" +findexec STF1 "tofino_test_harness" "tofino_test_harness" "model" +findexec STF2 "jbay_test_harness" "jbay_test_harness" "model" +findexec BFAS "bfas" "bfas" "" +findexec BFLINK "bflink" "bflink" "" +findexec REFLOW "reflow" "reflow" "" +findexec JSON_DIFF "json_diff" "json_diff" "" +findexec SCHEMA "gen_schema.py" "gen_schema.py" "ctx_json" +findexec SCHEMA_VAL "validate.py" "validate.py" "" +findexec WALLE "walle" "walle" "" + +function not() { if "$@"; then return 1; else return 0; fi } + +ctxt_json_ignore=$TESTDIR/ctxt_json_ignore_new +echo "Using context json ignore file - $ctxt_json_ignore" + +# -l specifies the key 'field' the vector will be sorted before comparison +if [ -r $ctxt_json_ignore ]; then + CTXT_DIFFARGS="-l start_offset -l entry_number -l name -l field_name -i @$ctxt_json_ignore" +else + CTXT_DIFFARGS="-al handle -i table_type" +fi + +TIMEOUT_COMMAND=$(which gtimeout || which timeout) +run() { + if $verbose; then + echo "$@" >/dev/tty + fi + if [ -z "$TIMEOUT" ]; then + $TIME_COMMAND "$@" + else + $TIME_COMMAND $TIMEOUT_COMMAND --foreground $TIMEOUT "$@" + fi + status=$? + if [ $status -eq 124 ]; then + echo >&2 $1 TIMEOUT + elif [ $status -gt 128 ]; then + echo >&2 $1 CRASH with signal $(expr $status - 128) + elif [ $status -gt 0 ]; then + echo >&2 $1 FAILED + fi + return $status +} + +function link_json() { + p4file=$1 + pushd $(dirname $p4file) >/dev/null + name=$(basename $p4file .p4) + ok=true + if [ -d $name.out ];then + cd $name.out + bindir=$PWD/glass + jsondir=$PWD/glass/cfg + if $brig;then + if [ -d brig ];then + bindir=$PWD/brig + jsondir=$PWD/brig + else + msg="$msg no $jsondir/brig found" + ok=false + rv=1 + fi + fi + if $ok && run $BFLINK --walle $WALLE --target tofino -o $bindir/tofino.bin $jsondir/*.cfg.json* >/dev/null 2>&1; then + msg="$msg link pass" + else + msg="$msg link failed" + flock $FAILLOG -c "echo '$1:' >>$FAILLOG; sed -e 's/^/ /'$name.out/link.txt >>$FAILLOG" + rv=1 + fi + fi + return $rv +} + +function test_p4() { + p4file="$1" + pushd $(dirname $p4file) >/dev/null + name=$(basename $p4file .p4) + if $clean; then + if [ -d $name.out ]; then + rm -rf $name.out + fi + fi + mkdir -p $name.out + expect_fail=$(sed -n "/^$name.p4/s/[^ ]* *//p" expected_failures.txt 2>/dev/null | head -1) + cd $name.out + ok=true + rv=0 + fail_type="" + #echo "about to run $name.p4, expecting ${expect_fail:-no} failure" + msg="$p4file" + start=`date +%s` + tfafile=brig/$name.tfa + if $diff; then + tfafile=glass/$name.tfa + fi + if $fast && [ -r $tfafile ]; then + true + else + mkdir -p brig + mkdir -p glass + # Remove old assembly files + if [ -d glass ]; then + rm -f glass/$name.tfa + rm -f glass/out.tfa + fi + if [ -d brig ]; then + rm -f brig/$name.tfa + rm -f brig/out.tfa + fi + # Run both glass and brig if '-b' and '-g' not specified + if $brig; then + clog='brig.log' + if $ok && not run $BRIG -D__TARGET_TOFINO__ ../$name.p4 -o brig/out.tfa brig.log 2>&1; then + ok=false + fi + if not $ok; then + msg="$msg p4 brig compile failed" + fi + fi + if $glass; then + clog='glsc.log' + if not run $GLSC -o glass $glsc_args ../$name.p4 glsc.log 2>&1; then + ok=false + fi + if not $ok; then + msg="$msg p4 glass compile failed" + fi + fi + if not $ok; then + fail_type="compile" + rv=1 + fi + if [ -d glass ]; then + cd glass + if [ out.tfa -nt $name.tfa ]; then + rm -f $name.tfa + ln -s out.tfa $name.tfa + fi + cd .. + fi + if [ -d brig ]; then + cd brig + if [ out.tfa -nt $name.tfa ]; then + rm -f $name.tfa + ln -s out.tfa $name.tfa + fi + cd .. + fi + if $glass && [ ! -r glass/$name.tfa ] && $ok; then + msg="$msg p4 glass compile failed to produce asm" + fail_type="compile" + rv=1 + ok=false + fi + if $brig && [ ! -r brig/$name.tfa ] && $ok; then + msg="$msg p4 brig compile failed to produce asm" + fail_type="compile" + rv=1 + ok=false + fi + if not $ok && ( [ $count -eq 1 ] || [ "$expect_fail" != "compile" ] ); then + flock $FAILLOG -c "echo '$p4file:' >>$FAILLOG; sed 's/^/ /' $clog >>$FAILLOG" + fi + fi + glsc_cfg=. + if $ok; then + rm -f $brig/*.json + if [ -d glass/cfg ]; then + glsc_cfg=glass/cfg + fi + fi + for f in $glsc_cfg/*.json; do + if $REFLOW $f | gzip -9 > $f.gz; then + rm $f + fi + done + if $diff; then + BFAS_OPTS="--gen_json -M" + else + BFAS_OPTS="" + fi + if $ok && run $BFAS -g -o brig $BFAS_OPTS -vvvvl brig/bfas.config.log $tfafile >brig/bfas.log 2>&1; then + # Validate context json output from assembler + $SCHEMA > schema.json + python $SCHEMA_VAL brig/context.json schema.json > context_json_schema_validate.log + for f in brig/*.cfg.json; do + if $REFLOW $f | gzip -9 > $f.gz; then + rm $f + fi + done + if $diff; then + for f in brig/*.cfg.json.gz; do + if zcmp -s $f $glsc_cfg/$(basename $f); then + continue + elif [ "$f" = "$name.out/regs.pipe.cfg.json.gz" ]; then + $JSON_DIFF -i mau $f $glsc_cfg/$(basename $f) + if [ $? -gt 128 ]; then + echo "***json_diff crashed" + fi + continue + fi + $JSON_DIFF $f $glsc_cfg/$(basename $f) + done > json_diff.txt + glsc_ctxt=glass/${name}_context_llir.json + if [ -d glass/context ]; then + glsc_ctxt=glass/context/context.json + fi + brig_ctxt=brig/context.json + if ! $skip_ctxtjson && [ -r $brig_ctxt ]; then + { $JSON_DIFF $CTXT_DIFFARGS $brig_ctxt $glsc_ctxt; + if [ $? -gt 128 ]; then echo "***json_diff crashed"; fi; } >> json_diff.txt + #echo $JSON_DIFF $CTXT_DIFFARGS $brig_ctxt $glsc_ctxt; + fi + cnt=$(grep -Ev '^\+\+\+|^---|"int_inj"' json_diff.txt | grep -Ec '^\+|^-') + if [ $cnt -gt 0 ]; then + msg="$msg mismatch" + fail_type="mismatch" + rv=1 + if [ $count -eq 1 ] || [ "$expect_fail" != "mismatch" ]; then + flock $FAILLOG -c "echo '$p4file:' >>$FAILLOG; cat json_diff.txt >>$FAILLOG" + fi + ok=false + else + msg="$msg pass" + let pass++ + fi + fi + elif $ok; then + msg="$msg bfas failed" + fail_type="bfas" + rv=1 + if [ $count -eq 1 ] || [ "$expect_fail" != "bfas" ]; then + flock $FAILLOG -c "echo '$p4file:' >>$FAILLOG; sed -e 's/^/ /' -e'/\n/!a\' brig/bfas.log >>$FAILLOG" + fi + ok=false + fi + if [ "$expect_fail" != "" ] && $diff; then + if $ok; then + msg="$msg (UNEXPECTED PASS -- expected $expect_fail failure)" + rv=3 + elif [ "$expect_fail" != "$fail_type" ]; then + msg="$msg (expected $expect_fail failure)" + if [ "$fail_type" = "mismatch" -o "$expect_fail" = "compile" ]; then + rv=2 + fi + else + msg="$msg (expected)" + rv=2 + fi + fi + if $TIME; then + let elapsed=`date +%s`-start + let min=elapsed/60 + let sec=elapsed%60 + if [ $sec -lt 10 ]; then + sec=0$sec + fi + msg="$msg ($min:$sec)" + fi + echo "$msg" + popd >/dev/null + return $rv +} + +function test_bfa() { + if [ -z "$2" ]; then + target="" + else + target="-t $2" + fi + msg="$1" + pushd $(dirname $1) >/dev/null + srcfile=$(basename $1) + name=${srcfile%.*} + mkdir -p $name.out + rm -f $name.out/*.json $name.out/*.json.gz $name.out/*.bin + expect_fail=$(sed -n "/^$srcfile/s/[^ ]* *//p" expected_failures.txt 2>/dev/null | head -1) + ok=true + rv=0 + start=`date +%s` + # added -Tcrash:0 to disable stack trace on crash as it seems unreasonably slow + if not run $BFAS --partial -g $target -Tcrash:0 -Mvvvvl $name.out/bfas.config.log $srcfile -o $name.out >$name.out/bfas.log 2>&1; then + msg="$msg bfas failed" + fail_type="bfas" + if [ $count -eq 1 ] || [ "$expect_fail" != "bfas" ]; then + flock $FAILLOG -c "echo '$1:' >>$FAILLOG; sed -e 's/^/ /' -e '/\n/!a\' $name.out/bfas.log >>$FAILLOG" + fi + rv=1 + ok=false + else + msg="$msg pass" + for f in $name.out/*.cfg.json; do + if $REFLOW $f | gzip -9 > $f.gz; then + rm $f + fi + done + for f in $name.out/*.bin; do + rm -f $f.gz + gzip -9 $f + done + fi + if [ "$expect_fail" != "" ]; then + if $ok; then + msg="$msg (UNEXPECTED PASS -- expected $expect_fail failure)" + rv=3 + elif [ "$expect_fail" != "$fail_type" ]; then + msg="$msg (expected $expect_fail failure)" + if [ "$fail_type" = "mismatch" -o "$expect_fail" = "compile" ]; then + rv=2 + fi + else + msg="$msg (expected)" + rv=2 + fi + fi + if $TIME; then + let elapsed=`date +%s`-start + let min=elapsed/60 + let sec=elapsed%60 + if [ $sec -lt 10 ]; then + sec=0$sec + fi + msg="$msg ($min:$sec)" + fi + echo "$msg" + popd >/dev/null + return $rv +} + +function test_stf() { + msg="$1" + pushd $(dirname $1) >/dev/null + name=$(basename $1 .stf) + rv=0 + if [[ $rv == 0 && -d $name.out ]]; then + bindir=$name.out + rm -f $name.out/stf.txt + if [ -d "$bindir/$name.out" ]; then + bindir="$bindir/$name.out" + fi + if [ -d $outdir ]; then + bindir=$outdir + fi + if [ -r $bindir/tofino.bin -o -r $bindir/tofino.bin.gz ]; then + STF=$STF1 + elif [ -r $bindir/tofino2.bin -o -r $bindir/tofino2.bin.gz ]; then + STF=$STF2 + else + STF= + echo "$msg not built" + popd >/dev/null + return 4 + fi + if [ ! -x $STF ]; then + echo "$msg simple_test_framework not available" + popd >/dev/null + return 4 + fi + start=`date +%s` + if run "$STF" -l $bindir $name.stf >$name.out/stf.txt 2>&1; then + msg="$msg pass" + else + msg="$msg fail" + rv=1 + flock $FAILLOG -c "echo '$1:' >>$FAILLOG; sed -e 's/^/ /' $name.out/stf.txt >>$FAILLOG" + fi + if $TIME; then + let elapsed=`date +%s`-start + let min=elapsed/60 + let sec=elapsed%60 + if [ $sec -lt 10 ]; then + sec=0$sec + fi + msg="$msg ($min:$sec)" + fi + echo "$msg" + else + echo "$msg not built" + rv=4 + fi + popd >/dev/null + return $rv +} + +pass=0 +fail=0 +skip=0 +expected_fail=0 +unexpected_pass=0 +running=0 +tokens=0 +token_request=0 + +function get_token() { + eval "dd bs=1 count=1 of=/dev/null <&$TOKEN_READ" 2>/dev/null + exit 99 +} + +function release_one_token() { + eval "dd if=/dev/zero bs=1 count=1 >&$TOKEN_WRITE" 2>/dev/null + let tokens-- + let token_request-- +} + +function release_all_tokens() { + if (( token_request > 0 )); then + eval "dd if=/dev/zero bs=1 count=$token_request >&$TOKEN_WRITE" 2>/dev/null + token_request=0 + fi +} + +function wait_1() { + if [[ ${BASH_VERSINFO[0]} -lt 4 ]]; then + wait %1 + rv=$? + else + wait -n + rv=$? + fi + case $rv in + 0) let pass++ + ;; + 1) let fail++ + ;; + 2) let fail++ + let expected_fail++ + ;; + 3) let pass++ + let unexpected_pass++ + ;; + 4) let skip++ + ;; + 99) let tokens++ + return + ;; + esac + let running-- +} + +if $verbose; then echo "running $PARALLEL threads"; fi + +for file in "$@"; do + if (( running >= PARALLEL + tokens )); then + if (( TOKEN_READ && tokens == token_request )); then + let token_request++ + get_token & + fi + wait_1 + fi + if $outdir; then + if [ "${file##*.}" == "stf" ]; then + let running++ + test_stf $file & + else + echo "-o option can only be passed for stf file" + echo "Input file : $file" + exit 1 + fi + elif [ "${file##*.}" == "p4" ]; then + let running++ + test_p4 $file & + elif [ "${file##*.}" == "bfa" ]; then + let running++ + test_bfa $file & + elif [ "${file##*.}" == "tfa" ]; then + let running++ + test_bfa $file tofino & + elif [ "${file##*.}" == "jba" ]; then + let running++ + test_bfa $file tofino2 & + elif [ "${file##*.}" == "stf" ]; then + let running++ + test_stf $file & + else + echo "unrecognized file type $file" + fi + if [[ ${BASH_VERSINFO[0]} -lt 4 ]]; then + wait_1 + fi + if $link; then + link_json $file + fi +done + +while (( running > 0 )); do + while (( running < PARALLEL + tokens && tokens > 0)); do + release_one_token + done + wait_1 +done + +release_all_tokens + +if [ $pass -ne 1 ]; then + pmsg="$pass tests passed" +else + pmsg="1 test passed" +fi +if [ $fail -ne 1 ]; then + fmsg="$fail tests failed" +else + fmsg="1 test failed" +fi + +if [ $unexpected_pass -gt 1 ]; then + uxp=" ($unexpected_pass tests unexpectedly pass)" +elif [ $unexpected_pass -gt 0 ]; then + uxp=" ($unexpected_pass test unexpectedly passes)" +else + uxp="" +fi + +echo "$pmsg, $fmsg ($expected_fail expected)$uxp" +echo "$pmsg, $fmsg ($expected_fail expected)$uxp" >>$FAILLOG + +if [ $fail -ne $expected_fail ]; then + exit 1 +fi diff --git a/backends/tofino/bf-asm/test/selector0.p4 b/backends/tofino/bf-asm/test/selector0.p4 new file mode 100644 index 00000000000..19aa5251f4b --- /dev/null +++ b/backends/tofino/bf-asm/test/selector0.p4 @@ -0,0 +1,60 @@ +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +field_list sel_fields { + data.f1; + data.f2; + data.f3; + data.f4; +} + +field_list_calculation sel_hash { + input { + sel_fields; + } + algorithm : crc16; + output_width : 14; +} + +action_selector sel { + selection_key : sel_hash; + selection_mode : fair; +} + +action noop() { } + +action_profile sel_profile { + actions { + noop; + } + size : 16384; + dynamic_action_selection : sel; +} + +table test1 { + reads { + data.b1 : exact; + } + action_profile : sel_profile; + size : 1024; +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/selector1.p4 b/backends/tofino/bf-asm/test/selector1.p4 new file mode 100644 index 00000000000..dc40bccc6c7 --- /dev/null +++ b/backends/tofino/bf-asm/test/selector1.p4 @@ -0,0 +1,62 @@ +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +field_list sel_fields { + data.f1; + data.f2; + data.f3; + data.f4; +} + +field_list_calculation sel_hash { + input { + sel_fields; + } + algorithm : crc16; + output_width : 14; +} + +action_selector sel { + selection_key : sel_hash; + selection_mode : fair; +} + +action noop() { } +action setf1(val) { modify_field(data.f1, val); } + +action_profile sel_profile { + actions { + noop; + setf1; + } + size : 16384; + dynamic_action_selection : sel; +} + +table test1 { + reads { + data.b1 : exact; + } + action_profile : sel_profile; + size : 1024; +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/selector2.p4 b/backends/tofino/bf-asm/test/selector2.p4 new file mode 100644 index 00000000000..39433fa7893 --- /dev/null +++ b/backends/tofino/bf-asm/test/selector2.p4 @@ -0,0 +1,62 @@ +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +field_list sel_fields { + data.f1; + data.f2; + data.f3; + data.f4; +} + +field_list_calculation sel_hash { + input { + sel_fields; + } + algorithm : crc16; + output_width : 14; +} + +action_selector sel { + selection_key : sel_hash; + selection_mode : fair; +} + +action noop() { } +action setf1(val) { modify_field(data.f1, val); } + +action_profile sel_profile { + actions { + noop; + setf1; + } + size : 16384; + dynamic_action_selection : sel; +} + +table test1 { + reads { + data.b1 : ternary; + } + action_profile : sel_profile; + size : 1024; +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/selector3.p4 b/backends/tofino/bf-asm/test/selector3.p4 new file mode 100644 index 00000000000..800d0ddb10b --- /dev/null +++ b/backends/tofino/bf-asm/test/selector3.p4 @@ -0,0 +1,69 @@ +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +field_list sel_fields { + data.f1; + data.f2; + data.f3; + data.f4; +} + +field_list_calculation sel_hash { + input { + sel_fields; + } + algorithm : crc16; + output_width : 14; +} + +action_selector sel { + selection_key : sel_hash; + selection_mode : fair; +} + +action noop() { } +action setf1(val) { modify_field(data.f1, val); } +action setall(v1, v2, v3, v4) { + modify_field(data.f1, v1); + modify_field(data.f2, v2); + modify_field(data.f3, v3); + modify_field(data.f4, v4); +} + +action_profile sel_profile { + actions { + noop; + setf1; + setall; + } + size : 16384; + dynamic_action_selection : sel; +} + +table test1 { + reads { + data.b1 : exact; + } + action_profile : sel_profile; + size : 1024; +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/stf/exact_match1.p4 b/backends/tofino/bf-asm/test/stf/exact_match1.p4 new file mode 100644 index 00000000000..681b35eb75c --- /dev/null +++ b/backends/tofino/bf-asm/test/stf/exact_match1.p4 @@ -0,0 +1,51 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + h1 : 16; + b1 : 8; + b2 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setb1(val, port) { + modify_field(data.b1, val); + modify_field(standard_metadata.egress_spec, port); +} + +table test1 { + reads { + data.f1 : exact; + } + actions { + setb1; + noop; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/stf/exact_match1.stf b/backends/tofino/bf-asm/test/stf/exact_match1.stf new file mode 100644 index 00000000000..34520d4e443 --- /dev/null +++ b/backends/tofino/bf-asm/test/stf/exact_match1.stf @@ -0,0 +1,8 @@ + +add test1 data.f1:0x01010101 setb1(val:0x7f, port:2) +add test1 data.f1:0x02020202 setb1(val:7, port:3) + +expect 2 01010101 ******** **** 7f 66 +packet 0 01010101 00000202 0303 55 66 77 88 +expect 3 02020202 ******** **** 07 66 +packet 2 02020202 00000303 0404 55 66 77 88 diff --git a/backends/tofino/bf-asm/test/stf/hash_action_basic.p4 b/backends/tofino/bf-asm/test/stf/hash_action_basic.p4 new file mode 100644 index 00000000000..ce99dacb23c --- /dev/null +++ b/backends/tofino/bf-asm/test/stf/hash_action_basic.p4 @@ -0,0 +1,64 @@ +header_type data_t { + fields { + f1 : 32; + f2 : 32; + h1 : 16; + h2 : 16; + h3 : 16; + h4 : 16; + } +} + +header data_t data; + +header_type counter_metadata_t { + fields { + counter_index : 16; + } +} + +metadata counter_metadata_t counter_metadata; + +parser start { + extract(data); + return ingress; +} + +action set_index(index, port) { + modify_field(counter_metadata.counter_index, index); + modify_field(standard_metadata.egress_spec, port); +} + +table index_setter { + reads { + data.f1 : exact; + data.f2 : exact; + } + actions { + set_index; + } + size : 2048; +} + +counter count1 { + type : packets; + static : stats; + instance_count : 16384; + min_width : 32; +} + +action count_entries() { + count(count1, counter_metadata.counter_index); +} + +table stats { + actions { + count_entries; + } + default_action: count_entries; +} + +control ingress { + apply(index_setter); + apply(stats); +} diff --git a/backends/tofino/bf-asm/test/stf/hash_action_basic.stf b/backends/tofino/bf-asm/test/stf/hash_action_basic.stf new file mode 100644 index 00000000000..4b0c4263abf --- /dev/null +++ b/backends/tofino/bf-asm/test/stf/hash_action_basic.stf @@ -0,0 +1,20 @@ +add index_setter data.f1:0x11111111 data.f2:0x22222222 set_index(index:9, port:1) +add index_setter data.f1:0x22222222 data.f2:0x33333333 set_index(index:9, port:2) +add index_setter data.f1:0x33333333 data.f2:0x44444444 set_index(index:9, port:2) +add index_setter data.f1:0x44444444 data.f2:0x55555555 set_index(index:8, port:3) + +expect 1 11111111 22222222 0101 0202 0303 0404 +packet 0 11111111 22222222 0101 0202 0303 0404 + +# expect 2 22222222 33333333 0202 0303 0404 0505 +# packet 0 22222222 33333333 0202 0303 0404 0505 + +# expect 2 33333333 44444444 0303 0404 0505 0606 +# packet 0 33333333 44444444 0303 0404 0505 0606 + +# expect 3 44444444 55555555 0404 0505 0606 0707 +# packet 0 44444444 55555555 0404 0505 0606 0707 + +wait +# check_counter count1(8) packets == 1 +check_counter count1(9) packets == 1 diff --git a/backends/tofino/bf-asm/test/stf/max_counters.p4 b/backends/tofino/bf-asm/test/stf/max_counters.p4 new file mode 100644 index 00000000000..dc0e090d1cb --- /dev/null +++ b/backends/tofino/bf-asm/test/stf/max_counters.p4 @@ -0,0 +1,87 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + c1 : 8; + c2 : 8; + c3 : 8; + c4 : 8; + } +} + +header data_t data; + +parser start { + extract(data); + return ingress; +} +action c1_2(val1, val2) { + modify_field(data.c1, val1); + modify_field(data.c2, val2); +} + +action c3_4(val3, val4, port) { + modify_field(data.c3, val3); + modify_field(data.c4, val4); + modify_field(standard_metadata.egress_spec, port); +} + +table test1 { + reads { + data.f1 : exact; + } + actions { + c1_2; + } +} + +table test2 { + reads { + data.f2 : exact; + } + actions { + c3_4; + } + size: 1024; +} + +counter cnt { + type: packets; + direct: test1; +} + +counter cnt2 { + type: bytes; + direct: test1; +} + +counter cnt3 { + type: packets; + direct: test2; +} + +counter cnt4 { + type: bytes; + direct: test2; +} + +control ingress { + apply(test1); + apply(test2); +} diff --git a/backends/tofino/bf-asm/test/stf/max_counters.stf b/backends/tofino/bf-asm/test/stf/max_counters.stf new file mode 100644 index 00000000000..804b1d81f96 --- /dev/null +++ b/backends/tofino/bf-asm/test/stf/max_counters.stf @@ -0,0 +1,14 @@ +add test1 data.f1:0x01010101 c1_2(val1:0x01, val2:0x02) +add test1 data.f1:0x02020202 c1_2(val1:0x10, val2:0x20) + +add test2 data.f2:0x03030303 c3_4(val3:0x03, val4:0x04, port:1) +add test2 data.f2:0x04040404 c3_4(val3:0x30, val4:0x40, port:2) + +expect 1 01010101 03030303 01 02 03 04 +packet 0 01010101 03030303 55 66 77 88 +expect 2 01010101 04040404 01 02 30 40 +packet 0 01010101 04040404 55 66 77 88 +expect 1 02020202 03030303 10 20 03 04 +packet 0 02020202 03030303 99 88 77 66 +expect 2 02020202 04040404 10 20 30 40 +packet 0 02020202 04040404 14 25 36 47 diff --git a/backends/tofino/bf-asm/test/stf/p4c-5198.bfa b/backends/tofino/bf-asm/test/stf/p4c-5198.bfa new file mode 100644 index 00000000000..fb658cf4d54 --- /dev/null +++ b/backends/tofino/bf-asm/test/stf/p4c-5198.bfa @@ -0,0 +1,6776 @@ +version: + version: 1.0.1 + run_id: "ecba7fb5cb3842db" + target: Tofino2 +phv ingress: + ig_intr_md_for_dprsr.mirror_type.$valid: H7(0) + ig_intr_md.ingress_port: { stage 0..8: H65(0..8), stage 9..13: DH20(0..8), stage 14..15: H65(0..8) } + hdr.fabric_trace.trace_counter: { stage 16..20: H43 } + hdr.fabric_trace.timestamp.0-31: MW11 + hdr.fabric_trace.timestamp.32-47: { stage 0..8: H52, stage 9: DH16, stage 10..19: H52 } + ig_md.ig_ft.srv6.sid.0-31: { stage 2..8: DW0 } + ig_md.ig_ft.srv6.sid.32-63: { stage 2..8: DW4 } + ig_md.ig_ft.srv6.sid.64-95: { stage 2..8: DW5 } + ig_md.ig_ft.srv6.sid.96-127: { stage 2..8: DW8 } + ig_md.ig_ft.srv6.g_sid.0-15: { stage 2..7: DH3 } + ig_md.ig_ft.srv6.g_sid.16-31: { stage 2..7: DH12 } + ig_md.ig_ft.srv6.g_sid.32-63: { stage 2..7: DW3 } + ig_md.ig_ft.srv6.g_sid.64-95: { stage 2..7: DW2 } + ig_md.ig_ft.srv6.g_sid.96-127: { stage 2..7: DW1 } + ig_md.ig_ft.srv6.args.0-31: { stage 11..12: W5 } + ig_md.ig_ft.srv6.args.32-63: { stage 11..12: W14 } + ig_md.ig_ft.srv6.c_sid: { stage 8: W0 } + ig_md.ig_ft.srv6.prefixlen: { stage 7..8: H8(6..13) } + ig_md.ig_ft.srv6.si: { stage 7..9: W6(0..1) } + ig_md.ig_ft.srv6.srh_terminate: { stage 9..14: B13(6) } + ig_md.ig_ft.srv6.next_hdr: { stage 2..14: MB1 } + ig_md.ig_ft.srv6.end_type: { stage 5..14: W30(0..4) } + ig_md.ig_ft.srv6.tmp_info: { stage 10..15: H16(0..14) } + ig_md.ig_ft.srv6.end_flag: { stage 10..14: H43(3) } + ig_md.ig_ft.srv6.sl_flag: { stage 9..14: B35(7) } + ig_md.ig_ft.srv6.tmp_no_frr: { stage 0..13: B34(1) } + ig_md.ig_ft.srv6.sl_minus_flag: { stage 1..8: H16(15) } + ig_md.ig_ft.srv6.global_pf_mode: { stage 6..8: W28(0..1) } + ig_md.ig_ft.srv6.pf_bypass: { stage 1..7: B10(6) } + ig_md.ig_ft.srv6.pf_downgrade: { stage 0..8: MB8(0) } + ig_md.ig_ft.srv6.ext_flag: { stage 7..16: H8(3) } + ig_md.ig_ft.srv6.lif_type: { stage 10..14: H57(0) } + ig_md.ig_ft.srv6.is_end_as: { stage 10..14: H30(7) } + hdr.fabric_base.pkt_type: B37(2..7) + hdr.fabric_base.is_mirror: B37(1) + hdr.fabric_base.is_mcast: B37(0) + hdr.fabric_qos.tc: { stage 0..6: H69(5..7) } + hdr.fabric_qos.color: { stage 0..6: H69(3..4) } + hdr.fabric_qos.track: { stage 0: H69(0) } + hdr.fabric_data_template_plus.flags: B15 + hdr.fabric_data_template_plus.vb: B36 + hdr.fabric_data_template_plus.vh0: H53 + hdr.fabric_data_template_plus.vh1: H19 + hdr.fabric_data_template_plus.vh2: H1 + hdr.fabric_data_template_plus.vh3: H17 + hdr.fabric_data_template_plus.one: H13(15) + hdr.fabric_data_template_plus.iif: H13(0..14) + hdr.ig_ft.ipv6.version: B41(4..7) + hdr.ig_ft.ipv6.traffic_class.0-3: B40(4..7) + hdr.ig_ft.ipv6.traffic_class.4-7: B41(0..3) + hdr.ig_ft.ipv6.flow_label.0-15: H3 + hdr.ig_ft.ipv6.flow_label.16-19: B40(0..3) + hdr.ig_ft.ipv6.payload_len: H0 + hdr.ig_ft.ipv6.next_hdr: MB6 + hdr.ig_ft.ipv6.src_addr.0-15: H2 + hdr.ig_ft.ipv6.src_addr.16-31: MH12 + hdr.ig_ft.ipv6.src_addr.32-63: MW2 + hdr.ig_ft.ipv6.src_addr.64-95: MW1 + hdr.ig_ft.ipv6.src_addr.96-127: MW0 + hdr.ig_ft.ipv6.dst_addr.0-31: MW3 + hdr.ig_ft.ipv6.dst_addr.32-63: MW6 + hdr.ig_ft.ipv6.dst_addr.64-95: MW7 + hdr.ig_ft.ipv6.dst_addr.96-127: MW8 + ig_md.ig_ft.lkp.vid: { stage 0..11: H67(0..11) } + ig_md.ig_ft.lkp.mac_dst_addr.0-31: { stage 0..15: W16 } + ig_md.ig_ft.lkp.mac_dst_addr.32-47: { stage 0..15: H64 } + ig_md.ig_ft.lkp.mac_src_addr.0-15: { stage 0..2: W30(0..15) } + ig_md.ig_ft.lkp.mac_src_addr.16-23: { stage 0..2: H22(0..7) } + ig_md.ig_ft.lkp.mac_src_addr.24-47: { stage 0..2: W17(0..23) } + ig_md.ig_ft.lkp.l4_port_label_32.0-15: { stage 1..8: H43 } + ig_md.ig_ft.lkp.l4_port_label_32.16-31: { stage 1..8: H57 } + ig_md.ig_ft.lkp.l4_src_port: { stage 0..11: H66 } + ig_md.ig_ft.lkp.l4_dst_port: { stage 0..11: W31(0..15) } + ig_md.ig_ft.lkp.ip_frag: { stage 3..8: H22(0..1) } + ig_md.ig_ft.lkp.ip_tos.0-1: { stage 1..8: B44(0..1) } + ig_md.ig_ft.lkp.ip_tos.2-3: { stage 1..8: B45(0..1) } + ig_md.ig_ft.lkp.ip_tos.4-7: { stage 1..8: B46(0..3) } + ig_md.ig_ft.lkp.ip_proto: { stage 0..11: B18 } + ig_md.ig_ft.lkp.srv6_ip_proto: { stage 0..1: MB0 } + ig_md.ig_ft.lkp.ip_src_addr.0-15: { stage 0..11: H10 } + ig_md.ig_ft.lkp.ip_src_addr.16-31: { stage 0..11: MH13 } + ig_md.ig_ft.lkp.ip_src_addr.32-63: { stage 0..11: W3 } + ig_md.ig_ft.lkp.ip_src_addr.64-95: { stage 0..11: W2 } + ig_md.ig_ft.lkp.ip_src_addr.96-127: { stage 0..11: W1 } + ig_md.ig_ft.lkp.ip_dst_addr.0-31: { stage 0..13: W4 } + ig_md.ig_ft.lkp.ip_dst_addr.32-63: { stage 0..13: W13 } + ig_md.ig_ft.lkp.ip_dst_addr.64-95: { stage 0..13: W15 } + ig_md.ig_ft.lkp.ip_dst_addr.96-127: { stage 0..13: W24 } + ig_md.ig_ft.lkp.tcp_flags: { stage 0..8: H29(0..7) } + ig_md.ig_ft.lkp.ip_ttl: { stage 0..11: MH0(0..7) } + ig_md.ig_ft.lkp.flow_label: { stage 0..3: W28(0..19) } + ig_md.ig_ft.lkp.tmp_ipv4_checksum: { stage 0: H20 } + hdr.ig_ft.vxlan.vni.0-15: H4 + hdr.ig_ft.vxlan.vni.16-23: B47 + ig_md.ig_ft.flags.ipv4_checksum_err: { stage 0..15: H8(1) } + ig_md.ig_ft.flags.inner_ipv4_checksum_err: { stage 0..10: H8(2) } + ig_md.ig_ft.flags.tunnel_info: { stage 13..20: H12(14) } + ig_md.ig_ft.flags.drop: { stage 16..18: H37(0) } + hdr.ig_ft.srv6_srh.next_hdr: MB4 + hdr.ig_ft.srv6_srh.seg_left: B14 + hdr.ig_ft.srv6_srh.last_entry: B47 + hdr.ig_ft.doh_e2e.next_hdr: { stage 0: B45, stage 1..8: DB13, stage 9..19: B45 } + hdr.ig_ft.doh_e2e.hdr_ext_len: { stage 0: B46, stage 1..8: DB12, stage 9..19: B46 } + hdr.ig_ft.doh_e2e.option_type: { stage 0: H28(8..15), stage 1..16: DH8(8..15), stage 17..19: H28(8..15) } + hdr.ig_ft.doh_e2e.option_len: { stage 0: H28(0..7), stage 1..16: DH8(0..7), stage 17..19: H28(0..7) } + ig_md.ig_ft.ifit.loss_label: { stage 0..15: MB12(3) } + ig_md.ig_ft.ifit.delay_label: { stage 0..15: MB14(2) } + ig_md.ig_ft.ifit.ifit_enable: { stage 10..15: W38(0) } + ig_md.ig_ft.ifit.dyna_learn_flag: { stage 10..15: H69(0) } + ig_md.ig_ft.ifit.ifit_decap_enable: { stage 10..15: H69(3) } + ig_md.ig_ft.ifit.endpoint_enable: { stage 6..17: B35(6) } + ig_md.ig_ft.ifit.hti: { stage 0..15: MB10(6..7) } + ig_md.ig_ft.ifit.index: { stage 9..17: H22(0..11) } + ig_md.ig_ft.ifit.var_h1: { stage 11..20: H54 } + ig_md.ig_ft.ifit.flow_id: { stage 0..11: MW5(4..23) } + ig_md.ig_ft.ifit.flow_node_id: { stage 0..11: MW10(4..23) } + hdr.ig_ft.doh.next_hdr: MB5 + hdr.ig_ft.srv6_h2h_ifit.reserved3.0-15: H4 + hdr.ig_ft.srv6_h2h_ifit.reserved3.16-23: { stage 0: B31, stage 1..15: DB8, stage 16..19: B31 } + hdr.ext_tunnel_decap.ext_type: B38(5..7) + hdr.ext_tunnel_decap.extend: B38(4) + hdr.ext_tunnel_decap.sub_type: B38(0..3) + hdr.ext_tunnel_decap.vb: B39 + hdr.ext_tunnel_decap.vh: H18 + hdr.ig_ft.ethernet.dst_addr.0-31: MW15 + hdr.ig_ft.ethernet.dst_addr.32-47: H23 + hdr.ig_ft.ethernet.src_addr.0-31: MW14 + hdr.ig_ft.ethernet.src_addr.32-47: H55 + hdr.ig_ft.ethernet.ether_type: MH14 + hdr.ig_ft.vlan_tag$0.pcp: W10(29..31) + hdr.ig_ft.vlan_tag$0.cfi: W10(28) + hdr.ig_ft.vlan_tag$0.vid: W10(16..27) + hdr.ig_ft.vlan_tag$0.ether_type: W10(0..15) + hdr.ig_ft.vlan_tag$1.pcp: W11(29..31) + hdr.ig_ft.vlan_tag$1.cfi: W11(28) + hdr.ig_ft.vlan_tag$1.vid: W11(16..27) + hdr.ig_ft.vlan_tag$1.ether_type: W11(0..15) + ig_md.ig_ft.common.mac_type: { stage 1..16: H71(10..11) } + ig_md.ig_ft.common.pkt_type: B37(2..7) + ig_md.ig_ft.common.pipeline_location: { stage 19..20: MB15 } + ig_md.ig_ft.common.eport.0-7: { stage 1..2: H16(0..7) } + ig_md.ig_ft.common.eport.8-15: { stage 1..2: MH6(8..15) } + ig_md.ig_ft.common.src_port: { stage 1..20: MB13 } + ig_md.ig_ft.common.from_cpu: { stage 1..18: B13(4) } + ig_md.ig_ft.common.hash_mode: { stage 1..4: W38(0..3) } + ig_md.ig_ft.common.mirror_dst_eport: { stage 6..20: H56 } + ig_md.ig_ft.common.ether_type: { stage 0..15: MH11 } + ig_md.ig_ft.common.iif: { stage 1..20: H15(0..14) } + ig_md.ig_ft.common.ul_iif: { stage 1..20: H14(0..14) } + ig_md.ig_ft.common.iif_type: { stage 1..18: W37(0) } + ig_md.ig_ft.common.bridge_type: { stage 1..18: B35(0..4) } + ig_md.ig_ft.common.usi: { stage 3..4: H20(4..13) } + ig_md.ig_ft.common.trace_vh3: { stage 16..20: H57 } + ig_md.ig_ft.common.redirect_recirc: { stage 14..17: B34(1) } + ig_md.ig_ft.common.vpntovpn_flag: { stage 14..16: H16(15) } + ig_md.ig_ft.common.drop_reason: { stage 6..20: B30 } + ig_md.ig_ft.common.tstamp_flag: { stage 6..18: W17(17) } + ig_md.ig_ft.common.extend: { stage 1..18: B13(7) } + ig_md.ig_ft.common.diag: { stage 1..18: B13(3) } + ig_md.ig_ft.common.track: { stage 1..18: H70(0) } + ig_md.ig_ft.common.decap_len: { stage 10..17: H29 } + hdr.ig_ft.ipv4.diffserv: B40 + hdr.ig_ft.ipv4.flags: B14(5..7) + hdr.ig_ft.ipv4.frag_offset.0-7: MB5 + hdr.ig_ft.ipv4.frag_offset.8-12: B14(0..4) + hdr.ig_ft.ipv4.protocol: MB4 + hdr.ig_ft.ipv4.src_addr.0-15: H0 + hdr.ig_ft.ipv4.src_addr.16-31: MH12 + hdr.ig_ft.ipv4.dst_addr: MW0 + hdr.ig_ft.ipv4_option.type: MB6 + hdr.ig_ft.ipv4_option.length: H2(8..15) + hdr.ig_ft.ipv4_option.value.8-15: H2(0..7) + hdr.ig_ft.mpls_ig$0.label.0-3: H5(12..15) + hdr.ig_ft.mpls_ig$0.label.4-19: H40 + hdr.ig_ft.mpls_ig$0.exp: H5(9..11) + hdr.ig_ft.mpls_ig$0.bos: H5(8) + hdr.ig_ft.mpls_ig$0.ttl: H5(0..7) + hdr.ig_ft.mpls_ig$1.label.0-3: H4(12..15) + hdr.ig_ft.mpls_ig$1.label.4-19: H39 + hdr.ig_ft.mpls_ig$1.exp: H4(9..11) + hdr.ig_ft.mpls_ig$1.bos: H4(8) + hdr.ig_ft.mpls_ig$1.ttl: H4(0..7) + hdr.ig_ft.mpls_ig$2.label.0-3: H3(12..15) + hdr.ig_ft.mpls_ig$2.label.4-19: H38 + hdr.ig_ft.mpls_ig$2.exp: H3(9..11) + hdr.ig_ft.mpls_ig$2.bos: H3(8) + hdr.ig_ft.mpls_ig$2.ttl: H3(0..7) + hdr.ig_ft.mpls_ig$3.label.0-3: H2(12..15) + hdr.ig_ft.mpls_ig$3.label.4-19: { stage 0..15: H37, stage 16..18: DH14, stage 19: H37 } + hdr.ig_ft.mpls_ig$3.exp: H2(9..11) + hdr.ig_ft.mpls_ig$3.bos: H2(8) + hdr.ig_ft.mpls_ig$3.ttl: H2(0..7) + hdr.ig_ft.mpls_ig$4.label.0-3: H0(12..15) + hdr.ig_ft.mpls_ig$4.label.4-19: { stage 0..11: H36, stage 12..18: DH13, stage 19: H36 } + hdr.ig_ft.mpls_ig$4.exp: H0(9..11) + hdr.ig_ft.mpls_ig$4.bos: H0(8) + hdr.ig_ft.mpls_ig$4.ttl: H0(0..7) + hdr.ig_ft.br_tag.ecid: { stage 0: H1(0..11) } + hdr.fabric_from_cpu_eth_ccm.dev_port: { stage 0..12: MW8(0..8) } + ig_md.ig_ft.route.vrf: { stage 4..20: H12(0..12) } + ig_md.ig_ft.route.rmac_hit: { stage 1..18: B12(7) } + ig_md.ig_ft.route.ipv4_unicast_enable: { stage 4..6: H22(8) } + ig_md.ig_ft.route.ipv6_unicast_enable: { stage 4..11: H8(5) } + ig_md.ig_ft.tunnel.mpls_enable: { stage 1..15: H8(4) } + ig_md.ig_ft.tunnel.type: { stage 1..15: B31(0..2) } + ig_md.ig_ft.tunnel.sub_type: { stage 3..15: W6(17..20) } + ig_md.ig_ft.tunnel.is_ttl_copy: { stage 1..18: H8(0) } + ig_md.ig_ft.tunnel.is_ttl_copy_1: { stage 6..8: W0(1) } + ig_md.ig_ft.tunnel.is_ttl_copy_2: { stage 7..8: W0(0) } + ig_md.ig_ft.tunnel.is_ttl_copy_3: { stage 8: W0(2) } + ig_md.ig_ft.tunnel.ttl_2: { stage 6..8: DH0(0..7) } + ig_md.ig_ft.tunnel.ttl_3: { stage 7..8: DH1(0..7) } + ig_md.ig_ft.tunnel.ttl_4: { stage 8: DH2(0..7) } + ig_md.ig_ft.tunnel.urpf_type: { stage 2..15: W38(4..7) } + ig_md.ig_ft.tunnel.decap_pre_len: { stage 1..16: H28 } + ig_md.ig_ft.tunnel.is_pre_len_add: { stage 14..16: H30(8) } + ig_md.ig_ft.tunnel.is_terminate: { stage 6..18: MH5(13) } + ig_md.ig_ft.tunnel.is_ilm_continue: { stage 6..7: MH4(0) } + ig_md.ig_ft.tunnel.is_vpn_terminate: { stage 5..15: W28(2) } + ig_md.ig_ft.tunnel.ipv4_true: { stage 11..20: H12(15) } + ig_md.ig_ft.tunnel.evpn_end_type: { stage 10..15: H57(1) } + ig_md.ig_ft.tunnel.inner_pkt_parsed: { stage 3..14: H6(12..14) } + ig_md.ig_ft.tunnel.src_netport_group: { stage 10..15: H43(0..2) } + ig_md.ig_ft.tunnel.source_id: { stage 10..15: H31(1..10) } + ig_md.ig_ft.tunnel.tmp_oif: { stage 7: MH4(0..14) } + ig_md.ig_ft.tunnel.srv6_flavors: { stage 5..8: W28(3..6) } + ig_md.ig_ft.tunnel.bypass_pw: { stage 6..15: W17(18) } + ig_md.ig_ft.tunnel.is_cw: { stage 8..14: H6(15) } + ig_md.ig_ft.tunnel.decap_num: { stage 9: MB2(0..1) } + ig_md.ig_ft.ipfix.flow_id: { stage 3..9: H70(8..15) } + ig_md.ig_ft.ipfix.sample_gap: { stage 3..6: MH9 } + ig_md.ig_ft.ipfix.random_num: { stage 1..9: H30 } + ig_md.ig_ft.ipfix.count: { stage 6..9: W17(1..16) } + ig_md.ig_ft.ipfix.delta: { stage 5: H31 } + ig_md.ig_ft.ipfix.random_flag: { stage 9: H52(0) } + ig_md.ig_ft.mirror.session_id: { stage 3..20: MB7 } + ig_md.ig_ft.mirror.meter_id: { stage 6: H16(0..9) } + ig_md.ig_ft.mirror.sample_flag: { stage 9..18: W17(0) } + ig_md.ig_ft.mirror.span_flag: { stage 6..18: B5(0) } + ig_md.ig_ft.mirror.flags: { stage 17..20: MB2 } + ig_md.ig_ft.mirror.ifit_flag: { stage 14..18: B6(0) } + ig_md.ig_ft.mirror.src: { stage 17..20: MB0(5..7) } + ig_md.ig_ft.mirror.type: { stage 17..20: MB0(0..4) } + ig_md.ig_ft.ebridge.evlan: { stage 5..18: H20(0..13) } + ig_md.ig_ft.ebridge.is_iif_block: { stage 4..18: B13(5) } + ul_lif_properties_check_usi_states_0: { stage 5: H22(9) } + ig_md.ig_ft.qos.meter_mode: { stage 5..9: H70(7) } + ig_md.ig_ft.qos.acl_meter_index.0-7: { stage 5..10: B6 } + ig_md.ig_ft.qos.acl_meter_index.8-13: { stage 5..10: H70(1..6) } + ig_md.ig_ft.qos.acl_meter_color: { stage 11..15: B5(3..4) } + ig_md.ig_ft.qos.lif_trust_mode: { stage 4..5: B5(5..7) } + ig_md.ig_ft.qos.lif_ds: { stage 4..5: H71(5..9) } + ig_md.ig_ft.qos.lif_meter_index: { stage 4..13: W37(1..14) } + ig_md.ig_ft.qos.is_auto_trust: { stage 4..15: B35(5) } + ig_md.ig_ft.qos.color: { stage 4..18: H71(0..1) } + ig_md.ig_ft.qos.tc: { stage 4..18: H71(2..4) } + ig_md.ig_ft.qos.BA: { stage 4..18: H6(11) } + ig_md.ig_ft.qos.set_dscp: { stage 12: B6(1) } + ig_md.ig_ft.qos.dscp: { stage 12: B44(2..7) } + ig_md.ig_ft.qos.chgDSCP_disable: { stage 12..18: H36(0) } + ig_md.ig_ft.qos.lif_meter_color: { stage 13..15: B5(1..2) } + ig_md.ig_ft.policer.slice1.vag_classid.0-7: { stage 3: H29(8..15) } + ig_md.ig_ft.policer.slice1.vag_classid.8-15: { stage 3: H69(8..15) } + ig_md.ig_ft.policer.slice2.vag_classid: { stage 3..8: W30(16..31) } + ig_md.ig_ft.policer.slice3.vag_classid: { stage 3..4: W31(16..31) } + ig_intr_md_for_dprsr.drop_ctl: { stage 4..20: W6(2..4) } + ig_intr_md_for_dprsr.mirror_type: { stage 17..20: B1(0..3) } + ig_intr_md_for_dprsr.mirror_io_select: { stage 16..20: H31(0) } + ig_intr_md_for_dprsr.drop_ctl.$valid: { stage 4..20: B10(3) } + ig_md.ig_ft.policer.mac_drop: { stage 5..15: B10(7) } + ig_md.ig_ft.policer.behavior_id: { stage 5..11: W6(5..16) } + hdr.ext_srv6.ext_type: { stage 17..20: B11(5..7) } + hdr.ext_srv6.extend: { stage 18..20: B11(4) } + hdr.ext_srv6.bypass_L3: { stage 7..20: B11(3) } + hdr.ext_srv6.level: { stage 7..20: B11(1..2) } + hdr.ext_srv6.is_ecmp: { stage 7..20: B11(0) } + hdr.ext_srv6.priority: { stage 7..20: W7(24..31) } + hdr.ext_srv6.nexthop: { stage 7..20: W7(8..23) } + hdr.ext_srv6.no_frr: { stage 14..20: W7(7) } + hdr.ext_srv6.nexthop_ext: { stage 7..20: W7(6) } + hdr.ext_srv6.is_pf: { stage 10..20: W7(5) } + hdr.ext_srv6.is_endx_pf: { stage 10..20: W7(4) } + hdr.ext_srv6.oam_flag: { stage 9..20: W7(0..3) } + hdr.fabric_qos_encap.data: { stage 19..20: B29 } + ig_intr_md_for_tm.ucast_egress_port: { stage 1..20: MW9(0..8) } + ig_intr_md_for_tm.bypass_egress: { stage 7..20: B12(6) } + ig_intr_md_for_tm.deflect_on_drop: { stage 16..20: H31(1) } + ig_intr_md_for_tm.qid: { stage 16..20: H30(0..6) } + ig_intr_md_for_tm.bypass_egress.$valid: { stage 7..20: H7(1) } + hdr.ext_ifit_encap.ext_type: { stage 16..20: H22(13..15) } + hdr.ext_ifit_encap.extend: { stage 16..20: H22(12) } + hdr.ext_ifit_encap.index: { stage 9..17: H22(0..11) } + hdr.ext_ifit_encap.var_h1: { stage 16..20: H21 } + cpu_egress_port_mapping_fabric_lag_flag: { stage 9..10: H65(0..6) } + ig_intr_md_for_tm.ucast_egress_port.$valid: { stage 1..20: B10(2) } + ig_intr_md_for_tm.qid.$valid: { stage 16..20: B9(5) } + ig_intr_md_for_tm.deflect_on_drop.$valid: { stage 19..20: H7(2) } + ig_intr_md_for_dprsr.mirror_io_select.$valid: { stage 19..20: H7(3) } + hdr.bridged_md_12_encap.decap_len: { stage 18..20: H24 } + hdr.switch_bridged_src.src: { stage 19..20: B28(5..7) } + hdr.switch_bridged_src.bridge_type: { stage 19..20: B28(0..4) } + $tmp11: { stage 20: B0 } + $pad14: { stage 20: H15(15) } + $pad15: { stage 20: H14(15) } + $pad18: { stage 20: H12(13) } + hdr.fabric_trace.$valid: { stage 7..20: H7(4) } + hdr.fabric_base.$valid: B10(4) + hdr.fabric_data_template_plus.$valid: B13(1) + hdr.ig_ft.ipv6.$valid: H7(5) + hdr.ig_ft.udp.$valid: H7(6) + hdr.ig_ft.vxlan.$valid: H7(7) + hdr.ig_ft.inner_ethernet.$valid: H7(8) + hdr.ig_ft.inner_ipv4.$valid: H7(9) + hdr.ig_ft.inner_ipv6.$valid: H7(10) + hdr.ig_ft.inner_vlan_tag.$valid: H7(11) + hdr.ig_ft.srv6_srh.$valid: H7(12) + hdr.ig_ft.doh_e2e.$valid: H7(13) + hdr.ig_ft.srv6_e2e_ifit.$valid: H7(14) + hdr.ig_ft.doh.$valid: H7(15) + hdr.ig_ft.srv6_h2h_ifit.$valid: B12(0) + hdr.ext_tunnel_decap.$valid: B13(0) + hdr.ig_ft.ethernet.$valid: B12(1) + hdr.ig_ft.ipv4.$valid: B12(2) + hdr.ig_ft.ipv4_option.$valid: B12(3) + hdr.ig_ft.br_tag.$valid: { stage 0..13: B12(4) } + hdr.ext_srv6.$valid: { stage 17..20: B13(2) } + hdr.fabric_qos_encap.$valid: { stage 7..20: B9(6) } + hdr.ext_ifit_encap.$valid: { stage 16..20: B12(5) } + hdr.bridged_md_12_encap.$valid: { stage 19..20: B9(7) } + hdr.switch_bridged_src.$valid: { stage 19..20: B10(5) } + hdr.ig_ft.srv6_list.$stkvalid: H6(0..10) + hdr.ig_ft.srv6_list$0.$valid: { stage 4..20: H6(10) } + hdr.ig_ft.srv6_list$1.$valid: { stage 4..20: H6(9) } + hdr.ig_ft.srv6_list$2.$valid: { stage 4..20: H6(8) } + hdr.ig_ft.srv6_list$3.$valid: { stage 4..20: H6(7) } + hdr.ig_ft.srv6_list$4.$valid: { stage 4..20: H6(6) } + hdr.ig_ft.srv6_list$5.$valid: { stage 4..20: H6(5) } + hdr.ig_ft.srv6_list$6.$valid: { stage 4..20: H6(4) } + hdr.ig_ft.srv6_list$7.$valid: { stage 4..20: H6(3) } + hdr.ig_ft.srv6_list$8.$valid: { stage 4..20: H6(2) } + hdr.ig_ft.srv6_list$9.$valid: { stage 4..20: H6(1) } + hdr.ig_ft.srv6_list$10.$valid: H6(0) + hdr.ig_ft.vlan_tag.$stkvalid: B10(0..1) + hdr.ig_ft.vlan_tag$0.$valid: B10(1) + hdr.ig_ft.vlan_tag$1.$valid: { stage 1..20: B10(0) } + hdr.ig_ft.mpls_ig.$stkvalid: B8 + hdr.ig_ft.mpls_ig$0.$valid: B8(7) + hdr.ig_ft.mpls_ig$1.$valid: { stage 5..20: B8(6) } + hdr.ig_ft.mpls_ig$2.$valid: { stage 5..20: B8(5) } + hdr.ig_ft.mpls_ig$3.$valid: { stage 5..20: B8(4) } + hdr.ig_ft.mpls_ig$4.$valid: B8(3) + hdr.ig_ft.mpls2_ig.$stkvalid: B9(0..4) + hdr.ig_ft.mpls2_ig$0.$valid: { stage 15..20: B9(4) } + hdr.ig_ft.mpls2_ig$1.$valid: { stage 20: B9(3) } + hdr.ig_ft.mpls2_ig$2.$valid: { stage 20: B9(2) } + hdr.ig_ft.mpls2_ig$3.$valid: { stage 20: B9(1) } + hdr.ig_ft.mpls2_ig$4.$valid: B9(0) + context_json: + DB8: + - { name : hdr.ig_ft.srv6_h2h_ifit.reserved3, live_start : 1, live_end : 15, mutually_exclusive_with: [ ] } + DB12: + - { name : hdr.ig_ft.doh_e2e.hdr_ext_len, live_start : 1, live_end : 8, mutually_exclusive_with: [ ] } + DB13: + - { name : hdr.ig_ft.doh_e2e.next_hdr, live_start : 1, live_end : 8, mutually_exclusive_with: [ ] } + DH0: + - { name : ig_md.ig_ft.tunnel.ttl_2, live_start : 6, live_end : 8, mutually_exclusive_with: [ ] } + DH1: + - { name : ig_md.ig_ft.tunnel.ttl_3, live_start : 7, live_end : 8, mutually_exclusive_with: [ ] } + DH2: + - { name : ig_md.ig_ft.tunnel.ttl_4, live_start : 8, live_end : 8, mutually_exclusive_with: [ ] } + DH3: + - { name : ig_md.ig_ft.srv6.g_sid, live_start : 2, live_end : 7, mutually_exclusive_with: [ ] } + DH8: + - { name : hdr.ig_ft.doh_e2e.option_type, live_start : 1, live_end : 16, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.doh_e2e.option_len, live_start : 1, live_end : 16, mutually_exclusive_with: [ ] } + DH12: + - { name : ig_md.ig_ft.srv6.g_sid, live_start : 2, live_end : 7, mutually_exclusive_with: [ ] } + DH13: + - { name : hdr.ig_ft.mpls_ig$4.label, live_start : 12, live_end : 18, mutually_exclusive_with: [ ] } + DH14: + - { name : hdr.ig_ft.mpls_ig$3.label, live_start : 16, live_end : 18, mutually_exclusive_with: [ ] } + DH16: + - { name : hdr.fabric_trace.timestamp, live_start : 9, live_end : 9, mutually_exclusive_with: [ ] } + DH20: + - { name : ig_intr_md.ingress_port, live_start : 9, live_end : 13, mutually_exclusive_with: [ ] } + DW0: + - { name : ig_md.ig_ft.srv6.sid, live_start : 2, live_end : 8, mutually_exclusive_with: [ ] } + DW1: + - { name : ig_md.ig_ft.srv6.g_sid, live_start : 2, live_end : 7, mutually_exclusive_with: [ ] } + DW2: + - { name : ig_md.ig_ft.srv6.g_sid, live_start : 2, live_end : 7, mutually_exclusive_with: [ ] } + DW3: + - { name : ig_md.ig_ft.srv6.g_sid, live_start : 2, live_end : 7, mutually_exclusive_with: [ ] } + DW4: + - { name : ig_md.ig_ft.srv6.sid, live_start : 2, live_end : 8, mutually_exclusive_with: [ ] } + DW5: + - { name : ig_md.ig_ft.srv6.sid, live_start : 2, live_end : 8, mutually_exclusive_with: [ ] } + DW8: + - { name : ig_md.ig_ft.srv6.sid, live_start : 2, live_end : 8, mutually_exclusive_with: [ ] } + MB0: + - { name : ig_md.ig_ft.lkp.srv6_ip_proto, live_start : 0, live_end : 1, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.mirror.src, live_start : 17, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.mirror.type, live_start : 17, live_end : deparser, mutually_exclusive_with: [ ] } + MB1: + - { name : ig_md.ig_ft.srv6.next_hdr, live_start : 2, live_end : 14, mutually_exclusive_with: [ ] } + MB2: + - { name : ig_md.ig_ft.tunnel.decap_num, live_start : 9, live_end : 9, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.mirror.flags, live_start : 17, live_end : deparser, mutually_exclusive_with: [ ] } + MB4: + - { name : hdr.ig_ft.srv6_srh.next_hdr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4.protocol ] } + - { name : hdr.ig_ft.ipv4.protocol, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.srv6_srh.next_hdr ] } + MB5: + - { name : hdr.ig_ft.doh.next_hdr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4.frag_offset ] } + - { name : hdr.ig_ft.ipv4.frag_offset, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.doh.next_hdr ] } + MB6: + - { name : hdr.ig_ft.ipv6.next_hdr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4_option.type ] } + - { name : hdr.ig_ft.ipv4_option.type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.next_hdr ] } + MB7: + - { name : ig_md.ig_ft.mirror.session_id, live_start : 3, live_end : deparser, mutually_exclusive_with: [ ] } + MB8: + - { name : ig_md.ig_ft.srv6.pf_downgrade, live_start : parser, live_end : 8, mutually_exclusive_with: [ ] } + MB10: + - { name : ig_md.ig_ft.ifit.hti, live_start : parser, live_end : 15, mutually_exclusive_with: [ ] } + MB12: + - { name : ig_md.ig_ft.ifit.loss_label, live_start : parser, live_end : 15, mutually_exclusive_with: [ ] } + MB13: + - { name : ig_md.ig_ft.common.src_port, live_start : 1, live_end : deparser, mutually_exclusive_with: [ ] } + MB14: + - { name : ig_md.ig_ft.ifit.delay_label, live_start : parser, live_end : 15, mutually_exclusive_with: [ ] } + MB15: + - { name : ig_md.ig_ft.common.pipeline_location, live_start : 19, live_end : deparser, mutually_exclusive_with: [ ] } + MH0: + - { name : ig_md.ig_ft.lkp.ip_ttl, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } + MH4: + - { name : ig_md.ig_ft.tunnel.is_ilm_continue, live_start : 6, live_end : 7, mutually_exclusive_with: [ ig_md.ig_ft.tunnel.tmp_oif ] } + - { name : ig_md.ig_ft.tunnel.tmp_oif, live_start : 7, live_end : 7, mutually_exclusive_with: [ ig_md.ig_ft.tunnel.is_ilm_continue ] } + MH5: + - { name : ig_md.ig_ft.tunnel.is_terminate, live_start : 6, live_end : 18, mutually_exclusive_with: [ ] } + MH6: + - { name : ig_md.ig_ft.common.eport, live_start : 1, live_end : 2, mutually_exclusive_with: [ ] } + MH9: + - { name : ig_md.ig_ft.ipfix.sample_gap, live_start : 3, live_end : 6, mutually_exclusive_with: [ ] } + MH11: + - { name : ig_md.ig_ft.common.ether_type, live_start : parser, live_end : 15, mutually_exclusive_with: [ ] } + MH12: + - { name : hdr.ig_ft.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4.src_addr ] } + - { name : hdr.ig_ft.ipv4.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.src_addr ] } + MH13: + - { name : ig_md.ig_ft.lkp.ip_src_addr, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } + MH14: + - { name : hdr.ig_ft.ethernet.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + MW0: + - { name : hdr.ig_ft.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4.dst_addr ] } + - { name : hdr.ig_ft.ipv4.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.src_addr ] } + MW1: + - { name : hdr.ig_ft.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + MW2: + - { name : hdr.ig_ft.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + MW3: + - { name : hdr.ig_ft.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + MW5: + - { name : ig_md.ig_ft.ifit.flow_id, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } + MW6: + - { name : hdr.ig_ft.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + MW7: + - { name : hdr.ig_ft.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + MW8: + - { name : hdr.ig_ft.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.fabric_from_cpu_eth_ccm.dev_port ] } + - { name : hdr.fabric_from_cpu_eth_ccm.dev_port, live_start : parser, live_end : 12, mutually_exclusive_with: [ hdr.ig_ft.ipv6.dst_addr ] } + MW9: + - { name : ig_intr_md_for_tm.ucast_egress_port, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } + MW10: + - { name : ig_md.ig_ft.ifit.flow_node_id, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } + MW11: + - { name : hdr.fabric_trace.timestamp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + MW14: + - { name : hdr.ig_ft.ethernet.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + MW15: + - { name : hdr.ig_ft.ethernet.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B0: + - { name : $tmp11, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + B1: + - { name : ig_intr_md_for_dprsr.mirror_type, live_start : 17, live_end : deparser, mutually_exclusive_with: [ ] } + B5: + - { name : ig_md.ig_ft.mirror.span_flag, live_start : 6, live_end : 18, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.qos.acl_meter_color, live_start : 11, live_end : 15, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.qos.lif_trust_mode, live_start : 4, live_end : 5, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.qos.lif_meter_color, live_start : 13, live_end : 15, mutually_exclusive_with: [ ] } + B6: + - { name : ig_md.ig_ft.mirror.ifit_flag, live_start : 14, live_end : 18, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.qos.acl_meter_index, live_start : 5, live_end : 10, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.qos.set_dscp, live_start : 12, live_end : 12, mutually_exclusive_with: [ ] } + B8: + - { name : hdr.ig_ft.mpls_ig$4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.mpls_ig.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.mpls_ig$0.$valid, live_start : 0, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.mpls_ig$1.$valid, live_start : 5, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.mpls_ig$2.$valid, live_start : 5, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.mpls_ig$3.$valid, live_start : 5, live_end : deparser, mutually_exclusive_with: [ ] } + B9: + - { name : ig_intr_md_for_tm.qid.$valid, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_qos_encap.$valid, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.bridged_md_12_encap.$valid, live_start : 19, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.mpls2_ig$4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.mpls2_ig.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.mpls2_ig$0.$valid, live_start : 15, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.mpls2_ig$1.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.mpls2_ig$2.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.mpls2_ig$3.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + B10: + - { name : ig_md.ig_ft.srv6.pf_bypass, live_start : 1, live_end : 7, mutually_exclusive_with: [ ] } + - { name : ig_intr_md_for_dprsr.drop_ctl.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.policer.mac_drop, live_start : 5, live_end : 15, mutually_exclusive_with: [ ] } + - { name : ig_intr_md_for_tm.ucast_egress_port.$valid, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_base.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.switch_bridged_src.$valid, live_start : 19, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.vlan_tag$0.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.vlan_tag.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.vlan_tag$1.$valid, live_start : 1, live_end : deparser, mutually_exclusive_with: [ ] } + B11: + - { name : hdr.ext_srv6.ext_type, live_start : 17, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ext_srv6.extend, live_start : 18, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ext_srv6.bypass_L3, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ext_srv6.level, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ext_srv6.is_ecmp, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } + B12: + - { name : ig_md.ig_ft.route.rmac_hit, live_start : 1, live_end : 18, mutually_exclusive_with: [ ] } + - { name : ig_intr_md_for_tm.bypass_egress, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.srv6_h2h_ifit.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.ethernet.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.ipv4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.ipv4_option.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.br_tag.$valid, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + - { name : hdr.ext_ifit_encap.$valid, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } + B13: + - { name : ig_md.ig_ft.srv6.srh_terminate, live_start : 9, live_end : 14, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.common.from_cpu, live_start : 1, live_end : 18, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.common.extend, live_start : 1, live_end : 18, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.common.diag, live_start : 1, live_end : 18, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.ebridge.is_iif_block, live_start : 4, live_end : 18, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_data_template_plus.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ext_tunnel_decap.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ext_srv6.$valid, live_start : 17, live_end : deparser, mutually_exclusive_with: [ ] } + B14: + - { name : hdr.ig_ft.srv6_srh.seg_left, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4.flags, hdr.ig_ft.ipv4.frag_offset ] } + - { name : hdr.ig_ft.ipv4.flags, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.srv6_srh.seg_left ] } + - { name : hdr.ig_ft.ipv4.frag_offset, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.srv6_srh.seg_left ] } + B15: + - { name : hdr.fabric_data_template_plus.flags, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B18: + - { name : ig_md.ig_ft.lkp.ip_proto, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } + B28: + - { name : hdr.switch_bridged_src.src, live_start : 19, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.switch_bridged_src.bridge_type, live_start : 19, live_end : deparser, mutually_exclusive_with: [ ] } + B29: + - { name : hdr.fabric_qos_encap.data, live_start : 19, live_end : deparser, mutually_exclusive_with: [ ] } + B30: + - { name : ig_md.ig_ft.common.drop_reason, live_start : 6, live_end : deparser, mutually_exclusive_with: [ ] } + B31: + - { name : hdr.ig_ft.srv6_h2h_ifit.reserved3, live_start : 0, live_end : 0, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.srv6_h2h_ifit.reserved3, live_start : 16, live_end : 19, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.tunnel.type, live_start : 1, live_end : 15, mutually_exclusive_with: [ ] } + B34: + - { name : ig_md.ig_ft.srv6.tmp_no_frr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.common.redirect_recirc, live_start : 14, live_end : 17, mutually_exclusive_with: [ ] } + B35: + - { name : ig_md.ig_ft.srv6.sl_flag, live_start : 9, live_end : 14, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.ifit.endpoint_enable, live_start : 6, live_end : 17, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.common.bridge_type, live_start : 1, live_end : 18, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.qos.is_auto_trust, live_start : 4, live_end : 15, mutually_exclusive_with: [ ] } + B36: + - { name : hdr.fabric_data_template_plus.vb, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B37: + - { name : ig_md.ig_ft.common.pkt_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_base.pkt_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_base.is_mirror, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_base.is_mcast, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B38: + - { name : hdr.ext_tunnel_decap.ext_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ext_tunnel_decap.extend, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ext_tunnel_decap.sub_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B39: + - { name : hdr.ext_tunnel_decap.vb, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B40: + - { name : hdr.ig_ft.ipv6.traffic_class, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4.diffserv ] } + - { name : hdr.ig_ft.ipv6.flow_label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4.diffserv ] } + - { name : hdr.ig_ft.ipv4.diffserv, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.traffic_class, hdr.ig_ft.ipv6.flow_label ] } + B41: + - { name : hdr.ig_ft.ipv6.version, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.ipv6.traffic_class, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B44: + - { name : ig_md.ig_ft.lkp.ip_tos, live_start : 1, live_end : 8, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.qos.dscp, live_start : 12, live_end : 12, mutually_exclusive_with: [ ] } + B45: + - { name : ig_md.ig_ft.lkp.ip_tos, live_start : 1, live_end : 8, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.doh_e2e.next_hdr, live_start : 0, live_end : 0, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.doh_e2e.next_hdr, live_start : 9, live_end : 19, mutually_exclusive_with: [ ] } + B46: + - { name : ig_md.ig_ft.lkp.ip_tos, live_start : 1, live_end : 8, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.doh_e2e.hdr_ext_len, live_start : 0, live_end : 0, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.doh_e2e.hdr_ext_len, live_start : 9, live_end : 19, mutually_exclusive_with: [ ] } + B47: + - { name : hdr.ig_ft.vxlan.vni, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.srv6_srh.last_entry ] } + - { name : hdr.ig_ft.srv6_srh.last_entry, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.vxlan.vni ] } + H0: + - { name : hdr.ig_ft.ipv6.payload_len, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4.src_addr, hdr.ig_ft.mpls_ig$4.label, hdr.ig_ft.mpls_ig$4.exp, hdr.ig_ft.mpls_ig$4.bos, hdr.ig_ft.mpls_ig$4.ttl ] } + - { name : hdr.ig_ft.ipv4.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.payload_len, hdr.ig_ft.mpls_ig$4.label, hdr.ig_ft.mpls_ig$4.exp, hdr.ig_ft.mpls_ig$4.bos, hdr.ig_ft.mpls_ig$4.ttl ] } + - { name : hdr.ig_ft.mpls_ig$4.label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.payload_len, hdr.ig_ft.ipv4.src_addr ] } + - { name : hdr.ig_ft.mpls_ig$4.exp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.payload_len, hdr.ig_ft.ipv4.src_addr ] } + - { name : hdr.ig_ft.mpls_ig$4.bos, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.payload_len, hdr.ig_ft.ipv4.src_addr ] } + - { name : hdr.ig_ft.mpls_ig$4.ttl, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.payload_len, hdr.ig_ft.ipv4.src_addr ] } + H1: + - { name : hdr.fabric_data_template_plus.vh2, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.br_tag.ecid ] } + - { name : hdr.ig_ft.br_tag.ecid, live_start : parser, live_end : 0, mutually_exclusive_with: [ hdr.fabric_data_template_plus.vh2 ] } + H2: + - { name : hdr.ig_ft.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4_option.length, hdr.ig_ft.ipv4_option.value, hdr.ig_ft.mpls_ig$3.label, hdr.ig_ft.mpls_ig$3.exp, hdr.ig_ft.mpls_ig$3.bos, hdr.ig_ft.mpls_ig$3.ttl ] } + - { name : hdr.ig_ft.ipv4_option.length, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.src_addr, hdr.ig_ft.mpls_ig$3.label, hdr.ig_ft.mpls_ig$3.exp, hdr.ig_ft.mpls_ig$3.bos, hdr.ig_ft.mpls_ig$3.ttl ] } + - { name : hdr.ig_ft.ipv4_option.value, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.src_addr, hdr.ig_ft.mpls_ig$3.label, hdr.ig_ft.mpls_ig$3.exp, hdr.ig_ft.mpls_ig$3.bos, hdr.ig_ft.mpls_ig$3.ttl ] } + - { name : hdr.ig_ft.mpls_ig$3.label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.src_addr, hdr.ig_ft.ipv4_option.length, hdr.ig_ft.ipv4_option.value ] } + - { name : hdr.ig_ft.mpls_ig$3.exp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.src_addr, hdr.ig_ft.ipv4_option.length, hdr.ig_ft.ipv4_option.value ] } + - { name : hdr.ig_ft.mpls_ig$3.bos, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.src_addr, hdr.ig_ft.ipv4_option.length, hdr.ig_ft.ipv4_option.value ] } + - { name : hdr.ig_ft.mpls_ig$3.ttl, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.src_addr, hdr.ig_ft.ipv4_option.length, hdr.ig_ft.ipv4_option.value ] } + H3: + - { name : hdr.ig_ft.ipv6.flow_label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.mpls_ig$2.label, hdr.ig_ft.mpls_ig$2.exp, hdr.ig_ft.mpls_ig$2.bos, hdr.ig_ft.mpls_ig$2.ttl ] } + - { name : hdr.ig_ft.mpls_ig$2.label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.flow_label ] } + - { name : hdr.ig_ft.mpls_ig$2.exp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.flow_label ] } + - { name : hdr.ig_ft.mpls_ig$2.bos, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.flow_label ] } + - { name : hdr.ig_ft.mpls_ig$2.ttl, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.flow_label ] } + H4: + - { name : hdr.ig_ft.vxlan.vni, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.srv6_h2h_ifit.reserved3, hdr.ig_ft.mpls_ig$1.label, hdr.ig_ft.mpls_ig$1.exp, hdr.ig_ft.mpls_ig$1.bos, hdr.ig_ft.mpls_ig$1.ttl ] } + - { name : hdr.ig_ft.srv6_h2h_ifit.reserved3, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.vxlan.vni, hdr.ig_ft.mpls_ig$1.label, hdr.ig_ft.mpls_ig$1.exp, hdr.ig_ft.mpls_ig$1.bos, hdr.ig_ft.mpls_ig$1.ttl ] } + - { name : hdr.ig_ft.mpls_ig$1.label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.vxlan.vni, hdr.ig_ft.srv6_h2h_ifit.reserved3 ] } + - { name : hdr.ig_ft.mpls_ig$1.exp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.vxlan.vni, hdr.ig_ft.srv6_h2h_ifit.reserved3 ] } + - { name : hdr.ig_ft.mpls_ig$1.bos, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.vxlan.vni, hdr.ig_ft.srv6_h2h_ifit.reserved3 ] } + - { name : hdr.ig_ft.mpls_ig$1.ttl, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.vxlan.vni, hdr.ig_ft.srv6_h2h_ifit.reserved3 ] } + H5: + - { name : hdr.ig_ft.mpls_ig$0.label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.mpls_ig$0.exp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.mpls_ig$0.bos, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.mpls_ig$0.ttl, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H6: + - { name : ig_md.ig_ft.tunnel.inner_pkt_parsed, live_start : 3, live_end : 14, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.tunnel.is_cw, live_start : 8, live_end : 14, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.qos.BA, live_start : 4, live_end : 18, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.srv6_list$10.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.srv6_list.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.srv6_list$0.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.srv6_list$1.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.srv6_list$2.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.srv6_list$3.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.srv6_list$4.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.srv6_list$5.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.srv6_list$6.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.srv6_list$7.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.srv6_list$8.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.srv6_list$9.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } + H7: + - { name : ig_intr_md_for_dprsr.mirror_type.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_intr_md_for_tm.bypass_egress.$valid, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_intr_md_for_tm.deflect_on_drop.$valid, live_start : 19, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_intr_md_for_dprsr.mirror_io_select.$valid, live_start : 19, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_trace.$valid, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.ipv6.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.udp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.vxlan.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.inner_ethernet.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.inner_ipv4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.inner_ipv6.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.inner_vlan_tag.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.srv6_srh.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.doh_e2e.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.srv6_e2e_ifit.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.doh.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H8: + - { name : ig_md.ig_ft.srv6.prefixlen, live_start : 7, live_end : 8, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.srv6.ext_flag, live_start : 7, live_end : 16, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.flags.ipv4_checksum_err, live_start : parser, live_end : 15, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.flags.inner_ipv4_checksum_err, live_start : parser, live_end : 10, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.route.ipv6_unicast_enable, live_start : 4, live_end : 11, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.tunnel.mpls_enable, live_start : 1, live_end : 15, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.tunnel.is_ttl_copy, live_start : 1, live_end : 18, mutually_exclusive_with: [ ] } + H10: + - { name : ig_md.ig_ft.lkp.ip_src_addr, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } + H12: + - { name : ig_md.ig_ft.flags.tunnel_info, live_start : 13, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.route.vrf, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.tunnel.ipv4_true, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : $pad18, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + H13: + - { name : hdr.fabric_data_template_plus.one, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_data_template_plus.iif, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H14: + - { name : ig_md.ig_ft.common.ul_iif, live_start : 1, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : $pad15, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + H15: + - { name : ig_md.ig_ft.common.iif, live_start : 1, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : $pad14, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + H16: + - { name : ig_md.ig_ft.srv6.tmp_info, live_start : 10, live_end : 15, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.srv6.sl_minus_flag, live_start : 1, live_end : 8, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.common.eport, live_start : 1, live_end : 2, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.common.vpntovpn_flag, live_start : 14, live_end : 16, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.mirror.meter_id, live_start : 6, live_end : 6, mutually_exclusive_with: [ ] } + H17: + - { name : hdr.fabric_data_template_plus.vh3, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H18: + - { name : hdr.ext_tunnel_decap.vh, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H19: + - { name : hdr.fabric_data_template_plus.vh1, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H20: + - { name : ig_md.ig_ft.lkp.tmp_ipv4_checksum, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.common.usi, live_start : 3, live_end : 4, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.ebridge.evlan, live_start : 5, live_end : 18, mutually_exclusive_with: [ ] } + H21: + - { name : hdr.ext_ifit_encap.var_h1, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } + H22: + - { name : ig_md.ig_ft.lkp.mac_src_addr, live_start : 0, live_end : 2, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.lkp.ip_frag, live_start : 3, live_end : 8, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.ifit.index, live_start : 9, live_end : 17, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.route.ipv4_unicast_enable, live_start : 4, live_end : 6, mutually_exclusive_with: [ ] } + - { name : ul_lif_properties_check_usi_states_0, live_start : 5, live_end : 5, mutually_exclusive_with: [ ] } + - { name : hdr.ext_ifit_encap.ext_type, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ext_ifit_encap.extend, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ext_ifit_encap.index, live_start : 9, live_end : 17, mutually_exclusive_with: [ ] } + H23: + - { name : hdr.ig_ft.ethernet.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H24: + - { name : hdr.bridged_md_12_encap.decap_len, live_start : 18, live_end : deparser, mutually_exclusive_with: [ ] } + H28: + - { name : hdr.ig_ft.doh_e2e.option_type, live_start : 0, live_end : 0, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.doh_e2e.option_type, live_start : 17, live_end : 19, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.doh_e2e.option_len, live_start : 0, live_end : 0, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.doh_e2e.option_len, live_start : 17, live_end : 19, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.tunnel.decap_pre_len, live_start : 1, live_end : 16, mutually_exclusive_with: [ ] } + H29: + - { name : ig_md.ig_ft.lkp.tcp_flags, live_start : 0, live_end : 8, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.common.decap_len, live_start : 10, live_end : 17, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.policer.slice1.vag_classid, live_start : 3, live_end : 3, mutually_exclusive_with: [ ] } + H30: + - { name : ig_md.ig_ft.srv6.is_end_as, live_start : 10, live_end : 14, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.tunnel.is_pre_len_add, live_start : 14, live_end : 16, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.ipfix.random_num, live_start : 1, live_end : 9, mutually_exclusive_with: [ ] } + - { name : ig_intr_md_for_tm.qid, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } + H31: + - { name : ig_md.ig_ft.tunnel.source_id, live_start : 10, live_end : 15, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.ipfix.delta, live_start : 5, live_end : 5, mutually_exclusive_with: [ ] } + - { name : ig_intr_md_for_dprsr.mirror_io_select, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_intr_md_for_tm.deflect_on_drop, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } + H36: + - { name : hdr.ig_ft.mpls_ig$4.label, live_start : 0, live_end : 11, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.mpls_ig$4.label, live_start : 19, live_end : 19, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.qos.chgDSCP_disable, live_start : 12, live_end : 18, mutually_exclusive_with: [ ] } + H37: + - { name : ig_md.ig_ft.flags.drop, live_start : 16, live_end : 18, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.mpls_ig$3.label, live_start : 0, live_end : 15, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.mpls_ig$3.label, live_start : 19, live_end : 19, mutually_exclusive_with: [ ] } + H38: + - { name : hdr.ig_ft.mpls_ig$2.label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H39: + - { name : hdr.ig_ft.mpls_ig$1.label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H40: + - { name : hdr.ig_ft.mpls_ig$0.label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H43: + - { name : hdr.fabric_trace.trace_counter, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.srv6.end_flag, live_start : 10, live_end : 14, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.lkp.l4_port_label_32, live_start : 1, live_end : 8, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.tunnel.src_netport_group, live_start : 10, live_end : 15, mutually_exclusive_with: [ ] } + H52: + - { name : hdr.fabric_trace.timestamp, live_start : 0, live_end : 8, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_trace.timestamp, live_start : 10, live_end : 19, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.ipfix.random_flag, live_start : 9, live_end : 9, mutually_exclusive_with: [ ] } + H53: + - { name : hdr.fabric_data_template_plus.vh0, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H54: + - { name : ig_md.ig_ft.ifit.var_h1, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } + H55: + - { name : hdr.ig_ft.ethernet.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H56: + - { name : ig_md.ig_ft.common.mirror_dst_eport, live_start : 6, live_end : deparser, mutually_exclusive_with: [ ] } + H57: + - { name : ig_md.ig_ft.srv6.lif_type, live_start : 10, live_end : 14, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.lkp.l4_port_label_32, live_start : 1, live_end : 8, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.common.trace_vh3, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.tunnel.evpn_end_type, live_start : 10, live_end : 15, mutually_exclusive_with: [ ] } + H64: + - { name : ig_md.ig_ft.lkp.mac_dst_addr, live_start : parser, live_end : 15, mutually_exclusive_with: [ ] } + H65: + - { name : ig_intr_md.ingress_port, live_start : 0, live_end : 8, mutually_exclusive_with: [ ] } + - { name : ig_intr_md.ingress_port, live_start : 14, live_end : 15, mutually_exclusive_with: [ ] } + - { name : cpu_egress_port_mapping_fabric_lag_flag, live_start : 9, live_end : 10, mutually_exclusive_with: [ ] } + H66: + - { name : ig_md.ig_ft.lkp.l4_src_port, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } + H67: + - { name : ig_md.ig_ft.lkp.vid, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } + H69: + - { name : hdr.fabric_qos.tc, live_start : parser, live_end : 6, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_qos.color, live_start : parser, live_end : 6, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_qos.track, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.ifit.dyna_learn_flag, live_start : 10, live_end : 15, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.ifit.ifit_decap_enable, live_start : 10, live_end : 15, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.policer.slice1.vag_classid, live_start : 3, live_end : 3, mutually_exclusive_with: [ ] } + H70: + - { name : ig_md.ig_ft.common.track, live_start : 1, live_end : 18, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.ipfix.flow_id, live_start : 3, live_end : 9, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.qos.meter_mode, live_start : 5, live_end : 9, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.qos.acl_meter_index, live_start : 5, live_end : 10, mutually_exclusive_with: [ ] } + H71: + - { name : ig_md.ig_ft.common.mac_type, live_start : 1, live_end : 16, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.qos.lif_ds, live_start : 4, live_end : 5, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.qos.color, live_start : 4, live_end : 18, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.qos.tc, live_start : 4, live_end : 18, mutually_exclusive_with: [ ] } + W0: + - { name : ig_md.ig_ft.srv6.c_sid, live_start : 8, live_end : 8, mutually_exclusive_with: [ ig_md.ig_ft.tunnel.is_ttl_copy_1, ig_md.ig_ft.tunnel.is_ttl_copy_2, ig_md.ig_ft.tunnel.is_ttl_copy_3 ] } + - { name : ig_md.ig_ft.tunnel.is_ttl_copy_1, live_start : 6, live_end : 8, mutually_exclusive_with: [ ig_md.ig_ft.srv6.c_sid ] } + - { name : ig_md.ig_ft.tunnel.is_ttl_copy_2, live_start : 7, live_end : 8, mutually_exclusive_with: [ ig_md.ig_ft.srv6.c_sid ] } + - { name : ig_md.ig_ft.tunnel.is_ttl_copy_3, live_start : 8, live_end : 8, mutually_exclusive_with: [ ig_md.ig_ft.srv6.c_sid ] } + W1: + - { name : ig_md.ig_ft.lkp.ip_src_addr, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } + W2: + - { name : ig_md.ig_ft.lkp.ip_src_addr, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } + W3: + - { name : ig_md.ig_ft.lkp.ip_src_addr, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } + W4: + - { name : ig_md.ig_ft.lkp.ip_dst_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + W5: + - { name : ig_md.ig_ft.srv6.args, live_start : 11, live_end : 12, mutually_exclusive_with: [ ] } + W6: + - { name : ig_md.ig_ft.srv6.si, live_start : 7, live_end : 9, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.tunnel.sub_type, live_start : 3, live_end : 15, mutually_exclusive_with: [ ] } + - { name : ig_intr_md_for_dprsr.drop_ctl, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.policer.behavior_id, live_start : 5, live_end : 11, mutually_exclusive_with: [ ] } + W7: + - { name : hdr.ext_srv6.priority, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ext_srv6.nexthop, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ext_srv6.no_frr, live_start : 14, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ext_srv6.nexthop_ext, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ext_srv6.is_pf, live_start : 10, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ext_srv6.is_endx_pf, live_start : 10, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ext_srv6.oam_flag, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } + W10: + - { name : hdr.ig_ft.vlan_tag$0.pcp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.vlan_tag$0.cfi, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.vlan_tag$0.vid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.vlan_tag$0.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W11: + - { name : hdr.ig_ft.vlan_tag$1.pcp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.vlan_tag$1.cfi, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.vlan_tag$1.vid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ig_ft.vlan_tag$1.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W13: + - { name : ig_md.ig_ft.lkp.ip_dst_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + W14: + - { name : ig_md.ig_ft.srv6.args, live_start : 11, live_end : 12, mutually_exclusive_with: [ ] } + W15: + - { name : ig_md.ig_ft.lkp.ip_dst_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + W16: + - { name : ig_md.ig_ft.lkp.mac_dst_addr, live_start : parser, live_end : 15, mutually_exclusive_with: [ ] } + W17: + - { name : ig_md.ig_ft.lkp.mac_src_addr, live_start : parser, live_end : 2, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.common.tstamp_flag, live_start : 6, live_end : 18, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.tunnel.bypass_pw, live_start : 6, live_end : 15, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.ipfix.count, live_start : 6, live_end : 9, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.mirror.sample_flag, live_start : 9, live_end : 18, mutually_exclusive_with: [ ] } + W24: + - { name : ig_md.ig_ft.lkp.ip_dst_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + W28: + - { name : ig_md.ig_ft.srv6.global_pf_mode, live_start : 6, live_end : 8, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.lkp.flow_label, live_start : 0, live_end : 3, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.tunnel.is_vpn_terminate, live_start : 5, live_end : 15, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.tunnel.srv6_flavors, live_start : 5, live_end : 8, mutually_exclusive_with: [ ] } + W30: + - { name : ig_md.ig_ft.srv6.end_type, live_start : 5, live_end : 14, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.lkp.mac_src_addr, live_start : parser, live_end : 2, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.policer.slice2.vag_classid, live_start : 3, live_end : 8, mutually_exclusive_with: [ ] } + W31: + - { name : ig_md.ig_ft.lkp.l4_dst_port, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.policer.slice3.vag_classid, live_start : 3, live_end : 4, mutually_exclusive_with: [ ] } + W37: + - { name : ig_md.ig_ft.common.iif_type, live_start : 1, live_end : 18, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.qos.lif_meter_index, live_start : 4, live_end : 13, mutually_exclusive_with: [ ] } + W38: + - { name : ig_md.ig_ft.ifit.ifit_enable, live_start : 10, live_end : 15, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.common.hash_mode, live_start : 1, live_end : 4, mutually_exclusive_with: [ ] } + - { name : ig_md.ig_ft.tunnel.urpf_type, live_start : 2, live_end : 15, mutually_exclusive_with: [ ] } +phv egress: + eg_intr_md_from_prsr.global_tstamp.0-31: { stage 0..17: MW12 } + eg_intr_md_from_prsr.global_tstamp.32-47: { stage 0..17: H42 } + eg_intr_md_for_dprsr.drop_ctl: { stage 15..20: B16(1..3) } + eg_intr_md_for_dprsr.mirror_type: { stage 16..20: B4(0..3) } + eg_intr_md_for_dprsr.mirror_io_select: MH18(0) + eg_intr_md_for_dprsr.mtu_trunc_len: { stage 17..20: MH17(0..13) } + eg_intr_md_for_dprsr.mirror_io_select.$valid: H9(0) + eg_intr_md.egress_port: MH16(0..8) + eg_intr_md.deflection_flag: { stage 0..17: W36(24) } + eg_intr_md.egress_port.$valid: H9(1) + eg_md.eg_ft.common.mac_type: { stage 16..17: B2(2..3) } + eg_md.eg_ft.common.pkt_length: { stage 0..16: H25 } + eg_md.eg_ft.common.pkt_type: B25(2..7) + eg_md.eg_ft.common.cpu_eth_encap_id: { stage 0..16: B42 } + eg_md.eg_ft.common.decap_len: { stage 0: MH8 } + eg_md.eg_ft.common.dst_port: B20 + eg_md.eg_ft.common.backpush_dst_port: B21 + eg_md.eg_ft.common.mirror_dst_eport: { stage 11..20: H51 } + eg_md.eg_ft.common.hash: { stage 0..13: H61, stage 14..17: DH21, stage 18: H61 } + eg_md.eg_ft.common.iif: H49(0..14) + eg_md.eg_ft.common.oif: H50(0..14) + eg_md.eg_ft.common.from_cpu: { stage 0..17: W34(6) } + eg_md.eg_ft.common.diag: { stage 0..16: W34(5) } + eg_md.eg_ft.common.is_mirror: B25(1) + eg_md.eg_ft.common.is_mcast: B25(0) + eg_md.eg_ft.common.track: B24(0) + eg_md.eg_ft.common.deq_timedelta: MW4 + eg_md.eg_ft.common.ether_type: { stage 0..14: MH15 } + eg_md.eg_ft.common.drop_reason: { stage 15..20: MB11 } + eg_md.eg_ft.common.pipeline_location: { stage 18..20: B26 } + eg_md.eg_ft.common.trace_counter: { stage 17..20: H62 } + eg_md.eg_ft.common.cpu_color: { stage 15..16: B3(2..3) } + eg_md.eg_ft.common.ve_map_miss: { stage 5..14: H41(13) } + eg_md.eg_ft.common.timestamp_delta: { stage 1: W12 } + eg_md.eg_ft.qos.acl_meter_color: { stage 3..14: B3(0..1) } + eg_md.eg_ft.qos.set_dscp: { stage 13: W19(0) } + eg_md.eg_ft.qos.dscp: { stage 1..13: H35(0..5) } + eg_md.eg_ft.qos.qdepth: { stage 0..5: W29(0..18) } + eg_md.eg_ft.qos.tc: B24(5..7) + eg_md.eg_ft.qos.color: B24(3..4) + eg_md.eg_ft.qos.q_hi_flag: { stage 1..13: W33(0) } + eg_md.eg_ft.qos.q_lo_flag: { stage 6..13: B3(6) } + eg_md.eg_ft.qos.etm_flag: { stage 4..13: B3(4) } + eg_md.eg_ft.flags.bypass_acl: { stage 1..13: B43(0) } + eg_md.eg_ft.flags.bypass_sec_acl: { stage 0..13: W34(0) } + eg_md.eg_ft.flags.drop: { stage 0..17: W34(4) } + eg_md.eg_ft.lkp.vid: { stage 4..15: H41(0..11) } + eg_md.eg_ft.lkp.ip_src_addr.0-15: { stage 0..13: H63 } + eg_md.eg_ft.lkp.ip_src_addr.16-31: { stage 0..13: H58 } + eg_md.eg_ft.lkp.ip_src_addr.32-63: { stage 0..12: W18 } + eg_md.eg_ft.lkp.ip_src_addr.64-95: { stage 0..12: W19 } + eg_md.eg_ft.lkp.ip_src_addr.96-127: { stage 0..13: W20 } + eg_md.eg_ft.lkp.ip_dst_addr.0-31: { stage 0..13: W21 } + eg_md.eg_ft.lkp.ip_dst_addr.32-63: { stage 0..13: W22 } + eg_md.eg_ft.lkp.ip_dst_addr.64-95: { stage 0..13: W23 } + eg_md.eg_ft.lkp.ip_dst_addr.96-127: { stage 0..13: W25 } + eg_md.eg_ft.lkp.ip_proto: { stage 0..13: MB3 } + eg_md.eg_ft.lkp.l4_src_port: { stage 0..13: H59 } + eg_md.eg_ft.lkp.l4_dst_port: { stage 0..13: W32(0..15) } + eg_md.eg_ft.lkp.l4_port_label_64.0-31: { stage 0..13: W26 } + eg_md.eg_ft.lkp.l4_port_label_64.32-63: { stage 0..13: W27 } + eg_md.eg_ft.lkp.tcp_flags: { stage 0..13: W35(0..7) } + eg_md.eg_ft.lkp.ip_frag: { stage 0..13: W34(2..3) } + eg_md.eg_ft.lkp.tmp_ipv4_checksum: MH7 + eg_md.eg_ft.ebridge.evlan: { stage 0: W33(0..13), stage 1..15: DW9(0..13), stage 16: W33(0..13) } + eg_md.eg_ft.ebridge.encap_vlan_action: { stage 4..15: W40(8..11) } + eg_md.eg_ft.ifit.dyna_learn_flag: { stage 1..14: B2(1) } + eg_md.eg_ft.ifit.ifit_decap_enable: { stage 0..14: B43(4) } + eg_md.eg_ft.ifit.loss_label: { stage 0..14: B43(3) } + eg_md.eg_ft.ifit.delay_stats_flag: { stage 0..14: B43(2) } + eg_md.eg_ft.ifit.index: { stage 0..14: H68(0..11) } + eg_md.eg_ft.ifit.var_h1: { stage 14..20: H63 } + eg_md.eg_ft.ifit.counter_index.0-7: { stage 1..15: W39(0..7) } + eg_md.eg_ft.ifit.counter_index.8-12: { stage 1..15: B17(2..6) } + hdr.eg_ft.ethernet.dst_addr.0-31: W9 + hdr.eg_ft.ethernet.dst_addr.32-47: H48 + hdr.eg_ft.ethernet.src_addr.0-15: H32 + hdr.eg_ft.ethernet.src_addr.16-31: H33 + hdr.eg_ft.ethernet.src_addr.32-47: H60 + hdr.eg_ft.ethernet.ether_type: MH1 + hdr.eg_ft.ipv4.version: H34(12..15) + hdr.eg_ft.ipv4.ihl: H34(8..11) + hdr.eg_ft.ipv4.diffserv: H34(0..7) + hdr.eg_ft.ipv4.hdr_checksum: MH2 + hdr.eg_ft.ipv6.version: H34(12..15) + hdr.eg_ft.ipv6.traffic_class: H34(4..11) + hdr.eg_ft.ipv6.flow_label.0-15: { stage 0: H35, stage 1..13: DH9, stage 14..18: H35 } + hdr.eg_ft.ipv6.flow_label.16-19: H34(0..3) + hdr.eg_ft.vlan_tag$0.pcp: H45(13..15) + hdr.eg_ft.vlan_tag$0.cfi: H45(12) + hdr.eg_ft.vlan_tag$0.vid: H45(0..11) + hdr.eg_ft.vlan_tag$0.ether_type: MH22 + hdr.eg_ft.vlan_tag$1.pcp: H44(13..15) + hdr.eg_ft.vlan_tag$1.cfi: H44(12) + hdr.eg_ft.vlan_tag$1.vid: H44(0..11) + hdr.eg_ft.vlan_tag$1.ether_type: MH21 + hdr.fabric_base.pkt_type: B23(2..7) + hdr.fabric_base.is_mirror: B23(1) + hdr.fabric_base.is_mcast: B23(0) + hdr.fabric_qos.tc: B22(5..7) + hdr.fabric_qos.color: B22(3..4) + hdr.fabric_qos.chgDSCP_disable: B22(2) + hdr.fabric_qos.BA: B22(1) + hdr.fabric_qos.track: B22(0) + hdr.fabric_data_template_plus.vh1: MH20 + hdr.fabric_data_template_plus.vh3.0-7: { stage 0: B33, stage 1..12: DB11, stage 13..18: B33 } + hdr.fabric_data_template_plus.one: H11(15) + hdr.fabric_data_template_plus.iif: H11(0..14) + hdr.ext_tunnel_decap.vb: { stage 0: B32, stage 1..12: DB10, stage 13..18: B32 } + hdr.ext_tunnel_decap.vh: MH19 + hdr.eg_ft.br_tag.epcp: H47(13..15) + hdr.eg_ft.br_tag.edei: H47(12) + hdr.eg_ft.br_tag.ingress_ecid: H47(0..11) + hdr.eg_ft.br_tag.reserved: W8(30..31) + hdr.eg_ft.br_tag.grp: W8(28..29) + hdr.eg_ft.br_tag.ecid: W8(16..27) + hdr.eg_ft.br_tag.ingress_ecid_ext: W8(8..15) + hdr.eg_ft.br_tag.ecid_ext: W8(0..7) + hdr.eg_ft.br_tag.ether_type: MH2 + hdr.eg_ft.ethernet_evpn.ether_type: MH23 + eg_md.eg_ft.policer.slice1.vag_classid: { stage 1..13: W34(7..22) } + eg_md.eg_ft.policer.slice2.vag_classid: { stage 1..9: W35(8..23) } + eg_md.eg_ft.policer.slice3.vag_classid: { stage 1..2: W32(16..31) } + eg_md.eg_ft.mirror.session_id: { stage 1..20: MB9 } + eg_md.eg_ft.mirror.meter_id: { stage 11: W39(8..17) } + eg_md.eg_ft.mirror.sample_flag: { stage 3..17: B17(1) } + eg_md.eg_ft.mirror.span_flag: { stage 11..17: B2(0) } + eg_md.eg_ft.mirror.backpush_flag: { stage 14..15: W18(0..2) } + eg_md.eg_ft.mirror.flags: { stage 16..20: B27 } + eg_md.eg_ft.mirror.src: { stage 16..20: B19(5..7) } + eg_md.eg_ft.mirror.type: { stage 16..20: B19(0..4) } + eg_md.eg_ft.mirror.ifit_flag: { stage 14..17: H61(0) } + eg_md.eg_ft.ipfix.flow_id: { stage 3..12: W39(18..25) } + eg_md.eg_ft.ipfix.sample_gap: { stage 3..10: MH10 } + eg_md.eg_ft.ipfix.random_num: { stage 1..12: H26 } + eg_md.eg_ft.ipfix.count.0-7: { stage 1..12: B32 } + eg_md.eg_ft.ipfix.count.8-15: { stage 1..12: B33 } + eg_md.eg_ft.ipfix.delta: { stage 11: H27 } + eg_md.eg_ft.ipfix.random_flag: { stage 12: B7(6) } + eg_intr_md_for_dprsr.mirror_type.$valid: { stage 16..20: H9(2) } + eg_md.eg_ft.policer.mac_drop: { stage 3..14: H41(12) } + eg_md.eg_ft.policer.behavior_id.0-7: { stage 3..12: W40(0..7) } + eg_md.eg_ft.policer.behavior_id.8-11: { stage 3..12: B16(4..7) } + trace_latency_latency_track: { stage 1: B3(5) } + hdr.fabric_eth_etype.ether_type: { stage 15..20: MH3 } + hdr.fabric_timestamp.timestamp.0-31: { stage 15..20: MW13 } + hdr.fabric_timestamp.timestamp.32-47: { stage 15..20: H46 } + eg_md.eg_ft.tunnel.ptag_igmod: { stage 1..15: B7(7) } + eg_intr_md_for_dprsr.drop_ctl.$valid: { stage 15..20: B16(0) } + eg_intr_md_for_dprsr.mtu_trunc_len.$valid: { stage 17..20: B7(4) } + $pad20: { stage 20: H50(15) } + $pad21: { stage 20: H49(15) } + $pad22: { stage 20: B24(1..2) } + hdr.ext_ifit.$valid: { stage 0: H9(3) } + hdr.eg_ft.ethernet.$valid: H9(4) + hdr.eg_ft.ipv4.$valid: H9(5) + hdr.pad.$valid: B7(5) + hdr.eg_ft.ipv6.$valid: H9(6) + hdr.eg_ft.ipv6_frag.$valid: H9(7) + hdr.eg_ft.mpls_vc_eg.$valid: H9(8) + hdr.fabric_base.$valid: H9(9) + hdr.fabric_qos.$valid: H9(10) + hdr.fabric_data_template_plus.$valid: H9(11) + hdr.ext_tunnel_decap.$valid: H9(12) + hdr.eg_ft.br_tag.$valid: B17(0) + hdr.eg_ft.ethernet_evpn.$valid: H9(13) + hdr.fabric_eth_etype.$valid: { stage 15..20: H9(14) } + hdr.fabric_timestamp.$valid: { stage 15..20: H9(15) } + hdr.eg_ft.vlan_tag.$stkvalid: B7(0..3) + hdr.eg_ft.vlan_tag$0.$valid: { stage 2..20: B7(2) } + hdr.eg_ft.vlan_tag$1.$valid: B7(1) + Eg_front.backpush_mirror.hi_check_reg$ena: { stage 20..0: H41(14) } + Eg_front.backpush_mirror.hi_check_reg$index: { stage 20..0: W40(12..21) } + context_json: + DB10: + - { name : hdr.ext_tunnel_decap.vb, live_start : 1, live_end : 12, mutually_exclusive_with: [ ] } + DB11: + - { name : hdr.fabric_data_template_plus.vh3, live_start : 1, live_end : 12, mutually_exclusive_with: [ ] } + DH9: + - { name : hdr.eg_ft.ipv6.flow_label, live_start : 1, live_end : 13, mutually_exclusive_with: [ ] } + DH21: + - { name : eg_md.eg_ft.common.hash, live_start : 14, live_end : 17, mutually_exclusive_with: [ ] } + DW9: + - { name : eg_md.eg_ft.ebridge.evlan, live_start : 1, live_end : 15, mutually_exclusive_with: [ ] } + MB3: + - { name : eg_md.eg_ft.lkp.ip_proto, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + MB9: + - { name : eg_md.eg_ft.mirror.session_id, live_start : 1, live_end : deparser, mutually_exclusive_with: [ ] } + MB11: + - { name : eg_md.eg_ft.common.drop_reason, live_start : 15, live_end : deparser, mutually_exclusive_with: [ ] } + MH1: + - { name : hdr.eg_ft.ethernet.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + MH2: + - { name : hdr.eg_ft.ipv4.hdr_checksum, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.eg_ft.br_tag.ether_type ] } + - { name : hdr.eg_ft.br_tag.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.eg_ft.ipv4.hdr_checksum ] } + MH3: + - { name : hdr.fabric_eth_etype.ether_type, live_start : 15, live_end : deparser, mutually_exclusive_with: [ ] } + MH7: + - { name : eg_md.eg_ft.lkp.tmp_ipv4_checksum, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + MH8: + - { name : eg_md.eg_ft.common.decap_len, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } + MH10: + - { name : eg_md.eg_ft.ipfix.sample_gap, live_start : 3, live_end : 10, mutually_exclusive_with: [ ] } + MH15: + - { name : eg_md.eg_ft.common.ether_type, live_start : parser, live_end : 14, mutually_exclusive_with: [ ] } + MH16: + - { name : eg_intr_md.egress_port, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + MH17: + - { name : eg_intr_md_for_dprsr.mtu_trunc_len, live_start : 17, live_end : deparser, mutually_exclusive_with: [ ] } + MH18: + - { name : eg_intr_md_for_dprsr.mirror_io_select, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + MH19: + - { name : hdr.ext_tunnel_decap.vh, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + MH20: + - { name : hdr.fabric_data_template_plus.vh1, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + MH21: + - { name : hdr.eg_ft.vlan_tag$1.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + MH22: + - { name : hdr.eg_ft.vlan_tag$0.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + MH23: + - { name : hdr.eg_ft.ethernet_evpn.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + MW4: + - { name : eg_md.eg_ft.common.deq_timedelta, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + MW12: + - { name : eg_intr_md_from_prsr.global_tstamp, live_start : parser, live_end : 17, mutually_exclusive_with: [ ] } + MW13: + - { name : hdr.fabric_timestamp.timestamp, live_start : 15, live_end : deparser, mutually_exclusive_with: [ ] } + B2: + - { name : eg_md.eg_ft.common.mac_type, live_start : 16, live_end : 17, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.ifit.dyna_learn_flag, live_start : 1, live_end : 14, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.mirror.span_flag, live_start : 11, live_end : 17, mutually_exclusive_with: [ ] } + B3: + - { name : eg_md.eg_ft.common.cpu_color, live_start : 15, live_end : 16, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.qos.acl_meter_color, live_start : 3, live_end : 14, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.qos.q_lo_flag, live_start : 6, live_end : 13, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.qos.etm_flag, live_start : 4, live_end : 13, mutually_exclusive_with: [ ] } + - { name : trace_latency_latency_track, live_start : 1, live_end : 1, mutually_exclusive_with: [ ] } + B4: + - { name : eg_intr_md_for_dprsr.mirror_type, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } + B7: + - { name : eg_md.eg_ft.ipfix.random_flag, live_start : 12, live_end : 12, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.tunnel.ptag_igmod, live_start : 1, live_end : 15, mutually_exclusive_with: [ ] } + - { name : eg_intr_md_for_dprsr.mtu_trunc_len.$valid, live_start : 17, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.pad.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.vlan_tag$1.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.vlan_tag.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.vlan_tag$0.$valid, live_start : 2, live_end : deparser, mutually_exclusive_with: [ ] } + B16: + - { name : eg_intr_md_for_dprsr.drop_ctl, live_start : 15, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.policer.behavior_id, live_start : 3, live_end : 12, mutually_exclusive_with: [ ] } + - { name : eg_intr_md_for_dprsr.drop_ctl.$valid, live_start : 15, live_end : deparser, mutually_exclusive_with: [ ] } + B17: + - { name : eg_md.eg_ft.ifit.counter_index, live_start : 1, live_end : 15, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.mirror.sample_flag, live_start : 3, live_end : 17, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.br_tag.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B19: + - { name : eg_md.eg_ft.mirror.src, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.mirror.type, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } + B20: + - { name : eg_md.eg_ft.common.dst_port, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B21: + - { name : eg_md.eg_ft.common.backpush_dst_port, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B22: + - { name : hdr.fabric_qos.tc, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_qos.color, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_qos.chgDSCP_disable, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_qos.BA, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_qos.track, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B23: + - { name : hdr.fabric_base.pkt_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_base.is_mirror, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_base.is_mcast, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B24: + - { name : eg_md.eg_ft.common.track, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.qos.tc, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.qos.color, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : $pad22, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + B25: + - { name : eg_md.eg_ft.common.pkt_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.common.is_mirror, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.common.is_mcast, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + B26: + - { name : eg_md.eg_ft.common.pipeline_location, live_start : 18, live_end : deparser, mutually_exclusive_with: [ ] } + B27: + - { name : eg_md.eg_ft.mirror.flags, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } + B32: + - { name : hdr.ext_tunnel_decap.vb, live_start : 0, live_end : 0, mutually_exclusive_with: [ ] } + - { name : hdr.ext_tunnel_decap.vb, live_start : 13, live_end : 18, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.ipfix.count, live_start : 1, live_end : 12, mutually_exclusive_with: [ ] } + B33: + - { name : hdr.fabric_data_template_plus.vh3, live_start : 0, live_end : 0, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_data_template_plus.vh3, live_start : 13, live_end : 18, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.ipfix.count, live_start : 1, live_end : 12, mutually_exclusive_with: [ ] } + B42: + - { name : eg_md.eg_ft.common.cpu_eth_encap_id, live_start : parser, live_end : 16, mutually_exclusive_with: [ ] } + B43: + - { name : eg_md.eg_ft.flags.bypass_acl, live_start : 1, live_end : 13, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.ifit.ifit_decap_enable, live_start : parser, live_end : 14, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.ifit.loss_label, live_start : parser, live_end : 14, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.ifit.delay_stats_flag, live_start : parser, live_end : 14, mutually_exclusive_with: [ ] } + H9: + - { name : eg_intr_md_for_dprsr.mirror_io_select.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : eg_intr_md.egress_port.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : eg_intr_md_for_dprsr.mirror_type.$valid, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ext_ifit.$valid, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.ethernet.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.ipv4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.ipv6.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.ipv6_frag.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.mpls_vc_eg.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_base.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_qos.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_data_template_plus.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.ext_tunnel_decap.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.ethernet_evpn.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_eth_etype.$valid, live_start : 15, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_timestamp.$valid, live_start : 15, live_end : deparser, mutually_exclusive_with: [ ] } + H11: + - { name : hdr.fabric_data_template_plus.one, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.fabric_data_template_plus.iif, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H25: + - { name : eg_md.eg_ft.common.pkt_length, live_start : parser, live_end : 16, mutually_exclusive_with: [ ] } + H26: + - { name : eg_md.eg_ft.ipfix.random_num, live_start : 1, live_end : 12, mutually_exclusive_with: [ ] } + H27: + - { name : eg_md.eg_ft.ipfix.delta, live_start : 11, live_end : 11, mutually_exclusive_with: [ ] } + H32: + - { name : hdr.eg_ft.ethernet.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H33: + - { name : hdr.eg_ft.ethernet.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H34: + - { name : hdr.eg_ft.ipv4.version, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.eg_ft.ipv6.version, hdr.eg_ft.ipv6.traffic_class, hdr.eg_ft.ipv6.flow_label ] } + - { name : hdr.eg_ft.ipv4.ihl, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.eg_ft.ipv6.version, hdr.eg_ft.ipv6.traffic_class, hdr.eg_ft.ipv6.flow_label ] } + - { name : hdr.eg_ft.ipv4.diffserv, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.eg_ft.ipv6.version, hdr.eg_ft.ipv6.traffic_class, hdr.eg_ft.ipv6.flow_label ] } + - { name : hdr.eg_ft.ipv6.version, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.eg_ft.ipv4.version, hdr.eg_ft.ipv4.ihl, hdr.eg_ft.ipv4.diffserv ] } + - { name : hdr.eg_ft.ipv6.traffic_class, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.eg_ft.ipv4.version, hdr.eg_ft.ipv4.ihl, hdr.eg_ft.ipv4.diffserv ] } + - { name : hdr.eg_ft.ipv6.flow_label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.eg_ft.ipv4.version, hdr.eg_ft.ipv4.ihl, hdr.eg_ft.ipv4.diffserv ] } + H35: + - { name : eg_md.eg_ft.qos.dscp, live_start : 1, live_end : 13, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.ipv6.flow_label, live_start : 0, live_end : 0, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.ipv6.flow_label, live_start : 14, live_end : 18, mutually_exclusive_with: [ ] } + H41: + - { name : eg_md.eg_ft.common.ve_map_miss, live_start : 5, live_end : 14, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.lkp.vid, live_start : 4, live_end : 15, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.policer.mac_drop, live_start : 3, live_end : 14, mutually_exclusive_with: [ ] } + - { name : Eg_front.backpush_mirror.hi_check_reg$ena, live_start : deparser, live_end : parser, mutually_exclusive_with: [ ] } + H42: + - { name : eg_intr_md_from_prsr.global_tstamp, live_start : parser, live_end : 17, mutually_exclusive_with: [ ] } + H44: + - { name : hdr.eg_ft.vlan_tag$1.pcp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.vlan_tag$1.cfi, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.vlan_tag$1.vid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H45: + - { name : hdr.eg_ft.vlan_tag$0.pcp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.vlan_tag$0.cfi, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.vlan_tag$0.vid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H46: + - { name : hdr.fabric_timestamp.timestamp, live_start : 15, live_end : deparser, mutually_exclusive_with: [ ] } + H47: + - { name : hdr.eg_ft.br_tag.epcp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.br_tag.edei, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.br_tag.ingress_ecid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H48: + - { name : hdr.eg_ft.ethernet.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H49: + - { name : eg_md.eg_ft.common.iif, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : $pad21, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + H50: + - { name : eg_md.eg_ft.common.oif, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : $pad20, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } + H51: + - { name : eg_md.eg_ft.common.mirror_dst_eport, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } + H58: + - { name : eg_md.eg_ft.lkp.ip_src_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + H59: + - { name : eg_md.eg_ft.lkp.l4_src_port, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + H60: + - { name : hdr.eg_ft.ethernet.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + H61: + - { name : eg_md.eg_ft.common.hash, live_start : 0, live_end : 13, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.common.hash, live_start : 18, live_end : 18, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.mirror.ifit_flag, live_start : 14, live_end : 17, mutually_exclusive_with: [ ] } + H62: + - { name : eg_md.eg_ft.common.trace_counter, live_start : 17, live_end : deparser, mutually_exclusive_with: [ ] } + H63: + - { name : eg_md.eg_ft.lkp.ip_src_addr, live_start : 0, live_end : 13, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.ifit.var_h1, live_start : 14, live_end : deparser, mutually_exclusive_with: [ ] } + H68: + - { name : eg_md.eg_ft.ifit.index, live_start : parser, live_end : 14, mutually_exclusive_with: [ ] } + W8: + - { name : hdr.eg_ft.br_tag.reserved, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.br_tag.grp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.br_tag.ecid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.br_tag.ingress_ecid_ext, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + - { name : hdr.eg_ft.br_tag.ecid_ext, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W9: + - { name : hdr.eg_ft.ethernet.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } + W12: + - { name : eg_md.eg_ft.common.timestamp_delta, live_start : 1, live_end : 1, mutually_exclusive_with: [ ] } + W18: + - { name : eg_md.eg_ft.lkp.ip_src_addr, live_start : 0, live_end : 12, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.mirror.backpush_flag, live_start : 14, live_end : 15, mutually_exclusive_with: [ ] } + W19: + - { name : eg_md.eg_ft.qos.set_dscp, live_start : 13, live_end : 13, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.lkp.ip_src_addr, live_start : 0, live_end : 12, mutually_exclusive_with: [ ] } + W20: + - { name : eg_md.eg_ft.lkp.ip_src_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + W21: + - { name : eg_md.eg_ft.lkp.ip_dst_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + W22: + - { name : eg_md.eg_ft.lkp.ip_dst_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + W23: + - { name : eg_md.eg_ft.lkp.ip_dst_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + W25: + - { name : eg_md.eg_ft.lkp.ip_dst_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + W26: + - { name : eg_md.eg_ft.lkp.l4_port_label_64, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + W27: + - { name : eg_md.eg_ft.lkp.l4_port_label_64, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + W29: + - { name : eg_md.eg_ft.qos.qdepth, live_start : parser, live_end : 5, mutually_exclusive_with: [ ] } + W32: + - { name : eg_md.eg_ft.lkp.l4_dst_port, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.policer.slice3.vag_classid, live_start : 1, live_end : 2, mutually_exclusive_with: [ ] } + W33: + - { name : eg_md.eg_ft.qos.q_hi_flag, live_start : 1, live_end : 13, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.ebridge.evlan, live_start : 0, live_end : 0, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.ebridge.evlan, live_start : 16, live_end : 16, mutually_exclusive_with: [ ] } + W34: + - { name : eg_md.eg_ft.common.from_cpu, live_start : parser, live_end : 17, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.common.diag, live_start : parser, live_end : 16, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.flags.bypass_sec_acl, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.flags.drop, live_start : parser, live_end : 17, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.lkp.ip_frag, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.policer.slice1.vag_classid, live_start : 1, live_end : 13, mutually_exclusive_with: [ ] } + W35: + - { name : eg_md.eg_ft.lkp.tcp_flags, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.policer.slice2.vag_classid, live_start : 1, live_end : 9, mutually_exclusive_with: [ ] } + W36: + - { name : eg_intr_md.deflection_flag, live_start : parser, live_end : 17, mutually_exclusive_with: [ ] } + W39: + - { name : eg_md.eg_ft.ifit.counter_index, live_start : 1, live_end : 15, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.mirror.meter_id, live_start : 11, live_end : 11, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.ipfix.flow_id, live_start : 3, live_end : 12, mutually_exclusive_with: [ ] } + W40: + - { name : eg_md.eg_ft.ebridge.encap_vlan_action, live_start : 4, live_end : 15, mutually_exclusive_with: [ ] } + - { name : eg_md.eg_ft.policer.behavior_id, live_start : 3, live_end : 12, mutually_exclusive_with: [ ] } + - { name : Eg_front.backpush_mirror.hi_check_reg$index, live_start : deparser, live_end : parser, mutually_exclusive_with: [ ] } +parser ingress: + start: $entry_point + bitwise_or: [ MB4, MB5, B8, B9, B10, B12, B13, B14, B15, B36, B37, B38, B39, B40, B41, B46, B47, H6, H7 ] + clear_on_write: [ MB0, MB8, MB10, MB12, MB14, MH11, MH13, MH14, MW5, MW10, B18, H10, W1, W2, W3, W4, W13, W15, W24 ] + hdr_len_adj: 32 + states: + $entry_point: + *: + H7: 1 # value 1 -> H7 bit[0]: ingress::ig_intr_md_for_dprsr.mirror_type.$valid + load: { byte0 : 8 } + buf_req: 9 + next: start + start: + match: [ byte0 ] + 0x*a: + 0..1: H65 # bit[7..15] -> H65 bit[8..0]: ingress::ig_intr_md.ingress_port + 2..3: H52 # ingress::hdr.fabric_trace.timestamp[47:32].32-47 + 4..7: MW11 # ingress::hdr.fabric_trace.timestamp[31:0].0-31 + 9: MB8 # bit[79] -> MB8 bit[0]: ingress::ig_md.ig_ft.srv6.pf_downgrade + shift: 32 + buf_req: 32 + next: parse_signal + 0x*7: + 0..1: H65 # bit[7..15] -> H65 bit[8..0]: ingress::ig_intr_md.ingress_port + 2..3: H52 # ingress::hdr.fabric_trace.timestamp[47:32].32-47 + 4..7: MW11 # ingress::hdr.fabric_trace.timestamp[31:0].0-31 + 9: MB8 # bit[79] -> MB8 bit[0]: ingress::ig_md.ig_ft.srv6.pf_downgrade + load: { byte1 : 9 } + shift: 32 + buf_req: 32 + next: start.$oob_stall_0 + 0x**: + 0..1: H65 # bit[7..15] -> H65 bit[8..0]: ingress::ig_intr_md.ingress_port + 2..3: H52 # ingress::hdr.fabric_trace.timestamp[47:32].32-47 + 4..7: MW11 # ingress::hdr.fabric_trace.timestamp[31:0].0-31 + 9: MB8 # bit[79] -> MB8 bit[0]: ingress::ig_md.ig_ft.srv6.pf_downgrade + load: { byte1 : 9 } + shift: 32 + buf_req: 32 + next: start.$oob_stall_1 + parse_signal: + *: + priority: 7 + 0: B37 + # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type + # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror + # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast + 0..1: H69 + # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc + # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color + # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track + 2: B15 # ingress::hdr.fabric_data_template_plus.flags + 3: B36 # ingress::hdr.fabric_data_template_plus.vb + 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 + 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 + 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 + 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 + 12..13: H13 + # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one + # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif + B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid + B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid + shift: 14 + buf_req: 14 + next: end + start.$oob_stall_0: + *: + load: { byte0 : 0 } + buf_req: 1 + next: parse_fabric_recirc + parse_fabric_recirc: + match: [ byte0 ] + 0b011100**: + 0: B37 + # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type + # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror + # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast + 0..1: H69 + # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc + # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color + # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track + 2: B15 # ingress::hdr.fabric_data_template_plus.flags + 2: MB8 # bit[23] -> MB8 bit[0]: ingress::ig_md.ig_ft.srv6.pf_downgrade + 3: B36 # ingress::hdr.fabric_data_template_plus.vb + 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 + 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 + 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 + 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 + 12..13: H13 + # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one + # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif + B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid + B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid + load: { byte1 : 2 } + shift: 14 + buf_req: 14 + next: parse_ipv6 + 0b011111**: + load: { byte0 : 2 } + buf_req: 3 + next: parse_fabric_evpn_110 + 0b010011**: + 0: B37 + # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type + # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror + # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast + 0..1: H69 + # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc + # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color + # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track + 2: B15 # ingress::hdr.fabric_data_template_plus.flags + 3: B36 # ingress::hdr.fabric_data_template_plus.vb + 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 + 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 + 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 + 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 + 12..13: H13 + # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one + # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif + 14..15: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 + 16..19: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 + 20..21: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 + 22..25: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 + 26..27: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid + B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid + load: { byte0 : 26, byte1 : 27 } + shift: 28 + buf_req: 28 + next: parse_fabric_2544_pktgen.$split_0 + 0x**: + buf_req: 0 + next: end + parse_ipv6: + *: + 0: B41 + # - bit[0..3] -> B41 bit[7..4]: ingress::hdr.ig_ft.ipv6.version + # - bit[4..7] -> B41 bit[3..0]: ingress::hdr.ig_ft.ipv6.traffic_class[7:4].4-7 + 1: B40 + # - bit[8..11] -> B40 bit[7..4]: ingress::hdr.ig_ft.ipv6.traffic_class[3:0].0-3 + # - bit[12..15] -> B40 bit[3..0]: ingress::hdr.ig_ft.ipv6.flow_label[19:16].16-19 + 2..3: H3 # ingress::hdr.ig_ft.ipv6.flow_label[15:0].0-15 + 4..5: H0 # ingress::hdr.ig_ft.ipv6.payload_len + 6: MB6 # ingress::hdr.ig_ft.ipv6.next_hdr + 6: B18 # ingress::ig_md.ig_ft.lkp.ip_proto + 6: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto + 6..7: MH0 # bit[56..63] -> MH0 bit[7..0]: ingress::ig_md.ig_ft.lkp.ip_ttl + 8..11: MW0 # ingress::hdr.ig_ft.ipv6.src_addr[127:96].96-127 + 12..15: MW1 # ingress::hdr.ig_ft.ipv6.src_addr[95:64].64-95 + 16..19: MW2 # ingress::hdr.ig_ft.ipv6.src_addr[63:32].32-63 + 20..21: MH12 # ingress::hdr.ig_ft.ipv6.src_addr[31:16].16-31 + 22..23: H2 # ingress::hdr.ig_ft.ipv6.src_addr[15:0].0-15 + 24..27: MW8 # ingress::hdr.ig_ft.ipv6.dst_addr[127:96].96-127 + 28..31: MW7 # ingress::hdr.ig_ft.ipv6.dst_addr[95:64].64-95 + clot 27 : + start: 7 + length: 17 + load: { byte0 : 6 } + shift: 32 + buf_req: 32 + next: parse_ipv6.$split_0 + parse_ipv6.$split_0: + match: [ byte0 ] + 0x3a: + 0..3: MW6 # ingress::hdr.ig_ft.ipv6.dst_addr[63:32].32-63 + 4..7: MW3 # ingress::hdr.ig_ft.ipv6.dst_addr[31:0].0-31 + H7: 32 # value 1 -> H7 bit[5]: ingress::hdr.ig_ft.ipv6.$valid + shift: 8 + buf_req: 8 + next: parse_icmp + 0x06: + 0..3: MW6 # ingress::hdr.ig_ft.ipv6.dst_addr[63:32].32-63 + 4..7: MW3 # ingress::hdr.ig_ft.ipv6.dst_addr[31:0].0-31 + H7: 32 # value 1 -> H7 bit[5]: ingress::hdr.ig_ft.ipv6.$valid + shift: 8 + buf_req: 8 + next: parse_tcp + 0x11: + 0..3: MW6 # ingress::hdr.ig_ft.ipv6.dst_addr[63:32].32-63 + 4..7: MW3 # ingress::hdr.ig_ft.ipv6.dst_addr[31:0].0-31 + H7: 32 # value 1 -> H7 bit[5]: ingress::hdr.ig_ft.ipv6.$valid + load: { byte0 : 10, byte1 : 11 } + shift: 8 + buf_req: 12 + next: parse_udp + 0x8f: + 0..3: MW6 # ingress::hdr.ig_ft.ipv6.dst_addr[63:32].32-63 + 4..7: MW3 # ingress::hdr.ig_ft.ipv6.dst_addr[31:0].0-31 + H7: 32 # value 1 -> H7 bit[5]: ingress::hdr.ig_ft.ipv6.$valid + load: { byte0 : 20, byte1 : 21 } + shift: 8 + buf_req: 22 + next: parse_inner_ethernet + 0x04: + 0..3: MW6 # ingress::hdr.ig_ft.ipv6.dst_addr[63:32].32-63 + 4..7: MW3 # ingress::hdr.ig_ft.ipv6.dst_addr[31:0].0-31 + H7: 32 # value 1 -> H7 bit[5]: ingress::hdr.ig_ft.ipv6.$valid + load: { byte0 : 8, byte1 : 14, byte2 : 15, byte3 : 17 } + shift: 8 + buf_req: 18 + next: parse_inner_ipv4 + 0x29: + 0..3: MW6 # ingress::hdr.ig_ft.ipv6.dst_addr[63:32].32-63 + 4..7: MW3 # ingress::hdr.ig_ft.ipv6.dst_addr[31:0].0-31 + H7: 32 # value 1 -> H7 bit[5]: ingress::hdr.ig_ft.ipv6.$valid + shift: 8 + buf_req: 8 + next: parse_inner_ipv6 + 0x2b: + 0..3: MW6 # ingress::hdr.ig_ft.ipv6.dst_addr[63:32].32-63 + 4..7: MW3 # ingress::hdr.ig_ft.ipv6.dst_addr[31:0].0-31 + H7: 32 # value 1 -> H7 bit[5]: ingress::hdr.ig_ft.ipv6.$valid + shift: 8 + buf_req: 8 + next: parse_srh_check + 0x3c: + 0..3: MW6 # ingress::hdr.ig_ft.ipv6.dst_addr[63:32].32-63 + 4..7: MW3 # ingress::hdr.ig_ft.ipv6.dst_addr[31:0].0-31 + H7: 32 # value 1 -> H7 bit[5]: ingress::hdr.ig_ft.ipv6.$valid + load: { byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_doh + 0x**: + 0..3: MW6 # ingress::hdr.ig_ft.ipv6.dst_addr[63:32].32-63 + 4..7: MW3 # ingress::hdr.ig_ft.ipv6.dst_addr[31:0].0-31 + H7: 32 # value 1 -> H7 bit[5]: ingress::hdr.ig_ft.ipv6.$valid + shift: 8 + buf_req: 8 + next: end + parse_icmp: + *: + 0..1: H66 # ingress::ig_md.ig_ft.lkp.l4_src_port + buf_req: 2 + next: end + parse_tcp: + *: + 0..1: H66 # ingress::ig_md.ig_ft.lkp.l4_src_port + 0..3: W31 # bit[16..31] -> W31 bit[15..0]: ingress::ig_md.ig_ft.lkp.l4_dst_port + 12..13: H29 # bit[104..111] -> H29 bit[7..0]: ingress::ig_md.ig_ft.lkp.tcp_flags + buf_req: 14 + next: end + parse_udp: + match: [ byte0, byte1 ] + value_set IgParser_front.udp_port_vxlan 1: + handle: 511 + field_mapping: + hdr.ig_ft.udp.dst_port(0..7) : byte1(0..7) + hdr.ig_ft.udp.dst_port(8..15) : byte0(0..7) + 0..1: H66 # ingress::ig_md.ig_ft.lkp.l4_src_port + 0..3: W31 # bit[16..31] -> W31 bit[15..0]: ingress::ig_md.ig_ft.lkp.l4_dst_port + H7: 64 # value 1 -> H7 bit[6]: ingress::hdr.ig_ft.udp.$valid + clot 17 : + start: 0 + length: 8 + shift: 8 + buf_req: 8 + next: parse_vxlan + 0x****: + 0..1: H66 # ingress::ig_md.ig_ft.lkp.l4_src_port + 0..3: W31 # bit[16..31] -> W31 bit[15..0]: ingress::ig_md.ig_ft.lkp.l4_dst_port + H7: 64 # value 1 -> H7 bit[6]: ingress::hdr.ig_ft.udp.$valid + clot 17 : + start: 0 + length: 8 + shift: 8 + buf_req: 8 + next: end + parse_vxlan: + *: + 4: B47 # ingress::hdr.ig_ft.vxlan.vni[23:16].16-23 + 5..6: H4 # ingress::hdr.ig_ft.vxlan.vni[15:0].0-15 + H7: 128 # value 1 -> H7 bit[7]: ingress::hdr.ig_ft.vxlan.$valid + clot 18 : + start: 0 + length: 8 + shift: 8 + buf_req: 8 + next: end + parse_inner_ethernet: + match: [ byte0, byte1 ] + 0x0800: + 0..1: H64 # ingress::ig_md.ig_ft.lkp.mac_dst_addr[47:32].32-47 + 2..5: W16 # ingress::ig_md.ig_ft.lkp.mac_dst_addr[31:0].0-31 + 5..8: W17 # bit[48..71] -> W17 bit[23..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[47:24].24-47 + 8..9: H22 # bit[72..79] -> H22 bit[7..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[23:16].16-23 + 8..11: W30 # bit[80..95] -> W30 bit[15..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[15:0].0-15 + H7: 256 # value 1 -> H7 bit[8]: ingress::hdr.ig_ft.inner_ethernet.$valid + clot 13 : + start: 0 + length: 14 + load: { byte0 : 14, byte1 : 20, byte2 : 21, byte3 : 23 } + shift: 14 + buf_req: 24 + next: parse_inner_ipv4 + 0x86dd: + 0..1: H64 # ingress::ig_md.ig_ft.lkp.mac_dst_addr[47:32].32-47 + 2..5: W16 # ingress::ig_md.ig_ft.lkp.mac_dst_addr[31:0].0-31 + 5..8: W17 # bit[48..71] -> W17 bit[23..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[47:24].24-47 + 8..9: H22 # bit[72..79] -> H22 bit[7..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[23:16].16-23 + 8..11: W30 # bit[80..95] -> W30 bit[15..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[15:0].0-15 + H7: 256 # value 1 -> H7 bit[8]: ingress::hdr.ig_ft.inner_ethernet.$valid + clot 13 : + start: 0 + length: 14 + shift: 14 + buf_req: 14 + next: parse_inner_ipv6 + 0x8100: + 0..1: H64 # ingress::ig_md.ig_ft.lkp.mac_dst_addr[47:32].32-47 + 2..5: W16 # ingress::ig_md.ig_ft.lkp.mac_dst_addr[31:0].0-31 + 5..8: W17 # bit[48..71] -> W17 bit[23..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[47:24].24-47 + 8..9: H22 # bit[72..79] -> H22 bit[7..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[23:16].16-23 + 8..11: W30 # bit[80..95] -> W30 bit[15..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[15:0].0-15 + H7: 256 # value 1 -> H7 bit[8]: ingress::hdr.ig_ft.inner_ethernet.$valid + clot 13 : + start: 0 + length: 14 + load: { byte0 : 16, byte1 : 17 } + shift: 14 + buf_req: 18 + next: parse_inner_vlan + 0x****: + 0..1: H64 # ingress::ig_md.ig_ft.lkp.mac_dst_addr[47:32].32-47 + 2..5: W16 # ingress::ig_md.ig_ft.lkp.mac_dst_addr[31:0].0-31 + 5..8: W17 # bit[48..71] -> W17 bit[23..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[47:24].24-47 + 8..9: H22 # bit[72..79] -> H22 bit[7..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[23:16].16-23 + 8..11: W30 # bit[80..95] -> W30 bit[15..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[15:0].0-15 + H7: 256 # value 1 -> H7 bit[8]: ingress::hdr.ig_ft.inner_ethernet.$valid + clot 13 : + start: 0 + length: 14 + shift: 14 + buf_req: 14 + next: end + parse_inner_ipv4: + match: [ byte3, byte0, byte1, byte2 ] + 0b00010001****0101**00000000000000: + checksum 0: + type: VERIFY + mask: [ 0, 1, 2..3, 4..5, 6, 6..7, 8, 9, 10..11, 12..15, 16..19 ] + swap: 0 + start: 1 + end: 1 + dest: H8(2) + 9: B18 # ingress::ig_md.ig_ft.lkp.ip_proto + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + 16..19: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H7: 512 # value 1 -> H7 bit[9]: ingress::hdr.ig_ft.inner_ipv4.$valid + clot 1 : + start: 0 + length: 20 + shift: 20 + buf_req: 20 + next: parse_inner_udp + 0b00000110****0101**00000000000000: + checksum 0: + type: VERIFY + mask: [ 0, 1, 2..3, 4..5, 6, 6..7, 8, 9, 10..11, 12..15, 16..19 ] + swap: 0 + start: 1 + end: 1 + dest: H8(2) + 9: B18 # ingress::ig_md.ig_ft.lkp.ip_proto + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + 16..19: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H7: 512 # value 1 -> H7 bit[9]: ingress::hdr.ig_ft.inner_ipv4.$valid + clot 1 : + start: 0 + length: 20 + shift: 20 + buf_req: 20 + next: parse_inner_tcp + 0x********: + checksum 0: + type: VERIFY + mask: [ 0, 1, 2..3, 4..5, 6, 6..7, 8, 9, 10..11, 12..15, 16..19 ] + swap: 0 + start: 1 + end: 1 + dest: H8(2) + 9: B18 # ingress::ig_md.ig_ft.lkp.ip_proto + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + 16..19: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H7: 512 # value 1 -> H7 bit[9]: ingress::hdr.ig_ft.inner_ipv4.$valid + clot 1 : + start: 0 + length: 20 + shift: 20 + buf_req: 20 + next: end + parse_inner_udp: + *: + 0..1: H66 # ingress::ig_md.ig_ft.lkp.l4_src_port + 0..3: W31 # bit[16..31] -> W31 bit[15..0]: ingress::ig_md.ig_ft.lkp.l4_dst_port + buf_req: 4 + next: end + parse_inner_tcp: + *: + 0..1: H66 # ingress::ig_md.ig_ft.lkp.l4_src_port + 0..3: W31 # bit[16..31] -> W31 bit[15..0]: ingress::ig_md.ig_ft.lkp.l4_dst_port + buf_req: 4 + next: end + parse_inner_ipv6: + *: + 0..3: W28 # bit[12..31] -> W28 bit[19..0]: ingress::ig_md.ig_ft.lkp.flow_label + 6: B18 # ingress::ig_md.ig_ft.lkp.ip_proto + 8..11: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 12..15: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 16..19: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 20..21: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 22..23: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + 24..27: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 28..31: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + H7: 1024 # value 1 -> H7 bit[10]: ingress::hdr.ig_ft.inner_ipv6.$valid + clot 0 : + start: 0 + length: 40 + load: { byte0 : 6 } + shift: 32 + buf_req: 32 + next: parse_inner_ipv6.$split_0 + parse_inner_ipv6.$split_0: + match: [ byte0 ] + 0x06: + 0..3: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 4..7: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + # clot 0 (spilled) + shift: 8 + buf_req: 8 + next: parse_inner_tcp + 0x11: + 0..3: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 4..7: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + # clot 0 (spilled) + shift: 8 + buf_req: 8 + next: parse_inner_udp + 0x**: + 0..3: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 4..7: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + # clot 0 (spilled) + shift: 8 + buf_req: 8 + next: end + parse_inner_vlan: + match: [ byte0, byte1 ] + 0x0800: + H7: 2048 # value 1 -> H7 bit[11]: ingress::hdr.ig_ft.inner_vlan_tag.$valid + clot 20 : + start: 0 + length: 4 + load: { byte0 : 4, byte1 : 10, byte2 : 11, byte3 : 13 } + shift: 4 + buf_req: 14 + next: parse_inner_ipv4 + 0x86dd: + H7: 2048 # value 1 -> H7 bit[11]: ingress::hdr.ig_ft.inner_vlan_tag.$valid + clot 20 : + start: 0 + length: 4 + shift: 4 + buf_req: 4 + next: parse_inner_ipv6 + 0x****: + H7: 2048 # value 1 -> H7 bit[11]: ingress::hdr.ig_ft.inner_vlan_tag.$valid + clot 20 : + start: 0 + length: 4 + shift: 4 + buf_req: 4 + next: end + parse_srh_check: + match: [ byte1 ] + 0b*******1: + load: { byte0 : 4 } + buf_req: 5 + next: parse_srh_downgrade + 0x**: + 0: MB4 # ingress::hdr.ig_ft.srv6_srh.next_hdr + 0: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto + 3: B14 # ingress::hdr.ig_ft.srv6_srh.seg_left + 4: B47 # ingress::hdr.ig_ft.srv6_srh.last_entry + 5: B34 # bit[46] -> B34 bit[1]: ingress::ig_md.ig_ft.srv6.tmp_no_frr + H7: 4096 # value 1 -> H7 bit[12]: ingress::hdr.ig_ft.srv6_srh.$valid + clot 19 : + start: 0 + length: 8 + load: { byte0 : 0, byte1 : 3, byte2 : 4 } + shift: 8 + buf_req: 8 + next: parse_srh_segment_0 + parse_srh_downgrade: + match: [ byte0 ] + 0x00: + 0: MB4 # ingress::hdr.ig_ft.srv6_srh.next_hdr + 0: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto + 3: B14 # ingress::hdr.ig_ft.srv6_srh.seg_left + 4: B47 # ingress::hdr.ig_ft.srv6_srh.last_entry + 5: B34 # bit[46] -> B34 bit[1]: ingress::ig_md.ig_ft.srv6.tmp_no_frr + H7: 4096 # value 1 -> H7 bit[12]: ingress::hdr.ig_ft.srv6_srh.$valid + clot 19 : + start: 0 + length: 8 + load: { byte0 : 0 } + shift: 8 + buf_req: 8 + next: set_active_gsid_dg_and_parse_srh_next_0 + 0x**: + 0: MB4 # ingress::hdr.ig_ft.srv6_srh.next_hdr + 0: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto + 3: B14 # ingress::hdr.ig_ft.srv6_srh.seg_left + 4: B47 # ingress::hdr.ig_ft.srv6_srh.last_entry + 5: B34 # bit[46] -> B34 bit[1]: ingress::ig_md.ig_ft.srv6.tmp_no_frr + H7: 4096 # value 1 -> H7 bit[12]: ingress::hdr.ig_ft.srv6_srh.$valid + clot 19 : + start: 0 + length: 8 + load: { byte0 : 0, byte1 : 4 } + shift: 8 + buf_req: 8 + next: set_active_gsid_dg_0 + set_active_gsid_dg_and_parse_srh_next_0: + *: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 1024 # value 1024 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 12 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + parse_srh_next_header: + match: [ byte0 ] + 0x3c: + load: { byte0 : 2 } + buf_req: 3 + next: parse_doh_e2e + 0x**: + buf_req: 0 + next: end + parse_doh_e2e: + match: [ byte0 ] + 0x12: + 0: B45 # ingress::hdr.ig_ft.doh_e2e.next_hdr + 1: B46 # ingress::hdr.ig_ft.doh_e2e.hdr_ext_len + 2..3: H28 + # - bit[16..23] -> H28 bit[15..8]: ingress::hdr.ig_ft.doh_e2e.option_type + # - bit[24..31] -> H28 bit[7..0]: ingress::hdr.ig_ft.doh_e2e.option_len + H7: 8192 # value 1 -> H7 bit[13]: ingress::hdr.ig_ft.doh_e2e.$valid + buf_req: 4 + next: parse_srv6_e2e_ifit + 0x**: + 0: B45 # ingress::hdr.ig_ft.doh_e2e.next_hdr + 1: B46 # ingress::hdr.ig_ft.doh_e2e.hdr_ext_len + 2..3: H28 + # - bit[16..23] -> H28 bit[15..8]: ingress::hdr.ig_ft.doh_e2e.option_type + # - bit[24..31] -> H28 bit[7..0]: ingress::hdr.ig_ft.doh_e2e.option_len + H7: 8192 # value 1 -> H7 bit[13]: ingress::hdr.ig_ft.doh_e2e.$valid + buf_req: 4 + next: end + parse_srv6_e2e_ifit: + *: + 0: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto + 3..6: MW5 # bit[32..51] -> MW5 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_id + 6: MB12 # bit[52] -> MB12 bit[3]: ingress::ig_md.ig_ft.ifit.loss_label + 6: MB14 # bit[53] -> MB14 bit[2]: ingress::ig_md.ig_ft.ifit.delay_label + 7..10: MW10 # bit[64..83] -> MW10 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_node_id + 11: MB10 # bit[88..89] -> MB10 bit[7..6]: ingress::ig_md.ig_ft.ifit.hti + H7: 16384 # value 1 -> H7 bit[14]: ingress::hdr.ig_ft.srv6_e2e_ifit.$valid + clot 14 : + start: 4 + length: 12 + shift: 16 + buf_req: 16 + next: end + set_active_gsid_dg_0: + match: [ byte1 ] + 0x01: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 1024 # value 1024 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 12 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header_dg_1 + 0x**: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 1024 # value 1024 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 12 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_dg_b1 + parse_srh_next_header_dg_1: + *: + H6: 512 # value 512 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 11 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + parse_srh_segment_dg_b1: + match: [ byte1 ] + 0x02: + H6: 512 # value 512 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 11 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header_dg_2 + 0x**: + H6: 512 # value 512 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 11 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_dg_b2 + parse_srh_next_header_dg_2: + *: + H6: 256 # value 256 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 10 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + parse_srh_segment_dg_b2: + match: [ byte1 ] + 0x03: + H6: 256 # value 256 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 10 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header_dg_3 + 0x**: + H6: 256 # value 256 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 10 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_dg_b3 + parse_srh_next_header_dg_3: + *: + H6: 128 # value 128 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 9 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + parse_srh_segment_dg_b3: + match: [ byte1 ] + 0x04: + H6: 128 # value 128 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 9 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header_dg_4 + 0x**: + H6: 128 # value 128 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 9 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_dg_b4 + parse_srh_next_header_dg_4: + *: + H6: 64 # value 64 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 8 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + parse_srh_segment_dg_b4: + match: [ byte1 ] + 0x05: + H6: 64 # value 64 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 8 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header_dg_5 + 0x**: + H6: 64 # value 64 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 8 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_dg_b5 + parse_srh_next_header_dg_5: + *: + H6: 32 # value 32 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 7 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + parse_srh_segment_dg_b5: + match: [ byte1 ] + 0x06: + H6: 32 # value 32 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 7 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header_dg_6 + 0x**: + H6: 32 # value 32 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 7 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_dg_b6 + parse_srh_next_header_dg_6: + *: + H6: 16 # value 16 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 6 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + parse_srh_segment_dg_b6: + match: [ byte1 ] + 0x07: + H6: 16 # value 16 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 6 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header_dg_7 + 0x**: + H6: 16 # value 16 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 6 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_dg_b7 + parse_srh_next_header_dg_7: + *: + H6: 8 # value 8 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 5 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + parse_srh_segment_dg_b7: + match: [ byte1 ] + 0x08: + H6: 8 # value 8 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 5 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header_dg_8 + 0x**: + H6: 8 # value 8 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 5 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_dg_b8 + parse_srh_next_header_dg_8: + *: + H6: 4 # value 4 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 4 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + parse_srh_segment_dg_b8: + match: [ byte1 ] + 0x09: + H6: 4 # value 4 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 4 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header_dg_9 + 0x**: + H6: 4 # value 4 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 4 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_dg_b9 + parse_srh_next_header_dg_9: + *: + H6: 2 # value 2 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 3 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + parse_srh_segment_dg_b9: + *: + H6: 2 # value 2 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 3 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header_10 + parse_srh_next_header_10: + *: + H6: 1 # value 1 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 2 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + parse_srh_segment_0: + match: [ byte2, byte1 ] + 0x0001: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 1024 # value 1024 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 12 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x0000: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 1024 # value 1024 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 12 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x00**: + H6: 1024 # value 1024 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 12 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x**01: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 1024 # value 1024 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 12 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_1 + 0x**00: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 1024 # value 1024 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 12 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_1 + 0x****: + H6: 1024 # value 1024 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 12 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_1 + parse_srh_segment_1: + match: [ byte2, byte1 ] + 0x0102: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 512 # value 512 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 11 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x0101: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 512 # value 512 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 11 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x01**: + H6: 512 # value 512 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 11 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x**02: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 512 # value 512 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 11 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_2 + 0x**01: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 512 # value 512 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 11 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_2 + 0x****: + H6: 512 # value 512 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 11 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_2 + parse_srh_segment_2: + match: [ byte2, byte1 ] + 0x0203: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 256 # value 256 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 10 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x0202: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 256 # value 256 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 10 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x02**: + H6: 256 # value 256 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 10 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x**03: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 256 # value 256 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 10 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_3 + 0x**02: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 256 # value 256 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 10 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_3 + 0x****: + H6: 256 # value 256 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 10 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_3 + parse_srh_segment_3: + match: [ byte2, byte1 ] + 0x0304: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 128 # value 128 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 9 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x0303: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 128 # value 128 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 9 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x03**: + H6: 128 # value 128 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 9 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x**04: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 128 # value 128 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 9 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_4 + 0x**03: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 128 # value 128 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 9 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_4 + 0x****: + H6: 128 # value 128 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 9 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_4 + parse_srh_segment_4: + match: [ byte2, byte1 ] + 0x0405: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 64 # value 64 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 8 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x0404: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 64 # value 64 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 8 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x04**: + H6: 64 # value 64 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 8 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x**05: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 64 # value 64 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 8 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_5 + 0x**04: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 64 # value 64 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 8 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_5 + 0x****: + H6: 64 # value 64 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 8 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_5 + parse_srh_segment_5: + match: [ byte2, byte1 ] + 0x0506: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 32 # value 32 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 7 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x0505: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 32 # value 32 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 7 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x05**: + H6: 32 # value 32 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 7 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x**06: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 32 # value 32 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 7 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_6 + 0x**05: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 32 # value 32 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 7 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_6 + 0x****: + H6: 32 # value 32 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 7 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_6 + parse_srh_segment_6: + match: [ byte2, byte1 ] + 0x0607: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 16 # value 16 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 6 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x0606: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 16 # value 16 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 6 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x06**: + H6: 16 # value 16 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 6 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x**07: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 16 # value 16 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 6 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_7 + 0x**06: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 16 # value 16 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 6 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_7 + 0x****: + H6: 16 # value 16 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 6 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_7 + parse_srh_segment_7: + match: [ byte2, byte1 ] + 0x0708: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 8 # value 8 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 5 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x0707: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 8 # value 8 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 5 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x07**: + H6: 8 # value 8 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 5 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x**08: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 8 # value 8 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 5 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_8 + 0x**07: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 8 # value 8 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 5 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_8 + 0x****: + H6: 8 # value 8 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 5 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_8 + parse_srh_segment_8: + match: [ byte2, byte1 ] + 0x0809: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 4 # value 4 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 4 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x0808: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 4 # value 4 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 4 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x08**: + H6: 4 # value 4 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 4 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x**09: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 4 # value 4 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 4 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_9 + 0x**08: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 4 # value 4 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 4 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_9 + 0x****: + H6: 4 # value 4 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 4 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_9 + parse_srh_segment_9: + match: [ byte2, byte1 ] + 0x090a: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 2 # value 2 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 3 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x0909: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 2 # value 2 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 3 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x09**: + H6: 2 # value 2 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 3 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x**0a: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 2 # value 2 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 3 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_10 + 0x**09: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 2 # value 2 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 3 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_10 + 0x****: + H6: 2 # value 2 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 3 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_segment_10 + parse_srh_segment_10: + match: [ byte2, byte1 ] + 0x0a0b: + 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 + 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 + H6: 1 # value 1 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 2 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x**0a: + 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + H6: 1 # value 1 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 2 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + 0x****: + H6: 1 # value 1 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid + clot 2 : + start: 0 + length: 16 + shift: 16 + buf_req: 16 + next: parse_srh_next_header + parse_doh: + match: [ byte0 ] + 0x12: + 0: MB5 # ingress::hdr.ig_ft.doh.next_hdr + H7: 32768 # value 1 -> H7 bit[15]: ingress::hdr.ig_ft.doh.$valid + clot 26 : + start: 1 + length: 3 + load: { byte0 : 0 } + buf_req: 1 + next: parse_h2h_ifit + 0x**: + 0: MB5 # ingress::hdr.ig_ft.doh.next_hdr + H7: 32768 # value 1 -> H7 bit[15]: ingress::hdr.ig_ft.doh.$valid + clot 26 : + start: 1 + length: 3 + buf_req: 1 + next: end + parse_h2h_ifit: + match: [ byte0 ] + 0x2b: + 0: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto + 3..6: MW5 # bit[32..51] -> MW5 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_id + 6: MB12 # bit[52] -> MB12 bit[3]: ingress::ig_md.ig_ft.ifit.loss_label + 6: MB14 # bit[53] -> MB14 bit[2]: ingress::ig_md.ig_ft.ifit.delay_label + 7..10: MW10 # bit[64..83] -> MW10 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_node_id + 11: MB10 # bit[88..89] -> MB10 bit[7..6]: ingress::ig_md.ig_ft.ifit.hti + 13: B31 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[23:16].16-23 + 14..15: H4 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[15:0].0-15 + B12: 1 # value 1 -> B12 bit[0]: ingress::hdr.ig_ft.srv6_h2h_ifit.$valid + clot 15 : + start: 4 + length: 9 + shift: 16 + buf_req: 16 + next: parse_srh_check + 0x8f: + 0: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto + 3..6: MW5 # bit[32..51] -> MW5 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_id + 6: MB12 # bit[52] -> MB12 bit[3]: ingress::ig_md.ig_ft.ifit.loss_label + 6: MB14 # bit[53] -> MB14 bit[2]: ingress::ig_md.ig_ft.ifit.delay_label + 7..10: MW10 # bit[64..83] -> MW10 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_node_id + 11: MB10 # bit[88..89] -> MB10 bit[7..6]: ingress::ig_md.ig_ft.ifit.hti + 13: B31 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[23:16].16-23 + 14..15: H4 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[15:0].0-15 + B12: 1 # value 1 -> B12 bit[0]: ingress::hdr.ig_ft.srv6_h2h_ifit.$valid + clot 15 : + start: 4 + length: 9 + load: { byte0 : 28, byte1 : 29 } + shift: 16 + buf_req: 30 + next: parse_inner_ethernet + 0x04: + 0: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto + 3..6: MW5 # bit[32..51] -> MW5 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_id + 6: MB12 # bit[52] -> MB12 bit[3]: ingress::ig_md.ig_ft.ifit.loss_label + 6: MB14 # bit[53] -> MB14 bit[2]: ingress::ig_md.ig_ft.ifit.delay_label + 7..10: MW10 # bit[64..83] -> MW10 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_node_id + 11: MB10 # bit[88..89] -> MB10 bit[7..6]: ingress::ig_md.ig_ft.ifit.hti + 13: B31 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[23:16].16-23 + 14..15: H4 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[15:0].0-15 + B12: 1 # value 1 -> B12 bit[0]: ingress::hdr.ig_ft.srv6_h2h_ifit.$valid + clot 15 : + start: 4 + length: 9 + load: { byte0 : 16, byte1 : 22, byte2 : 23, byte3 : 25 } + shift: 16 + buf_req: 26 + next: parse_inner_ipv4 + 0x29: + 0: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto + 3..6: MW5 # bit[32..51] -> MW5 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_id + 6: MB12 # bit[52] -> MB12 bit[3]: ingress::ig_md.ig_ft.ifit.loss_label + 6: MB14 # bit[53] -> MB14 bit[2]: ingress::ig_md.ig_ft.ifit.delay_label + 7..10: MW10 # bit[64..83] -> MW10 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_node_id + 11: MB10 # bit[88..89] -> MB10 bit[7..6]: ingress::ig_md.ig_ft.ifit.hti + 13: B31 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[23:16].16-23 + 14..15: H4 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[15:0].0-15 + B12: 1 # value 1 -> B12 bit[0]: ingress::hdr.ig_ft.srv6_h2h_ifit.$valid + clot 15 : + start: 4 + length: 9 + shift: 16 + buf_req: 16 + next: parse_inner_ipv6 + 0x**: + 0: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto + 3..6: MW5 # bit[32..51] -> MW5 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_id + 6: MB12 # bit[52] -> MB12 bit[3]: ingress::ig_md.ig_ft.ifit.loss_label + 6: MB14 # bit[53] -> MB14 bit[2]: ingress::ig_md.ig_ft.ifit.delay_label + 7..10: MW10 # bit[64..83] -> MW10 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_node_id + 11: MB10 # bit[88..89] -> MB10 bit[7..6]: ingress::ig_md.ig_ft.ifit.hti + 13: B31 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[23:16].16-23 + 14..15: H4 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[15:0].0-15 + B12: 1 # value 1 -> B12 bit[0]: ingress::hdr.ig_ft.srv6_h2h_ifit.$valid + clot 15 : + start: 4 + length: 9 + shift: 16 + buf_req: 16 + next: end + parse_fabric_evpn_110: + match: [ byte0 ] + 0b1*******: + 0: B37 + # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type + # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror + # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast + 0..1: H69 + # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc + # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color + # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track + 2: B15 # ingress::hdr.fabric_data_template_plus.flags + 3: B36 # ingress::hdr.fabric_data_template_plus.vb + 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 + 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 + 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 + 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 + 12..13: H13 + # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one + # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif + B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid + B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid + shift: 14 + buf_req: 14 + next: parse_extension_tunnel_decap + 0x**: + 0: B37 + # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type + # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror + # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast + 0..1: H69 + # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc + # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color + # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track + 2: B15 # ingress::hdr.fabric_data_template_plus.flags + 3: B36 # ingress::hdr.fabric_data_template_plus.vb + 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 + 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 + 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 + 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 + 12..13: H13 + # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one + # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif + B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid + B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid + load: { byte0 : 26, byte1 : 27 } + shift: 14 + buf_req: 28 + next: parse_ethernet_evpn110 + parse_extension_tunnel_decap: + *: + 0: B38 + # - bit[0..2] -> B38 bit[7..5]: ingress::hdr.ext_tunnel_decap.ext_type + # - bit[3] -> B38 bit[4]: ingress::hdr.ext_tunnel_decap.extend + # - bit[4..7] -> B38 bit[3..0]: ingress::hdr.ext_tunnel_decap.sub_type + 1: B39 # ingress::hdr.ext_tunnel_decap.vb + 2..3: H18 # ingress::hdr.ext_tunnel_decap.vh + B13: 1 # value 1 -> B13 bit[0]: ingress::hdr.ext_tunnel_decap.$valid + load: { byte0 : 16, byte1 : 17 } + shift: 4 + buf_req: 18 + next: parse_ethernet_evpn110 + parse_ethernet_evpn110: + match: [ byte0, byte1 ] + 0x8100: + 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 + 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 + 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 + 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid + load: { byte0 : 16, byte1 : 17 } + shift: 14 + buf_req: 18 + next: parse_vlan_evpn110 + 0x****: + 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 + 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 + 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 + 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid + shift: 14 + buf_req: 14 + next: end + parse_vlan_evpn110: + match: [ byte0, byte1 ] + 0x8100: + 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid + 0..3: W10 + # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp + # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi + # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid + # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type + B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_vlan1_evpn110 + 0x****: + 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid + 0..3: W10 + # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp + # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi + # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid + # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type + B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_vlan1_evpn110: + *: + 0..3: W11 + # - bit[0..2] -> W11 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[1].pcp + # - bit[3] -> W11 bit[28]: ingress::hdr.ig_ft.vlan_tag[1].cfi + # - bit[4..15] -> W11 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[1].vid + # - bit[16..31] -> W11 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[1].ether_type + B10: 1 # value 1 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_fabric_2544_pktgen.$split_0: + match: [ byte0, byte1 ] + 0x8100: + B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid + load: { byte0 : 2, byte1 : 3 } + buf_req: 4 + next: parse_vlan_2544 + 0x****: + B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid + buf_req: 0 + next: end + parse_vlan_2544: + match: [ byte0, byte1 ] + 0x8100: + 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid + 0..3: W10 + # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp + # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi + # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid + # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type + B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_vlan1_2544 + 0x****: + 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid + 0..3: W10 + # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp + # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi + # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid + # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type + B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_vlan1_2544: + *: + 0..3: W11 + # - bit[0..2] -> W11 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[1].pcp + # - bit[3] -> W11 bit[28]: ingress::hdr.ig_ft.vlan_tag[1].cfi + # - bit[4..15] -> W11 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[1].vid + # - bit[16..31] -> W11 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[1].ether_type + B10: 1 # value 1 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + start.$oob_stall_1: + *: + load: { byte0 : 12, byte2 : 13 } + buf_req: 14 + next: parse_ethernet + parse_ethernet: + match: [ byte0, byte2 ] + 0x0800: + 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 + 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 + 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 + 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type + B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid + load: { byte0 : 14 } + shift: 14 + buf_req: 15 + next: parse_ipv4 + 0x86dd: + 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 + 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 + 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 + 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type + B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid + shift: 14 + buf_req: 14 + next: parse_ipv6 + 0x8100: + 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 + 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 + 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 + 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type + B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid + load: { byte0 : 16, byte2 : 17 } + shift: 14 + buf_req: 18 + next: parse_vlan + 0x8847: + 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 + 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 + 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 + 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type + B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid + load: { byte0 : 16, byte1 : 20, byte2 : 24 } + shift: 14 + buf_req: 25 + next: parse_mpls + 0x893f: + 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 + 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 + 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 + 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type + B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid + load: { byte0 : 20, byte2 : 21 } + shift: 14 + buf_req: 22 + next: parse_1br + 0x9000: + 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 + 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 + 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 + 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type + B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid + load: { byte0 : 14 } + shift: 14 + buf_req: 15 + next: parse_fabric_eth_cpu + 0x88a8: + 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 + 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 + 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 + 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type + B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid + load: { byte0 : 16, byte2 : 17 } + shift: 14 + buf_req: 18 + next: parse_qinq + 0x9100: + 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 + 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 + 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 + 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type + B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid + load: { byte0 : 16, byte2 : 17 } + shift: 14 + buf_req: 18 + next: parse_qinq + value_set IgParser_front.qinq_tpid 1: + handle: 510 + field_mapping: + hdr.ig_ft.ethernet.ether_type(0..7) : byte2(0..7) + hdr.ig_ft.ethernet.ether_type(8..15) : byte0(0..7) + 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 + 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 + 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 + 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type + B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid + load: { byte0 : 16, byte2 : 17 } + shift: 14 + buf_req: 18 + next: parse_qinq + 0x****: + 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 + 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 + 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 + 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type + B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid + shift: 14 + buf_req: 14 + next: end + parse_ipv4: + match: [ byte0 ] + 0x*5: + checksum 0: + type: RESIDUAL + mask: [ 0, 1, 10..11 ] + swap: 0 + start: 1 + end: 1 + dest: H20 + end_pos: 19 + checksum 1: + type: VERIFY + mask: [ 0, 1, 2..3, 4..5, 6, 6..7, 8, 9, 10..11, 12..15, 16..19 ] + swap: 0 + start: 1 + end: 0 + 1: B40 # ingress::hdr.ig_ft.ipv4.diffserv + 6: B14 + # - bit[48..50] -> B14 bit[7..5]: ingress::hdr.ig_ft.ipv4.flags + # - bit[51..55] -> B14 bit[4..0]: ingress::hdr.ig_ft.ipv4.frag_offset[12:8].8-12 + 7: MB5 # ingress::hdr.ig_ft.ipv4.frag_offset[7:0].0-7 + 7..8: MH0 # bit[64..71] -> MH0 bit[7..0]: ingress::ig_md.ig_ft.lkp.ip_ttl + 9: MB4 # ingress::hdr.ig_ft.ipv4.protocol + 9: B18 # ingress::ig_md.ig_ft.lkp.ip_proto + 12..13: MH12 # ingress::hdr.ig_ft.ipv4.src_addr[31:16].16-31 + 14..15: H0 # ingress::hdr.ig_ft.ipv4.src_addr[15:0].0-15 + 16..19: MW0 # ingress::hdr.ig_ft.ipv4.dst_addr + B12: 4 # value 1 -> B12 bit[2]: ingress::hdr.ig_ft.ipv4.$valid + clot 16 : + start: 0 + length: 20 + load: { byte0 : 6, byte1 : 7, byte2 : 9 } + shift: 20 + buf_req: 20 + next: parse_ipv4_no_options + 0x*6: + checksum 0: + type: RESIDUAL + mask: [ 0, 1, 10..11 ] + swap: 0 + start: 1 + end: 1 + dest: H20 + end_pos: 19 + checksum 1: + type: VERIFY + mask: [ 0, 1, 2..3, 4..5, 6, 6..7, 8, 9, 10..11, 12..15, 16..19 ] + swap: 0 + start: 1 + end: 0 + 1: B40 # ingress::hdr.ig_ft.ipv4.diffserv + 6: B14 + # - bit[48..50] -> B14 bit[7..5]: ingress::hdr.ig_ft.ipv4.flags + # - bit[51..55] -> B14 bit[4..0]: ingress::hdr.ig_ft.ipv4.frag_offset[12:8].8-12 + 7: MB5 # ingress::hdr.ig_ft.ipv4.frag_offset[7:0].0-7 + 7..8: MH0 # bit[64..71] -> MH0 bit[7..0]: ingress::ig_md.ig_ft.lkp.ip_ttl + 9: MB4 # ingress::hdr.ig_ft.ipv4.protocol + 9: B18 # ingress::ig_md.ig_ft.lkp.ip_proto + 12..13: MH12 # ingress::hdr.ig_ft.ipv4.src_addr[31:16].16-31 + 14..15: H0 # ingress::hdr.ig_ft.ipv4.src_addr[15:0].0-15 + 16..19: MW0 # ingress::hdr.ig_ft.ipv4.dst_addr + B12: 4 # value 1 -> B12 bit[2]: ingress::hdr.ig_ft.ipv4.$valid + clot 16 : + start: 0 + length: 20 + load: { byte0 : 6, byte1 : 7, byte2 : 9 } + shift: 20 + buf_req: 20 + next: parse_ipv4_options + 0x**: + checksum 0: + type: RESIDUAL + mask: [ 0, 1, 10..11 ] + swap: 0 + start: 1 + end: 1 + dest: H20 + end_pos: 19 + checksum 1: + type: VERIFY + mask: [ 0, 1, 2..3, 4..5, 6, 6..7, 8, 9, 10..11, 12..15, 16..19 ] + swap: 0 + start: 1 + end: 0 + 1: B40 # ingress::hdr.ig_ft.ipv4.diffserv + 6: B14 + # - bit[48..50] -> B14 bit[7..5]: ingress::hdr.ig_ft.ipv4.flags + # - bit[51..55] -> B14 bit[4..0]: ingress::hdr.ig_ft.ipv4.frag_offset[12:8].8-12 + 7: MB5 # ingress::hdr.ig_ft.ipv4.frag_offset[7:0].0-7 + 7..8: MH0 # bit[64..71] -> MH0 bit[7..0]: ingress::ig_md.ig_ft.lkp.ip_ttl + 9: MB4 # ingress::hdr.ig_ft.ipv4.protocol + 9: B18 # ingress::ig_md.ig_ft.lkp.ip_proto + 12..13: MH12 # ingress::hdr.ig_ft.ipv4.src_addr[31:16].16-31 + 14..15: H0 # ingress::hdr.ig_ft.ipv4.src_addr[15:0].0-15 + 16..19: MW0 # ingress::hdr.ig_ft.ipv4.dst_addr + B12: 4 # value 1 -> B12 bit[2]: ingress::hdr.ig_ft.ipv4.$valid + clot 16 : + start: 0 + length: 20 + shift: 20 + buf_req: 20 + next: end + parse_ipv4_no_options: + match: [ byte2, byte0, byte1 ] + 0b00000001***0000000000000: + checksum 1: + type: VERIFY + mask: [ ] + swap: 0 + start: 0 + end: 1 + dest: H8(1) + buf_req: 0 + next: parse_icmp + 0b00000110***0000000000000: + checksum 1: + type: VERIFY + mask: [ ] + swap: 0 + start: 0 + end: 1 + dest: H8(1) + buf_req: 0 + next: parse_tcp + 0b00010001***0000000000000: + checksum 1: + type: VERIFY + mask: [ ] + swap: 0 + start: 0 + end: 1 + dest: H8(1) + load: { byte0 : 2, byte1 : 3 } + buf_req: 4 + next: parse_udp + 0x******: + checksum 1: + type: VERIFY + mask: [ ] + swap: 0 + start: 0 + end: 1 + dest: H8(1) + buf_req: 0 + next: end + parse_ipv4_options: + *: + checksum 1: + type: VERIFY + mask: [ 0, 1, 2..3 ] + swap: 0 + start: 0 + end: 0 + 0: MB6 # ingress::hdr.ig_ft.ipv4_option.type + 1..2: H2 + # - bit[8..15] -> H2 bit[15..8]: ingress::hdr.ig_ft.ipv4_option.length + # - bit[16..23] -> H2 bit[7..0]: ingress::hdr.ig_ft.ipv4_option.value[15:8].8-15 + B12: 8 # value 1 -> B12 bit[3]: ingress::hdr.ig_ft.ipv4_option.$valid + clot 28 : + start: 3 + length: 1 + shift: 4 + buf_req: 4 + next: parse_ipv4_no_options + parse_vlan: + match: [ byte0, byte2 ] + 0x0800: + 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid + 0..3: W10 + # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp + # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi + # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid + # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type + 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type + B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid + load: { byte0 : 4 } + shift: 4 + buf_req: 5 + next: parse_ipv4 + 0x8100: + 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid + 0..3: W10 + # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp + # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi + # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid + # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type + 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type + B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid + load: { byte0 : 6, byte2 : 7 } + shift: 4 + buf_req: 8 + next: parse_vlan_1 + 0x86dd: + 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid + 0..3: W10 + # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp + # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi + # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid + # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type + 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type + B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv6 + 0x8847: + 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid + 0..3: W10 + # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp + # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi + # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid + # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type + 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type + B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid + load: { byte0 : 6, byte1 : 10, byte2 : 14 } + shift: 4 + buf_req: 15 + next: parse_mpls + 0x****: + 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid + 0..3: W10 + # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp + # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi + # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid + # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type + 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type + B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_vlan_1: + match: [ byte0, byte2 ] + 0x0800: + 0..3: W11 + # - bit[0..2] -> W11 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[1].pcp + # - bit[3] -> W11 bit[28]: ingress::hdr.ig_ft.vlan_tag[1].cfi + # - bit[4..15] -> W11 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[1].vid + # - bit[16..31] -> W11 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[1].ether_type + 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type + B10: 1 # value 1 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid + load: { byte0 : 4 } + shift: 4 + buf_req: 5 + next: parse_ipv4 + 0x86dd: + 0..3: W11 + # - bit[0..2] -> W11 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[1].pcp + # - bit[3] -> W11 bit[28]: ingress::hdr.ig_ft.vlan_tag[1].cfi + # - bit[4..15] -> W11 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[1].vid + # - bit[16..31] -> W11 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[1].ether_type + 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type + B10: 1 # value 1 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv6 + 0x8847: + 0..3: W11 + # - bit[0..2] -> W11 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[1].pcp + # - bit[3] -> W11 bit[28]: ingress::hdr.ig_ft.vlan_tag[1].cfi + # - bit[4..15] -> W11 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[1].vid + # - bit[16..31] -> W11 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[1].ether_type + 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type + B10: 1 # value 1 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid + load: { byte0 : 6, byte1 : 10, byte2 : 14 } + shift: 4 + buf_req: 15 + next: parse_mpls + 0x8100: + 0..3: W11 + # - bit[0..2] -> W11 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[1].pcp + # - bit[3] -> W11 bit[28]: ingress::hdr.ig_ft.vlan_tag[1].cfi + # - bit[4..15] -> W11 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[1].vid + # - bit[16..31] -> W11 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[1].ether_type + 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type + B10: 1 # value 1 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + 0x****: + 0..3: W11 + # - bit[0..2] -> W11 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[1].pcp + # - bit[3] -> W11 bit[28]: ingress::hdr.ig_ft.vlan_tag[1].cfi + # - bit[4..15] -> W11 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[1].vid + # - bit[16..31] -> W11 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[1].ether_type + 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type + B10: 1 # value 1 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_mpls: + match: [ byte0, byte1, byte2 ] + 0b*******0*******0*******0: + 0..1: H40 # ingress::hdr.ig_ft.mpls_ig[0].label[19:4].4-19 + 2..3: H5 + # - bit[16..19] -> H5 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[0].label[3:0].0-3 + # - bit[20..22] -> H5 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[0].exp + # - bit[23] -> H5 bit[8]: ingress::hdr.ig_ft.mpls_ig[0].bos + # - bit[24..31] -> H5 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[0].ttl + 2..3: MH0 # bit[24..31] -> MH0 bit[7..0]: ingress::ig_md.ig_ft.lkp.ip_ttl + B8: 128 # value 128 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + load: { byte0 : 14, byte1 : 18, byte2 : 22 } + shift: 4 + buf_req: 23 + next: parse_mpls3_or_more + 0b*******0*******0*******1: + 0..1: H40 # ingress::hdr.ig_ft.mpls_ig[0].label[19:4].4-19 + 2..3: H5 + # - bit[16..19] -> H5 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[0].label[3:0].0-3 + # - bit[20..22] -> H5 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[0].exp + # - bit[23] -> H5 bit[8]: ingress::hdr.ig_ft.mpls_ig[0].bos + # - bit[24..31] -> H5 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[0].ttl + 2..3: MH0 # bit[24..31] -> MH0 bit[7..0]: ingress::ig_md.ig_ft.lkp.ip_ttl + B8: 128 # value 128 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + shift: 4 + buf_req: 4 + next: parse_mpls2 + 0b*******0*******1********: + 0..1: H40 # ingress::hdr.ig_ft.mpls_ig[0].label[19:4].4-19 + 2..3: H5 + # - bit[16..19] -> H5 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[0].label[3:0].0-3 + # - bit[20..22] -> H5 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[0].exp + # - bit[23] -> H5 bit[8]: ingress::hdr.ig_ft.mpls_ig[0].bos + # - bit[24..31] -> H5 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[0].ttl + 2..3: MH0 # bit[24..31] -> MH0 bit[7..0]: ingress::ig_md.ig_ft.lkp.ip_ttl + B8: 128 # value 128 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + shift: 4 + buf_req: 4 + next: parse_mpls1 + 0x******: + 0..1: H40 # ingress::hdr.ig_ft.mpls_ig[0].label[19:4].4-19 + 2..3: H5 + # - bit[16..19] -> H5 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[0].label[3:0].0-3 + # - bit[20..22] -> H5 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[0].exp + # - bit[23] -> H5 bit[8]: ingress::hdr.ig_ft.mpls_ig[0].bos + # - bit[24..31] -> H5 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[0].ttl + 2..3: MH0 # bit[24..31] -> MH0 bit[7..0]: ingress::ig_md.ig_ft.lkp.ip_ttl + B8: 128 # value 128 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + load: { byte0 : 4 } + shift: 4 + buf_req: 5 + next: parse_mpls_bos + parse_mpls3_or_more: + match: [ byte0, byte1, byte2 ] + 0b*******0*******0*******0: + 0..1: H39 # ingress::hdr.ig_ft.mpls_ig[1].label[19:4].4-19 + 2..3: H4 + # - bit[16..19] -> H4 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[1].label[3:0].0-3 + # - bit[20..22] -> H4 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[1].exp + # - bit[23] -> H4 bit[8]: ingress::hdr.ig_ft.mpls_ig[1].bos + # - bit[24..31] -> H4 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[1].ttl + 4..5: H38 # ingress::hdr.ig_ft.mpls_ig[2].label[19:4].4-19 + 6..7: H3 + # - bit[48..51] -> H3 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[2].label[3:0].0-3 + # - bit[52..54] -> H3 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[2].exp + # - bit[55] -> H3 bit[8]: ingress::hdr.ig_ft.mpls_ig[2].bos + # - bit[56..63] -> H3 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[2].ttl + 8..9: H37 # ingress::hdr.ig_ft.mpls_ig[3].label[19:4].4-19 + 10..11: H2 + # - bit[80..83] -> H2 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[3].label[3:0].0-3 + # - bit[84..86] -> H2 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[3].exp + # - bit[87] -> H2 bit[8]: ingress::hdr.ig_ft.mpls_ig[3].bos + # - bit[88..95] -> H2 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[3].ttl + B8: 112 + # - value 64 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + # - value 32 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + # - value 16 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + load: { byte0 : 22, byte1 : 26, byte2 : 30 } + shift: 12 + buf_req: 31 + next: parse_mpls6_or_more + 0b*******0*******0*******1: + 0..1: H39 # ingress::hdr.ig_ft.mpls_ig[1].label[19:4].4-19 + 2..3: H4 + # - bit[16..19] -> H4 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[1].label[3:0].0-3 + # - bit[20..22] -> H4 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[1].exp + # - bit[23] -> H4 bit[8]: ingress::hdr.ig_ft.mpls_ig[1].bos + # - bit[24..31] -> H4 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[1].ttl + 4..5: H38 # ingress::hdr.ig_ft.mpls_ig[2].label[19:4].4-19 + 6..7: H3 + # - bit[48..51] -> H3 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[2].label[3:0].0-3 + # - bit[52..54] -> H3 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[2].exp + # - bit[55] -> H3 bit[8]: ingress::hdr.ig_ft.mpls_ig[2].bos + # - bit[56..63] -> H3 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[2].ttl + 8..9: H37 # ingress::hdr.ig_ft.mpls_ig[3].label[19:4].4-19 + 10..11: H2 + # - bit[80..83] -> H2 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[3].label[3:0].0-3 + # - bit[84..86] -> H2 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[3].exp + # - bit[87] -> H2 bit[8]: ingress::hdr.ig_ft.mpls_ig[3].bos + # - bit[88..95] -> H2 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[3].ttl + B8: 112 + # - value 64 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + # - value 32 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + # - value 16 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + shift: 12 + buf_req: 12 + next: parse_mpls5 + 0b*******0*******1********: + 0..1: H39 # ingress::hdr.ig_ft.mpls_ig[1].label[19:4].4-19 + 2..3: H4 + # - bit[16..19] -> H4 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[1].label[3:0].0-3 + # - bit[20..22] -> H4 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[1].exp + # - bit[23] -> H4 bit[8]: ingress::hdr.ig_ft.mpls_ig[1].bos + # - bit[24..31] -> H4 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[1].ttl + 4..5: H38 # ingress::hdr.ig_ft.mpls_ig[2].label[19:4].4-19 + 6..7: H3 + # - bit[48..51] -> H3 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[2].label[3:0].0-3 + # - bit[52..54] -> H3 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[2].exp + # - bit[55] -> H3 bit[8]: ingress::hdr.ig_ft.mpls_ig[2].bos + # - bit[56..63] -> H3 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[2].ttl + 8..9: H37 # ingress::hdr.ig_ft.mpls_ig[3].label[19:4].4-19 + 10..11: H2 + # - bit[80..83] -> H2 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[3].label[3:0].0-3 + # - bit[84..86] -> H2 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[3].exp + # - bit[87] -> H2 bit[8]: ingress::hdr.ig_ft.mpls_ig[3].bos + # - bit[88..95] -> H2 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[3].ttl + B8: 112 + # - value 64 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + # - value 32 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + # - value 16 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + shift: 12 + buf_req: 12 + next: parse_mpls4 + 0x******: + 0..1: H39 # ingress::hdr.ig_ft.mpls_ig[1].label[19:4].4-19 + 2..3: H4 + # - bit[16..19] -> H4 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[1].label[3:0].0-3 + # - bit[20..22] -> H4 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[1].exp + # - bit[23] -> H4 bit[8]: ingress::hdr.ig_ft.mpls_ig[1].bos + # - bit[24..31] -> H4 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[1].ttl + 4..5: H38 # ingress::hdr.ig_ft.mpls_ig[2].label[19:4].4-19 + 6..7: H3 + # - bit[48..51] -> H3 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[2].label[3:0].0-3 + # - bit[52..54] -> H3 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[2].exp + # - bit[55] -> H3 bit[8]: ingress::hdr.ig_ft.mpls_ig[2].bos + # - bit[56..63] -> H3 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[2].ttl + 8..9: H37 # ingress::hdr.ig_ft.mpls_ig[3].label[19:4].4-19 + 10..11: H2 + # - bit[80..83] -> H2 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[3].label[3:0].0-3 + # - bit[84..86] -> H2 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[3].exp + # - bit[87] -> H2 bit[8]: ingress::hdr.ig_ft.mpls_ig[3].bos + # - bit[88..95] -> H2 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[3].ttl + B8: 112 + # - value 64 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + # - value 32 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + # - value 16 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + load: { byte0 : 12 } + shift: 12 + buf_req: 13 + next: parse_mpls_bos + parse_mpls6_or_more: + match: [ byte0, byte1, byte2 ] + 0b*******0*******0*******0: + 0..1: H36 # ingress::hdr.ig_ft.mpls_ig[4].label[19:4].4-19 + 2..3: H0 + # - bit[16..19] -> H0 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[4].label[3:0].0-3 + # - bit[20..22] -> H0 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[4].exp + # - bit[23] -> H0 bit[8]: ingress::hdr.ig_ft.mpls_ig[4].bos + # - bit[24..31] -> H0 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[4].ttl + B8: 8 # value 8 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + B9: 24 + # - value 16 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid + # - value 8 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid + clot 25 : + start: 4 + length: 4 + clot 24 : + start: 8 + length: 4 + shift: 12 + buf_req: 12 + next: parse_mpls10_or_more + 0b*******0*******0*******1: + 0..1: H36 # ingress::hdr.ig_ft.mpls_ig[4].label[19:4].4-19 + 2..3: H0 + # - bit[16..19] -> H0 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[4].label[3:0].0-3 + # - bit[20..22] -> H0 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[4].exp + # - bit[23] -> H0 bit[8]: ingress::hdr.ig_ft.mpls_ig[4].bos + # - bit[24..31] -> H0 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[4].ttl + B8: 8 # value 8 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + B9: 24 + # - value 16 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid + # - value 8 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid + clot 25 : + start: 4 + length: 4 + clot 24 : + start: 8 + length: 4 + shift: 12 + buf_req: 12 + next: parse_mpls9 + 0b*******0*******1********: + 0..1: H36 # ingress::hdr.ig_ft.mpls_ig[4].label[19:4].4-19 + 2..3: H0 + # - bit[16..19] -> H0 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[4].label[3:0].0-3 + # - bit[20..22] -> H0 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[4].exp + # - bit[23] -> H0 bit[8]: ingress::hdr.ig_ft.mpls_ig[4].bos + # - bit[24..31] -> H0 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[4].ttl + B8: 8 # value 8 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + B9: 24 + # - value 16 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid + # - value 8 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid + clot 25 : + start: 4 + length: 4 + clot 24 : + start: 8 + length: 4 + shift: 12 + buf_req: 12 + next: parse_mpls8 + 0x******: + 0..1: H36 # ingress::hdr.ig_ft.mpls_ig[4].label[19:4].4-19 + 2..3: H0 + # - bit[16..19] -> H0 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[4].label[3:0].0-3 + # - bit[20..22] -> H0 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[4].exp + # - bit[23] -> H0 bit[8]: ingress::hdr.ig_ft.mpls_ig[4].bos + # - bit[24..31] -> H0 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[4].ttl + B8: 8 # value 8 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + B9: 24 + # - value 16 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid + # - value 8 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid + clot 25 : + start: 4 + length: 4 + clot 24 : + start: 8 + length: 4 + load: { byte0 : 12 } + shift: 12 + buf_req: 13 + next: parse_mpls_bos + parse_mpls10_or_more: + *: + B9: 7 + # - value 4 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid + # - value 2 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid + # - value 1 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid + clot 23 : + start: 0 + length: 4 + clot 22 : + start: 4 + length: 4 + load: { byte0 : 10 } + shift: 8 + buf_req: 11 + next: parse_mpls10_or_more.$split_0 + parse_mpls10_or_more.$split_0: + match: [ byte0 ] + 0b*******1: + clot 21 : + start: 0 + length: 4 + load: { byte0 : 4 } + shift: 4 + buf_req: 5 + next: parse_mpls_bos + 0x**: + clot 21 : + start: 0 + length: 4 + shift: 4 + buf_req: 4 + next: end + parse_mpls_bos: + match: [ byte0 ] + 0x4*: + load: { byte0 : 0, byte1 : 6, byte2 : 7, byte3 : 9 } + buf_req: 10 + next: parse_inner_ipv4 + 0x6*: + 0..3: W28 # bit[12..31] -> W28 bit[19..0]: ingress::ig_md.ig_ft.lkp.flow_label + 6: B18 # ingress::ig_md.ig_ft.lkp.ip_proto + 8..11: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 + 12..15: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 + 16..19: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 + 20..21: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 + 22..23: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 + 24..27: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 + 28..31: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 + H7: 1024 # value 1 -> H7 bit[10]: ingress::hdr.ig_ft.inner_ipv6.$valid + clot 0 : + start: 0 + length: 40 + load: { byte0 : 6 } + shift: 32 + buf_req: 32 + next: parse_inner_ipv6.$split_0 + 0x**: + load: { byte0 : 12, byte1 : 13 } + buf_req: 14 + next: parse_inner_ethernet + parse_mpls9: + *: + B9: 6 + # - value 4 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid + # - value 2 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid + clot 23 : + start: 0 + length: 4 + clot 22 : + start: 4 + length: 4 + load: { byte0 : 8 } + shift: 8 + buf_req: 9 + next: parse_mpls_bos + parse_mpls8: + *: + B9: 4 # value 4 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid + clot 23 : + start: 0 + length: 4 + load: { byte0 : 4 } + shift: 4 + buf_req: 5 + next: parse_mpls_bos + parse_mpls5: + *: + 0..1: H36 # ingress::hdr.ig_ft.mpls_ig[4].label[19:4].4-19 + 2..3: H0 + # - bit[16..19] -> H0 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[4].label[3:0].0-3 + # - bit[20..22] -> H0 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[4].exp + # - bit[23] -> H0 bit[8]: ingress::hdr.ig_ft.mpls_ig[4].bos + # - bit[24..31] -> H0 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[4].ttl + B8: 8 # value 8 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + B9: 16 # value 16 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid + clot 25 : + start: 4 + length: 4 + load: { byte0 : 8 } + shift: 8 + buf_req: 9 + next: parse_mpls_bos + parse_mpls4: + *: + 0..1: H36 # ingress::hdr.ig_ft.mpls_ig[4].label[19:4].4-19 + 2..3: H0 + # - bit[16..19] -> H0 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[4].label[3:0].0-3 + # - bit[20..22] -> H0 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[4].exp + # - bit[23] -> H0 bit[8]: ingress::hdr.ig_ft.mpls_ig[4].bos + # - bit[24..31] -> H0 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[4].ttl + B8: 8 # value 8 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + load: { byte0 : 4 } + shift: 4 + buf_req: 5 + next: parse_mpls_bos + parse_mpls2: + *: + 0..1: H39 # ingress::hdr.ig_ft.mpls_ig[1].label[19:4].4-19 + 2..3: H4 + # - bit[16..19] -> H4 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[1].label[3:0].0-3 + # - bit[20..22] -> H4 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[1].exp + # - bit[23] -> H4 bit[8]: ingress::hdr.ig_ft.mpls_ig[1].bos + # - bit[24..31] -> H4 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[1].ttl + 4..5: H38 # ingress::hdr.ig_ft.mpls_ig[2].label[19:4].4-19 + 6..7: H3 + # - bit[48..51] -> H3 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[2].label[3:0].0-3 + # - bit[52..54] -> H3 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[2].exp + # - bit[55] -> H3 bit[8]: ingress::hdr.ig_ft.mpls_ig[2].bos + # - bit[56..63] -> H3 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[2].ttl + B8: 96 + # - value 64 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + # - value 32 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + load: { byte0 : 8 } + shift: 8 + buf_req: 9 + next: parse_mpls_bos + parse_mpls1: + *: + 0..1: H39 # ingress::hdr.ig_ft.mpls_ig[1].label[19:4].4-19 + 2..3: H4 + # - bit[16..19] -> H4 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[1].label[3:0].0-3 + # - bit[20..22] -> H4 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[1].exp + # - bit[23] -> H4 bit[8]: ingress::hdr.ig_ft.mpls_ig[1].bos + # - bit[24..31] -> H4 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[1].ttl + B8: 64 # value 64 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid + load: { byte0 : 4 } + shift: 4 + buf_req: 5 + next: parse_mpls_bos + parse_1br: + match: [ byte0, byte2 ] + 0x0800: + 2..3: H1 # bit[20..31] -> H1 bit[11..0]: ingress::hdr.ig_ft.br_tag.ecid + 6..7: MH11 # ingress::ig_md.ig_ft.common.ether_type + 6..7: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + B12: 16 # value 1 -> B12 bit[4]: ingress::hdr.ig_ft.br_tag.$valid + load: { byte0 : 8 } + shift: 8 + buf_req: 9 + next: parse_ipv4 + 0x86dd: + 2..3: H1 # bit[20..31] -> H1 bit[11..0]: ingress::hdr.ig_ft.br_tag.ecid + 6..7: MH11 # ingress::ig_md.ig_ft.common.ether_type + 6..7: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + B12: 16 # value 1 -> B12 bit[4]: ingress::hdr.ig_ft.br_tag.$valid + shift: 8 + buf_req: 8 + next: parse_ipv6 + 0x8100: + 2..3: H1 # bit[20..31] -> H1 bit[11..0]: ingress::hdr.ig_ft.br_tag.ecid + 6..7: MH11 # ingress::ig_md.ig_ft.common.ether_type + 6..7: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + B12: 16 # value 1 -> B12 bit[4]: ingress::hdr.ig_ft.br_tag.$valid + load: { byte0 : 10, byte2 : 11 } + shift: 8 + buf_req: 12 + next: parse_vlan + 0x8847: + 2..3: H1 # bit[20..31] -> H1 bit[11..0]: ingress::hdr.ig_ft.br_tag.ecid + 6..7: MH11 # ingress::ig_md.ig_ft.common.ether_type + 6..7: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + B12: 16 # value 1 -> B12 bit[4]: ingress::hdr.ig_ft.br_tag.$valid + load: { byte0 : 10, byte1 : 14, byte2 : 18 } + shift: 8 + buf_req: 19 + next: parse_mpls + 0x88a8: + 2..3: H1 # bit[20..31] -> H1 bit[11..0]: ingress::hdr.ig_ft.br_tag.ecid + 6..7: MH11 # ingress::ig_md.ig_ft.common.ether_type + 6..7: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + B12: 16 # value 1 -> B12 bit[4]: ingress::hdr.ig_ft.br_tag.$valid + load: { byte0 : 10, byte2 : 11 } + shift: 8 + buf_req: 12 + next: parse_qinq + 0x9100: + 2..3: H1 # bit[20..31] -> H1 bit[11..0]: ingress::hdr.ig_ft.br_tag.ecid + 6..7: MH11 # ingress::ig_md.ig_ft.common.ether_type + 6..7: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + B12: 16 # value 1 -> B12 bit[4]: ingress::hdr.ig_ft.br_tag.$valid + load: { byte0 : 10, byte2 : 11 } + shift: 8 + buf_req: 12 + next: parse_qinq + value_set IgParser_front.qinq_tpid 1: + handle: 510 + field_mapping: + hdr.ig_ft.br_tag.ether_type(0..7) : byte2(0..7) + hdr.ig_ft.br_tag.ether_type(8..15) : byte0(0..7) + 2..3: H1 # bit[20..31] -> H1 bit[11..0]: ingress::hdr.ig_ft.br_tag.ecid + 6..7: MH11 # ingress::ig_md.ig_ft.common.ether_type + 6..7: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + B12: 16 # value 1 -> B12 bit[4]: ingress::hdr.ig_ft.br_tag.$valid + load: { byte0 : 10, byte2 : 11 } + shift: 8 + buf_req: 12 + next: parse_qinq + 0x****: + 2..3: H1 # bit[20..31] -> H1 bit[11..0]: ingress::hdr.ig_ft.br_tag.ecid + 6..7: MH11 # ingress::ig_md.ig_ft.common.ether_type + 6..7: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + B12: 16 # value 1 -> B12 bit[4]: ingress::hdr.ig_ft.br_tag.$valid + shift: 8 + buf_req: 8 + next: end + parse_qinq: + match: [ byte0, byte2 ] + 0x8100: + 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid + 0..3: W10 + # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp + # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi + # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid + # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type + B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid + MH14: 33024 # value 33024 -> MH14 bit[15..0]: ingress::hdr.ig_ft.ethernet.ether_type + load: { byte0 : 6, byte2 : 7 } + shift: 4 + buf_req: 8 + next: parse_vlan_1 + 0x****: + 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid + 0..3: W10 + # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp + # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi + # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid + # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type + B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid + MH14: 33024 # value 33024 -> MH14 bit[15..0]: ingress::hdr.ig_ft.ethernet.ether_type + shift: 4 + buf_req: 4 + next: end + parse_fabric_eth_cpu: + match: [ byte0 ] + 0b001011**: + 0: B37 + # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type + # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror + # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast + 0..1: H69 + # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc + # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color + # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track + 0..3: MW8 # bit[23..31] -> MW8 bit[8..0]: ingress::hdr.fabric_from_cpu_eth_ccm.dev_port + B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid + shift: 4 + buf_req: 4 + next: end + 0x**: + load: { byte0 : 14, byte2 : 15 } + buf_req: 16 + next: parse_fabric_eth_cpu_common + parse_fabric_eth_cpu_common: + match: [ byte0, byte2 ] + 0x0800: + 0: B37 + # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type + # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror + # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast + 0..1: H69 + # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc + # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color + # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track + 2: B15 # ingress::hdr.fabric_data_template_plus.flags + 3: B36 # ingress::hdr.fabric_data_template_plus.vb + 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 + 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 + 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 + 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 + 12..13: H13 + # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one + # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif + 14..15: MH11 # ingress::ig_md.ig_ft.common.ether_type + 14..15: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid + B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid + load: { byte0 : 16 } + shift: 16 + buf_req: 17 + next: parse_ipv4 + 0x86dd: + 0: B37 + # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type + # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror + # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast + 0..1: H69 + # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc + # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color + # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track + 2: B15 # ingress::hdr.fabric_data_template_plus.flags + 3: B36 # ingress::hdr.fabric_data_template_plus.vb + 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 + 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 + 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 + 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 + 12..13: H13 + # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one + # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif + 14..15: MH11 # ingress::ig_md.ig_ft.common.ether_type + 14..15: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid + B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid + shift: 16 + buf_req: 16 + next: parse_ipv6 + 0x8847: + 0: B37 + # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type + # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror + # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast + 0..1: H69 + # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc + # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color + # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track + 2: B15 # ingress::hdr.fabric_data_template_plus.flags + 3: B36 # ingress::hdr.fabric_data_template_plus.vb + 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 + 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 + 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 + 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 + 12..13: H13 + # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one + # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif + 14..15: MH11 # ingress::ig_md.ig_ft.common.ether_type + 14..15: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid + B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid + load: { byte0 : 18, byte1 : 22, byte2 : 26 } + shift: 16 + buf_req: 27 + next: parse_mpls + 0x8100: + 0: B37 + # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type + # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror + # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast + 0..1: H69 + # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc + # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color + # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track + 2: B15 # ingress::hdr.fabric_data_template_plus.flags + 3: B36 # ingress::hdr.fabric_data_template_plus.vb + 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 + 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 + 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 + 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 + 12..13: H13 + # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one + # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif + 14..15: MH11 # ingress::ig_md.ig_ft.common.ether_type + 14..15: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid + B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid + load: { byte0 : 18, byte2 : 19 } + shift: 16 + buf_req: 20 + next: parse_vlan + 0x****: + 0: B37 + # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type + # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror + # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast + 0..1: H69 + # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc + # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color + # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track + 2: B15 # ingress::hdr.fabric_data_template_plus.flags + 3: B36 # ingress::hdr.fabric_data_template_plus.vb + 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 + 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 + 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 + 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 + 12..13: H13 + # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one + # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif + 14..15: MH11 # ingress::ig_md.ig_ft.common.ether_type + 14..15: MH14 # ingress::hdr.ig_ft.ethernet.ether_type + B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid + B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid + shift: 16 + buf_req: 16 + next: end +deparser ingress: + dictionary: + B28: B10(5) + # - bit[7..5]: ingress::hdr.switch_bridged_src.src if ingress::hdr.switch_bridged_src.$valid + # - bit[4..0]: ingress::hdr.switch_bridged_src.bridge_type if ingress::hdr.switch_bridged_src.$valid + B37: B10(4) + # - bit[7..2]: ingress::hdr.fabric_base.pkt_type if ingress::hdr.fabric_base.$valid + # - bit[1]: ingress::hdr.fabric_base.is_mirror if ingress::hdr.fabric_base.$valid + # - bit[0]: ingress::hdr.fabric_base.is_mcast if ingress::hdr.fabric_base.$valid + B29: B9(6) # ingress::hdr.fabric_qos_encap.data if ingress::hdr.fabric_qos_encap.$valid + H24: B9(7) # ingress::hdr.bridged_md_12_encap.decap_len if ingress::hdr.bridged_md_12_encap.$valid + B15: B13(1) # ingress::hdr.fabric_data_template_plus.flags if ingress::hdr.fabric_data_template_plus.$valid + B36: B13(1) # ingress::hdr.fabric_data_template_plus.vb if ingress::hdr.fabric_data_template_plus.$valid + H53: B13(1) # ingress::hdr.fabric_data_template_plus.vh0 if ingress::hdr.fabric_data_template_plus.$valid + H19: B13(1) # ingress::hdr.fabric_data_template_plus.vh1 if ingress::hdr.fabric_data_template_plus.$valid + H1: B13(1) # ingress::hdr.fabric_data_template_plus.vh2 if ingress::hdr.fabric_data_template_plus.$valid + H17: B13(1) # ingress::hdr.fabric_data_template_plus.vh3 if ingress::hdr.fabric_data_template_plus.$valid + H13: B13(1) + # - bit[15]: ingress::hdr.fabric_data_template_plus.one if ingress::hdr.fabric_data_template_plus.$valid + # - bit[14..0]: ingress::hdr.fabric_data_template_plus.iif if ingress::hdr.fabric_data_template_plus.$valid + B11: B13(2) + # - bit[7..5]: ingress::hdr.ext_srv6.ext_type if ingress::hdr.ext_srv6.$valid + # - bit[4]: ingress::hdr.ext_srv6.extend if ingress::hdr.ext_srv6.$valid + # - bit[3]: ingress::hdr.ext_srv6.bypass_L3 if ingress::hdr.ext_srv6.$valid + # - bit[2..1]: ingress::hdr.ext_srv6.level if ingress::hdr.ext_srv6.$valid + # - bit[0]: ingress::hdr.ext_srv6.is_ecmp if ingress::hdr.ext_srv6.$valid + W7: B13(2) + # - bit[31..24]: ingress::hdr.ext_srv6.priority if ingress::hdr.ext_srv6.$valid + # - bit[23..8]: ingress::hdr.ext_srv6.nexthop if ingress::hdr.ext_srv6.$valid + # - bit[7]: ingress::hdr.ext_srv6.no_frr if ingress::hdr.ext_srv6.$valid + # - bit[6]: ingress::hdr.ext_srv6.nexthop_ext if ingress::hdr.ext_srv6.$valid + # - bit[5]: ingress::hdr.ext_srv6.is_pf if ingress::hdr.ext_srv6.$valid + # - bit[4]: ingress::hdr.ext_srv6.is_endx_pf if ingress::hdr.ext_srv6.$valid + # - bit[3..0]: ingress::hdr.ext_srv6.oam_flag if ingress::hdr.ext_srv6.$valid + B38: B13(0) + # - bit[7..5]: ingress::hdr.ext_tunnel_decap.ext_type if ingress::hdr.ext_tunnel_decap.$valid + # - bit[4]: ingress::hdr.ext_tunnel_decap.extend if ingress::hdr.ext_tunnel_decap.$valid + # - bit[3..0]: ingress::hdr.ext_tunnel_decap.sub_type if ingress::hdr.ext_tunnel_decap.$valid + B39: B13(0) # ingress::hdr.ext_tunnel_decap.vb if ingress::hdr.ext_tunnel_decap.$valid + H18: B13(0) # ingress::hdr.ext_tunnel_decap.vh if ingress::hdr.ext_tunnel_decap.$valid + H22: B12(5) + # - bit[15..13]: ingress::hdr.ext_ifit_encap.ext_type if ingress::hdr.ext_ifit_encap.$valid + # - bit[12]: ingress::hdr.ext_ifit_encap.extend if ingress::hdr.ext_ifit_encap.$valid + # - bit[11..0]: ingress::hdr.ext_ifit_encap.index if ingress::hdr.ext_ifit_encap.$valid + H21: B12(5) # ingress::hdr.ext_ifit_encap.var_h1 if ingress::hdr.ext_ifit_encap.$valid + H23: B12(1) # ingress::hdr.ig_ft.ethernet.dst_addr.32-47 if ingress::hdr.ig_ft.ethernet.$valid + MW15: B12(1) # ingress::hdr.ig_ft.ethernet.dst_addr.0-31 if ingress::hdr.ig_ft.ethernet.$valid + H55: B12(1) # ingress::hdr.ig_ft.ethernet.src_addr.32-47 if ingress::hdr.ig_ft.ethernet.$valid + MW14: B12(1) # ingress::hdr.ig_ft.ethernet.src_addr.0-31 if ingress::hdr.ig_ft.ethernet.$valid + MH14: B12(1) # ingress::hdr.ig_ft.ethernet.ether_type if ingress::hdr.ig_ft.ethernet.$valid + W10: B10(1) + # - bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp if ingress::hdr.ig_ft.vlan_tag[0].$valid + # - bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi if ingress::hdr.ig_ft.vlan_tag[0].$valid + # - bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid if ingress::hdr.ig_ft.vlan_tag[0].$valid + # - bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type if ingress::hdr.ig_ft.vlan_tag[0].$valid + W11: B10(0) + # - bit[31..29]: ingress::hdr.ig_ft.vlan_tag[1].pcp if ingress::hdr.ig_ft.vlan_tag[1].$valid + # - bit[28]: ingress::hdr.ig_ft.vlan_tag[1].cfi if ingress::hdr.ig_ft.vlan_tag[1].$valid + # - bit[27..16]: ingress::hdr.ig_ft.vlan_tag[1].vid if ingress::hdr.ig_ft.vlan_tag[1].$valid + # - bit[15..0]: ingress::hdr.ig_ft.vlan_tag[1].ether_type if ingress::hdr.ig_ft.vlan_tag[1].$valid + H40: B8(7) # ingress::hdr.ig_ft.mpls_ig[0].label.4-19 if ingress::hdr.ig_ft.mpls_ig[0].$valid + H5: B8(7) + # - bit[15..12]: ingress::hdr.ig_ft.mpls_ig[0].label.0-3 if ingress::hdr.ig_ft.mpls_ig[0].$valid + # - bit[11..9]: ingress::hdr.ig_ft.mpls_ig[0].exp if ingress::hdr.ig_ft.mpls_ig[0].$valid + # - bit[8]: ingress::hdr.ig_ft.mpls_ig[0].bos if ingress::hdr.ig_ft.mpls_ig[0].$valid + # - bit[7..0]: ingress::hdr.ig_ft.mpls_ig[0].ttl if ingress::hdr.ig_ft.mpls_ig[0].$valid + H39: B8(6) # ingress::hdr.ig_ft.mpls_ig[1].label.4-19 if ingress::hdr.ig_ft.mpls_ig[1].$valid + H4: B8(6) + # - bit[15..12]: ingress::hdr.ig_ft.mpls_ig[1].label.0-3 if ingress::hdr.ig_ft.mpls_ig[1].$valid + # - bit[11..9]: ingress::hdr.ig_ft.mpls_ig[1].exp if ingress::hdr.ig_ft.mpls_ig[1].$valid + # - bit[8]: ingress::hdr.ig_ft.mpls_ig[1].bos if ingress::hdr.ig_ft.mpls_ig[1].$valid + # - bit[7..0]: ingress::hdr.ig_ft.mpls_ig[1].ttl if ingress::hdr.ig_ft.mpls_ig[1].$valid + H38: B8(5) # ingress::hdr.ig_ft.mpls_ig[2].label.4-19 if ingress::hdr.ig_ft.mpls_ig[2].$valid + H3: B8(5) + # - bit[15..12]: ingress::hdr.ig_ft.mpls_ig[2].label.0-3 if ingress::hdr.ig_ft.mpls_ig[2].$valid + # - bit[11..9]: ingress::hdr.ig_ft.mpls_ig[2].exp if ingress::hdr.ig_ft.mpls_ig[2].$valid + # - bit[8]: ingress::hdr.ig_ft.mpls_ig[2].bos if ingress::hdr.ig_ft.mpls_ig[2].$valid + # - bit[7..0]: ingress::hdr.ig_ft.mpls_ig[2].ttl if ingress::hdr.ig_ft.mpls_ig[2].$valid + H37: B8(4) # ingress::hdr.ig_ft.mpls_ig[3].label.4-19 if ingress::hdr.ig_ft.mpls_ig[3].$valid + H2: B8(4) + # - bit[15..12]: ingress::hdr.ig_ft.mpls_ig[3].label.0-3 if ingress::hdr.ig_ft.mpls_ig[3].$valid + # - bit[11..9]: ingress::hdr.ig_ft.mpls_ig[3].exp if ingress::hdr.ig_ft.mpls_ig[3].$valid + # - bit[8]: ingress::hdr.ig_ft.mpls_ig[3].bos if ingress::hdr.ig_ft.mpls_ig[3].$valid + # - bit[7..0]: ingress::hdr.ig_ft.mpls_ig[3].ttl if ingress::hdr.ig_ft.mpls_ig[3].$valid + H36: B8(3) # ingress::hdr.ig_ft.mpls_ig[4].label.4-19 if ingress::hdr.ig_ft.mpls_ig[4].$valid + H0: B8(3) + # - bit[15..12]: ingress::hdr.ig_ft.mpls_ig[4].label.0-3 if ingress::hdr.ig_ft.mpls_ig[4].$valid + # - bit[11..9]: ingress::hdr.ig_ft.mpls_ig[4].exp if ingress::hdr.ig_ft.mpls_ig[4].$valid + # - bit[8]: ingress::hdr.ig_ft.mpls_ig[4].bos if ingress::hdr.ig_ft.mpls_ig[4].$valid + # - bit[7..0]: ingress::hdr.ig_ft.mpls_ig[4].ttl if ingress::hdr.ig_ft.mpls_ig[4].$valid + clot 25: + pov: hdr.ig_ft.mpls2_ig$0.$valid + clot 24: + pov: hdr.ig_ft.mpls2_ig$1.$valid + clot 23: + pov: hdr.ig_ft.mpls2_ig$2.$valid + clot 22: + pov: hdr.ig_ft.mpls2_ig$3.$valid + clot 21: + pov: hdr.ig_ft.mpls2_ig$4.$valid + clot 16: + pov: hdr.ig_ft.ipv4.$valid + 1 : B40 + MB6: B12(3) # ingress::hdr.ig_ft.ipv4_option.type if ingress::hdr.ig_ft.ipv4_option.$valid + H2: B12(3) + # - bit[15..8]: ingress::hdr.ig_ft.ipv4_option.length if ingress::hdr.ig_ft.ipv4_option.$valid + # - bit[7..0]: ingress::hdr.ig_ft.ipv4_option.value[15:8].8-15 if ingress::hdr.ig_ft.ipv4_option.$valid + clot 28: + pov: hdr.ig_ft.ipv4_option.$valid + B41: H7(5) + # - bit[7..4]: ingress::hdr.ig_ft.ipv6.version if ingress::hdr.ig_ft.ipv6.$valid + # - bit[3..0]: ingress::hdr.ig_ft.ipv6.traffic_class.4-7 if ingress::hdr.ig_ft.ipv6.$valid + B40: H7(5) + # - bit[7..4]: ingress::hdr.ig_ft.ipv6.traffic_class.0-3 if ingress::hdr.ig_ft.ipv6.$valid + # - bit[3..0]: ingress::hdr.ig_ft.ipv6.flow_label.16-19 if ingress::hdr.ig_ft.ipv6.$valid + H3: H7(5) # ingress::hdr.ig_ft.ipv6.flow_label.0-15 if ingress::hdr.ig_ft.ipv6.$valid + H0: H7(5) # ingress::hdr.ig_ft.ipv6.payload_len if ingress::hdr.ig_ft.ipv6.$valid + MB6: H7(5) # ingress::hdr.ig_ft.ipv6.next_hdr if ingress::hdr.ig_ft.ipv6.$valid + clot 27: + pov: hdr.ig_ft.ipv6.$valid + MW8: H7(5) # ingress::hdr.ig_ft.ipv6.dst_addr.96-127 if ingress::hdr.ig_ft.ipv6.$valid + MW7: H7(5) # ingress::hdr.ig_ft.ipv6.dst_addr.64-95 if ingress::hdr.ig_ft.ipv6.$valid + MW6: H7(5) # ingress::hdr.ig_ft.ipv6.dst_addr.32-63 if ingress::hdr.ig_ft.ipv6.$valid + MW3: H7(5) # ingress::hdr.ig_ft.ipv6.dst_addr.0-31 if ingress::hdr.ig_ft.ipv6.$valid + MB5: H7(15) # ingress::hdr.ig_ft.doh.next_hdr if ingress::hdr.ig_ft.doh.$valid + clot 26: + pov: hdr.ig_ft.doh.$valid + clot 15: + pov: hdr.ig_ft.srv6_h2h_ifit.$valid + B31: B12(0) # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[23:0].16-23 if ingress::hdr.ig_ft.srv6_h2h_ifit.$valid + H4: B12(0) # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[23:0].0-15 if ingress::hdr.ig_ft.srv6_h2h_ifit.$valid + clot 19: + pov: hdr.ig_ft.srv6_srh.$valid + 3 : B14 + clot 12: + pov: hdr.ig_ft.srv6_list$0.$valid + clot 11: + pov: hdr.ig_ft.srv6_list$1.$valid + clot 10: + pov: hdr.ig_ft.srv6_list$2.$valid + clot 9: + pov: hdr.ig_ft.srv6_list$3.$valid + clot 8: + pov: hdr.ig_ft.srv6_list$4.$valid + clot 7: + pov: hdr.ig_ft.srv6_list$5.$valid + clot 6: + pov: hdr.ig_ft.srv6_list$6.$valid + clot 5: + pov: hdr.ig_ft.srv6_list$7.$valid + clot 4: + pov: hdr.ig_ft.srv6_list$8.$valid + clot 3: + pov: hdr.ig_ft.srv6_list$9.$valid + clot 2: + pov: hdr.ig_ft.srv6_list$10.$valid + B45: H7(13) # ingress::hdr.ig_ft.doh_e2e.next_hdr if ingress::hdr.ig_ft.doh_e2e.$valid + B46: H7(13) # ingress::hdr.ig_ft.doh_e2e.hdr_ext_len if ingress::hdr.ig_ft.doh_e2e.$valid + H28: H7(13) + # - bit[15..8]: ingress::hdr.ig_ft.doh_e2e.option_type if ingress::hdr.ig_ft.doh_e2e.$valid + # - bit[7..0]: ingress::hdr.ig_ft.doh_e2e.option_len if ingress::hdr.ig_ft.doh_e2e.$valid + clot 14: + pov: hdr.ig_ft.srv6_e2e_ifit.$valid + clot 17: + pov: hdr.ig_ft.udp.$valid + clot 18: + pov: hdr.ig_ft.vxlan.$valid + clot 13: + pov: hdr.ig_ft.inner_ethernet.$valid + clot 20: + pov: hdr.ig_ft.inner_vlan_tag.$valid + clot 1: + pov: hdr.ig_ft.inner_ipv4.$valid + clot 0: + pov: hdr.ig_ft.inner_ipv6.$valid + H43: H7(4) # ingress::hdr.fabric_trace.trace_counter if ingress::hdr.fabric_trace.$valid + H52: H7(4) # ingress::hdr.fabric_trace.timestamp.32-47 if ingress::hdr.fabric_trace.$valid + MW11: H7(4) # ingress::hdr.fabric_trace.timestamp.0-31 if ingress::hdr.fabric_trace.$valid + egress_unicast_port: { MW9(0..8): B10(2) } # bit[8..0]: ingress::ig_intr_md_for_tm.ucast_egress_port if ingress::ig_intr_md_for_tm.ucast_egress_port.$valid + deflect_on_drop: { H31(1..1): H7(2) } # bit[1]: ingress::ig_intr_md_for_tm.deflect_on_drop if ingress::ig_intr_md_for_tm.deflect_on_drop.$valid + qid: { H30(0..6): B9(5) } # bit[6..0]: ingress::ig_intr_md_for_tm.qid if ingress::ig_intr_md_for_tm.qid.$valid + bypss_egr: { B12(6..6): H7(1) } # bit[6]: ingress::ig_intr_md_for_tm.bypass_egress if ingress::ig_intr_md_for_tm.bypass_egress.$valid + drop_ctl: { W6(2..4): B10(3) } # bit[4..2]: ingress::ig_intr_md_for_dprsr.drop_ctl if ingress::ig_intr_md_for_dprsr.drop_ctl.$valid + mirr_io_sel: { H31(0..0): H7(3) } # bit[0]: ingress::ig_intr_md_for_dprsr.mirror_io_select if ingress::ig_intr_md_for_dprsr.mirror_io_select.$valid + mirror: + select: { B1(0..3): H7(0) } # bit[3..0]: ingress::ig_intr_md_for_dprsr.mirror_type + 0: + - B0 # ingress::$tmp11 + 1: + - MB7 # ingress::ig_md.ig_ft.mirror.session_id + - MB0 + # - bit[7..5]: ingress::ig_md.ig_ft.mirror.src + # - bit[4..0]: ingress::ig_md.ig_ft.mirror.type + - MB7 # ingress::ig_md.ig_ft.mirror.session_id + - B37 + # - bit[7..2]: ingress::hdr.fabric_base.pkt_type + # - bit[1]: ingress::hdr.fabric_base.is_mirror + # - bit[0]: ingress::hdr.fabric_base.is_mcast + - B29 # ingress::hdr.fabric_qos_encap.data + - MB2 # ingress::ig_md.ig_ft.mirror.flags + - MB13 # ingress::ig_md.ig_ft.common.src_port + - H53 # ingress::hdr.fabric_data_template_plus.vh0 + - H56 # ingress::ig_md.ig_ft.common.mirror_dst_eport + - H15(0..14) # bit[14..0]: ingress::ig_md.ig_ft.common.iif + - H54 # ingress::ig_md.ig_ft.ifit.var_h1 + - H14(0..14) # bit[14..0]: ingress::ig_md.ig_ft.common.ul_iif + 7: + - MB7 # ingress::ig_md.ig_ft.mirror.session_id + - MB0 + # - bit[7..5]: ingress::ig_md.ig_ft.mirror.src + # - bit[4..0]: ingress::ig_md.ig_ft.mirror.type + - MB7 # ingress::ig_md.ig_ft.mirror.session_id + - H56 # ingress::ig_md.ig_ft.common.mirror_dst_eport + - B37 + # - bit[7..2]: ingress::hdr.fabric_base.pkt_type + # - bit[1]: ingress::hdr.fabric_base.is_mirror + # - bit[0]: ingress::hdr.fabric_base.is_mcast + - B29 # ingress::hdr.fabric_qos_encap.data + - MB15 # ingress::ig_md.ig_ft.common.pipeline_location + - MB15 # ingress::ig_md.ig_ft.common.pipeline_location + - H43 # ingress::hdr.fabric_trace.trace_counter + - B30 # ingress::ig_md.ig_ft.common.drop_reason + - B30 # ingress::ig_md.ig_ft.common.drop_reason + - H53 # ingress::hdr.fabric_data_template_plus.vh0 + - H57 # ingress::ig_md.ig_ft.common.trace_vh3 + - H14(0..14) # bit[14..0]: ingress::ig_md.ig_ft.common.ul_iif + - H52 # ingress::hdr.fabric_trace.timestamp.32-47 + - MW11 # ingress::hdr.fabric_trace.timestamp.0-31 + 6: + - MB7 # ingress::ig_md.ig_ft.mirror.session_id + - MB0 + # - bit[7..5]: ingress::ig_md.ig_ft.mirror.src + # - bit[4..0]: ingress::ig_md.ig_ft.mirror.type + - MB7 # ingress::ig_md.ig_ft.mirror.session_id + - B37 + # - bit[7..2]: ingress::hdr.fabric_base.pkt_type + # - bit[1]: ingress::hdr.fabric_base.is_mirror + # - bit[0]: ingress::hdr.fabric_base.is_mcast + - B29 # ingress::hdr.fabric_qos_encap.data + - MB2 # ingress::ig_md.ig_ft.mirror.flags + - MB13 # ingress::ig_md.ig_ft.common.src_port + - H53 # ingress::hdr.fabric_data_template_plus.vh0 + - H56 # ingress::ig_md.ig_ft.common.mirror_dst_eport + - H15(0..14) # bit[14..0]: ingress::ig_md.ig_ft.common.iif + - H12 + # - bit[15]: ingress::ig_md.ig_ft.tunnel.ipv4_true + # - bit[14]: ingress::ig_md.ig_ft.flags.tunnel_info + # - bit[12..0]: ingress::ig_md.ig_ft.route.vrf + - H14(0..14) # bit[14..0]: ingress::ig_md.ig_ft.common.ul_iif +parser egress: + start: hdr.eg_ft.vlan_tag$shim.$entry_point + bitwise_or: [ B7, B22, B23, B24, B25, B32, B33, H9 ] + clear_on_write: [ MB3, MH15 ] + hdr_len_adj: 28 + meta_opt: 8191 + states: + hdr.eg_ft.vlan_tag$shim.$entry_point: + *: + 52..55: MW12 # buffer mapped I/O: bit[416..447] -> MW12 bit[31..0]: egress::eg_intr_md_from_prsr.global_tstamp[31:0].0-31 + 50..51: H42 # buffer mapped I/O: bit[400..415] -> H42 bit[15..0]: egress::eg_intr_md_from_prsr.global_tstamp[47:32].32-47 + B7: 8 # value 8 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + intr_md: 48 + load: { byte0 : 28 } + buf_req: 29 + next: start + start: + match: [ byte0 ] + 0x00: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + load: { byte0 : 29, byte1 : 31 } + shift: 28 + buf_req: 32 + next: parse_bridged_pkt_910 + 0x03: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + shift: 28 + buf_req: 28 + next: parse_bridged_pkt_110 + 0x05: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + load: { byte0 : 31 } + shift: 28 + buf_req: 32 + next: parse_bridged_pkt_310 + 0x06: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + load: { byte0 : 29 } + shift: 28 + buf_req: 30 + next: parse_bridged_pkt_recirc + 0x08: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + shift: 28 + buf_req: 28 + next: start.$oob_stall_0 + 0x09: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + load: { byte0 : 29 } + shift: 28 + buf_req: 30 + next: parse_bridged_pkt_710_front + 0x0b: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + shift: 28 + buf_req: 28 + next: parse_bridged_pkt_910_ccm + 0x0c: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + load: { byte0 : 29 } + shift: 28 + buf_req: 30 + next: parse_bridged_pkt_recirc + 0x0f: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + shift: 28 + buf_req: 28 + next: parse_bridged_pkt_signal + 0x10: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + shift: 28 + buf_req: 28 + next: parse_bridged_pkt_110_recirc + 0x11: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + shift: 28 + buf_req: 28 + next: start.$oob_stall_1 + 0x48: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + shift: 28 + buf_req: 28 + next: parse_xon_xoff_mirrored_metadata + 0x49: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + shift: 28 + buf_req: 28 + next: parse_xon_xoff_mirrored_metadata + 0x27: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + shift: 28 + buf_req: 28 + next: parse_common_mirrored_metadata + 0x47: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + shift: 28 + buf_req: 28 + next: parse_common_mirrored_metadata + 0x30: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + shift: 28 + buf_req: 28 + next: parse_common_mirrored_metadata + 0x50: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + shift: 28 + buf_req: 28 + next: parse_common_mirrored_metadata + 0x31: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + shift: 28 + buf_req: 28 + next: parse_common_mirrored_metadata + 0x51: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + shift: 28 + buf_req: 28 + next: parse_common_mirrored_metadata + 0x32: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + shift: 28 + buf_req: 28 + next: parse_ig_uplink_ifit_mirrored_metadata + 0x**: + 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port + 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth + 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta + 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag + 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length + MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select + H9: 3 + # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid + intr_md: 10 + shift: 28 + buf_req: 28 + next: parse_ghost + parse_bridged_pkt_910: + match: [ byte1, byte0 ] + 0o1*****: + 0..3: W34 + # - bit[25] -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu + # - bit[26] -> W34 bit[5]: egress::eg_md.eg_ft.common.diag + # - bit[27] -> W34 bit[4]: egress::eg_md.eg_ft.flags.drop + # - bit[28..29] -> W34 bit[3..2]: egress::eg_md.eg_ft.lkp.ip_frag + # - bit[31] -> W34 bit[0]: egress::eg_md.eg_ft.flags.bypass_sec_acl + 1: B25 + # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast + 2: B24 + # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc + # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color + # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track + 4: B20 # egress::eg_md.eg_ft.common.dst_port + 5..6: H61 # egress::eg_md.eg_ft.common.hash + 9..10: H50 # bit[73..87] -> H50 bit[14..0]: egress::eg_md.eg_ft.common.oif + 9..12: W33 # bit[90..103] -> W33 bit[13..0]: egress::eg_md.eg_ft.ebridge.evlan + 13..14: H49 # bit[105..119] -> H49 bit[14..0]: egress::eg_md.eg_ft.common.iif + 21..24: W27 # egress::eg_md.eg_ft.lkp.l4_port_label_64[63:32].32-63 + 25..28: W26 # egress::eg_md.eg_ft.lkp.l4_port_label_64[31:0].0-31 + 29..30: MH8 # egress::eg_md.eg_ft.common.decap_len + shift: 31 + buf_req: 31 + next: parse_ext_ifit + 0x****: + 0..3: W34 + # - bit[25] -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu + # - bit[26] -> W34 bit[5]: egress::eg_md.eg_ft.common.diag + # - bit[27] -> W34 bit[4]: egress::eg_md.eg_ft.flags.drop + # - bit[28..29] -> W34 bit[3..2]: egress::eg_md.eg_ft.lkp.ip_frag + # - bit[31] -> W34 bit[0]: egress::eg_md.eg_ft.flags.bypass_sec_acl + 1: B25 + # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast + 2: B24 + # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc + # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color + # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track + 4: B20 # egress::eg_md.eg_ft.common.dst_port + 5..6: H61 # egress::eg_md.eg_ft.common.hash + 9..10: H50 # bit[73..87] -> H50 bit[14..0]: egress::eg_md.eg_ft.common.oif + 9..12: W33 # bit[90..103] -> W33 bit[13..0]: egress::eg_md.eg_ft.ebridge.evlan + 13..14: H49 # bit[105..119] -> H49 bit[14..0]: egress::eg_md.eg_ft.common.iif + 21..24: W27 # egress::eg_md.eg_ft.lkp.l4_port_label_64[63:32].32-63 + 25..28: W26 # egress::eg_md.eg_ft.lkp.l4_port_label_64[31:0].0-31 + 29..30: MH8 # egress::eg_md.eg_ft.common.decap_len + shift: 31 + buf_req: 31 + next: parse_bridged_pkt_910.$oob_stall_0 + parse_ext_ifit: + *: + 0..1: H68 # bit[4..15] -> H68 bit[11..0]: egress::eg_md.eg_ft.ifit.index + 2: B43 + # - bit[19] -> B43 bit[4]: egress::eg_md.eg_ft.ifit.ifit_decap_enable + # - bit[20] -> B43 bit[3]: egress::eg_md.eg_ft.ifit.loss_label + # - bit[21] -> B43 bit[2]: egress::eg_md.eg_ft.ifit.delay_stats_flag + H9: 8 # value 1 -> H9 bit[3]: egress::hdr.ext_ifit.$valid + load: { byte0 : 16, byte1 : 17 } + shift: 4 + buf_req: 18 + next: parse_ethernet + parse_ethernet: + match: [ byte0, byte1 ] + 0x0800: + 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 + 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 + 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 + 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 + 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type + 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type + H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid + load: { byte0 : 14, byte1 : 20, byte2 : 21, byte3 : 23 } + shift: 14 + buf_req: 24 + next: parse_ipv4 + 0x86dd: + 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 + 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 + 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 + 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 + 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type + 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type + H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid + shift: 14 + buf_req: 14 + next: parse_ipv6 + 0x8847: + 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 + 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 + 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 + 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 + 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type + 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type + H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid + shift: 14 + buf_req: 14 + next: parse_mpls + 0x8100: + 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 + 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 + 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 + 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 + 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type + 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type + H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid + load: { byte0 : 16, byte1 : 17 } + shift: 14 + buf_req: 18 + next: parse_vlan + 0x****: + 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 + 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 + 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 + 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 + 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type + 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type + H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid + shift: 14 + buf_req: 14 + next: parse_pad + parse_ipv4: + match: [ byte3, byte0, byte1, byte2 ] + 0b00010001****0101***0000000000000: + checksum 0: + type: RESIDUAL + mask: [ 0, 1, 10..11 ] + swap: 0 + start: 1 + end: 1 + dest: MH7 + end_pos: 19 + checksum 2: + type: CLOT + mask: [ 0 ] + swap: 0 + start: 1 + end: 1 + dest: clot 2 + 0..1: H34 + # - bit[0..3] -> H34 bit[15..12]: egress::hdr.eg_ft.ipv4.version + # - bit[4..7] -> H34 bit[11..8]: egress::hdr.eg_ft.ipv4.ihl + # - bit[8..15] -> H34 bit[7..0]: egress::hdr.eg_ft.ipv4.diffserv + 9: MB3 # egress::eg_md.eg_ft.lkp.ip_proto + 10..11: MH2 # egress::hdr.eg_ft.ipv4.hdr_checksum + 12..13: H58 # egress::eg_md.eg_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H63 # egress::eg_md.eg_ft.lkp.ip_src_addr[15:0].0-15 + 16..19: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 + H9: 32 # value 1 -> H9 bit[5]: egress::hdr.eg_ft.ipv4.$valid + clot 2 : + start: 0 + length: 20 + checksum: 2 + shift: 20 + buf_req: 20 + next: parse_udp + 0b00000110****0101***0000000000000: + checksum 0: + type: RESIDUAL + mask: [ 0, 1, 10..11 ] + swap: 0 + start: 1 + end: 1 + dest: MH7 + end_pos: 19 + checksum 2: + type: CLOT + mask: [ 0 ] + swap: 0 + start: 1 + end: 1 + dest: clot 2 + 0..1: H34 + # - bit[0..3] -> H34 bit[15..12]: egress::hdr.eg_ft.ipv4.version + # - bit[4..7] -> H34 bit[11..8]: egress::hdr.eg_ft.ipv4.ihl + # - bit[8..15] -> H34 bit[7..0]: egress::hdr.eg_ft.ipv4.diffserv + 9: MB3 # egress::eg_md.eg_ft.lkp.ip_proto + 10..11: MH2 # egress::hdr.eg_ft.ipv4.hdr_checksum + 12..13: H58 # egress::eg_md.eg_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H63 # egress::eg_md.eg_ft.lkp.ip_src_addr[15:0].0-15 + 16..19: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 + H9: 32 # value 1 -> H9 bit[5]: egress::hdr.eg_ft.ipv4.$valid + clot 2 : + start: 0 + length: 20 + checksum: 2 + shift: 20 + buf_req: 20 + next: parse_tcp + 0b00000001****0101***0000000000000: + checksum 0: + type: RESIDUAL + mask: [ 0, 1, 10..11 ] + swap: 0 + start: 1 + end: 1 + dest: MH7 + end_pos: 19 + checksum 2: + type: CLOT + mask: [ 0 ] + swap: 0 + start: 1 + end: 1 + dest: clot 2 + 0..1: H34 + # - bit[0..3] -> H34 bit[15..12]: egress::hdr.eg_ft.ipv4.version + # - bit[4..7] -> H34 bit[11..8]: egress::hdr.eg_ft.ipv4.ihl + # - bit[8..15] -> H34 bit[7..0]: egress::hdr.eg_ft.ipv4.diffserv + 9: MB3 # egress::eg_md.eg_ft.lkp.ip_proto + 10..11: MH2 # egress::hdr.eg_ft.ipv4.hdr_checksum + 12..13: H58 # egress::eg_md.eg_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H63 # egress::eg_md.eg_ft.lkp.ip_src_addr[15:0].0-15 + 16..19: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 + H9: 32 # value 1 -> H9 bit[5]: egress::hdr.eg_ft.ipv4.$valid + clot 2 : + start: 0 + length: 20 + checksum: 2 + shift: 20 + buf_req: 20 + next: parse_icmp + 0x***6****: + checksum 0: + type: RESIDUAL + mask: [ 0, 1, 10..11 ] + swap: 0 + start: 1 + end: 1 + dest: MH7 + end_pos: 19 + checksum 2: + type: CLOT + mask: [ 0 ] + swap: 0 + start: 1 + end: 1 + dest: clot 2 + 0..1: H34 + # - bit[0..3] -> H34 bit[15..12]: egress::hdr.eg_ft.ipv4.version + # - bit[4..7] -> H34 bit[11..8]: egress::hdr.eg_ft.ipv4.ihl + # - bit[8..15] -> H34 bit[7..0]: egress::hdr.eg_ft.ipv4.diffserv + 9: MB3 # egress::eg_md.eg_ft.lkp.ip_proto + 10..11: MH2 # egress::hdr.eg_ft.ipv4.hdr_checksum + 12..13: H58 # egress::eg_md.eg_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H63 # egress::eg_md.eg_ft.lkp.ip_src_addr[15:0].0-15 + 16..19: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 + H9: 32 # value 1 -> H9 bit[5]: egress::hdr.eg_ft.ipv4.$valid + clot 2 : + start: 0 + length: 20 + checksum: 2 + load: { byte0 : 6, byte1 : 7, byte2 : 9 } + shift: 20 + buf_req: 20 + next: parse_ipv4_options + 0x***5****: + checksum 0: + type: RESIDUAL + mask: [ 0, 1, 10..11 ] + swap: 0 + start: 1 + end: 1 + dest: MH7 + end_pos: 19 + checksum 2: + type: CLOT + mask: [ 0 ] + swap: 0 + start: 1 + end: 1 + dest: clot 2 + 0..1: H34 + # - bit[0..3] -> H34 bit[15..12]: egress::hdr.eg_ft.ipv4.version + # - bit[4..7] -> H34 bit[11..8]: egress::hdr.eg_ft.ipv4.ihl + # - bit[8..15] -> H34 bit[7..0]: egress::hdr.eg_ft.ipv4.diffserv + 9: MB3 # egress::eg_md.eg_ft.lkp.ip_proto + 10..11: MH2 # egress::hdr.eg_ft.ipv4.hdr_checksum + 12..13: H58 # egress::eg_md.eg_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H63 # egress::eg_md.eg_ft.lkp.ip_src_addr[15:0].0-15 + 16..19: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 + H9: 32 # value 1 -> H9 bit[5]: egress::hdr.eg_ft.ipv4.$valid + clot 2 : + start: 0 + length: 20 + checksum: 2 + shift: 20 + buf_req: 20 + next: parse_pad + 0x********: + checksum 0: + type: RESIDUAL + mask: [ 0, 1, 10..11 ] + swap: 0 + start: 1 + end: 1 + dest: MH7 + end_pos: 19 + checksum 2: + type: CLOT + mask: [ 0 ] + swap: 0 + start: 1 + end: 1 + dest: clot 2 + 0..1: H34 + # - bit[0..3] -> H34 bit[15..12]: egress::hdr.eg_ft.ipv4.version + # - bit[4..7] -> H34 bit[11..8]: egress::hdr.eg_ft.ipv4.ihl + # - bit[8..15] -> H34 bit[7..0]: egress::hdr.eg_ft.ipv4.diffserv + 9: MB3 # egress::eg_md.eg_ft.lkp.ip_proto + 10..11: MH2 # egress::hdr.eg_ft.ipv4.hdr_checksum + 12..13: H58 # egress::eg_md.eg_ft.lkp.ip_src_addr[31:16].16-31 + 14..15: H63 # egress::eg_md.eg_ft.lkp.ip_src_addr[15:0].0-15 + 16..19: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 + H9: 32 # value 1 -> H9 bit[5]: egress::hdr.eg_ft.ipv4.$valid + clot 2 : + start: 0 + length: 20 + checksum: 2 + shift: 20 + buf_req: 20 + next: parse_pad + parse_udp: + *: + 0..1: H59 # egress::eg_md.eg_ft.lkp.l4_src_port + 0..3: W32 # bit[16..31] -> W32 bit[15..0]: egress::eg_md.eg_ft.lkp.l4_dst_port + buf_req: 4 + next: parse_pad + parse_pad: + *: + B7: 32 + # - value 1 -> B7 bit[5]: egress::hdr.pad.$valid + # - value 1 -> B7 bit[5]: egress::hdr.pad.$valid + clot 0 : + start: 0 + length: 64 + buf_req: 0 + next: end + parse_tcp: + *: + 0..1: H59 # egress::eg_md.eg_ft.lkp.l4_src_port + 0..3: W32 # bit[16..31] -> W32 bit[15..0]: egress::eg_md.eg_ft.lkp.l4_dst_port + 10..13: W35 # bit[104..111] -> W35 bit[7..0]: egress::eg_md.eg_ft.lkp.tcp_flags + buf_req: 14 + next: parse_pad + parse_icmp: + *: + 0..1: H59 # egress::eg_md.eg_ft.lkp.l4_src_port + buf_req: 2 + next: parse_pad + parse_ipv4_options: + match: [ byte2, byte0, byte1 ] + 0b00010001***0000000000000: + 4..5: H59 # egress::eg_md.eg_ft.lkp.l4_src_port + 4..7: W32 # bit[48..63] -> W32 bit[15..0]: egress::eg_md.eg_ft.lkp.l4_dst_port + buf_req: 8 + next: parse_pad + 0b00000110***0000000000000: + 4..5: H59 # egress::eg_md.eg_ft.lkp.l4_src_port + 4..7: W32 # bit[48..63] -> W32 bit[15..0]: egress::eg_md.eg_ft.lkp.l4_dst_port + 14..17: W35 # bit[136..143] -> W35 bit[7..0]: egress::eg_md.eg_ft.lkp.tcp_flags + buf_req: 18 + next: parse_pad + 0b00000001***0000000000000: + 4..5: H59 # egress::eg_md.eg_ft.lkp.l4_src_port + buf_req: 6 + next: parse_pad + 0x******: + buf_req: 0 + next: parse_pad + parse_ipv6: + *: + 0..1: H34 + # - bit[0..3] -> H34 bit[15..12]: egress::hdr.eg_ft.ipv6.version + # - bit[4..11] -> H34 bit[11..4]: egress::hdr.eg_ft.ipv6.traffic_class + # - bit[12..15] -> H34 bit[3..0]: egress::hdr.eg_ft.ipv6.flow_label[19:16].16-19 + 2..3: H35 # egress::hdr.eg_ft.ipv6.flow_label[15:0].0-15 + 6: MB3 # egress::eg_md.eg_ft.lkp.ip_proto + 8..11: W20 # egress::eg_md.eg_ft.lkp.ip_src_addr[127:96].96-127 + 12..15: W19 # egress::eg_md.eg_ft.lkp.ip_src_addr[95:64].64-95 + 16..19: W18 # egress::eg_md.eg_ft.lkp.ip_src_addr[63:32].32-63 + 20..21: H58 # egress::eg_md.eg_ft.lkp.ip_src_addr[31:16].16-31 + 22..23: H63 # egress::eg_md.eg_ft.lkp.ip_src_addr[15:0].0-15 + 24..27: W25 # egress::eg_md.eg_ft.lkp.ip_dst_addr[127:96].96-127 + 28..31: W23 # egress::eg_md.eg_ft.lkp.ip_dst_addr[95:64].64-95 + H9: 64 # value 1 -> H9 bit[6]: egress::hdr.eg_ft.ipv6.$valid + clot 1 : + start: 4 + length: 36 + load: { byte0 : 6 } + shift: 32 + buf_req: 32 + next: parse_ipv6.$split_0 + parse_ipv6.$split_0: + match: [ byte0 ] + 0x06: + 0..3: W22 # egress::eg_md.eg_ft.lkp.ip_dst_addr[63:32].32-63 + 4..7: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 + # clot 1 (spilled) + shift: 8 + buf_req: 8 + next: parse_tcp + 0x11: + 0..3: W22 # egress::eg_md.eg_ft.lkp.ip_dst_addr[63:32].32-63 + 4..7: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 + # clot 1 (spilled) + shift: 8 + buf_req: 8 + next: parse_udp + 0x3a: + 0..3: W22 # egress::eg_md.eg_ft.lkp.ip_dst_addr[63:32].32-63 + 4..7: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 + # clot 1 (spilled) + shift: 8 + buf_req: 8 + next: parse_icmp + 0x2c: + 0..3: W22 # egress::eg_md.eg_ft.lkp.ip_dst_addr[63:32].32-63 + 4..7: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 + # clot 1 (spilled) + load: { byte0 : 8, byte1 : 10, byte2 : 11 } + shift: 8 + buf_req: 12 + next: parse_ipv6_frag + 0x**: + 0..3: W22 # egress::eg_md.eg_ft.lkp.ip_dst_addr[63:32].32-63 + 4..7: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 + # clot 1 (spilled) + shift: 8 + buf_req: 8 + next: parse_pad + parse_ipv6_frag: + match: [ byte0, byte1, byte2 ] + 0o0140000*: + 0: MB3 # egress::eg_md.eg_ft.lkp.ip_proto + H9: 128 # value 1 -> H9 bit[7]: egress::hdr.eg_ft.ipv6_frag.$valid + clot 4 : + start: 0 + length: 8 + shift: 8 + buf_req: 8 + next: parse_tcp + 0o0420000*: + 0: MB3 # egress::eg_md.eg_ft.lkp.ip_proto + H9: 128 # value 1 -> H9 bit[7]: egress::hdr.eg_ft.ipv6_frag.$valid + clot 4 : + start: 0 + length: 8 + shift: 8 + buf_req: 8 + next: parse_udp + 0o1640000*: + 0: MB3 # egress::eg_md.eg_ft.lkp.ip_proto + H9: 128 # value 1 -> H9 bit[7]: egress::hdr.eg_ft.ipv6_frag.$valid + clot 4 : + start: 0 + length: 8 + shift: 8 + buf_req: 8 + next: parse_icmp + 0x******: + 0: MB3 # egress::eg_md.eg_ft.lkp.ip_proto + H9: 128 # value 1 -> H9 bit[7]: egress::hdr.eg_ft.ipv6_frag.$valid + clot 4 : + start: 0 + length: 8 + shift: 8 + buf_req: 8 + next: parse_pad + parse_mpls: + *: + H9: 256 # value 1 -> H9 bit[8]: egress::hdr.eg_ft.mpls_vc_eg.$valid + clot 6 : + start: 0 + length: 4 + shift: 4 + buf_req: 4 + next: parse_pad + parse_vlan: + match: [ byte0, byte1 ] + 0x0800: + 0..1: H45 + # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp + # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi + # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid + 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type + 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type + B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + load: { byte0 : 4, byte1 : 10, byte2 : 11, byte3 : 13 } + shift: 4 + buf_req: 14 + next: parse_ipv4 + 0x86dd: + 0..1: H45 + # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp + # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi + # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid + 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type + 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type + B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv6 + 0x8847: + 0..1: H45 + # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp + # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi + # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid + 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type + 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type + B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_mpls + 0x8100: + 0..1: H45 + # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp + # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi + # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid + 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type + 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type + B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + load: { byte0 : 6, byte1 : 7 } + shift: 4 + buf_req: 8 + next: parse_vlan.$it1 + 0x****: + 0..1: H45 + # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp + # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi + # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid + 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type + 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type + B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_pad + parse_vlan.$it1: + match: [ byte0, byte1 ] + 0x0800: + 0..1: H44 + # - bit[0..2] -> H44 bit[15..13]: egress::hdr.eg_ft.vlan_tag[1].pcp + # - bit[3] -> H44 bit[12]: egress::hdr.eg_ft.vlan_tag[1].cfi + # - bit[4..15] -> H44 bit[11..0]: egress::hdr.eg_ft.vlan_tag[1].vid + 2..3: MH21 # egress::hdr.eg_ft.vlan_tag[1].ether_type + 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type + B7: 2 # value 2 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + load: { byte0 : 4, byte1 : 10, byte2 : 11, byte3 : 13 } + shift: 4 + buf_req: 14 + next: parse_ipv4 + 0x86dd: + 0..1: H44 + # - bit[0..2] -> H44 bit[15..13]: egress::hdr.eg_ft.vlan_tag[1].pcp + # - bit[3] -> H44 bit[12]: egress::hdr.eg_ft.vlan_tag[1].cfi + # - bit[4..15] -> H44 bit[11..0]: egress::hdr.eg_ft.vlan_tag[1].vid + 2..3: MH21 # egress::hdr.eg_ft.vlan_tag[1].ether_type + 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type + B7: 2 # value 2 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv6 + 0x8847: + 0..1: H44 + # - bit[0..2] -> H44 bit[15..13]: egress::hdr.eg_ft.vlan_tag[1].pcp + # - bit[3] -> H44 bit[12]: egress::hdr.eg_ft.vlan_tag[1].cfi + # - bit[4..15] -> H44 bit[11..0]: egress::hdr.eg_ft.vlan_tag[1].vid + 2..3: MH21 # egress::hdr.eg_ft.vlan_tag[1].ether_type + 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type + B7: 2 # value 2 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_mpls + 0x8100: + 0..1: H44 + # - bit[0..2] -> H44 bit[15..13]: egress::hdr.eg_ft.vlan_tag[1].pcp + # - bit[3] -> H44 bit[12]: egress::hdr.eg_ft.vlan_tag[1].cfi + # - bit[4..15] -> H44 bit[11..0]: egress::hdr.eg_ft.vlan_tag[1].vid + 2..3: MH21 # egress::hdr.eg_ft.vlan_tag[1].ether_type + 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type + B7: 2 # value 2 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + 0x****: + 0..1: H44 + # - bit[0..2] -> H44 bit[15..13]: egress::hdr.eg_ft.vlan_tag[1].pcp + # - bit[3] -> H44 bit[12]: egress::hdr.eg_ft.vlan_tag[1].cfi + # - bit[4..15] -> H44 bit[11..0]: egress::hdr.eg_ft.vlan_tag[1].vid + 2..3: MH21 # egress::hdr.eg_ft.vlan_tag[1].ether_type + 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type + B7: 2 # value 2 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_pad + parse_bridged_pkt_910.$oob_stall_0: + *: + load: { byte0 : 12, byte1 : 13 } + buf_req: 14 + next: parse_ethernet + parse_bridged_pkt_110: + *: + 1: B25 + # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast + 2: B24 + # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc + # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color + # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track + 3..4: MH8 # egress::eg_md.eg_ft.common.decap_len + 10: B20 # egress::eg_md.eg_ft.common.dst_port + load: { byte0 : 29, byte1 : 30 } + shift: 17 + buf_req: 31 + next: parse_ethernet + parse_bridged_pkt_310: + match: [ byte0 ] + 0x**: + 1: B25 + # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast + 2: B24 + # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc + # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color + # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track + 8: B20 # egress::eg_md.eg_ft.common.dst_port + 9..10: H50 # bit[73..87] -> H50 bit[14..0]: egress::eg_md.eg_ft.common.oif + W34: 64 # value 1 -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu + load: { byte0 : 27, byte1 : 28 } + shift: 15 + buf_req: 29 + next: parse_ethernet_310 + parse_ethernet_310: + match: [ byte0, byte1 ] + 0x8100: + 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 + 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 + 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 + 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 + 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type + 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type + H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid + load: { byte0 : 16, byte1 : 17 } + shift: 14 + buf_req: 18 + next: parse_vlan_310 + 0x0800: + 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 + 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 + 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 + 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 + 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type + 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type + H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid + shift: 14 + buf_req: 14 + next: parse_ipv4_310 + 0x86dd: + 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 + 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 + 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 + 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 + 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type + 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type + H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid + shift: 14 + buf_req: 14 + next: parse_ipv6_310 + 0x****: + 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 + 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 + 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 + 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 + 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type + 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type + H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid + shift: 14 + buf_req: 14 + next: end + parse_vlan_310: + match: [ byte0, byte1 ] + 0x8100: + 0..1: H45 + # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp + # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi + # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid + 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type + 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type + B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_vlan1_310 + 0x0800: + 0..1: H45 + # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp + # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi + # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid + 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type + 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type + B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv4_310 + 0x86dd: + 0..1: H45 + # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp + # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi + # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid + 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type + 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type + B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_ipv6_310 + 0x****: + 0..1: H45 + # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp + # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi + # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid + 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type + 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type + B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_vlan1_310: + *: + 0..1: H44 + # - bit[0..2] -> H44 bit[15..13]: egress::hdr.eg_ft.vlan_tag[1].pcp + # - bit[3] -> H44 bit[12]: egress::hdr.eg_ft.vlan_tag[1].cfi + # - bit[4..15] -> H44 bit[11..0]: egress::hdr.eg_ft.vlan_tag[1].vid + 2..3: MH21 # egress::hdr.eg_ft.vlan_tag[1].ether_type + 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type + B7: 2 # value 2 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_ipv4_310: + *: + checksum 0: + type: RESIDUAL + mask: [ 0, 1, 10..11 ] + swap: 0 + start: 1 + end: 1 + dest: MH7 + end_pos: 19 + checksum 2: + type: CLOT + mask: [ 0 ] + swap: 0 + start: 1 + end: 1 + dest: clot 2 + 0..1: H34 + # - bit[0..3] -> H34 bit[15..12]: egress::hdr.eg_ft.ipv4.version + # - bit[4..7] -> H34 bit[11..8]: egress::hdr.eg_ft.ipv4.ihl + # - bit[8..15] -> H34 bit[7..0]: egress::hdr.eg_ft.ipv4.diffserv + 10..11: MH2 # egress::hdr.eg_ft.ipv4.hdr_checksum + H9: 32 # value 1 -> H9 bit[5]: egress::hdr.eg_ft.ipv4.$valid + clot 2 : + start: 0 + length: 20 + checksum: 2 + shift: 20 + buf_req: 20 + next: end + parse_ipv6_310: + *: + 0..1: H34 + # - bit[0..3] -> H34 bit[15..12]: egress::hdr.eg_ft.ipv6.version + # - bit[4..11] -> H34 bit[11..4]: egress::hdr.eg_ft.ipv6.traffic_class + # - bit[12..15] -> H34 bit[3..0]: egress::hdr.eg_ft.ipv6.flow_label[19:16].16-19 + 2..3: H35 # egress::hdr.eg_ft.ipv6.flow_label[15:0].0-15 + H9: 64 # value 1 -> H9 bit[6]: egress::hdr.eg_ft.ipv6.$valid + clot 1 : + start: 4 + length: 36 + shift: 32 + buf_req: 32 + next: parse_ipv6_310.$split_0 + parse_ipv6_310.$split_0: + *: + # clot 1 (spilled) + shift: 8 + buf_req: 8 + next: end + parse_bridged_pkt_recirc: + match: [ byte0 ] + 0b011100**: + 1: B23 + # - bit[0..5] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[6] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[7] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 1: B25 + # - bit[0..5] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - bit[6] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + # - bit[7] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast + 2: B22 + # - bit[8..10] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[11..12] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[13] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[14] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[15] -> B22 bit[0]: egress::hdr.fabric_qos.track + 2: B24 + # - bit[8..10] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc + # - bit[11..12] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color + # - bit[15] -> B24 bit[0]: egress::eg_md.eg_ft.common.track + 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 13..14: H11 + # - bit[96] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[97..111] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + H9: 3584 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + B42: 22 # value 22 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id + clot 5 : + start: 3 + length: 9 + shift: 15 + buf_req: 15 + next: parse_pad + 0x**: + shift: 1 + buf_req: 1 + next: end + start.$oob_stall_0: + *: + load: { byte0 : 3, byte1 : 15 } + buf_req: 16 + next: parse_bridged_pkt_710_cpu + parse_bridged_pkt_710_cpu: + match: [ byte1, byte0 ] + 0b******000*******: + 0..3: W34 # bit[25] -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu + 1: B23 + # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 1: B25 + # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast + 2: B22 + # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track + 2: B24 + # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc + # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color + # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track + 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 13..14: H11 + # - bit[104] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[105..119] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + 16: B42 # egress::eg_md.eg_ft.common.cpu_eth_encap_id + H9: 3584 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + clot 5 : + start: 3 + length: 9 + load: { byte0 : 29, byte1 : 30 } + shift: 17 + buf_req: 31 + next: parse_ethernet_310 + 0b******100*******: + 0..3: W34 # bit[25] -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu + 1: B23 + # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 1: B25 + # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast + 2: B22 + # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track + 2: B24 + # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc + # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color + # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track + 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 13..14: H11 + # - bit[104] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[105..119] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + 16: B42 # egress::eg_md.eg_ft.common.cpu_eth_encap_id + H9: 3584 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + clot 5 : + start: 3 + length: 9 + shift: 17 + buf_req: 17 + next: parse_ipv4_310 + 0b******110*******: + 0..3: W34 # bit[25] -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu + 1: B23 + # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 1: B25 + # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast + 2: B22 + # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track + 2: B24 + # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc + # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color + # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track + 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 13..14: H11 + # - bit[104] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[105..119] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + 16: B42 # egress::eg_md.eg_ft.common.cpu_eth_encap_id + H9: 3584 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + clot 5 : + start: 3 + length: 9 + shift: 17 + buf_req: 17 + next: parse_ipv6_310 + 0b********1*******: + 0..3: W34 # bit[25] -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu + 1: B23 + # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 1: B25 + # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast + 2: B22 + # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track + 2: B24 + # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc + # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color + # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track + 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 13..14: H11 + # - bit[104] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[105..119] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + 16: B42 # egress::eg_md.eg_ft.common.cpu_eth_encap_id + H9: 3584 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + clot 5 : + start: 3 + length: 9 + load: { byte0 : 15 } + shift: 17 + buf_req: 17 + next: parse_extension_tunnel_decap + 0x****: + 0..3: W34 # bit[25] -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu + 1: B23 + # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 1: B25 + # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast + 2: B22 + # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track + 2: B24 + # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc + # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color + # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track + 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 13..14: H11 + # - bit[104] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[105..119] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + 16: B42 # egress::eg_md.eg_ft.common.cpu_eth_encap_id + H9: 3584 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + clot 5 : + start: 3 + length: 9 + load: { byte0 : 17 } + shift: 17 + buf_req: 18 + next: parse_depth_pad + parse_extension_tunnel_decap: + match: [ byte0 ] + 0b******00: + 1: B32 # egress::hdr.ext_tunnel_decap.vb + 2..3: MH19 # egress::hdr.ext_tunnel_decap.vh + H9: 4096 # value 1 -> H9 bit[12]: egress::hdr.ext_tunnel_decap.$valid + clot 7 : + start: 0 + length: 1 + load: { byte0 : 16, byte1 : 17 } + shift: 4 + buf_req: 18 + next: parse_ethernet_310 + 0b******10: + 1: B32 # egress::hdr.ext_tunnel_decap.vb + 2..3: MH19 # egress::hdr.ext_tunnel_decap.vh + H9: 4096 # value 1 -> H9 bit[12]: egress::hdr.ext_tunnel_decap.$valid + clot 7 : + start: 0 + length: 1 + shift: 4 + buf_req: 4 + next: parse_ipv4_310 + 0b******11: + 1: B32 # egress::hdr.ext_tunnel_decap.vb + 2..3: MH19 # egress::hdr.ext_tunnel_decap.vh + H9: 4096 # value 1 -> H9 bit[12]: egress::hdr.ext_tunnel_decap.$valid + clot 7 : + start: 0 + length: 1 + shift: 4 + buf_req: 4 + next: parse_ipv6_310 + 0x**: + 1: B32 # egress::hdr.ext_tunnel_decap.vb + 2..3: MH19 # egress::hdr.ext_tunnel_decap.vh + H9: 4096 # value 1 -> H9 bit[12]: egress::hdr.ext_tunnel_decap.$valid + clot 7 : + start: 0 + length: 1 + load: { byte0 : 4 } + shift: 4 + buf_req: 5 + next: parse_depth_pad + parse_depth_pad: + match: [ byte0 ] + 0b1*******: + load: { byte0 : 0 } + buf_req: 1 + next: parse_depth_pad_1 + 0x**: + load: { byte0 : 0 } + buf_req: 1 + next: parse_depth_pad_2 + parse_depth_pad_1: + match: [ byte0 ] + 0b1*******: + load: { byte0 : 0 } + buf_req: 1 + next: parse_depth_pad_2 + 0x**: + load: { byte0 : 0 } + buf_req: 1 + next: end + parse_depth_pad_2: + match: [ byte0 ] + 0b1*******: + load: { byte0 : 0 } + buf_req: 1 + next: end + 0x**: + buf_req: 0 + next: end + parse_bridged_pkt_710_front: + match: [ byte0 ] + 0b001101**: + 1: B23 + # - bit[0..5] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[6] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[7] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 1: B25 + # - bit[0..5] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - bit[6] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + # - bit[7] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast + 2: B22 + # - bit[8..10] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[11..12] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[13] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[14] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[15] -> B22 bit[0]: egress::hdr.fabric_qos.track + 2: B24 + # - bit[8..10] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc + # - bit[11..12] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color + # - bit[15] -> B24 bit[0]: egress::eg_md.eg_ft.common.track + 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 13..14: H11 + # - bit[96] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[97..111] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + 15..16: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 + 17..20: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 + 21..22: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 + 23..24: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 + 25..26: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 + 27..28: MH1 # egress::hdr.eg_ft.ethernet.ether_type + 27..28: MH15 # egress::eg_md.eg_ft.common.ether_type + H9: 3600 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + # - value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid + W34: 64 # value 1 -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu + clot 5 : + start: 3 + length: 9 + shift: 29 + buf_req: 29 + next: parse_bridged_pkt_spec_cpu_eth.$split_0 + 0b001111**: + 1: B23 + # - bit[0..5] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[6] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[7] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 1: B25 + # - bit[0..5] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - bit[6] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + # - bit[7] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast + 2: B22 + # - bit[8..10] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[11..12] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[13] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[14] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[15] -> B22 bit[0]: egress::hdr.fabric_qos.track + 2: B24 + # - bit[8..10] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc + # - bit[11..12] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color + # - bit[15] -> B24 bit[0]: egress::eg_md.eg_ft.common.track + 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 13..14: H11 + # - bit[96] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[97..111] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + H9: 3584 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + W34: 64 # value 1 -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu + clot 5 : + start: 3 + length: 9 + shift: 15 + buf_req: 15 + next: parse_bridged_pkt_c2c.$split_0 + 0b011101**: + 1: B23 + # - bit[0..5] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[6] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[7] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 1: B25 + # - bit[0..5] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - bit[7] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast + 2: B22 + # - bit[8..10] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[11..12] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[13] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[14] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[15] -> B22 bit[0]: egress::hdr.fabric_qos.track + 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 13..14: H11 + # - bit[96] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[97..111] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + B25: 2 # value 1 -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + H9: 3584 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + clot 5 : + start: 3 + length: 9 + shift: 15 + buf_req: 15 + next: parse_bridged_pkt_ipfix_ig.$split_0 + 0b011110**: + 1: B23 + # - bit[0..5] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[6] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[7] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 1: B25 + # - bit[0..5] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - bit[7] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast + 2: B22 + # - bit[8..10] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[11..12] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[13] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[14] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[15] -> B22 bit[0]: egress::hdr.fabric_qos.track + 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 13..14: H11 + # - bit[96] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[97..111] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + B25: 2 # value 1 -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + H9: 3584 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + clot 5 : + start: 3 + length: 9 + shift: 15 + buf_req: 15 + next: parse_bridged_pkt_ipfix_eg.$split_0 + 0b000111**: + 4: B20 # egress::eg_md.eg_ft.common.dst_port + 15: B23 + # - bit[112..117] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[118] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[119] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 16: B22 + # - bit[120..122] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[123..124] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[125] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[126] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[127] -> B22 bit[0]: egress::hdr.fabric_qos.track + 21..22: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 26: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 27..28: H11 + # - bit[208] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[209..223] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + H9: 3584 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + B42: 8 # value 8 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id + clot 5 : + start: 17 + length: 9 + shift: 29 + buf_req: 29 + next: parse_bridged_pkt_trace.$split_0 + 0b010110**: + 15: B23 + # - bit[112..117] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[118] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[119] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 16: B22 + # - bit[120..122] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[123..124] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[125] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[126] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[127] -> B22 bit[0]: egress::hdr.fabric_qos.track + 21..22: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 26: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 27..28: H11 + # - bit[208] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[209..223] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + H9: 3584 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + B42: 21 # value 21 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id + clot 5 : + start: 17 + length: 9 + shift: 29 + buf_req: 29 + next: parse_bridged_pkt_ccm_trace.$split_0 + 0b010101**: + 2: B24 + # - bit[8..10] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc + # - bit[11..12] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color + # - bit[15] -> B24 bit[0]: egress::eg_md.eg_ft.common.track + 4: B20 # egress::eg_md.eg_ft.common.dst_port + B25: 86 + # - value 21 -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - value 1 -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + load: { byte0 : 27, byte1 : 28 } + shift: 15 + buf_req: 29 + next: parse_mirror_ethernet + 0x**: + shift: 1 + buf_req: 1 + next: end + parse_bridged_pkt_spec_cpu_eth.$split_0: + *: + B42: 18 # value 18 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id + load: { byte0 : 0 } + buf_req: 1 + next: parse_depth_pad + parse_bridged_pkt_c2c.$split_0: + *: + B42: 17 # value 17 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id + load: { byte0 : 0 } + buf_req: 1 + next: parse_depth_pad + parse_bridged_pkt_ipfix_ig.$split_0: + *: + B42: 4 # value 4 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id + load: { byte0 : 12, byte1 : 13 } + buf_req: 14 + next: parse_mirror_ethernet + parse_mirror_ethernet: + match: [ byte0, byte1 ] + 0x893f: + 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 + 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 + 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 + 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 + 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type + 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type + H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid + load: { byte0 : 20, byte1 : 21 } + shift: 14 + buf_req: 22 + next: parse_mirror_1br + 0x****: + 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 + 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 + 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 + 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 + 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 + 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type + 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type + H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid + load: { byte0 : 14 } + shift: 14 + buf_req: 15 + next: parse_depth_pad + parse_mirror_1br: + match: [ byte0, byte1 ] + 0x8100: + 0..1: H47 + # - bit[0..2] -> H47 bit[15..13]: egress::hdr.eg_ft.br_tag.epcp + # - bit[3] -> H47 bit[12]: egress::hdr.eg_ft.br_tag.edei + # - bit[4..15] -> H47 bit[11..0]: egress::hdr.eg_ft.br_tag.ingress_ecid + 2..5: W8 + # - bit[16..17] -> W8 bit[31..30]: egress::hdr.eg_ft.br_tag.reserved + # - bit[18..19] -> W8 bit[29..28]: egress::hdr.eg_ft.br_tag.grp + # - bit[20..31] -> W8 bit[27..16]: egress::hdr.eg_ft.br_tag.ecid + # - bit[32..39] -> W8 bit[15..8]: egress::hdr.eg_ft.br_tag.ingress_ecid_ext + # - bit[40..47] -> W8 bit[7..0]: egress::hdr.eg_ft.br_tag.ecid_ext + 6..7: MH2 # egress::hdr.eg_ft.br_tag.ether_type + 6..7: MH15 # egress::eg_md.eg_ft.common.ether_type + B17: 1 # value 1 -> B17 bit[0]: egress::hdr.eg_ft.br_tag.$valid + shift: 8 + buf_req: 8 + next: parse_mirror_1br_vlan + 0x****: + 0..1: H47 + # - bit[0..2] -> H47 bit[15..13]: egress::hdr.eg_ft.br_tag.epcp + # - bit[3] -> H47 bit[12]: egress::hdr.eg_ft.br_tag.edei + # - bit[4..15] -> H47 bit[11..0]: egress::hdr.eg_ft.br_tag.ingress_ecid + 2..5: W8 + # - bit[16..17] -> W8 bit[31..30]: egress::hdr.eg_ft.br_tag.reserved + # - bit[18..19] -> W8 bit[29..28]: egress::hdr.eg_ft.br_tag.grp + # - bit[20..31] -> W8 bit[27..16]: egress::hdr.eg_ft.br_tag.ecid + # - bit[32..39] -> W8 bit[15..8]: egress::hdr.eg_ft.br_tag.ingress_ecid_ext + # - bit[40..47] -> W8 bit[7..0]: egress::hdr.eg_ft.br_tag.ecid_ext + 6..7: MH2 # egress::hdr.eg_ft.br_tag.ether_type + 6..7: MH15 # egress::eg_md.eg_ft.common.ether_type + B17: 1 # value 1 -> B17 bit[0]: egress::hdr.eg_ft.br_tag.$valid + shift: 8 + buf_req: 8 + next: end + parse_mirror_1br_vlan: + *: + 0..1: H45 + # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp + # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi + # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid + 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type + 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type + B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_bridged_pkt_ipfix_eg.$split_0: + *: + B42: 5 # value 5 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id + load: { byte0 : 12, byte1 : 13 } + buf_req: 14 + next: parse_mirror_ethernet + parse_bridged_pkt_trace.$split_0: + *: + B25: 2 # value 1 -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + load: { byte0 : 0 } + buf_req: 1 + next: parse_depth_pad + parse_bridged_pkt_ccm_trace.$split_0: + *: + B25: 2 # value 1 -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + load: { byte0 : 0 } + buf_req: 1 + next: parse_depth_pad + parse_bridged_pkt_910_ccm: + *: + 1: B23 + # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 1: B25 + # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast + 2: B22 + # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track + 2: B24 # bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track + 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 13..14: H11 + # - bit[104] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[105..119] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + H9: 3584 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + W34: 64 # value 1 -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu + clot 5 : + start: 3 + length: 9 + shift: 15 + buf_req: 15 + next: parse_bridged_pkt_910_ccm.$split_0 + parse_bridged_pkt_910_ccm.$split_0: + *: + B42: 11 # value 11 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id + load: { byte0 : 0 } + buf_req: 1 + next: parse_depth_pad + parse_bridged_pkt_signal: + *: + 1: B23 + # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 1: B25 + # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast + 2: B22 + # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track + 2: B24 + # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc + # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color + # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track + 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 13..14: H11 + # - bit[104] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[105..119] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + H9: 3584 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + B42: 19 # value 19 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id + clot 5 : + start: 3 + length: 9 + load: { byte0 : 23 } + shift: 23 + buf_req: 24 + next: parse_depth_pad + parse_bridged_pkt_110_recirc: + *: + 1: B23 + # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 1: B25 + # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast + 2: B22 + # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track + 2: B24 + # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc + # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color + # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track + 3..4: MH8 # egress::eg_md.eg_ft.common.decap_len + 9..10: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 14: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 15..16: H11 + # - bit[120] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[121..135] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + H9: 3584 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + B42: 24 # value 24 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id + clot 5 : + start: 5 + length: 9 + shift: 17 + buf_req: 17 + next: parse_pad + start.$oob_stall_1: + *: + load: { byte0 : 5 } + buf_req: 6 + next: parse_bridged_pkt_110_recirc_evpn + parse_bridged_pkt_110_recirc_evpn: + match: [ byte0 ] + 0b1*******: + 1: B23 + # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 1: B25 # bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + 2: B22 + # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track + 2: B24 # bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track + 3..4: MH8 # egress::eg_md.eg_ft.common.decap_len + 9..10: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 14: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 15..16: H11 + # - bit[120] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[121..135] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + 15..16: H49 # bit[121..135] -> H49 bit[14..0]: egress::eg_md.eg_ft.common.iif + H9: 3584 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + B42: 25 # value 25 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id + clot 5 : + start: 5 + length: 9 + load: { byte0 : 18 } + shift: 17 + buf_req: 19 + next: parse_bridged_pkt_110_evpn_ext + 0x**: + 1: B23 + # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 1: B25 # bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + 2: B22 + # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track + 2: B24 # bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track + 3..4: MH8 # egress::eg_md.eg_ft.common.decap_len + 9..10: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 14: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 15..16: H11 + # - bit[120] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[121..135] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + 15..16: H49 # bit[121..135] -> H49 bit[14..0]: egress::eg_md.eg_ft.common.iif + H9: 3584 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + B42: 25 # value 25 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id + clot 5 : + start: 5 + length: 9 + load: { byte0 : 29, byte1 : 30 } + shift: 17 + buf_req: 31 + next: parse_ethernet_evpn110 + parse_bridged_pkt_110_evpn_ext: + match: [ byte0 ] + 0b****0***: + 1: B32 # egress::hdr.ext_tunnel_decap.vb + 2..3: MH19 # egress::hdr.ext_tunnel_decap.vh + H9: 4096 # value 1 -> H9 bit[12]: egress::hdr.ext_tunnel_decap.$valid + clot 7 : + start: 0 + length: 1 + load: { byte0 : 16, byte1 : 17 } + shift: 4 + buf_req: 18 + next: parse_ethernet_evpn110 + 0b****1***: + 1: B32 # egress::hdr.ext_tunnel_decap.vb + 2..3: MH19 # egress::hdr.ext_tunnel_decap.vh + H9: 4096 # value 1 -> H9 bit[12]: egress::hdr.ext_tunnel_decap.$valid + clot 7 : + start: 0 + length: 1 + shift: 4 + buf_req: 4 + next: parse_pw_cw + parse_ethernet_evpn110: + match: [ byte0, byte1 ] + 0x8100: + 12..13: MH23 # egress::hdr.eg_ft.ethernet_evpn.ether_type + H9: 8192 # value 1 -> H9 bit[13]: egress::hdr.eg_ft.ethernet_evpn.$valid + clot 3 : + start: 0 + length: 12 + load: { byte0 : 16, byte1 : 17 } + shift: 14 + buf_req: 18 + next: parse_vlan_evpn110 + 0x****: + 12..13: MH23 # egress::hdr.eg_ft.ethernet_evpn.ether_type + H9: 8192 # value 1 -> H9 bit[13]: egress::hdr.eg_ft.ethernet_evpn.$valid + clot 3 : + start: 0 + length: 12 + shift: 14 + buf_req: 14 + next: end + parse_vlan_evpn110: + match: [ byte0, byte1 ] + 0x8100: + 0..1: H45 + # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp + # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi + # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid + 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type + B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: parse_vlan1_evpn110 + 0x****: + 0..1: H45 + # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp + # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi + # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid + 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type + B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_vlan1_evpn110: + *: + 0..1: H44 + # - bit[0..2] -> H44 bit[15..13]: egress::hdr.eg_ft.vlan_tag[1].pcp + # - bit[3] -> H44 bit[12]: egress::hdr.eg_ft.vlan_tag[1].cfi + # - bit[4..15] -> H44 bit[11..0]: egress::hdr.eg_ft.vlan_tag[1].vid + 2..3: MH21 # egress::hdr.eg_ft.vlan_tag[1].ether_type + B7: 2 # value 2 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid + shift: 4 + buf_req: 4 + next: end + parse_pw_cw: + *: + load: { byte0 : 16, byte1 : 17 } + shift: 4 + buf_req: 18 + next: parse_ethernet_evpn110 + parse_xon_xoff_mirrored_metadata: + *: + 0: B42 # egress::eg_md.eg_ft.common.cpu_eth_encap_id + 3: B21 # egress::eg_md.eg_ft.common.backpush_dst_port + B25: 2 # value 1 -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + load: { byte0 : 16, byte1 : 17 } + shift: 4 + buf_req: 18 + next: parse_mirror_ethernet + parse_common_mirrored_metadata: + *: + 0: B42 # egress::eg_md.eg_ft.common.cpu_eth_encap_id + 3: B20 # egress::eg_md.eg_ft.common.dst_port + 4: B23 + # - bit[32..37] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[38] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[39] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 5: B22 + # - bit[40..42] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[43..44] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[45] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[46] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[47] -> B22 bit[0]: egress::hdr.fabric_qos.track + 10..11: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 15: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 16..17: H11 + # - bit[128] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[129..143] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + H9: 3584 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + B25: 2 # value 1 -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + clot 5 : + start: 6 + length: 9 + load: { byte0 : 18 } + shift: 18 + buf_req: 19 + next: parse_depth_pad + parse_ig_uplink_ifit_mirrored_metadata: + *: + 2: B23 + # - bit[16..21] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[22] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[23] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 3: B22 + # - bit[24..26] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[27..28] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[29] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[30] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[31] -> B22 bit[0]: egress::hdr.fabric_qos.track + 8..9: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 13: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 14..15: H11 + # - bit[112] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[113..127] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + H9: 3584 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + B42: 26 # value 26 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id + clot 5 : + start: 4 + length: 9 + shift: 16 + buf_req: 16 + next: parse_ig_uplink_ifit_mirrored_metadata.$split_0 + parse_ig_uplink_ifit_mirrored_metadata.$split_0: + *: + B25: 2 # value 1 -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + load: { byte0 : 0 } + buf_req: 1 + next: parse_depth_pad + parse_ghost: + *: + 0: B23 + # - bit[0..5] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[6] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[7] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast + 1: B22 + # - bit[8..10] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc + # - bit[11..12] -> B22 bit[4..3]: egress::hdr.fabric_qos.color + # - bit[13] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable + # - bit[14] -> B22 bit[1]: egress::hdr.fabric_qos.BA + # - bit[15] -> B22 bit[0]: egress::hdr.fabric_qos.track + 6..7: MH20 # egress::hdr.fabric_data_template_plus.vh1 + 11: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 + 12..13: H11 + # - bit[96] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one + # - bit[97..111] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif + H9: 3584 + # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid + # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid + # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid + B25: 110 + # - value 27 -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - value 1 -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror + clot 5 : + start: 2 + length: 9 + load: { byte0 : 14 } + shift: 14 + buf_req: 15 + next: parse_depth_pad +deparser egress: + dictionary: + H48: H9(4) # egress::hdr.eg_ft.ethernet.dst_addr.32-47 if egress::hdr.eg_ft.ethernet.$valid + W9: H9(4) # egress::hdr.eg_ft.ethernet.dst_addr.0-31 if egress::hdr.eg_ft.ethernet.$valid + H60: H9(4) # egress::hdr.eg_ft.ethernet.src_addr.32-47 if egress::hdr.eg_ft.ethernet.$valid + H33: H9(4) # egress::hdr.eg_ft.ethernet.src_addr.16-31 if egress::hdr.eg_ft.ethernet.$valid + H32: H9(4) # egress::hdr.eg_ft.ethernet.src_addr.0-15 if egress::hdr.eg_ft.ethernet.$valid + MH1: H9(4) # egress::hdr.eg_ft.ethernet.ether_type if egress::hdr.eg_ft.ethernet.$valid + H47: B17(0) + # - bit[15..13]: egress::hdr.eg_ft.br_tag.epcp if egress::hdr.eg_ft.br_tag.$valid + # - bit[12]: egress::hdr.eg_ft.br_tag.edei if egress::hdr.eg_ft.br_tag.$valid + # - bit[11..0]: egress::hdr.eg_ft.br_tag.ingress_ecid if egress::hdr.eg_ft.br_tag.$valid + W8: B17(0) + # - bit[31..30]: egress::hdr.eg_ft.br_tag.reserved if egress::hdr.eg_ft.br_tag.$valid + # - bit[29..28]: egress::hdr.eg_ft.br_tag.grp if egress::hdr.eg_ft.br_tag.$valid + # - bit[27..16]: egress::hdr.eg_ft.br_tag.ecid if egress::hdr.eg_ft.br_tag.$valid + # - bit[15..8]: egress::hdr.eg_ft.br_tag.ingress_ecid_ext if egress::hdr.eg_ft.br_tag.$valid + # - bit[7..0]: egress::hdr.eg_ft.br_tag.ecid_ext if egress::hdr.eg_ft.br_tag.$valid + MH2: B17(0) # egress::hdr.eg_ft.br_tag.ether_type if egress::hdr.eg_ft.br_tag.$valid + B23: H9(9) + # - bit[7..2]: egress::hdr.fabric_base.pkt_type if egress::hdr.fabric_base.$valid + # - bit[1]: egress::hdr.fabric_base.is_mirror if egress::hdr.fabric_base.$valid + # - bit[0]: egress::hdr.fabric_base.is_mcast if egress::hdr.fabric_base.$valid + B22: H9(10) + # - bit[7..5]: egress::hdr.fabric_qos.tc if egress::hdr.fabric_qos.$valid + # - bit[4..3]: egress::hdr.fabric_qos.color if egress::hdr.fabric_qos.$valid + # - bit[2]: egress::hdr.fabric_qos.chgDSCP_disable if egress::hdr.fabric_qos.$valid + # - bit[1]: egress::hdr.fabric_qos.BA if egress::hdr.fabric_qos.$valid + # - bit[0]: egress::hdr.fabric_qos.track if egress::hdr.fabric_qos.$valid + clot 5: + pov: hdr.fabric_data_template_plus.$valid + 4 : MH20 + B33: H9(11) # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 if egress::hdr.fabric_data_template_plus.$valid + H11: H9(11) + # - bit[15]: egress::hdr.fabric_data_template_plus.one if egress::hdr.fabric_data_template_plus.$valid + # - bit[14..0]: egress::hdr.fabric_data_template_plus.iif if egress::hdr.fabric_data_template_plus.$valid + MH3: H9(14) # egress::hdr.fabric_eth_etype.ether_type if egress::hdr.fabric_eth_etype.$valid + H46: H9(15) # egress::hdr.fabric_timestamp.timestamp.32-47 if egress::hdr.fabric_timestamp.$valid + MW13: H9(15) # egress::hdr.fabric_timestamp.timestamp.0-31 if egress::hdr.fabric_timestamp.$valid + clot 7: + pov: hdr.ext_tunnel_decap.$valid + B32: H9(12) # egress::hdr.ext_tunnel_decap.vb if egress::hdr.ext_tunnel_decap.$valid + MH19: H9(12) # egress::hdr.ext_tunnel_decap.vh if egress::hdr.ext_tunnel_decap.$valid + clot 3: + pov: hdr.eg_ft.ethernet_evpn.$valid + MH23: H9(13) # egress::hdr.eg_ft.ethernet_evpn.ether_type if egress::hdr.eg_ft.ethernet_evpn.$valid + H45: B7(2) + # - bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp if egress::hdr.eg_ft.vlan_tag[0].$valid + # - bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi if egress::hdr.eg_ft.vlan_tag[0].$valid + # - bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid if egress::hdr.eg_ft.vlan_tag[0].$valid + MH22: B7(2) # egress::hdr.eg_ft.vlan_tag[0].ether_type if egress::hdr.eg_ft.vlan_tag[0].$valid + H44: B7(1) + # - bit[15..13]: egress::hdr.eg_ft.vlan_tag[1].pcp if egress::hdr.eg_ft.vlan_tag[1].$valid + # - bit[12]: egress::hdr.eg_ft.vlan_tag[1].cfi if egress::hdr.eg_ft.vlan_tag[1].$valid + # - bit[11..0]: egress::hdr.eg_ft.vlan_tag[1].vid if egress::hdr.eg_ft.vlan_tag[1].$valid + MH21: B7(1) # egress::hdr.eg_ft.vlan_tag[1].ether_type if egress::hdr.eg_ft.vlan_tag[1].$valid + clot 2: + pov: hdr.eg_ft.ipv4.$valid + 0 : H34 + 10 : full_checksum 4 + H34: H9(6) + # - bit[15..12]: egress::hdr.eg_ft.ipv6.version if egress::hdr.eg_ft.ipv6.$valid + # - bit[11..4]: egress::hdr.eg_ft.ipv6.traffic_class if egress::hdr.eg_ft.ipv6.$valid + # - bit[3..0]: egress::hdr.eg_ft.ipv6.flow_label.16-19 if egress::hdr.eg_ft.ipv6.$valid + H35: H9(6) # egress::hdr.eg_ft.ipv6.flow_label.0-15 if egress::hdr.eg_ft.ipv6.$valid + clot 1: + pov: hdr.eg_ft.ipv6.$valid + clot 4: + pov: hdr.eg_ft.ipv6_frag.$valid + clot 6: + pov: hdr.eg_ft.mpls_vc_eg.$valid + clot 0: + pov: hdr.pad.$valid + partial_checksum 4: + - H34(0..7): { pov: H9(5) } # bit[7..0]: egress::hdr.eg_ft.ipv4.diffserv if egress::hdr.eg_ft.ipv4.$valid + - MH7: { pov: H9(5) } # egress::eg_md.eg_ft.lkp.tmp_ipv4_checksum if egress::hdr.eg_ft.ipv4.$valid + full_checksum 4: + - partial_checksum 4: { pov: H9(5) } + - clot 2: { pov: H9(5) } + drop_ctl: { B16(1..3): B16(0) } # bit[3..1]: egress::eg_intr_md_for_dprsr.drop_ctl if egress::eg_intr_md_for_dprsr.drop_ctl.$valid + mirr_io_sel: { MH18(0..0): H9(0) } # bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select if egress::eg_intr_md_for_dprsr.mirror_io_select.$valid + mtu_trunc_len: { MH17(0..13): B7(4) } # bit[13..0]: egress::eg_intr_md_for_dprsr.mtu_trunc_len if egress::eg_intr_md_for_dprsr.mtu_trunc_len.$valid + egress_unicast_port: { MH16(0..8): H9(1) } # bit[8..0]: egress::eg_intr_md.egress_port if egress::eg_intr_md.egress_port.$valid + mirror: + select: { B4(0..3): H9(2) } # bit[3..0]: egress::eg_intr_md_for_dprsr.mirror_type + 1: + - MB9 # egress::eg_md.eg_ft.mirror.session_id + - B19 + # - bit[7..5]: egress::eg_md.eg_ft.mirror.src + # - bit[4..0]: egress::eg_md.eg_ft.mirror.type + - MB9 # egress::eg_md.eg_ft.mirror.session_id + - B23 + # - bit[7..2]: egress::hdr.fabric_base.pkt_type + # - bit[1]: egress::hdr.fabric_base.is_mirror + # - bit[0]: egress::hdr.fabric_base.is_mcast + - B21 # egress::eg_md.eg_ft.common.backpush_dst_port + - B27 # egress::eg_md.eg_ft.mirror.flags + - B20 # egress::eg_md.eg_ft.common.dst_port + - H61 # egress::eg_md.eg_ft.common.hash + - H51 # egress::eg_md.eg_ft.common.mirror_dst_eport + - H50(0..14) # bit[14..0]: egress::eg_md.eg_ft.common.oif + - H63 # egress::eg_md.eg_ft.ifit.var_h1 + - H49(0..14) # bit[14..0]: egress::eg_md.eg_ft.common.iif + 7: + - MB9 # egress::eg_md.eg_ft.mirror.session_id + - B19 + # - bit[7..5]: egress::eg_md.eg_ft.mirror.src + # - bit[4..0]: egress::eg_md.eg_ft.mirror.type + - MB9 # egress::eg_md.eg_ft.mirror.session_id + - H51 # egress::eg_md.eg_ft.common.mirror_dst_eport + - B25 + # - bit[7..2]: egress::eg_md.eg_ft.common.pkt_type + # - bit[1]: egress::eg_md.eg_ft.common.is_mirror + # - bit[0]: egress::eg_md.eg_ft.common.is_mcast + - B24 + # - bit[7..5]: egress::eg_md.eg_ft.qos.tc + # - bit[4..3]: egress::eg_md.eg_ft.qos.color + # - bit[0]: egress::eg_md.eg_ft.common.track + - B26 # egress::eg_md.eg_ft.common.pipeline_location + - B26 # egress::eg_md.eg_ft.common.pipeline_location + - H62 # egress::eg_md.eg_ft.common.trace_counter + - MB11 # egress::eg_md.eg_ft.common.drop_reason + - MB11 # egress::eg_md.eg_ft.common.drop_reason + - MW4 # egress::eg_md.eg_ft.common.deq_timedelta + - H49(0..14) # bit[14..0]: egress::eg_md.eg_ft.common.iif + - H46 # egress::hdr.fabric_timestamp.timestamp.32-47 + - MW13 # egress::hdr.fabric_timestamp.timestamp.0-31 +stage 0 ingress: + mpr_stage_id: 0 + mpr_bus_dep_glob_exec: 0x0 + mpr_bus_dep_long_brch: 0x0 + mpr_always_run: 0x201f + phase0_match IgParser_front.$PORT_METADATA: + p4: + name: IgParser_front.$PORT_METADATA + size: 288 + preferred_match_type: exact + match_type: exact + size: 288 + p4_param_order: + ig_intr_md.ingress_port: { type: exact, size: 9 } + format: {port_type: 120..123, is_zero: 112..112} + constant_value: 0 + actions: + set_port_metadata: + - handle: 0x20000000 + - p4_param_order: { port_type: 4, is_zero: 1 } + ternary_match tbl_set_egress_port 0: + always_run: true + p4: { name: tbl_set_egress_port, hidden: true } + hit: [ END ] + miss: END + indirect: tbl_set_egress_port$tind + ternary_indirect tbl_set_egress_port$tind: + row: 0 + bus: 0 + format: { action: 0..0 } + instruction: tbl_set_egress_port$tind(action, $DEFAULT) + actions: + set_egress_port(0, 11): + - hit_allowed: { allowed: true } + - default_action: { allowed: true, is_constant: true } + - handle: 0x20000001 + - next_table: 0 + - set ig_intr_md_for_tm.ucast_egress_port.$valid, 1 + - set MW9, 4 + default_action: set_egress_port + + +primitives: "switch_tofino_x1.prim.json" +dynhash: "switch_tofino_x1.dynhash.json" diff --git a/backends/tofino/bf-asm/test/stf/p4c-5198.stf b/backends/tofino/bf-asm/test/stf/p4c-5198.stf new file mode 100644 index 00000000000..6aa0911799a --- /dev/null +++ b/backends/tofino/bf-asm/test/stf/p4c-5198.stf @@ -0,0 +1,11 @@ +packet 20 \ + 00 14 00 4b 2e a3 48 40 01 00 00 00 00 00 00 00 \ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ + 00 11 11 11 11 11 00 22 22 22 22 22 81 00 03 ea \ + 81 00 00 14 08 00 45 00 00 4e 00 01 00 00 40 06 + +expect 4 \ + 00 00 11 11 11 11 11 00 22 22 22 22 22 81 00 03 \ + ea 81 00 00 14 08 00 45 00 00 4e 00 01 00 00 40 \ + 06 + diff --git a/backends/tofino/bf-asm/test/stf/simple_counter.p4 b/backends/tofino/bf-asm/test/stf/simple_counter.p4 new file mode 100644 index 00000000000..1421c8b4736 --- /dev/null +++ b/backends/tofino/bf-asm/test/stf/simple_counter.p4 @@ -0,0 +1,73 @@ + +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + c1 : 8; + c2 : 8; + c3 : 8; + c4 : 8; + } +} + +header data_t data; + +parser start { + extract(data); + return ingress; +} +action c1_2(val1, val2) { + modify_field(data.c1, val1); + modify_field(data.c2, val2); +} + +action c3_4(val3, val4, port) { + modify_field(data.c3, val3); + modify_field(data.c4, val4); + modify_field(standard_metadata.egress_spec, port); +} + +table test1 { + reads { + data.f1 : exact; + } + actions { + c1_2; + } +} + +table test2 { + reads { + data.f2 : exact; + } + actions { + c3_4; + } + size: 1024; +} + +counter cnt { + type: packets; + direct: test1; +} + +control ingress { + apply(test1); + apply(test2); +} diff --git a/backends/tofino/bf-asm/test/stf/simple_counter.stf b/backends/tofino/bf-asm/test/stf/simple_counter.stf new file mode 100644 index 00000000000..ac66866e825 --- /dev/null +++ b/backends/tofino/bf-asm/test/stf/simple_counter.stf @@ -0,0 +1,15 @@ + +add test1 data.f1:0x01010101 c1_2(val1:0x01, val2:0x02) +add test1 data.f1:0x02020202 c1_2(val1:0x10, val2:0x20) + +add test2 data.f2:0x03030303 c3_4(val3:0x03, val4:0x04, port:1) +add test2 data.f2:0x04040404 c3_4(val3:0x30, val4:0x40, port:2) + +expect 1 01010101 03030303 01 02 03 04 +packet 0 01010101 03030303 55 66 77 88 +expect 2 01010101 04040404 01 02 30 40 +packet 0 01010101 04040404 55 66 77 88 +expect 1 02020202 03030303 10 20 03 04 +packet 0 02020202 03030303 99 88 77 66 +expect 2 02020202 04040404 10 20 30 40 +packet 0 02020202 04040404 14 25 36 47 diff --git a/backends/tofino/bf-asm/test/ternary_match0.p4 b/backends/tofino/bf-asm/test/ternary_match0.p4 new file mode 100644 index 00000000000..df0c0f900c0 --- /dev/null +++ b/backends/tofino/bf-asm/test/ternary_match0.p4 @@ -0,0 +1,34 @@ + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } + +table test1 { + reads { + data.f1 : ternary; + } + actions { + noop; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/ternary_match1.p4 b/backends/tofino/bf-asm/test/ternary_match1.p4 new file mode 100644 index 00000000000..05684341c80 --- /dev/null +++ b/backends/tofino/bf-asm/test/ternary_match1.p4 @@ -0,0 +1,40 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setb1(val, port) { + modify_field(data.b1, val); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +table test1 { + reads { + data.f1 : ternary; + } + actions { + setb1; + noop; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/ternary_match1.stf b/backends/tofino/bf-asm/test/ternary_match1.stf new file mode 100644 index 00000000000..50bdd050eed --- /dev/null +++ b/backends/tofino/bf-asm/test/ternary_match1.stf @@ -0,0 +1,18 @@ + +tcam_2bit_mode TRUE + +add test1 0 data.f1:0x****0101 setb1(val:0x7f, port:2) + +#write_raw_tcam 0:23:0 00000101 & 0000ffff +# for some reason, address 0 in the tcam is match address 7 for tind lookup? +#write_raw_sram 0:2:3 00fe0004 & 1ffffffff << 64 + +add test1 503 data.f1:0x****0202 setb1(val:7, port:3) + +#write_raw_tcam 0:23:503 00000202 & 0000ffff +#write_raw_sram 0:2:255 000e0006 & 1ffffffff << 0 + +expect 2 00000101 ******** ******** ******** 7f 66 +packet 0 00000101 00000202 00000303 00000404 55 66 77 88 +expect 3 00000202 ******** ******** ******** 07 66 +packet 1 00000202 00000303 00000404 00000404 55 66 77 88 diff --git a/backends/tofino/bf-asm/test/ternary_match2.p4 b/backends/tofino/bf-asm/test/ternary_match2.p4 new file mode 100644 index 00000000000..7bc043c3857 --- /dev/null +++ b/backends/tofino/bf-asm/test/ternary_match2.p4 @@ -0,0 +1,41 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setb1(val, port) { + modify_field(data.b1, val); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +table test1 { + reads { + data.f1 : ternary; + } + actions { + setb1; + noop; + } + size: 10000; +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/ternary_match2.stf b/backends/tofino/bf-asm/test/ternary_match2.stf new file mode 100644 index 00000000000..c1152cf9a2e --- /dev/null +++ b/backends/tofino/bf-asm/test/ternary_match2.stf @@ -0,0 +1,84 @@ + +tcam_2bit_mode TRUE + +add test1 0 data.f1:0b*******************************1 setb1(port:4, val:0) +add test1 600 data.f1:0b******************************1* setb1(port:4, val:1) +add test1 1200 data.f1:0b*****************************1** setb1(port:4, val:2) +add test1 1800 data.f1:0b****************************1*** setb1(port:4, val:3) +add test1 2400 data.f1:0b***************************1**** setb1(port:4, val:4) +add test1 3000 data.f1:0b**************************1***** setb1(port:4, val:5) +add test1 3500 data.f1:0b*************************1****** setb1(port:4, val:6) +add test1 4000 data.f1:0b************************1******* setb1(port:4, val:7) +add test1 4500 data.f1:0b***********************1******** setb1(port:4, val:8) +add test1 5000 data.f1:0b**********************1********* setb1(port:4, val:9) +add test1 5500 data.f1:0b*********************1********** setb1(port:4, val:10) +add test1 6000 data.f1:0b********************1*********** setb1(port:4, val:11) +add test1 6500 data.f1:0b*******************1************ setb1(port:4, val:12) +add test1 7000 data.f1:0b******************1************* setb1(port:4, val:13) +add test1 7500 data.f1:0b*****************1************** setb1(port:4, val:14) +add test1 8000 data.f1:0b****************1*************** setb1(port:4, val:15) +add test1 8500 data.f1:0b***************1**************** setb1(port:4, val:16) +add test1 9000 data.f1:0b**************1***************** setb1(port:4, val:17) +add test1 9500 data.f1:0b*************1****************** setb1(port:4, val:18) +add test1 9999 data.f1:0b************1******************* setb1(port:4, val:19) + +expect 4 00000001 ******** ******** ******** 00 66 +packet 0 00000001 02020202 03030303 04040404 55 66 77 88 +wait +expect 4 00000003 ******** ******** ******** 01 66 +packet 0 00000003 02020202 03030303 04040404 55 66 77 88 +wait +expect 4 00000007 ******** ******** ******** 02 66 +packet 0 00000007 02020202 03030303 04040404 55 66 77 88 +wait +expect 4 0000000f ******** ******** ******** 03 66 +packet 0 0000000f 02020202 03030303 04040404 55 66 77 88 +wait +expect 4 0000001f ******** ******** ******** 04 66 +packet 0 0000001f 02020202 03030303 04040404 55 66 77 88 +wait +expect 4 0000003f ******** ******** ******** 05 66 +packet 0 0000003f 02020202 03030303 04040404 55 66 77 88 +wait +expect 4 0000007f ******** ******** ******** 06 66 +packet 0 0000007f 02020202 03030303 04040404 55 66 77 88 +wait +expect 4 000000ff ******** ******** ******** 07 66 +packet 0 000000ff 02020202 03030303 04040404 55 66 77 88 +wait +expect 4 000001ff ******** ******** ******** 08 66 +packet 0 000001ff 02020202 03030303 04040404 55 66 77 88 +wait +expect 4 000003ff ******** ******** ******** 09 66 +packet 0 000003ff 02020202 03030303 04040404 55 66 77 88 +wait +expect 4 000007ff ******** ******** ******** 0a 66 +packet 0 000007ff 02020202 03030303 04040404 55 66 77 88 +wait +expect 4 00000fff ******** ******** ******** 0b 66 +packet 0 00000fff 02020202 03030303 04040404 55 66 77 88 +wait +expect 4 00001fff ******** ******** ******** 0c 66 +packet 0 00001fff 02020202 03030303 04040404 55 66 77 88 +wait +expect 4 00003fff ******** ******** ******** 0d 66 +packet 0 00003fff 02020202 03030303 04040404 55 66 77 88 +wait +expect 4 00007fff ******** ******** ******** 0e 66 +packet 0 00007fff 02020202 03030303 04040404 55 66 77 88 +wait +expect 4 0000ffff ******** ******** ******** 0f 66 +packet 0 0000ffff 02020202 03030303 04040404 55 66 77 88 +wait +expect 4 0001ffff ******** ******** ******** 10 66 +packet 0 0001ffff 02020202 03030303 04040404 55 66 77 88 +wait +expect 4 0003ffff ******** ******** ******** 11 66 +packet 0 0003ffff 02020202 03030303 04040404 55 66 77 88 +wait +expect 4 0007ffff ******** ******** ******** 12 66 +packet 0 0007ffff 02020202 03030303 04040404 55 66 77 88 +wait +expect 4 000fffff ******** ******** ******** 13 66 +packet 0 000fffff 02020202 03030303 04040404 55 66 77 88 +wait diff --git a/backends/tofino/bf-asm/test/ternary_match3.p4 b/backends/tofino/bf-asm/test/ternary_match3.p4 new file mode 100644 index 00000000000..15dbef5f6b7 --- /dev/null +++ b/backends/tofino/bf-asm/test/ternary_match3.p4 @@ -0,0 +1,43 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setb1(val, port) { + modify_field(data.b1, val); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +table test1 { + reads { + data.f1 : ternary; + data.f2 : ternary; + data.f3 : ternary; + data.f4 : ternary; + } + actions { + setb1; + noop; + } +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/ternary_match3.stf b/backends/tofino/bf-asm/test/ternary_match3.stf new file mode 100644 index 00000000000..a3f3a4c5ca9 --- /dev/null +++ b/backends/tofino/bf-asm/test/ternary_match3.stf @@ -0,0 +1,7 @@ + +tcam_2bit_mode TRUE + +add test1 0 data.f1:0x10111213 data.f2:0x20212223 data.f3:0x30313233 data.f4:0x40414243 setb1(val:0x7f, port:2) + +expect 2 10111213 ******** ******** ******** 7f 66 +packet 0 10111213 20212223 30313233 40414243 55 66 77 88 diff --git a/backends/tofino/bf-asm/test/ternary_match4.p4 b/backends/tofino/bf-asm/test/ternary_match4.p4 new file mode 100644 index 00000000000..592e69ee0d1 --- /dev/null +++ b/backends/tofino/bf-asm/test/ternary_match4.p4 @@ -0,0 +1,44 @@ +#include "tofino/intrinsic_metadata.p4" + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 32; + f4 : 32; + b1 : 8; + b2 : 8; + b3 : 8; + b4 : 8; + } +} +header data_t data; + +parser start { + extract(data); + return ingress; +} + +action noop() { } +action setb1(val, port) { + modify_field(data.b1, val); + modify_field(ig_intr_md_for_tm.ucast_egress_port, port); +} + +table test1 { + reads { + data.f1 : ternary; + data.f2 : ternary; + data.f3 : ternary; + data.f4 : ternary; + } + actions { + setb1; + noop; + } + size : 10000; +} + +control ingress { + apply(test1); +} diff --git a/backends/tofino/bf-asm/test/ternary_match4.stf b/backends/tofino/bf-asm/test/ternary_match4.stf new file mode 100644 index 00000000000..b3dc00da2fc --- /dev/null +++ b/backends/tofino/bf-asm/test/ternary_match4.stf @@ -0,0 +1,84 @@ + +tcam_2bit_mode TRUE + +add test1 0 data.f1:0x*******1 setb1(port:4, val:0) +add test1 600 data.f1:0x******1* setb1(port:4, val:1) +add test1 1200 data.f1:0x*****1** setb1(port:4, val:2) +add test1 1800 data.f1:0x****1*** setb1(port:4, val:3) +add test1 2400 data.f1:0x***1**** setb1(port:4, val:4) +add test1 3000 data.f1:0x**1***** setb1(port:4, val:5) +add test1 3500 data.f1:0x*1****** setb1(port:4, val:6) +add test1 4000 data.f1:0x1******* setb1(port:4, val:7) +add test1 4500 data.f2:0x*******1 setb1(port:4, val:8) +add test1 5000 data.f2:0x******1* setb1(port:4, val:9) +add test1 5500 data.f2:0x*****1** setb1(port:4, val:10) +add test1 6000 data.f2:0x****1*** setb1(port:4, val:11) +add test1 6500 data.f2:0x***1**** setb1(port:4, val:12) +add test1 7000 data.f2:0x**1***** setb1(port:4, val:13) +add test1 7500 data.f2:0x*1****** setb1(port:4, val:14) +add test1 8000 data.f2:0x1******* setb1(port:4, val:15) +add test1 8500 data.f3:0x*******1 setb1(port:4, val:16) +add test1 9000 data.f3:0x******1* setb1(port:4, val:17) +add test1 9500 data.f3:0x*****1** setb1(port:4, val:18) +add test1 9999 data.f3:0x****1*** setb1(port:4, val:19) + +expect 4 00000001 ******** ******** ******** 00 66 +packet 0 00000001 00000000 00000000 00000000 55 66 77 88 +wait +expect 4 00000011 ******** ******** ******** 01 66 +packet 0 00000011 00000000 00000000 00000000 55 66 77 88 +wait +expect 4 00000111 ******** ******** ******** 02 66 +packet 0 00000111 00000000 00000000 00000000 55 66 77 88 +wait +expect 4 00001111 ******** ******** ******** 03 66 +packet 0 00001111 00000000 00000000 00000000 55 66 77 88 +wait +expect 4 00011111 ******** ******** ******** 04 66 +packet 0 00011111 00000000 00000000 00000000 55 66 77 88 +wait +expect 4 00111111 ******** ******** ******** 05 66 +packet 0 00111111 00000000 00000000 00000000 55 66 77 88 +wait +expect 4 01111111 ******** ******** ******** 06 66 +packet 0 01111111 00000000 00000000 00000000 55 66 77 88 +wait +expect 4 11111111 ******** ******** ******** 07 66 +packet 0 11111111 00000000 00000000 00000000 55 66 77 88 +wait +expect 4 11111111 ******** ******** ******** 08 66 +packet 0 11111111 00000001 00000000 00000000 55 66 77 88 +wait +expect 4 11111111 ******** ******** ******** 09 66 +packet 0 11111111 00000011 00000000 00000000 55 66 77 88 +wait +expect 4 11111111 ******** ******** ******** 0a 66 +packet 0 11111111 00000111 00000000 00000000 55 66 77 88 +wait +expect 4 11111111 ******** ******** ******** 0b 66 +packet 0 11111111 00001111 00000000 00000000 55 66 77 88 +wait +expect 4 11111111 ******** ******** ******** 0c 66 +packet 0 11111111 00011111 00000000 00000000 55 66 77 88 +wait +expect 4 11111111 ******** ******** ******** 0d 66 +packet 0 11111111 00111111 00000000 00000000 55 66 77 88 +wait +expect 4 11111111 ******** ******** ******** 0e 66 +packet 0 11111111 01111111 00000000 00000000 55 66 77 88 +wait +expect 4 11111111 ******** ******** ******** 0f 66 +packet 0 11111111 11111111 00000000 00000000 55 66 77 88 +wait +expect 4 11111111 ******** ******** ******** 10 66 +packet 0 11111111 11111111 00000001 00000000 55 66 77 88 +wait +expect 4 11111111 ******** ******** ******** 11 66 +packet 0 11111111 11111111 00000011 00000000 55 66 77 88 +wait +expect 4 11111111 ******** ******** ******** 12 66 +packet 0 11111111 11111111 00000111 00000000 55 66 77 88 +wait +expect 4 11111111 ******** ******** ******** 13 66 +packet 0 11111111 11111111 00001111 00000000 55 66 77 88 +wait diff --git a/backends/tofino/bf-asm/test/test-bfas-bin b/backends/tofino/bf-asm/test/test-bfas-bin new file mode 100755 index 00000000000..636992e3962 --- /dev/null +++ b/backends/tofino/bf-asm/test/test-bfas-bin @@ -0,0 +1,144 @@ +#!/bin/bash + +shopt -s nullglob +set -o pipefail + +TESTDIR=$(cd $(dirname $0); pwd -P) +LOG=faillog.txt + +function findbin() { + for d in \ + $PWD \ + $PWD/.. \ + $PWD/../.. \ + $PWD/../../.. \ + $PWD/../../../.. \ + $TESTDIR/.. \ + $TESTDIR/../.. \ + ; do + for f in $(find $d -name '*test*' -prune -o -executable -type f -name $1); do + if [ "$f" -nt "$found" ]; then + found="$f" + fi + done + if [ -n "$found" ]; then + break; + fi + done + if [ -z "$found" ]; then + found=$(which $1) + fi + if [ -z "$found" ]; then + echo >&2 "Can't find $1 executable" + echo false + else + echo $found + fi +} + +BFAS=bfas #$(findbin bfas) +echo "BFAS=$BFAS" +BFLINK=bflink #$(findbin bflink) +echo "BFLINK=$BFLINK" +BFDUMPBIN=bfdumpbin #$(findbin bfdumpbin) +echo "BFDUMPBIN=$BFDUMPBIN" + +filter_zero="cat" +do_sort="cat" +target="tofino" +remove_temps=true + +while expr "$1" : - >/dev/null; do + case $1 in + --tofino) + target=tofino + ;; + --jbay) + target=tofino2 + ;; + --sort) + do_sort="sort" + ;; + --filter_zero) + filter_zero="grep -v '^R.*: 00000000$'" + ;; + --preserve) + remove_temps=false + ;; + -*) + echo >&2 "unknown argument $1" + ;; + esac + shift +done + +function test_bfa() { + local targ + targ=$target + dir=$(dirname $1) + name=$(basename $1) + if expr $name : '.*\.tfa' >/dev/null; then + targ=tofino + fi + if expr $name : '.*\.jba' >/dev/null; then + targ=tofino2 + fi + echo -n $1 + echo $1: >&2 + pushd $dir >/dev/null + rm -rf tmp-$name.out + rv=0 + mkdir tmp-$name.out + if $BFAS -t $targ --gen_json --singlepipe -vvvvl tmp-$name.out/bfas.config.log $name -o tmp-$name.out; then + pushd tmp-$name.out >/dev/null + if [ -r tofino.bin ]; then + $BFDUMPBIN -H -L tofino.bin | $filter_zero | $do_sort >bfas.dump + elif [ -r tofino2.bin ]; then + $BFDUMPBIN -H -L tofino2.bin | $filter_zero | $do_sort >bfas.dump + else + echo " no binary?" + rv=1 + fi + if (( rv == 0 )); then + $BFLINK -s -o walle.bin *.cfg.json >&2 + $BFDUMPBIN -H -L walle.bin | $filter_zero | $do_sort >walle.dump + if diff -u bfas.dump walle.dump >&2; then + echo " PASS" + else + echo " mismatch" + rv=1; + fi + fi + popd >/dev/null + else + echo " bfas failed" + rv=2 + fi + if $remove_temps; then + rm -rf tmp-$name.out + fi + popd >/dev/null + return $rv +} + +echo -n "started at " > $LOG +date >> $LOG + +if [ $# -eq 0 ]; then + set $(find . -name '*.bfa') +fi +pass=0 +fail=0 +for file in "$@"; do + if test_bfa $file 2>stdout.txt; then + let pass++ + else + if [[ $? -eq 1 ]]; then + let fail++ + fi + cat stdout.txt >>$LOG + fi + rm stdout.txt +done + +echo "$pass pass, $fail fail" diff --git a/backends/tofino/bf-asm/test/testgw.p4 b/backends/tofino/bf-asm/test/testgw.p4 new file mode 100644 index 00000000000..088dee1e776 --- /dev/null +++ b/backends/tofino/bf-asm/test/testgw.p4 @@ -0,0 +1,91 @@ +// Standard L2 Ethernet header +header_type ethernet_t { + fields { + dst_addr : 48; // width in bits + src_addr : 48; + ethertype : 16; + } +} + +header ethernet_t ethernet; + +header_type data_t { + fields { + f1 : 32; + f2 : 32; + f3 : 16; + f4 : 16; + f5 : 8; + f6 : 8; + f7 : 4; + f8 : 4; + } +} +header data_t data; + +parser start { + extract(ethernet); + return data; +} +parser data { + extract(data); + return ingress; +} + +action route_eth(egress_spec, src_addr) { + modify_field(standard_metadata.egress_spec, egress_spec); + modify_field(ethernet.src_addr, src_addr); +} +action noop() { } + +table routing { + reads { + ethernet.dst_addr : lpm; + } + actions { + route_eth; + noop; + } +} + +action setf2(val) { + modify_field(data.f2, val); + //add_to_field(data.f3, data.f4); +} + +table test1 { + reads { + data.f1 : exact; + } + actions { + setf2; + noop; + } +} + +action setf1(val) { + modify_field(data.f1, val); + //add_to_field(data.f4, 1); +} + +table test2 { + reads { + data.f2 : exact; + } + actions { + setf1; + noop; + } +} + +control ingress { + apply(routing); + if (data.f5 != data.f6) { + apply(test1); + } else { + apply(test2); + } +} + +control egress { +} diff --git a/backends/tofino/bf-asm/test/triv_eth.p4 b/backends/tofino/bf-asm/test/triv_eth.p4 new file mode 100644 index 00000000000..1b1962ccd89 --- /dev/null +++ b/backends/tofino/bf-asm/test/triv_eth.p4 @@ -0,0 +1,36 @@ +// Standard L2 Ethernet header +header_type ethernet_t { + fields { + dst_addr : 48; // width in bits + src_addr : 48; + ethertype : 16; + } +} + +header ethernet_t ethernet; + +// just ethernet +parser start { + extract(ethernet); + return ingress; +} + +action route_eth(egress_spec, src_addr) { + modify_field(standard_metadata.egress_spec, egress_spec); + modify_field(ethernet.src_addr, src_addr); +} +action noop() { } + +table routing { + reads { + ethernet.dst_addr : lpm; + } + actions { + route_eth; + noop; + } +} + +control ingress { + apply(routing); +} diff --git a/backends/tofino/bf-asm/test/triv_ipv4.p4 b/backends/tofino/bf-asm/test/triv_ipv4.p4 new file mode 100644 index 00000000000..c64a29278a2 --- /dev/null +++ b/backends/tofino/bf-asm/test/triv_ipv4.p4 @@ -0,0 +1,72 @@ +header_type ethernet_t { + fields { + dst_addr : 48; // width in bits + src_addr : 48; + ethertype : 16; + } +} + +header_type ipv4_t { + fields { + version : 4; + ihl : 4; + diffserv : 8; + totalLen : 16; + identification : 16; + flags : 3; + fragOffset : 13; + ttl : 8; + protocol : 8; + hdrChecksum : 16; + srcAddr : 32; + dstAddr : 32; +// options : *; // Variable length options + } +// length : ihl * 4; +// max_length : 60; +} + +header ethernet_t ethernet; +header ipv4_t ipv4; + +// Start with ethernet always. +parser start { + return ethernet; +} + +parser ethernet { + extract(ethernet); // Start with the ethernet header + return select(ethernet.ethertype) { + 0x800: ipv4; +// default: ingress; + } +} + +parser ipv4 { + extract(ipv4); + return ingress; +} + +action route_ipv4(egress_spec) { + add_to_field(ipv4.ttl, -1); + modify_field(standard_metadata.egress_spec, egress_spec); +} +action do_drop() { /*drop();*/ } +action do_noop() { } + +table routing { + reads { + ipv4.dstAddr : lpm; + } + actions { + do_drop; + route_ipv4; + } + size: 2048; +} + +control ingress { + apply(routing); +} +control egress { +} diff --git a/backends/tofino/bf-asm/test/update_config.py b/backends/tofino/bf-asm/test/update_config.py new file mode 100644 index 00000000000..9da725d15af --- /dev/null +++ b/backends/tofino/bf-asm/test/update_config.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 + +# Copyright 2013-present Barefoot Networks, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import argparse +from time import sleep + +import grpc +from p4 import p4runtime_pb2 +from p4.config import p4info_pb2 +from p4.tmp import p4config_pb2 +import google.protobuf.text_format +import struct + +parser = argparse.ArgumentParser(description='Mininet demo') +parser.add_argument('--dev-id', help='Device id of switch', + type=int, action="store", default=0) +parser.add_argument('--p4info', help='text p4info proto', + type=str, action="store", required=True) +parser.add_argument('--tofino-bin', help='tofino bin', + type=str, action="store", required=True) +parser.add_argument('--cxt-json', help='context json', + type=str, action="store", required=True) + +args = parser.parse_args() + + +def main(): + channel = grpc.insecure_channel('localhost:50051') + stub = p4runtime_pb2.P4RuntimeStub(channel) + + print("Sending P4 config") + request = p4runtime_pb2.SetForwardingPipelineConfigRequest() + request.device_id = 0 + config = request.config + with open(args.p4info) as p4info_f: + google.protobuf.text_format.Merge(p4info_f.read(), config.p4info) + device_config = p4config_pb2.P4DeviceConfig() + with open(args.tofino_bin) as tofino_bin_f: + with open(args.cxt_json) as cxt_json_f: + device_config.device_data = "" + prog_name = "easy" + device_config.device_data += struct.pack("^6fPraX}CDs9%)RW?nT?rxJUmpl40 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%0DQHM~seX`kTx0hoSHyeMj5ff$df6d1GYc^ho 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

%BmRW^aUK?Rx8+Q9-4}Bu5*+ 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ƒNL>zA_*-U_mA;4pyr;0~)RN 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 W3+Yl(oS!!tbvkADMcHYFLx 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 RfS0Ii-B7QWvF_gge*ngcfYSf~ literal 0 HcmV?d00001 diff --git a/backends/tofino/bf-asm/tofino/counter.h b/backends/tofino/bf-asm/tofino/counter.h new file mode 100644 index 00000000000..a9d6060bffe --- /dev/null +++ b/backends/tofino/bf-asm/tofino/counter.h @@ -0,0 +1,39 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_TOFINO_COUNTER_H_ +#define BF_ASM_TOFINO_COUNTER_H_ + +#include "tables.h" + +class Target::Tofino::CounterTable : public ::CounterTable { + friend class ::CounterTable; + CounterTable(int line, const char *n, gress_t gr, Stage *s, int lid) + : ::CounterTable(line, n, gr, s, lid) {} +}; + +template <> +void CounterTable::setup_teop_regs(Target::Tofino::mau_regs &, int) { + BUG(); // no teop on tofino +} + +template <> +void CounterTable::write_alu_vpn_range(Target::Tofino::mau_regs &) { + BUG(); // not available on tofino +} + +#endif /* BF_ASM_TOFINO_COUNTER_H_ */ diff --git a/backends/tofino/bf-asm/tofino/deparser.cpp b/backends/tofino/bf-asm/tofino/deparser.cpp new file mode 100644 index 00000000000..fa7cefa4f6a --- /dev/null +++ b/backends/tofino/bf-asm/tofino/deparser.cpp @@ -0,0 +1,926 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* deparser template specializations for tofino -- #included directly in top-level deparser.cpp */ + +#define YES(X) X +#define NO(X) + +#define SIMPLE_INTRINSIC(GR, PFX, NAME, IF_SHIFT) \ + DEPARSER_INTRINSIC(Tofino, GR, NAME, 1) { \ + PFX.NAME.phv = intrin.vals[0].val->reg.deparser_id(); \ + IF_SHIFT(PFX.NAME.shft = intrin.vals[0].val->lo;) \ + if (!intrin.vals[0].pov.empty()) \ + error(intrin.vals[0].pov.front().lineno, "No POV support in tofino " #NAME); \ + PFX.NAME.valid = 1; \ + } +#define SIMPLE_INTRINSIC_RENAME(GR, PFX, NAME, REGNAME, IF_SHIFT) \ + DEPARSER_INTRINSIC(Tofino, GR, NAME, 1) { \ + PFX.REGNAME.phv = intrin.vals[0].val->reg.deparser_id(); \ + IF_SHIFT(PFX.REGNAME.shft = intrin.vals[0].val->lo;) \ + PFX.REGNAME.valid = 1; \ + } +#define IIR_MAIN_INTRINSIC(NAME, SHFT) SIMPLE_INTRINSIC(INGRESS, regs.input.iir.main_i, NAME, SHFT) +#define IIR_INTRINSIC(NAME, SHFT) SIMPLE_INTRINSIC(INGRESS, regs.input.iir.ingr, NAME, SHFT) +#define HIR_INTRINSIC(NAME, SHFT) SIMPLE_INTRINSIC(INGRESS, regs.header.hir.ingr, NAME, SHFT) +#define HIR_INTRINSIC_RENAME(NAME, REGNAME, SHFT) \ + SIMPLE_INTRINSIC_RENAME(INGRESS, regs.header.hir.ingr, NAME, REGNAME, SHFT) +#define IER_MAIN_INTRINSIC(NAME, SHFT) SIMPLE_INTRINSIC(EGRESS, regs.input.ier.main_e, NAME, SHFT) +#define HER_INTRINSIC(NAME, SHFT) SIMPLE_INTRINSIC(EGRESS, regs.header.her.egr, NAME, SHFT) + +IIR_MAIN_INTRINSIC(egress_unicast_port, NO) +IIR_MAIN_INTRINSIC(drop_ctl, YES) +IIR_INTRINSIC(copy_to_cpu, YES) +HIR_INTRINSIC_RENAME(egress_multicast_group_0, egress_multicast_group[0], NO) +HIR_INTRINSIC_RENAME(egress_multicast_group_1, egress_multicast_group[1], NO) +HIR_INTRINSIC_RENAME(hash_lag_ecmp_mcast_0, hash_lag_ecmp_mcast[0], NO) +HIR_INTRINSIC_RENAME(hash_lag_ecmp_mcast_1, hash_lag_ecmp_mcast[1], NO) +HIR_INTRINSIC(copy_to_cpu_cos, YES) +DEPARSER_INTRINSIC(Tofino, INGRESS, ingress_port_source, 1) { + regs.header.hir.ingr.ingress_port.phv = intrin.vals[0].val->reg.deparser_id(); + regs.header.hir.ingr.ingress_port.sel = 0; +} +HIR_INTRINSIC(deflect_on_drop, YES) +HIR_INTRINSIC(meter_color, YES) +HIR_INTRINSIC(icos, YES) +HIR_INTRINSIC(qid, YES) +HIR_INTRINSIC(xid, NO) +HIR_INTRINSIC(yid, NO) +HIR_INTRINSIC(rid, NO) +HIR_INTRINSIC(bypss_egr, YES) +HIR_INTRINSIC(ct_disable, YES) +HIR_INTRINSIC(ct_mcast, YES) + +IER_MAIN_INTRINSIC(egress_unicast_port, NO) +IER_MAIN_INTRINSIC(drop_ctl, YES) +HER_INTRINSIC(force_tx_err, YES) +HER_INTRINSIC(tx_pkt_has_offsets, YES) +HER_INTRINSIC(capture_tx_ts, YES) +HER_INTRINSIC(coal, NO) +HER_INTRINSIC(ecos, YES) + +#undef SIMPLE_INTRINSIC +#undef IIR_MAIN_INTRINSIC +#undef IIR_INTRINSIC +#undef HIR_INTRINSIC +#undef IER_INTRINSIC +#undef HER_INTRINSIC + +#define TOFINO_DIGEST(GRESS, NAME, CFG, TBL, IFSHIFT, IFID, CNT) \ + DEPARSER_DIGEST(Tofino, GRESS, NAME, CNT, IFSHIFT(can_shift = true;)) { \ + CFG.phv = data.select->reg.deparser_id(); \ + IFSHIFT(CFG.shft = data.shift + data.select->lo;) \ + CFG.valid = 1; \ + if (!data.select.pov.empty()) \ + error(data.select.pov.front().lineno, "No POV bit support in tofino %s digest", \ + #NAME); \ + for (auto &set : data.layout) { \ + int id = set.first >> data.shift; \ + unsigned idx = 0; \ + bool first = true, ok = true; \ + int last = -1; \ + int maxidx = TBL[id].phvs.size() - 1; \ + for (auto ® : set.second) { \ + if (first) { \ + first = false; \ + IFID(TBL[id].id_phv = reg->reg.deparser_id(); continue;) \ + } \ + /* The same 16b/32b container cannot appear consecutively, but 8b can. */ \ + if (last == reg->reg.deparser_id() && reg->reg.size != 8) { \ + error(data.lineno, "%s: %db container %s seen in consecutive locations", \ + #NAME, reg->reg.size, reg->reg.name); \ + continue; \ + } \ + for (int i = reg->reg.size / 8; i > 0; i--) { \ + if (idx > maxidx) { \ + error(data.lineno, "%s digest limited to %d bytes", #NAME, maxidx + 1); \ + ok = false; \ + break; \ + } \ + TBL[id].phvs[idx++] = reg->reg.deparser_id(); \ + } \ + last = reg->reg.deparser_id(); \ + if (!ok) break; \ + } \ + TBL[id].valid = 1; \ + TBL[id].len = idx; \ + } \ + } + +TOFINO_DIGEST(INGRESS, learning, regs.input.iir.ingr.learn_cfg, regs.input.iir.ingr.learn_tbl, NO, + NO, 8) +TOFINO_DIGEST(INGRESS, mirror, regs.header.hir.main_i.mirror_cfg, regs.header.hir.main_i.mirror_tbl, + YES, YES, 8) +TOFINO_DIGEST(EGRESS, mirror, regs.header.her.main_e.mirror_cfg, regs.header.her.main_e.mirror_tbl, + YES, YES, 8) +TOFINO_DIGEST(INGRESS, resubmit, regs.input.iir.ingr.resub_cfg, regs.input.iir.ingr.resub_tbl, YES, + NO, 8) + +void tofino_field_dictionary(checked_array_base &fde_control, + checked_array_base &fde_data, + checked_array_base> &pov_layout, + std::vector &pov_order, + ordered_map ®_pov, + std::vector &dict, json::vector &fd_gress, + json::vector &fd_entries, gress_t gress) { + std::map pov; + json::vector chunk_bytes; + json::vector fd_entry_chunk_bytes; + unsigned pov_byte = 0, pov_size = 0, total_headers = 0; + for (auto &ent : pov_order) + if (pov.count(ent->reg.deparser_id()) == 0) { + total_headers++; + pov[ent->reg.deparser_id()] = pov_size; + pov_size += ent->reg.size; + for (unsigned i = 0; i < ent->reg.size; i += 8) { + if (pov_byte >= Target::Tofino::DEPARSER_MAX_POV_BYTES) { + error(ent.lineno, + "Exceeded hardware limit for POV bits (%d) in deparser. " + "Using %d or more headers. Please reduce the number of headers", + Target::Tofino::DEPARSER_MAX_POV_BYTES * 8, total_headers); + return; + } + pov_layout[pov_byte++] = ent->reg.deparser_id(); + } + } + while (pov_byte < Target::Tofino::DEPARSER_MAX_POV_BYTES) pov_layout[pov_byte++] = 0xff; + + int row = -1, prev = -1, prev_pov = -1; + bool prev_is_checksum = false; + unsigned pos = 0; + unsigned total_bytes = 0; + int prev_row = 0; + for (auto &ent : dict) { + unsigned size = ent.what->size(); + total_bytes += size; + int pov_bit = pov[ent.pov.front()->reg.deparser_id()] + ent.pov.front()->lo; + + if (options.match_compiler) { + if (ent.what->is()) { + /* checksum unit -- make sure it gets its own dictionary line */ + prev_pov = -1; + prev_is_checksum = true; + } else { + if (prev_is_checksum) prev_pov = -1; + prev_is_checksum = false; + } + } + + if (ent.what->is() && prev_pov == pov_bit && + int(ent.what->encode()) == prev && ent.what->size() & 6) + error(ent.lineno, "16 and 32-bit container cannot be repeatedly deparsed"); + while (size--) { + if (pov_bit != prev_pov || pos >= 4 /*|| (pos & (size-1)) != 0*/) { + if (row >= 0) { + fde_control[row].num_bytes = pos & 3; + fde_data[row].num_bytes = pos & 3; + } + // Entries used - (192 each in INGRESS & EGRESS for Tofino) + if (++row >= Target::Tofino::DEPARSER_MAX_FD_ENTRIES) { + error(ent.lineno, + "Exceeded hardware limit for " + "deparser field dictionary entries (%d). Using %d headers and %" PRIu64 + " containers. Please reduce the number of headers and/or their length.", + Target::Tofino::DEPARSER_MAX_FD_ENTRIES, total_headers, + uint64_t(dict.size())); + return; + } + fde_control[row].pov_sel = pov_bit; + fde_control[row].version = 0xf; + fde_control[row].valid = 1; + pos = 0; + } + if (prev_row != row) { + json::map fd; + json::map fd_entry; + fd["Field Dictionary Number"] = prev_row; + fd_entry["entry"] = prev_row; + auto prevPovReg = Phv::reg(pov_layout[fde_control[prev_row].pov_sel.value / 8]); + auto prevPovBit = fde_control[prev_row].pov_sel.value; + auto prevPovOffset = prevPovBit - reg_pov[prevPovReg]; + Deparser::write_pov_in_json(fd, fd_entry, prevPovReg, prevPovBit, prevPovOffset); + fd["Content"] = std::move(chunk_bytes); + fd_entry["chunks"] = std::move(fd_entry_chunk_bytes); + fd_gress.push_back(std::move(fd)); + fd_entries.push_back(std::move(fd_entry)); + prev_row = row; + } + auto povReg = Phv::reg(pov_layout[fde_control[row].pov_sel.value / 8]); + auto povBit = fde_control[row].pov_sel.value % povReg->size; + json::map chunk_byte; + json::map fd_entry_chunk_byte; + json::map fd_entry_chunk; + chunk_byte["Byte"] = pos; + fd_entry_chunk_byte["chunk_number"] = pos; + auto phvReg = Phv::reg(ent.what->encode()); + if (ent.what->encode() < CHECKSUM_ENGINE_PHVID_TOFINO_LOW || + ent.what->encode() > CHECKSUM_ENGINE_PHVID_TOFINO_HIGH) { + write_field_name_in_json(phvReg, povReg, povBit, chunk_byte, fd_entry_chunk, 11, + gress); + } else { + write_csum_const_in_json(ent.what->encode(), chunk_byte, fd_entry_chunk, gress); + } + fd_entry_chunk_byte["chunk"] = std::move(fd_entry_chunk); + chunk_bytes.push_back(std::move(chunk_byte.clone())); + fd_entry_chunk_bytes.push_back(std::move(fd_entry_chunk_byte.clone())); + fde_data[row].phv[pos++] = ent.what->encode(); + prev_pov = pov_bit; + } + + prev = ent.what->encode(); + } + if (pos) { + fde_control[row].num_bytes = pos & 3; + fde_data[row].num_bytes = pos & 3; + } + + // Compute average occupancy. For deparser FDE compression to work, + // need to make sure have certain average occupancy. + // This error check may still be too high level. I think it needs a finer granularity, + // but I'm not sure how to model the allowed variability of packet headers. + + // Tofino deparser has a maximum output header size of 480 bytes. This is done in 2 phases. + // Each phase can do 240 bytes, corresponding to 18 QFDEs (4 * 18 * 4 bytes = 288 bytes) + // This means that average occupancy must be better than 240 / 288 bytes, or roughly 83%. + // This is the value we will check. + // We gate the check on total bytes occupied being greater than 64 bytes in an attempt + // to consider the QFDE constraint that it can only drive four stage 2 buses for compression. + + unsigned max_bytes_for_rows_occupied = 4 * (row + 1); + double occupancy = 0.0; + + if (max_bytes_for_rows_occupied > 0) + occupancy = + static_cast(total_bytes) / static_cast(max_bytes_for_rows_occupied); + + if (total_bytes > 64 && occupancy < (240.0 / 288.0)) { + std::stringstream warn_msg; + warn_msg.precision(4); + warn_msg << "Deparser field dictionary occupancy is too sparse."; + warn_msg << "\nHardware requires an occupancy of " << 100.0 * 240.0 / 288.0 + << " to deparse the output header,"; + warn_msg << "\nbut the PHV layout for the header structures was such that" + " the occupancy was only " + << 100.0 * occupancy << "."; + warn_msg << "\nThis situation is usually caused by a program that has one or" + " more of the following requirements:"; + warn_msg << "\n 1. many 'short' headers that are not guaranteed to coexist" + " (e.g. less than 4 bytes)"; + warn_msg << "\n 2. many packet headers that are not multiples of 4 bytes"; + warn_msg << "\n 3. many conditionally updated checksums"; + warning(0, "%s", warn_msg.str().c_str()); + } +} + +template +void tofino_phv_ownership(bitvec phv_use[2], IN_GRP &in_grp, IN_SPLIT &in_split, EG_GRP &eg_grp, + EG_SPLIT &eg_split, unsigned first, unsigned count) { + BUG_CHECK(in_grp.val.size() == eg_grp.val.size()); + BUG_CHECK(in_split.val.size() == eg_split.val.size()); + BUG_CHECK((in_grp.val.size() + 1) * in_split.val.size() == count); + unsigned group_size = in_split.val.size(); + // DANGER -- this only works because tofino Phv::Register uids happend to match + // DANGER -- the deparser encoding of phv containers. + unsigned reg = first; + for (unsigned i = 0; i < in_grp.val.size(); i++, reg += group_size) { + unsigned last = reg + group_size - 1; + int count = 0; + if (phv_use[INGRESS].getrange(reg, group_size)) { + in_grp.val |= 1U << i; + if (i * group_size >= 16 && i * group_size < 32) + error(0, "%s..%s(R%d..R%d) used by ingress deparser but only available to egress", + Phv::reg(reg)->name, Phv::reg(last)->name, reg, last); + else + count++; + } + if (phv_use[EGRESS].getrange(reg, group_size)) { + eg_grp.val |= 1U << i; + if (i * group_size < 16) + error(0, "%s..%s(R%d..R%d) used by egress deparser but only available to ingress", + Phv::reg(reg)->name, Phv::reg(last)->name, reg, last); + else + count++; + } + if (count > 1) + error(0, "%s..%s(R%d..R%d) used by both ingress and egress deparser", + Phv::reg(reg)->name, Phv::reg(last)->name, reg, last); + } + in_split.val = phv_use[INGRESS].getrange(reg, group_size); + eg_split.val = phv_use[EGRESS].getrange(reg, group_size); +} + +static short tofino_phv2cksum[Target::Tofino::Phv::NUM_PHV_REGS][2] = { + // normal {LSWord, MSWord} + {287, 286}, + {283, 282}, + {279, 278}, + {275, 274}, + {271, 270}, + {267, 266}, + {263, 262}, + {259, 258}, + {255, 254}, + {251, 250}, + {247, 246}, + {243, 242}, + {239, 238}, + {235, 234}, + {231, 230}, + {227, 226}, + {223, 222}, + {219, 218}, + {215, 214}, + {211, 210}, + {207, 206}, + {203, 202}, + {199, 198}, + {195, 194}, + {191, 190}, + {187, 186}, + {183, 182}, + {179, 178}, + {175, 174}, + {171, 170}, + {167, 166}, + {163, 162}, + {285, 284}, + {281, 280}, + {277, 276}, + {273, 272}, + {269, 268}, + {265, 264}, + {261, 260}, + {257, 256}, + {253, 252}, + {249, 248}, + {245, 244}, + {241, 240}, + {237, 236}, + {233, 232}, + {229, 228}, + {225, 224}, + {221, 220}, + {217, 216}, + {213, 212}, + {209, 208}, + {205, 204}, + {201, 200}, + {197, 196}, + {193, 192}, + {189, 188}, + {185, 184}, + {181, 180}, + {177, 176}, + {173, 172}, + {169, 168}, + {165, 164}, + {161, 160}, + {147, -1}, + {145, -1}, + {143, -1}, + {141, -1}, + {127, -1}, + {125, -1}, + {123, -1}, + {121, -1}, + {107, -1}, + {105, -1}, + {103, -1}, + {101, -1}, + {87, -1}, + {85, -1}, + {83, -1}, + {81, -1}, + {67, -1}, + {65, -1}, + {63, -1}, + {61, -1}, + {47, -1}, + {45, -1}, + {43, -1}, + {41, -1}, + {27, -1}, + {25, -1}, + {23, -1}, + {21, -1}, + {7, -1}, + {5, -1}, + {3, -1}, + {1, -1}, + {146, -1}, + {144, -1}, + {142, -1}, + {140, -1}, + {126, -1}, + {124, -1}, + {122, -1}, + {120, -1}, + {106, -1}, + {104, -1}, + {102, -1}, + {100, -1}, + {86, -1}, + {84, -1}, + {82, -1}, + {80, -1}, + {66, -1}, + {64, -1}, + {62, -1}, + {60, -1}, + {46, -1}, + {44, -1}, + {42, -1}, + {40, -1}, + {26, -1}, + {24, -1}, + {22, -1}, + {20, -1}, + {6, -1}, + {4, -1}, + {2, -1}, + {0, -1}, + {159, -1}, + {157, -1}, + {155, -1}, + {153, -1}, + {151, -1}, + {149, -1}, + {139, -1}, + {137, -1}, + {135, -1}, + {133, -1}, + {131, -1}, + {129, -1}, + {119, -1}, + {117, -1}, + {115, -1}, + {113, -1}, + {111, -1}, + {109, -1}, + {99, -1}, + {97, -1}, + {95, -1}, + {93, -1}, + {91, -1}, + {89, -1}, + {79, -1}, + {77, -1}, + {75, -1}, + {73, -1}, + {71, -1}, + {69, -1}, + {59, -1}, + {57, -1}, + {55, -1}, + {53, -1}, + {51, -1}, + {49, -1}, + {39, -1}, + {37, -1}, + {35, -1}, + {33, -1}, + {31, -1}, + {29, -1}, + {19, -1}, + {17, -1}, + {15, -1}, + {13, -1}, + {11, -1}, + {9, -1}, + {158, -1}, + {156, -1}, + {154, -1}, + {152, -1}, + {150, -1}, + {148, -1}, + {138, -1}, + {136, -1}, + {134, -1}, + {132, -1}, + {130, -1}, + {128, -1}, + {118, -1}, + {116, -1}, + {114, -1}, + {112, -1}, + {110, -1}, + {108, -1}, + {98, -1}, + {96, -1}, + {94, -1}, + {92, -1}, + {90, -1}, + {88, -1}, + {78, -1}, + {76, -1}, + {74, -1}, + {72, -1}, + {70, -1}, + {68, -1}, + {58, -1}, + {56, -1}, + {54, -1}, + {52, -1}, + {50, -1}, + {48, -1}, + {38, -1}, + {36, -1}, + {34, -1}, + {32, -1}, + {30, -1}, + {28, -1}, + {18, -1}, + {16, -1}, + {14, -1}, + {12, -1}, + {10, -1}, + {8, -1}, + + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + {-1, -1}, + + // tagalong {LSWord, MSWord} + {1, 0}, + {3, 2}, + {5, 4}, + {7, 6}, + {9, 8}, + {11, 10}, + {13, 12}, + {15, 14}, + {17, 16}, + {19, 18}, + {21, 20}, + {23, 22}, + {25, 24}, + {27, 26}, + {29, 28}, + {31, 30}, + {33, 32}, + {35, 34}, + {37, 36}, + {39, 38}, + {41, 40}, + {43, 42}, + {45, 44}, + {47, 46}, + {49, 48}, + {51, 50}, + {53, 52}, + {55, 54}, + {57, 56}, + {59, 58}, + {61, 60}, + {63, 62}, + {64, -1}, + {65, -1}, + {66, -1}, + {67, -1}, + {68, -1}, + {69, -1}, + {70, -1}, + {71, -1}, + {72, -1}, + {73, -1}, + {74, -1}, + {75, -1}, + {76, -1}, + {77, -1}, + {78, -1}, + {79, -1}, + {80, -1}, + {81, -1}, + {82, -1}, + {83, -1}, + {84, -1}, + {85, -1}, + {86, -1}, + {87, -1}, + {88, -1}, + {89, -1}, + {90, -1}, + {91, -1}, + {92, -1}, + {93, -1}, + {94, -1}, + {95, -1}, + {96, -1}, + {97, -1}, + {98, -1}, + {99, -1}, + {100, -1}, + {101, -1}, + {102, -1}, + {103, -1}, + {104, -1}, + {105, -1}, + {106, -1}, + {107, -1}, + {108, -1}, + {109, -1}, + {110, -1}, + {111, -1}, + {112, -1}, + {113, -1}, + {114, -1}, + {115, -1}, + {116, -1}, + {117, -1}, + {118, -1}, + {119, -1}, + {120, -1}, + {121, -1}, + {122, -1}, + {123, -1}, + {124, -1}, + {125, -1}, + {126, -1}, + {127, -1}, + {128, -1}, + {129, -1}, + {130, -1}, + {131, -1}, + {132, -1}, + {133, -1}, + {134, -1}, + {135, -1}, + {136, -1}, + {137, -1}, + {138, -1}, + {139, -1}, + {140, -1}, + {141, -1}, + {142, -1}, + {143, -1}}; + +#define TAGALONG_THREAD_BASE \ + (Target::Tofino::Phv::COUNT_8BIT_TPHV + Target::Tofino::Phv::COUNT_16BIT_TPHV + \ + 2 * Target::Tofino::Phv::COUNT_32BIT_TPHV) + +template +static void copy_csum_cfg_entry(DTYPE &dst_unit, STYPE &src_unit) { + BUG_CHECK(dst_unit.size() == src_unit.size()); + + for (unsigned i = 0; i < dst_unit.size(); i++) { + auto &src = src_unit[i]; + auto &dst = dst_unit[i]; + + dst.zero_l_s_b = src.zero_l_s_b; + dst.zero_m_s_b = src.zero_m_s_b; + dst.swap = src.swap; + } +} + +template +static void init_tofino_checksum_entry(ENTRIES &entry) { + entry.zero_l_s_b = 1; + entry.zero_l_s_b.rewrite(); + entry.zero_m_s_b = 1; + entry.zero_m_s_b.rewrite(); + entry.swap = 0; + entry.swap.rewrite(); +} + +template +static void tofino_checksum_units(checked_array_base &main_csum_units, + checked_array_base &tagalong_csum_units, gress_t gress, + Deparser::FullChecksumUnit checksum_unit[]) { + BUG_CHECK(tofino_phv2cksum[Target::Tofino::Phv::NUM_PHV_REGS - 1][0] == 143); + for (int i = 0; i < Target::Tofino::DEPARSER_CHECKSUM_UNITS; i++) { + auto &main_unit = main_csum_units[i].csum_cfg_entry; + auto &tagalong_unit = tagalong_csum_units[i].csum_cfg_entry; + auto &tagalong_unit_zeros_as_ones = tagalong_csum_units[i].zeros_as_ones; + for (auto &ent : main_unit) init_tofino_checksum_entry(ent); + for (auto &ent : tagalong_unit) init_tofino_checksum_entry(ent); + if (checksum_unit[i].entries.empty()) continue; + // Tofino does not support checksum calculation using multiple + // partial checksum unit. + // Full checksum unit and partial checksum unit will always be same + BUG_CHECK(checksum_unit[i].entries.size() == 1); + auto &checksum_unit_entries = checksum_unit[i].entries[i]; + for (auto ® : checksum_unit_entries) { + int mask = reg.mask; + int swap = reg.swap; + int idx = reg->reg.deparser_id(); + if (!reg.pov.empty()) + error(reg.pov.front().lineno, "No POV support in tofino checksum"); + auto cksum_idx0 = tofino_phv2cksum[idx][0]; + auto cksum_idx1 = tofino_phv2cksum[idx][1]; + BUG_CHECK(cksum_idx0 >= 0); + if (idx >= 256) { + write_checksum_entry(tagalong_unit[cksum_idx0], mask & 3, swap & 1, i, + reg->reg.name); + if (cksum_idx1 >= 0) + write_checksum_entry(tagalong_unit[cksum_idx1], mask >> 2, swap >> 1, i, + reg->reg.name); + else + BUG_CHECK((mask >> 2 == 0) && (swap >> 1 == 0)); + } else { + write_checksum_entry(main_unit[cksum_idx0], mask & 3, swap & 1, i, reg->reg.name); + if (cksum_idx1 >= 0) + write_checksum_entry(main_unit[cksum_idx1], mask >> 2, swap >> 1, i, + reg->reg.name); + else + BUG_CHECK((mask >> 2 == 0) && (swap >> 1 == 0)); + } + } + // Thread non-tagalong checksum results through the tagalong unit + int idx = i + TAGALONG_THREAD_BASE + gress * Target::Tofino::DEPARSER_CHECKSUM_UNITS; + write_checksum_entry(tagalong_unit[idx], 0x3, 0x0, i); + // Setting Zeros_As_Ones enable + tagalong_unit_zeros_as_ones.en = checksum_unit[i].zeros_as_ones_en; + main_unit.set_modified(); + tagalong_unit.set_modified(); + } +} + +static void tofino_checksum_units( + Target::Tofino::deparser_regs ®s, + Deparser::FullChecksumUnit full_checksum_unit[2][MAX_DEPARSER_CHECKSUM_UNITS]) { + for (unsigned id = 2; id < MAX_DEPARSER_CHECKSUM_UNITS; id++) { + if (!full_checksum_unit[0][id].entries.empty() && + !full_checksum_unit[1][id].entries.empty()) + error(-1, "deparser checksum unit %d used in both ingress and egress", id); + } + + tofino_checksum_units(regs.input.iim.ii_phv_csum.csum_cfg, + regs.header.him.hi_tphv_csum.csum_cfg, INGRESS, + full_checksum_unit[INGRESS]); + tofino_checksum_units(regs.input.iem.ie_phv_csum.csum_cfg, + regs.header.hem.he_tphv_csum.csum_cfg, EGRESS, + full_checksum_unit[EGRESS]); + + // make sure shared units are configured identically + for (unsigned id = 2; id < Target::Tofino::DEPARSER_CHECKSUM_UNITS; id++) { + auto &eg_main_unit = regs.input.iem.ie_phv_csum.csum_cfg[id].csum_cfg_entry; + auto &ig_main_unit = regs.input.iim.ii_phv_csum.csum_cfg[id].csum_cfg_entry; + + auto &eg_tphv_unit = regs.header.hem.he_tphv_csum.csum_cfg[id].csum_cfg_entry; + auto &ig_tphv_unit = regs.header.him.hi_tphv_csum.csum_cfg[id].csum_cfg_entry; + + if (!full_checksum_unit[0][id].entries.empty()) { + copy_csum_cfg_entry(eg_main_unit, ig_main_unit); + copy_csum_cfg_entry(eg_tphv_unit, ig_tphv_unit); + } else if (!full_checksum_unit[1][id].entries.empty()) { + copy_csum_cfg_entry(ig_main_unit, eg_main_unit); + copy_csum_cfg_entry(ig_tphv_unit, eg_tphv_unit); + } + } +} + +template <> +void Deparser::write_config(Target::Tofino::deparser_regs ®s) { + regs.input.icr.inp_cfg.disable(); + regs.input.icr.intr.disable(); + regs.header.hem.he_edf_cfg.disable(); + regs.header.him.hi_edf_cfg.disable(); + + tofino_checksum_units(regs, full_checksum_unit); + json::map field_dictionary_alloc; + json::vector fd_gress; + json::vector fde_entries_i; + json::vector fde_entries_e; + + // Deparser resources + json::vector resources_deparser; + + // Create field dictionaries for ingress + tofino_field_dictionary(regs.input.iim.ii_fde_pov.fde_pov, regs.header.him.hi_fde_phv.fde_phv, + regs.input.iir.main_i.pov.phvs, pov_order[INGRESS], pov[INGRESS], + dictionary[INGRESS], fd_gress, fde_entries_i, INGRESS); + field_dictionary_alloc["ingress"] = std::move(fd_gress); + // Create field dictionaries for egress + tofino_field_dictionary(regs.input.iem.ie_fde_pov.fde_pov, regs.header.hem.he_fde_phv.fde_phv, + regs.input.ier.main_e.pov.phvs, pov_order[EGRESS], pov[EGRESS], + dictionary[EGRESS], fd_gress, fde_entries_e, EGRESS); + field_dictionary_alloc["egress"] = std::move(fd_gress); + + if (Log::verbosity() > 0) { + auto json_dump = open_output("logs/field_dictionary.log"); + *json_dump << &field_dictionary_alloc; + } + // Output deparser resources + report_resources_deparser_json(fde_entries_i, fde_entries_e); + + if (Phv::use(INGRESS).intersects(Phv::use(EGRESS))) { + warning(lineno[INGRESS], "Registers used in both ingress and egress in pipeline: %s", + Phv::db_regset(Phv::use(INGRESS) & Phv::use(EGRESS)).c_str()); + /* FIXME -- this only (sort-of) works because 'deparser' comes first in the alphabet, + * FIXME -- so is the first section to have its 'output' method run. Its a hack + * FIXME -- anyways to attempt to correct broken asm that should be an error */ + Phv::unsetuse(INGRESS, phv_use[EGRESS]); + Phv::unsetuse(EGRESS, phv_use[INGRESS]); + } + + tofino_phv_ownership(phv_use, regs.input.iir.ingr.phv8_grp, regs.input.iir.ingr.phv8_split, + regs.input.ier.egr.phv8_grp, regs.input.ier.egr.phv8_split, + Target::Tofino::Phv::FIRST_8BIT_PHV, Target::Tofino::Phv::COUNT_8BIT_PHV); + tofino_phv_ownership(phv_use, regs.input.iir.ingr.phv16_grp, regs.input.iir.ingr.phv16_split, + regs.input.ier.egr.phv16_grp, regs.input.ier.egr.phv16_split, + Target::Tofino::Phv::FIRST_16BIT_PHV, + Target::Tofino::Phv::COUNT_16BIT_PHV); + tofino_phv_ownership(phv_use, regs.input.iir.ingr.phv32_grp, regs.input.iir.ingr.phv32_split, + regs.input.ier.egr.phv32_grp, regs.input.ier.egr.phv32_split, + Target::Tofino::Phv::FIRST_32BIT_PHV, + Target::Tofino::Phv::COUNT_32BIT_PHV); + + for (unsigned i = 0; i < 8; i++) { + if (phv_use[EGRESS].intersects(Target::Tofino::Phv::tagalong_groups[i])) { + regs.input.icr.tphv_cfg.i_e_assign |= 1 << i; + if (phv_use[INGRESS].intersects(Target::Tofino::Phv::tagalong_groups[i])) { + error(lineno[INGRESS], + "tagalong group %d used in both ingress and " + "egress deparser", + i); + } + } + } + + for (auto &intrin : intrinsics) intrin.type->setregs(regs, *this, intrin); + + if (!regs.header.hir.ingr.ingress_port.sel.modified()) + regs.header.hir.ingr.ingress_port.sel = 1; + + for (auto &digest : digests) digest.type->setregs(regs, *this, digest); + + // The csum_cfg_entry registers are NOT reset by hardware and must be + // explicitly configured. We remove the disable_if_reset_value() calls on + // these register tree for now, but ideally they should have a flag to indicate no + // reset value is present and the register tree should prune only those regs + // if (options.condense_json) { + // regs.input.disable_if_reset_value(); + // regs.header.disable_if_reset_value(); } + if (error_count == 0 && options.gen_json) { + regs.input.emit_json(*open_output("regs.all.deparser.input_phase.cfg.json")); + regs.header.emit_json(*open_output("regs.all.deparser.header_phase.cfg.json")); + } + TopLevel::regs()->reg_pipe.deparser.hdr.set("regs.all.deparser.header_phase", + ®s.header); + TopLevel::regs()->reg_pipe.deparser.inp.set("regs.all.deparser.input_phase", + ®s.input); +} + +template <> +unsigned Deparser::FDEntry::Checksum::encode() { + return CHECKSUM_ENGINE_PHVID_TOFINO_LOW + (gress * CHECKSUM_ENGINE_PHVID_TOFINO_PER_GRESS) + + unit; +} + +template <> +unsigned Deparser::FDEntry::Constant::encode() { + error(lineno, "Tofino deparser does not support constant entries"); + return -1; +} + +template <> +void Deparser::gen_learn_quanta(Target::Tofino::parser_regs ®s, json::vector &learn_quanta) {} + +template <> +void Deparser::process(Target::Tofino *) { + // Chip-specific code for process method + // None for Tofino +} diff --git a/backends/tofino/bf-asm/tofino/exact_match.cpp b/backends/tofino/bf-asm/tofino/exact_match.cpp new file mode 100644 index 00000000000..42ff46b08f1 --- /dev/null +++ b/backends/tofino/bf-asm/tofino/exact_match.cpp @@ -0,0 +1,37 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "exact_match.h" + +void Target::Tofino::ExactMatchTable::setup_ways() { + ::ExactMatchTable::setup_ways(); + for (auto &row : layout) { + int first_way = -1; + for (auto &ram : row.memunits) { + int way = way_map.at(ram).way; + if (first_way < 0) { + first_way = way; + } else if (ways[way].group_xme != ways[first_way].group_xme) { + error(row.lineno, + "Ways %d and %d of table %s share address bus on row %d, " + "but use different hash groups", + first_way, way, name(), row.row); + break; + } + } + } +} diff --git a/backends/tofino/bf-asm/tofino/exact_match.h b/backends/tofino/bf-asm/tofino/exact_match.h new file mode 100644 index 00000000000..849b32d144f --- /dev/null +++ b/backends/tofino/bf-asm/tofino/exact_match.h @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_TOFINO_EXACT_MATCH_H_ +#define BF_ASM_TOFINO_EXACT_MATCH_H_ + +#include + +class Target::Tofino::ExactMatchTable : public ::ExactMatchTable { + friend class ::ExactMatchTable; + ExactMatchTable(int line, const char *n, gress_t gr, Stage *s, int lid) + : ::ExactMatchTable(line, n, gr, s, lid) {} + + void setup_ways() override; +}; + +#endif /* BF_ASM_TOFINO_EXACT_MATCH_H_ */ diff --git a/backends/tofino/bf-asm/tofino/gateway.cpp b/backends/tofino/bf-asm/tofino/gateway.cpp new file mode 100644 index 00000000000..0a2faeb6e1f --- /dev/null +++ b/backends/tofino/bf-asm/tofino/gateway.cpp @@ -0,0 +1,320 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "gateway.h" + +#include "hashexpr.h" +#include "hex.h" +#include "stage.h" +#include "ternary_match.h" + +/* Tofino1/2 Gateway table support + * GatewayTable uses the Table::Layout in a somewhat hacky way to track the gateway match + * and payload blocks. Layout may have either one or two entries. + * layout[0] is the layout for the gateway match -- which row and search bus is being used + * layout[1] is the layout for the payload -- which row and result bus is being used. + * if layout.size() == 1, there is no payload. + * The payload result bus is stored as bus[RESULT_BUS] even though it may be either a + * match result bus or a tind bus -- the second bit (so busses 2 and 3) are the tind + * busses as that is the way they they are encode in some registers. It should perhaps be + * changed to use the bus_type_t to track whether it is a match RESULT_BUS or a TIND_BUS + */ + +bool Target::Tofino::GatewayTable::check_match_key(MatchKey &key, const std::vector &vec, + bool is_xor) { + if (!::GatewayTable::check_match_key(key, vec, is_xor)) return false; + if (key.offset < 32 && (key.offset & 7) != (key.val->lo & 7)) + error(key.val.lineno, "Gateway %s key %s misaligned within byte", is_xor ? "xor" : "match", + key.val.name()); + if (key.offset + key.val->size() > (is_xor ? 32 : 44)) { + error(key.val.lineno, "Gateway %s key too big", is_xor ? "xor" : "match"); + return false; + } + if (key.offset >= 32 && !input_xbar.empty()) { + BUG_CHECK(input_xbar.size() == 1, "%s does not have one input xbar", name()); + auto hash = input_xbar[0]->hash_column(key.offset + 8); + if (hash.size() != 1 || hash[0]->bit || !hash[0]->fn || + !hash[0]->fn->match_phvref(key.val)) { + // FIXME: hash.size() maybe zero when key.valid is true. + // which means the key.offset is incorrect. + if (!key.valid) { + error(key.val.lineno, "Gateway %s key %s not in matching hash column", + is_xor ? "xor" : "match", key.val.name()); + return false; + } + } + } + return true; +} + +void Target::Tofino::GatewayTable::pass1() { + ::GatewayTable::pass1(); + /* in a gateway, the layout has one or two rows -- layout[0] specifies the gateway, and + * layout[1] specifies the payload. There will be no columns in either row. + */ + if (layout.empty() || layout[0].row < 0) + error(lineno, "No row specified in gateway"); + else if (!layout[0].bus.count(Layout::SEARCH_BUS) && (!match.empty() || !xor_match.empty())) + error(lineno, "No bus specified in gateway to read from"); + if (payload_unit >= 0 && have_payload < 0 && match_address < 0) + error(lineno, "payload_unit with no payload or match address in gateway"); + if (layout.size() > 1) { + if (layout[1].bus.count(Layout::RESULT_BUS) && (have_payload >= 0 || match_address >= 0)) { + int result_bus = layout[1].bus.at(Layout::RESULT_BUS); + if (payload_unit < 0) { + payload_unit = result_bus & 1; + } else if (payload_unit != (result_bus & 1)) { + error(layout[1].lineno, "payload unit %d cannot write to result bus %d", + payload_unit, result_bus); + } + } + if (layout[1].row < 0) { + error(layout[1].lineno, "payload_bus with no payload_row in gateway"); + } else if (Table *tbl = match_table) { + if (auto *tmatch = dynamic_cast(tbl)) tbl = tmatch->indirect; + if (tbl && !tbl->layout.empty()) { + for (auto &r : tbl->layout) { + if (r.row != layout[1].row) continue; + if (!r.bus.count(Layout::RESULT_BUS)) continue; + int match_rbus = r.bus.at(Layout::RESULT_BUS); + if (payload_unit >= 0 && payload_unit != (match_rbus & 1)) continue; + if (!layout[1].bus.count(Layout::RESULT_BUS)) + layout[1].bus[Layout::RESULT_BUS] = match_rbus; + if (match_rbus == layout[1].bus.at(Layout::RESULT_BUS)) { + if (tbl->to()) layout[1].bus[Layout::RESULT_BUS] |= 2; + break; + } + } + } + } else if (have_payload >= 0 || match_address >= 0) { + if (payload_unit) { + if (auto *old = stage->gw_payload_use[layout[1].row][payload_unit]) + error(layout[1].lineno, "payload %d.%d already in use by table %s", + layout[1].row, payload_unit, old->name()); + else + stage->gw_payload_use[layout[1].row][payload_unit] = this; + } + } else if (payload_unit >= 0) { + error(lineno, "payload_unit with no payload or match address in gateway"); + } + } else if ((have_payload >= 0 || match_address >= 0) && !match_table) { + error(have_payload, "payload on standalone gateway requires explicit payload_row"); + } else if (payload_unit >= 0 && match_table) { + bool ternary = false; + Table *tbl = match_table; + if (auto *tmatch = dynamic_cast(tbl)) { + ternary = true; + tbl = tmatch->indirect; + } + if (!tbl || tbl->layout.empty()) { + error(lineno, "No result busses in table %s for gateway payload", match_table->name()); + } else { + for (auto &r : tbl->layout) { + auto match_rbus = r.bus.count(Layout::RESULT_BUS) ? r.bus.at(Layout::RESULT_BUS) + : r.bus.at(Layout::SEARCH_BUS); + if (match_rbus >= 0 && payload_unit != (match_rbus & 1)) continue; + if (!stage->gw_payload_use[r.row][payload_unit]) { + layout.resize(2); + layout[1].row = r.row; + if (r.bus.count(Layout::RESULT_BUS)) + layout[1].bus[Layout::RESULT_BUS] = r.bus.at(Layout::RESULT_BUS); + else + layout[1].bus[Layout::RESULT_BUS] = + r.bus.at(Layout::SEARCH_BUS) | (ternary ? 2 : 0); + stage->gw_payload_use[r.row][payload_unit] = this; + break; + } + } + if (layout.size() < 2) + error(lineno, "No row in table %s has payload unit %d free", tbl->name(), + payload_unit); + } + } + if (layout.size() > 1 && layout[1].bus.count(Layout::RESULT_BUS)) { + int result_bus = layout[1].bus.at(Layout::RESULT_BUS); + Table *tbl = match_table; + if (auto *tmatch = dynamic_cast(tbl)) tbl = tmatch->indirect; + if (!tbl) tbl = this; + auto &bus_use = + (result_bus & 2) ? stage->tcam_indirect_bus_use : stage->match_result_bus_use; + auto *old = bus_use[layout[1].row][result_bus & 1]; + if (old && old != tbl) + error(layout[1].lineno, + "Gateway payload result bus %d conflict on row %d between " + "%s and %s", + result_bus, layout[1].row, name(), old->name()); + bus_use[layout[1].row][result_bus & 1] = tbl; + } +} + +void Target::Tofino::GatewayTable::pass2() { + ::GatewayTable::pass2(); + if (gw_unit < 0) { + if (layout[0].bus.count(Layout::SEARCH_BUS) && + !stage->gw_unit_use[layout[0].row][layout[0].bus.at(Layout::SEARCH_BUS)]) { + gw_unit = layout[0].bus.at(Layout::SEARCH_BUS); + } else { + for (int i = 0; i < 2; ++i) { + if (!stage->gw_unit_use[layout[0].row][i] && + !stage->sram_search_bus_use[layout[0].row][i]) { + gw_unit = i; + break; + } + } + } + if (gw_unit < 0) + error(layout[0].lineno, "No gateway units available on row %d", layout[0].row); + else + stage->gw_unit_use[layout[0].row][gw_unit] = this; + } + if (!layout[0].bus.count(Layout::SEARCH_BUS) && gw_unit >= 0) + layout[0].bus[Layout::SEARCH_BUS] = gw_unit; + if (payload_unit < 0 && (have_payload >= 0 || match_address >= 0)) { + if (layout.size() > 1) { + if (!layout[1].bus.count(Layout::RESULT_BUS)) { + if (!stage->gw_payload_use[layout[1].row][0]) + payload_unit = 0; + else if (!stage->gw_payload_use[layout[1].row][1]) + payload_unit = 1; + } else { + int u = layout[1].bus.at(Layout::RESULT_BUS) & 1; + if (!stage->gw_payload_use[layout[1].row][u]) payload_unit = u; + } + if (payload_unit >= 0) + stage->gw_payload_use[layout[1].row][payload_unit] = this; + else + error(lineno, "No payload available on row %d", layout[1].row); + } else if (Table *tbl = match_table) { + bool ternary = false; + if (auto *tmatch = dynamic_cast(tbl)) { + tbl = tmatch->indirect; + ternary = true; + } + if (tbl && !tbl->layout.empty()) { + for (auto &row : tbl->layout) { + auto match_rbus = row.bus.at(ternary ? Layout::TIND_BUS : Layout::RESULT_BUS); + BUG_CHECK(match_rbus >= 0); // alloc_busses on the match table must run first + if (stage->gw_payload_use[row.row][match_rbus]) { + continue; + } else { + payload_unit = match_rbus; + } + stage->gw_payload_use[row.row][payload_unit] = this; + layout.resize(2); + layout[1].row = row.row; + layout[1].bus[Layout::RESULT_BUS] = match_rbus | (ternary ? 2 : 0); + break; + } + if (payload_unit < 0) + error(lineno, "No row in table %s has a free payload unit", tbl->name()); + } else { + error(lineno, "No result busses in table %s for gateway payload", + match_table->name()); + } + } + } + if (payload_unit >= 0 && !layout[1].bus.count(Layout::RESULT_BUS)) { + BUG_CHECK(layout.size() > 1); + int row = layout[1].row; + Table *tbl = match_table; + int ternary = tbl ? 0 : -1; + if (auto *tmatch = dynamic_cast(tbl)) { + ternary = 1; + tbl = tmatch->indirect ? tmatch->indirect : tmatch; + } + if (!tbl) tbl = this; + for (int i = payload_unit; i < 4; i += 2) { + if (ternary >= 0 && (i >> 1) != ternary) continue; + auto &result_bus = (i & 2) ? stage->tcam_indirect_bus_use : stage->match_result_bus_use; + if (!result_bus[row][i & 1] || result_bus[row][i & 1] == tbl) { + layout[1].bus[Layout::RESULT_BUS] = i; + result_bus[row][i & 1] = tbl; + break; + } + } + if (!layout[1].bus.count(Layout::RESULT_BUS)) { + error(lineno, "No result bus available for gateway payload of table %s on row %d", + name(), layout[1].row); + } + } +} + +void Target::Tofino::GatewayTable::pass3() { + ::GatewayTable::pass3(); + if (layout[0].bus.count(Layout::SEARCH_BUS)) { + int search_bus = layout[0].bus.at(Layout::SEARCH_BUS); + auto *tbl = stage->sram_search_bus_use[layout[0].row][search_bus]; + // Sharing with an exact match -- make sure it is ok + if (!tbl) return; + for (auto &ixb : input_xbar) { + auto *sram_tbl = tbl->to(); + BUG_CHECK(sram_tbl, + "%s is not an SRamMatch table even though it is using a " + "search bus?", + tbl->name()); + SRamMatchTable::WayRam *way = nullptr; + for (auto &row : sram_tbl->layout) { + if (row.row == layout[0].row && row.bus.at(Layout::SEARCH_BUS) == search_bus) { + if (row.memunits.empty()) { + // FIXME -- not really used, so we don't need to check the + // match/hash group. Should this be an asm error? + return; + } + way = &sram_tbl->way_map.at(row.memunits[0]); + break; + } + } + BUG_CHECK(way, "%s claims to use search bus %d.%d, but we can't find it in the layout", + sram_tbl->name(), layout[0].row, search_bus); + if (ixb->hash_group() >= 0 && sram_tbl->ways[way->way].group_xme >= 0 && + ixb->hash_group() != sram_tbl->ways[way->way].group_xme) { + error(layout[0].lineno, + "%s sharing search bus %d.%d with %s, but wants a " + "different hash group", + name(), layout[0].row, search_bus, tbl->name()); + } + if (ixb->match_group() >= 0 && sram_tbl->word_ixbar_group[way->word] >= 0 && + gateway_needs_ixbar_group() && + ixb->match_group() != sram_tbl->word_ixbar_group[way->word]) { + error(layout[0].lineno, + "%s sharing search bus %d.%d with %s, but wants a " + "different match group", + name(), layout[0].row, search_bus, tbl->name()); + } + } + } +} + +template <> +void enable_gateway_payload_exact_shift_ovr(Target::Tofino::mau_regs ®s, int bus) { + // Not supported on tofino + BUG(); +} +template void enable_gateway_payload_exact_shift_ovr(Target::Tofino::mau_regs ®s, int bus); + +void Target::Tofino::GatewayTable::write_next_table_regs(Target::Tofino::mau_regs ®s) { + auto &merge = regs.rams.match.merge; + int idx = 3; + if (need_next_map_lut) error(lineno, "Tofino does not support using next_map_lut in gateways"); + for (auto &line : table) { + BUG_CHECK(idx >= 0); + if (!line.run_table) + merge.gateway_next_table_lut[logical_id][idx] = line.next.next_table_id(); + --idx; + } + if (!miss.run_table) merge.gateway_next_table_lut[logical_id][4] = miss.next.next_table_id(); +} diff --git a/backends/tofino/bf-asm/tofino/gateway.h b/backends/tofino/bf-asm/tofino/gateway.h new file mode 100644 index 00000000000..323ef5574fd --- /dev/null +++ b/backends/tofino/bf-asm/tofino/gateway.h @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_TOFINO_GATEWAY_H_ +#define BF_ASM_TOFINO_GATEWAY_H_ + +#include + +class Target::Tofino::GatewayTable : public ::GatewayTable { + friend class ::GatewayTable; + GatewayTable(int line, const char *n, gress_t gr, Stage *s, int lid) + : ::GatewayTable(line, n, gr, s, lid) {} + + void pass1() override; + void pass2() override; + void pass3() override; + + bool check_match_key(MatchKey &, const std::vector &, bool) override; + int gw_memory_unit() const override { return layout[0].row * 2 + gw_unit; } + REGSETS_IN_CLASS(Tofino, TARGET_OVERLOAD, void write_next_table_regs, (mau_regs &), override;) +}; + +template +void enable_gateway_payload_exact_shift_ovr(REGS ®s, int bus); +template <> +void enable_gateway_payload_exact_shift_ovr(Target::Tofino::mau_regs ®s, int bus); + +#endif /* BF_ASM_TOFINO_GATEWAY_H_ */ diff --git a/backends/tofino/bf-asm/tofino/input_xbar.cpp b/backends/tofino/bf-asm/tofino/input_xbar.cpp new file mode 100644 index 00000000000..114e0b81ebf --- /dev/null +++ b/backends/tofino/bf-asm/tofino/input_xbar.cpp @@ -0,0 +1,80 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "input_xbar.h" + +template <> +void InputXbar::write_galois_matrix(Target::Tofino::mau_regs ®s, HashTable id, + const std::map &mat) { + int parity_col = -1; + BUG_CHECK(id.type == HashTable::EXACT, "not an exact hash table %d", id.type); + if (hash_table_parity.count(id) && !options.disable_gfm_parity) { + parity_col = hash_table_parity[id]; + } + auto &hash = regs.dp.xbar_hash.hash; + std::set gfm_rows; + for (auto &col : mat) { + int c = col.first; + // Skip parity column encoding, if parity is set overall parity is + // computed later below + if (c == parity_col) continue; + const HashCol &h = col.second; + for (int word = 0; word < 4; word++) { + unsigned data = h.data.getrange(word * 16, 16); + unsigned valid = (h.valid >> word * 2) & 3; + if (data == 0 && valid == 0) continue; + auto &w = hash.galois_field_matrix[id.index * 4 + word][c]; + w.byte0 = data & 0xff; + w.byte1 = (data >> 8) & 0xff; + w.valid0 = valid & 1; + w.valid1 = (valid >> 1) & 1; + gfm_rows.insert(id.index * 4 + word); + } + } + // A GFM row can be shared by multiple tables. In most cases the columns are + // non overlapping but if they are overlapping the GFM encodings must be the + // same (e.g. ATCAM tables). The input xbar has checks to determine which + // cases are valid. + // The parity must be computed for all columns within the row and set into + // the parity column. + if (parity_col >= 0) { + for (auto r : gfm_rows) { + int hp_byte0 = 0, hp_byte1 = 0; + int hp_valid0 = 0, hp_valid1 = 0; + for (auto c = 0; c < 52; c++) { + if (c == parity_col) continue; + auto &w = hash.galois_field_matrix[r][c]; + hp_byte0 ^= w.byte0; + hp_byte1 ^= w.byte1; + hp_valid0 ^= w.valid0; + hp_valid1 ^= w.valid1; + } + auto &w_hp = hash.galois_field_matrix[r][parity_col]; + w_hp.byte0.rewrite(); + w_hp.byte1.rewrite(); + w_hp.valid0.rewrite(); + w_hp.valid1.rewrite(); + w_hp.byte0 = hp_byte0; + w_hp.byte1 = hp_byte1; + w_hp.valid0 = hp_valid0; + w_hp.valid1 = hp_valid1; + } + } +} + +template void InputXbar::write_galois_matrix(Target::Tofino::mau_regs ®s, HashTable id, + const std::map &mat); diff --git a/backends/tofino/bf-asm/tofino/input_xbar.h b/backends/tofino/bf-asm/tofino/input_xbar.h new file mode 100644 index 00000000000..0ea58054e21 --- /dev/null +++ b/backends/tofino/bf-asm/tofino/input_xbar.h @@ -0,0 +1,27 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_TOFINO_INPUT_XBAR_H_ +#define BF_ASM_TOFINO_INPUT_XBAR_H_ + +#include + +template <> +void InputXbar::write_galois_matrix(Target::Tofino::mau_regs ®s, HashTable id, + const std::map &mat); + +#endif /* BF_ASM_TOFINO_INPUT_XBAR_H_ */ diff --git a/backends/tofino/bf-asm/tofino/instruction.cpp b/backends/tofino/bf-asm/tofino/instruction.cpp new file mode 100644 index 00000000000..e2ca6ad7b87 --- /dev/null +++ b/backends/tofino/bf-asm/tofino/instruction.cpp @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Tofino overloads for instructions #included in instruction.cpp + * WARNING -- this is included in an anonymous namespace, as VLIWInstruction is + * in that anonymous namespace */ + +void VLIWInstruction::write_regs(Target::Tofino::mau_regs ®s, Table *tbl, + Table::Actions::Action *act) { + if (act != tbl->stage->imem_addr_use[tbl->gress][act->addr]) { + LOG3("skipping " << tbl->name() << '.' << act->name << " as its imem is used by " + << tbl->stage->imem_addr_use[tbl->gress][act->addr]->name); + return; + } + LOG2(this); + auto &imem = regs.dp.imem; + int iaddr = act->addr / ACTION_IMEM_COLORS; + int color = act->addr % ACTION_IMEM_COLORS; + unsigned bits = encode(); + BUG_CHECK(slot >= 0); + switch (Phv::reg(slot)->size) { + case 8: + imem.imem_subword8[slot - 64][iaddr].imem_subword8_instr = bits; + imem.imem_subword8[slot - 64][iaddr].imem_subword8_color = color; + imem.imem_subword8[slot - 64][iaddr].imem_subword8_parity = parity(bits) ^ color; + break; + case 16: + imem.imem_subword16[slot - 128][iaddr].imem_subword16_instr = bits; + imem.imem_subword16[slot - 128][iaddr].imem_subword16_color = color; + imem.imem_subword16[slot - 128][iaddr].imem_subword16_parity = parity(bits) ^ color; + break; + case 32: + imem.imem_subword32[slot][iaddr].imem_subword32_instr = bits; + imem.imem_subword32[slot][iaddr].imem_subword32_color = color; + imem.imem_subword32[slot][iaddr].imem_subword32_parity = parity(bits) ^ color; + break; + default: + BUG(); + } + auto &power_ctl = regs.dp.actionmux_din_power_ctl; + phvRead([&](const Phv::Slice &sl) { set_power_ctl_reg(power_ctl, sl.reg.mau_id()); }); +} diff --git a/backends/tofino/bf-asm/tofino/match_table.cpp b/backends/tofino/bf-asm/tofino/match_table.cpp new file mode 100644 index 00000000000..57513269851 --- /dev/null +++ b/backends/tofino/bf-asm/tofino/match_table.cpp @@ -0,0 +1,75 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* mau table template specializations for tofino -- #included directly in match_tables.cpp */ + +template <> +void MatchTable::write_next_table_regs(Target::Tofino::mau_regs ®s, Table *tbl) { + auto &merge = regs.rams.match.merge; + // Copies the values directly from the hit map provided by the compiler directly into the + // map + if (!tbl->get_hit_next().empty()) { + merge.next_table_map_en |= (1U << logical_id); + auto &mp = merge.next_table_map_data[logical_id]; + ubits<8> *map_data[8] = {&mp[0].next_table_map_data0, &mp[0].next_table_map_data1, + &mp[0].next_table_map_data2, &mp[0].next_table_map_data3, + &mp[1].next_table_map_data0, &mp[1].next_table_map_data1, + &mp[1].next_table_map_data2, &mp[1].next_table_map_data3}; + int index = 0; + for (auto &n : tbl->get_hit_next()) *map_data[index++] = n.next_table_id(); + } + + merge.next_table_format_data[logical_id].match_next_table_adr_mask = next_table_adr_mask; + + /** + * Unfortunately for the compiler/driver integration, this register is both required + * to be owned by the compiler and the driver. The driver is responsible for programming + * this register when the default action of a table is specified. The value written + * is the next_table_full of that particular action. + * + * However, the compiler owns this register in the following scenarios: + * 1. For match_with_no_key tables, where the pathway is through the hit pathway, + * the driver does not touch this register, as the values are actually reversed + * 2. For a table that is split into multiple tables, the driver only writes the + * last value. Thus the compiler now sets up this register for all tables + * before this. + */ + merge.next_table_format_data[logical_id].match_next_table_adr_miss_value = + tbl->get_miss_next().next_table_id(); + /** + * The next_table_format_data register is built up of three values: + * - match_next_table_adr_miss_value - Configurable at runtime + * - match_next_table_adr_mask - Static Config + * - match_next_table_adr_default - Static Config + * + * In order to reprogram the register at runtime, the driver must have all three values to + * not require a hardware read, even though only one is truly programmable. Thus in the + * context JSON, we provide the two extra values in an extremely poorly named JSON + * + * ERROR: Driver doesn't read the match_next_table_adr_default + * "default_next_table_mask" - match_next_table_adr_mask + * "default_next_table" - Only required if a table has no default_action specified, which is + * only a Glass value. This could always be 0. Perhaps we can remove from Brig through + * compiler version? + * + */ +} + +template <> +void MatchTable::write_regs(Target::Tofino::mau_regs ®s, int type, Table *result) { + write_common_regs(regs, type, result); +} diff --git a/backends/tofino/bf-asm/tofino/meter.h b/backends/tofino/bf-asm/tofino/meter.h new file mode 100644 index 00000000000..639c62ff306 --- /dev/null +++ b/backends/tofino/bf-asm/tofino/meter.h @@ -0,0 +1,39 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_TOFINO_METER_H_ +#define BF_ASM_TOFINO_METER_H_ + +#include + +class Target::Tofino::MeterTable : public ::MeterTable { + friend class ::MeterTable; + MeterTable(int line, const char *n, gress_t gr, Stage *s, int lid) + : ::MeterTable(line, n, gr, s, lid) {} +}; + +template <> +void MeterTable::setup_teop_regs(Target::Tofino::mau_regs &, int) { + BUG(); // no teop on tofino +} + +template <> +void MeterTable::write_alu_vpn_range(Target::Tofino::mau_regs &) { + BUG(); // not available on tofino +} + +#endif /* BF_ASM_TOFINO_METER_H_ */ diff --git a/backends/tofino/bf-asm/tofino/parser.cpp b/backends/tofino/bf-asm/tofino/parser.cpp new file mode 100644 index 00000000000..d61bbb48dce --- /dev/null +++ b/backends/tofino/bf-asm/tofino/parser.cpp @@ -0,0 +1,1631 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "misc.h" +#include "parser-tofino-jbay.h" +#include "target.h" +#include "top_level.h" + +// ---------------------------------------------------------------------------- +// Slots & Useful constants +// ---------------------------------------------------------------------------- + +// Following constants are used for detection of unused slot (e.g., initial value) and +// minimal/maximal indexes for extractor slots +static unsigned EXTRACT_SLOT_UNUSED = 511; +static unsigned EXTRACT_SLOT_CONSTANT_DIS = 0; +static unsigned EXTRACT_SLOT_CONSTANT_EN = 1; +static unsigned EXTRACT_SLOT_CONSTANT_ZERO = 0; +static unsigned PHV_MIN_INDEX = 0; +static unsigned PHV_MAX_INDEX = 224; +static unsigned TPHV_MIN_INDEX = 256; +static unsigned TPHV_MAX_INDEX = 368; + +/* remapping structure for getting at the config bits for phv output + * programming in a systematic way */ +struct tofino_phv_output_map { + int size; /* 8, 16, or 32 */ + ubits<9> *dst; + ubits_base *src; /* 6 or 8 bits */ + ubits<1> *src_type, *offset_add, *offset_rot; +}; +std::ostream &operator<<(std::ostream &of, const tofino_phv_output_map *om) { + of << om->size << "bit, dst = " << std::to_string(om->dst->value) + << ", src = " << std::to_string(om->src->value); + if (om->src_type) of << ", src_type = " << std::to_string(om->src_type->value); + if (om->offset_add) of << ", offset_add = " << std::to_string(om->offset_add->value); + if (om->offset_rot) of << ", offset_rot = " << std::to_string(om->offset_rot->value); + return of; +} +enum extractor_slots { + /* enum for indexes in the tofino_phv_output_map */ + phv_32b_0, + phv_32b_1, + phv_32b_2, + phv_32b_3, + phv_16b_0, + phv_16b_1, + phv_16b_2, + phv_16b_3, + phv_8b_0, + phv_8b_1, + phv_8b_2, + phv_8b_3, + tofino_phv_output_map_size, +}; + +// PHV use slots: ordered list of slots to try +// +// For example, when trying to find a 32b slot: +// 1. First try the 4 x 32b extractors. +// 2. If that fails, try pairs of 16b extractors. +// 3. If that still fails, finally try the 8b extractors together. +// +// For checksums, allocate in the reverse order as we need to fill +// from the last container back due to a HW bug (see MODEL-210). +// +// FIXME: what does "shift" represent??? +static struct phv_use_slots { + int idx; + unsigned usemask, shift, size; +} phv_32b_slots[] = {{phv_32b_0, 1U << phv_32b_0, 0, 32}, {phv_32b_1, 1U << phv_32b_1, 0, 32}, + {phv_32b_2, 1U << phv_32b_2, 0, 32}, {phv_32b_3, 1U << phv_32b_3, 0, 32}, + {phv_16b_0, 3U << phv_16b_0, 16, 16}, {phv_16b_2, 3U << phv_16b_2, 16, 16}, + {phv_8b_0, 0xfU << phv_8b_0, 24, 8}, {0, 0, 0, 0}}, + phv_16b_slots[] = {{phv_16b_0, 1U << phv_16b_0, 0, 16}, + {phv_16b_1, 1U << phv_16b_1, 0, 16}, + {phv_16b_2, 1U << phv_16b_2, 0, 16}, + {phv_16b_3, 1U << phv_16b_3, 0, 16}, + {phv_8b_0, 3U << phv_8b_0, 8, 8}, + {phv_8b_2, 3U << phv_8b_2, 8, 8}, + {0, 0, 0, 0}}, + phv_8b_slots[] = {{phv_8b_0, 1U << phv_8b_0, 0, 8}, + {phv_8b_1, 1U << phv_8b_1, 0, 8}, + {phv_8b_2, 1U << phv_8b_2, 0, 8}, + {phv_8b_3, 1U << phv_8b_3, 0, 8}, + {0, 0, 0, 0}}, + phv_32b_csum_slots[] = {{phv_32b_3, 1U << phv_32b_3, 0, 32}, + {phv_32b_2, 1U << phv_32b_2, 0, 32}, + {phv_32b_1, 1U << phv_32b_1, 0, 32}, + {phv_32b_0, 1U << phv_32b_0, 0, 32}, + {phv_16b_2, 3U << phv_16b_2, 16, 16}, + {phv_16b_0, 3U << phv_16b_0, 16, 16}, + {phv_8b_0, 0xfU << phv_8b_0, 24, 8}, + {0, 0, 0, 0}}, + phv_16b_csum_slots[] = {{phv_16b_3, 1U << phv_16b_3, 0, 16}, + {phv_16b_2, 1U << phv_16b_2, 0, 16}, + {phv_16b_1, 1U << phv_16b_1, 0, 16}, + {phv_16b_0, 1U << phv_16b_0, 0, 16}, + {phv_8b_2, 3U << phv_8b_2, 8, 8}, + {phv_8b_0, 3U << phv_8b_0, 8, 8}, + {0, 0, 0, 0}}, + phv_8b_csum_slots[] = {{phv_8b_3, 1U << phv_8b_3, 0, 8}, + {phv_8b_2, 1U << phv_8b_2, 0, 8}, + {phv_8b_1, 1U << phv_8b_1, 0, 8}, + {phv_8b_0, 1U << phv_8b_0, 0, 8}, + {0, 0, 0, 0}}; + +static phv_use_slots *get_phv_use_slots(int size) { + phv_use_slots *usable_slots = nullptr; + + if (size == 32) + usable_slots = phv_32b_slots; + else if (size == 16) + usable_slots = phv_16b_slots; + else if (size == 8) + usable_slots = phv_8b_slots; + else + BUG(); + + return usable_slots; +} + +static phv_use_slots *get_phv_csum_use_slots(int size) { + phv_use_slots *usable_slots = nullptr; + + if (size == 32) + usable_slots = phv_32b_csum_slots; + else if (size == 16) + usable_slots = phv_16b_csum_slots; + else if (size == 8) + usable_slots = phv_8b_csum_slots; + else + BUG(); + + return usable_slots; +} + +// ---------------------------------------------------------------------------- +// Helping classes +// ---------------------------------------------------------------------------- + +/// Helping cache to remember values for a different parser objects +/// based on the type of extraction size. The storage is done into two +/// layers and user is free to specify the values of layer 1 and layer 2 +/// types. The third type specifies the return value +template +class TwoLevelCache { + std::map> m_cache; + + public: + void insert(const T1 key1, T2 key2, T3 val) { m_cache[key1][key2] = val; } + + bool has(const T1 key1, T2 key2) const { + if (!m_cache.count(key1)) return false; + auto level1 = m_cache.at(key1); + + return level1.count(key2); + } + + T3 get(const T1 key1, T2 key2) const { return m_cache.at(key1).at(key2); } +}; + +/** + * @brief This class is used for internal tracking of Tofino output map + * extractor allocation. It is beneficial during the debugging process of this + * functionality because it can provid the answer to question: + * "What is alloacted into this extractor slot?" + */ +class MatchSlotTracker { + using SetMap = + TwoLevelCache; + using SaveMap = + TwoLevelCache; + using CsumMap = TwoLevelCache; + using PaddingMap = TwoLevelCache; + + public: + // Helping caches for tracking of slot occupancy mapping + SetMap setMap; + SaveMap saveMap; + CsumMap csumMap; + PaddingMap padMap; + + /** + * @brief Get the db slots object + * + * @param match Match line to dump + * @param slot_idx Passed index of slot which needs to be dumped + * @return std::string object with dumped data + */ + std::string get_db_slots(const Parser::State::Match *match, const int slot_idx) const { + std::stringstream ss; + ss << "Mapping for state " << match->state->name; + if (match->match) ss << ", match " << match->match; + ss << ", slot " << slot_idx << ": "; + + if (setMap.has(match, slot_idx)) { + auto set = setMap.get(match, slot_idx); + ss << "set, " << set->where; + } else if (saveMap.has(match, slot_idx)) { + auto save = saveMap.get(match, slot_idx); + ss << "save, " << save->where; + } else if (csumMap.has(match, slot_idx)) { + auto csum = csumMap.get(match, slot_idx); + ss << "csum, " << csum->dest; + } else if (padMap.has(match, slot_idx)) { + ss << "fake extraction padding, " << padMap.get(match, slot_idx); + } else { + ss << ""; + } + + return ss.str(); + } +}; + +static MatchSlotTracker matchSlotTracker; + +// ---------------------------------------------------------------------------- +// Parser configuration dump +// ---------------------------------------------------------------------------- + +template <> +void Parser::Checksum::write_config(Target::Tofino::parser_regs ®s, Parser *parser) { + if (unit == 0) + write_tofino_row_config(regs.memory[gress].po_csum_ctrl_0_row[addr]); + else if (unit == 1) + write_tofino_row_config(regs.memory[gress].po_csum_ctrl_1_row[addr]); + else + error(lineno, "invalid unit for parser checksum"); +} + +template <> +void Parser::CounterInit::write_config(Target::Tofino::parser_regs ®s, gress_t gress, int idx) { + auto &ctr_init_ram = regs.memory[gress].ml_ctr_init_ram[idx]; + ctr_init_ram.add = add; + ctr_init_ram.mask = mask; + ctr_init_ram.rotate = rot; + ctr_init_ram.max = max; + ctr_init_ram.src = src; +} + +template <> +void Parser::RateLimit::write_config(::Tofino::regs_pipe ®s, gress_t gress) { + if (gress == INGRESS) { + auto &ctrl = regs.pmarb.parb_reg.parb_group.i_output_rate_ctrl; + ctrl.ratectrl_inc = inc; + ctrl.ratectrl_dec = dec; + ctrl.ratectrl_max = max; + ctrl.ratectrl_ena = 1; + } else if (gress == EGRESS) { + auto &ctrl = regs.pmarb.parb_reg.parb_group.e_output_rate_ctrl; + ctrl.ratectrl_inc = inc; + ctrl.ratectrl_dec = dec; + ctrl.ratectrl_max = max; + ctrl.ratectrl_ena = 1; + } +} + +template <> +void Parser::State::Match::write_lookup_config(Target::Tofino::parser_regs ®s, State *state, + int row) const { + auto &word0 = regs.memory[state->gress].ml_tcam_row_word0[row]; + auto &word1 = regs.memory[state->gress].ml_tcam_row_word1[row]; + match_t lookup = {0, 0}; + unsigned dont_care = 0; + for (int i = 0; i < 4; i++) { + lookup.word0 <<= 8; + lookup.word1 <<= 8; + dont_care <<= 8; + if (state->key.data[i].bit >= 0) { + lookup.word0 |= ((match.word0 >> state->key.data[i].bit) & 0xff); + lookup.word1 |= ((match.word1 >> state->key.data[i].bit) & 0xff); + } else { + dont_care |= 0xff; + } + } + lookup.word0 |= dont_care; + lookup.word1 |= dont_care; + word0.lookup_16 = (lookup.word0 >> 16) & 0xffff; + word1.lookup_16 = (lookup.word1 >> 16) & 0xffff; + word0.lookup_8[0] = (lookup.word0 >> 8) & 0xff; + word1.lookup_8[0] = (lookup.word1 >> 8) & 0xff; + word0.lookup_8[1] = lookup.word0 & 0xff; + word1.lookup_8[1] = lookup.word1 & 0xff; + word0.curr_state = state->stateno.word0; + word1.curr_state = state->stateno.word1; + if (state->key.ctr_zero >= 0) { + word0.ctr_zero = (match.word0 >> state->key.ctr_zero) & 1; + word1.ctr_zero = (match.word1 >> state->key.ctr_zero) & 1; + } else { + word0.ctr_zero = word1.ctr_zero = 1; + } + + if (state->key.ctr_neg >= 0) { + word0.ctr_neg = (match.word0 >> state->key.ctr_neg) & 1; + word1.ctr_neg = (match.word1 >> state->key.ctr_neg) & 1; + } else { + word0.ctr_neg = word1.ctr_neg = 1; + } + + word0.ver_0 = word1.ver_0 = 1; + word0.ver_1 = word1.ver_1 = 1; +} + +/* FIXME -- combine these next two methods into a single method on MatchKey */ +/* FIXME -- factor Tofino/JBay variation better (most is common) */ +template <> +int Parser::State::write_lookup_config(Target::Tofino::parser_regs ®s, Parser *pa, State *state, + int row, const std::vector &prev) { + LOG2("-- checking match from state " << name << " (" << stateno << ')'); + auto &ea_row = regs.memory[gress].ml_ea_row[row]; + int max_off = -1; + for (int i = 0; i < 4; i++) { + if (i == 1) continue; + if (key.data[i].bit < 0) continue; + bool set = true; + for (State *p : prev) { + if (p->key.data[i].bit >= 0) { + set = false; + if (p->key.data[i].byte != key.data[i].byte) + error(p->lineno, + "Incompatible match fields between states " + "%s and %s, triggered from state %s", + name.c_str(), p->name.c_str(), state->name.c_str()); + } + } + if (set && key.data[i].byte != MatchKey::USE_SAVED) { + int off = key.data[i].byte + ea_row.shift_amt; + if (off < 0 || off >= 32) { + error(key.lineno, + "Match offset of %d in state %s out of range " + "for previous state %s", + key.data[i].byte, name.c_str(), state->name.c_str()); + } else if (i) { + ea_row.lookup_offset_8[(i - 2)] = off; + ea_row.ld_lookup_8[(i - 2)] = 1; + max_off = std::max(max_off, off); + } else { + ea_row.lookup_offset_16 = off; + ea_row.ld_lookup_16 = 1; + max_off = std::max(max_off, off + 1); + } + } + } + return max_off; +} + +template <> +int Parser::State::Match::write_load_config(Target::Tofino::parser_regs ®s, Parser *pa, + State *state, int row) const { + auto &ea_row = regs.memory[state->gress].ml_ea_row[row]; + int max_off = -1; + for (int i = 0; i < 4; i++) { + if (i == 1) continue; + if (load.data[i].bit < 0) continue; + if (load.data[i].byte != MatchKey::USE_SAVED) { + int off = load.data[i].byte; + if (off < 0 || off >= 32) { + error(load.lineno, "Load offset of %d in state %s out of range", load.data[i].byte, + state->name.c_str()); + } else if (i) { + ea_row.lookup_offset_8[(i - 2)] = off; + ea_row.ld_lookup_8[(i - 2)] = 1; + max_off = std::max(max_off, off); + } else { + ea_row.lookup_offset_16 = off; + ea_row.ld_lookup_16 = 1; + max_off = std::max(max_off, off + 1); + } + } + } + return max_off; +} + +// Narrow-to-wide extraction alignment needs adjusting when +// 8b/16b checksum validations are written in the same cycle +bool adjust_phv_use_slot(phv_use_slots &slot, int size, int csum_8b, int csum_16b) { + if ((size == 32 && slot.idx >= phv_16b_0) || (size == 16 && slot.idx >= phv_8b_0)) { + if (slot.idx <= phv_16b_3) { + slot.idx -= csum_16b; + slot.usemask >>= csum_16b; + return slot.idx >= phv_16b_0; + } else { + slot.idx -= csum_8b; + slot.usemask >>= csum_8b; + return slot.idx >= phv_8b_0; + } + } + return true; +} + +template <> +void Parser::Checksum::write_output_config(Target::Tofino::parser_regs ®s, Parser *pa, + State::Match *ma, void *_map, unsigned &used) const { + if (type != 0 || !dest) return; + + // checksum verification requires the last extractor to be a dummy (to work around a RTL bug) + // see MODEL-210 for discussion. + + tofino_phv_output_map *map = reinterpret_cast(_map); + + phv_use_slots *usable_slots = get_phv_csum_use_slots(dest->reg.size); + + auto &slot = usable_slots[0]; + + auto id = dest->reg.parser_id(); + *map[slot.idx].dst = id; + matchSlotTracker.csumMap.insert(ma, slot.idx, this); + // The source address is checked for source extract errors whenever the dest + // is not 511. To prevent errors when buf_req = 0 (corresponding to states with no extracts), + // point the source to the version area of the source range which is always valid. + *map[slot.idx].src = PARSER_SRC_MAX_IDX - (dest->reg.size / 8) + 1; + used |= slot.usemask; + + pa->phv_allow_bitwise_or[id] = 1; +} + +template <> +int Parser::State::Match::Save::write_output_config(Target::Tofino::parser_regs ®s, void *_map, + unsigned &used, int csum_8b, + int csum_16b) const { + tofino_phv_output_map *map = reinterpret_cast(_map); + + int slot_size = (hi - lo + 1) * 8; + phv_use_slots *usable_slots = get_phv_use_slots(slot_size); + + for (int i = 0; usable_slots[i].usemask; i++) { + auto slot = usable_slots[i]; + if (!adjust_phv_use_slot(slot, where->reg.size, csum_8b, csum_16b)) continue; + if (used & slot.usemask) continue; + if ((flags & ROTATE) && !map[slot.idx].offset_rot) continue; + + if ((where->reg.size == 32 && slot.idx >= phv_16b_0) || + (where->reg.size == 16 && slot.idx >= phv_8b_0)) { + match->has_narrow_to_wide_extract = true; + + if (where->reg.size == 32 && slot.idx == phv_8b_0) { + match->narrow_to_wide_32b_8.push_back(&where); + } else if (where->reg.size == 32 && slot.idx >= phv_16b_0) { + match->narrow_to_wide_32b_16.push_back(&where); + } else { + match->narrow_to_wide_16b_8.push_back(&where); + } + } + + // swizzle upper/lower pairs of extractors for 4x8->32 + // a 32b value using 8b extractors must use the extractors in this order: [2 3 0 1] + bool swizzle_b1 = where->reg.size == 32 && slot.idx == phv_8b_0; + + int byte = lo; + for (int i = slot.idx; slot.usemask & (1U << i); i++, byte += slot.size / 8U) { + int x = i; + if (swizzle_b1) x ^= 2; + + *map[x].dst = where->reg.parser_id(); + *map[x].src = byte; + matchSlotTracker.saveMap.insert(match, x, this); + if (flags & OFFSET) *map[x].offset_add = 1; + if (flags & ROTATE) *map[x].offset_rot = 1; + } + used |= slot.usemask; + return hi; + } + error(where.lineno, "Ran out of phv output extractor slots"); + return -1; +} + +bool can_slot_extract_constant(int slot) { + return slot != phv_16b_2 && slot != phv_16b_3 && slot != phv_32b_2 && slot != phv_32b_3; +} + +/** + * @brief Encode constant @p val for use with extractor slot @p slot. + * + * @param slot Valid value of enum extractor_slot + * @param val Constant to encode + * @return int The encoded constant, or -1 if given @p slot cannot extract a constant or is not a + * valid value of enum extractor_slot + */ +static int encode_constant_for_slot(int slot, unsigned val) { + if (!can_slot_extract_constant(slot)) return -1; + if (val == 0) return val; + switch (slot) { + case phv_32b_0: + case phv_32b_1: + for (int i = 0; i < 32; i++) { + if ((val & 1) && (0x7 & val) == val) return (i << 3) | val; + val = ((val >> 1) | (val << 31)) & 0xffffffffU; + } + return -1; + case phv_16b_0: + case phv_16b_1: + if ((val >> 16) && encode_constant_for_slot(slot, val >> 16) < 0) return -1; + val &= 0xffff; + for (int i = 0; i < 16; i++) { + if ((val & 1) && (0xf & val) == val) return (i << 4) | val; + val = ((val >> 1) | (val << 15)) & 0xffffU; + } + return -1; + case phv_8b_0: + case phv_8b_1: + case phv_8b_2: + case phv_8b_3: + return val & 0xff; + default: + BUG(); + return -1; + } +} + +template <> +void Parser::State::Match::Set::write_output_config(Target::Tofino::parser_regs ®s, void *_map, + unsigned &used, int csum_8b, + int csum_16b) const { + tofino_phv_output_map *map = reinterpret_cast(_map); + + phv_use_slots *usable_slots = get_phv_use_slots(where->reg.size); + + for (int i = 0; usable_slots[i].usemask; i++) { + auto slot = usable_slots[i]; + if (!adjust_phv_use_slot(slot, where->reg.size, csum_8b, csum_16b)) continue; + if (used & slot.usemask) continue; + if (!map[slot.idx].src_type) continue; + if ((flags & ROTATE) && (!map[slot.idx].offset_rot || slot.shift)) continue; + unsigned shift = 0; + bool can_encode = true; + for (int i = slot.idx; slot.usemask & (1U << i); i++) { + if (encode_constant_for_slot(i, (what << where->lo) >> shift) < 0) { + can_encode = false; + break; + } + shift += slot.size; + } + if (!can_encode) continue; + + if ((where->reg.size == 32 && slot.idx >= phv_16b_0) || + (where->reg.size == 16 && slot.idx >= phv_8b_0)) { + match->has_narrow_to_wide_extract = true; + + if (where->reg.size == 32 && slot.idx == phv_8b_0) { + match->narrow_to_wide_32b_8.push_back(&where); + } else if (where->reg.size == 32 && slot.idx >= phv_16b_0) { + match->narrow_to_wide_32b_16.push_back(&where); + } else { + match->narrow_to_wide_16b_8.push_back(&where); + } + } + + // swizzle upper/lower pairs of extractors for 4x8->32 + // a 32b value using 8b extractors must use the extractors in this order: [2 3 0 1] + bool swizzle_b1 = where->reg.size == 32 && slot.idx == phv_8b_0; + + // Go from most- to least-significant slice + shift = where->reg.size - slot.size; + for (int i = slot.idx; slot.usemask & (1U << i); i++) { + int x = i; + if (swizzle_b1) x ^= 2; + + *map[x].dst = where->reg.parser_id(); + *map[x].src_type = 1; + auto v = encode_constant_for_slot(x, (what << where->lo) >> shift); + *map[x].src = v; + matchSlotTracker.setMap.insert(match, x, this); + if (flags & OFFSET) *map[x].offset_add = 1; + if (flags & ROTATE) *map[x].offset_rot = 1; + shift -= slot.size; + } + used |= slot.usemask; + return; + } + error(where.lineno, "Ran out of phv output extractor slots"); +} + +/** Tofino1-specific output map management + * Tofino1 has separate 8- 16- and 32-bit extractors with various limitations on extracting + * constants and capability of ganging extractors to extract larger PHVs or extrating adjacent + * pairs of smaller PHVs. They're also addressed via named registers rather than an array, + * so we build an array of pointers into the reg object to simplify things. The `used` + * value ends up begin a simple 12-bit bitmap with 1 bit for each extractor. + */ + +#define OUTPUT_MAP_INIT(MAP, ROW, SIZE, INDEX) \ + MAP[phv_##SIZE##b_##INDEX].size = SIZE; \ + MAP[phv_##SIZE##b_##INDEX].dst = &ROW.phv_##SIZE##b_dst_##INDEX; \ + MAP[phv_##SIZE##b_##INDEX].src = &ROW.phv_##SIZE##b_src_##INDEX; \ + MAP[phv_##SIZE##b_##INDEX].src_type = &ROW.phv_##SIZE##b_src_type_##INDEX; \ + MAP[phv_##SIZE##b_##INDEX].offset_add = &ROW.phv_##SIZE##b_offset_add_dst_##INDEX; \ + MAP[phv_##SIZE##b_##INDEX].offset_rot = &ROW.phv_##SIZE##b_offset_rot_imm_##INDEX; +#define OUTPUT_MAP_INIT_PART(MAP, ROW, SIZE, INDEX) \ + MAP[phv_##SIZE##b_##INDEX].size = SIZE; \ + MAP[phv_##SIZE##b_##INDEX].dst = &ROW.phv_##SIZE##b_dst_##INDEX; \ + MAP[phv_##SIZE##b_##INDEX].src = &ROW.phv_##SIZE##b_src_##INDEX; \ + MAP[phv_##SIZE##b_##INDEX].src_type = 0; \ + MAP[phv_##SIZE##b_##INDEX].offset_add = &ROW.phv_##SIZE##b_offset_add_dst_##INDEX; \ + MAP[phv_##SIZE##b_##INDEX].offset_rot = 0; + +template <> +void *Parser::setup_phv_output_map(Target::Tofino::parser_regs ®s, gress_t gress, int row) { + static tofino_phv_output_map map[tofino_phv_output_map_size]; + auto &action_row = regs.memory[gress].po_action_row[row]; + OUTPUT_MAP_INIT(map, action_row, 32, 0) + OUTPUT_MAP_INIT(map, action_row, 32, 1) + OUTPUT_MAP_INIT_PART(map, action_row, 32, 2) + OUTPUT_MAP_INIT_PART(map, action_row, 32, 3) + OUTPUT_MAP_INIT(map, action_row, 16, 0) + OUTPUT_MAP_INIT(map, action_row, 16, 1) + OUTPUT_MAP_INIT_PART(map, action_row, 16, 2) + OUTPUT_MAP_INIT_PART(map, action_row, 16, 3) + OUTPUT_MAP_INIT(map, action_row, 8, 0) + OUTPUT_MAP_INIT(map, action_row, 8, 1) + OUTPUT_MAP_INIT(map, action_row, 8, 2) + OUTPUT_MAP_INIT(map, action_row, 8, 3) + return map; +} + +template <> +void Parser::mark_unused_output_map(Target::Tofino::parser_regs ®s, void *_map, unsigned used) { + tofino_phv_output_map *map = reinterpret_cast(_map); + for (int i = 0; i < tofino_phv_output_map_size; i++) + if (!(used & (1U << i))) *map[i].dst = 0x1ff; +} + +template <> +void Parser::State::Match::HdrLenIncStop::write_config( + Tofino::memories_all_parser_::_po_action_row &) const { + BUG(); // no hdr_len_inc_stop on tofino; should not get here +} + +template <> +void Parser::State::Match::Clot::write_config(Tofino::memories_all_parser_::_po_action_row &, int, + bool) const { + BUG(); // no CLOTs on tofino; should not get here +} + +template <> +void Parser::State::Match::write_counter_config( + Target::Tofino::parser_regs::_memory::_ml_ea_row &ea_row) const { + ea_row.ctr_amt_idx = ctr_instr ? ctr_instr->addr : ctr_imm_amt; + ea_row.ctr_ld_src = ctr_ld_src; + ea_row.ctr_load = ctr_load; +} + +template +void init_common_regs(Parser *p, COMMON ®s, gress_t gress) { + // TODO: fixed config copied from compiler -- needs to be controllable + for (int i = 0; i < 4; i++) { + if (p->start_state[i]) { + regs.start_state.state[i] = p->start_state[i]->stateno.word1; + regs.enable_.enable_[i] = 1; + } + regs.pri_start.pri[i] = p->priority[i]; + regs.pri_thresh.pri[i] = p->pri_thresh[i]; + } + regs.mode = 4; + regs.max_iter.max = 128; + if (p->parser_error.lineno >= 0) { + regs.err_phv_cfg.dst = p->parser_error->reg.parser_id(); + regs.err_phv_cfg.aram_mbe_en = 1; + regs.err_phv_cfg.ctr_range_err_en = 1; + regs.err_phv_cfg.dst_cont_err_en = 1; + regs.err_phv_cfg.fcs_err_en = 1; + regs.err_phv_cfg.multi_wr_err_en = 1; + regs.err_phv_cfg.no_tcam_match_err_en = 1; + regs.err_phv_cfg.partial_hdr_err_en = 1; + regs.err_phv_cfg.phv_owner_err_en = 1; + regs.err_phv_cfg.src_ext_err_en = 1; + regs.err_phv_cfg.timeout_cycle_err_en = 1; + regs.err_phv_cfg.timeout_iter_err_en = 1; + } +} + +enum class AnalysisType { BIT8, BIT16 }; +using extractor_slots_list = std::initializer_list; +const extractor_slots_list phv_8bit_extractors = {phv_8b_0, phv_8b_1, phv_8b_2, phv_8b_3}; +const extractor_slots_list phv_16bit_extractors = {phv_16b_0, phv_16b_1, phv_16b_2, phv_16b_3}; +// Declare a helping type for the count cache class +using ExtractionCountCache = TwoLevelCache; + +/// Count the number of extractions for a given @p match. +/// The method takes the @p elems list which holds PHV indexes to check +/// (accepted lists are @p phv_8bit_extractors and @p phv_16_bit_extractors). +int count_number_of_extractions(Parser *parser, Target::Tofino::parser_regs ®s, + Parser::State::Match *match, const AnalysisType type) { + int used = 0; + int row = parser->match_to_row.at(match); + auto map = reinterpret_cast( + parser->setup_phv_output_map(regs, parser->gress, row)); + + auto elems = type == AnalysisType::BIT8 ? phv_8bit_extractors : phv_16bit_extractors; + for (auto i : elems) { + if (map[i].dst->value != EXTRACT_SLOT_UNUSED) { + used++; + } + } + + return used; +} + +/// Pad collector object which provides mapping from a narrow-to-wide match +/// to added padding +class PaddingInfoCollector { + public: + struct PadInfo { + /// The number of added extractors to work correctly + int m_count8; + int m_count16; + + PadInfo() { + m_count8 = 0; + m_count16 = 0; + } + + void add(const AnalysisType type, const int val) { + if (type == AnalysisType::BIT8) { + m_count8 += val; + } else { + m_count16 += val; + } + } + }; + + /// Information for one parser state where the padding + // is being added + struct PadState { + /// Added padding information into parser states (successors or predecessors) + std::map m_padding; + + void addPadInfo(Parser::State::Match *match, AnalysisType pad, int count) { + if (count == 0) return; + + if (!m_padding.count(match)) { + m_padding[match] = new PadInfo; + } + + m_padding[match]->add(pad, count); + } + + bool hasPadInfo() { return m_padding.size() != 0; } + + void print() { + std::stringstream message; + message << " Pad State Info : " << std::endl; + for (auto &m : m_padding) { + message << " \t State(match) : " << m.first->state->name << "(" << m.first->match + << ")" << " -> { m_count8 : " << m.second->m_count8 + << ", m_count16 : " << m.second->m_count16 << " }" << std::endl; + } + LOG1(message.str()); + } + }; + + PadState *getPadState(Parser::State::Match *match) { + if (!m_nrw_matches.count(match)) { + m_nrw_matches[match] = new PadState; + } + + return m_nrw_matches[match]; + } + + void printPadInfo() { + for (auto s : m_nrw_matches) { + auto nrw_match = s.first; + auto info_collector = s.second; + // Skip the info if we don't have any stored padding + if (!info_collector->hasPadInfo()) { + continue; + } + + std::stringstream message; + message << "State " << nrw_match->state->name; + if (nrw_match->match == true) { + message << ", match " << nrw_match->match; + } + + message << " is using the narrow-to-wide extraction: " << std::endl; + + if (nrw_match->narrow_to_wide_32b_16.size() != 0) { + message << "\t* 32 bit extractors are replaced by 2 x 16 bit extractors: "; + for (auto ref : nrw_match->narrow_to_wide_32b_16) { + message << ref->name() << " "; + } + message << std::endl; + } + + if (nrw_match->narrow_to_wide_32b_8.size() != 0) { + message << "\t* 32 bit extractors are replaced by 4 x 8 bit extractors: "; + for (auto ref : nrw_match->narrow_to_wide_32b_8) { + message << ref->name() << " "; + } + message << std::endl; + } + + if (nrw_match->narrow_to_wide_16b_8.size() != 0) { + message << "\t* 16 bit extractors are replaced by 2 x 8 bit extractors: "; + for (auto ref : nrw_match->narrow_to_wide_16b_8) { + message << ref->name() << " "; + } + message << std::endl; + } + + message + << "The following extractions need to be added to parser states to work correctly:" + << std::endl; + + for (auto pad : info_collector->m_padding) { + auto match = pad.first; + auto pad_info = pad.second; + + message << "\t* State " << match->state->name; + if (match->match == true) { + message << ", match " << match->match; + } + + message << " needs " << pad_info->m_count8 << " x 8 bit and " << pad_info->m_count16 + << " x 16 bit extractions to be added" << std::endl; + } + + LOG1("WARNING: " << message.str()); + } + } + + private: + /// This provides mapping between the narrow-to-wide (NRW) match and collected + /// padding information + std::map m_nrw_matches; +}; + +/// Size of internal parser FIFO +static const int parser_fifo_size = 32; + +/// Compute the @p val / @p div and ceil it to the nearest upper value. The result +/// will be wrapped to the FIFO size in parser. +int ceil_and_wrap_to_fifo_size(int val, int div) { + int fifo_items = val > parser_fifo_size ? parser_fifo_size : val; + return (fifo_items + div - 1) / div; +} + +int analyze_worst_extractor_path(Parser *parser, Target::Tofino::parser_regs ®s, + Parser::State::Match *match, AnalysisType type, + std::set &visited, ExtractionCountCache &cache) { + if (visited.count(match->state)) { + // We have found a node in a loop --> we will get via our predessors into the same state. + // This means that we can take this loop many times and that we need to distribute the + // maximal FIFO value to our parets (we are predecessors of our parents). + // + // IN SUCH CASE THE NUMBER OF EXTRACTIONS FOR ALL SUCCESSORS DOESN'T CATCH + // THE REALITY. IT IS JUST FOR THE SIMULATION OF FULL PARSER FIFO BLOCKS. + // REALITY IS COVERED WHEN THE GRAPH DOESN'T HAVE LOOPS + return parser_fifo_size; + } + + if (LOGGING(3)) { + std::stringstream ss; + ss << "Processing match " << match->state->name << ", gress = " << match->state->gress; + if (match->match) { + ss << ", match " << match->match; + } + LOG3(ss.str()); + } + + // Check the cache if we know the result + if (cache.has(match, type)) { + return cache.get(match, type); + } + + // Mark node as visited and run the analysis + visited.insert(match->state); + int extractions = count_number_of_extractions(parser, regs, match, type); + int pred_extractions = 0; + for (auto pred : match->state->pred) { + pred_extractions = + std::max(pred_extractions, + analyze_worst_extractor_path(parser, regs, pred, type, visited, cache)); + } + + // Insert the result into the cache and unmark the node as visited + visited.erase(match->state); + int extraction_result = extractions + pred_extractions; + cache.insert(match, type, extraction_result); + + return extraction_result; +} + +/** + * @brief Dump the occupancy of extraction slots in output map + * + * @param match Current match which is being processed + * @param indexes Indexes to inspect + * @param prefix Prefix to add before the print + */ +static void print_slot_occupancy(const Parser::State::Match *match, + const std::initializer_list indexes, + const std::string prefix = "") { + // Print the prefix if not empty, iterate over checked indexes and + // print slot occupancy information. + std::stringstream ss; + std::string sep; + if (prefix != "") { + ss << prefix << " : " << std::endl; + sep = "\t* "; + } + + for (auto idx : indexes) { + ss << sep << matchSlotTracker.get_db_slots(match, idx) << std::endl; + } + + auto output = ss.str(); + if (output.size() == 0) return; + LOG5(output); +} + +/** + * @brief Set the @p pad_idx or @p from_idx based on the used extractor scenario + * + * @param pad_idx Input/output for padding index + * @param from_idx Input/output for source index + * @param used Number of used extractors + * @param has_csum State is using the VERIFY checksum + * @param match State match which is being processed + * @param map Pointer on the output map configuration + */ +static void set_idx_for_16b_extractions(unsigned &pad_idx, unsigned &from_idx, const unsigned used, + const bool has_csum, const Parser::State::Match *match, + struct tofino_phv_output_map *map) { + if (used == 1) { + // One extractor is being used and the index is stored in from_idx. The allocation + // strategy here is to keep data in tuples {0,1} and {2,3}. + if (from_idx == phv_16b_0 || from_idx == phv_16b_2) { + pad_idx = from_idx + 1; + } else if (from_idx == phv_16b_1 || from_idx == phv_16b_3) { + pad_idx = from_idx - 1; + } else { + // We should never reach this point + error(match->lineno, + "Cannot identify index for 16bit extractor padding (1 extractor)!"); + } + } else { + // Three extractors are used and the unused extractor index is stored in + // the pad_idx variable. We can keep indexes in tuples + if (has_csum) { + from_idx = phv_16b_3; + } else if (pad_idx == phv_16b_0 || pad_idx == phv_16b_2) { + from_idx = pad_idx + 1; + } else if (pad_idx == phv_16b_1 || pad_idx == phv_16b_3) { + from_idx = pad_idx - 1; + } else { + // We should never reach this point + error(match->lineno, + "Cannot identify index for 16bit extractor padding (3 extractors)!"); + } + } +} + +/** + * @brief Verify all invariants for the extractor padding configuration + * + * @param pad_idx Input/output for padding index + * @param from_idx Input/output for source index + * @param used Number of used extractors + * @param has_csum State is using the VERIFY checksum + * @param match State match which is being processed + * @param map Pointer on the output map configuration + */ +static void check_16b_extractor_configuration(const unsigned pad_idx, const unsigned from_idx, + const unsigned used, const bool has_csum, + const struct tofino_phv_output_map *map) { + // 1] Indexes are kept in tuples {0,1} and {2,3}. Checksum means that from_idx is + // set to the last extractor. + bool csum = has_csum && (from_idx == phv_16b_3); + bool first_tuple = (from_idx == phv_16b_0 || from_idx == phv_16b_1) && (pad_idx <= phv_16b_1); + bool second_tuple = (from_idx == phv_16b_2 || from_idx == phv_16b_3) && (pad_idx >= phv_16b_2); + BUG_CHECK(has_csum || first_tuple || second_tuple, + "Source and destination index are not configured correctly for 16bit 2n extractor " + "padding!"); + + // 2] All indexes are sourced from global version field which is tied to zeros. + // The Checksum case means that we need to set the from index on the last 16b extractor + BUG_CHECK(map[pad_idx].dst->value != EXTRACT_SLOT_UNUSED, + "Invalid extractor destination for 16bit 2n padding!"); + if (has_csum) { + BUG_CHECK(from_idx == phv_16b_3, + "Invalid from_idx for the 16bit 2n padding with checksum!"); + } + + // Check the slot configuration - sourcing from global field and no constant for {0,1} + BUG_CHECK( + *map[pad_idx].src >= PARSER_SRC_MAX_IDX - 3 && *map[pad_idx].src != EXTRACT_SLOT_UNUSED, + "Field is not sourcing from the global version field!"); + if (pad_idx == phv_16b_0 || pad_idx == phv_16b_1) { + BUG_CHECK(*map[pad_idx].src_type == 0, + "Invalid configuration of the source type for 16b 2n padding!"); + } +} + +// +// uArch for Tofino Parser: +// * Parser Output section +// * Checksum section +// * Parse Merge section + +/** + * @brief Perform the 16b padding onto map and computed index. + * + * @param regs Register configuration instance + * @param map Tofino output map pointer + * @param pad_idx Index which needs to be padded + * @param from_idx Index which is the source of the slot configuration + */ +static void do_16b_padding(Target::Tofino::parser_regs ®s, tofino_phv_output_map *map, + const unsigned pad_idx, const unsigned from_idx) { + // Add fake extractors to reach 2n constraint, we need to copy destination and source from + // the global version field which is tied to zeros in RTL. + // We are keeping both indexes in tuples {0,1} or {2,3}. + map[pad_idx].dst->rewrite(); + *map[pad_idx].dst = *map[from_idx].dst; + *map[pad_idx].src = PARSER_SRC_MAX_IDX - 1; + if (pad_idx < phv_16b_2) { + // Even though extractors {0, 1} can extract from constants, we want to extract + // from the tied-to-zero global version field for consistency across all 16b extractors + *map[pad_idx].src_type = EXTRACT_SLOT_CONSTANT_DIS; + } + + // Mark the dummy write dest as multi-write, we need to distinguish between PHV and TPHV + if (*map[from_idx].dst >= PHV_MIN_INDEX && *map[from_idx].dst < PHV_MAX_INDEX) { + regs.ingress.prsr_reg.no_multi_wr.nmw[*map[from_idx].dst].rewrite(); + regs.egress.prsr_reg.no_multi_wr.nmw[*map[from_idx].dst].rewrite(); + + regs.ingress.prsr_reg.no_multi_wr.nmw[*map[from_idx].dst] = 0; + regs.egress.prsr_reg.no_multi_wr.nmw[*map[from_idx].dst] = 0; + } else if (*map[from_idx].dst >= TPHV_MIN_INDEX && *map[from_idx].dst < TPHV_MAX_INDEX) { + auto tphv_idx = *map[from_idx].dst - TPHV_MIN_INDEX; + regs.ingress.prsr_reg.no_multi_wr.t_nmw[tphv_idx].rewrite(); + regs.egress.prsr_reg.no_multi_wr.t_nmw[tphv_idx].rewrite(); + + regs.ingress.prsr_reg.no_multi_wr.t_nmw[tphv_idx] = 0; + regs.egress.prsr_reg.no_multi_wr.t_nmw[tphv_idx] = 0; + } +} + +/// Add the fake extractions to have 2n 16b extractions. The function returns +/// the number of added extractions. +static int pad_to_16b_extracts_to_2n(Parser *parser, Target::Tofino::parser_regs ®s, + Parser::State::Match *match) { + // Obtain the slot configuration for given row + int row = parser->match_to_row.at(match); + auto map = reinterpret_cast( + parser->setup_phv_output_map(regs, parser->gress, row)); + if (LOGGING(5)) { + print_slot_occupancy(match, phv_16bit_extractors, "Before 16bit padding"); + } + + // Count number of used extractors - the number of extractions/constant set operations and + // checksums should be the padded to 2n. + unsigned used = 0; + unsigned pad_idx = 0; + unsigned from_idx = 0; + bool from_idx_is_8b_16b = false; + for (auto i : phv_16bit_extractors) { + if (map[i].dst->value == EXTRACT_SLOT_UNUSED) { + pad_idx = i; + } else { + used++; + // Try to get an 8b or 16b index. + // If we use a single 32b index to pad then we'll hit problems + // because we need 2 x 16b to fill a 32b container. + if (!from_idx_is_8b_16b) { + from_idx = i; + auto *reg = Phv::reg(map[i].dst->value); + from_idx_is_8b_16b = reg->size == 8 || reg->size == 16; + } + } + } + + // Check if csum equals VERIFY type and destination register size is 16 + bool has_csum = false; + for (auto &c : match->csum) { + if (c.type == 0 && c.dest && c.dest->reg.size == 16) { + has_csum = true; + break; + } + } + + // Identify indexes for source and destination slots for the padding + if (used == 1 || used == 3) { + set_idx_for_16b_extractions(pad_idx, from_idx, used, has_csum, match, map); + } else { + // Value is 0,2 or 4, we are good! + if (LOGGING(5)) { + LOG5("No 16bit padding is needed to add in " << match->state->name << " state."); + } + + return 0; + } + + // Add fake extractors to reach 2n constraint, we need to copy destination and source from + // the global version field which is tied to zeros in RTL. + // We are keeping both indexes in tuples {0,1} or {2,3}. + do_16b_padding(regs, map, pad_idx, from_idx); + matchSlotTracker.padMap.insert(match, pad_idx, &map[pad_idx]); + check_16b_extractor_configuration(pad_idx, from_idx, used, has_csum, map); + + // Match can also have a value set which means we need to do the initialization for + // other rows. The first row is being initialized, other rows needs the initialization + // and padding configuration + for (int vs_offset = 1; vs_offset < match->value_set_size; ++vs_offset) { + int nrow = row + vs_offset; + LOG5("Adding the padding for value_set " + << match->value_set_name << " offset = " << vs_offset << " (row = " << nrow << ")"); + map = reinterpret_cast( + parser->setup_phv_output_map(regs, parser->gress, nrow)); + do_16b_padding(regs, map, pad_idx, from_idx); + } + + if (LOGGING(5)) { + print_slot_occupancy(match, phv_16bit_extractors, "After 16bit padding"); + } + + return 1; +} + +/** + * @brief Perform the 8b padding onto map and computed index. + * + * @param regs Register configuration instance + * @param map Tofino output map pointer + * @param from_idx Index which is the source of the slot configuration + */ +static void do_8b_padding(Target::Tofino::parser_regs ®s, tofino_phv_output_map *map, + const unsigned from_idx) { + for (auto pad_idx : phv_8bit_extractors) { + if (map[pad_idx].dst->value != EXTRACT_SLOT_UNUSED) continue; + + // Extraction slot is not used and we need to put padding there. The main idea + // is to source from the zero constant + map[pad_idx].dst->rewrite(); + *map[pad_idx].dst = *map[from_idx].dst; + *map[pad_idx].src = EXTRACT_SLOT_CONSTANT_ZERO; + *map[pad_idx].src_type = EXTRACT_SLOT_CONSTANT_EN; + } + + // Mark the dummy write dest as multi-write, we need to distinguish between PHV and TPHV + if (*map[from_idx].dst >= PHV_MIN_INDEX && *map[from_idx].dst < PHV_MAX_INDEX) { + regs.ingress.prsr_reg.no_multi_wr.nmw[*map[from_idx].dst].rewrite(); + regs.egress.prsr_reg.no_multi_wr.nmw[*map[from_idx].dst].rewrite(); + + regs.ingress.prsr_reg.no_multi_wr.nmw[*map[from_idx].dst] = 0; + regs.egress.prsr_reg.no_multi_wr.nmw[*map[from_idx].dst] = 0; + } else if (*map[from_idx].dst >= TPHV_MIN_INDEX && *map[from_idx].dst < TPHV_MAX_INDEX) { + auto tphv_idx = *map[from_idx].dst - TPHV_MIN_INDEX; + regs.ingress.prsr_reg.no_multi_wr.t_nmw[tphv_idx].rewrite(); + regs.egress.prsr_reg.no_multi_wr.t_nmw[tphv_idx].rewrite(); + + regs.ingress.prsr_reg.no_multi_wr.t_nmw[tphv_idx] = 0; + regs.egress.prsr_reg.no_multi_wr.t_nmw[tphv_idx] = 0; + } +} + +/// Add the fake extractions to have 4n 8b extractions. The function returns +/// the number of added extractions. +static int pad_to_8b_extracts_to_4n(Parser *parser, Target::Tofino::parser_regs ®s, + Parser::State::Match *match) { + // Obtain the slot configuration for given row + int row = parser->match_to_row.at(match); + auto map = reinterpret_cast( + parser->setup_phv_output_map(regs, parser->gress, row)); + if (LOGGING(5)) { + print_slot_occupancy(match, phv_8bit_extractors, "Before 8bit padding"); + } + + // Count number of used extractors - the number of extraction/constant set operations and + // checksums should be padded to 4n. The source of the added padding will be stored in + // the from_idx variable. + unsigned used = 0; + unsigned from_idx = 0; + bool from_idx_is_8b = false; + for (auto i : phv_8bit_extractors) { + if (map[i].dst->value == EXTRACT_SLOT_UNUSED) continue; + // Update the used counter and remember the used slot + used++; + // Try to get an 8b index. + // If we use a single 16b index to pad then we'll hit problems + // because we need 2 x 8b to fill a 16b container. + if (!from_idx_is_8b) { + from_idx = i; + from_idx_is_8b = Phv::reg(map[i].dst->value)->size == 8; + } + } + + if (used % 4 == 0) { + if (LOGGING(5)) { + LOG5("No 8bit padding is needed to add in " << match->state->name << " state."); + } + + return 0; + } + + // Add fake extractions to meet the 4n constraint and setup tracking + do_8b_padding(regs, map, from_idx); + for (auto pad_idx : phv_8bit_extractors) { + matchSlotTracker.padMap.insert(match, pad_idx, &map[pad_idx]); + } + + // Match can also have a value set which means we need to do the initialization for + // other rows. The first row is being initialized, other rows needs the initialization + // and padding configuration + for (int vs_offset = 1; vs_offset < match->value_set_size; ++vs_offset) { + int nrow = row + vs_offset; + LOG5("Adding the padding for value_set " + << match->value_set_name << " offset = " << vs_offset << " (row = " << nrow << ")"); + map = reinterpret_cast( + parser->setup_phv_output_map(regs, parser->gress, nrow)); + do_8b_padding(regs, map, from_idx); + } + + if (LOGGING(5)) { + print_slot_occupancy(match, phv_8bit_extractors, "After 8bit padding"); + } + + return 4 - (used % 4); +} + +/// Add padding extracts to a parser state and its children. +/// +/// @tparam use_8bit Apply to 8b extracts (true) or 16b extracts (false) +/// @param parser Parser containing the state being padded +/// @param regs +/// @param node_count Number of states to pad, including this state. States with zero extracts are +/// not counted in @p node_count. +/// @param visited +/// @param pstate +template +void pad_nodes_extracts(Parser *parser, Target::Tofino::parser_regs ®s, int node_count, + Parser::State::Match *match, std::set &visited, + PaddingInfoCollector::PadState *pstate, + std::map &cache) { + if (node_count == 0 || !match) { + LOG4("Node count or nullptr match was reached"); + return; + } + + const std::string log_pad = use_8bit ? "8b" : "16b"; + if (visited.count(match->state)) { + LOG4("State " << match->state << " was already visited in " << log_pad << " padding."); + return; + } + + visited.insert(match->state); + LOG3("Padding " << log_pad << " extracts - state = " << match->state->name << ", " + << "remaining " << log_pad << " states to pad is " << node_count); + + pstate->print(); + // Memoization to minimize path visits + // If state is visited before with the same or higher node count dont visit it + // again. Cache holds a map from state to node count + if (cache[match] >= node_count && node_count > 0) { + LOG5(" Using cached state(match) : " << match->state->name << "(" << match->match + << ") -> node count " << cache[match]); + visited.erase(match->state); + return; + } + cache[match] = node_count; + LOG5(" Caching state(match) : " << match->state->name << "(" << match->match + << ") -> node count " << cache[match]); + + // We need to be sure that we will not be passing data to 2x16bit busses. Therefore, we have + // to pad the bus entirely for 16bit extractions. In addition, we need to see node_cout 16bit + // extactions - due to possible FIFO stalls. If the node doesn't contain the required + // extraction, we don't decrement the node_count value. + int new_node_count = node_count; + auto phv_type = use_8bit ? AnalysisType::BIT8 : AnalysisType::BIT16; + if (count_number_of_extractions(parser, regs, match, phv_type)) { + if (use_8bit) { + int pad = pad_to_8b_extracts_to_4n(parser, regs, match); + pstate->addPadInfo(match, AnalysisType::BIT8, pad); + } else { + int pad = pad_to_16b_extracts_to_2n(parser, regs, match); + pstate->addPadInfo(match, AnalysisType::BIT16, pad); + } + + new_node_count--; + } + if (LOGGING(5)) pstate->print(); + + for (auto state : match->next) { + for (auto next_match : state->match) { + pad_nodes_extracts(parser, regs, new_node_count, next_match, visited, pstate, + cache); + } + } + + visited.erase(match->state); +} + +// Helping aliases for padding functions +const auto pad_nodes_8b_extracts = pad_nodes_extracts; +const auto pad_nodes_16b_extracts = pad_nodes_extracts; + +void handle_narrow_to_wide_constraint(Parser *parser, Target::Tofino::parser_regs ®s) { + // 1] Apply narrow-to-wide constraints to all predecessors + std::set narrow_to_wide_matches; + PaddingInfoCollector pad_collector; + + for (auto &kv : parser->match_to_row) { + if (kv.first->has_narrow_to_wide_extract) narrow_to_wide_matches.insert(kv.first); + } + + if (narrow_to_wide_matches.size() == 0) { + LOG2("No narrow to wide matches has been detected."); + return; + } + + // Pad all predecessors + std::set all_preds; + for (auto m : narrow_to_wide_matches) { + auto states = m->get_all_preds(); + states.insert(m); + auto pstate = pad_collector.getPadState(m); + + for (auto p : states) { + if (all_preds.count(p)) continue; + + all_preds.insert(p); + int pad = pad_to_16b_extracts_to_2n(parser, regs, p); + pstate->addPadInfo(p, AnalysisType::BIT16, pad); + pad = pad_to_8b_extracts_to_4n(parser, regs, p); + pstate->addPadInfo(p, AnalysisType::BIT8, pad); + } + } + + // 2] Apply the narrow-to-wide constraints to a given number + // of child nodes. + ExtractionCountCache cache; + for (auto m : narrow_to_wide_matches) { + auto pstate = pad_collector.getPadState(m); + std::set visited_states; + int extracts_16b = analyze_worst_extractor_path(parser, regs, m, AnalysisType::BIT16, + visited_states, cache); + int extracts_8b = analyze_worst_extractor_path(parser, regs, m, AnalysisType::BIT8, + visited_states, cache); + + if (LOGGING(3)) { + std::stringstream ss; + ss << "INFO: Used extractors for " << m->state->gress << "," << m->state->name; + if (m->match) { + ss << "," << m->match; + } + ss << " - " << "8bit:" << extracts_8b << ", 16bit:" << extracts_16b; + LOG3(ss.str()); + } + + // Count the number of nodes we need to take, the arbiter is taking 4x8bit chunks + // and 2x16b chunks of data. The result will be ceiled to 16 because that is the + // depth of the FIFO. After that, we need to apply the 16b padding to a computed number + // of nodes and the same for 8b padding. + int pass_16b_nodes = ceil_and_wrap_to_fifo_size(extracts_16b, 2); + int pass_8b_nodes = ceil_and_wrap_to_fifo_size(extracts_8b, 4); + + // The state counts represent the states _after_ the n2w state. Increment by 1 to account + // for n2w state. + if (pass_8b_nodes) pass_8b_nodes++; + if (pass_16b_nodes) pass_16b_nodes++; + + // Pad extracts: 8b extracts should be padded based on the number of states to flush 16b + // narrow-to-wide extracts, and 16b extracts should be padded based on the number + // of states to flush 8b narrow-to-wide extracts. + std::map cacheNodeCount; + pad_nodes_16b_extracts(parser, regs, pass_8b_nodes, m, visited_states, pstate, + cacheNodeCount); + cacheNodeCount.clear(); + pad_nodes_8b_extracts(parser, regs, pass_16b_nodes, m, visited_states, pstate, + cacheNodeCount); + } + + if (LOGGING(1)) { + pad_collector.printPadInfo(); + } +} + +template <> +void Parser::write_config(Target::Tofino::parser_regs ®s, json::map &ctxt_json, + bool single_parser) { + /// remove after 8.7 release + if (single_parser) { + for (auto st : all) { + st->write_config(regs, this, ctxt_json[st->gress == EGRESS ? "egress" : "ingress"]); + } + } else { + ctxt_json["states"] = json::vector(); + for (auto st : all) st->write_config(regs, this, ctxt_json["states"]); + } + + if (error_count > 0) return; + + int i = 0; + for (auto ctr : counter_init) { + if (ctr) ctr->write_config(regs, gress, i); + ++i; + } + + for (i = 0; i < checksum_use.size(); i++) { + for (auto csum : checksum_use[i]) + if (csum) csum->write_config(regs, this); + } + + if (gress == INGRESS) { + init_common_regs(this, regs.ingress.prsr_reg, INGRESS); + // regs.ingress.ing_buf_regs.glb_group.disable(); + // regs.ingress.ing_buf_regs.chan0_group.chnl_drop.disable(); + // regs.ingress.ing_buf_regs.chan0_group.chnl_metadata_fix.disable(); + // regs.ingress.ing_buf_regs.chan1_group.chnl_drop.disable(); + // regs.ingress.ing_buf_regs.chan1_group.chnl_metadata_fix.disable(); + // regs.ingress.ing_buf_regs.chan2_group.chnl_drop.disable(); + // regs.ingress.ing_buf_regs.chan2_group.chnl_metadata_fix.disable(); + // regs.ingress.ing_buf_regs.chan3_group.chnl_drop.disable(); + // regs.ingress.ing_buf_regs.chan3_group.chnl_metadata_fix.disable(); + + regs.ingress.prsr_reg.hdr_len_adj.amt = hdr_len_adj; + } + + if (gress == EGRESS) { + init_common_regs(this, regs.egress.prsr_reg, EGRESS); + for (int i = 0; i < 4; i++) regs.egress.epb_prsr_port_regs.chnl_ctrl[i].meta_opt = meta_opt; + + int prsr_max_dph = get_prsr_max_dph(); + if (prsr_max_dph * 16 > Target::PARSER_DEPTH_MAX_BYTES_MULTITHREADED_EGRESS()) { + if (!options.tof1_egr_parse_depth_checks_disabled) + warning(lineno, + "Egress parser max depth exceeds %d, which requires disabling " + "multithreading in the parser", + Target::PARSER_DEPTH_MAX_BYTES_MULTITHREADED_EGRESS()); + options.tof1_egr_parse_depth_checks_disabled = true; + } + regs.egress.epb_prsr_port_regs.multi_threading.prsr_dph_max = prsr_max_dph; + regs.egress.prsr_reg.hdr_len_adj.amt = hdr_len_adj; + } + + // FIXME: The "|| 1" causes the PHV use information to be unconditionally copied + // into the PHV ownership. This forces the parser ownership to be identical to that + // in the pipe. + // Remove to allow different ownership, but make sure that header stacks + // are processed correctly. All stack elements writeable by the parser must + // be owned by the parser. + if (options.match_compiler || 1) { + phv_use[INGRESS] |= Phv::use(INGRESS); + phv_use[EGRESS] |= Phv::use(EGRESS); + } + + for (int i : phv_use[EGRESS]) { + auto id = Phv::reg(i)->parser_id(); + if (id >= 256) { + regs.merge.phv_owner.t_owner[id - 256] = 1; + regs.ingress.prsr_reg.phv_owner.t_owner[id - 256] = 1; + regs.egress.prsr_reg.phv_owner.t_owner[id - 256] = 1; + } else if (id < 224) { + regs.merge.phv_owner.owner[id] = 1; + regs.ingress.prsr_reg.phv_owner.owner[id] = 1; + regs.egress.prsr_reg.phv_owner.owner[id] = 1; + } + } + + for (int i = 0; i < 224; i++) { + if (!phv_allow_bitwise_or[i]) { + regs.ingress.prsr_reg.no_multi_wr.nmw[i] = 1; + regs.egress.prsr_reg.no_multi_wr.nmw[i] = 1; + } + if (phv_allow_bitwise_or[i] || phv_init_valid[i]) regs.merge.phv_valid.vld[i] = 1; + } + + for (int i = 0; i < 112; i++) + if (!phv_allow_bitwise_or[256 + i]) { + regs.ingress.prsr_reg.no_multi_wr.t_nmw[i] = 1; + regs.egress.prsr_reg.no_multi_wr.t_nmw[i] = 1; + } + + // if (options.condense_json) { + // // FIXME -- removing the uninitialized memory causes problems? + // // FIXME -- walle gets the addresses wrong. Might also require explicit + // // FIXME -- zeroing in the driver on real hardware + // // regs.memory[INGRESS].disable_if_reset_value(); + // // regs.memory[EGRESS].disable_if_reset_value(); + // regs.ingress.disable_if_reset_value(); + // regs.egress.disable_if_reset_value(); + // regs.merge.disable_if_reset_value(); + // } + + // Handles the constraint when using narrow extractors to generate wide values + // (either extracted from the packet or using the constants), then you need to + // follow the rule the _every_ preceding cycle must do: + // 0 or 4 8b extractions + // 0 or 2 or 4 16b extractions + handle_narrow_to_wide_constraint(this, regs); + + if (error_count == 0 && options.gen_json) { + /// TODO remove after 8.7 release + /// TODO Needs fix to simple test harness for parsers node + /// support + if (single_parser) { + if (gress == INGRESS) { + regs.memory[INGRESS].emit_json(*open_output("memories.all.parser.ingress.cfg.json"), + "ingress"); + regs.ingress.emit_json(*open_output("regs.all.parser.ingress.cfg.json")); + } else if (gress == EGRESS) { + regs.memory[EGRESS].emit_json(*open_output("memories.all.parser.egress.cfg.json"), + "egress"); + regs.egress.emit_json(*open_output("regs.all.parser.egress.cfg.json")); + } + regs.merge.emit_json(*open_output("regs.all.parse_merge.cfg.json")); + } else { + if (gress == INGRESS) { + regs.memory[INGRESS].emit_json( + *open_output("memories.all.parser.ingress.%02x.cfg.json", parser_no), + "ingress"); + regs.ingress.emit_json( + *open_output("regs.all.parser.ingress.%02x.cfg.json", parser_no)); + } + if (gress == EGRESS) { + regs.memory[EGRESS].emit_json( + *open_output("memories.all.parser.egress.%02x.cfg.json", parser_no), "egress"); + regs.egress.emit_json( + *open_output("regs.all.parser.egress.%02x.cfg.json", parser_no)); + } + regs.merge.emit_json(*open_output("regs.all.parse_merge.cfg.json")); + } + } + + /// TODO remove after 8.7 release + if (single_parser) { + for (int i = 0; i < 18; i++) { + if (gress == INGRESS) { + TopLevel::regs()->mem_pipe.i_prsr[i].set( + "memories.all.parser.ingress", ®s.memory[INGRESS]); + TopLevel::regs()->reg_pipe.pmarb.ibp18_reg.ibp_reg[i].set( + "regs.all.parser.ingress", ®s.ingress); + } else if (gress == EGRESS) { + TopLevel::regs()->mem_pipe.e_prsr[i].set( + "memories.all.parser.egress", ®s.memory[EGRESS]); + TopLevel::regs()->reg_pipe.pmarb.ebp18_reg.ebp_reg[i].set( + "regs.all.parser.egress", ®s.egress); + } + } + } else { + if (gress == INGRESS) { + TopLevel::regs()->parser_ingress.emplace( + ctxt_json["handle"]->as_number()->val, ®s.ingress); + TopLevel::regs()->parser_memory[INGRESS].emplace( + ctxt_json["handle"]->as_number()->val, ®s.memory[INGRESS]); + } else if (gress == EGRESS) { + TopLevel::regs()->parser_egress.emplace( + ctxt_json["handle"]->as_number()->val, ®s.egress); + TopLevel::regs()->parser_memory[EGRESS].emplace( + ctxt_json["handle"]->as_number()->val, ®s.memory[EGRESS]); + } + +#if 0 + /// for initiliazing the parser registers in default configuration. + int start_bit = port_use.ffs(); + do { + int end_bit = port_use.ffz(start_bit); + std::cout << "set memories and regs from " << start_bit + << " to " << end_bit - 1 << std::endl; + for (auto i = start_bit; i <= end_bit - 1; i++) { + TopLevel::regs()->mem_pipe.i_prsr[i] + .set("memories.all.parser.ingress", ®s.memory[INGRESS]); + TopLevel::regs()->reg_pipe.pmarb.ibp18_reg.ibp_reg[i] + .set("regs.all.parser.ingress", ®s.ingress); + TopLevel::regs()->mem_pipe.e_prsr[i] + .set("memories.all.parser.egress", ®s.memory[EGRESS]); + TopLevel::regs()->reg_pipe.pmarb.ebp18_reg.ebp_reg[i] + .set("regs.all.parser.egress", ®s.egress); + } + start_bit = port_use.ffs(end_bit); + } while (start_bit >= 0); +#endif + } + // all parsers share the same parser_merge configuration. + TopLevel::regs()->reg_pipe.pmarb.prsr_reg.set("regs.all.parse_merge", + ®s.merge); +} + +template <> +void Parser::gen_configuration_cache(Target::Tofino::parser_regs ®s, json::vector &cfg_cache) { + std::string reg_fqname; + std::string reg_name; + unsigned reg_value; + std::string reg_value_str; + unsigned reg_width = 8; + + if (gress == EGRESS) { + // epb_prsr_port_regs.chnl_ctrl + for (int i = 0; i < 4; i++) { + reg_fqname = "pmarb.ebp18_reg.ebp_reg[0].epb_prsr_port_regs.chnl_ctrl[" + + std::to_string(i) + "]"; + reg_name = "parser0_chnl_ctrl_" + std::to_string(i); + reg_value = regs.egress.epb_prsr_port_regs.chnl_ctrl[i]; + if ((reg_value != 0) || (options.match_compiler)) { + reg_value_str = int_to_hex_string(reg_value, reg_width); + add_cfg_reg(cfg_cache, reg_fqname, reg_name, reg_value_str); + } + } + + // epb_prsr_port_regs.multi_threading + reg_fqname = "pmarb.ebp18_reg.ebp_reg[0].epb_prsr_port_regs.multi_threading"; + reg_name = "parser0_multi_threading"; + reg_value = regs.egress.epb_prsr_port_regs.multi_threading; + if ((reg_value != 0) || (options.match_compiler)) { + reg_value_str = int_to_hex_string(reg_value, reg_width); + add_cfg_reg(cfg_cache, reg_fqname, reg_name, reg_value_str); + } + } +} diff --git a/backends/tofino/bf-asm/tofino/phv.cpp b/backends/tofino/bf-asm/tofino/phv.cpp new file mode 100644 index 00000000000..8a3e76e6a4b --- /dev/null +++ b/backends/tofino/bf-asm/tofino/phv.cpp @@ -0,0 +1,66 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "phv.h" + +void Target::Tofino::Phv::init_regs(::Phv &phv) { + // Allocating Tofino registers so the uids map to register encodings + static const struct { + char code[4]; + unsigned size, count; + } sizes[] = {{"W", 32, 64}, {"B", 8, 64}, {"H", 16, 96}, {"", 0, 32}, + {"TW", 32, 32}, {"TB", 8, 32}, {"TH", 16, 48}}; + unsigned uid = 0; + phv.regs.resize(NUM_PHV_REGS); + for (unsigned i = 0; i < sizeof sizes / sizeof *sizes; i++) { + for (unsigned j = 0; j < sizes[i].count; j++, uid++) { + auto reg = phv.regs[uid] = new Register; + memset(reg->name, 0, sizeof(reg->name)); + reg->type = (uid >= FIRST_TPHV) ? Register::TAGALONG : Register::NORMAL; + reg->index = j; + reg->uid = uid; + reg->size = sizes[i].size; + if (sizes[i].size) { + char buf[8]; + snprintf(buf, sizeof(buf), "R%d", uid); + phv.names[INGRESS][buf][0].slice = ::Phv::Slice(*reg, 0, sizes[i].size - 1); + phv.names[EGRESS][buf][0].slice = ::Phv::Slice(*reg, 0, sizes[i].size - 1); + snprintf(reg->name, sizeof(reg->name), "%.2s%d", sizes[i].code, j); + phv.names[INGRESS][reg->name][0].slice = ::Phv::Slice(*reg, 0, sizes[i].size - 1); + phv.names[EGRESS][reg->name][0].slice = ::Phv::Slice(*reg, 0, sizes[i].size - 1); + } + } + } + BUG_CHECK(uid == phv.regs.size()); +} + +static bitvec tagalong_group(int n) { + bitvec rv; + rv.setrange( + Target::Tofino::Phv::FIRST_8BIT_TPHV + n * (Target::Tofino::Phv::COUNT_8BIT_TPHV / 8), + Target::Tofino::Phv::COUNT_8BIT_TPHV / 8); + rv.setrange( + Target::Tofino::Phv::FIRST_16BIT_TPHV + n * (Target::Tofino::Phv::COUNT_16BIT_TPHV / 8), + Target::Tofino::Phv::COUNT_16BIT_TPHV / 8); + rv.setrange( + Target::Tofino::Phv::FIRST_32BIT_TPHV + n * (Target::Tofino::Phv::COUNT_32BIT_TPHV / 8), + Target::Tofino::Phv::COUNT_32BIT_TPHV / 8); + return rv; +} +const bitvec Target::Tofino::Phv::tagalong_groups[8] = { + tagalong_group(0), tagalong_group(1), tagalong_group(2), tagalong_group(3), + tagalong_group(4), tagalong_group(5), tagalong_group(6), tagalong_group(7)}; diff --git a/backends/tofino/bf-asm/tofino/phv.h b/backends/tofino/bf-asm/tofino/phv.h new file mode 100644 index 00000000000..f0baa667da7 --- /dev/null +++ b/backends/tofino/bf-asm/tofino/phv.h @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_TOFINO_PHV_H_ +#define BF_ASM_TOFINO_PHV_H_ + +#include "../phv.h" + +class Target::Tofino::Phv : public Target::Phv { + friend class ::Phv; + struct Register : public ::Phv::Register { + int parser_id() const override { return uid; } + int mau_id() const override { return uid < FIRST_TPHV ? uid : -1; } + int ixbar_id() const override { return uid < FIRST_TPHV ? uid : -1; } + int deparser_id() const override { return uid; } + }; + void init_regs(::Phv &phv) override; + target_t type() const override { return TOFINO; } + unsigned mau_groupsize() const override { return 16; } + + public: + enum { + NUM_PHV_REGS = 368, + FIRST_8BIT_PHV = 64, + COUNT_8BIT_PHV = 64, + FIRST_16BIT_PHV = 128, + COUNT_16BIT_PHV = 96, + FIRST_32BIT_PHV = 0, + COUNT_32BIT_PHV = 64, + FIRST_TPHV = 256, + FIRST_8BIT_TPHV = 288, + COUNT_8BIT_TPHV = 32, + FIRST_16BIT_TPHV = 320, + COUNT_16BIT_TPHV = 48, + FIRST_32BIT_TPHV = 256, + COUNT_32BIT_TPHV = 32, + }; + static const bitvec tagalong_groups[8]; +}; + +#endif /* BF_ASM_TOFINO_PHV_H_ */ diff --git a/backends/tofino/bf-asm/tofino/salu_inst.cpp b/backends/tofino/bf-asm/tofino/salu_inst.cpp new file mode 100644 index 00000000000..9e269c9a353 --- /dev/null +++ b/backends/tofino/bf-asm/tofino/salu_inst.cpp @@ -0,0 +1,196 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Tofino template specializations for instructions #included in salu_inst.cpp + * WARNING -- this is included in an anonymous namespace, as these SaluInstruction + * subclasses are all defined in that anonymous namespace */ + +template <> +void AluOP::write_regs(Target::Tofino::mau_regs ®s, Table *tbl_, Table::Actions::Action *act) { + LOG2(this); + auto tbl = dynamic_cast(tbl_); + BUG_CHECK(tbl); + int logical_home_row = tbl->layout[0].row; + auto &meter_group = regs.rams.map_alu.meter_group[logical_home_row / 4U]; + auto &salu = meter_group.stateful.salu_instr_state_alu[act->code][slot - ALU2LO]; + auto &salu_instr_common = meter_group.stateful.salu_instr_common[act->code]; + salu.salu_op = opc->opcode & 0xf; + salu.salu_arith = opc->opcode >> 4; + salu.salu_pred = predication_encode & Target::Tofino::STATEFUL_PRED_MASK; + const int alu_const_min = Target::STATEFUL_ALU_CONST_MIN(); + const int alu_const_max = Target::STATEFUL_ALU_CONST_MAX(); + if (srca) { + if (auto m = srca.to()) { + salu.salu_asrc_memory = 1; + salu.salu_asrc_memory_index = m->field->bit(0) > 0; + } else if (auto k = srca.to()) { + salu.salu_asrc_memory = 0; + if (k->value >= alu_const_min && k->value <= alu_const_max) { + salu.salu_const_src = k->value & Target::STATEFUL_ALU_CONST_MASK(); + salu.salu_regfile_const = 0; + } else { + salu.salu_const_src = tbl->get_const(k->lineno, k->value); + salu.salu_regfile_const = 1; + } + } else if (auto r = srca.to()) { + salu.salu_asrc_memory = 0; + salu.salu_const_src = r->index; + salu.salu_regfile_const = 1; + } else { + BUG(); + } + } + if (srcb) { + if (auto f = srcb.to()) { + salu.salu_bsrc_phv = 1; + salu.salu_bsrc_phv_index = f->phv_index(tbl); + } else if (auto m = srcb.to()) { + salu_instr_common.salu_alu2_lo_bsrc_math = 1; + if (auto b = m->of.to()) { + salu_instr_common.salu_alu2_lo_math_src = b->phv_index(tbl); + } else if (auto b = m->of.to()) { + salu_instr_common.salu_alu2_lo_math_src = b->field->bit(0) > 0 ? 3 : 2; + } else { + BUG(); + } + } else if (auto k = srcb.to()) { + salu.salu_bsrc_phv = 0; + if (k->value >= alu_const_min && k->value <= alu_const_max) { + salu.salu_const_src = k->value & Target::STATEFUL_ALU_CONST_MASK(); + salu.salu_regfile_const = 0; + } else { + salu.salu_const_src = tbl->get_const(k->lineno, k->value); + salu.salu_regfile_const = 1; + } + } else if (auto r = srcb.to()) { + salu.salu_bsrc_phv = 0; + salu.salu_const_src = r->index; + salu.salu_regfile_const = 1; + } else { + BUG(); + } + } +} +void AluOP::write_regs(Target::Tofino::mau_regs ®s, Table *tbl, Table::Actions::Action *act) { + write_regs(regs, tbl, act); +} + +template <> +void BitOP::write_regs(Target::Tofino::mau_regs ®s, Table *tbl, Table::Actions::Action *act) { + LOG2(this); + int logical_home_row = tbl->layout[0].row; + auto &meter_group = regs.rams.map_alu.meter_group[logical_home_row / 4U]; + auto &salu = meter_group.stateful.salu_instr_state_alu[act->code][slot - ALU2LO]; + salu.salu_op = opc->opcode & 0xf; + salu.salu_pred = predication_encode & Target::Tofino::STATEFUL_PRED_MASK; + // 1b instructions are from mem-lo to alu1-lo + salu.salu_asrc_memory = 1; + salu.salu_asrc_memory_index = 0; +} +void BitOP::write_regs(Target::Tofino::mau_regs ®s, Table *tbl, Table::Actions::Action *act) { + write_regs(regs, tbl, act); +} + +template <> +void CmpOP::write_regs(Target::Tofino::mau_regs ®s, Table *tbl_, Table::Actions::Action *act) { + LOG2(this); + auto tbl = dynamic_cast(tbl_); + BUG_CHECK(tbl); + int logical_home_row = tbl->layout[0].row; + auto &meter_group = regs.rams.map_alu.meter_group[logical_home_row / 4U]; + auto &salu = meter_group.stateful.salu_instr_cmp_alu[act->code][slot]; + if (srca) { + salu.salu_cmp_asrc_input = srca->field->bit(0) > 0; + salu.salu_cmp_asrc_sign = srca_neg; + salu.salu_cmp_asrc_enable = 1; + } + if (srcb) { + salu.salu_cmp_bsrc_input = srcb->phv_index(tbl); + salu.salu_cmp_bsrc_sign = srcb_neg; + salu.salu_cmp_bsrc_enable = 1; + } + if (srcc) { + if (auto k = dynamic_cast(srcc)) { + const int cmp_const_min = Target::STATEFUL_CMP_CONST_MIN(); + const int cmp_const_max = Target::STATEFUL_CMP_CONST_MAX(); + if (k->value >= cmp_const_min && k->value <= cmp_const_max) { + salu.salu_cmp_const_src = k->value & Target::STATEFUL_CMP_CONST_MASK(); + salu.salu_cmp_regfile_const = 0; + } else { + salu.salu_cmp_const_src = tbl->get_const(srcc->lineno, k->value); + salu.salu_cmp_regfile_const = 1; + } + } else if (auto r = dynamic_cast(srcc)) { + salu.salu_cmp_const_src = r->index; + salu.salu_cmp_regfile_const = 1; + } + } else { + salu.salu_cmp_const_src = 0; + salu.salu_cmp_regfile_const = 0; + } + salu.salu_cmp_opcode = opc->opcode | (type << 2); +} +void CmpOP::write_regs(Target::Tofino::mau_regs ®s, Table *tbl, Table::Actions::Action *act) { + write_regs(regs, tbl, act); +} + +#if HAVE_JBAY +void TMatchOP::write_regs(Target::Tofino::mau_regs ®s, Table *tbl, Table::Actions::Action *act) { + BUG(); // should never be called +} +#endif /* HAVE_JBAY */ + +void OutOP::decode_output_mux(Target::Tofino, Table *tbl, value_t &op) { + static const std::map ops_mux_lookup = { + {"mem_hi", 0}, {"mem_lo", 1}, {"memory_hi", 0}, {"memory_lo", 1}, + {"phv_hi", 2}, {"phv_lo", 3}, {"alu_hi", 4}, {"alu_lo", 5}, + {"alu_hi_out", 4}, {"alu_lo_out", 5}, {"predicate", 6}}; + if (op.type == tCMD && ops_mux_lookup.count(op[0].s)) + output_mux = ops_mux_lookup.at(op[0].s); + else if (op.type == tSTR && ops_mux_lookup.count(op.s)) + output_mux = ops_mux_lookup.at(op.s); + else + output_mux = -1; + if (src) { + int tmp = output_mux; + if (auto *phv = src.to()) + output_mux = 3 - phv->phv_index(tbl->to()); + else if (auto *mem = src.to()) + output_mux = mem->field->bit(0) > 0 ? 0 : 1; + BUG_CHECK(tmp < 0 || tmp == output_mux, "inconsistent output mux decode"); + } +} +int OutOP::decode_output_option(Target::Tofino, value_t &op) { return -1; } + +template <> +void OutOP::write_regs(Target::Tofino::mau_regs ®s, Table *tbl_, Table::Actions::Action *act) { + LOG2(this); + auto tbl = dynamic_cast(tbl_); + BUG_CHECK(tbl); + int logical_home_row = tbl->layout[0].row; + auto &meter_group = regs.rams.map_alu.meter_group[logical_home_row / 4U]; + auto &salu = meter_group.stateful.salu_instr_output_alu[act->code]; + if (predication_encode) { + salu.salu_output_cmpfn = predication_encode & Target::Tofino::STATEFUL_PRED_MASK; + } else { + salu.salu_output_cmpfn = STATEFUL_PREDICATION_ENCODE_UNCOND; + } + salu.salu_output_asrc = output_mux; +} +void OutOP::write_regs(Target::Tofino::mau_regs ®s, Table *tbl, Table::Actions::Action *act) { + write_regs(regs, tbl, act); +} diff --git a/backends/tofino/bf-asm/tofino/sram_match.cpp b/backends/tofino/bf-asm/tofino/sram_match.cpp new file mode 100644 index 00000000000..3756017cc77 --- /dev/null +++ b/backends/tofino/bf-asm/tofino/sram_match.cpp @@ -0,0 +1,95 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "stage.h" +#include "tables.h" + +static int find_in_ixbar(Table *table, std::vector &match) { + // It would seem like it would be possible to simplify this code by refactoring it + // to use one loop calling Table::find_on_ixbar (which does much of what this does),r + // but it is important to prefer a group defined in this table to one defined in other + // tables, which the two loops does. Could perhaps have a variant of find_on_ixbar that + // return *all* groups where the Phv::Ref is present (in priority order), so we could + // do the intersection (preserving priority order) rather than this repeated looping? + int max_i = -1; + LOG3("find_in_ixbar " << match); + for (unsigned group = 0; group < EXACT_XBAR_GROUPS; group++) { + LOG3(" looking in table in group " << group); + bool ok = true; + for (auto &r : match) { + LOG3(" looking for " << r); + for (auto &ixb : table->input_xbar) { + if (!ixb->find_exact(*r, group)) { + LOG3(" -- not found"); + ok = false; + break; + } + } + } + if (ok) { + LOG3(" success"); + return group; + } + } + for (unsigned group = 0; group < EXACT_XBAR_GROUPS; group++) { + LOG3(" looking in group " << group); + bool ok = true; + for (auto &r : match) { + LOG3(" looking for " << r); + bool found = false; + InputXbar::Group ixbar_group(InputXbar::Group::EXACT, group); + for (auto *in : table->stage->ixbar_use[ixbar_group]) { + if (in->find_exact(*r, group)) { + found = true; + break; + } + } + if (!found) { + LOG3(" -- not found"); + if (&r - &match[0] > max_i) max_i = &r - &match[0]; + ok = false; + break; + } + } + if (ok) { + LOG3(" success"); + return group; + } + } + if (max_i > 0) + error(match[max_i].lineno, "%s: Can't find %s and %s in same input xbar group", + table->name(), match[max_i].name(), match[0].name()); + else + error(match[0].lineno, "%s: Can't find %s in any input xbar group", table->name(), + match[0].name()); + return -1; +} + +void SRamMatchTable::setup_word_ixbar_group(Target::Tofino) { + word_ixbar_group.resize(match_in_word.size()); + unsigned i = 0; + for (auto &match : match_in_word) { + std::vector phv_ref_match; + for (auto *source : match) { + auto phv_ref = dynamic_cast(source); + BUG_CHECK(phv_ref); + BUG_CHECK(*phv_ref); + phv_ref_match.push_back(*phv_ref); + } + word_ixbar_group[i++] = phv_ref_match.empty() ? -1 : find_in_ixbar(this, phv_ref_match); + } +} diff --git a/backends/tofino/bf-asm/tofino/stage.cpp b/backends/tofino/bf-asm/tofino/stage.cpp new file mode 100644 index 00000000000..2c906e858a1 --- /dev/null +++ b/backends/tofino/bf-asm/tofino/stage.cpp @@ -0,0 +1,140 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* mau stage template specializations for tofino -- #included directly in top-level stage.cpp */ + +template <> +void Stage::write_regs(Target::Tofino::mau_regs ®s, bool) { + write_common_regs(regs); + auto &merge = regs.rams.match.merge; + for (gress_t gress : Range(INGRESS, EGRESS)) { + if (stageno == 0) { + merge.predication_ctl[gress].start_table_fifo_delay0 = pred_cycle(gress) - 1; + merge.predication_ctl[gress].start_table_fifo_delay1 = 0; + merge.predication_ctl[gress].start_table_fifo_enable = 1; + } else { + switch (stage_dep[gress]) { + case MATCH_DEP: + merge.predication_ctl[gress].start_table_fifo_delay0 = + this[-1].pipelength(gress) - this[-1].pred_cycle(gress) + + pred_cycle(gress) - 1; + merge.predication_ctl[gress].start_table_fifo_delay1 = + this[-1].pipelength(gress) - this[-1].pred_cycle(gress); + merge.predication_ctl[gress].start_table_fifo_enable = 3; + break; + case ACTION_DEP: + merge.predication_ctl[gress].start_table_fifo_delay0 = 1; + merge.predication_ctl[gress].start_table_fifo_delay1 = 0; + merge.predication_ctl[gress].start_table_fifo_enable = 1; + break; + case CONCURRENT: + merge.predication_ctl[gress].start_table_fifo_enable = 0; + break; + default: + BUG(); + } + } + if (stageno != 0) { + regs.dp.cur_stage_dependency_on_prev[gress] = MATCH_DEP - stage_dep[gress]; + if (stage_dep[gress] == CONCURRENT) regs.dp.stage_concurrent_with_prev |= 1U << gress; + } + if (stageno != AsmStage::numstages() - 1) + regs.dp.next_stage_dependency_on_cur[gress] = MATCH_DEP - this[1].stage_dep[gress]; + else if (AsmStage::numstages() < Target::NUM_MAU_STAGES()) + regs.dp.next_stage_dependency_on_cur[gress] = 2; + auto &deferred_eop_bus_delay = regs.rams.match.adrdist.deferred_eop_bus_delay[gress]; + deferred_eop_bus_delay.eop_internal_delay_fifo = pred_cycle(gress) + 3; + /* FIXME -- making this depend on the dependency of the next stage seems wrong */ + if (stageno == AsmStage::numstages() - 1) { + if (AsmStage::numstages() < Target::NUM_MAU_STAGES()) + deferred_eop_bus_delay.eop_output_delay_fifo = 0; + else + deferred_eop_bus_delay.eop_output_delay_fifo = pipelength(gress) - 1; + } else if (this[1].stage_dep[gress] == MATCH_DEP) + deferred_eop_bus_delay.eop_output_delay_fifo = pipelength(gress) - 1; + else if (this[1].stage_dep[gress] == ACTION_DEP) + deferred_eop_bus_delay.eop_output_delay_fifo = 1; + else + deferred_eop_bus_delay.eop_output_delay_fifo = 0; + deferred_eop_bus_delay.eop_delay_fifo_en = 1; + } + + for (gress_t gress : Range(INGRESS, EGRESS)) + if (table_use[gress] & USE_TCAM) + regs.tcams.tcam_piped |= options.match_compiler ? 3 : 1 << gress; + + bitvec in_use = match_use[INGRESS] | action_use[INGRESS] | action_set[INGRESS]; + bitvec eg_use = match_use[EGRESS] | action_use[EGRESS] | action_set[EGRESS]; + if (options.match_compiler) { + /* the glass compiler occasionally programs extra uses of random registers on + * busses where it doesn't actually use them. Sometimes, these regs + * are in use by the other thread, so rely on the deparser to correctly + * set the Phv::use info and strip out registers it says are used by + * the other thread */ + in_use -= Deparser::PhvUse(EGRESS); + eg_use -= Deparser::PhvUse(INGRESS); + } + /* FIXME -- if the regs are live across a stage (even if not used in that stage) they + * need to be set in the thread registers. For now we just assume if they are used + * anywhere, they need to be marked as live */ + in_use |= Phv::use(INGRESS); + eg_use |= Phv::use(EGRESS); + static const int phv_use_transpose[2][14] = { + {0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21}, + {4, 5, 6, 7, 12, 13, 14, 15, 22, 23, 24, 25, 26, 27}}; + // FIXME -- this code depends on the Phv::Register uids matching the + // FIXME -- mau encoding of phv containers. (FIXME-PHV) + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 14; j++) { + regs.dp.phv_ingress_thread_alu[i][j] = regs.dp.phv_ingress_thread_imem[i][j] = + regs.dp.phv_ingress_thread[i][j] = in_use.getrange(8 * phv_use_transpose[i][j], 8); + regs.dp.phv_egress_thread_alu[i][j] = regs.dp.phv_egress_thread_imem[i][j] = + regs.dp.phv_egress_thread[i][j] = eg_use.getrange(8 * phv_use_transpose[i][j], 8); + } + } +} + +template <> +void Stage::gen_configuration_cache(Target::Tofino::mau_regs ®s, json::vector &cfg_cache) { + Stage::gen_configuration_cache_common(regs, cfg_cache); + + unsigned reg_width = 8; // this means number of hex characters + std::string reg_fqname; + std::string reg_name; + unsigned reg_value; + std::string reg_value_str; + + // meter_ctl + auto &meter_ctl = regs.rams.map_alu.meter_group; + for (int i = 0; i < 4; i++) { + reg_fqname = "mau[" + std::to_string(stageno) + "].rams.map_alu.meter_group[" + + std::to_string(i) + "]" + ".meter.meter_ctl"; + reg_name = "stage_" + std::to_string(stageno) + "_meter_ctl_" + std::to_string(i); + reg_value = meter_ctl[i].meter.meter_ctl; + if ((reg_value != 0) || (options.match_compiler)) { + reg_value_str = int_to_hex_string(reg_value, reg_width); + add_cfg_reg(cfg_cache, reg_fqname, reg_name, reg_value_str); + } + } +} + +template <> +void Stage::gen_mau_stage_extension(Target::Tofino::mau_regs ®s, json::map &extend) { + BUG(); // stage extension not supported on tofino +} + +void AlwaysRunTable::write_regs(Target::Tofino::mau_regs &) { BUG(); } diff --git a/backends/tofino/bf-asm/tofino/stateful.cpp b/backends/tofino/bf-asm/tofino/stateful.cpp new file mode 100644 index 00000000000..4b8f908ff35 --- /dev/null +++ b/backends/tofino/bf-asm/tofino/stateful.cpp @@ -0,0 +1,77 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "stateful.h" + +int StatefulTable::parse_counter_mode(Target::Tofino target, const value_t &v) { + if (v != "counter") return -1; + if (v.type == tSTR) return 4; + if (v.type != tCMD || v.vec.size != 2) return -1; + static const std::map modes = {{"hit", 2}, {"miss", 1}, {"gateway", 3}}; + if (!modes.count(v[1].s)) return -1; + return modes.at(v[1].s); +} + +void StatefulTable::set_counter_mode(Target::Tofino target, int mode) { + stateful_counter_mode |= mode; +} + +template <> +void StatefulTable::write_logging_regs(Target::Tofino::mau_regs ®s) { + auto &merge = regs.rams.match.merge; + unsigned meter_group = layout.at(0).row / 4U; + auto &salu = regs.rams.map_alu.meter_group[meter_group].stateful; + for (MatchTable *m : match_tables) { + auto *call = m->get_call(this); + if (!call || call->args.at(0).type != Call::Arg::Counter) continue; + if (auto mode = call->args.at(0).count_mode()) { + merge.mau_stateful_log_counter_ctl[m->logical_id / 8U].set_subfield( + mode, 3 * (m->logical_id % 8U), 3); + for (auto &rep : merge.mau_stateful_log_ctl_ixbar_map[m->logical_id / 8U]) + rep.set_subfield(meter_group | 0x4, 3 * (m->logical_id % 8U), 3); + } + } + if (stateful_counter_mode) { + merge.mau_stateful_log_instruction_width.set_subfield(format->log2size - 3, 2 * meter_group, + 2); + merge.mau_stateful_log_vpn_offset[meter_group / 2].set_subfield(logvpn_min, + 6 * (meter_group % 2), 6); + merge.mau_stateful_log_vpn_limit[meter_group / 2].set_subfield(logvpn_max, + 6 * (meter_group % 2), 6); + } + + for (size_t i = 0; i < const_vals.size(); ++i) { + if (const_vals[i].value > INT_MAX || const_vals[i].value < INT_MIN) + error(const_vals[i].lineno, "constant value %" PRId64 " too large for stateful alu", + const_vals[i].value); + salu.salu_const_regfile[i] = const_vals[i].value & 0xffffffffU; + } +} + +/// Compute the proper value for the register +/// map_alu.meter_alu_group_data_delay_ctl[].meter_alu_right_group_delay +/// which controls the two halves of the ixbar->meter_alu fifo, based on a bytemask of which +/// bytes are needed in the meter_alu. On Tofino, the fifo is 64 bits wide, so each enable +/// bit controls 32 bits +int AttachedTable::meter_alu_fifo_enable_from_mask(Target::Tofino::mau_regs &, unsigned bytemask) { + int rv = 0; + if (bytemask & 0xf) rv |= 1; + if (bytemask & 0xf0) rv |= 2; + return rv; +} + +void StatefulTable::gen_tbl_cfg(Target::Tofino, json::map &tbl, json::map &stage_tbl) const {} diff --git a/backends/tofino/bf-asm/tofino/stateful.h b/backends/tofino/bf-asm/tofino/stateful.h new file mode 100644 index 00000000000..f13fea70d97 --- /dev/null +++ b/backends/tofino/bf-asm/tofino/stateful.h @@ -0,0 +1,33 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_TOFINO_STATEFUL_H_ +#define BF_ASM_TOFINO_STATEFUL_H_ + +#include +#include + +class Target::Tofino::StatefulTable : public ::StatefulTable { + friend class ::StatefulTable; + StatefulTable(int line, const char *n, gress_t gr, Stage *s, int lid) + : ::StatefulTable(line, n, gr, s, lid) {} +}; + +template <> +void StatefulTable::write_logging_regs(Target::Tofino::mau_regs ®s); + +#endif /* BF_ASM_TOFINO_STATEFUL_H_ */ diff --git a/backends/tofino/bf-asm/tofino/template_objects.yaml b/backends/tofino/bf-asm/tofino/template_objects.yaml new file mode 100644 index 00000000000..f8dde2503a9 --- /dev/null +++ b/backends/tofino/bf-asm/tofino/template_objects.yaml @@ -0,0 +1,109 @@ +# Copyright (C) 2024 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# +# SPDX-License-Identifier: Apache-2.0 + +global: + - namespace=Tofino + - emit_binary + - emit_fieldname + - emit_json + - enable_disable + - input_binary + - reverse_write + - write_dma=mapram_config + - write_dma=imem_subword8 + - write_dma=imem_subword16 + - write_dma=imem_subword32 + - write_dma=galois_field_matrix +generate: + memories: + pipe_top_level: + memories.pipe_top_level.h: [ decl, name=memories.top ] + memories.pipe_top_level.cpp: [ defn, name=memories.top, + -Imemories.pipe_top_level.h, -Imemories.pipe_addrmap.h ] + pipe_addrmap: + memories.pipe_addrmap.h: [ decl, name=memories.pipe ] + memories.pipe_addrmap.cpp: [ defn, name=memories.pipe, + -Imemories.pipe_addrmap.h, -Imemories.prsr_mem_main_rspec.h ] + prsr_mem_main_rspec: + memories.prsr_mem_main_rspec.h: [ decl, name=memories.all.parser.%s ] + memories.prsr_mem_main_rspec.cpp: [ defn, name=memories.all.parser.%s, + -Imemories.prsr_mem_main_rspec.h ] + regs: + tofino: + regs.tofino.h: [ decl, name=regs.top ] + regs.tofino.cpp: [ defn, name=regs.top, + -Iregs.tofino.h, -Iregs.pipe_addrmap.h ] + pipe_addrmap: + regs.pipe_addrmap.h: [ decl, name=regs.pipe, expand_disabled_vector ] + regs.pipe_addrmap.cpp: [ defn, name=regs.pipe, expand_disabled_vector, + -Iregs.pipe_addrmap.h, -Iregs.ibp_rspec.h, -Iregs.ebp_rspec.h, + -Iregs.prsr_reg_merge_rspec.h, -Iregs.mau_addrmap.h, + -Iregs.dprsr_inp.h, -Iregs.dprsr_hdr.h ] + # pmarb_rspec + ibp_rspec: # Ingress parser registers + regs.ibp_rspec.h: [ decl, name=regs.all.parser.ingress ] + regs.ibp_rspec.cpp: [ defn, name=regs.all.parser.ingress, + -Iregs.ibp_rspec.h ] + ebp_rspec: # Egress parser registers + regs.ebp_rspec.h: [ decl, name=regs.all.parser.egress ] + regs.ebp_rspec.cpp: [ defn, name=regs.all.parser.egress, + -Iregs.ebp_rspec.h ] + prsr_reg_merge_rspec: # Shared parser registers + regs.prsr_reg_merge_rspec.h: [ decl, name=regs.all.parse_merge ] + regs.prsr_reg_merge_rspec.cpp: [ defn, name=regs.all.parse_merge, + -Iregs.prsr_reg_merge_rspec.h ] + mau_addrmap: + regs.mau_addrmap.h: [ decl, name=regs.match_action_stage.%02x ] + regs.mau_addrmap.cpp: [ defn, name=regs.match_action_stage.%02x, + -Iregs.mau_addrmap.h ] + # dprsr_reg_rspec + dprsr_inp: + regs.dprsr_inp.h: [ decl, name=regs.all.deparser.input_phase, global=fde_pov ] + regs.dprsr_inp.cpp: [ defn, name=regs.all.deparser.input_phase, global=fde_pov, + -Iregs.dprsr_inp.h ] + #dprsr_out_ingr: {} + #dprsr_out_egr: {} + dprsr_hdr: + regs.dprsr_hdr.h: [ decl, name=regs.all.deparser.header_phase, global=fde_phv ] + regs.dprsr_hdr.cpp: [ defn, name=regs.all.deparser.header_phase, global=fde_phv, + -Iregs.dprsr_hdr.h ] +ignore: + memories: + - mau_addrmap + # pipe_top_level + - tm_pre_mem_rspec + - party_pgr_mem_rspec + regs: + # tofino + - dvsl_addrmap + - mac_addrmap + - serdes_addrmap + # pipe_addrmap + # pmarb_rspec + # ebp_rspec + - egrNx_regs + # parb_regs + - pbus_station_regs + - party_pgr_reg_rspec + - party_glue_reg_rspec + # dprsr_reg_rspec + - mir_buf_all + - dprsr_out_ingr + - dprsr_out_egr + # dprsr_hdr + # dprsr_hi_mem + - dprsr_h_pv_table_map diff --git a/backends/tofino/bf-asm/tofino/ternary_match.cpp b/backends/tofino/bf-asm/tofino/ternary_match.cpp new file mode 100644 index 00000000000..701c5e42920 --- /dev/null +++ b/backends/tofino/bf-asm/tofino/ternary_match.cpp @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ternary_match.h" + +#include "stage.h" + +void Target::Tofino::TernaryMatchTable::pass1() { + ::TernaryMatchTable::pass1(); + // Dont allocate id (mark them as used) for empty ternary tables (keyless + // tables). Keyless tables are marked ternary with a tind. They are setup by + // the driver to always miss (since there is no match) and run the miss + // action. The miss action is associated with the logical table space and + // does not need a tcam id association. This saves tcams ids to be assigned + // to actual ternary tables. This way we can have 8 real ternary match + // tables within a stage and not count the keyless among them. + // NOTE: The tcam_id is never assigned for these tables and will be set to + // default (-1). We also disable registers associated with tcam_id for this + // table. + if (layout_size() != 0) { + alloc_id("tcam", tcam_id, stage->pass1_tcam_id, TCAM_TABLES_PER_STAGE, false, + stage->tcam_id_use); + physical_ids[tcam_id] = 1; + } + // alloc_busses(stage->tcam_match_bus_use); -- now hardwired +} + +void Target::Tofino::TernaryIndirectTable::pass1() { + ::TernaryIndirectTable::pass1(); + alloc_busses(stage->tcam_indirect_bus_use, Layout::TIND_BUS); +} + +void Target::Tofino::TernaryMatchTable::check_tcam_match_bus( + const std::vector &layout) { + for (auto &row : layout) { + if (row.bus.empty()) continue; + for (auto &tcam : row.memunits) + if (row.bus.at(Table::Layout::SEARCH_BUS) != tcam.col) + error(row.lineno, "Tcam match bus hardwired to tcam column"); + } +} diff --git a/backends/tofino/bf-asm/tofino/ternary_match.h b/backends/tofino/bf-asm/tofino/ternary_match.h new file mode 100644 index 00000000000..15eec406a5f --- /dev/null +++ b/backends/tofino/bf-asm/tofino/ternary_match.h @@ -0,0 +1,40 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_TOFINO_TERNARY_MATCH_H_ +#define BF_ASM_TOFINO_TERNARY_MATCH_H_ + +#include + +class Target::Tofino::TernaryMatchTable : public ::TernaryMatchTable { + friend class ::TernaryMatchTable; + TernaryMatchTable(int line, const char *n, gress_t gr, Stage *s, int lid) + : ::TernaryMatchTable(line, n, gr, s, lid) {} + + void pass1() override; + void check_tcam_match_bus(const std::vector &); +}; + +class Target::Tofino::TernaryIndirectTable : public ::TernaryIndirectTable { + friend class ::TernaryIndirectTable; + TernaryIndirectTable(int line, const char *n, gress_t gr, Stage *s, int lid) + : ::TernaryIndirectTable(line, n, gr, s, lid) {} + + void pass1() override; +}; + +#endif /* BF_ASM_TOFINO_TERNARY_MATCH_H_ */ diff --git a/backends/tofino/bf-asm/top_level.cpp b/backends/tofino/bf-asm/top_level.cpp new file mode 100644 index 00000000000..d7d89d5f79c --- /dev/null +++ b/backends/tofino/bf-asm/top_level.cpp @@ -0,0 +1,126 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "top_level.h" + +#include "bfas.h" +#include "binary_output.h" +#include "bson.h" +#include "version.h" + +TopLevel *TopLevel::all = nullptr; + +TopLevel::TopLevel() { + BUG_CHECK(!all); + all = this; +} + +TopLevel::~TopLevel() { all = nullptr; } + +template +TopLevelRegs::TopLevelRegs() { + declare_registers(&this->mem_top, sizeof(this->mem_top), + [this](std::ostream &out, const char *addr, const void *end) { + out << "memories.top"; + this->mem_top.emit_fieldname(out, addr, end); + }); + declare_registers(&this->mem_pipe, sizeof(this->mem_pipe), + [this](std::ostream &out, const char *addr, const void *end) { + out << "memories.pipe"; + this->mem_pipe.emit_fieldname(out, addr, end); + }); + declare_registers(&this->reg_top, sizeof(this->reg_top), + [this](std::ostream &out, const char *addr, const void *end) { + out << "registers.top"; + this->reg_top.emit_fieldname(out, addr, end); + }); + declare_registers(&this->reg_pipe, sizeof(this->reg_pipe), + [this](std::ostream &out, const char *addr, const void *end) { + out << "registers.pipe"; + this->reg_pipe.emit_fieldname(out, addr, end); + }); +} + +template +TopLevelRegs::~TopLevelRegs() { + undeclare_registers(&this->mem_top); + undeclare_registers(&this->mem_pipe); + undeclare_registers(&this->reg_top); + undeclare_registers(&this->reg_pipe); +} + +template +void TopLevelRegs::output(json::map &ctxt_json) { + for (int i = 0; i < Target::NUM_PIPES(); i++) { + if (options.binary >= PIPE0 && options.binary != PIPE0 + i) { + this->mem_top.pipes[i].disable(); + this->reg_top.pipes[i].disable(); + } else { + this->mem_top.pipes[i].set("memories.pipe", &this->mem_pipe); + this->reg_top.pipes[i].set("regs.pipe", &this->reg_pipe); + } + } + if (options.condense_json) { + this->mem_top.disable_if_reset_value(); + this->mem_pipe.disable_if_reset_value(); + this->reg_top.disable_if_reset_value(); + this->reg_pipe.disable_if_reset_value(); + } + if (error_count == 0) { + if (options.gen_json) { + this->mem_top.emit_json(*open_output("memories.top.cfg.json")); + this->mem_pipe.emit_json(*open_output("memories.pipe.cfg.json")); + this->reg_top.emit_json(*open_output("regs.top.cfg.json")); + this->reg_pipe.emit_json(*open_output("regs.pipe.cfg.json")); + } + if (options.binary != NO_BINARY) { + auto binfile = open_output("%s.bin", TARGET::name); + json::map header; + header["asm_version"] = BFASM::Version::getVersion(); + if (ctxt_json["compiler_version"]) + header["compiler_version"] = ctxt_json["compiler_version"]->clone(); + header["reg_version"] = TARGET::top_level_regs::_regs_top::_reg_version; + if (ctxt_json["run_id"]) header["run_id"] = ctxt_json["run_id"]->clone(); + if (ctxt_json["program_name"]) + header["program_name"] = ctxt_json["program_name"]->clone(); + header["target"] = Target::name(); + header["stages"] = Target::NUM_MAU_STAGES(); + *binfile << binout::tag('H') << json::binary(header); + if (options.binary != ONE_PIPE) { + this->mem_top.emit_binary(*binfile, 0); + this->reg_top.emit_binary(*binfile, 0); + } else { + this->mem_pipe.emit_binary(*binfile, 0); + this->reg_pipe.emit_binary(*binfile, 0); + } + + if (options.multi_parsers) { + emit_parser_registers(this, *binfile); + } + } + } +} + +template +void TopLevelRegs::set_mau_stage(int stage, const char *file, + typename TARGET::mau_regs *regs, bool egress_only) { + BUG_CHECK(!egress_only, "separate egress MAU on target that does not support it"); + this->reg_pipe.mau[stage].set(file, regs); +} + +#define TOP_LEVEL_REGS(REGSET) template class TopLevelRegs; +FOR_ALL_REGISTER_SETS(TOP_LEVEL_REGS) diff --git a/backends/tofino/bf-asm/top_level.h b/backends/tofino/bf-asm/top_level.h new file mode 100644 index 00000000000..682f7c539cf --- /dev/null +++ b/backends/tofino/bf-asm/top_level.h @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_TOP_LEVEL_H_ +#define BF_ASM_TOP_LEVEL_H_ + +#include "json.h" +#include "target.h" + +template +class TopLevelRegs; + +class TopLevel { + protected: + TopLevel(); + + public: + static TopLevel *all; + virtual ~TopLevel(); + virtual void output(json::map &) = 0; + static void output_all(json::map &ctxtJson) { all->output(ctxtJson); } + template + static TopLevelRegs *regs(); +#define SET_MAU_STAGE(TARGET) \ + virtual void set_mau_stage(int, const char *, Target::TARGET::mau_regs *, bool) { \ + BUG_CHECK(!"register mismatch"); \ + } + FOR_ALL_REGISTER_SETS(SET_MAU_STAGE) +}; + +template +class TopLevelRegs : public TopLevel, public REGSET::top_level_regs { + public: + TopLevelRegs(); + ~TopLevelRegs(); + + void output(json::map &); + void set_mau_stage(int stage, const char *file, typename REGSET::mau_regs *regs, + bool egress_only); +}; + +template +TopLevelRegs *TopLevel::regs() { + return dynamic_cast *>(all); +} + +#endif /* BF_ASM_TOP_LEVEL_H_ */ diff --git a/backends/tofino/bf-asm/ubits.cpp b/backends/tofino/bf-asm/ubits.cpp new file mode 100644 index 00000000000..d362f36d183 --- /dev/null +++ b/backends/tofino/bf-asm/ubits.cpp @@ -0,0 +1,83 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ubits.h" + +#include +#include + +#include "hex.h" +#include "log.h" + +struct regrange { + const char *base; + size_t sz; + std::function fn; +}; + +static std::map *registers; + +static regrange *find_regrange(const void *addr_) { + const char *addr = static_cast(addr_); + if (registers) { + auto it = registers->upper_bound(addr); + if (it != registers->begin()) { + it--; + if (addr <= it->second.base + it->second.sz) return &it->second; + } + } + return nullptr; +} + +void declare_registers(const void *addr_, size_t sz, + std::function fn) { + const char *addr = static_cast(addr_); + if (!registers) registers = new std::map(); + registers->emplace(addr, regrange{addr, sz, fn}); +} + +void undeclare_registers(const void *addr_) { + const char *addr = static_cast(addr_); + registers->erase(addr); + if (registers->empty()) { + delete registers; + registers = 0; + } +} + +void print_regname(std::ostream &out, const void *addr, const void *end) { + if (auto rr = find_regrange(addr)) + rr->fn(out, static_cast(addr), end); + else + out << "???"; +} + +std::string string_regname(const void *addr, const void *end) { + std::stringstream tmp; + print_regname(tmp, addr, end); + return tmp.str(); +} + +void ubits_base::log(const char *op, uint64_t v) const { + if (LOGGING(1)) { + std::ostringstream tmp; + if (!find_regrange(this)) return; + LOG1(this << ' ' << op << ' ' << v + << (v != value ? tmp << " (now " << value << ")", tmp : tmp).str() << " (0x" + << hex(value) << ")"); + } +} diff --git a/backends/tofino/bf-asm/ubits.h b/backends/tofino/bf-asm/ubits.h new file mode 100644 index 00000000000..96ab8de18ee --- /dev/null +++ b/backends/tofino/bf-asm/ubits.h @@ -0,0 +1,178 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_UBITS_H_ // NOLINT(build/header_guard) +#define BF_ASM_UBITS_H_ + +#include +#include +#include + +#include +#include +#include + +#include "bitvec.h" +#include "log.h" + +using namespace P4; + +void declare_registers(const void *addr, size_t sz, + std::function fn); +void undeclare_registers(const void *addr); +void print_regname(std::ostream &out, const void *addr, const void *end); +std::string string_regname(const void *addr, const void *end); + +struct ubits_base; + +struct ubits_base { + uint64_t value, reset_value; + mutable bool read, write; + mutable bool disabled_; + + ubits_base() : value(0), reset_value(0), read(false), write(false), disabled_(false) {} + explicit ubits_base(uint64_t v) + : value(v), reset_value(v), read(false), write(false), disabled_(false) {} + operator uint64_t() const { + read = true; + return value; + } + bool modified() const { return write; } + void set_modified(bool v = true) { write = v; } + bool disabled() const { return disabled_; } + bool disable_if_unmodified() { return write ? false : (disabled_ = true); } + bool disable_if_zero() const { return value == 0 && !write; } + bool disable_if_reset_value() { return value == reset_value ? (disabled_ = true) : false; } + bool disable() const { + if (write) { + LOG1("ERROR: Disabling modified register in " << this); + return false; + } + disabled_ = true; + return disabled_; + } + void enable() const { disabled_ = false; } + void rewrite() { write = false; } + virtual uint64_t operator=(uint64_t v) = 0; + virtual const ubits_base &operator|=(uint64_t v) = 0; + virtual unsigned size() = 0; + void log(const char *op, uint64_t v) const; +}; + +inline std::ostream &operator<<(std::ostream &out, const ubits_base *u) { + print_regname(out, u, u + 1); + return out; +} + +template +struct ubits : ubits_base { + ubits() : ubits_base() {} + const ubits &check(std::true_type) { + if (value >= (uint64_t(1) << N)) { + LOG1("ERROR: out of range for " << N << " bits in " << this); + value &= (uint64_t(1) << N) - 1; + } + return *this; + } + const ubits &check(std::false_type) { return *this; } + const ubits &check() { + return check(std::integral_constant{}); + } + explicit ubits(uint64_t v) : ubits_base(v) { check(); } + ubits(const ubits &) = delete; + ubits(ubits &&) = default; + uint64_t operator=(uint64_t v) override { + if (disabled_) LOG1("ERROR: Writing disabled register value in " << this); + if (write) + LOG1((value != v ? "ERROR:" : "WARNING:") + << " Overwriting " << value << " with " << v << " in " << this); + value = v; + write = true; + log("=", v); + check(); + return v; + } + const ubits &operator=(const ubits &v) { + *this = v.value; + v.read = true; + return v; + } + const ubits_base &operator=(const ubits_base &v) { + *this = v.value; + v.read = true; + return v; + } + unsigned size() override { return N; } + const ubits &operator|=(uint64_t v) override { + if (disabled_) LOG1("ERROR: Writing disabled register value in " << this); + if (write && (v & value) != 0) + LOG1("WARNING: Overwriting " << value << " with " << (v | value) << " in " << this); + value |= v; + write = true; + log("|=", v); + return check(); + } + const ubits &operator|=(bitvec v) { + if (disabled_) LOG1("ERROR: Writing disabled register value in " << this); + if (v.ffs(N) > 0) + LOG1("ERROR: bitvec 0x" << v << " out of range for " << N << " bits in " << this); + uint64_t val = v.getrange(0, N); + if (write && (val & value) != 0) + LOG1("WARNING: Overwriting " << value << " with " << (val | value) << " in " << this); + value |= val; + write = true; + log("|=", val); + return check(); + } + const ubits &operator+=(uint64_t v) { + if (disabled_) LOG1("ERROR: Overwriting disabled register value in " << this); + value += v; + write = true; + log("+=", v); + return check(); + } + const ubits &operator^=(uint64_t v) { + if (disabled_) LOG1("ERROR: Overwriting disabled register value in " << this); + value ^= v; + write = true; + log("^=", v); + return check(); + } + const ubits &set_subfield(uint64_t v, unsigned bit, unsigned size) { + if (disabled_) LOG1("ERROR: Overwriting disabled register value in " << this); + uint64_t mask = (1ULL << size) - 1; + uint64_t oldv = (value >> bit) & mask; + if (bit + size > N) { + LOG1("ERROR: subfield " << bit << ".." << (bit + size - 1) << " out of range in " + << this); + } else if (write && oldv) { + LOG1((v != oldv ? "ERROR" : "WARNING") + << ": Overwriting subfield(" << bit << ".." << (bit + size - 1) << ") value " + << oldv << " with " << v << " in " << this); + } + if (v > mask) { + LOG1("ERROR: Subfield value " << v << " too large for " << size << " bits in " << this); + v &= mask; + } + value |= v << bit; + write = true; + log("|=", v << bit); + return check(); + } +}; + +#endif /* BF_ASM_UBITS_H_ */ diff --git a/backends/tofino/bf-asm/vector.c b/backends/tofino/bf-asm/vector.c new file mode 100644 index 00000000000..7a4df9f36f7 --- /dev/null +++ b/backends/tofino/bf-asm/vector.c @@ -0,0 +1,116 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "vector.h" + +struct raw_vector { + int capacity, size; + void *data; +}; + +int init_raw_vector(void *vec, size_t elsize, int mincap) +{ + struct raw_vector *v = (struct raw_vector *)vec; + v->size = 0; + v->capacity = 32 / elsize; + if (v->capacity < 4) v->capacity = 4; + if (v->capacity < mincap) v->capacity = mincap; + if (!(v->data = malloc(elsize * v->capacity))) + v->capacity = 0; + return v->data ? 0 : -1; +} + +int erase_raw_vector(void *vec, size_t elsize, int i, unsigned cnt) +{ + struct raw_vector *v = (struct raw_vector *)vec; + if (i < 0 && i >= v->size) return -1; + if (cnt == 0) cnt = 1; + if (i + cnt >= (unsigned)v->size) { + v->size = i; + } else { + char *p = (char *)v->data + i*elsize; + memmove(p, p + elsize*cnt, elsize * (v->size - i - cnt)); + v->size -= cnt; } + return 0; +} + +int expand_raw_vector(void *vec, size_t elsize) +{ + struct raw_vector *v = (struct raw_vector *)vec; + size_t ncap = v->capacity * 2U; + void *n; + if (ncap == 0) { + ncap = 32 / elsize; + if (ncap < 4) ncap = 4; } + if (ncap > (size_t)INT_MAX && (int)(ncap = INT_MAX) == v->capacity) { + errno = ERANGE; + return -1; } + if (!(n = realloc(v->data, elsize * ncap))) return -1; + v->capacity = ncap; + v->data = n; + return 0; +} + +int insert_raw_vector(void *vec, size_t elsize, int i, unsigned cnt) +{ + struct raw_vector *v = (struct raw_vector *)vec; + if (i < 0 && i > v->size) return -1; + if (cnt == 0) cnt = 1; + if (v->size + cnt > (unsigned)INT_MAX) { + errno = ERANGE; + return -1; } + if ((int)(v->size + cnt) > v->capacity) { + int newsz = v->size + cnt; + void *n; + if (newsz < v->capacity * 2) newsz = v->capacity * 2; + if (!(n = realloc(v->data, elsize * newsz))) return -1; + v->capacity = newsz; + v->data = n; } + if (i < v->size) { + char *p = (char *)v->data + i*elsize; + memmove(p + cnt*elsize, p, elsize * (v->size - i)); } + v->size += cnt; + return 0; +} + +int reserve_raw_vector(void *vec, size_t elsize, int size, int shrink) +{ + struct raw_vector *v = (struct raw_vector *)vec; + void *n; + if (v->capacity < size || (shrink && v->capacity > size)) { + if (!(n = realloc(v->data, elsize * size))) return -1; + v->capacity = size; + if (size < v->size) + v->size = size; + v->data = n; } + return 0; +} + +int shrink_raw_vector(void *vec, size_t elsize) +{ + struct raw_vector *v = (struct raw_vector *)vec; + void *n; + if (v->size < v->capacity) { + if (!(n = realloc(v->data, elsize * v->size))) return -1; + v->capacity = v->size; + v->data = n; } + return 0; +} diff --git a/backends/tofino/bf-asm/vector.h b/backends/tofino/bf-asm/vector.h new file mode 100644 index 00000000000..28524e7b831 --- /dev/null +++ b/backends/tofino/bf-asm/vector.h @@ -0,0 +1,229 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_VECTOR_H_ +#define BF_ASM_VECTOR_H_ + +/* C code and macros for VECTOR objects similar to C++ std::vector */ +#include + +#define CAT(A, B) A##B +#define VECTOR(NAME) CAT(NAME, _VECTOR) +#define DECLARE_VECTOR(TYPE, ...) \ + typedef struct CAT(TYPE, _VECTOR) { \ + int capacity, size; \ + TYPE *data; \ + __VA_ARGS__ \ + } CAT(TYPE, _VECTOR); +#define DECLARE_VECTOR2(NAME, ELTYPE, ...) \ + typedef struct CAT(NAME, _VECTOR) { \ + int capacity, size; \ + ELTYPE *data; \ + __VA_ARGS__ \ + } CAT(NAME, _VECTOR); + +#define RAW(X) X + +/* VECTOR constructors/destrutor + * can safely use memset(&vec, 0, sizeof(vec)) for initial capacity of 0, + * so global and calloc'd VECTORs are safe to use immediately + * local and malloc's VECTORs must be initialized before use, as they may + * contain garbage */ + +/* VECTOR_init(vec, capacity) + * initialize an empty vector with optional initial capacity + * VECTOR_initcopy(vec, from) + * initialize a vector as a copy of an existing vector + * VECTOR_initN(vec, val1, ...) + * initialize a vector with N values + * RETURNS + * 0 success + * -1 failure (out of memory), vector has capacity 0 + */ +#define VECTOR_init(vec, ...) init_raw_vector(&(vec), sizeof((vec).data[0]), RAW(__VA_ARGS__ + 0)) + +#define VECTOR_initcopy(vec, from) \ + (init_raw_vector(&(vec), sizeof((vec).data[0]), (from).size) \ + ? -1 \ + : (memcpy((vec).data, (from).data, ((vec).size = (from).size) * sizeof((vec).data[0])), \ + 0)) + +#define VECTOR_init1(vec, v1) \ + (init_raw_vector(&(vec), sizeof((vec).data[0]), 1) \ + ? -1 \ + : ((vec).size = 1, (vec).data[0] = (v1), 0)) +#define VECTOR_init2(vec, v1, v2) \ + (init_raw_vector(&(vec), sizeof((vec).data[0]), 2) \ + ? -1 \ + : ((vec).size = 2, (vec).data[0] = (v1), (vec).data[1] = (v2), 0)) +#define VECTOR_init3(vec, v1, v2, v3) \ + (init_raw_vector(&(vec), sizeof((vec).data[0]), 3) \ + ? -1 \ + : ((vec).size = 3, (vec).data[0] = (v1), (vec).data[1] = (v2), (vec).data[2] = (v3), 0)) +#define VECTOR_init4(vec, v1, v2, v3, v4) \ + (init_raw_vector(&(vec), sizeof((vec).data[0]), 4) \ + ? -1 \ + : ((vec).size = 3, (vec).data[0] = (v1), (vec).data[1] = (v2), (vec).data[2] = (v3), \ + (vec).data[3] = (v4), 0)) +#define VECTOR_init5(vec, v1, v2, v3, v4, v5) \ + (init_raw_vector(&(vec), sizeof((vec).data[0]), 5) \ + ? -1 \ + : ((vec).size = 3, (vec).data[0] = (v1), (vec).data[1] = (v2), (vec).data[2] = (v3), \ + (vec).data[3] = (v4), (vec).data[4] = (v5), 0)) + +#define EMPTY_VECTOR_INIT \ + { 0, 0, 0 } + +/* VECTOR_fini(vec) + * destroys a vector, freeing memory + * RETURNS + * void + */ +#define VECTOR_fini(vec) free((vec).data) + +/* VECTOR methods */ + +/* VECTOR_add(vec, val) + * add a single value to the end of a vector, increasing its size (and + * capacity if necessary) + * VECTOR_addcopy(vec, ptr, n) + * add a multiple value to the end of a vector, increasing its size (and + * capacity as necessary) + * VECTOR_copy(vec, from) + * replace a vector with a copy of another vector + * RETURNS + * 0 success + * -1 failure (out of memory), vector is unchanged + */ +#define VECTOR_add(vec, val) \ + (((vec).size == (vec).capacity && expand_raw_vector(&(vec), sizeof((vec).data[0]))) \ + ? -1 \ + : ((vec).data[(vec).size++] = (val), 0)) +#define VECTOR_addcopy(vec, ptr, n) \ + (VECTOR_reserve(vec, (vec).size + (n)) \ + ? -1 \ + : (memcpy((vec).data + (vec).size, (ptr), (n) * sizeof((vec).data[0])), \ + (vec).size += (n), 0)) +#define VECTOR_copy(vec, from) \ + (VECTOR_reserve(vec, (from).size) \ + ? -1 \ + : (memcpy((vec).data, (from).data, (from).size * sizeof((vec).data[0])), \ + (vec).size = (from).size, 0)) + +#define VECTOR_begin(vec) ((vec).data) +#define VECTOR_end(vec) ((vec).data + (vec).size) +#define VECTOR_empty(vec) ((vec).size == 0) + +/* VECTOR_erase(vec, idx, cnt) + * erase cnt elements from a vector (defaults to 1). If there are fewer + * than cnt elements in the vector after idx (inclusive), all will be + * erased + * RETURNS + * 0 success + * -1 idx is out of range + */ +#define VECTOR_erase(vec, idx, ...) \ + erase_raw_vector(&(vec), sizeof((vec).data[0]), idx, RAW(__VA_ARGS__ + 0)) + +/* VECTOR_expand(vec) + * increase the capacity of a vector, if possible. Does not affect the size + * RETURNS + * 0 success + * -1 failure (out of memory), vector is unchanged + */ +#define VECTOR_expand(vec) expand_raw_vector(&(vec), sizeof((vec).data[0])) + +/* VECTOR_foreach(vec, apply) + * apply a function or macro to every element of a vector + * not a valid expression, so doesn't really return anything + */ +#define VECTOR_foreach(vec, apply) \ + do { \ + for (int i_ = 0; i_ < (vec).size; i_++) { \ + apply((&(vec).data[i_])); \ + } \ + } while (0) + +/* VECTOR_insert(vec, idx, cnt) + * increase the size of a vector, adding uninitialized space at idx, and + * moving later elements of the vector up. cnt defaults to 1 + * RETURNS + * 0 success + * -1 failure -- idx is out of range[ERANGE], or out of memeory[ENOMEM] + * vector is unchanged + */ +#define VECTOR_insert(vec, idx, ...) \ + insert_raw_vector(&(vec), sizeof((vec).data[0]), idx, RAW(__VA_ARGS__ + 0)) + +#define VECTOR_pop(vec) ((vec).data[--(vec).size]) +#define VECTOR_push(vec, val) VECTOR_add(vec, val) + +/* VECTOR_reserve(vec, size, shrink) + * change the capacity of a vector. If shrink is false (default), will only + * increase the capacity. + * RETURNS + * 0 success + * -1 failure (out of memory), vector is unchanged + */ +#define VECTOR_reserve(vec, size, ...) \ + reserve_raw_vector(&(vec), sizeof((vec).data[0]), size, RAW(__VA_ARGS__ + 0)) + +/* VECTOR_resize(vec, size, shrink) + * change the size of a vector. If shrink is false (default), will only + * increase the capacity. + * RETURNS + * 0 success + * -1 failure (out of memory), vector is unchanged + */ +#define VECTOR_resize(vec, sz, ...) \ + (VECTOR_reserve(vec, sz, __VA_ARGS__) ? -1 : ((vec).size = (sz), 0)) + +/* VECTOR_shrink_to_fit(vec) + * reduce capacity to match the size, releasing memory if possible + * RETURNS + * 0 success + * -1 failure (realloc failed to shrink?), vector is unchanged + */ +#define VECTOR_shrink_to_fit(vec) shrink_raw_vector(&(vec), sizeof((vec).data[0])) + +/* VECTOR_terminate(vec, val) + * ensure that capacity is greater than size, and store val after + * the end of the vector. + * RETURNS + * 0 success + * -1 failure (out of memory), vector is unchanged + */ +#define VECTOR_terminate(vec, val) \ + (((vec).size == (vec).capacity && expand_raw_vector(&(vec), sizeof((vec).data[0]))) \ + ? -1 \ + : ((vec).data[(vec).size] = (val), 0)) +#define VECTOR_top(vec) ((vec).data[(vec).size - 1]) + +#ifdef __cplusplus +extern "C" { +#endif +extern int erase_raw_vector(void *vec, size_t elsize, int idx, unsigned cnt); +extern int expand_raw_vector(void *vec, size_t elsize); +extern int init_raw_vector(void *vec, size_t elsize, int mincap); +extern int insert_raw_vector(void *vec, size_t elsize, int idx, unsigned cnt); +extern int reserve_raw_vector(void *vec, size_t elsize, int size, int shrink); +extern int shrink_raw_vector(void *vec, size_t elsize); +#ifdef __cplusplus +} +#endif + +#endif /* BF_ASM_VECTOR_H_ */ diff --git a/backends/tofino/bf-asm/version.h b/backends/tofino/bf-asm/version.h new file mode 100644 index 00000000000..d4fd9442c71 --- /dev/null +++ b/backends/tofino/bf-asm/version.h @@ -0,0 +1,44 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include + +namespace BFASM { +// Singleton class representing the assembler version +class Version { + public: + static const std::string getVersion() { + static Version v; + return std::to_string(v.major) + "." + std::to_string(v.minor) + "." + + std::to_string(v.patch); + } + + private: + static constexpr int major = 1; + static constexpr int minor = 0; + static constexpr int patch = 1; + + Version() {} + + public: + // disable any other constructors + Version(Version const &) = delete; + void operator=(Version const &) = delete; +}; + +} // namespace BFASM diff --git a/backends/tofino/bf-asm/walle/README.md b/backends/tofino/bf-asm/walle/README.md new file mode 100644 index 00000000000..2e9b6a4b16a --- /dev/null +++ b/backends/tofino/bf-asm/walle/README.md @@ -0,0 +1,263 @@ +Walle - JSON-to-binary cruncher tool +==================================================== + +Walle serves as a layer of abstraction between the Tofino compiler and chip, +presenting the chip's memory hierarchy to the compiler as a set of JSON +structures that contain register/memory names and their values, while +abstracting away the actual addresses of these registers and the methods by +which they are programmed (DMA/direct PCIe writes/indirect instruction lists). + +Walle stores the exact structure of the chip's memory hierarchy in a +"chip.schema" file, which has to be generated from raw register data whenever +the chip registers change, and is then used afterwards to crunch compiler output +into a binary config file. It can also be used to generate "template" JSON that +looks like compiler output with the hardware's default values for all fields (in +most cases, 0). These templates are used by the compiler to enforce the correct +structure on its output data, and also in general should be regenerated whenever +the chip's registers change. + +Using Walle +---------------------------------------------------- +### Basic usage +#### Generating a schema +First, generate a chip schema. Invoke Walle with the `--generate-schema` flag +followed by the directory containing raw CSV files output by csrCompiler. If +the bfnregs repo is cloned into ~/bfnregs, this would be: + + ./walle.py --generate-schema ~/bfnregs/modules/tofino_regs/module/csv/ + +This will generate a file named `chip.schema` in the current working directory, +which is where it will look for the chip schema by default. The +`--schema SCHEMA-FILE` flag can be used to point Walle to a different schema, +or a different location to output the schema it is generating. + +#### Crunching compiler output +The most common use case for Walle is taking multiple config JSONs and +crunching them into a binary file Tofino's drivers can read. Just invoke +Walle with the names of all relevant JSON files, and optionally the name of +the file to output: + + ./walle.py cfg1.json cfg2.json cfg3.json -o chip_config.bin + +If the compiler was set up to dump all of its config output into an otherwise +empty directory, shell wildcards can be used to shorten this command. If that +dir is called 'cfgs', this would look like: + + ./walle.py cfgs/*.json -o chip_config.bin + +#### Generating templates +Walle can be used to generate blank register templates to be filled in by the +compiler. These templates are the JSON files that Walle would expect to see +given the current chip schema, but with all of the data set to the corresponding +hardware register's power-on default (in most cases, 0). + +To do so, Walle must be fed a JSON file enumerating the Semifore addressmap +objects it should generate templates for. This file must take this structure: + + { + "generated": { + "memories":[ + // memory addressmap names + ], + "regs":[ + // register addressmap names + ] + }, + "ignored": { + "memories":[ + // memory addressmap names + ], + "regs":[ + // register addressmap names + ] + } + } + +Names under 'memories' keys refer to addressmaps included by the top-level +'pipe_top_level.csr' file, while names under 'regs' keys refer to those included +by 'tofino.csr'. + +Address maps listed under 'generated' will cause a JSON template file to be +generated. Wherever that address map appears elsewhere in the hierarchy will be +replaced with a string reference to said JSON file. + +Address maps listed under 'ignored' will be replaced with a 0 when they appear +elsewhere in the hierarchy, and no JSON template file will be generated. + +Use the `--generate-templates` flag followed by the path to a file of the +format just discussed to generate template JSONs in a directory called +`templates` (which will be created in the working directory if it doesn't +already exist): + + ./walle.py --generate-templates templates_file + +These files can then be copied to the compiler's source tree. + +The templates themselves end in the extension '.cfg.json'. Walle will also +generate an identical hierarchy containing the bit-widths of each field, and +these files end in the extension '.size.json'. + +### Advanced usage +#### Directing the crunch process +Walle crunches by first loading all provided JSON files and verifying them +against its chip schema, and then drilling down from specified "top-level" +points in that cloud of JSON data. By default, these points are called +`memories.top` and `regs.top` and represent the memory and register hierarchies +of the chip, respectively. + +The `--top NAME` flag can be used to manually specify the top-level points to +drill down from. Multiple `--top NAME` flags can be included, and if any are +present the default top-level names are not used. + +This is equivalent to the default behavior: + + ./walle.py cfgs/*.json --top memories.top --top regs.top -o chip_config.bin + +One of them can be left out to only generate, say, only register configuration: + + ./walle.py cfgs/*.json --top regs.top -o chip_config.bin + +Walle calculates addresses relative to the top-level points specified, so it is +important that these points only ever refer to actual top-level points in the +Semifore register hierarchy. If it is desired to only generate, for example, +config data for the MAU or one pipe, the top-level JSON files should be +hand-tweaked to disable other parts of the configuration binary. See the +specification of the JSON config format for more details. + +#### Directing the template generation process +Walle generates a template file for each addressmap type specified in the +`template_objects` file which sits in the same folder as the Walle script. If +Walle encounters an instance of these addressmap types during template +generation, it leaves that tree of the JSON data unexpanded and replaces it +with a string indicating it expects a template to be plugged in to that +location. + +The type names of these addressmaps can be found by viewing the Semifore HTML +output of the reg and memory hierarchies and checking 'Header File Information' +at the top of the page. The 'Type Name' field that then appears within each +address map indicates the type which should be passed to Walle for +templatization. Semifore incorrectly capitlizes the first letter of the type +name - it should be all lowercase when specified to Walle. + +Note that the JSON fed to Walle does *not* have to follow the same template +structure as specified in the `template_objects` file - this templatization +control is just for convenience and reducing the file size of the generated +blank templates. + +Configuration JSON format +---------------------------------------------------- +Walle consumes JSON files that specify values to be written registers named in +the chip's Semifore specification. The structure of these JSON files directly +mirrors the structure found in the chip's Semifore specification. + +Each JSON file contains a dictionary that represents one instance of a Semifore +addressmap. Addressmap dictionaries' keys represent the Semifore names of +registers and nested addressmaps, while the values are either: + + * Dictionaries representing those objects + * Lists of dictionaries, in the case the object in question is an array + * Lists of lists (of lists of lists of lists of...) in the case the object + in question is an N-dimensional array + +Register dictionaries have field names as keys and integers as values. They +follow the same rules for lists in the event of a field array. The outer-most +dictionary also has these special Walle keys: + + * `_type` : The full type name that this file provides values for, of the + form `section.semifore_type`. For example, the parser's memories are of + type `memories.prsr_mem_rspec`, while its registers are of type + `regs.prsr_reg_rspec` + * `_name` : A name used to reference this file and its data elsewhere in + the config JSON + * `_schema_hash`: The MD5 hash of the raw Semifore output used to generate + the chip schema from which this file's structure was derived, used + to ensure the chip schema and JSON input match + * `_reg_version`: The git tag of the bfnregs repo commit used to generate + the chip schema from which this file's structure was derived. This value + isn't used by Walle itself, but is useful to manually determine which + version of the compiler or model a given config JSON was created for. + +At any point in the hierarchy, a register/addressmap value may be replaced +with: + + * A string containing the name of another JSON input file, which "stamps" + that other data down at this point in the memory hierarchy + * 0, indicating no write operation should be generated for the given object + +Fields cannot be "disabled with 0s" the way registers and addressmaps can, +since the register is the level of granularity at which the drivers write data. + +Config JSON can be hand-tweaked with 0's to produce a binary blob that +only writes to specific registers and leaves everything else alone, in order +to produce "initial boot" config blobs and then "soft reboot" config blobs. + +#### Error checking +Walle will fail to generate output if: + + * A field value ever exceeds the field's bit width as specified in the chip + schema + * A template is instantiated at a point in the hierarchy that does not + match the type expected by the chip schema (eg, naming an instance of + `memories.prsr_mem_rspec` in the top-level *register* JSON) + * A file's `_schema_hash` value does not match the hash stored in the chip + schema. This check can be suppressed with the flag + `--ignore-schema-mismatch`: + + ./walle.py cfgs/*.json --ignore-schema-mismatch -o chip_config.bin + + This flag is provided for development purposes, because even a small + change at one end of the register hierarchy (like correcting a typo in a + register *description*) will change the hash without actually affecting + the structure of the chip schema, and it would be a pain to have to + regenerate all templates and copy them over into the compiler source tree + just to get things working again. + + In the long run, however, this flag should not be used and schema hashes + should be consistent. + +Binary blob format +---------------------------------------------------- +Walle generates a sequence of binary write instructions for the driver which +are of the following types: + + * Direct register write - For 32 bit registers that can be addressed + directly from the PCIe bus, a simple address-data pair of the form: + + 4 bytes: "\0\0\0R" + 4 bytes: 32-bit PCIe address + 4 bytes: Data + All fields little-endian + + * Indirect register write - For registers wider than 32 bits, or to compose + many direct register writes into one write list that can be transmitted + across PCIe as a single transaction. + + TODO: not actually implemented driver-or-Walle-side yet, since the model + doesn't currently support indirect reg addressing + + * DMA block write - Automatically chosen for arrays of registers larger + than 4 elements, a base address and block of data: + + 4 bytes: "\0\0\0D" + 8 bytes: 42-bit chip address + 4 bytes: Bit-length of word + 4 bytes: Number of words + Following: Data, in 32-bit word chunks + All fields little-endian + + TODO: currently only registers in the 'memories' half of the hierarchy + will get rolled into DMA blocks, again because the model doesn't + currently support indirect reg addressing. Eventually this won't + be a problem + +The driver should execute these instructions in the order they are read. The +binary blob has no header or structure aside from these write instructions, +so multiple binary files can be concatenated together or split into parts as +needed. + +Walle can be optionally instructed to generate a direct register write to +address 0xFFFFFFFF at the very end of the file to signify to the model the end +of configuration data. This is enabled with the flag `--append-sentinel`: + + ./walle.py cfgs/*.json --append-sentinel -o chip_config.bin + diff --git a/backends/tofino/bf-asm/walle/chip.py b/backends/tofino/bf-asm/walle/chip.py new file mode 100644 index 00000000000..582398a9868 --- /dev/null +++ b/backends/tofino/bf-asm/walle/chip.py @@ -0,0 +1,167 @@ +# Copyright (C) 2024 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# +# SPDX-License-Identifier: Apache-2.0 + +""" +TODO: document this file +""" +import struct +from copy import copy + +class chip_object(object): + """ + TODO: docstring + """ + def __init__(self, addr, src_key): + self.addr = addr + self.src_key = src_key + + def add_offset (self, offset): + self.addr += offset + +class direct_reg(chip_object): + """ + A single register write operation, of the format: + + 4 bytes: "\0\0\0R" + 4 bytes: 32-bit PCIe address + 4 bytes: Data + + All fields little-endian + """ + + def __init__(self, addr, value, src_key=None): + chip_object.__init__(self, addr, src_key) + self.value=struct.pack("= 0: + byte_str += "\0\0\0R" + struct.pack("" + + def deepcopy(self): + new = copy(self) + new.values = new.values[:] + return new + + def bytes(self): + if self.width > 128: + # FIXME: this only works cleanly if width is a multiple of 128, can it be otherwise? + if self.width % 128 != 0: + sys.stderr.write("ERROR: register width %d not a multiple of 128" % self.width); + sys.exit(1) + new_values = [] + for value in self.values: + for chunk in range(0, self.width//8, 16): + new_values.append(value[chunk:chunk+16].rjust(128//8,chr(0))) + self.values = new_values + self.width = 128 + + if self.is_reg: + op_type = "\0\0\0B" + else: + op_type = "\0\0\0D" + bytestr = op_type + struct.pack(" 0: + outfile.write(indent) + outfile.write("// ") + outfile.write(' ' * pfx) + line = line.lstrip() + pt = line.rfind(' ', 0, maxlen-pfx-len(indent)) + if len(line) + len(indent) + pfx > maxlen: + if pt > 0: + outfile.write(line[0:pt]) + line = line[pt+1:] + else: + # line is longer than maxlen, but has no spaces. So don't split it or + # subsequent lines (this is probably a wide table with columns) + maxlen = len(line) + len(indent) + pfx + outfile.write(line) + line = '' + else: + outfile.write(line) + line = '' + outfile.write("\n") + +def indent_comment(indent, text): + if not text: return text + if text[-2:-1] != '\n': + text = text + '\n' + return indent + text.replace('\n', indent+'\n') + +######################################################################## +## Structures + +class CsrException (Exception): + """ + An exception that occured while crunching malformed data according to the + given chip schema. An exception handler in walle.py will catch these + exceptions and then attempt to print a "traceback" recording where in the + chip schema the exception occured. + + This traceback is maintained by keeping a local variable called 'path' in + any scope where a CsrException may be raised. 'path' is a list of + traversal_history objects. + """ + pass + +class traversal_history (object): + """ + A class which records part of Walle's traversal through input JSON data. A + single traversal_history corresponds to the traversal of one JSON file. + + Attributes: + @attr template_name + The value at the top level "_name" key of the file currently being + processed + @attr path + An ordered list of keys and list indices visited in the current + traversal of this file. + If we drill down into a dictionary at key "a", push "a" onto the list. + If we access elements of a list, push a tuple recording the index at + each dimension of the list and then the list name. Eg, + [(4,),"a"] to represent a[4] + [(1,2,3),"b"] to represent b[1][2][3] + """ + def __init__(self, template_name): + self.template_name = template_name + self.path = [] + +class binary_cache(object): + """ + A class used to store flat chip_obj lists, each corresponding to one JSON + file. The "_name" at the top of each JSON is used to index into the cache. + Requesting a JSON file from here will crunch it into binary if it hasn't + been already. + """ + def __init__(self, schema): + self.schema = schema + self.templates = {} + self.binary_templates = {} + + def get_type(self, key): + """ + Get the addressmap name that the binary data at the given key + corresponds to, of the form "section_name.addressmap_name". + """ + return self.templates[key]["_type"] + + def get_data (self, key, path=None): + """ + Return a list of objects inheriting from chip.chip_obj, representing + the write operations that must be done in the hardware to program a + hardware object of the given JSON file's "_type" + + These lists are a deep copy of the one stored internally, so it is safe + to modify them + """ + if path==None: + path = [] + + if key not in self.binary_templates: + obj_section, obj_type = self.templates[key]["_type"].split(".") + obj_schema = self.schema[obj_section][obj_type] + # TODO: There used to be a first deepcopy here, before the one in the + # return statement. 99% sure it was unnecessary, but if things + # seem broken revisit this + path.append(traversal_history(key)) + self.binary_templates[key] = obj_schema.generate_binary(self.templates[key], self, path) + path.pop() + + binary_data_copy = [] + for chip_obj in self.binary_templates[key]: + binary_data_copy.append(chip_obj.deepcopy()) + return binary_data_copy + +class csr_object (object): + """ + Base class for objects in a Semifore register hierarchy + + A Semifore object array is still represented as one csr_object instance, + albeit with a "count" attribute expressing how many hardware objects this + Semifore node actually corresponds to. + + Since all objects in Semifore have names and can be arrays, all csr_objects + have name and count attributes. Since arrays can be multidimensional, + count is _always_ a tuple of array sizes, even if that tuple has only one + element. Single elements will have a count of (1,). + """ + + def __init__(self, name, count): + self.name = name + self.count = count + + def replicate (self, templatized_self): + if self.count != (1,): + last_dim_obj = templatized_self + for dim in reversed(self.count): + last_dim_obj = [copy.deepcopy(last_dim_obj) for _ in range(0,dim)] + return last_dim_obj + else: + return templatized_self + + def is_field(self): + return False + def is_singleton(self): + return False + def singleton_obj(self): + return self + def contains_reference(self): + return False + +class csr_composite_object (csr_object): + """ + Base class for composite (non-leaf) CSR objects. All such objects have one + or more children + """ + def __init__(self, name, count): + csr_object.__init__(self, name, count) + def children(self): + raise CsrException("Unimplemented abstract method for " + type(self)) + + def check_child_rewrite(self, child, args): + """ + Check to see if the child needs to be rewritten per something in the args, and, if + so, rewrite it and return it. We call this a fair amount with the same child (so + work is duplicated); if that is a problem we should memoize. + """ + if self.name not in args.rewrite: + return child + if self.name not in args.rewrite_used: + args.rewrite_used[self.name] = {} + rewrite = args.rewrite[self.name] + if child.name not in rewrite: + return child + args.rewrite_used[self.name][child.name] = True + rewrite = rewrite[child.name] + if rewrite[0] == 'delete': + return None + elif rewrite[0] == 'scan_chain': + description = '' + offset = child.offset + while not isinstance(child, reg): + if hasattr(child, 'description') and child.description: + description = description + child.description + if description[-2:-1] != '\n': + description = description + '\n' + if len(child.children()) != 1 or child.count != (1,): + raise CsrException("unknown rewrite '%s' for %s.%s" % + (rewrite[child.name][0], name, child.name)) + child = child.children()[0] + if hasattr(child, 'description') and child.description: + description = description + child.description + if description[-2:-1] != '\n': + description = description + '\n' + child = scanset_reg(rewrite[1], tuple(rewrite[2]), offset, child.width, + self, child.fields) + child.description = description + if len(child.fields) == 1: + child.fields = copy.copy(child.fields) + child.fields[0].name = rewrite[1] + if len(rewrite) > 3: + #import pdb; pdb.set_trace() + def find_scan_sel(obj, name, offset): + desc = '' + for ch in obj.children(): + pfx = len(ch.name)+1 + if ch.name+"." == name[:pfx]: + return find_scan_sel(ch, name[pfx:], offset + ch.offset) + if ch.name == name: + offset = offset + ch.offset + desc_hdr = ch.name + ':\n' + if hasattr(ch, 'description') and ch.description: + desc = (desc + desc_hdr + indent_comment(' ', ch.description)) + desc_hdr = '' + if (len(ch.fields) == 1 and hasattr(ch.fields[0], 'description') and + ch.fields[0].description): + desc = (desc + desc_hdr + + indent_comment(' ', ch.fields[0].description)) + return offset, desc + return None, None + offset, desc = find_scan_sel(self, rewrite[3], 0) + if offset is None: + raise CsrException("No "+rewrite[3]+" in "+self.name+" for scan selector") + child.sel_offset = offset + child.description = child.description + desc + return child + else: + raise CsrException("unknown rewrite '%s' for %s.%s" % + (rewrite[el.name][0], name, el.name)) + return None + + def contains_reference(self): + """ + return true if this object (directly or indirectly) contains a reference to + a top_level object + """ + if not hasattr(self, 'contains_reference_cache'): + self.contains_reference_cache = False + for a in self.children(): + if a.top_level() or a.contains_reference(): + self.contains_reference_cache = True + break + return self.contains_reference_cache + + def gen_method_declarator(self, outfile, args, rtype, classname, name, argdecls, suffix): + outfile.write("%s " % rtype) + if args.gen_decl == 'defn': outfile.write("%s::" % classname) + outfile.write("%s(" % name) + first = True + for a in argdecls: + if not first: + outfile.write(", ") + if type(a) is tuple: + outfile.write(a[0]) + if args.gen_decl != 'defn': + outfile.write(" = " + a[1]) + else: + outfile.write(a) + first = False + outfile.write(")") + if suffix != '': + outfile.write(" %s" % suffix) + if args.gen_decl == 'decl': + outfile.write(";\n") + return True + outfile.write(" {\n") + return False + + def gen_emit_method(self, outfile, args, schema, classname, name, nameargs, indent): + outfile.write(indent) + argdecls = ["std::ostream &out"] + for idx, argtype in enumerate(nameargs): + argdecls.append("%sna%d" % (argtype, idx)) + if args.gen_decl == 'defn': + argdecls.append("indent_t indent") + else: + argdecls.append("indent_t indent = indent_t(1)") + if self.gen_method_declarator(outfile, args, "void", classname, + "emit_json", argdecls, "const"): + return + indent += " " + if args.enable_disable and not self.top_level(): + outfile.write("%sif (disabled_) {\n" % indent) + outfile.write('%s out << "0";\n' % indent) + outfile.write("%s return; }\n" % indent) + outfile.write("%sout << '{' << std::endl;\n" % indent) + first = True + if self.top_level(): + if len(nameargs) > 0: + tmplen = len(name) + len(nameargs)*10 + 32 + outfile.write("%schar tmp[%d];\n" % (indent, tmplen)) + outfile.write('%ssnprintf(tmp, sizeof(tmp), "%s"' % (indent, name)) + for i in range(0, len(nameargs)): + outfile.write(", na%d" % i) + outfile.write(");\n") + outfile.write('%sout << indent << "\\"_name\\": \\"" << tmp << "\\"";\n' % indent) + else: + outfile.write('%sout << indent << "\\"_name\\": \\"%s\\"";\n' % (indent, name)) + outfile.write('%sout << ", \\n";\n' % indent) + outfile.write('%sout << indent << "\\"_reg_version\\": \\"%s\\"";\n' % + (indent, schema["_reg_version"])) + outfile.write('%sout << ", \\n";\n' % indent) + outfile.write('%sout << indent << "\\"_schema_hash\\": \\"%s\\"";\n' % + (indent, schema["_schema_hash"])) + outfile.write('%sout << ", \\n";\n' % indent) + outfile.write('%sout << indent << "\\"_section\\": \\"%s\\"";\n' % + (indent, self.parent)) + outfile.write('%sout << ", \\n";\n' % indent) + outfile.write('%sout << indent << "\\"_type\\": \\"%s.%s\\"";\n' % + (indent, self.parent, self.name)) + outfile.write('%sout << ", \\n";\n' % indent) + outfile.write('%sout << indent << "\\"_walle_version\\": \\"%s\\"";\n' % + (indent, schema["_walle_version"])) + first = False + for a in sorted(self.children(), key=lambda a: a.name): + a = self.check_child_rewrite(a, args) + if a is None: continue + if not first: + outfile.write('%sout << ", \\n";\n' % indent) + outfile.write('%sout << indent << "\\"%s\\": ";\n' % (indent, a.name)) + if a.disabled() and not args.expand_disabled_vector: + outfile.write('%sout << "0";\n' % indent) + continue + field_name = a.name + if field_name in args.cpp_reserved: + field_name += '_' + if a.count != (1,): + for idx_num, idx in enumerate(a.count): + if args.enable_disable and args.checked_array and not a.disabled(): + outfile.write("%sif (%s" % (indent, field_name)) + for i in range(0, idx_num): + outfile.write("[i%d]" % i) + outfile.write(".disabled()) {\n") + outfile.write('%s out << "0";\n' % indent) + outfile.write("%s} else {\n" % indent) + indent += ' ' + outfile.write('%sout << "[\\n" << ++indent;\n' % indent) + outfile.write('%sfor (int i%d = 0; i%d < %d; i%d++) { \n' % + (indent, idx_num, idx_num, idx, idx_num)) + outfile.write('%s if (i%d) out << ", \\n" << indent;\n' % (indent, idx_num)) + indent += ' ' + single = a.singleton_obj() + if single != a: + outfile.write('%sout << "{\\n" << indent+1 << "\\"%s\\": " << %s' % + (indent, a.name, field_name)) + if a.count != (1,): + for i in range(0, len(a.count)): + outfile.write("[i%d]" % i) + outfile.write(" << '\\n';\n") + outfile.write("%sout << indent << '}';\n" % indent) + elif a.is_field() or a.top_level(): + outfile.write("%sout << %s" % (indent, field_name)) + if a.count != (1,): + for i in range(0, len(a.count)): + outfile.write("[i%d]" % i) + outfile.write(";\n") + elif a.disabled(): + outfile.write('%sout << 0;\n' % indent) + else: + outfile.write("%s%s" % (indent, field_name)) + if a.count != (1,): + for i in range(0, len(a.count)): + outfile.write("[i%d]" % i) + outfile.write(".emit_json(out, indent+1);\n") + if a.count != (1,): + for i in range(0, len(a.count)): + indent = indent[2:] + outfile.write("%s}\n" % indent) + outfile.write("%sout << '\\n' << --indent << ']';\n" % indent) + if args.enable_disable and args.checked_array and not a.disabled(): + indent = indent[2:] + outfile.write("%s}\n" %indent) + first = False + outfile.write("%sout << '\\n' << indent-1 << \"}\";\n" % indent) + indent = indent[2:] + outfile.write("%s}\n" % indent) + + def gen_uint_conversion(self, outfile, args, classname, indent): + pass + + def gen_emit_binary_method(self, outfile, args, classname, indent): + def child_name(child): + name = child.name + if name in args.cpp_reserved: + name += '_' + return name + def field_name(child): + name = child_name(child) + if child.count != (1,): + for i in range(0, len(child.count)): + name += "[j%d]" % i + return name + outfile.write(indent) + if self.gen_method_declarator(outfile, args, "void", classname, "emit_binary", + ["std::ostream &out", "uint64_t a"], "const"): + return + indent += " " + if args.enable_disable: + outfile.write("%sif (disabled_) return;\n" % indent) + root_parent = self.parent + while type(root_parent) is not str: + root_parent = root_parent.parent + addr_decl = "auto " + for a in self.children(): + addr_var = "a" + if a.disabled(): continue + a = self.check_child_rewrite(a, args) + if a is None: continue + if root_parent=="memories": + indirect = True + width_unit = 128 + address_unit = 16 + type_tag = 'D' + elif a.name in args.write_dma: + indirect = True + width_unit = 32 + address_unit = 1 + type_tag = 'B' + else: + indirect = False + width_unit = 32 + address_unit = 1 + type_tag = 'R' + if isinstance(a, scanset_reg): + a.output_binary(outfile, args, indent, address_unit, width_unit) + continue + if args.enable_disable: + outfile.write("%sif (!%s.disabled()) {\n" % (indent, child_name(a))) + indent += ' ' + if indirect and type(a) is reg: + outfile.write("%sout << binout::tag('%s') << binout::byte8" % (indent, type_tag) + + "(a + 0x%x) << binout::byte4(%d) << binout::byte4(%d);\n" % + (a.offset//address_unit, width_unit, + product(a.count) * a.width // width_unit)) + if a.count != (1,): + if args.enable_disable: + outfile.write("%sauto addr = a;\n" % indent) + else: + outfile.write("%s%saddr = a;\n" % (indent, addr_decl)) + addr_decl = ""; + addr_var = "addr" + for idx_num, idx in enumerate(a.count): + outfile.write('%sfor (int j%d = 0; j%d < %d; j%d++) { \n' % + (indent, idx_num, idx_num, idx, idx_num)) + indent += ' ' + single = a.singleton_obj() + if not indirect and single != a: + # FIXME -- should check each element being written singly to see if its + # disabled and not write it if so? The generate_binary code does not + # do that, so we don't emit C++ code to do it either. + # Would it cause problems for register arrays that are actually wideregs + # under the hood? See 3.2.1.1 in the Tofino Switch Architecture doc. + outfile.write("%sif (!%s.disabled()) {\n" % (indent, field_name(a))) + indent += ' ' + if single.msb >= 64: + for w in (list(range(single.msb//32, -1, -1)) + if args.reverse_write else + list(range(0, single.msb//32 + 1))): + outfile.write("%sout << binout::tag('R') << binout::byte4" % indent + + "(%s + 0x%x) << binout::byte4(%s.value.getrange(%d, 32));\n" % + (addr_var, a.offset//address_unit + 4, field_name(a), w*32)) + else: + if not args.reverse_write: + outfile.write("%sout << binout::tag('R') << binout::byte4" % indent + + "(%s + 0x%x) << binout::byte4(%s);\n" % + (addr_var, a.offset//address_unit, field_name(a))) + if single.msb >= 32: + outfile.write("%sout << binout::tag('R') << binout::byte4" % indent + + "(%s + 0x%x) << binout::byte4(%s >> 32);\n" % + (addr_var, a.offset//address_unit + 4, field_name(a))) + if args.reverse_write: + outfile.write("%sout << binout::tag('R') << binout::byte4" % indent + + "(%s + 0x%x) << binout::byte4(%s);\n" % + (addr_var, a.offset//address_unit, field_name(a))) + indent = indent[2:] + outfile.write("%s}\n" % indent) + else: + outfile.write(indent) + if a.top_level(): + outfile.write("if (%s)" % field_name(a)) + outfile.write(field_name(a)) + outfile.write("->" if a.top_level() else ".") + outfile.write("emit_binary(out, %s + 0x%x);\n" % + (addr_var, a.offset//address_unit)) + if a.count != (1,): + outfile.write("%saddr += 0x%x;\n" % (indent, a.address_stride()//address_unit)) + for i in range(0, len(a.count)): + indent = indent[2:] + outfile.write("%s}\n" % indent) + if args.enable_disable: + indent = indent[2:] + outfile.write("%s}\n" % indent) + indent = indent[2:] + outfile.write("%s}\n" % indent) + + def gen_input_binary_method(self, outfile, args, classname, indent): + def child_name(child): + name = child.name + if name in args.cpp_reserved: + name += '_' + return name + def field_name(child): + name = child_name(child) + if child.count != (1,): + for i in range(0, len(child.count)): + name += "[i%d]" % i + return name + outfile.write(indent) + if self.gen_method_declarator(outfile, args, "void", classname, "input_binary", + ["uint64_t a", "char t", "uint32_t *d", "size_t l"], ""): + return + indent += " " + root_parent = self.parent + while type(root_parent) is not str: + root_parent = root_parent.parent + if root_parent == "memories": + width_unit = 128 + address_unit = 16 + outfile.write("%sBUG_CHECK(t == 'D', \"'%%c' tag in memories\", t);\n" % indent); + else: + width_unit = 32 + address_unit = 1 + outfile.write("%sBUG_CHECK(t != 'D', \"'%%c' tag in %s\", t);\n" % + (indent, root_parent)) + first = True + for a in sorted(self.children(), key=lambda a: -a.offset): + outfile.write('%s%sif (a >= 0x%x) {\n' % + (indent, '' if first else '} else ', a.offset//address_unit)) + indent += ' ' + t = a + a = self.check_child_rewrite(a, args) + if a is None: + outfile.write('%sstd::cerr << "Address in ignored reg " << ' % indent + + 'string_regname(this, this+1) << ".%s" << std::endl;\n' % t.name) + elif isinstance(a, scanset_reg): + a.input_binary(outfile, args, indent, address_unit, width_unit) + elif a.disabled(): + outfile.write('%sstd::cerr << "Address in disabled reg " << ' % indent + + 'string_regname(this, this+1) << ".%s" << std::endl;\n' % a.name) + else: + outfile.write('%sa -= 0x%x;\n' % (indent, a.offset//address_unit)) + idx_suffix = '' + if a.count != (1,): + outfile.write('%ssize_t idx = a / 0x%x;\n' % + (indent, a.address_stride()//address_unit)) + for idx_num, idx in reversed(list(enumerate(a.count))): + outfile.write('%sint i%d = idx %% %d;\n' % (indent, idx_num, idx)) + if idx_num == 0: + outfile.write('%sBUG_CHECK(idx < %d, "Index too' % (indent, idx) + + ' large for %%s.%s[%%zd]",\n' % a.name) + outfile.write('%s ' % indent + + 'string_regname(this, this+1).c_str(), idx);\n') + else: + outfile.write('%sidx /= %d;\n' % (indent, idx)) + idx_suffix = ('[i%d]' % idx_num) + idx_suffix + outfile.write('%sa -= 0x%x * %s' % (indent, a.address_stride()//address_unit, + '(' * (len(a.count)-1))) + for idx_num, idx in enumerate(a.count): + if idx_num != 0: + outfile.write('*%d + ' % idx) + outfile.write('i%d' % idx_num) + if idx_num != 0: + outfile.write(')') + outfile.write(';\n'); + #outfile.write('%sstd::cout << string_regname(this, this+1) << ".%s' % + # (indent, a.name)) + #if a.count != (1,): + # for idx_num, idx in enumerate(a.count): + # outfile.write('[" << i%d << "]' % idx_num) + #outfile.write('" << std::endl;\n'); + access = '.' + if a.top_level(): + outfile.write('%sif (!%s) {\n' % (indent, field_name(a))) + outfile.write('%s auto *n = new %s;\n' % (indent, + a.canon_name(a.map.object_name)[0])) + outfile.write('%s auto fn = string_regname(this, this+1);\n' % indent); + outfile.write('%s declare_registers(n, sizeof(*n),\n' % indent); + outfile.write('%s [=](std::ostream &out, const char *addr, ' % indent + + 'const void *end) {\n'); + outfile.write('%s out << fn << ".%s' % (indent, child_name(a))) + if a.count != (1,): + for idx_num, idx in enumerate(a.count): + outfile.write('[" << i%d << "]' % idx_num) + outfile.write('";\n'); + outfile.write('%s n->emit_fieldname(out, addr, end); });\n' % indent) + outfile.write('%s %s.set("%s", n); }\n' % + (indent, field_name(a), child_name(a))) + access = '->' + single = a.singleton_obj() + if single != a: + outfile.write("%sBUG_CHECK(t == 'R' && l == 1, \"tag '%%c' " % indent + + 'input to singleton %s", t);\n' % field_name(a)) + if single.msb >= 64: + outfile.write('%sBUG("widereg singleton %s not implemented");' % + (indent, field_name(a))) + elif single.msb >= 32: + outfile.write('%sBUG_CHECK((a|4) == 4, "invalid addr %%zd in ' % indent + + '%s", a);\n' % field_name(a)) + outfile.write('%s%s.set_subfield(*d, a*8, 32);\n' % + (indent, field_name(a))) + else: + outfile.write('%s%s = *d;\n' % (indent, field_name(a))) + elif isinstance(a, reg) and a.count != (1,): + outfile.write('%sBUG_CHECK(a == 0 || l == 1, "%%" PRIu64 " off ' % indent + + 'start of %s", a);\n' % a.name) + if a.width%32 != 0: + raise CsrException("Register %s width not a multiple of 32" % a.name) + size = a.width//32 + outfile.write('%swhile (l > %d) {\n' % (indent, size)) + indent += ' '; + outfile.write('%s%s%sinput_binary(a, t, d, %d);\n' % + (indent, field_name(a), access, size)) + outfile.write('%sd += %d; l -= %d;\n' % (indent, size, size)) + for idx_num, idx in reversed(list(enumerate(a.count))): + outfile.write('%sif (++i%d >= %d) {\n' % (indent, idx_num, idx)) + indent += ' ' + if idx_num != 0: + outfile.write('%si%d = 0;\n' % (indent, idx_num)) + outfile.write('%sBUG("Too much data for %s");%s\n' % + (indent, a.name, ' }' * (len(a.count) + 1))) + indent = indent[2 * (len(a.count) + 1):] + outfile.write('%s%s%sinput_binary(a, t, d, l);\n' % + (indent, field_name(a), access)) + else: + outfile.write('%s%s%sinput_binary(a, t, d, l);\n' % + (indent, field_name(a), access)) + indent = indent[2:] + first = False + outfile.write('%s}\n' % indent) + + indent = indent[2:] + outfile.write('%s}\n' % indent) + + def gen_binary_offset_method(self, outfile, args, classname, indent): + outfile.write(indent) + if self.gen_method_declarator(outfile, args, "uint64_t", classname, "binary_offset", + ["const void *addr", ("int *bit_offset", "0")], "const"): + return + root_parent = self.parent + while type(root_parent) is not str: + root_parent = root_parent.parent + if root_parent=="memories": + width_unit = 128 + address_unit = 16 + else: + width_unit = 32 + address_unit = 1 + indent += " " + outfile.write("%suint64_t offset = 0;\n" % indent) + outfile.write("%sif (bit_offset) *bit_offset = 0;\n" %indent) + outfile.write("%sif (addr < this || addr >= this+1) " % indent) + if (self.contains_reference()): + outfile.write("{\n") + indent += " " + for a in self.children(): + if a.disabled(): continue + if not (a.top_level() or a.contains_reference()): continue + field_name = a.name + if field_name in args.cpp_reserved: + field_name += '_' + if a.count != (1,): + for i, idx in enumerate(a.count): + outfile.write('%sfor (int i%d = 0; i%d < %d; i%d++) { \n' % + (indent, i, i, idx, i)) + indent += ' ' + field_name += "[i%d]" % i + outfile.write("%sif ((offset = %s%sbinary_offset(addr, bit_offset)) != -1)\n" % + (indent, field_name, "->" if a.top_level() else ".")) + outfile.write("%s return offset + 0x%x" % (indent, a.offset//address_unit)) + if a.count != (1,): + for i, idx in enumerate(a.count): + stride = a.address_stride()//address_unit + for cnt in a.count[i+1:]: + stride = stride * cnt + outfile.write(" + i%d*0x%x" % (i, stride)) + outfile.write(";\n") + if a.count != (1,): + for i, idx in enumerate(a.count): + indent = indent[2:] + outfile.write("%s}\n" % indent) + + indent = indent[2:] + outfile.write("%s}\n" % indent) + else: + outfile.write("return -1;\n") + + first = True + for a in sorted(self.children(), key=lambda a: a.name, reverse=True): + if a.disabled(): continue + if a.top_level(): continue + a = self.check_child_rewrite(a, args) + if a is None: continue + field_name = a.name + if field_name in args.cpp_reserved: + field_name += '_' + outfile.write(indent) + if first: first = False + else: outfile.write("} else ") + outfile.write("if (addr >= &%s) {\n" % field_name) + indent += " " + outfile.write("%soffset = 0x%x;\n" % (indent, a.offset//address_unit)) + if a.count != (1,): + for i, idx in enumerate(a.count): + outfile.write("%sif (addr < &%s[0]) return offset;\n" % (indent, field_name)) + outfile.write("%sauto i%d = ((char *)addr - (char *)&%s[0])/sizeof(%s[0]);\n" % + (indent, i, field_name, field_name)) + stride = a.address_stride()//address_unit + for cnt in a.count[i+1:]: + stride = stride * cnt + outfile.write("%soffset += i%d * 0x%x;\n" % (indent, i, stride)) + field_name += "[i%d]" % i + single = a.singleton_obj() + if not single.is_field() and not single.top_level(): + outfile.write("%soffset += %s.binary_offset(addr, bit_offset);\n" % + (indent, field_name)) + indent = indent[2:] + if first: + outfile.write("%sreturn -1;\n" % indent) + else: + outfile.write("%s} else {\n" % indent) + outfile.write("%s return -1;\n" % indent) + outfile.write("%s}\n" % indent) + outfile.write("%sreturn offset;\n" % indent) + indent = indent[2:] + outfile.write("%s}\n" % indent) + + def gen_fieldname_method(self, outfile, args, classname, indent): + outfile.write(indent) + if self.gen_method_declarator(outfile, args, "void", classname, "emit_fieldname", + ["std::ostream &out", "const char *addr", "const void *end"], "const"): + return + indent += " " + if not self.is_singleton(): + outfile.write("%sif ((void *)addr == this && end == this+1) return;\n" % indent) + first = True + for a in sorted(self.children(), key=lambda a: a.name, reverse=True): + if a.disabled(): continue + a = self.check_child_rewrite(a, args) + if a is None: continue + field_name = a.name + if field_name in args.cpp_reserved: + field_name += '_' + outfile.write(indent) + if first: first = False + else: outfile.write("} else ") + outfile.write("if (addr >= (char *)&%s) {\n" % field_name) + indent += " " + outfile.write('%sout << ".%s";\n' % (indent, a.name)) + if a.count != (1,): + for i, idx in enumerate(a.count): + outfile.write("%sint i%d = (addr - (char *)&%s[0])/(int)sizeof(%s[0]);\n" % ( + indent, i, field_name, field_name)) + if idx > 1: + outfile.write("%sif (i%d < 0 || (i%d == 0 && 1 + &%s" % ( + indent, i, i, field_name)) + outfile.write(" == end)) return;\n") + outfile.write("%sout << '[' << i%d << ']';\n" % (indent, i)) + field_name += "[i%d]" % i + single = a.singleton_obj() + if not single.is_field() and not single.top_level(): + outfile.write("%s%s.emit_fieldname(out, addr, end);\n" % (indent, field_name)) + indent = indent[2:] + if not first: + outfile.write("%s}\n" % indent) + indent = indent[2:] + outfile.write("%s}\n" % indent) + + def gen_unpack_method(self, outfile, args, classname, indent): + outfile.write(indent) + if self.gen_method_declarator(outfile, args, "int", classname, "unpack_json", + ["json::obj *obj"], ""): + return + indent += " " + outfile.write("%sint rv = 0;\n" % indent) + outfile.write("%sjson::map *m = dynamic_cast(obj);\n" % indent) + outfile.write("%sif (!m) return -1;\n" % indent) + for a in sorted(self.children(), key=lambda a: a.name): + if a.disabled(): continue + a = self.check_child_rewrite(a, args) + if a is None: continue + index_num = 0 + if a.count != (1,): + for index_num, idx in enumerate(a.count): + outfile.write("%sif (json::vector *v%s = dynamic_cast(" % + (indent, index_num)) + indent += " " + if index_num > 0: + outfile.write("(*v%d)[i%d].get()" % (index_num-1, index_num-1)) + else: outfile.write('(*m)["%s"].get()' % a.name) + outfile.write("))\n") + outfile.write("%sfor (int i%d = 0; i%d < %d; i%d++)\n" % + (indent, index_num, index_num, idx, index_num)) + indent += " " + index_num = len(a.count) + single = a.singleton_obj() + field_name = a.name + if field_name in args.cpp_reserved: + field_name += '_' + if single != a: + outfile.write("%sif (json::map *s = dynamic_cast(" % indent) + indent += " " + if index_num > 0: + outfile.write("(*v%d)[i%d].get()" % (index_num-1, index_num-1)) + else: outfile.write('(*m)["%s"].get()' % a.name) + outfile.write("))\n") + outfile.write("%sif (json::number *n = dynamic_cast" % indent) + indent += " " + outfile.write('((*s)["%s"].get()))\n' % a.name) + outfile.write("%s%s" % (indent, field_name)) + if a.count != (1,): + for i in range(0, len(a.count)): + outfile.write("[i%d]" % i) + outfile.write(" = n->val;\n") + indent = indent[2:] + outfile.write("%selse rv = -1;\n" % indent) + indent = indent[2:] + outfile.write("%selse rv = -1;\n" % indent) + elif not a.is_field() and not a.top_level(): + outfile.write("%srv |= %s" % (indent, field_name)) + if a.count != (1,): + for i in range(0, len(a.count)): + outfile.write("[i%d]" % i) + outfile.write(".unpack_json(") + if index_num > 0: + outfile.write("(*v%d)[i%d].get()" % (index_num-1, index_num-1)) + else: outfile.write('(*m)["%s"].get()' % a.name) + outfile.write(");\n") + else: + jtype = "json::number" + access = " = n->val" + if a.top_level(): + jtype = "json::string" + access = ".set(n->c_str(), nullptr)" + outfile.write("%sif (%s *n = dynamic_cast<%s *>(" % (indent, jtype, jtype)) + indent += " " + if index_num > 0: + outfile.write("(*v%d)[i%d].get()" % (index_num-1, index_num-1)) + else: outfile.write('(*m)["%s"].get()' % a.name) + outfile.write(")) {\n") + outfile.write("%s%s" % (indent, field_name)) + if a.count != (1,): + for i in range(0, len(a.count)): + outfile.write("[i%d]" % i) + outfile.write("%s;\n" % access) + if a.top_level(): + outfile.write("%s} else if (json::number *n = dynamic_cast(" % + indent[2:]) + if index_num > 0: + outfile.write("(*v%d)[i%d].get()" % (index_num-1, index_num-1)) + else: outfile.write('(*m)["%s"].get()' % a.name) + outfile.write(")) {\n") + outfile.write("%sif (n->val) rv = -1;\n" % indent) + indent = indent[2:] + outfile.write("%s} else rv = -1;\n" % indent) + for i in range(0, index_num): + indent = indent[4:] + outfile.write("%selse rv = -1;\n" % indent) + outfile.write("%sreturn rv;\n" % indent) + indent = indent[2:] + outfile.write("%s}\n" % indent) + + def gen_dump_unread_method(self, outfile, args, classname, indent): + outfile.write(indent) + if self.gen_method_declarator(outfile, args, "void", classname, "dump_unread", + ["std::ostream &out", "prefix *pfx"], "const"): + return + indent += " " + need_lpfx = True + for a in sorted(self.children(), key=lambda a: a.name): + if a.disabled(): continue + a = self.check_child_rewrite(a, args) + if a is None: continue + field_name = a.name + if field_name in args.cpp_reserved: + field_name += '_' + if not a.singleton_obj().is_field() and not a.top_level(): + if need_lpfx: + outfile.write("%sprefix lpfx(pfx, 0);\n" % indent) + need_lpfx = False + outfile.write('%slpfx.str = "%s' % (indent, a.name)) + if a.count != (1,): + for idx in a.count: + outfile.write("[%d]" % idx) + outfile.write('";\n') + outfile.write("%s%s" % (indent, field_name)) + if a.count != (1,): + for idx in a.count: + outfile.write("[0]") + outfile.write(".dump_unread(out, &lpfx);\n") + else: + outfile.write("%sif (!%s" % (indent, field_name)) + if a.count != (1,): + for idx in a.count: + outfile.write("[0]") + outfile.write('.read) out << pfx << ".%s' % a.name) + if a.count != (1,): + for idx in a.count: + outfile.write("[%d]" % idx) + outfile.write('" << std::endl;\n') + indent = indent[2:] + outfile.write("%s}\n" % indent) + + def gen_modified_method(self, outfile, args, classname, indent): + outfile.write(indent) + if self.gen_method_declarator(outfile, args, "bool", classname, "modified", [], "const"): + return + indent += " " + for a in sorted(self.children(), key=lambda a: a.name): + if a.disabled(): continue + a = self.check_child_rewrite(a, args) + if a is None: continue + field_name = a.name + if field_name in args.cpp_reserved: + field_name += '_' + if not args.checked_array: + if a.count != (1,): + for index_num, idx in enumerate(a.count): + outfile.write("%sfor (int i%d = 0; i%d < %d; i%d++)\n" % + (indent, index_num, index_num, idx, index_num)) + indent += " " + outfile.write("%sif (%s" % (indent, field_name)) + if a.count != (1,): + for i in range(0, len(a.count)): + outfile.write("[i%d]" % i) + outfile.write(".modified()) return true;\n") + if a.count != (1,): + indent = indent[2*len(a.count):] + else: + outfile.write("%sif (%s.modified()) return true;\n" % (indent, field_name)) + outfile.write("%sreturn false;\n" % indent) + indent = indent[2:] + outfile.write("%s}\n" % indent) + + def gen_set_modified_method(self, outfile, args, classname, indent): + outfile.write(indent) + if self.gen_method_declarator(outfile, args, "void", classname, "set_modified", + [("bool v", "true")], ""): + return + indent += " " + for a in sorted(self.children(), key=lambda a: a.name): + if a.disabled(): continue + a = self.check_child_rewrite(a, args) + if a is None: continue + field_name = a.name + if field_name in args.cpp_reserved: + field_name += '_' + if not args.checked_array: + if a.count != (1,): + for index_num, idx in enumerate(a.count): + outfile.write("%sfor (int i%d = 0; i%d < %d; i%d++)\n" % + (indent, index_num, index_num, idx, index_num)) + indent += " " + outfile.write("%s%s" % (indent, field_name)) + if a.count != (1,): + for i in range(0, len(a.count)): + outfile.write("[i%d]" % i) + outfile.write(".set_modified(v);\n") + if a.count != (1,): + indent = indent[2*len(a.count):] + else: + outfile.write("%s%s.set_modified(v);\n" % (indent, field_name)) + indent = indent[2:] + outfile.write("%s}\n" % indent) + + def gen_disable_method(self, outfile, args, classname, indent): + outfile.write(indent) + if self.gen_method_declarator(outfile, args, "bool", classname, "disable", [], ""): + return + indent += " " + outfile.write("%sbool rv = true;\n" % indent) + outfile.write("%sif (modified()) {\n" % indent) + outfile.write('%s std::clog << "ERROR: Disabling modified record ";\n' % indent) + outfile.write("%s print_regname(std::clog, this, this+1);\n" % indent) + outfile.write("%s std::clog << std::endl; \n" % indent) + outfile.write("%s return false; }\n" % indent) + for a in sorted(self.children(), key=lambda a: a.name): + if a.disabled(): continue + a = self.check_child_rewrite(a, args) + if a is None: continue + field_name = a.name + if field_name in args.cpp_reserved: + field_name += '_' + if not args.checked_array: + if a.count != (1,): + for index_num, idx in enumerate(a.count): + outfile.write("%sfor (int i%d = 0; i%d < %d; i%d++)\n" % + (indent, index_num, index_num, idx, index_num)) + indent += " " + outfile.write("%sif (%s" % (indent, field_name)) + if a.count != (1,): + for i in range(0, len(a.count)): + outfile.write("[i%d]" % i) + outfile.write(".disable()) rv = true;\n") + if a.count != (1,): + indent = indent[2*len(a.count):] + else: + outfile.write("%sif (%s.disable()) rv = true;\n" % (indent, field_name)) + outfile.write("%sif (rv) disabled_ = true;\n" % indent) + outfile.write("%sreturn rv;\n" % indent) + indent = indent[2:] + outfile.write("%s}\n" % indent) + + def gen_disable_if_reset_value_method(self, outfile, args, classname, indent): + outfile.write(indent) + if self.gen_method_declarator(outfile, args, "bool", classname, + "disable_if_reset_value", [], ""): + return + indent += " " + outfile.write("%sbool rv = true;\n" % indent) + for a in sorted(self.children(), key=lambda a: a.name): + if a.disabled(): continue + a = self.check_child_rewrite(a, args) + if a is None: continue + field_name = a.name + if field_name in args.cpp_reserved: + field_name += '_' + if not args.checked_array: + if a.count != (1,): + for index_num, idx in enumerate(a.count): + outfile.write("%sfor (int i%d = 0; i%d < %d; i%d++)\n" % + (indent, index_num, index_num, idx, index_num)) + indent += " " + outfile.write("%sif (!%s" % (indent, field_name)) + if a.count != (1,): + for i in range(0, len(a.count)): + outfile.write("[i%d]" % i) + outfile.write(".disable_if_reset_value()) rv = false;\n") + if a.count != (1,): + indent = indent[2*len(a.count):] + else: + outfile.write("%sif (!%s.disable_if_reset_value()) rv = false;\n" % + (indent, field_name)) + outfile.write("%sif (rv) disabled_ = true;\n" % indent) + outfile.write("%sreturn rv;\n" % indent) + indent = indent[2:] + outfile.write("%s}\n" % indent) + + def gen_disable_if_unmodified_method(self, outfile, args, classname, indent): + outfile.write(indent) + if self.gen_method_declarator(outfile, args, "bool", classname, + "disable_if_unmodified", [], ""): + return + indent += " " + outfile.write("%sbool rv = true;\n" % indent) + for a in sorted(self.children(), key=lambda a: a.name): + if a.disabled(): continue + a = self.check_child_rewrite(a, args) + if a is None: continue + field_name = a.name + if field_name in args.cpp_reserved: + field_name += '_' + if not args.checked_array: + if a.count != (1,): + for index_num, idx in enumerate(a.count): + outfile.write("%sfor (int i%d = 0; i%d < %d; i%d++)\n" % + (indent, index_num, index_num, idx, index_num)) + indent += " " + outfile.write("%sif (!%s" % (indent, field_name)) + if a.count != (1,): + for i in range(0, len(a.count)): + outfile.write("[i%d]" % i) + outfile.write(".disable_if_unmodified()) rv = false;\n") + if a.count != (1,): + indent = indent[2*len(a.count):] + else: + outfile.write("%sif (!%s.disable_if_unmodified()) rv = false;\n" % + (indent, field_name)) + outfile.write("%sif (rv) disabled_ = true;\n" % indent) + outfile.write("%sreturn rv;\n" % indent) + indent = indent[2:] + outfile.write("%s}\n" % indent) + + def gen_disable_if_zero_method(self, outfile, args, classname, indent): + outfile.write(indent) + if self.gen_method_declarator(outfile, args, "bool", classname, "disable_if_zero", [], ""): + return + indent += " " + outfile.write("%sbool rv = true;\n" % indent) + for a in sorted(self.children(), key=lambda a: a.name): + if a.disabled(): continue + a = self.check_child_rewrite(a, args) + if a is None: continue + field_name = a.name + if field_name in args.cpp_reserved: + field_name += '_' + if not args.checked_array: + if a.count != (1,): + for index_num, idx in enumerate(a.count): + outfile.write("%sfor (int i%d = 0; i%d < %d; i%d++)\n" % + (indent, index_num, index_num, idx, index_num)) + indent += " " + outfile.write("%sif (!%s" % (indent, field_name)) + if a.count != (1,): + for i in range(0, len(a.count)): + outfile.write("[i%d]" % i) + outfile.write(".disable_if_zero()) rv = false;\n") + if a.count != (1,): + indent = indent[2*len(a.count):] + else: + outfile.write("%sif (!%s.disable_if_zero()) rv = false;\n" % (indent, field_name)) + outfile.write("%sif (rv && modified()) {\n" % indent) + outfile.write('%s std::clog << "Disabling modified zero record ";\n' % indent) + outfile.write("%s print_regname(std::clog, this, this+1);\n" % indent) + outfile.write("%s std::clog << std::endl;\n" % indent) + outfile.write("%s rv = false; }\n" % indent) + outfile.write("%sif (rv) disabled_ = true;\n" % indent) + outfile.write("%sreturn rv;\n" % indent) + indent = indent[2:] + outfile.write("%s}\n" % indent) + + def gen_enable_method(self, outfile, args, classname, indent): + outfile.write(indent) + if self.gen_method_declarator(outfile, args, "void", classname, "enable", [], ""): + return + indent += " " + for a in sorted(self.children(), key=lambda a: a.name): + if a.disabled(): continue + a = self.check_child_rewrite(a, args) + if a is None: continue + field_name = a.name + if field_name in args.cpp_reserved: + field_name += '_' + if not args.checked_array: + if a.count != (1,): + for index_num, idx in enumerate(a.count): + outfile.write("%sfor (int i%d = 0; i%d < %d; i%d++)\n" % + (indent, index_num, index_num, idx, index_num)) + indent += " " + outfile.write("%s%s" % (indent, field_name)) + if a.count != (1,): + for i in range(0, len(a.count)): + outfile.write("[i%d]" % i) + outfile.write(".enable();\n") + if a.count != (1,): + indent = indent[2*len(a.count):] + else: + outfile.write("%s%s.enable();\n" % (indent, field_name)) + outfile.write("%sdisabled_ = false;\n" % indent) + indent = indent[2:] + outfile.write("%s}\n" % indent) + + def find_alias_arrays(self, args, classname): + self.alias_arrays = [] + potential_alias_arrays = {} + array_match = re.compile('^(\w+)_(\d+)$') + for el in self.children(): + el = self.check_child_rewrite(el, args) + if el is None: continue + m = array_match.match(el.name) + if m: + base = m.group(1) + idx = int(m.group(2)) + typ = el.type_name(args, classname, "_" + el.name) + if base in potential_alias_arrays: + pot = potential_alias_arrays[base] + if typ != pot['type']: + pot['ok'] = False + if idx > pot['max']: + pot['max'] = idx + pot['mask'] |= 2**idx + else: + potential_alias_arrays[m.group(1)] = { + "ok": True, "max": idx, "mask": 2**idx, "type": typ } + for base, pot in potential_alias_arrays.items(): + if pot['ok'] and pot['max'] > 0 and pot['mask'] == 2**(pot['max']+1) - 1: + self.alias_arrays.append( (base, pot['type'], pot['max'] + 1) ) + + def need_ctor(self): + if self.alias_arrays: + return True + for el in self.children(): + el = self.check_child_rewrite(el, args) + if el is None: continue + s = el.singleton_obj() + if s.is_field() and s.default and s.default != 0: + if type(s.default) is tuple: + for v in s.default: + if v != 0: + return True + else: + return True + return False + + def gen_ctor(self, outfile, args, namestr, indent): + outfile.write("%s%s() : " % (indent, namestr)) + first = True + if args.enable_disable: + outfile.write("disabled_(false)") + first = False + for el in sorted(self.children(), key=lambda a: a.name): + if el.disabled(): continue + el = self.check_child_rewrite(el, args) + if el is None: continue + s = el.singleton_obj() + if s.is_field() and s.default and s.default != 0: + if type(s.default) is tuple: + ok = True + for v in s.default: + if v != 0: + ok = False + break + if ok: continue + if first: + first = False + else: + outfile.write(", ") + outfile.write(el.name) + if el.name in args.cpp_reserved: + outfile.write('_') + if type(s.default) is tuple and len(s.default) > 1: + outfile.write("({ ") + for v in s.default: + outfile.write(str(v)+", ") + outfile.write("})") + else: + outfile.write('(%d)' % s.default) + if hasattr(self, 'alias_arrays'): + for alias in self.alias_arrays: + outfile.write(",\n%s %s({" % (indent, alias[0])) + for idx in range(0, alias[2]): + if idx > 0: + outfile.write(",") + outfile.write(" &this->%s_%d" % (alias[0], idx)) + outfile.write(" })") + outfile.write(' {}\n') + + def canon_name(self, name): + namestr = '' + nameargs = [] + format = False + islong = False + for ch in name: + if format: + if ch in string.digits: + continue + elif ch == 'l': + islong = True + continue + elif ch == 'd' or ch == 'i' or ch == 'u' or ch == 'x': + nameargs.append('long ' if islong else 'int ') + elif ch == 'e' or ch == 'f' or ch == 'g': + nameargs.append('double ' if islong else 'float ') + elif ch == 's': + nameargs.append('const char *') + else: + raise CsrException("unknown conversion '%%%s' in name\n" % ch) + format = False + elif ch in string.ascii_letters or ch in string.digits or ch == '_': + namestr += ch + elif ch == '.': + namestr += '_' + elif ch == '%': + format = True + islong = False + else: + raise CsrException("invalid character '%s' in name\n" % ch) + return namestr, nameargs + + def type_name(self, args, parent, name): + namestr, nameargs = self.canon_name(name) + # FIXME -- should be checking for global names in args.global? + classname = parent + if classname != '': + classname += '::' + classname += namestr + rv = 'struct ' + classname + if self.count != (1, ): + if args.checked_array: + for idx in self.count: + rv = "checked_array<%d, %s>" % (idx, rv) + else: + for idx in self.count: + rv = "%s[%d]" % (rv, idx) + return rv; + + def gen_type(self, outfile, args, schema, parent, name, indent): + namestr, nameargs = self.canon_name(name) + classname = parent + if classname != '': + classname += '::' + classname += namestr + if args.alias_array and not hasattr(self, 'alias_arrays'): + self.find_alias_arrays(args, classname) + if args.gen_decl != 'defn': + indent += " " + outfile.write("struct %s {\n" % namestr) + if args.enable_disable: + outfile.write("%sbool disabled_;\n" % indent) + outfile.write("%sbool disabled() const { return disabled_; }\n" % indent) + if args.enable_disable or self.need_ctor(): + self.gen_ctor(outfile, args, namestr, indent) + if self.top_level(): + outfile.write('%sstatic constexpr const char *_reg_version = "%s";\n' % + (indent, schema['_reg_version'])) + outfile.write('%sstatic constexpr const char *_schema_hash = "%s";\n' % + (indent, schema['_schema_hash'])) + for el in sorted(self.children(), key=lambda a: a.name): + if el.disabled(): continue + el = self.check_child_rewrite(el, args) + if el is None: continue + typ = el.singleton_obj() + notclass = typ.is_field() or typ.top_level() + isglobal = el.name in args.global_types + if args.gen_decl != 'defn': + if hasattr(el, 'description') and el.description: + format_comment(outfile, indent, el.description) + if typ != el and hasattr(typ, 'description') and typ.description: + format_comment(outfile, indent, typ.description) + outfile.write(indent) + if args.checked_array and notclass and el.count != (1,): + for idx in el.count: + outfile.write("checked_array<%d, " % idx) + eltypenamestr = el.name + if isglobal: + eltypenamestr = "::" + eltypenamestr + else: + eltypenamestr = "_" + eltypenamestr + if el.name == self.name: + # FIXME -- maybe should elide the element if it is the only one? + # sort of like singleton_obj but deal with arrays too + eltypenamestr = eltypenamestr + "_el" + typ.gen_type(outfile, args, schema, classname, eltypenamestr, indent) + if args.gen_decl != 'defn': + field_name = el.name + if field_name in args.cpp_reserved: + field_name += '_' + if args.checked_array and el.count != (1,): + if not notclass: + if not isglobal: + outfile.write(";\n%s" % indent) + for idx in el.count: + outfile.write("checked_array<%d, " % idx) + outfile.write(eltypenamestr) + if el.count != (1,): + for idx in el.count: + outfile.write(">") + outfile.write(" %s;\n" % field_name) + else: + outfile.write(" %s" % field_name) + if el.count != (1,): + for idx in el.count: + outfile.write("[%d]" % idx) + outfile.write(";\n") + if args.gen_decl != 'defn' and hasattr(self, 'alias_arrays'): + for alias in self.alias_arrays: + outfile.write("%salias_array<%d, %s> %s;\n" % (indent, + alias[2], alias[1], alias[0])) + if args.delete_copy and args.gen_decl != 'defn': + if not args.enable_disable and not self.need_ctor(): + outfile.write("%s%s() = default;\n" % (indent, namestr)) + outfile.write("%s%s(const %s &) = delete;\n" % (indent, namestr, namestr)) + outfile.write("%s%s(%s &&) = delete;\n" % (indent, namestr, namestr)) + if args.emit_json: + self.gen_emit_method(outfile, args, schema, classname, name, nameargs, indent) + if args.emit_binary: + self.gen_uint_conversion(outfile, args, classname, indent) + self.gen_emit_binary_method(outfile, args, classname, indent) + if args.input_binary: + self.gen_input_binary_method(outfile, args, classname, indent) + if args.binary_offset: + self.gen_binary_offset_method(outfile, args, classname, indent) + if args.emit_fieldname: + self.gen_fieldname_method(outfile, args, classname, indent) + if args.unpack_json: + self.gen_unpack_method(outfile, args, classname, indent) + if args.dump_unread: + self.gen_dump_unread_method(outfile, args, classname, indent) + if args.enable_disable: + self.gen_modified_method(outfile, args, classname, indent) + self.gen_set_modified_method(outfile, args, classname, indent) + self.gen_disable_method(outfile, args, classname, indent) + self.gen_disable_if_reset_value_method(outfile, args, classname, indent) + self.gen_disable_if_unmodified_method(outfile, args, classname, indent) + self.gen_disable_if_zero_method(outfile, args, classname, indent) + self.gen_enable_method(outfile, args, classname, indent) + if args.gen_decl != 'defn': + indent = indent[2:] + outfile.write("%s}" % indent) + + def gen_global_types(self, outfile, args, schema): + for a in sorted(self.children(), key=lambda a: a.name): + if a.disabled(): continue + if not a.is_field() and not a.top_level(): + a.gen_global_types(outfile, args, schema) + if a.name in args.global_types: + if a.name in args.global_types_generated: + if args.global_types_generated[a.name] != a: + raise CsrException("Inconsistent definition of type "+a.name) + else: + args.global_types_generated[a.name] = a + a.gen_type(outfile, args, schema, "", a.name, "") + outfile.write(";\n") + +class address_map(csr_composite_object): + """ + A Semifore addressmap. Contains registers and instances of other + addressmaps. + + In practice, the count of an address_map is always (1,) and it is the + instances of the addressmap that are actually arrays. + + @attr templatization_behavior + Controls how this address map gets used during template generation: + - If None, it is expanded as a dictionary wherever it appears in the + register hierarchy + - If "top_level", it is split off into its own JSON file and + replaced wherever it appears in the register hierarchy with a + string reference to that JSON file + - If "disabled", it is replaced wherever it appears in the register + hierarchy with a 0 (indicating "don't write"). No JSON file for + the address map is generated + @attr objs + An ordered list of objects contained in the addressmap - either regs, + groups, or address_map_instances + + @attr parent + A string indicating which parent of the chip hierarchy the addressmap + falls under ("memories" or "regs) + """ + def __init__(self, name, count, parent): + csr_composite_object.__init__(self, name, count) + + self.templatization_behavior = None + self.objs = [] + self.parent = parent + + def min_width(self, round_to_power_of_2=True): + """ + Some addressmap arrays have an explicit "stride" specifying how much + address space each element takes up. When they don't, we calculate the + stride by summing up the widths of all contained objects and rounding + to the next highest power of 2. + + Whether an addressmap has a stride or not is up to the programmer of + the original Semifore CSR and, as far as Walle is conserned, arbitrary. + """ + width = 0 + for obj in self.objs: + obj_end = obj.offset * 8 + if type(obj) is reg: + obj_end += obj.width * product(obj.count) + elif type(obj) is address_map_instance or type(obj) is group: + try: + multiplier = product(obj.count) * obj.stride + except: + multiplier = 1 + obj_end += obj.min_width() * multiplier + else: + raise CsrException("Unrecognized object in address map ('"+type(obj)+"')") + if obj_end > width: + width = obj_end + + width //= 8 + + if round_to_power_of_2: + # Round stride up to the next largest power of 2 + round_width = 1 + while round_width < width: + round_width *= 2 + return round_width + else: + return width + + def generate_binary(self, data, cache, path): + if data == 0: + # No-op + return {} + elif isinstance(data, basestring): + # Refernce to template + + type_name = self.parent + "." + self.name + + if data not in cache.templates: + raise CsrException("Could not find template with name '"+data+"'") + + if cache.get_type(data) != type_name: + raise CsrException("Expected type of instantiated object '"+data+"' to be '"+type_name+"', found '"+cache.get_type(data)+"'") + + return cache.get_data(data, path) + elif type(data) is dict: + # Actual data + reg_values = [] + for obj in self.objs: + if obj.name not in data: + raise CsrException("Could not find key '"+obj.name+"'") + if data[obj.name] != 0 and not isinstance(data[obj.name], basestring): + if obj.count == (1,): + if type(data[obj.name]) is not dict: + raise CsrException("Expected dictionary at key '"+obj.name+"'") + else: + # TODO: check all dimensions are the right size, maybe if a 'strict errors' flag is used + if type(data[obj.name]) is not list or len(data[obj.name]) != obj.count[0]: + array_size = "x".join(map(str,obj.count)) + raise CsrException("Expected "+array_size+" element array of dictionaries at key '"+obj.name+"'") + + if type(obj) is reg: + if obj.count == (1,): + chip_obj = obj.generate_binary(data[obj.name], cache, path) + reset_value = obj.get_reset_value() + + if chip_obj is not None and reset_value is not None: + # Check if a non-zero value to put into the binary file is the same as the reset (initial) value. + # (We will continue to write zero values, for caution's sake. + # Would block writes work if leave out subsection?) + # If the non-zero value is the reset value, do not output it in the binary file. + # We are having too many problems where the driver is clearing things (like interrupt enables) + # before the binary file is loaded, and then the binary file re-enables them. + if reset_value == chip_obj.orig_value: + # print "Skipping setting %s, because it has the same value (%s) as its reset value of %s." % (obj.name, str(chip_obj), hex(reset_value)) + continue + + if chip_obj != None: + reg_values.append(chip_obj) + elif data[obj.name] != 0: + # TODO: we should be able to DMA anything into the chip, + # so this count > 4 heuristic should work well + # + # but right now the model doesn't implement chip- + # side register addresses, so we have to force + # direct register writes for the regs part of + # the schema and DMA for the mem part. lame. + # use this count heuristic once the model is fixed. + # + # if product(obj.count) > 4: + root_parent = obj.parent + while type(root_parent) is not str: + root_parent = root_parent.parent + # Force the mapram_config register programming + # on the DMA block write path to avoid a race during + # chip init where the map ram is being written and the + # ECC mode is also being configured. Since the map ram + # is written with block writes, forcing this register + # configuration on the same path removes the race. + + registers_to_write_with_dma = [ "mapram_config", + "imem_dark_subword16", "imem_dark_subword32", "imem_dark_subword8", + "imem_mocha_subword16", "imem_mocha_subword32", "imem_mocha_subword8", + "imem_subword16", "imem_subword32", "imem_subword8", + "galois_field_matrix"] + if product(obj.count) > 4 and (root_parent=="memories" or obj.name in registers_to_write_with_dma): + mem = chip.dma_block(obj.offset, obj.width, src_key=obj.name, is_reg=root_parent=="regs") + def mem_loop(sub_data, context): + path[-1].path.append(context) + for idx in range(0, obj.count[-1]): + context[-1] = idx + obj.generate_binary(sub_data[idx], cache, path, mem) + path[-1].path.pop() + nd_array_loop(obj.count, data[obj.name], mem_loop) + reg_values.append(mem) + else: + offset = [0] + width = obj.width//8 #TODO: warn if not power of (8 or 32 or w/e)? + def reg_loop(sub_data, context): + path[-1].path.append(context) + for idx in range(0, obj.count[-1]): + context[-1] = idx + chip_obj = obj.generate_binary(sub_data[idx], cache, path) + if chip_obj != None: + chip_obj.add_offset(offset[0]) + reg_values.append(chip_obj) + offset[0] += width + path[-1].path.pop() + nd_array_loop(obj.count, data[obj.name], reg_loop) + + elif type(obj) is address_map_instance or type(obj) is group: + if obj.count == (1,): + sub_chip_objs = obj.generate_binary(data[obj.name], cache, path) + for sub_chip_obj in sub_chip_objs: + sub_chip_obj.add_offset(obj.offset) + reg_values.append(sub_chip_obj) + elif data[obj.name] != 0: + offset = [0] + def addr_map_loop(sub_data, context): + path[-1].path.append(context) + for idx in range(0, obj.count[-1]): + context[-1] = idx + sub_chip_objs = obj.generate_binary(sub_data[idx], cache, path) + for sub_chip_obj in sub_chip_objs: + sub_chip_obj.add_offset(obj.offset+offset[0]) + reg_values.append(sub_chip_obj) + offset[0] += obj.stride + path[-1].path.pop() + nd_array_loop(obj.count, data[obj.name], addr_map_loop) + else: + raise CsrException("Unrecognized object in address map ('"+type(obj)+"')") + + return reg_values + else: + raise CsrException( + "Expected dictionary at addressmap node '%s' but found value of type %s" % ( + self.name, type(data).__name__ + )) + + def generate_template(self, inject_size): + self_dict = {} + if self.templatization_behavior == "disabled": + return None + if self.templatization_behavior == "top_level": + self_dict["_type"] = self.parent + "." + self.name + self_dict["_name"] = "template("+self_dict["_type"]+")" + for obj in self.objs: + self_dict[obj.name] = obj.generate_template(inject_size) + return self.replicate(self_dict) + + def children(self): + return self.objs + def is_singleton(self): + return len(self.objs) == 1 and self.objs[0].count == (1,) + def disabled(self): + return self.templatization_behavior == "disabled" + def top_level(self): + return self.templatization_behavior == "top_level" + + def generate_cpp(self, outfile, args, schema): + try: + name = args.name + except AttributeError: + name = self.name + self.gen_type(outfile, args, schema, '', name, '') + all_used = True + for obj in args.rewrite: + if obj not in args.rewrite_used: + sys.stderr.write("Rewrite object %s not found\n" % obj) + all_used = False + else: + for child in args.rewrite[obj]: + if child not in args.rewrite_used[obj]: + sys.stderr.write("Rewrite child %s.%s not found\n" % (obj, child)) + all_used = False + if not all_used: + raise CsrException("Unused rewrite clauses in templates") + + def print_as_text(self, indent): + if self.templatization_behavior != "disabled": + print("%saddress_map %s%s:" % (indent, self.name, str(self.count))) + for ch in self.objs: + ch.print_as_text(indent+" ") + +class address_map_instance(csr_composite_object): + """ + TODO: docstring + @attr offset + offset from the start of the containing address_map (instance) + @attr map + address_map object that is an instance of + @attr stride + If @count is not (1,), this is the offset from each instance in the array to + the next. If @count is (1,) this should be null + """ + def __init__(self, name, count, offset, addrmap, stride): + csr_composite_object.__init__(self, name, count) + + self.offset = offset + self.map = addrmap + self.stride = stride + + def min_width(self): + return self.map.min_width() + + def generate_binary(self, data, cache, path): + path[-1].path.append(self.name) + binary = self.map.generate_binary(data, cache, path) + path[-1].path.pop() + return binary + + def generate_template(self, inject_size): + if self.map.templatization_behavior == "top_level": + return self.replicate(self.map.name+"_object") + elif self.map.templatization_behavior == "disabled": + return self.replicate(0) + else: + return self.replicate(self.map.generate_template(inject_size)) + + def children(self): + return self.map.objs + def is_singleton(self): + return len(self.map.objs) == 1 and self.map.objs[0].count == (1,) + def disabled(self): + return self.map.templatization_behavior == "disabled" + def top_level(self): + return self.map.templatization_behavior == "top_level" + def address_stride(self): + return self.stride + + def type_name(self, args, parent, name): + self.map.type_name(args, parent, name) + + def gen_type(self, outfile, args, schema, parent, name, indent): + if self.map.templatization_behavior == "disabled": + raise CsrException("disabled address_map hit in gen_type") + elif self.map.templatization_behavior == "top_level": + if args.gen_decl != 'defn': + tname = self.map.object_name + if tname is None: + tname = self.map.parent + '.' + self.map.name + outfile.write("register_reference" % self.canon_name(tname)[0]) + else: + self.map.gen_type(outfile, args, schema, parent, name, indent) + + def print_as_text(self, indent): + print("%saddress_map_instance %s%s: offset=0x%x%s" % ( + indent, self.name, str(self.count), self.offset, + " stride=0x%x" % self.stride if self.stride else "")) + if self.map.templatization_behavior == "top_level": + print("%s address_map %s%s: (top level %s)" % ( + indent, self.name, str(self.count), self.map.name)) + else: + self.map.print_as_text(indent+" ") + + +class group(address_map): + """ + TODO: docstring + @attr stride + If @count is not (1,) this the offset from each element to the next + If @count is (1,) this should be null + @attr offset + offset from the start of the containing addres_map + """ + def __init__(self, name, count, offset, parent, stride): + address_map.__init__(self, name, count, parent) + self.stride = stride + self.offset = offset + + def generate_binary(self, data, cache, path): + path[-1].path.append(self.name) + binary = address_map.generate_binary(self, data, cache, path) + path[-1].path.pop() + return binary + + def min_width(self): + """ + A group array's stride, unlike addressmap instance arrays, is not + rounded up to a power of two if it has to be calculated. + """ + if self.stride != None: + return self.stride + else: + return address_map.min_width(self, round_to_power_of_2=False) + + def address_stride(self): + return self.stride + + def print_as_text(self, indent): + print("%sgroup %s%s: offset=0x%x%s" % ( + indent, self.name, str(self.count), self.offset, + " stride=0x%x" % self.stride if self.stride else "")) + for ch in self.objs: + ch.print_as_text(indent+" ") + + +class reg(csr_composite_object): + """ + TODO: docstring + @attr parent + Containing address_map object + @attr offset + Offset from the start of the containing address_map_instance + @attr width + width in bits + @attr fields + vector of fields in the register + """ + def __init__(self, name, count, offset, width, parent): + csr_composite_object.__init__(self, name, count) + + self.parent = parent + self.offset = offset + self.width = width + self.fields = [] + + def __str__(self): + f = "(" + sep = "" + for x in self.fields: + f += sep + str(x) + sep = ", " + f += ")" + return "reg %s fields:%s" % (self.name, f) + + def get_reset_value(self): + rv = 0 + for f in self.fields: + rv |= (f.default[0] << f.lsb) + return rv + + def generate_binary(self, data, cache, path, mem=None): + if data == 0: + # No-op + return None + elif isinstance(data, basestring): + # Refernce to template + + path[-1].path.append(self.name) + + type_name = self.parent + "." + self.name + + if data not in cache.templates: + raise CsrException("Could not find template with name '"+data+"'") + + if cache.get_type(data) != type_name: + raise CsrException("Expected type of instantiated object '"+data+"' to be '"+type_name+"', found '"+cache.get_type(data)+"'") + + cached_data = cache.get_data(data, path) + path[-1].path.pop() + + if mem: + mem.add_word(cached_data) + else: + return cached_data + elif type(data) is dict: + path[-1].path.append(self.name) + + reg_value = [0] + # TODO: put field names in path histories + for field in self.fields: + + if field.name not in data: + raise CsrException("Could not find key '"+field.name+"'") + + width = field.msb-field.lsb+1 + if field.count == (1,): + value = data[field.name] + if type(value) is not int: + raise CsrException( + "Expected integer value for field '%s.%s' but found value of type %s" % ( + self.name, field.name, type(value).__name__ + )) + elif value < 0: + raise CsrException( + "Value for field '%s.%s' is negative (%i)" % ( + self.name, field.name, value + )) + elif value <= pow(2, width): + reg_value[0] |= value << field.lsb + else: + raise CsrException( + "Width of field '%s.%s' (%i bits) not large enough to hold value (%i)" % ( + self.name, field.name, width, value + )) + else: + offset = [0] + def field_loop(sub_data, context): + path[-1].path.append(context) + for idx in range(0, field.count[-1]): + context[-1] = idx + value = sub_data[idx] + if type(value) is not int: + raise CsrException( + "Expected integer value for field '%s.%s%s' but found value of type %s" % ( + self.name, field.name, array_str(context), type(value).__name__ + )) + elif value < 0: + raise CsrException( + "Value for field '%s.%s%s' is negative (%i)" % ( + self.name, field.name, array_str(context), value + )) + elif value <= pow(2, width): + reg_value[0] |= value << field.lsb + offset[0] + offset[0] += width + else: + raise CsrException( + "Width of field '%s.%s%s' (%i bits) not large enough to hold value (%i)" % ( + self.name, field.name, array_str(context), width, value + )) + path[-1].path.pop() + + # TODO: check all dimension sizes + if type(data[field.name]) is not list or len(data[field.name]) != field.count[0]: + array_size = "x".join(map(str,field.count)) + raise CsrException("Expected "+array_size+" element array of integers at key '"+field.name+"'") + + nd_array_loop(field.count, data[field.name], field_loop) + + path[-1].path.pop() + + if mem: + mem.add_word(reg_value[0]) + elif self.width <= 32: + return chip.direct_reg(self.offset, reg_value[0], src_key=self.name) + else: + return chip.indirect_reg(self.offset, reg_value[0], self.width, src_key=self.name) + else: + raise CsrException( + "Expected dictionary at register node '%s' but found value of type %s" % ( + self.name, type(data).__name__ + )) + + + def generate_template(self, inject_size): + self_dict = {} + for field in self.fields: + self_dict[field.name] = field.generate_template(inject_size) + return self.replicate(self_dict) + + def children(self): + return self.fields + def is_singleton(self): + return len(self.fields) == 1 and self.fields[0].count == (1,) + def singleton_obj(self): + if self.is_singleton() and self.fields[0].name == self.name: + return self.fields[0] + return self + def address_stride(self): + return self.width // 8 + + def disabled(self): + return False + def top_level(self): + return False + + def gen_word_expressions(self, args, prefix): + """ + generate expressions to calculate the value of each word of the register + """ + class context: + shift = 0 + words = [] + context.words = [None] * ((self.width + 31) // 32) + for a in self.fields: + field_name = a.name + if field_name in args.cpp_reserved: + field_name += '_' + if prefix: + if self.name == a.name and len(self.fields) == 1: + field_name = prefix + else: + field_name = prefix + "." + field_name + context.shift = a.lsb; + def emit_field_slice(field, word, shift): + if context.words[word] is None: + context.words[word] = '' + else: + context.words[word] += " + " + if shift != 0: + context.words[word] += "(" + context.words[word] += field + if shift > 0: + context.words[word] += " << %d)" % shift + elif shift < 0: + context.words[word] += " >> %d)" % -shift + def emit_ubits_field(index_list): + word = context.shift // 32 + shift = context.shift % 32 + name = field_name + array_str(index_list) + emit_field_slice(name, word, shift) + if shift + a.msb - a.lsb >= 32: + emit_field_slice(name, word+1, shift - 32) + if shift + a.msb - a.lsb >= 64: + emit_field_slice(name, word+2, shift - 64) + context.shift = context.shift + a.msb - a.lsb + 1 + def emit_widereg_field(index_list): + word = context.shift // 32 + shift = context.shift % 32 + name = field_name + array_str(index_list) + ".value.getrange(" + emit_field_slice(name + "0, %d)" % (32 - shift), word, shift) + shift = 32 - shift + while shift < a.msb - a.lsb + 1: + word += 1 + emit_field_slice(name + "%d, 32)" % shift, word, 0) + shift += 32 + if a.count != (1,): + if a.msb - a.lsb + 1 > 64: + count_array_loop(a.count, emit_widereg_field) + else: + count_array_loop(a.count, emit_ubits_field) + else: + if a.msb - a.lsb + 1 > 64: + emit_widereg_field(None) + else: + emit_ubits_field(None) + return context.words + + def gen_uint_conversion(self, outfile, args, classname, indent): + if self.width > 32: + return + outfile.write(indent) + if self.gen_method_declarator(outfile, args, "", classname, "operator uint32_t", + [], "const"): + return + outfile.write("%s return " % indent); + outfile.write("%s;\n" % self.gen_word_expressions(args, None)[0]) + outfile.write("%s}\n" % indent) + + def gen_emit_binary_method(self, outfile, args, classname, indent): + outfile.write(indent) + if self.gen_method_declarator(outfile, args, "void", classname, "emit_binary", + ["std::ostream &out", "uint64_t a"], "const"): + return + indent += " " + if self.count != (1,): + pass + indirect = ((self.parent.parent=="memories") or (self.name in args.write_dma)) + if not indirect: + outfile.write("%sif (!disabled_) {\n" % indent); + indent += " " + pairs = enumerate(self.gen_word_expressions(args, None)) + if not indirect and args.reverse_write: + # DANGER -- certain registers must be written in reverse order (higher + # address then lower), so we reverse the order of register writes here. + # block writes must be in order (lowest to highest) as they are a block + pairs = reversed(list(pairs)) + for idx, val in pairs: + if val is None: + val = '0' + outfile.write("%sout << " % indent); + if not indirect: + outfile.write("binout::tag('R') << binout::byte4(a + %d)\n" % (idx*4)) + outfile.write("%s << " % indent) + outfile.write("binout::byte4(%s);\n" % val) + if not indirect: + indent = indent[2:] + outfile.write("%s}\n" % indent) + indent = indent[2:] + outfile.write("%s}\n" % indent) + + def gen_input_binary_method(self, outfile, args, classname, indent): + outfile.write(indent) + if self.gen_method_declarator(outfile, args, "void", classname, "input_binary", + ["uint64_t a", "char t", "uint32_t *d", "size_t l"], ""): + return + indent += ' ' + words = (self.width + 31) // 32 + indirect = self.parent.parent == "memories" or (self.name in args.write_dma) or words == 1 + # words == 1 is not really indirect, but we don't need to figure out which word is + # being written, so we can use the simpler code + zero_default = True + for a in self.fields: + if isinstance(a.default, tuple): + if reduce(ior, a.default, 0) != 0: + zero_default = False + break + elif a.default is None or a.default != 0: + zero_default = False + break + if indirect: + outfile.write('%sBUG_CHECK(l == %d, "expecting %d words, got %%zd in %s", l);\n' % + (indent, words, words, self.name)) + if zero_default: + outfile.write('%sif ((d[0]' % indent) + for i in range(1,words): + outfile.write('|d[%d]' % i) + outfile.write(') == 0) return;\n') + else: + outfile.write('%sBUG_CHECK(t == \'R\' && l == 1, "expecting direct in %s");\n' % + (indent, self.name)) + if zero_default: + outfile.write('%sif (d[0] == 0) return;\n' % indent) + outfile.write('%sa /= 4;\n' % indent) + for a in self.fields: + field_name = a.name + if field_name in args.cpp_reserved: + field_name += '_' + lsb = a.lsb + size = a.msb - a.lsb + 1 + def input_ubits_field(index_list): + nonlocal lsb + outfile.write(indent) + if indirect: + word = lsb//32 + aop = '=' + else: + outfile.write('if (a == %d) ' % (lsb//32)) + word = 0 + aop = '|=' + outfile.write('%s%s %s ' % (field_name, array_str(index_list), aop)) + if lsb%32 + size < 32: + outfile.write('(d[%d] >> %d) & 0x%x;\n' % (word, + lsb%32, (1 << size) - 1)) + elif lsb%32 + size == 32: + outfile.write('d[%d] >> %d;\n' % (word, lsb%32)) + else: + outfile.write('(d[%d] >> %d)' % (word, lsb%32)) + if indirect: + outfile.write(' | ') + else: + outfile.write(';\n') + msb = lsb+size-1 + for i in range(lsb//32 + 1, msb//32): + if indirect: + outfile.write('((uint64_t)d[%d] << %d) | ' % (i, i*32 - lsb)) + else: + outfile.write('%sif (a == %d) %s%s |= (uint64_t)d[0] << %d;\n' % + (indent, i, field_name, array_str(index_list), i*32 - lsb)) + if indirect: + outfile.write('(((uint64_t)d[%d] & 0x%x) << %d);\n' % (msb//32, + (1 << (msb%32 + 1)) - 1, msb//32*32 - lsb)) + else: + outfile.write('%sif (a == %d) %s%s |= ((uint64_t)d[0] & 0x%x) << %d;\n' % + (indent, msb//32, field_name, array_str(index_list), + (1 << (msb%32 + 1)) - 1, msb//32*32 - lsb)) + lsb += size + def input_widereg_field(index_list): + nonlocal lsb + outfile.write('%sBUG("widereg input not implemented");\n' % indent) + lsb += size + if a.count != (1,): + if a.msb - a.lsb + 1 > 64: + count_array_loop(a.count, input_widereg_field) + else: + count_array_loop(a.count, input_ubits_field) + else: + if a.msb - a.lsb + 1 > 64: + input_widereg_field(None) + else: + input_ubits_field(None) + + indent = indent[2:] + outfile.write('%s}\n' % indent) + + def gen_binary_offset_method(self, outfile, args, classname, indent): + outfile.write(indent) + if self.gen_method_declarator(outfile, args, "uint64_t", classname, "binary_offset", + ["const void *addr", ("int *bit_offset", "0")], "const"): + return + indent += " " + outfile.write("%sif (bit_offset) {" %indent) + indent += " " + outfile.write("%s/* TDB */\n" % indent) + indent = indent[2:] + outfile.write("%s}\n" % indent) + outfile.write("%sreturn 0;\n" % indent) + indent = indent[2:] + outfile.write("%s}\n" % indent) + + def print_as_text(self, indent): + print("%sreg %s%s: offset=0x%x width=%d" % ( + indent, self.name, str(self.count), self.offset, self.width)) + for ch in self.fields: + ch.print_as_text(indent+" ") + +class scanset_reg(reg): + """ + A register that needs to be written multiple times (same address) to hold an array + @attr parent + Containing address_map object + @attr offset + Offset from the start of the containing address_map_instance + @attr sel_offset + offset from the start of the containing address_map_instance for the selector reg + @attr width + width in bits + @attr fields + vector of fields in the register + """ + def __init__(self, name, count, offset, width, parent, fields): + reg.__init__(self, name, count, offset, width, parent) + if isinstance(fields, list): + self.fields = fields + else: + self.fields = [fields] + + def __str__(self): + f = "(" + sep = "" + for x in self.fields: + f += sep + str(x) + sep = ", " + f += ")" + return "scanset %s%s fields:%s" % (self.name, str(self.count), f) + + + def output_binary(self, outfile, args, indent, address_unit, width_unit): + #import pdb; pdb.set_trace() + name = self.name + if name in args.cpp_reserved: + name += '_' + if self.count == (1,): + raise CsrException("invalid count in scanset_reg") + if args.enable_disable: + outfile.write("%sif (!%s.disabled()) {\n" % (indent, name)) + indent += ' ' + if not hasattr(self, 'sel_offset'): + if args.enable_disable: + outfile.write("%sif (!%s.disabled()) {\n" % (indent, name)) + indent += ' ' + outfile.write("%sout << binout::tag('S') << binout::byte8(0)" % indent + + " << binout::byte4(0)\n%s " % indent + + " << binout::byte8(a + 0x%x)" % (self.offset//address_unit) + + " << binout::byte4(32) << binout::byte4(%d);\n" % + (product(self.count) * self.width // width_unit)) + for idx_num, idx in enumerate(self.count): + outfile.write('%sfor (int j%d = 0; j%d < %d; j%d++) { \n' % + (indent, idx_num, idx_num, idx, idx_num)) + name = name + "[j%d]" % idx_num + if hasattr(self, 'sel_offset') and idx_num == 0: + if args.enable_disable: + outfile.write("%sif (!%s.disabled()) {\n" % (indent, name)) + indent += ' ' + outfile.write("%sout << binout::tag('S') << binout::byte8" % indent + + "(a + 0x%x)" % (self.sel_offset//address_unit) + + " << binout::byte4(j0)\n%s " % indent + + " << binout::byte8(a + 0x%x)" % (self.offset//address_unit) + + " << binout::byte4(32) << binout::byte4(%d);\n" % + (product(self.count[1:]) * self.width // width_unit)) + indent += ' ' + pairs = enumerate(self.gen_word_expressions(args, name)) + for idx, val in pairs: + if val is None: + val = '0' + outfile.write("%sout << binout::byte4(%s);\n" % (indent, val)) + for i in range(0, len(self.count) + (2 if args.enable_disable else 0)): + indent = indent[2:] + outfile.write("%s}\n" % indent) + + def input_binary(self, outfile, args, indent, address_unit, width_unit): + raise CsrException("scanset_reg.input_binary not implemented") + + +class field(csr_object): + """ + TODO: docstring + @attr default + default (reset-init) value + @attr parent + containing register object + @attr msb, lsb + Range of bits in containing register for this field. If @count is not (1,), this + is just the first element; the second will be at lsb = msb+1 etc + """ + def __init__(self, name, count, msb, lsb, default, parent): + csr_object.__init__(self, name, count) + + self.default = default + self.parent = parent + self.msb = msb + self.lsb = lsb + + def __str__(self): + return "%s[%d:%d]" % (self.name, self.msb, self.lsb) + + def generate_template(self, inject_size): + if inject_size: + return self.replicate(self.msb-self.lsb+1) + else: + if self.count == (1,): + return self.default[0] + else: + return self.default + + def is_field(self): + return True + def disabled(self): + return False + def top_level(self): + return False + def type_name(self, args, parent, name): + size = self.msb-self.lsb+1 + if size > 64: + rv = "widereg<%d>" % size + else: + rv = "ubits<%d>" % size + if self.count != (1, ): + if args.checked_array: + for idx in self.count: + rv = "checked_array<%d, %s>" % (idx, rv) + else: + for idx in self.count: + rv = "%s[%d]" % (rv, idx) + return rv + + def gen_type(self, outfile, args, schema, parent, name, indent): + size = self.msb-self.lsb+1 + if args.gen_decl != 'defn': + if size > 64: + outfile.write("widereg<%d>" % size) + else: + outfile.write("ubits<%d>" % size) + + def print_as_text(self, indent): + print("%sfield %s%s: [%d:%d]%s" % ( + indent, self.name, str(self.count), self.msb, self.lsb, + " default=" + str(self.default) if self.default else "")) + + +######################################################################## +## Utility functions + +def parse_resets(reset_str): + """ + Turn a reset value from a Semifore CSV string into a tuple of ints + + Semifore CSV formats most reset values as hex integers of the from 0x___ + Arrays of fields, however, result in comma-separated lists: + [0x__, 0x__, ...] + + If the array is 1D this function will still output the size as a 1-element + tuple, just for consistency of iterability. + """ + reset_strs = reset_str.replace("[","").replace("]","").split(",") + resets = [int(x,0) for x in reset_strs] + return tuple(resets) + +def parse_array_size(size_str): + """ + Turn an array size from a Semifore CSV string into a tuple of ints + + Semifore CSV formats the size of an array as an int in square brackets. + Multidimensional arrays are just a lot of these concatenated together: + [i] + [i][j][k] + ... + + If the array is 1D this function will still output the size as a 1-element + tuple, just for consistency of iterability. + """ + size_strs = size_str.replace("]","").split("[")[1:] + sizes = list(map(int, size_strs)) + if len(sizes) > 0: + return tuple(sizes) + else: + return (1,) + +def parse_csrcompiler_csv (filename, section_name): + """ + Given a Semifore CSV file, parse it into a bunch of csr_object instances. + Since the chip hierarchy is contained across multiple CSV files, each one + has a unique "section name". + + @param filename The filename of the CSV file to parse + @param section_name A string meaningfully describing the contents of + the CSV (eg, "memories" and "regs") + @return A list of all addressmaps parsed out of the file. + """ + + csv_field_types = { + "configuration", + "userdefined configuration", + "constant", + "counter", + "status", + "hierarchicalInterrupt", + "interrupt" + } + + csv_addressmap_types = { + "addressmap", + "userdefined addressmap", + } + + csv_register_types = { + "register", + "wide register", + "userdefined register", + "userdefined wide register", + } + + csv_group_types = { + "group", + "userdefined group", + } + + addr_maps = {} + active_addr_map = None + active_group = [] + active_reg = None + active_reg_default = 0 + + with open(filename, "rt", encoding='utf-8', errors='ignore') as csv_file: + csv_reader = csv.DictReader(csv_file) + row_num = 0 + for row in csv_reader: + array_size = parse_array_size(row["Array"]) + + active_object = None + if len(active_group) > 0: + active_container = active_group[-1] + else: + active_container = active_addr_map + + if row["Type"] in csv_addressmap_types: + addr_maps[row["Identifier"]] = address_map( + row["Identifier"], + array_size, + section_name + ) + active_addr_map = addr_maps[row["Identifier"]] + elif row["Type"] in csv_register_types: + reg_width = int(row["Register Size"].replace(" bits",""),0) + active_container.objs.append(reg(row["Identifier"], array_size, int(row["Offset"],0), reg_width, active_addr_map)) + active_reg = active_container.objs[-1] + active_object = active_reg + if row["Reset Value"] == "": + active_reg_default = 0 + else: + active_reg_default = int(row["Reset Value"],0) + elif row["Type"] in csv_field_types: + if len(array_size) > 1: + raise CsrException("Multi-dimensional field arrays not currently supported (in CSV file '"+filename+"' line "+str(row_num)+")") + range_tokens = row["Position"].replace("[","").replace("]","").split(":") + msb = int(range_tokens[0]) + if len(range_tokens) == 1: + lsb = msb + else: + lsb = int(range_tokens[1]) + if row["Reset Value"] == "": + default = [] + elem_width = msb-lsb+1 + elem_mask = 2**elem_width - 1 + for elem_idx in range(array_size[0]): + default_offset = lsb + elem_width*elem_idx + default_val = (active_reg_default >> default_offset) & elem_mask + default.append(default_val) + default = tuple(default) + else: + default = parse_resets(row["Reset Value"]) + if array_size != (1,): + if len(default) == 1: + default = default*array_size[0] + elif len(default) != array_size[0]: + raise CsrException("Field reset value list is not the same length as the field array itself (in CSV file '"+filename+"' line "+str(row_num)+")") + + active_reg.fields.append(field(row["Identifier"], array_size, msb, lsb, default, active_reg)) + active_object = active_reg.fields[-1] + elif row["Type"] == "addressmap instance": + try: + stride = int(row["Stride"].replace(" bytes",""),0) + except: + stride = addr_maps[row["Type Name"]].min_width() + + active_container.objs.append( + address_map_instance( + row["Identifier"], + array_size, + int(row["Offset"],0), + addr_maps[row["Type Name"]], + None if array_size == (1,) else stride + ) + ) + elif row["Type"] in csv_group_types: + try: + stride = int(row["Stride"].replace(" bytes",""),0) + except: + stride = None + + active_container.objs.append( + group ( + row["Identifier"], + array_size, + int(row["Offset"],0), + section_name, + None if array_size == (1,) else stride + ) + ) + active_group.append(active_container.objs[-1]) + active_object = active_group[-1] + elif row["Type"] == "endgroup": + popped_group = active_group.pop() + if popped_group.stride == None: + popped_group.stride = popped_group.min_width() + elif row["Type"] == "userdefined memory": + # ignore for now? + pass + elif row["Type"] == "reserved": + # ignore for now? + pass + elif row["Type"] == "unknown": + # ignore for now? + pass + else: + raise CsrException("Unrecognized type '"+row["Type"]+"' in CSV file '"+filename+"' line "+str(row_num)) + + if "Description" in row and row["Description"] and active_object: + active_object.description = row["Description"] + + row_num += 1 + + return addr_maps + + +def build_schema (dir, walle_version): + """ + Build a chip schema based on the top-level CSV files from Semifore + + The schema is a dictionary of dictionaries. The top-level keys are the + "sections" of the chip's interface and metadata: + - memories: Memories and large register arrays. Things like the parser + TCAM are found here. Taken from the _mem Semifore + hierarchy, in byte-granularity chip addresses + - regs: Registers, like statistics counters and MAU crossbars. + Taken from the Semifore hierarchy, in 32-bit PCIe + addresses + - _schema_hash: An MD5 hash of the CSV file contents used to generate + the rest of the schema + + The non-metadata entries contain a dictionary of all of that hierarchy's + addressmaps, mapping from addressmap name to addrses_map objects. + + @param dir A string pointing to the directory containing (a copy of) the + bfnregs repo subdir "modules/_reg" generated by Semifore + using csr_config.css + @return A new schema object + """ + new_schema = {} + schema_hash = 0 + hasher = hashlib.md5() + + version_file = os.path.join(dir, "..", "..", "VERSION") + csv_files = os.path.join(dir, "module", "csv") + if not os.path.isdir(csv_files): + csv_files = dir + + if not os.path.isfile(version_file) or not os.path.isdir(csv_files): + raise Exception("Directory '"+os.path.abspath(dir)+"' could not be opened, "+ + "does not exist, or does not appear to be a valid bfnregs "+ + "chip module.") + + for filename in os.listdir(csv_files): + if filename.endswith(".csv"): + key = os.path.splitext(filename)[0] + if key == "pipe_top_level": + key = "memories" + elif key == "tofino": + key = "regs" + elif key.endswith("_mem"): + key = "memories" + elif key.endswith("_reg"): + key = "regs" + filename = os.path.join(csv_files, filename) + + new_schema[key] = parse_csrcompiler_csv(filename, key) + + with open(filename, "rb") as csv_file: + hasher.update(csv_file.read()) + + if len(new_schema) == 0: + raise Exception("No csv files found under '" + os.path.abspath(csv_files) + "'"); + + with open(version_file, "r") as version_file_handle: + reg_version = version_file_handle.read() + hasher.update(reg_version.encode('utf-8')) + + new_schema["_reg_version"] = reg_version + new_schema["_walle_version"] = walle_version + new_schema["_schema_hash"] = hasher.hexdigest() + + return new_schema + +# Unit tests +if __name__ == "__main__": + y = reg("bar", (1,), 0, 32, None) + y.fields.append(field("y1", (1,), 7, 0, y)) + y.fields.append(field("y2", (1,), 15, 8, y)) + y.fields.append(field("y3", (1,), 23, 16, y)) + y.fields.append(field("y4", (1,), 31, 24, y)) + data={ + "y1" : 0x30, + "y2" : 0x32, + "y3" : 0x34, + "y4" : 0x36, + } + z = y.generate_binary(data, None, [traversal_history("root")]) + if z.value != "0246": + print("ERROR: Expected 32-bit object to have string value '6420'") + print(" 32 bit value was " + z.value) + + y = reg("baz", (1,), 0, 40, None) + y.fields.append(field("y1", (1,), 7, 0, y)) + y.fields.append(field("y2", (1,), 15, 8, y)) + y.fields.append(field("y3", (1,), 23, 16, y)) + y.fields.append(field("y4", (1,), 31, 24, y)) + y.fields.append(field("y5", (1,), 39, 32, y)) + data={ + "y1" : 0x30, + "y2" : 0x32, + "y3" : 0x34, + "y4" : 0x36, + "y5" : 0x38, + } + z = y.generate_binary(data, None, [traversal_history("root")]) + if z.value != "02468": + print("Expected 40-bit field to have string value '86420'") + print(" 40 bit value was " + z.value) diff --git a/backends/tofino/bf-asm/walle/walle.py b/backends/tofino/bf-asm/walle/walle.py new file mode 100755 index 00000000000..0f32d339e0e --- /dev/null +++ b/backends/tofino/bf-asm/walle/walle.py @@ -0,0 +1,711 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2024 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# +# SPDX-License-Identifier: Apache-2.0 +""" +Walle - JSON-to-binary cruncher tool +See README.md for usage instructions + +The code is organized into three main modules: + - walle: Command-line interface and glue code + - csr: Code dealing with compiler-facing JSON files and raw Semifore CSV + files + - chip: Code dealing with driver-facing binary config files + +The main program flow is, on a first run of Walle: + - The csr module is used to parse Semifore CSV files into the classes + that inherit from csr_object, each of which being a Python representation + of a Semifore object. + - These objects are pickled into a file called "chip.schema" so the raw CSV + does not have to be used again or distributed with the toolchain. + +Thereafter, Walle operates on JSON files that mirror the structure of the +Semifore hierarchy and assign integer values to register fields from the +schema. The details of this format are specified in the README.md fileself. + - To generate blank JSON, the csr module will recursively call the + generate_template() methods of the csr_objects in the schema. + - To crunch JSON into binary, the csr module will recursively call + generate_binary() methods of the csr_objects in the schema, passing + along the relevent tree of JSON data. These methods create a flat list of + objects that represent driver write operations, all of which are classes + from the chip module that inherit from chip_obj. + - The flat list of chip objects is looped over, calling each one's bytes() + method which returns the actual binary string to be passed to the driver. + These bytes are concatenated onto the binary file being output. + The address of this write may be manipulated, since Semifore addresses + are auto-generated and may need to be operated on before they appear as + the chip expects (for instance, chip memories are word-addressed while + Semifore addresses are byte-addressed) + +It's important to note that all addresses calculated within one JSON file are +relative, so to produce correct chip addresses the binary __must__ be +calculated starting at a top-level addressmap in the Semifore hierarchy. When +expanding a JSON config to contain data instead of references to other JSON +files, Walle will alter the addresses calculated for the _included_ JSON +to be relative to the addresses in the _including_ JSON. +""" +import argparse +import sys +import os +import subprocess + +import pickle +import json +import yaml +import copy + +import csr +import chip + +__version__ = '0.4.13' + +######################################################################## +## Utility functions + +class CsrUnpickler(pickle.Unpickler): + """ + This module is a hacky fix for a bug that sometimes shows up when using a + chip.schema file generated across different systems. + + Specifically: + On system A, walle is a globally installed package via setup.py and can + be accessed from the terminal with the command 'walle' + On system B, walle is NOT globally installed and instead accessed locally + by directly pointing to walle.py + + The chip.schema files generated on A and B will encode Python classes + from two different module paths. A will have classes from "walle.csr" while + B will have classes from "csr". If we move a schema from one system to + another, the module lookup will fail. + + We fix this by looking for references to classes from the 'csr' module and + directly retrieving them from the csr module that this top-level script has + already imported. + """ + def find_class(self, module, name): + if module == "csr" or module[-4:] == ".csr": + return getattr(csr,name) + else: + return pickle.Unpickler.find_class(self, module, name) + +def annotate_names (obj, threshold, path=""): + if type(obj) is list: + if threshold > 0 and len(obj) > threshold: + for idx, elem in enumerate(obj): + if type(elem) is dict: + elem["_absolute_name"] = path+"_"+str(idx) + annotate_names(elem, threshold, path) + else: + for elem in obj: + annotate_names(elem, threshold, path) + elif type(obj) is dict: + for key, elem in list(obj.items()): + annotate_names(elem, threshold, (path+"_" if len(path)>0 else "")+key) + +def print_schema_info (schema_file, schema): + hierarchies = [] + sys.stdout.write("file: "+schema_file+"\n") + for key in schema: + if key[0] == "_": + sys.stdout.write(key[1:]+": "+str(schema[key])+"\n") + else: + hierarchies.append(key) + sys.stdout.write("hierarchies: "+", ".join(hierarchies)+"\n") + +def parse_template_args(args, params): + """ + Extend argparse.Namespace with additional arguments for cpp generation + from templates.yaml that may not exist as command line arguments + FIXME -- should be a way to do this with ArgParse? + """ + def bool_arg(args, attr, val): + if not type(val) is bool: + raise Exception("Attribute "+attr+" requires bool argument, got "+str(val)) + setattr(args, attr, val) + def str_arg(args, attr, val): + if not type(val) is str: + raise Exception("Attribute "+attr+" requires string argument, got "+str(val)) + setattr(args, attr, val) + def add_list_arg(args, attr, val): getattr(args, attr).append(val) + def add_set_arg(args, attr, val): getattr(args, attr).add(val) + def set_decl(args, attr, val): args.gen_decl = 'decl' + def set_defn(args, attr, val): args.gen_decl = 'defn' + def no_arg(args, attr, val): pass + + options = { + 'alias_array': (True, bool_arg), + 'binary_offset': (False, bool_arg), + 'checked_array': (True, bool_arg), + 'decl': (None, set_decl), + 'delete_copy': (False, bool_arg), + 'defn': (None, set_defn), + 'dump_unread': (False, bool_arg), + 'emit_binary': (False, bool_arg), + 'emit_fieldname': (False, bool_arg), + 'emit_json': (False, bool_arg), + 'enable_disable': (False, bool_arg), + 'expand_disabled_vector': (False, bool_arg), + 'gen_decl': ('both', str_arg), + 'global_types': (set(), add_set_arg), + 'global': (None, lambda args, attr, val: add_set_arg(args, 'global_types', val)), + 'include': ([], add_list_arg), + 'input_binary': (False, bool_arg), + 'name': (None, str_arg), + 'namespace': (False, str_arg), + 'reverse_write': (False, bool_arg), + 'rewrite': ({}, no_arg), + 'rewrite_used': ({}, no_arg), + 'unpack_json': (False, bool_arg), + 'widereg': (False, bool_arg), + 'write_dma': (set(), add_set_arg) + } + + if not hasattr(args, 'cpp_reserved'): + args.cpp_reserved = set([ + "and", "asm", "auto", "break", "case", "catch", "char", "class", "const", "continue", + "default", "delete", "do", "double", "else", "enum", "extern", "float", "for", + "friend", "goto", "if", "inline", "int", "long", "new", "not", "or", "operator", + "private", "protected", "public", "register", "return", "short", "signed", "sizeof", + "static", "struct", "switch", "template", "this", "throw", "try", "typedef", "union", + "unsigned", "virtual", "void", "volatile", "while", "xor" ]) + for opt in options: + if options[opt][0] is not None: + if hasattr(args, opt): + setattr(args, opt, copy.copy(getattr(args, opt))) + else: + setattr(args, opt, copy.copy(options[opt][0])) + for p in params: + s = p.split('=', 1) + if p in options: + options[p][1](args, p, True) + elif p[0] == '-' and p[1:] in options: + options[p[1:]][1](args, p[1:], False) + elif s[0] in options: + options[s[0]][1](args, s[0], s[1]) + elif p[:2] == "-I": + args.include.append(p[2:]) + else: + sys.stderr.write("Unknown parameter %s\n" % str(p)); + + if args.enable_disable: + args.cpp_reserved = args.cpp_reserved.copy() + args.cpp_reserved.update(["disable", "disabled", "disable_if_unmodified", + "disable_if_zero", "enable", "modified", "set_modified"]) + +def read_template_file(template_file, args, schema): + with open(template_file, "rb") as template_objects_file: + templatization_cfg = yaml.load(template_objects_file, Loader=yaml.SafeLoader) + top_level_objs = templatization_cfg["generate"] + disabled_objs = templatization_cfg["ignore"] + if "global" in templatization_cfg: + parse_template_args(args, templatization_cfg["global"]) + for section_name, section in list(schema.items()): + if section_name not in top_level_objs: + if section_name[0] != "_": + sys.stderr.write("no template cfg for "+section_name+", ignoring\n"); + continue; + for obj in top_level_objs[section_name]: + section[obj].templatization_behavior = "top_level" + section[obj].object_name = None + if top_level_objs[section_name][obj] is None: continue + for fname, params in list(top_level_objs[section_name][obj].items()): + for p in params: + if p[:5] == 'name=': + section[obj].object_name = p[5:] + break + for obj in disabled_objs[section_name]: + if section[obj].templatization_behavior != None: + raise Exception(obj+" cannot be both templatized and ignored") + section[obj].templatization_behavior = "disabled" + return top_level_objs + +def generate_templates (args, schema): + if args.o == None: + args.o = "templates" + if not os.path.exists(args.o): + os.makedirs(args.o) + + top_level_objs = read_template_file(args.generate_templates, args, schema) + for section_name, section in list(schema.items()): + if section_name not in top_level_objs: + continue; + for top_level_obj in top_level_objs[section_name]: + template = section[top_level_obj].generate_template(False) + sizes = section[top_level_obj].generate_template(True) + + if args.template_indices != None: + annotate_names(template, args.template_indices) + annotate_names(sizes, args.template_indices) + + # Copy in schema metadata + schema_metadata = [key for key in list(schema.keys()) if key[0]=="_"] + for metadata in schema_metadata: + template[metadata] = schema[metadata] + sizes[metadata] = schema[metadata] + template["_section"] = section_name + sizes["_section"] = section_name + + cfg_name = section_name+"."+top_level_obj+".cfg.json" + with open(os.path.join(args.o, cfg_name), "wb") as outfile: + json.dump(template, outfile, indent=4, sort_keys=True) + size_name = section_name+"."+top_level_obj+".size.json" + with open(os.path.join(args.o, size_name), "wb") as outfile: + json.dump(sizes, outfile, indent=4, sort_keys=True) + + +def arbitrary_ASCII_text_to_52digit_decimal_hash(input): + import hashlib + # 52 characters left in 63 after the prefix "IDENTIFIER_", + # and math.log2(10**52) => 172.74026093414284, + # and math.log2(10**52)/8 => 21.592532616767855, + # so going to request 22 bytes of hash digest. + + # the next line of commented-out code is _fantastic_ in/on Python 3.8.10, + # but fails in/on Python 3.5.2 [as present in/on the Jarvis image on my old BXDSW VM as of Sept. 7 2022 1:40am NY time] + ### hash_digest_as_bytes = hashlib.shake_256( bytes(input, "ASCII") ).digest(22) + hash_digest_as_bytes = hashlib.sha224( bytes(input, "ASCII") ).digest() + # sha224 => 28 bytes of digest, the closest match that is >= 22 bytes and available in/on Python 3.5.2 + + hash_digest_as_int = int.from_bytes(hash_digest_as_bytes, "big") + return ("%052d" % hash_digest_as_int)[:52] + + + +def arbitrary_text_to_valid_C_identifier(input_iterable_of_characters, dry_run_to_get_hash_input = False): + """Takes a single input, which must be an iterable of characters for correct behavior to be + promised. When given valid input, returns a string that is a valid C and C++ identifier, + regardless of what characters are used in the input. + + _Intentionally_ *not* considering [ASCII] underscores as OK to copy untranslated as-is, + since _both_ leading underscores _and_ 2-or-more underscores in a row are considered as + ''reserved'' by the ISO C++ standard [and probably also by the ISO C standard]. + + _Only_ ASCII alphanumerics are ''OK as is''. + + Quoting : + + "The C standard requires only that the first 63 be significant" + + In other words, the first 63 characters are definitely going to be "paid attention to", + and the rest may be handled as "comments". I think we are probably safe with shifting + our upper bound to 200 or 999 characters. + + Using a decimal hash to almost-guarantee uniqueness in the first 63 characters.""" + + if (not input_iterable_of_characters) or (len(input_iterable_of_characters)<1): + raise ValueError("This function requires an input of positive length.") + + INCLUSIVE_MAX_OUTPUT_LENGTH = 255 # D. R. Y. + + temp_ASCIIonly_string = "" + for char in input_iterable_of_characters: + if len(temp_ASCIIonly_string) > 999: # there`s not much good in letting it go on for an arbitrarily-long time + break + if '/' == char: # {part 1 of 3} of a kludge so that we can include path separators in the hash input + temp_ASCIIonly_string += char + if char.isalnum() and (ord(char)>=32) and (ord(char)<=126): + # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + # "char.isascii()" does _not_ always work + temp_ASCIIonly_string += char + elif not ( temp_ASCIIonly_string.endswith('_') or temp_ASCIIonly_string.endswith('/') ): + # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + # {part 2 of 3} of a kludge so that we can include path separators in the hash input + temp_ASCIIonly_string += '_' + + if dry_run_to_get_hash_input: + return temp_ASCIIonly_string + + result = "IDENTIFIER_" + arbitrary_ASCII_text_to_52digit_decimal_hash(temp_ASCIIonly_string) + if not temp_ASCIIonly_string.startswith('_'): + result += '_' + result += temp_ASCIIonly_string + + result = result[:INCLUSIVE_MAX_OUTPUT_LENGTH] + result = result.replace('/', '_') # {part 3 of 3} of a kludge so that we can include path separators in the hash input + return result + + + +def pathname_to_valid_C_identifier(file_pathname, dry_run_to_get_hash_input = False): + """This makes the assumption that the input is a string + [or at least "string-like object"] + with the data in a format along the lines of "/a/b/c/d/e/file" + """ + assert len(file_pathname) > 0 + + first_char_upper_case = lambda x: "" if (len(x)<1) else x[0].upper() + x[1:].lower() + + # somewhat hackish... does anybody want to propose an "elegant" alternative for the next 3 lines? + if file_pathname.endswith(".cpp"): file_pathname = file_pathname[:-4] + if file_pathname.endswith(".hpp"): file_pathname = file_pathname[:-4] + if file_pathname.endswith(".h" ): file_pathname = file_pathname[:-2] + + split = file_pathname.split('/') # POSIXism warning re '/' + file = first_char_upper_case(split[-1]) + last_4_dirs_if_possible = [ first_char_upper_case(x) for x in split[-5:-1] ] # worst-case scenario, this is an empty list + + return arbitrary_text_to_valid_C_identifier('/'.join(last_4_dirs_if_possible+[file]), dry_run_to_get_hash_input) + + + +def generate_cPlusPlus_file(outfile, top_level, args, schema, file_basename): + outfile.write("/* Autogenerated from %s and %s -- DO NOT EDIT */\n" % ( + args.schema, args.generate_cpp)) + + fake_pathname = args.o + '/' + top_level.name + '/' + file_basename + + synthetic_identifier = pathname_to_valid_C_identifier(fake_pathname) + outfile.write("/* --- vvv --- DEBUG --- vvv ---\n") + outfile.write("DEBUG: args.o = ''%s''\n" % args.o) + outfile.write("DEBUG: file_basename = ''%s''\n" % file_basename) + outfile.write("\n") + outfile.write("DEBUG: args.schema = ''%s''\n" % args.schema) + outfile.write("DEBUG: top_level.name = ''%s''\n" % top_level.name) + outfile.write("DEBUG: top_level.parent = ''%s''\n" % top_level.parent) + outfile.write("\n") + outfile.write("DEBUG: fake_pathname = ''%s''\n" % fake_pathname) + outfile.write("\n") + outfile.write( "DEBUG: input to hash algo.: ''%s''\n" % pathname_to_valid_C_identifier(fake_pathname, dry_run_to_get_hash_input = True) ) + outfile.write(" --- ^^^ --- DEBUG --- ^^^ --- */\n") + del fake_pathname + + if args.gen_decl == 'decl': + outfile.write('#ifndef %s\n' % synthetic_identifier) + outfile.write('#define %s 1\n\n' % synthetic_identifier) + + for incl in args.include: + outfile.write('#include "%s"\n' % incl) + if args.emit_json or args.emit_fieldname or args.dump_unread: + outfile.write('#include "indent.h"\n') + if args.unpack_json: + outfile.write('#include "json.h"\n') + if args.alias_array: + outfile.write('#include "alias_array.h"\n') + if args.checked_array: + outfile.write('#include "checked_array.h"\n') + if args.emit_binary: + outfile.write('#include "binary_output.h"\n') + outfile.write('#include "ubits.h"\n') + outfile.write('#include "register_reference.h"\n') + if args.widereg: + outfile.write('#include "widereg.h"\n') + outfile.write('\n') + outfile.write("using namespace P4;") + if len(args.global_types) > 0: + args.global_types_generated = {} + top_level.gen_global_types(outfile, args, schema) + if args.namespace: + outfile.write('namespace %s {\n\n' % args.namespace) + top_level.generate_cpp(outfile, args, schema) + outfile.write(";\n") + if args.namespace: + outfile.write('\n} // end namespace %s\n\n' % args.namespace) + if args.gen_decl == 'decl': + outfile.write('\n#endif /* end of "ifndef %s" */\n' % synthetic_identifier) + +def extend_args(args, params): + """ + parse additional template arguments into a copy of 'args' + """ + args = copy.copy(args) + parse_template_args(args, params) + return args + +def generate_cpp (args, schema): + if args.o == None: + args.o = "gen" + if not os.path.exists(args.o): + os.makedirs(args.o) + + top_level_objs = read_template_file(args.generate_cpp, args, schema) + global_args = args + for section_name, section in list(schema.items()): + if section_name not in top_level_objs: + continue; + for top_level_obj,files in list(top_level_objs[section_name].items()): + if files is None: continue + args = global_args + if 'args' in files: + args = extend_args(args, files['args']) + if 'rewrite' in files: + args = copy.copy(args) + args.rewrite = files['rewrite'] + for generate_file,params in list(files.items()): + if generate_file == 'args': continue + if generate_file == 'rewrite': continue + if (("DEBUG" in globals().keys()) and globals()["DEBUG"]) or ("DEBUG" in locals().keys()) and locals()["DEBUG"]: + print ("===vvv=== DEBUG ===vvv===") + print ("globals:", globals()) + print ("locals:", locals()) + print ("===^^^=== DEBUG ===^^^===") + generate_cPlusPlus_file(open(os.path.join(args.o, generate_file), "w"), + section[top_level_obj], + extend_args(args, params), + schema, + generate_file) + +def print_schema_text(args, schema): + def do_print(indent, obj): + for key,val in list(obj.items()): + if type(val) is str: + print("%s%s: %s" % (indent, key, val)) + elif type(val) is dict: + print("%s%s:" % (indent, key)) + do_print(indent+" ", val) + elif val.templatization_behavior == "top_level": + print("%s%s:" % (indent, key)) + val.print_as_text(indent+" ") + + read_template_file(args.print_schema, args, schema) + do_print("", schema) + +def build_binary_cache (args, schema): + cache = csr.binary_cache(schema) + try: + for config_filename in args.configs: + with open(config_filename, "rb") as configfile: + try: + template = json.load(configfile) + except: + sys.stderr.write("ERROR: Input file '"+config_filename+"' could not be decoded as JSON.\n") + sys.exit(1) + + if (type(template) is not dict or + "_name" not in template or + "_type" not in template): + sys.stderr.write("ERROR: Input file '"+config_filename+"' does not appear to be valid Walle configuration JSON.\n") + sys.exit(1) + + if ("_schema_hash" not in template or + template["_schema_hash"] != schema["_schema_hash"]): + sys.stderr.write("ERROR: Input file '"+config_filename+"' does not match the current chip schema.\n") + if not args.ignore_schema_mismatch: + sys.exit(1) + + cache.templates[template["_name"]] = template + except IOError as e: + sys.stderr.write("ERROR: Could not open '%s' for reading: %s (errno %i).\n"%(config_filename,e[1],e[0])) + sys.exit(e[0]) + + return cache + +def dump_binary (args, binary_cache, out_file): + addr_func = { + # Memories are ram-word addressed, not byte addressed + "memories": lambda addr: addr >> 4, + + # TODO: use actual func once model+indirect writes are fixed + "regs": lambda addr: addr + # # Regs are give in 32-bit PCIe address space and need to be + # # converted to 42-bit chip address space + # "regs": lambda addr: ((addr&0x0FF80000)<<14)|(addr&0x0007FFFF) + } + + for template in args.top: + try: + path = [] + data = binary_cache.get_data(template, path=path) + data_type = binary_cache.get_type(template) + except csr.CsrException as e: + # TODO: decompose: + sys.stderr.write("ERROR: "+str(e)+"\n") + tb = [] + for frame in path: + tb.append("{"+frame.template_name+"}") + arr_subscript = None + for node in frame.path: + if type(node) is str: + tb.append(node) + if arr_subscript != None: + tb[-1] += arr_subscript + arr_subscript = None + elif type(node) is list: + arr_subscript = csr.array_str(node) + else: + tb.append(str(node)) + sys.stderr.write("Traceback: "+".".join(tb)+"\n") + sys.exit(1) + + template_section = data_type.split(".")[0] + for chip_obj in data: + chip_obj.addr = addr_func[template_section](chip_obj.addr) + out_file.write(chip_obj.bytes()) + + if args.append_sentinel: + out_file.write(chip.direct_reg(0xFFFFFFFF, 0).bytes()) + +def walle_process(parser, args=None): + if len(args.top) == 0: + args.top = ["memories.top", "regs.top"] + + if args.generate_schema != None: + schema = csr.build_schema(args.generate_schema, __version__) + with open(args.schema, "wb") as outfile: + pickle.dump(schema, outfile, protocol=2) + print("Schema generated from:\n") + cmd = 'echo | git -C %s log -1' % args.generate_schema + output = subprocess.check_output(cmd, shell=True) + print(output.decode('utf-8')) + outfile.write(b'\n\n' + output) + + if args.generate_templates != None: + if not os.path.isfile(args.schema): + sys.stderr.write("ERROR: Schema file '"+os.path.abspath(args.schema)+ + "' could not be opened or does not exist.\n") + sys.exit(1) + generate_templates(args, schema) + else: + + if not os.path.isfile(args.schema): + sys.stderr.write("ERROR: Schema file '"+os.path.abspath(args.schema)+ + "' could not be opened or does not exist.\n") + sys.exit(1) + + with open(args.schema, "rb") as infile: + schema = CsrUnpickler(infile).load() + + if args.schema_info: + print_schema_info(os.path.abspath(args.schema), schema) + elif args.dump_schema: + print(yaml.dump(schema)) + elif args.print_schema: + print_schema_text(args, schema) + elif args.generate_templates != None: + generate_templates(args, schema) + elif args.generate_cpp != None: + generate_cpp(args, schema) + else: + if len(args.configs)==0: + parser.print_help() + else: + if args.o == None: + args.o = "a.out" + cache = build_binary_cache(args, schema) + with open(args.o,"wb") as binfile: + dump_binary(args, cache, binfile) + + sys.stdout.write("Binary '"+args.o+"' generated successfully.\n") + +def main(): + """ + The main entry point for the script + """ + + parser = argparse.ArgumentParser() + parser.add_argument( + '-v', '--version', + action='version', version='%(prog)s ' + __version__ + ) + parser.add_argument( + "--schema", '-s', + metavar='SCHEMA-FILE', + help="The chip schema to use", + type=str, + default="chip.schema" + ) + parser.add_argument( + "--schema-info", + action='store_true', + help="Print metadata stored in the selected chip schema and exit" + ) + parser.add_argument( + "--target", "-t", + help="The chip target", + type=str, + default="tofino" + ) + parser.add_argument( + "--dump-schema", + action='store_true', + help="Dump chip schema as yaml" + ) + parser.add_argument( + "--print-schema", + metavar='TOP-LEVEL-OBJS-FILE', + type=str, + help="Dump chip schema as (readable?) text" + ) + parser.add_argument( + "--generate-schema", + metavar='BFNREGS-TARGET-DIR', + type=str, + help="Generate a chip schema from the bfnregs target regs directory", + default=None + ) + parser.add_argument( + "--ignore-schema-mismatch", + action='store_true', + help="Attempt to crunch input files, even if they do not match the current chip schema", + ) + parser.add_argument( + "--generate-templates", + metavar='TOP-LEVEL-OBJS-FILE', + type=str, + help="Generate an 'all-0s' template for each addressmap listed in the given top-level objects file", + ) + parser.add_argument( + "--generate-cpp", + metavar='TOP-LEVEL-OBJS-FILE', + type=str, + help="Generate C++ code for each addressmap listed in the given top-level objects file", + ) + parser.add_argument( + "--template-indices", + metavar='THRESHOLD', + help="Include human-readable index keys for register arrays greater than the specified threshold size", + type=int, + default=None + ) + parser.add_argument( + "--append-sentinel", + action='store_true', + help="Append a direct register write to address 0xFFFFFFFF to the end of the binary output", + ) + parser.add_argument( + '--top', + metavar='IDENTIFIER', + type=str, + action='append', + default=[], + help='Identifier of a template to generate binary config data for' + ) + parser.add_argument( + '-o', + metavar='FILE', + type=str, + default=None, + help='Name of file to write binary config data into (or directory to write templates into)' + ) + parser.add_argument( + 'configs', + metavar='CONFIG-FILE', + type=str, nargs='*', + help='A JSON configuration file to process' + ) + + args = parser.parse_args() + if getattr( sys, 'frozen', False ) : + # running as a bundle: look for the schema in the bundled directory + args.schema = os.path.join(sys._MEIPASS, 'lib', args.target, 'chip.schema') + walle_process(parser, args) + + +######################################################################## +## Frontend logic + +if __name__ == "__main__": + main() diff --git a/backends/tofino/bf-asm/widereg.cpp b/backends/tofino/bf-asm/widereg.cpp new file mode 100644 index 00000000000..c5140eda57c --- /dev/null +++ b/backends/tofino/bf-asm/widereg.cpp @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "widereg.h" + +#include +#include + +#include "log.h" + +void widereg_base::log(const char *op, bitvec v) const { + std::ostringstream tmp; + LOG1(this << ' ' << op << ' ' << v + << (v != value ? tmp << " (now " << value << ")", tmp : tmp).str()); +} diff --git a/backends/tofino/bf-asm/widereg.h b/backends/tofino/bf-asm/widereg.h new file mode 100644 index 00000000000..5fc8dbca673 --- /dev/null +++ b/backends/tofino/bf-asm/widereg.h @@ -0,0 +1,170 @@ +/** + * Copyright (C) 2024 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BF_ASM_WIDEREG_H_ +#define BF_ASM_WIDEREG_H_ + +#include + +#include +#include +#include + +#include "bitvec.h" +#include "log.h" + +using namespace P4; + +void print_regname(std::ostream &out, const void *addr, const void *end); + +struct widereg_base; + +struct widereg_base { + bitvec value, reset_value; + mutable bool read, write; + mutable bool disabled_; + + widereg_base() : read(false), write(false), disabled_(false) {} + explicit widereg_base(bitvec v) + : value(v), reset_value(v), read(false), write(false), disabled_(false) {} + explicit widereg_base(uintptr_t v) + : value(v), reset_value(v), read(false), write(false), disabled_(false) {} +#if __WORDSIZE == 64 + // For 32-bit systems intptr_t is defined as int + explicit widereg_base(intptr_t v) + : value(v), reset_value(v), read(false), write(false), disabled_(false) {} +#endif + explicit widereg_base(int v) + : value(v), reset_value(v), read(false), write(false), disabled_(false) {} + operator bitvec() const { + read = true; + return value; + } + bool modified() const { return write; } + void set_modified(bool v = true) { write = v; } + bool disabled() const { return disabled_; } + bool disable_if_unmodified() { return write ? false : (disabled_ = true); } + bool disable_if_zero() const { return value.empty() && !write; } + bool disable_if_reset_value() { return value == reset_value ? (disabled_ = true) : false; } + bool disable() const { + if (write) { + LOG1("ERROR: Disabling modified register in " << this); + return false; + } + disabled_ = true; + return disabled_; + } + void enable() const { disabled_ = false; } + void rewrite() { write = false; } + virtual bitvec operator=(bitvec v) = 0; + virtual unsigned size() = 0; + void log(const char *op, bitvec v) const; +}; + +inline static unsigned int to_unsigned(const bitvec &v) { + std::stringstream ss; + ss << v; + std::string str(ss.str()); + unsigned int rv = std::strtoul(str.c_str(), 0, 16); + return rv; +} + +inline std::ostream &operator<<(std::ostream &out, const widereg_base *u) { + print_regname(out, u, u + 1); + return out; +} +inline std::ostream &operator<<(std::ostream &out, const widereg_base &u) { + return out << to_unsigned(u.value); +} + +template +struct widereg : widereg_base { + widereg() : widereg_base() {} + const widereg &check() { + if (value.max().index() >= N) { + LOG1("ERROR: out of range for " << N << " bits in " << this); + value.clrrange(N, value.max().index() - N + 1); + } + return *this; + } + explicit widereg(bitvec v) : widereg_base(v) { check(); } + explicit widereg(uintptr_t v) : widereg_base(v) { check(); } +#if __WORDSIZE == 64 + // For 32-bit systems intptr_t is defined as int + explicit widereg(intptr_t v) : widereg_base(v) { check(); } +#endif + explicit widereg(int v) : widereg_base(v) { check(); } + widereg(const widereg &) = delete; + widereg(widereg &&) = default; + bitvec operator=(bitvec v) { + if (disabled_) LOG1("ERROR: Writing disabled register value in " << this); + if (write) LOG1("WARNING: Overwriting " << value << " with " << v << " in " << this); + value = v; + write = true; + log("=", v); + check(); + return v; + } + uintptr_t operator=(uintptr_t v) { + *this = bitvec(v); + return v; + } + intptr_t operator=(intptr_t v) { + *this = bitvec(v); + return v; + } + const widereg &operator=(const widereg &v) { + *this = v.value; + v.read = true; + return v; + } + const widereg_base &operator=(const widereg_base &v) { + *this = v.value; + v.read = true; + return v; + } + unsigned size() { return N; } + const widereg &operator|=(bitvec v) { + if (disabled_) LOG1("ERROR: Writing disabled register value in " << this); + if (write) + LOG1("WARNING: Overwriting " << value << " with " << (v | value) << " in " << this); + value |= v; + write = true; + log("|=", v); + return check(); + } + const widereg &set_subfield(uintptr_t v, unsigned bit, unsigned size) { + if (disabled_) LOG1("ERROR: Writing disabled register value in " << this); + if (bit + size > N) { + LOG1("ERROR: subfield " << bit << ".." << (bit + size - 1) << " out of range in " + << this); + } else if (auto o = value.getrange(bit, size)) { + if (write) + LOG1((o != v ? "ERROR" : "WARNING") + << ": Overwriting subfield(" << bit << ".." << (bit + size - 1) << ") value " + << o << " with " << v << " in " << this); + } + if (v >= (1U << size)) + LOG1("ERROR: Subfield value " << v << " too large for " << size << " bits in " << this); + value.putrange(bit, size, v); + write = true; + log("|=", bitvec(v) << bit); + return check(); + } +}; + +#endif /* BF_ASM_WIDEREG_H_ */ From dbe1977e5422fc99f6d6a4ced6f7427a85fb8f04 Mon Sep 17 00:00:00 2001 From: fruffy Date: Thu, 6 Feb 2025 21:42:30 -0500 Subject: [PATCH 02/19] Bf-asm integration fixes. Signed-off-by: fruffy --- backends/tofino/CMakeLists.txt | 4 + backends/tofino/LICENSE | 2 +- backends/tofino/bf-asm/CMakeLists.txt | 162 ++++-------------- backends/tofino/bf-asm/README.md | 4 - backends/tofino/bf-asm/action_bus.cpp | 4 +- backends/tofino/bf-asm/action_bus.h | 8 +- backends/tofino/bf-asm/action_table.cpp | 6 +- backends/tofino/bf-asm/alias_array.h | 6 +- backends/tofino/bf-asm/asm-parse.ypp | 6 +- backends/tofino/bf-asm/asm-types.h | 14 +- backends/tofino/bf-asm/atcam_match.cpp | 8 +- backends/tofino/bf-asm/attached_table.cpp | 6 +- backends/tofino/bf-asm/bfas.cpp | 8 +- backends/tofino/bf-asm/bfas.h | 6 +- backends/tofino/bf-asm/bson.cpp | 2 +- backends/tofino/bf-asm/bson.h | 2 +- backends/tofino/bf-asm/checked_array.h | 8 +- backends/tofino/bf-asm/counter.cpp | 6 +- backends/tofino/bf-asm/crash.cpp | 4 +- backends/tofino/bf-asm/data_switchbox.h | 10 +- backends/tofino/bf-asm/deparser.cpp | 4 +- backends/tofino/bf-asm/deparser.h | 4 +- backends/tofino/bf-asm/disasm.h | 2 +- backends/tofino/bf-asm/dynhash.cpp | 2 +- backends/tofino/bf-asm/error_mode.cpp | 2 +- backends/tofino/bf-asm/error_mode.h | 6 +- backends/tofino/bf-asm/escape.h | 8 +- backends/tofino/bf-asm/exact_match.cpp | 8 +- backends/tofino/bf-asm/exename.h | 6 +- backends/tofino/bf-asm/fdstream.h | 6 +- backends/tofino/bf-asm/flexible_headers.cpp | 2 +- backends/tofino/bf-asm/gateway.cpp | 8 +- backends/tofino/bf-asm/gtest/gateway.cpp | 2 +- backends/tofino/bf-asm/gtest/hashexpr.cpp | 2 +- .../tofino/bf-asm/gtest/register-matcher.h | 6 +- backends/tofino/bf-asm/hash_action.cpp | 4 +- backends/tofino/bf-asm/hash_dist.cpp | 4 +- backends/tofino/bf-asm/hash_dist.h | 6 +- backends/tofino/bf-asm/hashdump.cpp | 4 +- backends/tofino/bf-asm/hashexpr.cpp | 4 +- backends/tofino/bf-asm/hashexpr.h | 8 +- backends/tofino/bf-asm/idletime.cpp | 4 +- backends/tofino/bf-asm/input_xbar.cpp | 12 +- backends/tofino/bf-asm/input_xbar.h | 10 +- backends/tofino/bf-asm/instruction.cpp | 4 +- backends/tofino/bf-asm/instruction.h | 8 +- backends/tofino/bf-asm/jbay/counter.h | 6 +- backends/tofino/bf-asm/jbay/gateway.cpp | 4 +- backends/tofino/bf-asm/jbay/gateway.h | 11 +- backends/tofino/bf-asm/jbay/input_xbar.cpp | 2 +- backends/tofino/bf-asm/jbay/input_xbar.h | 8 +- backends/tofino/bf-asm/jbay/meter.h | 6 +- backends/tofino/bf-asm/jbay/parser.cpp | 6 +- backends/tofino/bf-asm/jbay/phv.cpp | 2 +- backends/tofino/bf-asm/jbay/phv.h | 8 +- backends/tofino/bf-asm/jbay/stateful.cpp | 2 +- backends/tofino/bf-asm/jbay/stateful.h | 10 +- backends/tofino/bf-asm/json.cpp | 4 +- backends/tofino/bf-asm/json.h | 8 +- backends/tofino/bf-asm/json_diff.cpp | 4 +- backends/tofino/bf-asm/map.h | 6 +- backends/tofino/bf-asm/mask_counter.h | 8 +- backends/tofino/bf-asm/match_source.h | 9 +- backends/tofino/bf-asm/match_table.cpp | 6 +- backends/tofino/bf-asm/meter.cpp | 4 +- backends/tofino/bf-asm/misc.cpp | 2 +- backends/tofino/bf-asm/misc.h | 8 +- backends/tofino/bf-asm/p4_table.cpp | 2 +- backends/tofino/bf-asm/p4_table.h | 8 +- backends/tofino/bf-asm/parser-tofino-jbay.cpp | 10 +- backends/tofino/bf-asm/parser-tofino-jbay.h | 4 +- backends/tofino/bf-asm/parser.h | 10 +- backends/tofino/bf-asm/phase0.cpp | 4 +- backends/tofino/bf-asm/phv.cpp | 2 +- backends/tofino/bf-asm/phv.h | 12 +- backends/tofino/bf-asm/power_ctl.h | 6 +- backends/tofino/bf-asm/primitives.cpp | 4 +- backends/tofino/bf-asm/proxy_hash.cpp | 4 +- backends/tofino/bf-asm/register_reference.h | 8 +- .../tofino/bf-asm/rvalue_reference_wrapper.h | 6 +- backends/tofino/bf-asm/salu_inst.cpp | 6 +- backends/tofino/bf-asm/sections.h | 8 +- backends/tofino/bf-asm/selection.cpp | 6 +- backends/tofino/bf-asm/slist.h | 6 +- backends/tofino/bf-asm/sram_match.cpp | 18 +- backends/tofino/bf-asm/stage.cpp | 6 +- backends/tofino/bf-asm/stage.h | 10 +- backends/tofino/bf-asm/stateful.cpp | 6 +- backends/tofino/bf-asm/synth2port.cpp | 6 +- backends/tofino/bf-asm/tables.cpp | 6 +- backends/tofino/bf-asm/tables.h | 18 +- backends/tofino/bf-asm/target.cpp | 4 +- backends/tofino/bf-asm/target.h | 44 ++--- backends/tofino/bf-asm/ternary_match.cpp | 8 +- backends/tofino/bf-asm/tofino/action_table.h | 8 +- backends/tofino/bf-asm/tofino/counter.h | 8 +- backends/tofino/bf-asm/tofino/exact_match.cpp | 2 +- backends/tofino/bf-asm/tofino/exact_match.h | 8 +- backends/tofino/bf-asm/tofino/gateway.cpp | 10 +- backends/tofino/bf-asm/tofino/gateway.h | 8 +- backends/tofino/bf-asm/tofino/input_xbar.cpp | 2 +- backends/tofino/bf-asm/tofino/input_xbar.h | 8 +- backends/tofino/bf-asm/tofino/meter.h | 8 +- backends/tofino/bf-asm/tofino/parser.cpp | 8 +- backends/tofino/bf-asm/tofino/phv.cpp | 2 +- backends/tofino/bf-asm/tofino/phv.h | 8 +- backends/tofino/bf-asm/tofino/salu_inst.cpp | 2 +- backends/tofino/bf-asm/tofino/sram_match.cpp | 5 +- backends/tofino/bf-asm/tofino/stateful.cpp | 2 +- backends/tofino/bf-asm/tofino/stateful.h | 10 +- .../tofino/bf-asm/tofino/ternary_match.cpp | 4 +- backends/tofino/bf-asm/tofino/ternary_match.h | 8 +- backends/tofino/bf-asm/top_level.h | 10 +- backends/tofino/bf-asm/ubits.cpp | 4 +- backends/tofino/bf-asm/ubits.h | 10 +- backends/tofino/bf-asm/vector.h | 6 +- backends/tofino/bf-asm/walle/chip.py | 54 ++++-- backends/tofino/bf-asm/walle/walle.py | 16 +- backends/tofino/bf-asm/widereg.cpp | 2 +- backends/tofino/bf-asm/widereg.h | 10 +- backends/tofino/bf-p4c/driver/barefoot.py | 31 ++-- backends/tofino/bf-p4c/driver/p4c.tofino.cfg | 3 +- backends/tofino/bf-p4c/driver/p4c.tofino2.cfg | 3 +- 123 files changed, 468 insertions(+), 560 deletions(-) diff --git a/backends/tofino/CMakeLists.txt b/backends/tofino/CMakeLists.txt index 8ceaf2e1eb2..205f62d10ed 100644 --- a/backends/tofino/CMakeLists.txt +++ b/backends/tofino/CMakeLists.txt @@ -229,6 +229,7 @@ set (BF_P4C_IR_SRCS bf-p4c/parde/match_register.cpp bf-p4c/parde/clot/clot.cpp bf-p4c/phv/phv.cpp + # FIXME: This should be a library. bf-utils/dynamic_hash/dynamic_hash.cpp bf-utils/dynamic_hash/bfn_hash_algorithm.cpp ) @@ -240,3 +241,6 @@ endforeach() set(EXTENSION_IR_SOURCES ${EXTENSION_IR_SOURCES} ${QUAL_BF_P4C_IR_SRCS} PARENT_SCOPE) add_subdirectory(bf-p4c) + +# Initialize bf-asm after bf-p4c. +add_subdirectory(bf-asm) diff --git a/backends/tofino/LICENSE b/backends/tofino/LICENSE index a24a1c32224..bc47beb02fe 100644 --- a/backends/tofino/LICENSE +++ b/backends/tofino/LICENSE @@ -1,4 +1,4 @@ -Copyright (C) 2024 Intel Corporation +Copyright (C) 2025 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy diff --git a/backends/tofino/bf-asm/CMakeLists.txt b/backends/tofino/bf-asm/CMakeLists.txt index bfdfabdf151..2e9b4abf7de 100644 --- a/backends/tofino/bf-asm/CMakeLists.txt +++ b/backends/tofino/bf-asm/CMakeLists.txt @@ -15,22 +15,13 @@ # # SPDX-License-Identifier: Apache-2.0 -####### Tofino assembler -cmake_minimum_required (VERSION 3.16.3 FATAL_ERROR) - -find_program(CCACHE_PROGRAM ccache) -if(CCACHE_PROGRAM) - MESSAGE(STATUS "Enabling ccache") - set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}") -endif() - -project (BFASM) - +# # ##### Tofino assembler MESSAGE("-- Adding bf-asm") OPTION(ASAN_ENABLED "Enable ASAN checks" OFF) -set (BFASM_LIB_DEPS dynhashStatic) +set (BFASM_LIB_DEPS p4ctoolkit ${P4C_LIB_DEPS}) +set (BFASM_GEN_DIR ${CMAKE_CURRENT_BINARY_DIR}/gen) find_package (BISON REQUIRED) find_package (FLEX REQUIRED) @@ -68,7 +59,7 @@ macro(get_schema_version schema_file schema_var) OUTPUT_VARIABLE __schema_version RESULT_VARIABLE __schema_errcode ERROR_VARIABLE __schema_errstr - WORKING_DIRECTORY ${P4C_SOURCE_DIR}/backends/tofino/compiler_interfaces/schemas) + WORKING_DIRECTORY ${BFN_P4C_SOURCE_DIR}/compiler_interfaces/schemas) if (${__schema_errcode}) MESSAGE(FATAL_ERROR "Error retrieving ${schema_file} version ${__schema_errstr}") endif() @@ -78,11 +69,11 @@ endmacro(get_schema_version) # change: context and manifest for now # We generate a pair of dummy dependency files will be ignored set(SCHEMA_FILES - ${P4C_SOURCE_DIR}/backends/tofino/compiler_interfaces/schemas/context_schema.py - ${P4C_SOURCE_DIR}/backends/tofino/compiler_interfaces/schemas/manifest_schema.py - ${P4C_SOURCE_DIR}/backends/tofino/compiler_interfaces/schemas/phv_schema.py - ${P4C_SOURCE_DIR}/backends/tofino/compiler_interfaces/schemas/power_schema.py - ${P4C_SOURCE_DIR}/backends/tofino/compiler_interfaces/schemas/resources_schema.py + ${BFN_P4C_SOURCE_DIR}/compiler_interfaces/schemas/context_schema.py + ${BFN_P4C_SOURCE_DIR}/compiler_interfaces/schemas/manifest_schema.py + ${BFN_P4C_SOURCE_DIR}/compiler_interfaces/schemas/phv_schema.py + ${BFN_P4C_SOURCE_DIR}/compiler_interfaces/schemas/power_schema.py + ${BFN_P4C_SOURCE_DIR}/compiler_interfaces/schemas/resources_schema.py ) foreach (f ${SCHEMA_FILES}) configure_file(${f} ${CMAKE_BINARY_DIR}/${f}.dep) @@ -91,8 +82,6 @@ endforeach() get_schema_version(context_schema CONTEXT_SCHEMA_VERSION) MESSAGE(STATUS "Found context schema version ${CONTEXT_SCHEMA_VERSION}") add_definitions("-DCONTEXT_SCHEMA_VERSION=\"${CONTEXT_SCHEMA_VERSION}\"") -set (BFN_P4C_LIB_DIR ${P4C_SOURCE_DIR}/lib) -include_directories(${BFASM_SOURCE_DIR} ${BFASM_BINARY_DIR} ${BFN_P4C_LIB_DIR} ${P4C_SOURCE_DIR}) # ASAN CHECKS if (ASAN_ENABLED) @@ -168,64 +157,17 @@ set (BFAS_COMMON_SOURCES ubits.cpp vector.c widereg.cpp - ${BFN_P4C_LIB_DIR}/bitvec.cpp - ${BFN_P4C_LIB_DIR}/hex.cpp - ${BFN_P4C_LIB_DIR}/indent.cpp - ${BFN_P4C_LIB_DIR}/log.cpp - ${BFN_P4C_LIB_DIR}/cstring.cpp - ${BFN_P4C_LIB_DIR}/hash.cpp - ) - -SET (BFAS_COMMON_HEADERS - action_bus.h - asm-types.h - bfas.h - checked_array.h - constants.h - data_switchbox.h - deparser.h - depositfield.h - error_mode.h - escape.h - exename.h - fdstream.h - hash_dist.h - hashexpr.h - input_xbar.h - instruction.h - json.h - mask_counter.h - match_source.h - misc.h - p4_table.h - parser.h - parser-tofino-jbay.h - phv.h - power_ctl.h - register_reference.h - rvalue_reference_wrapper.h - sections.h - slist.h - stage.h - tables.h - target.h - top_level.h - ubits.h - widereg.h - alloc.h - ) - -# \TODO: use the headers from p4c/lib for utilities -set (BFAS_UTIL_HEADERS - map.h - vector.h + # FIXME: This should be a library. + ${BFN_P4C_SOURCE_DIR}/bf-utils/dynamic_hash/dynamic_hash.cpp + ${BFN_P4C_SOURCE_DIR}/bf-utils/dynamic_hash/bfn_hash_algorithm.cpp ) set (BFAS_GEN_SOURCES - ${BFASM_BINARY_DIR}/asm-parse.cpp - ${BFASM_BINARY_DIR}/gen/uptr_sizes.h) + ${BFASM_GEN_DIR}/asm-parse.cpp + ${BFASM_GEN_DIR}/gen/uptr_sizes.h +) -BISON_TARGET (asm-parse asm-parse.ypp ${CMAKE_CURRENT_BINARY_DIR}/asm-parse.cpp VERBOSE) +BISON_TARGET (asm-parse asm-parse.ypp ${BFASM_GEN_DIR}/asm-parse.cpp VERBOSE) add_custom_command(OUTPUT lex-yaml.c COMMAND ${FLEX_EXECUTABLE} -t ${CMAKE_CURRENT_SOURCE_DIR}/lex-yaml.l > lex-yaml.c @@ -233,7 +175,7 @@ add_custom_command(OUTPUT lex-yaml.c COMMENT "Generating lex-yaml.cpp") add_custom_command(OUTPUT gen/uptr_sizes.h - COMMAND ${CMAKE_COMMAND} -E make_directory ${BFASM_BINARY_DIR}/gen + COMMAND ${CMAKE_COMMAND} -E make_directory ${BFASM_GEN_DIR}/gen COMMAND mksizes > gen/uptr_sizes.h DEPENDS lex-yaml.c mksizes) @@ -251,9 +193,9 @@ set (HAVE_JBAY 1) set (BFASM_LIBS ${BFASM_LIBS} regs_jbay) # Other configuration files that need to be generated -configure_file ("${BFASM_SOURCE_DIR}/cmake/config.h.in" "${BFASM_BINARY_DIR}/config.h") +configure_file ("${BFASM_SOURCE_DIR}/cmake/config.h.in" "${BFASM_GEN_DIR}/config.h") -set_source_files_properties (${BFAS_GEN_SOURCES} ${BFASM_BINARY_DIR}/lex-yaml.c +set_source_files_properties (${BFAS_GEN_SOURCES} ${BFASM_GEN_DIR}/lex-yaml.c PROPERTIES GENERATED TRUE) set (BFAS_SOURCES ${BFAS_COMMON_SOURCES} ${BFAS_GEN_SOURCES} @@ -261,24 +203,6 @@ set (BFAS_SOURCES ${BFAS_COMMON_SOURCES} ${BFAS_GEN_SOURCES} ${BFAS_JBAY_SRCS} ) -set (CPPLINT_FILES - ${JSONDIFF_SOURCES} - ${BFDUMPBIN_SOURCES} - ${REFLOW_SOURCES} - ${B2J_SOURCES} - ${J2B_SOURCES} - ${MKSIZE_SOURCES} - ${BFAS_COMMON_SOURCES} - ${BFAS_TOFINO_SRCS} - ${BFAS_JBAY_SRCS} - ${BFAS_UTIL_HEADERS} - ${BFAS_COMMON_HEADERS} - ${BFAS_TOFINO_HEADERS} - ${BFAS_JBAY_HEADERS} - ) -list(REMOVE_ITEM CPPLINT_FILES vector.c) -list(REMOVE_DUPLICATES CPPLINT_FILES) - # json_diff add_executable (json_diff ${JSONDIFF_SOURCES}) @@ -306,12 +230,13 @@ add_executable (j2b ${J2B_SOURCES}) # mksizes add_executable (mksizes ${MKSIZES_SOURCES}) -set_source_files_properties(${BFAS_SOURCES} PROPERTIES COMPILE_FLAGS ${BFASM_CXX_FLAGS}) +# set_source_files_properties(${BFAS_SOURCES} PROPERTIES COMPILE_FLAGS ${BFASM_CXX_FLAGS}) # Remove compiler flag that is C++ only for vector.c -string(REPLACE "-Wno-overloaded-virtual" "" vector_c_flags ${BFASM_CXX_FLAGS}) -set_source_files_properties(vector.c PROPERTIES COMPILE_FLAGS ${vector_c_flags}) +# string(REPLACE "-Wno-overloaded-virtual" "" vector_c_flags ${BFASM_CXX_FLAGS}) +# set_source_files_properties(vector.c PROPERTIES COMPILE_FLAGS ${vector_c_flags}) add_executable (bfas ${BFAS_SOURCES}) -target_link_libraries (bfas ${BFASM_LIBS} ${BFASM_LIB_DEPS} absl::strings absl::str_format absl::base absl::flags absl::flags_parse absl::status absl::hash) +target_compile_options(bfas PRIVATE -std=gnu++17) # Enable extensions for bfas. +target_link_libraries (bfas ${BFASM_LIBS} ${BFASM_LIB_DEPS}) install (TARGETS bfas RUNTIME DESTINATION bin) @@ -324,31 +249,20 @@ add_dependencies(p4c_driver linkbfas) add_custom_target(check-asm - COMMAND export BUILDDIR=${BFASM_BINARY_DIR} && cd ${BFASM_SOURCE_DIR}/test && + COMMAND export BUILDDIR=${BFASM_GEN_DIR} && cd ${BFASM_SOURCE_DIR}/test && ./runtests asm/*.tfa asm/*.jba asm/*.bfa asm/*.stf) # This is broken and it doesn't make sense to use p4 tests here anyways # add_custom_target(check-all-asm -# COMMAND export BUILDDIR=${BFASM_BINARY_DIR} && cd ${BFASM_SOURCE_DIR}/test && +# COMMAND export BUILDDIR=${BFASM_GEN_DIR} && cd ${BFASM_SOURCE_DIR}/test && # ./runtests -f asm/*.tfa *.p4 mau/*.p4 -# COMMAND export BUILDDIR=${BFASM_BINARY_DIR} && cd ${BFASM_SOURCE_DIR}/test && +# COMMAND export BUILDDIR=${BFASM_GEN_DIR} && cd ${BFASM_SOURCE_DIR}/test && # ./runtests -f -b stf/*.stf brig/*.p4) add_custom_target(check-sanity - COMMAND export BUILDDIR=${BFASM_BINARY_DIR} && cd ${BFASM_SOURCE_DIR}/test && + COMMAND export BUILDDIR=${BFASM_GEN_DIR} && cd ${BFASM_SOURCE_DIR}/test && ./runtests *.p4) -set (CPPLINT_CMD ${BFN_P4C_SOURCE_DIR}/p4c/tools/cpplint.py) -set (CPPLINT_ARGS --root=${BFASM_SOURCE_DIR}/.. --extensions=h,hpp,cpp,ypp,l) -add_custom_target(cpplint-asm - COMMAND ${CPPLINT_CMD} ${CPPLINT_ARGS} ${CPPLINT_FILES} - WORKING_DIRECTORY ${BFASM_SOURCE_DIR} - COMMENT "cpplint") -add_custom_target(cpplint-asm-quiet - COMMAND ${CPPLINT_CMD} --quiet ${CPPLINT_ARGS} ${CPPLINT_FILES} - WORKING_DIRECTORY ${BFASM_SOURCE_DIR} - COMMENT "cpplint quietly") - string(CONFIGURE "/^DECLARE_(ABSTRACT_)?TABLE_TYPE\(([a-zA-Z0-9_]+)/2/c/" CTAGS_CXX_REGEXP @ONLY) add_custom_target(ctags-asm COMMAND ctags -R -I VECTOR --exclude=test --exclude=submodules @@ -370,7 +284,7 @@ if (ENABLE_GTESTS) add_library (bfas_lib ${BFAS_SOURCES}) target_compile_definitions(bfas_lib PRIVATE BUILDING_FOR_GTEST) # removes main() - target_link_libraries (bfas_lib PRIVATE ${BFASM_LIBS} ${BFASM_LIB_DEPS} absl::strings absl::str_format absl::base absl::flags absl::flags_parse absl::status absl::hash) + target_link_libraries (bfas_lib PRIVATE ${BFASM_LIBS} ${BFASM_LIB_DEPS}) set(BFAS_GTEST_SOURCES gtest/gtestasm.cpp @@ -384,27 +298,11 @@ if (ENABLE_GTESTS) gtest/register-matcher.cpp ) - set(BFP4C_SOURCES - ${BFN_P4C_LIB_DIR}/bitvec.cpp - ${BFN_P4C_LIB_DIR}/compile_context.cpp - ${BFN_P4C_LIB_DIR}/cstring.cpp - ${BFN_P4C_LIB_DIR}/error_catalog.cpp - ${BFN_P4C_LIB_DIR}/error_message.cpp - ${BFN_P4C_LIB_DIR}/error_reporter.h - ${BFN_P4C_LIB_DIR}/hash.cpp - ${BFN_P4C_LIB_DIR}/options.cpp - ${BFN_P4C_LIB_DIR}/source_file.cpp - ${BFN_P4C_LIB_DIR}/stringify.cpp -) - # Do not use a unity build for gtestasm (for now). set_source_files_properties (${BFAS_GTEST_SOURCES} PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE) add_executable (gtestasm ${BFAS_GTEST_SOURCES} ${BFP4C_SOURCES}) - include_directories( - ${BFN_P4C_SOURCE_DIR}/p4c - ) - target_link_libraries (gtestasm PRIVATE bfas_lib gtest absl::strings absl::str_format absl::base absl::flags absl::flags_parse absl::status absl::hash) + target_link_libraries (gtestasm PRIVATE bfas_lib gtest) target_compile_options (gtestasm PRIVATE -Wall -Wextra -ggdb -O3 -Wno-unused-parameter -Wno-sign-compare) diff --git a/backends/tofino/bf-asm/README.md b/backends/tofino/bf-asm/README.md index 5e4008a8a0c..ed0f50f1ae0 100644 --- a/backends/tofino/bf-asm/README.md +++ b/backends/tofino/bf-asm/README.md @@ -2,10 +2,6 @@ ## Documentation -Documentation on using the assembler, notes on file formats, and internals are -in [Google Drive > Barefoot shared > documents > Software > Assembler] -(https://drive.google.com/drive/folders/0Byf8esgFy8YacmNzMmZiSkN4OFU) - ## Setup The repository contains code for the Barefoot assembler (bfas) and linker (walle). diff --git a/backends/tofino/bf-asm/action_bus.cpp b/backends/tofino/bf-asm/action_bus.cpp index 299743a607b..20131031e68 100644 --- a/backends/tofino/bf-asm/action_bus.cpp +++ b/backends/tofino/bf-asm/action_bus.cpp @@ -19,9 +19,9 @@ #include -#include "hex.h" +#include "lib/hex.h" #include "misc.h" -#include "stage.h" +#include "backends/tofino/bf-asm/stage.h" static MeterBus_t MeterBus; diff --git a/backends/tofino/bf-asm/action_bus.h b/backends/tofino/bf-asm/action_bus.h index ea798429b7f..f19352532e7 100644 --- a/backends/tofino/bf-asm/action_bus.h +++ b/backends/tofino/bf-asm/action_bus.h @@ -15,12 +15,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_ACTION_BUS_H_ -#define BF_ASM_ACTION_BUS_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_ACTION_BUS_H_ +#define BACKENDS_TOFINO_BF_ASM_ACTION_BUS_H_ #include -#include "tables.h" +#include "backends/tofino/bf-asm/tables.h" // static struct MeterBus_t {} MeterBus; struct MeterBus_t {}; @@ -241,4 +241,4 @@ class ActionBus { auto slots() const { return Values(by_byte); } }; -#endif /* BF_ASM_ACTION_BUS_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_ACTION_BUS_H_ */ diff --git a/backends/tofino/bf-asm/action_table.cpp b/backends/tofino/bf-asm/action_table.cpp index 24e532528cd..b1f61996140 100644 --- a/backends/tofino/bf-asm/action_table.cpp +++ b/backends/tofino/bf-asm/action_table.cpp @@ -16,11 +16,11 @@ */ #include "action_bus.h" -#include "algorithm.h" +#include "lib/algorithm.h" #include "input_xbar.h" #include "instruction.h" -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" // template specialization declarations #include "tofino/action_table.h" diff --git a/backends/tofino/bf-asm/alias_array.h b/backends/tofino/bf-asm/alias_array.h index 5551776e446..0c4fb161e8e 100644 --- a/backends/tofino/bf-asm/alias_array.h +++ b/backends/tofino/bf-asm/alias_array.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_ALIAS_ARRAY_H_ -#define BF_ASM_ALIAS_ARRAY_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_ALIAS_ARRAY_H_ +#define BACKENDS_TOFINO_BF_ASM_ALIAS_ARRAY_H_ #include @@ -139,4 +139,4 @@ class alias_array : public alias_array_base { } }; -#endif /* BF_ASM_ALIAS_ARRAY_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_ALIAS_ARRAY_H_ */ diff --git a/backends/tofino/bf-asm/asm-parse.ypp b/backends/tofino/bf-asm/asm-parse.ypp index 11a0bb15d72..d0e9c50c837 100644 --- a/backends/tofino/bf-asm/asm-parse.ypp +++ b/backends/tofino/bf-asm/asm-parse.ypp @@ -17,10 +17,10 @@ %{ #define YYDEBUG 1 -#include "asm-types.h" +#include "backends/tofino/bf-asm/asm-types.h" #include #include -#include "sections.h" +#include "backends/tofino/bf-asm/sections.h" #include #include static int yylex(); @@ -370,7 +370,7 @@ error_resync: /* epsilon */ | error_resync indent_elements { free_value(&$2); } #pragma GCC diagnostic ignored "-Wpragmas" #pragma GCC diagnostic ignored "-Wdeprecated-register" #pragma GCC diagnostic ignored "-Wsign-compare" -#include "lex-yaml.c" +#include "backends/tofino/bf-asm/lex-yaml.c" #pragma GCC diagnostic pop int error_count = 0; diff --git a/backends/tofino/bf-asm/asm-types.h b/backends/tofino/bf-asm/asm-types.h index 32dccfb91d8..b6b92b8c1fc 100644 --- a/backends/tofino/bf-asm/asm-types.h +++ b/backends/tofino/bf-asm/asm-types.h @@ -15,12 +15,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_ASM_TYPES_H_ -#define BF_ASM_ASM_TYPES_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_ASM_TYPES_H_ +#define BACKENDS_TOFINO_BF_ASM_ASM_TYPES_H_ #include -#include -#include #include #include #include @@ -32,9 +30,11 @@ #include #include +#include "backends/tofino/bf-asm/map.h" +#include "backends/tofino/bf-asm/json.h" #include "bfas.h" -#include "json.h" -#include "map.h" +#include "lib/bitops.h" +#include "lib/bitvec.h" #include "mask_counter.h" #include "vector.h" @@ -491,4 +491,4 @@ class Contextable { #endif /* __cplusplus */ -#endif /* BF_ASM_ASM_TYPES_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_ASM_TYPES_H_ */ diff --git a/backends/tofino/bf-asm/atcam_match.cpp b/backends/tofino/bf-asm/atcam_match.cpp index 533487772e3..8f9c53155f5 100644 --- a/backends/tofino/bf-asm/atcam_match.cpp +++ b/backends/tofino/bf-asm/atcam_match.cpp @@ -16,13 +16,13 @@ */ #include "action_bus.h" -#include "algorithm.h" -#include "hex.h" +#include "lib/algorithm.h" +#include "lib/hex.h" #include "input_xbar.h" #include "instruction.h" #include "misc.h" -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" void AlgTcamMatchTable::setup(VECTOR(pair_t) & data) { common_init_setup(data, false, P4Table::MatchEntry); diff --git a/backends/tofino/bf-asm/attached_table.cpp b/backends/tofino/bf-asm/attached_table.cpp index 049c1d88b0e..a9ba38e013f 100644 --- a/backends/tofino/bf-asm/attached_table.cpp +++ b/backends/tofino/bf-asm/attached_table.cpp @@ -20,12 +20,12 @@ #include #include "action_bus.h" -#include "algorithm.h" +#include "lib/algorithm.h" #include "input_xbar.h" #include "instruction.h" #include "misc.h" -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" void AttachedTable::pass1() { if (default_action.empty()) default_action = get_default_action(); diff --git a/backends/tofino/bf-asm/bfas.cpp b/backends/tofino/bf-asm/bfas.cpp index 8a282498a2d..18a51a9dd22 100644 --- a/backends/tofino/bf-asm/bfas.cpp +++ b/backends/tofino/bf-asm/bfas.cpp @@ -25,14 +25,14 @@ #include #include -#include "../p4c/backends/tofino/bf-p4c/git_sha_version.h" // for BF_P4C_GIT_SHA -#include "../p4c/backends/tofino/bf-p4c/version.h" +#include "backends/tofino/bf-p4c/git_sha_version.h" // for BF_P4C_GIT_SHA +#include "backends/tofino/bf-p4c/version.h" #include "constants.h" -#include "indent.h" +#include "lib/indent.h" #include "misc.h" #include "parser-tofino-jbay.h" #include "sections.h" -#include "target.h" +#include "backends/tofino/bf-asm/target.h" #include "top_level.h" #define MAJOR_VERSION 1 diff --git a/backends/tofino/bf-asm/bfas.h b/backends/tofino/bf-asm/bfas.h index f2662dc39f3..ed13b05d7b7 100644 --- a/backends/tofino/bf-asm/bfas.h +++ b/backends/tofino/bf-asm/bfas.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_BFAS_H_ -#define BF_ASM_BFAS_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_BFAS_H_ +#define BACKENDS_TOFINO_BF_ASM_BFAS_H_ #include #include @@ -179,4 +179,4 @@ class VersionIter { extern unsigned unique_table_offset; -#endif /* BF_ASM_BFAS_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_BFAS_H_ */ diff --git a/backends/tofino/bf-asm/bson.cpp b/backends/tofino/bf-asm/bson.cpp index 15cdcb4b545..b6f0d8d261a 100644 --- a/backends/tofino/bf-asm/bson.cpp +++ b/backends/tofino/bf-asm/bson.cpp @@ -19,7 +19,7 @@ #include -#include "hex.h" +#include "lib/hex.h" namespace { uint8_t get8(std::istream &in) { diff --git a/backends/tofino/bf-asm/bson.h b/backends/tofino/bf-asm/bson.h index 6f3f850e0fd..84dd18111ad 100644 --- a/backends/tofino/bf-asm/bson.h +++ b/backends/tofino/bf-asm/bson.h @@ -20,7 +20,7 @@ #include -#include "json.h" +#include "backends/tofino/bf-asm/json.h" namespace json { diff --git a/backends/tofino/bf-asm/checked_array.h b/backends/tofino/bf-asm/checked_array.h index cda1b1f2ba7..0c047fd0474 100644 --- a/backends/tofino/bf-asm/checked_array.h +++ b/backends/tofino/bf-asm/checked_array.h @@ -15,13 +15,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_CHECKED_ARRAY_H_ -#define BF_ASM_CHECKED_ARRAY_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_CHECKED_ARRAY_H_ +#define BACKENDS_TOFINO_BF_ASM_CHECKED_ARRAY_H_ #include #include "bfas.h" // to get at the options -#include "log.h" +#include "lib/log.h" void print_regname(std::ostream &out, const void *addr, const void *end); @@ -143,4 +143,4 @@ inline std::ostream &operator<<(std::ostream &out, checked_array *arr) { return out; } -#endif /* BF_ASM_CHECKED_ARRAY_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_CHECKED_ARRAY_H_ */ diff --git a/backends/tofino/bf-asm/counter.cpp b/backends/tofino/bf-asm/counter.cpp index ca9d310f956..78e658929e2 100644 --- a/backends/tofino/bf-asm/counter.cpp +++ b/backends/tofino/bf-asm/counter.cpp @@ -15,12 +15,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "algorithm.h" +#include "lib/algorithm.h" #include "data_switchbox.h" #include "input_xbar.h" #include "misc.h" -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" // target specific template specializations #include "tofino/counter.h" diff --git a/backends/tofino/bf-asm/crash.cpp b/backends/tofino/bf-asm/crash.cpp index bccab36eb3a..dbc517d1b7c 100644 --- a/backends/tofino/bf-asm/crash.cpp +++ b/backends/tofino/bf-asm/crash.cpp @@ -35,8 +35,8 @@ #include "bfas.h" #include "exename.h" -#include "hex.h" -#include "log.h" +#include "lib/hex.h" +#include "lib/log.h" using namespace P4; diff --git a/backends/tofino/bf-asm/data_switchbox.h b/backends/tofino/bf-asm/data_switchbox.h index f54c06b4740..d69d952f899 100644 --- a/backends/tofino/bf-asm/data_switchbox.h +++ b/backends/tofino/bf-asm/data_switchbox.h @@ -15,11 +15,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_DATA_SWITCHBOX_H_ -#define BF_ASM_DATA_SWITCHBOX_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_DATA_SWITCHBOX_H_ +#define BACKENDS_TOFINO_BF_ASM_DATA_SWITCHBOX_H_ -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" /* * Code to handle programming of the Ram Data Bus Horizontal/Vertical Switchbox @@ -165,4 +165,4 @@ class DataSwitchboxSetup { } }; -#endif /* BF_ASM_DATA_SWITCHBOX_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_DATA_SWITCHBOX_H_ */ diff --git a/backends/tofino/bf-asm/deparser.cpp b/backends/tofino/bf-asm/deparser.cpp index c3c2280f29a..0fdbfb3c55e 100644 --- a/backends/tofino/bf-asm/deparser.cpp +++ b/backends/tofino/bf-asm/deparser.cpp @@ -23,8 +23,8 @@ #include "misc.h" #include "parser-tofino-jbay.h" #include "phv.h" -#include "range.h" -#include "target.h" +#include "lib/range.h" +#include "backends/tofino/bf-asm/target.h" #include "top_level.h" #include "ubits.h" diff --git a/backends/tofino/bf-asm/deparser.h b/backends/tofino/bf-asm/deparser.h index 5136dd91fb5..1a655130946 100644 --- a/backends/tofino/bf-asm/deparser.h +++ b/backends/tofino/bf-asm/deparser.h @@ -22,9 +22,9 @@ #include -#include "bitops.h" +#include "lib/bitops.h" #include "constants.h" -#include "ordered_set.h" +#include "lib/ordered_set.h" #include "phv.h" #include "sections.h" diff --git a/backends/tofino/bf-asm/disasm.h b/backends/tofino/bf-asm/disasm.h index a59514a27be..285d6661fe8 100644 --- a/backends/tofino/bf-asm/disasm.h +++ b/backends/tofino/bf-asm/disasm.h @@ -18,7 +18,7 @@ #ifndef DISASM_H_ #define DISASM_H_ -#include "target.h" +#include "backends/tofino/bf-asm/target.h" class Disasm { public: diff --git a/backends/tofino/bf-asm/dynhash.cpp b/backends/tofino/bf-asm/dynhash.cpp index c77779686d4..ec265328e8c 100644 --- a/backends/tofino/bf-asm/dynhash.cpp +++ b/backends/tofino/bf-asm/dynhash.cpp @@ -20,7 +20,7 @@ #include #include "bfas.h" -#include "json.h" +#include "backends/tofino/bf-asm/json.h" #include "sections.h" class DynHash : public Section { diff --git a/backends/tofino/bf-asm/error_mode.cpp b/backends/tofino/bf-asm/error_mode.cpp index 93f1d3c6793..4d888d1a775 100644 --- a/backends/tofino/bf-asm/error_mode.cpp +++ b/backends/tofino/bf-asm/error_mode.cpp @@ -17,7 +17,7 @@ #include "error_mode.h" -#include "stage.h" +#include "backends/tofino/bf-asm/stage.h" DefaultErrorMode DefaultErrorMode::singleton; diff --git a/backends/tofino/bf-asm/error_mode.h b/backends/tofino/bf-asm/error_mode.h index b5a6739cbac..b0d5cb75e0b 100644 --- a/backends/tofino/bf-asm/error_mode.h +++ b/backends/tofino/bf-asm/error_mode.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_ERROR_MODE_H_ -#define BF_ASM_ERROR_MODE_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_ERROR_MODE_H_ +#define BACKENDS_TOFINO_BF_ASM_ERROR_MODE_H_ #include "sections.h" @@ -70,4 +70,4 @@ class DefaultErrorMode : public Section, public ErrorMode { static ErrorMode get() { return singleton; } }; -#endif /* BF_ASM_ERROR_MODE_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_ERROR_MODE_H_ */ diff --git a/backends/tofino/bf-asm/escape.h b/backends/tofino/bf-asm/escape.h index cc76afa5ffd..22cd45f6ac1 100644 --- a/backends/tofino/bf-asm/escape.h +++ b/backends/tofino/bf-asm/escape.h @@ -15,13 +15,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_ESCAPE_H_ -#define BF_ASM_ESCAPE_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_ESCAPE_H_ +#define BACKENDS_TOFINO_BF_ASM_ESCAPE_H_ #include #include -#include "hex.h" +#include "lib/hex.h" class escape { std::string str; @@ -53,4 +53,4 @@ inline std::ostream &operator<<(std::ostream &os, escape e) { return os; } -#endif /* BF_ASM_ESCAPE_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_ESCAPE_H_ */ diff --git a/backends/tofino/bf-asm/exact_match.cpp b/backends/tofino/bf-asm/exact_match.cpp index a92d49c7297..2f891189b4a 100644 --- a/backends/tofino/bf-asm/exact_match.cpp +++ b/backends/tofino/bf-asm/exact_match.cpp @@ -18,14 +18,14 @@ #include "tofino/exact_match.h" #include "action_bus.h" -#include "algorithm.h" +#include "lib/algorithm.h" #include "hashexpr.h" -#include "hex.h" +#include "lib/hex.h" #include "input_xbar.h" #include "instruction.h" #include "misc.h" -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" void ExactMatchTable::setup(VECTOR(pair_t) & data) { common_init_setup(data, false, P4Table::MatchEntry); diff --git a/backends/tofino/bf-asm/exename.h b/backends/tofino/bf-asm/exename.h index 957775dc58f..4e2523b5daf 100644 --- a/backends/tofino/bf-asm/exename.h +++ b/backends/tofino/bf-asm/exename.h @@ -15,11 +15,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_EXENAME_H_ -#define BF_ASM_EXENAME_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_EXENAME_H_ +#define BACKENDS_TOFINO_BF_ASM_EXENAME_H_ /** Attempt to determine the executable name and return a static path to it. Will use * argv0 if provided and nothing better can be found */ const char *exename(const char *argv0 = nullptr); -#endif /* BF_ASM_EXENAME_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_EXENAME_H_ */ diff --git a/backends/tofino/bf-asm/fdstream.h b/backends/tofino/bf-asm/fdstream.h index 524414374ed..8cd4fb96775 100644 --- a/backends/tofino/bf-asm/fdstream.h +++ b/backends/tofino/bf-asm/fdstream.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_FDSTREAM_H_ -#define BF_ASM_FDSTREAM_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_FDSTREAM_H_ +#define BACKENDS_TOFINO_BF_ASM_FDSTREAM_H_ #include #include @@ -58,4 +58,4 @@ class fdstream : public std::iostream { void setclose(std::function fn) { closefn = fn; } }; -#endif /* BF_ASM_FDSTREAM_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_FDSTREAM_H_ */ diff --git a/backends/tofino/bf-asm/flexible_headers.cpp b/backends/tofino/bf-asm/flexible_headers.cpp index e485b834e28..37a1b75683f 100644 --- a/backends/tofino/bf-asm/flexible_headers.cpp +++ b/backends/tofino/bf-asm/flexible_headers.cpp @@ -15,7 +15,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include "backends/tofino/bf-asm/sections.h" #include diff --git a/backends/tofino/bf-asm/gateway.cpp b/backends/tofino/bf-asm/gateway.cpp index f669f9b9d9b..26bb8a99cdd 100644 --- a/backends/tofino/bf-asm/gateway.cpp +++ b/backends/tofino/bf-asm/gateway.cpp @@ -15,14 +15,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "algorithm.h" +#include "lib/algorithm.h" #include "hashexpr.h" -#include "hex.h" +#include "lib/hex.h" #include "input_xbar.h" #include "instruction.h" #include "misc.h" -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" // template specialization declarations #include "jbay/gateway.h" diff --git a/backends/tofino/bf-asm/gtest/gateway.cpp b/backends/tofino/bf-asm/gtest/gateway.cpp index e6a8e7ed060..66c531438df 100644 --- a/backends/tofino/bf-asm/gtest/gateway.cpp +++ b/backends/tofino/bf-asm/gtest/gateway.cpp @@ -17,7 +17,7 @@ #include "bfas.h" #include "gtest/gtest.h" -#include "stage.h" +#include "backends/tofino/bf-asm/stage.h" namespace { diff --git a/backends/tofino/bf-asm/gtest/hashexpr.cpp b/backends/tofino/bf-asm/gtest/hashexpr.cpp index 24410349b95..97146185eb5 100644 --- a/backends/tofino/bf-asm/gtest/hashexpr.cpp +++ b/backends/tofino/bf-asm/gtest/hashexpr.cpp @@ -19,7 +19,7 @@ #include "bfas.h" #include "gtest/gtest.h" -#include "stage.h" +#include "backends/tofino/bf-asm/stage.h" namespace { diff --git a/backends/tofino/bf-asm/gtest/register-matcher.h b/backends/tofino/bf-asm/gtest/register-matcher.h index 7cfed4482a3..1e138882b3f 100644 --- a/backends/tofino/bf-asm/gtest/register-matcher.h +++ b/backends/tofino/bf-asm/gtest/register-matcher.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_GTEST_REGISTER_MATCHER_H_ -#define BF_ASM_GTEST_REGISTER_MATCHER_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_GTEST_REGISTER_MATCHER_H_ +#define BACKENDS_TOFINO_BF_ASM_GTEST_REGISTER_MATCHER_H_ #include #include @@ -64,4 +64,4 @@ class RegisterMatcher { } \ } while (false) -#endif /* BF_ASM_GTEST_REGISTER_MATCHER_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_GTEST_REGISTER_MATCHER_H_ */ diff --git a/backends/tofino/bf-asm/hash_action.cpp b/backends/tofino/bf-asm/hash_action.cpp index 2095fe0fe01..88ac15645bb 100644 --- a/backends/tofino/bf-asm/hash_action.cpp +++ b/backends/tofino/bf-asm/hash_action.cpp @@ -20,8 +20,8 @@ #include "action_bus.h" #include "input_xbar.h" #include "misc.h" -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" // target specific instantiatitions diff --git a/backends/tofino/bf-asm/hash_dist.cpp b/backends/tofino/bf-asm/hash_dist.cpp index 1a61eeb3ddf..1240a7557ac 100644 --- a/backends/tofino/bf-asm/hash_dist.cpp +++ b/backends/tofino/bf-asm/hash_dist.cpp @@ -19,8 +19,8 @@ #include -#include "range.h" -#include "stage.h" +#include "lib/range.h" +#include "backends/tofino/bf-asm/stage.h" static void set_output_bit(unsigned &xbar_use, value_t &v) { if (CHECKTYPE(v, tSTR)) { diff --git a/backends/tofino/bf-asm/hash_dist.h b/backends/tofino/bf-asm/hash_dist.h index f673c032b3a..de8005d754c 100644 --- a/backends/tofino/bf-asm/hash_dist.h +++ b/backends/tofino/bf-asm/hash_dist.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_HASH_DIST_H_ -#define BF_ASM_HASH_DIST_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_HASH_DIST_H_ +#define BACKENDS_TOFINO_BF_ASM_HASH_DIST_H_ #include @@ -58,4 +58,4 @@ struct HashDistribution { void write_regs(REGS ®s, Table *); }; -#endif /* BF_ASM_HASH_DIST_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_HASH_DIST_H_ */ diff --git a/backends/tofino/bf-asm/hashdump.cpp b/backends/tofino/bf-asm/hashdump.cpp index 462bc613b6f..459d866a3a6 100644 --- a/backends/tofino/bf-asm/hashdump.cpp +++ b/backends/tofino/bf-asm/hashdump.cpp @@ -19,8 +19,8 @@ #include #include "gen/tofino/disas.regs.mau_addrmap.h" -#include "hex.h" -#include "json.h" +#include "lib/hex.h" +#include "backends/tofino/bf-asm/json.h" static Tofino::regs_mau_addrmap regs; diff --git a/backends/tofino/bf-asm/hashexpr.cpp b/backends/tofino/bf-asm/hashexpr.cpp index 1e951aec5bc..75e8c85715d 100644 --- a/backends/tofino/bf-asm/hashexpr.cpp +++ b/backends/tofino/bf-asm/hashexpr.cpp @@ -17,8 +17,8 @@ #include "hashexpr.h" -#include "bitops.h" -#include "bitvec.h" +#include "lib/bitops.h" +#include "lib/bitvec.h" #include "input_xbar.h" static bitvec crc(bitvec poly, bitvec val) { diff --git a/backends/tofino/bf-asm/hashexpr.h b/backends/tofino/bf-asm/hashexpr.h index 1764d3e6000..cb63eca5e34 100644 --- a/backends/tofino/bf-asm/hashexpr.h +++ b/backends/tofino/bf-asm/hashexpr.h @@ -15,10 +15,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_HASHEXPR_H_ -#define BF_ASM_HASHEXPR_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_HASHEXPR_H_ +#define BACKENDS_TOFINO_BF_ASM_HASHEXPR_H_ -#include "dynamic_hash/dynamic_hash.h" +#include "backends/tofino/bf-utils/dynamic_hash/dynamic_hash.h" #include "input_xbar.h" #include "phv.h" @@ -74,4 +74,4 @@ class HashExpr : public IHasDbPrint { extern void dump(const HashExpr *); extern void dump(const HashExpr &); -#endif /* BF_ASM_HASHEXPR_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_HASHEXPR_H_ */ diff --git a/backends/tofino/bf-asm/idletime.cpp b/backends/tofino/bf-asm/idletime.cpp index 55e0fff0f86..6ad20c59bbe 100644 --- a/backends/tofino/bf-asm/idletime.cpp +++ b/backends/tofino/bf-asm/idletime.cpp @@ -16,8 +16,8 @@ */ #include "misc.h" -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" void IdletimeTable::setup(VECTOR(pair_t) & data) { setup_layout(layout, data); diff --git a/backends/tofino/bf-asm/input_xbar.cpp b/backends/tofino/bf-asm/input_xbar.cpp index 28696802be5..a1dae55a8b6 100644 --- a/backends/tofino/bf-asm/input_xbar.cpp +++ b/backends/tofino/bf-asm/input_xbar.cpp @@ -23,16 +23,16 @@ #include #include "hashexpr.h" -#include "log.h" +#include "lib/log.h" #include "misc.h" #include "power_ctl.h" -#include "range.h" -#include "stage.h" -#include "tables.h" +#include "lib/range.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" // template specialization declarations -#include "jbay/input_xbar.h" -#include "tofino/input_xbar.h" +#include "backends/tofino/bf-asm/jbay/input_xbar.h" +#include "backends/tofino/bf-asm/tofino/input_xbar.h" void HashCol::dbprint(std::ostream &out) const { out << "HashCol: " << " lineno: " << lineno << " bit: " << bit << " data: " << data diff --git a/backends/tofino/bf-asm/input_xbar.h b/backends/tofino/bf-asm/input_xbar.h index 70a5b1780b0..772ba492eab 100644 --- a/backends/tofino/bf-asm/input_xbar.h +++ b/backends/tofino/bf-asm/input_xbar.h @@ -15,14 +15,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_INPUT_XBAR_H_ -#define BF_ASM_INPUT_XBAR_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_INPUT_XBAR_H_ +#define BACKENDS_TOFINO_BF_ASM_INPUT_XBAR_H_ #include +#include "backends/tofino/bf-utils/dynamic_hash/dynamic_hash.h" #include "constants.h" -#include "dynamic_hash/dynamic_hash.h" -#include "ordered_map.h" +#include "lib/ordered_map.h" #include "phv.h" class Table; @@ -364,4 +364,4 @@ inline std::ostream &operator<<(std::ostream &out, InputXbar::HashTable ht) { return out << " hashtable " << ht.index; } -#endif /* BF_ASM_INPUT_XBAR_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_INPUT_XBAR_H_ */ diff --git a/backends/tofino/bf-asm/instruction.cpp b/backends/tofino/bf-asm/instruction.cpp index e8a086f0883..0878f2138dc 100644 --- a/backends/tofino/bf-asm/instruction.cpp +++ b/backends/tofino/bf-asm/instruction.cpp @@ -23,8 +23,8 @@ #include "depositfield.h" #include "phv.h" #include "power_ctl.h" -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" namespace { constexpr int RotationBits = 16; diff --git a/backends/tofino/bf-asm/instruction.h b/backends/tofino/bf-asm/instruction.h index 5e2c41df92d..795012985c5 100644 --- a/backends/tofino/bf-asm/instruction.h +++ b/backends/tofino/bf-asm/instruction.h @@ -15,14 +15,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_INSTRUCTION_H_ -#define BF_ASM_INSTRUCTION_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_INSTRUCTION_H_ +#define BACKENDS_TOFINO_BF_ASM_INSTRUCTION_H_ #include #include -#include "tables.h" +#include "backends/tofino/bf-asm/tables.h" struct Instruction : public IHasDbPrint { int lineno; @@ -72,4 +72,4 @@ std::unique_ptr genNoopFill(Table *tbl, Table::Actions::Action *act int slot); } -#endif /* BF_ASM_INSTRUCTION_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_INSTRUCTION_H_ */ diff --git a/backends/tofino/bf-asm/jbay/counter.h b/backends/tofino/bf-asm/jbay/counter.h index 826c4e6af1f..0b6655964ab 100644 --- a/backends/tofino/bf-asm/jbay/counter.h +++ b/backends/tofino/bf-asm/jbay/counter.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_JBAY_COUNTER_H_ -#define BF_ASM_JBAY_COUNTER_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_JBAY_COUNTER_H_ +#define BACKENDS_TOFINO_BF_ASM_JBAY_COUNTER_H_ template void CounterTable::setup_teop_regs_2(REGS ®s, int stats_group_index) { @@ -118,4 +118,4 @@ void CounterTable::write_alu_vpn_range(Target::JBay::mau_regs ®s) { write_alu_vpn_range_2(regs); } -#endif /* BF_ASM_JBAY_COUNTER_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_JBAY_COUNTER_H_ */ diff --git a/backends/tofino/bf-asm/jbay/gateway.cpp b/backends/tofino/bf-asm/jbay/gateway.cpp index 1e163400737..9f7da083748 100644 --- a/backends/tofino/bf-asm/jbay/gateway.cpp +++ b/backends/tofino/bf-asm/jbay/gateway.cpp @@ -15,9 +15,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "gateway.h" +#include "backends/tofino/bf-asm/jbay/gateway.h" -#include +#include "backends/tofino/bf-asm/stage.h" void Target::Tofino::GatewayTable::write_next_table_regs(Target::JBay::mau_regs ®s) { auto &merge = regs.rams.match.merge; diff --git a/backends/tofino/bf-asm/jbay/gateway.h b/backends/tofino/bf-asm/jbay/gateway.h index 08e1b0e9929..107cafe068e 100644 --- a/backends/tofino/bf-asm/jbay/gateway.h +++ b/backends/tofino/bf-asm/jbay/gateway.h @@ -15,16 +15,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_JBAY_GATEWAY_H_ -#define BF_ASM_JBAY_GATEWAY_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_JBAY_GATEWAY_H_ +#define BACKENDS_TOFINO_BF_ASM_JBAY_GATEWAY_H_ -#include - -#include +#include "backends/tofino/bf-asm/tofino/gateway.h" +#include "backends/tofino/bf-asm/tables.h" #if HAVE_JBAY template <> void GatewayTable::standalone_write_regs(Target::JBay::mau_regs ®s); #endif /* HAVE_JBAY */ -#endif /* BF_ASM_JBAY_GATEWAY_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_JBAY_GATEWAY_H_ */ diff --git a/backends/tofino/bf-asm/jbay/input_xbar.cpp b/backends/tofino/bf-asm/jbay/input_xbar.cpp index 8a9d9d58adb..e0e7e7e61b7 100644 --- a/backends/tofino/bf-asm/jbay/input_xbar.cpp +++ b/backends/tofino/bf-asm/jbay/input_xbar.cpp @@ -15,7 +15,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "input_xbar.h" +#include "backends/tofino/bf-asm/jbay/input_xbar.h" template <> void InputXbar::write_galois_matrix(Target::JBay::mau_regs ®s, HashTable id, diff --git a/backends/tofino/bf-asm/jbay/input_xbar.h b/backends/tofino/bf-asm/jbay/input_xbar.h index ebe850219fb..766b714ef13 100644 --- a/backends/tofino/bf-asm/jbay/input_xbar.h +++ b/backends/tofino/bf-asm/jbay/input_xbar.h @@ -15,10 +15,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_JBAY_INPUT_XBAR_H_ -#define BF_ASM_JBAY_INPUT_XBAR_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_JBAY_INPUT_XBAR_H_ +#define BACKENDS_TOFINO_BF_ASM_JBAY_INPUT_XBAR_H_ -#include +#include "backends/tofino/bf-asm/input_xbar.h" #if HAVE_JBAY template <> @@ -26,4 +26,4 @@ void InputXbar::write_galois_matrix(Target::JBay::mau_regs ®s, HashTable id, const std::map &mat); #endif /* HAVE_JBAY */ -#endif /* BF_ASM_JBAY_INPUT_XBAR_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_JBAY_INPUT_XBAR_H_ */ diff --git a/backends/tofino/bf-asm/jbay/meter.h b/backends/tofino/bf-asm/jbay/meter.h index 7071025ff2f..f6c8e6ef449 100644 --- a/backends/tofino/bf-asm/jbay/meter.h +++ b/backends/tofino/bf-asm/jbay/meter.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_JBAY_METER_H_ -#define BF_ASM_JBAY_METER_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_JBAY_METER_H_ +#define BACKENDS_TOFINO_BF_ASM_JBAY_METER_H_ template void MeterTable::setup_teop_regs_2(REGS ®s, int meter_group_index) { @@ -137,4 +137,4 @@ void MeterTable::write_alu_vpn_range(Target::JBay::mau_regs ®s) { write_alu_vpn_range_2(regs); } -#endif /* BF_ASM_JBAY_METER_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_JBAY_METER_H_ */ diff --git a/backends/tofino/bf-asm/jbay/parser.cpp b/backends/tofino/bf-asm/jbay/parser.cpp index 4a6a07e83ea..34948f0180d 100644 --- a/backends/tofino/bf-asm/jbay/parser.cpp +++ b/backends/tofino/bf-asm/jbay/parser.cpp @@ -15,9 +15,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "parser-tofino-jbay.h" -#include "stage.h" -#include "top_level.h" +#include "backends/tofino/bf-asm/parser-tofino-jbay.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/top_level.h" template <> void Parser::Checksum::write_config(Target::JBay::parser_regs ®s, Parser *parser) { diff --git a/backends/tofino/bf-asm/jbay/phv.cpp b/backends/tofino/bf-asm/jbay/phv.cpp index 96612045a0d..ba01b84ae00 100644 --- a/backends/tofino/bf-asm/jbay/phv.cpp +++ b/backends/tofino/bf-asm/jbay/phv.cpp @@ -15,7 +15,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "phv.h" +#include "backends/tofino/bf-asm/jbay/phv.h" void Target::JBay::Phv::init_regs(::Phv &phv) { // Allocating JBay regs so the uids map to mau register encodings diff --git a/backends/tofino/bf-asm/jbay/phv.h b/backends/tofino/bf-asm/jbay/phv.h index 965e1c899d2..92b7af5532a 100644 --- a/backends/tofino/bf-asm/jbay/phv.h +++ b/backends/tofino/bf-asm/jbay/phv.h @@ -15,10 +15,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_JBAY_PHV_H_ -#define BF_ASM_JBAY_PHV_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_JBAY_PHV_H_ +#define BACKENDS_TOFINO_BF_ASM_JBAY_PHV_H_ -#include "../phv.h" +#include "backends/tofino/bf-asm/phv.h" class Target::JBay::Phv : public Target::Phv { friend class ::Phv; @@ -53,4 +53,4 @@ class Target::Tofino2A0::Phv : public Target::JBay::Phv { target_t type() const override { return TOFINO2A0; } }; -#endif /* BF_ASM_JBAY_PHV_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_JBAY_PHV_H_ */ diff --git a/backends/tofino/bf-asm/jbay/stateful.cpp b/backends/tofino/bf-asm/jbay/stateful.cpp index 9bb9737fd07..a429828b723 100644 --- a/backends/tofino/bf-asm/jbay/stateful.cpp +++ b/backends/tofino/bf-asm/jbay/stateful.cpp @@ -15,7 +15,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "stateful.h" +#include "backends/tofino/bf-asm/jbay/stateful.h" static const char *function_names[] = {"none", "log", "fifo", "stack", "clear"}; diff --git a/backends/tofino/bf-asm/jbay/stateful.h b/backends/tofino/bf-asm/jbay/stateful.h index 3be1ab3aaaa..57e67544515 100644 --- a/backends/tofino/bf-asm/jbay/stateful.h +++ b/backends/tofino/bf-asm/jbay/stateful.h @@ -15,11 +15,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_JBAY_STATEFUL_H_ -#define BF_ASM_JBAY_STATEFUL_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_JBAY_STATEFUL_H_ +#define BACKENDS_TOFINO_BF_ASM_JBAY_STATEFUL_H_ -#include -#include +#include "backends/tofino/bf-asm/tables.h" +#include "backends/tofino/bf-asm/target.h" #if HAVE_JBAY @@ -57,4 +57,4 @@ template <> void StatefulTable::write_logging_regs(Target::JBay::mau_regs ®s); #endif /* HAVE_JBAY || || */ -#endif /* BF_ASM_JBAY_STATEFUL_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_JBAY_STATEFUL_H_ */ diff --git a/backends/tofino/bf-asm/json.cpp b/backends/tofino/bf-asm/json.cpp index 694bd424f72..4f1d1572024 100644 --- a/backends/tofino/bf-asm/json.cpp +++ b/backends/tofino/bf-asm/json.cpp @@ -15,12 +15,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "json.h" +#include "backends/tofino/bf-asm/json.h" #include #include -#include "hex.h" +#include "lib/hex.h" namespace json { diff --git a/backends/tofino/bf-asm/json.h b/backends/tofino/bf-asm/json.h index a4ff1777b3a..3d8a926682d 100644 --- a/backends/tofino/bf-asm/json.h +++ b/backends/tofino/bf-asm/json.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_JSON_H_ // NOLINT(build/header_guard) -#define BF_ASM_JSON_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_JSON_H_ // NOLINT(build/header_guard) +#define BACKENDS_TOFINO_BF_ASM_JSON_H_ #include @@ -29,7 +29,7 @@ #include #include -#include "ordered_map.h" +#include "lib/ordered_map.h" #include "rvalue_reference_wrapper.h" using namespace P4; @@ -636,4 +636,4 @@ inline std::ostream &operator<<(std::ostream &out, const map::element_ref &el) { extern void dump(const json::obj *); extern void dump(const json::obj &); -#endif /* BF_ASM_JSON_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_JSON_H_ */ diff --git a/backends/tofino/bf-asm/json_diff.cpp b/backends/tofino/bf-asm/json_diff.cpp index 554dc117ca6..61f1a566674 100644 --- a/backends/tofino/bf-asm/json_diff.cpp +++ b/backends/tofino/bf-asm/json_diff.cpp @@ -21,8 +21,8 @@ #include #include "fdstream.h" -#include "json.h" -#include "ordered_map.h" +#include "backends/tofino/bf-asm/json.h" +#include "lib/ordered_map.h" static bool show_deletion = true; static bool show_addition = true; diff --git a/backends/tofino/bf-asm/map.h b/backends/tofino/bf-asm/map.h index 965b2e6029b..07cd6567691 100644 --- a/backends/tofino/bf-asm/map.h +++ b/backends/tofino/bf-asm/map.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_MAP_H_ -#define BF_ASM_MAP_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_MAP_H_ +#define BACKENDS_TOFINO_BF_ASM_MAP_H_ #include @@ -252,4 +252,4 @@ MapForKey ValuesForKey(M &m, typename M::key_type k) { return MapForKey(m, k); } -#endif /* BF_ASM_MAP_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_MAP_H_ */ diff --git a/backends/tofino/bf-asm/mask_counter.h b/backends/tofino/bf-asm/mask_counter.h index 9628563cb5b..caa93b1d696 100644 --- a/backends/tofino/bf-asm/mask_counter.h +++ b/backends/tofino/bf-asm/mask_counter.h @@ -15,12 +15,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_MASK_COUNTER_H_ -#define BF_ASM_MASK_COUNTER_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_MASK_COUNTER_H_ +#define BACKENDS_TOFINO_BF_ASM_MASK_COUNTER_H_ #include -#include "bitvec.h" +#include "lib/bitvec.h" class MaskCounter { unsigned mask, val; @@ -62,4 +62,4 @@ class MaskCounter { } }; -#endif /* BF_ASM_MASK_COUNTER_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_MASK_COUNTER_H_ */ diff --git a/backends/tofino/bf-asm/match_source.h b/backends/tofino/bf-asm/match_source.h index c58a4e8a252..1f600e2813e 100644 --- a/backends/tofino/bf-asm/match_source.h +++ b/backends/tofino/bf-asm/match_source.h @@ -15,11 +15,14 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef BACKENDS_TOFINO_BF_ASM_MATCH_SOURCE_H_ +#define BACKENDS_TOFINO_BF_ASM_MATCH_SOURCE_H_ + #include #include -#ifndef BF_ASM_MATCH_SOURCE_H_ -#define BF_ASM_MATCH_SOURCE_H_ +#include "backends/tofino/bf-asm/asm-types.h" +#include "lib/stringify.h" /** * A source for a match key of a table. The source can either be from the input xbar, or from the @@ -78,4 +81,4 @@ class HashMatchSource : public MatchSource { void dbprint(std::ostream &out) const { out << name() << "(" << lo << ".." << hi << ")"; } }; -#endif /* BF_ASM_MATCH_SOURCE_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_MATCH_SOURCE_H_ */ diff --git a/backends/tofino/bf-asm/match_table.cpp b/backends/tofino/bf-asm/match_table.cpp index 9fa48fd1a2e..53efe5b29d9 100644 --- a/backends/tofino/bf-asm/match_table.cpp +++ b/backends/tofino/bf-asm/match_table.cpp @@ -20,12 +20,12 @@ #include #include "action_bus.h" -#include "algorithm.h" +#include "lib/algorithm.h" #include "input_xbar.h" #include "instruction.h" #include "misc.h" -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" Table::Format *MatchTable::get_format() const { if (!format && gateway) return gateway->get_format(); diff --git a/backends/tofino/bf-asm/meter.cpp b/backends/tofino/bf-asm/meter.cpp index e44206a6804..11f3bb7280e 100644 --- a/backends/tofino/bf-asm/meter.cpp +++ b/backends/tofino/bf-asm/meter.cpp @@ -18,8 +18,8 @@ #include "data_switchbox.h" #include "input_xbar.h" #include "misc.h" -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" // target specific template specializations #include "tofino/meter.h" diff --git a/backends/tofino/bf-asm/misc.cpp b/backends/tofino/bf-asm/misc.cpp index 6c2c39020b4..9d46e663068 100644 --- a/backends/tofino/bf-asm/misc.cpp +++ b/backends/tofino/bf-asm/misc.cpp @@ -22,7 +22,7 @@ #include #include "bfas.h" -#include "target.h" +#include "backends/tofino/bf-asm/target.h" int remove_name_tail_range(std::string &name, int *size) { auto tail = name.rfind('.'); diff --git a/backends/tofino/bf-asm/misc.h b/backends/tofino/bf-asm/misc.h index 9aa7da5e83a..910e666a632 100644 --- a/backends/tofino/bf-asm/misc.h +++ b/backends/tofino/bf-asm/misc.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_MISC_H_ -#define BF_ASM_MISC_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_MISC_H_ +#define BACKENDS_TOFINO_BF_ASM_MISC_H_ #include #include @@ -29,7 +29,7 @@ #include #include "asm-types.h" -#include "json.h" +#include "backends/tofino/bf-asm/json.h" template auto setup_muxctl(T ®, int val) -> decltype((void)reg.enabled_2bit_muxctl_enable) { @@ -215,4 +215,4 @@ bool input_int_match(const value_t value, match_t &match, int width); /// @return True if the given keys are a subset of the map's keys bool require_keys(const value_t &data, std::set keys); -#endif /* BF_ASM_MISC_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_MISC_H_ */ diff --git a/backends/tofino/bf-asm/p4_table.cpp b/backends/tofino/bf-asm/p4_table.cpp index 6b8b2a185f6..e6461273822 100644 --- a/backends/tofino/bf-asm/p4_table.cpp +++ b/backends/tofino/bf-asm/p4_table.cpp @@ -17,7 +17,7 @@ #include "p4_table.h" -#include "tables.h" +#include "backends/tofino/bf-asm/tables.h" static std::map alpms; diff --git a/backends/tofino/bf-asm/p4_table.h b/backends/tofino/bf-asm/p4_table.h index 183690764c0..6b937c7539d 100644 --- a/backends/tofino/bf-asm/p4_table.h +++ b/backends/tofino/bf-asm/p4_table.h @@ -15,14 +15,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_P4_TABLE_H_ -#define BF_ASM_P4_TABLE_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_P4_TABLE_H_ +#define BACKENDS_TOFINO_BF_ASM_P4_TABLE_H_ #include #include #include "asm-types.h" -#include "json.h" +#include "backends/tofino/bf-asm/json.h" class Table; class P4Table; @@ -91,4 +91,4 @@ class P4Table { static std::string direction_name(gress_t); }; -#endif /* BF_ASM_P4_TABLE_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_P4_TABLE_H_ */ diff --git a/backends/tofino/bf-asm/parser-tofino-jbay.cpp b/backends/tofino/bf-asm/parser-tofino-jbay.cpp index d5e3d17b21c..69509e0d8c4 100644 --- a/backends/tofino/bf-asm/parser-tofino-jbay.cpp +++ b/backends/tofino/bf-asm/parser-tofino-jbay.cpp @@ -19,14 +19,14 @@ #include -#include "algorithm.h" +#include "lib/algorithm.h" #include "constants.h" #include "misc.h" -#include "ordered_set.h" +#include "lib/ordered_set.h" #include "phv.h" -#include "range.h" -#include "stage.h" -#include "target.h" +#include "lib/range.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/target.h" #include "top_level.h" #include "vector.h" diff --git a/backends/tofino/bf-asm/parser-tofino-jbay.h b/backends/tofino/bf-asm/parser-tofino-jbay.h index 7fe0329897b..f195ab42532 100644 --- a/backends/tofino/bf-asm/parser-tofino-jbay.h +++ b/backends/tofino/bf-asm/parser-tofino-jbay.h @@ -22,11 +22,11 @@ #include #include -#include "bitvec.h" +#include "lib/bitvec.h" #include "parser.h" #include "phv.h" #include "sections.h" -#include "target.h" +#include "backends/tofino/bf-asm/target.h" #include "ubits.h" enum { diff --git a/backends/tofino/bf-asm/parser.h b/backends/tofino/bf-asm/parser.h index eadde8592e2..3e2ef2a47f8 100644 --- a/backends/tofino/bf-asm/parser.h +++ b/backends/tofino/bf-asm/parser.h @@ -15,13 +15,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_PARSER_H_ -#define BF_ASM_PARSER_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_PARSER_H_ +#define BACKENDS_TOFINO_BF_ASM_PARSER_H_ #include "asm-types.h" -#include "json.h" +#include "backends/tofino/bf-asm/json.h" #include "sections.h" -#include "target.h" +#include "backends/tofino/bf-asm/target.h" #include "vector.h" /** @@ -42,4 +42,4 @@ class BaseAsmParser : public Section { explicit BaseAsmParser(const char *name_) : Section(name_) {} }; -#endif /* BF_ASM_PARSER_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_PARSER_H_ */ diff --git a/backends/tofino/bf-asm/phase0.cpp b/backends/tofino/bf-asm/phase0.cpp index d29f908608d..54bb63d761c 100644 --- a/backends/tofino/bf-asm/phase0.cpp +++ b/backends/tofino/bf-asm/phase0.cpp @@ -16,8 +16,8 @@ */ #include "parser-tofino-jbay.h" -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" DEFINE_TABLE_TYPE(Phase0MatchTable) diff --git a/backends/tofino/bf-asm/phv.cpp b/backends/tofino/bf-asm/phv.cpp index 370270a3a1a..065b3fb6f01 100644 --- a/backends/tofino/bf-asm/phv.cpp +++ b/backends/tofino/bf-asm/phv.cpp @@ -20,7 +20,7 @@ #include #include -#include "log.h" +#include "lib/log.h" #include "misc.h" Phv Phv::phv; diff --git a/backends/tofino/bf-asm/phv.h b/backends/tofino/bf-asm/phv.h index cf1b0fd7de2..3420d81883b 100644 --- a/backends/tofino/bf-asm/phv.h +++ b/backends/tofino/bf-asm/phv.h @@ -15,19 +15,19 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_PHV_H_ -#define BF_ASM_PHV_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_PHV_H_ +#define BACKENDS_TOFINO_BF_ASM_PHV_H_ #include #include #include "bfas.h" -#include "bitvec.h" -#include "json.h" +#include "lib/bitvec.h" +#include "backends/tofino/bf-asm/json.h" #include "match_source.h" #include "misc.h" #include "sections.h" -#include "target.h" +#include "backends/tofino/bf-asm/target.h" class Phv : public Section { void start(int lineno, VECTOR(value_t) args) override; @@ -326,4 +326,4 @@ inline unsigned Phv::mau_groupsize() { return phv.target->mau_groupsize(); } #include "jbay/phv.h" #endif /* HAVE_JBAY */ -#endif /* BF_ASM_PHV_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_PHV_H_ */ diff --git a/backends/tofino/bf-asm/power_ctl.h b/backends/tofino/bf-asm/power_ctl.h index 05bd315887b..cbae87a075b 100644 --- a/backends/tofino/bf-asm/power_ctl.h +++ b/backends/tofino/bf-asm/power_ctl.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_POWER_CTL_H_ -#define BF_ASM_POWER_CTL_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_POWER_CTL_H_ +#define BACKENDS_TOFINO_BF_ASM_POWER_CTL_H_ #include "misc.h" @@ -62,4 +62,4 @@ void set_power_ctl_reg(checked_array<2, checked_array<16, ubits>> &power_ctl, power_ctl[side][reg / I] |= 1U << reg % I; } -#endif /* BF_ASM_POWER_CTL_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_POWER_CTL_H_ */ diff --git a/backends/tofino/bf-asm/primitives.cpp b/backends/tofino/bf-asm/primitives.cpp index 65689e339fe..828507439e0 100644 --- a/backends/tofino/bf-asm/primitives.cpp +++ b/backends/tofino/bf-asm/primitives.cpp @@ -20,8 +20,8 @@ #include #include "bfas.h" -#include "json.h" -#include "log.h" +#include "backends/tofino/bf-asm/json.h" +#include "lib/log.h" #include "sections.h" class Primitives : public Section { diff --git a/backends/tofino/bf-asm/proxy_hash.cpp b/backends/tofino/bf-asm/proxy_hash.cpp index 543b0189f88..0fb38d3f3b0 100644 --- a/backends/tofino/bf-asm/proxy_hash.cpp +++ b/backends/tofino/bf-asm/proxy_hash.cpp @@ -16,8 +16,8 @@ */ #include "input_xbar.h" -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" void ProxyHashMatchTable::setup(VECTOR(pair_t) & data) { common_init_setup(data, false, P4Table::MatchEntry); diff --git a/backends/tofino/bf-asm/register_reference.h b/backends/tofino/bf-asm/register_reference.h index 6d3c3c67c4a..12536d2dbbd 100644 --- a/backends/tofino/bf-asm/register_reference.h +++ b/backends/tofino/bf-asm/register_reference.h @@ -15,13 +15,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_REGISTER_REFERENCE_H_ -#define BF_ASM_REGISTER_REFERENCE_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_REGISTER_REFERENCE_H_ +#define BACKENDS_TOFINO_BF_ASM_REGISTER_REFERENCE_H_ #include #include -#include "log.h" +#include "lib/log.h" /* used by `dump_unread` methods to hold a concatenation of string literals for printing. * Allocated on the stack, the `pfx` chain prints the calling context */ @@ -108,4 +108,4 @@ inline std::ostream &operator<<(std::ostream &out, const register_reference return out; } -#endif /* BF_ASM_REGISTER_REFERENCE_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_REGISTER_REFERENCE_H_ */ diff --git a/backends/tofino/bf-asm/rvalue_reference_wrapper.h b/backends/tofino/bf-asm/rvalue_reference_wrapper.h index 81b361500d1..a86e4e946e3 100644 --- a/backends/tofino/bf-asm/rvalue_reference_wrapper.h +++ b/backends/tofino/bf-asm/rvalue_reference_wrapper.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_RVALUE_REFERENCE_WRAPPER_H_ -#define BF_ASM_RVALUE_REFERENCE_WRAPPER_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_RVALUE_REFERENCE_WRAPPER_H_ +#define BACKENDS_TOFINO_BF_ASM_RVALUE_REFERENCE_WRAPPER_H_ template class rvalue_reference_wrapper { @@ -30,4 +30,4 @@ class rvalue_reference_wrapper { T &&get() { return std::move(*ref); } }; -#endif /* BF_ASM_RVALUE_REFERENCE_WRAPPER_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_RVALUE_REFERENCE_WRAPPER_H_ */ diff --git a/backends/tofino/bf-asm/salu_inst.cpp b/backends/tofino/bf-asm/salu_inst.cpp index e6fef86a18f..8e8c36d90d2 100644 --- a/backends/tofino/bf-asm/salu_inst.cpp +++ b/backends/tofino/bf-asm/salu_inst.cpp @@ -21,11 +21,11 @@ #include -#include "hex.h" +#include "lib/hex.h" #include "instruction.h" #include "phv.h" -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" namespace StatefulAlu { diff --git a/backends/tofino/bf-asm/sections.h b/backends/tofino/bf-asm/sections.h index 9c08b73789e..414e23e3420 100644 --- a/backends/tofino/bf-asm/sections.h +++ b/backends/tofino/bf-asm/sections.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_SECTIONS_H_ -#define BF_ASM_SECTIONS_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_SECTIONS_H_ +#define BACKENDS_TOFINO_BF_ASM_SECTIONS_H_ #include @@ -24,7 +24,7 @@ #include "asm-types.h" #include "bfas.h" -#include "json.h" +#include "backends/tofino/bf-asm/json.h" #include "map.h" /// A Section represents a top level section in assembly @@ -101,4 +101,4 @@ class Section : virtual public Parsable, virtual public Contextable { static Section *test_get(const char *name) { return get(name); } }; -#endif /* BF_ASM_SECTIONS_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_SECTIONS_H_ */ diff --git a/backends/tofino/bf-asm/selection.cpp b/backends/tofino/bf-asm/selection.cpp index cfb923916bf..8b2ff359768 100644 --- a/backends/tofino/bf-asm/selection.cpp +++ b/backends/tofino/bf-asm/selection.cpp @@ -15,12 +15,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "algorithm.h" +#include "lib/algorithm.h" #include "data_switchbox.h" #include "input_xbar.h" #include "misc.h" -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" void SelectionTable::setup(VECTOR(pair_t) & data) { setup_layout(layout, data); diff --git a/backends/tofino/bf-asm/slist.h b/backends/tofino/bf-asm/slist.h index ca3948f1220..d68a7dd6bad 100644 --- a/backends/tofino/bf-asm/slist.h +++ b/backends/tofino/bf-asm/slist.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_SLIST_H_ -#define BF_ASM_SLIST_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_SLIST_H_ +#define BACKENDS_TOFINO_BF_ASM_SLIST_H_ template class slist { @@ -49,4 +49,4 @@ class slist { iterator end() const { return iterator(); } }; -#endif /* BF_ASM_SLIST_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_SLIST_H_ */ diff --git a/backends/tofino/bf-asm/sram_match.cpp b/backends/tofino/bf-asm/sram_match.cpp index 34be42ca43f..a7faa88ed32 100644 --- a/backends/tofino/bf-asm/sram_match.cpp +++ b/backends/tofino/bf-asm/sram_match.cpp @@ -15,15 +15,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "action_bus.h" -#include "algorithm.h" -#include "hex.h" -#include "input_xbar.h" -#include "instruction.h" -#include "mask_counter.h" -#include "misc.h" -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/action_bus.h" +#include "backends/tofino/bf-asm/input_xbar.h" +#include "backends/tofino/bf-asm/instruction.h" +#include "backends/tofino/bf-asm/mask_counter.h" +#include "backends/tofino/bf-asm/misc.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" +#include "lib/algorithm.h" +#include "lib/hex.h" Table::Format::Field *SRamMatchTable::lookup_field(const std::string &n, const std::string &act) const { diff --git a/backends/tofino/bf-asm/stage.cpp b/backends/tofino/bf-asm/stage.cpp index 2cec2bc17f9..ccabeab2be3 100644 --- a/backends/tofino/bf-asm/stage.cpp +++ b/backends/tofino/bf-asm/stage.cpp @@ -15,7 +15,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "stage.h" +#include "backends/tofino/bf-asm/stage.h" #include #include @@ -27,9 +27,9 @@ #include "misc.h" #include "parser.h" #include "phv.h" -#include "range.h" +#include "lib/range.h" #include "sections.h" -#include "target.h" +#include "backends/tofino/bf-asm/target.h" #include "top_level.h" extern std::string asmfile_name; diff --git a/backends/tofino/bf-asm/stage.h b/backends/tofino/bf-asm/stage.h index 89baab5c9f2..9ef5585768d 100644 --- a/backends/tofino/bf-asm/stage.h +++ b/backends/tofino/bf-asm/stage.h @@ -15,17 +15,17 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_STAGE_H_ -#define BF_ASM_STAGE_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_STAGE_H_ +#define BACKENDS_TOFINO_BF_ASM_STAGE_H_ #include #include #include "alloc.h" -#include "bitvec.h" +#include "lib/bitvec.h" #include "error_mode.h" #include "input_xbar.h" -#include "tables.h" +#include "backends/tofino/bf-asm/tables.h" class Stage_data { /* we encapsulate all the Stage non-static fields in a base class to automate the @@ -224,4 +224,4 @@ class AsmStage : public Section { } }; -#endif /* BF_ASM_STAGE_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_STAGE_H_ */ diff --git a/backends/tofino/bf-asm/stateful.cpp b/backends/tofino/bf-asm/stateful.cpp index b655a68baec..8fc9126fa77 100644 --- a/backends/tofino/bf-asm/stateful.cpp +++ b/backends/tofino/bf-asm/stateful.cpp @@ -17,14 +17,14 @@ #include "tofino/stateful.h" -#include "algorithm.h" +#include "lib/algorithm.h" #include "data_switchbox.h" #include "input_xbar.h" #include "instruction.h" #include "jbay/stateful.h" #include "misc.h" -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" void StatefulTable::parse_register_params(int idx, const value_t &val) { if (idx < 0 || idx > Target::STATEFUL_REGFILE_ROWS()) diff --git a/backends/tofino/bf-asm/synth2port.cpp b/backends/tofino/bf-asm/synth2port.cpp index 398bd4e2d84..44188811daa 100644 --- a/backends/tofino/bf-asm/synth2port.cpp +++ b/backends/tofino/bf-asm/synth2port.cpp @@ -15,12 +15,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "algorithm.h" +#include "lib/algorithm.h" #include "data_switchbox.h" #include "input_xbar.h" #include "misc.h" -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" void Synth2Port::common_init_setup(const VECTOR(pair_t) & data, bool, P4Table::type p4type) { setup_layout(layout, data); diff --git a/backends/tofino/bf-asm/tables.cpp b/backends/tofino/bf-asm/tables.cpp index fdebf2aa6ee..c5686f9c674 100644 --- a/backends/tofino/bf-asm/tables.cpp +++ b/backends/tofino/bf-asm/tables.cpp @@ -15,7 +15,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "tables.h" +#include "backends/tofino/bf-asm/tables.h" #include @@ -23,11 +23,11 @@ #include #include "action_bus.h" -#include "algorithm.h" +#include "lib/algorithm.h" #include "input_xbar.h" #include "instruction.h" #include "misc.h" -#include "stage.h" +#include "backends/tofino/bf-asm/stage.h" // template specialization declarations diff --git a/backends/tofino/bf-asm/tables.h b/backends/tofino/bf-asm/tables.h index 80ff23409f3..effa3ea9045 100644 --- a/backends/tofino/bf-asm/tables.h +++ b/backends/tofino/bf-asm/tables.h @@ -15,10 +15,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_TABLES_H_ // NOLINT(build/header_guard) -#define BF_ASM_TABLES_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_TABLES_H_ // NOLINT(build/header_guard) +#define BACKENDS_TOFINO_BF_ASM_TABLES_H_ -#include #include #include @@ -27,20 +26,21 @@ #include #include -#include "algorithm.h" +#include "lib/algorithm.h" #include "alloc.h" #include "asm-types.h" -#include "bitvec.h" #include "constants.h" #include "hash_dist.h" #include "input_xbar.h" -#include "json.h" +#include "backends/tofino/bf-asm/json.h" +#include "lib/bitops.h" +#include "lib/bitvec.h" +#include "lib/ordered_map.h" #include "map.h" -#include "ordered_map.h" #include "p4_table.h" #include "phv.h" #include "slist.h" -#include "target.h" +#include "backends/tofino/bf-asm/target.h" class ActionBus; struct ActionBusSource; @@ -2193,4 +2193,4 @@ DECLARE_TABLE_TYPE(StatefulTable, Synth2Port, "stateful", bool p4c_5192_workaround(const Actions::Action *) const; ) -#endif /* BF_ASM_TABLES_H_ */ // NOLINT(build/header_guard) +#endif /* BACKENDS_TOFINO_BF_ASM_TABLES_H_ */ // NOLINT(build/header_guard) diff --git a/backends/tofino/bf-asm/target.cpp b/backends/tofino/bf-asm/target.cpp index 89628f0eb32..5f55af35108 100644 --- a/backends/tofino/bf-asm/target.cpp +++ b/backends/tofino/bf-asm/target.cpp @@ -15,14 +15,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "target.h" +#include "backends/tofino/bf-asm/target.h" #include #include "asm-types.h" #include "bson.h" #include "parser.h" -#include "tables.h" +#include "backends/tofino/bf-asm/tables.h" #include "ubits.h" void declare_registers(const Target::Tofino::top_level_regs *regs) { diff --git a/backends/tofino/bf-asm/target.h b/backends/tofino/bf-asm/target.h index 3160c1cc9c5..81530e5c158 100644 --- a/backends/tofino/bf-asm/target.h +++ b/backends/tofino/bf-asm/target.h @@ -247,17 +247,17 @@ class Target { static int numMauStagesOverride; }; -#include "gen/tofino/memories.pipe_addrmap.h" -#include "gen/tofino/memories.pipe_top_level.h" -#include "gen/tofino/memories.prsr_mem_main_rspec.h" -#include "gen/tofino/regs.dprsr_hdr.h" -#include "gen/tofino/regs.dprsr_inp.h" -#include "gen/tofino/regs.ebp_rspec.h" -#include "gen/tofino/regs.ibp_rspec.h" -#include "gen/tofino/regs.mau_addrmap.h" -#include "gen/tofino/regs.pipe_addrmap.h" -#include "gen/tofino/regs.prsr_reg_merge_rspec.h" -#include "gen/tofino/regs.tofino.h" +#include "backends/tofino/bf-asm/gen/tofino/memories.pipe_addrmap.h" +#include "backends/tofino/bf-asm/gen/tofino/memories.pipe_top_level.h" +#include "backends/tofino/bf-asm/gen/tofino/memories.prsr_mem_main_rspec.h" +#include "backends/tofino/bf-asm/gen/tofino/regs.dprsr_hdr.h" +#include "backends/tofino/bf-asm/gen/tofino/regs.dprsr_inp.h" +#include "backends/tofino/bf-asm/gen/tofino/regs.ebp_rspec.h" +#include "backends/tofino/bf-asm/gen/tofino/regs.ibp_rspec.h" +#include "backends/tofino/bf-asm/gen/tofino/regs.mau_addrmap.h" +#include "backends/tofino/bf-asm/gen/tofino/regs.pipe_addrmap.h" +#include "backends/tofino/bf-asm/gen/tofino/regs.prsr_reg_merge_rspec.h" +#include "backends/tofino/bf-asm/gen/tofino/regs.tofino.h" class Target::Tofino : public Target { public: @@ -423,17 +423,17 @@ void undeclare_registers(const Target::Tofino::deparser_regs *regs); void emit_parser_registers(const Target::Tofino::top_level_regs *regs, std::ostream &); #if HAVE_JBAY -#include "gen/jbay/memories.jbay_mem.h" -#include "gen/jbay/memories.pipe_addrmap.h" -#include "gen/jbay/memories.prsr_mem_main_rspec.h" -#include "gen/jbay/regs.dprsr_reg.h" -#include "gen/jbay/regs.epb_prsr4_reg.h" -#include "gen/jbay/regs.ipb_prsr4_reg.h" -#include "gen/jbay/regs.jbay_reg.h" -#include "gen/jbay/regs.mau_addrmap.h" -#include "gen/jbay/regs.pipe_addrmap.h" -#include "gen/jbay/regs.pmerge_reg.h" -#include "gen/jbay/regs.prsr_reg_main_rspec.h" +#include "backends/tofino/bf-asm/gen/jbay/memories.jbay_mem.h" +#include "backends/tofino/bf-asm/gen/jbay/memories.pipe_addrmap.h" +#include "backends/tofino/bf-asm/gen/jbay/memories.prsr_mem_main_rspec.h" +#include "backends/tofino/bf-asm/gen/jbay/regs.dprsr_reg.h" +#include "backends/tofino/bf-asm/gen/jbay/regs.epb_prsr4_reg.h" +#include "backends/tofino/bf-asm/gen/jbay/regs.ipb_prsr4_reg.h" +#include "backends/tofino/bf-asm/gen/jbay/regs.jbay_reg.h" +#include "backends/tofino/bf-asm/gen/jbay/regs.mau_addrmap.h" +#include "backends/tofino/bf-asm/gen/jbay/regs.pipe_addrmap.h" +#include "backends/tofino/bf-asm/gen/jbay/regs.pmerge_reg.h" +#include "backends/tofino/bf-asm/gen/jbay/regs.prsr_reg_main_rspec.h" class Target::JBay : public Target { public: diff --git a/backends/tofino/bf-asm/ternary_match.cpp b/backends/tofino/bf-asm/ternary_match.cpp index c13fcab80f1..9ecee2971b0 100644 --- a/backends/tofino/bf-asm/ternary_match.cpp +++ b/backends/tofino/bf-asm/ternary_match.cpp @@ -18,13 +18,13 @@ #include "tofino/ternary_match.h" #include "action_bus.h" -#include "algorithm.h" +#include "lib/algorithm.h" #include "input_xbar.h" #include "instruction.h" #include "misc.h" -#include "range.h" -#include "stage.h" -#include "tables.h" +#include "lib/range.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" Table::Format::Field *TernaryMatchTable::lookup_field(const std::string &n, const std::string &act) const { diff --git a/backends/tofino/bf-asm/tofino/action_table.h b/backends/tofino/bf-asm/tofino/action_table.h index 3945a775160..1c8c39ac142 100644 --- a/backends/tofino/bf-asm/tofino/action_table.h +++ b/backends/tofino/bf-asm/tofino/action_table.h @@ -15,10 +15,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_TOFINO_ACTION_TABLE_H_ -#define BF_ASM_TOFINO_ACTION_TABLE_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_TOFINO_ACTION_TABLE_H_ +#define BACKENDS_TOFINO_BF_ASM_TOFINO_ACTION_TABLE_H_ -#include "tables.h" +#include "backends/tofino/bf-asm/tables.h" class Target::Tofino::ActionTable : public ::ActionTable { friend class ::ActionTable; @@ -26,4 +26,4 @@ class Target::Tofino::ActionTable : public ::ActionTable { : ::ActionTable(line, n, gr, s, lid) {} }; -#endif /* BF_ASM_TOFINO_ACTION_TABLE_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_TOFINO_ACTION_TABLE_H_ */ diff --git a/backends/tofino/bf-asm/tofino/counter.h b/backends/tofino/bf-asm/tofino/counter.h index a9d6060bffe..484b5f49c52 100644 --- a/backends/tofino/bf-asm/tofino/counter.h +++ b/backends/tofino/bf-asm/tofino/counter.h @@ -15,10 +15,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_TOFINO_COUNTER_H_ -#define BF_ASM_TOFINO_COUNTER_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_TOFINO_COUNTER_H_ +#define BACKENDS_TOFINO_BF_ASM_TOFINO_COUNTER_H_ -#include "tables.h" +#include "backends/tofino/bf-asm/tables.h" class Target::Tofino::CounterTable : public ::CounterTable { friend class ::CounterTable; @@ -36,4 +36,4 @@ void CounterTable::write_alu_vpn_range(Target::Tofino::mau_regs &) { BUG(); // not available on tofino } -#endif /* BF_ASM_TOFINO_COUNTER_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_TOFINO_COUNTER_H_ */ diff --git a/backends/tofino/bf-asm/tofino/exact_match.cpp b/backends/tofino/bf-asm/tofino/exact_match.cpp index 42ff46b08f1..dcd8d5d022a 100644 --- a/backends/tofino/bf-asm/tofino/exact_match.cpp +++ b/backends/tofino/bf-asm/tofino/exact_match.cpp @@ -15,7 +15,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "exact_match.h" +#include "backends/tofino/bf-asm/tofino/exact_match.h" void Target::Tofino::ExactMatchTable::setup_ways() { ::ExactMatchTable::setup_ways(); diff --git a/backends/tofino/bf-asm/tofino/exact_match.h b/backends/tofino/bf-asm/tofino/exact_match.h index 849b32d144f..a4e6199bb9d 100644 --- a/backends/tofino/bf-asm/tofino/exact_match.h +++ b/backends/tofino/bf-asm/tofino/exact_match.h @@ -15,10 +15,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_TOFINO_EXACT_MATCH_H_ -#define BF_ASM_TOFINO_EXACT_MATCH_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_TOFINO_EXACT_MATCH_H_ +#define BACKENDS_TOFINO_BF_ASM_TOFINO_EXACT_MATCH_H_ -#include +#include "backends/tofino/bf-asm/tables.h" class Target::Tofino::ExactMatchTable : public ::ExactMatchTable { friend class ::ExactMatchTable; @@ -28,4 +28,4 @@ class Target::Tofino::ExactMatchTable : public ::ExactMatchTable { void setup_ways() override; }; -#endif /* BF_ASM_TOFINO_EXACT_MATCH_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_TOFINO_EXACT_MATCH_H_ */ diff --git a/backends/tofino/bf-asm/tofino/gateway.cpp b/backends/tofino/bf-asm/tofino/gateway.cpp index 0a2faeb6e1f..9be05e17d70 100644 --- a/backends/tofino/bf-asm/tofino/gateway.cpp +++ b/backends/tofino/bf-asm/tofino/gateway.cpp @@ -15,12 +15,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "gateway.h" +#include "backends/tofino/bf-asm/tofino/gateway.h" -#include "hashexpr.h" -#include "hex.h" -#include "stage.h" -#include "ternary_match.h" +#include "backends/tofino/bf-asm/hashexpr.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tofino/ternary_match.h" +#include "lib/hex.h" /* Tofino1/2 Gateway table support * GatewayTable uses the Table::Layout in a somewhat hacky way to track the gateway match diff --git a/backends/tofino/bf-asm/tofino/gateway.h b/backends/tofino/bf-asm/tofino/gateway.h index 323ef5574fd..b8836f32afd 100644 --- a/backends/tofino/bf-asm/tofino/gateway.h +++ b/backends/tofino/bf-asm/tofino/gateway.h @@ -15,10 +15,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_TOFINO_GATEWAY_H_ -#define BF_ASM_TOFINO_GATEWAY_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_TOFINO_GATEWAY_H_ +#define BACKENDS_TOFINO_BF_ASM_TOFINO_GATEWAY_H_ -#include +#include "backends/tofino/bf-asm/tables.h" class Target::Tofino::GatewayTable : public ::GatewayTable { friend class ::GatewayTable; @@ -39,4 +39,4 @@ void enable_gateway_payload_exact_shift_ovr(REGS ®s, int bus); template <> void enable_gateway_payload_exact_shift_ovr(Target::Tofino::mau_regs ®s, int bus); -#endif /* BF_ASM_TOFINO_GATEWAY_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_TOFINO_GATEWAY_H_ */ diff --git a/backends/tofino/bf-asm/tofino/input_xbar.cpp b/backends/tofino/bf-asm/tofino/input_xbar.cpp index 114e0b81ebf..5a3334b5cd4 100644 --- a/backends/tofino/bf-asm/tofino/input_xbar.cpp +++ b/backends/tofino/bf-asm/tofino/input_xbar.cpp @@ -15,7 +15,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "input_xbar.h" +#include "backends/tofino/bf-asm/tofino/input_xbar.h" template <> void InputXbar::write_galois_matrix(Target::Tofino::mau_regs ®s, HashTable id, diff --git a/backends/tofino/bf-asm/tofino/input_xbar.h b/backends/tofino/bf-asm/tofino/input_xbar.h index 0ea58054e21..5fcf746e7ce 100644 --- a/backends/tofino/bf-asm/tofino/input_xbar.h +++ b/backends/tofino/bf-asm/tofino/input_xbar.h @@ -15,13 +15,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_TOFINO_INPUT_XBAR_H_ -#define BF_ASM_TOFINO_INPUT_XBAR_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_TOFINO_INPUT_XBAR_H_ +#define BACKENDS_TOFINO_BF_ASM_TOFINO_INPUT_XBAR_H_ -#include +#include "backends/tofino/bf-asm/input_xbar.h" template <> void InputXbar::write_galois_matrix(Target::Tofino::mau_regs ®s, HashTable id, const std::map &mat); -#endif /* BF_ASM_TOFINO_INPUT_XBAR_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_TOFINO_INPUT_XBAR_H_ */ diff --git a/backends/tofino/bf-asm/tofino/meter.h b/backends/tofino/bf-asm/tofino/meter.h index 639c62ff306..f812ecee37c 100644 --- a/backends/tofino/bf-asm/tofino/meter.h +++ b/backends/tofino/bf-asm/tofino/meter.h @@ -15,10 +15,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_TOFINO_METER_H_ -#define BF_ASM_TOFINO_METER_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_TOFINO_METER_H_ +#define BACKENDS_TOFINO_BF_ASM_TOFINO_METER_H_ -#include +#include "backends/tofino/bf-asm/tables.h" class Target::Tofino::MeterTable : public ::MeterTable { friend class ::MeterTable; @@ -36,4 +36,4 @@ void MeterTable::write_alu_vpn_range(Target::Tofino::mau_regs &) { BUG(); // not available on tofino } -#endif /* BF_ASM_TOFINO_METER_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_TOFINO_METER_H_ */ diff --git a/backends/tofino/bf-asm/tofino/parser.cpp b/backends/tofino/bf-asm/tofino/parser.cpp index d61bbb48dce..2ef8f7b510b 100644 --- a/backends/tofino/bf-asm/tofino/parser.cpp +++ b/backends/tofino/bf-asm/tofino/parser.cpp @@ -22,10 +22,10 @@ #include #include -#include "misc.h" -#include "parser-tofino-jbay.h" -#include "target.h" -#include "top_level.h" +#include "backends/tofino/bf-asm/misc.h" +#include "backends/tofino/bf-asm/parser-tofino-jbay.h" +#include "backends/tofino/bf-asm/target.h" +#include "backends/tofino/bf-asm/top_level.h" // ---------------------------------------------------------------------------- // Slots & Useful constants diff --git a/backends/tofino/bf-asm/tofino/phv.cpp b/backends/tofino/bf-asm/tofino/phv.cpp index 8a3e76e6a4b..7e8c19f8b45 100644 --- a/backends/tofino/bf-asm/tofino/phv.cpp +++ b/backends/tofino/bf-asm/tofino/phv.cpp @@ -15,7 +15,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "phv.h" +#include "backends/tofino/bf-asm/tofino/phv.h" void Target::Tofino::Phv::init_regs(::Phv &phv) { // Allocating Tofino registers so the uids map to register encodings diff --git a/backends/tofino/bf-asm/tofino/phv.h b/backends/tofino/bf-asm/tofino/phv.h index f0baa667da7..1f16dc391d6 100644 --- a/backends/tofino/bf-asm/tofino/phv.h +++ b/backends/tofino/bf-asm/tofino/phv.h @@ -15,10 +15,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_TOFINO_PHV_H_ -#define BF_ASM_TOFINO_PHV_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_TOFINO_PHV_H_ +#define BACKENDS_TOFINO_BF_ASM_TOFINO_PHV_H_ -#include "../phv.h" +#include "backends/tofino/bf-asm/phv.h" class Target::Tofino::Phv : public Target::Phv { friend class ::Phv; @@ -52,4 +52,4 @@ class Target::Tofino::Phv : public Target::Phv { static const bitvec tagalong_groups[8]; }; -#endif /* BF_ASM_TOFINO_PHV_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_TOFINO_PHV_H_ */ diff --git a/backends/tofino/bf-asm/tofino/salu_inst.cpp b/backends/tofino/bf-asm/tofino/salu_inst.cpp index 9e269c9a353..208e12ae028 100644 --- a/backends/tofino/bf-asm/tofino/salu_inst.cpp +++ b/backends/tofino/bf-asm/tofino/salu_inst.cpp @@ -6,7 +6,7 @@ * * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software distributed under the + * Unless required by applicable law or agreed to in writing, software d2istributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language governing permissions * and limitations under the License. diff --git a/backends/tofino/bf-asm/tofino/sram_match.cpp b/backends/tofino/bf-asm/tofino/sram_match.cpp index 3756017cc77..b956e13e5b9 100644 --- a/backends/tofino/bf-asm/tofino/sram_match.cpp +++ b/backends/tofino/bf-asm/tofino/sram_match.cpp @@ -15,8 +15,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "stage.h" -#include "tables.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" +#include "lib/log.h" static int find_in_ixbar(Table *table, std::vector &match) { // It would seem like it would be possible to simplify this code by refactoring it diff --git a/backends/tofino/bf-asm/tofino/stateful.cpp b/backends/tofino/bf-asm/tofino/stateful.cpp index 4b8f908ff35..9265d2d5bb5 100644 --- a/backends/tofino/bf-asm/tofino/stateful.cpp +++ b/backends/tofino/bf-asm/tofino/stateful.cpp @@ -15,7 +15,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "stateful.h" +#include "backends/tofino/bf-asm/tofino/stateful.h" int StatefulTable::parse_counter_mode(Target::Tofino target, const value_t &v) { if (v != "counter") return -1; diff --git a/backends/tofino/bf-asm/tofino/stateful.h b/backends/tofino/bf-asm/tofino/stateful.h index f13fea70d97..fab94ea2ee9 100644 --- a/backends/tofino/bf-asm/tofino/stateful.h +++ b/backends/tofino/bf-asm/tofino/stateful.h @@ -15,11 +15,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_TOFINO_STATEFUL_H_ -#define BF_ASM_TOFINO_STATEFUL_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_TOFINO_STATEFUL_H_ +#define BACKENDS_TOFINO_BF_ASM_TOFINO_STATEFUL_H_ -#include -#include +#include "backends/tofino/bf-asm/tables.h" +#include "backends/tofino/bf-asm/target.h" class Target::Tofino::StatefulTable : public ::StatefulTable { friend class ::StatefulTable; @@ -30,4 +30,4 @@ class Target::Tofino::StatefulTable : public ::StatefulTable { template <> void StatefulTable::write_logging_regs(Target::Tofino::mau_regs ®s); -#endif /* BF_ASM_TOFINO_STATEFUL_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_TOFINO_STATEFUL_H_ */ diff --git a/backends/tofino/bf-asm/tofino/ternary_match.cpp b/backends/tofino/bf-asm/tofino/ternary_match.cpp index 701c5e42920..e18bdf96723 100644 --- a/backends/tofino/bf-asm/tofino/ternary_match.cpp +++ b/backends/tofino/bf-asm/tofino/ternary_match.cpp @@ -15,9 +15,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "ternary_match.h" +#include "backends/tofino/bf-asm/tofino/ternary_match.h" -#include "stage.h" +#include "backends/tofino/bf-asm/stage.h" void Target::Tofino::TernaryMatchTable::pass1() { ::TernaryMatchTable::pass1(); diff --git a/backends/tofino/bf-asm/tofino/ternary_match.h b/backends/tofino/bf-asm/tofino/ternary_match.h index 15eec406a5f..cfb635443b1 100644 --- a/backends/tofino/bf-asm/tofino/ternary_match.h +++ b/backends/tofino/bf-asm/tofino/ternary_match.h @@ -15,10 +15,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_TOFINO_TERNARY_MATCH_H_ -#define BF_ASM_TOFINO_TERNARY_MATCH_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_TOFINO_TERNARY_MATCH_H_ +#define BACKENDS_TOFINO_BF_ASM_TOFINO_TERNARY_MATCH_H_ -#include +#include "backends/tofino/bf-asm/tables.h" class Target::Tofino::TernaryMatchTable : public ::TernaryMatchTable { friend class ::TernaryMatchTable; @@ -37,4 +37,4 @@ class Target::Tofino::TernaryIndirectTable : public ::TernaryIndirectTable { void pass1() override; }; -#endif /* BF_ASM_TOFINO_TERNARY_MATCH_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_TOFINO_TERNARY_MATCH_H_ */ diff --git a/backends/tofino/bf-asm/top_level.h b/backends/tofino/bf-asm/top_level.h index 682f7c539cf..9c150607a71 100644 --- a/backends/tofino/bf-asm/top_level.h +++ b/backends/tofino/bf-asm/top_level.h @@ -15,11 +15,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_TOP_LEVEL_H_ -#define BF_ASM_TOP_LEVEL_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_TOP_LEVEL_H_ +#define BACKENDS_TOFINO_BF_ASM_TOP_LEVEL_H_ -#include "json.h" -#include "target.h" +#include "backends/tofino/bf-asm/json.h" +#include "backends/tofino/bf-asm/target.h" template class TopLevelRegs; @@ -58,4 +58,4 @@ TopLevelRegs *TopLevel::regs() { return dynamic_cast *>(all); } -#endif /* BF_ASM_TOP_LEVEL_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_TOP_LEVEL_H_ */ diff --git a/backends/tofino/bf-asm/ubits.cpp b/backends/tofino/bf-asm/ubits.cpp index d362f36d183..2b90cceb6d9 100644 --- a/backends/tofino/bf-asm/ubits.cpp +++ b/backends/tofino/bf-asm/ubits.cpp @@ -20,8 +20,8 @@ #include #include -#include "hex.h" -#include "log.h" +#include "lib/hex.h" +#include "lib/log.h" struct regrange { const char *base; diff --git a/backends/tofino/bf-asm/ubits.h b/backends/tofino/bf-asm/ubits.h index 96ab8de18ee..adc4248f955 100644 --- a/backends/tofino/bf-asm/ubits.h +++ b/backends/tofino/bf-asm/ubits.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_UBITS_H_ // NOLINT(build/header_guard) -#define BF_ASM_UBITS_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_UBITS_H_ // NOLINT(build/header_guard) +#define BACKENDS_TOFINO_BF_ASM_UBITS_H_ #include #include @@ -26,8 +26,8 @@ #include #include -#include "bitvec.h" -#include "log.h" +#include "lib/bitvec.h" +#include "lib/log.h" using namespace P4; @@ -175,4 +175,4 @@ struct ubits : ubits_base { } }; -#endif /* BF_ASM_UBITS_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_UBITS_H_ */ diff --git a/backends/tofino/bf-asm/vector.h b/backends/tofino/bf-asm/vector.h index 28524e7b831..520fa636058 100644 --- a/backends/tofino/bf-asm/vector.h +++ b/backends/tofino/bf-asm/vector.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_VECTOR_H_ -#define BF_ASM_VECTOR_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_VECTOR_H_ +#define BACKENDS_TOFINO_BF_ASM_VECTOR_H_ /* C code and macros for VECTOR objects similar to C++ std::vector */ #include @@ -226,4 +226,4 @@ extern int shrink_raw_vector(void *vec, size_t elsize); } #endif -#endif /* BF_ASM_VECTOR_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_VECTOR_H_ */ diff --git a/backends/tofino/bf-asm/walle/chip.py b/backends/tofino/bf-asm/walle/chip.py index 582398a9868..8156a5ee62c 100644 --- a/backends/tofino/bf-asm/walle/chip.py +++ b/backends/tofino/bf-asm/walle/chip.py @@ -21,17 +21,20 @@ import struct from copy import copy + class chip_object(object): """ TODO: docstring """ + def __init__(self, addr, src_key): self.addr = addr self.src_key = src_key - def add_offset (self, offset): + def add_offset(self, offset): self.addr += offset + class direct_reg(chip_object): """ A single register write operation, of the format: @@ -45,7 +48,7 @@ class direct_reg(chip_object): def __init__(self, addr, value, src_key=None): chip_object.__init__(self, addr, src_key) - self.value=struct.pack("= 0: - byte_str += "\0\0\0R" + struct.pack("" - + def deepcopy(self): new = copy(self) new.values = new.values[:] @@ -148,12 +159,12 @@ def bytes(self): if self.width > 128: # FIXME: this only works cleanly if width is a multiple of 128, can it be otherwise? if self.width % 128 != 0: - sys.stderr.write("ERROR: register width %d not a multiple of 128" % self.width); + sys.stderr.write("ERROR: register width %d not a multiple of 128" % self.width) sys.exit(1) new_values = [] for value in self.values: - for chunk in range(0, self.width//8, 16): - new_values.append(value[chunk:chunk+16].rjust(128//8,chr(0))) + for chunk in range(0, self.width // 8, 16): + new_values.append(value[chunk : chunk + 16].rjust(128 // 8, chr(0))) self.values = new_values self.width = 128 @@ -161,7 +172,12 @@ def bytes(self): op_type = "\0\0\0B" else: op_type = "\0\0\0D" - bytestr = op_type + struct.pack(" 0: diff --git a/backends/tofino/bf-asm/widereg.cpp b/backends/tofino/bf-asm/widereg.cpp index c5140eda57c..f6b223423c0 100644 --- a/backends/tofino/bf-asm/widereg.cpp +++ b/backends/tofino/bf-asm/widereg.cpp @@ -20,7 +20,7 @@ #include #include -#include "log.h" +#include "lib/log.h" void widereg_base::log(const char *op, bitvec v) const { std::ostringstream tmp; diff --git a/backends/tofino/bf-asm/widereg.h b/backends/tofino/bf-asm/widereg.h index 5fc8dbca673..f6f8e37a05e 100644 --- a/backends/tofino/bf-asm/widereg.h +++ b/backends/tofino/bf-asm/widereg.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BF_ASM_WIDEREG_H_ -#define BF_ASM_WIDEREG_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_WIDEREG_H_ +#define BACKENDS_TOFINO_BF_ASM_WIDEREG_H_ #include @@ -24,8 +24,8 @@ #include #include -#include "bitvec.h" -#include "log.h" +#include "lib/bitvec.h" +#include "lib/log.h" using namespace P4; @@ -167,4 +167,4 @@ struct widereg : widereg_base { } }; -#endif /* BF_ASM_WIDEREG_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_WIDEREG_H_ */ diff --git a/backends/tofino/bf-p4c/driver/barefoot.py b/backends/tofino/bf-p4c/driver/barefoot.py index 23233325fa5..b94b403f1dc 100755 --- a/backends/tofino/bf-p4c/driver/barefoot.py +++ b/backends/tofino/bf-p4c/driver/barefoot.py @@ -179,12 +179,6 @@ def add_command_line_options(self): default=False, help="Add source outputs to the archive.", ) - self._argGroup.add_argument( - "--enable-bf-asm", - action="store_true", - default=False, - help="Use the assembler to generate a binary.", - ) self._argGroup.add_argument( "--bf-rt-schema", action="store", @@ -487,19 +481,18 @@ def process_command_line_options(self, opts): """! Main parsing or command line options @param opts Object holding set arguments """ - # Add assembler options if they are available. - if opts.enable_bf_asm or os.getenv("ENABLE_BF_ASM"): - if os.environ['P4C_BUILD_TYPE'] == "DEVELOPER": - bfas = find_file('bf-asm', 'bfas') - else: - bfas = find_file(os.environ['P4C_BIN_DIR'], 'bfas') - - bfrt_schema = find_file(os.environ['P4C_BIN_DIR'], 'bfrt_schema.py') - p4c_gen_conf = find_file(os.environ['P4C_BIN_DIR'], 'p4c-gen-conf') - self.add_command('assembler', bfas) - self.add_command('bf-rt-verifier', bfrt_schema) - self.add_command('p4c-gen-conf', p4c_gen_conf) - self._commandsEnabled.append('assembler') + # Add assembler options. + if os.environ['P4C_BUILD_TYPE'] == "DEVELOPER": + bfas = find_file('bf-asm', 'bfas') + else: + bfas = find_file(os.environ['P4C_BIN_DIR'], 'bfas') + + bfrt_schema = find_file(os.environ['P4C_BIN_DIR'], 'bfrt_schema.py') + p4c_gen_conf = find_file(os.environ['P4C_BIN_DIR'], 'p4c-gen-conf') + self.add_command('assembler', bfas) + self.add_command('bf-rt-verifier', bfrt_schema) + self.add_command('p4c-gen-conf', p4c_gen_conf) + self._commandsEnabled.append('assembler') BackendDriver.process_command_line_options(self, opts) diff --git a/backends/tofino/bf-p4c/driver/p4c.tofino.cfg b/backends/tofino/bf-p4c/driver/p4c.tofino.cfg index 09fbd5bfc24..05e840437b8 100644 --- a/backends/tofino/bf-p4c/driver/p4c.tofino.cfg +++ b/backends/tofino/bf-p4c/driver/p4c.tofino.cfg @@ -27,8 +27,7 @@ class TofinoBackend(bfn.BarefootBackend): self.config_compiler("__TARGET_TOFINO__=1") def process_command_line_options(self, opts): - if opts.enable_bf_asm or os.getenv("ENABLE_BF_ASM"): - self.config_assembler("tofino") + self.config_assembler("tofino") bfn.BarefootBackend.process_command_line_options(self, opts) diff --git a/backends/tofino/bf-p4c/driver/p4c.tofino2.cfg b/backends/tofino/bf-p4c/driver/p4c.tofino2.cfg index 1a8001e26fe..f452bdea69e 100644 --- a/backends/tofino/bf-p4c/driver/p4c.tofino2.cfg +++ b/backends/tofino/bf-p4c/driver/p4c.tofino2.cfg @@ -37,8 +37,7 @@ class Tofino2Backend(bfn.BarefootBackend): self.config_compiler("__TOFINO2_VARIANT__={}".format(Tofino2Variants[target])) def process_command_line_options(self, opts): - if opts.enable_bf_asm or os.getenv("ENABLE_BF_ASM"): - self.config_assembler(self._target) + self.config_assembler(self._target) bfn.BarefootBackend.process_command_line_options(self, opts) for t in Tofino2Variants.keys(): From b1e5ae75a4239b30106094b2b2d076eb340adc19 Mon Sep 17 00:00:00 2001 From: fruffy Date: Thu, 6 Feb 2025 21:45:00 -0500 Subject: [PATCH 03/19] Formatting. Signed-off-by: fruffy --- backends/tofino/bf-asm/CMakeLists.txt | 4 - backends/tofino/bf-asm/action_bus.cpp | 2 +- backends/tofino/bf-asm/action_table.cpp | 6 +- backends/tofino/bf-asm/asm-types.h | 2 +- backends/tofino/bf-asm/atcam_match.cpp | 8 +- backends/tofino/bf-asm/attached_table.cpp | 6 +- backends/tofino/bf-asm/bfas.cpp | 2 +- backends/tofino/bf-asm/counter.cpp | 6 +- backends/tofino/bf-asm/deparser.cpp | 4 +- backends/tofino/bf-asm/deparser.h | 2 +- backends/tofino/bf-asm/dynhash.cpp | 2 +- backends/tofino/bf-asm/exact_match.cpp | 8 +- backends/tofino/bf-asm/flexible_headers.cpp | 4 +- backends/tofino/bf-asm/gateway.cpp | 8 +- backends/tofino/bf-asm/gtest/gateway.cpp | 2 +- backends/tofino/bf-asm/gtest/hashexpr.cpp | 2 +- backends/tofino/bf-asm/hash_action.cpp | 4 +- backends/tofino/bf-asm/hash_dist.cpp | 2 +- backends/tofino/bf-asm/hashdump.cpp | 2 +- backends/tofino/bf-asm/hashexpr.cpp | 2 +- backends/tofino/bf-asm/idletime.cpp | 2 +- backends/tofino/bf-asm/input_xbar.cpp | 6 +- backends/tofino/bf-asm/instruction.cpp | 4 +- backends/tofino/bf-asm/jbay/gateway.h | 2 +- backends/tofino/bf-asm/json_diff.cpp | 2 +- backends/tofino/bf-asm/match_table.cpp | 6 +- backends/tofino/bf-asm/meter.cpp | 4 +- backends/tofino/bf-asm/misc.cpp | 2 +- backends/tofino/bf-asm/parser-tofino-jbay.cpp | 10 +- backends/tofino/bf-asm/parser-tofino-jbay.h | 2 +- backends/tofino/bf-asm/parser.h | 2 +- backends/tofino/bf-asm/phase0.cpp | 2 +- backends/tofino/bf-asm/phv.h | 4 +- backends/tofino/bf-asm/primitives.cpp | 2 +- backends/tofino/bf-asm/proxy_hash.cpp | 2 +- backends/tofino/bf-asm/salu_inst.cpp | 6 +- backends/tofino/bf-asm/sections.h | 2 +- backends/tofino/bf-asm/selection.cpp | 6 +- backends/tofino/bf-asm/stage.cpp | 4 +- backends/tofino/bf-asm/stage.h | 4 +- backends/tofino/bf-asm/stateful.cpp | 6 +- backends/tofino/bf-asm/synth2port.cpp | 6 +- backends/tofino/bf-asm/tables.cpp | 4 +- backends/tofino/bf-asm/tables.h | 6 +- backends/tofino/bf-asm/target.cpp | 2 +- backends/tofino/bf-asm/ternary_match.cpp | 8 +- .../bfas_lookup_test/bfas_lookup_cases.py | 29 +- .../test/bfas_lookup_test/bfas_lookup_test.py | 17 +- backends/tofino/bf-asm/test/update_config.py | 17 +- backends/tofino/bf-asm/test/validate.py | 13 +- backends/tofino/bf-asm/walle/csr.py | 1313 +++++++++++------ backends/tofino/bf-asm/walle/walle.py | 429 ++++-- .../compiler_interfaces/schemas/mau_schema.py | 1 - .../schemas/power_schema.py | 1 - .../tools/create_mau_characterize.py | 27 +- .../tools/create_mau_json.py | 9 +- .../tools/create_phv_json.py | 6 +- 57 files changed, 1295 insertions(+), 751 deletions(-) diff --git a/backends/tofino/bf-asm/CMakeLists.txt b/backends/tofino/bf-asm/CMakeLists.txt index 2e9b4abf7de..fc6f026ce83 100644 --- a/backends/tofino/bf-asm/CMakeLists.txt +++ b/backends/tofino/bf-asm/CMakeLists.txt @@ -23,10 +23,6 @@ OPTION(ASAN_ENABLED "Enable ASAN checks" OFF) set (BFASM_LIB_DEPS p4ctoolkit ${P4C_LIB_DEPS}) set (BFASM_GEN_DIR ${CMAKE_CURRENT_BINARY_DIR}/gen) -find_package (BISON REQUIRED) -find_package (FLEX REQUIRED) -find_package(absl REQUIRED) - # other required libraries include (CheckLibraryExists) # check includes diff --git a/backends/tofino/bf-asm/action_bus.cpp b/backends/tofino/bf-asm/action_bus.cpp index 20131031e68..a6d4184b0a9 100644 --- a/backends/tofino/bf-asm/action_bus.cpp +++ b/backends/tofino/bf-asm/action_bus.cpp @@ -19,9 +19,9 @@ #include +#include "backends/tofino/bf-asm/stage.h" #include "lib/hex.h" #include "misc.h" -#include "backends/tofino/bf-asm/stage.h" static MeterBus_t MeterBus; diff --git a/backends/tofino/bf-asm/action_table.cpp b/backends/tofino/bf-asm/action_table.cpp index b1f61996140..7e24acee618 100644 --- a/backends/tofino/bf-asm/action_table.cpp +++ b/backends/tofino/bf-asm/action_table.cpp @@ -16,11 +16,11 @@ */ #include "action_bus.h" -#include "lib/algorithm.h" -#include "input_xbar.h" -#include "instruction.h" #include "backends/tofino/bf-asm/stage.h" #include "backends/tofino/bf-asm/tables.h" +#include "input_xbar.h" +#include "instruction.h" +#include "lib/algorithm.h" // template specialization declarations #include "tofino/action_table.h" diff --git a/backends/tofino/bf-asm/asm-types.h b/backends/tofino/bf-asm/asm-types.h index b6b92b8c1fc..392146fe40f 100644 --- a/backends/tofino/bf-asm/asm-types.h +++ b/backends/tofino/bf-asm/asm-types.h @@ -30,8 +30,8 @@ #include #include -#include "backends/tofino/bf-asm/map.h" #include "backends/tofino/bf-asm/json.h" +#include "backends/tofino/bf-asm/map.h" #include "bfas.h" #include "lib/bitops.h" #include "lib/bitvec.h" diff --git a/backends/tofino/bf-asm/atcam_match.cpp b/backends/tofino/bf-asm/atcam_match.cpp index 8f9c53155f5..4b36885f439 100644 --- a/backends/tofino/bf-asm/atcam_match.cpp +++ b/backends/tofino/bf-asm/atcam_match.cpp @@ -16,13 +16,13 @@ */ #include "action_bus.h" -#include "lib/algorithm.h" -#include "lib/hex.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" #include "input_xbar.h" #include "instruction.h" +#include "lib/algorithm.h" +#include "lib/hex.h" #include "misc.h" -#include "backends/tofino/bf-asm/stage.h" -#include "backends/tofino/bf-asm/tables.h" void AlgTcamMatchTable::setup(VECTOR(pair_t) & data) { common_init_setup(data, false, P4Table::MatchEntry); diff --git a/backends/tofino/bf-asm/attached_table.cpp b/backends/tofino/bf-asm/attached_table.cpp index a9ba38e013f..c2bc1356aae 100644 --- a/backends/tofino/bf-asm/attached_table.cpp +++ b/backends/tofino/bf-asm/attached_table.cpp @@ -20,12 +20,12 @@ #include #include "action_bus.h" -#include "lib/algorithm.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" #include "input_xbar.h" #include "instruction.h" +#include "lib/algorithm.h" #include "misc.h" -#include "backends/tofino/bf-asm/stage.h" -#include "backends/tofino/bf-asm/tables.h" void AttachedTable::pass1() { if (default_action.empty()) default_action = get_default_action(); diff --git a/backends/tofino/bf-asm/bfas.cpp b/backends/tofino/bf-asm/bfas.cpp index 18a51a9dd22..980f271015f 100644 --- a/backends/tofino/bf-asm/bfas.cpp +++ b/backends/tofino/bf-asm/bfas.cpp @@ -25,6 +25,7 @@ #include #include +#include "backends/tofino/bf-asm/target.h" #include "backends/tofino/bf-p4c/git_sha_version.h" // for BF_P4C_GIT_SHA #include "backends/tofino/bf-p4c/version.h" #include "constants.h" @@ -32,7 +33,6 @@ #include "misc.h" #include "parser-tofino-jbay.h" #include "sections.h" -#include "backends/tofino/bf-asm/target.h" #include "top_level.h" #define MAJOR_VERSION 1 diff --git a/backends/tofino/bf-asm/counter.cpp b/backends/tofino/bf-asm/counter.cpp index 78e658929e2..c643532ea21 100644 --- a/backends/tofino/bf-asm/counter.cpp +++ b/backends/tofino/bf-asm/counter.cpp @@ -15,12 +15,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "lib/algorithm.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" #include "data_switchbox.h" #include "input_xbar.h" +#include "lib/algorithm.h" #include "misc.h" -#include "backends/tofino/bf-asm/stage.h" -#include "backends/tofino/bf-asm/tables.h" // target specific template specializations #include "tofino/counter.h" diff --git a/backends/tofino/bf-asm/deparser.cpp b/backends/tofino/bf-asm/deparser.cpp index 0fdbfb3c55e..ebd6c4684cd 100644 --- a/backends/tofino/bf-asm/deparser.cpp +++ b/backends/tofino/bf-asm/deparser.cpp @@ -19,12 +19,12 @@ #include +#include "backends/tofino/bf-asm/target.h" #include "constants.h" +#include "lib/range.h" #include "misc.h" #include "parser-tofino-jbay.h" #include "phv.h" -#include "lib/range.h" -#include "backends/tofino/bf-asm/target.h" #include "top_level.h" #include "ubits.h" diff --git a/backends/tofino/bf-asm/deparser.h b/backends/tofino/bf-asm/deparser.h index 1a655130946..d561907e3e7 100644 --- a/backends/tofino/bf-asm/deparser.h +++ b/backends/tofino/bf-asm/deparser.h @@ -22,8 +22,8 @@ #include -#include "lib/bitops.h" #include "constants.h" +#include "lib/bitops.h" #include "lib/ordered_set.h" #include "phv.h" #include "sections.h" diff --git a/backends/tofino/bf-asm/dynhash.cpp b/backends/tofino/bf-asm/dynhash.cpp index ec265328e8c..c3457c4bb58 100644 --- a/backends/tofino/bf-asm/dynhash.cpp +++ b/backends/tofino/bf-asm/dynhash.cpp @@ -19,8 +19,8 @@ #include #include -#include "bfas.h" #include "backends/tofino/bf-asm/json.h" +#include "bfas.h" #include "sections.h" class DynHash : public Section { diff --git a/backends/tofino/bf-asm/exact_match.cpp b/backends/tofino/bf-asm/exact_match.cpp index 2f891189b4a..d715a740b2f 100644 --- a/backends/tofino/bf-asm/exact_match.cpp +++ b/backends/tofino/bf-asm/exact_match.cpp @@ -18,14 +18,14 @@ #include "tofino/exact_match.h" #include "action_bus.h" -#include "lib/algorithm.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" #include "hashexpr.h" -#include "lib/hex.h" #include "input_xbar.h" #include "instruction.h" +#include "lib/algorithm.h" +#include "lib/hex.h" #include "misc.h" -#include "backends/tofino/bf-asm/stage.h" -#include "backends/tofino/bf-asm/tables.h" void ExactMatchTable::setup(VECTOR(pair_t) & data) { common_init_setup(data, false, P4Table::MatchEntry); diff --git a/backends/tofino/bf-asm/flexible_headers.cpp b/backends/tofino/bf-asm/flexible_headers.cpp index 37a1b75683f..df3489a6a51 100644 --- a/backends/tofino/bf-asm/flexible_headers.cpp +++ b/backends/tofino/bf-asm/flexible_headers.cpp @@ -15,10 +15,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "backends/tofino/bf-asm/sections.h" - #include +#include "backends/tofino/bf-asm/sections.h" + namespace BFASM { // Singleton class representing the assembler flexible_headers diff --git a/backends/tofino/bf-asm/gateway.cpp b/backends/tofino/bf-asm/gateway.cpp index 26bb8a99cdd..e25c3ed15c0 100644 --- a/backends/tofino/bf-asm/gateway.cpp +++ b/backends/tofino/bf-asm/gateway.cpp @@ -15,14 +15,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "lib/algorithm.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" #include "hashexpr.h" -#include "lib/hex.h" #include "input_xbar.h" #include "instruction.h" +#include "lib/algorithm.h" +#include "lib/hex.h" #include "misc.h" -#include "backends/tofino/bf-asm/stage.h" -#include "backends/tofino/bf-asm/tables.h" // template specialization declarations #include "jbay/gateway.h" diff --git a/backends/tofino/bf-asm/gtest/gateway.cpp b/backends/tofino/bf-asm/gtest/gateway.cpp index 66c531438df..31ed73fc773 100644 --- a/backends/tofino/bf-asm/gtest/gateway.cpp +++ b/backends/tofino/bf-asm/gtest/gateway.cpp @@ -15,9 +15,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "backends/tofino/bf-asm/stage.h" #include "bfas.h" #include "gtest/gtest.h" -#include "backends/tofino/bf-asm/stage.h" namespace { diff --git a/backends/tofino/bf-asm/gtest/hashexpr.cpp b/backends/tofino/bf-asm/gtest/hashexpr.cpp index 97146185eb5..e65f6696976 100644 --- a/backends/tofino/bf-asm/gtest/hashexpr.cpp +++ b/backends/tofino/bf-asm/gtest/hashexpr.cpp @@ -17,9 +17,9 @@ #include "hashexpr.h" +#include "backends/tofino/bf-asm/stage.h" #include "bfas.h" #include "gtest/gtest.h" -#include "backends/tofino/bf-asm/stage.h" namespace { diff --git a/backends/tofino/bf-asm/hash_action.cpp b/backends/tofino/bf-asm/hash_action.cpp index 88ac15645bb..2c99bbfd4f6 100644 --- a/backends/tofino/bf-asm/hash_action.cpp +++ b/backends/tofino/bf-asm/hash_action.cpp @@ -18,10 +18,10 @@ #include #include "action_bus.h" -#include "input_xbar.h" -#include "misc.h" #include "backends/tofino/bf-asm/stage.h" #include "backends/tofino/bf-asm/tables.h" +#include "input_xbar.h" +#include "misc.h" // target specific instantiatitions diff --git a/backends/tofino/bf-asm/hash_dist.cpp b/backends/tofino/bf-asm/hash_dist.cpp index 1240a7557ac..6e900137124 100644 --- a/backends/tofino/bf-asm/hash_dist.cpp +++ b/backends/tofino/bf-asm/hash_dist.cpp @@ -19,8 +19,8 @@ #include -#include "lib/range.h" #include "backends/tofino/bf-asm/stage.h" +#include "lib/range.h" static void set_output_bit(unsigned &xbar_use, value_t &v) { if (CHECKTYPE(v, tSTR)) { diff --git a/backends/tofino/bf-asm/hashdump.cpp b/backends/tofino/bf-asm/hashdump.cpp index 459d866a3a6..572e4e4e31e 100644 --- a/backends/tofino/bf-asm/hashdump.cpp +++ b/backends/tofino/bf-asm/hashdump.cpp @@ -18,9 +18,9 @@ #include #include +#include "backends/tofino/bf-asm/json.h" #include "gen/tofino/disas.regs.mau_addrmap.h" #include "lib/hex.h" -#include "backends/tofino/bf-asm/json.h" static Tofino::regs_mau_addrmap regs; diff --git a/backends/tofino/bf-asm/hashexpr.cpp b/backends/tofino/bf-asm/hashexpr.cpp index 75e8c85715d..2d2312aa6ce 100644 --- a/backends/tofino/bf-asm/hashexpr.cpp +++ b/backends/tofino/bf-asm/hashexpr.cpp @@ -17,9 +17,9 @@ #include "hashexpr.h" +#include "input_xbar.h" #include "lib/bitops.h" #include "lib/bitvec.h" -#include "input_xbar.h" static bitvec crc(bitvec poly, bitvec val) { int poly_size = poly.max().index() + 1; diff --git a/backends/tofino/bf-asm/idletime.cpp b/backends/tofino/bf-asm/idletime.cpp index 6ad20c59bbe..297988c4621 100644 --- a/backends/tofino/bf-asm/idletime.cpp +++ b/backends/tofino/bf-asm/idletime.cpp @@ -15,9 +15,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "misc.h" #include "backends/tofino/bf-asm/stage.h" #include "backends/tofino/bf-asm/tables.h" +#include "misc.h" void IdletimeTable::setup(VECTOR(pair_t) & data) { setup_layout(layout, data); diff --git a/backends/tofino/bf-asm/input_xbar.cpp b/backends/tofino/bf-asm/input_xbar.cpp index a1dae55a8b6..d3ba86cc054 100644 --- a/backends/tofino/bf-asm/input_xbar.cpp +++ b/backends/tofino/bf-asm/input_xbar.cpp @@ -22,13 +22,13 @@ #include +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" #include "hashexpr.h" #include "lib/log.h" +#include "lib/range.h" #include "misc.h" #include "power_ctl.h" -#include "lib/range.h" -#include "backends/tofino/bf-asm/stage.h" -#include "backends/tofino/bf-asm/tables.h" // template specialization declarations #include "backends/tofino/bf-asm/jbay/input_xbar.h" diff --git a/backends/tofino/bf-asm/instruction.cpp b/backends/tofino/bf-asm/instruction.cpp index 0878f2138dc..1ad824d0d36 100644 --- a/backends/tofino/bf-asm/instruction.cpp +++ b/backends/tofino/bf-asm/instruction.cpp @@ -20,11 +20,11 @@ #include #include "action_bus.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" #include "depositfield.h" #include "phv.h" #include "power_ctl.h" -#include "backends/tofino/bf-asm/stage.h" -#include "backends/tofino/bf-asm/tables.h" namespace { constexpr int RotationBits = 16; diff --git a/backends/tofino/bf-asm/jbay/gateway.h b/backends/tofino/bf-asm/jbay/gateway.h index 107cafe068e..81cd538e75c 100644 --- a/backends/tofino/bf-asm/jbay/gateway.h +++ b/backends/tofino/bf-asm/jbay/gateway.h @@ -18,8 +18,8 @@ #ifndef BACKENDS_TOFINO_BF_ASM_JBAY_GATEWAY_H_ #define BACKENDS_TOFINO_BF_ASM_JBAY_GATEWAY_H_ -#include "backends/tofino/bf-asm/tofino/gateway.h" #include "backends/tofino/bf-asm/tables.h" +#include "backends/tofino/bf-asm/tofino/gateway.h" #if HAVE_JBAY template <> diff --git a/backends/tofino/bf-asm/json_diff.cpp b/backends/tofino/bf-asm/json_diff.cpp index 61f1a566674..27ff15e6219 100644 --- a/backends/tofino/bf-asm/json_diff.cpp +++ b/backends/tofino/bf-asm/json_diff.cpp @@ -20,8 +20,8 @@ #include #include -#include "fdstream.h" #include "backends/tofino/bf-asm/json.h" +#include "fdstream.h" #include "lib/ordered_map.h" static bool show_deletion = true; diff --git a/backends/tofino/bf-asm/match_table.cpp b/backends/tofino/bf-asm/match_table.cpp index 53efe5b29d9..ca326088a5a 100644 --- a/backends/tofino/bf-asm/match_table.cpp +++ b/backends/tofino/bf-asm/match_table.cpp @@ -20,12 +20,12 @@ #include #include "action_bus.h" -#include "lib/algorithm.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" #include "input_xbar.h" #include "instruction.h" +#include "lib/algorithm.h" #include "misc.h" -#include "backends/tofino/bf-asm/stage.h" -#include "backends/tofino/bf-asm/tables.h" Table::Format *MatchTable::get_format() const { if (!format && gateway) return gateway->get_format(); diff --git a/backends/tofino/bf-asm/meter.cpp b/backends/tofino/bf-asm/meter.cpp index 11f3bb7280e..23ee71b1ea2 100644 --- a/backends/tofino/bf-asm/meter.cpp +++ b/backends/tofino/bf-asm/meter.cpp @@ -15,11 +15,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" #include "data_switchbox.h" #include "input_xbar.h" #include "misc.h" -#include "backends/tofino/bf-asm/stage.h" -#include "backends/tofino/bf-asm/tables.h" // target specific template specializations #include "tofino/meter.h" diff --git a/backends/tofino/bf-asm/misc.cpp b/backends/tofino/bf-asm/misc.cpp index 9d46e663068..28cddb8932f 100644 --- a/backends/tofino/bf-asm/misc.cpp +++ b/backends/tofino/bf-asm/misc.cpp @@ -21,8 +21,8 @@ #include #include -#include "bfas.h" #include "backends/tofino/bf-asm/target.h" +#include "bfas.h" int remove_name_tail_range(std::string &name, int *size) { auto tail = name.rfind('.'); diff --git a/backends/tofino/bf-asm/parser-tofino-jbay.cpp b/backends/tofino/bf-asm/parser-tofino-jbay.cpp index 69509e0d8c4..44e2837f22f 100644 --- a/backends/tofino/bf-asm/parser-tofino-jbay.cpp +++ b/backends/tofino/bf-asm/parser-tofino-jbay.cpp @@ -19,14 +19,14 @@ #include -#include "lib/algorithm.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/target.h" #include "constants.h" -#include "misc.h" +#include "lib/algorithm.h" #include "lib/ordered_set.h" -#include "phv.h" #include "lib/range.h" -#include "backends/tofino/bf-asm/stage.h" -#include "backends/tofino/bf-asm/target.h" +#include "misc.h" +#include "phv.h" #include "top_level.h" #include "vector.h" diff --git a/backends/tofino/bf-asm/parser-tofino-jbay.h b/backends/tofino/bf-asm/parser-tofino-jbay.h index f195ab42532..74dd41aab77 100644 --- a/backends/tofino/bf-asm/parser-tofino-jbay.h +++ b/backends/tofino/bf-asm/parser-tofino-jbay.h @@ -22,11 +22,11 @@ #include #include +#include "backends/tofino/bf-asm/target.h" #include "lib/bitvec.h" #include "parser.h" #include "phv.h" #include "sections.h" -#include "backends/tofino/bf-asm/target.h" #include "ubits.h" enum { diff --git a/backends/tofino/bf-asm/parser.h b/backends/tofino/bf-asm/parser.h index 3e2ef2a47f8..e49e79025b4 100644 --- a/backends/tofino/bf-asm/parser.h +++ b/backends/tofino/bf-asm/parser.h @@ -20,8 +20,8 @@ #include "asm-types.h" #include "backends/tofino/bf-asm/json.h" -#include "sections.h" #include "backends/tofino/bf-asm/target.h" +#include "sections.h" #include "vector.h" /** diff --git a/backends/tofino/bf-asm/phase0.cpp b/backends/tofino/bf-asm/phase0.cpp index 54bb63d761c..4e182ae28c1 100644 --- a/backends/tofino/bf-asm/phase0.cpp +++ b/backends/tofino/bf-asm/phase0.cpp @@ -15,9 +15,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "parser-tofino-jbay.h" #include "backends/tofino/bf-asm/stage.h" #include "backends/tofino/bf-asm/tables.h" +#include "parser-tofino-jbay.h" DEFINE_TABLE_TYPE(Phase0MatchTable) diff --git a/backends/tofino/bf-asm/phv.h b/backends/tofino/bf-asm/phv.h index 3420d81883b..41694f513b3 100644 --- a/backends/tofino/bf-asm/phv.h +++ b/backends/tofino/bf-asm/phv.h @@ -21,13 +21,13 @@ #include #include +#include "backends/tofino/bf-asm/json.h" +#include "backends/tofino/bf-asm/target.h" #include "bfas.h" #include "lib/bitvec.h" -#include "backends/tofino/bf-asm/json.h" #include "match_source.h" #include "misc.h" #include "sections.h" -#include "backends/tofino/bf-asm/target.h" class Phv : public Section { void start(int lineno, VECTOR(value_t) args) override; diff --git a/backends/tofino/bf-asm/primitives.cpp b/backends/tofino/bf-asm/primitives.cpp index 828507439e0..d9ee4a885a7 100644 --- a/backends/tofino/bf-asm/primitives.cpp +++ b/backends/tofino/bf-asm/primitives.cpp @@ -19,8 +19,8 @@ #include #include -#include "bfas.h" #include "backends/tofino/bf-asm/json.h" +#include "bfas.h" #include "lib/log.h" #include "sections.h" diff --git a/backends/tofino/bf-asm/proxy_hash.cpp b/backends/tofino/bf-asm/proxy_hash.cpp index 0fb38d3f3b0..13395de2d5c 100644 --- a/backends/tofino/bf-asm/proxy_hash.cpp +++ b/backends/tofino/bf-asm/proxy_hash.cpp @@ -15,9 +15,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "input_xbar.h" #include "backends/tofino/bf-asm/stage.h" #include "backends/tofino/bf-asm/tables.h" +#include "input_xbar.h" void ProxyHashMatchTable::setup(VECTOR(pair_t) & data) { common_init_setup(data, false, P4Table::MatchEntry); diff --git a/backends/tofino/bf-asm/salu_inst.cpp b/backends/tofino/bf-asm/salu_inst.cpp index 8e8c36d90d2..b5a52f4b622 100644 --- a/backends/tofino/bf-asm/salu_inst.cpp +++ b/backends/tofino/bf-asm/salu_inst.cpp @@ -21,11 +21,11 @@ #include -#include "lib/hex.h" -#include "instruction.h" -#include "phv.h" #include "backends/tofino/bf-asm/stage.h" #include "backends/tofino/bf-asm/tables.h" +#include "instruction.h" +#include "lib/hex.h" +#include "phv.h" namespace StatefulAlu { diff --git a/backends/tofino/bf-asm/sections.h b/backends/tofino/bf-asm/sections.h index 414e23e3420..ea44ce80f07 100644 --- a/backends/tofino/bf-asm/sections.h +++ b/backends/tofino/bf-asm/sections.h @@ -23,8 +23,8 @@ #include #include "asm-types.h" -#include "bfas.h" #include "backends/tofino/bf-asm/json.h" +#include "bfas.h" #include "map.h" /// A Section represents a top level section in assembly diff --git a/backends/tofino/bf-asm/selection.cpp b/backends/tofino/bf-asm/selection.cpp index 8b2ff359768..4db49dd9415 100644 --- a/backends/tofino/bf-asm/selection.cpp +++ b/backends/tofino/bf-asm/selection.cpp @@ -15,12 +15,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "lib/algorithm.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" #include "data_switchbox.h" #include "input_xbar.h" +#include "lib/algorithm.h" #include "misc.h" -#include "backends/tofino/bf-asm/stage.h" -#include "backends/tofino/bf-asm/tables.h" void SelectionTable::setup(VECTOR(pair_t) & data) { setup_layout(layout, data); diff --git a/backends/tofino/bf-asm/stage.cpp b/backends/tofino/bf-asm/stage.cpp index ccabeab2be3..c69e7277b4b 100644 --- a/backends/tofino/bf-asm/stage.cpp +++ b/backends/tofino/bf-asm/stage.cpp @@ -22,14 +22,14 @@ #include +#include "backends/tofino/bf-asm/target.h" #include "deparser.h" #include "input_xbar.h" +#include "lib/range.h" #include "misc.h" #include "parser.h" #include "phv.h" -#include "lib/range.h" #include "sections.h" -#include "backends/tofino/bf-asm/target.h" #include "top_level.h" extern std::string asmfile_name; diff --git a/backends/tofino/bf-asm/stage.h b/backends/tofino/bf-asm/stage.h index 9ef5585768d..f5f2cdae2c8 100644 --- a/backends/tofino/bf-asm/stage.h +++ b/backends/tofino/bf-asm/stage.h @@ -22,10 +22,10 @@ #include #include "alloc.h" -#include "lib/bitvec.h" +#include "backends/tofino/bf-asm/tables.h" #include "error_mode.h" #include "input_xbar.h" -#include "backends/tofino/bf-asm/tables.h" +#include "lib/bitvec.h" class Stage_data { /* we encapsulate all the Stage non-static fields in a base class to automate the diff --git a/backends/tofino/bf-asm/stateful.cpp b/backends/tofino/bf-asm/stateful.cpp index 8fc9126fa77..d36b74191e2 100644 --- a/backends/tofino/bf-asm/stateful.cpp +++ b/backends/tofino/bf-asm/stateful.cpp @@ -17,14 +17,14 @@ #include "tofino/stateful.h" -#include "lib/algorithm.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" #include "data_switchbox.h" #include "input_xbar.h" #include "instruction.h" #include "jbay/stateful.h" +#include "lib/algorithm.h" #include "misc.h" -#include "backends/tofino/bf-asm/stage.h" -#include "backends/tofino/bf-asm/tables.h" void StatefulTable::parse_register_params(int idx, const value_t &val) { if (idx < 0 || idx > Target::STATEFUL_REGFILE_ROWS()) diff --git a/backends/tofino/bf-asm/synth2port.cpp b/backends/tofino/bf-asm/synth2port.cpp index 44188811daa..f86d33e5254 100644 --- a/backends/tofino/bf-asm/synth2port.cpp +++ b/backends/tofino/bf-asm/synth2port.cpp @@ -15,12 +15,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "lib/algorithm.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" #include "data_switchbox.h" #include "input_xbar.h" +#include "lib/algorithm.h" #include "misc.h" -#include "backends/tofino/bf-asm/stage.h" -#include "backends/tofino/bf-asm/tables.h" void Synth2Port::common_init_setup(const VECTOR(pair_t) & data, bool, P4Table::type p4type) { setup_layout(layout, data); diff --git a/backends/tofino/bf-asm/tables.cpp b/backends/tofino/bf-asm/tables.cpp index c5686f9c674..48dc181e5a8 100644 --- a/backends/tofino/bf-asm/tables.cpp +++ b/backends/tofino/bf-asm/tables.cpp @@ -23,11 +23,11 @@ #include #include "action_bus.h" -#include "lib/algorithm.h" +#include "backends/tofino/bf-asm/stage.h" #include "input_xbar.h" #include "instruction.h" +#include "lib/algorithm.h" #include "misc.h" -#include "backends/tofino/bf-asm/stage.h" // template specialization declarations diff --git a/backends/tofino/bf-asm/tables.h b/backends/tofino/bf-asm/tables.h index effa3ea9045..a0f19873756 100644 --- a/backends/tofino/bf-asm/tables.h +++ b/backends/tofino/bf-asm/tables.h @@ -26,13 +26,14 @@ #include #include -#include "lib/algorithm.h" #include "alloc.h" #include "asm-types.h" +#include "backends/tofino/bf-asm/json.h" +#include "backends/tofino/bf-asm/target.h" #include "constants.h" #include "hash_dist.h" #include "input_xbar.h" -#include "backends/tofino/bf-asm/json.h" +#include "lib/algorithm.h" #include "lib/bitops.h" #include "lib/bitvec.h" #include "lib/ordered_map.h" @@ -40,7 +41,6 @@ #include "p4_table.h" #include "phv.h" #include "slist.h" -#include "backends/tofino/bf-asm/target.h" class ActionBus; struct ActionBusSource; diff --git a/backends/tofino/bf-asm/target.cpp b/backends/tofino/bf-asm/target.cpp index 5f55af35108..d5df8a93ecd 100644 --- a/backends/tofino/bf-asm/target.cpp +++ b/backends/tofino/bf-asm/target.cpp @@ -20,9 +20,9 @@ #include #include "asm-types.h" +#include "backends/tofino/bf-asm/tables.h" #include "bson.h" #include "parser.h" -#include "backends/tofino/bf-asm/tables.h" #include "ubits.h" void declare_registers(const Target::Tofino::top_level_regs *regs) { diff --git a/backends/tofino/bf-asm/ternary_match.cpp b/backends/tofino/bf-asm/ternary_match.cpp index 9ecee2971b0..a5d195db7fc 100644 --- a/backends/tofino/bf-asm/ternary_match.cpp +++ b/backends/tofino/bf-asm/ternary_match.cpp @@ -18,13 +18,13 @@ #include "tofino/ternary_match.h" #include "action_bus.h" -#include "lib/algorithm.h" +#include "backends/tofino/bf-asm/stage.h" +#include "backends/tofino/bf-asm/tables.h" #include "input_xbar.h" #include "instruction.h" -#include "misc.h" +#include "lib/algorithm.h" #include "lib/range.h" -#include "backends/tofino/bf-asm/stage.h" -#include "backends/tofino/bf-asm/tables.h" +#include "misc.h" Table::Format::Field *TernaryMatchTable::lookup_field(const std::string &n, const std::string &act) const { diff --git a/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_cases.py b/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_cases.py index fb0f38a6f99..9912ea2c060 100644 --- a/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_cases.py +++ b/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_cases.py @@ -10,16 +10,21 @@ # TEST_LIST = [ - ["../asm/network_tap.bfa", [], { - "ingress,parse_inner_ipv6": (68, 30), - "ingress,parse_ipv6.$split_1": (56, 18), - "ingress,parse_inner_tcp": (72, 34), - "ingress,parse_volte,0x6*": (68, 28), - "egress,parse_gtp_base,0x01****": (60, 36), - "egress,parse_imsi": (64, 38), - "egress,parse_volte,0x6*": (60, 36), - "egress,parse_inner_tcp": (64, 44), - "egress,parse_inner_ipv6": (64, 40), - "egress,parse_ipv6": (32, 18), - "egress,parse_mpls_bos,0x6*": (52, 26)}], + [ + "../asm/network_tap.bfa", + [], + { + "ingress,parse_inner_ipv6": (68, 30), + "ingress,parse_ipv6.$split_1": (56, 18), + "ingress,parse_inner_tcp": (72, 34), + "ingress,parse_volte,0x6*": (68, 28), + "egress,parse_gtp_base,0x01****": (60, 36), + "egress,parse_imsi": (64, 38), + "egress,parse_volte,0x6*": (60, 36), + "egress,parse_inner_tcp": (64, 44), + "egress,parse_inner_ipv6": (64, 40), + "egress,parse_ipv6": (32, 18), + "egress,parse_mpls_bos,0x6*": (52, 26), + }, + ], ] diff --git a/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_test.py b/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_test.py index 40013374d1d..6b327392c40 100755 --- a/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_test.py +++ b/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_test.py @@ -1,13 +1,13 @@ #!/usr/bin/env python3 import os -import shlex -import subprocess import pdb import pprint +import re +import shlex +import subprocess import sys import traceback -import re import bfas_lookup_cases @@ -41,7 +41,9 @@ def run_bfas_translation(bfa_file, bfa_options, log_file): * log_file - file we want to log into """ try: - bfa_command = [BFAS_TOOL_ABS, "-v", "-v", "-v", "-v", "-l", log_file] + bfa_options + [bfa_file] + bfa_command = ( + [BFAS_TOOL_ABS, "-v", "-v", "-v", "-v", "-l", log_file] + bfa_options + [bfa_file] + ) cmd_concat = ' '.join(bfa_command) p = subprocess.Popen(cmd_concat, shell=True) p.wait() @@ -100,8 +102,11 @@ def run_test(): # Check that both dictionaries contains same keys same_key_set = set(expected_results.keys()) == set(translation_results.keys()) if not same_key_set: - raise RuntimeError("Key sets are not same:\n\tExpected: {}\n\tReceived{}".format( - expected_results.keys(), translation_results.keys())) + raise RuntimeError( + "Key sets are not same:\n\tExpected: {}\n\tReceived{}".format( + expected_results.keys(), translation_results.keys() + ) + ) # Iterate over the dictionary and check results for match, values in expected_results.items(): diff --git a/backends/tofino/bf-asm/test/update_config.py b/backends/tofino/bf-asm/test/update_config.py index 9da725d15af..01e8ff20e2e 100644 --- a/backends/tofino/bf-asm/test/update_config.py +++ b/backends/tofino/bf-asm/test/update_config.py @@ -16,24 +16,20 @@ # import argparse +import struct from time import sleep +import google.protobuf.text_format import grpc from p4 import p4runtime_pb2 from p4.config import p4info_pb2 from p4.tmp import p4config_pb2 -import google.protobuf.text_format -import struct parser = argparse.ArgumentParser(description='Mininet demo') -parser.add_argument('--dev-id', help='Device id of switch', - type=int, action="store", default=0) -parser.add_argument('--p4info', help='text p4info proto', - type=str, action="store", required=True) -parser.add_argument('--tofino-bin', help='tofino bin', - type=str, action="store", required=True) -parser.add_argument('--cxt-json', help='context json', - type=str, action="store", required=True) +parser.add_argument('--dev-id', help='Device id of switch', type=int, action="store", default=0) +parser.add_argument('--p4info', help='text p4info proto', type=str, action="store", required=True) +parser.add_argument('--tofino-bin', help='tofino bin', type=str, action="store", required=True) +parser.add_argument('--cxt-json', help='context json', type=str, action="store", required=True) args = parser.parse_args() @@ -66,5 +62,6 @@ def main(): # print request response = stub.SetForwardingPipelineConfig(request) + if __name__ == '__main__': main() diff --git a/backends/tofino/bf-asm/test/validate.py b/backends/tofino/bf-asm/test/validate.py index bafe90415ed..80d8416109c 100755 --- a/backends/tofino/bf-asm/test/validate.py +++ b/backends/tofino/bf-asm/test/validate.py @@ -1,13 +1,14 @@ import json import sys + from jsonschema import validate json_file = sys.argv[1] schema_file = sys.argv[2] -print "Validating `%s` JSON file against `%s` schema..." % (json_file, schema_file) +print("Validating `%s` JSON file against `%s` schema..." % (json_file, schema_file)) -j = {} +j = {} with open(json_file, 'r') as f: j = json.load(f) @@ -17,9 +18,9 @@ try: validate(j, s) -except Exception, e: - print "Failed to validate JSON file against schema." - print str(e) +except Exception as e: + print("Failed to validate JSON file against schema.") + print(f"{e}") exit(1) -print "File validated against schema." +print("File validated against schema.") diff --git a/backends/tofino/bf-asm/walle/csr.py b/backends/tofino/bf-asm/walle/csr.py index c50a1312923..5f709d35d28 100644 --- a/backends/tofino/bf-asm/walle/csr.py +++ b/backends/tofino/bf-asm/walle/csr.py @@ -21,31 +21,32 @@ TODO: explain how to generate Semifore CSV files properly """ +import copy import csv -import os.path +import glob import hashlib -import copy -import string +import os.path import re +import string import sys -import glob - -from operator import mul -from operator import ior +from functools import reduce +from operator import ior, mul import chip -from functools import reduce ######################################################################## ## Utility functions + def array_str(array_idx): """ Given a list of integers, return a string containing those integers in [] for generating a C++ index expression """ - if array_idx is None: return "" - return reduce(lambda x,y: x+"[%i]"%y,array_idx,"") + if array_idx is None: + return "" + return reduce(lambda x, y: x + "[%i]" % y, array_idx, "") + def product(seq): """ @@ -54,7 +55,8 @@ def product(seq): @param seq A list of integers @return The product of the integers in the list """ - return reduce(mul, seq, 1 ) + return reduce(mul, seq, 1) + def nd_array_loop(count, data, func, context=None, current_dim=0): """ @@ -83,14 +85,17 @@ def nd_array_loop(count, data, func, context=None, current_dim=0): intended to be stored beyond the current scope. """ if context == None: - context = [0]*len(count) - if current_dim < len(count)-1: + context = [0] * len(count) + if current_dim < len(count) - 1: for idx in range(0, count[current_dim]): context[current_dim] = idx - nd_array_loop(count, None if data is None else data[idx], func, context, current_dim+1) + nd_array_loop( + count, None if data is None else data[idx], func, context, current_dim + 1 + ) else: func(data, context) + def count_array_loop(count, func, context=None, current_dim=0): """ Given a vector of dimensions, call func for each possible legal index @@ -109,16 +114,15 @@ def count_array_loop(count, func, context=None, current_dim=0): intended to be stored beyond the current scope. """ if context == None: - context = [0]*len(count) + context = [0] * len(count) if current_dim < len(count): for idx in range(0, count[current_dim]): context[current_dim] = idx - count_array_loop(count, func, context, current_dim+1) + count_array_loop(count, func, context, current_dim + 1) else: func(context) - def format_comment(outfile, indent, text): """ Output text as a C++ comment block in an output file @@ -143,11 +147,11 @@ def format_comment(outfile, indent, text): outfile.write("// ") outfile.write(' ' * pfx) line = line.lstrip() - pt = line.rfind(' ', 0, maxlen-pfx-len(indent)) + pt = line.rfind(' ', 0, maxlen - pfx - len(indent)) if len(line) + len(indent) + pfx > maxlen: if pt > 0: outfile.write(line[0:pt]) - line = line[pt+1:] + line = line[pt + 1 :] else: # line is longer than maxlen, but has no spaces. So don't split it or # subsequent lines (this is probably a wide table with columns) @@ -159,16 +163,20 @@ def format_comment(outfile, indent, text): line = '' outfile.write("\n") + def indent_comment(indent, text): - if not text: return text + if not text: + return text if text[-2:-1] != '\n': text = text + '\n' - return indent + text.replace('\n', indent+'\n') + return indent + text.replace('\n', indent + '\n') + ######################################################################## ## Structures -class CsrException (Exception): + +class CsrException(Exception): """ An exception that occured while crunching malformed data according to the given chip schema. An exception handler in walle.py will catch these @@ -179,9 +187,11 @@ class CsrException (Exception): any scope where a CsrException may be raised. 'path' is a list of traversal_history objects. """ + pass -class traversal_history (object): + +class traversal_history(object): """ A class which records part of Walle's traversal through input JSON data. A single traversal_history corresponds to the traversal of one JSON file. @@ -199,10 +209,12 @@ class traversal_history (object): [(4,),"a"] to represent a[4] [(1,2,3),"b"] to represent b[1][2][3] """ + def __init__(self, template_name): self.template_name = template_name self.path = [] + class binary_cache(object): """ A class used to store flat chip_obj lists, each corresponding to one JSON @@ -210,6 +222,7 @@ class binary_cache(object): Requesting a JSON file from here will crunch it into binary if it hasn't been already. """ + def __init__(self, schema): self.schema = schema self.templates = {} @@ -222,7 +235,7 @@ def get_type(self, key): """ return self.templates[key]["_type"] - def get_data (self, key, path=None): + def get_data(self, key, path=None): """ Return a list of objects inheriting from chip.chip_obj, representing the write operations that must be done in the hardware to program a @@ -231,7 +244,7 @@ def get_data (self, key, path=None): These lists are a deep copy of the one stored internally, so it is safe to modify them """ - if path==None: + if path == None: path = [] if key not in self.binary_templates: @@ -249,7 +262,8 @@ def get_data (self, key, path=None): binary_data_copy.append(chip_obj.deepcopy()) return binary_data_copy -class csr_object (object): + +class csr_object(object): """ Base class for objects in a Semifore register hierarchy @@ -267,31 +281,37 @@ def __init__(self, name, count): self.name = name self.count = count - def replicate (self, templatized_self): + def replicate(self, templatized_self): if self.count != (1,): last_dim_obj = templatized_self for dim in reversed(self.count): - last_dim_obj = [copy.deepcopy(last_dim_obj) for _ in range(0,dim)] + last_dim_obj = [copy.deepcopy(last_dim_obj) for _ in range(0, dim)] return last_dim_obj else: return templatized_self def is_field(self): return False + def is_singleton(self): return False + def singleton_obj(self): return self + def contains_reference(self): return False -class csr_composite_object (csr_object): + +class csr_composite_object(csr_object): """ Base class for composite (non-leaf) CSR objects. All such objects have one or more children """ + def __init__(self, name, count): csr_object.__init__(self, name, count) + def children(self): raise CsrException("Unimplemented abstract method for " + type(self)) @@ -321,48 +341,59 @@ def check_child_rewrite(self, child, args): if description[-2:-1] != '\n': description = description + '\n' if len(child.children()) != 1 or child.count != (1,): - raise CsrException("unknown rewrite '%s' for %s.%s" % - (rewrite[child.name][0], name, child.name)) + raise CsrException( + "unknown rewrite '%s' for %s.%s" + % (rewrite[child.name][0], name, child.name) + ) child = child.children()[0] if hasattr(child, 'description') and child.description: description = description + child.description if description[-2:-1] != '\n': description = description + '\n' - child = scanset_reg(rewrite[1], tuple(rewrite[2]), offset, child.width, - self, child.fields) + child = scanset_reg( + rewrite[1], tuple(rewrite[2]), offset, child.width, self, child.fields + ) child.description = description if len(child.fields) == 1: child.fields = copy.copy(child.fields) child.fields[0].name = rewrite[1] if len(rewrite) > 3: - #import pdb; pdb.set_trace() + # import pdb; pdb.set_trace() def find_scan_sel(obj, name, offset): desc = '' for ch in obj.children(): - pfx = len(ch.name)+1 - if ch.name+"." == name[:pfx]: + pfx = len(ch.name) + 1 + if ch.name + "." == name[:pfx]: return find_scan_sel(ch, name[pfx:], offset + ch.offset) if ch.name == name: offset = offset + ch.offset desc_hdr = ch.name + ':\n' if hasattr(ch, 'description') and ch.description: - desc = (desc + desc_hdr + indent_comment(' ', ch.description)) + desc = desc + desc_hdr + indent_comment(' ', ch.description) desc_hdr = '' - if (len(ch.fields) == 1 and hasattr(ch.fields[0], 'description') and - ch.fields[0].description): - desc = (desc + desc_hdr + - indent_comment(' ', ch.fields[0].description)) + if ( + len(ch.fields) == 1 + and hasattr(ch.fields[0], 'description') + and ch.fields[0].description + ): + desc = ( + desc + desc_hdr + indent_comment(' ', ch.fields[0].description) + ) return offset, desc return None, None + offset, desc = find_scan_sel(self, rewrite[3], 0) if offset is None: - raise CsrException("No "+rewrite[3]+" in "+self.name+" for scan selector") + raise CsrException( + "No " + rewrite[3] + " in " + self.name + " for scan selector" + ) child.sel_offset = offset child.description = child.description + desc return child else: - raise CsrException("unknown rewrite '%s' for %s.%s" % - (rewrite[el.name][0], name, el.name)) + raise CsrException( + "unknown rewrite '%s' for %s.%s" % (rewrite[el.name][0], name, el.name) + ) return None def contains_reference(self): @@ -380,7 +411,8 @@ def contains_reference(self): def gen_method_declarator(self, outfile, args, rtype, classname, name, argdecls, suffix): outfile.write("%s " % rtype) - if args.gen_decl == 'defn': outfile.write("%s::" % classname) + if args.gen_decl == 'defn': + outfile.write("%s::" % classname) outfile.write("%s(" % name) first = True for a in argdecls: @@ -411,8 +443,9 @@ def gen_emit_method(self, outfile, args, schema, classname, name, nameargs, inde argdecls.append("indent_t indent") else: argdecls.append("indent_t indent = indent_t(1)") - if self.gen_method_declarator(outfile, args, "void", classname, - "emit_json", argdecls, "const"): + if self.gen_method_declarator( + outfile, args, "void", classname, "emit_json", argdecls, "const" + ): return indent += " " if args.enable_disable and not self.top_level(): @@ -423,7 +456,7 @@ def gen_emit_method(self, outfile, args, schema, classname, name, nameargs, inde first = True if self.top_level(): if len(nameargs) > 0: - tmplen = len(name) + len(nameargs)*10 + 32 + tmplen = len(name) + len(nameargs) * 10 + 32 outfile.write("%schar tmp[%d];\n" % (indent, tmplen)) outfile.write('%ssnprintf(tmp, sizeof(tmp), "%s"' % (indent, name)) for i in range(0, len(nameargs)): @@ -433,24 +466,34 @@ def gen_emit_method(self, outfile, args, schema, classname, name, nameargs, inde else: outfile.write('%sout << indent << "\\"_name\\": \\"%s\\"";\n' % (indent, name)) outfile.write('%sout << ", \\n";\n' % indent) - outfile.write('%sout << indent << "\\"_reg_version\\": \\"%s\\"";\n' % - (indent, schema["_reg_version"])) + outfile.write( + '%sout << indent << "\\"_reg_version\\": \\"%s\\"";\n' + % (indent, schema["_reg_version"]) + ) outfile.write('%sout << ", \\n";\n' % indent) - outfile.write('%sout << indent << "\\"_schema_hash\\": \\"%s\\"";\n' % - (indent, schema["_schema_hash"])) + outfile.write( + '%sout << indent << "\\"_schema_hash\\": \\"%s\\"";\n' + % (indent, schema["_schema_hash"]) + ) outfile.write('%sout << ", \\n";\n' % indent) - outfile.write('%sout << indent << "\\"_section\\": \\"%s\\"";\n' % - (indent, self.parent)) + outfile.write( + '%sout << indent << "\\"_section\\": \\"%s\\"";\n' % (indent, self.parent) + ) outfile.write('%sout << ", \\n";\n' % indent) - outfile.write('%sout << indent << "\\"_type\\": \\"%s.%s\\"";\n' % - (indent, self.parent, self.name)) + outfile.write( + '%sout << indent << "\\"_type\\": \\"%s.%s\\"";\n' + % (indent, self.parent, self.name) + ) outfile.write('%sout << ", \\n";\n' % indent) - outfile.write('%sout << indent << "\\"_walle_version\\": \\"%s\\"";\n' % - (indent, schema["_walle_version"])) + outfile.write( + '%sout << indent << "\\"_walle_version\\": \\"%s\\"";\n' + % (indent, schema["_walle_version"]) + ) first = False for a in sorted(self.children(), key=lambda a: a.name): a = self.check_child_rewrite(a, args) - if a is None: continue + if a is None: + continue if not first: outfile.write('%sout << ", \\n";\n' % indent) outfile.write('%sout << indent << "\\"%s\\": ";\n' % (indent, a.name)) @@ -471,14 +514,18 @@ def gen_emit_method(self, outfile, args, schema, classname, name, nameargs, inde outfile.write("%s} else {\n" % indent) indent += ' ' outfile.write('%sout << "[\\n" << ++indent;\n' % indent) - outfile.write('%sfor (int i%d = 0; i%d < %d; i%d++) { \n' % - (indent, idx_num, idx_num, idx, idx_num)) + outfile.write( + '%sfor (int i%d = 0; i%d < %d; i%d++) { \n' + % (indent, idx_num, idx_num, idx, idx_num) + ) outfile.write('%s if (i%d) out << ", \\n" << indent;\n' % (indent, idx_num)) indent += ' ' single = a.singleton_obj() if single != a: - outfile.write('%sout << "{\\n" << indent+1 << "\\"%s\\": " << %s' % - (indent, a.name, field_name)) + outfile.write( + '%sout << "{\\n" << indent+1 << "\\"%s\\": " << %s' + % (indent, a.name, field_name) + ) if a.count != (1,): for i in range(0, len(a.count)): outfile.write("[i%d]" % i) @@ -505,7 +552,7 @@ def gen_emit_method(self, outfile, args, schema, classname, name, nameargs, inde outfile.write("%sout << '\\n' << --indent << ']';\n" % indent) if args.enable_disable and args.checked_array and not a.disabled(): indent = indent[2:] - outfile.write("%s}\n" %indent) + outfile.write("%s}\n" % indent) first = False outfile.write("%sout << '\\n' << indent-1 << \"}\";\n" % indent) indent = indent[2:] @@ -520,15 +567,24 @@ def child_name(child): if name in args.cpp_reserved: name += '_' return name + def field_name(child): name = child_name(child) if child.count != (1,): for i in range(0, len(child.count)): name += "[j%d]" % i return name + outfile.write(indent) - if self.gen_method_declarator(outfile, args, "void", classname, "emit_binary", - ["std::ostream &out", "uint64_t a"], "const"): + if self.gen_method_declarator( + outfile, + args, + "void", + classname, + "emit_binary", + ["std::ostream &out", "uint64_t a"], + "const", + ): return indent += " " if args.enable_disable: @@ -539,10 +595,12 @@ def field_name(child): addr_decl = "auto " for a in self.children(): addr_var = "a" - if a.disabled(): continue + if a.disabled(): + continue a = self.check_child_rewrite(a, args) - if a is None: continue - if root_parent=="memories": + if a is None: + continue + if root_parent == "memories": indirect = True width_unit = 128 address_unit = 16 @@ -564,20 +622,27 @@ def field_name(child): outfile.write("%sif (!%s.disabled()) {\n" % (indent, child_name(a))) indent += ' ' if indirect and type(a) is reg: - outfile.write("%sout << binout::tag('%s') << binout::byte8" % (indent, type_tag) + - "(a + 0x%x) << binout::byte4(%d) << binout::byte4(%d);\n" % - (a.offset//address_unit, width_unit, - product(a.count) * a.width // width_unit)) + outfile.write( + "%sout << binout::tag('%s') << binout::byte8" % (indent, type_tag) + + "(a + 0x%x) << binout::byte4(%d) << binout::byte4(%d);\n" + % ( + a.offset // address_unit, + width_unit, + product(a.count) * a.width // width_unit, + ) + ) if a.count != (1,): if args.enable_disable: outfile.write("%sauto addr = a;\n" % indent) else: outfile.write("%s%saddr = a;\n" % (indent, addr_decl)) - addr_decl = ""; + addr_decl = "" addr_var = "addr" for idx_num, idx in enumerate(a.count): - outfile.write('%sfor (int j%d = 0; j%d < %d; j%d++) { \n' % - (indent, idx_num, idx_num, idx, idx_num)) + outfile.write( + '%sfor (int j%d = 0; j%d < %d; j%d++) { \n' + % (indent, idx_num, idx_num, idx, idx_num) + ) indent += ' ' single = a.singleton_obj() if not indirect and single != a: @@ -589,25 +654,35 @@ def field_name(child): outfile.write("%sif (!%s.disabled()) {\n" % (indent, field_name(a))) indent += ' ' if single.msb >= 64: - for w in (list(range(single.msb//32, -1, -1)) - if args.reverse_write else - list(range(0, single.msb//32 + 1))): - outfile.write("%sout << binout::tag('R') << binout::byte4" % indent + - "(%s + 0x%x) << binout::byte4(%s.value.getrange(%d, 32));\n" % - (addr_var, a.offset//address_unit + 4, field_name(a), w*32)) + for w in ( + list(range(single.msb // 32, -1, -1)) + if args.reverse_write + else list(range(0, single.msb // 32 + 1)) + ): + outfile.write( + "%sout << binout::tag('R') << binout::byte4" % indent + + "(%s + 0x%x) << binout::byte4(%s.value.getrange(%d, 32));\n" + % (addr_var, a.offset // address_unit + 4, field_name(a), w * 32) + ) else: if not args.reverse_write: - outfile.write("%sout << binout::tag('R') << binout::byte4" % indent + - "(%s + 0x%x) << binout::byte4(%s);\n" % - (addr_var, a.offset//address_unit, field_name(a))) + outfile.write( + "%sout << binout::tag('R') << binout::byte4" % indent + + "(%s + 0x%x) << binout::byte4(%s);\n" + % (addr_var, a.offset // address_unit, field_name(a)) + ) if single.msb >= 32: - outfile.write("%sout << binout::tag('R') << binout::byte4" % indent + - "(%s + 0x%x) << binout::byte4(%s >> 32);\n" % - (addr_var, a.offset//address_unit + 4, field_name(a))) + outfile.write( + "%sout << binout::tag('R') << binout::byte4" % indent + + "(%s + 0x%x) << binout::byte4(%s >> 32);\n" + % (addr_var, a.offset // address_unit + 4, field_name(a)) + ) if args.reverse_write: - outfile.write("%sout << binout::tag('R') << binout::byte4" % indent + - "(%s + 0x%x) << binout::byte4(%s);\n" % - (addr_var, a.offset//address_unit, field_name(a))) + outfile.write( + "%sout << binout::tag('R') << binout::byte4" % indent + + "(%s + 0x%x) << binout::byte4(%s);\n" + % (addr_var, a.offset // address_unit, field_name(a)) + ) indent = indent[2:] outfile.write("%s}\n" % indent) else: @@ -616,10 +691,11 @@ def field_name(child): outfile.write("if (%s)" % field_name(a)) outfile.write(field_name(a)) outfile.write("->" if a.top_level() else ".") - outfile.write("emit_binary(out, %s + 0x%x);\n" % - (addr_var, a.offset//address_unit)) + outfile.write( + "emit_binary(out, %s + 0x%x);\n" % (addr_var, a.offset // address_unit) + ) if a.count != (1,): - outfile.write("%saddr += 0x%x;\n" % (indent, a.address_stride()//address_unit)) + outfile.write("%saddr += 0x%x;\n" % (indent, a.address_stride() // address_unit)) for i in range(0, len(a.count)): indent = indent[2:] outfile.write("%s}\n" % indent) @@ -635,15 +711,24 @@ def child_name(child): if name in args.cpp_reserved: name += '_' return name + def field_name(child): name = child_name(child) if child.count != (1,): for i in range(0, len(child.count)): name += "[i%d]" % i return name + outfile.write(indent) - if self.gen_method_declarator(outfile, args, "void", classname, "input_binary", - ["uint64_t a", "char t", "uint32_t *d", "size_t l"], ""): + if self.gen_method_declarator( + outfile, + args, + "void", + classname, + "input_binary", + ["uint64_t a", "char t", "uint32_t *d", "size_t l"], + "", + ): return indent += " " root_parent = self.parent @@ -652,114 +737,144 @@ def field_name(child): if root_parent == "memories": width_unit = 128 address_unit = 16 - outfile.write("%sBUG_CHECK(t == 'D', \"'%%c' tag in memories\", t);\n" % indent); + outfile.write("%sBUG_CHECK(t == 'D', \"'%%c' tag in memories\", t);\n" % indent) else: width_unit = 32 address_unit = 1 - outfile.write("%sBUG_CHECK(t != 'D', \"'%%c' tag in %s\", t);\n" % - (indent, root_parent)) + outfile.write( + "%sBUG_CHECK(t != 'D', \"'%%c' tag in %s\", t);\n" % (indent, root_parent) + ) first = True for a in sorted(self.children(), key=lambda a: -a.offset): - outfile.write('%s%sif (a >= 0x%x) {\n' % - (indent, '' if first else '} else ', a.offset//address_unit)) + outfile.write( + '%s%sif (a >= 0x%x) {\n' + % (indent, '' if first else '} else ', a.offset // address_unit) + ) indent += ' ' t = a a = self.check_child_rewrite(a, args) if a is None: - outfile.write('%sstd::cerr << "Address in ignored reg " << ' % indent + - 'string_regname(this, this+1) << ".%s" << std::endl;\n' % t.name) + outfile.write( + '%sstd::cerr << "Address in ignored reg " << ' % indent + + 'string_regname(this, this+1) << ".%s" << std::endl;\n' % t.name + ) elif isinstance(a, scanset_reg): a.input_binary(outfile, args, indent, address_unit, width_unit) elif a.disabled(): - outfile.write('%sstd::cerr << "Address in disabled reg " << ' % indent + - 'string_regname(this, this+1) << ".%s" << std::endl;\n' % a.name) + outfile.write( + '%sstd::cerr << "Address in disabled reg " << ' % indent + + 'string_regname(this, this+1) << ".%s" << std::endl;\n' % a.name + ) else: - outfile.write('%sa -= 0x%x;\n' % (indent, a.offset//address_unit)) + outfile.write('%sa -= 0x%x;\n' % (indent, a.offset // address_unit)) idx_suffix = '' if a.count != (1,): - outfile.write('%ssize_t idx = a / 0x%x;\n' % - (indent, a.address_stride()//address_unit)) + outfile.write( + '%ssize_t idx = a / 0x%x;\n' % (indent, a.address_stride() // address_unit) + ) for idx_num, idx in reversed(list(enumerate(a.count))): outfile.write('%sint i%d = idx %% %d;\n' % (indent, idx_num, idx)) if idx_num == 0: - outfile.write('%sBUG_CHECK(idx < %d, "Index too' % (indent, idx) + - ' large for %%s.%s[%%zd]",\n' % a.name) - outfile.write('%s ' % indent + - 'string_regname(this, this+1).c_str(), idx);\n') + outfile.write( + '%sBUG_CHECK(idx < %d, "Index too' % (indent, idx) + + ' large for %%s.%s[%%zd]",\n' % a.name + ) + outfile.write( + '%s ' % indent + + 'string_regname(this, this+1).c_str(), idx);\n' + ) else: outfile.write('%sidx /= %d;\n' % (indent, idx)) idx_suffix = ('[i%d]' % idx_num) + idx_suffix - outfile.write('%sa -= 0x%x * %s' % (indent, a.address_stride()//address_unit, - '(' * (len(a.count)-1))) + outfile.write( + '%sa -= 0x%x * %s' + % (indent, a.address_stride() // address_unit, '(' * (len(a.count) - 1)) + ) for idx_num, idx in enumerate(a.count): if idx_num != 0: outfile.write('*%d + ' % idx) outfile.write('i%d' % idx_num) if idx_num != 0: outfile.write(')') - outfile.write(';\n'); - #outfile.write('%sstd::cout << string_regname(this, this+1) << ".%s' % + outfile.write(';\n') + # outfile.write('%sstd::cout << string_regname(this, this+1) << ".%s' % # (indent, a.name)) - #if a.count != (1,): + # if a.count != (1,): # for idx_num, idx in enumerate(a.count): # outfile.write('[" << i%d << "]' % idx_num) - #outfile.write('" << std::endl;\n'); + # outfile.write('" << std::endl;\n'); access = '.' if a.top_level(): outfile.write('%sif (!%s) {\n' % (indent, field_name(a))) - outfile.write('%s auto *n = new %s;\n' % (indent, - a.canon_name(a.map.object_name)[0])) - outfile.write('%s auto fn = string_regname(this, this+1);\n' % indent); - outfile.write('%s declare_registers(n, sizeof(*n),\n' % indent); - outfile.write('%s [=](std::ostream &out, const char *addr, ' % indent + - 'const void *end) {\n'); + outfile.write( + '%s auto *n = new %s;\n' % (indent, a.canon_name(a.map.object_name)[0]) + ) + outfile.write('%s auto fn = string_regname(this, this+1);\n' % indent) + outfile.write('%s declare_registers(n, sizeof(*n),\n' % indent) + outfile.write( + '%s [=](std::ostream &out, const char *addr, ' % indent + + 'const void *end) {\n' + ) outfile.write('%s out << fn << ".%s' % (indent, child_name(a))) if a.count != (1,): for idx_num, idx in enumerate(a.count): outfile.write('[" << i%d << "]' % idx_num) - outfile.write('";\n'); + outfile.write('";\n') outfile.write('%s n->emit_fieldname(out, addr, end); });\n' % indent) - outfile.write('%s %s.set("%s", n); }\n' % - (indent, field_name(a), child_name(a))) + outfile.write( + '%s %s.set("%s", n); }\n' % (indent, field_name(a), child_name(a)) + ) access = '->' single = a.singleton_obj() if single != a: - outfile.write("%sBUG_CHECK(t == 'R' && l == 1, \"tag '%%c' " % indent + - 'input to singleton %s", t);\n' % field_name(a)) + outfile.write( + "%sBUG_CHECK(t == 'R' && l == 1, \"tag '%%c' " % indent + + 'input to singleton %s", t);\n' % field_name(a) + ) if single.msb >= 64: - outfile.write('%sBUG("widereg singleton %s not implemented");' % - (indent, field_name(a))) + outfile.write( + '%sBUG("widereg singleton %s not implemented");' + % (indent, field_name(a)) + ) elif single.msb >= 32: - outfile.write('%sBUG_CHECK((a|4) == 4, "invalid addr %%zd in ' % indent + - '%s", a);\n' % field_name(a)) - outfile.write('%s%s.set_subfield(*d, a*8, 32);\n' % - (indent, field_name(a))) + outfile.write( + '%sBUG_CHECK((a|4) == 4, "invalid addr %%zd in ' % indent + + '%s", a);\n' % field_name(a) + ) + outfile.write('%s%s.set_subfield(*d, a*8, 32);\n' % (indent, field_name(a))) else: outfile.write('%s%s = *d;\n' % (indent, field_name(a))) elif isinstance(a, reg) and a.count != (1,): - outfile.write('%sBUG_CHECK(a == 0 || l == 1, "%%" PRIu64 " off ' % indent + - 'start of %s", a);\n' % a.name) - if a.width%32 != 0: + outfile.write( + '%sBUG_CHECK(a == 0 || l == 1, "%%" PRIu64 " off ' % indent + + 'start of %s", a);\n' % a.name + ) + if a.width % 32 != 0: raise CsrException("Register %s width not a multiple of 32" % a.name) - size = a.width//32 + size = a.width // 32 outfile.write('%swhile (l > %d) {\n' % (indent, size)) - indent += ' '; - outfile.write('%s%s%sinput_binary(a, t, d, %d);\n' % - (indent, field_name(a), access, size)) + indent += ' ' + outfile.write( + '%s%s%sinput_binary(a, t, d, %d);\n' % (indent, field_name(a), access, size) + ) outfile.write('%sd += %d; l -= %d;\n' % (indent, size, size)) for idx_num, idx in reversed(list(enumerate(a.count))): outfile.write('%sif (++i%d >= %d) {\n' % (indent, idx_num, idx)) indent += ' ' if idx_num != 0: outfile.write('%si%d = 0;\n' % (indent, idx_num)) - outfile.write('%sBUG("Too much data for %s");%s\n' % - (indent, a.name, ' }' * (len(a.count) + 1))) - indent = indent[2 * (len(a.count) + 1):] - outfile.write('%s%s%sinput_binary(a, t, d, l);\n' % - (indent, field_name(a), access)) + outfile.write( + '%sBUG("Too much data for %s");%s\n' + % (indent, a.name, ' }' * (len(a.count) + 1)) + ) + indent = indent[2 * (len(a.count) + 1) :] + outfile.write( + '%s%s%sinput_binary(a, t, d, l);\n' % (indent, field_name(a), access) + ) else: - outfile.write('%s%s%sinput_binary(a, t, d, l);\n' % - (indent, field_name(a), access)) + outfile.write( + '%s%s%sinput_binary(a, t, d, l);\n' % (indent, field_name(a), access) + ) indent = indent[2:] first = False outfile.write('%s}\n' % indent) @@ -769,13 +884,20 @@ def field_name(child): def gen_binary_offset_method(self, outfile, args, classname, indent): outfile.write(indent) - if self.gen_method_declarator(outfile, args, "uint64_t", classname, "binary_offset", - ["const void *addr", ("int *bit_offset", "0")], "const"): + if self.gen_method_declarator( + outfile, + args, + "uint64_t", + classname, + "binary_offset", + ["const void *addr", ("int *bit_offset", "0")], + "const", + ): return root_parent = self.parent while type(root_parent) is not str: root_parent = root_parent.parent - if root_parent=="memories": + if root_parent == "memories": width_unit = 128 address_unit = 16 else: @@ -783,30 +905,35 @@ def gen_binary_offset_method(self, outfile, args, classname, indent): address_unit = 1 indent += " " outfile.write("%suint64_t offset = 0;\n" % indent) - outfile.write("%sif (bit_offset) *bit_offset = 0;\n" %indent) + outfile.write("%sif (bit_offset) *bit_offset = 0;\n" % indent) outfile.write("%sif (addr < this || addr >= this+1) " % indent) - if (self.contains_reference()): + if self.contains_reference(): outfile.write("{\n") indent += " " for a in self.children(): - if a.disabled(): continue - if not (a.top_level() or a.contains_reference()): continue + if a.disabled(): + continue + if not (a.top_level() or a.contains_reference()): + continue field_name = a.name if field_name in args.cpp_reserved: field_name += '_' if a.count != (1,): for i, idx in enumerate(a.count): - outfile.write('%sfor (int i%d = 0; i%d < %d; i%d++) { \n' % - (indent, i, i, idx, i)) + outfile.write( + '%sfor (int i%d = 0; i%d < %d; i%d++) { \n' % (indent, i, i, idx, i) + ) indent += ' ' field_name += "[i%d]" % i - outfile.write("%sif ((offset = %s%sbinary_offset(addr, bit_offset)) != -1)\n" % - (indent, field_name, "->" if a.top_level() else ".")) - outfile.write("%s return offset + 0x%x" % (indent, a.offset//address_unit)) + outfile.write( + "%sif ((offset = %s%sbinary_offset(addr, bit_offset)) != -1)\n" + % (indent, field_name, "->" if a.top_level() else ".") + ) + outfile.write("%s return offset + 0x%x" % (indent, a.offset // address_unit)) if a.count != (1,): for i, idx in enumerate(a.count): - stride = a.address_stride()//address_unit - for cnt in a.count[i+1:]: + stride = a.address_stride() // address_unit + for cnt in a.count[i + 1 :]: stride = stride * cnt outfile.write(" + i%d*0x%x" % (i, stride)) outfile.write(";\n") @@ -822,33 +949,41 @@ def gen_binary_offset_method(self, outfile, args, classname, indent): first = True for a in sorted(self.children(), key=lambda a: a.name, reverse=True): - if a.disabled(): continue - if a.top_level(): continue + if a.disabled(): + continue + if a.top_level(): + continue a = self.check_child_rewrite(a, args) - if a is None: continue + if a is None: + continue field_name = a.name if field_name in args.cpp_reserved: field_name += '_' outfile.write(indent) - if first: first = False - else: outfile.write("} else ") + if first: + first = False + else: + outfile.write("} else ") outfile.write("if (addr >= &%s) {\n" % field_name) indent += " " - outfile.write("%soffset = 0x%x;\n" % (indent, a.offset//address_unit)) + outfile.write("%soffset = 0x%x;\n" % (indent, a.offset // address_unit)) if a.count != (1,): for i, idx in enumerate(a.count): outfile.write("%sif (addr < &%s[0]) return offset;\n" % (indent, field_name)) - outfile.write("%sauto i%d = ((char *)addr - (char *)&%s[0])/sizeof(%s[0]);\n" % - (indent, i, field_name, field_name)) - stride = a.address_stride()//address_unit - for cnt in a.count[i+1:]: + outfile.write( + "%sauto i%d = ((char *)addr - (char *)&%s[0])/sizeof(%s[0]);\n" + % (indent, i, field_name, field_name) + ) + stride = a.address_stride() // address_unit + for cnt in a.count[i + 1 :]: stride = stride * cnt outfile.write("%soffset += i%d * 0x%x;\n" % (indent, i, stride)) field_name += "[i%d]" % i single = a.singleton_obj() if not single.is_field() and not single.top_level(): - outfile.write("%soffset += %s.binary_offset(addr, bit_offset);\n" % - (indent, field_name)) + outfile.write( + "%soffset += %s.binary_offset(addr, bit_offset);\n" % (indent, field_name) + ) indent = indent[2:] if first: outfile.write("%sreturn -1;\n" % indent) @@ -862,33 +997,47 @@ def gen_binary_offset_method(self, outfile, args, classname, indent): def gen_fieldname_method(self, outfile, args, classname, indent): outfile.write(indent) - if self.gen_method_declarator(outfile, args, "void", classname, "emit_fieldname", - ["std::ostream &out", "const char *addr", "const void *end"], "const"): + if self.gen_method_declarator( + outfile, + args, + "void", + classname, + "emit_fieldname", + ["std::ostream &out", "const char *addr", "const void *end"], + "const", + ): return indent += " " if not self.is_singleton(): outfile.write("%sif ((void *)addr == this && end == this+1) return;\n" % indent) first = True for a in sorted(self.children(), key=lambda a: a.name, reverse=True): - if a.disabled(): continue + if a.disabled(): + continue a = self.check_child_rewrite(a, args) - if a is None: continue + if a is None: + continue field_name = a.name if field_name in args.cpp_reserved: field_name += '_' outfile.write(indent) - if first: first = False - else: outfile.write("} else ") + if first: + first = False + else: + outfile.write("} else ") outfile.write("if (addr >= (char *)&%s) {\n" % field_name) indent += " " outfile.write('%sout << ".%s";\n' % (indent, a.name)) if a.count != (1,): for i, idx in enumerate(a.count): - outfile.write("%sint i%d = (addr - (char *)&%s[0])/(int)sizeof(%s[0]);\n" % ( - indent, i, field_name, field_name)) + outfile.write( + "%sint i%d = (addr - (char *)&%s[0])/(int)sizeof(%s[0]);\n" + % (indent, i, field_name, field_name) + ) if idx > 1: - outfile.write("%sif (i%d < 0 || (i%d == 0 && 1 + &%s" % ( - indent, i, i, field_name)) + outfile.write( + "%sif (i%d < 0 || (i%d == 0 && 1 + &%s" % (indent, i, i, field_name) + ) outfile.write(" == end)) return;\n") outfile.write("%sout << '[' << i%d << ']';\n" % (indent, i)) field_name += "[i%d]" % i @@ -903,29 +1052,37 @@ def gen_fieldname_method(self, outfile, args, classname, indent): def gen_unpack_method(self, outfile, args, classname, indent): outfile.write(indent) - if self.gen_method_declarator(outfile, args, "int", classname, "unpack_json", - ["json::obj *obj"], ""): + if self.gen_method_declarator( + outfile, args, "int", classname, "unpack_json", ["json::obj *obj"], "" + ): return indent += " " outfile.write("%sint rv = 0;\n" % indent) outfile.write("%sjson::map *m = dynamic_cast(obj);\n" % indent) outfile.write("%sif (!m) return -1;\n" % indent) for a in sorted(self.children(), key=lambda a: a.name): - if a.disabled(): continue + if a.disabled(): + continue a = self.check_child_rewrite(a, args) - if a is None: continue + if a is None: + continue index_num = 0 if a.count != (1,): for index_num, idx in enumerate(a.count): - outfile.write("%sif (json::vector *v%s = dynamic_cast(" % - (indent, index_num)) + outfile.write( + "%sif (json::vector *v%s = dynamic_cast(" + % (indent, index_num) + ) indent += " " if index_num > 0: - outfile.write("(*v%d)[i%d].get()" % (index_num-1, index_num-1)) - else: outfile.write('(*m)["%s"].get()' % a.name) + outfile.write("(*v%d)[i%d].get()" % (index_num - 1, index_num - 1)) + else: + outfile.write('(*m)["%s"].get()' % a.name) outfile.write("))\n") - outfile.write("%sfor (int i%d = 0; i%d < %d; i%d++)\n" % - (indent, index_num, index_num, idx, index_num)) + outfile.write( + "%sfor (int i%d = 0; i%d < %d; i%d++)\n" + % (indent, index_num, index_num, idx, index_num) + ) indent += " " index_num = len(a.count) single = a.singleton_obj() @@ -936,8 +1093,9 @@ def gen_unpack_method(self, outfile, args, classname, indent): outfile.write("%sif (json::map *s = dynamic_cast(" % indent) indent += " " if index_num > 0: - outfile.write("(*v%d)[i%d].get()" % (index_num-1, index_num-1)) - else: outfile.write('(*m)["%s"].get()' % a.name) + outfile.write("(*v%d)[i%d].get()" % (index_num - 1, index_num - 1)) + else: + outfile.write('(*m)["%s"].get()' % a.name) outfile.write("))\n") outfile.write("%sif (json::number *n = dynamic_cast" % indent) indent += " " @@ -958,8 +1116,9 @@ def gen_unpack_method(self, outfile, args, classname, indent): outfile.write("[i%d]" % i) outfile.write(".unpack_json(") if index_num > 0: - outfile.write("(*v%d)[i%d].get()" % (index_num-1, index_num-1)) - else: outfile.write('(*m)["%s"].get()' % a.name) + outfile.write("(*v%d)[i%d].get()" % (index_num - 1, index_num - 1)) + else: + outfile.write('(*m)["%s"].get()' % a.name) outfile.write(");\n") else: jtype = "json::number" @@ -970,8 +1129,9 @@ def gen_unpack_method(self, outfile, args, classname, indent): outfile.write("%sif (%s *n = dynamic_cast<%s *>(" % (indent, jtype, jtype)) indent += " " if index_num > 0: - outfile.write("(*v%d)[i%d].get()" % (index_num-1, index_num-1)) - else: outfile.write('(*m)["%s"].get()' % a.name) + outfile.write("(*v%d)[i%d].get()" % (index_num - 1, index_num - 1)) + else: + outfile.write('(*m)["%s"].get()' % a.name) outfile.write(")) {\n") outfile.write("%s%s" % (indent, field_name)) if a.count != (1,): @@ -979,11 +1139,13 @@ def gen_unpack_method(self, outfile, args, classname, indent): outfile.write("[i%d]" % i) outfile.write("%s;\n" % access) if a.top_level(): - outfile.write("%s} else if (json::number *n = dynamic_cast(" % - indent[2:]) + outfile.write( + "%s} else if (json::number *n = dynamic_cast(" % indent[2:] + ) if index_num > 0: - outfile.write("(*v%d)[i%d].get()" % (index_num-1, index_num-1)) - else: outfile.write('(*m)["%s"].get()' % a.name) + outfile.write("(*v%d)[i%d].get()" % (index_num - 1, index_num - 1)) + else: + outfile.write('(*m)["%s"].get()' % a.name) outfile.write(")) {\n") outfile.write("%sif (n->val) rv = -1;\n" % indent) indent = indent[2:] @@ -997,15 +1159,24 @@ def gen_unpack_method(self, outfile, args, classname, indent): def gen_dump_unread_method(self, outfile, args, classname, indent): outfile.write(indent) - if self.gen_method_declarator(outfile, args, "void", classname, "dump_unread", - ["std::ostream &out", "prefix *pfx"], "const"): + if self.gen_method_declarator( + outfile, + args, + "void", + classname, + "dump_unread", + ["std::ostream &out", "prefix *pfx"], + "const", + ): return indent += " " need_lpfx = True for a in sorted(self.children(), key=lambda a: a.name): - if a.disabled(): continue + if a.disabled(): + continue a = self.check_child_rewrite(a, args) - if a is None: continue + if a is None: + continue field_name = a.name if field_name in args.cpp_reserved: field_name += '_' @@ -1042,17 +1213,21 @@ def gen_modified_method(self, outfile, args, classname, indent): return indent += " " for a in sorted(self.children(), key=lambda a: a.name): - if a.disabled(): continue + if a.disabled(): + continue a = self.check_child_rewrite(a, args) - if a is None: continue + if a is None: + continue field_name = a.name if field_name in args.cpp_reserved: field_name += '_' if not args.checked_array: if a.count != (1,): for index_num, idx in enumerate(a.count): - outfile.write("%sfor (int i%d = 0; i%d < %d; i%d++)\n" % - (indent, index_num, index_num, idx, index_num)) + outfile.write( + "%sfor (int i%d = 0; i%d < %d; i%d++)\n" + % (indent, index_num, index_num, idx, index_num) + ) indent += " " outfile.write("%sif (%s" % (indent, field_name)) if a.count != (1,): @@ -1060,7 +1235,7 @@ def gen_modified_method(self, outfile, args, classname, indent): outfile.write("[i%d]" % i) outfile.write(".modified()) return true;\n") if a.count != (1,): - indent = indent[2*len(a.count):] + indent = indent[2 * len(a.count) :] else: outfile.write("%sif (%s.modified()) return true;\n" % (indent, field_name)) outfile.write("%sreturn false;\n" % indent) @@ -1069,22 +1244,27 @@ def gen_modified_method(self, outfile, args, classname, indent): def gen_set_modified_method(self, outfile, args, classname, indent): outfile.write(indent) - if self.gen_method_declarator(outfile, args, "void", classname, "set_modified", - [("bool v", "true")], ""): + if self.gen_method_declarator( + outfile, args, "void", classname, "set_modified", [("bool v", "true")], "" + ): return indent += " " for a in sorted(self.children(), key=lambda a: a.name): - if a.disabled(): continue + if a.disabled(): + continue a = self.check_child_rewrite(a, args) - if a is None: continue + if a is None: + continue field_name = a.name if field_name in args.cpp_reserved: field_name += '_' if not args.checked_array: if a.count != (1,): for index_num, idx in enumerate(a.count): - outfile.write("%sfor (int i%d = 0; i%d < %d; i%d++)\n" % - (indent, index_num, index_num, idx, index_num)) + outfile.write( + "%sfor (int i%d = 0; i%d < %d; i%d++)\n" + % (indent, index_num, index_num, idx, index_num) + ) indent += " " outfile.write("%s%s" % (indent, field_name)) if a.count != (1,): @@ -1092,7 +1272,7 @@ def gen_set_modified_method(self, outfile, args, classname, indent): outfile.write("[i%d]" % i) outfile.write(".set_modified(v);\n") if a.count != (1,): - indent = indent[2*len(a.count):] + indent = indent[2 * len(a.count) :] else: outfile.write("%s%s.set_modified(v);\n" % (indent, field_name)) indent = indent[2:] @@ -1110,17 +1290,21 @@ def gen_disable_method(self, outfile, args, classname, indent): outfile.write("%s std::clog << std::endl; \n" % indent) outfile.write("%s return false; }\n" % indent) for a in sorted(self.children(), key=lambda a: a.name): - if a.disabled(): continue + if a.disabled(): + continue a = self.check_child_rewrite(a, args) - if a is None: continue + if a is None: + continue field_name = a.name if field_name in args.cpp_reserved: field_name += '_' if not args.checked_array: if a.count != (1,): for index_num, idx in enumerate(a.count): - outfile.write("%sfor (int i%d = 0; i%d < %d; i%d++)\n" % - (indent, index_num, index_num, idx, index_num)) + outfile.write( + "%sfor (int i%d = 0; i%d < %d; i%d++)\n" + % (indent, index_num, index_num, idx, index_num) + ) indent += " " outfile.write("%sif (%s" % (indent, field_name)) if a.count != (1,): @@ -1128,7 +1312,7 @@ def gen_disable_method(self, outfile, args, classname, indent): outfile.write("[i%d]" % i) outfile.write(".disable()) rv = true;\n") if a.count != (1,): - indent = indent[2*len(a.count):] + indent = indent[2 * len(a.count) :] else: outfile.write("%sif (%s.disable()) rv = true;\n" % (indent, field_name)) outfile.write("%sif (rv) disabled_ = true;\n" % indent) @@ -1138,23 +1322,28 @@ def gen_disable_method(self, outfile, args, classname, indent): def gen_disable_if_reset_value_method(self, outfile, args, classname, indent): outfile.write(indent) - if self.gen_method_declarator(outfile, args, "bool", classname, - "disable_if_reset_value", [], ""): + if self.gen_method_declarator( + outfile, args, "bool", classname, "disable_if_reset_value", [], "" + ): return indent += " " outfile.write("%sbool rv = true;\n" % indent) for a in sorted(self.children(), key=lambda a: a.name): - if a.disabled(): continue + if a.disabled(): + continue a = self.check_child_rewrite(a, args) - if a is None: continue + if a is None: + continue field_name = a.name if field_name in args.cpp_reserved: field_name += '_' if not args.checked_array: if a.count != (1,): for index_num, idx in enumerate(a.count): - outfile.write("%sfor (int i%d = 0; i%d < %d; i%d++)\n" % - (indent, index_num, index_num, idx, index_num)) + outfile.write( + "%sfor (int i%d = 0; i%d < %d; i%d++)\n" + % (indent, index_num, index_num, idx, index_num) + ) indent += " " outfile.write("%sif (!%s" % (indent, field_name)) if a.count != (1,): @@ -1162,10 +1351,11 @@ def gen_disable_if_reset_value_method(self, outfile, args, classname, indent): outfile.write("[i%d]" % i) outfile.write(".disable_if_reset_value()) rv = false;\n") if a.count != (1,): - indent = indent[2*len(a.count):] + indent = indent[2 * len(a.count) :] else: - outfile.write("%sif (!%s.disable_if_reset_value()) rv = false;\n" % - (indent, field_name)) + outfile.write( + "%sif (!%s.disable_if_reset_value()) rv = false;\n" % (indent, field_name) + ) outfile.write("%sif (rv) disabled_ = true;\n" % indent) outfile.write("%sreturn rv;\n" % indent) indent = indent[2:] @@ -1173,23 +1363,28 @@ def gen_disable_if_reset_value_method(self, outfile, args, classname, indent): def gen_disable_if_unmodified_method(self, outfile, args, classname, indent): outfile.write(indent) - if self.gen_method_declarator(outfile, args, "bool", classname, - "disable_if_unmodified", [], ""): + if self.gen_method_declarator( + outfile, args, "bool", classname, "disable_if_unmodified", [], "" + ): return indent += " " outfile.write("%sbool rv = true;\n" % indent) for a in sorted(self.children(), key=lambda a: a.name): - if a.disabled(): continue + if a.disabled(): + continue a = self.check_child_rewrite(a, args) - if a is None: continue + if a is None: + continue field_name = a.name if field_name in args.cpp_reserved: field_name += '_' if not args.checked_array: if a.count != (1,): for index_num, idx in enumerate(a.count): - outfile.write("%sfor (int i%d = 0; i%d < %d; i%d++)\n" % - (indent, index_num, index_num, idx, index_num)) + outfile.write( + "%sfor (int i%d = 0; i%d < %d; i%d++)\n" + % (indent, index_num, index_num, idx, index_num) + ) indent += " " outfile.write("%sif (!%s" % (indent, field_name)) if a.count != (1,): @@ -1197,10 +1392,11 @@ def gen_disable_if_unmodified_method(self, outfile, args, classname, indent): outfile.write("[i%d]" % i) outfile.write(".disable_if_unmodified()) rv = false;\n") if a.count != (1,): - indent = indent[2*len(a.count):] + indent = indent[2 * len(a.count) :] else: - outfile.write("%sif (!%s.disable_if_unmodified()) rv = false;\n" % - (indent, field_name)) + outfile.write( + "%sif (!%s.disable_if_unmodified()) rv = false;\n" % (indent, field_name) + ) outfile.write("%sif (rv) disabled_ = true;\n" % indent) outfile.write("%sreturn rv;\n" % indent) indent = indent[2:] @@ -1213,17 +1409,21 @@ def gen_disable_if_zero_method(self, outfile, args, classname, indent): indent += " " outfile.write("%sbool rv = true;\n" % indent) for a in sorted(self.children(), key=lambda a: a.name): - if a.disabled(): continue + if a.disabled(): + continue a = self.check_child_rewrite(a, args) - if a is None: continue + if a is None: + continue field_name = a.name if field_name in args.cpp_reserved: field_name += '_' if not args.checked_array: if a.count != (1,): for index_num, idx in enumerate(a.count): - outfile.write("%sfor (int i%d = 0; i%d < %d; i%d++)\n" % - (indent, index_num, index_num, idx, index_num)) + outfile.write( + "%sfor (int i%d = 0; i%d < %d; i%d++)\n" + % (indent, index_num, index_num, idx, index_num) + ) indent += " " outfile.write("%sif (!%s" % (indent, field_name)) if a.count != (1,): @@ -1231,7 +1431,7 @@ def gen_disable_if_zero_method(self, outfile, args, classname, indent): outfile.write("[i%d]" % i) outfile.write(".disable_if_zero()) rv = false;\n") if a.count != (1,): - indent = indent[2*len(a.count):] + indent = indent[2 * len(a.count) :] else: outfile.write("%sif (!%s.disable_if_zero()) rv = false;\n" % (indent, field_name)) outfile.write("%sif (rv && modified()) {\n" % indent) @@ -1250,17 +1450,21 @@ def gen_enable_method(self, outfile, args, classname, indent): return indent += " " for a in sorted(self.children(), key=lambda a: a.name): - if a.disabled(): continue + if a.disabled(): + continue a = self.check_child_rewrite(a, args) - if a is None: continue + if a is None: + continue field_name = a.name if field_name in args.cpp_reserved: field_name += '_' if not args.checked_array: if a.count != (1,): for index_num, idx in enumerate(a.count): - outfile.write("%sfor (int i%d = 0; i%d < %d; i%d++)\n" % - (indent, index_num, index_num, idx, index_num)) + outfile.write( + "%sfor (int i%d = 0; i%d < %d; i%d++)\n" + % (indent, index_num, index_num, idx, index_num) + ) indent += " " outfile.write("%s%s" % (indent, field_name)) if a.count != (1,): @@ -1268,7 +1472,7 @@ def gen_enable_method(self, outfile, args, classname, indent): outfile.write("[i%d]" % i) outfile.write(".enable();\n") if a.count != (1,): - indent = indent[2*len(a.count):] + indent = indent[2 * len(a.count) :] else: outfile.write("%s%s.enable();\n" % (indent, field_name)) outfile.write("%sdisabled_ = false;\n" % indent) @@ -1281,7 +1485,8 @@ def find_alias_arrays(self, args, classname): array_match = re.compile('^(\w+)_(\d+)$') for el in self.children(): el = self.check_child_rewrite(el, args) - if el is None: continue + if el is None: + continue m = array_match.match(el.name) if m: base = m.group(1) @@ -1296,17 +1501,22 @@ def find_alias_arrays(self, args, classname): pot['mask'] |= 2**idx else: potential_alias_arrays[m.group(1)] = { - "ok": True, "max": idx, "mask": 2**idx, "type": typ } + "ok": True, + "max": idx, + "mask": 2**idx, + "type": typ, + } for base, pot in potential_alias_arrays.items(): - if pot['ok'] and pot['max'] > 0 and pot['mask'] == 2**(pot['max']+1) - 1: - self.alias_arrays.append( (base, pot['type'], pot['max'] + 1) ) + if pot['ok'] and pot['max'] > 0 and pot['mask'] == 2 ** (pot['max'] + 1) - 1: + self.alias_arrays.append((base, pot['type'], pot['max'] + 1)) def need_ctor(self): if self.alias_arrays: return True for el in self.children(): el = self.check_child_rewrite(el, args) - if el is None: continue + if el is None: + continue s = el.singleton_obj() if s.is_field() and s.default and s.default != 0: if type(s.default) is tuple: @@ -1324,9 +1534,11 @@ def gen_ctor(self, outfile, args, namestr, indent): outfile.write("disabled_(false)") first = False for el in sorted(self.children(), key=lambda a: a.name): - if el.disabled(): continue + if el.disabled(): + continue el = self.check_child_rewrite(el, args) - if el is None: continue + if el is None: + continue s = el.singleton_obj() if s.is_field() and s.default and s.default != 0: if type(s.default) is tuple: @@ -1335,7 +1547,8 @@ def gen_ctor(self, outfile, args, namestr, indent): if v != 0: ok = False break - if ok: continue + if ok: + continue if first: first = False else: @@ -1346,7 +1559,7 @@ def gen_ctor(self, outfile, args, namestr, indent): if type(s.default) is tuple and len(s.default) > 1: outfile.write("({ ") for v in s.default: - outfile.write(str(v)+", ") + outfile.write(str(v) + ", ") outfile.write("})") else: outfile.write('(%d)' % s.default) @@ -1400,14 +1613,14 @@ def type_name(self, args, parent, name): classname += '::' classname += namestr rv = 'struct ' + classname - if self.count != (1, ): + if self.count != (1,): if args.checked_array: for idx in self.count: rv = "checked_array<%d, %s>" % (idx, rv) else: for idx in self.count: rv = "%s[%d]" % (rv, idx) - return rv; + return rv def gen_type(self, outfile, args, schema, parent, name, indent): namestr, nameargs = self.canon_name(name) @@ -1426,14 +1639,20 @@ def gen_type(self, outfile, args, schema, parent, name, indent): if args.enable_disable or self.need_ctor(): self.gen_ctor(outfile, args, namestr, indent) if self.top_level(): - outfile.write('%sstatic constexpr const char *_reg_version = "%s";\n' % - (indent, schema['_reg_version'])) - outfile.write('%sstatic constexpr const char *_schema_hash = "%s";\n' % - (indent, schema['_schema_hash'])) + outfile.write( + '%sstatic constexpr const char *_reg_version = "%s";\n' + % (indent, schema['_reg_version']) + ) + outfile.write( + '%sstatic constexpr const char *_schema_hash = "%s";\n' + % (indent, schema['_schema_hash']) + ) for el in sorted(self.children(), key=lambda a: a.name): - if el.disabled(): continue + if el.disabled(): + continue el = self.check_child_rewrite(el, args) - if el is None: continue + if el is None: + continue typ = el.singleton_obj() notclass = typ.is_field() or typ.top_level() isglobal = el.name in args.global_types @@ -1479,8 +1698,9 @@ def gen_type(self, outfile, args, schema, parent, name, indent): outfile.write(";\n") if args.gen_decl != 'defn' and hasattr(self, 'alias_arrays'): for alias in self.alias_arrays: - outfile.write("%salias_array<%d, %s> %s;\n" % (indent, - alias[2], alias[1], alias[0])) + outfile.write( + "%salias_array<%d, %s> %s;\n" % (indent, alias[2], alias[1], alias[0]) + ) if args.delete_copy and args.gen_decl != 'defn': if not args.enable_disable and not self.need_ctor(): outfile.write("%s%s() = default;\n" % (indent, namestr)) @@ -1515,18 +1735,20 @@ def gen_type(self, outfile, args, schema, parent, name, indent): def gen_global_types(self, outfile, args, schema): for a in sorted(self.children(), key=lambda a: a.name): - if a.disabled(): continue + if a.disabled(): + continue if not a.is_field() and not a.top_level(): a.gen_global_types(outfile, args, schema) if a.name in args.global_types: if a.name in args.global_types_generated: if args.global_types_generated[a.name] != a: - raise CsrException("Inconsistent definition of type "+a.name) + raise CsrException("Inconsistent definition of type " + a.name) else: args.global_types_generated[a.name] = a a.gen_type(outfile, args, schema, "", a.name, "") outfile.write(";\n") + class address_map(csr_composite_object): """ A Semifore addressmap. Contains registers and instances of other @@ -1553,6 +1775,7 @@ class address_map(csr_composite_object): A string indicating which parent of the chip hierarchy the addressmap falls under ("memories" or "regs) """ + def __init__(self, name, count, parent): csr_composite_object.__init__(self, name, count) @@ -1582,7 +1805,7 @@ def min_width(self, round_to_power_of_2=True): multiplier = 1 obj_end += obj.min_width() * multiplier else: - raise CsrException("Unrecognized object in address map ('"+type(obj)+"')") + raise CsrException("Unrecognized object in address map ('" + type(obj) + "')") if obj_end > width: width = obj_end @@ -1607,10 +1830,18 @@ def generate_binary(self, data, cache, path): type_name = self.parent + "." + self.name if data not in cache.templates: - raise CsrException("Could not find template with name '"+data+"'") + raise CsrException("Could not find template with name '" + data + "'") if cache.get_type(data) != type_name: - raise CsrException("Expected type of instantiated object '"+data+"' to be '"+type_name+"', found '"+cache.get_type(data)+"'") + raise CsrException( + "Expected type of instantiated object '" + + data + + "' to be '" + + type_name + + "', found '" + + cache.get_type(data) + + "'" + ) return cache.get_data(data, path) elif type(data) is dict: @@ -1618,16 +1849,22 @@ def generate_binary(self, data, cache, path): reg_values = [] for obj in self.objs: if obj.name not in data: - raise CsrException("Could not find key '"+obj.name+"'") + raise CsrException("Could not find key '" + obj.name + "'") if data[obj.name] != 0 and not isinstance(data[obj.name], basestring): if obj.count == (1,): if type(data[obj.name]) is not dict: - raise CsrException("Expected dictionary at key '"+obj.name+"'") + raise CsrException("Expected dictionary at key '" + obj.name + "'") else: # TODO: check all dimensions are the right size, maybe if a 'strict errors' flag is used if type(data[obj.name]) is not list or len(data[obj.name]) != obj.count[0]: - array_size = "x".join(map(str,obj.count)) - raise CsrException("Expected "+array_size+" element array of dictionaries at key '"+obj.name+"'") + array_size = "x".join(map(str, obj.count)) + raise CsrException( + "Expected " + + array_size + + " element array of dictionaries at key '" + + obj.name + + "'" + ) if type(obj) is reg: if obj.count == (1,): @@ -1668,24 +1905,42 @@ def generate_binary(self, data, cache, path): # is written with block writes, forcing this register # configuration on the same path removes the race. - registers_to_write_with_dma = [ "mapram_config", - "imem_dark_subword16", "imem_dark_subword32", "imem_dark_subword8", - "imem_mocha_subword16", "imem_mocha_subword32", "imem_mocha_subword8", - "imem_subword16", "imem_subword32", "imem_subword8", - "galois_field_matrix"] - if product(obj.count) > 4 and (root_parent=="memories" or obj.name in registers_to_write_with_dma): - mem = chip.dma_block(obj.offset, obj.width, src_key=obj.name, is_reg=root_parent=="regs") + registers_to_write_with_dma = [ + "mapram_config", + "imem_dark_subword16", + "imem_dark_subword32", + "imem_dark_subword8", + "imem_mocha_subword16", + "imem_mocha_subword32", + "imem_mocha_subword8", + "imem_subword16", + "imem_subword32", + "imem_subword8", + "galois_field_matrix", + ] + if product(obj.count) > 4 and ( + root_parent == "memories" or obj.name in registers_to_write_with_dma + ): + mem = chip.dma_block( + obj.offset, + obj.width, + src_key=obj.name, + is_reg=root_parent == "regs", + ) + def mem_loop(sub_data, context): path[-1].path.append(context) for idx in range(0, obj.count[-1]): context[-1] = idx obj.generate_binary(sub_data[idx], cache, path, mem) path[-1].path.pop() + nd_array_loop(obj.count, data[obj.name], mem_loop) reg_values.append(mem) else: offset = [0] - width = obj.width//8 #TODO: warn if not power of (8 or 32 or w/e)? + width = obj.width // 8 # TODO: warn if not power of (8 or 32 or w/e)? + def reg_loop(sub_data, context): path[-1].path.append(context) for idx in range(0, obj.count[-1]): @@ -1696,6 +1951,7 @@ def reg_loop(sub_data, context): reg_values.append(chip_obj) offset[0] += width path[-1].path.pop() + nd_array_loop(obj.count, data[obj.name], reg_loop) elif type(obj) is address_map_instance or type(obj) is group: @@ -1706,26 +1962,28 @@ def reg_loop(sub_data, context): reg_values.append(sub_chip_obj) elif data[obj.name] != 0: offset = [0] + def addr_map_loop(sub_data, context): path[-1].path.append(context) for idx in range(0, obj.count[-1]): context[-1] = idx sub_chip_objs = obj.generate_binary(sub_data[idx], cache, path) for sub_chip_obj in sub_chip_objs: - sub_chip_obj.add_offset(obj.offset+offset[0]) + sub_chip_obj.add_offset(obj.offset + offset[0]) reg_values.append(sub_chip_obj) offset[0] += obj.stride path[-1].path.pop() + nd_array_loop(obj.count, data[obj.name], addr_map_loop) else: - raise CsrException("Unrecognized object in address map ('"+type(obj)+"')") + raise CsrException("Unrecognized object in address map ('" + type(obj) + "')") return reg_values else: raise CsrException( - "Expected dictionary at addressmap node '%s' but found value of type %s" % ( - self.name, type(data).__name__ - )) + "Expected dictionary at addressmap node '%s' but found value of type %s" + % (self.name, type(data).__name__) + ) def generate_template(self, inject_size): self_dict = {} @@ -1733,17 +1991,20 @@ def generate_template(self, inject_size): return None if self.templatization_behavior == "top_level": self_dict["_type"] = self.parent + "." + self.name - self_dict["_name"] = "template("+self_dict["_type"]+")" + self_dict["_name"] = "template(" + self_dict["_type"] + ")" for obj in self.objs: self_dict[obj.name] = obj.generate_template(inject_size) return self.replicate(self_dict) def children(self): return self.objs + def is_singleton(self): return len(self.objs) == 1 and self.objs[0].count == (1,) + def disabled(self): return self.templatization_behavior == "disabled" + def top_level(self): return self.templatization_behavior == "top_level" @@ -1770,7 +2031,8 @@ def print_as_text(self, indent): if self.templatization_behavior != "disabled": print("%saddress_map %s%s:" % (indent, self.name, str(self.count))) for ch in self.objs: - ch.print_as_text(indent+" ") + ch.print_as_text(indent + " ") + class address_map_instance(csr_composite_object): """ @@ -1783,6 +2045,7 @@ class address_map_instance(csr_composite_object): If @count is not (1,), this is the offset from each instance in the array to the next. If @count is (1,) this should be null """ + def __init__(self, name, count, offset, addrmap, stride): csr_composite_object.__init__(self, name, count) @@ -1801,7 +2064,7 @@ def generate_binary(self, data, cache, path): def generate_template(self, inject_size): if self.map.templatization_behavior == "top_level": - return self.replicate(self.map.name+"_object") + return self.replicate(self.map.name + "_object") elif self.map.templatization_behavior == "disabled": return self.replicate(0) else: @@ -1809,12 +2072,16 @@ def generate_template(self, inject_size): def children(self): return self.map.objs + def is_singleton(self): return len(self.map.objs) == 1 and self.map.objs[0].count == (1,) + def disabled(self): return self.map.templatization_behavior == "disabled" + def top_level(self): return self.map.templatization_behavior == "top_level" + def address_stride(self): return self.stride @@ -1834,14 +2101,23 @@ def gen_type(self, outfile, args, schema, parent, name, indent): self.map.gen_type(outfile, args, schema, parent, name, indent) def print_as_text(self, indent): - print("%saddress_map_instance %s%s: offset=0x%x%s" % ( - indent, self.name, str(self.count), self.offset, - " stride=0x%x" % self.stride if self.stride else "")) + print( + "%saddress_map_instance %s%s: offset=0x%x%s" + % ( + indent, + self.name, + str(self.count), + self.offset, + " stride=0x%x" % self.stride if self.stride else "", + ) + ) if self.map.templatization_behavior == "top_level": - print("%s address_map %s%s: (top level %s)" % ( - indent, self.name, str(self.count), self.map.name)) + print( + "%s address_map %s%s: (top level %s)" + % (indent, self.name, str(self.count), self.map.name) + ) else: - self.map.print_as_text(indent+" ") + self.map.print_as_text(indent + " ") class group(address_map): @@ -1853,6 +2129,7 @@ class group(address_map): @attr offset offset from the start of the containing addres_map """ + def __init__(self, name, count, offset, parent, stride): address_map.__init__(self, name, count, parent) self.stride = stride @@ -1878,11 +2155,18 @@ def address_stride(self): return self.stride def print_as_text(self, indent): - print("%sgroup %s%s: offset=0x%x%s" % ( - indent, self.name, str(self.count), self.offset, - " stride=0x%x" % self.stride if self.stride else "")) + print( + "%sgroup %s%s: offset=0x%x%s" + % ( + indent, + self.name, + str(self.count), + self.offset, + " stride=0x%x" % self.stride if self.stride else "", + ) + ) for ch in self.objs: - ch.print_as_text(indent+" ") + ch.print_as_text(indent + " ") class reg(csr_composite_object): @@ -1897,6 +2181,7 @@ class reg(csr_composite_object): @attr fields vector of fields in the register """ + def __init__(self, name, count, offset, width, parent): csr_composite_object.__init__(self, name, count) @@ -1917,7 +2202,7 @@ def __str__(self): def get_reset_value(self): rv = 0 for f in self.fields: - rv |= (f.default[0] << f.lsb) + rv |= f.default[0] << f.lsb return rv def generate_binary(self, data, cache, path, mem=None): @@ -1932,10 +2217,18 @@ def generate_binary(self, data, cache, path, mem=None): type_name = self.parent + "." + self.name if data not in cache.templates: - raise CsrException("Could not find template with name '"+data+"'") + raise CsrException("Could not find template with name '" + data + "'") if cache.get_type(data) != type_name: - raise CsrException("Expected type of instantiated object '"+data+"' to be '"+type_name+"', found '"+cache.get_type(data)+"'") + raise CsrException( + "Expected type of instantiated object '" + + data + + "' to be '" + + type_name + + "', found '" + + cache.get_type(data) + + "'" + ) cached_data = cache.get_data(data, path) path[-1].path.pop() @@ -1952,30 +2245,31 @@ def generate_binary(self, data, cache, path, mem=None): for field in self.fields: if field.name not in data: - raise CsrException("Could not find key '"+field.name+"'") + raise CsrException("Could not find key '" + field.name + "'") - width = field.msb-field.lsb+1 + width = field.msb - field.lsb + 1 if field.count == (1,): value = data[field.name] if type(value) is not int: raise CsrException( - "Expected integer value for field '%s.%s' but found value of type %s" % ( - self.name, field.name, type(value).__name__ - )) + "Expected integer value for field '%s.%s' but found value of type %s" + % (self.name, field.name, type(value).__name__) + ) elif value < 0: raise CsrException( - "Value for field '%s.%s' is negative (%i)" % ( - self.name, field.name, value - )) + "Value for field '%s.%s' is negative (%i)" + % (self.name, field.name, value) + ) elif value <= pow(2, width): reg_value[0] |= value << field.lsb else: raise CsrException( - "Width of field '%s.%s' (%i bits) not large enough to hold value (%i)" % ( - self.name, field.name, width, value - )) + "Width of field '%s.%s' (%i bits) not large enough to hold value (%i)" + % (self.name, field.name, width, value) + ) else: offset = [0] + def field_loop(sub_data, context): path[-1].path.append(context) for idx in range(0, field.count[-1]): @@ -1983,28 +2277,42 @@ def field_loop(sub_data, context): value = sub_data[idx] if type(value) is not int: raise CsrException( - "Expected integer value for field '%s.%s%s' but found value of type %s" % ( - self.name, field.name, array_str(context), type(value).__name__ - )) + "Expected integer value for field '%s.%s%s' but found value of type %s" + % ( + self.name, + field.name, + array_str(context), + type(value).__name__, + ) + ) elif value < 0: raise CsrException( - "Value for field '%s.%s%s' is negative (%i)" % ( - self.name, field.name, array_str(context), value - )) + "Value for field '%s.%s%s' is negative (%i)" + % (self.name, field.name, array_str(context), value) + ) elif value <= pow(2, width): reg_value[0] |= value << field.lsb + offset[0] offset[0] += width else: raise CsrException( - "Width of field '%s.%s%s' (%i bits) not large enough to hold value (%i)" % ( - self.name, field.name, array_str(context), width, value - )) + "Width of field '%s.%s%s' (%i bits) not large enough to hold value (%i)" + % (self.name, field.name, array_str(context), width, value) + ) path[-1].path.pop() # TODO: check all dimension sizes - if type(data[field.name]) is not list or len(data[field.name]) != field.count[0]: - array_size = "x".join(map(str,field.count)) - raise CsrException("Expected "+array_size+" element array of integers at key '"+field.name+"'") + if ( + type(data[field.name]) is not list + or len(data[field.name]) != field.count[0] + ): + array_size = "x".join(map(str, field.count)) + raise CsrException( + "Expected " + + array_size + + " element array of integers at key '" + + field.name + + "'" + ) nd_array_loop(field.count, data[field.name], field_loop) @@ -2018,10 +2326,9 @@ def field_loop(sub_data, context): return chip.indirect_reg(self.offset, reg_value[0], self.width, src_key=self.name) else: raise CsrException( - "Expected dictionary at register node '%s' but found value of type %s" % ( - self.name, type(data).__name__ - )) - + "Expected dictionary at register node '%s' but found value of type %s" + % (self.name, type(data).__name__) + ) def generate_template(self, inject_size): self_dict = {} @@ -2031,17 +2338,21 @@ def generate_template(self, inject_size): def children(self): return self.fields + def is_singleton(self): return len(self.fields) == 1 and self.fields[0].count == (1,) + def singleton_obj(self): if self.is_singleton() and self.fields[0].name == self.name: return self.fields[0] return self + def address_stride(self): return self.width // 8 def disabled(self): return False + def top_level(self): return False @@ -2049,9 +2360,11 @@ def gen_word_expressions(self, args, prefix): """ generate expressions to calculate the value of each word of the register """ + class context: shift = 0 words = [] + context.words = [None] * ((self.width + 31) // 32) for a in self.fields: field_name = a.name @@ -2062,7 +2375,8 @@ class context: field_name = prefix else: field_name = prefix + "." + field_name - context.shift = a.lsb; + context.shift = a.lsb + def emit_field_slice(field, word, shift): if context.words[word] is None: context.words[word] = '' @@ -2075,16 +2389,18 @@ def emit_field_slice(field, word, shift): context.words[word] += " << %d)" % shift elif shift < 0: context.words[word] += " >> %d)" % -shift + def emit_ubits_field(index_list): word = context.shift // 32 shift = context.shift % 32 name = field_name + array_str(index_list) emit_field_slice(name, word, shift) if shift + a.msb - a.lsb >= 32: - emit_field_slice(name, word+1, shift - 32) + emit_field_slice(name, word + 1, shift - 32) if shift + a.msb - a.lsb >= 64: - emit_field_slice(name, word+2, shift - 64) + emit_field_slice(name, word + 2, shift - 64) context.shift = context.shift + a.msb - a.lsb + 1 + def emit_widereg_field(index_list): word = context.shift // 32 shift = context.shift % 32 @@ -2095,6 +2411,7 @@ def emit_widereg_field(index_list): word += 1 emit_field_slice(name + "%d, 32)" % shift, word, 0) shift += 32 + if a.count != (1,): if a.msb - a.lsb + 1 > 64: count_array_loop(a.count, emit_widereg_field) @@ -2111,24 +2428,32 @@ def gen_uint_conversion(self, outfile, args, classname, indent): if self.width > 32: return outfile.write(indent) - if self.gen_method_declarator(outfile, args, "", classname, "operator uint32_t", - [], "const"): + if self.gen_method_declarator( + outfile, args, "", classname, "operator uint32_t", [], "const" + ): return - outfile.write("%s return " % indent); + outfile.write("%s return " % indent) outfile.write("%s;\n" % self.gen_word_expressions(args, None)[0]) outfile.write("%s}\n" % indent) def gen_emit_binary_method(self, outfile, args, classname, indent): outfile.write(indent) - if self.gen_method_declarator(outfile, args, "void", classname, "emit_binary", - ["std::ostream &out", "uint64_t a"], "const"): + if self.gen_method_declarator( + outfile, + args, + "void", + classname, + "emit_binary", + ["std::ostream &out", "uint64_t a"], + "const", + ): return indent += " " if self.count != (1,): pass - indirect = ((self.parent.parent=="memories") or (self.name in args.write_dma)) + indirect = (self.parent.parent == "memories") or (self.name in args.write_dma) if not indirect: - outfile.write("%sif (!disabled_) {\n" % indent); + outfile.write("%sif (!disabled_) {\n" % indent) indent += " " pairs = enumerate(self.gen_word_expressions(args, None)) if not indirect and args.reverse_write: @@ -2139,9 +2464,9 @@ def gen_emit_binary_method(self, outfile, args, classname, indent): for idx, val in pairs: if val is None: val = '0' - outfile.write("%sout << " % indent); + outfile.write("%sout << " % indent) if not indirect: - outfile.write("binout::tag('R') << binout::byte4(a + %d)\n" % (idx*4)) + outfile.write("binout::tag('R') << binout::byte4(a + %d)\n" % (idx * 4)) outfile.write("%s << " % indent) outfile.write("binout::byte4(%s);\n" % val) if not indirect: @@ -2152,8 +2477,15 @@ def gen_emit_binary_method(self, outfile, args, classname, indent): def gen_input_binary_method(self, outfile, args, classname, indent): outfile.write(indent) - if self.gen_method_declarator(outfile, args, "void", classname, "input_binary", - ["uint64_t a", "char t", "uint32_t *d", "size_t l"], ""): + if self.gen_method_declarator( + outfile, + args, + "void", + classname, + "input_binary", + ["uint64_t a", "char t", "uint32_t *d", "size_t l"], + "", + ): return indent += ' ' words = (self.width + 31) // 32 @@ -2170,16 +2502,20 @@ def gen_input_binary_method(self, outfile, args, classname, indent): zero_default = False break if indirect: - outfile.write('%sBUG_CHECK(l == %d, "expecting %d words, got %%zd in %s", l);\n' % - (indent, words, words, self.name)) + outfile.write( + '%sBUG_CHECK(l == %d, "expecting %d words, got %%zd in %s", l);\n' + % (indent, words, words, self.name) + ) if zero_default: outfile.write('%sif ((d[0]' % indent) - for i in range(1,words): + for i in range(1, words): outfile.write('|d[%d]' % i) outfile.write(') == 0) return;\n') else: - outfile.write('%sBUG_CHECK(t == \'R\' && l == 1, "expecting direct in %s");\n' % - (indent, self.name)) + outfile.write( + '%sBUG_CHECK(t == \'R\' && l == 1, "expecting direct in %s");\n' + % (indent, self.name) + ) if zero_default: outfile.write('%sif (d[0] == 0) return;\n' % indent) outfile.write('%sa /= 4;\n' % indent) @@ -2189,47 +2525,61 @@ def gen_input_binary_method(self, outfile, args, classname, indent): field_name += '_' lsb = a.lsb size = a.msb - a.lsb + 1 + def input_ubits_field(index_list): nonlocal lsb outfile.write(indent) if indirect: - word = lsb//32 + word = lsb // 32 aop = '=' else: - outfile.write('if (a == %d) ' % (lsb//32)) + outfile.write('if (a == %d) ' % (lsb // 32)) word = 0 aop = '|=' outfile.write('%s%s %s ' % (field_name, array_str(index_list), aop)) - if lsb%32 + size < 32: - outfile.write('(d[%d] >> %d) & 0x%x;\n' % (word, - lsb%32, (1 << size) - 1)) - elif lsb%32 + size == 32: - outfile.write('d[%d] >> %d;\n' % (word, lsb%32)) + if lsb % 32 + size < 32: + outfile.write('(d[%d] >> %d) & 0x%x;\n' % (word, lsb % 32, (1 << size) - 1)) + elif lsb % 32 + size == 32: + outfile.write('d[%d] >> %d;\n' % (word, lsb % 32)) else: - outfile.write('(d[%d] >> %d)' % (word, lsb%32)) + outfile.write('(d[%d] >> %d)' % (word, lsb % 32)) if indirect: outfile.write(' | ') else: outfile.write(';\n') - msb = lsb+size-1 - for i in range(lsb//32 + 1, msb//32): + msb = lsb + size - 1 + for i in range(lsb // 32 + 1, msb // 32): if indirect: - outfile.write('((uint64_t)d[%d] << %d) | ' % (i, i*32 - lsb)) + outfile.write('((uint64_t)d[%d] << %d) | ' % (i, i * 32 - lsb)) else: - outfile.write('%sif (a == %d) %s%s |= (uint64_t)d[0] << %d;\n' % - (indent, i, field_name, array_str(index_list), i*32 - lsb)) + outfile.write( + '%sif (a == %d) %s%s |= (uint64_t)d[0] << %d;\n' + % (indent, i, field_name, array_str(index_list), i * 32 - lsb) + ) if indirect: - outfile.write('(((uint64_t)d[%d] & 0x%x) << %d);\n' % (msb//32, - (1 << (msb%32 + 1)) - 1, msb//32*32 - lsb)) + outfile.write( + '(((uint64_t)d[%d] & 0x%x) << %d);\n' + % (msb // 32, (1 << (msb % 32 + 1)) - 1, msb // 32 * 32 - lsb) + ) else: - outfile.write('%sif (a == %d) %s%s |= ((uint64_t)d[0] & 0x%x) << %d;\n' % - (indent, msb//32, field_name, array_str(index_list), - (1 << (msb%32 + 1)) - 1, msb//32*32 - lsb)) + outfile.write( + '%sif (a == %d) %s%s |= ((uint64_t)d[0] & 0x%x) << %d;\n' + % ( + indent, + msb // 32, + field_name, + array_str(index_list), + (1 << (msb % 32 + 1)) - 1, + msb // 32 * 32 - lsb, + ) + ) lsb += size + def input_widereg_field(index_list): nonlocal lsb outfile.write('%sBUG("widereg input not implemented");\n' % indent) lsb += size + if a.count != (1,): if a.msb - a.lsb + 1 > 64: count_array_loop(a.count, input_widereg_field) @@ -2246,11 +2596,18 @@ def input_widereg_field(index_list): def gen_binary_offset_method(self, outfile, args, classname, indent): outfile.write(indent) - if self.gen_method_declarator(outfile, args, "uint64_t", classname, "binary_offset", - ["const void *addr", ("int *bit_offset", "0")], "const"): + if self.gen_method_declarator( + outfile, + args, + "uint64_t", + classname, + "binary_offset", + ["const void *addr", ("int *bit_offset", "0")], + "const", + ): return indent += " " - outfile.write("%sif (bit_offset) {" %indent) + outfile.write("%sif (bit_offset) {" % indent) indent += " " outfile.write("%s/* TDB */\n" % indent) indent = indent[2:] @@ -2260,10 +2617,13 @@ def gen_binary_offset_method(self, outfile, args, classname, indent): outfile.write("%s}\n" % indent) def print_as_text(self, indent): - print("%sreg %s%s: offset=0x%x width=%d" % ( - indent, self.name, str(self.count), self.offset, self.width)) + print( + "%sreg %s%s: offset=0x%x width=%d" + % (indent, self.name, str(self.count), self.offset, self.width) + ) for ch in self.fields: - ch.print_as_text(indent+" ") + ch.print_as_text(indent + " ") + class scanset_reg(reg): """ @@ -2279,6 +2639,7 @@ class scanset_reg(reg): @attr fields vector of fields in the register """ + def __init__(self, name, count, offset, width, parent, fields): reg.__init__(self, name, count, offset, width, parent) if isinstance(fields, list): @@ -2295,9 +2656,8 @@ def __str__(self): f += ")" return "scanset %s%s fields:%s" % (self.name, str(self.count), f) - def output_binary(self, outfile, args, indent, address_unit, width_unit): - #import pdb; pdb.set_trace() + # import pdb; pdb.set_trace() name = self.name if name in args.cpp_reserved: name += '_' @@ -2310,25 +2670,31 @@ def output_binary(self, outfile, args, indent, address_unit, width_unit): if args.enable_disable: outfile.write("%sif (!%s.disabled()) {\n" % (indent, name)) indent += ' ' - outfile.write("%sout << binout::tag('S') << binout::byte8(0)" % indent + - " << binout::byte4(0)\n%s " % indent + - " << binout::byte8(a + 0x%x)" % (self.offset//address_unit) + - " << binout::byte4(32) << binout::byte4(%d);\n" % - (product(self.count) * self.width // width_unit)) + outfile.write( + "%sout << binout::tag('S') << binout::byte8(0)" % indent + + " << binout::byte4(0)\n%s " % indent + + " << binout::byte8(a + 0x%x)" % (self.offset // address_unit) + + " << binout::byte4(32) << binout::byte4(%d);\n" + % (product(self.count) * self.width // width_unit) + ) for idx_num, idx in enumerate(self.count): - outfile.write('%sfor (int j%d = 0; j%d < %d; j%d++) { \n' % - (indent, idx_num, idx_num, idx, idx_num)) + outfile.write( + '%sfor (int j%d = 0; j%d < %d; j%d++) { \n' + % (indent, idx_num, idx_num, idx, idx_num) + ) name = name + "[j%d]" % idx_num if hasattr(self, 'sel_offset') and idx_num == 0: if args.enable_disable: outfile.write("%sif (!%s.disabled()) {\n" % (indent, name)) indent += ' ' - outfile.write("%sout << binout::tag('S') << binout::byte8" % indent + - "(a + 0x%x)" % (self.sel_offset//address_unit) + - " << binout::byte4(j0)\n%s " % indent + - " << binout::byte8(a + 0x%x)" % (self.offset//address_unit) + - " << binout::byte4(32) << binout::byte4(%d);\n" % - (product(self.count[1:]) * self.width // width_unit)) + outfile.write( + "%sout << binout::tag('S') << binout::byte8" % indent + + "(a + 0x%x)" % (self.sel_offset // address_unit) + + " << binout::byte4(j0)\n%s " % indent + + " << binout::byte8(a + 0x%x)" % (self.offset // address_unit) + + " << binout::byte4(32) << binout::byte4(%d);\n" + % (product(self.count[1:]) * self.width // width_unit) + ) indent += ' ' pairs = enumerate(self.gen_word_expressions(args, name)) for idx, val in pairs: @@ -2354,6 +2720,7 @@ class field(csr_object): Range of bits in containing register for this field. If @count is not (1,), this is just the first element; the second will be at lsb = msb+1 etc """ + def __init__(self, name, count, msb, lsb, default, parent): csr_object.__init__(self, name, count) @@ -2367,7 +2734,7 @@ def __str__(self): def generate_template(self, inject_size): if inject_size: - return self.replicate(self.msb-self.lsb+1) + return self.replicate(self.msb - self.lsb + 1) else: if self.count == (1,): return self.default[0] @@ -2376,17 +2743,20 @@ def generate_template(self, inject_size): def is_field(self): return True + def disabled(self): return False + def top_level(self): return False + def type_name(self, args, parent, name): - size = self.msb-self.lsb+1 + size = self.msb - self.lsb + 1 if size > 64: rv = "widereg<%d>" % size else: rv = "ubits<%d>" % size - if self.count != (1, ): + if self.count != (1,): if args.checked_array: for idx in self.count: rv = "checked_array<%d, %s>" % (idx, rv) @@ -2396,7 +2766,7 @@ def type_name(self, args, parent, name): return rv def gen_type(self, outfile, args, schema, parent, name, indent): - size = self.msb-self.lsb+1 + size = self.msb - self.lsb + 1 if args.gen_decl != 'defn': if size > 64: outfile.write("widereg<%d>" % size) @@ -2404,14 +2774,23 @@ def gen_type(self, outfile, args, schema, parent, name, indent): outfile.write("ubits<%d>" % size) def print_as_text(self, indent): - print("%sfield %s%s: [%d:%d]%s" % ( - indent, self.name, str(self.count), self.msb, self.lsb, - " default=" + str(self.default) if self.default else "")) + print( + "%sfield %s%s: [%d:%d]%s" + % ( + indent, + self.name, + str(self.count), + self.msb, + self.lsb, + " default=" + str(self.default) if self.default else "", + ) + ) ######################################################################## ## Utility functions + def parse_resets(reset_str): """ Turn a reset value from a Semifore CSV string into a tuple of ints @@ -2423,10 +2802,11 @@ def parse_resets(reset_str): If the array is 1D this function will still output the size as a 1-element tuple, just for consistency of iterability. """ - reset_strs = reset_str.replace("[","").replace("]","").split(",") - resets = [int(x,0) for x in reset_strs] + reset_strs = reset_str.replace("[", "").replace("]", "").split(",") + resets = [int(x, 0) for x in reset_strs] return tuple(resets) + def parse_array_size(size_str): """ Turn an array size from a Semifore CSV string into a tuple of ints @@ -2440,14 +2820,15 @@ def parse_array_size(size_str): If the array is 1D this function will still output the size as a 1-element tuple, just for consistency of iterability. """ - size_strs = size_str.replace("]","").split("[")[1:] + size_strs = size_str.replace("]", "").split("[")[1:] sizes = list(map(int, size_strs)) if len(sizes) > 0: return tuple(sizes) else: return (1,) -def parse_csrcompiler_csv (filename, section_name): + +def parse_csrcompiler_csv(filename, section_name): """ Given a Semifore CSV file, parse it into a bunch of csr_object instances. Since the chip hierarchy is contained across multiple CSV files, each one @@ -2466,7 +2847,7 @@ def parse_csrcompiler_csv (filename, section_name): "counter", "status", "hierarchicalInterrupt", - "interrupt" + "interrupt", } csv_addressmap_types = { @@ -2506,24 +2887,36 @@ def parse_csrcompiler_csv (filename, section_name): if row["Type"] in csv_addressmap_types: addr_maps[row["Identifier"]] = address_map( - row["Identifier"], - array_size, - section_name + row["Identifier"], array_size, section_name ) active_addr_map = addr_maps[row["Identifier"]] elif row["Type"] in csv_register_types: - reg_width = int(row["Register Size"].replace(" bits",""),0) - active_container.objs.append(reg(row["Identifier"], array_size, int(row["Offset"],0), reg_width, active_addr_map)) + reg_width = int(row["Register Size"].replace(" bits", ""), 0) + active_container.objs.append( + reg( + row["Identifier"], + array_size, + int(row["Offset"], 0), + reg_width, + active_addr_map, + ) + ) active_reg = active_container.objs[-1] active_object = active_reg if row["Reset Value"] == "": active_reg_default = 0 else: - active_reg_default = int(row["Reset Value"],0) + active_reg_default = int(row["Reset Value"], 0) elif row["Type"] in csv_field_types: if len(array_size) > 1: - raise CsrException("Multi-dimensional field arrays not currently supported (in CSV file '"+filename+"' line "+str(row_num)+")") - range_tokens = row["Position"].replace("[","").replace("]","").split(":") + raise CsrException( + "Multi-dimensional field arrays not currently supported (in CSV file '" + + filename + + "' line " + + str(row_num) + + ")" + ) + range_tokens = row["Position"].replace("[", "").replace("]", "").split(":") msb = int(range_tokens[0]) if len(range_tokens) == 1: lsb = msb @@ -2531,10 +2924,10 @@ def parse_csrcompiler_csv (filename, section_name): lsb = int(range_tokens[1]) if row["Reset Value"] == "": default = [] - elem_width = msb-lsb+1 + elem_width = msb - lsb + 1 elem_mask = 2**elem_width - 1 for elem_idx in range(array_size[0]): - default_offset = lsb + elem_width*elem_idx + default_offset = lsb + elem_width * elem_idx default_val = (active_reg_default >> default_offset) & elem_mask default.append(default_val) default = tuple(default) @@ -2542,15 +2935,23 @@ def parse_csrcompiler_csv (filename, section_name): default = parse_resets(row["Reset Value"]) if array_size != (1,): if len(default) == 1: - default = default*array_size[0] + default = default * array_size[0] elif len(default) != array_size[0]: - raise CsrException("Field reset value list is not the same length as the field array itself (in CSV file '"+filename+"' line "+str(row_num)+")") - - active_reg.fields.append(field(row["Identifier"], array_size, msb, lsb, default, active_reg)) + raise CsrException( + "Field reset value list is not the same length as the field array itself (in CSV file '" + + filename + + "' line " + + str(row_num) + + ")" + ) + + active_reg.fields.append( + field(row["Identifier"], array_size, msb, lsb, default, active_reg) + ) active_object = active_reg.fields[-1] elif row["Type"] == "addressmap instance": try: - stride = int(row["Stride"].replace(" bytes",""),0) + stride = int(row["Stride"].replace(" bytes", ""), 0) except: stride = addr_maps[row["Type Name"]].min_width() @@ -2558,24 +2959,24 @@ def parse_csrcompiler_csv (filename, section_name): address_map_instance( row["Identifier"], array_size, - int(row["Offset"],0), + int(row["Offset"], 0), addr_maps[row["Type Name"]], - None if array_size == (1,) else stride + None if array_size == (1,) else stride, ) ) elif row["Type"] in csv_group_types: try: - stride = int(row["Stride"].replace(" bytes",""),0) + stride = int(row["Stride"].replace(" bytes", ""), 0) except: stride = None active_container.objs.append( - group ( + group( row["Identifier"], array_size, - int(row["Offset"],0), + int(row["Offset"], 0), section_name, - None if array_size == (1,) else stride + None if array_size == (1,) else stride, ) ) active_group.append(active_container.objs[-1]) @@ -2594,7 +2995,14 @@ def parse_csrcompiler_csv (filename, section_name): # ignore for now? pass else: - raise CsrException("Unrecognized type '"+row["Type"]+"' in CSV file '"+filename+"' line "+str(row_num)) + raise CsrException( + "Unrecognized type '" + + row["Type"] + + "' in CSV file '" + + filename + + "' line " + + str(row_num) + ) if "Description" in row and row["Description"] and active_object: active_object.description = row["Description"] @@ -2604,7 +3012,7 @@ def parse_csrcompiler_csv (filename, section_name): return addr_maps -def build_schema (dir, walle_version): +def build_schema(dir, walle_version): """ Build a chip schema based on the top-level CSV files from Semifore @@ -2637,9 +3045,13 @@ def build_schema (dir, walle_version): csv_files = dir if not os.path.isfile(version_file) or not os.path.isdir(csv_files): - raise Exception("Directory '"+os.path.abspath(dir)+"' could not be opened, "+ - "does not exist, or does not appear to be a valid bfnregs "+ - "chip module.") + raise Exception( + "Directory '" + + os.path.abspath(dir) + + "' could not be opened, " + + "does not exist, or does not appear to be a valid bfnregs " + + "chip module." + ) for filename in os.listdir(csv_files): if filename.endswith(".csv"): @@ -2660,7 +3072,7 @@ def build_schema (dir, walle_version): hasher.update(csv_file.read()) if len(new_schema) == 0: - raise Exception("No csv files found under '" + os.path.abspath(csv_files) + "'"); + raise Exception("No csv files found under '" + os.path.abspath(csv_files) + "'") with open(version_file, "r") as version_file_handle: reg_version = version_file_handle.read() @@ -2672,18 +3084,19 @@ def build_schema (dir, walle_version): return new_schema + # Unit tests if __name__ == "__main__": y = reg("bar", (1,), 0, 32, None) - y.fields.append(field("y1", (1,), 7, 0, y)) - y.fields.append(field("y2", (1,), 15, 8, y)) + y.fields.append(field("y1", (1,), 7, 0, y)) + y.fields.append(field("y2", (1,), 15, 8, y)) y.fields.append(field("y3", (1,), 23, 16, y)) y.fields.append(field("y4", (1,), 31, 24, y)) - data={ - "y1" : 0x30, - "y2" : 0x32, - "y3" : 0x34, - "y4" : 0x36, + data = { + "y1": 0x30, + "y2": 0x32, + "y3": 0x34, + "y4": 0x36, } z = y.generate_binary(data, None, [traversal_history("root")]) if z.value != "0246": @@ -2691,17 +3104,17 @@ def build_schema (dir, walle_version): print(" 32 bit value was " + z.value) y = reg("baz", (1,), 0, 40, None) - y.fields.append(field("y1", (1,), 7, 0, y)) - y.fields.append(field("y2", (1,), 15, 8, y)) + y.fields.append(field("y1", (1,), 7, 0, y)) + y.fields.append(field("y2", (1,), 15, 8, y)) y.fields.append(field("y3", (1,), 23, 16, y)) y.fields.append(field("y4", (1,), 31, 24, y)) y.fields.append(field("y5", (1,), 39, 32, y)) - data={ - "y1" : 0x30, - "y2" : 0x32, - "y3" : 0x34, - "y4" : 0x36, - "y5" : 0x38, + data = { + "y1": 0x30, + "y2": 0x32, + "y3": 0x34, + "y4": 0x36, + "y5": 0x38, } z = y.generate_binary(data, None, [traversal_history("root")]) if z.value != "02468": diff --git a/backends/tofino/bf-asm/walle/walle.py b/backends/tofino/bf-asm/walle/walle.py index 84bebbd5750..b90ec493515 100755 --- a/backends/tofino/bf-asm/walle/walle.py +++ b/backends/tofino/bf-asm/walle/walle.py @@ -59,23 +59,23 @@ to be relative to the addresses in the _including_ JSON. """ import argparse -import sys +import copy +import json import os -import subprocess - import pickle -import json -import yaml -import copy +import subprocess +import sys -import csr import chip +import csr +import yaml __version__ = '0.4.13' ######################################################################## ## Utility functions + class CsrUnpickler(pickle.Unpickler): """ This module is a hacky fix for a bug that sometimes shows up when using a @@ -96,35 +96,39 @@ class CsrUnpickler(pickle.Unpickler): directly retrieving them from the csr module that this top-level script has already imported. """ + def find_class(self, module, name): if module == "csr" or module[-4:] == ".csr": - return getattr(csr,name) + return getattr(csr, name) else: return pickle.Unpickler.find_class(self, module, name) -def annotate_names (obj, threshold, path=""): + +def annotate_names(obj, threshold, path=""): if type(obj) is list: if threshold > 0 and len(obj) > threshold: for idx, elem in enumerate(obj): if type(elem) is dict: - elem["_absolute_name"] = path+"_"+str(idx) + elem["_absolute_name"] = path + "_" + str(idx) annotate_names(elem, threshold, path) else: for elem in obj: annotate_names(elem, threshold, path) elif type(obj) is dict: for key, elem in list(obj.items()): - annotate_names(elem, threshold, (path+"_" if len(path)>0 else "")+key) + annotate_names(elem, threshold, (path + "_" if len(path) > 0 else "") + key) -def print_schema_info (schema_file, schema): + +def print_schema_info(schema_file, schema): hierarchies = [] - sys.stdout.write("file: "+schema_file+"\n") + sys.stdout.write("file: " + schema_file + "\n") for key in schema: if key[0] == "_": - sys.stdout.write(key[1:]+": "+str(schema[key])+"\n") + sys.stdout.write(key[1:] + ": " + str(schema[key]) + "\n") else: hierarchies.append(key) - sys.stdout.write("hierarchies: "+", ".join(hierarchies)+"\n") + sys.stdout.write("hierarchies: " + ", ".join(hierarchies) + "\n") + def parse_template_args(args, params): """ @@ -132,19 +136,31 @@ def parse_template_args(args, params): from templates.yaml that may not exist as command line arguments FIXME -- should be a way to do this with ArgParse? """ + def bool_arg(args, attr, val): if not type(val) is bool: - raise Exception("Attribute "+attr+" requires bool argument, got "+str(val)) + raise Exception("Attribute " + attr + " requires bool argument, got " + str(val)) setattr(args, attr, val) + def str_arg(args, attr, val): if not type(val) is str: - raise Exception("Attribute "+attr+" requires string argument, got "+str(val)) + raise Exception("Attribute " + attr + " requires string argument, got " + str(val)) setattr(args, attr, val) - def add_list_arg(args, attr, val): getattr(args, attr).append(val) - def add_set_arg(args, attr, val): getattr(args, attr).add(val) - def set_decl(args, attr, val): args.gen_decl = 'decl' - def set_defn(args, attr, val): args.gen_decl = 'defn' - def no_arg(args, attr, val): pass + + def add_list_arg(args, attr, val): + getattr(args, attr).append(val) + + def add_set_arg(args, attr, val): + getattr(args, attr).add(val) + + def set_decl(args, attr, val): + args.gen_decl = 'decl' + + def set_defn(args, attr, val): + args.gen_decl = 'defn' + + def no_arg(args, attr, val): + pass options = { 'alias_array': (True, bool_arg), @@ -171,17 +187,66 @@ def no_arg(args, attr, val): pass 'rewrite_used': ({}, no_arg), 'unpack_json': (False, bool_arg), 'widereg': (False, bool_arg), - 'write_dma': (set(), add_set_arg) + 'write_dma': (set(), add_set_arg), } if not hasattr(args, 'cpp_reserved'): - args.cpp_reserved = set([ - "and", "asm", "auto", "break", "case", "catch", "char", "class", "const", "continue", - "default", "delete", "do", "double", "else", "enum", "extern", "float", "for", - "friend", "goto", "if", "inline", "int", "long", "new", "not", "or", "operator", - "private", "protected", "public", "register", "return", "short", "signed", "sizeof", - "static", "struct", "switch", "template", "this", "throw", "try", "typedef", "union", - "unsigned", "virtual", "void", "volatile", "while", "xor" ]) + args.cpp_reserved = set( + [ + "and", + "asm", + "auto", + "break", + "case", + "catch", + "char", + "class", + "const", + "continue", + "default", + "delete", + "do", + "double", + "else", + "enum", + "extern", + "float", + "for", + "friend", + "goto", + "if", + "inline", + "int", + "long", + "new", + "not", + "or", + "operator", + "private", + "protected", + "public", + "register", + "return", + "short", + "signed", + "sizeof", + "static", + "struct", + "switch", + "template", + "this", + "throw", + "try", + "typedef", + "union", + "unsigned", + "virtual", + "void", + "volatile", + "while", + "xor", + ] + ) for opt in options: if options[opt][0] is not None: if hasattr(args, opt): @@ -199,12 +264,22 @@ def no_arg(args, attr, val): pass elif p[:2] == "-I": args.include.append(p[2:]) else: - sys.stderr.write("Unknown parameter %s\n" % str(p)); + sys.stderr.write("Unknown parameter %s\n" % str(p)) if args.enable_disable: args.cpp_reserved = args.cpp_reserved.copy() - args.cpp_reserved.update(["disable", "disabled", "disable_if_unmodified", - "disable_if_zero", "enable", "modified", "set_modified"]) + args.cpp_reserved.update( + [ + "disable", + "disabled", + "disable_if_unmodified", + "disable_if_zero", + "enable", + "modified", + "set_modified", + ] + ) + def read_template_file(template_file, args, schema): with open(template_file, "rb") as template_objects_file: @@ -216,12 +291,13 @@ def read_template_file(template_file, args, schema): for section_name, section in list(schema.items()): if section_name not in top_level_objs: if section_name[0] != "_": - sys.stderr.write("no template cfg for "+section_name+", ignoring\n"); - continue; + sys.stderr.write("no template cfg for " + section_name + ", ignoring\n") + continue for obj in top_level_objs[section_name]: section[obj].templatization_behavior = "top_level" section[obj].object_name = None - if top_level_objs[section_name][obj] is None: continue + if top_level_objs[section_name][obj] is None: + continue for fname, params in list(top_level_objs[section_name][obj].items()): for p in params: if p[:5] == 'name=': @@ -229,11 +305,12 @@ def read_template_file(template_file, args, schema): break for obj in disabled_objs[section_name]: if section[obj].templatization_behavior != None: - raise Exception(obj+" cannot be both templatized and ignored") + raise Exception(obj + " cannot be both templatized and ignored") section[obj].templatization_behavior = "disabled" return top_level_objs -def generate_templates (args, schema): + +def generate_templates(args, schema): if args.o == None: args.o = "templates" if not os.path.exists(args.o): @@ -242,7 +319,7 @@ def generate_templates (args, schema): top_level_objs = read_template_file(args.generate_templates, args, schema) for section_name, section in list(schema.items()): if section_name not in top_level_objs: - continue; + continue for top_level_obj in top_level_objs[section_name]: template = section[top_level_obj].generate_template(False) sizes = section[top_level_obj].generate_template(True) @@ -252,78 +329,83 @@ def generate_templates (args, schema): annotate_names(sizes, args.template_indices) # Copy in schema metadata - schema_metadata = [key for key in list(schema.keys()) if key[0]=="_"] + schema_metadata = [key for key in list(schema.keys()) if key[0] == "_"] for metadata in schema_metadata: template[metadata] = schema[metadata] sizes[metadata] = schema[metadata] template["_section"] = section_name sizes["_section"] = section_name - cfg_name = section_name+"."+top_level_obj+".cfg.json" + cfg_name = section_name + "." + top_level_obj + ".cfg.json" with open(os.path.join(args.o, cfg_name), "wb") as outfile: json.dump(template, outfile, indent=4, sort_keys=True) - size_name = section_name+"."+top_level_obj+".size.json" + size_name = section_name + "." + top_level_obj + ".size.json" with open(os.path.join(args.o, size_name), "wb") as outfile: json.dump(sizes, outfile, indent=4, sort_keys=True) def arbitrary_ASCII_text_to_52digit_decimal_hash(input): import hashlib + # 52 characters left in 63 after the prefix "IDENTIFIER_", # and math.log2(10**52) => 172.74026093414284, # and math.log2(10**52)/8 => 21.592532616767855, # so going to request 22 bytes of hash digest. - # the next line of commented-out code is _fantastic_ in/on Python 3.8.10, # but fails in/on Python 3.5.2 [as present in/on the Jarvis image on my old BXDSW VM as of Sept. 7 2022 1:40am NY time] ### hash_digest_as_bytes = hashlib.shake_256( bytes(input, "ASCII") ).digest(22) - hash_digest_as_bytes = hashlib.sha224( bytes(input, "ASCII") ).digest() - # sha224 => 28 bytes of digest, the closest match that is >= 22 bytes and available in/on Python 3.5.2 + hash_digest_as_bytes = hashlib.sha224(bytes(input, "ASCII")).digest() + # sha224 => 28 bytes of digest, the closest match that is >= 22 bytes and available in/on Python 3.5.2 hash_digest_as_int = int.from_bytes(hash_digest_as_bytes, "big") return ("%052d" % hash_digest_as_int)[:52] - -def arbitrary_text_to_valid_C_identifier(input_iterable_of_characters, dry_run_to_get_hash_input = False): +def arbitrary_text_to_valid_C_identifier( + input_iterable_of_characters, dry_run_to_get_hash_input=False +): """Takes a single input, which must be an iterable of characters for correct behavior to be - promised. When given valid input, returns a string that is a valid C and C++ identifier, - regardless of what characters are used in the input. + promised. When given valid input, returns a string that is a valid C and C++ identifier, + regardless of what characters are used in the input. - _Intentionally_ *not* considering [ASCII] underscores as OK to copy untranslated as-is, - since _both_ leading underscores _and_ 2-or-more underscores in a row are considered as - ''reserved'' by the ISO C++ standard [and probably also by the ISO C standard]. + _Intentionally_ *not* considering [ASCII] underscores as OK to copy untranslated as-is, + since _both_ leading underscores _and_ 2-or-more underscores in a row are considered as + ''reserved'' by the ISO C++ standard [and probably also by the ISO C standard]. - _Only_ ASCII alphanumerics are ''OK as is''. + _Only_ ASCII alphanumerics are ''OK as is''. - Quoting : + Quoting : - "The C standard requires only that the first 63 be significant" + "The C standard requires only that the first 63 be significant" - In other words, the first 63 characters are definitely going to be "paid attention to", - and the rest may be handled as "comments". I think we are probably safe with shifting - our upper bound to 200 or 999 characters. + In other words, the first 63 characters are definitely going to be "paid attention to", + and the rest may be handled as "comments". I think we are probably safe with shifting + our upper bound to 200 or 999 characters. - Using a decimal hash to almost-guarantee uniqueness in the first 63 characters.""" + Using a decimal hash to almost-guarantee uniqueness in the first 63 characters.""" - if (not input_iterable_of_characters) or (len(input_iterable_of_characters)<1): + if (not input_iterable_of_characters) or (len(input_iterable_of_characters) < 1): raise ValueError("This function requires an input of positive length.") - INCLUSIVE_MAX_OUTPUT_LENGTH = 255 # D. R. Y. + INCLUSIVE_MAX_OUTPUT_LENGTH = 255 # D. R. Y. temp_ASCIIonly_string = "" for char in input_iterable_of_characters: - if len(temp_ASCIIonly_string) > 999: # there`s not much good in letting it go on for an arbitrarily-long time + if ( + len(temp_ASCIIonly_string) > 999 + ): # there`s not much good in letting it go on for an arbitrarily-long time break - if '/' == char: # {part 1 of 3} of a kludge so that we can include path separators in the hash input + if ( + '/' == char + ): # {part 1 of 3} of a kludge so that we can include path separators in the hash input temp_ASCIIonly_string += char - if char.isalnum() and (ord(char)>=32) and (ord(char)<=126): - # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - # "char.isascii()" does _not_ always work + if char.isalnum() and (ord(char) >= 32) and (ord(char) <= 126): + # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + # "char.isascii()" does _not_ always work temp_ASCIIonly_string += char - elif not ( temp_ASCIIonly_string.endswith('_') or temp_ASCIIonly_string.endswith('/') ): - # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - # {part 2 of 3} of a kludge so that we can include path separators in the hash input + elif not (temp_ASCIIonly_string.endswith('_') or temp_ASCIIonly_string.endswith('/')): + # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + # {part 2 of 3} of a kludge so that we can include path separators in the hash input temp_ASCIIonly_string += '_' if dry_run_to_get_hash_input: @@ -335,36 +417,44 @@ def arbitrary_text_to_valid_C_identifier(input_iterable_of_characters, dry_run_t result += temp_ASCIIonly_string result = result[:INCLUSIVE_MAX_OUTPUT_LENGTH] - result = result.replace('/', '_') # {part 3 of 3} of a kludge so that we can include path separators in the hash input + result = result.replace( + '/', '_' + ) # {part 3 of 3} of a kludge so that we can include path separators in the hash input return result - -def pathname_to_valid_C_identifier(file_pathname, dry_run_to_get_hash_input = False): +def pathname_to_valid_C_identifier(file_pathname, dry_run_to_get_hash_input=False): """This makes the assumption that the input is a string - [or at least "string-like object"] - with the data in a format along the lines of "/a/b/c/d/e/file" + [or at least "string-like object"] + with the data in a format along the lines of "/a/b/c/d/e/file" """ assert len(file_pathname) > 0 - first_char_upper_case = lambda x: "" if (len(x)<1) else x[0].upper() + x[1:].lower() + first_char_upper_case = lambda x: "" if (len(x) < 1) else x[0].upper() + x[1:].lower() # somewhat hackish... does anybody want to propose an "elegant" alternative for the next 3 lines? - if file_pathname.endswith(".cpp"): file_pathname = file_pathname[:-4] - if file_pathname.endswith(".hpp"): file_pathname = file_pathname[:-4] - if file_pathname.endswith(".h" ): file_pathname = file_pathname[:-2] - - split = file_pathname.split('/') # POSIXism warning re '/' + if file_pathname.endswith(".cpp"): + file_pathname = file_pathname[:-4] + if file_pathname.endswith(".hpp"): + file_pathname = file_pathname[:-4] + if file_pathname.endswith(".h"): + file_pathname = file_pathname[:-2] + + split = file_pathname.split('/') # POSIXism warning re '/' file = first_char_upper_case(split[-1]) - last_4_dirs_if_possible = [ first_char_upper_case(x) for x in split[-5:-1] ] # worst-case scenario, this is an empty list - - return arbitrary_text_to_valid_C_identifier('/'.join(last_4_dirs_if_possible+[file]), dry_run_to_get_hash_input) + last_4_dirs_if_possible = [ + first_char_upper_case(x) for x in split[-5:-1] + ] # worst-case scenario, this is an empty list + return arbitrary_text_to_valid_C_identifier( + '/'.join(last_4_dirs_if_possible + [file]), dry_run_to_get_hash_input + ) def generate_cPlusPlus_file(outfile, top_level, args, schema, file_basename): - outfile.write("/* Autogenerated from %s and %s -- DO NOT EDIT */\n" % ( - args.schema, args.generate_cpp)) + outfile.write( + "/* Autogenerated from %s and %s -- DO NOT EDIT */\n" % (args.schema, args.generate_cpp) + ) fake_pathname = args.o + '/' + top_level.name + '/' + file_basename @@ -379,12 +469,15 @@ def generate_cPlusPlus_file(outfile, top_level, args, schema, file_basename): outfile.write("\n") outfile.write("DEBUG: fake_pathname = ''%s''\n" % fake_pathname) outfile.write("\n") - outfile.write( "DEBUG: input to hash algo.: ''%s''\n" % pathname_to_valid_C_identifier(fake_pathname, dry_run_to_get_hash_input = True) ) + outfile.write( + "DEBUG: input to hash algo.: ''%s''\n" + % pathname_to_valid_C_identifier(fake_pathname, dry_run_to_get_hash_input=True) + ) outfile.write(" --- ^^^ --- DEBUG --- ^^^ --- */\n") del fake_pathname if args.gen_decl == 'decl': - outfile.write('#ifndef %s\n' % synthetic_identifier) + outfile.write('#ifndef %s\n' % synthetic_identifier) outfile.write('#define %s 1\n\n' % synthetic_identifier) for incl in args.include: @@ -417,6 +510,7 @@ def generate_cPlusPlus_file(outfile, top_level, args, schema, file_basename): if args.gen_decl == 'decl': outfile.write('\n#endif /* end of "ifndef %s" */\n' % synthetic_identifier) + def extend_args(args, params): """ parse additional template arguments into a copy of 'args' @@ -425,7 +519,8 @@ def extend_args(args, params): parse_template_args(args, params) return args -def generate_cpp (args, schema): + +def generate_cpp(args, schema): if args.o == None: args.o = "gen" if not os.path.exists(args.o): @@ -435,45 +530,56 @@ def generate_cpp (args, schema): global_args = args for section_name, section in list(schema.items()): if section_name not in top_level_objs: - continue; - for top_level_obj,files in list(top_level_objs[section_name].items()): - if files is None: continue + continue + for top_level_obj, files in list(top_level_objs[section_name].items()): + if files is None: + continue args = global_args if 'args' in files: args = extend_args(args, files['args']) if 'rewrite' in files: args = copy.copy(args) args.rewrite = files['rewrite'] - for generate_file,params in list(files.items()): - if generate_file == 'args': continue - if generate_file == 'rewrite': continue - if (("DEBUG" in globals().keys()) and globals()["DEBUG"]) or ("DEBUG" in locals().keys()) and locals()["DEBUG"]: - print ("===vvv=== DEBUG ===vvv===") - print ("globals:", globals()) - print ("locals:", locals()) - print ("===^^^=== DEBUG ===^^^===") - generate_cPlusPlus_file(open(os.path.join(args.o, generate_file), "w"), - section[top_level_obj], - extend_args(args, params), - schema, - generate_file) + for generate_file, params in list(files.items()): + if generate_file == 'args': + continue + if generate_file == 'rewrite': + continue + if ( + (("DEBUG" in globals().keys()) and globals()["DEBUG"]) + or ("DEBUG" in locals().keys()) + and locals()["DEBUG"] + ): + print("===vvv=== DEBUG ===vvv===") + print("globals:", globals()) + print("locals:", locals()) + print("===^^^=== DEBUG ===^^^===") + generate_cPlusPlus_file( + open(os.path.join(args.o, generate_file), "w"), + section[top_level_obj], + extend_args(args, params), + schema, + generate_file, + ) + def print_schema_text(args, schema): def do_print(indent, obj): - for key,val in list(obj.items()): + for key, val in list(obj.items()): if type(val) is str: print("%s%s: %s" % (indent, key, val)) elif type(val) is dict: print("%s%s:" % (indent, key)) - do_print(indent+" ", val) + do_print(indent + " ", val) elif val.templatization_behavior == "top_level": print("%s%s:" % (indent, key)) - val.print_as_text(indent+" ") + val.print_as_text(indent + " ") read_template_file(args.print_schema, args, schema) do_print("", schema) -def build_binary_cache (args, schema): + +def build_binary_cache(args, schema): cache = csr.binary_cache(schema) try: for config_filename in args.configs: @@ -481,33 +587,48 @@ def build_binary_cache (args, schema): try: template = json.load(configfile) except: - sys.stderr.write("ERROR: Input file '"+config_filename+"' could not be decoded as JSON.\n") + sys.stderr.write( + "ERROR: Input file '" + + config_filename + + "' could not be decoded as JSON.\n" + ) sys.exit(1) - if (type(template) is not dict or - "_name" not in template or - "_type" not in template): - sys.stderr.write("ERROR: Input file '"+config_filename+"' does not appear to be valid Walle configuration JSON.\n") + if type(template) is not dict or "_name" not in template or "_type" not in template: + sys.stderr.write( + "ERROR: Input file '" + + config_filename + + "' does not appear to be valid Walle configuration JSON.\n" + ) sys.exit(1) - if ("_schema_hash" not in template or - template["_schema_hash"] != schema["_schema_hash"]): - sys.stderr.write("ERROR: Input file '"+config_filename+"' does not match the current chip schema.\n") + if ( + "_schema_hash" not in template + or template["_schema_hash"] != schema["_schema_hash"] + ): + sys.stderr.write( + "ERROR: Input file '" + + config_filename + + "' does not match the current chip schema.\n" + ) if not args.ignore_schema_mismatch: sys.exit(1) cache.templates[template["_name"]] = template except IOError as e: - sys.stderr.write("ERROR: Could not open '%s' for reading: %s (errno %i).\n"%(config_filename,e[1],e[0])) + sys.stderr.write( + "ERROR: Could not open '%s' for reading: %s (errno %i).\n" + % (config_filename, e[1], e[0]) + ) sys.exit(e[0]) return cache -def dump_binary (args, binary_cache, out_file): + +def dump_binary(args, binary_cache, out_file): addr_func = { # Memories are ram-word addressed, not byte addressed "memories": lambda addr: addr >> 4, - # TODO: use actual func once model+indirect writes are fixed "regs": lambda addr: addr # # Regs are give in 32-bit PCIe address space and need to be @@ -522,10 +643,10 @@ def dump_binary (args, binary_cache, out_file): data_type = binary_cache.get_type(template) except csr.CsrException as e: # TODO: decompose: - sys.stderr.write("ERROR: "+str(e)+"\n") + sys.stderr.write("ERROR: " + str(e) + "\n") tb = [] for frame in path: - tb.append("{"+frame.template_name+"}") + tb.append("{" + frame.template_name + "}") arr_subscript = None for node in frame.path: if type(node) is str: @@ -537,7 +658,7 @@ def dump_binary (args, binary_cache, out_file): arr_subscript = csr.array_str(node) else: tb.append(str(node)) - sys.stderr.write("Traceback: "+".".join(tb)+"\n") + sys.stderr.write("Traceback: " + ".".join(tb) + "\n") sys.exit(1) template_section = data_type.split(".")[0] @@ -548,6 +669,7 @@ def dump_binary (args, binary_cache, out_file): if args.append_sentinel: out_file.write(chip.direct_reg(0xFFFFFFFF, 0).bytes()) + def walle_process(parser, args=None): if len(args.top) == 0: args.top = ["memories.top", "regs.top"] @@ -564,15 +686,21 @@ def walle_process(parser, args=None): if args.generate_templates != None: if not os.path.isfile(args.schema): - sys.stderr.write("ERROR: Schema file '"+os.path.abspath(args.schema)+ - "' could not be opened or does not exist.\n") + sys.stderr.write( + "ERROR: Schema file '" + + os.path.abspath(args.schema) + + "' could not be opened or does not exist.\n" + ) sys.exit(1) generate_templates(args, schema) else: if not os.path.isfile(args.schema): - sys.stderr.write("ERROR: Schema file '"+os.path.abspath(args.schema)+ - "' could not be opened or does not exist.\n") + sys.stderr.write( + "ERROR: Schema file '" + + os.path.abspath(args.schema) + + "' could not be opened or does not exist.\n" + ) sys.exit(1) with open(args.schema, "rb") as infile: @@ -589,16 +717,17 @@ def walle_process(parser, args=None): elif args.generate_cpp != None: generate_cpp(args, schema) else: - if len(args.configs)==0: + if len(args.configs) == 0: parser.print_help() else: if args.o == None: args.o = "a.out" cache = build_binary_cache(args, schema) - with open(args.o,"wb") as binfile: + with open(args.o, "wb") as binfile: dump_binary(args, cache, binfile) - sys.stdout.write("Binary '"+args.o+"' generated successfully.\n") + sys.stdout.write("Binary '" + args.o + "' generated successfully.\n") + def main(): """ @@ -606,45 +735,34 @@ def main(): """ parser = argparse.ArgumentParser() + parser.add_argument('-v', '--version', action='version', version='%(prog)s ' + __version__) parser.add_argument( - '-v', '--version', - action='version', version='%(prog)s ' + __version__ - ) - parser.add_argument( - "--schema", '-s', + "--schema", + '-s', metavar='SCHEMA-FILE', help="The chip schema to use", type=str, - default="chip.schema" + default="chip.schema", ) parser.add_argument( "--schema-info", action='store_true', - help="Print metadata stored in the selected chip schema and exit" - ) - parser.add_argument( - "--target", "-t", - help="The chip target", - type=str, - default="tofino" - ) - parser.add_argument( - "--dump-schema", - action='store_true', - help="Dump chip schema as yaml" + help="Print metadata stored in the selected chip schema and exit", ) + parser.add_argument("--target", "-t", help="The chip target", type=str, default="tofino") + parser.add_argument("--dump-schema", action='store_true', help="Dump chip schema as yaml") parser.add_argument( "--print-schema", metavar='TOP-LEVEL-OBJS-FILE', type=str, - help="Dump chip schema as (readable?) text" + help="Dump chip schema as (readable?) text", ) parser.add_argument( "--generate-schema", metavar='BFNREGS-TARGET-DIR', type=str, help="Generate a chip schema from the bfnregs target regs directory", - default=None + default=None, ) parser.add_argument( "--ignore-schema-mismatch", @@ -668,7 +786,7 @@ def main(): metavar='THRESHOLD', help="Include human-readable index keys for register arrays greater than the specified threshold size", type=int, - default=None + default=None, ) parser.add_argument( "--append-sentinel", @@ -681,24 +799,25 @@ def main(): type=str, action='append', default=[], - help='Identifier of a template to generate binary config data for' + help='Identifier of a template to generate binary config data for', ) parser.add_argument( '-o', metavar='FILE', type=str, default=None, - help='Name of file to write binary config data into (or directory to write templates into)' + help='Name of file to write binary config data into (or directory to write templates into)', ) parser.add_argument( 'configs', metavar='CONFIG-FILE', - type=str, nargs='*', - help='A JSON configuration file to process' + type=str, + nargs='*', + help='A JSON configuration file to process', ) args = parser.parse_args() - if getattr( sys, 'frozen', False ) : + if getattr(sys, 'frozen', False): # running as a bundle: look for the schema in the bundled directory args.schema = os.path.join(sys._MEIPASS, 'lib', args.target, 'chip.schema') walle_process(parser, args) diff --git a/backends/tofino/compiler_interfaces/schemas/mau_schema.py b/backends/tofino/compiler_interfaces/schemas/mau_schema.py index 72a64ef051d..39b0a53dfa8 100644 --- a/backends/tofino/compiler_interfaces/schemas/mau_schema.py +++ b/backends/tofino/compiler_interfaces/schemas/mau_schema.py @@ -233,7 +233,6 @@ class StageMatchMemoryDetails(StageMemoryDetailsWithEntryWidthAndIdeal): class MatchTables(jsl.Document): - class StageDetails(jsl.Document): title = "StageDetails" description = "Information about packing and resource usage on a per-stage basis." diff --git a/backends/tofino/compiler_interfaces/schemas/power_schema.py b/backends/tofino/compiler_interfaces/schemas/power_schema.py index 04e5cddc7e9..386c6da7242 100644 --- a/backends/tofino/compiler_interfaces/schemas/power_schema.py +++ b/backends/tofino/compiler_interfaces/schemas/power_schema.py @@ -111,7 +111,6 @@ class Features(jsl.Document): class MatchTables(jsl.Document): - class StageDetails(jsl.Document): title = "StageDetails" description = "Information about table power usage on a per-stage basis." diff --git a/backends/tofino/compiler_interfaces/tools/create_mau_characterize.py b/backends/tofino/compiler_interfaces/tools/create_mau_characterize.py index e2d117eaf3e..ed276579d82 100755 --- a/backends/tofino/compiler_interfaces/tools/create_mau_characterize.py +++ b/backends/tofino/compiler_interfaces/tools/create_mau_characterize.py @@ -766,9 +766,12 @@ def log_match_and_action_formats(all_match_and_action_formats): for table_name, stage in keys: if table_name not in tbl_to_info: tbl_to_info[table_name] = OrderedDict() - match_format_json, actual_match_entries, action_formats_json, actual_action_entries = ( - all_match_and_action_formats[(table_name, stage)] - ) + ( + match_format_json, + actual_match_entries, + action_formats_json, + actual_action_entries, + ) = all_match_and_action_formats[(table_name, stage)] tbl_to_info[table_name][stage] = ( match_format_json, actual_match_entries, @@ -789,9 +792,12 @@ def log_match_and_action_formats(all_match_and_action_formats): all_match_formats = [] all_action_formats = [] for stage in tbl_to_info[table_name]: - match_format_json, actual_match_entries, action_formats_json, actual_action_entries = ( - tbl_to_info[table_name][stage] - ) + ( + match_format_json, + actual_match_entries, + action_formats_json, + actual_action_entries, + ) = tbl_to_info[table_name][stage] all_match_formats.append((stage, match_format_json, actual_match_entries)) all_action_formats.append((stage, action_formats_json, actual_action_entries)) @@ -844,9 +850,12 @@ def produce_mau_characterize(source, output): log.info("%s\n" % box) # Populate table summary information - table_info, sram_summary, all_overhead_structures, all_match_and_action_formats = ( - _parse_mau_json(context) - ) + ( + table_info, + sram_summary, + all_overhead_structures, + all_match_and_action_formats, + ) = _parse_mau_json(context) # Output summary table in log file diff --git a/backends/tofino/compiler_interfaces/tools/create_mau_json.py b/backends/tofino/compiler_interfaces/tools/create_mau_json.py index d121e48f011..6874e88f50d 100755 --- a/backends/tofino/compiler_interfaces/tools/create_mau_json.py +++ b/backends/tofino/compiler_interfaces/tools/create_mau_json.py @@ -579,10 +579,11 @@ def get_match_memory(match_stage_table, match_table, context, entries_so_far): mem_elem["entry_bit_width_requested"] = ideal_entry_bits mem_elem["entry_bit_width_allocated"] = allocated_match_bits - mem_elem["ideal_entries_per_table_word"], mem_elem["ideal_table_word_bit_width"] = ( - get_ideal_match_entries( - match_stage_table, match_table, mem_elem["imm_bit_width_in_overhead_requested"] - ) + ( + mem_elem["ideal_entries_per_table_word"], + mem_elem["ideal_table_word_bit_width"], + ) = get_ideal_match_entries( + match_stage_table, match_table, mem_elem["imm_bit_width_in_overhead_requested"] ) memories.append(mem_elem) diff --git a/backends/tofino/compiler_interfaces/tools/create_phv_json.py b/backends/tofino/compiler_interfaces/tools/create_phv_json.py index af8ea34233d..0d3fa689c13 100755 --- a/backends/tofino/compiler_interfaces/tools/create_phv_json.py +++ b/backends/tofino/compiler_interfaces/tools/create_phv_json.py @@ -318,9 +318,9 @@ def produce_containers_node(context): rec = OrderedDict() rec["field_name"] = field_name - rec["field_class"] = ( - "pkt" # FIXME: Don't know how to get the value from context.json. - ) + rec[ + "field_class" + ] = "pkt" # FIXME: Don't know how to get the value from context.json. rec["field_msb"] = field_msb rec["field_lsb"] = field_lsb rec["phv_msb"] = phv_msb From 8559cb333ae53ee8781981e02fdb858587a063a5 Mon Sep 17 00:00:00 2001 From: fruffy Date: Thu, 6 Feb 2025 22:01:48 -0500 Subject: [PATCH 04/19] Fix config.h naming conflict. Signed-off-by: fruffy --- backends/tofino/CMakeLists.txt | 3 +- backends/tofino/bf-asm/CMakeLists.txt | 72 ++++++++++-------- backends/tofino/bf-asm/action_bus.cpp | 3 +- backends/tofino/bf-asm/asm-parse.ypp | 2 +- backends/tofino/bf-asm/attached_table.cpp | 3 +- backends/tofino/bf-asm/cmake/Abseil.cmake | 76 ------------------- .../cmake/{config.h.in => config.h.cmake} | 4 +- backends/tofino/bf-asm/crash.cpp | 3 +- backends/tofino/bf-asm/deparser.cpp | 3 +- backends/tofino/bf-asm/hash_dist.cpp | 3 +- backends/tofino/bf-asm/input_xbar.cpp | 2 +- backends/tofino/bf-asm/instruction.cpp | 3 +- backends/tofino/bf-asm/instruction.h | 3 +- backends/tofino/bf-asm/lex-yaml.l | 2 +- backends/tofino/bf-asm/match_table.cpp | 3 +- backends/tofino/bf-asm/parser-tofino-jbay.cpp | 3 +- backends/tofino/bf-asm/salu_inst.cpp | 3 +- backends/tofino/bf-asm/stage.cpp | 2 +- backends/tofino/bf-asm/tables.cpp | 3 +- backends/tofino/bf-asm/tables.h | 3 +- backends/tofino/bf-asm/target.cpp | 3 +- backends/tofino/bf-asm/target.h | 3 +- 22 files changed, 60 insertions(+), 145 deletions(-) delete mode 100644 backends/tofino/bf-asm/cmake/Abseil.cmake rename backends/tofino/bf-asm/cmake/{config.h.in => config.h.cmake} (92%) diff --git a/backends/tofino/CMakeLists.txt b/backends/tofino/CMakeLists.txt index 205f62d10ed..16612a6d97e 100644 --- a/backends/tofino/CMakeLists.txt +++ b/backends/tofino/CMakeLists.txt @@ -85,8 +85,7 @@ else() set (BFN_P4C_GIT_SHA $ENV{BFN_P4C_GIT_SHA}) endif() endif() -set (ENV{P4C_VERSION} "${BFN_P4C_VERSION} (SHA: ${BFN_P4C_GIT_SHA})") -MESSAGE(STATUS "p4c-barefoot version: $ENV{P4C_VERSION}") +MESSAGE(STATUS "p4c-barefoot version: ${BFN_P4C_VERSION}") # Generate the sha specific version file. It includes the GIT SHA. # Because this version changes frequently, we include it separately from the normal version files. diff --git a/backends/tofino/bf-asm/CMakeLists.txt b/backends/tofino/bf-asm/CMakeLists.txt index fc6f026ce83..fea436eda86 100644 --- a/backends/tofino/bf-asm/CMakeLists.txt +++ b/backends/tofino/bf-asm/CMakeLists.txt @@ -15,13 +15,15 @@ # # SPDX-License-Identifier: Apache-2.0 -# # ##### Tofino assembler +# # # #### Tofino assembler +project(BFASM) + MESSAGE("-- Adding bf-asm") OPTION(ASAN_ENABLED "Enable ASAN checks" OFF) set (BFASM_LIB_DEPS p4ctoolkit ${P4C_LIB_DEPS}) -set (BFASM_GEN_DIR ${CMAKE_CURRENT_BINARY_DIR}/gen) +set (BFASM_GEN_DIR ${BFASM_BINARY_DIR}/gen) # other required libraries include (CheckLibraryExists) @@ -106,6 +108,24 @@ set (J2B_SOURCES j2b.cpp json.cpp bson.cpp) # mksizes set (MKSIZES_SOURCES mksizes.cpp) +# json_diff +add_executable (json_diff ${JSONDIFF_SOURCES}) + +# bfdumpbin +add_executable (bfdumpbin ${BFDUMPBIN_SOURCES}) + +# reflow +add_executable (reflow ${REFLOW_SOURCES}) + +# b2j +add_executable (b2j ${B2J_SOURCES}) + +# j2b +add_executable (j2b ${J2B_SOURCES}) + +# mksizes +add_executable (mksizes ${MKSIZES_SOURCES}) + set (BFAS_COMMON_SOURCES action_bus.cpp action_table.cpp @@ -158,22 +178,25 @@ set (BFAS_COMMON_SOURCES ${BFN_P4C_SOURCE_DIR}/bf-utils/dynamic_hash/bfn_hash_algorithm.cpp ) -set (BFAS_GEN_SOURCES - ${BFASM_GEN_DIR}/asm-parse.cpp - ${BFASM_GEN_DIR}/gen/uptr_sizes.h -) BISON_TARGET (asm-parse asm-parse.ypp ${BFASM_GEN_DIR}/asm-parse.cpp VERBOSE) -add_custom_command(OUTPUT lex-yaml.c - COMMAND ${FLEX_EXECUTABLE} -t ${CMAKE_CURRENT_SOURCE_DIR}/lex-yaml.l > lex-yaml.c +add_custom_command(OUTPUT ${BFASM_GEN_DIR}/uptr_sizes.h + COMMAND ${CMAKE_COMMAND} -E make_directory ${BFASM_GEN_DIR} + COMMAND ${BFASM_BINARY_DIR}/mksizes > ${BFASM_GEN_DIR}/uptr_sizes.h) +add_custom_target(bfasm_uptr DEPENDS mksizes ${BFASM_GEN_DIR}/uptr_sizes.h) + +add_custom_command(OUTPUT ${BFASM_GEN_DIR}/lex-yaml.c + COMMAND ${FLEX_EXECUTABLE} -t ${BFASM_SOURCE_DIR}/lex-yaml.l > ${BFASM_GEN_DIR}/lex-yaml.c DEPENDS ${BFASM_SOURCE_DIR}/lex-yaml.l COMMENT "Generating lex-yaml.cpp") +add_custom_target(bfasm_yaml DEPENDS ${BFASM_GEN_DIR}/lex-yaml.c) +add_dependencies(bfasm_yaml bfasm_uptr) -add_custom_command(OUTPUT gen/uptr_sizes.h - COMMAND ${CMAKE_COMMAND} -E make_directory ${BFASM_GEN_DIR}/gen - COMMAND mksizes > gen/uptr_sizes.h - DEPENDS lex-yaml.c mksizes) +set (BFAS_GEN_SOURCES + ${BFASM_GEN_DIR}/asm-parse.cpp + ${BFASM_GEN_DIR}/uptr_sizes.h +) set (BFASM_WALLE ${BFASM_SOURCE_DIR}/walle/walle.py) set (WALLE_SOURCES @@ -189,22 +212,15 @@ set (HAVE_JBAY 1) set (BFASM_LIBS ${BFASM_LIBS} regs_jbay) # Other configuration files that need to be generated -configure_file ("${BFASM_SOURCE_DIR}/cmake/config.h.in" "${BFASM_GEN_DIR}/config.h") +configure_file ("${BFASM_SOURCE_DIR}/cmake/config.h.cmake" "${BFASM_BINARY_DIR}/config.h") -set_source_files_properties (${BFAS_GEN_SOURCES} ${BFASM_GEN_DIR}/lex-yaml.c - PROPERTIES GENERATED TRUE) +set_source_files_properties (${BFAS_GEN_SOURCES} ${BFASM_GEN_DIR}/lex-yaml.c PROPERTIES GENERATED TRUE) set (BFAS_SOURCES ${BFAS_COMMON_SOURCES} ${BFAS_GEN_SOURCES} ${BFAS_TOFINO_SRCS} ${BFAS_JBAY_SRCS} ) -# json_diff -add_executable (json_diff ${JSONDIFF_SOURCES}) - -# bfdumpbin -add_executable (bfdumpbin ${BFDUMPBIN_SOURCES}) - # bfdis if (ENABLE_GTESTS) # FIXME -- bfdis depends on bfas_lib which is only built if GTESTS are enabled. So for @@ -214,17 +230,6 @@ if (ENABLE_GTESTS) target_link_libraries (bfdis bfas_lib ${BFASM_LIBS} ${BFASM_LIB_DEPS}) endif() -# reflow -add_executable (reflow ${REFLOW_SOURCES}) - -# b2j -add_executable (b2j ${B2J_SOURCES}) - -# j2b -add_executable (j2b ${J2B_SOURCES}) - -# mksizes -add_executable (mksizes ${MKSIZES_SOURCES}) # set_source_files_properties(${BFAS_SOURCES} PROPERTIES COMPILE_FLAGS ${BFASM_CXX_FLAGS}) # Remove compiler flag that is C++ only for vector.c @@ -233,12 +238,13 @@ add_executable (mksizes ${MKSIZES_SOURCES}) add_executable (bfas ${BFAS_SOURCES}) target_compile_options(bfas PRIVATE -std=gnu++17) # Enable extensions for bfas. target_link_libraries (bfas ${BFASM_LIBS} ${BFASM_LIB_DEPS}) +add_dependencies(bfas bfasm_yaml) install (TARGETS bfas RUNTIME DESTINATION bin) # Link bfas into the p4c binary folder. add_custom_target(linkbfas - COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_CURRENT_BINARY_DIR}/bfas ${P4C_BINARY_DIR}/bfas + COMMAND ${CMAKE_COMMAND} -E create_symlink ${BFASM_BINARY_DIR}/bfas ${P4C_BINARY_DIR}/bfas ) add_dependencies(linkbfas bfas) add_dependencies(p4c_driver linkbfas) diff --git a/backends/tofino/bf-asm/action_bus.cpp b/backends/tofino/bf-asm/action_bus.cpp index a6d4184b0a9..5d9b88d09a7 100644 --- a/backends/tofino/bf-asm/action_bus.cpp +++ b/backends/tofino/bf-asm/action_bus.cpp @@ -17,8 +17,7 @@ #include "action_bus.h" -#include - +#include "backends/tofino/bf-asm/config.h" #include "backends/tofino/bf-asm/stage.h" #include "lib/hex.h" #include "misc.h" diff --git a/backends/tofino/bf-asm/asm-parse.ypp b/backends/tofino/bf-asm/asm-parse.ypp index d0e9c50c837..2092fc60eef 100644 --- a/backends/tofino/bf-asm/asm-parse.ypp +++ b/backends/tofino/bf-asm/asm-parse.ypp @@ -370,7 +370,7 @@ error_resync: /* epsilon */ | error_resync indent_elements { free_value(&$2); } #pragma GCC diagnostic ignored "-Wpragmas" #pragma GCC diagnostic ignored "-Wdeprecated-register" #pragma GCC diagnostic ignored "-Wsign-compare" -#include "backends/tofino/bf-asm/lex-yaml.c" +#include "backends/tofino/bf-asm/gen/lex-yaml.c" #pragma GCC diagnostic pop int error_count = 0; diff --git a/backends/tofino/bf-asm/attached_table.cpp b/backends/tofino/bf-asm/attached_table.cpp index c2bc1356aae..921bd97f4f5 100644 --- a/backends/tofino/bf-asm/attached_table.cpp +++ b/backends/tofino/bf-asm/attached_table.cpp @@ -15,11 +15,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - #include #include "action_bus.h" +#include "backends/tofino/bf-asm/config.h" #include "backends/tofino/bf-asm/stage.h" #include "backends/tofino/bf-asm/tables.h" #include "input_xbar.h" diff --git a/backends/tofino/bf-asm/cmake/Abseil.cmake b/backends/tofino/bf-asm/cmake/Abseil.cmake deleted file mode 100644 index 1e32d333e2a..00000000000 --- a/backends/tofino/bf-asm/cmake/Abseil.cmake +++ /dev/null @@ -1,76 +0,0 @@ -macro(p4c_obtain_abseil) - option( - P4C_USE_PREINSTALLED_ABSEIL - "Look for a preinstalled version of Abseil in the system instead of installing the library using FetchContent." - OFF - ) - - # If P4C_USE_PREINSTALLED_ABSEIL is ON just try to find a preinstalled version of Abseil. - if(P4C_USE_PREINSTALLED_ABSEIL) - if(ENABLE_ABSEIL_STATIC) - set(SAVED_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) - set(CMAKE_FIND_LIBRARY_SUFFIXES .a) - endif() - - set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) - find_package(absl REQUIRED) - - if(ENABLE_ABSEIL_STATIC) - set(CMAKE_FIND_LIBRARY_SUFFIXES ${SAVED_CMAKE_FIND_LIBRARY_SUFFIXES}) - endif() - else() - set(P4C_ABSEIL_VERSION "20240116.1") - message(STATUS "Fetching Abseil version ${P4C_ABSEIL_VERSION} for P4C...") - - # Unity builds do not work for Abseil... - set(CMAKE_UNITY_BUILD_PREV ${CMAKE_UNITY_BUILD}) - set(CMAKE_UNITY_BUILD OFF) - - # Print out download state while setting up Abseil. - set(FETCHCONTENT_QUIET_PREV ${FETCHCONTENT_QUIET}) - set(FETCHCONTENT_QUIET OFF) - - set(ABSL_USE_EXTERNAL_GOOGLETEST ON) - set(ABSL_FIND_GOOGLETEST OFF) - set(ABSL_BUILD_TESTING OFF) - set(ABSL_ENABLE_INSTALL OFF) - set(ABSL_USE_SYSTEM_INCLUDES ON) - set(ABSL_PROPAGATE_CXX_STD ON) - - FetchContent_Declare( - abseil - URL https://github.com/abseil/abseil-cpp/releases/download/${P4C_ABSEIL_VERSION}/abseil-cpp-${P4C_ABSEIL_VERSION}.tar.gz - URL_HASH SHA256=3c743204df78366ad2eaf236d6631d83f6bc928d1705dd0000b872e53b73dc6a - USES_TERMINAL_DOWNLOAD TRUE - GIT_PROGRESS TRUE - ) - fetchcontent_makeavailable_but_exclude_install(abseil) - - # Suppress warnings for all Abseil targets. - get_all_targets(ABSL_BUILD_TARGETS ${absl_SOURCE_DIR}) - foreach(target ${ABSL_BUILD_TARGETS}) - if(target MATCHES "absl_*") - # Do not suppress warnings for Abseil library targets that are aliased. - get_target_property(target_type ${target} TYPE) - if (NOT ${target_type} STREQUAL "INTERFACE_LIBRARY") - # We need this workaround because of https://github.com/abseil/abseil-cpp/issues/1664. - # TODO: Remove once the Abseil compilation issue is fixed. - if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 14) - target_compile_options(${target} PUBLIC "-mbmi") - endif() - target_compile_options(${target} PRIVATE "-Wno-error" "-w") - endif() - endif() - endforeach() - # TODO: Remove once the Abseil compilation issue is fixed. - if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 14) - message(WARNING "Compiling with GCC > 14. Adding -mbmi to Abseil targets, this may cause incompatibility with old CPUs.") - endif() - - # Reset temporary variable modifications. - set(CMAKE_UNITY_BUILD ${CMAKE_UNITY_BUILD_PREV}) - set(FETCHCONTENT_QUIET ${FETCHCONTENT_QUIET_PREV}) - endif() - - message(STATUS "Done with setting up Abseil for P4C.") -endmacro(p4c_obtain_abseil) diff --git a/backends/tofino/bf-asm/cmake/config.h.in b/backends/tofino/bf-asm/cmake/config.h.cmake similarity index 92% rename from backends/tofino/bf-asm/cmake/config.h.in rename to backends/tofino/bf-asm/cmake/config.h.cmake index acbd002ead2..0114e1b81b7 100644 --- a/backends/tofino/bf-asm/cmake/config.h.in +++ b/backends/tofino/bf-asm/cmake/config.h.cmake @@ -7,8 +7,6 @@ /* Define to 1 if you have the ucontext.h header */ #cmakedefine HAVE_UCONTEXT_H @HAVE_UCONTEXT_H@ - - /* Define to 1 if we include JBay */ #cmakedefine HAVE_JBAY @HAVE_JBAY@ @@ -19,7 +17,7 @@ #cmakedefine CONTEXT_SCHEMA_VERSION "@CONTEXT_SCHEMA_VERSION@" /* define the version */ -#define TFAS_VERSION "${BFN_P4C_VERSION}" +#cmakedefine TFAS_VERSION "@BFN_P4C_VERSION@" #endif // __BFASM_CONFIG_H__ diff --git a/backends/tofino/bf-asm/crash.cpp b/backends/tofino/bf-asm/crash.cpp index dbc517d1b7c..c8cdc6e6457 100644 --- a/backends/tofino/bf-asm/crash.cpp +++ b/backends/tofino/bf-asm/crash.cpp @@ -15,8 +15,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include + +#include "backends/tofino/bf-asm/config.h" #if HAVE_EXECINFO_H #include #endif diff --git a/backends/tofino/bf-asm/deparser.cpp b/backends/tofino/bf-asm/deparser.cpp index ebd6c4684cd..bdc05c67305 100644 --- a/backends/tofino/bf-asm/deparser.cpp +++ b/backends/tofino/bf-asm/deparser.cpp @@ -17,8 +17,7 @@ #include "deparser.h" -#include - +#include "backends/tofino/bf-asm/config.h" #include "backends/tofino/bf-asm/target.h" #include "constants.h" #include "lib/range.h" diff --git a/backends/tofino/bf-asm/hash_dist.cpp b/backends/tofino/bf-asm/hash_dist.cpp index 6e900137124..f447841020f 100644 --- a/backends/tofino/bf-asm/hash_dist.cpp +++ b/backends/tofino/bf-asm/hash_dist.cpp @@ -17,8 +17,7 @@ #include "hash_dist.h" -#include - +#include "backends/tofino/bf-asm/config.h" #include "backends/tofino/bf-asm/stage.h" #include "lib/range.h" diff --git a/backends/tofino/bf-asm/input_xbar.cpp b/backends/tofino/bf-asm/input_xbar.cpp index d3ba86cc054..63263eb058c 100644 --- a/backends/tofino/bf-asm/input_xbar.cpp +++ b/backends/tofino/bf-asm/input_xbar.cpp @@ -17,11 +17,11 @@ #include "input_xbar.h" -#include #include #include +#include "backends/tofino/bf-asm/config.h" #include "backends/tofino/bf-asm/stage.h" #include "backends/tofino/bf-asm/tables.h" #include "hashexpr.h" diff --git a/backends/tofino/bf-asm/instruction.cpp b/backends/tofino/bf-asm/instruction.cpp index 1ad824d0d36..074c5576ae9 100644 --- a/backends/tofino/bf-asm/instruction.cpp +++ b/backends/tofino/bf-asm/instruction.cpp @@ -17,9 +17,8 @@ #include "instruction.h" -#include - #include "action_bus.h" +#include "backends/tofino/bf-asm/config.h" #include "backends/tofino/bf-asm/stage.h" #include "backends/tofino/bf-asm/tables.h" #include "depositfield.h" diff --git a/backends/tofino/bf-asm/instruction.h b/backends/tofino/bf-asm/instruction.h index 795012985c5..48d2eaa721b 100644 --- a/backends/tofino/bf-asm/instruction.h +++ b/backends/tofino/bf-asm/instruction.h @@ -18,10 +18,9 @@ #ifndef BACKENDS_TOFINO_BF_ASM_INSTRUCTION_H_ #define BACKENDS_TOFINO_BF_ASM_INSTRUCTION_H_ -#include - #include +#include "backends/tofino/bf-asm/config.h" #include "backends/tofino/bf-asm/tables.h" struct Instruction : public IHasDbPrint { diff --git a/backends/tofino/bf-asm/lex-yaml.l b/backends/tofino/bf-asm/lex-yaml.l index 4033978fc18..c28facd913e 100644 --- a/backends/tofino/bf-asm/lex-yaml.l +++ b/backends/tofino/bf-asm/lex-yaml.l @@ -131,7 +131,7 @@ int indent_depth(const char *pfx) { return rv; } -#include "gen/uptr_sizes.h" +#include "backends/tofino/bf-asm/gen/uptr_sizes.h" void bigint_mul(VECTOR(uintptr_t) &val, unsigned f) { unsigned carry = 0; diff --git a/backends/tofino/bf-asm/match_table.cpp b/backends/tofino/bf-asm/match_table.cpp index ca326088a5a..0df1315c732 100644 --- a/backends/tofino/bf-asm/match_table.cpp +++ b/backends/tofino/bf-asm/match_table.cpp @@ -15,11 +15,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - #include #include "action_bus.h" +#include "backends/tofino/bf-asm/config.h" #include "backends/tofino/bf-asm/stage.h" #include "backends/tofino/bf-asm/tables.h" #include "input_xbar.h" diff --git a/backends/tofino/bf-asm/parser-tofino-jbay.cpp b/backends/tofino/bf-asm/parser-tofino-jbay.cpp index 44e2837f22f..f6a522f9ebc 100644 --- a/backends/tofino/bf-asm/parser-tofino-jbay.cpp +++ b/backends/tofino/bf-asm/parser-tofino-jbay.cpp @@ -17,8 +17,7 @@ #include "parser-tofino-jbay.h" -#include - +#include "backends/tofino/bf-asm/config.h" #include "backends/tofino/bf-asm/stage.h" #include "backends/tofino/bf-asm/target.h" #include "constants.h" diff --git a/backends/tofino/bf-asm/salu_inst.cpp b/backends/tofino/bf-asm/salu_inst.cpp index b5a52f4b622..5cb71957343 100644 --- a/backends/tofino/bf-asm/salu_inst.cpp +++ b/backends/tofino/bf-asm/salu_inst.cpp @@ -15,12 +15,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include - #include #include +#include "backends/tofino/bf-asm/config.h" #include "backends/tofino/bf-asm/stage.h" #include "backends/tofino/bf-asm/tables.h" #include "instruction.h" diff --git a/backends/tofino/bf-asm/stage.cpp b/backends/tofino/bf-asm/stage.cpp index c69e7277b4b..2e80360f1b7 100644 --- a/backends/tofino/bf-asm/stage.cpp +++ b/backends/tofino/bf-asm/stage.cpp @@ -17,11 +17,11 @@ #include "backends/tofino/bf-asm/stage.h" -#include #include #include +#include "backends/tofino/bf-asm/config.h" #include "backends/tofino/bf-asm/target.h" #include "deparser.h" #include "input_xbar.h" diff --git a/backends/tofino/bf-asm/tables.cpp b/backends/tofino/bf-asm/tables.cpp index 48dc181e5a8..3ec9043c3de 100644 --- a/backends/tofino/bf-asm/tables.cpp +++ b/backends/tofino/bf-asm/tables.cpp @@ -17,12 +17,11 @@ #include "backends/tofino/bf-asm/tables.h" -#include - #include #include #include "action_bus.h" +#include "backends/tofino/bf-asm/config.h" #include "backends/tofino/bf-asm/stage.h" #include "input_xbar.h" #include "instruction.h" diff --git a/backends/tofino/bf-asm/tables.h b/backends/tofino/bf-asm/tables.h index a0f19873756..4042b750929 100644 --- a/backends/tofino/bf-asm/tables.h +++ b/backends/tofino/bf-asm/tables.h @@ -18,8 +18,6 @@ #ifndef BACKENDS_TOFINO_BF_ASM_TABLES_H_ // NOLINT(build/header_guard) #define BACKENDS_TOFINO_BF_ASM_TABLES_H_ -#include - #include #include #include @@ -28,6 +26,7 @@ #include "alloc.h" #include "asm-types.h" +#include "backends/tofino/bf-asm/config.h" #include "backends/tofino/bf-asm/json.h" #include "backends/tofino/bf-asm/target.h" #include "constants.h" diff --git a/backends/tofino/bf-asm/target.cpp b/backends/tofino/bf-asm/target.cpp index d5df8a93ecd..d85bb92c7fb 100644 --- a/backends/tofino/bf-asm/target.cpp +++ b/backends/tofino/bf-asm/target.cpp @@ -17,9 +17,8 @@ #include "backends/tofino/bf-asm/target.h" -#include - #include "asm-types.h" +#include "backends/tofino/bf-asm/config.h" #include "backends/tofino/bf-asm/tables.h" #include "bson.h" #include "parser.h" diff --git a/backends/tofino/bf-asm/target.h b/backends/tofino/bf-asm/target.h index 81530e5c158..f89d52f8297 100644 --- a/backends/tofino/bf-asm/target.h +++ b/backends/tofino/bf-asm/target.h @@ -18,9 +18,8 @@ #ifndef TARGET_H_ #define TARGET_H_ -#include - #include "asm-types.h" +#include "backends/tofino/bf-asm/config.h" #include "bfas.h" #include "map.h" From 2ef89e6421c3cd0c43facaab77a0a18fd30e7a21 Mon Sep 17 00:00:00 2001 From: fruffy Date: Fri, 7 Feb 2025 08:33:16 -0500 Subject: [PATCH 05/19] Do not throw errors when compiling. Properly depend on p4ctoolkit. Signed-off-by: fruffy --- backends/tofino/bf-asm/CMakeLists.txt | 17 ++++++++++++++- backends/tofino/bf-asm/jbay/CMakeLists.txt | 19 +++++------------ backends/tofino/bf-asm/tofino/CMakeLists.txt | 22 +++++--------------- 3 files changed, 26 insertions(+), 32 deletions(-) diff --git a/backends/tofino/bf-asm/CMakeLists.txt b/backends/tofino/bf-asm/CMakeLists.txt index fea436eda86..58c9a6ce0c2 100644 --- a/backends/tofino/bf-asm/CMakeLists.txt +++ b/backends/tofino/bf-asm/CMakeLists.txt @@ -110,21 +110,33 @@ set (MKSIZES_SOURCES mksizes.cpp) # json_diff add_executable (json_diff ${JSONDIFF_SOURCES}) +# Disable errors for warnings. FIXME: Get rid of this. +target_compile_options(json_diff PUBLIC "-Wno-error") # bfdumpbin add_executable (bfdumpbin ${BFDUMPBIN_SOURCES}) +# Disable errors for warnings. FIXME: Get rid of this. +target_compile_options(bfdumpbin PUBLIC "-Wno-error") # reflow add_executable (reflow ${REFLOW_SOURCES}) +# Disable errors for warnings. FIXME: Get rid of this. +target_compile_options(reflow PUBLIC "-Wno-error") # b2j add_executable (b2j ${B2J_SOURCES}) +# Disable errors for warnings. FIXME: Get rid of this. +target_compile_options(b2j PUBLIC "-Wno-error") # j2b add_executable (j2b ${J2B_SOURCES}) +# Disable errors for warnings. FIXME: Get rid of this. +target_compile_options(j2b PUBLIC "-Wno-error") # mksizes add_executable (mksizes ${MKSIZES_SOURCES}) +# Disable errors for warnings. FIXME: Get rid of this. +target_compile_options(mksizes PUBLIC "-Wno-error") set (BFAS_COMMON_SOURCES action_bus.cpp @@ -236,7 +248,10 @@ endif() # string(REPLACE "-Wno-overloaded-virtual" "" vector_c_flags ${BFASM_CXX_FLAGS}) # set_source_files_properties(vector.c PROPERTIES COMPILE_FLAGS ${vector_c_flags}) add_executable (bfas ${BFAS_SOURCES}) -target_compile_options(bfas PRIVATE -std=gnu++17) # Enable extensions for bfas. +# Enable extensions for bfas. FIXME: Do we need this? +target_compile_options(bfas PRIVATE -std=gnu++17) +# Disable errors for warnings. FIXME: Get rid of this. +target_compile_options(bfas PUBLIC "-Wno-error") target_link_libraries (bfas ${BFASM_LIBS} ${BFASM_LIB_DEPS}) add_dependencies(bfas bfasm_yaml) diff --git a/backends/tofino/bf-asm/jbay/CMakeLists.txt b/backends/tofino/bf-asm/jbay/CMakeLists.txt index 87f256cfba4..52fa8f73680 100644 --- a/backends/tofino/bf-asm/jbay/CMakeLists.txt +++ b/backends/tofino/bf-asm/jbay/CMakeLists.txt @@ -40,9 +40,7 @@ add_custom_command(OUTPUT ${GEN_JBAY_HDRS} ${GEN_JBAY_SRCS} DEPENDS template_objects.yaml chip.schema ${WALLE_SOURCES} COMMENT "Generating cpp code for jbay from jbay/chip.schema") -set_source_files_properties( - ${GEN_JBAY_SRCS} ${GEN_JBAY_HDRS} - PROPERTIES GENERATED TRUE) +set_source_files_properties(${GEN_JBAY_SRCS} ${GEN_JBAY_HDRS} PROPERTIES GENERATED TRUE) set (BFAS_JBAY_SRCS jbay/gateway.cpp @@ -52,14 +50,7 @@ set (BFAS_JBAY_SRCS PARENT_SCOPE ) -set (BFAS_JBAY_HEADERS - jbay/counter.h - jbay/gateway.h - jbay/input_xbar.h - jbay/meter.h - jbay/stateful.h - PARENT_SCOPE - ) - -include_directories (${BFASM_BINARY_DIR}/gen/jbay) -add_library (regs_jbay ${GEN_JBAY_SRCS} ${GEN_JBAY_HDRS}) +add_library (regs_jbay ${GEN_JBAY_SRCS}) +target_link_libraries (regs_jbay p4ctoolkit) +# Disable errors for warnings. FIXME: Get rid of this. +target_compile_options(regs_jbay PUBLIC "-Wno-error") diff --git a/backends/tofino/bf-asm/tofino/CMakeLists.txt b/backends/tofino/bf-asm/tofino/CMakeLists.txt index 4eb63e26fe3..f36c390ae40 100644 --- a/backends/tofino/bf-asm/tofino/CMakeLists.txt +++ b/backends/tofino/bf-asm/tofino/CMakeLists.txt @@ -34,9 +34,7 @@ foreach(f IN LISTS GEN_TOFINO) list (APPEND GEN_TOFINO_HDRS ${BFASM_BINARY_DIR}/gen/tofino/${f}.h) endforeach() -set_source_files_properties( - ${GEN_TOFINO_SRCS} ${GEN_TOFINO_HDRS} - PROPERTIES GENERATED TRUE) +set_source_files_properties(${GEN_TOFINO_SRCS} ${GEN_TOFINO_HDRS} PROPERTIES GENERATED TRUE) add_custom_command(OUTPUT ${GEN_TOFINO_HDRS} ${GEN_TOFINO_SRCS} COMMAND ${BFASM_WALLE} --schema chip.schema --generate-cpp template_objects.yaml -o ${BFASM_BINARY_DIR}/gen/tofino @@ -55,18 +53,8 @@ set (BFAS_TOFINO_SRCS PARENT_SCOPE ) -set (BFAS_TOFINO_HEADERS - tofino/action_table.h - tofino/counter.h - tofino/exact_match.h - tofino/gateway.h - tofino/input_xbar.h - tofino/meter.h - tofino/phv.h - tofino/stateful.h - tofino/ternary_match.h - PARENT_SCOPE - ) -include_directories (${BFASM_BINARY_DIR}/gen/tofino) -add_library (regs_tofino ${GEN_TOFINO_SRCS} ${GEN_TOFINO_HDRS}) +add_library (regs_tofino ${GEN_TOFINO_SRCS}) +target_link_libraries (regs_tofino p4ctoolkit) +# Disable errors for warnings. FIXME: Get rid of this. +target_compile_options(regs_tofino PUBLIC "-Wno-error") From c37441b91e4fe043ff22b386260a1f2ff073c57a Mon Sep 17 00:00:00 2001 From: fruffy Date: Sat, 8 Feb 2025 12:45:17 -0500 Subject: [PATCH 06/19] cpplint fixes. Signed-off-by: fruffy --- backends/tofino/bf-asm/CPPLINT.cfg | 25 --- backends/tofino/bf-asm/alloc.h | 6 +- backends/tofino/bf-asm/binary_output.h | 12 +- backends/tofino/bf-asm/bson.h | 10 +- backends/tofino/bf-asm/map.h | 4 +- backends/tofino/bf-asm/tables.h | 166 ++++++++++++------- backends/tofino/bf-asm/test/ptf/p4features.h | 5 + 7 files changed, 126 insertions(+), 102 deletions(-) delete mode 100644 backends/tofino/bf-asm/CPPLINT.cfg diff --git a/backends/tofino/bf-asm/CPPLINT.cfg b/backends/tofino/bf-asm/CPPLINT.cfg deleted file mode 100644 index 3a79f137f4d..00000000000 --- a/backends/tofino/bf-asm/CPPLINT.cfg +++ /dev/null @@ -1,25 +0,0 @@ -set noparent -filter=-build/include_subdir -filter=-build/c++11 -filter=-build/include_what_you_use -filter=-build/namespaces -filter=-legal/copyright -filter=-runtime/int -filter=-runtime/references -filter=-readability/todo -filter=-readability/function -filter=-readability/casting -linelength=100 -# include bf-asm in the cpp header guard prefix. -root=.. -filematch=*.ypp -# yacc productions&actions really confuse cpplint.py, so disable a bunch of things -filter=-readability/braces -filter=-whitespace/braces -filter=-whitespace/semicolon -filter=-readability/namespace - -filematch=*.l -filter=-whitespace/semicolon,-whitespace/braces,-whitespace/comma -filter=-whitespace/operators -filter=-readability/multiline_string, diff --git a/backends/tofino/bf-asm/alloc.h b/backends/tofino/bf-asm/alloc.h index 11683595f05..3b09161bbfc 100644 --- a/backends/tofino/bf-asm/alloc.h +++ b/backends/tofino/bf-asm/alloc.h @@ -1,5 +1,5 @@ -#ifndef EXTENSIONS_BF_P4C_COMMON_ALLOC_H_ -#define EXTENSIONS_BF_P4C_COMMON_ALLOC_H_ +#ifndef BACKENDS_TOFINO_BF_ASM_ALLOC_H_ +#define BACKENDS_TOFINO_BF_ASM_ALLOC_H_ #include @@ -226,4 +226,4 @@ class Alloc3D : public Alloc3Dbase { } // namespace BFN -#endif /* EXTENSIONS_BF_P4C_COMMON_ALLOC_H_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_ALLOC_H_ */ diff --git a/backends/tofino/bf-asm/binary_output.h b/backends/tofino/bf-asm/binary_output.h index ad137482315..23d56608a8d 100644 --- a/backends/tofino/bf-asm/binary_output.h +++ b/backends/tofino/bf-asm/binary_output.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef _binary_output_h_ -#define _binary_output_h_ +#ifndef BACKENDS_TOFINO_BF_ASM_BINARY_OUTPUT_H_ +#define BACKENDS_TOFINO_BF_ASM_BINARY_OUTPUT_H_ #include #include @@ -27,7 +27,7 @@ class tag { char data[4] = {0, 0, 0, 0}; public: - tag(char ch) { data[3] = ch; } + tag(char ch) { data[3] = ch; } // NOLINT(runtime/explicit) friend std::ostream &operator<<(std::ostream &out, const tag &e) { return out.write(e.data, 4); } @@ -37,7 +37,7 @@ class byte4 { char data[4]; public: - byte4(uint32_t v) { + byte4(uint32_t v) { // NOLINT(runtime/explicit) data[0] = v & 0xff; data[1] = (v >> 8) & 0xff; data[2] = (v >> 16) & 0xff; @@ -52,7 +52,7 @@ class byte8 { char data[8]; public: - byte8(uint64_t v) { + byte8(uint64_t v) { // NOLINT(runtime/explicit) data[0] = v & 0xff; data[1] = (v >> 8) & 0xff; data[2] = (v >> 16) & 0xff; @@ -69,4 +69,4 @@ class byte8 { } // end namespace binout -#endif /* _binary_output_h_ */ +#endif /* BACKENDS_TOFINO_BF_ASM_BINARY_OUTPUT_H_ */ diff --git a/backends/tofino/bf-asm/bson.h b/backends/tofino/bf-asm/bson.h index 84dd18111ad..d193123c322 100644 --- a/backends/tofino/bf-asm/bson.h +++ b/backends/tofino/bf-asm/bson.h @@ -15,8 +15,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef _bson_h_ -#define _bson_h_ +#ifndef BACKENDS_TOFINO_BF_ASM_BSON_H_ +#define BACKENDS_TOFINO_BF_ASM_BSON_H_ #include @@ -27,9 +27,9 @@ namespace json { template struct bson_wrap { T &o; - bson_wrap(T &o) : o(o) {} + bson_wrap(T &o) : o(o) {} // NOLINT(runtime/explicit) template - bson_wrap(U &o) : o(o) {} + bson_wrap(U &o) : o(o) {} // NOLINT(runtime/explicit) }; template @@ -71,4 +71,4 @@ inline std::ostream &operator<<(std::ostream &out, bson_wrap - IterKeys(U &map) : b(map.begin()), e(map.end()) {} + IterKeys(U &map) : b(map.begin()), e(map.end()) {} // NOLINT(runtime/explicit) IterKeys(PairIter b, PairIter e) : b(b), e(e) {} iterator begin() const { return b; } iterator end() const { return e; } @@ -181,7 +181,7 @@ struct IterValues { } b, e; template - IterValues(U &map) : b(map.begin()), e(map.end()) {} + IterValues(U &map) : b(map.begin()), e(map.end()) {} // NOLINT(runtime/explicit) IterValues(PairIter b, PairIter e) : b(b), e(e) {} iterator begin() const { return b; } iterator end() const { return e; } diff --git a/backends/tofino/bf-asm/tables.h b/backends/tofino/bf-asm/tables.h index 4042b750929..1ba0d5b0b32 100644 --- a/backends/tofino/bf-asm/tables.h +++ b/backends/tofino/bf-asm/tables.h @@ -15,7 +15,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef BACKENDS_TOFINO_BF_ASM_TABLES_H_ // NOLINT(build/header_guard) +#ifndef BACKENDS_TOFINO_BF_ASM_TABLES_H_ #define BACKENDS_TOFINO_BF_ASM_TABLES_H_ #include @@ -24,10 +24,14 @@ #include #include -#include "alloc.h" -#include "asm-types.h" +#include "backends/tofino/bf-asm/alloc.h" +#include "backends/tofino/bf-asm/asm-types.h" #include "backends/tofino/bf-asm/config.h" #include "backends/tofino/bf-asm/json.h" +#include "backends/tofino/bf-asm/map.h" +#include "backends/tofino/bf-asm/p4_table.h" +#include "backends/tofino/bf-asm/phv.h" +#include "backends/tofino/bf-asm/slist.h" #include "backends/tofino/bf-asm/target.h" #include "constants.h" #include "hash_dist.h" @@ -36,10 +40,6 @@ #include "lib/bitops.h" #include "lib/bitvec.h" #include "lib/ordered_map.h" -#include "map.h" -#include "p4_table.h" -#include "phv.h" -#include "slist.h" class ActionBus; struct ActionBusSource; @@ -1158,9 +1158,13 @@ DECLARE_ABSTRACT_TABLE_TYPE( return attached.find_address_field(tbl); } Format::Field *lookup_field(const std::string &n, const std::string &act = "") const override; - bool run_at_eop() override { return attached.run_at_eop(); } virtual bool is_ternary() { - return false; - } void gen_idletime_tbl_cfg(json::map &stage_tbl) const; + bool run_at_eop() override { return attached.run_at_eop(); } + // FIXME: This comment is necessary to stop cpplint from complaining. The format is off because + // this code is within a macro. + virtual bool is_ternary() { return false; } + // FIXME: This comment is necessary to stop cpplint from complaining. The format is off because + // this code is within a macro. + void gen_idletime_tbl_cfg(json::map &stage_tbl) const; int direct_shiftcount() const override { return 64; } void gen_hash_bits(const std::map &hash_table, InputXbar::HashTable ht_id, @@ -1225,6 +1229,8 @@ DECLARE_ABSTRACT_TABLE_TYPE( { write_regs_vt(regs); }) DECLARE_ABSTRACT_TABLE_TYPE(SRamMatchTable, MatchTable, // exact, atcam, or proxy_hash + + // NOLINTNEXTLINE (whitespace/indent) public: struct Ram : public MemUnit { using MemUnit::MemUnit; @@ -1251,6 +1257,7 @@ DECLARE_ABSTRACT_TABLE_TYPE(SRamMatchTable, MatchTable, // exact, atcam, } }; + // NOLINTNEXTLINE (whitespace/indent) protected: std::vector ways; struct WayRam { int way, index, word, bank; }; @@ -1320,6 +1327,8 @@ DECLARE_ABSTRACT_TABLE_TYPE(SRamMatchTable, MatchTable, // exact, atcam, virtual void gen_ghost_bits(int hash_function_number, json::vector &ghost_bits_to_hash_bits, json::vector &ghost_bits_info) const { } virtual void no_overhead_determine_result_bus_usage(); + + // NOLINTNEXTLINE (whitespace/indent) public: Format::Field *lookup_field(const std::string &n, const std::string &act = "") const override; OVERLOAD_FUNC_FOREACH(TARGET_CLASS, virtual void, setup_word_ixbar_group, (), ()) @@ -1372,6 +1381,7 @@ DECLARE_TABLE_TYPE( std::vector stash_rows; std::vector stash_cols; std::vector stash_units; std::vector stash_overhead_rows; + // NOLINTNEXTLINE (whitespace/indent) public : int unitram_type() override { return UnitRam::MATCH; } table_type_t table_type() const override { return EXACT; } bool has_group(int grp) { @@ -1442,6 +1452,8 @@ DECLARE_TABLE_TYPE( void add_proxy_hash_function(json::map &stage_tbl) const;) DECLARE_TABLE_TYPE(TernaryMatchTable, MatchTable, "ternary_match", + + // NOLINTNEXTLINE (whitespace/indent) protected: void vpn_params(int &width, int &depth, int &period, const char *&period_name) const override; struct Match { @@ -1463,6 +1475,8 @@ DECLARE_TABLE_TYPE(TernaryMatchTable, MatchTable, "ternary_match", friend class TernaryIndirectTable; virtual void check_tcam_match_bus(const std::vector &) = 0; + + // NOLINTNEXTLINE (whitespace/indent) public: void pass0() override; int tcam_id = -1; @@ -1576,6 +1590,7 @@ DECLARE_TABLE_TYPE(TernaryMatchTable, MatchTable, "ternary_match", if (CHECKTYPE(v, tSTR)) indirect = v; } + // NOLINTNEXTLINE (whitespace/indent) private: template void tcam_table_map(REGS ®s, int row, int col); ) @@ -1603,6 +1618,8 @@ DECLARE_TABLE_TYPE( Layout::bus_type_t default_bus_type() const override { return Layout::RESULT_BUS; }) DECLARE_TABLE_TYPE(TernaryIndirectTable, Table, "ternary_indirect", + + // NOLINTNEXTLINE (whitespace/indent) protected: TernaryMatchTable *match_table = nullptr; AttachedTables attached; @@ -1636,6 +1653,8 @@ DECLARE_TABLE_TYPE(TernaryIndirectTable, Table, "ternary_indirect", void write_merge_regs, (mau_regs ®s, int type, int bus), override { write_merge_regs_vt(regs, type, bus); }) int unitram_type() override { return UnitRam::TERNARY_INDIRECTION; } + + // NOLINTNEXTLINE (whitespace/indent) public: Format::Field *lookup_field(const std::string &n, const std::string &act = "") const override; @@ -1682,8 +1701,14 @@ DECLARE_ABSTRACT_TABLE_TYPE( Call & action_call() override { return match_tables.size() == 1 ? (*match_tables.begin())->action_call() : action; - } int json_memunit(const MemUnit &u) const override; - void pass1() override; virtual unsigned get_alu_index() const { + } + // FIXME: This comment is necessary to stop cpplint from complaining. The format is off because + // this code is within a macro. + int json_memunit(const MemUnit &u) const override; + void pass1() override; + // FIXME: This comment is necessary to stop cpplint from complaining. The format is off because + // this code is within a macro. + virtual unsigned get_alu_index() const { if (layout.size() > 0) return layout[0].row / 4U; error(lineno, "Cannot determine ALU Index for table %s", name()); return 0; @@ -1694,50 +1719,69 @@ DECLARE_ABSTRACT_TABLE_TYPE( METER_ACCESS_TYPE default_type, unsigned &adr_mask, unsigned &per_entry_mux_ctl, unsigned &adr_default, unsigned &meter_type_position); + + // NOLINTNEXTLINE (whitespace/indent) protected : // Accessed by Meter/Selection/Stateful Tables as "meter_alu_index" // Accessed by Statistics (Counter) Tables as "stats_alu_index" void add_alu_index(json::map &stage_tbl, std::string alu_index) const; + + // NOLINTNEXTLINE (whitespace/indent) public - : const MatchTable *get_match_table() - const override { return match_tables.size() == 1 ? *match_tables.begin() : 0; } MatchTable - *get_match_table() override { - return match_tables.size() == 1 ? *match_tables.begin() : 0; - } std::set - get_match_tables() override { return match_tables; } bool has_per_flow_enable() - const { return per_flow_enable; } std::string get_per_flow_enable_param() { - return per_flow_enable_param; - } Format::Field *get_per_flow_enable_param(MatchTable *m) const override { - return per_flow_enable ? m->lookup_field(per_flow_enable_param) : nullptr; - } Format::Field *get_meter_address_param(MatchTable *m) const override { - std::string pfe_name = - per_flow_enable_param.substr(0, per_flow_enable_param.find("_pfe")); - return per_flow_enable ? m->lookup_field(pfe_name + "_addr") : nullptr; - } Format::Field *get_meter_type_param(MatchTable *m) const override { - std::string pfe_name = - per_flow_enable_param.substr(0, per_flow_enable_param.find("_pfe")); - return per_flow_enable ? m->lookup_field(pfe_name + "_type") : nullptr; - } bool get_per_flow_enable() { return per_flow_enable; } bool is_direct() - const { return direct; } virtual int default_pfe_adjust() - const { return 0; } std::string get_default_action() override { - if (!default_action.empty()) return default_action; - for (auto m : match_tables) { - std::string def_action = m->get_default_action(); - if (!def_action.empty()) return def_action; - } - return ""; - } default_action_params *get_default_action_parameters() override { - if (!default_action_parameters.empty()) - return &default_action_parameters; - for (auto m : match_tables) { - if (auto def_action_params = m->get_default_action_parameters()) - if (!def_action_params->empty()) return def_action_params; - } - return nullptr; - } bool validate_call(Table::Call &call, MatchTable *self, - size_t required_args, int hash_dist_type, - Table::Call &first_call) override; + : + // FIXME: This comment is necessary to stop cpplint from complaining. The format is off because + // this code is within a macro. + const MatchTable *get_match_table() + const override { return match_tables.size() == 1 ? *match_tables.begin() : 0; } + // FIXME: This comment is necessary to stop cpplint from complaining. The format is off because + // this code is within a macro. + MatchTable *get_match_table() + override { return match_tables.size() == 1 ? *match_tables.begin() : 0; } + // FIXME: This comment is necessary to stop cpplint from complaining. The format is off because + // this code is within a macro. + std::set + get_match_tables() override { return match_tables; } bool has_per_flow_enable() + const { return per_flow_enable; } std::string get_per_flow_enable_param() { + return per_flow_enable_param; + } Format::Field *get_per_flow_enable_param(MatchTable *m) const override { + return per_flow_enable ? m->lookup_field(per_flow_enable_param) : nullptr; + } Format::Field *get_meter_address_param(MatchTable *m) const override { + std::string pfe_name = + per_flow_enable_param.substr(0, per_flow_enable_param.find("_pfe")); + return per_flow_enable ? m->lookup_field(pfe_name + "_addr") : nullptr; + } Format::Field *get_meter_type_param(MatchTable *m) const override { + std::string pfe_name = + per_flow_enable_param.substr(0, per_flow_enable_param.find("_pfe")); + return per_flow_enable ? m->lookup_field(pfe_name + "_type") : nullptr; + } + // FIXME: This comment is necessary to stop cpplint from complaining. The format is off because + // this code is within a macro. + bool get_per_flow_enable() { return per_flow_enable; } bool is_direct() const { return direct; } + // FIXME: This comment is necessary to stop cpplint from complaining. The format is off because + // this code is within a macro. + virtual int default_pfe_adjust() const { return 0; } + // FIXME: This comment is necessary to stop cpplint from complaining. The format is off because + // this code is within a macro. + std::string get_default_action() override { + if (!default_action.empty()) return default_action; + for (auto m : match_tables) { + std::string def_action = m->get_default_action(); + if (!def_action.empty()) return def_action; + } + return ""; + } + // FIXME: This comment is necessary to stop cpplint from complaining. The format is off because + // this code is within a macro. + default_action_params *get_default_action_parameters() override { + if (!default_action_parameters.empty()) return &default_action_parameters; + for (auto m : match_tables) { + if (auto def_action_params = m->get_default_action_parameters()) + if (!def_action_params->empty()) return def_action_params; + } + return nullptr; + } bool validate_call(Table::Call &call, MatchTable *self, size_t required_args, + int hash_dist_type, Table::Call &first_call) override; // used by Selection and Stateful tables. FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, int meter_alu_fifo_enable_from_mask, (mau_regs &, unsigned bytemask))) @@ -1784,6 +1828,8 @@ DECLARE_TABLE_TYPE( const override { return true; } bool needs_next() const override { return true; }) DECLARE_TABLE_TYPE(GatewayTable, Table, "gateway", + + // NOLINTNEXTLINE (whitespace/indent) protected: MatchTable *match_table = 0; uint64_t payload = -1; @@ -1797,6 +1843,8 @@ DECLARE_TABLE_TYPE(GatewayTable, Table, "gateway", std::string gateway_name; std::string gateway_cond; bool always_run = false; // only for standalone + + // NOLINTNEXTLINE (whitespace/indent) public: struct MatchKey { int offset; @@ -1812,6 +1860,8 @@ DECLARE_TABLE_TYPE(GatewayTable, Table, "gateway", offset(off), val(gr, stg, v), valid(vld) {} bool operator<(const MatchKey &a) const { return offset < a.offset; } }; + + // NOLINTNEXTLINE (whitespace/indent) protected: std::vector match, xor_match; struct Match { @@ -1836,6 +1886,8 @@ DECLARE_TABLE_TYPE(GatewayTable, Table, "gateway", if (m.offset < 32) return true; return !xor_match.empty(); } + + // NOLINTNEXTLINE (whitespace/indent) public: table_type_t table_type() const override { return GATEWAY; } virtual int find_next_lut_entry(Table *tbl, const Match &match); @@ -2006,10 +2058,8 @@ DECLARE_TABLE_TYPE( void setup_teop_regs(REGS ®s, int stats_group_index); template void write_alu_vpn_range(REGS ®s); -#if HAVE_JBAY template void setup_teop_regs_2(REGS ®s, int stats_group_index); template void write_alu_vpn_range_2(REGS ®s); -#endif /* HAVE_JBAY || */ struct lrt_params { // largest recent with threshold paramters int lineno; @@ -2049,10 +2099,8 @@ DECLARE_TABLE_TYPE( template void write_regs_home_row(REGS ®s, unsigned row); template void write_mapram_color_regs(REGS ®s, bool &push_on_overflow); -#if HAVE_JBAY template void setup_teop_regs_2(REGS ®s, int stats_group_index); template void write_alu_vpn_range_2(REGS ®s); -#endif /* HAVE_JBAY || */ int sweep_interval = 2; public : enum {NO_COLOR_MAP, IDLE_MAP_ADDR, STATS_MAP_ADDR} color_mapram_addr = NO_COLOR_MAP; @@ -2094,9 +2142,7 @@ Instruction *genNoop(StatefulTable *tbl, Table::Actions::Action *act); DECLARE_TABLE_TYPE(StatefulTable, Synth2Port, "stateful", table_type_t table_type() const override { return STATEFUL; } -#if HAVE_JBAY bool setup_jbay(const pair_t &kv); -#endif /* HAVE_JBAY */ template void write_action_regs_vt(REGS ®s, const Actions::Action *); FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_action_regs, (mau_regs ®s, const Actions::Action *act), override; ) @@ -2106,9 +2152,7 @@ DECLARE_TABLE_TYPE(StatefulTable, Synth2Port, "stateful", FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_merge_regs, (mau_regs ®s, MatchTable *match, int type, int bus, const std::vector &args), override; ) -#if HAVE_JBAY template void write_tofino2_common_regs(REGS ®s); -#endif /* HAVE_JBAY */ struct const_info_t { int lineno; int64_t value; @@ -2152,6 +2196,8 @@ DECLARE_TABLE_TYPE(StatefulTable, Synth2Port, "stateful", int pred_shift = 0, pred_comb_shift = 0; int stage_alu_id = -1; Ref underflow_action, overflow_action; + + // NOLINTNEXTLINE (whitespace/indent) public: Ref bound_selector; unsigned phv_byte_mask = 0; @@ -2185,11 +2231,9 @@ DECLARE_TABLE_TYPE(StatefulTable, Synth2Port, "stateful", OVERLOAD_FUNC_FOREACH(REGISTER_SET, void, set_counter_mode, (int mode), (mode)) OVERLOAD_FUNC_FOREACH(REGISTER_SET, void, gen_tbl_cfg, (json::map &tbl, json::map &stage_tbl) const, (tbl, stage_tbl)) -#if HAVE_JBAY BFN::Alloc1D tmatch_use; -#endif /* HAVE_JBAY */ bool p4c_5192_workaround(const Actions::Action *) const; ) -#endif /* BACKENDS_TOFINO_BF_ASM_TABLES_H_ */ // NOLINT(build/header_guard) +#endif /* BACKENDS_TOFINO_BF_ASM_TABLES_H_ */ diff --git a/backends/tofino/bf-asm/test/ptf/p4features.h b/backends/tofino/bf-asm/test/ptf/p4features.h index cf4ff426b95..5bdfeeaff80 100644 --- a/backends/tofino/bf-asm/test/ptf/p4features.h +++ b/backends/tofino/bf-asm/test/ptf/p4features.h @@ -1,3 +1,6 @@ +#ifndef BACKENDS_TOFINO_BF_ASM_TEST_PTF_P4FEATURES_H_ +#define BACKENDS_TOFINO_BF_ASM_TEST_PTF_P4FEATURES_H_ + #define MATCH_ATCAM #define MATCH_COUNT 50000 #define STATS_INDIRECT @@ -6,3 +9,5 @@ #define STATEFUL_COUNT 40000 #define ACTION_DIRECT #define ACTION_COUNT 50000 + +#endif /* BACKENDS_TOFINO_BF_ASM_TEST_PTF_P4FEATURES_H_ */ From eb5ce19b6928e10a585a920866a07f64ab114891 Mon Sep 17 00:00:00 2001 From: fruffy Date: Sat, 8 Feb 2025 12:45:58 -0500 Subject: [PATCH 07/19] Do not fail if spdlog already is instantiated but the build folder is missing. Signed-off-by: fruffy --- backends/tofino/cmake/spdlog.cmake | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/backends/tofino/cmake/spdlog.cmake b/backends/tofino/cmake/spdlog.cmake index c4d8fdce85e..361da20dd29 100644 --- a/backends/tofino/cmake/spdlog.cmake +++ b/backends/tofino/cmake/spdlog.cmake @@ -1,21 +1,33 @@ message(STATUS "Fetching spdlog") -include(FetchContent) - # Preserve previous FETCHCONTENT_QUIET setting set(FETCHCONTENT_QUIET_PREV ${FETCHCONTENT_QUIET}) set(FETCHCONTENT_QUIET OFF) +set(SPDLOG_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/spdlog) + +# Check if the source directory exists. +if(EXISTS ${SPDLOG_SOURCE_DIR}/CMakeLists.txt) + # If it exists but wasn't built before, manually add it. + set(FETCHCONTENT_SOURCE_DIR_SPDLOG ${SPDLOG_SOURCE_DIR}) + # Avoid fetching again. + set(FETCHCONTENT_UPDATES_DISCONNECTED_SPDLOG ON) +endif() + FetchContent_Declare( spdlog GIT_REPOSITORY https://github.com/gabime/spdlog.git GIT_TAG v1.8.3 - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/spdlog + SOURCE_DIR ${SPDLOG_SOURCE_DIR} USES_TERMINAL_DOWNLOAD TRUE GIT_PROGRESS TRUE ) -FetchContent_MakeAvailable(spdlog) +FetchContent_GetProperties(spdlog) +if(NOT spdlog_POPULATED) + FetchContent_Populate(spdlog) + add_subdirectory(${SPDLOG_SOURCE_DIR} ${CMAKE_BINARY_DIR}/spdlog) +endif() # Restore FETCHCONTENT_QUIET setting set(FETCHCONTENT_QUIET ${FETCHCONTENT_QUIET_PREV}) From 67f20c331a77e60d7c61f7e4b9d085b4ee7f33db Mon Sep 17 00:00:00 2001 From: fruffy Date: Sat, 8 Feb 2025 13:58:01 -0500 Subject: [PATCH 08/19] Remove HAVE_JBAY guards. Signed-off-by: fruffy --- backends/tofino/CMakeLists.txt | 3 --- backends/tofino/bf-asm/CMakeLists.txt | 5 +---- backends/tofino/bf-asm/bfas.cpp | 4 ---- backends/tofino/bf-asm/cmake/config.h.cmake | 6 ------ backends/tofino/bf-asm/counter.cpp | 2 -- backends/tofino/bf-asm/deparser.cpp | 2 -- backends/tofino/bf-asm/input_xbar.cpp | 2 -- backends/tofino/bf-asm/instruction.cpp | 8 -------- backends/tofino/bf-asm/jbay/gateway.h | 2 -- backends/tofino/bf-asm/jbay/input_xbar.h | 2 -- backends/tofino/bf-asm/jbay/stateful.h | 3 --- backends/tofino/bf-asm/match_table.cpp | 2 -- backends/tofino/bf-asm/meter.cpp | 4 ---- backends/tofino/bf-asm/parser-tofino-jbay.cpp | 2 -- backends/tofino/bf-asm/phv.cpp | 2 -- backends/tofino/bf-asm/phv.h | 2 -- backends/tofino/bf-asm/salu_inst.cpp | 17 +---------------- backends/tofino/bf-asm/selection.cpp | 4 ---- backends/tofino/bf-asm/stateful.cpp | 2 -- backends/tofino/bf-asm/target.cpp | 2 -- backends/tofino/bf-asm/target.h | 17 +---------------- backends/tofino/bf-asm/tofino/salu_inst.cpp | 2 -- backends/tofino/bf-p4c/CMakeLists.txt | 3 --- backends/tofino/bf-p4c/arch/psa/psa.cpp | 2 -- backends/tofino/bf-p4c/arch/v1model.cpp | 4 ---- backends/tofino/bf-p4c/mau/action_analysis.cpp | 2 -- backends/tofino/bf-p4c/mau/asm_output.cpp | 2 -- backends/tofino/bf-p4c/mau/gateway.cpp | 2 -- backends/tofino/bf-p4c/mau/stateful_alu.cpp | 4 ---- backends/tofino/bf-p4c/mau/tofino/memories.cpp | 3 --- backends/tofino/bf-p4c/mau/walk_power_graph.cpp | 2 -- backends/tofino/bf-p4c/midend.cpp | 2 -- .../bf-p4c/midend/parser_enforce_depth_req.cpp | 2 -- 33 files changed, 3 insertions(+), 120 deletions(-) diff --git a/backends/tofino/CMakeLists.txt b/backends/tofino/CMakeLists.txt index 16612a6d97e..64d52bf83f1 100644 --- a/backends/tofino/CMakeLists.txt +++ b/backends/tofino/CMakeLists.txt @@ -23,9 +23,6 @@ if (CMAKE_BUILD_TYPE STREQUAL Release OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInf add_definitions("-DRELEASE_BUILD=1") endif() -# JBay is always enabled, the preprocessor guard is deprecated -add_definitions("-DHAVE_JBAY=1") - list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") if (ENABLE_STATIC_LIBS) diff --git a/backends/tofino/bf-asm/CMakeLists.txt b/backends/tofino/bf-asm/CMakeLists.txt index 58c9a6ce0c2..88819ec5cdb 100644 --- a/backends/tofino/bf-asm/CMakeLists.txt +++ b/backends/tofino/bf-asm/CMakeLists.txt @@ -217,11 +217,8 @@ set (WALLE_SOURCES ${BFASM_SOURCE_DIR}/walle/walle.py) add_subdirectory (tofino) -set (HAVE_TOFINO 1) -set (BFASM_LIBS regs_tofino) add_subdirectory (jbay) -set (HAVE_JBAY 1) -set (BFASM_LIBS ${BFASM_LIBS} regs_jbay) +set (BFASM_LIBS ${BFASM_LIBS} regs_jbay regs_tofino) # Other configuration files that need to be generated configure_file ("${BFASM_SOURCE_DIR}/cmake/config.h.cmake" "${BFASM_BINARY_DIR}/config.h") diff --git a/backends/tofino/bf-asm/bfas.cpp b/backends/tofino/bf-asm/bfas.cpp index 980f271015f..94bd4476ed6 100644 --- a/backends/tofino/bf-asm/bfas.cpp +++ b/backends/tofino/bf-asm/bfas.cpp @@ -53,11 +53,7 @@ option_t options = { .match_compiler = false, .multi_parsers = true, // TODO Remove option after testing .partial_input = false, -#if HAVE_JBAY .singlewrite = true, -#else - .singlewrite = false, -#endif /* !HAVE_JBAY && ! */ .stage_dependency_pattern = "", .target = NO_TARGET, .tof2lab44_workaround = false, diff --git a/backends/tofino/bf-asm/cmake/config.h.cmake b/backends/tofino/bf-asm/cmake/config.h.cmake index 0114e1b81b7..3e8ae79d73f 100644 --- a/backends/tofino/bf-asm/cmake/config.h.cmake +++ b/backends/tofino/bf-asm/cmake/config.h.cmake @@ -7,12 +7,6 @@ /* Define to 1 if you have the ucontext.h header */ #cmakedefine HAVE_UCONTEXT_H @HAVE_UCONTEXT_H@ -/* Define to 1 if we include JBay */ -#cmakedefine HAVE_JBAY @HAVE_JBAY@ - -/* Define to 1 if we include Tofino */ -#cmakedefine HAVE_TOFINO @HAVE_TOFINO@ - /* Schema version */ #cmakedefine CONTEXT_SCHEMA_VERSION "@CONTEXT_SCHEMA_VERSION@" diff --git a/backends/tofino/bf-asm/counter.cpp b/backends/tofino/bf-asm/counter.cpp index c643532ea21..d2edb0e76b4 100644 --- a/backends/tofino/bf-asm/counter.cpp +++ b/backends/tofino/bf-asm/counter.cpp @@ -24,9 +24,7 @@ // target specific template specializations #include "tofino/counter.h" -#if HAVE_JBAY #include "jbay/counter.h" -#endif /* HAVE_JBAY */ void CounterTable::setup(VECTOR(pair_t) & data) { common_init_setup(data, false, P4Table::Statistics); diff --git a/backends/tofino/bf-asm/deparser.cpp b/backends/tofino/bf-asm/deparser.cpp index bdc05c67305..ec14da82774 100644 --- a/backends/tofino/bf-asm/deparser.cpp +++ b/backends/tofino/bf-asm/deparser.cpp @@ -600,9 +600,7 @@ void Deparser::report_resources_deparser_json(json::vector &fde_entries_i, } #include "tofino/deparser.cpp" // NOLINT(build/include) -#if HAVE_JBAY #include "jbay/deparser.cpp" // NOLINT(build/include) -#endif /* HAVE_JBAY */ std::vector Deparser::merge_csum_entries( const std::vector &entries, int id) { diff --git a/backends/tofino/bf-asm/input_xbar.cpp b/backends/tofino/bf-asm/input_xbar.cpp index 63263eb058c..4e84c5be8af 100644 --- a/backends/tofino/bf-asm/input_xbar.cpp +++ b/backends/tofino/bf-asm/input_xbar.cpp @@ -952,9 +952,7 @@ void InputXbar::write_regs(REGS ®s) { } template void InputXbar::write_regs(Target::Tofino::mau_regs &); -#if HAVE_JBAY template void InputXbar::write_regs(Target::JBay::mau_regs &); -#endif /* HAVE_JBAY */ template void InputXbar::write_xmu_regs(REGS ®s) { diff --git a/backends/tofino/bf-asm/instruction.cpp b/backends/tofino/bf-asm/instruction.cpp index 074c5576ae9..b37e2ca9a28 100644 --- a/backends/tofino/bf-asm/instruction.cpp +++ b/backends/tofino/bf-asm/instruction.cpp @@ -681,18 +681,14 @@ auto Operand::Named::lookup(Base *&ref) -> Base * { struct VLIWInstruction : Instruction { explicit VLIWInstruction(int l) : Instruction(l) {} virtual int encode() = 0; -#if HAVE_JBAY template void write_regs_2(REGS ®s, Table *tbl, Table::Actions::Action *act); -#endif /* HAVE_JBAY || */ FOR_ALL_REGISTER_SETS(DECLARE_FORWARD_VIRTUAL_INSTRUCTION_WRITE_REGS) }; // target specific template specializations #include "tofino/instruction.cpp" // NOLINT(build/include) -#if HAVE_JBAY #include "jbay/instruction.cpp" // NOLINT(build/include) -#endif /* HAVE_JBAY */ struct AluOP : VLIWInstruction { enum special_flags { @@ -1652,9 +1648,7 @@ bool ShiftOP::equiv(Instruction *a_) { static std::set tofino12 = std::set({ TOFINO, -#if HAVE_JBAY JBAY, -#endif }); // lifted from MAU uArch 15.1.6 @@ -1707,7 +1701,6 @@ static CondMoveMux::Decode tf_opCondMux("cmux", TOFINO, 0x6, false, 2, "conditional-mux"); // NOLINT static NulOP::Decode tf_opInvalidate("invalidate", TOFINO, 0x3800); // NOLINT -#if HAVE_JBAY static std::set jb_targets = std::set({ JBAY, }); @@ -1727,7 +1720,6 @@ static AluOP::Decode jb_opGTEQU("gtequ", jb_targets, 0x02e), // NOLINT jb_opNEQ("neq", jb_targets, 0x2ae, AluOP::Commutative), // NOLINT jb_opEQ64("eq64", jb_targets, 0x26e, AluOP::Commutative), // NOLINT jb_opNEQ64("neq64", jb_targets, 0x2ee, AluOP::Commutative); // NOLINT -#endif /* HAVE_JBAY || */ std::unique_ptr genNoopFill(Table *tbl, Table::Actions::Action *act, const char *op, int slot) { diff --git a/backends/tofino/bf-asm/jbay/gateway.h b/backends/tofino/bf-asm/jbay/gateway.h index 81cd538e75c..3700f07f9dd 100644 --- a/backends/tofino/bf-asm/jbay/gateway.h +++ b/backends/tofino/bf-asm/jbay/gateway.h @@ -21,9 +21,7 @@ #include "backends/tofino/bf-asm/tables.h" #include "backends/tofino/bf-asm/tofino/gateway.h" -#if HAVE_JBAY template <> void GatewayTable::standalone_write_regs(Target::JBay::mau_regs ®s); -#endif /* HAVE_JBAY */ #endif /* BACKENDS_TOFINO_BF_ASM_JBAY_GATEWAY_H_ */ diff --git a/backends/tofino/bf-asm/jbay/input_xbar.h b/backends/tofino/bf-asm/jbay/input_xbar.h index 766b714ef13..45b11f3c581 100644 --- a/backends/tofino/bf-asm/jbay/input_xbar.h +++ b/backends/tofino/bf-asm/jbay/input_xbar.h @@ -20,10 +20,8 @@ #include "backends/tofino/bf-asm/input_xbar.h" -#if HAVE_JBAY template <> void InputXbar::write_galois_matrix(Target::JBay::mau_regs ®s, HashTable id, const std::map &mat); -#endif /* HAVE_JBAY */ #endif /* BACKENDS_TOFINO_BF_ASM_JBAY_INPUT_XBAR_H_ */ diff --git a/backends/tofino/bf-asm/jbay/stateful.h b/backends/tofino/bf-asm/jbay/stateful.h index 57e67544515..91d9a8cb8a4 100644 --- a/backends/tofino/bf-asm/jbay/stateful.h +++ b/backends/tofino/bf-asm/jbay/stateful.h @@ -21,8 +21,6 @@ #include "backends/tofino/bf-asm/tables.h" #include "backends/tofino/bf-asm/target.h" -#if HAVE_JBAY - // FIXME -- should be a namespace somwhere? Or in class StatefulTable /* for jbay counter mode, we may need both a push and a pop mode, as well as counter_function, * so we pack them all into an int with some shifts and masks */ @@ -56,5 +54,4 @@ int parse_jbay_counter_mode(const value_t &v); template <> void StatefulTable::write_logging_regs(Target::JBay::mau_regs ®s); -#endif /* HAVE_JBAY || || */ #endif /* BACKENDS_TOFINO_BF_ASM_JBAY_STATEFUL_H_ */ diff --git a/backends/tofino/bf-asm/match_table.cpp b/backends/tofino/bf-asm/match_table.cpp index 0df1315c732..34a62974468 100644 --- a/backends/tofino/bf-asm/match_table.cpp +++ b/backends/tofino/bf-asm/match_table.cpp @@ -287,9 +287,7 @@ void MatchTable::gen_idletime_tbl_cfg(json::map &stage_tbl) const { } #include "tofino/match_table.cpp" // NOLINT(build/include) -#if HAVE_JBAY #include "jbay/match_table.cpp" // NOLINT(build/include) -#endif /* HAVE_JBAY */ template void MatchTable::write_common_regs(typename TARGET::mau_regs ®s, int type, Table *result) { diff --git a/backends/tofino/bf-asm/meter.cpp b/backends/tofino/bf-asm/meter.cpp index 23ee71b1ea2..f4123b2eb1b 100644 --- a/backends/tofino/bf-asm/meter.cpp +++ b/backends/tofino/bf-asm/meter.cpp @@ -23,9 +23,7 @@ // target specific template specializations #include "tofino/meter.h" -#if HAVE_JBAY #include "jbay/meter.h" -#endif /* HAVE_JBAY */ Table::Layout::bus_type_t MeterTable::default_bus_type() const { // FIXME -- this is a bit of a hack -- if color_mapram_addr has been set, we want the @@ -946,7 +944,6 @@ void MeterTable::meter_color_logical_to_phys(Target::Tofino::mau_regs ®s, int } } -#if HAVE_JBAY template <> void MeterTable::meter_color_logical_to_phys(Target::JBay::mau_regs ®s, int logical_id, int alu) { @@ -977,7 +974,6 @@ void MeterTable::meter_color_logical_to_phys(Target::JBay::mau_regs ®s, int l } adrdist.meter_color_logical_to_phys_icxbar_ctl[logical_id] |= 1 << alu; } -#endif /* HAVE_JBAY */ void MeterTable::gen_tbl_cfg(json::vector &out) const { // FIXME -- factor common Synth2Port stuff diff --git a/backends/tofino/bf-asm/parser-tofino-jbay.cpp b/backends/tofino/bf-asm/parser-tofino-jbay.cpp index f6a522f9ebc..2e26435059c 100644 --- a/backends/tofino/bf-asm/parser-tofino-jbay.cpp +++ b/backends/tofino/bf-asm/parser-tofino-jbay.cpp @@ -603,10 +603,8 @@ std::map Parser::parser_handles; void Parser::write_config(RegisterSetBase ®s, json::map &json, bool legacy) { if (auto *tofino_regs = dynamic_cast(®s)) write_config(*tofino_regs, json, legacy); -#ifdef HAVE_JBAY else if (auto *jbay_regs = dynamic_cast(®s)) write_config(*jbay_regs, json, legacy); -#endif /* HAVE_JBAY */ } // output context.json format with multiple parser support diff --git a/backends/tofino/bf-asm/phv.cpp b/backends/tofino/bf-asm/phv.cpp index 065b3fb6f01..cc4b10e8617 100644 --- a/backends/tofino/bf-asm/phv.cpp +++ b/backends/tofino/bf-asm/phv.cpp @@ -493,6 +493,4 @@ void Phv::output(json::map &ctxt_json) { } #include "tofino/phv.cpp" // NOLINT(build/include) -#if HAVE_JBAY #include "jbay/phv.cpp" // NOLINT(build/include) -#endif /* HAVE_JBAY */ diff --git a/backends/tofino/bf-asm/phv.h b/backends/tofino/bf-asm/phv.h index 41694f513b3..e88f6e2017d 100644 --- a/backends/tofino/bf-asm/phv.h +++ b/backends/tofino/bf-asm/phv.h @@ -322,8 +322,6 @@ class Target::Phv { inline unsigned Phv::mau_groupsize() { return phv.target->mau_groupsize(); } #include "tofino/phv.h" -#if HAVE_JBAY #include "jbay/phv.h" -#endif /* HAVE_JBAY */ #endif /* BACKENDS_TOFINO_BF_ASM_PHV_H_ */ diff --git a/backends/tofino/bf-asm/salu_inst.cpp b/backends/tofino/bf-asm/salu_inst.cpp index 5cb71957343..965b34564e4 100644 --- a/backends/tofino/bf-asm/salu_inst.cpp +++ b/backends/tofino/bf-asm/salu_inst.cpp @@ -779,8 +779,6 @@ Instruction *CmpOP::pass1(Table *tbl_, Table::Actions::Action *act) { return this; } -#if HAVE_JBAY - struct TMatchOP : public SaluInstruction { const struct Decode : public Instruction::Decode { std::string name; @@ -817,9 +815,7 @@ struct TMatchOP : public SaluInstruction { }; static TMatchOP::Decode opTMatch("tmatch", { -#if HAVE_JBAY JBAY, -#endif }); Instruction *TMatchOP::Decode::decode(Table *tbl, const Table::Actions::Action *act, @@ -901,7 +897,6 @@ Instruction *TMatchOP::pass1(Table *tbl_, Table::Actions::Action *act) { } return this; } -#endif /* HAVE_JBAY || */ // Output ALU instruction struct OutOP : public SaluInstruction { @@ -913,10 +908,8 @@ struct OutOP : public SaluInstruction { int predication_encode = STATEFUL_PREDICATION_ENCODE_UNCOND; operand src; int output_mux = -1; -#if HAVE_JBAY bool lmatch = false; int lmatch_pred = 0; -#endif /* HAVE_JBAY */ FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void decode_output_mux, (register_type, Table *tbl, value_t &op)) void decode_output_mux(Table *tbl, value_t &op) { @@ -937,9 +930,7 @@ struct OutOP : public SaluInstruction { } void dbprint(std::ostream &out) const override { out << "INSTR: output " << "pred=0x" << hex(predication_encode) -#if HAVE_JBAY << " word" << (slot - ALUOUT0) -#endif /* HAVE_JBAY */ << " mux=" << output_mux; } template @@ -976,7 +967,6 @@ Instruction *OutOP::Decode::decode(Table *tbl, const Table::Actions::Action *act } } rv->slot = ALUOUT; -#if HAVE_JBAY // Check for destination if (idx < op.size && op[idx].startsWith("word")) { int unit = -1; @@ -995,7 +985,6 @@ Instruction *OutOP::Decode::decode(Table *tbl, const Table::Actions::Action *act rv->slot = unit + ALUOUT0; idx++; } -#endif /* HAVE_JBAY */ // Check mux operand if (idx < op.size) { rv->src = operand(tbl, act, op[idx], false); @@ -1029,7 +1018,6 @@ Instruction *OutOP::pass1(Table *tbl_, Table::Actions::Action *act) { error(lineno, "Only one output of predication allowed"); act->pred_comb_sel = predication_encode; } -#if HAVE_JBAY if (lmatch) { if (tbl->output_lmatch) { auto *other = dynamic_cast(tbl->output_lmatch); @@ -1041,14 +1029,11 @@ Instruction *OutOP::pass1(Table *tbl_, Table::Actions::Action *act) { } tbl->output_lmatch = this; } -#endif /* HAVE_JBAY */ return this; } +#include "jbay/salu_inst.cpp" // NOLINT(build/include) #include "tofino/salu_inst.cpp" // NOLINT(build/include) -#if HAVE_JBAY -#include "jbay/salu_inst.cpp" // NOLINT(build/include) -#endif /* HAVE_JBAY */ } // end namespace StatefulAlu diff --git a/backends/tofino/bf-asm/selection.cpp b/backends/tofino/bf-asm/selection.cpp index 4db49dd9415..e4fafd0441a 100644 --- a/backends/tofino/bf-asm/selection.cpp +++ b/backends/tofino/bf-asm/selection.cpp @@ -272,14 +272,12 @@ void SelectionTable::setup_physical_alu_map(Target::Tofino::mau_regs ®s, int merge.mau_physical_to_meter_alu_ixbar_map[type][bus / 8U].set_subfield(4 | alu, 3 * (bus % 8U), 3); } -#if HAVE_JBAY template <> void SelectionTable::setup_physical_alu_map(Target::JBay::mau_regs ®s, int type, int bus, int alu) { auto &merge = regs.rams.match.merge; merge.mau_physical_to_meter_alu_icxbar_map[type][bus / 8U] |= (1U << alu) << (4 * (bus % 8U)); } -#endif /* HAVE_JBAY */ template void SelectionTable::write_regs_vt(REGS ®s) { @@ -401,7 +399,6 @@ void SelectionTable::setup_logical_alu_map(Target::Tofino::mau_regs ®s, int l merge.mau_meter_alu_to_logical_map[logical_id / 8U].set_subfield(4 | alu, 3 * (logical_id % 8U), 3); } -#if HAVE_JBAY template <> void SelectionTable::setup_logical_alu_map(Target::JBay::mau_regs ®s, int logical_id, int alu) { auto &merge = regs.rams.match.merge; @@ -409,7 +406,6 @@ void SelectionTable::setup_logical_alu_map(Target::JBay::mau_regs ®s, int log merge.mau_meter_alu_to_logical_map[logical_id / 8U].set_subfield(4 | alu, 3 * (logical_id % 8U), 3); } -#endif /* HAVE_JBAY */ std::vector SelectionTable::determine_spare_bank_memory_units() const { if (bound_stateful) return bound_stateful->determine_spare_bank_memory_units(); diff --git a/backends/tofino/bf-asm/stateful.cpp b/backends/tofino/bf-asm/stateful.cpp index d36b74191e2..44e2236dd26 100644 --- a/backends/tofino/bf-asm/stateful.cpp +++ b/backends/tofino/bf-asm/stateful.cpp @@ -112,11 +112,9 @@ void StatefulTable::setup(VECTOR(pair_t) & data) { error(v.key.lineno, "Unknow item %s in math_table", value_desc(kv.key)); } } -#if HAVE_JBAY } else if (options.target >= JBAY && setup_jbay(kv)) { /* jbay specific extensions done in setup_jbay */ // FIXME -- these should probably be based on individual Target::FEATURE() queries -#endif /* HAVE_JBAY */ } else if (kv.key == "log_vpn") { logvpn_lineno = kv.value.lineno; if (CHECKTYPE2(kv.value, tINT, tRANGE)) { diff --git a/backends/tofino/bf-asm/target.cpp b/backends/tofino/bf-asm/target.cpp index d85bb92c7fb..daea10fd1ad 100644 --- a/backends/tofino/bf-asm/target.cpp +++ b/backends/tofino/bf-asm/target.cpp @@ -147,7 +147,6 @@ void emit_parser_registers(const Target::Tofino::top_level_regs *regs, std::ostr } } -#if HAVE_JBAY void declare_registers(const Target::JBay::top_level_regs *regs) { declare_registers(®s->mem_top, sizeof(regs->mem_top), [=](std::ostream &out, const char *addr, const void *end) { @@ -276,7 +275,6 @@ void emit_parser_registers(const Target::JBay::top_level_regs *regs, std::ostrea eg.second->emit_binary(out, 0); } } -#endif /* HAVE_JBAY */ int Target::numMauStagesOverride = 0; diff --git a/backends/tofino/bf-asm/target.h b/backends/tofino/bf-asm/target.h index f89d52f8297..9bf99443829 100644 --- a/backends/tofino/bf-asm/target.h +++ b/backends/tofino/bf-asm/target.h @@ -31,7 +31,6 @@ struct MemUnit; * FOR_ALL_TARGET_CLASSES -- metamacro that expands for each distinct target class * a subset of the register sets */ -#if HAVE_JBAY #define FOR_ALL_TARGETS(M, ...) \ M(Tofino, ##__VA_ARGS__) \ M(JBay, ##__VA_ARGS__) \ @@ -43,17 +42,12 @@ struct MemUnit; M(Tofino, ##__VA_ARGS__) \ M(JBay, ##__VA_ARGS__) #define FOR_ALL_TARGET_CLASSES(M, ...) M(Tofino, ##__VA_ARGS__) -#else -#define FOR_ALL_TARGETS(M, ...) M(Tofino, ##__VA_ARGS__) -#define FOR_ALL_REGISTER_SETS(M, ...) M(Tofino, ##__VA_ARGS__) -#define FOR_ALL_TARGET_CLASSES(M, ...) M(Tofino, ##__VA_ARGS__) -#endif /* ! && !HAVE_CLOUBREAK && !HAVE_JBAY */ + // alias FOR_ALL -> FOR_EACH so the the group name does need to be plural #define FOR_EACH_TARGET FOR_ALL_TARGETS #define FOR_EACH_REGISTER_SET FOR_ALL_REGISTER_SETS #define FOR_EACH_TARGET_CLASS FOR_ALL_TARGET_CLASSES -#if HAVE_JBAY #define TARGETS_IN_CLASS_Tofino(M, ...) \ M(Tofino, ##__VA_ARGS__) \ M(JBay, ##__VA_ARGS__) \ @@ -64,19 +58,13 @@ struct MemUnit; #define REGSETS_IN_CLASS_Tofino(M, ...) \ M(Tofino, ##__VA_ARGS__) \ M(JBay, ##__VA_ARGS__) -#else -#define TARGETS_IN_CLASS_Tofino(M, ...) M(Tofino, ##__VA_ARGS__) -#define REGSETS_IN_CLASS_Tofino(M, ...) M(Tofino, ##__VA_ARGS__) -#endif -#if HAVE_JBAY #define TARGETS_USING_REGS_JBay(M, ...) \ M(JBay, ##__VA_ARGS__) \ M(Tofino2H, ##__VA_ARGS__) \ M(Tofino2M, ##__VA_ARGS__) \ M(Tofino2U, ##__VA_ARGS__) \ M(Tofino2A0, ##__VA_ARGS__) -#endif #define TARGETS_USING_REGS_Tofino(M, ...) M(Tofino, ##__VA_ARGS__) #define TARGETS_IN_CLASS(CL, ...) TARGETS_IN_CLASS_##CL(__VA_ARGS__) @@ -421,7 +409,6 @@ void declare_registers(const Target::Tofino::deparser_regs *regs); void undeclare_registers(const Target::Tofino::deparser_regs *regs); void emit_parser_registers(const Target::Tofino::top_level_regs *regs, std::ostream &); -#if HAVE_JBAY #include "backends/tofino/bf-asm/gen/jbay/memories.jbay_mem.h" #include "backends/tofino/bf-asm/gen/jbay/memories.pipe_addrmap.h" #include "backends/tofino/bf-asm/gen/jbay/memories.prsr_mem_main_rspec.h" @@ -654,8 +641,6 @@ class Target::Tofino2A0 : public Target::JBay { void emit_parser_registers(const Target::JBay::top_level_regs *regs, std::ostream &); -#endif /* HAVE_JBAY */ - /** Macro to buid a switch table switching on a target_t, expanding to the same * code for each target, with TARGET being a typedef for the target type */ #define SWITCH_FOREACH_TARGET(VAR, ...) \ diff --git a/backends/tofino/bf-asm/tofino/salu_inst.cpp b/backends/tofino/bf-asm/tofino/salu_inst.cpp index 208e12ae028..31205779b3a 100644 --- a/backends/tofino/bf-asm/tofino/salu_inst.cpp +++ b/backends/tofino/bf-asm/tofino/salu_inst.cpp @@ -148,11 +148,9 @@ void CmpOP::write_regs(Target::Tofino::mau_regs ®s, Table *tbl, Table::Action write_regs(regs, tbl, act); } -#if HAVE_JBAY void TMatchOP::write_regs(Target::Tofino::mau_regs ®s, Table *tbl, Table::Actions::Action *act) { BUG(); // should never be called } -#endif /* HAVE_JBAY */ void OutOP::decode_output_mux(Target::Tofino, Table *tbl, value_t &op) { static const std::map ops_mux_lookup = { diff --git a/backends/tofino/bf-p4c/CMakeLists.txt b/backends/tofino/bf-p4c/CMakeLists.txt index 0a5410a6d3e..412b5f3818b 100644 --- a/backends/tofino/bf-p4c/CMakeLists.txt +++ b/backends/tofino/bf-p4c/CMakeLists.txt @@ -558,9 +558,6 @@ target_compile_definitions(bfp4c INTERFACE "-DCONFIG_PREFIX=\"${CMAKE_INSTALL_PREFIX}\"" INTERFACE "-DCONFIG_PKGDATADIR=\"${CMAKE_INSTALL_PREFIX}/${P4C_ARTIFACTS_OUTPUT_DIRECTORY}\"" ) -target_compile_definitions(bfp4c - INTERFACE "-DHAVE_JBAY=1" -) if (ENABLE_BAREFOOT_INTERNAL) target_compile_definitions(bfp4c INTERFACE "-DBAREFOOT_INTERNAL=1" diff --git a/backends/tofino/bf-p4c/arch/psa/psa.cpp b/backends/tofino/bf-p4c/arch/psa/psa.cpp index dd430a6a501..3bea131ba4e 100644 --- a/backends/tofino/bf-p4c/arch/psa/psa.cpp +++ b/backends/tofino/bf-p4c/arch/psa/psa.cpp @@ -901,12 +901,10 @@ class LoadTargetArchitecture : public Inspector { filenames.push_back("tofino1_specs.p4"); filenames.push_back("tofino1_base.p4"); } -#if HAVE_JBAY else { filenames.push_back("tofino2_specs.p4"); filenames.push_back("tofino2_base.p4"); } -#endif // HAVE_JBAY filenames.push_back("tofino/stratum.p4"); filenames.push_back("tofino/p4_14_prim.p4"); diff --git a/backends/tofino/bf-p4c/arch/v1model.cpp b/backends/tofino/bf-p4c/arch/v1model.cpp index b02b32930f4..81e30554104 100644 --- a/backends/tofino/bf-p4c/arch/v1model.cpp +++ b/backends/tofino/bf-p4c/arch/v1model.cpp @@ -170,7 +170,6 @@ class LoadTargetArchitecture : public Inspector { structure->addMetadata(EGRESS, MetadataField{"standard_metadata"_cs, "egress_rid"_cs, 16}, MetadataField{"eg_intr_md"_cs, "egress_rid"_cs, 16}); -#ifdef HAVE_JBAY structure->addMetadata(INGRESS, MetadataField{"ig_intr_md_for_mb"_cs, "mirror_io_select"_cs, 1}, MetadataField{"ig_intr_md_for_dprsr"_cs, "mirror_io_select"_cs, 1}); @@ -225,7 +224,6 @@ class LoadTargetArchitecture : public Inspector { structure->addMetadata( EGRESS, MetadataField{"eg_intr_md_for_mb"_cs, "mirror_coalesce_length"_cs, 8}, MetadataField{"eg_intr_md_for_dprsr"_cs, "mirror_coalesce_length"_cs, 8}); -#endif } void analyzeTofinoModel() { @@ -314,12 +312,10 @@ class LoadTargetArchitecture : public Inspector { filenames.push_back("tofino1_specs.p4"); filenames.push_back("tofino1_base.p4"); } -#if HAVE_JBAY else if (Device::currentDevice() == Device::JBAY) { filenames.push_back("tofino2_specs.p4"); filenames.push_back("tofino2_base.p4"); } -#endif // HAVE_JBAY else BUG("Unsupported device id %s", Device::currentDevice()); filenames.push_back("tofino/stratum.p4"); diff --git a/backends/tofino/bf-p4c/mau/action_analysis.cpp b/backends/tofino/bf-p4c/mau/action_analysis.cpp index 3ec4dc731b3..3697c4846b9 100644 --- a/backends/tofino/bf-p4c/mau/action_analysis.cpp +++ b/backends/tofino/bf-p4c/mau/action_analysis.cpp @@ -2417,9 +2417,7 @@ void ActionAnalysis::check_constant_to_actiondata(ContainerAction &cont_action, // 16 and 20, the range for instruction constants is different between architectures. // For Tofino it is -8..7 but for JBay it is -4..7 int const_src_min = CONST_SRC_MAX; -#ifdef HAVE_JBAY if (Device::currentDevice() == Device::JBAY) const_src_min = JBAY_CONST_SRC_MIN; -#endif /* HAVE_JBAY */ if (cont_action.convert_instr_to_bitmasked_set || cont_action.convert_instr_to_byte_rotate_merge) { diff --git a/backends/tofino/bf-p4c/mau/asm_output.cpp b/backends/tofino/bf-p4c/mau/asm_output.cpp index 5e19bef1cdd..040a9f3ad40 100644 --- a/backends/tofino/bf-p4c/mau/asm_output.cpp +++ b/backends/tofino/bf-p4c/mau/asm_output.cpp @@ -1053,9 +1053,7 @@ void MauAsmOutput::emit_table_format(std::ostream &out, indent_t indent, fmt_state fmt; out << indent << "format: {"; int group = (ternary || gateway) ? -1 : 0; -#ifdef HAVE_JBAY if (Device::currentDevice() == Device::JBAY && gateway) group = 0; -#endif for (auto match_group : use.match_groups) { int type; diff --git a/backends/tofino/bf-p4c/mau/gateway.cpp b/backends/tofino/bf-p4c/mau/gateway.cpp index 727e570d8cb..559cba36b27 100644 --- a/backends/tofino/bf-p4c/mau/gateway.cpp +++ b/backends/tofino/bf-p4c/mau/gateway.cpp @@ -43,7 +43,6 @@ const Device::GatewaySpec &TofinoDevice::getGatewaySpec() const { }; return spec; } -#if HAVE_JBAY const Device::GatewaySpec &JBayDevice::getGatewaySpec() const { static const Device::GatewaySpec spec = { /* .PhvBytes = */ 4, @@ -59,7 +58,6 @@ const Device::GatewaySpec &JBayDevice::getGatewaySpec() const { }; return spec; } -#endif class CanonGatewayExpr::NeedNegate : public Inspector { bool rv = false; diff --git a/backends/tofino/bf-p4c/mau/stateful_alu.cpp b/backends/tofino/bf-p4c/mau/stateful_alu.cpp index bb419a004e6..e2a6ae97804 100644 --- a/backends/tofino/bf-p4c/mau/stateful_alu.cpp +++ b/backends/tofino/bf-p4c/mau/stateful_alu.cpp @@ -46,7 +46,6 @@ const Device::StatefulAluSpec &TofinoDevice::getStatefulAluSpec() const { return spec; } -#if HAVE_JBAY const Device::StatefulAluSpec &JBayDevice::getStatefulAluSpec() const { static const Device::StatefulAluSpec spec = { /* .CmpMask = */ true, @@ -64,7 +63,6 @@ const Device::StatefulAluSpec &JBayDevice::getStatefulAluSpec() const { /* .MaxRegfileRows = */ 4}; return spec; } -#endif /** * @brief This class detects a following pattern: @@ -2283,13 +2281,11 @@ std::map, std::vectorleft_to_place(); diff --git a/backends/tofino/bf-p4c/mau/walk_power_graph.cpp b/backends/tofino/bf-p4c/mau/walk_power_graph.cpp index 7a727149c5d..5a495c12dfe 100644 --- a/backends/tofino/bf-p4c/mau/walk_power_graph.cpp +++ b/backends/tofino/bf-p4c/mau/walk_power_graph.cpp @@ -444,10 +444,8 @@ double WalkPowerGraph::estimate_power() { always_powered_on_.clear(); if (Device::currentDevice() == Device::TOFINO) { return estimate_power_tofino(); -#if HAVE_JBAY } else if (Device::currentDevice() == Device::JBAY) { return estimate_power_non_tofino(); -#endif /* HAVE_JBAY */ } else { BUG("estimate_power -- invalid device %d", Device::currentDevice()); } diff --git a/backends/tofino/bf-p4c/midend.cpp b/backends/tofino/bf-p4c/midend.cpp index 85467f960be..56552c9a28a 100644 --- a/backends/tofino/bf-p4c/midend.cpp +++ b/backends/tofino/bf-p4c/midend.cpp @@ -328,14 +328,12 @@ bool skipFlexibleHeader(const Visitor::Context *, const IR::Type_StructLike *e) */ class CompileTimeOperations : public P4::CompileTimeOperations { bool preorder(const IR::Declaration_Instance *di) { -#ifdef HAVE_JBAY // JBay supports (limited) div/mod in RegisterAction if (Device::currentDevice() == Device::JBAY) { if (auto st = di->type->to()) { if (st->baseType->path->name.name.endsWith("Action")) return false; } } -#endif return true; } }; diff --git a/backends/tofino/bf-p4c/midend/parser_enforce_depth_req.cpp b/backends/tofino/bf-p4c/midend/parser_enforce_depth_req.cpp index 5e9a7922c27..203bd3edd66 100644 --- a/backends/tofino/bf-p4c/midend/parser_enforce_depth_req.cpp +++ b/backends/tofino/bf-p4c/midend/parser_enforce_depth_req.cpp @@ -507,9 +507,7 @@ class AddParserPad : public Modifier { // Tofino1-like architectures std::set tofArch = { "tna"_cs, -#if HAVE_JBAY "t2na"_cs, -#endif /* HAVE_JBAY */ }; /** From 181c7d47cd2a071d85a2ca09417c34597c26830e Mon Sep 17 00:00:00 2001 From: fruffy Date: Sat, 8 Feb 2025 15:23:51 -0500 Subject: [PATCH 09/19] Tweaks. Signed-off-by: fruffy --- backends/tofino/bf-asm/CMakeLists.txt | 6 +++--- backends/tofino/bf-asm/alloc.h | 1 + backends/tofino/bf-asm/crash.cpp | 12 ++++++------ backends/tofino/bf-asm/gtest/register-matcher.h | 2 +- backends/tofino/bf-asm/instruction.cpp | 2 +- backends/tofino/bf-asm/json.h | 2 +- backends/tofino/bf-p4c/arch/psa/psa.cpp | 3 +-- backends/tofino/bf-p4c/arch/v1model.cpp | 6 ++---- backends/tofino/bf-p4c/driver/barefoot.py | 2 +- 9 files changed, 17 insertions(+), 19 deletions(-) diff --git a/backends/tofino/bf-asm/CMakeLists.txt b/backends/tofino/bf-asm/CMakeLists.txt index 88819ec5cdb..a881d6a48bd 100644 --- a/backends/tofino/bf-asm/CMakeLists.txt +++ b/backends/tofino/bf-asm/CMakeLists.txt @@ -240,10 +240,10 @@ if (ENABLE_GTESTS) endif() -# set_source_files_properties(${BFAS_SOURCES} PROPERTIES COMPILE_FLAGS ${BFASM_CXX_FLAGS}) +set_source_files_properties(${BFAS_SOURCES} PROPERTIES COMPILE_FLAGS ${BFASM_CXX_FLAGS}) # Remove compiler flag that is C++ only for vector.c -# string(REPLACE "-Wno-overloaded-virtual" "" vector_c_flags ${BFASM_CXX_FLAGS}) -# set_source_files_properties(vector.c PROPERTIES COMPILE_FLAGS ${vector_c_flags}) +string(REPLACE "-Wno-overloaded-virtual" "" vector_c_flags ${BFASM_CXX_FLAGS}) +set_source_files_properties(vector.c PROPERTIES COMPILE_FLAGS ${vector_c_flags}) add_executable (bfas ${BFAS_SOURCES}) # Enable extensions for bfas. FIXME: Do we need this? target_compile_options(bfas PRIVATE -std=gnu++17) diff --git a/backends/tofino/bf-asm/alloc.h b/backends/tofino/bf-asm/alloc.h index 3b09161bbfc..f2577bc30c6 100644 --- a/backends/tofino/bf-asm/alloc.h +++ b/backends/tofino/bf-asm/alloc.h @@ -5,6 +5,7 @@ #include #include +#include namespace BFN { diff --git a/backends/tofino/bf-asm/crash.cpp b/backends/tofino/bf-asm/crash.cpp index c8cdc6e6457..a092bce2696 100644 --- a/backends/tofino/bf-asm/crash.cpp +++ b/backends/tofino/bf-asm/crash.cpp @@ -103,15 +103,15 @@ const char *addr2line(void *addr, const char *text) { int pfd1[2], pfd2[2]; char *p = buffer; const char *argv[4] = {"/bin/sh", "-c", buffer, 0}; - strcpy(p, "addr2line "); - p += strlen(p); // NOLINT - strcpy(p, " -Cfspe "); - p += strlen(p); // NOLINT + strcpy(p, "addr2line "); // NOLINT + p += strlen(p); + strcpy(p, " -Cfspe "); // NOLINT + p += strlen(p); t = text + strlen(text); if (!memchr(text, '/', t - text)) { - strcpy(p, "$(which "); + strcpy(p, "$(which "); // NOLINT p += strlen(p); - } // NOLINT + } memcpy(p, text, t - text); p += t - text; if (!memchr(text, '/', t - text)) *p++ = ')'; diff --git a/backends/tofino/bf-asm/gtest/register-matcher.h b/backends/tofino/bf-asm/gtest/register-matcher.h index 1e138882b3f..c6f63c89769 100644 --- a/backends/tofino/bf-asm/gtest/register-matcher.h +++ b/backends/tofino/bf-asm/gtest/register-matcher.h @@ -24,7 +24,7 @@ #include "bf-asm/ubits.h" #include "gtest/gtest.h" -#include "p4c/lib/bitvec.h" +#include "lib/bitvec.h" namespace BfAsm { diff --git a/backends/tofino/bf-asm/instruction.cpp b/backends/tofino/bf-asm/instruction.cpp index b37e2ca9a28..d470b19a283 100644 --- a/backends/tofino/bf-asm/instruction.cpp +++ b/backends/tofino/bf-asm/instruction.cpp @@ -687,8 +687,8 @@ struct VLIWInstruction : Instruction { }; // target specific template specializations +#include "jbay/instruction.cpp" // NOLINT(build/include) #include "tofino/instruction.cpp" // NOLINT(build/include) -#include "jbay/instruction.cpp" // NOLINT(build/include) struct AluOP : VLIWInstruction { enum special_flags { diff --git a/backends/tofino/bf-asm/json.h b/backends/tofino/bf-asm/json.h index 3d8a926682d..4bd76105f47 100644 --- a/backends/tofino/bf-asm/json.h +++ b/backends/tofino/bf-asm/json.h @@ -29,8 +29,8 @@ #include #include +#include "backends/tofino/bf-asm/rvalue_reference_wrapper.h" #include "lib/ordered_map.h" -#include "rvalue_reference_wrapper.h" using namespace P4; diff --git a/backends/tofino/bf-p4c/arch/psa/psa.cpp b/backends/tofino/bf-p4c/arch/psa/psa.cpp index 3bea131ba4e..c93f63e561c 100644 --- a/backends/tofino/bf-p4c/arch/psa/psa.cpp +++ b/backends/tofino/bf-p4c/arch/psa/psa.cpp @@ -900,8 +900,7 @@ class LoadTargetArchitecture : public Inspector { if (Device::currentDevice() == Device::TOFINO) { filenames.push_back("tofino1_specs.p4"); filenames.push_back("tofino1_base.p4"); - } - else { + } else { filenames.push_back("tofino2_specs.p4"); filenames.push_back("tofino2_base.p4"); } diff --git a/backends/tofino/bf-p4c/arch/v1model.cpp b/backends/tofino/bf-p4c/arch/v1model.cpp index 81e30554104..9811778738b 100644 --- a/backends/tofino/bf-p4c/arch/v1model.cpp +++ b/backends/tofino/bf-p4c/arch/v1model.cpp @@ -311,12 +311,10 @@ class LoadTargetArchitecture : public Inspector { if (Device::currentDevice() == Device::TOFINO) { filenames.push_back("tofino1_specs.p4"); filenames.push_back("tofino1_base.p4"); - } - else if (Device::currentDevice() == Device::JBAY) { + } else if (Device::currentDevice() == Device::JBAY) { filenames.push_back("tofino2_specs.p4"); filenames.push_back("tofino2_base.p4"); - } - else + } else BUG("Unsupported device id %s", Device::currentDevice()); filenames.push_back("tofino/stratum.p4"); filenames.push_back("tofino/p4_14_prim.p4"); diff --git a/backends/tofino/bf-p4c/driver/barefoot.py b/backends/tofino/bf-p4c/driver/barefoot.py index b94b403f1dc..a0af756b1f1 100755 --- a/backends/tofino/bf-p4c/driver/barefoot.py +++ b/backends/tofino/bf-p4c/driver/barefoot.py @@ -483,7 +483,7 @@ def process_command_line_options(self, opts): """ # Add assembler options. if os.environ['P4C_BUILD_TYPE'] == "DEVELOPER": - bfas = find_file('bf-asm', 'bfas') + bfas = find_file('.', 'bfas') else: bfas = find_file(os.environ['P4C_BIN_DIR'], 'bfas') From 675a8a1b77920622f03c2456461c641496172b32 Mon Sep 17 00:00:00 2001 From: fruffy Date: Sat, 8 Feb 2025 16:06:20 -0500 Subject: [PATCH 10/19] Gtest. Signed-off-by: fruffy --- backends/tofino/bf-asm/CMakeLists.txt | 2 +- backends/tofino/bf-asm/gtest/asm-types.cpp | 4 ++-- backends/tofino/bf-asm/gtest/depositfield.cpp | 4 ++-- backends/tofino/bf-asm/gtest/gateway.cpp | 4 ++-- backends/tofino/bf-asm/gtest/gtestasm.cpp | 3 ++- backends/tofino/bf-asm/gtest/hashexpr.cpp | 7 ++++--- backends/tofino/bf-asm/gtest/mirror.cpp | 7 ++++--- backends/tofino/bf-asm/gtest/parser-test.cpp | 7 ++++--- backends/tofino/bf-asm/gtest/register-matcher.cpp | 2 +- backends/tofino/bf-asm/gtest/register-matcher.h | 5 +++-- 10 files changed, 25 insertions(+), 20 deletions(-) diff --git a/backends/tofino/bf-asm/CMakeLists.txt b/backends/tofino/bf-asm/CMakeLists.txt index a881d6a48bd..66c4c9a0a55 100644 --- a/backends/tofino/bf-asm/CMakeLists.txt +++ b/backends/tofino/bf-asm/CMakeLists.txt @@ -316,7 +316,7 @@ if (ENABLE_GTESTS) set_source_files_properties (${BFAS_GTEST_SOURCES} PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE) add_executable (gtestasm ${BFAS_GTEST_SOURCES} ${BFP4C_SOURCES}) - target_link_libraries (gtestasm PRIVATE bfas_lib gtest) + target_link_libraries (gtestasm PRIVATE bfas_lib gtest ${BFASM_LIB_DEPS}) target_compile_options (gtestasm PRIVATE -Wall -Wextra -ggdb -O3 -Wno-unused-parameter -Wno-sign-compare) diff --git a/backends/tofino/bf-asm/gtest/asm-types.cpp b/backends/tofino/bf-asm/gtest/asm-types.cpp index d723334de09..f03908e26bd 100644 --- a/backends/tofino/bf-asm/gtest/asm-types.cpp +++ b/backends/tofino/bf-asm/gtest/asm-types.cpp @@ -15,9 +15,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "asm-types.h" +#include "backends/tofino/bf-asm/asm-types.h" -#include "gtest/gtest.h" +#include namespace { diff --git a/backends/tofino/bf-asm/gtest/depositfield.cpp b/backends/tofino/bf-asm/gtest/depositfield.cpp index e60e1f0a8ab..b307b445f46 100644 --- a/backends/tofino/bf-asm/gtest/depositfield.cpp +++ b/backends/tofino/bf-asm/gtest/depositfield.cpp @@ -15,9 +15,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "depositfield.h" +#include "backends/tofino/bf-asm/depositfield.h" -#include "gtest/gtest.h" +#include #if __cplusplus < 201402L && __cpp_binary_literals < 201304 #error "Binary literals are required" diff --git a/backends/tofino/bf-asm/gtest/gateway.cpp b/backends/tofino/bf-asm/gtest/gateway.cpp index 31ed73fc773..91effb09e90 100644 --- a/backends/tofino/bf-asm/gtest/gateway.cpp +++ b/backends/tofino/bf-asm/gtest/gateway.cpp @@ -16,8 +16,8 @@ */ #include "backends/tofino/bf-asm/stage.h" -#include "bfas.h" -#include "gtest/gtest.h" +#include "backends/tofino/bf-asm/bfas.h" +#include namespace { diff --git a/backends/tofino/bf-asm/gtest/gtestasm.cpp b/backends/tofino/bf-asm/gtest/gtestasm.cpp index 68a6eb753cd..85950ee1b9b 100644 --- a/backends/tofino/bf-asm/gtest/gtestasm.cpp +++ b/backends/tofino/bf-asm/gtest/gtestasm.cpp @@ -17,7 +17,8 @@ #include -#include "gtest/gtest.h" +#include + #include "lib/compile_context.h" #include "lib/log.h" #include "lib/options.h" diff --git a/backends/tofino/bf-asm/gtest/hashexpr.cpp b/backends/tofino/bf-asm/gtest/hashexpr.cpp index e65f6696976..f89c199472a 100644 --- a/backends/tofino/bf-asm/gtest/hashexpr.cpp +++ b/backends/tofino/bf-asm/gtest/hashexpr.cpp @@ -15,11 +15,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "hashexpr.h" +#include "backends/tofino/bf-asm/hashexpr.h" +#include + +#include "backends/tofino/bf-asm/bfas.h" #include "backends/tofino/bf-asm/stage.h" -#include "bfas.h" -#include "gtest/gtest.h" namespace { diff --git a/backends/tofino/bf-asm/gtest/mirror.cpp b/backends/tofino/bf-asm/gtest/mirror.cpp index 5486b74fd7f..bfa377d83e6 100644 --- a/backends/tofino/bf-asm/gtest/mirror.cpp +++ b/backends/tofino/bf-asm/gtest/mirror.cpp @@ -15,9 +15,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "deparser.h" -#include "gtest/gtest.h" -#include "sections.h" +#include + +#include "backends/tofino/bf-asm/deparser.h" +#include "backends/tofino/bf-asm/sections.h" namespace { diff --git a/backends/tofino/bf-asm/gtest/parser-test.cpp b/backends/tofino/bf-asm/gtest/parser-test.cpp index c666cbc1a93..c741a23fd75 100644 --- a/backends/tofino/bf-asm/gtest/parser-test.cpp +++ b/backends/tofino/bf-asm/gtest/parser-test.cpp @@ -15,9 +15,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "bfas.h" -#include "gtest/gtest.h" -#include "parser-tofino-jbay.h" +#include + +#include "backends/tofino/bf-asm/bfas.h" +#include "backends/tofino/bf-asm/jbay/parser-tofino-jbay.h" namespace { diff --git a/backends/tofino/bf-asm/gtest/register-matcher.cpp b/backends/tofino/bf-asm/gtest/register-matcher.cpp index 74b58d9aa51..a1a6c4595d3 100644 --- a/backends/tofino/bf-asm/gtest/register-matcher.cpp +++ b/backends/tofino/bf-asm/gtest/register-matcher.cpp @@ -15,7 +15,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "register-matcher.h" +#include "backends/tofino/bf-asm/register-matcher.h" #include #include diff --git a/backends/tofino/bf-asm/gtest/register-matcher.h b/backends/tofino/bf-asm/gtest/register-matcher.h index c6f63c89769..aa47a8203fd 100644 --- a/backends/tofino/bf-asm/gtest/register-matcher.h +++ b/backends/tofino/bf-asm/gtest/register-matcher.h @@ -18,12 +18,13 @@ #ifndef BACKENDS_TOFINO_BF_ASM_GTEST_REGISTER_MATCHER_H_ #define BACKENDS_TOFINO_BF_ASM_GTEST_REGISTER_MATCHER_H_ +#include + #include #include #include -#include "bf-asm/ubits.h" -#include "gtest/gtest.h" +#include "backends/tofino/bf-asm/ubits.h" #include "lib/bitvec.h" namespace BfAsm { From 244e0ce03e5cc856c8506c4027675c664c2fdd24 Mon Sep 17 00:00:00 2001 From: fruffy Date: Sat, 15 Feb 2025 15:45:02 -0500 Subject: [PATCH 11/19] Fix a standard compliance problem with an untyped struct. Signed-off-by: fruffy --- backends/tofino/bf-asm/action_bus.cpp | 20 ++++----- backends/tofino/bf-asm/alloc.h | 2 +- backends/tofino/bf-asm/asm-parse.ypp | 4 +- backends/tofino/bf-asm/asm-types.cpp | 4 +- backends/tofino/bf-asm/asm-types.h | 8 ++-- backends/tofino/bf-asm/counter.cpp | 2 +- backends/tofino/bf-asm/deparser.cpp | 2 +- backends/tofino/bf-asm/gateway.cpp | 12 +++--- backends/tofino/bf-asm/gtest/gateway.cpp | 5 ++- .../tofino/bf-asm/gtest/register-matcher.cpp | 2 +- .../tofino/bf-asm/gtest/register-matcher.h | 1 + backends/tofino/bf-asm/hashexpr.cpp | 6 +-- backends/tofino/bf-asm/input_xbar.cpp | 6 +-- backends/tofino/bf-asm/instruction.cpp | 16 +++---- backends/tofino/bf-asm/match_source.h | 4 +- backends/tofino/bf-asm/match_table.cpp | 2 +- backends/tofino/bf-asm/meter.cpp | 8 ++-- backends/tofino/bf-asm/parser-tofino-jbay.cpp | 28 ++++++------ backends/tofino/bf-asm/phv.cpp | 14 +++--- backends/tofino/bf-asm/phv.h | 2 +- backends/tofino/bf-asm/salu_inst.cpp | 11 +++-- backends/tofino/bf-asm/sram_match.cpp | 13 +++--- backends/tofino/bf-asm/stateful.cpp | 4 +- backends/tofino/bf-asm/tables.cpp | 43 ++++++++++--------- 24 files changed, 112 insertions(+), 107 deletions(-) diff --git a/backends/tofino/bf-asm/action_bus.cpp b/backends/tofino/bf-asm/action_bus.cpp index 5d9b88d09a7..8006c73d7c8 100644 --- a/backends/tofino/bf-asm/action_bus.cpp +++ b/backends/tofino/bf-asm/action_bus.cpp @@ -117,7 +117,7 @@ ActionBus::ActionBus(Table *tbl, VECTOR(pair_t) & data) { lineno = data.size ? data[0].key.lineno : -1; for (auto &kv : data) { if (!CHECKTYPE2(kv.key, tINT, tRANGE)) continue; - unsigned idx = kv.key.type == tRANGE ? kv.key.lo : kv.key.i; + unsigned idx = kv.key.type == tRANGE ? kv.key.range.lo : kv.key.i; if (!CHECKTYPE2M(kv.value, tSTR, tCMD, "field name or slice")) continue; const char *name = kv.value.s; value_t *name_ref = &kv.value; @@ -132,14 +132,14 @@ ActionBus::ActionBus(Table *tbl, VECTOR(pair_t) & data) { if (!PCHECKTYPE2M(kv.value.vec.size == 2, kv.value[1], tRANGE, tSTR, "field name or slice")) continue; - // if ((kv.value[1].lo & 7) != 0 || (kv.value[1].hi & 7) != 7) { + // if ((kv.value[1].range.lo & 7) != 0 || (kv.value[1].range.hi & 7) != 7) { // error(kv.value.lineno, "Slice must be byte slice"); // continue; } name = kv.value[0].s; name_ref = &kv.value[0]; if (kv.value[1].type == tRANGE) { - off = kv.value[1].lo; - sz = kv.value[1].hi - kv.value[1].lo + 1; + off = kv.value[1].range.lo; + sz = kv.value[1].range.hi - kv.value[1].range.lo + 1; } else if (kv.value[1] != "color") { error(kv.value[1].lineno, "unexpected %s", kv.value[1].s); } @@ -189,10 +189,10 @@ ActionBus::ActionBus(Table *tbl, VECTOR(pair_t) & data) { ActionBusSource(src.hd, hd_hi), 32, 0); } } else if (kv.value[i].type == tRANGE) { - if ((kv.value[i].lo & 7) != 0 || (kv.value[i].hi & 7) != 7) + if ((kv.value[i].range.lo & 7) != 0 || (kv.value[i].range.hi & 7) != 7) error(kv.value.lineno, "Slice must be byte slice"); - off += kv.value[i].lo; - sz = kv.value[i].hi - kv.value[i].lo + 1; + off += kv.value[i].range.lo; + sz = kv.value[i].range.hi - kv.value[i].range.lo + 1; } else { error(kv.value[i].lineno, "Unexpected hash_dist %s", value_desc(kv.value[i])); @@ -202,8 +202,8 @@ ActionBus::ActionBus(Table *tbl, VECTOR(pair_t) & data) { } else if (kv.value.type == tCMD && kv.value == "rng") { src = ActionBusSource(RandomNumberGen(kv.value[1].i)); if (kv.value.vec.size > 2 && CHECKTYPE(kv.value[2], tRANGE)) { - off = kv.value[2].lo; - sz = kv.value[2].hi + 1 - off; + off = kv.value[2].range.lo; + sz = kv.value[2].range.hi + 1 - off; } } else if (name_ref) { src = ActionBusSource(new Table::Ref(*name_ref)); @@ -226,7 +226,7 @@ ActionBus::ActionBus(Table *tbl, VECTOR(pair_t) & data) { error(kv.value.lineno, "Invalid slice of %d bit field %s", f->size, name); } if (kv.key.type == tRANGE) { - unsigned size = (kv.key.hi - idx + 1) * 8; + unsigned size = (kv.key.range.hi - idx + 1) * 8; // Make slot size (sz) same as no. of bytes allocated on action bus. if (size > sz) sz = size; } else if (!sz) { diff --git a/backends/tofino/bf-asm/alloc.h b/backends/tofino/bf-asm/alloc.h index f2577bc30c6..e3aac68e5e1 100644 --- a/backends/tofino/bf-asm/alloc.h +++ b/backends/tofino/bf-asm/alloc.h @@ -4,8 +4,8 @@ #include #include -#include #include +#include namespace BFN { diff --git a/backends/tofino/bf-asm/asm-parse.ypp b/backends/tofino/bf-asm/asm-parse.ypp index 2092fc60eef..8c9c5e1a463 100644 --- a/backends/tofino/bf-asm/asm-parse.ypp +++ b/backends/tofino/bf-asm/asm-parse.ypp @@ -46,8 +46,8 @@ static value_t value(VECTOR(uintptr_t) &v, int lineno_adj) { return rv; } static value_t value(int lo, int hi, int lineno_adj) { value_t rv{tRANGE, lineno - lineno_adj}; - rv.lo = lo; - rv.hi = hi; + rv.range.lo = lo; + rv.range.hi = hi; return rv; } static value_t value(char *v, int lineno_adj) { value_t rv{tSTR, lineno - lineno_adj}; diff --git a/backends/tofino/bf-asm/asm-types.cpp b/backends/tofino/bf-asm/asm-types.cpp index 7325da5cc55..8fc2ea055f5 100644 --- a/backends/tofino/bf-asm/asm-types.cpp +++ b/backends/tofino/bf-asm/asm-types.cpp @@ -222,7 +222,7 @@ const char *value_desc(const value_t *p) { case tBIGINT: return ""; case tRANGE: - snprintf(buffer, sizeof(buffer), "%d..%d", p->lo, p->hi); + snprintf(buffer, sizeof(buffer), "%d..%d", p->range.lo, p->range.hi); return buffer; case tMATCH: return ""; @@ -292,7 +292,7 @@ bool operator==(const struct value_t &a, const struct value_t &b) { if (b.bigi.data[i]) return false; return true; case tRANGE: - return a.lo == b.lo && a.hi == b.hi; + return a.range.lo == b.range.lo && a.range.hi == b.range.hi; case tSTR: return !strcmp(a.s, b.s); case tMATCH: diff --git a/backends/tofino/bf-asm/asm-types.h b/backends/tofino/bf-asm/asm-types.h index 392146fe40f..994e5f74e10 100644 --- a/backends/tofino/bf-asm/asm-types.h +++ b/backends/tofino/bf-asm/asm-types.h @@ -120,7 +120,7 @@ struct value_t { struct { int lo; int hi; - }; + } range; char *s; match_t m; VECTOR(match_t) bigm; @@ -279,9 +279,9 @@ std::unique_ptr toJson(VECTOR(pair_t) &); #define PCHECKTYPE2M(P, V, T1, T2, M) \ (((P) && ((V).type == (T1) || (V).type == (T2))) || \ (error((V).lineno, "Syntax error, expecting %s", M), 0)) -#define VALIDATE_RANGE(V) \ - ((V).type != tRANGE || (V).lo <= (V).hi || \ - (error((V).lineno, "Invalid range %d..%d", (V).lo, (V).hi), 0)) +#define VALIDATE_RANGE(V) \ + ((V).type != tRANGE || (V).range.lo <= (V).range.hi || \ + (error((V).lineno, "Invalid range %d..%d", (V).range.lo, (V).range.hi), 0)) inline value_t *get(VECTOR(pair_t) & map, const char *key) { for (auto &kv : map) diff --git a/backends/tofino/bf-asm/counter.cpp b/backends/tofino/bf-asm/counter.cpp index d2edb0e76b4..04c497f990c 100644 --- a/backends/tofino/bf-asm/counter.cpp +++ b/backends/tofino/bf-asm/counter.cpp @@ -23,8 +23,8 @@ #include "misc.h" // target specific template specializations -#include "tofino/counter.h" #include "jbay/counter.h" +#include "tofino/counter.h" void CounterTable::setup(VECTOR(pair_t) & data) { common_init_setup(data, false, P4Table::Statistics); diff --git a/backends/tofino/bf-asm/deparser.cpp b/backends/tofino/bf-asm/deparser.cpp index ec14da82774..7a1ed225426 100644 --- a/backends/tofino/bf-asm/deparser.cpp +++ b/backends/tofino/bf-asm/deparser.cpp @@ -599,8 +599,8 @@ void Deparser::report_resources_deparser_json(json::vector &fde_entries_i, *deparser_json_dump << &resources_deparser; } +#include "jbay/deparser.cpp" // NOLINT(build/include) #include "tofino/deparser.cpp" // NOLINT(build/include) -#include "jbay/deparser.cpp" // NOLINT(build/include) std::vector Deparser::merge_csum_entries( const std::vector &entries, int id) { diff --git a/backends/tofino/bf-asm/gateway.cpp b/backends/tofino/bf-asm/gateway.cpp index e25c3ed15c0..48d8b74b20f 100644 --- a/backends/tofino/bf-asm/gateway.cpp +++ b/backends/tofino/bf-asm/gateway.cpp @@ -15,18 +15,18 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "backends/tofino/bf-asm/hashexpr.h" +#include "backends/tofino/bf-asm/input_xbar.h" +#include "backends/tofino/bf-asm/instruction.h" +#include "backends/tofino/bf-asm/misc.h" #include "backends/tofino/bf-asm/stage.h" #include "backends/tofino/bf-asm/tables.h" -#include "hashexpr.h" -#include "input_xbar.h" -#include "instruction.h" #include "lib/algorithm.h" #include "lib/hex.h" -#include "misc.h" // template specialization declarations -#include "jbay/gateway.h" -#include "tofino/gateway.h" +#include "backends/tofino/bf-asm/jbay/gateway.h" +#include "backends/tofino/bf-asm/tofino/gateway.h" static struct { unsigned units, bits, half_shift, mask, half_mask; diff --git a/backends/tofino/bf-asm/gtest/gateway.cpp b/backends/tofino/bf-asm/gtest/gateway.cpp index 91effb09e90..437afdfc6a2 100644 --- a/backends/tofino/bf-asm/gtest/gateway.cpp +++ b/backends/tofino/bf-asm/gtest/gateway.cpp @@ -15,10 +15,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "backends/tofino/bf-asm/stage.h" -#include "backends/tofino/bf-asm/bfas.h" #include +#include "backends/tofino/bf-asm/bfas.h" +#include "backends/tofino/bf-asm/stage.h" + namespace { // Verify that the next table registers are correctly configured for a standalone gateway with a diff --git a/backends/tofino/bf-asm/gtest/register-matcher.cpp b/backends/tofino/bf-asm/gtest/register-matcher.cpp index a1a6c4595d3..77b5abf64ce 100644 --- a/backends/tofino/bf-asm/gtest/register-matcher.cpp +++ b/backends/tofino/bf-asm/gtest/register-matcher.cpp @@ -15,7 +15,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "backends/tofino/bf-asm/register-matcher.h" +#include "backends/tofino/bf-asm/gtest/register-matcher.h" #include #include diff --git a/backends/tofino/bf-asm/gtest/register-matcher.h b/backends/tofino/bf-asm/gtest/register-matcher.h index aa47a8203fd..6f993bb617c 100644 --- a/backends/tofino/bf-asm/gtest/register-matcher.h +++ b/backends/tofino/bf-asm/gtest/register-matcher.h @@ -24,6 +24,7 @@ #include #include +#include "backends/tofino/bf-asm/register-matcher.h" #include "backends/tofino/bf-asm/ubits.h" #include "lib/bitvec.h" diff --git a/backends/tofino/bf-asm/hashexpr.cpp b/backends/tofino/bf-asm/hashexpr.cpp index 2d2312aa6ce..af384b077e2 100644 --- a/backends/tofino/bf-asm/hashexpr.cpp +++ b/backends/tofino/bf-asm/hashexpr.cpp @@ -615,7 +615,7 @@ HashExpr *HashExpr::create(gress_t gress, int stage, const value_t &what) { return rv; } else if (what[0] == "slice") { if (what.vec.size < 3 || what[2].type == tRANGE - ? what.vec.size > 3 || what[2].hi < what[2].lo + ? what.vec.size > 3 || what[2].range.hi < what[2].range.lo : what[2].type != tINT || what.vec.size > 4 || (what.vec.size == 4 && what[3].type != tINT)) { error(what.lineno, "Invalid slice operation"); @@ -624,8 +624,8 @@ HashExpr *HashExpr::create(gress_t gress, int stage, const value_t &what) { Slice *rv = new Slice(what.lineno); rv->what = create(gress, stage, what[1]); if (what[2].type == tRANGE) { - rv->start = what[2].lo; - rv->_width = what[2].hi - what[2].lo + 1; + rv->start = what[2].range.lo; + rv->_width = what[2].range.hi - what[2].range.lo + 1; } else { rv->start = what[2].i; if (what.vec.size > 3) rv->_width = what[3].i; diff --git a/backends/tofino/bf-asm/input_xbar.cpp b/backends/tofino/bf-asm/input_xbar.cpp index 4e84c5be8af..cdee0a81cc8 100644 --- a/backends/tofino/bf-asm/input_xbar.cpp +++ b/backends/tofino/bf-asm/input_xbar.cpp @@ -130,8 +130,8 @@ void InputXbar::parse_group(Table *t, Group gr, const value_t &value) { if (reg.key.type == tINT) { lo = reg.key.i; } else { - lo = reg.key.lo; - hi = reg.key.hi; + lo = reg.key.range.lo; + hi = reg.key.range.hi; } if (lo < 0 || lo >= group_size(gr.type)) { error(reg.key.lineno, "Invalid offset for %s group", group_type(gr.type)); @@ -211,7 +211,7 @@ void InputXbar::parse_hash_table(Table *t, HashTable ht, const value_t &value) { c.key.i, c.key.i); } else if (c.key.type == tRANGE) { setup_hash(hash_tables[ht], ht, t->gress, t->stage->stageno, c.value, c.key.lineno, - c.key.lo, c.key.hi); + c.key.range.lo, c.key.range.hi); } else if (CHECKTYPEM(c.key, tCMD, "hash column decriptor")) { if (c.key.vec.size != 2 || c.key[0] != "valid" || c.key[1].type != tINT || options.target != TOFINO) { diff --git a/backends/tofino/bf-asm/instruction.cpp b/backends/tofino/bf-asm/instruction.cpp index d470b19a283..7f5827ee498 100644 --- a/backends/tofino/bf-asm/instruction.cpp +++ b/backends/tofino/bf-asm/instruction.cpp @@ -340,8 +340,8 @@ struct Operand : public IHasDbPrint { auto *rv = new HashDist(v[0].lineno, tbl); for (int i = 1; i < v.size; ++i) { if (v[i].type == tRANGE && rv->lo == -1) { - rv->lo = v[i].lo; - rv->hi = v[i].hi; + rv->lo = v[i].range.lo; + rv->hi = v[i].range.hi; } else if (CHECKTYPE(v[i], tINT)) { rv->units.push_back(v[i].i); } else { @@ -455,8 +455,8 @@ struct Operand : public IHasDbPrint { if (v.size > 1 && CHECKTYPE(v[1], tINT)) rng.unit = v[1].i; if (rng.unit < 0 || rng.unit > 1) error(v[0].lineno, "invalid random number generator"); if (v.size > 2 && CHECKTYPE(v[2], tRANGE)) { - lo = v[2].lo; - hi = v[2].hi; + lo = v[2].range.lo; + hi = v[2].range.hi; if (lo < 0 || hi > 31 || hi < lo) error(v[2].lineno, "invalid random number generator slice"); } @@ -598,8 +598,8 @@ static void parse_slice(const VECTOR(value_t) & vec, int idx, int &lo, int &hi) if (vec[idx].type == tINT) { lo = hi = vec[idx].i; } else { - lo = vec[idx].lo; - hi = vec[idx].hi; + lo = vec[idx].range.lo; + hi = vec[idx].range.hi; } } } @@ -630,8 +630,8 @@ Operand::Operand(Table *tbl, const Table::Actions::Action *act, const value_t &v if (name == "hash_dist" && lo == hi) { auto hd = new HashDist(v.lineno, tbl, lo); if (v.type == tCMD && v[1].type == tRANGE) { - hd->lo = v[1].lo; - hd->hi = v[1].hi; + hd->lo = v[1].range.lo; + hd->hi = v[1].range.hi; } op = hd; return; diff --git a/backends/tofino/bf-asm/match_source.h b/backends/tofino/bf-asm/match_source.h index 1f600e2813e..0014e0ed38f 100644 --- a/backends/tofino/bf-asm/match_source.h +++ b/backends/tofino/bf-asm/match_source.h @@ -59,8 +59,8 @@ class HashMatchSource : public MatchSource { error(value.lineno, "Hash Match source must come from a hash group"); if (value.vec.size != 2) error(value.lineno, "Hash Match source requires a range"); if (CHECKTYPE(value.vec[1], tRANGE)) { - lo = value.vec[1].lo; - hi = value.vec[1].hi; + lo = value.vec[1].range.lo; + hi = value.vec[1].range.hi; } } } diff --git a/backends/tofino/bf-asm/match_table.cpp b/backends/tofino/bf-asm/match_table.cpp index 34a62974468..caf0d78ca53 100644 --- a/backends/tofino/bf-asm/match_table.cpp +++ b/backends/tofino/bf-asm/match_table.cpp @@ -286,8 +286,8 @@ void MatchTable::gen_idletime_tbl_cfg(json::map &stage_tbl) const { if (idletime) idletime->gen_stage_tbl_cfg(stage_tbl); } +#include "jbay/match_table.cpp" // NOLINT(build/include) #include "tofino/match_table.cpp" // NOLINT(build/include) -#include "jbay/match_table.cpp" // NOLINT(build/include) template void MatchTable::write_common_regs(typename TARGET::mau_regs ®s, int type, Table *result) { diff --git a/backends/tofino/bf-asm/meter.cpp b/backends/tofino/bf-asm/meter.cpp index f4123b2eb1b..64cb1419823 100644 --- a/backends/tofino/bf-asm/meter.cpp +++ b/backends/tofino/bf-asm/meter.cpp @@ -22,8 +22,8 @@ #include "misc.h" // target specific template specializations -#include "tofino/meter.h" #include "jbay/meter.h" +#include "tofino/meter.h" Table::Layout::bus_type_t MeterTable::default_bus_type() const { // FIXME -- this is a bit of a hack -- if color_mapram_addr has been set, we want the @@ -75,10 +75,10 @@ void MeterTable::setup(VECTOR(pair_t) & data) { if (CHECKTYPE(kv.value.vec[1], tINT)) pre_color_hash_dist_unit = kv.value.vec[1].i; if (CHECKTYPE(kv.value.vec[2], tRANGE)) { auto range = kv.value.vec[2]; - int diff = range.hi - range.lo + 1; - if (diff != 2 || range.lo % 2 != 0) + int diff = range.range.hi - range.range.lo + 1; + if (diff != 2 || range.range.lo % 2 != 0) error(kv.value.lineno, "Invalid hash distribution range for precolor"); - pre_color_bit_lo = range.lo; + pre_color_bit_lo = range.range.lo; } } } else if (kv.key == "type") { diff --git a/backends/tofino/bf-asm/parser-tofino-jbay.cpp b/backends/tofino/bf-asm/parser-tofino-jbay.cpp index 2e26435059c..70e20667916 100644 --- a/backends/tofino/bf-asm/parser-tofino-jbay.cpp +++ b/backends/tofino/bf-asm/parser-tofino-jbay.cpp @@ -37,10 +37,10 @@ void AsmParser::init_port_use(bitvec &port_use, const value_t &arg) { init_port_use(port_use, arg[i]); } } else if (arg.type == tRANGE) { - if (arg.hi > arg.lo) - error(arg.lineno, "port range hi index %d cannot be smaller than lo index %d", arg.hi, - arg.lo); - port_use.setrange(arg.lo, arg.hi - arg.lo + 1); + if (arg.range.hi > arg.range.lo) + error(arg.lineno, "port range hi index %d cannot be smaller than lo index %d", + arg.range.hi, arg.range.lo); + port_use.setrange(arg.range.lo, arg.range.hi - arg.range.lo + 1); } else if (arg.type == tINT) { port_use.setbit(arg.i); } @@ -703,8 +703,8 @@ Parser::Checksum::Checksum(gress_t gress, pair_t data) : lineno(data.key.lineno) auto range = kv.value[i]; unsigned lo = 0, hi = 0; if (range.type == tRANGE) { - lo = range.lo; - hi = range.hi; + lo = range.range.lo; + hi = range.range.hi; } else if (range.type == tINT) { lo = hi = range.i; } else { @@ -1110,12 +1110,12 @@ int Parser::State::MatchKey::setup_match_el(int at, value_t &spec) { case tINT: return add_byte(at, spec.i); case tRANGE: - if (spec.lo >= spec.hi) { + if (spec.range.lo >= spec.range.hi) { error(spec.lineno, "Invalid match range"); return -1; } - if (at >= 0) at += spec.hi - spec.lo; - for (int i = spec.hi; i >= spec.lo; i--) { + if (at >= 0) at += spec.range.hi - spec.range.lo; + for (int i = spec.range.hi; i >= spec.range.lo; i--) { if (add_byte(at, i) < 0) return -1; if (at >= 0) at--; } @@ -1367,7 +1367,7 @@ Parser::State::Match::Match(int l, gress_t gress, State *s, match_t m, VECTOR(pa } else if (kv.key.type == tINT) { save.push_back(new Save(gress, this, kv.key.i, kv.key.i, kv.value)); } else if (kv.key.type == tRANGE) { - save.push_back(new Save(gress, this, kv.key.lo, kv.key.hi, kv.value)); + save.push_back(new Save(gress, this, kv.key.range.lo, kv.key.range.hi, kv.value)); } else if (kv.value.type == tINT) { set.push_back(new Set(gress, this, kv.key, kv.value.i)); } else if (kv.value.type == tCMD && kv.value[0] == "rotate") { @@ -1482,8 +1482,8 @@ Parser::State::Match::Clot::Clot(gress_t gress, const value_t &tag, const value_ start = data.i; length = 1; } else if (data.type == tRANGE) { - start = data.lo; - length = data.hi - data.lo + 1; + start = data.range.lo; + length = data.range.hi - data.range.lo + 1; } else { for (auto &kv : data.map) { if (kv.key == "start") { @@ -1551,8 +1551,8 @@ Parser::State::Match::FieldMapping::FieldMapping(Phv::Ref &ref, const value_t &a if (CHECKTYPE(a, tCMD)) { where = ref; container_id = a.vec[0].s; - lo = a.vec[1].lo; - hi = a.vec[1].hi; + lo = a.vec[1].range.lo; + hi = a.vec[1].range.hi; } else { error(a.lineno, "Syntax error"); } diff --git a/backends/tofino/bf-asm/phv.cpp b/backends/tofino/bf-asm/phv.cpp index cc4b10e8617..61ade268af1 100644 --- a/backends/tofino/bf-asm/phv.cpp +++ b/backends/tofino/bf-asm/phv.cpp @@ -71,7 +71,7 @@ int Phv::addreg(gress_t gress, const char *name, const value_t &what, int stage, if (key.type == tINT) rv |= addreg(gress, name, kv.value, key.i); else - rv |= addreg(gress, name, kv.value, key.lo, key.hi); + rv |= addreg(gress, name, kv.value, key.range.lo, key.range.hi); } } int size = -1; @@ -126,7 +126,7 @@ int Phv::addreg(gress_t gress, const char *name, const value_t &what, int stage, } else if (what[1].type == tINT) { reg[stage].slice = Slice(*sl, what[1].i, what[1].i); } else { - reg[stage].slice = Slice(*sl, what[1].lo, what[1].hi); + reg[stage].slice = Slice(*sl, what[1].range.lo, what[1].range.hi); } reg[stage].max_stage = max_stage; if (!reg[stage].slice.valid) { @@ -186,11 +186,11 @@ Phv::Ref::Ref(gress_t g, int stage, const value_t &n) if (n[1].type == tINT) { lo = hi = n[1].i; } else { - lo = n[1].lo; - hi = n[1].hi; + lo = n[1].range.lo; + hi = n[1].range.hi; if (lo > hi) { - lo = n[1].hi; - hi = n[1].lo; + lo = n[1].range.hi; + hi = n[1].range.lo; } } } @@ -492,5 +492,5 @@ void Phv::output(json::map &ctxt_json) { // phv_alloc.push_back(std::move(phv_alloc_stage.clone())); } } +#include "jbay/phv.cpp" // NOLINT(build/include) #include "tofino/phv.cpp" // NOLINT(build/include) -#include "jbay/phv.cpp" // NOLINT(build/include) diff --git a/backends/tofino/bf-asm/phv.h b/backends/tofino/bf-asm/phv.h index e88f6e2017d..133a72365c6 100644 --- a/backends/tofino/bf-asm/phv.h +++ b/backends/tofino/bf-asm/phv.h @@ -321,7 +321,7 @@ class Target::Phv { inline unsigned Phv::mau_groupsize() { return phv.target->mau_groupsize(); } -#include "tofino/phv.h" #include "jbay/phv.h" +#include "tofino/phv.h" #endif /* BACKENDS_TOFINO_BF_ASM_PHV_H_ */ diff --git a/backends/tofino/bf-asm/salu_inst.cpp b/backends/tofino/bf-asm/salu_inst.cpp index 965b34564e4..aaa0c8c207d 100644 --- a/backends/tofino/bf-asm/salu_inst.cpp +++ b/backends/tofino/bf-asm/salu_inst.cpp @@ -136,9 +136,9 @@ struct operand : public IHasDbPrint { else BUG(); if (v.type == tCMD && PCHECKTYPE(v.vec.size == 2, v[1], tRANGE)) { - if ((v[1].lo & 7) || ((v[1].hi + 1) & 7)) + if ((v[1].range.lo & 7) || ((v[1].range.hi + 1) & 7)) error(lineno, "only byte slices allowed on %s", v[0].s); - mask = (1U << (v[1].hi + 1) / 8U) - (1U << (v[1].lo / 8U)); + mask = (1U << (v[1].range.hi + 1) / 8U) - (1U << (v[1].range.lo / 8U)); } } void dbprint(std::ostream &out) const override { out << (pi ? "phv_hi" : "phv_lo"); } @@ -278,7 +278,7 @@ operand::operand(Table *tbl, const Table::Actions::Action *act, const value_t &v if (v->type == tCMD) { BUG_CHECK(v->vec.size > 0 && v->vec[0].type == tSTR); if (auto f = tbl->format->field(v->vec[0].s)) { - if (v->vec.size > 1 && CHECKTYPE(v->vec[1], tRANGE) && v->vec[1].lo != 0) + if (v->vec.size > 1 && CHECKTYPE(v->vec[1], tRANGE) && v->vec[1].range.lo != 0) error(v->vec[1].lineno, "Can't slice memory field %s in stateful action", v->vec[0].s); op = new Memory(v->lineno, tbl, f); @@ -929,9 +929,8 @@ struct OutOP : public SaluInstruction { return src ? src->phvRead(fn) : false; } void dbprint(std::ostream &out) const override { - out << "INSTR: output " << "pred=0x" << hex(predication_encode) - << " word" << (slot - ALUOUT0) - << " mux=" << output_mux; + out << "INSTR: output " << "pred=0x" << hex(predication_encode) << " word" + << (slot - ALUOUT0) << " mux=" << output_mux; } template void write_regs(REGS ®s, Table *tbl, Table::Actions::Action *act); diff --git a/backends/tofino/bf-asm/sram_match.cpp b/backends/tofino/bf-asm/sram_match.cpp index a7faa88ed32..cfec66b31fe 100644 --- a/backends/tofino/bf-asm/sram_match.cpp +++ b/backends/tofino/bf-asm/sram_match.cpp @@ -588,9 +588,9 @@ bool SRamMatchTable::parse_way(const value_t &v) { if (kv.value.type == tINT) { way.index = kv.value.i; } else { - way.index = kv.value.lo; - way.index_hi = kv.value.hi; - index_size = kv.value.hi - kv.value.lo + 1; + way.index = kv.value.range.lo; + way.index_hi = kv.value.range.hi; + index_size = kv.value.range.hi - kv.value.range.lo + 1; } if (way.index > Target::IXBAR_HASH_INDEX_MAX() || way.index % Target::IXBAR_HASH_INDEX_STRIDE() != 0) @@ -602,13 +602,14 @@ bool SRamMatchTable::parse_way(const value_t &v) { if (kv.value[1].type == tINT) { way.select <<= kv.value[1].i; } else { - way.select <<= kv.value[1].lo; - if (kv.value[1].hi < way.select.max().index()) + way.select <<= kv.value[1].range.lo; + if (kv.value[1].range.hi < way.select.max().index()) error(kv.value.lineno, "invalid select mask for range"); } } } else if (kv.value.type == tRANGE) { - way.select.setrange(kv.value.lo, kv.value.hi - kv.value.lo + 1); + way.select.setrange(kv.value.range.lo, + kv.value.range.hi - kv.value.range.lo + 1); } else { error(kv.value.lineno, "invalid select %s", value_desc(&kv.value)); } diff --git a/backends/tofino/bf-asm/stateful.cpp b/backends/tofino/bf-asm/stateful.cpp index 44e2236dd26..ab125df0abc 100644 --- a/backends/tofino/bf-asm/stateful.cpp +++ b/backends/tofino/bf-asm/stateful.cpp @@ -121,8 +121,8 @@ void StatefulTable::setup(VECTOR(pair_t) & data) { if (kv.value.type == tINT) { logvpn_min = logvpn_max = kv.value.i; } else { - logvpn_min = kv.value.lo; - logvpn_max = kv.value.hi; + logvpn_min = kv.value.range.lo; + logvpn_max = kv.value.range.hi; } } } else if (kv.key == "pred_shift") { diff --git a/backends/tofino/bf-asm/tables.cpp b/backends/tofino/bf-asm/tables.cpp index 3ec9043c3de..c2980c73a41 100644 --- a/backends/tofino/bf-asm/tables.cpp +++ b/backends/tofino/bf-asm/tables.cpp @@ -236,9 +236,9 @@ static int add_rows(std::vector &layout, const value_t &rows) { if (rows.type == tINT) { add_row(rows.lineno, layout, rows.i); } else { - int step = rows.lo > rows.hi ? -1 : 1; - for (int i = rows.lo; i != rows.hi; i += step) add_row(rows.lineno, layout, i); - add_row(rows.lineno, layout, rows.hi); + int step = rows.range.lo > rows.range.hi ? -1 : 1; + for (int i = rows.range.lo; i != rows.range.hi; i += step) add_row(rows.lineno, layout, i); + add_row(rows.lineno, layout, rows.range.hi); } return 0; } @@ -289,9 +289,10 @@ static int add_cols(int stage, Table::Layout &row, const value_t &cols) { } if (!CHECKTYPE2(cols, tINT, tRANGE)) return 1; if (cols.type == tINT) return add_col(cols.lineno, stage, row, cols.i); - int step = cols.lo > cols.hi ? -1 : 1; - for (int i = cols.lo; i != cols.hi; i += step) rv |= add_col(cols.lineno, stage, row, i); - rv |= add_col(cols.lineno, stage, row, cols.hi); + int step = cols.range.lo > cols.range.hi ? -1 : 1; + for (int i = cols.range.lo; i != cols.range.hi; i += step) + rv |= add_col(cols.lineno, stage, row, i); + rv |= add_col(cols.lineno, stage, row, cols.range.hi); return rv; } @@ -311,9 +312,10 @@ static int add_stages(Table::Layout &row, const value_t &stages) { } if (!CHECKTYPE2(stages, tINT, tRANGE)) return 1; if (stages.type == tINT) return add_col(stages.lineno, stages.i, row, 0); - int step = stages.lo > stages.hi ? -1 : 1; - for (int i = stages.lo; i != stages.hi; i += step) rv |= add_col(stages.lineno, i, row, 0); - rv |= add_col(stages.lineno, stages.hi, row, 0); + int step = stages.range.lo > stages.range.hi ? -1 : 1; + for (int i = stages.range.lo; i != stages.range.hi; i += step) + rv |= add_col(stages.lineno, i, row, 0); + rv |= add_col(stages.lineno, stages.range.hi, row, 0); return rv; } @@ -1264,17 +1266,18 @@ Table::Format::Format(Table *t, const VECTOR(pair_t) & data, bool may_overlap) : f->size = kv.value.i; append_bits(f->bits, nextbit, nextbit + f->size - 1); } else if (kv.value.type == tRANGE) { - if (kv.value.lo > kv.value.hi) - error(kv.value.lineno, "invalid range %d..%d", kv.value.lo, kv.value.hi); - append_bits(f->bits, kv.value.lo, kv.value.hi); - f->size = kv.value.hi - kv.value.lo + 1; + if (kv.value.range.lo > kv.value.range.hi) + error(kv.value.lineno, "invalid range %d..%d", kv.value.range.lo, + kv.value.range.hi); + append_bits(f->bits, kv.value.range.lo, kv.value.range.hi); + f->size = kv.value.range.hi - kv.value.range.lo + 1; } else if (kv.value.type == tVEC) { f->size = 0; for (auto &c : kv.value.vec) if (CHECKTYPE(c, tRANGE) && VALIDATE_RANGE(c)) { - append_bits(f->bits, c.lo, c.hi); - f->size += c.hi - c.lo + 1; - if ((size_t)c.hi + 1 > size) size = c.hi + 1; + append_bits(f->bits, c.range.lo, c.range.hi); + f->size += c.range.hi - c.range.lo + 1; + if ((size_t)c.range.hi + 1 > size) size = c.range.hi + 1; } } nextbit = f->bits.back().hi + 1; @@ -1495,8 +1498,8 @@ Table::Actions::Action::alias_t::alias_t(value_t &data) { if (data.vec[1].type == tINT) { lo = hi = data.vec[1].i; } else { - lo = data.vec[1].lo; - hi = data.vec[1].hi; + lo = data.vec[1].range.lo; + hi = data.vec[1].range.hi; } } } else { @@ -1535,8 +1538,8 @@ void Table::Actions::Action::setup_mod_cond_values(value_t &map) { if (v[1].type == tINT) { lo = hi = v[1].i; } else if (v[1].type == tRANGE) { - lo = v[1].lo; - hi = v[1].hi; + lo = v[1].range.lo; + hi = v[1].range.hi; } mod_cond_values.at(kv.key.s).at(array_index).setrange(lo, hi - lo + 1); } From e484ff4e7a8a21908d93585e3e02574c1a26e9af Mon Sep 17 00:00:00 2001 From: fruffy Date: Sat, 15 Feb 2025 16:33:05 -0500 Subject: [PATCH 12/19] Small fixes. Signed-off-by: fruffy --- backends/tofino/bf-asm/CMakeLists.txt | 2 ++ backends/tofino/bf-asm/gtest/parser-test.cpp | 2 +- backends/tofino/bf-asm/gtest/register-matcher.h | 1 - backends/tofino/bf-asm/walle/walle.py | 2 +- .../tofino/compiler_interfaces/tools/create_phv_json.py | 6 +++--- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/backends/tofino/bf-asm/CMakeLists.txt b/backends/tofino/bf-asm/CMakeLists.txt index 66c4c9a0a55..012875e8d17 100644 --- a/backends/tofino/bf-asm/CMakeLists.txt +++ b/backends/tofino/bf-asm/CMakeLists.txt @@ -319,6 +319,8 @@ if (ENABLE_GTESTS) target_link_libraries (gtestasm PRIVATE bfas_lib gtest ${BFASM_LIB_DEPS}) target_compile_options (gtestasm PRIVATE -Wall -Wextra -ggdb -O3 -Wno-unused-parameter -Wno-sign-compare) + # Disable errors for warnings. FIXME: Get rid of this. + target_compile_options(gtestasm PUBLIC "-Wno-error") # Add to CTests - but this is in the BFASM project viz build/bf-asm, not build/p4c add_test (NAME gtestasm COMMAND gtestasm WORKING_DIRECTORY ${P4C_BINARY_DIR}) diff --git a/backends/tofino/bf-asm/gtest/parser-test.cpp b/backends/tofino/bf-asm/gtest/parser-test.cpp index c741a23fd75..f2bed038d8d 100644 --- a/backends/tofino/bf-asm/gtest/parser-test.cpp +++ b/backends/tofino/bf-asm/gtest/parser-test.cpp @@ -18,7 +18,7 @@ #include #include "backends/tofino/bf-asm/bfas.h" -#include "backends/tofino/bf-asm/jbay/parser-tofino-jbay.h" +#include "backends/tofino/bf-asm/parser-tofino-jbay.h" namespace { diff --git a/backends/tofino/bf-asm/gtest/register-matcher.h b/backends/tofino/bf-asm/gtest/register-matcher.h index 6f993bb617c..aa47a8203fd 100644 --- a/backends/tofino/bf-asm/gtest/register-matcher.h +++ b/backends/tofino/bf-asm/gtest/register-matcher.h @@ -24,7 +24,6 @@ #include #include -#include "backends/tofino/bf-asm/register-matcher.h" #include "backends/tofino/bf-asm/ubits.h" #include "lib/bitvec.h" diff --git a/backends/tofino/bf-asm/walle/walle.py b/backends/tofino/bf-asm/walle/walle.py index b90ec493515..ec2f3ebef53 100755 --- a/backends/tofino/bf-asm/walle/walle.py +++ b/backends/tofino/bf-asm/walle/walle.py @@ -630,7 +630,7 @@ def dump_binary(args, binary_cache, out_file): # Memories are ram-word addressed, not byte addressed "memories": lambda addr: addr >> 4, # TODO: use actual func once model+indirect writes are fixed - "regs": lambda addr: addr + "regs": lambda addr: addr, # # Regs are give in 32-bit PCIe address space and need to be # # converted to 42-bit chip address space # "regs": lambda addr: ((addr&0x0FF80000)<<14)|(addr&0x0007FFFF) diff --git a/backends/tofino/compiler_interfaces/tools/create_phv_json.py b/backends/tofino/compiler_interfaces/tools/create_phv_json.py index 0d3fa689c13..af8ea34233d 100755 --- a/backends/tofino/compiler_interfaces/tools/create_phv_json.py +++ b/backends/tofino/compiler_interfaces/tools/create_phv_json.py @@ -318,9 +318,9 @@ def produce_containers_node(context): rec = OrderedDict() rec["field_name"] = field_name - rec[ - "field_class" - ] = "pkt" # FIXME: Don't know how to get the value from context.json. + rec["field_class"] = ( + "pkt" # FIXME: Don't know how to get the value from context.json. + ) rec["field_msb"] = field_msb rec["field_lsb"] = field_lsb rec["phv_msb"] = phv_msb From 3cbc9176ab46be2128280ebdb6c1dcde11e30da1 Mon Sep 17 00:00:00 2001 From: fruffy Date: Thu, 20 Feb 2025 10:40:17 -0500 Subject: [PATCH 13/19] Remove test code. Signed-off-by: fruffy --- backends/tofino/bf-asm/CMakeLists.txt | 20 +- backends/tofino/bf-asm/test/CMakeLists.txt | 112 - backends/tofino/bf-asm/test/acl1.p4 | 319 - backends/tofino/bf-asm/test/action_bus1.p4 | 40 - backends/tofino/bf-asm/test/action_chain1.p4 | 83 - backends/tofino/bf-asm/test/action_chain1.stf | 20 - backends/tofino/bf-asm/test/action_chain2.p4 | 83 - .../bf-asm/test/asm/action_bus_alignment.tfa | 422 - .../test/asm/action_default_multiple.tfa | 112 - .../tofino/bf-asm/test/asm/always_run.jba | 16 - .../tofino/bf-asm/test/asm/always_run.stf | 2 - .../tofino/bf-asm/test/asm/counter_lrt1.tfa | 10 - backends/tofino/bf-asm/test/asm/em1-clot.jba | 98 - backends/tofino/bf-asm/test/asm/em1-clot.stf | 8 - .../bf-asm/test/asm/expected_failures.txt | 14 - .../bf-asm/test/asm/hash_action_basic.tfa | 112 - .../bf-asm/test/asm/hash_action_gateway2.stf | 22 - .../bf-asm/test/asm/hash_action_gateway2.tfa | 120 - .../bf-asm/test/asm/jbay_sful_syntax.jba | 51 - .../tofino/bf-asm/test/asm/network_tap.bfa | 13304 ------------- backends/tofino/bf-asm/test/asm/p4c-2257.bfa | 16228 ---------------- backends/tofino/bf-asm/test/asm/p4c-4021.bfa | 2381 --- .../bf-asm/test/asm/parser_value_set.tfa | 23 - .../bf-asm/test/asm/parser_zero_write.jba | 6 - backends/tofino/bf-asm/test/asm/rng.tfa | 22 - .../asm/stateful_multiple_output_error.tfa | 348 - .../test/asm/switch_l2_profile_tofino.tfa | 5453 ------ .../bf-asm/test/asm/table_action_alias.tfa | 66 - .../test/asm/table_alias_fields_error.tfa | 66 - backends/tofino/bf-asm/test/asm/tor.tfa | 1587 -- .../bf-asm/test/bfas_lookup_test/__init__.py | 0 .../bfas_lookup_test/bfas_lookup_cases.py | 30 - .../test/bfas_lookup_test/bfas_lookup_test.py | 131 - backends/tofino/bf-asm/test/checksum1.p4 | 120 - backends/tofino/bf-asm/test/counter1.p4 | 44 - backends/tofino/bf-asm/test/counter2.p4 | 44 - backends/tofino/bf-asm/test/counter3.p4 | 53 - backends/tofino/bf-asm/test/counter4.p4 | 45 - backends/tofino/bf-asm/test/counter5.p4 | 44 - backends/tofino/bf-asm/test/ctx_json | 1 - backends/tofino/bf-asm/test/ctxt_json_ignore | 94 - .../tofino/bf-asm/test/ctxt_json_ignore_new | 9 - backends/tofino/bf-asm/test/exact_match0.p4 | 35 - backends/tofino/bf-asm/test/exact_match1.p4 | 40 - backends/tofino/bf-asm/test/exact_match1.stf | 11 - backends/tofino/bf-asm/test/exact_match2.p4 | 41 - backends/tofino/bf-asm/test/exact_match3.p4 | 41 - backends/tofino/bf-asm/test/exact_match4.p4 | 42 - backends/tofino/bf-asm/test/exact_match5.p4 | 43 - backends/tofino/bf-asm/test/exact_match6.p4 | 43 - backends/tofino/bf-asm/test/exact_match7.p4 | 41 - backends/tofino/bf-asm/test/exact_match8.p4 | 54 - backends/tofino/bf-asm/test/exact_match9.p4 | 44 - .../tofino/bf-asm/test/exact_match_valid1.p4 | 44 - .../tofino/bf-asm/test/expected_failures.txt | 41 - backends/tofino/bf-asm/test/gateway1.p4 | 48 - backends/tofino/bf-asm/test/gateway2.p4 | 48 - backends/tofino/bf-asm/test/gateway3.p4 | 51 - backends/tofino/bf-asm/test/gateway4.p4 | 62 - backends/tofino/bf-asm/test/gateway5.p4 | 54 - backends/tofino/bf-asm/test/gateway6.p4 | 48 - backends/tofino/bf-asm/test/gateway7.p4 | 48 - backends/tofino/bf-asm/test/hash_index0.p4 | 36 - backends/tofino/bf-asm/test/hash_index1.p4 | 38 - backends/tofino/bf-asm/test/hash_index2.p4 | 51 - backends/tofino/bf-asm/test/hash_index3.p4 | 63 - backends/tofino/bf-asm/test/hash_index5.p4 | 37 - backends/tofino/bf-asm/test/instruct1.p4 | 61 - backends/tofino/bf-asm/test/instruct2.p4 | 39 - backends/tofino/bf-asm/test/instruct3.p4 | 34 - backends/tofino/bf-asm/test/instruct4.p4 | 35 - backends/tofino/bf-asm/test/instruct5.p4 | 56 - .../test/internal/brig/expected_failures.txt | 2 - .../internal/brig/test_config_123_meter_2.p4 | 118 - .../test_config_223_simple_set_metadata.p4 | 82 - ...ebug_issue_1_invalid_action_pack_format.p4 | 84 - .../debug_issue_2_action_data_bus.PRAGMA | 610 - .../internal/debug_issue_3_7_way_table.p4 | 82 - .../debug_issue_4_small_exact_match_key.p4 | 81 - .../tofino/bf-asm/test/internal/dileep.p4 | 290 - .../tofino/bf-asm/test/internal/dileep10.p4 | 186 - .../tofino/bf-asm/test/internal/dileep11.p4 | 183 - .../tofino/bf-asm/test/internal/dileep12.p4 | 449 - .../tofino/bf-asm/test/internal/dileep2.p4 | 329 - .../tofino/bf-asm/test/internal/dileep3.p4 | 358 - .../tofino/bf-asm/test/internal/dileep4.p4 | 412 - .../bf-asm/test/internal/dileep5.PRAGMA | 487 - .../bf-asm/test/internal/dileep6.PHV_BUG | 592 - .../tofino/bf-asm/test/internal/dileep7-b.p4 | 577 - .../bf-asm/test/internal/dileep7.PRAGMA | 573 - .../tofino/bf-asm/test/internal/dileep8.p4 | 593 - .../bf-asm/test/internal/dileep9.PRAGMA | 188 - .../bf-asm/test/internal/google-tor/lag.p4 | 48 - .../bf-asm/test/internal/google-tor/tor.p4 | 672 - .../test/internal/test_7_storm_control.p4 | 140 - .../internal/test_config_100_hash_action.p4 | 105 - .../internal/test_config_101_switch_msdc.p4 | 3838 ---- .../internal/test_config_102_clone.NOT_READY | 97 - .../test/internal/test_config_102_clone.p4 | 97 - .../internal/test_config_103_first_phase_0.p4 | 129 - .../test_config_10_new_crossbar_allocation.p4 | 120 - .../internal/test_config_114_simple_drop.p4 | 71 - .../test_config_115_hash_parity_groups.p4 | 103 - ...t_config_116_predication_with_condition.p4 | 109 - .../test_config_117_first_tcam_range.p4 | 68 - .../internal/test_config_118_tcam_range_2.p4 | 88 - .../internal/test_config_119_tcam_range_3.p4 | 88 - .../test_config_11_simple_gateway_table.p4 | 121 - .../internal/test_config_120_tcam_range_4.p4 | 88 - .../internal/test_config_121_tcam_range_5.p4 | 88 - .../internal/test_config_122_tcam_range_6.p4 | 70 - .../test/internal/test_config_123_meter_2.p4 | 118 - .../test/internal/test_config_124_meter_3.p4 | 113 - .../test_config_125_meter_pre_color.p4 | 112 - .../test_config_126_meter_pre_color_2.p4 | 114 - .../test_config_127_meter_pre_color_3.p4 | 160 - .../test_config_128_table_placement_bug.p4 | 101 - .../internal/test_config_12_no_overhead.p4 | 72 - .../test_config_130_test_default_action.p4 | 115 - .../test_config_132_meter_pre_color_4.p4 | 172 - .../internal/test_config_134_stage_deps.p4 | 120 - .../internal/test_config_135_tcam_range_7.p4 | 71 - .../test_config_136_tcam_error_detection.p4 | 73 - .../test_config_137_tcam_error_detection_2.p4 | 131 - .../test_config_138_tcam_error_detection_3.p4 | 147 - .../test_config_139_tcam_error_detection_4.p4 | 140 - .../test_config_13_first_selection.p4 | 152 - .../internal/test_config_140_table_counter.p4 | 103 - .../internal/test_config_142_stateful_bfd.p4 | 103 - .../test_config_143_packing_constants.p4 | 80 - .../internal/test_config_144_recirculate.p4 | 56 - .../test_config_145_shift_primitives.p4 | 69 - .../internal/test_config_146_two_drops.p4 | 69 - .../test_config_147_subtract_primitive.p4 | 69 - .../test_config_148_action_profile.p4 | 67 - ...onfig_149_signed_and_saturating_add_sub.p4 | 85 - ...st_config_14_auto_immediate_action_data.p4 | 97 - .../test_config_150_action_bus_allocation.p4 | 90 - ...test_config_151_action_bus_allocation_2.p4 | 84 - .../test_config_152_stateful_simple_cntr.p4 | 72 - ...ig_153_stateful_simple_cntr_with_output.p4 | 91 - .../test_config_154_stateful_sampling.p4 | 85 - .../test_config_155_stateful_3_alus.p4 | 139 - .../test_config_156_indirect_stateful_cntr.p4 | 107 - ...test_config_157_random_number_generator.p4 | 75 - .../internal/test_config_158_share_vliw.p4 | 81 - ...est_config_159_stateful_using_phv_field.p4 | 90 - .../test/internal/test_config_15_wide_key.p4 | 93 - ...est_config_160_stateful_single_bit_mode.p4 | 127 - .../test_config_161_new_primitives.p4 | 123 - .../test_config_162_add_header_init.p4 | 80 - ...est_config_163_stateful_table_math_unit.p4 | 92 - ...fig_164_stateful_deterministic_sampling.p4 | 115 - ...nfig_165_stateful_bfd_failure_detection.p4 | 125 - ...est_config_166_stateful_generic_counter.p4 | 96 - ...t_config_167_stateful_flowlet_switching.p4 | 144 - .../internal/test_config_168_meter_bug.p4 | 89 - ...test_config_169_stateful_sflow_sequence.p4 | 195 - ..._16_action_packing_multi_entry_with_pad.p4 | 79 - ...fig_170_stateful_selection_table_update.p4 | 167 - .../test_config_171_stateful_conga.p4 | 175 - .../test_config_172_stateful_heavy_hitter.p4 | 262 - .../test_config_173_stateful_bloom_filter.p4 | 259 - ...test_config_175_match_table_with_no_key.p4 | 70 - .../internal/test_config_176_extend_crc16.p4 | 77 - .../internal/test_config_177_meter_test.p4 | 90 - .../internal/test_config_178_hash_action.p4 | 69 - ...fig_179_check_if_sequential_action_used.p4 | 79 - ..._config_17_action_packing_wide_with_pad.p4 | 82 - .../test_config_180_first_proxy_hash.p4 | 74 - .../test_config_181_first_alg_tcam.p4 | 161 - .../test_config_182_warp_primitive.p4 | 81 - .../internal/test_config_183_sample_e2e.p4 | 58 - .../internal/test_config_184_stateful_bug1.p4 | 103 - .../internal/test_config_185_first_lpf.p4 | 105 - .../internal/test_config_186_hlir_modify.p4 | 89 - .../internal/test_config_187_proxy_hash_2.p4 | 61 - .../test_config_188_action_data_overflow.p4 | 59 - .../internal/test_config_189_stat_with_lrt.p4 | 62 - .../internal/test_config_18_first_bit_xor.p4 | 100 - .../test_config_190_modify_with_expr.p4 | 69 - .../internal/test_config_191_invalidate.p4 | 64 - ...test_config_192_stateful_driven_by_hash.p4 | 300 - ...test_config_193_indirect_stats_no_reads.p4 | 64 - .../test_config_194_same_action_param.p4 | 103 - ...st_config_195_stateful_predicate_output.p4 | 96 - .../test/internal/test_config_196_hit_miss.p4 | 119 - .../test_config_197_default_next_table.p4 | 109 - .../test_config_198_shared_action_profile.p4 | 92 - ...test_config_199_stateful_constant_index.p4 | 67 - ...g_19_immediate_but_no_action_data_table.p4 | 76 - .../test_config_1_ternary_match_crossbar.p4 | 51 - .../test_config_200_counter_constant_index.p4 | 63 - .../test_config_201_meter_constant_index.p4 | 109 - .../test_config_202_write_same_byte.p4 | 67 - .../test_config_203_first_reduction_or.p4 | 144 - .../test_config_204_no_tables_in_stage0.p4 | 75 - .../test_config_205_modify_field_from_hash.p4 | 90 - .../test_config_206_stateful_logging.p4 | 70 - .../internal/test_config_207_not_gateway.p4 | 61 - .../internal/test_config_208_table_no_key.p4 | 51 - .../test_config_209_pack_hash_dist.p4 | 137 - .../test_config_20_table_dependencies.p4 | 131 - .../test/internal/test_config_21_tcam_vpns.p4 | 76 - .../test_config_22_direct_mapped_exact.p4 | 92 - .../test_config_23_same_container_modified.p4 | 95 - .../test_config_24_action_entries_pragma.p4 | 87 - .../test_config_25_no_reads_for_table.p4 | 83 - .../test_config_26_direct_add_primitive.p4 | 88 - .../test_config_2_action_data_table_sizing.p4 | 66 - .../test_config_30_action_data_imm_param.p4 | 87 - .../test_config_31_action_data_imm_imm.p4 | 87 - ...est_config_32_action_data_imm_param_imm.p4 | 44 - .../test_config_33_action_data_paramx3.p4 | 44 - ...test_config_34_action_data_1_bit_params.p4 | 114 - ...ig_35_action_data_1_bit_params_and_imms.p4 | 113 - .../test_config_36_action_data_field_param.p4 | 43 - .../test_config_37_action_data_field_field.p4 | 46 - ...fig_38_action_data_field_same_container.p4 | 46 - ...test_config_39_action_data_add_to_field.p4 | 46 - .../test_config_3_add_to_field.PHV_BUG | 74 - .../test_config_40_action_data_bit_xor.p4 | 46 - ...est_config_41_action_data_remove_header.p4 | 46 - .../test_config_42_action_data_add_header.p4 | 45 - .../test_config_43_action_data_drop.PHV_BUG | 46 - .../test_config_44_action_data_immediate.p4 | 47 - ...ction_data_immediate_param_and_constant.p4 | 49 - ...test_config_46_action_data_big_constant.p4 | 87 - ...g_47_action_data_big_constant_immediate.p4 | 87 - ...st_config_48_action_data_bit_masked_set.p4 | 44 - ...49_action_data_bit_masked_set_immediate.p4 | 50 - .../internal/test_config_4_modify_field.p4 | 65 - ...ig_50_action_data_different_size_fields.p4 | 44 - ...ction_data_same_parameter_used_multiple.p4 | 51 - .../internal/test_config_52_copy_header.p4 | 45 - .../test_config_53_ternary_swizzle.p4 | 43 - ...fig_54_modify_field_different_size.PHV_BUG | 51 - .../test_config_55_generate_digest.p4 | 42 - .../test_config_56_iterate_through_packing.p4 | 39 - ..._config_57_tcam_with_44_bits_no_version.p4 | 41 - .../test_config_58_tcam_with_40_bits.p4 | 41 - ...config_59_tcam_with_44_bits_and_version.p4 | 41 - .../internal/test_config_5_sram_allocation.p4 | 69 - ...tcam_with_44_and_no_version_high_nibble.p4 | 41 - ..._with_44_bits_and_no_version_low_nibble.p4 | 41 - ...config_62_tcam_with_48_bits_and_version.p4 | 41 - ...fig_63_tcam_with_48_bits_and_no_version.p4 | 41 - ...config_64_tcam_with_84_bits_and_version.p4 | 41 - ...am_with_84_bits_high_nibble_and_version.p4 | 45 - ...cam_with_84_bits_low_nibble_and_version.p4 | 45 - ...cam_with_84_bits_high_nibble_no_version.p4 | 45 - ...tcam_with_84_bits_low_nibble_no_version.p4 | 45 - ...config_68_tcam_with_88_bits_and_version.p4 | 45 - ..._config_69_tcam_with_88_bits_no_version.p4 | 45 - .../test_config_6_sram_and_tcam_allocation.p4 | 131 - ...onfig_70_tcam_with_128_bits_and_version.p4 | 43 - ...ig_71_tcam_with_128_bits_and_no_version.p4 | 43 - ...onfig_72_tcam_with_172_bits_and_version.p4 | 45 - ...m_with_172_bits_high_nibble_and_version.p4 | 48 - ...am_with_172_bits_low_nibble_and_version.p4 | 48 - ...cam_with_172_bits_low_nibble_no_version.p4 | 48 - ...config_75_tcam_with_176_bits_no_version.p4 | 47 - ...onfig_76_tcam_with_176_bits_and_version.p4 | 47 - ...onfig_77_tcam_with_216_bits_and_version.p4 | 51 - ...m_with_220_bits_high_nibble_and_version.p4 | 56 - ...am_with_220_bits_high_nibble_no_version.p4 | 52 - ...cam_with_220_bits_low_nibble_no_version.p4 | 52 - ..._config_81_indirect_action_data_default.p4 | 60 - .../internal/test_config_82_param_sharing.p4 | 78 - ...no_immediate_when_indirect_action_table.p4 | 53 - .../test_config_84_simple_wide_exact_match.p4 | 53 - .../internal/test_config_85_table_ordering.p4 | 126 - ...tiple_action_widths_for_indirect_action.p4 | 95 - ...hare_parameter_for_different_containers.p4 | 59 - ...fig_88_testing_action_data_allocation_3.p4 | 192 - ...tion_data_allocation_3_with_partial_ram.p4 | 121 - .../internal/test_config_8_next_table.BUG | 175 - ...ta_allocation_3_with_fields_in_overhead.p4 | 121 - ...test_config_91_gateway_with_split_table.p4 | 77 - .../test_config_92_bit_xor_10_bits.p4 | 56 - .../internal/test_config_93_push_and_pop.p4 | 71 - ...est_config_94_action_constant_alignment.p4 | 75 - ...test_config_95_first_meter_table.NOT_READY | 105 - .../test/internal/test_config_96_hash_data.p4 | 171 - .../test_config_97_unrelated_tables.p4 | 94 - .../test_config_98_multiple_control_flow.p4 | 103 - .../test_config_99_share_exact_match_key.p4 | 91 - .../test_config_9_no_ternary_indirection.p4 | 92 - .../internal/test_tp_1_one_table_spill.p4 | 104 - .../test/internal/vk_basic_ipv4.PHV_BUG | 629 - .../test/internal/vk_basic_ipv4_20150706.p4 | 707 - .../test/internal/vk_basic_ipv4_subset.p4 | 189 - backends/tofino/bf-asm/test/jdiff.sh | 84 - backends/tofino/bf-asm/test/mac_rewrite.p4 | 149 - .../tofino/bf-asm/test/mau/01-FlexCounter.p4 | 89 - .../test/mau/02-FlexCounterActionProfile.p4 | 101 - .../tofino/bf-asm/test/mau/02-FullPHV1.p4 | 766 - .../tofino/bf-asm/test/mau/04-FieldProblem.p4 | 91 - .../tofino/bf-asm/test/mau/07-MacAddrCheck.p4 | 52 - .../bf-asm/test/mau/08-MacAddrCheck1.p4 | 55 - .../bf-asm/test/mau/08-MultiProtocolIfElse.p4 | 199 - .../bf-asm/test/mau/09-MacAddrCheck2.p4 | 56 - .../bf-asm/test/mau/10-AssignChooseSource.p4 | 100 - .../tofino/bf-asm/test/mau/12-Counters.p4 | 49 - .../test/mau/12-SmallToBigFieldWithMask8.p4 | 59 - backends/tofino/bf-asm/test/mau/14-Counter.p4 | 36 - .../test/mau/15-MultiProtocolIfElseMinimal.p4 | 107 - .../tofino/bf-asm/test/mau/16-NoHeaders.p4 | 19 - .../tofino/bf-asm/test/mau/19-SimpleTrill.p4 | 94 - .../bf-asm/test/mau/20-SimpleTrillTwoStep.p4 | 115 - .../test/mau/22-BigToSmallFieldWithMask8.p4 | 58 - .../test/mau/22-SimpleTrillThreeStep.p4 | 124 - .../tofino/bf-asm/test/mau/action_params.p4 | 136 - .../bf-asm/test/mau/basic_ipv4_selection.p4 | 215 - backends/tofino/bf-asm/test/mau/do_nothing.p4 | 36 - .../bf-asm/test/mau/expected_failures.txt | 111 - backends/tofino/bf-asm/test/mau/instruct1.p4 | 61 - backends/tofino/bf-asm/test/mau/selector1.p4 | 60 - .../tofino/bf-asm/test/mau/ternary_match0.p4 | 34 - backends/tofino/bf-asm/test/meter_test1.p4 | 69 - backends/tofino/bf-asm/test/parser1.p4 | 154 - backends/tofino/bf-asm/test/parser2.p4 | 255 - backends/tofino/bf-asm/test/parser3.p4 | 63 - backends/tofino/bf-asm/test/parser_dc_full.p4 | 959 - .../tofino/bf-asm/test/port_vlan_mapping.p4 | 1415 -- backends/tofino/bf-asm/test/proxy_hash1.p4 | 109 - .../bf-asm/test/ptf/action_spec_format.p4 | 464 - backends/tofino/bf-asm/test/ptf/alpm_test.p4 | 173 - backends/tofino/bf-asm/test/ptf/basic_ipv4.p4 | 866 - .../bf-asm/test/ptf/basic_ipv4_selector.p4 | 269 - .../tofino/bf-asm/test/ptf/basic_switching.p4 | 79 - backends/tofino/bf-asm/test/ptf/dkm.p4 | 214 - .../tofino/bf-asm/test/ptf/drivers_test.p4 | 477 - backends/tofino/bf-asm/test/ptf/easy.p4 | 32 - .../tofino/bf-asm/test/ptf/easy_ternary.p4 | 32 - backends/tofino/bf-asm/test/ptf/ecmp_pi.p4 | 221 - backends/tofino/bf-asm/test/ptf/emulation.p4 | 202 - backends/tofino/bf-asm/test/ptf/exm_direct.p4 | 723 - .../tofino/bf-asm/test/ptf/exm_direct_1.p4 | 780 - .../tofino/bf-asm/test/ptf/exm_indirect_1.p4 | 893 - .../tofino/bf-asm/test/ptf/exm_smoke_test.p4 | 766 - .../tofino/bf-asm/test/ptf/fast_reconfig.p4 | 279 - backends/tofino/bf-asm/test/ptf/fr_test.p4 | 635 - .../bf-asm/test/ptf/includes/headers.p4 | 41 - .../tofino/bf-asm/test/ptf/includes/parser.p4 | 46 - backends/tofino/bf-asm/test/ptf/iterator.p4 | 195 - .../tofino/bf-asm/test/ptf/mau_mem_test.p4 | 294 - .../tofino/bf-asm/test/ptf/mau_tcam_test.p4 | 282 - backends/tofino/bf-asm/test/ptf/mau_test.p4 | 1285 -- backends/tofino/bf-asm/test/ptf/meters.p4 | 447 - .../tofino/bf-asm/test/ptf/multi_device.p4 | 692 - .../tofino/bf-asm/test/ptf/multicast_scale.p4 | 120 - .../tofino/bf-asm/test/ptf/multicast_test.p4 | 279 - backends/tofino/bf-asm/test/ptf/p4features.h | 13 - .../tofino/bf-asm/test/ptf/parser_intr_md.p4 | 129 - .../tofino/bf-asm/test/ptf/pcie_pkt_test.p4 | 30 - backends/tofino/bf-asm/test/ptf/pctr.p4 | 226 - backends/tofino/bf-asm/test/ptf/perf_test.p4 | 245 - .../tofino/bf-asm/test/ptf/perf_test_alpm.p4 | 217 - backends/tofino/bf-asm/test/ptf/pgrs.p4 | 309 - .../tofino/bf-asm/test/ptf/pktgen_headers.p4 | 57 - backends/tofino/bf-asm/test/ptf/pvs.p4 | 160 - backends/tofino/bf-asm/test/ptf/range.p4 | 185 - backends/tofino/bf-asm/test/ptf/resubmit.p4 | 129 - .../bf-asm/test/ptf/smoke_large_tbls.p4 | 253 - backends/tofino/bf-asm/test/ptf/stats_pi.p4 | 171 - backends/tofino/bf-asm/test/ptf/stful.p4 | 932 - backends/tofino/bf-asm/test/ptf/tofino.p4 | 145 - .../bf-asm/test/ptf/tofino/constants.p4 | 52 - .../test/ptf/tofino/intrinsic_metadata.p4 | 445 - .../bf-asm/test/ptf/tofino/lpf_blackbox.p4 | 53 - .../bf-asm/test/ptf/tofino/meter_blackbox.p4 | 83 - .../bf-asm/test/ptf/tofino/pktgen_headers.p4 | 57 - .../bf-asm/test/ptf/tofino/primitives.p4 | 26 - .../test/ptf/tofino/stateful_alu_blackbox.p4 | 276 - .../bf-asm/test/ptf/tofino/wred_blackbox.p4 | 64 - .../tofino/bf-asm/test/ptf/tofino_diag.p4 | 158 - backends/tofino/bf-asm/test/runtests | 703 - backends/tofino/bf-asm/test/selector0.p4 | 60 - backends/tofino/bf-asm/test/selector1.p4 | 62 - backends/tofino/bf-asm/test/selector2.p4 | 62 - backends/tofino/bf-asm/test/selector3.p4 | 69 - .../tofino/bf-asm/test/stf/exact_match1.p4 | 51 - .../tofino/bf-asm/test/stf/exact_match1.stf | 8 - .../bf-asm/test/stf/hash_action_basic.p4 | 64 - .../bf-asm/test/stf/hash_action_basic.stf | 20 - .../tofino/bf-asm/test/stf/max_counters.p4 | 87 - .../tofino/bf-asm/test/stf/max_counters.stf | 14 - backends/tofino/bf-asm/test/stf/p4c-5198.bfa | 6776 ------- backends/tofino/bf-asm/test/stf/p4c-5198.stf | 11 - .../tofino/bf-asm/test/stf/simple_counter.p4 | 73 - .../tofino/bf-asm/test/stf/simple_counter.stf | 15 - backends/tofino/bf-asm/test/ternary_match0.p4 | 34 - backends/tofino/bf-asm/test/ternary_match1.p4 | 40 - .../tofino/bf-asm/test/ternary_match1.stf | 18 - backends/tofino/bf-asm/test/ternary_match2.p4 | 41 - .../tofino/bf-asm/test/ternary_match2.stf | 84 - backends/tofino/bf-asm/test/ternary_match3.p4 | 43 - .../tofino/bf-asm/test/ternary_match3.stf | 7 - backends/tofino/bf-asm/test/ternary_match4.p4 | 44 - .../tofino/bf-asm/test/ternary_match4.stf | 84 - backends/tofino/bf-asm/test/test-bfas-bin | 144 - backends/tofino/bf-asm/test/testgw.p4 | 91 - backends/tofino/bf-asm/test/triv_eth.p4 | 36 - backends/tofino/bf-asm/test/triv_ipv4.p4 | 72 - backends/tofino/bf-asm/test/update_config.py | 67 - backends/tofino/bf-asm/test/validate.py | 26 - .../bf-asm/test/validate_outer_ethernet.p4 | 170 - backends/tofino/bf-asm/test/wide_action1.p4 | 62 - backends/tofino/bf-asm/test/wide_action2.p4 | 81 - backends/tofino/bf-asm/test/wide_action3.p4 | 63 - 411 files changed, 1 insertion(+), 102875 deletions(-) delete mode 100644 backends/tofino/bf-asm/test/CMakeLists.txt delete mode 100644 backends/tofino/bf-asm/test/acl1.p4 delete mode 100644 backends/tofino/bf-asm/test/action_bus1.p4 delete mode 100644 backends/tofino/bf-asm/test/action_chain1.p4 delete mode 100644 backends/tofino/bf-asm/test/action_chain1.stf delete mode 100644 backends/tofino/bf-asm/test/action_chain2.p4 delete mode 100644 backends/tofino/bf-asm/test/asm/action_bus_alignment.tfa delete mode 100644 backends/tofino/bf-asm/test/asm/action_default_multiple.tfa delete mode 100644 backends/tofino/bf-asm/test/asm/always_run.jba delete mode 100644 backends/tofino/bf-asm/test/asm/always_run.stf delete mode 100644 backends/tofino/bf-asm/test/asm/counter_lrt1.tfa delete mode 100644 backends/tofino/bf-asm/test/asm/em1-clot.jba delete mode 100644 backends/tofino/bf-asm/test/asm/em1-clot.stf delete mode 100644 backends/tofino/bf-asm/test/asm/expected_failures.txt delete mode 100644 backends/tofino/bf-asm/test/asm/hash_action_basic.tfa delete mode 100644 backends/tofino/bf-asm/test/asm/hash_action_gateway2.stf delete mode 100644 backends/tofino/bf-asm/test/asm/hash_action_gateway2.tfa delete mode 100644 backends/tofino/bf-asm/test/asm/jbay_sful_syntax.jba delete mode 100644 backends/tofino/bf-asm/test/asm/network_tap.bfa delete mode 100644 backends/tofino/bf-asm/test/asm/p4c-2257.bfa delete mode 100644 backends/tofino/bf-asm/test/asm/p4c-4021.bfa delete mode 100644 backends/tofino/bf-asm/test/asm/parser_value_set.tfa delete mode 100644 backends/tofino/bf-asm/test/asm/parser_zero_write.jba delete mode 100644 backends/tofino/bf-asm/test/asm/rng.tfa delete mode 100644 backends/tofino/bf-asm/test/asm/stateful_multiple_output_error.tfa delete mode 100644 backends/tofino/bf-asm/test/asm/switch_l2_profile_tofino.tfa delete mode 100644 backends/tofino/bf-asm/test/asm/table_action_alias.tfa delete mode 100644 backends/tofino/bf-asm/test/asm/table_alias_fields_error.tfa delete mode 100644 backends/tofino/bf-asm/test/asm/tor.tfa delete mode 100644 backends/tofino/bf-asm/test/bfas_lookup_test/__init__.py delete mode 100644 backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_cases.py delete mode 100755 backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_test.py delete mode 100644 backends/tofino/bf-asm/test/checksum1.p4 delete mode 100644 backends/tofino/bf-asm/test/counter1.p4 delete mode 100644 backends/tofino/bf-asm/test/counter2.p4 delete mode 100644 backends/tofino/bf-asm/test/counter3.p4 delete mode 100644 backends/tofino/bf-asm/test/counter4.p4 delete mode 100644 backends/tofino/bf-asm/test/counter5.p4 delete mode 120000 backends/tofino/bf-asm/test/ctx_json delete mode 100644 backends/tofino/bf-asm/test/ctxt_json_ignore delete mode 100644 backends/tofino/bf-asm/test/ctxt_json_ignore_new delete mode 100644 backends/tofino/bf-asm/test/exact_match0.p4 delete mode 100644 backends/tofino/bf-asm/test/exact_match1.p4 delete mode 100644 backends/tofino/bf-asm/test/exact_match1.stf delete mode 100644 backends/tofino/bf-asm/test/exact_match2.p4 delete mode 100644 backends/tofino/bf-asm/test/exact_match3.p4 delete mode 100644 backends/tofino/bf-asm/test/exact_match4.p4 delete mode 100644 backends/tofino/bf-asm/test/exact_match5.p4 delete mode 100644 backends/tofino/bf-asm/test/exact_match6.p4 delete mode 100644 backends/tofino/bf-asm/test/exact_match7.p4 delete mode 100644 backends/tofino/bf-asm/test/exact_match8.p4 delete mode 100644 backends/tofino/bf-asm/test/exact_match9.p4 delete mode 100644 backends/tofino/bf-asm/test/exact_match_valid1.p4 delete mode 100644 backends/tofino/bf-asm/test/expected_failures.txt delete mode 100644 backends/tofino/bf-asm/test/gateway1.p4 delete mode 100644 backends/tofino/bf-asm/test/gateway2.p4 delete mode 100644 backends/tofino/bf-asm/test/gateway3.p4 delete mode 100644 backends/tofino/bf-asm/test/gateway4.p4 delete mode 100644 backends/tofino/bf-asm/test/gateway5.p4 delete mode 100644 backends/tofino/bf-asm/test/gateway6.p4 delete mode 100644 backends/tofino/bf-asm/test/gateway7.p4 delete mode 100644 backends/tofino/bf-asm/test/hash_index0.p4 delete mode 100644 backends/tofino/bf-asm/test/hash_index1.p4 delete mode 100644 backends/tofino/bf-asm/test/hash_index2.p4 delete mode 100644 backends/tofino/bf-asm/test/hash_index3.p4 delete mode 100644 backends/tofino/bf-asm/test/hash_index5.p4 delete mode 100644 backends/tofino/bf-asm/test/instruct1.p4 delete mode 100644 backends/tofino/bf-asm/test/instruct2.p4 delete mode 100644 backends/tofino/bf-asm/test/instruct3.p4 delete mode 100644 backends/tofino/bf-asm/test/instruct4.p4 delete mode 100644 backends/tofino/bf-asm/test/instruct5.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/brig/expected_failures.txt delete mode 100644 backends/tofino/bf-asm/test/internal/brig/test_config_123_meter_2.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/brig/test_config_223_simple_set_metadata.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/debug_issue_1_invalid_action_pack_format.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/debug_issue_2_action_data_bus.PRAGMA delete mode 100644 backends/tofino/bf-asm/test/internal/debug_issue_3_7_way_table.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/debug_issue_4_small_exact_match_key.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/dileep.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/dileep10.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/dileep11.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/dileep12.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/dileep2.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/dileep3.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/dileep4.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/dileep5.PRAGMA delete mode 100644 backends/tofino/bf-asm/test/internal/dileep6.PHV_BUG delete mode 100644 backends/tofino/bf-asm/test/internal/dileep7-b.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/dileep7.PRAGMA delete mode 100644 backends/tofino/bf-asm/test/internal/dileep8.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/dileep9.PRAGMA delete mode 100644 backends/tofino/bf-asm/test/internal/google-tor/lag.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/google-tor/tor.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_7_storm_control.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_100_hash_action.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_101_switch_msdc.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_102_clone.NOT_READY delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_102_clone.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_103_first_phase_0.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_10_new_crossbar_allocation.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_114_simple_drop.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_115_hash_parity_groups.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_116_predication_with_condition.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_117_first_tcam_range.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_118_tcam_range_2.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_119_tcam_range_3.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_11_simple_gateway_table.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_120_tcam_range_4.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_121_tcam_range_5.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_122_tcam_range_6.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_123_meter_2.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_124_meter_3.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_125_meter_pre_color.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_126_meter_pre_color_2.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_127_meter_pre_color_3.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_128_table_placement_bug.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_12_no_overhead.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_130_test_default_action.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_132_meter_pre_color_4.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_134_stage_deps.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_135_tcam_range_7.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_136_tcam_error_detection.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_137_tcam_error_detection_2.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_138_tcam_error_detection_3.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_139_tcam_error_detection_4.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_13_first_selection.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_140_table_counter.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_142_stateful_bfd.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_143_packing_constants.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_144_recirculate.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_145_shift_primitives.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_146_two_drops.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_147_subtract_primitive.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_148_action_profile.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_149_signed_and_saturating_add_sub.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_14_auto_immediate_action_data.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_150_action_bus_allocation.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_151_action_bus_allocation_2.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_152_stateful_simple_cntr.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_153_stateful_simple_cntr_with_output.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_154_stateful_sampling.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_155_stateful_3_alus.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_156_indirect_stateful_cntr.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_157_random_number_generator.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_158_share_vliw.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_159_stateful_using_phv_field.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_15_wide_key.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_160_stateful_single_bit_mode.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_161_new_primitives.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_162_add_header_init.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_163_stateful_table_math_unit.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_164_stateful_deterministic_sampling.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_165_stateful_bfd_failure_detection.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_166_stateful_generic_counter.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_167_stateful_flowlet_switching.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_168_meter_bug.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_169_stateful_sflow_sequence.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_16_action_packing_multi_entry_with_pad.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_170_stateful_selection_table_update.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_171_stateful_conga.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_172_stateful_heavy_hitter.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_173_stateful_bloom_filter.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_175_match_table_with_no_key.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_176_extend_crc16.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_177_meter_test.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_178_hash_action.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_179_check_if_sequential_action_used.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_17_action_packing_wide_with_pad.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_180_first_proxy_hash.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_181_first_alg_tcam.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_182_warp_primitive.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_183_sample_e2e.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_184_stateful_bug1.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_185_first_lpf.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_186_hlir_modify.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_187_proxy_hash_2.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_188_action_data_overflow.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_189_stat_with_lrt.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_18_first_bit_xor.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_190_modify_with_expr.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_191_invalidate.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_192_stateful_driven_by_hash.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_193_indirect_stats_no_reads.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_194_same_action_param.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_195_stateful_predicate_output.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_196_hit_miss.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_197_default_next_table.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_198_shared_action_profile.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_199_stateful_constant_index.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_19_immediate_but_no_action_data_table.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_1_ternary_match_crossbar.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_200_counter_constant_index.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_201_meter_constant_index.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_202_write_same_byte.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_203_first_reduction_or.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_204_no_tables_in_stage0.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_205_modify_field_from_hash.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_206_stateful_logging.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_207_not_gateway.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_208_table_no_key.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_209_pack_hash_dist.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_20_table_dependencies.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_21_tcam_vpns.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_22_direct_mapped_exact.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_23_same_container_modified.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_24_action_entries_pragma.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_25_no_reads_for_table.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_26_direct_add_primitive.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_2_action_data_table_sizing.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_30_action_data_imm_param.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_31_action_data_imm_imm.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_32_action_data_imm_param_imm.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_33_action_data_paramx3.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_34_action_data_1_bit_params.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_35_action_data_1_bit_params_and_imms.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_36_action_data_field_param.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_37_action_data_field_field.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_38_action_data_field_same_container.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_39_action_data_add_to_field.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_3_add_to_field.PHV_BUG delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_40_action_data_bit_xor.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_41_action_data_remove_header.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_42_action_data_add_header.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_43_action_data_drop.PHV_BUG delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_44_action_data_immediate.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_45_action_data_immediate_param_and_constant.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_46_action_data_big_constant.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_47_action_data_big_constant_immediate.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_48_action_data_bit_masked_set.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_49_action_data_bit_masked_set_immediate.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_4_modify_field.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_50_action_data_different_size_fields.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_51_action_data_same_parameter_used_multiple.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_52_copy_header.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_53_ternary_swizzle.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_54_modify_field_different_size.PHV_BUG delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_55_generate_digest.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_56_iterate_through_packing.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_57_tcam_with_44_bits_no_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_58_tcam_with_40_bits.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_59_tcam_with_44_bits_and_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_5_sram_allocation.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_60_tcam_with_44_and_no_version_high_nibble.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_61_tcam_with_44_bits_and_no_version_low_nibble.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_62_tcam_with_48_bits_and_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_63_tcam_with_48_bits_and_no_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_64_tcam_with_84_bits_and_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_64_tcam_with_84_bits_high_nibble_and_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_65_tcam_with_84_bits_low_nibble_and_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_66_tcam_with_84_bits_high_nibble_no_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_67_tcam_with_84_bits_low_nibble_no_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_68_tcam_with_88_bits_and_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_69_tcam_with_88_bits_no_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_6_sram_and_tcam_allocation.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_70_tcam_with_128_bits_and_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_71_tcam_with_128_bits_and_no_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_72_tcam_with_172_bits_and_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_72_tcam_with_172_bits_high_nibble_and_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_73_tcam_with_172_bits_low_nibble_and_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_74_tcam_with_172_bits_low_nibble_no_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_75_tcam_with_176_bits_no_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_76_tcam_with_176_bits_and_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_77_tcam_with_216_bits_and_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_78_tcam_with_220_bits_high_nibble_and_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_79_tcam_with_220_bits_high_nibble_no_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_80_tcam_with_220_bits_low_nibble_no_version.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_81_indirect_action_data_default.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_82_param_sharing.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_83_no_immediate_when_indirect_action_table.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_84_simple_wide_exact_match.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_85_table_ordering.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_86_multiple_action_widths_for_indirect_action.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_87_share_parameter_for_different_containers.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_88_testing_action_data_allocation_3.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_89_testing_action_data_allocation_3_with_partial_ram.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_8_next_table.BUG delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_90_testing_action_data_allocation_3_with_fields_in_overhead.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_91_gateway_with_split_table.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_92_bit_xor_10_bits.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_93_push_and_pop.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_94_action_constant_alignment.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_95_first_meter_table.NOT_READY delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_96_hash_data.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_97_unrelated_tables.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_98_multiple_control_flow.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_99_share_exact_match_key.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_config_9_no_ternary_indirection.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/test_tp_1_one_table_spill.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/vk_basic_ipv4.PHV_BUG delete mode 100644 backends/tofino/bf-asm/test/internal/vk_basic_ipv4_20150706.p4 delete mode 100644 backends/tofino/bf-asm/test/internal/vk_basic_ipv4_subset.p4 delete mode 100755 backends/tofino/bf-asm/test/jdiff.sh delete mode 100644 backends/tofino/bf-asm/test/mac_rewrite.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/01-FlexCounter.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/02-FlexCounterActionProfile.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/02-FullPHV1.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/04-FieldProblem.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/07-MacAddrCheck.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/08-MacAddrCheck1.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/08-MultiProtocolIfElse.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/09-MacAddrCheck2.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/10-AssignChooseSource.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/12-Counters.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/12-SmallToBigFieldWithMask8.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/14-Counter.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/15-MultiProtocolIfElseMinimal.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/16-NoHeaders.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/19-SimpleTrill.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/20-SimpleTrillTwoStep.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/22-BigToSmallFieldWithMask8.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/22-SimpleTrillThreeStep.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/action_params.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/basic_ipv4_selection.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/do_nothing.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/expected_failures.txt delete mode 100644 backends/tofino/bf-asm/test/mau/instruct1.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/selector1.p4 delete mode 100644 backends/tofino/bf-asm/test/mau/ternary_match0.p4 delete mode 100644 backends/tofino/bf-asm/test/meter_test1.p4 delete mode 100644 backends/tofino/bf-asm/test/parser1.p4 delete mode 100644 backends/tofino/bf-asm/test/parser2.p4 delete mode 100644 backends/tofino/bf-asm/test/parser3.p4 delete mode 100644 backends/tofino/bf-asm/test/parser_dc_full.p4 delete mode 100644 backends/tofino/bf-asm/test/port_vlan_mapping.p4 delete mode 100644 backends/tofino/bf-asm/test/proxy_hash1.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/action_spec_format.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/alpm_test.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/basic_ipv4.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/basic_ipv4_selector.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/basic_switching.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/dkm.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/drivers_test.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/easy.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/easy_ternary.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/ecmp_pi.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/emulation.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/exm_direct.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/exm_direct_1.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/exm_indirect_1.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/exm_smoke_test.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/fast_reconfig.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/fr_test.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/includes/headers.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/includes/parser.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/iterator.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/mau_mem_test.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/mau_tcam_test.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/mau_test.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/meters.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/multi_device.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/multicast_scale.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/multicast_test.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/p4features.h delete mode 100644 backends/tofino/bf-asm/test/ptf/parser_intr_md.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/pcie_pkt_test.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/pctr.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/perf_test.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/perf_test_alpm.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/pgrs.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/pktgen_headers.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/pvs.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/range.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/resubmit.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/smoke_large_tbls.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/stats_pi.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/stful.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/tofino.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/tofino/constants.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/tofino/intrinsic_metadata.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/tofino/lpf_blackbox.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/tofino/meter_blackbox.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/tofino/pktgen_headers.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/tofino/primitives.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/tofino/stateful_alu_blackbox.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/tofino/wred_blackbox.p4 delete mode 100644 backends/tofino/bf-asm/test/ptf/tofino_diag.p4 delete mode 100755 backends/tofino/bf-asm/test/runtests delete mode 100644 backends/tofino/bf-asm/test/selector0.p4 delete mode 100644 backends/tofino/bf-asm/test/selector1.p4 delete mode 100644 backends/tofino/bf-asm/test/selector2.p4 delete mode 100644 backends/tofino/bf-asm/test/selector3.p4 delete mode 100644 backends/tofino/bf-asm/test/stf/exact_match1.p4 delete mode 100644 backends/tofino/bf-asm/test/stf/exact_match1.stf delete mode 100644 backends/tofino/bf-asm/test/stf/hash_action_basic.p4 delete mode 100644 backends/tofino/bf-asm/test/stf/hash_action_basic.stf delete mode 100644 backends/tofino/bf-asm/test/stf/max_counters.p4 delete mode 100644 backends/tofino/bf-asm/test/stf/max_counters.stf delete mode 100644 backends/tofino/bf-asm/test/stf/p4c-5198.bfa delete mode 100644 backends/tofino/bf-asm/test/stf/p4c-5198.stf delete mode 100644 backends/tofino/bf-asm/test/stf/simple_counter.p4 delete mode 100644 backends/tofino/bf-asm/test/stf/simple_counter.stf delete mode 100644 backends/tofino/bf-asm/test/ternary_match0.p4 delete mode 100644 backends/tofino/bf-asm/test/ternary_match1.p4 delete mode 100644 backends/tofino/bf-asm/test/ternary_match1.stf delete mode 100644 backends/tofino/bf-asm/test/ternary_match2.p4 delete mode 100644 backends/tofino/bf-asm/test/ternary_match2.stf delete mode 100644 backends/tofino/bf-asm/test/ternary_match3.p4 delete mode 100644 backends/tofino/bf-asm/test/ternary_match3.stf delete mode 100644 backends/tofino/bf-asm/test/ternary_match4.p4 delete mode 100644 backends/tofino/bf-asm/test/ternary_match4.stf delete mode 100755 backends/tofino/bf-asm/test/test-bfas-bin delete mode 100644 backends/tofino/bf-asm/test/testgw.p4 delete mode 100644 backends/tofino/bf-asm/test/triv_eth.p4 delete mode 100644 backends/tofino/bf-asm/test/triv_ipv4.p4 delete mode 100644 backends/tofino/bf-asm/test/update_config.py delete mode 100755 backends/tofino/bf-asm/test/validate.py delete mode 100644 backends/tofino/bf-asm/test/validate_outer_ethernet.p4 delete mode 100644 backends/tofino/bf-asm/test/wide_action1.p4 delete mode 100644 backends/tofino/bf-asm/test/wide_action2.p4 delete mode 100644 backends/tofino/bf-asm/test/wide_action3.p4 diff --git a/backends/tofino/bf-asm/CMakeLists.txt b/backends/tofino/bf-asm/CMakeLists.txt index 012875e8d17..5afc518db18 100644 --- a/backends/tofino/bf-asm/CMakeLists.txt +++ b/backends/tofino/bf-asm/CMakeLists.txt @@ -262,29 +262,11 @@ add_dependencies(linkbfas bfas) add_dependencies(p4c_driver linkbfas) -add_custom_target(check-asm - COMMAND export BUILDDIR=${BFASM_GEN_DIR} && cd ${BFASM_SOURCE_DIR}/test && - ./runtests asm/*.tfa asm/*.jba asm/*.bfa asm/*.stf) - -# This is broken and it doesn't make sense to use p4 tests here anyways -# add_custom_target(check-all-asm -# COMMAND export BUILDDIR=${BFASM_GEN_DIR} && cd ${BFASM_SOURCE_DIR}/test && -# ./runtests -f asm/*.tfa *.p4 mau/*.p4 -# COMMAND export BUILDDIR=${BFASM_GEN_DIR} && cd ${BFASM_SOURCE_DIR}/test && -# ./runtests -f -b stf/*.stf brig/*.p4) - -add_custom_target(check-sanity - COMMAND export BUILDDIR=${BFASM_GEN_DIR} && cd ${BFASM_SOURCE_DIR}/test && - ./runtests *.p4) - string(CONFIGURE "/^DECLARE_(ABSTRACT_)?TABLE_TYPE\(([a-zA-Z0-9_]+)/2/c/" CTAGS_CXX_REGEXP @ONLY) add_custom_target(ctags-asm - COMMAND ctags -R -I VECTOR --exclude=test --exclude=submodules - "--regex-C++=${CTAGS_CXX_REGEXP}" + COMMAND ctags -R -I VECTOR "--regex-C++=${CTAGS_CXX_REGEXP}" COMMENT "Generating ctags") -# Build the bf-asm test suite -add_subdirectory(test) if (ENABLE_GTESTS) # TODO Components need to be built, once, into intermediate libraries. diff --git a/backends/tofino/bf-asm/test/CMakeLists.txt b/backends/tofino/bf-asm/test/CMakeLists.txt deleted file mode 100644 index 0e0df7246b9..00000000000 --- a/backends/tofino/bf-asm/test/CMakeLists.txt +++ /dev/null @@ -1,112 +0,0 @@ -####### Tofino assembler -- tests -cmake_minimum_required (VERSION 3.16.3 FATAL_ERROR) - -project (BFASM_TEST) - -set (CMAKE_MODULE_PATH ${BFN_P4C_SOURCE_DIR}/p4c/cmake) - -MESSAGE("-- Adding bf-asm test suite") - -# common test utils -#include(../../p4-tests/TestUtils.cmake) - -if (ENABLE_TEST_ISOLATION) - get_filename_component(P4C_RUNTEST ../../p4-tests/internal/runtest-isolated REALPATH) -else() - get_filename_component(P4C_RUNTEST ../../p4-tests/runtest REALPATH) -endif() - - -# extra test args can be passed as unamed arguments -function(bfas_add_test_with_args device toolsdevice alias bfafile test_args cmake_args) - # create the test - MESSAGE("Invoking: p4c_add_test_with_args (${device} ${P4C_RUNTEST} FALSE ${alias} ${bfafile} \"${test_args}\" \"-${device} ${cmake_args}\")") - MESSAGE("#macro(p4c_add_test_with_args tag driver isXfail alias p4test test_args cmake_args)") - #macro(p4c_add_test_with_args tag driver isXfail alias p4test test_args cmake_args) - p4c_add_test_with_args (${device} ${P4C_RUNTEST} FALSE ${alias} - ${bfafile} "${test_args}" "-${device} ${cmake_args}") - if (PTF_REQUIREMENTS_MET) - set(__havePTF 0) - string (REGEX REPLACE ".bfa$" ".stf" __stffile ${bfafile}) - if (ENABLE_STF2PTF AND NOT ${__havePTF} AND EXISTS ${BFASM_TEST_SOURCE_DIR}/${__stffile}) - # Also add as PTF test the STF - # MESSAGE(STATUS "STF2PTF: Generating ${P4C_BINARY_DIR}/${device}/${__ptffile}/test.py") - set(__havePTF 1) - endif() - if (${__havePTF}) - p4c_test_set_name(__testname ${device} ${alias}) - set_ptf_test_locks(${__testname}) - p4c_add_test_label(${device} "ptf" ${alias}) - endif() - endif() # PTF_REQUIREMENTS_MET - if (HARLYN_STF_${toolsdevice}) - string (REGEX REPLACE ".bfa$" ".stf" __stffile ${bfafile}) - if (EXISTS ${BFASM_TEST_SOURCE_DIR}/${__stffile}) - p4c_add_test_label(${device} "stf" ${alias}) - endif() - endif(HARLYN_STF_${toolsdevice}) -endfunction(bfas_add_test_with_args) - -# extra test args can be passed as unamed arguments -#macro(p4c_add_bf_backend_tests device toolsdevice arch label tests) -#endmacro(p4c_add_bf_backend_tests) -macro(bfas_add_tests device toolsdevice arch label tests) - set (_testExtraArgs "${ARGN}") - # do not add the device directly to _testExtraArgs - # this is used later to add other tests for multiple configurations. - # set (_testExtraArgs "${_testExtraArgs} -${device}") - - # if STF is not found, disable all stf tests - if (NOT HARLYN_STF_${toolsdevice}) - set (_testExtraArgs "${_testExtraArgs} -norun") - endif() - - if (PTF_REQUIREMENTS_MET) - set (_testExtraArgs "${_testExtraArgs} -ptf") - if (ENABLE_STF2PTF) - if ( "${device}" STREQUAL "tofino") - set (_testExtraArgs "${_testExtraArgs} -stf2ptf") - endif() - endif() - endif() - - # If label is not empty, add it to the tests - foreach (ts "${tests}") - MESSAGE("Processing ${ts}") - file (GLOB __testfiles RELATIVE ${BFASM_SOURCE_DIR} ${ts}) - foreach (__p4file ${__testfiles}) - bfas_add_backend_test_and_label(${device} ${toolsdevice} ${__p4file} ${__p4file} "${label}" - "${_testExtraArgs}" "") - endforeach() # __p4file - endforeach() -endmacro(bfas_add_tests) - -macro(bfas_add_backend_test_and_label device toolsdevice alias bfa_file label test_args cmake_args) - bfas_add_test_with_args(${device} ${toolsdevice} ${alias} ${bfa_file} "${test_args}" "${cmake_args}") - p4c_add_test_label(${device} "${label}" ${alias}) -endmacro(bfas_add_backend_test_and_label ) - - -if (ENABLE_TESTING) - # Replace P4C source/binary paths temporarily to override the defaults used by p4c_add_test_with_args - set(P4C_SOURCE_DIR_ORIG ${P4C_SOURCE_DIR}) - set(P4C_SOURCE_DIR ${BFASM_SOURCE_DIR}) - set(P4C_BINARY_DIR_ORIG ${P4C_BINARY_DIR}) - set(P4C_BINARY_DIR ${BFASM_BINARY_DIR}) - - set (JBAY_INCLUDE_PATTERNS "target:.*Tofino2") - #set (JBAY_EXCLUDE_PATTERNS ) - #set (JBAY_EXCLUDE_FILES ) - - set (BFA_FILES - "${CMAKE_CURRENT_SOURCE_DIR}/stf/*.bfa") - p4c_find_tests("${BFA_FILES}" JBAY_TESTS_PRE1 INCLUDE "${JBAY_INCLUDE_PATTERNS}" EXCLUDE "${JBAY_EXCLUDE_PATTERNS}") - bfn_find_tests("${JBAY_TESTS_PRE1}" JBAY_TESTS EXCLUDE "${JBAY_EXCLUDE_FILES}") - - bfas_add_tests("tofino2_asm" "jbay" "bfas_jbay" "base" "${JBAY_TESTS}") - - # Restore the P4C source/binary dirs - set(P4C_SOURCE_DIR ${P4C_SOURCE_DIR_ORIG}) - set(P4C_BINARY_DIR ${P4C_BINARY_DIR_ORIG}) -endif() - diff --git a/backends/tofino/bf-asm/test/acl1.p4 b/backends/tofino/bf-asm/test/acl1.p4 deleted file mode 100644 index 3e4417736da..00000000000 --- a/backends/tofino/bf-asm/test/acl1.p4 +++ /dev/null @@ -1,319 +0,0 @@ - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -/* - * ACL and QoS metadata - */ -header_type acl_metadata_t { - fields { - acl_deny : 1; /* ifacl/vacl deny action */ - racl_deny : 1; /* racl deny action */ - acl_nexthop : 16; /* next hop from ifacl/vacl */ - racl_nexthop : 16; /* next hop from racl */ - acl_nexthop_type : 1; /* ecmp or nexthop */ - racl_nexthop_type : 1; /* ecmp or nexthop */ - acl_redirect : 1; /* ifacl/vacl redirect action */ - racl_redirect : 1; /* racl redirect action */ - if_label : 15; /* if label for acls */ - bd_label : 16; /* bd label for acls */ - mirror_session_id : 10; /* mirror session id */ - } -} - -@pragma pa_solitary ingress acl_metadata.if_label - -metadata acl_metadata_t acl_metadata; - -header_type ingress_metadata_t { - fields { - ingress_port : 9; /* input physical port */ - ifindex : 16; /* input interface index */ - egress_ifindex : 16; /* egress interface index */ - port_type : 2; /* ingress port type */ - - outer_bd : 16; /* outer BD */ - bd : 16; /* BD */ - - drop_flag : 1; /* if set, drop the packet */ - drop_reason : 8; /* drop reason */ - control_frame: 1; /* control frame */ - enable_dod : 1; /* enable deflect on drop */ - } -} - -metadata ingress_metadata_t ingress_metadata; - -header_type fabric_metadata_t { - fields { - packetType : 3; - fabric_header_present : 1; - reason_code : 16; /* cpu reason code */ - } -} - -metadata fabric_metadata_t fabric_metadata; - -header_type ipv4_metadata_t { - fields { - lkp_ipv4_sa : 32; - lkp_ipv4_da : 32; - ipv4_unicast_enabled : 1; /* is ipv4 unicast routing enabled */ - ipv4_urpf_mode : 2; /* 0: none, 1: strict, 3: loose */ - } -} - -metadata ipv4_metadata_t ipv4_metadata; - -header_type ipv6_metadata_t { - fields { - lkp_ipv6_sa : 128; /* ipv6 source address */ - lkp_ipv6_da : 128; /* ipv6 destination address*/ - - ipv6_unicast_enabled : 1; /* is ipv6 unicast routing enabled on BD */ - ipv6_src_is_link_local : 1; /* source is link local address */ - ipv6_urpf_mode : 2; /* 0: none, 1: strict, 3: loose */ - } -} - -//@pragma pa_alias ingress ipv4_metadata.lkp_ipv4_sa ipv6_metadata.lkp_ipv6_sa -//@pragma pa_alias ingress ipv4_metadata.lkp_ipv4_da ipv6_metadata.lkp_ipv6_da - -metadata ipv6_metadata_t ipv6_metadata; - - -header_type l2_metadata_t { - fields { - lkp_pkt_type : 3; - lkp_mac_sa : 48; - lkp_mac_da : 48; - lkp_mac_type : 16; - - l2_nexthop : 16; /* next hop from l2 */ - l2_nexthop_type : 1; /* ecmp or nexthop */ - l2_redirect : 1; /* l2 redirect action */ - l2_src_miss : 1; /* l2 source miss */ - l2_src_move : 16; /* l2 source interface mis-match */ - stp_group: 10; /* spanning tree group id */ - stp_state : 3; /* spanning tree port state */ - bd_stats_idx : 16; /* ingress BD stats index */ - learning_enabled : 1; /* is learning enabled */ - port_vlan_mapping_miss : 1; /* port vlan mapping miss */ - same_if_check : 16; /* same interface check */ - } -} - -metadata l2_metadata_t l2_metadata; - -header_type l3_metadata_t { - fields { - lkp_ip_type : 2; - lkp_ip_version : 4; - lkp_ip_proto : 8; - lkp_ip_tc : 8; - lkp_ip_ttl : 8; - lkp_l4_sport : 16; - lkp_l4_dport : 16; - lkp_inner_l4_sport : 16; - lkp_inner_l4_dport : 16; - - vrf : 12; /* VRF */ - rmac_group : 10; /* Rmac group, for rmac indirection */ - rmac_hit : 1; /* dst mac is the router's mac */ - urpf_mode : 2; /* urpf mode for current lookup */ - urpf_hit : 1; /* hit in urpf table */ - urpf_check_fail :1; /* urpf check failed */ - urpf_bd_group : 16; /* urpf bd group */ - fib_hit : 1; /* fib hit */ - fib_nexthop : 16; /* next hop from fib */ - fib_nexthop_type : 1; /* ecmp or nexthop */ - same_bd_check : 16; /* ingress bd xor egress bd */ - nexthop_index : 16; /* nexthop/rewrite index */ - routed : 1; /* is packet routed? */ - outer_routed : 1; /* is outer packet routed? */ - mtu_index : 8; /* index into mtu table */ - l3_mtu_check : 16 (saturating); /* result of mtu check */ - } -} - -metadata l3_metadata_t l3_metadata; - -header_type security_metadata_t { - fields { - storm_control_color : 1; /* 0 : pass, 1 : fail */ - ipsg_enabled : 1; /* is ip source guard feature enabled */ - ipsg_check_fail : 1; /* ipsg check failed */ - } -} - -metadata security_metadata_t security_metadata; - -header_type tunnel_metadata_t { - fields { - ingress_tunnel_type : 5; /* tunnel type from parser */ - tunnel_vni : 24; /* tunnel id */ - mpls_enabled : 1; /* is mpls enabled on BD */ - mpls_label: 20; /* Mpls label */ - mpls_exp: 3; /* Mpls Traffic Class */ - mpls_ttl: 8; /* Mpls Ttl */ - egress_tunnel_type : 5; /* type of tunnel */ - tunnel_index: 14; /* tunnel index */ - tunnel_src_index : 9; /* index to tunnel src ip */ - tunnel_smac_index : 9; /* index to tunnel src mac */ - tunnel_dst_index : 14; /* index to tunnel dst ip */ - tunnel_dmac_index : 14; /* index to tunnel dst mac */ - vnid : 24; /* tunnel vnid */ - tunnel_terminate : 1; /* is tunnel being terminated? */ - tunnel_if_check : 1; /* tun terminate xor originate */ - egress_header_count: 4; /* number of mpls header stack */ - } -} -metadata tunnel_metadata_t tunnel_metadata; - -/*****************************************************************************/ -/* System ACL */ -/*****************************************************************************/ -counter drop_stats { - type : packets; - instance_count : 256; -} - -counter drop_stats_2 { - type : packets; - instance_count : 256; -} - -field_list mirror_info { - ingress_metadata.ifindex; - ingress_metadata.drop_reason; -} - -action negative_mirror(session_id) { - //clone_ingress_pkt_to_egress(session_id, mirror_info); - //drop(); -} - -action redirect_to_cpu(reason_code) { - copy_to_cpu(reason_code); - //drop(); -} - -field_list cpu_info { - ingress_metadata.bd; - ingress_metadata.ifindex; - fabric_metadata.reason_code; -} - -action copy_to_cpu(reason_code) { - modify_field(fabric_metadata.reason_code, reason_code); - //clone_ingress_pkt_to_egress(250, cpu_info); -} - -action drop_packet() { - //drop(); -} - -action drop_packet_with_reason(drop_reason) { - count(drop_stats, drop_reason); - //drop(); -} - -action congestion_mirror_set() { -} - -action nop() { -} - - -table system_acl { - reads { - acl_metadata.if_label : ternary; - acl_metadata.bd_label : ternary; - - /* ip acl */ - ipv4_metadata.lkp_ipv4_sa : ternary; - ipv4_metadata.lkp_ipv4_da : ternary; - l3_metadata.lkp_ip_proto : ternary; - - /* mac acl */ - l2_metadata.lkp_mac_sa : ternary; - l2_metadata.lkp_mac_da : ternary; - l2_metadata.lkp_mac_type : ternary; - - ingress_metadata.ifindex : ternary; - - /* drop reasons */ - l2_metadata.port_vlan_mapping_miss : ternary; - security_metadata.ipsg_check_fail : ternary; - acl_metadata.acl_deny : ternary; - acl_metadata.racl_deny: ternary; - l3_metadata.urpf_check_fail : ternary; - ingress_metadata.drop_flag : ternary; - - l3_metadata.rmac_hit : ternary; - - /* - * other checks, routed link_local packet, l3 same if check, - * expired ttl - */ - l3_metadata.routed : ternary; - ipv6_metadata.ipv6_src_is_link_local : ternary; - l2_metadata.same_if_check : ternary; - tunnel_metadata.tunnel_if_check : ternary; - l3_metadata.same_bd_check : ternary; - l3_metadata.lkp_ip_ttl : ternary; - l2_metadata.stp_state : ternary; - ingress_metadata.control_frame: ternary; - ipv4_metadata.ipv4_unicast_enabled : ternary; - - /* egress information */ - ingress_metadata.egress_ifindex : ternary; - - /* deflect on drop (-ve mirror) */ - ingress_metadata.enable_dod: ternary; - } - actions { - nop; - redirect_to_cpu; - copy_to_cpu; - drop_packet; - drop_packet_with_reason; - negative_mirror; - congestion_mirror_set; - } - size : 512; -} - -action drop_stats_update() { - count(drop_stats_2, ingress_metadata.drop_reason); -} - -table drop_stats { - actions { - drop_stats_update; - } - size : 256; -} - -control ingress { - apply(system_acl); - if (ingress_metadata.drop_flag == 1) { - apply(drop_stats); - } -} diff --git a/backends/tofino/bf-asm/test/action_bus1.p4 b/backends/tofino/bf-asm/test/action_bus1.p4 deleted file mode 100644 index 490be365449..00000000000 --- a/backends/tofino/bf-asm/test/action_bus1.p4 +++ /dev/null @@ -1,40 +0,0 @@ -/* try to fill the action bus with 32-bit values... */ -#define REP5(M, ...) M(__VA_ARGS__, 1) M(__VA_ARGS__, 2) M(__VA_ARGS__, 3) \ - M(__VA_ARGS__, 4) M(__VA_ARGS__, 5) -#define REP8(M, ...) M(__VA_ARGS__, 1) M(__VA_ARGS__, 2) M(__VA_ARGS__, 3) \ - M(__VA_ARGS__, 4) M(__VA_ARGS__, 5) M(__VA_ARGS__, 6) \ - M(__VA_ARGS__, 7) M(__VA_ARGS__, 8) - -header_type data_t { - fields { -#define F32(A,B) f##A##_##B : 32; -REP8(REP5,F32) - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -#define MF(A,B) modify_field(data.f##A##_##B, v##B); -#define SET(_,A) action set##A(v1,v2,v3,v4,v5) { REP5(MF,A) } -REP8(SET) - -#define TBL(_,A) table tbl##A { \ - reads { \ - data.f##A##_1 : exact; \ - } \ - actions { \ - set##A; \ - noop; \ - } \ -} -REP8(TBL) -#define USE_TBL(_,A) apply(tbl##A); - -control ingress { - REP8(USE_TBL) -} diff --git a/backends/tofino/bf-asm/test/action_chain1.p4 b/backends/tofino/bf-asm/test/action_chain1.p4 deleted file mode 100644 index f8c7d0a652e..00000000000 --- a/backends/tofino/bf-asm/test/action_chain1.p4 +++ /dev/null @@ -1,83 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - h1 : 16; - b1 : 8; - b2 : 8; - } -} - -header_type extra_t { - fields { - h : 16; - b1 : 8; - b2 : 8; - } -} - -header data_t data; -header extra_t extra[4]; - -parser start { - extract(data); - return extra; -} -parser extra { - extract(extra[next]); - return select(latest.b2) { - 0x80 mask 0x80: extra; - default: ingress; - } -} - -action setb1(port, val) { - modify_field(data.b1, val); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} -action noop() { } -action setb2(val) { modify_field(data.b2, val); } -action set0b1(val) { modify_field(extra[0].b1, val); } -action set1b1(val) { modify_field(extra[1].b1, val); } -action set2b2(val) { modify_field(extra[2].b2, val); } -action act1(val) { modify_field(extra[0].b1, val); } -action act2(val) { modify_field(extra[0].b1, val); } -action act3(val) { modify_field(extra[0].b1, val); } - -table test1 { - reads { data.f1 : ternary; } - actions { - setb1; - noop; - } -} -table ex1 { - reads { extra[0].h : ternary; } - actions { - set0b1; - act1; - act2; - act3; - noop; - } -} -table tbl1 { - reads { data.f2 : ternary; } - actions { setb2; noop; } } -table tbl2 { - reads { data.f2 : ternary; } - actions { set1b1; noop; } } -table tbl3 { - reads { data.f2 : ternary; } - actions { set2b2; noop; } } - -control ingress { - apply(test1); - apply(ex1) { - act1 { apply(tbl1); } - act2 { apply(tbl2); } - act3 { apply(tbl3); } - } -} diff --git a/backends/tofino/bf-asm/test/action_chain1.stf b/backends/tofino/bf-asm/test/action_chain1.stf deleted file mode 100644 index 766ff01b893..00000000000 --- a/backends/tofino/bf-asm/test/action_chain1.stf +++ /dev/null @@ -1,20 +0,0 @@ - -add test1 0 data.f1:0x****0101 setb1(val:0x7f, port:2) -add test1 503 data.f1:0x****0202 setb1(val:7, port:3) - -#expect 2 00000101 ******** **** 7f 66 -#packet 0 00000101 00000202 0303 55 66 7777 88 00 -#expect 3 00000202 ******** **** 07 66 -#packet 2 00000202 00000303 0404 55 66 7777 88 00 -#wait - -add ex1 100 extra$0.h:0x25** act1(val:0x25) -add tbl1 100 data.f2:0x0202**** setb2(val:0x26) -add ex1 110 extra$0.h:0x2525 act2(val:0x27) -add tbl2 100 data.f2:0x0202**** set1b1(val:0x28) - -# compiler+asm bug: not setting up next table from ex1 properly -packet 0 01010101 02020202 0303 55 66 2500 ff 7f 01020304 -expect 2 01010101 02020202 0303 7f 26 2500 25 7f 01020304 -#packet 0 01010101 02020202 0303 55 66 2525 ff ff 3333 ff 7f 01020304 -#expect 2 01010101 02020202 0303 7f 66 2525 27 ff 3333 28 7f 01020304 diff --git a/backends/tofino/bf-asm/test/action_chain2.p4 b/backends/tofino/bf-asm/test/action_chain2.p4 deleted file mode 100644 index 8916b64e2b9..00000000000 --- a/backends/tofino/bf-asm/test/action_chain2.p4 +++ /dev/null @@ -1,83 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - h1 : 16; - b1 : 8; - b2 : 8; - } -} - -header_type extra_t { - fields { - h : 16; - b1 : 8; - b2 : 8; - } -} - -header data_t data; -header extra_t extra[4]; - -parser start { - extract(data); - return extra; -} -parser extra { - extract(extra[next]); - return select(latest.b2) { - 0x80 mask 0x80: extra; - default: ingress; - } -} - -action setb1(port, val) { - modify_field(data.b1, val); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} -action noop() { } -action setb2(val) { modify_field(data.b2, val); } -action set0b1(val) { modify_field(extra[0].b1, val); } -action set1b1(val) { modify_field(extra[1].b1, val); } -action set2b2(val) { modify_field(extra[2].b2, val); } -action act1(val) { modify_field(extra[0].b1, val); } -action act2(val) { modify_field(extra[0].b1, val); } -action act3(val) { modify_field(extra[0].b1, val); } - -table test1 { - reads { data.f1 : exact; } - actions { - setb1; - noop; - } -} -table ex1 { - reads { extra[0].h : exact; } - actions { - set0b1; - act1; - act2; - act3; - noop; - } -} -table tbl1 { - reads { data.f2 : exact; } - actions { setb2; noop; } } -table tbl2 { - reads { data.f2 : exact; } - actions { set1b1; noop; } } -table tbl3 { - reads { data.f2 : exact; } - actions { set2b2; noop; } } - -control ingress { - apply(test1); - apply(ex1) { - act1 { apply(tbl1); } - act2 { apply(tbl2); } - act3 { apply(tbl3); } - } -} diff --git a/backends/tofino/bf-asm/test/asm/action_bus_alignment.tfa b/backends/tofino/bf-asm/test/asm/action_bus_alignment.tfa deleted file mode 100644 index d04b91b80bc..00000000000 --- a/backends/tofino/bf-asm/test/asm/action_bus_alignment.tfa +++ /dev/null @@ -1,422 +0,0 @@ -version: 1.0.0 -phv ingress: - $always_deparse: B34(0) - $bridged_metadata_indicator: B32 - data.f1: W37 - data.f2: W36 - data.f3: W38 - data.h1: W35(16..31) - data.h2: W35(0..15) - data.h3: W34(16..31) - data.h4: W34(0..15) - data.h5: W33(16..31) - data.h6: W33(0..15) - data.b1: B33 - data.b2: H32(8..15) - data.b3: H32(0..7) - data.b4: W32(24..31) - data.b5: W32(16..23) - data.b6: W32(8..15) - data.b7: W32(0..7) - data.$valid: B35(0) -phv egress: - eg_intr_md.egress_port: H40(0..8) - data.f1: TW5 - data.f2: TW4 - data.f3: TW6 - data.h1: TW3(16..31) - data.h2: TW3(0..15) - data.h3: TW2(16..31) - data.h4: TW2(0..15) - data.h5: TW1(16..31) - data.h6: TW1(0..15) - data.b1: TB0 - data.b2: TH0(8..15) - data.b3: TH0(0..7) - data.b4: TW0(24..31) - data.b5: TW0(16..23) - data.b6: TW0(8..15) - data.b7: TW0(0..7) - data.$valid: B40(0) -parser ingress: - start: $entry_point - hdr_len_adj: 16 - states: - $entry_point: # from state ingress::$entry_point - 0x*: - B32: 0 # value 0 -> B32 L[0..7]b: ingress::$bridged_metadata_indicator - B34: 1 # value 1 -> B34 L[0]b: ingress::$always_deparse - buf_req: 0 - next: $ingress_tna_entry_point - $ingress_tna_entry_point: # from state ingress::$ingress_tna_entry_point - 0x*: - buf_req: 0 - next: $ingress_metadata - $ingress_metadata: # from state ingress::$ingress_metadata - 0x*: - buf_req: 1 - next: $check_resubmit - $check_resubmit: # from state ingress::$check_resubmit - match: [ 0 ] - # - match N[0]B: cast - 0b0*******: - shift: 8 - buf_req: 8 - next: $phase0 - 0b1*******: - shift: 8 - buf_req: 8 - next: end - $phase0: # from state ingress::$phase0 - 0x*: - shift: 8 - buf_req: 8 - next: $skip_to_packet - $skip_to_packet: # from state ingress::$skip_to_packet - 0x*: - buf_req: 0 - next: start - start: # from state ingress::start - 0x*: - 0..3: W37 # ingress::data.f1 - 4..7: W36 # ingress::data.f2 - 8..11: W38 # ingress::data.f3 - 12..15: W35 - # - N[96..111]b -> W35 L[16..31]b: ingress::data.h1 - # - N[112..127]b -> W35 L[0..15]b: ingress::data.h2 - 24: B33 # ingress::data.b1 - 25..26: H32 - # - N[200..207]b -> H32 L[8..15]b: ingress::data.b2 - # - N[208..215]b -> H32 L[0..7]b: ingress::data.b3 - B35: 1 # value 1 -> B35 L[0]b: ingress::data.$valid - shift: 16 - buf_req: 27 - next: start.$split - start.$split: # from state ingress::start - 0x*: - 0..3: W34 - # - N[128..143]b -> W34 L[16..31]b: ingress::data.h3 - # - N[144..159]b -> W34 L[0..15]b: ingress::data.h4 - 4..7: W33 - # - N[160..175]b -> W33 L[16..31]b: ingress::data.h5 - # - N[176..191]b -> W33 L[0..15]b: ingress::data.h6 - 11..14: W32 - # - N[216..223]b -> W32 L[24..31]b: ingress::data.b4 - # - N[224..231]b -> W32 L[16..23]b: ingress::data.b5 - # - N[232..239]b -> W32 L[8..15]b: ingress::data.b6 - # - N[240..247]b -> W32 L[0..7]b: ingress::data.b7 - shift: 15 - buf_req: 15 - next: end -deparser ingress: - dictionary: - B32: B34(0) # ingress::$bridged_metadata_indicator if ingress::$always_deparse - W37: B35(0) # ingress::data.f1 if ingress::data.$valid - W36: B35(0) # ingress::data.f2 if ingress::data.$valid - W38: B35(0) # ingress::data.f3 if ingress::data.$valid - W35: B35(0) - # - L[16..31]b: ingress::data.h1 if ingress::data.$valid - # - L[0..15]b: ingress::data.h2 if ingress::data.$valid - W34: B35(0) - # - L[16..31]b: ingress::data.h3 if ingress::data.$valid - # - L[0..15]b: ingress::data.h4 if ingress::data.$valid - W33: B35(0) - # - L[16..31]b: ingress::data.h5 if ingress::data.$valid - # - L[0..15]b: ingress::data.h6 if ingress::data.$valid - B33: B35(0) # ingress::data.b1 if ingress::data.$valid - H32: B35(0) - # - L[8..15]b: ingress::data.b2 if ingress::data.$valid - # - L[0..7]b: ingress::data.b3 if ingress::data.$valid - W32: B35(0) - # - L[24..31]b: ingress::data.b4 if ingress::data.$valid - # - L[16..23]b: ingress::data.b5 if ingress::data.$valid - # - L[8..15]b: ingress::data.b6 if ingress::data.$valid - # - L[0..7]b: ingress::data.b7 if ingress::data.$valid -parser egress: - start: $entry_point - hdr_len_adj: 27 - meta_opt: 8191 - states: - $entry_point: # from state egress::$entry_point - 0x*: - buf_req: 0 - next: $egress_tna_entry_point - $egress_tna_entry_point: # from state egress::$egress_tna_entry_point - 0x*: - buf_req: 0 - next: $egress_metadata - $egress_metadata: # from state egress::$egress_metadata - 0x*: - 0..1: H40 # N[7..15]b -> H40 L[0..8]b: egress::eg_intr_md.egress_port - shift: 27 - buf_req: 28 - next: $check_mirrored - $check_mirrored: # from state egress::$check_mirrored - match: [ 0 ] - # - match N[0]B: BFN::LookaheadExpression - 0b****0***: - buf_req: 0 - next: $bridge_metadata_extract - 0b****1***: - buf_req: 0 - next: end - $bridge_metadata_extract: # from state egress::$bridge_metadata_extract - 0x*: - shift: 1 - buf_req: 1 - next: start - start: # from state egress::start - 0x*: - 0..3: TW5 # egress::data.f1 - 4..7: TW4 # egress::data.f2 - 8..11: TW6 # egress::data.f3 - 12..15: TW3 - # - N[96..111]b -> TW3 L[16..31]b: egress::data.h1 - # - N[112..127]b -> TW3 L[0..15]b: egress::data.h2 - 24: TB0 # egress::data.b1 - 25..26: TH0 - # - N[200..207]b -> TH0 L[8..15]b: egress::data.b2 - # - N[208..215]b -> TH0 L[0..7]b: egress::data.b3 - B40: 1 # value 1 -> B40 L[0]b: egress::data.$valid - shift: 16 - buf_req: 27 - next: start.$split.0 - start.$split.0: # from state egress::start - 0x*: - 0..3: TW2 - # - N[128..143]b -> TW2 L[16..31]b: egress::data.h3 - # - N[144..159]b -> TW2 L[0..15]b: egress::data.h4 - 4..7: TW1 - # - N[160..175]b -> TW1 L[16..31]b: egress::data.h5 - # - N[176..191]b -> TW1 L[0..15]b: egress::data.h6 - 11..14: TW0 - # - N[216..223]b -> TW0 L[24..31]b: egress::data.b4 - # - N[224..231]b -> TW0 L[16..23]b: egress::data.b5 - # - N[232..239]b -> TW0 L[8..15]b: egress::data.b6 - # - N[240..247]b -> TW0 L[0..7]b: egress::data.b7 - shift: 15 - buf_req: 15 - next: end -deparser egress: - dictionary: - TW5: B40(0) # egress::data.f1 if egress::data.$valid - TW4: B40(0) # egress::data.f2 if egress::data.$valid - TW6: B40(0) # egress::data.f3 if egress::data.$valid - TW3: B40(0) - # - L[16..31]b: egress::data.h1 if egress::data.$valid - # - L[0..15]b: egress::data.h2 if egress::data.$valid - TW2: B40(0) - # - L[16..31]b: egress::data.h3 if egress::data.$valid - # - L[0..15]b: egress::data.h4 if egress::data.$valid - TW1: B40(0) - # - L[16..31]b: egress::data.h5 if egress::data.$valid - # - L[0..15]b: egress::data.h6 if egress::data.$valid - TB0: B40(0) # egress::data.b1 if egress::data.$valid - TH0: B40(0) - # - L[8..15]b: egress::data.b2 if egress::data.$valid - # - L[0..7]b: egress::data.b3 if egress::data.$valid - TW0: B40(0) - # - L[24..31]b: egress::data.b4 if egress::data.$valid - # - L[16..23]b: egress::data.b5 if egress::data.$valid - # - L[8..15]b: egress::data.b6 if egress::data.$valid - # - L[0..7]b: egress::data.b7 if egress::data.$valid - egress_unicast_port: H40 # L[0..8]b: egress::eg_intr_md.egress_port -stage 0 ingress: - exact_match test3_0 0: - p4: { name: test3, size: 1024 } - p4_param_order: - data.f3: { type: exact, size: 32 } - row: 7 - bus: 0 - column: [ 2, 3, 4 ] - ways: - - [0, 0, 0x0, [7, 2]] - - [0, 1, 0x0, [7, 3]] - - [0, 2, 0x0, [7, 4]] - input_xbar: - exact group 0: { 0: data.f3 } - hash 0: - 0..7: random(data.f3(10..31)) ^ data.f3(0..7) - 10..17: random(data.f3(10..31)) ^ data.f3(0..7) - 20..27: random(data.f3(10..31)) ^ data.f3(0..7) - 8..9: random(data.f3(10..31)) ^ data.f3(8..9) - 18..19: random(data.f3(10..31)) ^ data.f3(8..9) - 28..29: random(data.f3(10..31)) ^ data.f3(8..9) - hash group 0: - table: [0] - format: { action(0): 0..0, version(0): 112..115, counter_addr(0): 1..12, counter_pfe(0): 13..13, match(0): [34..39, 16..31 ] } - match: [ data.f3(10..31) ] - next: test2_0 - stats: test3_0$counter..test3_counter(counter_addr) - actions: - my_count: - - p4_param_order: {idx: 32 } - - default_action: { allowed: true } - - { idx: counter_addr } - - test3_0$counter..test3_counter(idx) - NoAction: - - default_action: { allowed: true } - - 0 - default_action: NoAction - counter test3_0$counter..test3_counter: - p4: { name: test3_counter, size: 4000 } - row: 13 - column: [ 0, 1 ] - maprams: [ 0, 1 ] - count: packets - format: {packets(0): 96..127, packets(1): 64..95, packets(2): 32..63, packets(3): 0..31} - per_flow_enable: counter_pfe - exact_match test2_0 1: - p4: { name: test2, size: 5000, action_profile: set_b4_6 } - p4_param_order: - data.f2: { type: exact, size: 32 } - row: [ 6, 7 ] - bus: [ 0, 1 ] - column: - - 2 - - [ 5, 6, 7 ] - ways: - - [1, 0, 0x0, [7, 5]] - - [1, 1, 0x0, [7, 6]] - - [1, 2, 0x0, [7, 7]] - - [1, 3, 0x0, [6, 2]] - input_xbar: - exact group 0: { 64: data.f2 } - hash 1: - 0..7: random(data.f2(10..31)) ^ data.f2(0..7) - 10..17: random(data.f2(10..31)) ^ data.f2(0..7) - 20..27: random(data.f2(10..31)) ^ data.f2(0..7) - 30..37: random(data.f2(10..31)) ^ data.f2(0..7) - 8..9: random(data.f2(10..31)) ^ data.f2(8..9) - 18..19: random(data.f2(10..31)) ^ data.f2(8..9) - 28..29: random(data.f2(10..31)) ^ data.f2(8..9) - 38..39: random(data.f2(10..31)) ^ data.f2(8..9) - hash group 1: - table: [1] - format: { action(0): 0..1, version(0): 112..115, meter_addr(0): 4..13, meter_pfe(0): 14..14, action_addr(0): 15..25, match(0): [66..71, 48..63 ], action(1): 2..3, version(1): 116..119, meter_addr(1): 26..35, meter_pfe(1): 36..36, action_addr(1): 37..47, match(1): [90..95, 72..87 ] } - match: [ data.f2(10..31) ] - next: test1_0 - action: test2_0$action(action, action_addr) - selector: test2_0$act_sel..set_b4_6(meter_addr) - default_action: NoAction - action test2_0$action: - p4: { name: set_b4_6, size: 1024 } - row: 15 - column: 4 - home_row: 15 - format setb4: { $adf_f0: 0..31 } - format setb5: { $adf_f0: 0..31 } - format setb6: { $adf_f0: 0..31 } - action_bus: { 96..99 : $adf_f0 } - actions: - setb4: - - p4_param_order: {val4: 8 } - - default_action: { allowed: true } - - { val4: $adf_f0(24..31) } - - set data.b4, val4 - setb5: - - p4_param_order: {val5: 8 } - - default_action: { allowed: true } - - { val5: $adf_f0(16..23) } - - set data.b5, val5 - setb6: - - p4_param_order: {val6: 8 } - - default_action: { allowed: true } - - { val6: $adf_f0(8..15) } - - set data.b6, val6 - NoAction: - - default_action: { allowed: true } - - { } - selection test2_0$act_sel..set_b4_6: - p4: { name: set_b4_6 } - row: 15 - column: [ 2, 3 ] - maprams: [ 2, 3 ] - input_xbar: - exact group 1: { 0: data.h4, 16: data.h5, 32: data.h6 } - hash 2: - 0..13: random(data.h4, data.h5, data.h6) - hash group 2: - table: [2] - mode: fair 0 - per_flow_enable: meter_pfe - non_linear: true - pool_sizes: [120] -stage 1 ingress: - exact_match test1_0 0: - p4: { name: test1, size: 10000, action_profile: set_b1_3 } - p4_param_order: - data.f1: { type: exact, size: 32 } - row: 7 - bus: 0 - column: [ 2, 3, 4, 5, 6 ] - ways: - - [0, 0, 0x1, [7, 2], [7, 3]] - - [0, 1, 0x0, [7, 4]] - - [0, 2, 0x0, [7, 5]] - - [0, 3, 0x0, [7, 6]] - input_xbar: - exact group 0: { 0: data.f1 } - hash 0: - 0..7: random(data.f1(10..31)) ^ data.f1(0..7) - 10..17: random(data.f1(10..31)) ^ data.f1(0..7) - 20..27: random(data.f1(10..31)) ^ data.f1(0..7) - 30..37: random(data.f1(10..31)) ^ data.f1(0..7) - 8..9: random(data.f1(10..31)) ^ data.f1(8..9) - 18..19: random(data.f1(10..31)) ^ data.f1(8..9) - 28..29: random(data.f1(10..31)) ^ data.f1(8..9) - 38..39: random(data.f1(10..31)) ^ data.f1(8..9) - 40: random(data.f1(10..31)) - hash group 0: - table: [0] - format: { action(0): 0..1, version(0): 112..115, meter_addr(0): 4..13, meter_pfe(0): 14..14, action_addr(0): 15..32, match(0): [82..87, 64..79 ], action(1): 2..3, version(1): 116..119, meter_addr(1): 33..42, meter_pfe(1): 43..43, action_addr(1): 44..61, match(1): [106..111, 88..103 ] } - match: [ data.f1(10..31) ] - next: END - action: test1_0$action(action, action_addr) - selector: test1_0$act_sel..set_b1_3(meter_addr) - default_action: NoAction - action test1_0$action: - p4: { name: set_b1_3, size: 80000 } - row: [ 15, 13 ] - column: - - [ 3, 4, 5 ] - - [ 0, 1 ] - home_row: 15 - format setb1: { $adf_b0: 0..7 } - format setb2: { $adf_h0: 0..15 } - format setb3: { $adf_h0: 0..15 } - action_bus: { 0 : $adf_b0, 32..33 : $adf_h0 } - actions: - setb1: - - p4_param_order: {val1: 8 } - - default_action: { allowed: true } - - { val1: $adf_b0 } - - set data.b1, val1 - setb2: - - p4_param_order: {val2: 8 } - - default_action: { allowed: true } - - { val2: $adf_h0(8..15) } - - set data.b2, val2 - setb3: - - p4_param_order: {val3: 8 } - - default_action: { allowed: true } - - { val3: $adf_h0(0..7) } - - set data.b3, val3 - NoAction: - - default_action: { allowed: true } - - { } - selection test1_0$act_sel..set_b1_3: - p4: { name: set_b1_3 } - row: 15 - column: [ 1, 2 ] - maprams: [ 1, 2 ] - input_xbar: - exact group 0: { 64: data.h2, 80: data.h1, 112: data.h3 } - hash 1: - 0..13: stripe(crc(0x8fdb, data.h2, data.h1, data.h3)) - hash group 1: - table: [1] - mode: fair 0 - per_flow_enable: meter_pfe - non_linear: true - pool_sizes: [120] diff --git a/backends/tofino/bf-asm/test/asm/action_default_multiple.tfa b/backends/tofino/bf-asm/test/asm/action_default_multiple.tfa deleted file mode 100644 index 9175efea79c..00000000000 --- a/backends/tofino/bf-asm/test/asm/action_default_multiple.tfa +++ /dev/null @@ -1,112 +0,0 @@ -version: 1.0.0 -phv ingress: - standard_metadata.egress_spec: H0(0..8) - data.b1: B3 - data.b2: B2 - data.b3: B1 - data.b4: B0 - data.$valid: B15(7) -phv egress: - standard_metadata.egress_port: H16(0..8) - data.$valid: B31(7) -parser ingress: - start: $ingress_metadata_shim - $ingress_metadata_shim: - 0x*: - shift: 16 - next: start$ - start$: - 0x*: - 0: data.b1 - 1: data.b2 - 2: data.b3 - 3: data.b4 - shift: 4 - next: start$.0 - start$.0: - 0x*: - data.$valid: 1 - next: end -deparser ingress: - dictionary: - data.b1: data.$valid - data.b2: data.$valid - data.b3: data.$valid - data.b4: data.$valid - egress_unicast_port: standard_metadata.egress_spec -parser egress: - start: $egress_metadata_shim - $egress_metadata_shim: - 0x*: - 0..1: H16 - shift: 2 - next: end -deparser egress: - dictionary: {} - egress_unicast_port: standard_metadata.egress_port -stage 0 ingress: - exact_match first 0: - p4: { name: first } - row: 1 - bus: 1 - column: [ ] - next: second - actions: - b1_act: - - { b1: immediate(0..7) } - - set data.b1, b1 - default_action: b1_act - default_action_parameters: - b1: 1 - exact_match second 1: - p4: { name: second } - row: 1 - bus: 0 - column: [ ] - next: third - actions: - b2_act: - - { b2: immediate(0..7) } - - set data.b2, b2 - default_action: b2_act - default_action_parameters: - b2: 2 - exact_match third 2: - p4: { name: third } - row: 0 - bus: 1 - column: [ ] - next: fourth - actions: - b3_act: - - { b3: immediate(0..7) } - - set data.b3, b3 - default_action: b3_act - default_action_parameters: - b3: 3 - exact_match fourth 3: - p4: { name: fourth } - row: 0 - bus: 0 - column: [ ] - next: port_set - actions: - b4_act: - - { b4: immediate(0..7) } - - set data.b4, b4 - default_action: b4_act - default_action_parameters: - b4: 4 - exact_match port_set 4: - p4: { name: port_set } - row: 2 - bus: 0 - column: [ ] - next: END - actions: - set_port: - - { port: immediate(0..8) } - - set standard_metadata.egress_spec, port - default_action: set_port - default_action_parameters: - port: 5 diff --git a/backends/tofino/bf-asm/test/asm/always_run.jba b/backends/tofino/bf-asm/test/asm/always_run.jba deleted file mode 100644 index 35fad4ad4c5..00000000000 --- a/backends/tofino/bf-asm/test/asm/always_run.jba +++ /dev/null @@ -1,16 +0,0 @@ -parser ingress: - start: - 0x*: - shift: 32 - next: end -stage 0 ingress: - always_run_action: - - set H0, 3 - - set B1, 1 -deparser ingress: - egress_unicast_port: { H0: B1(0) } -parser egress: - start: - 0x*: - shift: 4 - next: end diff --git a/backends/tofino/bf-asm/test/asm/always_run.stf b/backends/tofino/bf-asm/test/asm/always_run.stf deleted file mode 100644 index 345a9126bb8..00000000000 --- a/backends/tofino/bf-asm/test/asm/always_run.stf +++ /dev/null @@ -1,2 +0,0 @@ -expect 3 0102030405060708090a0b0c0d0e0f -packet 0 0102030405060708090a0b0c0d0e0f diff --git a/backends/tofino/bf-asm/test/asm/counter_lrt1.tfa b/backends/tofino/bf-asm/test/asm/counter_lrt1.tfa deleted file mode 100644 index d981af1c5e0..00000000000 --- a/backends/tofino/bf-asm/test/asm/counter_lrt1.tfa +++ /dev/null @@ -1,10 +0,0 @@ -stage 0 ingress: - counter a: - row: 15 - column: [ 0, 1, 2, 3 ] - count: bytes - format: { bytes(0): 32, bytes(1): 32, bytes(2): 32, bytes(3): 32 } - lrt: - - { threshold: 0x1000, interval: 0x1000000 } - - { threshold: 0x10000, interval: 0x100000 } - - { threshold: 0x100000, interval: 0x10000 } diff --git a/backends/tofino/bf-asm/test/asm/em1-clot.jba b/backends/tofino/bf-asm/test/asm/em1-clot.jba deleted file mode 100644 index 1b6ad53164e..00000000000 --- a/backends/tofino/bf-asm/test/asm/em1-clot.jba +++ /dev/null @@ -1,98 +0,0 @@ -version: 1.0.0 -phv ingress: - standard_metadata.egress_spec: H0(0..8) - data.f1: W0 - data.b1: B0 - data.$valid: B11(7) -phv egress: - standard_metadata.egress_port: H16(0..8) - data.$valid: B31(7) -parser ingress: - start: $ingress_metadata_shim - $ingress_metadata_shim: - match: [ 0 ] - # - [0] (buffer) - 0b0*******: - next: $ingress_metadata - 0b1*******: - next: $ingress_metadata - $ingress_metadata: - 0x*: - shift: 8 - next: $phase0 - $phase0: - 0x*: - shift: 24 - next: start - start: - 0x*: - clot 1: 0..11 - 0..3: data.f1 - 10: data.b1 - data.$valid: 1 - shift: 12 - next: end -deparser ingress: - dictionary: - clot 1: - pov: data.$valid - 10: data.b1 - egress_unicast_port: { standard_metadata.egress_spec: data.$valid } -parser egress: - start: $egress_metadata_shim - $egress_metadata_shim: - 0x*: - 0..1: H16 - # - L[0..8]b standard_metadata.egress_port - shift: 2 - next: $bridged_metadata - $bridged_metadata: - 0x*: - next: start - start: - 0x*: - clot X: - start: 0 - length: 12 - data.$valid: 1 - shift: 12 - next: end -deparser egress: - dictionary: - clot X: data.$valid - egress_unicast_port: { standard_metadata.egress_port: data.$valid } -stage 0 ingress: - exact_match test1 0: - p4: { name: test1 } - p4_param_order: - data.f1: { type: exact, size: 32 } - row: 7 - bus: 0 - column: [ 2, 3, 4 ] - ways: - - [0, 0, 0x0, [7, 2]] - - [0, 1, 0x0, [7, 3]] - - [0, 2, 0x0, [7, 4]] - input_xbar: - exact group 0: { 0: data.f1 } - hash 0: - 0..9: random(data.f1(10..31)) ^ stripe(data.f1(0..7), data.f1(8..9)) - 10..19: random(data.f1(10..31)) ^ stripe(data.f1(0..7), data.f1(8..9)) - 20..29: random(data.f1(10..31)) ^ stripe(data.f1(0..7), data.f1(8..9)) - hash group 0: - table: [0] - format: { action(0): 0..1, immediate(0): 2..25, version(0): 112..115, match(0): [50..55, 40..47, 32..39 ] } - match: [ data.f1(10..31) ] - next: END - action_bus: { 2 : immediate(16..23), 32..33 : immediate(0..15) } - actions: - setb1: - - p4_param_order: {val: 8, port: 9 } - - { port: immediate(0..8), val: immediate(16..23) } - - set data.b1, val - - set standard_metadata.egress_spec, port - noop: - - { } - NoAction: - - { } - default_action: NoAction diff --git a/backends/tofino/bf-asm/test/asm/em1-clot.stf b/backends/tofino/bf-asm/test/asm/em1-clot.stf deleted file mode 100644 index 88e0059e450..00000000000 --- a/backends/tofino/bf-asm/test/asm/em1-clot.stf +++ /dev/null @@ -1,8 +0,0 @@ - -add test1 data.f1:0x01010101 setb1(val:0x7f, port:2) -add test1 data.f1:0x02020202 setb1(val:7, port:3) - -expect 2 01010101 00000202 0303 7f 66 77 88 -packet 0 01010101 00000202 0303 55 66 77 88 -#expect 3 02020202 00000303 0404 07 66 77 88 -#packet 2 02020202 00000303 0404 55 66 77 88 diff --git a/backends/tofino/bf-asm/test/asm/expected_failures.txt b/backends/tofino/bf-asm/test/asm/expected_failures.txt deleted file mode 100644 index 0e41bd93111..00000000000 --- a/backends/tofino/bf-asm/test/asm/expected_failures.txt +++ /dev/null @@ -1,14 +0,0 @@ -- assembler failures on assembly tests. - -stateful_multiple_output_error.tfa bfas -- assembler must fail due to multiple output instructions in a stateful table - -table_alias_fields_error.tfa bfas -- alias fields index are out of range with allowed values - --- the rest give various assembler errors -- delete them? -hash_action_basic.tfa bfas -hash_action_gateway2.tfa bfas -action_default_multiple.tfa bfas -switch_l2_profile_tofino.tfa bfas -tor.tfa bfas diff --git a/backends/tofino/bf-asm/test/asm/hash_action_basic.tfa b/backends/tofino/bf-asm/test/asm/hash_action_basic.tfa deleted file mode 100644 index 2fab4ec4dc8..00000000000 --- a/backends/tofino/bf-asm/test/asm/hash_action_basic.tfa +++ /dev/null @@ -1,112 +0,0 @@ -version: 1.0.0 -phv ingress: - standard_metadata.egress_spec: H0(0..8) - data.f1: W1 - data.f2: W0 - data.h1: TH0 - data.h2: TH1 - data.h3: TH2 - data.h4: TH3 - counter_metadata.counter_index: H1 - data.$valid: B11(7) -phv egress: - standard_metadata.egress_port: H16(0..8) -parser ingress: - start: $ingress_metadata_shim - $ingress_metadata_shim: - 0x*: - shift: 16 - next: start$ - start$: - 0x*: - 0..3: data.f1 - 4..7: data.f2 - 8..9: data.h1 - 10..11: data.h2 - 12..13: data.h3 - 14..15: data.h4 - data.$valid: 1 - shift: 16 - next: end -deparser ingress: - dictionary: - data.f1: data.$valid - data.f2: data.$valid - data.h1: data.$valid - data.h2: data.$valid - data.h3: data.$valid - data.h4: data.$valid - egress_unicast_port: standard_metadata.egress_spec -parser egress: - start: $egress_metadata_shim - $egress_metadata_shim: - 0x*: - 0..1: H16 - shift: 2 - next: end -deparser egress: - dictionary: {} - egress_unicast_port: standard_metadata.egress_port -stage 0 ingress: - exact_match index_setter 0: - p4: { name: index_setter, size: 2048 } - row: 7 - bus: 0 - column: [ 2, 3, 4, 5 ] - ways: - - [0, 0, 0x0, [7, 2]] - - [0, 1, 0x0, [7, 3]] - - [0, 2, 0x0, [7, 4]] - - [0, 3, 0x0, [7, 5]] - input_xbar: - group 0: { 0: data.f1, 32: data.f2 } - hash 0: - 0..9: random(data.f1(10..31), data.f2) ^ stripe(data.f1(0..9)) - 10..19: random(data.f1(10..31), data.f2) ^ stripe(data.f1(0..9)) - 20..29: random(data.f1(10..31), data.f2) ^ stripe(data.f1(0..9)) - 30..39: random(data.f1(10..31), data.f2) ^ stripe(data.f1(0..9)) - hash group 0: - table: [0] - format: { action(0): 1, immediate(0): 32, version(0): 124..127, match(0): 34..87 } - match: [ data.f1(10..31), data.f2 ] - next: stats - actions: - set_index: - - { index: immediate(0..15), port: immediate(16..31) } - - set counter_metadata.counter_index, index - - set standard_metadata.egress_spec, port - NoAction_1: - - 0 - default_action: NoAction_1 -stage 1 ingress: - hash_action stats 0: - p4: { name: stats } - hash_dist: - 0: {hash: 0, mask: 65535} - row: 0 - bus: 0 - input_xbar: - group 0: { 0: counter_metadata.counter_index } - hash 0: - 0..15: counter_metadata.counter_index - hash group 0: - table: [0] - gateway: - row: 0 - #bus: 0 - 0x0: END - miss: END - next: END - stats: - - stats$counter.count1(hash_dist 0) - actions: - count_entries: - - 0 - default_action: count_entries - counter stats$counter.count1: - p4: { name: count1 } - row: 13 - column: [ 0, 1, 2, 3 ] - maprams: [ 0, 1, 2, 3 ] - count: packets - format: {packets(0): 106..126, packets(1): 85..105, packets(2): 64..84, packets(3): 42..62, packets(4): 21..41, packets(5): 0..20} diff --git a/backends/tofino/bf-asm/test/asm/hash_action_gateway2.stf b/backends/tofino/bf-asm/test/asm/hash_action_gateway2.stf deleted file mode 100644 index 19b896fd5dd..00000000000 --- a/backends/tofino/bf-asm/test/asm/hash_action_gateway2.stf +++ /dev/null @@ -1,22 +0,0 @@ - -add index_setter data.f1:0x11111111 data.f2:0x22222222 set_index(index:9, port:1) -add index_setter data.f1:0x22222222 data.f2:0x33333333 set_index(index:9, port:2) -add index_setter data.f1:0x33333333 data.f2:0x44444444 set_index(index:9, port:2) -add index_setter data.f1:0x44444444 data.f2:0x55555555 set_index(index:8, port:3) - - -expect 1 11111111 22222222 0101 0202 0303 0404 -packet 0 11111111 22222222 0101 0202 0303 0404 - -# expect 2 22222222 33333333 0202 0303 0404 0505 -# packet 0 22222222 33333333 0202 0303 0404 0505 - -# expect 2 33333333 44444444 0303 0404 0505 0606 -# packet 0 33333333 44444444 0303 0404 0505 0606 - -# expect 3 44444444 55555555 0404 0505 0606 0707 -# packet 0 44444444 55555555 0404 0505 0606 0707 - -wait -# check_counter count1(8) packets == 1 -check_counter count1(9) packets == 1 diff --git a/backends/tofino/bf-asm/test/asm/hash_action_gateway2.tfa b/backends/tofino/bf-asm/test/asm/hash_action_gateway2.tfa deleted file mode 100644 index f0bd5f653b5..00000000000 --- a/backends/tofino/bf-asm/test/asm/hash_action_gateway2.tfa +++ /dev/null @@ -1,120 +0,0 @@ -version: 1.0.0 -phv ingress: - standard_metadata.egress_spec: H0(0..8) - data.f1: W1 - data.f2: W0 - data.h1: TH0 - data.h2: TH2 - data.h3: TH1 - data.h4: TH3 - counter_metadata.counter_index: H1 - counter_metadata.counter_run: B0(0..3) - data.$valid: B0(7) -phv egress: - standard_metadata.egress_port: H16(0..8) -parser ingress: - start: $ingress_metadata_shim - $ingress_metadata_shim: - 0x*: - shift: 16 - next: start$ - start$: - 0x*: - 0..3: data.f1 - 4..7: data.f2 - 8..9: data.h1 - 10..11: data.h2 - 12..13: data.h3 - 14..15: data.h4 - data.$valid: 1 - shift: 16 - next: end -deparser ingress: - dictionary: - data.f1: data.$valid - data.f2: data.$valid - data.h1: data.$valid - data.h2: data.$valid - data.h3: data.$valid - data.h4: data.$valid - egress_unicast_port: standard_metadata.egress_spec -parser egress: - start: $egress_metadata_shim - $egress_metadata_shim: - 0x*: - 0..1: H16 - shift: 2 - next: end -deparser egress: - dictionary: {} - egress_unicast_port: standard_metadata.egress_port -stage 0 ingress: - exact_match index_setter 0: - p4: { name: index_setter, size: 2048 } - row: 7 - bus: 0 - column: [ 2, 3, 4, 5 ] - ways: - - [0, 0, 0x0, [7, 2]] - - [0, 1, 0x0, [7, 3]] - - [0, 2, 0x0, [7, 4]] - - [0, 3, 0x0, [7, 5]] - input_xbar: - group 0: { 0: data.f1, 32: data.f2 } - hash 0: - 0..9: random(data.f1(10..31), data.f2) ^ stripe(data.f1(0..9)) - 10..19: random(data.f1(10..31), data.f2) ^ stripe(data.f1(0..9)) - 20..29: random(data.f1(10..31), data.f2) ^ stripe(data.f1(0..9)) - 30..39: random(data.f1(10..31), data.f2) ^ stripe(data.f1(0..9)) - hash group 0: - table: [0] - format: { action(0): 1, immediate(0): 32, version(0): 124..127, match(0): 34..87 } - match: [ data.f1(10..31), data.f2 ] - next: stats - actions: - set_index: - - { index: immediate(0..15), port: immediate(16..31) } - - set counter_metadata.counter_index, index - - set standard_metadata.egress_spec, port - - set counter_metadata.counter_run, 1 - NoAction_1: - - 0 - default_action: NoAction_1 -stage 1 ingress: - hash_action stats 0: - p4: { name: stats } - row: 0 - bus: 0 - #column: [ ] - hash_dist: - 0: {hash: 0, mask: 65535, shift: 1} - input_xbar: - group 0: { 0: counter_metadata.counter_index } - hash 0: - 0..15: counter_metadata.counter_index - hash group 0: - table: [0] - gateway: - input_xbar: - group 0: { 16: counter_metadata.counter_run } - row: 0 - #bus: 0 - payload: 1 - match: { 0: counter_metadata.counter_run } - 0x*1: END - miss: run_table - next: END - stats: - - stats$counter.count1(hash_dist 0) - actions: - count_entries: - - 0 - default_action: count_entries - counter stats$counter.count1: - p4: { name: count1 } - row: 13 - column: [ 0, 1, 2, 3, 4, 5 ] - maprams: [ 0, 1, 2, 3, 4, 5 ] - count: packets - per_flow_enable: true - format: {packets(0): 96..127, packets(1): 64..95, packets(2): 32..63, packets(3): 0..31} diff --git a/backends/tofino/bf-asm/test/asm/jbay_sful_syntax.jba b/backends/tofino/bf-asm/test/asm/jbay_sful_syntax.jba deleted file mode 100644 index 9ba417d3b15..00000000000 --- a/backends/tofino/bf-asm/test/asm/jbay_sful_syntax.jba +++ /dev/null @@ -1,51 +0,0 @@ -version: 1.0.0 -phv ingress: - $always_deparse: B1(0) - $bridged_metadata_indicator: B0 - data.f1: W7 - data.f2: W0 - data.f3: W1 - data.f4: W10 - data.h1: W3(16..31) - data.h2: W3(0..15) - data.h3: W6(16..31) - data.h4: W6(0..15) - data.b1: W2(24..31) - data.b2: W2(16..23) - data.b3: W2(8..15) - data.b4: W2(0..7) - ig_intr_md_for_tm.ucast_egress_port: H4(0..8) - $tmp1: B1(1) - data.$valid: B1(2) -stage 0 ingress: - stateful test1_0$salu..accum: - p4: { name: accum } - row: 15 - column: [ 0, 1 ] - maprams: [ 0, 1 ] - input_xbar: - exact group 1: { 0: data.f2, 32: data.f3 } - format: { lo: 32, hi:32 } - actions: - sful_0: - - add hi, hi, 1 - - grt.u p2, data.f2, -1000 - - lss.u p1, data.f2, -2000 - - add cmp2 & cmp1, lo, lo, data.f3 - - sub !cmp2 & cmp1, lo, lo, data.f3 - - output word0, mem_lo - - output word1, alu_hi - per_flow_enable: meter_pfe - stateful test2: - row: 11 - column: [ 0, 1, 2, 3, 4, 5 ] - maprams: [ 0, 1, 2, 3, 4, 5 ] - input_xbar: - exact group 2: { 0: data.h2, 16: data.h1 } - sbus and not: - match: test1_0$salu..accum - format: { lo: 16, hi: 16 } - actions: - a0: - - lss.s p3, data.h1, lo - - grt.s p2, data.h2, lo, -100 diff --git a/backends/tofino/bf-asm/test/asm/network_tap.bfa b/backends/tofino/bf-asm/test/asm/network_tap.bfa deleted file mode 100644 index bba4bc4ebef..00000000000 --- a/backends/tofino/bf-asm/test/asm/network_tap.bfa +++ /dev/null @@ -1,13304 +0,0 @@ -version: - version: 1.0.1 - run_id: "adab53b4e08ee326" - target: Tofino -phv ingress: - ig_md.lkp.ip_proto: B11 - ig_md.lkp.ip_src_addr.0-31: W49 - ig_md.lkp.ip_src_addr.32-63: W50 - ig_md.lkp.ip_src_addr.64-95: W51 - ig_md.lkp.ip_src_addr.96-127: W52 - ig_md.lkp.ip_dst_addr.0-31: W53 - ig_md.lkp.ip_dst_addr.32-63: W54 - ig_md.lkp.ip_dst_addr.64-95: W55 - ig_md.lkp.ip_dst_addr.96-127: W56 - ig_md.lkp.l4_src_port: H9 - ig_md.lkp.l4_dst_port: H11 - ig_md.lkp.inner_l4_src_port: H10 - ig_md.lkp.inner_l4_dst_port: H12 - ig_md.count_index.0-7: B5 - ig_md.count_index.8-17: H6(0..9) - ig_md.hash: W2 - ig_md.in_ig_port_type: B6(0..2) - ig_md.trunc_type: B2(6..7) - ig_md.action_type: W1(13..20) - ig_md.ip_hdr_location: H3(0..7) - ig_md.pkt_proto_type: H3(8..15) - ig_md.port_group_id: W0(13..28) - ig_md.tunnel_type.0-4: B6(3..7) - ig_md.tunnel_type.5-5: B7(0) - ig_md.vlan_index: H8 - ig_md.mirror.src: B9 - ig_md.mirror.type: B10 - ig_md.mirror.session_id: H2(0..9) - hdr.bridged_md.src: B0 - hdr.bridged_md.pkt_proto_type: H3(8..15) - hdr.bridged_md.ip_hdr_location: H3(0..7) - hdr.bridged_md.pad1: B7(1..7) - hdr.bridged_md.tunnel_type.0-4: B6(3..7) - hdr.bridged_md.tunnel_type.5-5: B7(0) - hdr.bridged_md.in_ig_port_type: B6(0..2) - hdr.ethernet.dst_addr.0-15: H7 - hdr.ethernet.dst_addr.16-47: TW26 - hdr.ethernet.src_addr.0-15: TH25 - hdr.ethernet.src_addr.16-47: TW27 - hdr.ethernet.ether_type: H5 - hdr.ipv4.version: TW0(28..31) - hdr.ipv4.ihl: TW0(24..27) - hdr.ipv4.diffserv: TW0(16..23) - hdr.ipv4.total_len: TW0(0..15) - hdr.ipv4.identification.0-7: TB10 - hdr.ipv4.identification.8-15: TB11 - hdr.ipv4.flags: TB8(5..7) - hdr.ipv4.frag_offset.0-7: TB9 - hdr.ipv4.frag_offset.8-12: TB8(0..4) - hdr.ipv4.ttl: TW16(24..31) - hdr.ipv4.protocol: TW16(16..23) - hdr.ipv4.hdr_checksum: TW16(0..15) - hdr.ipv4.src_addr.0-15: TH29 - hdr.ipv4.src_addr.16-31: TH36 - hdr.ipv4.dst_addr.0-15: TH37 - hdr.ipv4.dst_addr.16-31: TH38 - hdr.tcp.src_port: TW18(16..31) - hdr.tcp.dst_port: TW18(0..15) - hdr.tcp.seq_no: TW25 - hdr.tcp.ack_no.0-7: TB19 - hdr.tcp.ack_no.8-15: TB24 - hdr.tcp.ack_no.16-31: TH39 - hdr.tcp.data_offset: TW1(28..31) - hdr.tcp.res: TW1(24..27) - hdr.tcp.flags: TW1(16..23) - hdr.tcp.window: TW1(0..15) - hdr.tcp.checksum: TW19(16..31) - hdr.tcp.urgent_ptr: TW19(0..15) - hdr.gtpv2_8b.version: TH0(13..15) - hdr.gtpv2_8b.pb: TH0(12) - hdr.gtpv2_8b.tf: TH0(11) - hdr.gtpv2_8b.spare1: TH0(8..10) - hdr.gtpv2_8b.message_type: TH0(0..7) - hdr.gtpv2_8b.total_len: TH1 - hdr.gtpv2_8b.seq_no.0-7: TB18 - hdr.gtpv2_8b.seq_no.8-23: TH26 - hdr.gtpv2_8b.spare2: TB17 - hdr.imsi.type: TW2(24..31) - hdr.imsi.len: TW2(8..23) - hdr.imsi.spare: TW2(4..7) - hdr.imsi.instance: TW2(0..3) - hdr.imsi.num_digit.0-31: TW17 - hdr.imsi.num_digit.32-63: TW24 - hdr.imsi.num_digit.64-79: TH24 - hdr.imsi.num_digit.80-95: TH27 - hdr.imsi.num_digit.96-103: TB16 - hdr.imsi.num_digit.104-111: TB25 - hdr.imsi.num_digit.112-127: TH28 - hdr.cause_ie_6b.type: TB1 - hdr.cause_ie_6b.len: TW3(16..31) - hdr.cause_ie_6b.spare1: TW3(12..15) - hdr.cause_ie_6b.instance: TW3(8..11) - hdr.cause_ie_6b.cause_value: TW3(0..7) - hdr.cause_ie_6b.spare2: TB0(3..7) - hdr.cause_ie_6b.pce: TB0(2) - hdr.cause_ie_6b.bce: TB0(1) - hdr.cause_ie_6b.cs: TB0(0) - hdr.cause_ie_10b.type: TB1 - hdr.cause_ie_10b.len: TW3(16..31) - hdr.cause_ie_10b.spare1: TW3(12..15) - hdr.cause_ie_10b.instance: TW3(8..11) - hdr.cause_ie_10b.cause_value: TW3(0..7) - hdr.cause_ie_10b.spare2: TB0(3..7) - hdr.cause_ie_10b.pce: TB0(2) - hdr.cause_ie_10b.bce: TB0(1) - hdr.cause_ie_10b.cs: TB0(0) - hdr.cause_ie_10b.type_oe: TH3(8..15) - hdr.cause_ie_10b.len_oe.0-7: TH2(8..15) - hdr.cause_ie_10b.len_oe.8-15: TH3(0..7) - hdr.cause_ie_10b.spare_oe: TH2(4..7) - hdr.cause_ie_10b.instance_oe: TH2(0..3) - hdr.inner_ipv4.version: TW2(28..31) - hdr.inner_ipv4.ihl: TW2(24..27) - hdr.inner_ipv4.diffserv: TW2(16..23) - hdr.inner_ipv4.total_len: TW2(0..15) - hdr.inner_ipv4.identification: TH24 - hdr.inner_ipv4.flags: TH3(13..15) - hdr.inner_ipv4.frag_offset: TH3(0..12) - hdr.inner_ipv4.ttl: TW17(24..31) - hdr.inner_ipv4.protocol: TW17(16..23) - hdr.inner_ipv4.hdr_checksum: TW17(0..15) - hdr.inner_ipv4.src_addr.0-7: TB16 - hdr.inner_ipv4.src_addr.8-15: TB25 - hdr.inner_ipv4.src_addr.16-31: TH40 - hdr.inner_ipv4.dst_addr.0-7: TB26 - hdr.inner_ipv4.dst_addr.8-15: TB27 - hdr.inner_ipv4.dst_addr.16-31: TH41 - hdr.inner_tcp.src_port: TH28 - hdr.inner_tcp.dst_port: TH27 - hdr.inner_tcp.seq_no: W6 - hdr.inner_tcp.ack_no: W7 - hdr.inner_tcp.data_offset: TW3(28..31) - hdr.inner_tcp.res: TW3(24..27) - hdr.inner_tcp.flags: TW3(16..23) - hdr.inner_tcp.window: TW3(0..15) - hdr.inner_tcp.checksum: TW24(16..31) - hdr.inner_tcp.urgent_ptr: TW24(0..15) - hdr.sip.data: W8 - hdr.inner_udp.src_port: TW3(16..31) - hdr.inner_udp.dst_port: TW3(0..15) - hdr.inner_udp.hdr_length: TW24(16..31) - hdr.inner_udp.checksum: TW24(0..15) - hdr.inner_icmp.type_: TW3(24..31) - hdr.inner_icmp.code: TW3(16..23) - hdr.inner_icmp.hdr_checksum: TW3(0..15) - hdr.ipsec_esp.spi: W9 - hdr.ipsec_esp.sn: W10 - hdr.inner_ipv6.version: TW2(28..31) - hdr.inner_ipv6.traffic_class: TW2(20..27) - hdr.inner_ipv6.flow_label: TW2(0..19) - hdr.inner_ipv6.payload_len: TH3 - hdr.inner_ipv6.next_hdr: B8 - hdr.inner_ipv6.hop_limit: TB16 - hdr.inner_ipv6.src_addr.0-31: W11 - hdr.inner_ipv6.src_addr.32-63: W12 - hdr.inner_ipv6.src_addr.64-95: W13 - hdr.inner_ipv6.src_addr.96-127: W14 - hdr.inner_ipv6.dst_addr.0-31: W15 - hdr.inner_ipv6.dst_addr.32-63: W32 - hdr.inner_ipv6.dst_addr.64-95: W33 - hdr.inner_ipv6.dst_addr.96-127: W34 - hdr.gtpv2_12b.version: TH0(13..15) - hdr.gtpv2_12b.pb: TH0(12) - hdr.gtpv2_12b.tf: TH0(11) - hdr.gtpv2_12b.spare1: TH0(8..10) - hdr.gtpv2_12b.message_type: TH0(0..7) - hdr.gtpv2_12b.total_len: TH1 - hdr.gtpv2_12b.teid: W35 - hdr.gtpv2_12b.seq_no.0-7: TB18 - hdr.gtpv2_12b.seq_no.8-23: TH26 - hdr.gtpv2_12b.spare2: TB17 - hdr.udp.src_port: TW18(16..31) - hdr.udp.dst_port: TW18(0..15) - hdr.udp.hdr_length: TW19(16..31) - hdr.udp.checksum: TW19(0..15) - hdr.vxlan.flags: TW1(24..31) - hdr.vxlan.reserved: TW1(0..23) - hdr.vxlan.vni.0-7: TH0(8..15) - hdr.vxlan.vni.8-23: TH1 - hdr.vxlan.reserved2: TH0(0..7) - hdr.inner_ethernet.dst_addr.0-7: TB17 - hdr.inner_ethernet.dst_addr.8-15: TB18 - hdr.inner_ethernet.dst_addr.16-47: TW25 - hdr.inner_ethernet.src_addr.0-15: TH26 - hdr.inner_ethernet.src_addr.16-23: TB0 - hdr.inner_ethernet.src_addr.24-31: TB1 - hdr.inner_ethernet.src_addr.32-47: TH39 - hdr.inner_ethernet.ether_type: TH2 - hdr.gtpv1_8b.version: TH0(13..15) - hdr.gtpv1_8b.pt: TH0(12) - hdr.gtpv1_8b.reserved: TH0(11) - hdr.gtpv1_8b.e: TH0(10) - hdr.gtpv1_8b.s: TH0(9) - hdr.gtpv1_8b.pn: TH0(8) - hdr.gtpv1_8b.message_type: TH0(0..7) - hdr.gtpv1_8b.message_len: TH1 - hdr.gtpv1_8b.teid: TW1 - hdr.gtpv1_12b.version: TH0(13..15) - hdr.gtpv1_12b.pt: TH0(12) - hdr.gtpv1_12b.reserved: TH0(11) - hdr.gtpv1_12b.e: TH0(10) - hdr.gtpv1_12b.s: TH0(9) - hdr.gtpv1_12b.pn: TH0(8) - hdr.gtpv1_12b.message_type: TH0(0..7) - hdr.gtpv1_12b.message_len: TH1 - hdr.gtpv1_12b.teid: TW25 - hdr.gtpv1_12b.seq_no: TW1(16..31) - hdr.gtpv1_12b.n_pdu_no: TW1(8..15) - hdr.gtpv1_12b.next_ex_hdr_t: TW1(0..7) - hdr.l2tp.TLxxSxOP: TW1(20..31) - hdr.l2tp.version: TW1(16..19) - hdr.l2tp.l2tp_length: TW1(8..15) - hdr.l2tp.tunnel_id.0-7: TB0 - hdr.l2tp.tunnel_id.8-15: TW1(0..7) - hdr.l2tp.session_id: TH26 - hdr.l2tp.Ns.0-7: TB18 - hdr.l2tp.Ns.8-15: TB19 - hdr.l2tp.Nr: TH0 - hdr.l2tp.offset_size: TB17 - hdr.l2tp.offset_pad: TB1 - hdr.pppoe.version: TH1(12..15) - hdr.pppoe.type: TH1(8..11) - hdr.pppoe.code: TH1(0..7) - hdr.pppoe.session_id: TH2 - hdr.pppoe.pppoe_length: TW25(16..31) - hdr.pppoe.ppp_proto: TW25(0..15) - hdr.icmp.type_: TW1(24..31) - hdr.icmp.code: TW1(16..23) - hdr.icmp.hdr_checksum: TW1(0..15) - hdr.sctp.src_port: TW1(16..31) - hdr.sctp.dst_port: TW1(0..15) - hdr.sctp.verifTag: TW2 - hdr.sctp.checksum: TH0 - hdr.gre.C: TH0(15) - hdr.gre.R: TH0(14) - hdr.gre.K: TH0(13) - hdr.gre.S: TH0(12) - hdr.gre.s: TH0(11) - hdr.gre.recurse: TH0(8..10) - hdr.gre.flags: TH0(3..7) - hdr.gre.version: TH0(0..2) - hdr.gre.proto.0-7: TB0 - hdr.gre.proto.8-15: TB1 - hdr.ipv6.version: TW0(28..31) - hdr.ipv6.traffic_class: TW0(20..27) - hdr.ipv6.flow_label: TW0(0..19) - hdr.ipv6.payload_len: TW16(16..31) - hdr.ipv6.next_hdr: TW16(8..15) - hdr.ipv6.hop_limit: TW16(0..7) - hdr.ipv6.src_addr.0-15: TH29 - hdr.ipv6.src_addr.16-31: TH36 - hdr.ipv6.src_addr.32-47: TH37 - hdr.ipv6.src_addr.48-63: TH38 - hdr.ipv6.src_addr.64-71: TB8 - hdr.ipv6.src_addr.72-79: TB9 - hdr.ipv6.src_addr.80-87: TB10 - hdr.ipv6.src_addr.88-95: TB11 - hdr.ipv6.src_addr.96-127: W36 - hdr.ipv6.dst_addr.0-31: W37 - hdr.ipv6.dst_addr.32-63: W38 - hdr.ipv6.dst_addr.64-95: W39 - hdr.ipv6.dst_addr.96-127: W40 - hdr.vlan_tag$0.pcp: H4(13..15) - hdr.vlan_tag$0.cfi: H4(12) - hdr.vlan_tag$0.vid: H4(0..11) - hdr.vlan_tag$0.ether_type: TH4 - hdr.vlan_tag$1.pcp: TH5(13..15) - hdr.vlan_tag$1.cfi: TH5(12) - hdr.vlan_tag$1.vid: TH5(0..11) - hdr.vlan_tag$1.ether_type.0-7: TB2 - hdr.vlan_tag$1.ether_type.8-15: TB3 - hdr.vlan_tag$2.pcp: TW8(29..31) - hdr.vlan_tag$2.cfi: TW8(28) - hdr.vlan_tag$2.vid: TW8(16..27) - hdr.vlan_tag$2.ether_type: TW8(0..15) - hdr.vlan_tag$3.pcp: TW9(29..31) - hdr.vlan_tag$3.cfi: TW9(28) - hdr.vlan_tag$3.vid: TW9(16..27) - hdr.vlan_tag$3.ether_type: TW9(0..15) - hdr.vlan_tag$4.pcp: TW10(29..31) - hdr.vlan_tag$4.cfi: TW10(28) - hdr.vlan_tag$4.vid: TW10(16..27) - hdr.vlan_tag$4.ether_type: TW10(0..15) - hdr.mpls$0.label: TW11(12..31) - hdr.mpls$0.exp: TW11(9..11) - hdr.mpls$0.bos: TW11(8) - hdr.mpls$0.ttl: TW11(0..7) - hdr.mpls$1.label.0-3: TH12(12..15) - hdr.mpls$1.label.4-19: TH13 - hdr.mpls$1.exp: TH12(9..11) - hdr.mpls$1.bos: TH12(8) - hdr.mpls$1.ttl: TH12(0..7) - hdr.mpls$2.label.0-3: TH14(12..15) - hdr.mpls$2.label.4-19: TH15 - hdr.mpls$2.exp: TH14(9..11) - hdr.mpls$2.bos: TH14(8) - hdr.mpls$2.ttl: TH14(0..7) - hdr.mpls$3.label.0-3: TH16(12..15) - hdr.mpls$3.label.4-19: TH17 - hdr.mpls$3.exp: TH16(9..11) - hdr.mpls$3.bos: TH16(8) - hdr.mpls$3.ttl: TH16(0..7) - hdr.fabric.pad1: W5(31) - hdr.fabric.is_hit: W5(30) - hdr.fabric.is_to_cn78: W5(29) - hdr.fabric.is_to_td3: W5(28) - hdr.fabric.is_hdr_decap: W5(27) - hdr.fabric.ig_port_type: W5(24..26) - hdr.fabric.pad2: W5(18..23) - hdr.fabric.mac_index: W5(0..17) - hdr.fabric.pad4: B4(4..7) - hdr.fabric.flags_drop: B4(3) - hdr.fabric.is_trunc_mir: B4(2) - hdr.fabric.count_index.0-15: W3(16..31) - hdr.fabric.count_index.16-17: B4(0..1) - hdr.fabric.mc_index: W3(0..15) - hdr.fabric.vlan_index: W4(16..31) - hdr.fabric.ether_type: W4(0..15) - hdr.fabric_from_cn78.action_type: W4(24..31) - hdr.fabric_from_cn78.port_group_id: W3(16..31) - hdr.fabric_from_cn78.ether_type: W3(0..15) - ig_intr_md_for_tm.ucast_egress_port: H1(0..8) - ig_intr_md_for_tm.bypass_egress: B2(5) - ig_intr_md_for_tm.mcast_grp_b: H0 - ig_intr_md_for_tm.level1_mcast_hash: W0(0..12) - ig_intr_md_for_tm.level2_mcast_hash: W1(0..12) - ig_intr_md_for_dprsr.drop_ctl: B3(4..6) - ig_intr_md_for_dprsr.mirror_type: B1(0..2) - __pad_3: H2(10..15) - __pad_4: H6(10..15) - hdr.bridged_md.$valid: W41(0) - hdr.ethernet.$valid: W41(1) - hdr.ipv4.$valid: W41(2) - hdr.tcp.$valid: W41(3) - hdr.gtpv2_8b.$valid: W41(4) - hdr.imsi.$valid: W41(5) - hdr.cause_ie_6b.$valid: W41(6) - hdr.cause_ie_10b.$valid: W41(7) - hdr.inner_ipv4.$valid: W41(8) - hdr.inner_tcp.$valid: W41(9) - hdr.sip.$valid: W41(10) - hdr.inner_udp.$valid: W41(11) - hdr.inner_icmp.$valid: W41(12) - hdr.ipsec_esp.$valid: W41(13) - hdr.inner_ipv6.$valid: W41(14) - hdr.gtpv2_12b.$valid: W41(15) - hdr.udp.$valid: W41(16) - hdr.vxlan.$valid: W41(17) - hdr.inner_ethernet.$valid: W41(18) - hdr.gtpv1_8b.$valid: W41(19) - hdr.gtpv1_12b.$valid: W41(20) - hdr.l2tp.$valid: W41(21) - hdr.pppoe.$valid: W41(22) - hdr.icmp.$valid: W41(23) - hdr.sctp.$valid: W41(24) - hdr.gre.$valid: W41(25) - hdr.ipv6.$valid: W41(26) - hdr.fabric.$valid: W41(27) - hdr.fabric_from_cn78.$valid: W41(28) - hdr.mpls.$stkvalid: B3(0..3) - hdr.mpls$0.$valid: B3(3) - hdr.mpls$1.$valid: B3(2) - hdr.mpls$2.$valid: B3(1) - hdr.mpls$3.$valid: B3(0) - hdr.vlan_tag.$stkvalid: B2(0..4) - hdr.vlan_tag$0.$valid: B2(4) - hdr.vlan_tag$1.$valid: B2(3) - hdr.vlan_tag$2.$valid: B2(2) - hdr.vlan_tag$3.$valid: B2(1) - hdr.vlan_tag$4.$valid: B2(0) - context_json: - TB8: - - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.flags, hdr.ipv4.frag_offset ] } - TB9: - - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.frag_offset ] } - TB10: - - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.identification ] } - TB11: - - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.identification ] } - TH29: - - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.src_addr ] } - TH36: - - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.src_addr ] } - TH37: - - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.dst_addr ] } - TH38: - - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.dst_addr ] } - TW26: - - { name : hdr.ethernet.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B0: - - { name : hdr.bridged_md.src, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - B1: - - { name : ig_intr_md_for_dprsr.mirror_type, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } - B2: - - { name : hdr.vlan_tag$0.$valid, live_start : 0, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.vlan_tag$1.$valid, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.vlan_tag$2.$valid, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.vlan_tag$3.$valid, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.vlan_tag$4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.vlan_tag.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_intr_md_for_tm.bypass_egress, live_start : 0, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_md.trunc_type, live_start : 9, live_end : 11, mutually_exclusive_with: [ ] } - B3: - - { name : hdr.mpls$0.$valid, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.mpls$1.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.mpls$2.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.mpls$3.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.mpls.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_intr_md_for_dprsr.drop_ctl, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } - B4: - - { name : hdr.fabric.count_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.flags_drop, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.is_trunc_mir, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.pad4, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B5: - - { name : ig_md.count_index, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - B6: - - { name : hdr.bridged_md.in_ig_port_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.bridged_md.tunnel_type, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_md.in_ig_port_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_md.tunnel_type, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } - B7: - - { name : hdr.bridged_md.pad1, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.bridged_md.tunnel_type, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_md.tunnel_type, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } - B8: - - { name : hdr.inner_ipv6.next_hdr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B9: - - { name : ig_md.mirror.src, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } - B10: - - { name : ig_md.mirror.type, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } - B11: - - { name : ig_md.lkp.ip_proto, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } - H0: - - { name : ig_intr_md_for_tm.mcast_grp_b, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } - H1: - - { name : ig_intr_md_for_tm.ucast_egress_port, live_start : 10, live_end : deparser, mutually_exclusive_with: [ ] } - H2: - - { name : __pad_3, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_md.mirror.session_id, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } - H3: - - { name : hdr.bridged_md.ip_hdr_location, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.bridged_md.pkt_proto_type, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_md.ip_hdr_location, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_md.pkt_proto_type, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } - H4: - - { name : hdr.vlan_tag$0.cfi, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.vlan_tag$0.pcp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.vlan_tag$0.vid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H5: - - { name : hdr.ethernet.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H6: - - { name : __pad_4, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_md.count_index, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - H7: - - { name : hdr.ethernet.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H8: - - { name : ig_md.vlan_index, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - H9: - - { name : ig_md.lkp.l4_src_port, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } - H10: - - { name : ig_md.lkp.inner_l4_src_port, live_start : parser, live_end : 9, mutually_exclusive_with: [ ] } - H11: - - { name : ig_md.lkp.l4_dst_port, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } - H12: - - { name : ig_md.lkp.inner_l4_dst_port, live_start : parser, live_end : 9, mutually_exclusive_with: [ ] } - W0: - - { name : ig_intr_md_for_tm.level1_mcast_hash, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_md.port_group_id, live_start : 0, live_end : 1, mutually_exclusive_with: [ ] } - W1: - - { name : ig_intr_md_for_tm.level2_mcast_hash, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_md.action_type, live_start : 0, live_end : 1, mutually_exclusive_with: [ ] } - W2: - - { name : ig_md.hash, live_start : 0, live_end : 11, mutually_exclusive_with: [ ] } - W3: - - { name : hdr.fabric.count_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.fabric_from_cn78.ether_type, hdr.fabric_from_cn78.port_group_id ] } - - { name : hdr.fabric.mc_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.fabric_from_cn78.ether_type, hdr.fabric_from_cn78.port_group_id ] } - - { name : hdr.fabric_from_cn78.ether_type, live_start : parser, live_end : 0, mutually_exclusive_with: [ hdr.fabric.count_index, hdr.fabric.mc_index ] } - - { name : hdr.fabric_from_cn78.port_group_id, live_start : parser, live_end : 0, mutually_exclusive_with: [ hdr.fabric.count_index, hdr.fabric.mc_index ] } - W4: - - { name : hdr.fabric.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.fabric_from_cn78.action_type ] } - - { name : hdr.fabric.vlan_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.fabric_from_cn78.action_type ] } - - { name : hdr.fabric_from_cn78.action_type, live_start : parser, live_end : 0, mutually_exclusive_with: [ hdr.fabric.ether_type, hdr.fabric.vlan_index ] } - W5: - - { name : hdr.fabric.ig_port_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.is_hdr_decap, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.is_hit, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.is_to_cn78, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.is_to_td3, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.mac_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.pad1, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.pad2, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W6: - - { name : hdr.inner_tcp.seq_no, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W7: - - { name : hdr.inner_tcp.ack_no, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W8: - - { name : hdr.sip.data, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W9: - - { name : hdr.ipsec_esp.spi, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W10: - - { name : hdr.ipsec_esp.sn, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W11: - - { name : hdr.inner_ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W12: - - { name : hdr.inner_ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W13: - - { name : hdr.inner_ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W14: - - { name : hdr.inner_ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W15: - - { name : hdr.inner_ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W32: - - { name : hdr.inner_ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W33: - - { name : hdr.inner_ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W34: - - { name : hdr.inner_ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W35: - - { name : hdr.gtpv2_12b.teid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W36: - - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W37: - - { name : hdr.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W38: - - { name : hdr.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W39: - - { name : hdr.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W40: - - { name : hdr.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W41: - - { name : hdr.bridged_md.$valid, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.cause_ie_10b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.cause_ie_6b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ethernet.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_from_cn78.$valid, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } - - { name : hdr.gre.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.gtpv1_12b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.gtpv1_8b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.gtpv2_12b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.gtpv2_8b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.icmp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.imsi.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.inner_ethernet.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.inner_icmp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.inner_ipv4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.inner_ipv6.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.inner_tcp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.inner_udp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ipsec_esp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ipv4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ipv6.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.l2tp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.pppoe.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.sctp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.sip.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.tcp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.udp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.vxlan.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W49: - - { name : ig_md.lkp.ip_src_addr, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } - W50: - - { name : ig_md.lkp.ip_src_addr, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } - W51: - - { name : ig_md.lkp.ip_src_addr, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } - W52: - - { name : ig_md.lkp.ip_src_addr, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } - W53: - - { name : ig_md.lkp.ip_dst_addr, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } - W54: - - { name : ig_md.lkp.ip_dst_addr, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } - W55: - - { name : ig_md.lkp.ip_dst_addr, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } - W56: - - { name : ig_md.lkp.ip_dst_addr, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } -phv egress: - eg_intr_md.egress_port: H16(0..8) - eg_md.lkp.inner_l4_src_port: H25 - eg_md.lkp.inner_l4_dst_port: H26 - eg_md.in_ig_port_type: B20(0..2) - eg_md.ip_hdr_location: H23(0..7) - eg_md.pkt_proto_type: H23(8..15) - hdr.fabric_to_cn78.pkt_proto_type: H23(8..15) - hdr.fabric_to_cn78.ip_hdr_location: H23(0..7) - hdr.fabric_to_cn78.payload_crc32: TH7 - hdr.fabric_to_cn78.ether_type: H18 - hdr.ethernet.dst_addr.0-15: H24 - hdr.ethernet.dst_addr.16-47: TW31 - hdr.ethernet.src_addr.0-15: TH6 - hdr.ethernet.src_addr.16-31: TH35 - hdr.ethernet.src_addr.32-47: TH42 - hdr.ethernet.ether_type: H19 - hdr.ipv4.version: TW4(28..31) - hdr.ipv4.ihl: TW4(24..27) - hdr.ipv4.diffserv: TW4(16..23) - hdr.ipv4.total_len: TW4(0..15) - hdr.ipv4.identification: TW20(16..31) - hdr.ipv4.flags: TW20(13..15) - hdr.ipv4.frag_offset: TW20(0..12) - hdr.ipv4.ttl: TH31(8..15) - hdr.ipv4.protocol: TH31(0..7) - hdr.ipv4.hdr_checksum: TW22(0..15) - hdr.ipv4.src_addr.0-15: TH43 - hdr.ipv4.src_addr.16-31: TH44 - hdr.ipv4.dst_addr.0-15: TH45 - hdr.ipv4.dst_addr.16-31: TH46 - hdr.tcp.src_port: TW23(16..31) - hdr.tcp.dst_port: TW23(0..15) - hdr.tcp.seq_no: TW30 - hdr.tcp.ack_no.0-7: TB23 - hdr.tcp.ack_no.8-15: TB28 - hdr.tcp.ack_no.16-31: TH47 - hdr.tcp.data_offset: TW5(28..31) - hdr.tcp.res: TW5(24..27) - hdr.tcp.flags: TW5(16..23) - hdr.tcp.window: TW5(0..15) - hdr.tcp.checksum: TH32 - hdr.tcp.urgent_ptr.0-7: TB21 - hdr.tcp.urgent_ptr.8-15: TB22 - hdr.gtpv2_8b.version: TH8(13..15) - hdr.gtpv2_8b.pb: TH8(12) - hdr.gtpv2_8b.tf: TH8(11) - hdr.gtpv2_8b.spare1: TH8(8..10) - hdr.gtpv2_8b.message_type: TH8(0..7) - hdr.gtpv2_8b.total_len: TH9 - hdr.gtpv2_8b.seq_no.0-7: TH33(8..15) - hdr.gtpv2_8b.seq_no.8-23: TH34 - hdr.gtpv2_8b.spare2: TH33(0..7) - hdr.imsi.type: TW6(24..31) - hdr.imsi.len: TW6(8..23) - hdr.imsi.spare: TW6(4..7) - hdr.imsi.instance: TW6(0..3) - hdr.imsi.num_digit.0-31: TW21 - hdr.imsi.num_digit.32-63: TW28 - hdr.imsi.num_digit.64-95: TW29 - hdr.imsi.num_digit.96-103: TB20 - hdr.imsi.num_digit.104-111: TB29 - hdr.imsi.num_digit.112-127: TH30 - hdr.cause_ie_6b.type: TB5 - hdr.cause_ie_6b.len: TW7(16..31) - hdr.cause_ie_6b.spare1: TW7(12..15) - hdr.cause_ie_6b.instance: TW7(8..11) - hdr.cause_ie_6b.cause_value: TW7(0..7) - hdr.cause_ie_6b.spare2: TB4(3..7) - hdr.cause_ie_6b.pce: TB4(2) - hdr.cause_ie_6b.bce: TB4(1) - hdr.cause_ie_6b.cs: TB4(0) - hdr.cause_ie_10b.type: TB5 - hdr.cause_ie_10b.len: TW7(16..31) - hdr.cause_ie_10b.spare1: TW7(12..15) - hdr.cause_ie_10b.instance: TW7(8..11) - hdr.cause_ie_10b.cause_value: TW7(0..7) - hdr.cause_ie_10b.spare2: TB4(3..7) - hdr.cause_ie_10b.pce: TB4(2) - hdr.cause_ie_10b.bce: TB4(1) - hdr.cause_ie_10b.cs: TB4(0) - hdr.cause_ie_10b.type_oe: TH11(8..15) - hdr.cause_ie_10b.len_oe.0-7: TH10(8..15) - hdr.cause_ie_10b.len_oe.8-15: TH11(0..7) - hdr.cause_ie_10b.spare_oe: TH10(4..7) - hdr.cause_ie_10b.instance_oe: TH10(0..3) - hdr.inner_ipv4.version: TW6(28..31) - hdr.inner_ipv4.ihl: TW6(24..27) - hdr.inner_ipv4.diffserv: TW6(16..23) - hdr.inner_ipv4.total_len: TW6(0..15) - hdr.inner_ipv4.identification: TH30 - hdr.inner_ipv4.flags: TH11(13..15) - hdr.inner_ipv4.frag_offset: TH11(0..12) - hdr.inner_ipv4.ttl: TW21(24..31) - hdr.inner_ipv4.protocol: TW21(16..23) - hdr.inner_ipv4.hdr_checksum: TW21(0..15) - hdr.inner_ipv4.src_addr.0-7: TB20 - hdr.inner_ipv4.src_addr.8-15: TB29 - hdr.inner_ipv4.src_addr.16-23: TB30 - hdr.inner_ipv4.src_addr.24-31: TB31 - hdr.inner_ipv4.dst_addr: W18 - hdr.inner_tcp.src_port: TW28(16..31) - hdr.inner_tcp.dst_port: TW28(0..15) - hdr.inner_tcp.seq_no: W19 - hdr.inner_tcp.ack_no: W20 - hdr.inner_tcp.data_offset: TW7(28..31) - hdr.inner_tcp.res: TW7(24..27) - hdr.inner_tcp.flags: TW7(16..23) - hdr.inner_tcp.window: TW7(0..15) - hdr.inner_tcp.checksum: TW29(16..31) - hdr.inner_tcp.urgent_ptr: TW29(0..15) - hdr.sip.data: W21 - hdr.inner_udp.src_port: TW7(16..31) - hdr.inner_udp.dst_port: TW7(0..15) - hdr.inner_udp.hdr_length: TW28(16..31) - hdr.inner_udp.checksum: TW28(0..15) - hdr.inner_icmp.type_: TW7(24..31) - hdr.inner_icmp.code: TW7(16..23) - hdr.inner_icmp.hdr_checksum: TW7(0..15) - hdr.ipsec_esp.spi: W22 - hdr.ipsec_esp.sn: W23 - hdr.inner_ipv6.version: TW6(28..31) - hdr.inner_ipv6.traffic_class: TW6(20..27) - hdr.inner_ipv6.flow_label: TW6(0..19) - hdr.inner_ipv6.payload_len: TH11 - hdr.inner_ipv6.next_hdr: B19 - hdr.inner_ipv6.hop_limit: TB20 - hdr.inner_ipv6.src_addr.0-31: W18 - hdr.inner_ipv6.src_addr.32-63: W24 - hdr.inner_ipv6.src_addr.64-95: W25 - hdr.inner_ipv6.src_addr.96-127: W26 - hdr.inner_ipv6.dst_addr.0-31: W27 - hdr.inner_ipv6.dst_addr.32-63: W28 - hdr.inner_ipv6.dst_addr.64-95: W29 - hdr.inner_ipv6.dst_addr.96-127: W30 - hdr.gtpv2_12b.version: TH8(13..15) - hdr.gtpv2_12b.pb: TH8(12) - hdr.gtpv2_12b.tf: TH8(11) - hdr.gtpv2_12b.spare1: TH8(8..10) - hdr.gtpv2_12b.message_type: TH8(0..7) - hdr.gtpv2_12b.total_len: TH9 - hdr.gtpv2_12b.teid: W31 - hdr.gtpv2_12b.seq_no.0-7: TH33(8..15) - hdr.gtpv2_12b.seq_no.8-23: TH34 - hdr.gtpv2_12b.spare2: TH33(0..7) - hdr.udp.src_port: TW23(16..31) - hdr.udp.dst_port: TW23(0..15) - hdr.udp.hdr_length: TH32 - hdr.udp.checksum.0-7: TB22 - hdr.udp.checksum.8-15: TB23 - hdr.vxlan.flags: TW5(24..31) - hdr.vxlan.reserved: TW5(0..23) - hdr.vxlan.vni.0-7: TH8(8..15) - hdr.vxlan.vni.8-23: TH9 - hdr.vxlan.reserved2: TH8(0..7) - hdr.inner_ethernet.dst_addr.0-7: TB4 - hdr.inner_ethernet.dst_addr.8-15: TB5 - hdr.inner_ethernet.dst_addr.16-47: TW30 - hdr.inner_ethernet.src_addr.0-15: TH33 - hdr.inner_ethernet.src_addr.16-31: TH34 - hdr.inner_ethernet.src_addr.32-47: TH47 - hdr.inner_ethernet.ether_type: TH10 - hdr.gtpv1_8b.version: TH8(13..15) - hdr.gtpv1_8b.pt: TH8(12) - hdr.gtpv1_8b.reserved: TH8(11) - hdr.gtpv1_8b.e: TH8(10) - hdr.gtpv1_8b.s: TH8(9) - hdr.gtpv1_8b.pn: TH8(8) - hdr.gtpv1_8b.message_type: TH8(0..7) - hdr.gtpv1_8b.message_len: TH9 - hdr.gtpv1_8b.teid: TW5 - hdr.gtpv1_12b.version: TH8(13..15) - hdr.gtpv1_12b.pt: TH8(12) - hdr.gtpv1_12b.reserved: TH8(11) - hdr.gtpv1_12b.e: TH8(10) - hdr.gtpv1_12b.s: TH8(9) - hdr.gtpv1_12b.pn: TH8(8) - hdr.gtpv1_12b.message_type: TH8(0..7) - hdr.gtpv1_12b.message_len: TH9 - hdr.gtpv1_12b.teid: TW30 - hdr.gtpv1_12b.seq_no: TW5(16..31) - hdr.gtpv1_12b.n_pdu_no: TW5(8..15) - hdr.gtpv1_12b.next_ex_hdr_t: TW5(0..7) - hdr.l2tp.TLxxSxOP: TW5(20..31) - hdr.l2tp.version: TW5(16..19) - hdr.l2tp.l2tp_length: TW5(8..15) - hdr.l2tp.tunnel_id.0-7: TB4 - hdr.l2tp.tunnel_id.8-15: TW5(0..7) - hdr.l2tp.session_id: TH34 - hdr.l2tp.Ns: TH33 - hdr.l2tp.Nr: TH8 - hdr.l2tp.offset_size: TB21 - hdr.l2tp.offset_pad: TB5 - hdr.pppoe.version: TH9(12..15) - hdr.pppoe.type: TH9(8..11) - hdr.pppoe.code: TH9(0..7) - hdr.pppoe.session_id: TH10 - hdr.pppoe.pppoe_length: TW30(16..31) - hdr.pppoe.ppp_proto: TW30(0..15) - hdr.icmp.type_: TW5(24..31) - hdr.icmp.code: TW5(16..23) - hdr.icmp.hdr_checksum: TW5(0..15) - hdr.sctp.src_port: TW5(16..31) - hdr.sctp.dst_port: TW5(0..15) - hdr.sctp.verifTag: TW6 - hdr.sctp.checksum: TH8 - hdr.gre.C: TH8(15) - hdr.gre.R: TH8(14) - hdr.gre.K: TH8(13) - hdr.gre.S: TH8(12) - hdr.gre.s: TH8(11) - hdr.gre.recurse: TH8(8..10) - hdr.gre.flags: TH8(3..7) - hdr.gre.version: TH8(0..2) - hdr.gre.proto.0-7: TB4 - hdr.gre.proto.8-15: TB5 - hdr.ipv6.version: TW4(28..31) - hdr.ipv6.traffic_class: TW4(20..27) - hdr.ipv6.flow_label: TW4(0..19) - hdr.ipv6.payload_len: TW20(16..31) - hdr.ipv6.next_hdr: TW20(8..15) - hdr.ipv6.hop_limit: TW20(0..7) - hdr.ipv6.src_addr.0-15: TH31 - hdr.ipv6.src_addr.16-31: TH43 - hdr.ipv6.src_addr.32-47: TH44 - hdr.ipv6.src_addr.48-63: TH45 - hdr.ipv6.src_addr.64-95: TW22 - hdr.ipv6.src_addr.96-111: TH46 - hdr.ipv6.src_addr.112-127: H22 - hdr.ipv6.dst_addr.0-31: W44 - hdr.ipv6.dst_addr.32-63: W45 - hdr.ipv6.dst_addr.64-95: W46 - hdr.ipv6.dst_addr.96-127: W47 - hdr.vlan_tag$0.pcp: H21(13..15) - hdr.vlan_tag$0.cfi: H21(12) - hdr.vlan_tag$0.vid: H21(0..11) - hdr.vlan_tag$0.ether_type.0-7: TB6 - hdr.vlan_tag$0.ether_type.8-15: TB7 - hdr.vlan_tag$1.pcp: TW12(29..31) - hdr.vlan_tag$1.cfi: TW12(28) - hdr.vlan_tag$1.vid: TW12(16..27) - hdr.vlan_tag$1.ether_type: TW12(0..15) - hdr.vlan_tag$2.pcp: TW13(29..31) - hdr.vlan_tag$2.cfi: TW13(28) - hdr.vlan_tag$2.vid: TW13(16..27) - hdr.vlan_tag$2.ether_type: TW13(0..15) - hdr.vlan_tag$3.pcp: TW14(29..31) - hdr.vlan_tag$3.cfi: TW14(28) - hdr.vlan_tag$3.vid: TW14(16..27) - hdr.vlan_tag$3.ether_type: TW14(0..15) - hdr.vlan_tag$4.pcp: TW15(29..31) - hdr.vlan_tag$4.cfi: TW15(28) - hdr.vlan_tag$4.vid: TW15(16..27) - hdr.vlan_tag$4.ether_type: TW15(0..15) - hdr.mpls$0.label.0-3: TH18(12..15) - hdr.mpls$0.label.4-19: TH19 - hdr.mpls$0.exp: TH18(9..11) - hdr.mpls$0.bos: TH18(8) - hdr.mpls$0.ttl: TH18(0..7) - hdr.mpls$1.label.0-3: TH20(12..15) - hdr.mpls$1.label.4-19: TH21 - hdr.mpls$1.exp: TH20(9..11) - hdr.mpls$1.bos: TH20(8) - hdr.mpls$1.ttl: TH20(0..7) - hdr.mpls$2.label.0-3: TH22(12..15) - hdr.mpls$2.label.4-19: TH23 - hdr.mpls$2.exp: TH22(9..11) - hdr.mpls$2.bos: TH22(8) - hdr.mpls$2.ttl: TH22(0..7) - hdr.mpls$3.label.0-3: TB12(4..7) - hdr.mpls$3.label.4-11: TB14 - hdr.mpls$3.label.12-19: TB15 - hdr.mpls$3.exp: TB12(1..3) - hdr.mpls$3.bos: TB12(0) - hdr.mpls$3.ttl: TB13 - hdr.fabric.pad1: W16(31) - hdr.fabric.is_hit: W16(30) - hdr.fabric.is_to_cn78: W16(29) - hdr.fabric.is_to_td3: W16(28) - hdr.fabric.is_hdr_decap: W16(27) - hdr.fabric.ig_port_type: W16(24..26) - hdr.fabric.pad2: W16(18..23) - hdr.fabric.mac_index: W16(0..17) - hdr.fabric.pad4: W17(28..31) - hdr.fabric.flags_drop: W17(27) - hdr.fabric.is_trunc_mir: W17(26) - hdr.fabric.count_index: W17(8..25) - hdr.fabric.mc_index.0-7: B18 - hdr.fabric.mc_index.8-15: W17(0..7) - hdr.fabric.vlan_index: H20 - hdr.fabric.ether_type: H17 - hdr.fabric_to_cn78.$valid: W48(0) - hdr.ethernet.$valid: W48(1) - hdr.ipv4.$valid: W48(2) - hdr.tcp.$valid: W48(3) - hdr.gtpv2_8b.$valid: W48(4) - hdr.imsi.$valid: W48(5) - hdr.cause_ie_6b.$valid: W48(6) - hdr.cause_ie_10b.$valid: W48(7) - hdr.inner_ipv4.$valid: W48(8) - hdr.inner_tcp.$valid: W48(9) - hdr.sip.$valid: W48(10) - hdr.inner_udp.$valid: W48(11) - hdr.inner_icmp.$valid: W48(12) - hdr.ipsec_esp.$valid: W48(13) - hdr.inner_ipv6.$valid: W48(14) - hdr.gtpv2_12b.$valid: W48(15) - hdr.udp.$valid: W48(16) - hdr.vxlan.$valid: W48(17) - hdr.inner_ethernet.$valid: W48(18) - hdr.gtpv1_8b.$valid: W48(19) - hdr.gtpv1_12b.$valid: W48(20) - hdr.l2tp.$valid: W48(21) - hdr.pppoe.$valid: W48(22) - hdr.icmp.$valid: W48(23) - hdr.sctp.$valid: W48(24) - hdr.gre.$valid: W48(25) - hdr.ipv6.$valid: W48(26) - hdr.fabric.$valid: W48(27) - hdr.mpls.$stkvalid: B17(0..3) - hdr.mpls$0.$valid: B17(3) - hdr.mpls$1.$valid: B17(2) - hdr.mpls$2.$valid: B17(1) - hdr.mpls$3.$valid: B17(0) - hdr.vlan_tag.$stkvalid: B16(0..4) - hdr.vlan_tag$0.$valid: B16(4) - hdr.vlan_tag$1.$valid: B16(3) - hdr.vlan_tag$2.$valid: B16(2) - hdr.vlan_tag$3.$valid: B16(1) - hdr.vlan_tag$4.$valid: B16(0) - context_json: - TH31: - - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.protocol, hdr.ipv4.ttl ] } - TH43: - - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.src_addr ] } - TH44: - - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.src_addr ] } - TH45: - - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.dst_addr ] } - TH46: - - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.dst_addr ] } - TW22: - - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ipv4.hdr_checksum ] } - TW31: - - { name : hdr.ethernet.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B16: - - { name : hdr.vlan_tag$0.$valid, live_start : 0, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.vlan_tag$1.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.vlan_tag$2.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.vlan_tag$3.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.vlan_tag$4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.vlan_tag.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B17: - - { name : hdr.mpls$0.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.mpls$1.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.mpls$2.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.mpls$3.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.mpls.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B18: - - { name : hdr.fabric.mc_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B19: - - { name : hdr.inner_ipv6.next_hdr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B20: - - { name : eg_md.in_ig_port_type, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } - H16: - - { name : eg_intr_md.egress_port, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H17: - - { name : hdr.fabric.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H18: - - { name : hdr.fabric_to_cn78.ether_type, live_start : 1, live_end : deparser, mutually_exclusive_with: [ ] } - H19: - - { name : hdr.ethernet.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H20: - - { name : hdr.fabric.vlan_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H21: - - { name : hdr.vlan_tag$0.cfi, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.vlan_tag$0.pcp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.vlan_tag$0.vid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H22: - - { name : hdr.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H23: - - { name : eg_md.ip_hdr_location, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : eg_md.pkt_proto_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_to_cn78.ip_hdr_location, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_to_cn78.pkt_proto_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H24: - - { name : hdr.ethernet.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H25: - - { name : eg_md.lkp.inner_l4_src_port, live_start : parser, live_end : 3, mutually_exclusive_with: [ ] } - H26: - - { name : eg_md.lkp.inner_l4_dst_port, live_start : parser, live_end : 3, mutually_exclusive_with: [ ] } - W16: - - { name : hdr.fabric.ig_port_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.is_hdr_decap, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.is_hit, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.is_to_cn78, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.is_to_td3, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.mac_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.pad1, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.pad2, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W17: - - { name : hdr.fabric.count_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.flags_drop, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.is_trunc_mir, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.mc_index, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.pad4, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W18: - - { name : hdr.inner_ipv4.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.inner_ipv6.src_addr ] } - - { name : hdr.inner_ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.inner_ipv4.dst_addr ] } - W19: - - { name : hdr.inner_tcp.seq_no, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W20: - - { name : hdr.inner_tcp.ack_no, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W21: - - { name : hdr.sip.data, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W22: - - { name : hdr.ipsec_esp.spi, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W23: - - { name : hdr.ipsec_esp.sn, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W24: - - { name : hdr.inner_ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W25: - - { name : hdr.inner_ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W26: - - { name : hdr.inner_ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W27: - - { name : hdr.inner_ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W28: - - { name : hdr.inner_ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W29: - - { name : hdr.inner_ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W30: - - { name : hdr.inner_ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W31: - - { name : hdr.gtpv2_12b.teid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W44: - - { name : hdr.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W45: - - { name : hdr.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W46: - - { name : hdr.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W47: - - { name : hdr.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W48: - - { name : hdr.cause_ie_10b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.cause_ie_6b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ethernet.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_to_cn78.$valid, live_start : 1, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.gre.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.gtpv1_12b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.gtpv1_8b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.gtpv2_12b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.gtpv2_8b.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.icmp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.imsi.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.inner_ethernet.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.inner_icmp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.inner_ipv4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.inner_ipv6.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.inner_tcp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.inner_udp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ipsec_esp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ipv4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ipv6.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.l2tp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.pppoe.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.sctp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.sip.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.tcp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.udp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.vxlan.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } -parser ingress: - start: $entry_point - init_zero: [ B11, W49, W50, W51, W52, W53, W54, W55, W56, H9, H11, H10, H12, B5, H6, W2, B6, B2, W1, W0, H8, B9, B10, H2, B3, W41, B0 ] - bitwise_or: [ B2, B3, W41 ] - hdr_len_adj: 16 - states: - $entry_point: - *: - load: { byte1 : 0 } - buf_req: 1 - next: start - start: - match: [ byte1 ] - 0b1*******: - shift: 8 - buf_req: 8 - next: end - 0b0*******: - load: { half : 28..29 } - shift: 8 - buf_req: 30 - next: TofinoIngressParserInner_2_parse_port_metadata - TofinoIngressParserInner_2_parse_port_metadata: - match: [ half ] - 0x0800: - 0: B6 # bit[5..7] -> B6 bit[2..0]: ingress::ig_md.in_ig_port_type - 8..11: TW26 # ingress::hdr.ethernet.dst_addr[47:16].16-47 - 12..13: H7 # ingress::hdr.ethernet.dst_addr[15:0].0-15 - 14..17: TW27 # ingress::hdr.ethernet.src_addr[47:16].16-47 - 18..19: TH25 # ingress::hdr.ethernet.src_addr[15:0].0-15 - 20..21: H5 # ingress::hdr.ethernet.ether_type - W41: 2 # value 1 -> W41 bit[1]: ingress::hdr.ethernet.$valid - shift: 22 - buf_req: 22 - next: parse_ipv4 - 0x86dd: - 0: B6 # bit[5..7] -> B6 bit[2..0]: ingress::ig_md.in_ig_port_type - 8..11: TW26 # ingress::hdr.ethernet.dst_addr[47:16].16-47 - 12..13: H7 # ingress::hdr.ethernet.dst_addr[15:0].0-15 - 14..17: TW27 # ingress::hdr.ethernet.src_addr[47:16].16-47 - 18..19: TH25 # ingress::hdr.ethernet.src_addr[15:0].0-15 - 20..21: H5 # ingress::hdr.ethernet.ether_type - W41: 2 # value 1 -> W41 bit[1]: ingress::hdr.ethernet.$valid - shift: 22 - buf_req: 22 - next: parse_ipv6 - 0x8100: - 0: B6 # bit[5..7] -> B6 bit[2..0]: ingress::ig_md.in_ig_port_type - 8..11: TW26 # ingress::hdr.ethernet.dst_addr[47:16].16-47 - 12..13: H7 # ingress::hdr.ethernet.dst_addr[15:0].0-15 - 14..17: TW27 # ingress::hdr.ethernet.src_addr[47:16].16-47 - 18..19: TH25 # ingress::hdr.ethernet.src_addr[15:0].0-15 - 20..21: H5 # ingress::hdr.ethernet.ether_type - W41: 2 # value 1 -> W41 bit[1]: ingress::hdr.ethernet.$valid - load: { half : 24..25 } - shift: 22 - buf_req: 26 - next: parse_vlan - 0x8847: - 0: B6 # bit[5..7] -> B6 bit[2..0]: ingress::ig_md.in_ig_port_type - 8..11: TW26 # ingress::hdr.ethernet.dst_addr[47:16].16-47 - 12..13: H7 # ingress::hdr.ethernet.dst_addr[15:0].0-15 - 14..17: TW27 # ingress::hdr.ethernet.src_addr[47:16].16-47 - 18..19: TH25 # ingress::hdr.ethernet.src_addr[15:0].0-15 - 20..21: H5 # ingress::hdr.ethernet.ether_type - W41: 2 # value 1 -> W41 bit[1]: ingress::hdr.ethernet.$valid - load: { byte1 : 24 } - shift: 22 - buf_req: 25 - next: parse_mpls - 0x81fe: - 0: B6 # bit[5..7] -> B6 bit[2..0]: ingress::ig_md.in_ig_port_type - 8..11: TW26 # ingress::hdr.ethernet.dst_addr[47:16].16-47 - 12..13: H7 # ingress::hdr.ethernet.dst_addr[15:0].0-15 - 14..17: TW27 # ingress::hdr.ethernet.src_addr[47:16].16-47 - 18..19: TH25 # ingress::hdr.ethernet.src_addr[15:0].0-15 - 20..21: H5 # ingress::hdr.ethernet.ether_type - W41: 2 # value 1 -> W41 bit[1]: ingress::hdr.ethernet.$valid - shift: 22 - buf_req: 22 - next: TofinoIngressParserInner_2_parse_port_metadata.$oob_stall_0 - 0x81ff: - 0: B6 # bit[5..7] -> B6 bit[2..0]: ingress::ig_md.in_ig_port_type - 8..11: TW26 # ingress::hdr.ethernet.dst_addr[47:16].16-47 - 12..13: H7 # ingress::hdr.ethernet.dst_addr[15:0].0-15 - 14..17: TW27 # ingress::hdr.ethernet.src_addr[47:16].16-47 - 18..19: TH25 # ingress::hdr.ethernet.src_addr[15:0].0-15 - 20..21: H5 # ingress::hdr.ethernet.ether_type - W41: 2 # value 1 -> W41 bit[1]: ingress::hdr.ethernet.$valid - load: { half : 26..27 } - shift: 22 - buf_req: 28 - next: parse_from_cn78 - 0x****: - 0: B6 # bit[5..7] -> B6 bit[2..0]: ingress::ig_md.in_ig_port_type - 8..11: TW26 # ingress::hdr.ethernet.dst_addr[47:16].16-47 - 12..13: H7 # ingress::hdr.ethernet.dst_addr[15:0].0-15 - 14..17: TW27 # ingress::hdr.ethernet.src_addr[47:16].16-47 - 18..19: TH25 # ingress::hdr.ethernet.src_addr[15:0].0-15 - 20..21: H5 # ingress::hdr.ethernet.ether_type - W41: 2 # value 1 -> W41 bit[1]: ingress::hdr.ethernet.$valid - shift: 22 - buf_req: 22 - next: end - parse_ipv4: - *: - 0..3: TW0 - # - bit[0..3] -> TW0 bit[31..28]: ingress::hdr.ipv4.version - # - bit[4..7] -> TW0 bit[27..24]: ingress::hdr.ipv4.ihl - # - bit[8..15] -> TW0 bit[23..16]: ingress::hdr.ipv4.diffserv - # - bit[16..31] -> TW0 bit[15..0]: ingress::hdr.ipv4.total_len - 4: TB11 # ingress::hdr.ipv4.identification[15:8].8-15 - 5: TB10 # ingress::hdr.ipv4.identification[7:0].0-7 - 6: TB8 - # - bit[48..50] -> TB8 bit[7..5]: ingress::hdr.ipv4.flags - # - bit[51..55] -> TB8 bit[4..0]: ingress::hdr.ipv4.frag_offset[12:8].8-12 - 7: TB9 # ingress::hdr.ipv4.frag_offset[7:0].0-7 - 8..11: TW16 - # - bit[64..71] -> TW16 bit[31..24]: ingress::hdr.ipv4.ttl - # - bit[72..79] -> TW16 bit[23..16]: ingress::hdr.ipv4.protocol - # - bit[80..95] -> TW16 bit[15..0]: ingress::hdr.ipv4.hdr_checksum - 12..13: TH36 # ingress::hdr.ipv4.src_addr[31:16].16-31 - 12..15: W49 # ingress::ig_md.lkp.ip_src_addr[31:0].0-31 - 14..15: TH29 # ingress::hdr.ipv4.src_addr[15:0].0-15 - 16..17: TH38 # ingress::hdr.ipv4.dst_addr[31:16].16-31 - 16..19: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 - 18..19: TH37 # ingress::hdr.ipv4.dst_addr[15:0].0-15 - load: { byte1 : 9 } - shift: 9 - buf_req: 20 - next: parse_ipv4.$split_0 - parse_ipv4.$split_0: - match: [ byte1 ] - 0x06: - 0: B11 # ingress::ig_md.lkp.ip_proto - W41: 4 # value 1 -> W41 bit[2]: ingress::hdr.ipv4.$valid - shift: 11 - buf_req: 11 - next: parse_tcp - 0x11: - 0: B11 # ingress::ig_md.lkp.ip_proto - W41: 4 # value 1 -> W41 bit[2]: ingress::hdr.ipv4.$valid - load: { half : 13..14 } - shift: 11 - buf_req: 15 - next: parse_udp - 0x01: - 0: B11 # ingress::ig_md.lkp.ip_proto - W41: 4 # value 1 -> W41 bit[2]: ingress::hdr.ipv4.$valid - shift: 11 - buf_req: 11 - next: parse_icmp - 0x84: - 0: B11 # ingress::ig_md.lkp.ip_proto - W41: 4 # value 1 -> W41 bit[2]: ingress::hdr.ipv4.$valid - load: { half : 13..14 } - shift: 11 - buf_req: 15 - next: parse_sctp - 0x29: - 0: B11 # ingress::ig_md.lkp.ip_proto - W41: 4 # value 1 -> W41 bit[2]: ingress::hdr.ipv4.$valid - shift: 11 - buf_req: 11 - next: parse_inner_ipv6 - 0x04: - 0: B11 # ingress::ig_md.lkp.ip_proto - W41: 4 # value 1 -> W41 bit[2]: ingress::hdr.ipv4.$valid - load: { byte1 : 20 } - shift: 11 - buf_req: 21 - next: parse_inner_ipv4 - 0x2f: - 0: B11 # ingress::ig_md.lkp.ip_proto - W41: 4 # value 1 -> W41 bit[2]: ingress::hdr.ipv4.$valid - load: { half : 12..13, byte0 : 14 } - shift: 11 - buf_req: 15 - next: parse_gre - 0x**: - 0: B11 # ingress::ig_md.lkp.ip_proto - W41: 4 # value 1 -> W41 bit[2]: ingress::hdr.ipv4.$valid - shift: 11 - buf_req: 11 - next: end - parse_tcp: - *: - 0..1: H9 # ingress::ig_md.lkp.l4_src_port - 0..3: TW18 - # - bit[0..15] -> TW18 bit[31..16]: ingress::hdr.tcp.src_port - # - bit[16..31] -> TW18 bit[15..0]: ingress::hdr.tcp.dst_port - 2..3: H11 # ingress::ig_md.lkp.l4_dst_port - 4..7: TW25 # ingress::hdr.tcp.seq_no - 8..9: TH39 # ingress::hdr.tcp.ack_no[31:16].16-31 - 10: TB24 # ingress::hdr.tcp.ack_no[15:8].8-15 - 11: TB19 # ingress::hdr.tcp.ack_no[7:0].0-7 - 12..15: TW1 - # - bit[96..99] -> TW1 bit[31..28]: ingress::hdr.tcp.data_offset - # - bit[100..103] -> TW1 bit[27..24]: ingress::hdr.tcp.res - # - bit[104..111] -> TW1 bit[23..16]: ingress::hdr.tcp.flags - # - bit[112..127] -> TW1 bit[15..0]: ingress::hdr.tcp.window - 16..19: TW19 - # - bit[128..143] -> TW19 bit[31..16]: ingress::hdr.tcp.checksum - # - bit[144..159] -> TW19 bit[15..0]: ingress::hdr.tcp.urgent_ptr - load: { half : 2..3 } - shift: 20 - buf_req: 20 - next: parse_tcp.$split_0 - parse_tcp.$split_0: - match: [ half ] - 0x01bb: - W41: 8 # value 1 -> W41 bit[3]: ingress::hdr.tcp.$valid - buf_req: 0 - next: end - 0x084b: - W41: 8 # value 1 -> W41 bit[3]: ingress::hdr.tcp.$valid - load: { byte1 : 0 } - buf_req: 1 - next: parse_gtpv2 - 0x****: - W41: 8 # value 1 -> W41 bit[3]: ingress::hdr.tcp.$valid - buf_req: 0 - next: end - parse_gtpv2: - match: [ byte1 ] - 0b***0****: - load: { byte1 : 1 } - buf_req: 2 - next: parse_gtpv2_8b - 0b***1****: - load: { byte1 : 1 } - buf_req: 2 - next: parse_gtpv2_12b - 0x**: - buf_req: 0 - next: end - parse_gtpv2_8b: - match: [ byte1 ] - 0x20: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len - 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 - 7: TB17 # ingress::hdr.gtpv2_8b.spare2 - W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x26: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len - 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 - 7: TB17 # ingress::hdr.gtpv2_8b.spare2 - W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x27: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len - 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 - 7: TB17 # ingress::hdr.gtpv2_8b.spare2 - W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x47: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len - 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 - 7: TB17 # ingress::hdr.gtpv2_8b.spare2 - W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x67: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len - 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 - 7: TB17 # ingress::hdr.gtpv2_8b.spare2 - W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x85: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len - 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 - 7: TB17 # ingress::hdr.gtpv2_8b.spare2 - W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x88: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len - 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 - 7: TB17 # ingress::hdr.gtpv2_8b.spare2 - W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x97: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len - 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 - 7: TB17 # ingress::hdr.gtpv2_8b.spare2 - W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x9f: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len - 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 - 7: TB17 # ingress::hdr.gtpv2_8b.spare2 - W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0xa2: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len - 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 - 7: TB17 # ingress::hdr.gtpv2_8b.spare2 - W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0xa4: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len - 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 - 7: TB17 # ingress::hdr.gtpv2_8b.spare2 - W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0xa6: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len - 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 - 7: TB17 # ingress::hdr.gtpv2_8b.spare2 - W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x68: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len - 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 - 7: TB17 # ingress::hdr.gtpv2_8b.spare2 - W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x82: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len - 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 - 7: TB17 # ingress::hdr.gtpv2_8b.spare2 - W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0xff: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len - 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 - 7: TB17 # ingress::hdr.gtpv2_8b.spare2 - W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid - load: { byte1 : 8 } - shift: 8 - buf_req: 9 - next: parse_volte - 0x**: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_8b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_8b.total_len - 4..5: TH26 # ingress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6: TB18 # ingress::hdr.gtpv2_8b.seq_no[7:0].0-7 - 7: TB17 # ingress::hdr.gtpv2_8b.spare2 - W41: 16 # value 1 -> W41 bit[4]: ingress::hdr.gtpv2_8b.$valid - shift: 8 - buf_req: 8 - next: end - parse_gtp_base: - match: [ half, byte0 ] - 0x01****: - 0..3: TW2 - # - bit[0..7] -> TW2 bit[31..24]: ingress::hdr.imsi.type - # - bit[8..23] -> TW2 bit[23..8]: ingress::hdr.imsi.len - # - bit[24..27] -> TW2 bit[7..4]: ingress::hdr.imsi.spare - # - bit[28..31] -> TW2 bit[3..0]: ingress::hdr.imsi.instance - 4..5: TH28 # ingress::hdr.imsi.num_digit[127:112].112-127 - 6: TB25 # ingress::hdr.imsi.num_digit[111:104].104-111 - 7: TB16 # ingress::hdr.imsi.num_digit[103:96].96-103 - 8..9: TH27 # ingress::hdr.imsi.num_digit[95:80].80-95 - 10..11: TH24 # ingress::hdr.imsi.num_digit[79:64].64-79 - 12..15: TW24 # ingress::hdr.imsi.num_digit[63:32].32-63 - 16..19: TW17 # ingress::hdr.imsi.num_digit[31:0].0-31 - W41: 32 # value 1 -> W41 bit[5]: ingress::hdr.imsi.$valid - shift: 20 - buf_req: 20 - next: end - 0x020002: - 0: TB1 # ingress::hdr.cause_ie_6b.type - 1..4: TW3 - # - bit[8..23] -> TW3 bit[31..16]: ingress::hdr.cause_ie_6b.len - # - bit[24..27] -> TW3 bit[15..12]: ingress::hdr.cause_ie_6b.spare1 - # - bit[28..31] -> TW3 bit[11..8]: ingress::hdr.cause_ie_6b.instance - # - bit[32..39] -> TW3 bit[7..0]: ingress::hdr.cause_ie_6b.cause_value - 5: TB0 - # - bit[40..44] -> TB0 bit[7..3]: ingress::hdr.cause_ie_6b.spare2 - # - bit[45] -> TB0 bit[2]: ingress::hdr.cause_ie_6b.pce - # - bit[46] -> TB0 bit[1]: ingress::hdr.cause_ie_6b.bce - # - bit[47] -> TB0 bit[0]: ingress::hdr.cause_ie_6b.cs - W41: 64 # value 1 -> W41 bit[6]: ingress::hdr.cause_ie_6b.$valid - shift: 6 - buf_req: 6 - next: parse_imsi - 0x020006: - 0: TB1 # ingress::hdr.cause_ie_10b.type - 1..4: TW3 - # - bit[8..23] -> TW3 bit[31..16]: ingress::hdr.cause_ie_10b.len - # - bit[24..27] -> TW3 bit[15..12]: ingress::hdr.cause_ie_10b.spare1 - # - bit[28..31] -> TW3 bit[11..8]: ingress::hdr.cause_ie_10b.instance - # - bit[32..39] -> TW3 bit[7..0]: ingress::hdr.cause_ie_10b.cause_value - 5: TB0 - # - bit[40..44] -> TB0 bit[7..3]: ingress::hdr.cause_ie_10b.spare2 - # - bit[45] -> TB0 bit[2]: ingress::hdr.cause_ie_10b.pce - # - bit[46] -> TB0 bit[1]: ingress::hdr.cause_ie_10b.bce - # - bit[47] -> TB0 bit[0]: ingress::hdr.cause_ie_10b.cs - 6..7: TH3 - # - bit[48..55] -> TH3 bit[15..8]: ingress::hdr.cause_ie_10b.type_oe - # - bit[56..63] -> TH3 bit[7..0]: ingress::hdr.cause_ie_10b.len_oe[15:8].8-15 - 8..9: TH2 - # - bit[64..71] -> TH2 bit[15..8]: ingress::hdr.cause_ie_10b.len_oe[7:0].0-7 - # - bit[72..75] -> TH2 bit[7..4]: ingress::hdr.cause_ie_10b.spare_oe - # - bit[76..79] -> TH2 bit[3..0]: ingress::hdr.cause_ie_10b.instance_oe - W41: 128 # value 1 -> W41 bit[7]: ingress::hdr.cause_ie_10b.$valid - shift: 10 - buf_req: 10 - next: parse_imsi - 0x******: - buf_req: 0 - next: end - parse_imsi: - *: - 0..3: TW2 - # - bit[0..7] -> TW2 bit[31..24]: ingress::hdr.imsi.type - # - bit[8..23] -> TW2 bit[23..8]: ingress::hdr.imsi.len - # - bit[24..27] -> TW2 bit[7..4]: ingress::hdr.imsi.spare - # - bit[28..31] -> TW2 bit[3..0]: ingress::hdr.imsi.instance - 4..5: TH28 # ingress::hdr.imsi.num_digit[127:112].112-127 - 6: TB25 # ingress::hdr.imsi.num_digit[111:104].104-111 - 7: TB16 # ingress::hdr.imsi.num_digit[103:96].96-103 - 8..9: TH27 # ingress::hdr.imsi.num_digit[95:80].80-95 - 10..11: TH24 # ingress::hdr.imsi.num_digit[79:64].64-79 - 12..15: TW24 # ingress::hdr.imsi.num_digit[63:32].32-63 - 16..19: TW17 # ingress::hdr.imsi.num_digit[31:0].0-31 - W41: 32 # value 1 -> W41 bit[5]: ingress::hdr.imsi.$valid - shift: 20 - buf_req: 20 - next: end - parse_volte: - match: [ byte1 ] - 0x4*: - load: { byte1 : 9 } - buf_req: 10 - next: parse_inner_ipv4 - 0x6*: - 0..3: TW2 - # - bit[0..3] -> TW2 bit[31..28]: ingress::hdr.inner_ipv6.version - # - bit[4..11] -> TW2 bit[27..20]: ingress::hdr.inner_ipv6.traffic_class - # - bit[12..31] -> TW2 bit[19..0]: ingress::hdr.inner_ipv6.flow_label - 4..5: TH3 # ingress::hdr.inner_ipv6.payload_len - 6: B8 # ingress::hdr.inner_ipv6.next_hdr - 7: TB16 # ingress::hdr.inner_ipv6.hop_limit - 8..11: W14 # ingress::hdr.inner_ipv6.src_addr[127:96].96-127 - 12..15: W13 # ingress::hdr.inner_ipv6.src_addr[95:64].64-95 - 16..19: W12 # ingress::hdr.inner_ipv6.src_addr[63:32].32-63 - W41: 16384 # value 1 -> W41 bit[14]: ingress::hdr.inner_ipv6.$valid - load: { byte1 : 6 } - shift: 20 - buf_req: 20 - next: parse_inner_ipv6.$split_0 - 0x**: - buf_req: 0 - next: end - parse_inner_ipv4: - match: [ byte1 ] - 0x06: - 0..3: TW2 - # - bit[0..3] -> TW2 bit[31..28]: ingress::hdr.inner_ipv4.version - # - bit[4..7] -> TW2 bit[27..24]: ingress::hdr.inner_ipv4.ihl - # - bit[8..15] -> TW2 bit[23..16]: ingress::hdr.inner_ipv4.diffserv - # - bit[16..31] -> TW2 bit[15..0]: ingress::hdr.inner_ipv4.total_len - 4..5: TH24 # ingress::hdr.inner_ipv4.identification - 6..7: TH3 - # - bit[48..50] -> TH3 bit[15..13]: ingress::hdr.inner_ipv4.flags - # - bit[51..63] -> TH3 bit[12..0]: ingress::hdr.inner_ipv4.frag_offset - 8..11: TW17 - # - bit[64..71] -> TW17 bit[31..24]: ingress::hdr.inner_ipv4.ttl - # - bit[72..79] -> TW17 bit[23..16]: ingress::hdr.inner_ipv4.protocol - # - bit[80..95] -> TW17 bit[15..0]: ingress::hdr.inner_ipv4.hdr_checksum - 12..13: TH40 # ingress::hdr.inner_ipv4.src_addr[31:16].16-31 - 14: TB25 # ingress::hdr.inner_ipv4.src_addr[15:8].8-15 - 15: TB16 # ingress::hdr.inner_ipv4.src_addr[7:0].0-7 - 16..17: TH41 # ingress::hdr.inner_ipv4.dst_addr[31:16].16-31 - 18: TB27 # ingress::hdr.inner_ipv4.dst_addr[15:8].8-15 - 19: TB26 # ingress::hdr.inner_ipv4.dst_addr[7:0].0-7 - W41: 256 # value 1 -> W41 bit[8]: ingress::hdr.inner_ipv4.$valid - shift: 20 - buf_req: 20 - next: parse_inner_tcp - 0x11: - 0..3: TW2 - # - bit[0..3] -> TW2 bit[31..28]: ingress::hdr.inner_ipv4.version - # - bit[4..7] -> TW2 bit[27..24]: ingress::hdr.inner_ipv4.ihl - # - bit[8..15] -> TW2 bit[23..16]: ingress::hdr.inner_ipv4.diffserv - # - bit[16..31] -> TW2 bit[15..0]: ingress::hdr.inner_ipv4.total_len - 4..5: TH24 # ingress::hdr.inner_ipv4.identification - 6..7: TH3 - # - bit[48..50] -> TH3 bit[15..13]: ingress::hdr.inner_ipv4.flags - # - bit[51..63] -> TH3 bit[12..0]: ingress::hdr.inner_ipv4.frag_offset - 8..11: TW17 - # - bit[64..71] -> TW17 bit[31..24]: ingress::hdr.inner_ipv4.ttl - # - bit[72..79] -> TW17 bit[23..16]: ingress::hdr.inner_ipv4.protocol - # - bit[80..95] -> TW17 bit[15..0]: ingress::hdr.inner_ipv4.hdr_checksum - 12..13: TH40 # ingress::hdr.inner_ipv4.src_addr[31:16].16-31 - 14: TB25 # ingress::hdr.inner_ipv4.src_addr[15:8].8-15 - 15: TB16 # ingress::hdr.inner_ipv4.src_addr[7:0].0-7 - 16..17: TH41 # ingress::hdr.inner_ipv4.dst_addr[31:16].16-31 - 18: TB27 # ingress::hdr.inner_ipv4.dst_addr[15:8].8-15 - 19: TB26 # ingress::hdr.inner_ipv4.dst_addr[7:0].0-7 - W41: 256 # value 1 -> W41 bit[8]: ingress::hdr.inner_ipv4.$valid - shift: 20 - buf_req: 20 - next: parse_inner_udp - 0x01: - 0..3: TW2 - # - bit[0..3] -> TW2 bit[31..28]: ingress::hdr.inner_ipv4.version - # - bit[4..7] -> TW2 bit[27..24]: ingress::hdr.inner_ipv4.ihl - # - bit[8..15] -> TW2 bit[23..16]: ingress::hdr.inner_ipv4.diffserv - # - bit[16..31] -> TW2 bit[15..0]: ingress::hdr.inner_ipv4.total_len - 4..5: TH24 # ingress::hdr.inner_ipv4.identification - 6..7: TH3 - # - bit[48..50] -> TH3 bit[15..13]: ingress::hdr.inner_ipv4.flags - # - bit[51..63] -> TH3 bit[12..0]: ingress::hdr.inner_ipv4.frag_offset - 8..11: TW17 - # - bit[64..71] -> TW17 bit[31..24]: ingress::hdr.inner_ipv4.ttl - # - bit[72..79] -> TW17 bit[23..16]: ingress::hdr.inner_ipv4.protocol - # - bit[80..95] -> TW17 bit[15..0]: ingress::hdr.inner_ipv4.hdr_checksum - 12..13: TH40 # ingress::hdr.inner_ipv4.src_addr[31:16].16-31 - 14: TB25 # ingress::hdr.inner_ipv4.src_addr[15:8].8-15 - 15: TB16 # ingress::hdr.inner_ipv4.src_addr[7:0].0-7 - 16..17: TH41 # ingress::hdr.inner_ipv4.dst_addr[31:16].16-31 - 18: TB27 # ingress::hdr.inner_ipv4.dst_addr[15:8].8-15 - 19: TB26 # ingress::hdr.inner_ipv4.dst_addr[7:0].0-7 - W41: 256 # value 1 -> W41 bit[8]: ingress::hdr.inner_ipv4.$valid - shift: 20 - buf_req: 20 - next: parse_inner_icmp - 0x32: - 0..3: TW2 - # - bit[0..3] -> TW2 bit[31..28]: ingress::hdr.inner_ipv4.version - # - bit[4..7] -> TW2 bit[27..24]: ingress::hdr.inner_ipv4.ihl - # - bit[8..15] -> TW2 bit[23..16]: ingress::hdr.inner_ipv4.diffserv - # - bit[16..31] -> TW2 bit[15..0]: ingress::hdr.inner_ipv4.total_len - 4..5: TH24 # ingress::hdr.inner_ipv4.identification - 6..7: TH3 - # - bit[48..50] -> TH3 bit[15..13]: ingress::hdr.inner_ipv4.flags - # - bit[51..63] -> TH3 bit[12..0]: ingress::hdr.inner_ipv4.frag_offset - 8..11: TW17 - # - bit[64..71] -> TW17 bit[31..24]: ingress::hdr.inner_ipv4.ttl - # - bit[72..79] -> TW17 bit[23..16]: ingress::hdr.inner_ipv4.protocol - # - bit[80..95] -> TW17 bit[15..0]: ingress::hdr.inner_ipv4.hdr_checksum - 12..13: TH40 # ingress::hdr.inner_ipv4.src_addr[31:16].16-31 - 14: TB25 # ingress::hdr.inner_ipv4.src_addr[15:8].8-15 - 15: TB16 # ingress::hdr.inner_ipv4.src_addr[7:0].0-7 - 16..17: TH41 # ingress::hdr.inner_ipv4.dst_addr[31:16].16-31 - 18: TB27 # ingress::hdr.inner_ipv4.dst_addr[15:8].8-15 - 19: TB26 # ingress::hdr.inner_ipv4.dst_addr[7:0].0-7 - W41: 256 # value 1 -> W41 bit[8]: ingress::hdr.inner_ipv4.$valid - shift: 20 - buf_req: 20 - next: parse_inner_esp - 0x**: - 0..3: TW2 - # - bit[0..3] -> TW2 bit[31..28]: ingress::hdr.inner_ipv4.version - # - bit[4..7] -> TW2 bit[27..24]: ingress::hdr.inner_ipv4.ihl - # - bit[8..15] -> TW2 bit[23..16]: ingress::hdr.inner_ipv4.diffserv - # - bit[16..31] -> TW2 bit[15..0]: ingress::hdr.inner_ipv4.total_len - 4..5: TH24 # ingress::hdr.inner_ipv4.identification - 6..7: TH3 - # - bit[48..50] -> TH3 bit[15..13]: ingress::hdr.inner_ipv4.flags - # - bit[51..63] -> TH3 bit[12..0]: ingress::hdr.inner_ipv4.frag_offset - 8..11: TW17 - # - bit[64..71] -> TW17 bit[31..24]: ingress::hdr.inner_ipv4.ttl - # - bit[72..79] -> TW17 bit[23..16]: ingress::hdr.inner_ipv4.protocol - # - bit[80..95] -> TW17 bit[15..0]: ingress::hdr.inner_ipv4.hdr_checksum - 12..13: TH40 # ingress::hdr.inner_ipv4.src_addr[31:16].16-31 - 14: TB25 # ingress::hdr.inner_ipv4.src_addr[15:8].8-15 - 15: TB16 # ingress::hdr.inner_ipv4.src_addr[7:0].0-7 - 16..17: TH41 # ingress::hdr.inner_ipv4.dst_addr[31:16].16-31 - 18: TB27 # ingress::hdr.inner_ipv4.dst_addr[15:8].8-15 - 19: TB26 # ingress::hdr.inner_ipv4.dst_addr[7:0].0-7 - W41: 256 # value 1 -> W41 bit[8]: ingress::hdr.inner_ipv4.$valid - shift: 20 - buf_req: 20 - next: end - parse_inner_tcp: - *: - 0..1: TH28 # ingress::hdr.inner_tcp.src_port - 0..1: H10 # ingress::ig_md.lkp.inner_l4_src_port - 2..3: TH27 # ingress::hdr.inner_tcp.dst_port - 2..3: H12 # ingress::ig_md.lkp.inner_l4_dst_port - 4..7: W6 # ingress::hdr.inner_tcp.seq_no - 8..11: W7 # ingress::hdr.inner_tcp.ack_no - 12..15: TW3 - # - bit[96..99] -> TW3 bit[31..28]: ingress::hdr.inner_tcp.data_offset - # - bit[100..103] -> TW3 bit[27..24]: ingress::hdr.inner_tcp.res - # - bit[104..111] -> TW3 bit[23..16]: ingress::hdr.inner_tcp.flags - # - bit[112..127] -> TW3 bit[15..0]: ingress::hdr.inner_tcp.window - 16..19: TW24 - # - bit[128..143] -> TW24 bit[31..16]: ingress::hdr.inner_tcp.checksum - # - bit[144..159] -> TW24 bit[15..0]: ingress::hdr.inner_tcp.urgent_ptr - W41: 1536 - # - value 1 -> W41 bit[9]: ingress::hdr.inner_tcp.$valid - # - value 1 -> W41 bit[10]: ingress::hdr.sip.$valid - shift: 20 - buf_req: 20 - next: parse_inner_tcp.$split_0 - parse_inner_tcp.$split_0: - *: - 0..3: W8 # ingress::hdr.sip.data - shift: 4 - buf_req: 4 - next: end - parse_inner_udp: - *: - 0..1: H10 # ingress::ig_md.lkp.inner_l4_src_port - 0..3: TW3 - # - bit[0..15] -> TW3 bit[31..16]: ingress::hdr.inner_udp.src_port - # - bit[16..31] -> TW3 bit[15..0]: ingress::hdr.inner_udp.dst_port - 2..3: H12 # ingress::ig_md.lkp.inner_l4_dst_port - 4..7: TW24 - # - bit[32..47] -> TW24 bit[31..16]: ingress::hdr.inner_udp.hdr_length - # - bit[48..63] -> TW24 bit[15..0]: ingress::hdr.inner_udp.checksum - W41: 2048 # value 1 -> W41 bit[11]: ingress::hdr.inner_udp.$valid - shift: 8 - buf_req: 8 - next: end - parse_inner_icmp: - *: - 0..3: TW3 - # - bit[0..7] -> TW3 bit[31..24]: ingress::hdr.inner_icmp.type_ - # - bit[8..15] -> TW3 bit[23..16]: ingress::hdr.inner_icmp.code - # - bit[16..31] -> TW3 bit[15..0]: ingress::hdr.inner_icmp.hdr_checksum - W41: 4096 # value 1 -> W41 bit[12]: ingress::hdr.inner_icmp.$valid - shift: 4 - buf_req: 4 - next: end - parse_inner_esp: - *: - 0..3: W9 # ingress::hdr.ipsec_esp.spi - 4..7: W10 # ingress::hdr.ipsec_esp.sn - W41: 8192 # value 1 -> W41 bit[13]: ingress::hdr.ipsec_esp.$valid - shift: 8 - buf_req: 8 - next: parse_inner_tcp - parse_inner_ipv6.$split_0: - *: - 0..3: W11 # ingress::hdr.inner_ipv6.src_addr[31:0].0-31 - 4..7: W34 # ingress::hdr.inner_ipv6.dst_addr[127:96].96-127 - 8..11: W33 # ingress::hdr.inner_ipv6.dst_addr[95:64].64-95 - 12..15: W32 # ingress::hdr.inner_ipv6.dst_addr[63:32].32-63 - shift: 16 - buf_req: 16 - next: parse_inner_ipv6.$split_1 - parse_inner_ipv6.$split_1: - match: [ byte1 ] - 0x06: - 0..3: W15 # ingress::hdr.inner_ipv6.dst_addr[31:0].0-31 - shift: 4 - buf_req: 4 - next: parse_inner_tcp - 0x11: - 0..3: W15 # ingress::hdr.inner_ipv6.dst_addr[31:0].0-31 - shift: 4 - buf_req: 4 - next: parse_inner_udp - 0x3a: - 0..3: W15 # ingress::hdr.inner_ipv6.dst_addr[31:0].0-31 - shift: 4 - buf_req: 4 - next: parse_inner_icmp - 0x32: - 0..3: W15 # ingress::hdr.inner_ipv6.dst_addr[31:0].0-31 - shift: 4 - buf_req: 4 - next: parse_inner_esp - 0x**: - 0..3: W15 # ingress::hdr.inner_ipv6.dst_addr[31:0].0-31 - shift: 4 - buf_req: 4 - next: end - parse_gtpv2_12b: - match: [ byte1 ] - 0x20: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len - 4..7: W35 # ingress::hdr.gtpv2_12b.teid - 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 - 11: TB17 # ingress::hdr.gtpv2_12b.spare2 - W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x26: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len - 4..7: W35 # ingress::hdr.gtpv2_12b.teid - 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 - 11: TB17 # ingress::hdr.gtpv2_12b.spare2 - W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x27: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len - 4..7: W35 # ingress::hdr.gtpv2_12b.teid - 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 - 11: TB17 # ingress::hdr.gtpv2_12b.spare2 - W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x47: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len - 4..7: W35 # ingress::hdr.gtpv2_12b.teid - 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 - 11: TB17 # ingress::hdr.gtpv2_12b.spare2 - W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x67: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len - 4..7: W35 # ingress::hdr.gtpv2_12b.teid - 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 - 11: TB17 # ingress::hdr.gtpv2_12b.spare2 - W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x85: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len - 4..7: W35 # ingress::hdr.gtpv2_12b.teid - 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 - 11: TB17 # ingress::hdr.gtpv2_12b.spare2 - W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x88: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len - 4..7: W35 # ingress::hdr.gtpv2_12b.teid - 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 - 11: TB17 # ingress::hdr.gtpv2_12b.spare2 - W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x97: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len - 4..7: W35 # ingress::hdr.gtpv2_12b.teid - 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 - 11: TB17 # ingress::hdr.gtpv2_12b.spare2 - W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x9f: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len - 4..7: W35 # ingress::hdr.gtpv2_12b.teid - 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 - 11: TB17 # ingress::hdr.gtpv2_12b.spare2 - W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0xa2: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len - 4..7: W35 # ingress::hdr.gtpv2_12b.teid - 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 - 11: TB17 # ingress::hdr.gtpv2_12b.spare2 - W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0xa4: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len - 4..7: W35 # ingress::hdr.gtpv2_12b.teid - 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 - 11: TB17 # ingress::hdr.gtpv2_12b.spare2 - W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0xa6: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len - 4..7: W35 # ingress::hdr.gtpv2_12b.teid - 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 - 11: TB17 # ingress::hdr.gtpv2_12b.spare2 - W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x68: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len - 4..7: W35 # ingress::hdr.gtpv2_12b.teid - 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 - 11: TB17 # ingress::hdr.gtpv2_12b.spare2 - W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x82: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len - 4..7: W35 # ingress::hdr.gtpv2_12b.teid - 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 - 11: TB17 # ingress::hdr.gtpv2_12b.spare2 - W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0xff: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len - 4..7: W35 # ingress::hdr.gtpv2_12b.teid - 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 - 11: TB17 # ingress::hdr.gtpv2_12b.spare2 - W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid - load: { byte1 : 12 } - shift: 12 - buf_req: 13 - next: parse_volte - 0x**: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv2_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv2_12b.pb - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv2_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv2_12b.total_len - 4..7: W35 # ingress::hdr.gtpv2_12b.teid - 8..9: TH26 # ingress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10: TB18 # ingress::hdr.gtpv2_12b.seq_no[7:0].0-7 - 11: TB17 # ingress::hdr.gtpv2_12b.spare2 - W41: 32768 # value 1 -> W41 bit[15]: ingress::hdr.gtpv2_12b.$valid - shift: 12 - buf_req: 12 - next: end - parse_udp: - match: [ half ] - value_set IgParser_inner_2.udp_port_vxlan 1: - handle: 507 - field_mapping: - hdr.udp.dst_port(0..15) : half(0..15) - 0..1: H9 # ingress::ig_md.lkp.l4_src_port - 0..3: TW18 - # - bit[0..15] -> TW18 bit[31..16]: ingress::hdr.udp.src_port - # - bit[16..31] -> TW18 bit[15..0]: ingress::hdr.udp.dst_port - 2..3: H11 # ingress::ig_md.lkp.l4_dst_port - 4..7: TW19 - # - bit[32..47] -> TW19 bit[31..16]: ingress::hdr.udp.hdr_length - # - bit[48..63] -> TW19 bit[15..0]: ingress::hdr.udp.checksum - W41: 65536 # value 1 -> W41 bit[16]: ingress::hdr.udp.$valid - shift: 8 - buf_req: 8 - next: parse_vxlan - 0x0868: - 0..1: H9 # ingress::ig_md.lkp.l4_src_port - 0..3: TW18 - # - bit[0..15] -> TW18 bit[31..16]: ingress::hdr.udp.src_port - # - bit[16..31] -> TW18 bit[15..0]: ingress::hdr.udp.dst_port - 2..3: H11 # ingress::ig_md.lkp.l4_dst_port - 4..7: TW19 - # - bit[32..47] -> TW19 bit[31..16]: ingress::hdr.udp.hdr_length - # - bit[48..63] -> TW19 bit[15..0]: ingress::hdr.udp.checksum - W41: 65536 # value 1 -> W41 bit[16]: ingress::hdr.udp.$valid - shift: 8 - buf_req: 8 - next: parse_gtpu - 0x0d3a: - 0..1: H9 # ingress::ig_md.lkp.l4_src_port - 0..3: TW18 - # - bit[0..15] -> TW18 bit[31..16]: ingress::hdr.udp.src_port - # - bit[16..31] -> TW18 bit[15..0]: ingress::hdr.udp.dst_port - 2..3: H11 # ingress::ig_md.lkp.l4_dst_port - 4..7: TW19 - # - bit[32..47] -> TW19 bit[31..16]: ingress::hdr.udp.hdr_length - # - bit[48..63] -> TW19 bit[15..0]: ingress::hdr.udp.checksum - W41: 65536 # value 1 -> W41 bit[16]: ingress::hdr.udp.$valid - shift: 8 - buf_req: 8 - next: parse_gtp - 0x084b: - 0..1: H9 # ingress::ig_md.lkp.l4_src_port - 0..3: TW18 - # - bit[0..15] -> TW18 bit[31..16]: ingress::hdr.udp.src_port - # - bit[16..31] -> TW18 bit[15..0]: ingress::hdr.udp.dst_port - 2..3: H11 # ingress::ig_md.lkp.l4_dst_port - 4..7: TW19 - # - bit[32..47] -> TW19 bit[31..16]: ingress::hdr.udp.hdr_length - # - bit[48..63] -> TW19 bit[15..0]: ingress::hdr.udp.checksum - W41: 65536 # value 1 -> W41 bit[16]: ingress::hdr.udp.$valid - load: { byte1 : 8 } - shift: 8 - buf_req: 9 - next: parse_gtp_verx - 0x06a5: - 0..1: H9 # ingress::ig_md.lkp.l4_src_port - 0..3: TW18 - # - bit[0..15] -> TW18 bit[31..16]: ingress::hdr.udp.src_port - # - bit[16..31] -> TW18 bit[15..0]: ingress::hdr.udp.dst_port - 2..3: H11 # ingress::ig_md.lkp.l4_dst_port - 4..7: TW19 - # - bit[32..47] -> TW19 bit[31..16]: ingress::hdr.udp.hdr_length - # - bit[48..63] -> TW19 bit[15..0]: ingress::hdr.udp.checksum - W41: 65536 # value 1 -> W41 bit[16]: ingress::hdr.udp.$valid - shift: 8 - buf_req: 8 - next: parse_l2tp - 0x****: - 0..1: H9 # ingress::ig_md.lkp.l4_src_port - 0..3: TW18 - # - bit[0..15] -> TW18 bit[31..16]: ingress::hdr.udp.src_port - # - bit[16..31] -> TW18 bit[15..0]: ingress::hdr.udp.dst_port - 2..3: H11 # ingress::ig_md.lkp.l4_dst_port - 4..7: TW19 - # - bit[32..47] -> TW19 bit[31..16]: ingress::hdr.udp.hdr_length - # - bit[48..63] -> TW19 bit[15..0]: ingress::hdr.udp.checksum - W41: 65536 # value 1 -> W41 bit[16]: ingress::hdr.udp.$valid - shift: 8 - buf_req: 8 - next: end - parse_vxlan: - *: - 0..3: TW1 - # - bit[0..7] -> TW1 bit[31..24]: ingress::hdr.vxlan.flags - # - bit[8..31] -> TW1 bit[23..0]: ingress::hdr.vxlan.reserved - 4..5: TH1 # ingress::hdr.vxlan.vni[23:8].8-23 - 6..7: TH0 - # - bit[48..55] -> TH0 bit[15..8]: ingress::hdr.vxlan.vni[7:0].0-7 - # - bit[56..63] -> TH0 bit[7..0]: ingress::hdr.vxlan.reserved2 - 8..11: TW25 # ingress::hdr.inner_ethernet.dst_addr[47:16].16-47 - 12: TB18 # ingress::hdr.inner_ethernet.dst_addr[15:8].8-15 - 13: TB17 # ingress::hdr.inner_ethernet.dst_addr[7:0].0-7 - 14..15: TH39 # ingress::hdr.inner_ethernet.src_addr[47:32].32-47 - 16: TB1 # ingress::hdr.inner_ethernet.src_addr[31:24].24-31 - 17: TB0 # ingress::hdr.inner_ethernet.src_addr[23:16].16-23 - 18..19: TH26 # ingress::hdr.inner_ethernet.src_addr[15:0].0-15 - W41: 393216 - # - value 1 -> W41 bit[17]: ingress::hdr.vxlan.$valid - # - value 1 -> W41 bit[18]: ingress::hdr.inner_ethernet.$valid - load: { half : 20..21 } - shift: 20 - buf_req: 22 - next: parse_vxlan.$split_0 - parse_vxlan.$split_0: - match: [ half ] - 0x0800: - 0..1: TH2 # ingress::hdr.inner_ethernet.ether_type - load: { byte1 : 11 } - shift: 2 - buf_req: 12 - next: parse_inner_ipv4 - 0x86dd: - 0..1: TH2 # ingress::hdr.inner_ethernet.ether_type - shift: 2 - buf_req: 2 - next: parse_inner_ipv6 - 0x****: - 0..1: TH2 # ingress::hdr.inner_ethernet.ether_type - shift: 2 - buf_req: 2 - next: end - parse_inner_ipv6: - *: - 0..3: TW2 - # - bit[0..3] -> TW2 bit[31..28]: ingress::hdr.inner_ipv6.version - # - bit[4..11] -> TW2 bit[27..20]: ingress::hdr.inner_ipv6.traffic_class - # - bit[12..31] -> TW2 bit[19..0]: ingress::hdr.inner_ipv6.flow_label - 4..5: TH3 # ingress::hdr.inner_ipv6.payload_len - 6: B8 # ingress::hdr.inner_ipv6.next_hdr - 7: TB16 # ingress::hdr.inner_ipv6.hop_limit - 8..11: W14 # ingress::hdr.inner_ipv6.src_addr[127:96].96-127 - 12..15: W13 # ingress::hdr.inner_ipv6.src_addr[95:64].64-95 - 16..19: W12 # ingress::hdr.inner_ipv6.src_addr[63:32].32-63 - W41: 16384 # value 1 -> W41 bit[14]: ingress::hdr.inner_ipv6.$valid - load: { byte1 : 6 } - shift: 20 - buf_req: 20 - next: parse_inner_ipv6.$split_0 - parse_gtpu: - *: - load: { byte1 : 0 } - buf_req: 1 - next: parse_gtpv1 - parse_gtpv1: - match: [ byte1 ] - 0b*****000: - load: { byte1 : 1 } - buf_req: 2 - next: parse_gtpv1_8b - 0b*****0*1: - load: { byte1 : 1 } - buf_req: 2 - next: parse_gtpv1_12b - 0b*****01*: - load: { byte1 : 1 } - buf_req: 2 - next: parse_gtpv1_12b - 0x**: - buf_req: 0 - next: end - parse_gtpv1_8b: - match: [ byte1 ] - 0x20: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len - 4..7: TW1 # ingress::hdr.gtpv1_8b.teid - W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x26: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len - 4..7: TW1 # ingress::hdr.gtpv1_8b.teid - W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x27: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len - 4..7: TW1 # ingress::hdr.gtpv1_8b.teid - W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x47: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len - 4..7: TW1 # ingress::hdr.gtpv1_8b.teid - W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x67: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len - 4..7: TW1 # ingress::hdr.gtpv1_8b.teid - W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x85: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len - 4..7: TW1 # ingress::hdr.gtpv1_8b.teid - W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x88: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len - 4..7: TW1 # ingress::hdr.gtpv1_8b.teid - W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x97: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len - 4..7: TW1 # ingress::hdr.gtpv1_8b.teid - W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x9f: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len - 4..7: TW1 # ingress::hdr.gtpv1_8b.teid - W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0xa2: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len - 4..7: TW1 # ingress::hdr.gtpv1_8b.teid - W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0xa4: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len - 4..7: TW1 # ingress::hdr.gtpv1_8b.teid - W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0xa6: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len - 4..7: TW1 # ingress::hdr.gtpv1_8b.teid - W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x68: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len - 4..7: TW1 # ingress::hdr.gtpv1_8b.teid - W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x82: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len - 4..7: TW1 # ingress::hdr.gtpv1_8b.teid - W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0xff: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len - 4..7: TW1 # ingress::hdr.gtpv1_8b.teid - W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid - load: { byte1 : 8 } - shift: 8 - buf_req: 9 - next: parse_volte - 0x**: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_8b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_8b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_8b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_8b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_8b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_8b.message_len - 4..7: TW1 # ingress::hdr.gtpv1_8b.teid - W41: 524288 # value 1 -> W41 bit[19]: ingress::hdr.gtpv1_8b.$valid - shift: 8 - buf_req: 8 - next: end - parse_gtpv1_12b: - match: [ byte1 ] - 0x20: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len - 4..7: TW25 # ingress::hdr.gtpv1_12b.teid - 8..11: TW1 - # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t - W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x26: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len - 4..7: TW25 # ingress::hdr.gtpv1_12b.teid - 8..11: TW1 - # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t - W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x27: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len - 4..7: TW25 # ingress::hdr.gtpv1_12b.teid - 8..11: TW1 - # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t - W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x47: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len - 4..7: TW25 # ingress::hdr.gtpv1_12b.teid - 8..11: TW1 - # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t - W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x67: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len - 4..7: TW25 # ingress::hdr.gtpv1_12b.teid - 8..11: TW1 - # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t - W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x85: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len - 4..7: TW25 # ingress::hdr.gtpv1_12b.teid - 8..11: TW1 - # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t - W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x88: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len - 4..7: TW25 # ingress::hdr.gtpv1_12b.teid - 8..11: TW1 - # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t - W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x97: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len - 4..7: TW25 # ingress::hdr.gtpv1_12b.teid - 8..11: TW1 - # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t - W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x9f: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len - 4..7: TW25 # ingress::hdr.gtpv1_12b.teid - 8..11: TW1 - # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t - W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0xa2: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len - 4..7: TW25 # ingress::hdr.gtpv1_12b.teid - 8..11: TW1 - # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t - W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0xa4: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len - 4..7: TW25 # ingress::hdr.gtpv1_12b.teid - 8..11: TW1 - # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t - W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0xa6: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len - 4..7: TW25 # ingress::hdr.gtpv1_12b.teid - 8..11: TW1 - # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t - W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x68: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len - 4..7: TW25 # ingress::hdr.gtpv1_12b.teid - 8..11: TW1 - # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t - W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x82: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len - 4..7: TW25 # ingress::hdr.gtpv1_12b.teid - 8..11: TW1 - # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t - W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0xff: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len - 4..7: TW25 # ingress::hdr.gtpv1_12b.teid - 8..11: TW1 - # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t - W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid - load: { byte1 : 12 } - shift: 12 - buf_req: 13 - next: parse_volte - 0x**: - 0..1: TH0 - # - bit[0..2] -> TH0 bit[15..13]: ingress::hdr.gtpv1_12b.version - # - bit[3] -> TH0 bit[12]: ingress::hdr.gtpv1_12b.pt - # - bit[4] -> TH0 bit[11]: ingress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH0 bit[10]: ingress::hdr.gtpv1_12b.e - # - bit[6] -> TH0 bit[9]: ingress::hdr.gtpv1_12b.s - # - bit[7] -> TH0 bit[8]: ingress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH0 bit[7..0]: ingress::hdr.gtpv1_12b.message_type - 2..3: TH1 # ingress::hdr.gtpv1_12b.message_len - 4..7: TW25 # ingress::hdr.gtpv1_12b.teid - 8..11: TW1 - # - bit[64..79] -> TW1 bit[31..16]: ingress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW1 bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW1 bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t - W41: 1048576 # value 1 -> W41 bit[20]: ingress::hdr.gtpv1_12b.$valid - shift: 12 - buf_req: 12 - next: end - parse_gtp: - *: - load: { byte1 : 0 } - buf_req: 1 - next: parse_gtpv1 - parse_gtp_verx: - match: [ byte1 ] - 0b001*****: - load: { byte1 : 0 } - buf_req: 1 - next: parse_gtpv1 - 0b010*****: - load: { byte1 : 0 } - buf_req: 1 - next: parse_gtpv2 - 0x**: - buf_req: 0 - next: end - parse_l2tp: - *: - 0..3: TW1 - # - bit[0..11] -> TW1 bit[31..20]: ingress::hdr.l2tp.TLxxSxOP - # - bit[12..15] -> TW1 bit[19..16]: ingress::hdr.l2tp.version - # - bit[16..23] -> TW1 bit[15..8]: ingress::hdr.l2tp.l2tp_length - # - bit[24..31] -> TW1 bit[7..0]: ingress::hdr.l2tp.tunnel_id[15:8].8-15 - 4: TB0 # ingress::hdr.l2tp.tunnel_id[7:0].0-7 - 5..6: TH26 # ingress::hdr.l2tp.session_id - 7: TB19 # ingress::hdr.l2tp.Ns[15:8].8-15 - 8: TB18 # ingress::hdr.l2tp.Ns[7:0].0-7 - 9..10: TH0 # ingress::hdr.l2tp.Nr - 11: TB17 # ingress::hdr.l2tp.offset_size - W41: 2097152 # value 1 -> W41 bit[21]: ingress::hdr.l2tp.$valid - load: { byte1 : 0 } - shift: 12 - buf_req: 12 - next: parse_l2tp.$split_0 - parse_l2tp.$split_0: - match: [ byte1 ] - 0b0*******: - 0: TB1 # ingress::hdr.l2tp.offset_pad - load: { half : 7..8, byte0 : 9 } - shift: 1 - buf_req: 10 - next: parse_pppoe - 0x**: - 0: TB1 # ingress::hdr.l2tp.offset_pad - shift: 1 - buf_req: 1 - next: end - parse_pppoe: - match: [ half, byte0 ] - 0x00214*: - 0..1: TH1 - # - bit[0..3] -> TH1 bit[15..12]: ingress::hdr.pppoe.version - # - bit[4..7] -> TH1 bit[11..8]: ingress::hdr.pppoe.type - # - bit[8..15] -> TH1 bit[7..0]: ingress::hdr.pppoe.code - 2..3: TH2 # ingress::hdr.pppoe.session_id - 4..7: TW25 - # - bit[32..47] -> TW25 bit[31..16]: ingress::hdr.pppoe.pppoe_length - # - bit[48..63] -> TW25 bit[15..0]: ingress::hdr.pppoe.ppp_proto - W41: 4194304 # value 1 -> W41 bit[22]: ingress::hdr.pppoe.$valid - load: { byte1 : 17 } - shift: 8 - buf_req: 18 - next: parse_inner_ipv4 - 0x00216*: - 0..1: TH1 - # - bit[0..3] -> TH1 bit[15..12]: ingress::hdr.pppoe.version - # - bit[4..7] -> TH1 bit[11..8]: ingress::hdr.pppoe.type - # - bit[8..15] -> TH1 bit[7..0]: ingress::hdr.pppoe.code - 2..3: TH2 # ingress::hdr.pppoe.session_id - 4..7: TW25 - # - bit[32..47] -> TW25 bit[31..16]: ingress::hdr.pppoe.pppoe_length - # - bit[48..63] -> TW25 bit[15..0]: ingress::hdr.pppoe.ppp_proto - W41: 4194304 # value 1 -> W41 bit[22]: ingress::hdr.pppoe.$valid - shift: 8 - buf_req: 8 - next: parse_inner_ipv6 - 0x******: - 0..1: TH1 - # - bit[0..3] -> TH1 bit[15..12]: ingress::hdr.pppoe.version - # - bit[4..7] -> TH1 bit[11..8]: ingress::hdr.pppoe.type - # - bit[8..15] -> TH1 bit[7..0]: ingress::hdr.pppoe.code - 2..3: TH2 # ingress::hdr.pppoe.session_id - 4..7: TW25 - # - bit[32..47] -> TW25 bit[31..16]: ingress::hdr.pppoe.pppoe_length - # - bit[48..63] -> TW25 bit[15..0]: ingress::hdr.pppoe.ppp_proto - W41: 4194304 # value 1 -> W41 bit[22]: ingress::hdr.pppoe.$valid - shift: 8 - buf_req: 8 - next: end - parse_icmp: - *: - 0..3: TW1 - # - bit[0..7] -> TW1 bit[31..24]: ingress::hdr.icmp.type_ - # - bit[8..15] -> TW1 bit[23..16]: ingress::hdr.icmp.code - # - bit[16..31] -> TW1 bit[15..0]: ingress::hdr.icmp.hdr_checksum - W41: 8388608 # value 1 -> W41 bit[23]: ingress::hdr.icmp.$valid - shift: 4 - buf_req: 4 - next: end - parse_sctp: - match: [ half ] - 0x8e3c: - 0..3: TW1 - # - bit[0..15] -> TW1 bit[31..16]: ingress::hdr.sctp.src_port - # - bit[16..31] -> TW1 bit[15..0]: ingress::hdr.sctp.dst_port - 4..7: TW2 # ingress::hdr.sctp.verifTag - 8..9: TH0 # ingress::hdr.sctp.checksum - W41: 16777216 # value 1 -> W41 bit[24]: ingress::hdr.sctp.$valid - shift: 10 - buf_req: 10 - next: end - 0x960c: - 0..3: TW1 - # - bit[0..15] -> TW1 bit[31..16]: ingress::hdr.sctp.src_port - # - bit[16..31] -> TW1 bit[15..0]: ingress::hdr.sctp.dst_port - 4..7: TW2 # ingress::hdr.sctp.verifTag - 8..9: TH0 # ingress::hdr.sctp.checksum - W41: 16777216 # value 1 -> W41 bit[24]: ingress::hdr.sctp.$valid - shift: 10 - buf_req: 10 - next: end - 0x0f1c: - 0..3: TW1 - # - bit[0..15] -> TW1 bit[31..16]: ingress::hdr.sctp.src_port - # - bit[16..31] -> TW1 bit[15..0]: ingress::hdr.sctp.dst_port - 4..7: TW2 # ingress::hdr.sctp.verifTag - 8..9: TH0 # ingress::hdr.sctp.checksum - W41: 16777216 # value 1 -> W41 bit[24]: ingress::hdr.sctp.$valid - shift: 10 - buf_req: 10 - next: end - 0x71be: - 0..3: TW1 - # - bit[0..15] -> TW1 bit[31..16]: ingress::hdr.sctp.src_port - # - bit[16..31] -> TW1 bit[15..0]: ingress::hdr.sctp.dst_port - 4..7: TW2 # ingress::hdr.sctp.verifTag - 8..9: TH0 # ingress::hdr.sctp.checksum - W41: 16777216 # value 1 -> W41 bit[24]: ingress::hdr.sctp.$valid - shift: 10 - buf_req: 10 - next: end - 0x****: - 0..3: TW1 - # - bit[0..15] -> TW1 bit[31..16]: ingress::hdr.sctp.src_port - # - bit[16..31] -> TW1 bit[15..0]: ingress::hdr.sctp.dst_port - 4..7: TW2 # ingress::hdr.sctp.verifTag - 8..9: TH0 # ingress::hdr.sctp.checksum - W41: 16777216 # value 1 -> W41 bit[24]: ingress::hdr.sctp.$valid - shift: 10 - buf_req: 10 - next: end - parse_gre: - match: [ half, byte0 ] - 0b*****0011000100000001011: - 0..1: TH0 - # - bit[0] -> TH0 bit[15]: ingress::hdr.gre.C - # - bit[1] -> TH0 bit[14]: ingress::hdr.gre.R - # - bit[2] -> TH0 bit[13]: ingress::hdr.gre.K - # - bit[3] -> TH0 bit[12]: ingress::hdr.gre.S - # - bit[4] -> TH0 bit[11]: ingress::hdr.gre.s - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gre.recurse - # - bit[8..12] -> TH0 bit[7..3]: ingress::hdr.gre.flags - # - bit[13..15] -> TH0 bit[2..0]: ingress::hdr.gre.version - 2: TB1 # ingress::hdr.gre.proto[15:8].8-15 - 3: TB0 # ingress::hdr.gre.proto[7:0].0-7 - W41: 33554432 # value 1 -> W41 bit[25]: ingress::hdr.gre.$valid - load: { half : 10..11, byte0 : 12 } - shift: 4 - buf_req: 13 - next: parse_pptp - 0b*****0000000100000000000: - 0..1: TH0 - # - bit[0] -> TH0 bit[15]: ingress::hdr.gre.C - # - bit[1] -> TH0 bit[14]: ingress::hdr.gre.R - # - bit[2] -> TH0 bit[13]: ingress::hdr.gre.K - # - bit[3] -> TH0 bit[12]: ingress::hdr.gre.S - # - bit[4] -> TH0 bit[11]: ingress::hdr.gre.s - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gre.recurse - # - bit[8..12] -> TH0 bit[7..3]: ingress::hdr.gre.flags - # - bit[13..15] -> TH0 bit[2..0]: ingress::hdr.gre.version - 2: TB1 # ingress::hdr.gre.proto[15:8].8-15 - 3: TB0 # ingress::hdr.gre.proto[7:0].0-7 - W41: 33554432 # value 1 -> W41 bit[25]: ingress::hdr.gre.$valid - shift: 4 - buf_req: 4 - next: parse_gre_ipv4 - 0b*****0001000011011011101: - 0..1: TH0 - # - bit[0] -> TH0 bit[15]: ingress::hdr.gre.C - # - bit[1] -> TH0 bit[14]: ingress::hdr.gre.R - # - bit[2] -> TH0 bit[13]: ingress::hdr.gre.K - # - bit[3] -> TH0 bit[12]: ingress::hdr.gre.S - # - bit[4] -> TH0 bit[11]: ingress::hdr.gre.s - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gre.recurse - # - bit[8..12] -> TH0 bit[7..3]: ingress::hdr.gre.flags - # - bit[13..15] -> TH0 bit[2..0]: ingress::hdr.gre.version - 2: TB1 # ingress::hdr.gre.proto[15:8].8-15 - 3: TB0 # ingress::hdr.gre.proto[7:0].0-7 - W41: 33554432 # value 1 -> W41 bit[25]: ingress::hdr.gre.$valid - shift: 4 - buf_req: 4 - next: parse_inner_ipv6 - 0x******: - 0..1: TH0 - # - bit[0] -> TH0 bit[15]: ingress::hdr.gre.C - # - bit[1] -> TH0 bit[14]: ingress::hdr.gre.R - # - bit[2] -> TH0 bit[13]: ingress::hdr.gre.K - # - bit[3] -> TH0 bit[12]: ingress::hdr.gre.S - # - bit[4] -> TH0 bit[11]: ingress::hdr.gre.s - # - bit[5..7] -> TH0 bit[10..8]: ingress::hdr.gre.recurse - # - bit[8..12] -> TH0 bit[7..3]: ingress::hdr.gre.flags - # - bit[13..15] -> TH0 bit[2..0]: ingress::hdr.gre.version - 2: TB1 # ingress::hdr.gre.proto[15:8].8-15 - 3: TB0 # ingress::hdr.gre.proto[7:0].0-7 - W41: 33554432 # value 1 -> W41 bit[25]: ingress::hdr.gre.$valid - shift: 4 - buf_req: 4 - next: end - parse_pptp: - match: [ half, byte0 ] - 0x00214*: - 0..1: TH1 - # - bit[0..3] -> TH1 bit[15..12]: ingress::hdr.pppoe.version - # - bit[4..7] -> TH1 bit[11..8]: ingress::hdr.pppoe.type - # - bit[8..15] -> TH1 bit[7..0]: ingress::hdr.pppoe.code - 2..3: TH2 # ingress::hdr.pppoe.session_id - 4..7: TW25 - # - bit[32..47] -> TW25 bit[31..16]: ingress::hdr.pppoe.pppoe_length - # - bit[48..63] -> TW25 bit[15..0]: ingress::hdr.pppoe.ppp_proto - W41: 4194304 # value 1 -> W41 bit[22]: ingress::hdr.pppoe.$valid - load: { byte1 : 17 } - shift: 8 - buf_req: 18 - next: parse_inner_ipv4 - 0x00216*: - 0..1: TH1 - # - bit[0..3] -> TH1 bit[15..12]: ingress::hdr.pppoe.version - # - bit[4..7] -> TH1 bit[11..8]: ingress::hdr.pppoe.type - # - bit[8..15] -> TH1 bit[7..0]: ingress::hdr.pppoe.code - 2..3: TH2 # ingress::hdr.pppoe.session_id - 4..7: TW25 - # - bit[32..47] -> TW25 bit[31..16]: ingress::hdr.pppoe.pppoe_length - # - bit[48..63] -> TW25 bit[15..0]: ingress::hdr.pppoe.ppp_proto - W41: 4194304 # value 1 -> W41 bit[22]: ingress::hdr.pppoe.$valid - shift: 8 - buf_req: 8 - next: parse_inner_ipv6 - 0x******: - 0..1: TH1 - # - bit[0..3] -> TH1 bit[15..12]: ingress::hdr.pppoe.version - # - bit[4..7] -> TH1 bit[11..8]: ingress::hdr.pppoe.type - # - bit[8..15] -> TH1 bit[7..0]: ingress::hdr.pppoe.code - 2..3: TH2 # ingress::hdr.pppoe.session_id - 4..7: TW25 - # - bit[32..47] -> TW25 bit[31..16]: ingress::hdr.pppoe.pppoe_length - # - bit[48..63] -> TW25 bit[15..0]: ingress::hdr.pppoe.ppp_proto - W41: 4194304 # value 1 -> W41 bit[22]: ingress::hdr.pppoe.$valid - shift: 8 - buf_req: 8 - next: end - parse_gre_ipv4: - *: - load: { byte1 : 9 } - buf_req: 10 - next: parse_inner_ipv4 - parse_ipv6: - *: - 0..3: TW0 - # - bit[0..3] -> TW0 bit[31..28]: ingress::hdr.ipv6.version - # - bit[4..11] -> TW0 bit[27..20]: ingress::hdr.ipv6.traffic_class - # - bit[12..31] -> TW0 bit[19..0]: ingress::hdr.ipv6.flow_label - 4..7: TW16 - # - bit[32..47] -> TW16 bit[31..16]: ingress::hdr.ipv6.payload_len - # - bit[48..55] -> TW16 bit[15..8]: ingress::hdr.ipv6.next_hdr - # - bit[56..63] -> TW16 bit[7..0]: ingress::hdr.ipv6.hop_limit - 6: B11 # ingress::ig_md.lkp.ip_proto - 8..11: W36 # ingress::hdr.ipv6.src_addr[127:96].96-127 - 8..11: W52 # ingress::ig_md.lkp.ip_src_addr[127:96].96-127 - 12: TB11 # ingress::hdr.ipv6.src_addr[95:88].88-95 - 13: TB10 # ingress::hdr.ipv6.src_addr[87:80].80-87 - 14: TB9 # ingress::hdr.ipv6.src_addr[79:72].72-79 - 16..17: TH38 # ingress::hdr.ipv6.src_addr[63:48].48-63 - 18..19: TH37 # ingress::hdr.ipv6.src_addr[47:32].32-47 - 20..21: TH36 # ingress::hdr.ipv6.src_addr[31:16].16-31 - 22..23: TH29 # ingress::hdr.ipv6.src_addr[15:0].0-15 - load: { byte1 : 6 } - shift: 12 - buf_req: 24 - next: parse_ipv6.$split_0 - parse_ipv6.$split_0: - *: - 0..3: W51 # ingress::ig_md.lkp.ip_src_addr[95:64].64-95 - 3: TB8 # ingress::hdr.ipv6.src_addr[71:64].64-71 - 4..7: W50 # ingress::ig_md.lkp.ip_src_addr[63:32].32-63 - 8..11: W49 # ingress::ig_md.lkp.ip_src_addr[31:0].0-31 - 12..15: W40 # ingress::hdr.ipv6.dst_addr[127:96].96-127 - shift: 12 - buf_req: 16 - next: parse_ipv6.$split_1 - parse_ipv6.$split_1: - *: - 0..3: W56 # ingress::ig_md.lkp.ip_dst_addr[127:96].96-127 - 4..7: W39 # ingress::hdr.ipv6.dst_addr[95:64].64-95 - 4..7: W55 # ingress::ig_md.lkp.ip_dst_addr[95:64].64-95 - 8..11: W38 # ingress::hdr.ipv6.dst_addr[63:32].32-63 - W41: 67108864 # value 1 -> W41 bit[26]: ingress::hdr.ipv6.$valid - shift: 8 - buf_req: 12 - next: parse_ipv6.$split_2 - parse_ipv6.$split_2: - match: [ byte1 ] - 0x06: - 0..3: W54 # ingress::ig_md.lkp.ip_dst_addr[63:32].32-63 - 4..7: W37 # ingress::hdr.ipv6.dst_addr[31:0].0-31 - 4..7: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 - shift: 8 - buf_req: 8 - next: parse_tcp - 0x11: - 0..3: W54 # ingress::ig_md.lkp.ip_dst_addr[63:32].32-63 - 4..7: W37 # ingress::hdr.ipv6.dst_addr[31:0].0-31 - 4..7: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 - load: { half : 10..11 } - shift: 8 - buf_req: 12 - next: parse_udp - 0x3a: - 0..3: W54 # ingress::ig_md.lkp.ip_dst_addr[63:32].32-63 - 4..7: W37 # ingress::hdr.ipv6.dst_addr[31:0].0-31 - 4..7: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 - shift: 8 - buf_req: 8 - next: parse_icmp - 0x84: - 0..3: W54 # ingress::ig_md.lkp.ip_dst_addr[63:32].32-63 - 4..7: W37 # ingress::hdr.ipv6.dst_addr[31:0].0-31 - 4..7: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 - load: { half : 10..11 } - shift: 8 - buf_req: 12 - next: parse_sctp - 0x29: - 0..3: W54 # ingress::ig_md.lkp.ip_dst_addr[63:32].32-63 - 4..7: W37 # ingress::hdr.ipv6.dst_addr[31:0].0-31 - 4..7: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 - shift: 8 - buf_req: 8 - next: parse_inner_ipv6 - 0x04: - 0..3: W54 # ingress::ig_md.lkp.ip_dst_addr[63:32].32-63 - 4..7: W37 # ingress::hdr.ipv6.dst_addr[31:0].0-31 - 4..7: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 - load: { byte1 : 17 } - shift: 8 - buf_req: 18 - next: parse_inner_ipv4 - 0x2f: - 0..3: W54 # ingress::ig_md.lkp.ip_dst_addr[63:32].32-63 - 4..7: W37 # ingress::hdr.ipv6.dst_addr[31:0].0-31 - 4..7: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 - load: { half : 9..10, byte0 : 11 } - shift: 8 - buf_req: 12 - next: parse_gre - 0x**: - 0..3: W54 # ingress::ig_md.lkp.ip_dst_addr[63:32].32-63 - 4..7: W37 # ingress::hdr.ipv6.dst_addr[31:0].0-31 - 4..7: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 - shift: 8 - buf_req: 8 - next: end - parse_vlan: - match: [ half ] - 0x0800: - 0..1: H4 - # - bit[0..2] -> H4 bit[15..13]: ingress::hdr.vlan_tag[0].pcp - # - bit[3] -> H4 bit[12]: ingress::hdr.vlan_tag[0].cfi - # - bit[4..15] -> H4 bit[11..0]: ingress::hdr.vlan_tag[0].vid - 2..3: TH4 # ingress::hdr.vlan_tag[0].ether_type - B2: 16 # value 16 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv4 - 0x86dd: - 0..1: H4 - # - bit[0..2] -> H4 bit[15..13]: ingress::hdr.vlan_tag[0].pcp - # - bit[3] -> H4 bit[12]: ingress::hdr.vlan_tag[0].cfi - # - bit[4..15] -> H4 bit[11..0]: ingress::hdr.vlan_tag[0].vid - 2..3: TH4 # ingress::hdr.vlan_tag[0].ether_type - B2: 16 # value 16 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv6 - 0x8100: - 0..1: H4 - # - bit[0..2] -> H4 bit[15..13]: ingress::hdr.vlan_tag[0].pcp - # - bit[3] -> H4 bit[12]: ingress::hdr.vlan_tag[0].cfi - # - bit[4..15] -> H4 bit[11..0]: ingress::hdr.vlan_tag[0].vid - 2..3: TH4 # ingress::hdr.vlan_tag[0].ether_type - B2: 16 # value 16 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - load: { half : 6..7 } - shift: 4 - buf_req: 8 - next: parse_vlan.$it1 - 0x8847: - 0..1: H4 - # - bit[0..2] -> H4 bit[15..13]: ingress::hdr.vlan_tag[0].pcp - # - bit[3] -> H4 bit[12]: ingress::hdr.vlan_tag[0].cfi - # - bit[4..15] -> H4 bit[11..0]: ingress::hdr.vlan_tag[0].vid - 2..3: TH4 # ingress::hdr.vlan_tag[0].ether_type - B2: 16 # value 16 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - load: { byte1 : 6 } - shift: 4 - buf_req: 7 - next: parse_mpls - 0x****: - 0..1: H4 - # - bit[0..2] -> H4 bit[15..13]: ingress::hdr.vlan_tag[0].pcp - # - bit[3] -> H4 bit[12]: ingress::hdr.vlan_tag[0].cfi - # - bit[4..15] -> H4 bit[11..0]: ingress::hdr.vlan_tag[0].vid - 2..3: TH4 # ingress::hdr.vlan_tag[0].ether_type - B2: 16 # value 16 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_vlan.$it1: - match: [ half ] - 0x0800: - 0..1: TH5 - # - bit[0..2] -> TH5 bit[15..13]: ingress::hdr.vlan_tag[1].pcp - # - bit[3] -> TH5 bit[12]: ingress::hdr.vlan_tag[1].cfi - # - bit[4..15] -> TH5 bit[11..0]: ingress::hdr.vlan_tag[1].vid - 2: TB3 # ingress::hdr.vlan_tag[1].ether_type[15:8].8-15 - 3: TB2 # ingress::hdr.vlan_tag[1].ether_type[7:0].0-7 - B2: 8 # value 8 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv4 - 0x86dd: - 0..1: TH5 - # - bit[0..2] -> TH5 bit[15..13]: ingress::hdr.vlan_tag[1].pcp - # - bit[3] -> TH5 bit[12]: ingress::hdr.vlan_tag[1].cfi - # - bit[4..15] -> TH5 bit[11..0]: ingress::hdr.vlan_tag[1].vid - 2: TB3 # ingress::hdr.vlan_tag[1].ether_type[15:8].8-15 - 3: TB2 # ingress::hdr.vlan_tag[1].ether_type[7:0].0-7 - B2: 8 # value 8 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv6 - 0x8100: - 0..1: TH5 - # - bit[0..2] -> TH5 bit[15..13]: ingress::hdr.vlan_tag[1].pcp - # - bit[3] -> TH5 bit[12]: ingress::hdr.vlan_tag[1].cfi - # - bit[4..15] -> TH5 bit[11..0]: ingress::hdr.vlan_tag[1].vid - 2: TB3 # ingress::hdr.vlan_tag[1].ether_type[15:8].8-15 - 3: TB2 # ingress::hdr.vlan_tag[1].ether_type[7:0].0-7 - B2: 8 # value 8 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - load: { half : 6..7 } - shift: 4 - buf_req: 8 - next: parse_vlan.$it2 - 0x8847: - 0..1: TH5 - # - bit[0..2] -> TH5 bit[15..13]: ingress::hdr.vlan_tag[1].pcp - # - bit[3] -> TH5 bit[12]: ingress::hdr.vlan_tag[1].cfi - # - bit[4..15] -> TH5 bit[11..0]: ingress::hdr.vlan_tag[1].vid - 2: TB3 # ingress::hdr.vlan_tag[1].ether_type[15:8].8-15 - 3: TB2 # ingress::hdr.vlan_tag[1].ether_type[7:0].0-7 - B2: 8 # value 8 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - load: { byte1 : 6 } - shift: 4 - buf_req: 7 - next: parse_mpls - 0x****: - 0..1: TH5 - # - bit[0..2] -> TH5 bit[15..13]: ingress::hdr.vlan_tag[1].pcp - # - bit[3] -> TH5 bit[12]: ingress::hdr.vlan_tag[1].cfi - # - bit[4..15] -> TH5 bit[11..0]: ingress::hdr.vlan_tag[1].vid - 2: TB3 # ingress::hdr.vlan_tag[1].ether_type[15:8].8-15 - 3: TB2 # ingress::hdr.vlan_tag[1].ether_type[7:0].0-7 - B2: 8 # value 8 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_vlan.$it2: - match: [ half ] - 0x0800: - 0..3: TW8 - # - bit[0..2] -> TW8 bit[31..29]: ingress::hdr.vlan_tag[2].pcp - # - bit[3] -> TW8 bit[28]: ingress::hdr.vlan_tag[2].cfi - # - bit[4..15] -> TW8 bit[27..16]: ingress::hdr.vlan_tag[2].vid - # - bit[16..31] -> TW8 bit[15..0]: ingress::hdr.vlan_tag[2].ether_type - B2: 4 # value 4 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv4 - 0x86dd: - 0..3: TW8 - # - bit[0..2] -> TW8 bit[31..29]: ingress::hdr.vlan_tag[2].pcp - # - bit[3] -> TW8 bit[28]: ingress::hdr.vlan_tag[2].cfi - # - bit[4..15] -> TW8 bit[27..16]: ingress::hdr.vlan_tag[2].vid - # - bit[16..31] -> TW8 bit[15..0]: ingress::hdr.vlan_tag[2].ether_type - B2: 4 # value 4 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv6 - 0x8100: - 0..3: TW8 - # - bit[0..2] -> TW8 bit[31..29]: ingress::hdr.vlan_tag[2].pcp - # - bit[3] -> TW8 bit[28]: ingress::hdr.vlan_tag[2].cfi - # - bit[4..15] -> TW8 bit[27..16]: ingress::hdr.vlan_tag[2].vid - # - bit[16..31] -> TW8 bit[15..0]: ingress::hdr.vlan_tag[2].ether_type - B2: 4 # value 4 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - load: { half : 6..7 } - shift: 4 - buf_req: 8 - next: parse_vlan.$it3 - 0x8847: - 0..3: TW8 - # - bit[0..2] -> TW8 bit[31..29]: ingress::hdr.vlan_tag[2].pcp - # - bit[3] -> TW8 bit[28]: ingress::hdr.vlan_tag[2].cfi - # - bit[4..15] -> TW8 bit[27..16]: ingress::hdr.vlan_tag[2].vid - # - bit[16..31] -> TW8 bit[15..0]: ingress::hdr.vlan_tag[2].ether_type - B2: 4 # value 4 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - load: { byte1 : 6 } - shift: 4 - buf_req: 7 - next: parse_mpls - 0x****: - 0..3: TW8 - # - bit[0..2] -> TW8 bit[31..29]: ingress::hdr.vlan_tag[2].pcp - # - bit[3] -> TW8 bit[28]: ingress::hdr.vlan_tag[2].cfi - # - bit[4..15] -> TW8 bit[27..16]: ingress::hdr.vlan_tag[2].vid - # - bit[16..31] -> TW8 bit[15..0]: ingress::hdr.vlan_tag[2].ether_type - B2: 4 # value 4 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_vlan.$it3: - match: [ half ] - 0x0800: - 0..3: TW9 - # - bit[0..2] -> TW9 bit[31..29]: ingress::hdr.vlan_tag[3].pcp - # - bit[3] -> TW9 bit[28]: ingress::hdr.vlan_tag[3].cfi - # - bit[4..15] -> TW9 bit[27..16]: ingress::hdr.vlan_tag[3].vid - # - bit[16..31] -> TW9 bit[15..0]: ingress::hdr.vlan_tag[3].ether_type - B2: 2 # value 2 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv4 - 0x86dd: - 0..3: TW9 - # - bit[0..2] -> TW9 bit[31..29]: ingress::hdr.vlan_tag[3].pcp - # - bit[3] -> TW9 bit[28]: ingress::hdr.vlan_tag[3].cfi - # - bit[4..15] -> TW9 bit[27..16]: ingress::hdr.vlan_tag[3].vid - # - bit[16..31] -> TW9 bit[15..0]: ingress::hdr.vlan_tag[3].ether_type - B2: 2 # value 2 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv6 - 0x8100: - 0..3: TW9 - # - bit[0..2] -> TW9 bit[31..29]: ingress::hdr.vlan_tag[3].pcp - # - bit[3] -> TW9 bit[28]: ingress::hdr.vlan_tag[3].cfi - # - bit[4..15] -> TW9 bit[27..16]: ingress::hdr.vlan_tag[3].vid - # - bit[16..31] -> TW9 bit[15..0]: ingress::hdr.vlan_tag[3].ether_type - B2: 2 # value 2 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - load: { half : 6..7 } - shift: 4 - buf_req: 8 - next: parse_vlan.$it4 - 0x8847: - 0..3: TW9 - # - bit[0..2] -> TW9 bit[31..29]: ingress::hdr.vlan_tag[3].pcp - # - bit[3] -> TW9 bit[28]: ingress::hdr.vlan_tag[3].cfi - # - bit[4..15] -> TW9 bit[27..16]: ingress::hdr.vlan_tag[3].vid - # - bit[16..31] -> TW9 bit[15..0]: ingress::hdr.vlan_tag[3].ether_type - B2: 2 # value 2 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - load: { byte1 : 6 } - shift: 4 - buf_req: 7 - next: parse_mpls - 0x****: - 0..3: TW9 - # - bit[0..2] -> TW9 bit[31..29]: ingress::hdr.vlan_tag[3].pcp - # - bit[3] -> TW9 bit[28]: ingress::hdr.vlan_tag[3].cfi - # - bit[4..15] -> TW9 bit[27..16]: ingress::hdr.vlan_tag[3].vid - # - bit[16..31] -> TW9 bit[15..0]: ingress::hdr.vlan_tag[3].ether_type - B2: 2 # value 2 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_vlan.$it4: - match: [ half ] - 0x0800: - 0..3: TW10 - # - bit[0..2] -> TW10 bit[31..29]: ingress::hdr.vlan_tag[4].pcp - # - bit[3] -> TW10 bit[28]: ingress::hdr.vlan_tag[4].cfi - # - bit[4..15] -> TW10 bit[27..16]: ingress::hdr.vlan_tag[4].vid - # - bit[16..31] -> TW10 bit[15..0]: ingress::hdr.vlan_tag[4].ether_type - B2: 1 # value 1 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv4 - 0x86dd: - 0..3: TW10 - # - bit[0..2] -> TW10 bit[31..29]: ingress::hdr.vlan_tag[4].pcp - # - bit[3] -> TW10 bit[28]: ingress::hdr.vlan_tag[4].cfi - # - bit[4..15] -> TW10 bit[27..16]: ingress::hdr.vlan_tag[4].vid - # - bit[16..31] -> TW10 bit[15..0]: ingress::hdr.vlan_tag[4].ether_type - B2: 1 # value 1 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv6 - 0x8100: - 0..3: TW10 - # - bit[0..2] -> TW10 bit[31..29]: ingress::hdr.vlan_tag[4].pcp - # - bit[3] -> TW10 bit[28]: ingress::hdr.vlan_tag[4].cfi - # - bit[4..15] -> TW10 bit[27..16]: ingress::hdr.vlan_tag[4].vid - # - bit[16..31] -> TW10 bit[15..0]: ingress::hdr.vlan_tag[4].ether_type - B2: 1 # value 1 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - 0x8847: - 0..3: TW10 - # - bit[0..2] -> TW10 bit[31..29]: ingress::hdr.vlan_tag[4].pcp - # - bit[3] -> TW10 bit[28]: ingress::hdr.vlan_tag[4].cfi - # - bit[4..15] -> TW10 bit[27..16]: ingress::hdr.vlan_tag[4].vid - # - bit[16..31] -> TW10 bit[15..0]: ingress::hdr.vlan_tag[4].ether_type - B2: 1 # value 1 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - load: { byte1 : 6 } - shift: 4 - buf_req: 7 - next: parse_mpls - 0x****: - 0..3: TW10 - # - bit[0..2] -> TW10 bit[31..29]: ingress::hdr.vlan_tag[4].pcp - # - bit[3] -> TW10 bit[28]: ingress::hdr.vlan_tag[4].cfi - # - bit[4..15] -> TW10 bit[27..16]: ingress::hdr.vlan_tag[4].vid - # - bit[16..31] -> TW10 bit[15..0]: ingress::hdr.vlan_tag[4].ether_type - B2: 1 # value 1 -> B2 bit[4..0]: ingress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_mpls: - match: [ byte1 ] - 0b*******0: - 0..3: TW11 - # - bit[0..19] -> TW11 bit[31..12]: ingress::hdr.mpls[0].label - # - bit[20..22] -> TW11 bit[11..9]: ingress::hdr.mpls[0].exp - # - bit[23] -> TW11 bit[8]: ingress::hdr.mpls[0].bos - # - bit[24..31] -> TW11 bit[7..0]: ingress::hdr.mpls[0].ttl - B3: 8 # value 8 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid - load: { byte1 : 6 } - shift: 4 - buf_req: 7 - next: parse_mpls.$it1 - 0b*******1: - 0..3: TW11 - # - bit[0..19] -> TW11 bit[31..12]: ingress::hdr.mpls[0].label - # - bit[20..22] -> TW11 bit[11..9]: ingress::hdr.mpls[0].exp - # - bit[23] -> TW11 bit[8]: ingress::hdr.mpls[0].bos - # - bit[24..31] -> TW11 bit[7..0]: ingress::hdr.mpls[0].ttl - B3: 8 # value 8 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid - load: { byte1 : 4 } - shift: 4 - buf_req: 5 - next: parse_mpls_bos - 0x**: - 0..3: TW11 - # - bit[0..19] -> TW11 bit[31..12]: ingress::hdr.mpls[0].label - # - bit[20..22] -> TW11 bit[11..9]: ingress::hdr.mpls[0].exp - # - bit[23] -> TW11 bit[8]: ingress::hdr.mpls[0].bos - # - bit[24..31] -> TW11 bit[7..0]: ingress::hdr.mpls[0].ttl - B3: 8 # value 8 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_mpls.$it1: - match: [ byte1 ] - 0b*******0: - 0..1: TH13 # ingress::hdr.mpls[1].label[19:4].4-19 - 2..3: TH12 - # - bit[16..19] -> TH12 bit[15..12]: ingress::hdr.mpls[1].label[3:0].0-3 - # - bit[20..22] -> TH12 bit[11..9]: ingress::hdr.mpls[1].exp - # - bit[23] -> TH12 bit[8]: ingress::hdr.mpls[1].bos - # - bit[24..31] -> TH12 bit[7..0]: ingress::hdr.mpls[1].ttl - B3: 4 # value 4 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid - load: { byte1 : 6 } - shift: 4 - buf_req: 7 - next: parse_mpls.$it2 - 0b*******1: - 0..1: TH13 # ingress::hdr.mpls[1].label[19:4].4-19 - 2..3: TH12 - # - bit[16..19] -> TH12 bit[15..12]: ingress::hdr.mpls[1].label[3:0].0-3 - # - bit[20..22] -> TH12 bit[11..9]: ingress::hdr.mpls[1].exp - # - bit[23] -> TH12 bit[8]: ingress::hdr.mpls[1].bos - # - bit[24..31] -> TH12 bit[7..0]: ingress::hdr.mpls[1].ttl - B3: 4 # value 4 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid - load: { byte1 : 4 } - shift: 4 - buf_req: 5 - next: parse_mpls_bos - 0x**: - 0..1: TH13 # ingress::hdr.mpls[1].label[19:4].4-19 - 2..3: TH12 - # - bit[16..19] -> TH12 bit[15..12]: ingress::hdr.mpls[1].label[3:0].0-3 - # - bit[20..22] -> TH12 bit[11..9]: ingress::hdr.mpls[1].exp - # - bit[23] -> TH12 bit[8]: ingress::hdr.mpls[1].bos - # - bit[24..31] -> TH12 bit[7..0]: ingress::hdr.mpls[1].ttl - B3: 4 # value 4 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_mpls.$it2: - match: [ byte1 ] - 0b*******0: - 0..1: TH15 # ingress::hdr.mpls[2].label[19:4].4-19 - 2..3: TH14 - # - bit[16..19] -> TH14 bit[15..12]: ingress::hdr.mpls[2].label[3:0].0-3 - # - bit[20..22] -> TH14 bit[11..9]: ingress::hdr.mpls[2].exp - # - bit[23] -> TH14 bit[8]: ingress::hdr.mpls[2].bos - # - bit[24..31] -> TH14 bit[7..0]: ingress::hdr.mpls[2].ttl - B3: 2 # value 2 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid - load: { byte1 : 6 } - shift: 4 - buf_req: 7 - next: parse_mpls.$it3 - 0b*******1: - 0..1: TH15 # ingress::hdr.mpls[2].label[19:4].4-19 - 2..3: TH14 - # - bit[16..19] -> TH14 bit[15..12]: ingress::hdr.mpls[2].label[3:0].0-3 - # - bit[20..22] -> TH14 bit[11..9]: ingress::hdr.mpls[2].exp - # - bit[23] -> TH14 bit[8]: ingress::hdr.mpls[2].bos - # - bit[24..31] -> TH14 bit[7..0]: ingress::hdr.mpls[2].ttl - B3: 2 # value 2 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid - load: { byte1 : 4 } - shift: 4 - buf_req: 5 - next: parse_mpls_bos - 0x**: - 0..1: TH15 # ingress::hdr.mpls[2].label[19:4].4-19 - 2..3: TH14 - # - bit[16..19] -> TH14 bit[15..12]: ingress::hdr.mpls[2].label[3:0].0-3 - # - bit[20..22] -> TH14 bit[11..9]: ingress::hdr.mpls[2].exp - # - bit[23] -> TH14 bit[8]: ingress::hdr.mpls[2].bos - # - bit[24..31] -> TH14 bit[7..0]: ingress::hdr.mpls[2].ttl - B3: 2 # value 2 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_mpls.$it3: - match: [ byte1 ] - 0b*******0: - 0..1: TH17 # ingress::hdr.mpls[3].label[19:4].4-19 - 2..3: TH16 - # - bit[16..19] -> TH16 bit[15..12]: ingress::hdr.mpls[3].label[3:0].0-3 - # - bit[20..22] -> TH16 bit[11..9]: ingress::hdr.mpls[3].exp - # - bit[23] -> TH16 bit[8]: ingress::hdr.mpls[3].bos - # - bit[24..31] -> TH16 bit[7..0]: ingress::hdr.mpls[3].ttl - B3: 1 # value 1 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid - shift: 4 - buf_req: 4 - next: end - 0b*******1: - 0..1: TH17 # ingress::hdr.mpls[3].label[19:4].4-19 - 2..3: TH16 - # - bit[16..19] -> TH16 bit[15..12]: ingress::hdr.mpls[3].label[3:0].0-3 - # - bit[20..22] -> TH16 bit[11..9]: ingress::hdr.mpls[3].exp - # - bit[23] -> TH16 bit[8]: ingress::hdr.mpls[3].bos - # - bit[24..31] -> TH16 bit[7..0]: ingress::hdr.mpls[3].ttl - B3: 1 # value 1 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid - load: { byte1 : 4 } - shift: 4 - buf_req: 5 - next: parse_mpls_bos - 0x**: - 0..1: TH17 # ingress::hdr.mpls[3].label[19:4].4-19 - 2..3: TH16 - # - bit[16..19] -> TH16 bit[15..12]: ingress::hdr.mpls[3].label[3:0].0-3 - # - bit[20..22] -> TH16 bit[11..9]: ingress::hdr.mpls[3].exp - # - bit[23] -> TH16 bit[8]: ingress::hdr.mpls[3].bos - # - bit[24..31] -> TH16 bit[7..0]: ingress::hdr.mpls[3].ttl - B3: 1 # value 1 -> B3 bit[3..0]: ingress::hdr.mpls.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_mpls_bos: - match: [ byte1 ] - 0x4*: - 0..3: TW0 - # - bit[0..3] -> TW0 bit[31..28]: ingress::hdr.ipv4.version - # - bit[4..7] -> TW0 bit[27..24]: ingress::hdr.ipv4.ihl - # - bit[8..15] -> TW0 bit[23..16]: ingress::hdr.ipv4.diffserv - # - bit[16..31] -> TW0 bit[15..0]: ingress::hdr.ipv4.total_len - 4: TB11 # ingress::hdr.ipv4.identification[15:8].8-15 - 5: TB10 # ingress::hdr.ipv4.identification[7:0].0-7 - 6: TB8 - # - bit[48..50] -> TB8 bit[7..5]: ingress::hdr.ipv4.flags - # - bit[51..55] -> TB8 bit[4..0]: ingress::hdr.ipv4.frag_offset[12:8].8-12 - 7: TB9 # ingress::hdr.ipv4.frag_offset[7:0].0-7 - 8..11: TW16 - # - bit[64..71] -> TW16 bit[31..24]: ingress::hdr.ipv4.ttl - # - bit[72..79] -> TW16 bit[23..16]: ingress::hdr.ipv4.protocol - # - bit[80..95] -> TW16 bit[15..0]: ingress::hdr.ipv4.hdr_checksum - 12..13: TH36 # ingress::hdr.ipv4.src_addr[31:16].16-31 - 12..15: W49 # ingress::ig_md.lkp.ip_src_addr[31:0].0-31 - 14..15: TH29 # ingress::hdr.ipv4.src_addr[15:0].0-15 - 16..17: TH38 # ingress::hdr.ipv4.dst_addr[31:16].16-31 - 16..19: W53 # ingress::ig_md.lkp.ip_dst_addr[31:0].0-31 - 18..19: TH37 # ingress::hdr.ipv4.dst_addr[15:0].0-15 - load: { byte1 : 9 } - shift: 9 - buf_req: 20 - next: parse_ipv4.$split_0 - 0x6*: - 0..3: TW0 - # - bit[0..3] -> TW0 bit[31..28]: ingress::hdr.ipv6.version - # - bit[4..11] -> TW0 bit[27..20]: ingress::hdr.ipv6.traffic_class - # - bit[12..31] -> TW0 bit[19..0]: ingress::hdr.ipv6.flow_label - 4..7: TW16 - # - bit[32..47] -> TW16 bit[31..16]: ingress::hdr.ipv6.payload_len - # - bit[48..55] -> TW16 bit[15..8]: ingress::hdr.ipv6.next_hdr - # - bit[56..63] -> TW16 bit[7..0]: ingress::hdr.ipv6.hop_limit - 6: B11 # ingress::ig_md.lkp.ip_proto - 8..11: W36 # ingress::hdr.ipv6.src_addr[127:96].96-127 - 8..11: W52 # ingress::ig_md.lkp.ip_src_addr[127:96].96-127 - 12: TB11 # ingress::hdr.ipv6.src_addr[95:88].88-95 - 13: TB10 # ingress::hdr.ipv6.src_addr[87:80].80-87 - 14: TB9 # ingress::hdr.ipv6.src_addr[79:72].72-79 - 16..17: TH38 # ingress::hdr.ipv6.src_addr[63:48].48-63 - 18..19: TH37 # ingress::hdr.ipv6.src_addr[47:32].32-47 - 20..21: TH36 # ingress::hdr.ipv6.src_addr[31:16].16-31 - 22..23: TH29 # ingress::hdr.ipv6.src_addr[15:0].0-15 - load: { byte1 : 6 } - shift: 12 - buf_req: 24 - next: parse_ipv6.$split_0 - 0x**: - buf_req: 0 - next: end - TofinoIngressParserInner_2_parse_port_metadata.$oob_stall_0: - *: - load: { half : 11..12 } - buf_req: 13 - next: parse_fabric - parse_fabric: - match: [ half ] - 0x0800: - 0..3: W5 - # - bit[0] -> W5 bit[31]: ingress::hdr.fabric.pad1 - # - bit[1] -> W5 bit[30]: ingress::hdr.fabric.is_hit - # - bit[2] -> W5 bit[29]: ingress::hdr.fabric.is_to_cn78 - # - bit[3] -> W5 bit[28]: ingress::hdr.fabric.is_to_td3 - # - bit[4] -> W5 bit[27]: ingress::hdr.fabric.is_hdr_decap - # - bit[5..7] -> W5 bit[26..24]: ingress::hdr.fabric.ig_port_type - # - bit[8..13] -> W5 bit[23..18]: ingress::hdr.fabric.pad2 - # - bit[14..31] -> W5 bit[17..0]: ingress::hdr.fabric.mac_index - 4: B4 - # - bit[32..35] -> B4 bit[7..4]: ingress::hdr.fabric.pad4 - # - bit[36] -> B4 bit[3]: ingress::hdr.fabric.flags_drop - # - bit[37] -> B4 bit[2]: ingress::hdr.fabric.is_trunc_mir - # - bit[38..39] -> B4 bit[1..0]: ingress::hdr.fabric.count_index[17:16].16-17 - 5..8: W3 - # - bit[40..55] -> W3 bit[31..16]: ingress::hdr.fabric.count_index[15:0].0-15 - # - bit[56..71] -> W3 bit[15..0]: ingress::hdr.fabric.mc_index - 9..12: W4 - # - bit[72..87] -> W4 bit[31..16]: ingress::hdr.fabric.vlan_index - # - bit[88..103] -> W4 bit[15..0]: ingress::hdr.fabric.ether_type - W41: 134217728 # value 1 -> W41 bit[27]: ingress::hdr.fabric.$valid - shift: 13 - buf_req: 13 - next: parse_ipv4 - 0x86dd: - 0..3: W5 - # - bit[0] -> W5 bit[31]: ingress::hdr.fabric.pad1 - # - bit[1] -> W5 bit[30]: ingress::hdr.fabric.is_hit - # - bit[2] -> W5 bit[29]: ingress::hdr.fabric.is_to_cn78 - # - bit[3] -> W5 bit[28]: ingress::hdr.fabric.is_to_td3 - # - bit[4] -> W5 bit[27]: ingress::hdr.fabric.is_hdr_decap - # - bit[5..7] -> W5 bit[26..24]: ingress::hdr.fabric.ig_port_type - # - bit[8..13] -> W5 bit[23..18]: ingress::hdr.fabric.pad2 - # - bit[14..31] -> W5 bit[17..0]: ingress::hdr.fabric.mac_index - 4: B4 - # - bit[32..35] -> B4 bit[7..4]: ingress::hdr.fabric.pad4 - # - bit[36] -> B4 bit[3]: ingress::hdr.fabric.flags_drop - # - bit[37] -> B4 bit[2]: ingress::hdr.fabric.is_trunc_mir - # - bit[38..39] -> B4 bit[1..0]: ingress::hdr.fabric.count_index[17:16].16-17 - 5..8: W3 - # - bit[40..55] -> W3 bit[31..16]: ingress::hdr.fabric.count_index[15:0].0-15 - # - bit[56..71] -> W3 bit[15..0]: ingress::hdr.fabric.mc_index - 9..12: W4 - # - bit[72..87] -> W4 bit[31..16]: ingress::hdr.fabric.vlan_index - # - bit[88..103] -> W4 bit[15..0]: ingress::hdr.fabric.ether_type - W41: 134217728 # value 1 -> W41 bit[27]: ingress::hdr.fabric.$valid - shift: 13 - buf_req: 13 - next: parse_ipv6 - 0x8100: - 0..3: W5 - # - bit[0] -> W5 bit[31]: ingress::hdr.fabric.pad1 - # - bit[1] -> W5 bit[30]: ingress::hdr.fabric.is_hit - # - bit[2] -> W5 bit[29]: ingress::hdr.fabric.is_to_cn78 - # - bit[3] -> W5 bit[28]: ingress::hdr.fabric.is_to_td3 - # - bit[4] -> W5 bit[27]: ingress::hdr.fabric.is_hdr_decap - # - bit[5..7] -> W5 bit[26..24]: ingress::hdr.fabric.ig_port_type - # - bit[8..13] -> W5 bit[23..18]: ingress::hdr.fabric.pad2 - # - bit[14..31] -> W5 bit[17..0]: ingress::hdr.fabric.mac_index - 4: B4 - # - bit[32..35] -> B4 bit[7..4]: ingress::hdr.fabric.pad4 - # - bit[36] -> B4 bit[3]: ingress::hdr.fabric.flags_drop - # - bit[37] -> B4 bit[2]: ingress::hdr.fabric.is_trunc_mir - # - bit[38..39] -> B4 bit[1..0]: ingress::hdr.fabric.count_index[17:16].16-17 - 5..8: W3 - # - bit[40..55] -> W3 bit[31..16]: ingress::hdr.fabric.count_index[15:0].0-15 - # - bit[56..71] -> W3 bit[15..0]: ingress::hdr.fabric.mc_index - 9..12: W4 - # - bit[72..87] -> W4 bit[31..16]: ingress::hdr.fabric.vlan_index - # - bit[88..103] -> W4 bit[15..0]: ingress::hdr.fabric.ether_type - W41: 134217728 # value 1 -> W41 bit[27]: ingress::hdr.fabric.$valid - load: { half : 15..16 } - shift: 13 - buf_req: 17 - next: parse_vlan - 0x8847: - 0..3: W5 - # - bit[0] -> W5 bit[31]: ingress::hdr.fabric.pad1 - # - bit[1] -> W5 bit[30]: ingress::hdr.fabric.is_hit - # - bit[2] -> W5 bit[29]: ingress::hdr.fabric.is_to_cn78 - # - bit[3] -> W5 bit[28]: ingress::hdr.fabric.is_to_td3 - # - bit[4] -> W5 bit[27]: ingress::hdr.fabric.is_hdr_decap - # - bit[5..7] -> W5 bit[26..24]: ingress::hdr.fabric.ig_port_type - # - bit[8..13] -> W5 bit[23..18]: ingress::hdr.fabric.pad2 - # - bit[14..31] -> W5 bit[17..0]: ingress::hdr.fabric.mac_index - 4: B4 - # - bit[32..35] -> B4 bit[7..4]: ingress::hdr.fabric.pad4 - # - bit[36] -> B4 bit[3]: ingress::hdr.fabric.flags_drop - # - bit[37] -> B4 bit[2]: ingress::hdr.fabric.is_trunc_mir - # - bit[38..39] -> B4 bit[1..0]: ingress::hdr.fabric.count_index[17:16].16-17 - 5..8: W3 - # - bit[40..55] -> W3 bit[31..16]: ingress::hdr.fabric.count_index[15:0].0-15 - # - bit[56..71] -> W3 bit[15..0]: ingress::hdr.fabric.mc_index - 9..12: W4 - # - bit[72..87] -> W4 bit[31..16]: ingress::hdr.fabric.vlan_index - # - bit[88..103] -> W4 bit[15..0]: ingress::hdr.fabric.ether_type - W41: 134217728 # value 1 -> W41 bit[27]: ingress::hdr.fabric.$valid - load: { byte1 : 15 } - shift: 13 - buf_req: 16 - next: parse_mpls - 0x****: - 0..3: W5 - # - bit[0] -> W5 bit[31]: ingress::hdr.fabric.pad1 - # - bit[1] -> W5 bit[30]: ingress::hdr.fabric.is_hit - # - bit[2] -> W5 bit[29]: ingress::hdr.fabric.is_to_cn78 - # - bit[3] -> W5 bit[28]: ingress::hdr.fabric.is_to_td3 - # - bit[4] -> W5 bit[27]: ingress::hdr.fabric.is_hdr_decap - # - bit[5..7] -> W5 bit[26..24]: ingress::hdr.fabric.ig_port_type - # - bit[8..13] -> W5 bit[23..18]: ingress::hdr.fabric.pad2 - # - bit[14..31] -> W5 bit[17..0]: ingress::hdr.fabric.mac_index - 4: B4 - # - bit[32..35] -> B4 bit[7..4]: ingress::hdr.fabric.pad4 - # - bit[36] -> B4 bit[3]: ingress::hdr.fabric.flags_drop - # - bit[37] -> B4 bit[2]: ingress::hdr.fabric.is_trunc_mir - # - bit[38..39] -> B4 bit[1..0]: ingress::hdr.fabric.count_index[17:16].16-17 - 5..8: W3 - # - bit[40..55] -> W3 bit[31..16]: ingress::hdr.fabric.count_index[15:0].0-15 - # - bit[56..71] -> W3 bit[15..0]: ingress::hdr.fabric.mc_index - 9..12: W4 - # - bit[72..87] -> W4 bit[31..16]: ingress::hdr.fabric.vlan_index - # - bit[88..103] -> W4 bit[15..0]: ingress::hdr.fabric.ether_type - W41: 134217728 # value 1 -> W41 bit[27]: ingress::hdr.fabric.$valid - shift: 13 - buf_req: 13 - next: end - parse_from_cn78: - match: [ half ] - 0x0800: - 0..3: W4 # bit[0..7] -> W4 bit[31..24]: ingress::hdr.fabric_from_cn78.action_type - 2..5: W3 - # - bit[16..31] -> W3 bit[31..16]: ingress::hdr.fabric_from_cn78.port_group_id - # - bit[32..47] -> W3 bit[15..0]: ingress::hdr.fabric_from_cn78.ether_type - W41: 268435456 # value 1 -> W41 bit[28]: ingress::hdr.fabric_from_cn78.$valid - shift: 6 - buf_req: 6 - next: parse_ipv4 - 0x86dd: - 0..3: W4 # bit[0..7] -> W4 bit[31..24]: ingress::hdr.fabric_from_cn78.action_type - 2..5: W3 - # - bit[16..31] -> W3 bit[31..16]: ingress::hdr.fabric_from_cn78.port_group_id - # - bit[32..47] -> W3 bit[15..0]: ingress::hdr.fabric_from_cn78.ether_type - W41: 268435456 # value 1 -> W41 bit[28]: ingress::hdr.fabric_from_cn78.$valid - shift: 6 - buf_req: 6 - next: parse_ipv6 - 0x8100: - 0..3: W4 # bit[0..7] -> W4 bit[31..24]: ingress::hdr.fabric_from_cn78.action_type - 2..5: W3 - # - bit[16..31] -> W3 bit[31..16]: ingress::hdr.fabric_from_cn78.port_group_id - # - bit[32..47] -> W3 bit[15..0]: ingress::hdr.fabric_from_cn78.ether_type - W41: 268435456 # value 1 -> W41 bit[28]: ingress::hdr.fabric_from_cn78.$valid - load: { half : 8..9 } - shift: 6 - buf_req: 10 - next: parse_vlan - 0x8847: - 0..3: W4 # bit[0..7] -> W4 bit[31..24]: ingress::hdr.fabric_from_cn78.action_type - 2..5: W3 - # - bit[16..31] -> W3 bit[31..16]: ingress::hdr.fabric_from_cn78.port_group_id - # - bit[32..47] -> W3 bit[15..0]: ingress::hdr.fabric_from_cn78.ether_type - W41: 268435456 # value 1 -> W41 bit[28]: ingress::hdr.fabric_from_cn78.$valid - load: { byte1 : 8 } - shift: 6 - buf_req: 9 - next: parse_mpls - 0x****: - 0..3: W4 # bit[0..7] -> W4 bit[31..24]: ingress::hdr.fabric_from_cn78.action_type - 2..5: W3 - # - bit[16..31] -> W3 bit[31..16]: ingress::hdr.fabric_from_cn78.port_group_id - # - bit[32..47] -> W3 bit[15..0]: ingress::hdr.fabric_from_cn78.ether_type - W41: 268435456 # value 1 -> W41 bit[28]: ingress::hdr.fabric_from_cn78.$valid - shift: 6 - buf_req: 6 - next: end -deparser ingress: - dictionary: - B0: W41(0) # ingress::hdr.bridged_md.src if ingress::hdr.bridged_md.$valid - H3: W41(0) - # - bit[15..8]: ingress::hdr.bridged_md.pkt_proto_type if ingress::hdr.bridged_md.$valid - # - bit[7..0]: ingress::hdr.bridged_md.ip_hdr_location if ingress::hdr.bridged_md.$valid - B7: W41(0) - # - bit[7..1]: ingress::hdr.bridged_md.pad1 if ingress::hdr.bridged_md.$valid - # - bit[0]: ingress::hdr.bridged_md.tunnel_type.5-5 if ingress::hdr.bridged_md.$valid - B6: W41(0) - # - bit[7..3]: ingress::hdr.bridged_md.tunnel_type.0-4 if ingress::hdr.bridged_md.$valid - # - bit[2..0]: ingress::hdr.bridged_md.in_ig_port_type if ingress::hdr.bridged_md.$valid - TW26: W41(1) # ingress::hdr.ethernet.dst_addr.16-47 if ingress::hdr.ethernet.$valid - H7: W41(1) # ingress::hdr.ethernet.dst_addr.0-15 if ingress::hdr.ethernet.$valid - TW27: W41(1) # ingress::hdr.ethernet.src_addr.16-47 if ingress::hdr.ethernet.$valid - TH25: W41(1) # ingress::hdr.ethernet.src_addr.0-15 if ingress::hdr.ethernet.$valid - H5: W41(1) # ingress::hdr.ethernet.ether_type if ingress::hdr.ethernet.$valid - W5: W41(27) - # - bit[31]: ingress::hdr.fabric.pad1 if ingress::hdr.fabric.$valid - # - bit[30]: ingress::hdr.fabric.is_hit if ingress::hdr.fabric.$valid - # - bit[29]: ingress::hdr.fabric.is_to_cn78 if ingress::hdr.fabric.$valid - # - bit[28]: ingress::hdr.fabric.is_to_td3 if ingress::hdr.fabric.$valid - # - bit[27]: ingress::hdr.fabric.is_hdr_decap if ingress::hdr.fabric.$valid - # - bit[26..24]: ingress::hdr.fabric.ig_port_type if ingress::hdr.fabric.$valid - # - bit[23..18]: ingress::hdr.fabric.pad2 if ingress::hdr.fabric.$valid - # - bit[17..0]: ingress::hdr.fabric.mac_index if ingress::hdr.fabric.$valid - B4: W41(27) - # - bit[7..4]: ingress::hdr.fabric.pad4 if ingress::hdr.fabric.$valid - # - bit[3]: ingress::hdr.fabric.flags_drop if ingress::hdr.fabric.$valid - # - bit[2]: ingress::hdr.fabric.is_trunc_mir if ingress::hdr.fabric.$valid - # - bit[1..0]: ingress::hdr.fabric.count_index.16-17 if ingress::hdr.fabric.$valid - W3: W41(27) - # - bit[31..16]: ingress::hdr.fabric.count_index.0-15 if ingress::hdr.fabric.$valid - # - bit[15..0]: ingress::hdr.fabric.mc_index if ingress::hdr.fabric.$valid - W4: W41(27) - # - bit[31..16]: ingress::hdr.fabric.vlan_index if ingress::hdr.fabric.$valid - # - bit[15..0]: ingress::hdr.fabric.ether_type if ingress::hdr.fabric.$valid - H4: B2(4) - # - bit[15..13]: ingress::hdr.vlan_tag[0].pcp if ingress::hdr.vlan_tag[0].$valid - # - bit[12]: ingress::hdr.vlan_tag[0].cfi if ingress::hdr.vlan_tag[0].$valid - # - bit[11..0]: ingress::hdr.vlan_tag[0].vid if ingress::hdr.vlan_tag[0].$valid - TH4: B2(4) # ingress::hdr.vlan_tag[0].ether_type if ingress::hdr.vlan_tag[0].$valid - TH5: B2(3) - # - bit[15..13]: ingress::hdr.vlan_tag[1].pcp if ingress::hdr.vlan_tag[1].$valid - # - bit[12]: ingress::hdr.vlan_tag[1].cfi if ingress::hdr.vlan_tag[1].$valid - # - bit[11..0]: ingress::hdr.vlan_tag[1].vid if ingress::hdr.vlan_tag[1].$valid - TB3: B2(3) # ingress::hdr.vlan_tag[1].ether_type.8-15 if ingress::hdr.vlan_tag[1].$valid - TB2: B2(3) # ingress::hdr.vlan_tag[1].ether_type.0-7 if ingress::hdr.vlan_tag[1].$valid - TW8: B2(2) - # - bit[31..29]: ingress::hdr.vlan_tag[2].pcp if ingress::hdr.vlan_tag[2].$valid - # - bit[28]: ingress::hdr.vlan_tag[2].cfi if ingress::hdr.vlan_tag[2].$valid - # - bit[27..16]: ingress::hdr.vlan_tag[2].vid if ingress::hdr.vlan_tag[2].$valid - # - bit[15..0]: ingress::hdr.vlan_tag[2].ether_type if ingress::hdr.vlan_tag[2].$valid - TW9: B2(1) - # - bit[31..29]: ingress::hdr.vlan_tag[3].pcp if ingress::hdr.vlan_tag[3].$valid - # - bit[28]: ingress::hdr.vlan_tag[3].cfi if ingress::hdr.vlan_tag[3].$valid - # - bit[27..16]: ingress::hdr.vlan_tag[3].vid if ingress::hdr.vlan_tag[3].$valid - # - bit[15..0]: ingress::hdr.vlan_tag[3].ether_type if ingress::hdr.vlan_tag[3].$valid - TW10: B2(0) - # - bit[31..29]: ingress::hdr.vlan_tag[4].pcp if ingress::hdr.vlan_tag[4].$valid - # - bit[28]: ingress::hdr.vlan_tag[4].cfi if ingress::hdr.vlan_tag[4].$valid - # - bit[27..16]: ingress::hdr.vlan_tag[4].vid if ingress::hdr.vlan_tag[4].$valid - # - bit[15..0]: ingress::hdr.vlan_tag[4].ether_type if ingress::hdr.vlan_tag[4].$valid - TW11: B3(3) - # - bit[31..12]: ingress::hdr.mpls[0].label if ingress::hdr.mpls[0].$valid - # - bit[11..9]: ingress::hdr.mpls[0].exp if ingress::hdr.mpls[0].$valid - # - bit[8]: ingress::hdr.mpls[0].bos if ingress::hdr.mpls[0].$valid - # - bit[7..0]: ingress::hdr.mpls[0].ttl if ingress::hdr.mpls[0].$valid - TH13: B3(2) # ingress::hdr.mpls[1].label.4-19 if ingress::hdr.mpls[1].$valid - TH12: B3(2) - # - bit[15..12]: ingress::hdr.mpls[1].label.0-3 if ingress::hdr.mpls[1].$valid - # - bit[11..9]: ingress::hdr.mpls[1].exp if ingress::hdr.mpls[1].$valid - # - bit[8]: ingress::hdr.mpls[1].bos if ingress::hdr.mpls[1].$valid - # - bit[7..0]: ingress::hdr.mpls[1].ttl if ingress::hdr.mpls[1].$valid - TH15: B3(1) # ingress::hdr.mpls[2].label.4-19 if ingress::hdr.mpls[2].$valid - TH14: B3(1) - # - bit[15..12]: ingress::hdr.mpls[2].label.0-3 if ingress::hdr.mpls[2].$valid - # - bit[11..9]: ingress::hdr.mpls[2].exp if ingress::hdr.mpls[2].$valid - # - bit[8]: ingress::hdr.mpls[2].bos if ingress::hdr.mpls[2].$valid - # - bit[7..0]: ingress::hdr.mpls[2].ttl if ingress::hdr.mpls[2].$valid - TH17: B3(0) # ingress::hdr.mpls[3].label.4-19 if ingress::hdr.mpls[3].$valid - TH16: B3(0) - # - bit[15..12]: ingress::hdr.mpls[3].label.0-3 if ingress::hdr.mpls[3].$valid - # - bit[11..9]: ingress::hdr.mpls[3].exp if ingress::hdr.mpls[3].$valid - # - bit[8]: ingress::hdr.mpls[3].bos if ingress::hdr.mpls[3].$valid - # - bit[7..0]: ingress::hdr.mpls[3].ttl if ingress::hdr.mpls[3].$valid - TW0: W41(2) - # - bit[31..28]: ingress::hdr.ipv4.version if ingress::hdr.ipv4.$valid - # - bit[27..24]: ingress::hdr.ipv4.ihl if ingress::hdr.ipv4.$valid - # - bit[23..16]: ingress::hdr.ipv4.diffserv if ingress::hdr.ipv4.$valid - # - bit[15..0]: ingress::hdr.ipv4.total_len if ingress::hdr.ipv4.$valid - TB11: W41(2) # ingress::hdr.ipv4.identification.8-15 if ingress::hdr.ipv4.$valid - TB10: W41(2) # ingress::hdr.ipv4.identification.0-7 if ingress::hdr.ipv4.$valid - TB8: W41(2) - # - bit[7..5]: ingress::hdr.ipv4.flags if ingress::hdr.ipv4.$valid - # - bit[4..0]: ingress::hdr.ipv4.frag_offset.8-12 if ingress::hdr.ipv4.$valid - TB9: W41(2) # ingress::hdr.ipv4.frag_offset.0-7 if ingress::hdr.ipv4.$valid - TW16: W41(2) - # - bit[31..24]: ingress::hdr.ipv4.ttl if ingress::hdr.ipv4.$valid - # - bit[23..16]: ingress::hdr.ipv4.protocol if ingress::hdr.ipv4.$valid - # - bit[15..0]: ingress::hdr.ipv4.hdr_checksum if ingress::hdr.ipv4.$valid - TH36: W41(2) # ingress::hdr.ipv4.src_addr.16-31 if ingress::hdr.ipv4.$valid - TH29: W41(2) # ingress::hdr.ipv4.src_addr.0-15 if ingress::hdr.ipv4.$valid - TH38: W41(2) # ingress::hdr.ipv4.dst_addr.16-31 if ingress::hdr.ipv4.$valid - TH37: W41(2) # ingress::hdr.ipv4.dst_addr.0-15 if ingress::hdr.ipv4.$valid - TW0: W41(26) - # - bit[31..28]: ingress::hdr.ipv6.version if ingress::hdr.ipv6.$valid - # - bit[27..20]: ingress::hdr.ipv6.traffic_class if ingress::hdr.ipv6.$valid - # - bit[19..0]: ingress::hdr.ipv6.flow_label if ingress::hdr.ipv6.$valid - TW16: W41(26) - # - bit[31..16]: ingress::hdr.ipv6.payload_len if ingress::hdr.ipv6.$valid - # - bit[15..8]: ingress::hdr.ipv6.next_hdr if ingress::hdr.ipv6.$valid - # - bit[7..0]: ingress::hdr.ipv6.hop_limit if ingress::hdr.ipv6.$valid - W36: W41(26) # ingress::hdr.ipv6.src_addr.96-127 if ingress::hdr.ipv6.$valid - TB11: W41(26) # ingress::hdr.ipv6.src_addr.88-95 if ingress::hdr.ipv6.$valid - TB10: W41(26) # ingress::hdr.ipv6.src_addr.80-87 if ingress::hdr.ipv6.$valid - TB9: W41(26) # ingress::hdr.ipv6.src_addr.72-79 if ingress::hdr.ipv6.$valid - TB8: W41(26) # ingress::hdr.ipv6.src_addr.64-71 if ingress::hdr.ipv6.$valid - TH38: W41(26) # ingress::hdr.ipv6.src_addr.48-63 if ingress::hdr.ipv6.$valid - TH37: W41(26) # ingress::hdr.ipv6.src_addr.32-47 if ingress::hdr.ipv6.$valid - TH36: W41(26) # ingress::hdr.ipv6.src_addr.16-31 if ingress::hdr.ipv6.$valid - TH29: W41(26) # ingress::hdr.ipv6.src_addr.0-15 if ingress::hdr.ipv6.$valid - W40: W41(26) # ingress::hdr.ipv6.dst_addr.96-127 if ingress::hdr.ipv6.$valid - W39: W41(26) # ingress::hdr.ipv6.dst_addr.64-95 if ingress::hdr.ipv6.$valid - W38: W41(26) # ingress::hdr.ipv6.dst_addr.32-63 if ingress::hdr.ipv6.$valid - W37: W41(26) # ingress::hdr.ipv6.dst_addr.0-31 if ingress::hdr.ipv6.$valid - TW18: W41(16) - # - bit[31..16]: ingress::hdr.udp.src_port if ingress::hdr.udp.$valid - # - bit[15..0]: ingress::hdr.udp.dst_port if ingress::hdr.udp.$valid - TW19: W41(16) - # - bit[31..16]: ingress::hdr.udp.hdr_length if ingress::hdr.udp.$valid - # - bit[15..0]: ingress::hdr.udp.checksum if ingress::hdr.udp.$valid - TW18: W41(3) - # - bit[31..16]: ingress::hdr.tcp.src_port if ingress::hdr.tcp.$valid - # - bit[15..0]: ingress::hdr.tcp.dst_port if ingress::hdr.tcp.$valid - TW25: W41(3) # ingress::hdr.tcp.seq_no if ingress::hdr.tcp.$valid - TH39: W41(3) # ingress::hdr.tcp.ack_no.16-31 if ingress::hdr.tcp.$valid - TB24: W41(3) # ingress::hdr.tcp.ack_no.8-15 if ingress::hdr.tcp.$valid - TB19: W41(3) # ingress::hdr.tcp.ack_no.0-7 if ingress::hdr.tcp.$valid - TW1: W41(3) - # - bit[31..28]: ingress::hdr.tcp.data_offset if ingress::hdr.tcp.$valid - # - bit[27..24]: ingress::hdr.tcp.res if ingress::hdr.tcp.$valid - # - bit[23..16]: ingress::hdr.tcp.flags if ingress::hdr.tcp.$valid - # - bit[15..0]: ingress::hdr.tcp.window if ingress::hdr.tcp.$valid - TW19: W41(3) - # - bit[31..16]: ingress::hdr.tcp.checksum if ingress::hdr.tcp.$valid - # - bit[15..0]: ingress::hdr.tcp.urgent_ptr if ingress::hdr.tcp.$valid - TW1: W41(23) - # - bit[31..24]: ingress::hdr.icmp.type_ if ingress::hdr.icmp.$valid - # - bit[23..16]: ingress::hdr.icmp.code if ingress::hdr.icmp.$valid - # - bit[15..0]: ingress::hdr.icmp.hdr_checksum if ingress::hdr.icmp.$valid - TW1: W41(24) - # - bit[31..16]: ingress::hdr.sctp.src_port if ingress::hdr.sctp.$valid - # - bit[15..0]: ingress::hdr.sctp.dst_port if ingress::hdr.sctp.$valid - TW2: W41(24) # ingress::hdr.sctp.verifTag if ingress::hdr.sctp.$valid - TH0: W41(24) # ingress::hdr.sctp.checksum if ingress::hdr.sctp.$valid - TW1: W41(21) - # - bit[31..20]: ingress::hdr.l2tp.TLxxSxOP if ingress::hdr.l2tp.$valid - # - bit[19..16]: ingress::hdr.l2tp.version if ingress::hdr.l2tp.$valid - # - bit[15..8]: ingress::hdr.l2tp.l2tp_length if ingress::hdr.l2tp.$valid - # - bit[7..0]: ingress::hdr.l2tp.tunnel_id.8-15 if ingress::hdr.l2tp.$valid - TB0: W41(21) # ingress::hdr.l2tp.tunnel_id.0-7 if ingress::hdr.l2tp.$valid - TH26: W41(21) # ingress::hdr.l2tp.session_id if ingress::hdr.l2tp.$valid - TB19: W41(21) # ingress::hdr.l2tp.Ns.8-15 if ingress::hdr.l2tp.$valid - TB18: W41(21) # ingress::hdr.l2tp.Ns.0-7 if ingress::hdr.l2tp.$valid - TH0: W41(21) # ingress::hdr.l2tp.Nr if ingress::hdr.l2tp.$valid - TB17: W41(21) # ingress::hdr.l2tp.offset_size if ingress::hdr.l2tp.$valid - TB1: W41(21) # ingress::hdr.l2tp.offset_pad if ingress::hdr.l2tp.$valid - TH1: W41(22) - # - bit[15..12]: ingress::hdr.pppoe.version if ingress::hdr.pppoe.$valid - # - bit[11..8]: ingress::hdr.pppoe.type if ingress::hdr.pppoe.$valid - # - bit[7..0]: ingress::hdr.pppoe.code if ingress::hdr.pppoe.$valid - TH2: W41(22) # ingress::hdr.pppoe.session_id if ingress::hdr.pppoe.$valid - TW25: W41(22) - # - bit[31..16]: ingress::hdr.pppoe.pppoe_length if ingress::hdr.pppoe.$valid - # - bit[15..0]: ingress::hdr.pppoe.ppp_proto if ingress::hdr.pppoe.$valid - TH1: W41(22) - # - bit[15..12]: ingress::hdr.pppoe.version if ingress::hdr.pppoe.$valid - # - bit[11..8]: ingress::hdr.pppoe.type if ingress::hdr.pppoe.$valid - # - bit[7..0]: ingress::hdr.pppoe.code if ingress::hdr.pppoe.$valid - TH2: W41(22) # ingress::hdr.pppoe.session_id if ingress::hdr.pppoe.$valid - TW25: W41(22) - # - bit[31..16]: ingress::hdr.pppoe.pppoe_length if ingress::hdr.pppoe.$valid - # - bit[15..0]: ingress::hdr.pppoe.ppp_proto if ingress::hdr.pppoe.$valid - TH0: W41(25) - # - bit[15]: ingress::hdr.gre.C if ingress::hdr.gre.$valid - # - bit[14]: ingress::hdr.gre.R if ingress::hdr.gre.$valid - # - bit[13]: ingress::hdr.gre.K if ingress::hdr.gre.$valid - # - bit[12]: ingress::hdr.gre.S if ingress::hdr.gre.$valid - # - bit[11]: ingress::hdr.gre.s if ingress::hdr.gre.$valid - # - bit[10..8]: ingress::hdr.gre.recurse if ingress::hdr.gre.$valid - # - bit[7..3]: ingress::hdr.gre.flags if ingress::hdr.gre.$valid - # - bit[2..0]: ingress::hdr.gre.version if ingress::hdr.gre.$valid - TB1: W41(25) # ingress::hdr.gre.proto.8-15 if ingress::hdr.gre.$valid - TB0: W41(25) # ingress::hdr.gre.proto.0-7 if ingress::hdr.gre.$valid - TH0: W41(19) - # - bit[15..13]: ingress::hdr.gtpv1_8b.version if ingress::hdr.gtpv1_8b.$valid - # - bit[12]: ingress::hdr.gtpv1_8b.pt if ingress::hdr.gtpv1_8b.$valid - # - bit[11]: ingress::hdr.gtpv1_8b.reserved if ingress::hdr.gtpv1_8b.$valid - # - bit[10]: ingress::hdr.gtpv1_8b.e if ingress::hdr.gtpv1_8b.$valid - # - bit[9]: ingress::hdr.gtpv1_8b.s if ingress::hdr.gtpv1_8b.$valid - # - bit[8]: ingress::hdr.gtpv1_8b.pn if ingress::hdr.gtpv1_8b.$valid - # - bit[7..0]: ingress::hdr.gtpv1_8b.message_type if ingress::hdr.gtpv1_8b.$valid - TH1: W41(19) # ingress::hdr.gtpv1_8b.message_len if ingress::hdr.gtpv1_8b.$valid - TW1: W41(19) # ingress::hdr.gtpv1_8b.teid if ingress::hdr.gtpv1_8b.$valid - TH0: W41(20) - # - bit[15..13]: ingress::hdr.gtpv1_12b.version if ingress::hdr.gtpv1_12b.$valid - # - bit[12]: ingress::hdr.gtpv1_12b.pt if ingress::hdr.gtpv1_12b.$valid - # - bit[11]: ingress::hdr.gtpv1_12b.reserved if ingress::hdr.gtpv1_12b.$valid - # - bit[10]: ingress::hdr.gtpv1_12b.e if ingress::hdr.gtpv1_12b.$valid - # - bit[9]: ingress::hdr.gtpv1_12b.s if ingress::hdr.gtpv1_12b.$valid - # - bit[8]: ingress::hdr.gtpv1_12b.pn if ingress::hdr.gtpv1_12b.$valid - # - bit[7..0]: ingress::hdr.gtpv1_12b.message_type if ingress::hdr.gtpv1_12b.$valid - TH1: W41(20) # ingress::hdr.gtpv1_12b.message_len if ingress::hdr.gtpv1_12b.$valid - TW25: W41(20) # ingress::hdr.gtpv1_12b.teid if ingress::hdr.gtpv1_12b.$valid - TW1: W41(20) - # - bit[31..16]: ingress::hdr.gtpv1_12b.seq_no if ingress::hdr.gtpv1_12b.$valid - # - bit[15..8]: ingress::hdr.gtpv1_12b.n_pdu_no if ingress::hdr.gtpv1_12b.$valid - # - bit[7..0]: ingress::hdr.gtpv1_12b.next_ex_hdr_t if ingress::hdr.gtpv1_12b.$valid - TH0: W41(4) - # - bit[15..13]: ingress::hdr.gtpv2_8b.version if ingress::hdr.gtpv2_8b.$valid - # - bit[12]: ingress::hdr.gtpv2_8b.pb if ingress::hdr.gtpv2_8b.$valid - # - bit[11]: ingress::hdr.gtpv2_8b.tf if ingress::hdr.gtpv2_8b.$valid - # - bit[10..8]: ingress::hdr.gtpv2_8b.spare1 if ingress::hdr.gtpv2_8b.$valid - # - bit[7..0]: ingress::hdr.gtpv2_8b.message_type if ingress::hdr.gtpv2_8b.$valid - TH1: W41(4) # ingress::hdr.gtpv2_8b.total_len if ingress::hdr.gtpv2_8b.$valid - TH26: W41(4) # ingress::hdr.gtpv2_8b.seq_no.8-23 if ingress::hdr.gtpv2_8b.$valid - TB18: W41(4) # ingress::hdr.gtpv2_8b.seq_no.0-7 if ingress::hdr.gtpv2_8b.$valid - TB17: W41(4) # ingress::hdr.gtpv2_8b.spare2 if ingress::hdr.gtpv2_8b.$valid - TH0: W41(15) - # - bit[15..13]: ingress::hdr.gtpv2_12b.version if ingress::hdr.gtpv2_12b.$valid - # - bit[12]: ingress::hdr.gtpv2_12b.pb if ingress::hdr.gtpv2_12b.$valid - # - bit[11]: ingress::hdr.gtpv2_12b.tf if ingress::hdr.gtpv2_12b.$valid - # - bit[10..8]: ingress::hdr.gtpv2_12b.spare1 if ingress::hdr.gtpv2_12b.$valid - # - bit[7..0]: ingress::hdr.gtpv2_12b.message_type if ingress::hdr.gtpv2_12b.$valid - TH1: W41(15) # ingress::hdr.gtpv2_12b.total_len if ingress::hdr.gtpv2_12b.$valid - W35: W41(15) # ingress::hdr.gtpv2_12b.teid if ingress::hdr.gtpv2_12b.$valid - TH26: W41(15) # ingress::hdr.gtpv2_12b.seq_no.8-23 if ingress::hdr.gtpv2_12b.$valid - TB18: W41(15) # ingress::hdr.gtpv2_12b.seq_no.0-7 if ingress::hdr.gtpv2_12b.$valid - TB17: W41(15) # ingress::hdr.gtpv2_12b.spare2 if ingress::hdr.gtpv2_12b.$valid - TB1: W41(6) # ingress::hdr.cause_ie_6b.type if ingress::hdr.cause_ie_6b.$valid - TW3: W41(6) - # - bit[31..16]: ingress::hdr.cause_ie_6b.len if ingress::hdr.cause_ie_6b.$valid - # - bit[15..12]: ingress::hdr.cause_ie_6b.spare1 if ingress::hdr.cause_ie_6b.$valid - # - bit[11..8]: ingress::hdr.cause_ie_6b.instance if ingress::hdr.cause_ie_6b.$valid - # - bit[7..0]: ingress::hdr.cause_ie_6b.cause_value if ingress::hdr.cause_ie_6b.$valid - TB0: W41(6) - # - bit[7..3]: ingress::hdr.cause_ie_6b.spare2 if ingress::hdr.cause_ie_6b.$valid - # - bit[2]: ingress::hdr.cause_ie_6b.pce if ingress::hdr.cause_ie_6b.$valid - # - bit[1]: ingress::hdr.cause_ie_6b.bce if ingress::hdr.cause_ie_6b.$valid - # - bit[0]: ingress::hdr.cause_ie_6b.cs if ingress::hdr.cause_ie_6b.$valid - TB1: W41(7) # ingress::hdr.cause_ie_10b.type if ingress::hdr.cause_ie_10b.$valid - TW3: W41(7) - # - bit[31..16]: ingress::hdr.cause_ie_10b.len if ingress::hdr.cause_ie_10b.$valid - # - bit[15..12]: ingress::hdr.cause_ie_10b.spare1 if ingress::hdr.cause_ie_10b.$valid - # - bit[11..8]: ingress::hdr.cause_ie_10b.instance if ingress::hdr.cause_ie_10b.$valid - # - bit[7..0]: ingress::hdr.cause_ie_10b.cause_value if ingress::hdr.cause_ie_10b.$valid - TB0: W41(7) - # - bit[7..3]: ingress::hdr.cause_ie_10b.spare2 if ingress::hdr.cause_ie_10b.$valid - # - bit[2]: ingress::hdr.cause_ie_10b.pce if ingress::hdr.cause_ie_10b.$valid - # - bit[1]: ingress::hdr.cause_ie_10b.bce if ingress::hdr.cause_ie_10b.$valid - # - bit[0]: ingress::hdr.cause_ie_10b.cs if ingress::hdr.cause_ie_10b.$valid - TH3: W41(7) - # - bit[15..8]: ingress::hdr.cause_ie_10b.type_oe if ingress::hdr.cause_ie_10b.$valid - # - bit[7..0]: ingress::hdr.cause_ie_10b.len_oe.8-15 if ingress::hdr.cause_ie_10b.$valid - TH2: W41(7) - # - bit[15..8]: ingress::hdr.cause_ie_10b.len_oe.0-7 if ingress::hdr.cause_ie_10b.$valid - # - bit[7..4]: ingress::hdr.cause_ie_10b.spare_oe if ingress::hdr.cause_ie_10b.$valid - # - bit[3..0]: ingress::hdr.cause_ie_10b.instance_oe if ingress::hdr.cause_ie_10b.$valid - TW2: W41(5) - # - bit[31..24]: ingress::hdr.imsi.type if ingress::hdr.imsi.$valid - # - bit[23..8]: ingress::hdr.imsi.len if ingress::hdr.imsi.$valid - # - bit[7..4]: ingress::hdr.imsi.spare if ingress::hdr.imsi.$valid - # - bit[3..0]: ingress::hdr.imsi.instance if ingress::hdr.imsi.$valid - TH28: W41(5) # ingress::hdr.imsi.num_digit.112-127 if ingress::hdr.imsi.$valid - TB25: W41(5) # ingress::hdr.imsi.num_digit.104-111 if ingress::hdr.imsi.$valid - TB16: W41(5) # ingress::hdr.imsi.num_digit.96-103 if ingress::hdr.imsi.$valid - TH27: W41(5) # ingress::hdr.imsi.num_digit.80-95 if ingress::hdr.imsi.$valid - TH24: W41(5) # ingress::hdr.imsi.num_digit.64-79 if ingress::hdr.imsi.$valid - TW24: W41(5) # ingress::hdr.imsi.num_digit.32-63 if ingress::hdr.imsi.$valid - TW17: W41(5) # ingress::hdr.imsi.num_digit.0-31 if ingress::hdr.imsi.$valid - TW1: W41(17) - # - bit[31..24]: ingress::hdr.vxlan.flags if ingress::hdr.vxlan.$valid - # - bit[23..0]: ingress::hdr.vxlan.reserved if ingress::hdr.vxlan.$valid - TH1: W41(17) # ingress::hdr.vxlan.vni.8-23 if ingress::hdr.vxlan.$valid - TH0: W41(17) - # - bit[15..8]: ingress::hdr.vxlan.vni.0-7 if ingress::hdr.vxlan.$valid - # - bit[7..0]: ingress::hdr.vxlan.reserved2 if ingress::hdr.vxlan.$valid - TW25: W41(18) # ingress::hdr.inner_ethernet.dst_addr.16-47 if ingress::hdr.inner_ethernet.$valid - TB18: W41(18) # ingress::hdr.inner_ethernet.dst_addr.8-15 if ingress::hdr.inner_ethernet.$valid - TB17: W41(18) # ingress::hdr.inner_ethernet.dst_addr.0-7 if ingress::hdr.inner_ethernet.$valid - TH39: W41(18) # ingress::hdr.inner_ethernet.src_addr.32-47 if ingress::hdr.inner_ethernet.$valid - TB1: W41(18) # ingress::hdr.inner_ethernet.src_addr.24-31 if ingress::hdr.inner_ethernet.$valid - TB0: W41(18) # ingress::hdr.inner_ethernet.src_addr.16-23 if ingress::hdr.inner_ethernet.$valid - TH26: W41(18) # ingress::hdr.inner_ethernet.src_addr.0-15 if ingress::hdr.inner_ethernet.$valid - TH2: W41(18) # ingress::hdr.inner_ethernet.ether_type if ingress::hdr.inner_ethernet.$valid - TW2: W41(8) - # - bit[31..28]: ingress::hdr.inner_ipv4.version if ingress::hdr.inner_ipv4.$valid - # - bit[27..24]: ingress::hdr.inner_ipv4.ihl if ingress::hdr.inner_ipv4.$valid - # - bit[23..16]: ingress::hdr.inner_ipv4.diffserv if ingress::hdr.inner_ipv4.$valid - # - bit[15..0]: ingress::hdr.inner_ipv4.total_len if ingress::hdr.inner_ipv4.$valid - TH24: W41(8) # ingress::hdr.inner_ipv4.identification if ingress::hdr.inner_ipv4.$valid - TH3: W41(8) - # - bit[15..13]: ingress::hdr.inner_ipv4.flags if ingress::hdr.inner_ipv4.$valid - # - bit[12..0]: ingress::hdr.inner_ipv4.frag_offset if ingress::hdr.inner_ipv4.$valid - TW17: W41(8) - # - bit[31..24]: ingress::hdr.inner_ipv4.ttl if ingress::hdr.inner_ipv4.$valid - # - bit[23..16]: ingress::hdr.inner_ipv4.protocol if ingress::hdr.inner_ipv4.$valid - # - bit[15..0]: ingress::hdr.inner_ipv4.hdr_checksum if ingress::hdr.inner_ipv4.$valid - TH40: W41(8) # ingress::hdr.inner_ipv4.src_addr.16-31 if ingress::hdr.inner_ipv4.$valid - TB25: W41(8) # ingress::hdr.inner_ipv4.src_addr.8-15 if ingress::hdr.inner_ipv4.$valid - TB16: W41(8) # ingress::hdr.inner_ipv4.src_addr.0-7 if ingress::hdr.inner_ipv4.$valid - TH41: W41(8) # ingress::hdr.inner_ipv4.dst_addr.16-31 if ingress::hdr.inner_ipv4.$valid - TB27: W41(8) # ingress::hdr.inner_ipv4.dst_addr.8-15 if ingress::hdr.inner_ipv4.$valid - TB26: W41(8) # ingress::hdr.inner_ipv4.dst_addr.0-7 if ingress::hdr.inner_ipv4.$valid - TW2: W41(14) - # - bit[31..28]: ingress::hdr.inner_ipv6.version if ingress::hdr.inner_ipv6.$valid - # - bit[27..20]: ingress::hdr.inner_ipv6.traffic_class if ingress::hdr.inner_ipv6.$valid - # - bit[19..0]: ingress::hdr.inner_ipv6.flow_label if ingress::hdr.inner_ipv6.$valid - TH3: W41(14) # ingress::hdr.inner_ipv6.payload_len if ingress::hdr.inner_ipv6.$valid - B8: W41(14) # ingress::hdr.inner_ipv6.next_hdr if ingress::hdr.inner_ipv6.$valid - TB16: W41(14) # ingress::hdr.inner_ipv6.hop_limit if ingress::hdr.inner_ipv6.$valid - W14: W41(14) # ingress::hdr.inner_ipv6.src_addr.96-127 if ingress::hdr.inner_ipv6.$valid - W13: W41(14) # ingress::hdr.inner_ipv6.src_addr.64-95 if ingress::hdr.inner_ipv6.$valid - W12: W41(14) # ingress::hdr.inner_ipv6.src_addr.32-63 if ingress::hdr.inner_ipv6.$valid - W11: W41(14) # ingress::hdr.inner_ipv6.src_addr.0-31 if ingress::hdr.inner_ipv6.$valid - W34: W41(14) # ingress::hdr.inner_ipv6.dst_addr.96-127 if ingress::hdr.inner_ipv6.$valid - W33: W41(14) # ingress::hdr.inner_ipv6.dst_addr.64-95 if ingress::hdr.inner_ipv6.$valid - W32: W41(14) # ingress::hdr.inner_ipv6.dst_addr.32-63 if ingress::hdr.inner_ipv6.$valid - W15: W41(14) # ingress::hdr.inner_ipv6.dst_addr.0-31 if ingress::hdr.inner_ipv6.$valid - TW3: W41(11) - # - bit[31..16]: ingress::hdr.inner_udp.src_port if ingress::hdr.inner_udp.$valid - # - bit[15..0]: ingress::hdr.inner_udp.dst_port if ingress::hdr.inner_udp.$valid - TW24: W41(11) - # - bit[31..16]: ingress::hdr.inner_udp.hdr_length if ingress::hdr.inner_udp.$valid - # - bit[15..0]: ingress::hdr.inner_udp.checksum if ingress::hdr.inner_udp.$valid - TH28: W41(9) # ingress::hdr.inner_tcp.src_port if ingress::hdr.inner_tcp.$valid - TH27: W41(9) # ingress::hdr.inner_tcp.dst_port if ingress::hdr.inner_tcp.$valid - W6: W41(9) # ingress::hdr.inner_tcp.seq_no if ingress::hdr.inner_tcp.$valid - W7: W41(9) # ingress::hdr.inner_tcp.ack_no if ingress::hdr.inner_tcp.$valid - TW3: W41(9) - # - bit[31..28]: ingress::hdr.inner_tcp.data_offset if ingress::hdr.inner_tcp.$valid - # - bit[27..24]: ingress::hdr.inner_tcp.res if ingress::hdr.inner_tcp.$valid - # - bit[23..16]: ingress::hdr.inner_tcp.flags if ingress::hdr.inner_tcp.$valid - # - bit[15..0]: ingress::hdr.inner_tcp.window if ingress::hdr.inner_tcp.$valid - TW24: W41(9) - # - bit[31..16]: ingress::hdr.inner_tcp.checksum if ingress::hdr.inner_tcp.$valid - # - bit[15..0]: ingress::hdr.inner_tcp.urgent_ptr if ingress::hdr.inner_tcp.$valid - TW3: W41(12) - # - bit[31..24]: ingress::hdr.inner_icmp.type_ if ingress::hdr.inner_icmp.$valid - # - bit[23..16]: ingress::hdr.inner_icmp.code if ingress::hdr.inner_icmp.$valid - # - bit[15..0]: ingress::hdr.inner_icmp.hdr_checksum if ingress::hdr.inner_icmp.$valid - W9: W41(13) # ingress::hdr.ipsec_esp.spi if ingress::hdr.ipsec_esp.$valid - W10: W41(13) # ingress::hdr.ipsec_esp.sn if ingress::hdr.ipsec_esp.$valid - W8: W41(10) # ingress::hdr.sip.data if ingress::hdr.sip.$valid - egress_unicast_port: H1(0..8) # bit[8..0]: ingress::ig_intr_md_for_tm.ucast_egress_port - bypss_egr: B2(5..5) # bit[5]: ingress::ig_intr_md_for_tm.bypass_egress - drop_ctl: B3(4..6) # bit[6..4]: ingress::ig_intr_md_for_dprsr.drop_ctl - egress_multicast_group_1: - - H0 # ingress::ig_intr_md_for_tm.mcast_grp_b - hash_lag_ecmp_mcast_0: - - W0(0..12) # bit[12..0]: ingress::ig_intr_md_for_tm.level1_mcast_hash - hash_lag_ecmp_mcast_1: - - W1(0..12) # bit[12..0]: ingress::ig_intr_md_for_tm.level2_mcast_hash - mirror: - select: B1(0..2) # bit[2..0]: ingress::ig_intr_md_for_dprsr.mirror_type - 5: - - H2(0..9) # bit[9..0]: ingress::ig_md.mirror.session_id - - B9 # ingress::ig_md.mirror.src - - B10 # ingress::ig_md.mirror.type - - H2(0..9) # bit[9..0]: ingress::ig_md.mirror.session_id - - H6(0..9) # bit[9..0]: ingress::ig_md.count_index.8-17 - - B5 # ingress::ig_md.count_index.0-7 - - H8 # ingress::ig_md.vlan_index -parser egress: - start: $entry_point - init_zero: [ H25, H26, B20, W48, B17, B16 ] - bitwise_or: [ B16, B17, W48 ] - hdr_len_adj: 27 - meta_opt: 8191 - states: - $entry_point: - *: - load: { byte1 : 27 } - buf_req: 28 - next: start - start: - match: [ byte1 ] - 0x00: - 0..1: H16 # bit[7..15] -> H16 bit[8..0]: egress::eg_intr_md.egress_port - shift: 27 - buf_req: 27 - next: parse_bridged_metadata - 0x01: - 0..1: H16 # bit[7..15] -> H16 bit[8..0]: egress::eg_intr_md.egress_port - shift: 27 - buf_req: 27 - next: parse_truncate_only_metadata - 0x**: - 0..1: H16 # bit[7..15] -> H16 bit[8..0]: egress::eg_intr_md.egress_port - shift: 27 - buf_req: 27 - next: end - parse_bridged_metadata: - *: - 1..2: H23 - # - bit[8..15] -> H23 bit[15..8]: egress::eg_md.pkt_proto_type - # - bit[16..23] -> H23 bit[7..0]: egress::eg_md.ip_hdr_location - 4: B20 # bit[37..39] -> B20 bit[2..0]: egress::eg_md.in_ig_port_type - shift: 5 - buf_req: 5 - next: parse_ethernet - parse_ethernet: - *: - 0..3: TW31 # egress::hdr.ethernet.dst_addr[47:16].16-47 - 4..5: H24 # egress::hdr.ethernet.dst_addr[15:0].0-15 - 6..7: TH42 # egress::hdr.ethernet.src_addr[47:32].32-47 - 8..9: TH35 # egress::hdr.ethernet.src_addr[31:16].16-31 - 10..11: TH6 # egress::hdr.ethernet.src_addr[15:0].0-15 - W48: 2 # value 1 -> W48 bit[1]: egress::hdr.ethernet.$valid - load: { half : 12..13 } - shift: 12 - buf_req: 14 - next: parse_ethernet.$split_0 - parse_ethernet.$split_0: - match: [ half ] - 0x0800: - 0..1: H19 # egress::hdr.ethernet.ether_type - shift: 2 - buf_req: 2 - next: parse_ipv4 - 0x86dd: - 0..1: H19 # egress::hdr.ethernet.ether_type - shift: 2 - buf_req: 2 - next: parse_ipv6 - 0x8100: - 0..1: H19 # egress::hdr.ethernet.ether_type - load: { half : 4..5 } - shift: 2 - buf_req: 6 - next: parse_vlan - 0x8847: - 0..1: H19 # egress::hdr.ethernet.ether_type - load: { byte1 : 4 } - shift: 2 - buf_req: 5 - next: parse_mpls - 0x81fe: - 0..1: H19 # egress::hdr.ethernet.ether_type - load: { half : 13..14 } - shift: 2 - buf_req: 15 - next: parse_fabric - 0x****: - 0..1: H19 # egress::hdr.ethernet.ether_type - shift: 2 - buf_req: 2 - next: end - parse_ipv4: - *: - 0..3: TW4 - # - bit[0..3] -> TW4 bit[31..28]: egress::hdr.ipv4.version - # - bit[4..7] -> TW4 bit[27..24]: egress::hdr.ipv4.ihl - # - bit[8..15] -> TW4 bit[23..16]: egress::hdr.ipv4.diffserv - # - bit[16..31] -> TW4 bit[15..0]: egress::hdr.ipv4.total_len - 4..7: TW20 - # - bit[32..47] -> TW20 bit[31..16]: egress::hdr.ipv4.identification - # - bit[48..50] -> TW20 bit[15..13]: egress::hdr.ipv4.flags - # - bit[51..63] -> TW20 bit[12..0]: egress::hdr.ipv4.frag_offset - 8..9: TH31 - # - bit[64..71] -> TH31 bit[15..8]: egress::hdr.ipv4.ttl - # - bit[72..79] -> TH31 bit[7..0]: egress::hdr.ipv4.protocol - 8..11: TW22 # bit[80..95] -> TW22 bit[15..0]: egress::hdr.ipv4.hdr_checksum - 12..13: TH44 # egress::hdr.ipv4.src_addr[31:16].16-31 - 14..15: TH43 # egress::hdr.ipv4.src_addr[15:0].0-15 - 16..17: TH46 # egress::hdr.ipv4.dst_addr[31:16].16-31 - W48: 4 # value 1 -> W48 bit[2]: egress::hdr.ipv4.$valid - load: { byte1 : 9 } - shift: 18 - buf_req: 18 - next: parse_ipv4.$split_0 - parse_ipv4.$split_0: - match: [ byte1 ] - 0x06: - 0..1: TH45 # egress::hdr.ipv4.dst_addr[15:0].0-15 - load: { half : 4..5 } - shift: 2 - buf_req: 6 - next: parse_tcp - 0x11: - 0..1: TH45 # egress::hdr.ipv4.dst_addr[15:0].0-15 - load: { half : 4..5 } - shift: 2 - buf_req: 6 - next: parse_udp - 0x01: - 0..1: TH45 # egress::hdr.ipv4.dst_addr[15:0].0-15 - shift: 2 - buf_req: 2 - next: parse_icmp - 0x84: - 0..1: TH45 # egress::hdr.ipv4.dst_addr[15:0].0-15 - load: { half : 4..5 } - shift: 2 - buf_req: 6 - next: parse_sctp - 0x29: - 0..1: TH45 # egress::hdr.ipv4.dst_addr[15:0].0-15 - shift: 2 - buf_req: 2 - next: parse_inner_ipv6 - 0x04: - 0..1: TH45 # egress::hdr.ipv4.dst_addr[15:0].0-15 - load: { byte1 : 11 } - shift: 2 - buf_req: 12 - next: parse_inner_ipv4 - 0x2f: - 0..1: TH45 # egress::hdr.ipv4.dst_addr[15:0].0-15 - load: { half : 3..4, byte0 : 5 } - shift: 2 - buf_req: 6 - next: parse_gre - 0x**: - 0..1: TH45 # egress::hdr.ipv4.dst_addr[15:0].0-15 - shift: 2 - buf_req: 2 - next: end - parse_tcp: - match: [ half ] - 0x01bb: - 0..3: TW23 - # - bit[0..15] -> TW23 bit[31..16]: egress::hdr.tcp.src_port - # - bit[16..31] -> TW23 bit[15..0]: egress::hdr.tcp.dst_port - 4..7: TW30 # egress::hdr.tcp.seq_no - 8..9: TH47 # egress::hdr.tcp.ack_no[31:16].16-31 - 10: TB28 # egress::hdr.tcp.ack_no[15:8].8-15 - 11: TB23 # egress::hdr.tcp.ack_no[7:0].0-7 - 12..15: TW5 - # - bit[96..99] -> TW5 bit[31..28]: egress::hdr.tcp.data_offset - # - bit[100..103] -> TW5 bit[27..24]: egress::hdr.tcp.res - # - bit[104..111] -> TW5 bit[23..16]: egress::hdr.tcp.flags - # - bit[112..127] -> TW5 bit[15..0]: egress::hdr.tcp.window - 16..17: TH32 # egress::hdr.tcp.checksum - 18: TB22 # egress::hdr.tcp.urgent_ptr[15:8].8-15 - 19: TB21 # egress::hdr.tcp.urgent_ptr[7:0].0-7 - W48: 8 # value 1 -> W48 bit[3]: egress::hdr.tcp.$valid - shift: 20 - buf_req: 20 - next: end - 0x084b: - 0..3: TW23 - # - bit[0..15] -> TW23 bit[31..16]: egress::hdr.tcp.src_port - # - bit[16..31] -> TW23 bit[15..0]: egress::hdr.tcp.dst_port - 4..7: TW30 # egress::hdr.tcp.seq_no - 8..9: TH47 # egress::hdr.tcp.ack_no[31:16].16-31 - 10: TB28 # egress::hdr.tcp.ack_no[15:8].8-15 - 11: TB23 # egress::hdr.tcp.ack_no[7:0].0-7 - 12..15: TW5 - # - bit[96..99] -> TW5 bit[31..28]: egress::hdr.tcp.data_offset - # - bit[100..103] -> TW5 bit[27..24]: egress::hdr.tcp.res - # - bit[104..111] -> TW5 bit[23..16]: egress::hdr.tcp.flags - # - bit[112..127] -> TW5 bit[15..0]: egress::hdr.tcp.window - 16..17: TH32 # egress::hdr.tcp.checksum - 18: TB22 # egress::hdr.tcp.urgent_ptr[15:8].8-15 - 19: TB21 # egress::hdr.tcp.urgent_ptr[7:0].0-7 - W48: 8 # value 1 -> W48 bit[3]: egress::hdr.tcp.$valid - load: { byte1 : 20 } - shift: 20 - buf_req: 21 - next: parse_gtpv2 - 0x****: - 0..3: TW23 - # - bit[0..15] -> TW23 bit[31..16]: egress::hdr.tcp.src_port - # - bit[16..31] -> TW23 bit[15..0]: egress::hdr.tcp.dst_port - 4..7: TW30 # egress::hdr.tcp.seq_no - 8..9: TH47 # egress::hdr.tcp.ack_no[31:16].16-31 - 10: TB28 # egress::hdr.tcp.ack_no[15:8].8-15 - 11: TB23 # egress::hdr.tcp.ack_no[7:0].0-7 - 12..15: TW5 - # - bit[96..99] -> TW5 bit[31..28]: egress::hdr.tcp.data_offset - # - bit[100..103] -> TW5 bit[27..24]: egress::hdr.tcp.res - # - bit[104..111] -> TW5 bit[23..16]: egress::hdr.tcp.flags - # - bit[112..127] -> TW5 bit[15..0]: egress::hdr.tcp.window - 16..17: TH32 # egress::hdr.tcp.checksum - 18: TB22 # egress::hdr.tcp.urgent_ptr[15:8].8-15 - 19: TB21 # egress::hdr.tcp.urgent_ptr[7:0].0-7 - W48: 8 # value 1 -> W48 bit[3]: egress::hdr.tcp.$valid - shift: 20 - buf_req: 20 - next: end - parse_gtpv2: - match: [ byte1 ] - 0b***0****: - load: { byte1 : 1 } - buf_req: 2 - next: parse_gtpv2_8b - 0b***1****: - load: { byte1 : 1 } - buf_req: 2 - next: parse_gtpv2_12b - 0x**: - buf_req: 0 - next: end - parse_gtpv2_8b: - match: [ byte1 ] - 0x20: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type - 2..3: TH9 # egress::hdr.gtpv2_8b.total_len - 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6..7: TH33 - # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 - # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 - W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x26: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type - 2..3: TH9 # egress::hdr.gtpv2_8b.total_len - 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6..7: TH33 - # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 - # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 - W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x27: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type - 2..3: TH9 # egress::hdr.gtpv2_8b.total_len - 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6..7: TH33 - # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 - # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 - W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x47: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type - 2..3: TH9 # egress::hdr.gtpv2_8b.total_len - 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6..7: TH33 - # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 - # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 - W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x67: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type - 2..3: TH9 # egress::hdr.gtpv2_8b.total_len - 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6..7: TH33 - # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 - # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 - W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x85: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type - 2..3: TH9 # egress::hdr.gtpv2_8b.total_len - 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6..7: TH33 - # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 - # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 - W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x88: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type - 2..3: TH9 # egress::hdr.gtpv2_8b.total_len - 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6..7: TH33 - # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 - # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 - W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x97: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type - 2..3: TH9 # egress::hdr.gtpv2_8b.total_len - 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6..7: TH33 - # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 - # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 - W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x9f: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type - 2..3: TH9 # egress::hdr.gtpv2_8b.total_len - 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6..7: TH33 - # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 - # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 - W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0xa2: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type - 2..3: TH9 # egress::hdr.gtpv2_8b.total_len - 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6..7: TH33 - # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 - # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 - W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0xa4: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type - 2..3: TH9 # egress::hdr.gtpv2_8b.total_len - 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6..7: TH33 - # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 - # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 - W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0xa6: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type - 2..3: TH9 # egress::hdr.gtpv2_8b.total_len - 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6..7: TH33 - # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 - # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 - W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x68: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type - 2..3: TH9 # egress::hdr.gtpv2_8b.total_len - 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6..7: TH33 - # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 - # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 - W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x82: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type - 2..3: TH9 # egress::hdr.gtpv2_8b.total_len - 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6..7: TH33 - # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 - # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 - W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0xff: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type - 2..3: TH9 # egress::hdr.gtpv2_8b.total_len - 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6..7: TH33 - # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 - # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 - W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid - load: { byte1 : 8 } - shift: 8 - buf_req: 9 - next: parse_volte - 0x**: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_8b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_8b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_8b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_8b.message_type - 2..3: TH9 # egress::hdr.gtpv2_8b.total_len - 4..5: TH34 # egress::hdr.gtpv2_8b.seq_no[23:8].8-23 - 6..7: TH33 - # - bit[48..55] -> TH33 bit[15..8]: egress::hdr.gtpv2_8b.seq_no[7:0].0-7 - # - bit[56..63] -> TH33 bit[7..0]: egress::hdr.gtpv2_8b.spare2 - W48: 16 # value 1 -> W48 bit[4]: egress::hdr.gtpv2_8b.$valid - shift: 8 - buf_req: 8 - next: end - parse_gtp_base: - match: [ half, byte0 ] - 0x01****: - 0..3: TW6 - # - bit[0..7] -> TW6 bit[31..24]: egress::hdr.imsi.type - # - bit[8..23] -> TW6 bit[23..8]: egress::hdr.imsi.len - # - bit[24..27] -> TW6 bit[7..4]: egress::hdr.imsi.spare - # - bit[28..31] -> TW6 bit[3..0]: egress::hdr.imsi.instance - 4..5: TH30 # egress::hdr.imsi.num_digit[127:112].112-127 - 6: TB29 # egress::hdr.imsi.num_digit[111:104].104-111 - 7: TB20 # egress::hdr.imsi.num_digit[103:96].96-103 - 8..11: TW29 # egress::hdr.imsi.num_digit[95:64].64-95 - 12..15: TW28 # egress::hdr.imsi.num_digit[63:32].32-63 - 16..19: TW21 # egress::hdr.imsi.num_digit[31:0].0-31 - W48: 32 # value 1 -> W48 bit[5]: egress::hdr.imsi.$valid - shift: 20 - buf_req: 20 - next: end - 0x020002: - 0: TB5 # egress::hdr.cause_ie_6b.type - 1..4: TW7 - # - bit[8..23] -> TW7 bit[31..16]: egress::hdr.cause_ie_6b.len - # - bit[24..27] -> TW7 bit[15..12]: egress::hdr.cause_ie_6b.spare1 - # - bit[28..31] -> TW7 bit[11..8]: egress::hdr.cause_ie_6b.instance - # - bit[32..39] -> TW7 bit[7..0]: egress::hdr.cause_ie_6b.cause_value - 5: TB4 - # - bit[40..44] -> TB4 bit[7..3]: egress::hdr.cause_ie_6b.spare2 - # - bit[45] -> TB4 bit[2]: egress::hdr.cause_ie_6b.pce - # - bit[46] -> TB4 bit[1]: egress::hdr.cause_ie_6b.bce - # - bit[47] -> TB4 bit[0]: egress::hdr.cause_ie_6b.cs - W48: 64 # value 1 -> W48 bit[6]: egress::hdr.cause_ie_6b.$valid - shift: 6 - buf_req: 6 - next: parse_imsi - 0x020006: - 0: TB5 # egress::hdr.cause_ie_10b.type - 1..4: TW7 - # - bit[8..23] -> TW7 bit[31..16]: egress::hdr.cause_ie_10b.len - # - bit[24..27] -> TW7 bit[15..12]: egress::hdr.cause_ie_10b.spare1 - # - bit[28..31] -> TW7 bit[11..8]: egress::hdr.cause_ie_10b.instance - # - bit[32..39] -> TW7 bit[7..0]: egress::hdr.cause_ie_10b.cause_value - 5: TB4 - # - bit[40..44] -> TB4 bit[7..3]: egress::hdr.cause_ie_10b.spare2 - # - bit[45] -> TB4 bit[2]: egress::hdr.cause_ie_10b.pce - # - bit[46] -> TB4 bit[1]: egress::hdr.cause_ie_10b.bce - # - bit[47] -> TB4 bit[0]: egress::hdr.cause_ie_10b.cs - 6..7: TH11 - # - bit[48..55] -> TH11 bit[15..8]: egress::hdr.cause_ie_10b.type_oe - # - bit[56..63] -> TH11 bit[7..0]: egress::hdr.cause_ie_10b.len_oe[15:8].8-15 - 8..9: TH10 - # - bit[64..71] -> TH10 bit[15..8]: egress::hdr.cause_ie_10b.len_oe[7:0].0-7 - # - bit[72..75] -> TH10 bit[7..4]: egress::hdr.cause_ie_10b.spare_oe - # - bit[76..79] -> TH10 bit[3..0]: egress::hdr.cause_ie_10b.instance_oe - W48: 128 # value 1 -> W48 bit[7]: egress::hdr.cause_ie_10b.$valid - shift: 10 - buf_req: 10 - next: parse_imsi - 0x******: - buf_req: 0 - next: end - parse_imsi: - *: - 0..3: TW6 - # - bit[0..7] -> TW6 bit[31..24]: egress::hdr.imsi.type - # - bit[8..23] -> TW6 bit[23..8]: egress::hdr.imsi.len - # - bit[24..27] -> TW6 bit[7..4]: egress::hdr.imsi.spare - # - bit[28..31] -> TW6 bit[3..0]: egress::hdr.imsi.instance - 4..5: TH30 # egress::hdr.imsi.num_digit[127:112].112-127 - 6: TB29 # egress::hdr.imsi.num_digit[111:104].104-111 - 7: TB20 # egress::hdr.imsi.num_digit[103:96].96-103 - 8..11: TW29 # egress::hdr.imsi.num_digit[95:64].64-95 - 12..15: TW28 # egress::hdr.imsi.num_digit[63:32].32-63 - 16..19: TW21 # egress::hdr.imsi.num_digit[31:0].0-31 - W48: 32 # value 1 -> W48 bit[5]: egress::hdr.imsi.$valid - shift: 20 - buf_req: 20 - next: end - parse_volte: - match: [ byte1 ] - 0x4*: - load: { byte1 : 9 } - buf_req: 10 - next: parse_inner_ipv4 - 0x6*: - 0..3: TW6 - # - bit[0..3] -> TW6 bit[31..28]: egress::hdr.inner_ipv6.version - # - bit[4..11] -> TW6 bit[27..20]: egress::hdr.inner_ipv6.traffic_class - # - bit[12..31] -> TW6 bit[19..0]: egress::hdr.inner_ipv6.flow_label - 4..5: TH11 # egress::hdr.inner_ipv6.payload_len - 6: B19 # egress::hdr.inner_ipv6.next_hdr - 7: TB20 # egress::hdr.inner_ipv6.hop_limit - 8..11: W26 # egress::hdr.inner_ipv6.src_addr[127:96].96-127 - 12..15: W25 # egress::hdr.inner_ipv6.src_addr[95:64].64-95 - 16..19: W24 # egress::hdr.inner_ipv6.src_addr[63:32].32-63 - W48: 16384 # value 1 -> W48 bit[14]: egress::hdr.inner_ipv6.$valid - load: { byte1 : 6 } - shift: 20 - buf_req: 20 - next: parse_inner_ipv6.$split_0 - 0x**: - buf_req: 0 - next: end - parse_inner_ipv4: - match: [ byte1 ] - 0x06: - 0..3: TW6 - # - bit[0..3] -> TW6 bit[31..28]: egress::hdr.inner_ipv4.version - # - bit[4..7] -> TW6 bit[27..24]: egress::hdr.inner_ipv4.ihl - # - bit[8..15] -> TW6 bit[23..16]: egress::hdr.inner_ipv4.diffserv - # - bit[16..31] -> TW6 bit[15..0]: egress::hdr.inner_ipv4.total_len - 4..5: TH30 # egress::hdr.inner_ipv4.identification - 6..7: TH11 - # - bit[48..50] -> TH11 bit[15..13]: egress::hdr.inner_ipv4.flags - # - bit[51..63] -> TH11 bit[12..0]: egress::hdr.inner_ipv4.frag_offset - 8..11: TW21 - # - bit[64..71] -> TW21 bit[31..24]: egress::hdr.inner_ipv4.ttl - # - bit[72..79] -> TW21 bit[23..16]: egress::hdr.inner_ipv4.protocol - # - bit[80..95] -> TW21 bit[15..0]: egress::hdr.inner_ipv4.hdr_checksum - 12: TB31 # egress::hdr.inner_ipv4.src_addr[31:24].24-31 - 13: TB30 # egress::hdr.inner_ipv4.src_addr[23:16].16-23 - 14: TB29 # egress::hdr.inner_ipv4.src_addr[15:8].8-15 - 15: TB20 # egress::hdr.inner_ipv4.src_addr[7:0].0-7 - 16..19: W18 # egress::hdr.inner_ipv4.dst_addr - W48: 256 # value 1 -> W48 bit[8]: egress::hdr.inner_ipv4.$valid - shift: 20 - buf_req: 20 - next: parse_inner_tcp - 0x11: - 0..3: TW6 - # - bit[0..3] -> TW6 bit[31..28]: egress::hdr.inner_ipv4.version - # - bit[4..7] -> TW6 bit[27..24]: egress::hdr.inner_ipv4.ihl - # - bit[8..15] -> TW6 bit[23..16]: egress::hdr.inner_ipv4.diffserv - # - bit[16..31] -> TW6 bit[15..0]: egress::hdr.inner_ipv4.total_len - 4..5: TH30 # egress::hdr.inner_ipv4.identification - 6..7: TH11 - # - bit[48..50] -> TH11 bit[15..13]: egress::hdr.inner_ipv4.flags - # - bit[51..63] -> TH11 bit[12..0]: egress::hdr.inner_ipv4.frag_offset - 8..11: TW21 - # - bit[64..71] -> TW21 bit[31..24]: egress::hdr.inner_ipv4.ttl - # - bit[72..79] -> TW21 bit[23..16]: egress::hdr.inner_ipv4.protocol - # - bit[80..95] -> TW21 bit[15..0]: egress::hdr.inner_ipv4.hdr_checksum - 12: TB31 # egress::hdr.inner_ipv4.src_addr[31:24].24-31 - 13: TB30 # egress::hdr.inner_ipv4.src_addr[23:16].16-23 - 14: TB29 # egress::hdr.inner_ipv4.src_addr[15:8].8-15 - 15: TB20 # egress::hdr.inner_ipv4.src_addr[7:0].0-7 - 16..19: W18 # egress::hdr.inner_ipv4.dst_addr - W48: 256 # value 1 -> W48 bit[8]: egress::hdr.inner_ipv4.$valid - shift: 20 - buf_req: 20 - next: parse_inner_udp - 0x01: - 0..3: TW6 - # - bit[0..3] -> TW6 bit[31..28]: egress::hdr.inner_ipv4.version - # - bit[4..7] -> TW6 bit[27..24]: egress::hdr.inner_ipv4.ihl - # - bit[8..15] -> TW6 bit[23..16]: egress::hdr.inner_ipv4.diffserv - # - bit[16..31] -> TW6 bit[15..0]: egress::hdr.inner_ipv4.total_len - 4..5: TH30 # egress::hdr.inner_ipv4.identification - 6..7: TH11 - # - bit[48..50] -> TH11 bit[15..13]: egress::hdr.inner_ipv4.flags - # - bit[51..63] -> TH11 bit[12..0]: egress::hdr.inner_ipv4.frag_offset - 8..11: TW21 - # - bit[64..71] -> TW21 bit[31..24]: egress::hdr.inner_ipv4.ttl - # - bit[72..79] -> TW21 bit[23..16]: egress::hdr.inner_ipv4.protocol - # - bit[80..95] -> TW21 bit[15..0]: egress::hdr.inner_ipv4.hdr_checksum - 12: TB31 # egress::hdr.inner_ipv4.src_addr[31:24].24-31 - 13: TB30 # egress::hdr.inner_ipv4.src_addr[23:16].16-23 - 14: TB29 # egress::hdr.inner_ipv4.src_addr[15:8].8-15 - 15: TB20 # egress::hdr.inner_ipv4.src_addr[7:0].0-7 - 16..19: W18 # egress::hdr.inner_ipv4.dst_addr - W48: 256 # value 1 -> W48 bit[8]: egress::hdr.inner_ipv4.$valid - shift: 20 - buf_req: 20 - next: parse_inner_icmp - 0x32: - 0..3: TW6 - # - bit[0..3] -> TW6 bit[31..28]: egress::hdr.inner_ipv4.version - # - bit[4..7] -> TW6 bit[27..24]: egress::hdr.inner_ipv4.ihl - # - bit[8..15] -> TW6 bit[23..16]: egress::hdr.inner_ipv4.diffserv - # - bit[16..31] -> TW6 bit[15..0]: egress::hdr.inner_ipv4.total_len - 4..5: TH30 # egress::hdr.inner_ipv4.identification - 6..7: TH11 - # - bit[48..50] -> TH11 bit[15..13]: egress::hdr.inner_ipv4.flags - # - bit[51..63] -> TH11 bit[12..0]: egress::hdr.inner_ipv4.frag_offset - 8..11: TW21 - # - bit[64..71] -> TW21 bit[31..24]: egress::hdr.inner_ipv4.ttl - # - bit[72..79] -> TW21 bit[23..16]: egress::hdr.inner_ipv4.protocol - # - bit[80..95] -> TW21 bit[15..0]: egress::hdr.inner_ipv4.hdr_checksum - 12: TB31 # egress::hdr.inner_ipv4.src_addr[31:24].24-31 - 13: TB30 # egress::hdr.inner_ipv4.src_addr[23:16].16-23 - 14: TB29 # egress::hdr.inner_ipv4.src_addr[15:8].8-15 - 15: TB20 # egress::hdr.inner_ipv4.src_addr[7:0].0-7 - 16..19: W18 # egress::hdr.inner_ipv4.dst_addr - W48: 256 # value 1 -> W48 bit[8]: egress::hdr.inner_ipv4.$valid - shift: 20 - buf_req: 20 - next: parse_inner_esp - 0x**: - 0..3: TW6 - # - bit[0..3] -> TW6 bit[31..28]: egress::hdr.inner_ipv4.version - # - bit[4..7] -> TW6 bit[27..24]: egress::hdr.inner_ipv4.ihl - # - bit[8..15] -> TW6 bit[23..16]: egress::hdr.inner_ipv4.diffserv - # - bit[16..31] -> TW6 bit[15..0]: egress::hdr.inner_ipv4.total_len - 4..5: TH30 # egress::hdr.inner_ipv4.identification - 6..7: TH11 - # - bit[48..50] -> TH11 bit[15..13]: egress::hdr.inner_ipv4.flags - # - bit[51..63] -> TH11 bit[12..0]: egress::hdr.inner_ipv4.frag_offset - 8..11: TW21 - # - bit[64..71] -> TW21 bit[31..24]: egress::hdr.inner_ipv4.ttl - # - bit[72..79] -> TW21 bit[23..16]: egress::hdr.inner_ipv4.protocol - # - bit[80..95] -> TW21 bit[15..0]: egress::hdr.inner_ipv4.hdr_checksum - 12: TB31 # egress::hdr.inner_ipv4.src_addr[31:24].24-31 - 13: TB30 # egress::hdr.inner_ipv4.src_addr[23:16].16-23 - 14: TB29 # egress::hdr.inner_ipv4.src_addr[15:8].8-15 - 15: TB20 # egress::hdr.inner_ipv4.src_addr[7:0].0-7 - 16..19: W18 # egress::hdr.inner_ipv4.dst_addr - W48: 256 # value 1 -> W48 bit[8]: egress::hdr.inner_ipv4.$valid - shift: 20 - buf_req: 20 - next: end - parse_inner_tcp: - *: - 0..1: H25 # egress::eg_md.lkp.inner_l4_src_port - 0..3: TW28 - # - bit[0..15] -> TW28 bit[31..16]: egress::hdr.inner_tcp.src_port - # - bit[16..31] -> TW28 bit[15..0]: egress::hdr.inner_tcp.dst_port - 2..3: H26 # egress::eg_md.lkp.inner_l4_dst_port - 4..7: W19 # egress::hdr.inner_tcp.seq_no - 8..11: W20 # egress::hdr.inner_tcp.ack_no - 12..15: TW7 - # - bit[96..99] -> TW7 bit[31..28]: egress::hdr.inner_tcp.data_offset - # - bit[100..103] -> TW7 bit[27..24]: egress::hdr.inner_tcp.res - # - bit[104..111] -> TW7 bit[23..16]: egress::hdr.inner_tcp.flags - # - bit[112..127] -> TW7 bit[15..0]: egress::hdr.inner_tcp.window - W48: 1536 - # - value 1 -> W48 bit[9]: egress::hdr.inner_tcp.$valid - # - value 1 -> W48 bit[10]: egress::hdr.sip.$valid - shift: 16 - buf_req: 16 - next: parse_inner_tcp.$split_0 - parse_inner_tcp.$split_0: - *: - 0..3: TW29 - # - bit[0..15] -> TW29 bit[31..16]: egress::hdr.inner_tcp.checksum - # - bit[16..31] -> TW29 bit[15..0]: egress::hdr.inner_tcp.urgent_ptr - 4..7: W21 # egress::hdr.sip.data - shift: 8 - buf_req: 8 - next: end - parse_inner_udp: - *: - 0..1: H25 # egress::eg_md.lkp.inner_l4_src_port - 0..3: TW7 - # - bit[0..15] -> TW7 bit[31..16]: egress::hdr.inner_udp.src_port - # - bit[16..31] -> TW7 bit[15..0]: egress::hdr.inner_udp.dst_port - 2..3: H26 # egress::eg_md.lkp.inner_l4_dst_port - 4..7: TW28 - # - bit[32..47] -> TW28 bit[31..16]: egress::hdr.inner_udp.hdr_length - # - bit[48..63] -> TW28 bit[15..0]: egress::hdr.inner_udp.checksum - W48: 2048 # value 1 -> W48 bit[11]: egress::hdr.inner_udp.$valid - shift: 8 - buf_req: 8 - next: end - parse_inner_icmp: - *: - 0..3: TW7 - # - bit[0..7] -> TW7 bit[31..24]: egress::hdr.inner_icmp.type_ - # - bit[8..15] -> TW7 bit[23..16]: egress::hdr.inner_icmp.code - # - bit[16..31] -> TW7 bit[15..0]: egress::hdr.inner_icmp.hdr_checksum - W48: 4096 # value 1 -> W48 bit[12]: egress::hdr.inner_icmp.$valid - shift: 4 - buf_req: 4 - next: end - parse_inner_esp: - *: - 0..3: W22 # egress::hdr.ipsec_esp.spi - 4..7: W23 # egress::hdr.ipsec_esp.sn - W48: 8192 # value 1 -> W48 bit[13]: egress::hdr.ipsec_esp.$valid - shift: 8 - buf_req: 8 - next: parse_inner_tcp - parse_inner_ipv6.$split_0: - *: - 0..3: W18 # egress::hdr.inner_ipv6.src_addr[31:0].0-31 - 4..7: W30 # egress::hdr.inner_ipv6.dst_addr[127:96].96-127 - 8..11: W29 # egress::hdr.inner_ipv6.dst_addr[95:64].64-95 - 12..15: W28 # egress::hdr.inner_ipv6.dst_addr[63:32].32-63 - shift: 16 - buf_req: 16 - next: parse_inner_ipv6.$split_1 - parse_inner_ipv6.$split_1: - match: [ byte1 ] - 0x06: - 0..3: W27 # egress::hdr.inner_ipv6.dst_addr[31:0].0-31 - shift: 4 - buf_req: 4 - next: parse_inner_tcp - 0x11: - 0..3: W27 # egress::hdr.inner_ipv6.dst_addr[31:0].0-31 - shift: 4 - buf_req: 4 - next: parse_inner_udp - 0x3a: - 0..3: W27 # egress::hdr.inner_ipv6.dst_addr[31:0].0-31 - shift: 4 - buf_req: 4 - next: parse_inner_icmp - 0x32: - 0..3: W27 # egress::hdr.inner_ipv6.dst_addr[31:0].0-31 - shift: 4 - buf_req: 4 - next: parse_inner_esp - 0x**: - 0..3: W27 # egress::hdr.inner_ipv6.dst_addr[31:0].0-31 - shift: 4 - buf_req: 4 - next: end - parse_gtpv2_12b: - match: [ byte1 ] - 0x20: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type - 2..3: TH9 # egress::hdr.gtpv2_12b.total_len - 4..7: W31 # egress::hdr.gtpv2_12b.teid - 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10..11: TH33 - # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 - # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 - W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x26: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type - 2..3: TH9 # egress::hdr.gtpv2_12b.total_len - 4..7: W31 # egress::hdr.gtpv2_12b.teid - 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10..11: TH33 - # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 - # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 - W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x27: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type - 2..3: TH9 # egress::hdr.gtpv2_12b.total_len - 4..7: W31 # egress::hdr.gtpv2_12b.teid - 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10..11: TH33 - # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 - # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 - W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x47: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type - 2..3: TH9 # egress::hdr.gtpv2_12b.total_len - 4..7: W31 # egress::hdr.gtpv2_12b.teid - 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10..11: TH33 - # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 - # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 - W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x67: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type - 2..3: TH9 # egress::hdr.gtpv2_12b.total_len - 4..7: W31 # egress::hdr.gtpv2_12b.teid - 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10..11: TH33 - # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 - # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 - W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x85: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type - 2..3: TH9 # egress::hdr.gtpv2_12b.total_len - 4..7: W31 # egress::hdr.gtpv2_12b.teid - 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10..11: TH33 - # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 - # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 - W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x88: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type - 2..3: TH9 # egress::hdr.gtpv2_12b.total_len - 4..7: W31 # egress::hdr.gtpv2_12b.teid - 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10..11: TH33 - # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 - # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 - W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x97: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type - 2..3: TH9 # egress::hdr.gtpv2_12b.total_len - 4..7: W31 # egress::hdr.gtpv2_12b.teid - 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10..11: TH33 - # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 - # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 - W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x9f: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type - 2..3: TH9 # egress::hdr.gtpv2_12b.total_len - 4..7: W31 # egress::hdr.gtpv2_12b.teid - 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10..11: TH33 - # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 - # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 - W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0xa2: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type - 2..3: TH9 # egress::hdr.gtpv2_12b.total_len - 4..7: W31 # egress::hdr.gtpv2_12b.teid - 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10..11: TH33 - # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 - # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 - W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0xa4: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type - 2..3: TH9 # egress::hdr.gtpv2_12b.total_len - 4..7: W31 # egress::hdr.gtpv2_12b.teid - 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10..11: TH33 - # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 - # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 - W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0xa6: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type - 2..3: TH9 # egress::hdr.gtpv2_12b.total_len - 4..7: W31 # egress::hdr.gtpv2_12b.teid - 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10..11: TH33 - # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 - # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 - W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x68: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type - 2..3: TH9 # egress::hdr.gtpv2_12b.total_len - 4..7: W31 # egress::hdr.gtpv2_12b.teid - 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10..11: TH33 - # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 - # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 - W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x82: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type - 2..3: TH9 # egress::hdr.gtpv2_12b.total_len - 4..7: W31 # egress::hdr.gtpv2_12b.teid - 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10..11: TH33 - # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 - # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 - W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0xff: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type - 2..3: TH9 # egress::hdr.gtpv2_12b.total_len - 4..7: W31 # egress::hdr.gtpv2_12b.teid - 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10..11: TH33 - # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 - # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 - W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid - load: { byte1 : 12 } - shift: 12 - buf_req: 13 - next: parse_volte - 0x**: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv2_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv2_12b.pb - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv2_12b.tf - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gtpv2_12b.spare1 - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv2_12b.message_type - 2..3: TH9 # egress::hdr.gtpv2_12b.total_len - 4..7: W31 # egress::hdr.gtpv2_12b.teid - 8..9: TH34 # egress::hdr.gtpv2_12b.seq_no[23:8].8-23 - 10..11: TH33 - # - bit[80..87] -> TH33 bit[15..8]: egress::hdr.gtpv2_12b.seq_no[7:0].0-7 - # - bit[88..95] -> TH33 bit[7..0]: egress::hdr.gtpv2_12b.spare2 - W48: 32768 # value 1 -> W48 bit[15]: egress::hdr.gtpv2_12b.$valid - shift: 12 - buf_req: 12 - next: end - parse_udp: - match: [ half ] - value_set EgParser_inner_2.udp_port_vxlan 1: - handle: 506 - field_mapping: - hdr.udp.dst_port(0..15) : half(0..15) - 0..3: TW23 - # - bit[0..15] -> TW23 bit[31..16]: egress::hdr.udp.src_port - # - bit[16..31] -> TW23 bit[15..0]: egress::hdr.udp.dst_port - 4..5: TH32 # egress::hdr.udp.hdr_length - 6: TB23 # egress::hdr.udp.checksum[15:8].8-15 - 7: TB22 # egress::hdr.udp.checksum[7:0].0-7 - W48: 65536 # value 1 -> W48 bit[16]: egress::hdr.udp.$valid - shift: 8 - buf_req: 8 - next: parse_vxlan - 0x0868: - 0..3: TW23 - # - bit[0..15] -> TW23 bit[31..16]: egress::hdr.udp.src_port - # - bit[16..31] -> TW23 bit[15..0]: egress::hdr.udp.dst_port - 4..5: TH32 # egress::hdr.udp.hdr_length - 6: TB23 # egress::hdr.udp.checksum[15:8].8-15 - 7: TB22 # egress::hdr.udp.checksum[7:0].0-7 - W48: 65536 # value 1 -> W48 bit[16]: egress::hdr.udp.$valid - shift: 8 - buf_req: 8 - next: parse_gtpu - 0x0d3a: - 0..3: TW23 - # - bit[0..15] -> TW23 bit[31..16]: egress::hdr.udp.src_port - # - bit[16..31] -> TW23 bit[15..0]: egress::hdr.udp.dst_port - 4..5: TH32 # egress::hdr.udp.hdr_length - 6: TB23 # egress::hdr.udp.checksum[15:8].8-15 - 7: TB22 # egress::hdr.udp.checksum[7:0].0-7 - W48: 65536 # value 1 -> W48 bit[16]: egress::hdr.udp.$valid - shift: 8 - buf_req: 8 - next: parse_gtp - 0x084b: - 0..3: TW23 - # - bit[0..15] -> TW23 bit[31..16]: egress::hdr.udp.src_port - # - bit[16..31] -> TW23 bit[15..0]: egress::hdr.udp.dst_port - 4..5: TH32 # egress::hdr.udp.hdr_length - 6: TB23 # egress::hdr.udp.checksum[15:8].8-15 - 7: TB22 # egress::hdr.udp.checksum[7:0].0-7 - W48: 65536 # value 1 -> W48 bit[16]: egress::hdr.udp.$valid - load: { byte1 : 8 } - shift: 8 - buf_req: 9 - next: parse_gtp_verx - 0x06a5: - 0..3: TW23 - # - bit[0..15] -> TW23 bit[31..16]: egress::hdr.udp.src_port - # - bit[16..31] -> TW23 bit[15..0]: egress::hdr.udp.dst_port - 4..5: TH32 # egress::hdr.udp.hdr_length - 6: TB23 # egress::hdr.udp.checksum[15:8].8-15 - 7: TB22 # egress::hdr.udp.checksum[7:0].0-7 - W48: 65536 # value 1 -> W48 bit[16]: egress::hdr.udp.$valid - load: { byte1 : 8 } - shift: 8 - buf_req: 9 - next: parse_l2tp - 0x****: - 0..3: TW23 - # - bit[0..15] -> TW23 bit[31..16]: egress::hdr.udp.src_port - # - bit[16..31] -> TW23 bit[15..0]: egress::hdr.udp.dst_port - 4..5: TH32 # egress::hdr.udp.hdr_length - 6: TB23 # egress::hdr.udp.checksum[15:8].8-15 - 7: TB22 # egress::hdr.udp.checksum[7:0].0-7 - W48: 65536 # value 1 -> W48 bit[16]: egress::hdr.udp.$valid - shift: 8 - buf_req: 8 - next: end - parse_vxlan: - *: - 0..3: TW5 - # - bit[0..7] -> TW5 bit[31..24]: egress::hdr.vxlan.flags - # - bit[8..31] -> TW5 bit[23..0]: egress::hdr.vxlan.reserved - 4..5: TH9 # egress::hdr.vxlan.vni[23:8].8-23 - 6..7: TH8 - # - bit[48..55] -> TH8 bit[15..8]: egress::hdr.vxlan.vni[7:0].0-7 - # - bit[56..63] -> TH8 bit[7..0]: egress::hdr.vxlan.reserved2 - 8..11: TW30 # egress::hdr.inner_ethernet.dst_addr[47:16].16-47 - 12: TB5 # egress::hdr.inner_ethernet.dst_addr[15:8].8-15 - 13: TB4 # egress::hdr.inner_ethernet.dst_addr[7:0].0-7 - 14..15: TH47 # egress::hdr.inner_ethernet.src_addr[47:32].32-47 - 16..17: TH34 # egress::hdr.inner_ethernet.src_addr[31:16].16-31 - W48: 393216 - # - value 1 -> W48 bit[17]: egress::hdr.vxlan.$valid - # - value 1 -> W48 bit[18]: egress::hdr.inner_ethernet.$valid - load: { half : 20..21 } - shift: 18 - buf_req: 22 - next: parse_vxlan.$split_0 - parse_vxlan.$split_0: - match: [ half ] - 0x0800: - 0..1: TH33 # egress::hdr.inner_ethernet.src_addr[15:0].0-15 - 2..3: TH10 # egress::hdr.inner_ethernet.ether_type - load: { byte1 : 13 } - shift: 4 - buf_req: 14 - next: parse_inner_ipv4 - 0x86dd: - 0..1: TH33 # egress::hdr.inner_ethernet.src_addr[15:0].0-15 - 2..3: TH10 # egress::hdr.inner_ethernet.ether_type - shift: 4 - buf_req: 4 - next: parse_inner_ipv6 - 0x****: - 0..1: TH33 # egress::hdr.inner_ethernet.src_addr[15:0].0-15 - 2..3: TH10 # egress::hdr.inner_ethernet.ether_type - shift: 4 - buf_req: 4 - next: end - parse_inner_ipv6: - *: - 0..3: TW6 - # - bit[0..3] -> TW6 bit[31..28]: egress::hdr.inner_ipv6.version - # - bit[4..11] -> TW6 bit[27..20]: egress::hdr.inner_ipv6.traffic_class - # - bit[12..31] -> TW6 bit[19..0]: egress::hdr.inner_ipv6.flow_label - 4..5: TH11 # egress::hdr.inner_ipv6.payload_len - 6: B19 # egress::hdr.inner_ipv6.next_hdr - 7: TB20 # egress::hdr.inner_ipv6.hop_limit - 8..11: W26 # egress::hdr.inner_ipv6.src_addr[127:96].96-127 - 12..15: W25 # egress::hdr.inner_ipv6.src_addr[95:64].64-95 - 16..19: W24 # egress::hdr.inner_ipv6.src_addr[63:32].32-63 - W48: 16384 # value 1 -> W48 bit[14]: egress::hdr.inner_ipv6.$valid - load: { byte1 : 6 } - shift: 20 - buf_req: 20 - next: parse_inner_ipv6.$split_0 - parse_gtpu: - *: - load: { byte1 : 0 } - buf_req: 1 - next: parse_gtpv1 - parse_gtpv1: - match: [ byte1 ] - 0b*****000: - load: { byte1 : 1 } - buf_req: 2 - next: parse_gtpv1_8b - 0b*****0*1: - load: { byte1 : 1 } - buf_req: 2 - next: parse_gtpv1_12b - 0b*****01*: - load: { byte1 : 1 } - buf_req: 2 - next: parse_gtpv1_12b - 0x**: - buf_req: 0 - next: end - parse_gtpv1_8b: - match: [ byte1 ] - 0x20: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type - 2..3: TH9 # egress::hdr.gtpv1_8b.message_len - 4..7: TW5 # egress::hdr.gtpv1_8b.teid - W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x26: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type - 2..3: TH9 # egress::hdr.gtpv1_8b.message_len - 4..7: TW5 # egress::hdr.gtpv1_8b.teid - W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x27: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type - 2..3: TH9 # egress::hdr.gtpv1_8b.message_len - 4..7: TW5 # egress::hdr.gtpv1_8b.teid - W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x47: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type - 2..3: TH9 # egress::hdr.gtpv1_8b.message_len - 4..7: TW5 # egress::hdr.gtpv1_8b.teid - W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x67: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type - 2..3: TH9 # egress::hdr.gtpv1_8b.message_len - 4..7: TW5 # egress::hdr.gtpv1_8b.teid - W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x85: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type - 2..3: TH9 # egress::hdr.gtpv1_8b.message_len - 4..7: TW5 # egress::hdr.gtpv1_8b.teid - W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x88: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type - 2..3: TH9 # egress::hdr.gtpv1_8b.message_len - 4..7: TW5 # egress::hdr.gtpv1_8b.teid - W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x97: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type - 2..3: TH9 # egress::hdr.gtpv1_8b.message_len - 4..7: TW5 # egress::hdr.gtpv1_8b.teid - W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x9f: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type - 2..3: TH9 # egress::hdr.gtpv1_8b.message_len - 4..7: TW5 # egress::hdr.gtpv1_8b.teid - W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0xa2: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type - 2..3: TH9 # egress::hdr.gtpv1_8b.message_len - 4..7: TW5 # egress::hdr.gtpv1_8b.teid - W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0xa4: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type - 2..3: TH9 # egress::hdr.gtpv1_8b.message_len - 4..7: TW5 # egress::hdr.gtpv1_8b.teid - W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0xa6: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type - 2..3: TH9 # egress::hdr.gtpv1_8b.message_len - 4..7: TW5 # egress::hdr.gtpv1_8b.teid - W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x68: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type - 2..3: TH9 # egress::hdr.gtpv1_8b.message_len - 4..7: TW5 # egress::hdr.gtpv1_8b.teid - W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0x82: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type - 2..3: TH9 # egress::hdr.gtpv1_8b.message_len - 4..7: TW5 # egress::hdr.gtpv1_8b.teid - W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid - load: { half : 8..9, byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_gtp_base - 0xff: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type - 2..3: TH9 # egress::hdr.gtpv1_8b.message_len - 4..7: TW5 # egress::hdr.gtpv1_8b.teid - W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid - load: { byte1 : 8 } - shift: 8 - buf_req: 9 - next: parse_volte - 0x**: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_8b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_8b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_8b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_8b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_8b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_8b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_8b.message_type - 2..3: TH9 # egress::hdr.gtpv1_8b.message_len - 4..7: TW5 # egress::hdr.gtpv1_8b.teid - W48: 524288 # value 1 -> W48 bit[19]: egress::hdr.gtpv1_8b.$valid - shift: 8 - buf_req: 8 - next: end - parse_gtpv1_12b: - match: [ byte1 ] - 0x20: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type - 2..3: TH9 # egress::hdr.gtpv1_12b.message_len - 4..7: TW30 # egress::hdr.gtpv1_12b.teid - 8..11: TW5 - # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t - W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x26: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type - 2..3: TH9 # egress::hdr.gtpv1_12b.message_len - 4..7: TW30 # egress::hdr.gtpv1_12b.teid - 8..11: TW5 - # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t - W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x27: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type - 2..3: TH9 # egress::hdr.gtpv1_12b.message_len - 4..7: TW30 # egress::hdr.gtpv1_12b.teid - 8..11: TW5 - # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t - W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x47: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type - 2..3: TH9 # egress::hdr.gtpv1_12b.message_len - 4..7: TW30 # egress::hdr.gtpv1_12b.teid - 8..11: TW5 - # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t - W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x67: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type - 2..3: TH9 # egress::hdr.gtpv1_12b.message_len - 4..7: TW30 # egress::hdr.gtpv1_12b.teid - 8..11: TW5 - # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t - W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x85: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type - 2..3: TH9 # egress::hdr.gtpv1_12b.message_len - 4..7: TW30 # egress::hdr.gtpv1_12b.teid - 8..11: TW5 - # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t - W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x88: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type - 2..3: TH9 # egress::hdr.gtpv1_12b.message_len - 4..7: TW30 # egress::hdr.gtpv1_12b.teid - 8..11: TW5 - # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t - W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x97: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type - 2..3: TH9 # egress::hdr.gtpv1_12b.message_len - 4..7: TW30 # egress::hdr.gtpv1_12b.teid - 8..11: TW5 - # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t - W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x9f: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type - 2..3: TH9 # egress::hdr.gtpv1_12b.message_len - 4..7: TW30 # egress::hdr.gtpv1_12b.teid - 8..11: TW5 - # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t - W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0xa2: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type - 2..3: TH9 # egress::hdr.gtpv1_12b.message_len - 4..7: TW30 # egress::hdr.gtpv1_12b.teid - 8..11: TW5 - # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t - W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0xa4: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type - 2..3: TH9 # egress::hdr.gtpv1_12b.message_len - 4..7: TW30 # egress::hdr.gtpv1_12b.teid - 8..11: TW5 - # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t - W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0xa6: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type - 2..3: TH9 # egress::hdr.gtpv1_12b.message_len - 4..7: TW30 # egress::hdr.gtpv1_12b.teid - 8..11: TW5 - # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t - W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x68: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type - 2..3: TH9 # egress::hdr.gtpv1_12b.message_len - 4..7: TW30 # egress::hdr.gtpv1_12b.teid - 8..11: TW5 - # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t - W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0x82: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type - 2..3: TH9 # egress::hdr.gtpv1_12b.message_len - 4..7: TW30 # egress::hdr.gtpv1_12b.teid - 8..11: TW5 - # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t - W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid - load: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: parse_gtp_base - 0xff: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type - 2..3: TH9 # egress::hdr.gtpv1_12b.message_len - 4..7: TW30 # egress::hdr.gtpv1_12b.teid - 8..11: TW5 - # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t - W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid - load: { byte1 : 12 } - shift: 12 - buf_req: 13 - next: parse_volte - 0x**: - 0..1: TH8 - # - bit[0..2] -> TH8 bit[15..13]: egress::hdr.gtpv1_12b.version - # - bit[3] -> TH8 bit[12]: egress::hdr.gtpv1_12b.pt - # - bit[4] -> TH8 bit[11]: egress::hdr.gtpv1_12b.reserved - # - bit[5] -> TH8 bit[10]: egress::hdr.gtpv1_12b.e - # - bit[6] -> TH8 bit[9]: egress::hdr.gtpv1_12b.s - # - bit[7] -> TH8 bit[8]: egress::hdr.gtpv1_12b.pn - # - bit[8..15] -> TH8 bit[7..0]: egress::hdr.gtpv1_12b.message_type - 2..3: TH9 # egress::hdr.gtpv1_12b.message_len - 4..7: TW30 # egress::hdr.gtpv1_12b.teid - 8..11: TW5 - # - bit[64..79] -> TW5 bit[31..16]: egress::hdr.gtpv1_12b.seq_no - # - bit[80..87] -> TW5 bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no - # - bit[88..95] -> TW5 bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t - W48: 1048576 # value 1 -> W48 bit[20]: egress::hdr.gtpv1_12b.$valid - shift: 12 - buf_req: 12 - next: end - parse_gtp: - *: - load: { byte1 : 0 } - buf_req: 1 - next: parse_gtpv1 - parse_gtp_verx: - match: [ byte1 ] - 0b001*****: - load: { byte1 : 0 } - buf_req: 1 - next: parse_gtpv1 - 0b010*****: - load: { byte1 : 0 } - buf_req: 1 - next: parse_gtpv2 - 0x**: - buf_req: 0 - next: end - parse_l2tp: - match: [ byte1 ] - 0b0*******: - 0..3: TW5 - # - bit[0..11] -> TW5 bit[31..20]: egress::hdr.l2tp.TLxxSxOP - # - bit[12..15] -> TW5 bit[19..16]: egress::hdr.l2tp.version - # - bit[16..23] -> TW5 bit[15..8]: egress::hdr.l2tp.l2tp_length - # - bit[24..31] -> TW5 bit[7..0]: egress::hdr.l2tp.tunnel_id[15:8].8-15 - 4: TB4 # egress::hdr.l2tp.tunnel_id[7:0].0-7 - 5..6: TH34 # egress::hdr.l2tp.session_id - 7..8: TH33 # egress::hdr.l2tp.Ns - 9..10: TH8 # egress::hdr.l2tp.Nr - 11: TB21 # egress::hdr.l2tp.offset_size - 12: TB5 # egress::hdr.l2tp.offset_pad - W48: 2097152 # value 1 -> W48 bit[21]: egress::hdr.l2tp.$valid - load: { half : 19..20, byte0 : 21 } - shift: 13 - buf_req: 22 - next: parse_pppoe - 0x**: - 0..3: TW5 - # - bit[0..11] -> TW5 bit[31..20]: egress::hdr.l2tp.TLxxSxOP - # - bit[12..15] -> TW5 bit[19..16]: egress::hdr.l2tp.version - # - bit[16..23] -> TW5 bit[15..8]: egress::hdr.l2tp.l2tp_length - # - bit[24..31] -> TW5 bit[7..0]: egress::hdr.l2tp.tunnel_id[15:8].8-15 - 4: TB4 # egress::hdr.l2tp.tunnel_id[7:0].0-7 - 5..6: TH34 # egress::hdr.l2tp.session_id - 7..8: TH33 # egress::hdr.l2tp.Ns - 9..10: TH8 # egress::hdr.l2tp.Nr - 11: TB21 # egress::hdr.l2tp.offset_size - 12: TB5 # egress::hdr.l2tp.offset_pad - W48: 2097152 # value 1 -> W48 bit[21]: egress::hdr.l2tp.$valid - shift: 13 - buf_req: 13 - next: end - parse_pppoe: - match: [ half, byte0 ] - 0x00214*: - 0..1: TH9 - # - bit[0..3] -> TH9 bit[15..12]: egress::hdr.pppoe.version - # - bit[4..7] -> TH9 bit[11..8]: egress::hdr.pppoe.type - # - bit[8..15] -> TH9 bit[7..0]: egress::hdr.pppoe.code - 2..3: TH10 # egress::hdr.pppoe.session_id - 4..7: TW30 - # - bit[32..47] -> TW30 bit[31..16]: egress::hdr.pppoe.pppoe_length - # - bit[48..63] -> TW30 bit[15..0]: egress::hdr.pppoe.ppp_proto - W48: 4194304 # value 1 -> W48 bit[22]: egress::hdr.pppoe.$valid - load: { byte1 : 17 } - shift: 8 - buf_req: 18 - next: parse_inner_ipv4 - 0x00216*: - 0..1: TH9 - # - bit[0..3] -> TH9 bit[15..12]: egress::hdr.pppoe.version - # - bit[4..7] -> TH9 bit[11..8]: egress::hdr.pppoe.type - # - bit[8..15] -> TH9 bit[7..0]: egress::hdr.pppoe.code - 2..3: TH10 # egress::hdr.pppoe.session_id - 4..7: TW30 - # - bit[32..47] -> TW30 bit[31..16]: egress::hdr.pppoe.pppoe_length - # - bit[48..63] -> TW30 bit[15..0]: egress::hdr.pppoe.ppp_proto - W48: 4194304 # value 1 -> W48 bit[22]: egress::hdr.pppoe.$valid - shift: 8 - buf_req: 8 - next: parse_inner_ipv6 - 0x******: - 0..1: TH9 - # - bit[0..3] -> TH9 bit[15..12]: egress::hdr.pppoe.version - # - bit[4..7] -> TH9 bit[11..8]: egress::hdr.pppoe.type - # - bit[8..15] -> TH9 bit[7..0]: egress::hdr.pppoe.code - 2..3: TH10 # egress::hdr.pppoe.session_id - 4..7: TW30 - # - bit[32..47] -> TW30 bit[31..16]: egress::hdr.pppoe.pppoe_length - # - bit[48..63] -> TW30 bit[15..0]: egress::hdr.pppoe.ppp_proto - W48: 4194304 # value 1 -> W48 bit[22]: egress::hdr.pppoe.$valid - shift: 8 - buf_req: 8 - next: end - parse_icmp: - *: - 0..3: TW5 - # - bit[0..7] -> TW5 bit[31..24]: egress::hdr.icmp.type_ - # - bit[8..15] -> TW5 bit[23..16]: egress::hdr.icmp.code - # - bit[16..31] -> TW5 bit[15..0]: egress::hdr.icmp.hdr_checksum - W48: 8388608 # value 1 -> W48 bit[23]: egress::hdr.icmp.$valid - shift: 4 - buf_req: 4 - next: end - parse_sctp: - match: [ half ] - 0x8e3c: - 0..3: TW5 - # - bit[0..15] -> TW5 bit[31..16]: egress::hdr.sctp.src_port - # - bit[16..31] -> TW5 bit[15..0]: egress::hdr.sctp.dst_port - 4..7: TW6 # egress::hdr.sctp.verifTag - 8..9: TH8 # egress::hdr.sctp.checksum - W48: 16777216 # value 1 -> W48 bit[24]: egress::hdr.sctp.$valid - shift: 10 - buf_req: 10 - next: end - 0x960c: - 0..3: TW5 - # - bit[0..15] -> TW5 bit[31..16]: egress::hdr.sctp.src_port - # - bit[16..31] -> TW5 bit[15..0]: egress::hdr.sctp.dst_port - 4..7: TW6 # egress::hdr.sctp.verifTag - 8..9: TH8 # egress::hdr.sctp.checksum - W48: 16777216 # value 1 -> W48 bit[24]: egress::hdr.sctp.$valid - shift: 10 - buf_req: 10 - next: end - 0x0f1c: - 0..3: TW5 - # - bit[0..15] -> TW5 bit[31..16]: egress::hdr.sctp.src_port - # - bit[16..31] -> TW5 bit[15..0]: egress::hdr.sctp.dst_port - 4..7: TW6 # egress::hdr.sctp.verifTag - 8..9: TH8 # egress::hdr.sctp.checksum - W48: 16777216 # value 1 -> W48 bit[24]: egress::hdr.sctp.$valid - shift: 10 - buf_req: 10 - next: end - 0x71be: - 0..3: TW5 - # - bit[0..15] -> TW5 bit[31..16]: egress::hdr.sctp.src_port - # - bit[16..31] -> TW5 bit[15..0]: egress::hdr.sctp.dst_port - 4..7: TW6 # egress::hdr.sctp.verifTag - 8..9: TH8 # egress::hdr.sctp.checksum - W48: 16777216 # value 1 -> W48 bit[24]: egress::hdr.sctp.$valid - shift: 10 - buf_req: 10 - next: end - 0x****: - 0..3: TW5 - # - bit[0..15] -> TW5 bit[31..16]: egress::hdr.sctp.src_port - # - bit[16..31] -> TW5 bit[15..0]: egress::hdr.sctp.dst_port - 4..7: TW6 # egress::hdr.sctp.verifTag - 8..9: TH8 # egress::hdr.sctp.checksum - W48: 16777216 # value 1 -> W48 bit[24]: egress::hdr.sctp.$valid - shift: 10 - buf_req: 10 - next: end - parse_gre: - match: [ half, byte0 ] - 0b*****0011000100000001011: - 0..1: TH8 - # - bit[0] -> TH8 bit[15]: egress::hdr.gre.C - # - bit[1] -> TH8 bit[14]: egress::hdr.gre.R - # - bit[2] -> TH8 bit[13]: egress::hdr.gre.K - # - bit[3] -> TH8 bit[12]: egress::hdr.gre.S - # - bit[4] -> TH8 bit[11]: egress::hdr.gre.s - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gre.recurse - # - bit[8..12] -> TH8 bit[7..3]: egress::hdr.gre.flags - # - bit[13..15] -> TH8 bit[2..0]: egress::hdr.gre.version - 2: TB5 # egress::hdr.gre.proto[15:8].8-15 - 3: TB4 # egress::hdr.gre.proto[7:0].0-7 - W48: 33554432 # value 1 -> W48 bit[25]: egress::hdr.gre.$valid - load: { half : 10..11, byte0 : 12 } - shift: 4 - buf_req: 13 - next: parse_pptp - 0b*****0000000100000000000: - 0..1: TH8 - # - bit[0] -> TH8 bit[15]: egress::hdr.gre.C - # - bit[1] -> TH8 bit[14]: egress::hdr.gre.R - # - bit[2] -> TH8 bit[13]: egress::hdr.gre.K - # - bit[3] -> TH8 bit[12]: egress::hdr.gre.S - # - bit[4] -> TH8 bit[11]: egress::hdr.gre.s - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gre.recurse - # - bit[8..12] -> TH8 bit[7..3]: egress::hdr.gre.flags - # - bit[13..15] -> TH8 bit[2..0]: egress::hdr.gre.version - 2: TB5 # egress::hdr.gre.proto[15:8].8-15 - 3: TB4 # egress::hdr.gre.proto[7:0].0-7 - W48: 33554432 # value 1 -> W48 bit[25]: egress::hdr.gre.$valid - shift: 4 - buf_req: 4 - next: parse_gre_ipv4 - 0b*****0001000011011011101: - 0..1: TH8 - # - bit[0] -> TH8 bit[15]: egress::hdr.gre.C - # - bit[1] -> TH8 bit[14]: egress::hdr.gre.R - # - bit[2] -> TH8 bit[13]: egress::hdr.gre.K - # - bit[3] -> TH8 bit[12]: egress::hdr.gre.S - # - bit[4] -> TH8 bit[11]: egress::hdr.gre.s - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gre.recurse - # - bit[8..12] -> TH8 bit[7..3]: egress::hdr.gre.flags - # - bit[13..15] -> TH8 bit[2..0]: egress::hdr.gre.version - 2: TB5 # egress::hdr.gre.proto[15:8].8-15 - 3: TB4 # egress::hdr.gre.proto[7:0].0-7 - W48: 33554432 # value 1 -> W48 bit[25]: egress::hdr.gre.$valid - shift: 4 - buf_req: 4 - next: parse_inner_ipv6 - 0x******: - 0..1: TH8 - # - bit[0] -> TH8 bit[15]: egress::hdr.gre.C - # - bit[1] -> TH8 bit[14]: egress::hdr.gre.R - # - bit[2] -> TH8 bit[13]: egress::hdr.gre.K - # - bit[3] -> TH8 bit[12]: egress::hdr.gre.S - # - bit[4] -> TH8 bit[11]: egress::hdr.gre.s - # - bit[5..7] -> TH8 bit[10..8]: egress::hdr.gre.recurse - # - bit[8..12] -> TH8 bit[7..3]: egress::hdr.gre.flags - # - bit[13..15] -> TH8 bit[2..0]: egress::hdr.gre.version - 2: TB5 # egress::hdr.gre.proto[15:8].8-15 - 3: TB4 # egress::hdr.gre.proto[7:0].0-7 - W48: 33554432 # value 1 -> W48 bit[25]: egress::hdr.gre.$valid - shift: 4 - buf_req: 4 - next: end - parse_pptp: - match: [ half, byte0 ] - 0x00214*: - 0..1: TH9 - # - bit[0..3] -> TH9 bit[15..12]: egress::hdr.pppoe.version - # - bit[4..7] -> TH9 bit[11..8]: egress::hdr.pppoe.type - # - bit[8..15] -> TH9 bit[7..0]: egress::hdr.pppoe.code - 2..3: TH10 # egress::hdr.pppoe.session_id - 4..7: TW30 - # - bit[32..47] -> TW30 bit[31..16]: egress::hdr.pppoe.pppoe_length - # - bit[48..63] -> TW30 bit[15..0]: egress::hdr.pppoe.ppp_proto - W48: 4194304 # value 1 -> W48 bit[22]: egress::hdr.pppoe.$valid - load: { byte1 : 17 } - shift: 8 - buf_req: 18 - next: parse_inner_ipv4 - 0x00216*: - 0..1: TH9 - # - bit[0..3] -> TH9 bit[15..12]: egress::hdr.pppoe.version - # - bit[4..7] -> TH9 bit[11..8]: egress::hdr.pppoe.type - # - bit[8..15] -> TH9 bit[7..0]: egress::hdr.pppoe.code - 2..3: TH10 # egress::hdr.pppoe.session_id - 4..7: TW30 - # - bit[32..47] -> TW30 bit[31..16]: egress::hdr.pppoe.pppoe_length - # - bit[48..63] -> TW30 bit[15..0]: egress::hdr.pppoe.ppp_proto - W48: 4194304 # value 1 -> W48 bit[22]: egress::hdr.pppoe.$valid - shift: 8 - buf_req: 8 - next: parse_inner_ipv6 - 0x******: - 0..1: TH9 - # - bit[0..3] -> TH9 bit[15..12]: egress::hdr.pppoe.version - # - bit[4..7] -> TH9 bit[11..8]: egress::hdr.pppoe.type - # - bit[8..15] -> TH9 bit[7..0]: egress::hdr.pppoe.code - 2..3: TH10 # egress::hdr.pppoe.session_id - 4..7: TW30 - # - bit[32..47] -> TW30 bit[31..16]: egress::hdr.pppoe.pppoe_length - # - bit[48..63] -> TW30 bit[15..0]: egress::hdr.pppoe.ppp_proto - W48: 4194304 # value 1 -> W48 bit[22]: egress::hdr.pppoe.$valid - shift: 8 - buf_req: 8 - next: end - parse_gre_ipv4: - *: - load: { byte1 : 9 } - buf_req: 10 - next: parse_inner_ipv4 - parse_ipv6: - *: - 0..3: TW4 - # - bit[0..3] -> TW4 bit[31..28]: egress::hdr.ipv6.version - # - bit[4..11] -> TW4 bit[27..20]: egress::hdr.ipv6.traffic_class - # - bit[12..31] -> TW4 bit[19..0]: egress::hdr.ipv6.flow_label - 4..7: TW20 - # - bit[32..47] -> TW20 bit[31..16]: egress::hdr.ipv6.payload_len - # - bit[48..55] -> TW20 bit[15..8]: egress::hdr.ipv6.next_hdr - # - bit[56..63] -> TW20 bit[7..0]: egress::hdr.ipv6.hop_limit - 8..9: H22 # egress::hdr.ipv6.src_addr[127:112].112-127 - 10..11: TH46 # egress::hdr.ipv6.src_addr[111:96].96-111 - 12..15: TW22 # egress::hdr.ipv6.src_addr[95:64].64-95 - 16..17: TH45 # egress::hdr.ipv6.src_addr[63:48].48-63 - 18..19: TH44 # egress::hdr.ipv6.src_addr[47:32].32-47 - 24..27: W47 # egress::hdr.ipv6.dst_addr[127:96].96-127 - W48: 67108864 # value 1 -> W48 bit[26]: egress::hdr.ipv6.$valid - load: { byte1 : 6 } - shift: 20 - buf_req: 28 - next: parse_ipv6.$split_0 - parse_ipv6.$split_0: - match: [ byte1 ] - 0x06: - 0..1: TH43 # egress::hdr.ipv6.src_addr[31:16].16-31 - 2..3: TH31 # egress::hdr.ipv6.src_addr[15:0].0-15 - 8..11: W46 # egress::hdr.ipv6.dst_addr[95:64].64-95 - 12..15: W45 # egress::hdr.ipv6.dst_addr[63:32].32-63 - 16..19: W44 # egress::hdr.ipv6.dst_addr[31:0].0-31 - load: { half : 22..23 } - shift: 20 - buf_req: 24 - next: parse_tcp - 0x11: - 0..1: TH43 # egress::hdr.ipv6.src_addr[31:16].16-31 - 2..3: TH31 # egress::hdr.ipv6.src_addr[15:0].0-15 - 8..11: W46 # egress::hdr.ipv6.dst_addr[95:64].64-95 - 12..15: W45 # egress::hdr.ipv6.dst_addr[63:32].32-63 - 16..19: W44 # egress::hdr.ipv6.dst_addr[31:0].0-31 - load: { half : 22..23 } - shift: 20 - buf_req: 24 - next: parse_udp - 0x3a: - 0..1: TH43 # egress::hdr.ipv6.src_addr[31:16].16-31 - 2..3: TH31 # egress::hdr.ipv6.src_addr[15:0].0-15 - 8..11: W46 # egress::hdr.ipv6.dst_addr[95:64].64-95 - 12..15: W45 # egress::hdr.ipv6.dst_addr[63:32].32-63 - 16..19: W44 # egress::hdr.ipv6.dst_addr[31:0].0-31 - shift: 20 - buf_req: 20 - next: parse_icmp - 0x84: - 0..1: TH43 # egress::hdr.ipv6.src_addr[31:16].16-31 - 2..3: TH31 # egress::hdr.ipv6.src_addr[15:0].0-15 - 8..11: W46 # egress::hdr.ipv6.dst_addr[95:64].64-95 - 12..15: W45 # egress::hdr.ipv6.dst_addr[63:32].32-63 - 16..19: W44 # egress::hdr.ipv6.dst_addr[31:0].0-31 - load: { half : 22..23 } - shift: 20 - buf_req: 24 - next: parse_sctp - 0x29: - 0..1: TH43 # egress::hdr.ipv6.src_addr[31:16].16-31 - 2..3: TH31 # egress::hdr.ipv6.src_addr[15:0].0-15 - 8..11: W46 # egress::hdr.ipv6.dst_addr[95:64].64-95 - 12..15: W45 # egress::hdr.ipv6.dst_addr[63:32].32-63 - 16..19: W44 # egress::hdr.ipv6.dst_addr[31:0].0-31 - shift: 20 - buf_req: 20 - next: parse_inner_ipv6 - 0x04: - 0..1: TH43 # egress::hdr.ipv6.src_addr[31:16].16-31 - 2..3: TH31 # egress::hdr.ipv6.src_addr[15:0].0-15 - 8..11: W46 # egress::hdr.ipv6.dst_addr[95:64].64-95 - 12..15: W45 # egress::hdr.ipv6.dst_addr[63:32].32-63 - 16..19: W44 # egress::hdr.ipv6.dst_addr[31:0].0-31 - load: { byte1 : 29 } - shift: 20 - buf_req: 30 - next: parse_inner_ipv4 - 0x2f: - 0..1: TH43 # egress::hdr.ipv6.src_addr[31:16].16-31 - 2..3: TH31 # egress::hdr.ipv6.src_addr[15:0].0-15 - 8..11: W46 # egress::hdr.ipv6.dst_addr[95:64].64-95 - 12..15: W45 # egress::hdr.ipv6.dst_addr[63:32].32-63 - 16..19: W44 # egress::hdr.ipv6.dst_addr[31:0].0-31 - load: { half : 21..22, byte0 : 23 } - shift: 20 - buf_req: 24 - next: parse_gre - 0x**: - 0..1: TH43 # egress::hdr.ipv6.src_addr[31:16].16-31 - 2..3: TH31 # egress::hdr.ipv6.src_addr[15:0].0-15 - 8..11: W46 # egress::hdr.ipv6.dst_addr[95:64].64-95 - 12..15: W45 # egress::hdr.ipv6.dst_addr[63:32].32-63 - 16..19: W44 # egress::hdr.ipv6.dst_addr[31:0].0-31 - shift: 20 - buf_req: 20 - next: end - parse_vlan: - match: [ half ] - 0x0800: - 0..1: H21 - # - bit[0..2] -> H21 bit[15..13]: egress::hdr.vlan_tag[0].pcp - # - bit[3] -> H21 bit[12]: egress::hdr.vlan_tag[0].cfi - # - bit[4..15] -> H21 bit[11..0]: egress::hdr.vlan_tag[0].vid - 2: TB7 # egress::hdr.vlan_tag[0].ether_type[15:8].8-15 - 3: TB6 # egress::hdr.vlan_tag[0].ether_type[7:0].0-7 - B16: 16 # value 16 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv4 - 0x86dd: - 0..1: H21 - # - bit[0..2] -> H21 bit[15..13]: egress::hdr.vlan_tag[0].pcp - # - bit[3] -> H21 bit[12]: egress::hdr.vlan_tag[0].cfi - # - bit[4..15] -> H21 bit[11..0]: egress::hdr.vlan_tag[0].vid - 2: TB7 # egress::hdr.vlan_tag[0].ether_type[15:8].8-15 - 3: TB6 # egress::hdr.vlan_tag[0].ether_type[7:0].0-7 - B16: 16 # value 16 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv6 - 0x8100: - 0..1: H21 - # - bit[0..2] -> H21 bit[15..13]: egress::hdr.vlan_tag[0].pcp - # - bit[3] -> H21 bit[12]: egress::hdr.vlan_tag[0].cfi - # - bit[4..15] -> H21 bit[11..0]: egress::hdr.vlan_tag[0].vid - 2: TB7 # egress::hdr.vlan_tag[0].ether_type[15:8].8-15 - 3: TB6 # egress::hdr.vlan_tag[0].ether_type[7:0].0-7 - B16: 16 # value 16 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - load: { half : 6..7 } - shift: 4 - buf_req: 8 - next: parse_vlan.$it1 - 0x8847: - 0..1: H21 - # - bit[0..2] -> H21 bit[15..13]: egress::hdr.vlan_tag[0].pcp - # - bit[3] -> H21 bit[12]: egress::hdr.vlan_tag[0].cfi - # - bit[4..15] -> H21 bit[11..0]: egress::hdr.vlan_tag[0].vid - 2: TB7 # egress::hdr.vlan_tag[0].ether_type[15:8].8-15 - 3: TB6 # egress::hdr.vlan_tag[0].ether_type[7:0].0-7 - B16: 16 # value 16 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - load: { byte1 : 6 } - shift: 4 - buf_req: 7 - next: parse_mpls - 0x****: - 0..1: H21 - # - bit[0..2] -> H21 bit[15..13]: egress::hdr.vlan_tag[0].pcp - # - bit[3] -> H21 bit[12]: egress::hdr.vlan_tag[0].cfi - # - bit[4..15] -> H21 bit[11..0]: egress::hdr.vlan_tag[0].vid - 2: TB7 # egress::hdr.vlan_tag[0].ether_type[15:8].8-15 - 3: TB6 # egress::hdr.vlan_tag[0].ether_type[7:0].0-7 - B16: 16 # value 16 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_vlan.$it1: - match: [ half ] - 0x0800: - 0..3: TW12 - # - bit[0..2] -> TW12 bit[31..29]: egress::hdr.vlan_tag[1].pcp - # - bit[3] -> TW12 bit[28]: egress::hdr.vlan_tag[1].cfi - # - bit[4..15] -> TW12 bit[27..16]: egress::hdr.vlan_tag[1].vid - # - bit[16..31] -> TW12 bit[15..0]: egress::hdr.vlan_tag[1].ether_type - B16: 8 # value 8 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv4 - 0x86dd: - 0..3: TW12 - # - bit[0..2] -> TW12 bit[31..29]: egress::hdr.vlan_tag[1].pcp - # - bit[3] -> TW12 bit[28]: egress::hdr.vlan_tag[1].cfi - # - bit[4..15] -> TW12 bit[27..16]: egress::hdr.vlan_tag[1].vid - # - bit[16..31] -> TW12 bit[15..0]: egress::hdr.vlan_tag[1].ether_type - B16: 8 # value 8 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv6 - 0x8100: - 0..3: TW12 - # - bit[0..2] -> TW12 bit[31..29]: egress::hdr.vlan_tag[1].pcp - # - bit[3] -> TW12 bit[28]: egress::hdr.vlan_tag[1].cfi - # - bit[4..15] -> TW12 bit[27..16]: egress::hdr.vlan_tag[1].vid - # - bit[16..31] -> TW12 bit[15..0]: egress::hdr.vlan_tag[1].ether_type - B16: 8 # value 8 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - load: { half : 6..7 } - shift: 4 - buf_req: 8 - next: parse_vlan.$it2 - 0x8847: - 0..3: TW12 - # - bit[0..2] -> TW12 bit[31..29]: egress::hdr.vlan_tag[1].pcp - # - bit[3] -> TW12 bit[28]: egress::hdr.vlan_tag[1].cfi - # - bit[4..15] -> TW12 bit[27..16]: egress::hdr.vlan_tag[1].vid - # - bit[16..31] -> TW12 bit[15..0]: egress::hdr.vlan_tag[1].ether_type - B16: 8 # value 8 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - load: { byte1 : 6 } - shift: 4 - buf_req: 7 - next: parse_mpls - 0x****: - 0..3: TW12 - # - bit[0..2] -> TW12 bit[31..29]: egress::hdr.vlan_tag[1].pcp - # - bit[3] -> TW12 bit[28]: egress::hdr.vlan_tag[1].cfi - # - bit[4..15] -> TW12 bit[27..16]: egress::hdr.vlan_tag[1].vid - # - bit[16..31] -> TW12 bit[15..0]: egress::hdr.vlan_tag[1].ether_type - B16: 8 # value 8 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_vlan.$it2: - match: [ half ] - 0x0800: - 0..3: TW13 - # - bit[0..2] -> TW13 bit[31..29]: egress::hdr.vlan_tag[2].pcp - # - bit[3] -> TW13 bit[28]: egress::hdr.vlan_tag[2].cfi - # - bit[4..15] -> TW13 bit[27..16]: egress::hdr.vlan_tag[2].vid - # - bit[16..31] -> TW13 bit[15..0]: egress::hdr.vlan_tag[2].ether_type - B16: 4 # value 4 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv4 - 0x86dd: - 0..3: TW13 - # - bit[0..2] -> TW13 bit[31..29]: egress::hdr.vlan_tag[2].pcp - # - bit[3] -> TW13 bit[28]: egress::hdr.vlan_tag[2].cfi - # - bit[4..15] -> TW13 bit[27..16]: egress::hdr.vlan_tag[2].vid - # - bit[16..31] -> TW13 bit[15..0]: egress::hdr.vlan_tag[2].ether_type - B16: 4 # value 4 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv6 - 0x8100: - 0..3: TW13 - # - bit[0..2] -> TW13 bit[31..29]: egress::hdr.vlan_tag[2].pcp - # - bit[3] -> TW13 bit[28]: egress::hdr.vlan_tag[2].cfi - # - bit[4..15] -> TW13 bit[27..16]: egress::hdr.vlan_tag[2].vid - # - bit[16..31] -> TW13 bit[15..0]: egress::hdr.vlan_tag[2].ether_type - B16: 4 # value 4 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - load: { half : 6..7 } - shift: 4 - buf_req: 8 - next: parse_vlan.$it3 - 0x8847: - 0..3: TW13 - # - bit[0..2] -> TW13 bit[31..29]: egress::hdr.vlan_tag[2].pcp - # - bit[3] -> TW13 bit[28]: egress::hdr.vlan_tag[2].cfi - # - bit[4..15] -> TW13 bit[27..16]: egress::hdr.vlan_tag[2].vid - # - bit[16..31] -> TW13 bit[15..0]: egress::hdr.vlan_tag[2].ether_type - B16: 4 # value 4 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - load: { byte1 : 6 } - shift: 4 - buf_req: 7 - next: parse_mpls - 0x****: - 0..3: TW13 - # - bit[0..2] -> TW13 bit[31..29]: egress::hdr.vlan_tag[2].pcp - # - bit[3] -> TW13 bit[28]: egress::hdr.vlan_tag[2].cfi - # - bit[4..15] -> TW13 bit[27..16]: egress::hdr.vlan_tag[2].vid - # - bit[16..31] -> TW13 bit[15..0]: egress::hdr.vlan_tag[2].ether_type - B16: 4 # value 4 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_vlan.$it3: - match: [ half ] - 0x0800: - 0..3: TW14 - # - bit[0..2] -> TW14 bit[31..29]: egress::hdr.vlan_tag[3].pcp - # - bit[3] -> TW14 bit[28]: egress::hdr.vlan_tag[3].cfi - # - bit[4..15] -> TW14 bit[27..16]: egress::hdr.vlan_tag[3].vid - # - bit[16..31] -> TW14 bit[15..0]: egress::hdr.vlan_tag[3].ether_type - B16: 2 # value 2 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv4 - 0x86dd: - 0..3: TW14 - # - bit[0..2] -> TW14 bit[31..29]: egress::hdr.vlan_tag[3].pcp - # - bit[3] -> TW14 bit[28]: egress::hdr.vlan_tag[3].cfi - # - bit[4..15] -> TW14 bit[27..16]: egress::hdr.vlan_tag[3].vid - # - bit[16..31] -> TW14 bit[15..0]: egress::hdr.vlan_tag[3].ether_type - B16: 2 # value 2 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv6 - 0x8100: - 0..3: TW14 - # - bit[0..2] -> TW14 bit[31..29]: egress::hdr.vlan_tag[3].pcp - # - bit[3] -> TW14 bit[28]: egress::hdr.vlan_tag[3].cfi - # - bit[4..15] -> TW14 bit[27..16]: egress::hdr.vlan_tag[3].vid - # - bit[16..31] -> TW14 bit[15..0]: egress::hdr.vlan_tag[3].ether_type - B16: 2 # value 2 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - load: { half : 6..7 } - shift: 4 - buf_req: 8 - next: parse_vlan.$it4 - 0x8847: - 0..3: TW14 - # - bit[0..2] -> TW14 bit[31..29]: egress::hdr.vlan_tag[3].pcp - # - bit[3] -> TW14 bit[28]: egress::hdr.vlan_tag[3].cfi - # - bit[4..15] -> TW14 bit[27..16]: egress::hdr.vlan_tag[3].vid - # - bit[16..31] -> TW14 bit[15..0]: egress::hdr.vlan_tag[3].ether_type - B16: 2 # value 2 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - load: { byte1 : 6 } - shift: 4 - buf_req: 7 - next: parse_mpls - 0x****: - 0..3: TW14 - # - bit[0..2] -> TW14 bit[31..29]: egress::hdr.vlan_tag[3].pcp - # - bit[3] -> TW14 bit[28]: egress::hdr.vlan_tag[3].cfi - # - bit[4..15] -> TW14 bit[27..16]: egress::hdr.vlan_tag[3].vid - # - bit[16..31] -> TW14 bit[15..0]: egress::hdr.vlan_tag[3].ether_type - B16: 2 # value 2 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_vlan.$it4: - match: [ half ] - 0x0800: - 0..3: TW15 - # - bit[0..2] -> TW15 bit[31..29]: egress::hdr.vlan_tag[4].pcp - # - bit[3] -> TW15 bit[28]: egress::hdr.vlan_tag[4].cfi - # - bit[4..15] -> TW15 bit[27..16]: egress::hdr.vlan_tag[4].vid - # - bit[16..31] -> TW15 bit[15..0]: egress::hdr.vlan_tag[4].ether_type - B16: 1 # value 1 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv4 - 0x86dd: - 0..3: TW15 - # - bit[0..2] -> TW15 bit[31..29]: egress::hdr.vlan_tag[4].pcp - # - bit[3] -> TW15 bit[28]: egress::hdr.vlan_tag[4].cfi - # - bit[4..15] -> TW15 bit[27..16]: egress::hdr.vlan_tag[4].vid - # - bit[16..31] -> TW15 bit[15..0]: egress::hdr.vlan_tag[4].ether_type - B16: 1 # value 1 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv6 - 0x8100: - 0..3: TW15 - # - bit[0..2] -> TW15 bit[31..29]: egress::hdr.vlan_tag[4].pcp - # - bit[3] -> TW15 bit[28]: egress::hdr.vlan_tag[4].cfi - # - bit[4..15] -> TW15 bit[27..16]: egress::hdr.vlan_tag[4].vid - # - bit[16..31] -> TW15 bit[15..0]: egress::hdr.vlan_tag[4].ether_type - B16: 1 # value 1 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - 0x8847: - 0..3: TW15 - # - bit[0..2] -> TW15 bit[31..29]: egress::hdr.vlan_tag[4].pcp - # - bit[3] -> TW15 bit[28]: egress::hdr.vlan_tag[4].cfi - # - bit[4..15] -> TW15 bit[27..16]: egress::hdr.vlan_tag[4].vid - # - bit[16..31] -> TW15 bit[15..0]: egress::hdr.vlan_tag[4].ether_type - B16: 1 # value 1 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - load: { byte1 : 6 } - shift: 4 - buf_req: 7 - next: parse_mpls - 0x****: - 0..3: TW15 - # - bit[0..2] -> TW15 bit[31..29]: egress::hdr.vlan_tag[4].pcp - # - bit[3] -> TW15 bit[28]: egress::hdr.vlan_tag[4].cfi - # - bit[4..15] -> TW15 bit[27..16]: egress::hdr.vlan_tag[4].vid - # - bit[16..31] -> TW15 bit[15..0]: egress::hdr.vlan_tag[4].ether_type - B16: 1 # value 1 -> B16 bit[4..0]: egress::hdr.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_mpls: - match: [ byte1 ] - 0b*******0: - 0..1: TH19 # egress::hdr.mpls[0].label[19:4].4-19 - 2..3: TH18 - # - bit[16..19] -> TH18 bit[15..12]: egress::hdr.mpls[0].label[3:0].0-3 - # - bit[20..22] -> TH18 bit[11..9]: egress::hdr.mpls[0].exp - # - bit[23] -> TH18 bit[8]: egress::hdr.mpls[0].bos - # - bit[24..31] -> TH18 bit[7..0]: egress::hdr.mpls[0].ttl - B17: 8 # value 8 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid - load: { byte1 : 6 } - shift: 4 - buf_req: 7 - next: parse_mpls.$it1 - 0b*******1: - 0..1: TH19 # egress::hdr.mpls[0].label[19:4].4-19 - 2..3: TH18 - # - bit[16..19] -> TH18 bit[15..12]: egress::hdr.mpls[0].label[3:0].0-3 - # - bit[20..22] -> TH18 bit[11..9]: egress::hdr.mpls[0].exp - # - bit[23] -> TH18 bit[8]: egress::hdr.mpls[0].bos - # - bit[24..31] -> TH18 bit[7..0]: egress::hdr.mpls[0].ttl - B17: 8 # value 8 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid - load: { byte1 : 4 } - shift: 4 - buf_req: 5 - next: parse_mpls_bos - 0x**: - 0..1: TH19 # egress::hdr.mpls[0].label[19:4].4-19 - 2..3: TH18 - # - bit[16..19] -> TH18 bit[15..12]: egress::hdr.mpls[0].label[3:0].0-3 - # - bit[20..22] -> TH18 bit[11..9]: egress::hdr.mpls[0].exp - # - bit[23] -> TH18 bit[8]: egress::hdr.mpls[0].bos - # - bit[24..31] -> TH18 bit[7..0]: egress::hdr.mpls[0].ttl - B17: 8 # value 8 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_mpls.$it1: - match: [ byte1 ] - 0b*******0: - 0..1: TH21 # egress::hdr.mpls[1].label[19:4].4-19 - 2..3: TH20 - # - bit[16..19] -> TH20 bit[15..12]: egress::hdr.mpls[1].label[3:0].0-3 - # - bit[20..22] -> TH20 bit[11..9]: egress::hdr.mpls[1].exp - # - bit[23] -> TH20 bit[8]: egress::hdr.mpls[1].bos - # - bit[24..31] -> TH20 bit[7..0]: egress::hdr.mpls[1].ttl - B17: 4 # value 4 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid - load: { byte1 : 6 } - shift: 4 - buf_req: 7 - next: parse_mpls.$it2 - 0b*******1: - 0..1: TH21 # egress::hdr.mpls[1].label[19:4].4-19 - 2..3: TH20 - # - bit[16..19] -> TH20 bit[15..12]: egress::hdr.mpls[1].label[3:0].0-3 - # - bit[20..22] -> TH20 bit[11..9]: egress::hdr.mpls[1].exp - # - bit[23] -> TH20 bit[8]: egress::hdr.mpls[1].bos - # - bit[24..31] -> TH20 bit[7..0]: egress::hdr.mpls[1].ttl - B17: 4 # value 4 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid - load: { byte1 : 4 } - shift: 4 - buf_req: 5 - next: parse_mpls_bos - 0x**: - 0..1: TH21 # egress::hdr.mpls[1].label[19:4].4-19 - 2..3: TH20 - # - bit[16..19] -> TH20 bit[15..12]: egress::hdr.mpls[1].label[3:0].0-3 - # - bit[20..22] -> TH20 bit[11..9]: egress::hdr.mpls[1].exp - # - bit[23] -> TH20 bit[8]: egress::hdr.mpls[1].bos - # - bit[24..31] -> TH20 bit[7..0]: egress::hdr.mpls[1].ttl - B17: 4 # value 4 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_mpls.$it2: - match: [ byte1 ] - 0b*******0: - 0..1: TH23 # egress::hdr.mpls[2].label[19:4].4-19 - 2..3: TH22 - # - bit[16..19] -> TH22 bit[15..12]: egress::hdr.mpls[2].label[3:0].0-3 - # - bit[20..22] -> TH22 bit[11..9]: egress::hdr.mpls[2].exp - # - bit[23] -> TH22 bit[8]: egress::hdr.mpls[2].bos - # - bit[24..31] -> TH22 bit[7..0]: egress::hdr.mpls[2].ttl - B17: 2 # value 2 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid - shift: 4 - buf_req: 4 - next: parse_mpls.$it3 - 0b*******1: - 0..1: TH23 # egress::hdr.mpls[2].label[19:4].4-19 - 2..3: TH22 - # - bit[16..19] -> TH22 bit[15..12]: egress::hdr.mpls[2].label[3:0].0-3 - # - bit[20..22] -> TH22 bit[11..9]: egress::hdr.mpls[2].exp - # - bit[23] -> TH22 bit[8]: egress::hdr.mpls[2].bos - # - bit[24..31] -> TH22 bit[7..0]: egress::hdr.mpls[2].ttl - B17: 2 # value 2 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid - load: { byte1 : 4 } - shift: 4 - buf_req: 5 - next: parse_mpls_bos - 0x**: - 0..1: TH23 # egress::hdr.mpls[2].label[19:4].4-19 - 2..3: TH22 - # - bit[16..19] -> TH22 bit[15..12]: egress::hdr.mpls[2].label[3:0].0-3 - # - bit[20..22] -> TH22 bit[11..9]: egress::hdr.mpls[2].exp - # - bit[23] -> TH22 bit[8]: egress::hdr.mpls[2].bos - # - bit[24..31] -> TH22 bit[7..0]: egress::hdr.mpls[2].ttl - B17: 2 # value 2 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_mpls.$it3: - *: - 0: TB15 # egress::hdr.mpls[3].label[19:12].12-19 - 1: TB14 # egress::hdr.mpls[3].label[11:4].4-11 - 2: TB12 - # - bit[16..19] -> TB12 bit[7..4]: egress::hdr.mpls[3].label[3:0].0-3 - # - bit[20..22] -> TB12 bit[3..1]: egress::hdr.mpls[3].exp - # - bit[23] -> TB12 bit[0]: egress::hdr.mpls[3].bos - 3: TB13 # egress::hdr.mpls[3].ttl - load: { byte1 : 2 } - shift: 4 - buf_req: 4 - next: parse_mpls.$it3.$split_0 - parse_mpls.$it3.$split_0: - match: [ byte1 ] - 0b*******0: - B17: 1 # value 1 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid - buf_req: 0 - next: end - 0b*******1: - B17: 1 # value 1 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid - load: { byte1 : 0 } - buf_req: 1 - next: parse_mpls_bos - 0x**: - B17: 1 # value 1 -> B17 bit[3..0]: egress::hdr.mpls.$stkvalid - buf_req: 0 - next: end - parse_mpls_bos: - match: [ byte1 ] - 0x4*: - 0..3: TW4 - # - bit[0..3] -> TW4 bit[31..28]: egress::hdr.ipv4.version - # - bit[4..7] -> TW4 bit[27..24]: egress::hdr.ipv4.ihl - # - bit[8..15] -> TW4 bit[23..16]: egress::hdr.ipv4.diffserv - # - bit[16..31] -> TW4 bit[15..0]: egress::hdr.ipv4.total_len - 4..7: TW20 - # - bit[32..47] -> TW20 bit[31..16]: egress::hdr.ipv4.identification - # - bit[48..50] -> TW20 bit[15..13]: egress::hdr.ipv4.flags - # - bit[51..63] -> TW20 bit[12..0]: egress::hdr.ipv4.frag_offset - 8..9: TH31 - # - bit[64..71] -> TH31 bit[15..8]: egress::hdr.ipv4.ttl - # - bit[72..79] -> TH31 bit[7..0]: egress::hdr.ipv4.protocol - 8..11: TW22 # bit[80..95] -> TW22 bit[15..0]: egress::hdr.ipv4.hdr_checksum - 12..13: TH44 # egress::hdr.ipv4.src_addr[31:16].16-31 - 14..15: TH43 # egress::hdr.ipv4.src_addr[15:0].0-15 - 16..17: TH46 # egress::hdr.ipv4.dst_addr[31:16].16-31 - W48: 4 # value 1 -> W48 bit[2]: egress::hdr.ipv4.$valid - load: { byte1 : 9 } - shift: 18 - buf_req: 18 - next: parse_ipv4.$split_0 - 0x6*: - 0..3: TW4 - # - bit[0..3] -> TW4 bit[31..28]: egress::hdr.ipv6.version - # - bit[4..11] -> TW4 bit[27..20]: egress::hdr.ipv6.traffic_class - # - bit[12..31] -> TW4 bit[19..0]: egress::hdr.ipv6.flow_label - 4..7: TW20 - # - bit[32..47] -> TW20 bit[31..16]: egress::hdr.ipv6.payload_len - # - bit[48..55] -> TW20 bit[15..8]: egress::hdr.ipv6.next_hdr - # - bit[56..63] -> TW20 bit[7..0]: egress::hdr.ipv6.hop_limit - 8..9: H22 # egress::hdr.ipv6.src_addr[127:112].112-127 - 10..11: TH46 # egress::hdr.ipv6.src_addr[111:96].96-111 - 12..15: TW22 # egress::hdr.ipv6.src_addr[95:64].64-95 - 16..17: TH45 # egress::hdr.ipv6.src_addr[63:48].48-63 - 18..19: TH44 # egress::hdr.ipv6.src_addr[47:32].32-47 - 24..27: W47 # egress::hdr.ipv6.dst_addr[127:96].96-127 - W48: 67108864 # value 1 -> W48 bit[26]: egress::hdr.ipv6.$valid - load: { byte1 : 6 } - shift: 20 - buf_req: 28 - next: parse_ipv6.$split_0 - 0x**: - buf_req: 0 - next: end - parse_fabric: - match: [ half ] - 0x0800: - 0..3: W16 - # - bit[0] -> W16 bit[31]: egress::hdr.fabric.pad1 - # - bit[1] -> W16 bit[30]: egress::hdr.fabric.is_hit - # - bit[2] -> W16 bit[29]: egress::hdr.fabric.is_to_cn78 - # - bit[3] -> W16 bit[28]: egress::hdr.fabric.is_to_td3 - # - bit[4] -> W16 bit[27]: egress::hdr.fabric.is_hdr_decap - # - bit[5..7] -> W16 bit[26..24]: egress::hdr.fabric.ig_port_type - # - bit[8..13] -> W16 bit[23..18]: egress::hdr.fabric.pad2 - # - bit[14..31] -> W16 bit[17..0]: egress::hdr.fabric.mac_index - 4..7: W17 - # - bit[32..35] -> W17 bit[31..28]: egress::hdr.fabric.pad4 - # - bit[36] -> W17 bit[27]: egress::hdr.fabric.flags_drop - # - bit[37] -> W17 bit[26]: egress::hdr.fabric.is_trunc_mir - # - bit[38..55] -> W17 bit[25..8]: egress::hdr.fabric.count_index - # - bit[56..63] -> W17 bit[7..0]: egress::hdr.fabric.mc_index[15:8].8-15 - 8: B18 # egress::hdr.fabric.mc_index[7:0].0-7 - 9..10: H20 # egress::hdr.fabric.vlan_index - 11..12: H17 # egress::hdr.fabric.ether_type - W48: 134217728 # value 1 -> W48 bit[27]: egress::hdr.fabric.$valid - shift: 13 - buf_req: 13 - next: parse_ipv4 - 0x86dd: - 0..3: W16 - # - bit[0] -> W16 bit[31]: egress::hdr.fabric.pad1 - # - bit[1] -> W16 bit[30]: egress::hdr.fabric.is_hit - # - bit[2] -> W16 bit[29]: egress::hdr.fabric.is_to_cn78 - # - bit[3] -> W16 bit[28]: egress::hdr.fabric.is_to_td3 - # - bit[4] -> W16 bit[27]: egress::hdr.fabric.is_hdr_decap - # - bit[5..7] -> W16 bit[26..24]: egress::hdr.fabric.ig_port_type - # - bit[8..13] -> W16 bit[23..18]: egress::hdr.fabric.pad2 - # - bit[14..31] -> W16 bit[17..0]: egress::hdr.fabric.mac_index - 4..7: W17 - # - bit[32..35] -> W17 bit[31..28]: egress::hdr.fabric.pad4 - # - bit[36] -> W17 bit[27]: egress::hdr.fabric.flags_drop - # - bit[37] -> W17 bit[26]: egress::hdr.fabric.is_trunc_mir - # - bit[38..55] -> W17 bit[25..8]: egress::hdr.fabric.count_index - # - bit[56..63] -> W17 bit[7..0]: egress::hdr.fabric.mc_index[15:8].8-15 - 8: B18 # egress::hdr.fabric.mc_index[7:0].0-7 - 9..10: H20 # egress::hdr.fabric.vlan_index - 11..12: H17 # egress::hdr.fabric.ether_type - W48: 134217728 # value 1 -> W48 bit[27]: egress::hdr.fabric.$valid - shift: 13 - buf_req: 13 - next: parse_ipv6 - 0x8100: - 0..3: W16 - # - bit[0] -> W16 bit[31]: egress::hdr.fabric.pad1 - # - bit[1] -> W16 bit[30]: egress::hdr.fabric.is_hit - # - bit[2] -> W16 bit[29]: egress::hdr.fabric.is_to_cn78 - # - bit[3] -> W16 bit[28]: egress::hdr.fabric.is_to_td3 - # - bit[4] -> W16 bit[27]: egress::hdr.fabric.is_hdr_decap - # - bit[5..7] -> W16 bit[26..24]: egress::hdr.fabric.ig_port_type - # - bit[8..13] -> W16 bit[23..18]: egress::hdr.fabric.pad2 - # - bit[14..31] -> W16 bit[17..0]: egress::hdr.fabric.mac_index - 4..7: W17 - # - bit[32..35] -> W17 bit[31..28]: egress::hdr.fabric.pad4 - # - bit[36] -> W17 bit[27]: egress::hdr.fabric.flags_drop - # - bit[37] -> W17 bit[26]: egress::hdr.fabric.is_trunc_mir - # - bit[38..55] -> W17 bit[25..8]: egress::hdr.fabric.count_index - # - bit[56..63] -> W17 bit[7..0]: egress::hdr.fabric.mc_index[15:8].8-15 - 8: B18 # egress::hdr.fabric.mc_index[7:0].0-7 - 9..10: H20 # egress::hdr.fabric.vlan_index - 11..12: H17 # egress::hdr.fabric.ether_type - W48: 134217728 # value 1 -> W48 bit[27]: egress::hdr.fabric.$valid - load: { half : 15..16 } - shift: 13 - buf_req: 17 - next: parse_vlan - 0x8847: - 0..3: W16 - # - bit[0] -> W16 bit[31]: egress::hdr.fabric.pad1 - # - bit[1] -> W16 bit[30]: egress::hdr.fabric.is_hit - # - bit[2] -> W16 bit[29]: egress::hdr.fabric.is_to_cn78 - # - bit[3] -> W16 bit[28]: egress::hdr.fabric.is_to_td3 - # - bit[4] -> W16 bit[27]: egress::hdr.fabric.is_hdr_decap - # - bit[5..7] -> W16 bit[26..24]: egress::hdr.fabric.ig_port_type - # - bit[8..13] -> W16 bit[23..18]: egress::hdr.fabric.pad2 - # - bit[14..31] -> W16 bit[17..0]: egress::hdr.fabric.mac_index - 4..7: W17 - # - bit[32..35] -> W17 bit[31..28]: egress::hdr.fabric.pad4 - # - bit[36] -> W17 bit[27]: egress::hdr.fabric.flags_drop - # - bit[37] -> W17 bit[26]: egress::hdr.fabric.is_trunc_mir - # - bit[38..55] -> W17 bit[25..8]: egress::hdr.fabric.count_index - # - bit[56..63] -> W17 bit[7..0]: egress::hdr.fabric.mc_index[15:8].8-15 - 8: B18 # egress::hdr.fabric.mc_index[7:0].0-7 - 9..10: H20 # egress::hdr.fabric.vlan_index - 11..12: H17 # egress::hdr.fabric.ether_type - W48: 134217728 # value 1 -> W48 bit[27]: egress::hdr.fabric.$valid - load: { byte1 : 15 } - shift: 13 - buf_req: 16 - next: parse_mpls - 0x****: - 0..3: W16 - # - bit[0] -> W16 bit[31]: egress::hdr.fabric.pad1 - # - bit[1] -> W16 bit[30]: egress::hdr.fabric.is_hit - # - bit[2] -> W16 bit[29]: egress::hdr.fabric.is_to_cn78 - # - bit[3] -> W16 bit[28]: egress::hdr.fabric.is_to_td3 - # - bit[4] -> W16 bit[27]: egress::hdr.fabric.is_hdr_decap - # - bit[5..7] -> W16 bit[26..24]: egress::hdr.fabric.ig_port_type - # - bit[8..13] -> W16 bit[23..18]: egress::hdr.fabric.pad2 - # - bit[14..31] -> W16 bit[17..0]: egress::hdr.fabric.mac_index - 4..7: W17 - # - bit[32..35] -> W17 bit[31..28]: egress::hdr.fabric.pad4 - # - bit[36] -> W17 bit[27]: egress::hdr.fabric.flags_drop - # - bit[37] -> W17 bit[26]: egress::hdr.fabric.is_trunc_mir - # - bit[38..55] -> W17 bit[25..8]: egress::hdr.fabric.count_index - # - bit[56..63] -> W17 bit[7..0]: egress::hdr.fabric.mc_index[15:8].8-15 - 8: B18 # egress::hdr.fabric.mc_index[7:0].0-7 - 9..10: H20 # egress::hdr.fabric.vlan_index - 11..12: H17 # egress::hdr.fabric.ether_type - W48: 134217728 # value 1 -> W48 bit[27]: egress::hdr.fabric.$valid - shift: 13 - buf_req: 13 - next: end - parse_truncate_only_metadata: - *: - 9..12: TW31 # egress::hdr.ethernet.dst_addr[47:16].16-47 - 13..14: H24 # egress::hdr.ethernet.dst_addr[15:0].0-15 - 15..16: TH42 # egress::hdr.ethernet.src_addr[47:32].32-47 - 17..18: TH35 # egress::hdr.ethernet.src_addr[31:16].16-31 - 19..20: TH6 # egress::hdr.ethernet.src_addr[15:0].0-15 - W48: 2 # value 1 -> W48 bit[1]: egress::hdr.ethernet.$valid - load: { half : 21..22 } - shift: 21 - buf_req: 23 - next: parse_ethernet.$split_0 -deparser egress: - dictionary: - TW31: W48(1) # egress::hdr.ethernet.dst_addr.16-47 if egress::hdr.ethernet.$valid - H24: W48(1) # egress::hdr.ethernet.dst_addr.0-15 if egress::hdr.ethernet.$valid - TH42: W48(1) # egress::hdr.ethernet.src_addr.32-47 if egress::hdr.ethernet.$valid - TH35: W48(1) # egress::hdr.ethernet.src_addr.16-31 if egress::hdr.ethernet.$valid - TH6: W48(1) # egress::hdr.ethernet.src_addr.0-15 if egress::hdr.ethernet.$valid - H19: W48(1) # egress::hdr.ethernet.ether_type if egress::hdr.ethernet.$valid - W16: W48(27) - # - bit[31]: egress::hdr.fabric.pad1 if egress::hdr.fabric.$valid - # - bit[30]: egress::hdr.fabric.is_hit if egress::hdr.fabric.$valid - # - bit[29]: egress::hdr.fabric.is_to_cn78 if egress::hdr.fabric.$valid - # - bit[28]: egress::hdr.fabric.is_to_td3 if egress::hdr.fabric.$valid - # - bit[27]: egress::hdr.fabric.is_hdr_decap if egress::hdr.fabric.$valid - # - bit[26..24]: egress::hdr.fabric.ig_port_type if egress::hdr.fabric.$valid - # - bit[23..18]: egress::hdr.fabric.pad2 if egress::hdr.fabric.$valid - # - bit[17..0]: egress::hdr.fabric.mac_index if egress::hdr.fabric.$valid - W17: W48(27) - # - bit[31..28]: egress::hdr.fabric.pad4 if egress::hdr.fabric.$valid - # - bit[27]: egress::hdr.fabric.flags_drop if egress::hdr.fabric.$valid - # - bit[26]: egress::hdr.fabric.is_trunc_mir if egress::hdr.fabric.$valid - # - bit[25..8]: egress::hdr.fabric.count_index if egress::hdr.fabric.$valid - # - bit[7..0]: egress::hdr.fabric.mc_index.8-15 if egress::hdr.fabric.$valid - B18: W48(27) # egress::hdr.fabric.mc_index.0-7 if egress::hdr.fabric.$valid - H20: W48(27) # egress::hdr.fabric.vlan_index if egress::hdr.fabric.$valid - H17: W48(27) # egress::hdr.fabric.ether_type if egress::hdr.fabric.$valid - H23: W48(0) - # - bit[15..8]: egress::hdr.fabric_to_cn78.pkt_proto_type if egress::hdr.fabric_to_cn78.$valid - # - bit[7..0]: egress::hdr.fabric_to_cn78.ip_hdr_location if egress::hdr.fabric_to_cn78.$valid - TH7: W48(0) # egress::hdr.fabric_to_cn78.payload_crc32 if egress::hdr.fabric_to_cn78.$valid - H18: W48(0) # egress::hdr.fabric_to_cn78.ether_type if egress::hdr.fabric_to_cn78.$valid - H21: B16(4) - # - bit[15..13]: egress::hdr.vlan_tag[0].pcp if egress::hdr.vlan_tag[0].$valid - # - bit[12]: egress::hdr.vlan_tag[0].cfi if egress::hdr.vlan_tag[0].$valid - # - bit[11..0]: egress::hdr.vlan_tag[0].vid if egress::hdr.vlan_tag[0].$valid - TB7: B16(4) # egress::hdr.vlan_tag[0].ether_type.8-15 if egress::hdr.vlan_tag[0].$valid - TB6: B16(4) # egress::hdr.vlan_tag[0].ether_type.0-7 if egress::hdr.vlan_tag[0].$valid - TW12: B16(3) - # - bit[31..29]: egress::hdr.vlan_tag[1].pcp if egress::hdr.vlan_tag[1].$valid - # - bit[28]: egress::hdr.vlan_tag[1].cfi if egress::hdr.vlan_tag[1].$valid - # - bit[27..16]: egress::hdr.vlan_tag[1].vid if egress::hdr.vlan_tag[1].$valid - # - bit[15..0]: egress::hdr.vlan_tag[1].ether_type if egress::hdr.vlan_tag[1].$valid - TW13: B16(2) - # - bit[31..29]: egress::hdr.vlan_tag[2].pcp if egress::hdr.vlan_tag[2].$valid - # - bit[28]: egress::hdr.vlan_tag[2].cfi if egress::hdr.vlan_tag[2].$valid - # - bit[27..16]: egress::hdr.vlan_tag[2].vid if egress::hdr.vlan_tag[2].$valid - # - bit[15..0]: egress::hdr.vlan_tag[2].ether_type if egress::hdr.vlan_tag[2].$valid - TW14: B16(1) - # - bit[31..29]: egress::hdr.vlan_tag[3].pcp if egress::hdr.vlan_tag[3].$valid - # - bit[28]: egress::hdr.vlan_tag[3].cfi if egress::hdr.vlan_tag[3].$valid - # - bit[27..16]: egress::hdr.vlan_tag[3].vid if egress::hdr.vlan_tag[3].$valid - # - bit[15..0]: egress::hdr.vlan_tag[3].ether_type if egress::hdr.vlan_tag[3].$valid - TW15: B16(0) - # - bit[31..29]: egress::hdr.vlan_tag[4].pcp if egress::hdr.vlan_tag[4].$valid - # - bit[28]: egress::hdr.vlan_tag[4].cfi if egress::hdr.vlan_tag[4].$valid - # - bit[27..16]: egress::hdr.vlan_tag[4].vid if egress::hdr.vlan_tag[4].$valid - # - bit[15..0]: egress::hdr.vlan_tag[4].ether_type if egress::hdr.vlan_tag[4].$valid - TH19: B17(3) # egress::hdr.mpls[0].label.4-19 if egress::hdr.mpls[0].$valid - TH18: B17(3) - # - bit[15..12]: egress::hdr.mpls[0].label.0-3 if egress::hdr.mpls[0].$valid - # - bit[11..9]: egress::hdr.mpls[0].exp if egress::hdr.mpls[0].$valid - # - bit[8]: egress::hdr.mpls[0].bos if egress::hdr.mpls[0].$valid - # - bit[7..0]: egress::hdr.mpls[0].ttl if egress::hdr.mpls[0].$valid - TH21: B17(2) # egress::hdr.mpls[1].label.4-19 if egress::hdr.mpls[1].$valid - TH20: B17(2) - # - bit[15..12]: egress::hdr.mpls[1].label.0-3 if egress::hdr.mpls[1].$valid - # - bit[11..9]: egress::hdr.mpls[1].exp if egress::hdr.mpls[1].$valid - # - bit[8]: egress::hdr.mpls[1].bos if egress::hdr.mpls[1].$valid - # - bit[7..0]: egress::hdr.mpls[1].ttl if egress::hdr.mpls[1].$valid - TH23: B17(1) # egress::hdr.mpls[2].label.4-19 if egress::hdr.mpls[2].$valid - TH22: B17(1) - # - bit[15..12]: egress::hdr.mpls[2].label.0-3 if egress::hdr.mpls[2].$valid - # - bit[11..9]: egress::hdr.mpls[2].exp if egress::hdr.mpls[2].$valid - # - bit[8]: egress::hdr.mpls[2].bos if egress::hdr.mpls[2].$valid - # - bit[7..0]: egress::hdr.mpls[2].ttl if egress::hdr.mpls[2].$valid - TB15: B17(0) # egress::hdr.mpls[3].label.12-19 if egress::hdr.mpls[3].$valid - TB14: B17(0) # egress::hdr.mpls[3].label.4-11 if egress::hdr.mpls[3].$valid - TB12: B17(0) - # - bit[7..4]: egress::hdr.mpls[3].label.0-3 if egress::hdr.mpls[3].$valid - # - bit[3..1]: egress::hdr.mpls[3].exp if egress::hdr.mpls[3].$valid - # - bit[0]: egress::hdr.mpls[3].bos if egress::hdr.mpls[3].$valid - TB13: B17(0) # egress::hdr.mpls[3].ttl if egress::hdr.mpls[3].$valid - TW4: W48(2) - # - bit[31..28]: egress::hdr.ipv4.version if egress::hdr.ipv4.$valid - # - bit[27..24]: egress::hdr.ipv4.ihl if egress::hdr.ipv4.$valid - # - bit[23..16]: egress::hdr.ipv4.diffserv if egress::hdr.ipv4.$valid - # - bit[15..0]: egress::hdr.ipv4.total_len if egress::hdr.ipv4.$valid - TW20: W48(2) - # - bit[31..16]: egress::hdr.ipv4.identification if egress::hdr.ipv4.$valid - # - bit[15..13]: egress::hdr.ipv4.flags if egress::hdr.ipv4.$valid - # - bit[12..0]: egress::hdr.ipv4.frag_offset if egress::hdr.ipv4.$valid - TH31: W48(2) - # - bit[15..8]: egress::hdr.ipv4.ttl if egress::hdr.ipv4.$valid - # - bit[7..0]: egress::hdr.ipv4.protocol if egress::hdr.ipv4.$valid - TH44: W48(2) # egress::hdr.ipv4.src_addr.16-31 if egress::hdr.ipv4.$valid - TH43: W48(2) # egress::hdr.ipv4.src_addr.0-15 if egress::hdr.ipv4.$valid - TH46: W48(2) # egress::hdr.ipv4.dst_addr.16-31 if egress::hdr.ipv4.$valid - TH45: W48(2) # egress::hdr.ipv4.dst_addr.0-15 if egress::hdr.ipv4.$valid - TW4: W48(26) - # - bit[31..28]: egress::hdr.ipv6.version if egress::hdr.ipv6.$valid - # - bit[27..20]: egress::hdr.ipv6.traffic_class if egress::hdr.ipv6.$valid - # - bit[19..0]: egress::hdr.ipv6.flow_label if egress::hdr.ipv6.$valid - TW20: W48(26) - # - bit[31..16]: egress::hdr.ipv6.payload_len if egress::hdr.ipv6.$valid - # - bit[15..8]: egress::hdr.ipv6.next_hdr if egress::hdr.ipv6.$valid - # - bit[7..0]: egress::hdr.ipv6.hop_limit if egress::hdr.ipv6.$valid - H22: W48(26) # egress::hdr.ipv6.src_addr.112-127 if egress::hdr.ipv6.$valid - TH46: W48(26) # egress::hdr.ipv6.src_addr.96-111 if egress::hdr.ipv6.$valid - TW22: W48(26) # egress::hdr.ipv6.src_addr.64-95 if egress::hdr.ipv6.$valid - TH45: W48(26) # egress::hdr.ipv6.src_addr.48-63 if egress::hdr.ipv6.$valid - TH44: W48(26) # egress::hdr.ipv6.src_addr.32-47 if egress::hdr.ipv6.$valid - TH43: W48(26) # egress::hdr.ipv6.src_addr.16-31 if egress::hdr.ipv6.$valid - TH31: W48(26) # egress::hdr.ipv6.src_addr.0-15 if egress::hdr.ipv6.$valid - W47: W48(26) # egress::hdr.ipv6.dst_addr.96-127 if egress::hdr.ipv6.$valid - W46: W48(26) # egress::hdr.ipv6.dst_addr.64-95 if egress::hdr.ipv6.$valid - W45: W48(26) # egress::hdr.ipv6.dst_addr.32-63 if egress::hdr.ipv6.$valid - W44: W48(26) # egress::hdr.ipv6.dst_addr.0-31 if egress::hdr.ipv6.$valid - TW23: W48(16) - # - bit[31..16]: egress::hdr.udp.src_port if egress::hdr.udp.$valid - # - bit[15..0]: egress::hdr.udp.dst_port if egress::hdr.udp.$valid - TH32: W48(16) # egress::hdr.udp.hdr_length if egress::hdr.udp.$valid - TB23: W48(16) # egress::hdr.udp.checksum.8-15 if egress::hdr.udp.$valid - TB22: W48(16) # egress::hdr.udp.checksum.0-7 if egress::hdr.udp.$valid - TW23: W48(3) - # - bit[31..16]: egress::hdr.tcp.src_port if egress::hdr.tcp.$valid - # - bit[15..0]: egress::hdr.tcp.dst_port if egress::hdr.tcp.$valid - TW30: W48(3) # egress::hdr.tcp.seq_no if egress::hdr.tcp.$valid - TH47: W48(3) # egress::hdr.tcp.ack_no.16-31 if egress::hdr.tcp.$valid - TB28: W48(3) # egress::hdr.tcp.ack_no.8-15 if egress::hdr.tcp.$valid - TB23: W48(3) # egress::hdr.tcp.ack_no.0-7 if egress::hdr.tcp.$valid - TW5: W48(3) - # - bit[31..28]: egress::hdr.tcp.data_offset if egress::hdr.tcp.$valid - # - bit[27..24]: egress::hdr.tcp.res if egress::hdr.tcp.$valid - # - bit[23..16]: egress::hdr.tcp.flags if egress::hdr.tcp.$valid - # - bit[15..0]: egress::hdr.tcp.window if egress::hdr.tcp.$valid - TH32: W48(3) # egress::hdr.tcp.checksum if egress::hdr.tcp.$valid - TB22: W48(3) # egress::hdr.tcp.urgent_ptr.8-15 if egress::hdr.tcp.$valid - TB21: W48(3) # egress::hdr.tcp.urgent_ptr.0-7 if egress::hdr.tcp.$valid - TW5: W48(23) - # - bit[31..24]: egress::hdr.icmp.type_ if egress::hdr.icmp.$valid - # - bit[23..16]: egress::hdr.icmp.code if egress::hdr.icmp.$valid - # - bit[15..0]: egress::hdr.icmp.hdr_checksum if egress::hdr.icmp.$valid - TW5: W48(24) - # - bit[31..16]: egress::hdr.sctp.src_port if egress::hdr.sctp.$valid - # - bit[15..0]: egress::hdr.sctp.dst_port if egress::hdr.sctp.$valid - TW6: W48(24) # egress::hdr.sctp.verifTag if egress::hdr.sctp.$valid - TH8: W48(24) # egress::hdr.sctp.checksum if egress::hdr.sctp.$valid - TW5: W48(21) - # - bit[31..20]: egress::hdr.l2tp.TLxxSxOP if egress::hdr.l2tp.$valid - # - bit[19..16]: egress::hdr.l2tp.version if egress::hdr.l2tp.$valid - # - bit[15..8]: egress::hdr.l2tp.l2tp_length if egress::hdr.l2tp.$valid - # - bit[7..0]: egress::hdr.l2tp.tunnel_id.8-15 if egress::hdr.l2tp.$valid - TB4: W48(21) # egress::hdr.l2tp.tunnel_id.0-7 if egress::hdr.l2tp.$valid - TH34: W48(21) # egress::hdr.l2tp.session_id if egress::hdr.l2tp.$valid - TH33: W48(21) # egress::hdr.l2tp.Ns if egress::hdr.l2tp.$valid - TH8: W48(21) # egress::hdr.l2tp.Nr if egress::hdr.l2tp.$valid - TB21: W48(21) # egress::hdr.l2tp.offset_size if egress::hdr.l2tp.$valid - TB5: W48(21) # egress::hdr.l2tp.offset_pad if egress::hdr.l2tp.$valid - TH9: W48(22) - # - bit[15..12]: egress::hdr.pppoe.version if egress::hdr.pppoe.$valid - # - bit[11..8]: egress::hdr.pppoe.type if egress::hdr.pppoe.$valid - # - bit[7..0]: egress::hdr.pppoe.code if egress::hdr.pppoe.$valid - TH10: W48(22) # egress::hdr.pppoe.session_id if egress::hdr.pppoe.$valid - TW30: W48(22) - # - bit[31..16]: egress::hdr.pppoe.pppoe_length if egress::hdr.pppoe.$valid - # - bit[15..0]: egress::hdr.pppoe.ppp_proto if egress::hdr.pppoe.$valid - TH9: W48(22) - # - bit[15..12]: egress::hdr.pppoe.version if egress::hdr.pppoe.$valid - # - bit[11..8]: egress::hdr.pppoe.type if egress::hdr.pppoe.$valid - # - bit[7..0]: egress::hdr.pppoe.code if egress::hdr.pppoe.$valid - TH10: W48(22) # egress::hdr.pppoe.session_id if egress::hdr.pppoe.$valid - TW30: W48(22) - # - bit[31..16]: egress::hdr.pppoe.pppoe_length if egress::hdr.pppoe.$valid - # - bit[15..0]: egress::hdr.pppoe.ppp_proto if egress::hdr.pppoe.$valid - TH8: W48(25) - # - bit[15]: egress::hdr.gre.C if egress::hdr.gre.$valid - # - bit[14]: egress::hdr.gre.R if egress::hdr.gre.$valid - # - bit[13]: egress::hdr.gre.K if egress::hdr.gre.$valid - # - bit[12]: egress::hdr.gre.S if egress::hdr.gre.$valid - # - bit[11]: egress::hdr.gre.s if egress::hdr.gre.$valid - # - bit[10..8]: egress::hdr.gre.recurse if egress::hdr.gre.$valid - # - bit[7..3]: egress::hdr.gre.flags if egress::hdr.gre.$valid - # - bit[2..0]: egress::hdr.gre.version if egress::hdr.gre.$valid - TB5: W48(25) # egress::hdr.gre.proto.8-15 if egress::hdr.gre.$valid - TB4: W48(25) # egress::hdr.gre.proto.0-7 if egress::hdr.gre.$valid - TH8: W48(19) - # - bit[15..13]: egress::hdr.gtpv1_8b.version if egress::hdr.gtpv1_8b.$valid - # - bit[12]: egress::hdr.gtpv1_8b.pt if egress::hdr.gtpv1_8b.$valid - # - bit[11]: egress::hdr.gtpv1_8b.reserved if egress::hdr.gtpv1_8b.$valid - # - bit[10]: egress::hdr.gtpv1_8b.e if egress::hdr.gtpv1_8b.$valid - # - bit[9]: egress::hdr.gtpv1_8b.s if egress::hdr.gtpv1_8b.$valid - # - bit[8]: egress::hdr.gtpv1_8b.pn if egress::hdr.gtpv1_8b.$valid - # - bit[7..0]: egress::hdr.gtpv1_8b.message_type if egress::hdr.gtpv1_8b.$valid - TH9: W48(19) # egress::hdr.gtpv1_8b.message_len if egress::hdr.gtpv1_8b.$valid - TW5: W48(19) # egress::hdr.gtpv1_8b.teid if egress::hdr.gtpv1_8b.$valid - TH8: W48(20) - # - bit[15..13]: egress::hdr.gtpv1_12b.version if egress::hdr.gtpv1_12b.$valid - # - bit[12]: egress::hdr.gtpv1_12b.pt if egress::hdr.gtpv1_12b.$valid - # - bit[11]: egress::hdr.gtpv1_12b.reserved if egress::hdr.gtpv1_12b.$valid - # - bit[10]: egress::hdr.gtpv1_12b.e if egress::hdr.gtpv1_12b.$valid - # - bit[9]: egress::hdr.gtpv1_12b.s if egress::hdr.gtpv1_12b.$valid - # - bit[8]: egress::hdr.gtpv1_12b.pn if egress::hdr.gtpv1_12b.$valid - # - bit[7..0]: egress::hdr.gtpv1_12b.message_type if egress::hdr.gtpv1_12b.$valid - TH9: W48(20) # egress::hdr.gtpv1_12b.message_len if egress::hdr.gtpv1_12b.$valid - TW30: W48(20) # egress::hdr.gtpv1_12b.teid if egress::hdr.gtpv1_12b.$valid - TW5: W48(20) - # - bit[31..16]: egress::hdr.gtpv1_12b.seq_no if egress::hdr.gtpv1_12b.$valid - # - bit[15..8]: egress::hdr.gtpv1_12b.n_pdu_no if egress::hdr.gtpv1_12b.$valid - # - bit[7..0]: egress::hdr.gtpv1_12b.next_ex_hdr_t if egress::hdr.gtpv1_12b.$valid - TH8: W48(4) - # - bit[15..13]: egress::hdr.gtpv2_8b.version if egress::hdr.gtpv2_8b.$valid - # - bit[12]: egress::hdr.gtpv2_8b.pb if egress::hdr.gtpv2_8b.$valid - # - bit[11]: egress::hdr.gtpv2_8b.tf if egress::hdr.gtpv2_8b.$valid - # - bit[10..8]: egress::hdr.gtpv2_8b.spare1 if egress::hdr.gtpv2_8b.$valid - # - bit[7..0]: egress::hdr.gtpv2_8b.message_type if egress::hdr.gtpv2_8b.$valid - TH9: W48(4) # egress::hdr.gtpv2_8b.total_len if egress::hdr.gtpv2_8b.$valid - TH34: W48(4) # egress::hdr.gtpv2_8b.seq_no.8-23 if egress::hdr.gtpv2_8b.$valid - TH33: W48(4) - # - bit[15..8]: egress::hdr.gtpv2_8b.seq_no.0-7 if egress::hdr.gtpv2_8b.$valid - # - bit[7..0]: egress::hdr.gtpv2_8b.spare2 if egress::hdr.gtpv2_8b.$valid - TH8: W48(15) - # - bit[15..13]: egress::hdr.gtpv2_12b.version if egress::hdr.gtpv2_12b.$valid - # - bit[12]: egress::hdr.gtpv2_12b.pb if egress::hdr.gtpv2_12b.$valid - # - bit[11]: egress::hdr.gtpv2_12b.tf if egress::hdr.gtpv2_12b.$valid - # - bit[10..8]: egress::hdr.gtpv2_12b.spare1 if egress::hdr.gtpv2_12b.$valid - # - bit[7..0]: egress::hdr.gtpv2_12b.message_type if egress::hdr.gtpv2_12b.$valid - TH9: W48(15) # egress::hdr.gtpv2_12b.total_len if egress::hdr.gtpv2_12b.$valid - W31: W48(15) # egress::hdr.gtpv2_12b.teid if egress::hdr.gtpv2_12b.$valid - TH34: W48(15) # egress::hdr.gtpv2_12b.seq_no.8-23 if egress::hdr.gtpv2_12b.$valid - TH33: W48(15) - # - bit[15..8]: egress::hdr.gtpv2_12b.seq_no.0-7 if egress::hdr.gtpv2_12b.$valid - # - bit[7..0]: egress::hdr.gtpv2_12b.spare2 if egress::hdr.gtpv2_12b.$valid - TB5: W48(6) # egress::hdr.cause_ie_6b.type if egress::hdr.cause_ie_6b.$valid - TW7: W48(6) - # - bit[31..16]: egress::hdr.cause_ie_6b.len if egress::hdr.cause_ie_6b.$valid - # - bit[15..12]: egress::hdr.cause_ie_6b.spare1 if egress::hdr.cause_ie_6b.$valid - # - bit[11..8]: egress::hdr.cause_ie_6b.instance if egress::hdr.cause_ie_6b.$valid - # - bit[7..0]: egress::hdr.cause_ie_6b.cause_value if egress::hdr.cause_ie_6b.$valid - TB4: W48(6) - # - bit[7..3]: egress::hdr.cause_ie_6b.spare2 if egress::hdr.cause_ie_6b.$valid - # - bit[2]: egress::hdr.cause_ie_6b.pce if egress::hdr.cause_ie_6b.$valid - # - bit[1]: egress::hdr.cause_ie_6b.bce if egress::hdr.cause_ie_6b.$valid - # - bit[0]: egress::hdr.cause_ie_6b.cs if egress::hdr.cause_ie_6b.$valid - TB5: W48(7) # egress::hdr.cause_ie_10b.type if egress::hdr.cause_ie_10b.$valid - TW7: W48(7) - # - bit[31..16]: egress::hdr.cause_ie_10b.len if egress::hdr.cause_ie_10b.$valid - # - bit[15..12]: egress::hdr.cause_ie_10b.spare1 if egress::hdr.cause_ie_10b.$valid - # - bit[11..8]: egress::hdr.cause_ie_10b.instance if egress::hdr.cause_ie_10b.$valid - # - bit[7..0]: egress::hdr.cause_ie_10b.cause_value if egress::hdr.cause_ie_10b.$valid - TB4: W48(7) - # - bit[7..3]: egress::hdr.cause_ie_10b.spare2 if egress::hdr.cause_ie_10b.$valid - # - bit[2]: egress::hdr.cause_ie_10b.pce if egress::hdr.cause_ie_10b.$valid - # - bit[1]: egress::hdr.cause_ie_10b.bce if egress::hdr.cause_ie_10b.$valid - # - bit[0]: egress::hdr.cause_ie_10b.cs if egress::hdr.cause_ie_10b.$valid - TH11: W48(7) - # - bit[15..8]: egress::hdr.cause_ie_10b.type_oe if egress::hdr.cause_ie_10b.$valid - # - bit[7..0]: egress::hdr.cause_ie_10b.len_oe.8-15 if egress::hdr.cause_ie_10b.$valid - TH10: W48(7) - # - bit[15..8]: egress::hdr.cause_ie_10b.len_oe.0-7 if egress::hdr.cause_ie_10b.$valid - # - bit[7..4]: egress::hdr.cause_ie_10b.spare_oe if egress::hdr.cause_ie_10b.$valid - # - bit[3..0]: egress::hdr.cause_ie_10b.instance_oe if egress::hdr.cause_ie_10b.$valid - TW6: W48(5) - # - bit[31..24]: egress::hdr.imsi.type if egress::hdr.imsi.$valid - # - bit[23..8]: egress::hdr.imsi.len if egress::hdr.imsi.$valid - # - bit[7..4]: egress::hdr.imsi.spare if egress::hdr.imsi.$valid - # - bit[3..0]: egress::hdr.imsi.instance if egress::hdr.imsi.$valid - TH30: W48(5) # egress::hdr.imsi.num_digit.112-127 if egress::hdr.imsi.$valid - TB29: W48(5) # egress::hdr.imsi.num_digit.104-111 if egress::hdr.imsi.$valid - TB20: W48(5) # egress::hdr.imsi.num_digit.96-103 if egress::hdr.imsi.$valid - TW29: W48(5) # egress::hdr.imsi.num_digit.64-95 if egress::hdr.imsi.$valid - TW28: W48(5) # egress::hdr.imsi.num_digit.32-63 if egress::hdr.imsi.$valid - TW21: W48(5) # egress::hdr.imsi.num_digit.0-31 if egress::hdr.imsi.$valid - TW5: W48(17) - # - bit[31..24]: egress::hdr.vxlan.flags if egress::hdr.vxlan.$valid - # - bit[23..0]: egress::hdr.vxlan.reserved if egress::hdr.vxlan.$valid - TH9: W48(17) # egress::hdr.vxlan.vni.8-23 if egress::hdr.vxlan.$valid - TH8: W48(17) - # - bit[15..8]: egress::hdr.vxlan.vni.0-7 if egress::hdr.vxlan.$valid - # - bit[7..0]: egress::hdr.vxlan.reserved2 if egress::hdr.vxlan.$valid - TW30: W48(18) # egress::hdr.inner_ethernet.dst_addr.16-47 if egress::hdr.inner_ethernet.$valid - TB5: W48(18) # egress::hdr.inner_ethernet.dst_addr.8-15 if egress::hdr.inner_ethernet.$valid - TB4: W48(18) # egress::hdr.inner_ethernet.dst_addr.0-7 if egress::hdr.inner_ethernet.$valid - TH47: W48(18) # egress::hdr.inner_ethernet.src_addr.32-47 if egress::hdr.inner_ethernet.$valid - TH34: W48(18) # egress::hdr.inner_ethernet.src_addr.16-31 if egress::hdr.inner_ethernet.$valid - TH33: W48(18) # egress::hdr.inner_ethernet.src_addr.0-15 if egress::hdr.inner_ethernet.$valid - TH10: W48(18) # egress::hdr.inner_ethernet.ether_type if egress::hdr.inner_ethernet.$valid - TW6: W48(8) - # - bit[31..28]: egress::hdr.inner_ipv4.version if egress::hdr.inner_ipv4.$valid - # - bit[27..24]: egress::hdr.inner_ipv4.ihl if egress::hdr.inner_ipv4.$valid - # - bit[23..16]: egress::hdr.inner_ipv4.diffserv if egress::hdr.inner_ipv4.$valid - # - bit[15..0]: egress::hdr.inner_ipv4.total_len if egress::hdr.inner_ipv4.$valid - TH30: W48(8) # egress::hdr.inner_ipv4.identification if egress::hdr.inner_ipv4.$valid - TH11: W48(8) - # - bit[15..13]: egress::hdr.inner_ipv4.flags if egress::hdr.inner_ipv4.$valid - # - bit[12..0]: egress::hdr.inner_ipv4.frag_offset if egress::hdr.inner_ipv4.$valid - TW21: W48(8) - # - bit[31..24]: egress::hdr.inner_ipv4.ttl if egress::hdr.inner_ipv4.$valid - # - bit[23..16]: egress::hdr.inner_ipv4.protocol if egress::hdr.inner_ipv4.$valid - # - bit[15..0]: egress::hdr.inner_ipv4.hdr_checksum if egress::hdr.inner_ipv4.$valid - TB31: W48(8) # egress::hdr.inner_ipv4.src_addr.24-31 if egress::hdr.inner_ipv4.$valid - TB30: W48(8) # egress::hdr.inner_ipv4.src_addr.16-23 if egress::hdr.inner_ipv4.$valid - TB29: W48(8) # egress::hdr.inner_ipv4.src_addr.8-15 if egress::hdr.inner_ipv4.$valid - TB20: W48(8) # egress::hdr.inner_ipv4.src_addr.0-7 if egress::hdr.inner_ipv4.$valid - W18: W48(8) # egress::hdr.inner_ipv4.dst_addr if egress::hdr.inner_ipv4.$valid - TW6: W48(14) - # - bit[31..28]: egress::hdr.inner_ipv6.version if egress::hdr.inner_ipv6.$valid - # - bit[27..20]: egress::hdr.inner_ipv6.traffic_class if egress::hdr.inner_ipv6.$valid - # - bit[19..0]: egress::hdr.inner_ipv6.flow_label if egress::hdr.inner_ipv6.$valid - TH11: W48(14) # egress::hdr.inner_ipv6.payload_len if egress::hdr.inner_ipv6.$valid - B19: W48(14) # egress::hdr.inner_ipv6.next_hdr if egress::hdr.inner_ipv6.$valid - TB20: W48(14) # egress::hdr.inner_ipv6.hop_limit if egress::hdr.inner_ipv6.$valid - W26: W48(14) # egress::hdr.inner_ipv6.src_addr.96-127 if egress::hdr.inner_ipv6.$valid - W25: W48(14) # egress::hdr.inner_ipv6.src_addr.64-95 if egress::hdr.inner_ipv6.$valid - W24: W48(14) # egress::hdr.inner_ipv6.src_addr.32-63 if egress::hdr.inner_ipv6.$valid - W18: W48(14) # egress::hdr.inner_ipv6.src_addr.0-31 if egress::hdr.inner_ipv6.$valid - W30: W48(14) # egress::hdr.inner_ipv6.dst_addr.96-127 if egress::hdr.inner_ipv6.$valid - W29: W48(14) # egress::hdr.inner_ipv6.dst_addr.64-95 if egress::hdr.inner_ipv6.$valid - W28: W48(14) # egress::hdr.inner_ipv6.dst_addr.32-63 if egress::hdr.inner_ipv6.$valid - W27: W48(14) # egress::hdr.inner_ipv6.dst_addr.0-31 if egress::hdr.inner_ipv6.$valid - TW7: W48(11) - # - bit[31..16]: egress::hdr.inner_udp.src_port if egress::hdr.inner_udp.$valid - # - bit[15..0]: egress::hdr.inner_udp.dst_port if egress::hdr.inner_udp.$valid - TW28: W48(11) - # - bit[31..16]: egress::hdr.inner_udp.hdr_length if egress::hdr.inner_udp.$valid - # - bit[15..0]: egress::hdr.inner_udp.checksum if egress::hdr.inner_udp.$valid - TW28: W48(9) - # - bit[31..16]: egress::hdr.inner_tcp.src_port if egress::hdr.inner_tcp.$valid - # - bit[15..0]: egress::hdr.inner_tcp.dst_port if egress::hdr.inner_tcp.$valid - W19: W48(9) # egress::hdr.inner_tcp.seq_no if egress::hdr.inner_tcp.$valid - W20: W48(9) # egress::hdr.inner_tcp.ack_no if egress::hdr.inner_tcp.$valid - TW7: W48(9) - # - bit[31..28]: egress::hdr.inner_tcp.data_offset if egress::hdr.inner_tcp.$valid - # - bit[27..24]: egress::hdr.inner_tcp.res if egress::hdr.inner_tcp.$valid - # - bit[23..16]: egress::hdr.inner_tcp.flags if egress::hdr.inner_tcp.$valid - # - bit[15..0]: egress::hdr.inner_tcp.window if egress::hdr.inner_tcp.$valid - TW29: W48(9) - # - bit[31..16]: egress::hdr.inner_tcp.checksum if egress::hdr.inner_tcp.$valid - # - bit[15..0]: egress::hdr.inner_tcp.urgent_ptr if egress::hdr.inner_tcp.$valid - TW7: W48(12) - # - bit[31..24]: egress::hdr.inner_icmp.type_ if egress::hdr.inner_icmp.$valid - # - bit[23..16]: egress::hdr.inner_icmp.code if egress::hdr.inner_icmp.$valid - # - bit[15..0]: egress::hdr.inner_icmp.hdr_checksum if egress::hdr.inner_icmp.$valid - W22: W48(13) # egress::hdr.ipsec_esp.spi if egress::hdr.ipsec_esp.$valid - W23: W48(13) # egress::hdr.ipsec_esp.sn if egress::hdr.ipsec_esp.$valid - W21: W48(10) # egress::hdr.sip.data if egress::hdr.sip.$valid - egress_unicast_port: H16(0..8) # bit[8..0]: egress::eg_intr_md.egress_port -stage 0 ingress: - dependency: match - phase0_match IgParser_inner_2.$PORT_METADATA: - p4: - name: IgParser_inner_2.$PORT_METADATA - size: 288 - preferred_match_type: exact - match_type: exact - size: 288 - p4_param_order: - ig_intr_md.ingress_port: { type: exact, size: 9 } - format: {ig_port_type: 56..58} - constant_value: 0 - actions: - set_port_metadata: - - handle: 0x20020000 - - p4_param_order: { ig_port_type: 3 } - hash_action tbl_compute_ip_hash 0: - p4: { name: tbl_compute_ip_hash, hidden: true } - row: 0 - bus: 0 - hash_dist: - 0: { hash: 0, mask: 0xffff, shift: 0 } - 1: { hash: 0, mask: 0xffff, shift: 0 } - input_xbar: - exact group 0: { 0: ig_md.lkp.ip_src_addr.0-31, 32: ig_md.lkp.ip_src_addr.32-63, 64: ig_md.lkp.ip_src_addr.64-95, 96: ig_md.lkp.ip_src_addr.96-127 } - exact group 1: { 0: ig_md.lkp.ip_dst_addr.0-31, 32: ig_md.lkp.ip_dst_addr.32-63, 64: ig_md.lkp.ip_dst_addr.64-95, 96: ig_md.lkp.ip_dst_addr.96-127 } - exact group 2: { 0: ig_md.lkp.l4_dst_port, 16: ig_md.lkp.l4_src_port, 32: ig_md.lkp.ip_proto } - hash 0: - 0..15: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 168: ig_md.lkp.ip_src_addr.0-31, 200: ig_md.lkp.ip_src_addr.32-63 }, { })), 0..15) - hash 1: - 0..15: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 232: ig_md.lkp.ip_src_addr.64-95, 264: ig_md.lkp.ip_src_addr.96-127 }, { })), 0..15) - hash 2: - 0..15: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 40: ig_md.lkp.ip_dst_addr.0-31, 72: ig_md.lkp.ip_dst_addr.32-63 }, { })), 0..15) - hash 3: - 0..15: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 104: ig_md.lkp.ip_dst_addr.64-95, 136: ig_md.lkp.ip_dst_addr.96-127 }, { })), 0..15) - hash 4: - 0..15: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 0: ig_md.lkp.l4_src_port, 16: ig_md.lkp.l4_dst_port, 32: ig_md.lkp.ip_proto }, { })), 0..15) - hash group 0: - table: [0, 1, 2, 3, 4] - seed: 0x7f64 - exact group 0: { 0: ig_md.lkp.ip_src_addr.0-31, 32: ig_md.lkp.ip_src_addr.32-63, 64: ig_md.lkp.ip_src_addr.64-95, 96: ig_md.lkp.ip_src_addr.96-127 } - exact group 1: { 0: ig_md.lkp.ip_dst_addr.0-31, 32: ig_md.lkp.ip_dst_addr.32-63, 64: ig_md.lkp.ip_dst_addr.64-95, 96: ig_md.lkp.ip_dst_addr.96-127 } - exact group 2: { 0: ig_md.lkp.l4_dst_port, 16: ig_md.lkp.l4_src_port, 32: ig_md.lkp.ip_proto } - hash 0: - 16..31: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 168: ig_md.lkp.ip_src_addr.0-31, 200: ig_md.lkp.ip_src_addr.32-63 }, { })), 16..31) - hash 1: - 16..31: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 232: ig_md.lkp.ip_src_addr.64-95, 264: ig_md.lkp.ip_src_addr.96-127 }, { })), 16..31) - hash 2: - 16..31: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 40: ig_md.lkp.ip_dst_addr.0-31, 72: ig_md.lkp.ip_dst_addr.32-63 }, { })), 16..31) - hash 3: - 16..31: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 104: ig_md.lkp.ip_dst_addr.64-95, 136: ig_md.lkp.ip_dst_addr.96-127 }, { })), 16..31) - hash 4: - 16..31: slice(stripe(crc_rev(0x82608edb, 0xffffffff, 0xffffffff, 296, { 0: ig_md.lkp.l4_src_port, 16: ig_md.lkp.l4_dst_port, 32: ig_md.lkp.ip_proto }, { })), 16..31) - hash group 0: - table: [0, 1, 2, 3, 4] - seed: 0x24d10000 - gateway: - name: tbl_compute_ip_hash-gateway - row: 2 - bus: 0 - unit: 1 - 0x0: cond-73 - miss: cond-73 - condition: - expression: "true(always hit)" - true: cond-73 - false: cond-73 - next: [] - action_bus: { 96..99 : hash_dist(0, 1) } - instruction: tbl_compute_ip_hash($DEFAULT, $DEFAULT) - actions: - compute_ip_hash(0, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000015 - - next_table: 0 - - set W2, hash_dist(0, 1, 0..31) - default_action: compute_ip_hash - gateway cond-73 1: - name: cond-73 - input_xbar: - exact group 2: { 64: ig_md.in_ig_port_type } - row: 4 - bus: 1 - unit: 0 - match: { 0: ig_md.in_ig_port_type } - 0b*****010: cn78_decap_inner_fabric_bfn_from_cn78 - miss: tbl_network_tap331 - condition: - expression: "(ig_md.in_ig_port_type == 2)" - true: cn78_decap_inner_fabric_bfn_from_cn78 - false: tbl_network_tap331 - ternary_match cn78_decap_inner_fabric_bfn_from_cn78 2: - p4: { name: Ig_inner_2.cn78_decap_inner.fabric_bfn_from_cn78, size: 1024 } - gateway: - name: cond-74 - input_xbar: - exact group 2: { 92: hdr.fabric_from_cn78.$valid } - row: 3 - bus: 1 - unit: 0 - match: { 4: hdr.fabric_from_cn78.$valid } - 0b***1: run_table - miss: cn78_decap_inner_handle_from_cn78_normal - condition: - expression: "(hdr.fabric_from_cn78.$valid == 1)" - true: cn78_decap_inner_fabric_bfn_from_cn78 - false: cn78_decap_inner_handle_from_cn78_normal - hit: [ cn78_decap_inner_handle_from_cn78_normal ] - miss: cn78_decap_inner_handle_from_cn78_normal - indirect: cn78_decap_inner_fabric_bfn_from_cn78$tind - ternary_indirect cn78_decap_inner_fabric_bfn_from_cn78$tind: - row: 1 - bus: 1 - format: { action: 0..0 } - instruction: cn78_decap_inner_fabric_bfn_from_cn78$tind(action, $DEFAULT) - actions: - Ig_inner_2.cn78_decap_inner.terminate_from_cn78_and_add_fabric(1, 2): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000001 - - next_table: 0 - - set hdr.fabric.$valid, 1 - - set hdr.ethernet.ether_type, 33278 - - set hdr.fabric.mc_index, 0 - - set hdr.fabric.is_hdr_decap, 0 - - set hdr.fabric.is_trunc_mir, 0 - - set ig_md.action_type, hdr.fabric_from_cn78.action_type - - set ig_md.port_group_id, hdr.fabric_from_cn78.port_group_id - - deposit-field W4(16..31), 0, W3 - default_action: Ig_inner_2.cn78_decap_inner.terminate_from_cn78_and_add_fabric - ternary_match tbl_network_tap331 3: - p4: { name: tbl_network_tap331 } - gateway: - name: cond-75 - input_xbar: - exact group 2: { 64: ig_md.in_ig_port_type } - row: 2 - bus: 1 - unit: 0 - match: { 0: ig_md.in_ig_port_type } - 0b*****011: run_table - miss: in_ipv6_t_acl$st0 - condition: - expression: "(ig_md.in_ig_port_type == 3)" - true: tbl_network_tap331 - false: in_ipv6_t_acl$st0 - hit: [ ip_hdr_location_locate ] - miss: ip_hdr_location_locate - indirect: tbl_network_tap331$tind - ternary_indirect tbl_network_tap331$tind: - row: 1 - bus: 0 - format: { action: 0..0 } - instruction: tbl_network_tap331$tind(action, $DEFAULT) - actions: - network_tap331(1, 3): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000007 - - next_table: 0 - - set ig_intr_md_for_tm.bypass_egress, 1 - default_action: network_tap331 - ternary_match in_ipv6_t_acl$st0 4: - p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } - hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } - ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } - ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } - hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } - row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - match: - - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } - - { group: 1, byte_config: 3, dirtcam: 0x155 } - - { group: 2, dirtcam: 0x155 } - - { group: 3, dirtcam: 0x155 } - - { group: 4, dirtcam: 0x155 } - - { group: 5, dirtcam: 0x155 } - - { group: 6, dirtcam: 0x155 } - - { group: 7, dirtcam: 0x55 } - gateway: - name: cond-76 - input_xbar: - exact group 2: { 78: hdr.inner_ipv6.$valid, 84: hdr.vlan_tag$0.$valid, 120: hdr.fabric.ig_port_type } - row: 1 - bus: 1 - unit: 1 - match: { 0: hdr.fabric.ig_port_type, 12: hdr.vlan_tag$0.$valid, 22: hdr.inner_ipv6.$valid } - 0b*1*********1*********001: run_table - miss: ip_hdr_location_locate - condition: - expression: "(hdr.fabric.ig_port_type == 1 && hdr.vlan_tag[0].$valid == 1 && hdr.inner_ipv6.$valid == 1)" - true: in_ipv6_t_acl$st0 - false: ip_hdr_location_locate - hit: [ ip_hdr_location_locate ] - miss: in_ipv6_t_acl$st1 - indirect: in_ipv6_t_acl$st0$tind - ternary_indirect in_ipv6_t_acl$st0$tind: - row: 0 - bus: 0 - column: 2 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - format: { action: 0..5 } - action: in_ipv6_t_acl$st0$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_t_acl$st0$tind(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000008 - - next_table: 0 - - { } - Ig_inner_2.in_ipv6_t.drop(4, 4): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000009 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.drop_and_count(6, 6): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000a - - next_table: 0 - - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - bitmasked-set B4, $data0, B4 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.redirect_port(8, 8): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000b - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.redirect_port_and_count(10, 10): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000c - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_to_eg(12, 12): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000d - - next_table: 0 - - { } - - set W5(29..30), 3 - Ig_inner_2.in_ipv6_t.forward_and_modify_mac(14, 14): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000e - - next_table: 0 - - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(16, 16): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000f - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.set_mc(18, 18): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000010 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } - - set hdr.fabric.mc_index, mc_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir(20, 20): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000011 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(22, 22): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000012 - - next_table: 0 - - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set B4(0..2), $data0 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(24, 24): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000013 - - next_table: 0 - - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(26, 26): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000014 - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - default_action: NoAction - action in_ipv6_t_acl$st0$action_data: - p4: { name: Ig_inner_2.in_ipv6_t.acl$action } - row: 3 - column: 0 - vpns: [ 0 ] - home_row: - - 3 - format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } - format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 104..107 : $adf_f2, 108..111 : $adf_f3, 112..115 : $adf_f0, 116..119 : $adf_f1 } -stage 1 ingress: - dependency: match - exact_match cn78_decap_inner_handle_from_cn78_normal 1: - p4: { name: Ig_inner_2.cn78_decap_inner.handle_from_cn78_normal, size: 1024 } - p4_param_order: - ig_md.action_type: { type: exact, size: 8, full_size: 8 } - row: 4 - search_bus: 1 - result_bus: 0 - column: 11 - stash: - row: [ 4 ] - col: [ 11 ] - unit: [ 0 ] - ways: - - [0, 0, 0x0, [4, 11]] - input_xbar: - exact group 0: { 13: ig_md.action_type } - hash 0: - 0..2: ig_md.action_type(0..2) - 3..7: ig_md.action_type(3..7) - hash group 0: - table: [0] - seed: 0x0 - format: { action(0): 0..2, version(0): 112..115 } - match_group_map: [ [ 0 ] ] - hit: [ ip_hdr_location_locate ] - miss: ip_hdr_location_locate - action: cn78_decap_inner_handle_from_cn78_normal$action_data($DIRECT, $DEFAULT) - instruction: cn78_decap_inner_handle_from_cn78_normal(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000002 - - next_table: 0 - - { } - Ig_inner_2.cn78_decap_inner.set_duplication(1, 24): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000003 - - next_table: 0 - - { } - - set hdr.fabric.is_hit, 1 - - set hdr.fabric.mc_index, ig_md.port_group_id - Ig_inner_2.cn78_decap_inner.set_redirect(2, 26): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000004 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, ig_md.port_group_id - - bitmasked-set W5, $data0, W5 - Ig_inner_2.cn78_decap_inner.set_hdr_decap(3, 28): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000005 - - next_table: 0 - - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } - - bitmasked-set W5, $data0, W5 - Ig_inner_2.cn78_decap_inner.set_trunc_mir(4, 30): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000006 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W5, $data0, W5 - default_action: NoAction - action cn78_decap_inner_handle_from_cn78_normal$action_data: - p4: { name: Ig_inner_2.cn78_decap_inner.handle_from_cn78_normal$action } - row: 3 - column: 0 - vpns: [ 0 ] - home_row: - - 3 - format Ig_inner_2.cn78_decap_inner.set_redirect: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Ig_inner_2.cn78_decap_inner.set_hdr_decap: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Ig_inner_2.cn78_decap_inner.set_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63 } - action_bus: { 112..115 : $adf_f0, 116..119 : $adf_f1 } - ternary_match in_ipv6_t_acl$st1 0: - p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } - hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } - ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } - ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } - hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } - row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - match: - - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } - - { group: 1, byte_config: 3, dirtcam: 0x155 } - - { group: 2, dirtcam: 0x155 } - - { group: 3, dirtcam: 0x155 } - - { group: 4, dirtcam: 0x155 } - - { group: 5, dirtcam: 0x155 } - - { group: 6, dirtcam: 0x155 } - - { group: 7, dirtcam: 0x55 } - hit: [ ip_hdr_location_locate ] - miss: in_ipv6_t_acl$st2 - indirect: in_ipv6_t_acl$st1$tind - ternary_indirect in_ipv6_t_acl$st1$tind: - row: 0 - bus: 0 - column: 2 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - format: { action: 0..5 } - action: in_ipv6_t_acl$st1$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_t_acl$st1$tind(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000008 - - next_table: 0 - - { } - Ig_inner_2.in_ipv6_t.drop(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000009 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.drop_and_count(2, 2): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000a - - next_table: 0 - - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - bitmasked-set B4, $data0, B4 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.redirect_port(4, 4): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000b - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.redirect_port_and_count(6, 6): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000c - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_to_eg(8, 8): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000d - - next_table: 0 - - { } - - set W5(29..30), 3 - Ig_inner_2.in_ipv6_t.forward_and_modify_mac(10, 10): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000e - - next_table: 0 - - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000f - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.set_mc(14, 14): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000010 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } - - set hdr.fabric.mc_index, mc_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir(16, 16): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000011 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(18, 18): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000012 - - next_table: 0 - - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set B4(0..2), $data0 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(20, 20): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000013 - - next_table: 0 - - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(22, 22): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000014 - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - default_action: NoAction - action in_ipv6_t_acl$st1$action_data: - p4: { name: Ig_inner_2.in_ipv6_t.acl$action } - row: 2 - column: 2 - vpns: [ 0 ] - home_row: - - 2 - format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } - format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } -stage 2 ingress: - dependency: match - ternary_match in_ipv6_t_acl$st2 0: - p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } - hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } - ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } - ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } - hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } - row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - match: - - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } - - { group: 1, byte_config: 3, dirtcam: 0x155 } - - { group: 2, dirtcam: 0x155 } - - { group: 3, dirtcam: 0x155 } - - { group: 4, dirtcam: 0x155 } - - { group: 5, dirtcam: 0x155 } - - { group: 6, dirtcam: 0x155 } - - { group: 7, dirtcam: 0x55 } - hit: [ ip_hdr_location_locate ] - miss: in_ipv6_t_acl$st3 - indirect: in_ipv6_t_acl$st2$tind - ternary_indirect in_ipv6_t_acl$st2$tind: - row: 0 - bus: 0 - column: 2 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - format: { action: 0..5 } - action: in_ipv6_t_acl$st2$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_t_acl$st2$tind(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000008 - - next_table: 0 - - { } - Ig_inner_2.in_ipv6_t.drop(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000009 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.drop_and_count(2, 2): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000a - - next_table: 0 - - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - bitmasked-set B4, $data0, B4 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.redirect_port(4, 4): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000b - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.redirect_port_and_count(6, 6): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000c - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_to_eg(8, 8): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000d - - next_table: 0 - - { } - - set W5(29..30), 3 - Ig_inner_2.in_ipv6_t.forward_and_modify_mac(10, 10): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000e - - next_table: 0 - - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000f - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.set_mc(14, 14): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000010 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } - - set hdr.fabric.mc_index, mc_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir(16, 16): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000011 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(18, 18): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000012 - - next_table: 0 - - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set B4(0..2), $data0 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(20, 20): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000013 - - next_table: 0 - - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(22, 22): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000014 - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - default_action: NoAction - action in_ipv6_t_acl$st2$action_data: - p4: { name: Ig_inner_2.in_ipv6_t.acl$action } - row: 3 - column: 0 - vpns: [ 0 ] - home_row: - - 3 - format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } - format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } -stage 3 ingress: - dependency: match - ternary_match in_ipv6_t_acl$st3 0: - p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } - hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } - ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } - ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } - hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } - row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - match: - - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } - - { group: 1, byte_config: 3, dirtcam: 0x155 } - - { group: 2, dirtcam: 0x155 } - - { group: 3, dirtcam: 0x155 } - - { group: 4, dirtcam: 0x155 } - - { group: 5, dirtcam: 0x155 } - - { group: 6, dirtcam: 0x155 } - - { group: 7, dirtcam: 0x55 } - hit: [ ip_hdr_location_locate ] - miss: in_ipv6_t_acl$st4 - indirect: in_ipv6_t_acl$st3$tind - ternary_indirect in_ipv6_t_acl$st3$tind: - row: 0 - bus: 0 - column: 2 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - format: { action: 0..5 } - action: in_ipv6_t_acl$st3$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_t_acl$st3$tind(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000008 - - next_table: 0 - - { } - Ig_inner_2.in_ipv6_t.drop(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000009 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.drop_and_count(2, 2): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000a - - next_table: 0 - - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - bitmasked-set B4, $data0, B4 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.redirect_port(4, 4): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000b - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.redirect_port_and_count(6, 6): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000c - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_to_eg(8, 8): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000d - - next_table: 0 - - { } - - set W5(29..30), 3 - Ig_inner_2.in_ipv6_t.forward_and_modify_mac(10, 10): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000e - - next_table: 0 - - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000f - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.set_mc(14, 14): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000010 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } - - set hdr.fabric.mc_index, mc_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir(16, 16): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000011 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(18, 18): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000012 - - next_table: 0 - - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set B4(0..2), $data0 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(20, 20): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000013 - - next_table: 0 - - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(22, 22): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000014 - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - default_action: NoAction - action in_ipv6_t_acl$st3$action_data: - p4: { name: Ig_inner_2.in_ipv6_t.acl$action } - row: 3 - column: 0 - vpns: [ 0 ] - home_row: - - 3 - format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } - format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } -stage 4 ingress: - dependency: match - ternary_match in_ipv6_t_acl$st4 0: - p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } - hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } - ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } - ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } - hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } - row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - match: - - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } - - { group: 1, byte_config: 3, dirtcam: 0x155 } - - { group: 2, dirtcam: 0x155 } - - { group: 3, dirtcam: 0x155 } - - { group: 4, dirtcam: 0x155 } - - { group: 5, dirtcam: 0x155 } - - { group: 6, dirtcam: 0x155 } - - { group: 7, dirtcam: 0x55 } - hit: [ ip_hdr_location_locate ] - miss: in_ipv6_t_acl$st5 - indirect: in_ipv6_t_acl$st4$tind - ternary_indirect in_ipv6_t_acl$st4$tind: - row: 0 - bus: 0 - column: 2 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - format: { action: 0..5 } - action: in_ipv6_t_acl$st4$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_t_acl$st4$tind(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000008 - - next_table: 0 - - { } - Ig_inner_2.in_ipv6_t.drop(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000009 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.drop_and_count(2, 2): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000a - - next_table: 0 - - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - bitmasked-set B4, $data0, B4 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.redirect_port(4, 4): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000b - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.redirect_port_and_count(6, 6): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000c - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_to_eg(8, 8): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000d - - next_table: 0 - - { } - - set W5(29..30), 3 - Ig_inner_2.in_ipv6_t.forward_and_modify_mac(10, 10): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000e - - next_table: 0 - - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000f - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.set_mc(14, 14): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000010 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } - - set hdr.fabric.mc_index, mc_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir(16, 16): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000011 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(18, 18): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000012 - - next_table: 0 - - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set B4(0..2), $data0 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(20, 20): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000013 - - next_table: 0 - - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(22, 22): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000014 - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - default_action: NoAction - action in_ipv6_t_acl$st4$action_data: - p4: { name: Ig_inner_2.in_ipv6_t.acl$action } - row: 3 - column: 0 - vpns: [ 0 ] - home_row: - - 3 - format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } - format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } -stage 5 ingress: - dependency: match - ternary_match in_ipv6_t_acl$st5 0: - p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } - hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } - ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } - ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } - hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } - row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - match: - - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } - - { group: 1, byte_config: 3, dirtcam: 0x155 } - - { group: 2, dirtcam: 0x155 } - - { group: 3, dirtcam: 0x155 } - - { group: 4, dirtcam: 0x155 } - - { group: 5, dirtcam: 0x155 } - - { group: 6, dirtcam: 0x155 } - - { group: 7, dirtcam: 0x55 } - hit: [ ip_hdr_location_locate ] - miss: in_ipv6_t_acl$st6 - indirect: in_ipv6_t_acl$st5$tind - ternary_indirect in_ipv6_t_acl$st5$tind: - row: 0 - bus: 0 - column: 2 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - format: { action: 0..5 } - action: in_ipv6_t_acl$st5$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_t_acl$st5$tind(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000008 - - next_table: 0 - - { } - Ig_inner_2.in_ipv6_t.drop(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000009 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.drop_and_count(2, 2): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000a - - next_table: 0 - - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - bitmasked-set B4, $data0, B4 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.redirect_port(4, 4): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000b - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.redirect_port_and_count(6, 6): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000c - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_to_eg(8, 8): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000d - - next_table: 0 - - { } - - set W5(29..30), 3 - Ig_inner_2.in_ipv6_t.forward_and_modify_mac(10, 10): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000e - - next_table: 0 - - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000f - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.set_mc(14, 14): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000010 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } - - set hdr.fabric.mc_index, mc_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir(16, 16): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000011 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(18, 18): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000012 - - next_table: 0 - - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set B4(0..2), $data0 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(20, 20): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000013 - - next_table: 0 - - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(22, 22): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000014 - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - default_action: NoAction - action in_ipv6_t_acl$st5$action_data: - p4: { name: Ig_inner_2.in_ipv6_t.acl$action } - row: 3 - column: 0 - vpns: [ 0 ] - home_row: - - 3 - format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } - format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } -stage 6 ingress: - dependency: match - ternary_match in_ipv6_t_acl$st6 0: - p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } - hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } - ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } - ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } - hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } - row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - match: - - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } - - { group: 1, byte_config: 3, dirtcam: 0x155 } - - { group: 2, dirtcam: 0x155 } - - { group: 3, dirtcam: 0x155 } - - { group: 4, dirtcam: 0x155 } - - { group: 5, dirtcam: 0x155 } - - { group: 6, dirtcam: 0x155 } - - { group: 7, dirtcam: 0x55 } - hit: [ ip_hdr_location_locate ] - miss: in_ipv6_t_acl$st7 - indirect: in_ipv6_t_acl$st6$tind - ternary_indirect in_ipv6_t_acl$st6$tind: - row: 0 - bus: 0 - column: 2 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - format: { action: 0..5 } - action: in_ipv6_t_acl$st6$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_t_acl$st6$tind(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000008 - - next_table: 0 - - { } - Ig_inner_2.in_ipv6_t.drop(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000009 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.drop_and_count(2, 2): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000a - - next_table: 0 - - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - bitmasked-set B4, $data0, B4 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.redirect_port(4, 4): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000b - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.redirect_port_and_count(6, 6): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000c - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_to_eg(8, 8): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000d - - next_table: 0 - - { } - - set W5(29..30), 3 - Ig_inner_2.in_ipv6_t.forward_and_modify_mac(10, 10): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000e - - next_table: 0 - - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000f - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.set_mc(14, 14): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000010 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } - - set hdr.fabric.mc_index, mc_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir(16, 16): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000011 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(18, 18): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000012 - - next_table: 0 - - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set B4(0..2), $data0 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(20, 20): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000013 - - next_table: 0 - - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(22, 22): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000014 - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - default_action: NoAction - action in_ipv6_t_acl$st6$action_data: - p4: { name: Ig_inner_2.in_ipv6_t.acl$action } - row: 3 - column: 0 - vpns: [ 0 ] - home_row: - - 3 - format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } - format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } -stage 7 ingress: - dependency: match - ternary_match in_ipv6_t_acl$st7 0: - p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } - hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } - ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } - ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } - hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } - row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - match: - - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } - - { group: 1, byte_config: 3, dirtcam: 0x155 } - - { group: 2, dirtcam: 0x155 } - - { group: 3, dirtcam: 0x155 } - - { group: 4, dirtcam: 0x155 } - - { group: 5, dirtcam: 0x155 } - - { group: 6, dirtcam: 0x155 } - - { group: 7, dirtcam: 0x55 } - hit: [ ip_hdr_location_locate ] - miss: in_ipv6_t_acl$st8 - indirect: in_ipv6_t_acl$st7$tind - ternary_indirect in_ipv6_t_acl$st7$tind: - row: 0 - bus: 0 - column: 2 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - format: { action: 0..5 } - action: in_ipv6_t_acl$st7$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_t_acl$st7$tind(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000008 - - next_table: 0 - - { } - Ig_inner_2.in_ipv6_t.drop(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000009 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.drop_and_count(2, 2): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000a - - next_table: 0 - - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - bitmasked-set B4, $data0, B4 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.redirect_port(4, 4): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000b - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.redirect_port_and_count(6, 6): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000c - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_to_eg(8, 8): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000d - - next_table: 0 - - { } - - set W5(29..30), 3 - Ig_inner_2.in_ipv6_t.forward_and_modify_mac(10, 10): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000e - - next_table: 0 - - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000f - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.set_mc(14, 14): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000010 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } - - set hdr.fabric.mc_index, mc_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir(16, 16): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000011 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(18, 18): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000012 - - next_table: 0 - - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set B4(0..2), $data0 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(20, 20): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000013 - - next_table: 0 - - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(22, 22): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000014 - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - default_action: NoAction - action in_ipv6_t_acl$st7$action_data: - p4: { name: Ig_inner_2.in_ipv6_t.acl$action } - row: 3 - column: 0 - vpns: [ 0 ] - home_row: - - 3 - format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } - format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } -stage 8 ingress: - dependency: match - ternary_match in_ipv6_t_acl$st8 0: - p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } - hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } - ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } - ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } - hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } - row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - match: - - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } - - { group: 1, byte_config: 3, dirtcam: 0x155 } - - { group: 2, dirtcam: 0x155 } - - { group: 3, dirtcam: 0x155 } - - { group: 4, dirtcam: 0x155 } - - { group: 5, dirtcam: 0x155 } - - { group: 6, dirtcam: 0x155 } - - { group: 7, dirtcam: 0x55 } - hit: [ ip_hdr_location_locate ] - miss: in_ipv6_t_acl$st9 - indirect: in_ipv6_t_acl$st8$tind - ternary_indirect in_ipv6_t_acl$st8$tind: - row: 0 - bus: 0 - column: 4 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - format: { action: 0..5 } - action: in_ipv6_t_acl$st8$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_t_acl$st8$tind(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000008 - - next_table: 0 - - { } - Ig_inner_2.in_ipv6_t.drop(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000009 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.drop_and_count(2, 2): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000a - - next_table: 0 - - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - bitmasked-set B4, $data0, B4 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.redirect_port(4, 4): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000b - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.redirect_port_and_count(6, 6): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000c - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_to_eg(8, 8): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000d - - next_table: 0 - - { } - - set W5(29..30), 3 - Ig_inner_2.in_ipv6_t.forward_and_modify_mac(10, 10): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000e - - next_table: 0 - - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000f - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.set_mc(14, 14): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000010 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } - - set hdr.fabric.mc_index, mc_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir(16, 16): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000011 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(18, 18): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000012 - - next_table: 0 - - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set B4(0..2), $data0 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(20, 20): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000013 - - next_table: 0 - - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(22, 22): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000014 - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - default_action: NoAction - action in_ipv6_t_acl$st8$action_data: - p4: { name: Ig_inner_2.in_ipv6_t.acl$action } - row: 14 - column: 4 - vpns: [ 0 ] - home_row: - - 14 - format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } - format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } -stage 9 ingress: - dependency: match - ternary_match in_ipv6_t_acl$st9 0: - p4: { name: Ig_inner_2.in_ipv6_t.acl, size: 10240 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: ternary, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_src_addr" } - hdr.inner_ipv6.dst_addr: { type: ternary, size: 128, full_size: 128, key_name: "in_dst_addr" } - ig_md.lkp.inner_l4_src_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_src_port" } - ig_md.lkp.inner_l4_dst_port: { type: ternary, size: 16, full_size: 16, key_name: "in_l4_dst_port" } - hdr.inner_ipv6.next_hdr: { type: ternary, size: 8, full_size: 8, key_name: "in_ip_proto" } - row: [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - match: - - { group: 0, byte_group: 2, byte_config: 1, dirtcam: 0x555 } - - { group: 1, byte_config: 3, dirtcam: 0x155 } - - { group: 2, dirtcam: 0x155 } - - { group: 3, dirtcam: 0x155 } - - { group: 4, dirtcam: 0x155 } - - { group: 5, dirtcam: 0x155 } - - { group: 6, dirtcam: 0x155 } - - { group: 7, dirtcam: 0x55 } - hit: [ ip_hdr_location_locate ] - miss: ip_hdr_location_locate - indirect: in_ipv6_t_acl$st9$tind - ternary_indirect in_ipv6_t_acl$st9$tind: - row: 1 - bus: 0 - column: 4 - input_xbar: - ternary group 0: { 0: hdr.inner_ipv6.src_addr.0-31, 32: hdr.inner_ipv6.src_addr.32-63(0..7) } - ternary group 1: { 0: hdr.inner_ipv6.src_addr.32-63(16..31), 16: hdr.inner_ipv6.src_addr.64-95(0..7), 24: hdr.inner_ipv6.src_addr.32-63(8..15), 32: hdr.inner_ipv6.src_addr.64-95(16..23) } - ternary group 2: { 0: hdr.inner_ipv6.src_addr.64-95(24..31), 8: hdr.inner_ipv6.src_addr.96-127(0..7), 16: hdr.inner_ipv6.src_addr.64-95(8..15), 24: hdr.inner_ipv6.src_addr.96-127(16..31) } - ternary group 3: { 0: hdr.inner_ipv6.src_addr.96-127(8..15), 8: hdr.inner_ipv6.dst_addr.0-31(16..31), 24: hdr.inner_ipv6.dst_addr.0-31(0..15) } - ternary group 4: { 0: hdr.inner_ipv6.dst_addr.32-63(16..31), 16: hdr.inner_ipv6.dst_addr.32-63(0..15), 32: hdr.inner_ipv6.dst_addr.64-95(16..23) } - ternary group 5: { 0: hdr.inner_ipv6.dst_addr.64-95(0..15), 16: hdr.inner_ipv6.dst_addr.96-127(16..23), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.96-127(0..7) } - ternary group 6: { 0: hdr.inner_ipv6.dst_addr.96-127(8..15), 8: ig_md.lkp.inner_l4_src_port(0..7), 16: hdr.inner_ipv6.dst_addr.96-127(24..31), 24: ig_md.lkp.inner_l4_dst_port(0..7), 32: ig_md.lkp.inner_l4_src_port(8..15) } - ternary group 7: { 0: ig_md.lkp.inner_l4_dst_port(8..15), 8: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.next_hdr } - byte group 2: { 6: hdr.fabric.is_hit } - format: { action: 0..5 } - action: in_ipv6_t_acl$st9$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_t_acl$st9$tind(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000008 - - next_table: 0 - - { } - Ig_inner_2.in_ipv6_t.drop(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000009 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.drop_and_count(2, 2): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000a - - next_table: 0 - - { count_idx.0-15: $adf_f0(0..15), $data0: $adf_b2(0..3), count_idx.16-17: $data0(0..1), $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_b3(0..3), $constant1: $mask0(0..1), $constant1: 3, $constant2: $mask0(3..3), $constant2: 1, $data1: $adf_f2(28..30), $constant4: $data1(0..0), $constant4: 1, $constant3: $data1(2..2), $constant3: 1, $mask1: $adf_f3(28..30), $constant5: $mask1(0..0), $constant5: 1, $constant6: $mask1(2..2), $constant6: 1 } - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - bitmasked-set B4, $data0, B4 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.redirect_port(4, 4): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000b - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.redirect_port_and_count(6, 6): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000c - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_to_eg(8, 8): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000d - - next_table: 0 - - { } - - set W5(29..30), 3 - Ig_inner_2.in_ipv6_t.forward_and_modify_mac(10, 10): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000e - - next_table: 0 - - { $data0: $adf_f0(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f1(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000000f - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.set_mc(14, 14): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000010 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, mc_idx: $adf_f2(0..15) } - - set hdr.fabric.mc_index, mc_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir(16, 16): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000011 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt(18, 18): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000012 - - next_table: 0 - - { $data0: $adf_b0(0..2), count_idx.16-17: $data0(0..1), $constant0: $data0(2..2), $constant0: 1, $data1: $adf_f2(28..30), $constant2: $data1(0..0), $constant2: 1, $constant1: $data1(2..2), $constant1: 1, $mask0: $adf_f3(28..30), $constant3: $mask0(0..0), $constant3: 1, $constant4: $mask0(2..2), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set B4(0..2), $data0 - - bitmasked-set W5, $data1, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr(20, 20): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000013 - - next_table: 0 - - { $data0: $adf_f0(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f1(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f2(0..15) } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W5, $data0, W5 - Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt(22, 22): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000014 - - next_table: 0 - - { count_idx.16-17: $adf_b0(0..1), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, vlan_idx: $adf_f1(0..15), count_idx.0-15: $adf_f1(16..31) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index.0-15, count_idx.0-15 - - set hdr.fabric.count_index.16-17, count_idx.16-17 - - bitmasked-set W5, $data0, W5 - default_action: NoAction - action in_ipv6_t_acl$st9$action_data: - p4: { name: Ig_inner_2.in_ipv6_t.acl$action } - row: 14 - column: 4 - vpns: [ 0 ] - home_row: - - 14 - format Ig_inner_2.in_ipv6_t.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.drop_and_count: { $adf_f0: 0..31, $adf_b2: 16..23, $adf_b3: 24..31, $adf_f2: 64..95, $adf_f3: 96..127 } - format Ig_inner_2.in_ipv6_t.redirect_port: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.redirect_port_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_modify_mac: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_modify_mac_and_count: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.set_mc: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_trunc_mir_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Ig_inner_2.in_ipv6_t.forward_and_decap_pkt_hdr_and_cnt: { $adf_b0: 0..7, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 16 : $adf_b0, 18 : $adf_b2, 19 : $adf_b3, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } - ternary_match ip_hdr_location_locate 1: - p4: { name: Ig_inner_2.ip_hdr_location.locate, size: 2048 } - p4_param_order: - hdr.ethernet.$valid: { type: exact, size: 1, full_size: 1 } - hdr.vlan_tag$0.$valid: { type: ternary, size: 1, full_size: 1 } - hdr.vlan_tag$1.$valid: { type: ternary, size: 1, full_size: 1 } - hdr.vlan_tag$2.$valid: { type: ternary, size: 1, full_size: 1 } - hdr.vlan_tag$3.$valid: { type: ternary, size: 1, full_size: 1 } - hdr.mpls$0.$valid: { type: exact, size: 1, full_size: 1 } - hdr.ipv4.$valid: { type: exact, size: 1, full_size: 1 } - hdr.ipv6.$valid: { type: exact, size: 1, full_size: 1 } - hdr.tcp.$valid: { type: exact, size: 1, full_size: 1 } - hdr.udp.$valid: { type: exact, size: 1, full_size: 1 } - hdr.sctp.$valid: { type: exact, size: 1, full_size: 1 } - hdr.gre.$valid: { type: exact, size: 1, full_size: 1 } - hdr.pppoe.$valid: { type: exact, size: 1, full_size: 1 } - hdr.gtpv1_8b.$valid: { type: exact, size: 1, full_size: 1 } - hdr.gtpv1_12b.$valid: { type: exact, size: 1, full_size: 1 } - hdr.gtpv2_8b.$valid: { type: exact, size: 1, full_size: 1 } - hdr.gtpv2_12b.$valid: { type: exact, size: 1, full_size: 1 } - hdr.vxlan.$valid: { type: exact, size: 1, full_size: 1 } - hdr.inner_ethernet.$valid: { type: exact, size: 1, full_size: 1 } - hdr.inner_ipv4.$valid: { type: exact, size: 1, full_size: 1 } - hdr.inner_ipv6.$valid: { type: exact, size: 1, full_size: 1 } - row: [ 8, 9, 10, 11, 8, 9, 10, 11 ] - bus: [ 0, 0, 0, 0, 1, 1, 1, 1 ] - column: - - 0 - - 0 - - 0 - - 0 - - 1 - - 1 - - 1 - - 1 - input_xbar: - ternary group 8: { 1: hdr.ethernet.$valid, 2: hdr.ipv4.$valid, 3: hdr.tcp.$valid, 4: hdr.gtpv2_8b.$valid, 8: hdr.inner_ipv4.$valid, 14: hdr.inner_ipv6.$valid, 15: hdr.gtpv2_12b.$valid, 16: hdr.udp.$valid, 17: hdr.vxlan.$valid, 18: hdr.inner_ethernet.$valid, 19: hdr.gtpv1_8b.$valid, 20: hdr.gtpv1_12b.$valid, 22: hdr.pppoe.$valid, 24: hdr.sctp.$valid, 25: hdr.gre.$valid, 26: hdr.ipv6.$valid, 33: hdr.vlan_tag$3.$valid, 34: hdr.vlan_tag$2.$valid, 35: hdr.vlan_tag$1.$valid, 36: hdr.vlan_tag$0.$valid } - byte group 0: { 3: hdr.mpls$0.$valid } - match: - - { group: 8, byte_group: 0, byte_config: 0, dirtcam: 0x555 } - - { byte_config: 3, dirtcam: 0x0 } - hit: [ tbl_add_bridged_md_pipe_2 ] - miss: tbl_add_bridged_md_pipe_2 - indirect: ip_hdr_location_locate$tind - ternary_indirect ip_hdr_location_locate$tind: - row: 0 - bus: 0 - column: 4 - input_xbar: - ternary group 8: { 1: hdr.ethernet.$valid, 2: hdr.ipv4.$valid, 3: hdr.tcp.$valid, 4: hdr.gtpv2_8b.$valid, 8: hdr.inner_ipv4.$valid, 14: hdr.inner_ipv6.$valid, 15: hdr.gtpv2_12b.$valid, 16: hdr.udp.$valid, 17: hdr.vxlan.$valid, 18: hdr.inner_ethernet.$valid, 19: hdr.gtpv1_8b.$valid, 20: hdr.gtpv1_12b.$valid, 22: hdr.pppoe.$valid, 24: hdr.sctp.$valid, 25: hdr.gre.$valid, 26: hdr.ipv6.$valid, 33: hdr.vlan_tag$3.$valid, 34: hdr.vlan_tag$2.$valid, 35: hdr.vlan_tag$1.$valid, 36: hdr.vlan_tag$0.$valid } - byte group 0: { 3: hdr.mpls$0.$valid } - format: { action: 0..0, immediate: 1..24 } - action_bus: { 2 : immediate(16..23), 32..33 : immediate(0..15) } - instruction: ip_hdr_location_locate$tind(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000016 - - next_table: 0 - - { } - Ig_inner_2.ip_hdr_location.set_ip_hdr_location(1, 3): - - p4_param_order: { len_before_ip: 8, proto_type: 8, tunnel_type: 6, trunc_type: 2 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000017 - - next_table: 0 - - { $data0: immediate(0..15), len_before_ip: $data0(0..7), proto_type: $data0(8..15), tunnel_type.0-4: immediate(16..20), trunc_type: immediate(21..22), tunnel_type.5-5: immediate(23..23) } - - set ig_md.tunnel_type.0-4, tunnel_type.0-4 - - set ig_md.tunnel_type.5-5, tunnel_type.5-5 - - set ig_md.trunc_type, trunc_type - - set H3, $data0 - default_action: NoAction - ternary_match tbl_add_bridged_md_pipe_2 2: - p4: { name: tbl_add_bridged_md_pipe_2 } - gateway: - name: cond-79 - input_xbar: - exact group 0: { 5: ig_intr_md_for_tm.bypass_egress } - row: 0 - bus: 1 - unit: 0 - match: { 5: ig_intr_md_for_tm.bypass_egress } - 0b**0: run_table - miss: lag_inner_last_lag - condition: - expression: "(ig_intr_md_for_tm.bypass_egress == 0)" - true: tbl_add_bridged_md_pipe_2 - false: lag_inner_last_lag - hit: [ lag_inner_last_lag ] - miss: lag_inner_last_lag - indirect: tbl_add_bridged_md_pipe_2$tind - ternary_indirect tbl_add_bridged_md_pipe_2$tind: - row: 0 - bus: 1 - format: { action: 0..0 } - instruction: tbl_add_bridged_md_pipe_2$tind(action, $DEFAULT) - actions: - add_bridged_md_pipe(1, 5): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x2000001e - - next_table: 0 - - set hdr.bridged_md.$valid, 1 - default_action: add_bridged_md_pipe -stage 10 ingress: - dependency: match - exact_match lag_inner_last_lag 1: - p4: { name: Ig_inner_2.lag_inner_last.lag, size: 256, action_profile: Ig_inner_2.lag_inner_last.lag_selector } - p4_param_order: - hdr.fabric.is_to_cn78: { type: exact, size: 1, full_size: 1, key_name: "is_to_cn78" } - hdr.fabric.is_to_td3: { type: exact, size: 1, full_size: 1, key_name: "is_to_td3" } - row: 1 - search_bus: 1 - result_bus: 0 - column: 6 - stash: - row: [ 1 ] - col: [ 6 ] - unit: [ 0 ] - ways: - - [1, 0, 0x0, [1, 6]] - input_xbar: - exact group 1: { 92: hdr.fabric.is_to_td3, 93: hdr.fabric.is_to_cn78 } - hash 3: - 0: hdr.fabric.is_to_td3 - 1: hdr.fabric.is_to_cn78 - hash group 1: - table: [3] - seed: 0x0 - format: { action(0): 0..1, version(0): 112..115, meter_addr(0): 2..11, meter_pfe(0): 12..12, action_addr(0): 13..23 } - match_group_map: [ [ 0 ] ] - gateway: - name: cond-78 - input_xbar: - exact group 1: { 32: hdr.fabric.mc_index } - row: 1 - bus: 1 - unit: 0 - match: { 0: hdr.fabric.mc_index(0..7), 8: hdr.fabric.mc_index(8..15) } - 0x0000: run_table - miss: truncate_mirror - condition: - expression: "(hdr.fabric.mc_index == 0)" - true: lag_inner_last_lag - false: truncate_mirror - hit: [ truncate_mirror ] - miss: truncate_mirror - selector: lag_inner_last_lag$selector.Ig_inner_2.lag_inner_last.lag_selector_sel(meter_addr, meter_pfe, $DEFAULT) - selector_length: lag_inner_last_lag$selector.Ig_inner_2.lag_inner_last.lag_selector_sel($DEFAULT, $DEFAULT) - action: lag_inner_last_lag$action_data.Ig_inner_2.lag_inner_last.lag_selector(action_addr, $DEFAULT) - instruction: lag_inner_last_lag(action, $DEFAULT) - actions: - Ig_inner_2.lag_inner_last.lag_miss(1, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x2000001c - - next_table: 0 - - { } - Ig_inner_2.lag_inner_last.set_lag_port(2, 1): - - p4_param_order: { port: 9 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000001d - - next_table: 0 - - { port: $adf_h0(0..8) } - - set ig_intr_md_for_tm.ucast_egress_port, port - default_action: Ig_inner_2.lag_inner_last.lag_miss - selection lag_inner_last_lag$selector.Ig_inner_2.lag_inner_last.lag_selector_sel: - p4: { name: Ig_inner_2.lag_inner_last.lag_selector_sel, size: 4 } - row: 15 - column: [ 3, 4 ] - maprams: [ 3, 4 ] - input_xbar: - exact group 2: { 0: ig_md.hash(0..15) } - hash 4: - 0..13: ig_md.hash(0..13) - hash group 2: - table: [4] - seed: 0x0 - mode: fair 0 - non_linear: true - pool_sizes: [120] - action lag_inner_last_lag$action_data.Ig_inner_2.lag_inner_last.lag_selector: - p4: { name: Ig_inner_2.lag_inner_last.lag_selector, size: 1024 } - row: 13 - column: 3 - vpns: [ 0 ] - home_row: - - 13 - format Ig_inner_2.lag_inner_last.set_lag_port: { $adf_h0: 0..15 } - action_bus: { 36..37 : $adf_h0 } - stateful lag_inner_last_lag$salu.Ig_inner_2.lag_inner_last.lag_selector_sel$salu: - p4: { name: Ig_inner_2.lag_inner_last.lag_selector_sel$salu, size: 131072, hidden: true } - selection_table: lag_inner_last_lag$selector.Ig_inner_2.lag_inner_last.lag_selector_sel - row: 15 - column: [ 3, 4 ] - maprams: [ 3, 4 ] - format: { lo: 1 } - actions: - set_bit_at_alu$0: - - set_bit_at - clr_bit_at_alu$0: - - clr_bit_at -stage 11 ingress: - dependency: concurrent - exact_match truncate_mirror 0: - p4: { name: Ig_inner_2.truncate.mirror, size: 512, action_profile: Ig_inner_2.truncate.lag_selector } - p4_param_order: - ig_md.trunc_type: { type: exact, size: 2, full_size: 2, key_name: "trunc_type" } - row: 5 - bus: 1 - column: 4 - stash: - row: [ 5 ] - col: [ 4 ] - unit: [ 0 ] - ways: - - [0, 0, 0x0, [5, 4]] - input_xbar: - exact group 0: { 6: ig_md.trunc_type } - hash 0: - 0..1: ig_md.trunc_type - hash group 0: - table: [0] - seed: 0x0 - format: { action(0): 0..1, version(0): 112..115, meter_addr(0): 2..11, meter_pfe(0): 12..12, action_addr(0): 13..23 } - match_group_map: [ [ 0 ] ] - gateway: - name: cond-77 - input_xbar: - exact group 0: { 10: hdr.fabric.is_trunc_mir } - row: 5 - bus: 1 - unit: 0 - match: { 2: hdr.fabric.is_trunc_mir } - 0b*****1: run_table - miss: mc_duplicate - condition: - expression: "(hdr.fabric.is_trunc_mir == 1)" - true: truncate_mirror - false: mc_duplicate - hit: [ mc_duplicate ] - miss: mc_duplicate - selector: truncate_mirror$selector.Ig_inner_2.truncate.lag_selector_sel(meter_addr, meter_pfe, $DEFAULT) - selector_length: truncate_mirror$selector.Ig_inner_2.truncate.lag_selector_sel($DEFAULT, $DEFAULT) - action: truncate_mirror$action_data.Ig_inner_2.truncate.lag_selector(action_addr, $DEFAULT) - instruction: truncate_mirror(action, $DEFAULT) - actions: - NoAction(1, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x2000001a - - next_table: 0 - - { } - Ig_inner_2.truncate.set_lag_session(2, 1): - - p4_param_order: { session_id: 10 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000001b - - next_table: 0 - - { session_id: $adf_h0(0..9) } - - set ig_intr_md_for_dprsr.drop_ctl, 1 - - set ig_md.mirror.src, 1 - - set ig_md.mirror.type, 5 - - set ig_md.mirror.session_id, session_id - - set ig_intr_md_for_dprsr.mirror_type, 5 - default_action: NoAction - selection truncate_mirror$selector.Ig_inner_2.truncate.lag_selector_sel: - p4: { name: Ig_inner_2.truncate.lag_selector_sel, size: 4 } - row: 15 - column: [ 2, 3 ] - maprams: [ 2, 3 ] - input_xbar: - exact group 0: { 64: ig_md.hash(0..15) } - hash 1: - 0..13: ig_md.hash(0..13) - hash group 1: - table: [1] - seed: 0x0 - mode: fair 0 - non_linear: true - pool_sizes: [120] - action truncate_mirror$action_data.Ig_inner_2.truncate.lag_selector: - p4: { name: Ig_inner_2.truncate.lag_selector, size: 1024 } - row: 13 - column: 2 - vpns: [ 0 ] - home_row: - - 13 - format Ig_inner_2.truncate.set_lag_session: { $adf_h0: 0..15 } - action_bus: { 32..33 : $adf_h0 } - stateful truncate_mirror$salu.Ig_inner_2.truncate.lag_selector_sel$salu: - p4: { name: Ig_inner_2.truncate.lag_selector_sel$salu, size: 131072, hidden: true } - selection_table: truncate_mirror$selector.Ig_inner_2.truncate.lag_selector_sel - row: 15 - column: [ 2, 3 ] - maprams: [ 2, 3 ] - format: { lo: 1 } - actions: - set_bit_at_alu$0: - - set_bit_at - clr_bit_at_alu$0: - - clr_bit_at - exact_match mc_duplicate 1: - p4: { name: Ig_inner_2.mc.duplicate, size: 65536 } - p4_param_order: - hdr.fabric.mc_index: { type: exact, size: 16, full_size: 16 } - row: [ 7, 6, 5 ] - bus: [ 0, 0, 0 ] - column: - - [ 2, 3, 4, 5, 6, 7 ] - - [ 2, 3, 4, 5, 6, 7 ] - - [ 2, 3 ] - stash: - row: [ 7 ] - col: [ 2 ] - unit: [ 0 ] - ways: - - [2, 0, 0x1, [7, 2], [7, 3]] - - [2, 1, 0x2, [7, 4], [7, 5]] - - [2, 2, 0x4, [7, 6], [7, 7]] - - [2, 3, 0x8, [6, 2], [6, 3]] - - [2, 0, 0x1, [6, 4], [6, 5]] - - [2, 1, 0x2, [6, 6], [6, 7]] - - [2, 2, 0x4, [5, 2], [5, 3]] - input_xbar: - exact group 1: { 0: hdr.fabric.mc_index } - hash 2: - 0..7: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(0..7) - 8..9: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(8..9) - 40: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(10) - 11..18: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(0..7) - 19: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(8) - 10: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(10) - 41: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(9) - 22..29: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(0..7) - 20..21: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(9..10) - 42: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(8) - 33..39: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(0..6) - 30..32: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(8..10) - 43: random(hdr.fabric.mc_index(11..15)) ^ hdr.fabric.mc_index(7) - hash group 2: - table: [2] - seed: 0xf63800a4eec - format: { action(0): 0..0, version(0): 112..115, match(0): 35..39, action(1): 1..1, version(1): 116..119, match(1): 43..47, action(2): 2..2, version(2): 120..123, match(2): 51..55, action(3): 3..3, version(3): 124..127, match(3): 59..63, action(4): 4..4, version(4): 8..11, match(4): 67..71 } - match: [ hdr.fabric.mc_index(11..15) ] - match_group_map: [ [ 0, 1, 2, 3, 4 ] ] - hit: [ END ] - miss: END - action: mc_duplicate$action_data($DIRECT, $DEFAULT) - instruction: mc_duplicate(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000018 - - next_table: 0 - - { } - Ig_inner_2.mc.set_mgid(1, 2): - - p4_param_order: { mgid: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000019 - - next_table: 0 - - { mgid: $adf_h0(0..15) } - - set ig_intr_md_for_tm.mcast_grp_b, mgid - - set ig_intr_md_for_tm.level1_mcast_hash, ig_md.hash(0..12) - - set ig_intr_md_for_tm.level2_mcast_hash, ig_md.hash(16..28) - default_action: NoAction - action mc_duplicate$action_data: - p4: { name: Ig_inner_2.mc.duplicate$action } - row: [ 15, 13, 11 ] - word: [ 0, 0, 0 ] - column: - - [ 4, 5 ] - - [ 3, 4, 5 ] - - [ 0, 1, 2, 3 ] - vpns: - - [ 0, 1 ] - - [ 2, 3, 4 ] - - [ 5, 6, 7, 8 ] - home_row: - - 15 - format Ig_inner_2.mc.set_mgid: { $adf_h0: 0..15 } - action_bus: { 36..37 : $adf_h0 } -stage 0 egress: - dependency: match - gateway cond-80 5: - name: cond-80 - input_xbar: - exact group 2: { 96: eg_md.in_ig_port_type } - row: 1 - bus: 0 - unit: 0 - match: { 0: eg_md.in_ig_port_type } - 0b*****101: fabric_decap_inner_decap - miss: in_ipv6_e_acl_2$st0 - condition: - expression: "(eg_md.in_ig_port_type == 5)" - true: fabric_decap_inner_decap - false: in_ipv6_e_acl_2$st0 - ternary_match fabric_decap_inner_decap 6: - p4: { name: Eg_inner_2.fabric_decap_inner.decap, size: 128 } - gateway: - name: cond-81 - input_xbar: - exact group 3: { 27: hdr.fabric.$valid } - row: 0 - bus: 1 - unit: 1 - match: { 3: hdr.fabric.$valid } - 0b****1: run_table - miss: cn78_encap_inner_fabric_bfn_to_cn78 - condition: - expression: "(hdr.fabric.$valid == 1)" - true: fabric_decap_inner_decap - false: cn78_encap_inner_fabric_bfn_to_cn78 - hit: [ cn78_encap_inner_fabric_bfn_to_cn78 ] - miss: cn78_encap_inner_fabric_bfn_to_cn78 - indirect: fabric_decap_inner_decap$tind - ternary_indirect fabric_decap_inner_decap$tind: - row: 0 - bus: 1 - format: { action: 0..0 } - instruction: fabric_decap_inner_decap$tind(action, $DEFAULT) - actions: - Eg_inner_2.fabric_decap_inner.remove_fabric(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x2000001f - - next_table: 0 - - set hdr.fabric.$valid, 0 - - set hdr.ethernet.ether_type, hdr.fabric.ether_type - default_action: Eg_inner_2.fabric_decap_inner.remove_fabric - exact_match in_ipv6_e_acl_2$st0 7: - p4: { name: Eg_inner_2.in_ipv6_e.acl, size: 38912 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } - hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } - eg_md.lkp.inner_l4_src_port: { type: exact, size: 16, full_size: 16, key_name: "in_l4_src_port" } - eg_md.lkp.inner_l4_dst_port: { type: exact, size: 16, full_size: 16, key_name: "in_l4_dst_port" } - hdr.inner_ipv6.next_hdr: { type: exact, size: 8, full_size: 8, key_name: "in_ip_proto" } - row: [ 5, 6, 7, 2, 3, 4 ] - bus: [ 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - stash: - row: [ 5, 6, 7 ] - col: [ 2, 2, 2 ] - unit: [ 0, 0, 0 ] - ways: - - [1, 0, 0x3, [7, 2], [6, 2], [5, 2], [7, 3], [6, 3], [5, 3], [7, 4], [6, 4], [5, 4], [7, 5], [6, 5], [5, 5]] - - [1, 1, 0xc, [7, 6], [6, 6], [5, 6], [7, 7], [6, 7], [5, 7], [7, 8], [6, 8], [5, 8], [7, 9], [6, 9], [5, 9]] - - [1, 2, 0x30, [7, 10], [6, 10], [5, 10], [7, 11], [6, 11], [5, 11], [4, 2], [3, 2], [2, 2], [4, 3], [3, 3], [2, 3]] - - [1, 3, 0xc0, [4, 4], [3, 4], [2, 4], [4, 5], [3, 5], [2, 5], [4, 6], [3, 6], [2, 6], [4, 7], [3, 7], [2, 7]] - - [1, 0, 0x1, [4, 8], [3, 8], [2, 8], [4, 9], [3, 9], [2, 9]] - - [1, 1, 0x0, [4, 10], [3, 10], [2, 10]] - input_xbar: - exact group 3: { 0: hdr.inner_ipv6.src_addr.0-31(0..23), 32: hdr.inner_ipv6.src_addr.32-63(0..23), 62: hdr.fabric.is_hit, 64: hdr.inner_ipv6.src_addr.64-95(0..23), 88: hdr.inner_ipv6.src_addr.0-31(24..31), 96: hdr.inner_ipv6.src_addr.96-127(0..23), 120: hdr.inner_ipv6.src_addr.32-63(24..31) } - exact group 4: { 0: hdr.inner_ipv6.dst_addr.0-31(0..23), 24: hdr.inner_ipv6.src_addr.64-95(24..31), 32: hdr.inner_ipv6.dst_addr.32-63(0..23), 56: hdr.inner_ipv6.src_addr.96-127(24..31), 64: hdr.inner_ipv6.dst_addr.64-95(0..23), 88: hdr.inner_ipv6.dst_addr.0-31(24..31), 96: hdr.inner_ipv6.dst_addr.96-127(0..23), 120: hdr.inner_ipv6.dst_addr.32-63(24..31) } - exact group 5: { 0: hdr.vlan_tag$0.vid, 16: eg_md.lkp.inner_l4_src_port(0..7), 24: hdr.inner_ipv6.dst_addr.64-95(24..31), 32: eg_md.lkp.inner_l4_dst_port(0..7), 40: eg_md.lkp.inner_l4_src_port(8..15), 48: hdr.inner_ipv6.next_hdr, 56: hdr.inner_ipv6.dst_addr.96-127(24..31), 72: eg_md.lkp.inner_l4_dst_port(8..15) } - hash 6: - 0..9: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.fabric.is_hit) - 40..41: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.fabric.is_hit) - 10..19: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.fabric.is_hit) - 42..43: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.fabric.is_hit) - 20..29: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.fabric.is_hit) - 44..45: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.fabric.is_hit) - 30..39: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.fabric.is_hit) - 46..47: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.fabric.is_hit) - hash 7: - 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.32-63(24..31)) - 40..41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.32-63(24..31)) - 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.32-63(24..31)) - 42..43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.32-63(24..31)) - 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.32-63(24..31)) - 44..45: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.32-63(24..31)) - 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.32-63(24..31)) - 46..47: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.32-63(24..31)) - hash 8: - 0..9: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.src_addr.96-127(24..31)) - 40..41: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.src_addr.96-127(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.src_addr.96-127(24..31)) - 42..43: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.src_addr.96-127(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.src_addr.96-127(24..31)) - 44..45: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.src_addr.96-127(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.src_addr.96-127(24..31)) - 46..47: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.src_addr.96-127(24..31)) - hash 9: - 0..9: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31)) - 40..41: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31)) - 42..43: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31)) - 44..45: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31)) - 46..47: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31)) - hash 10: - 0..3: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) - 4..9: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..5) - 40..41: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - 11..14: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) - 15..19: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..4) - 10: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(5) - 42..43: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - 22..25: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) - 26..29: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..3) - 20..21: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(4..5) - 44..45: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - 33..36: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) - 37..39: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..2) - 30..32: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(3..5) - 46..47: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.64-95(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - hash 11: - 0..9: random(eg_md.lkp.inner_l4_dst_port(8..15)) - 40..41: random(eg_md.lkp.inner_l4_dst_port(8..15)) - 10..19: random(eg_md.lkp.inner_l4_dst_port(8..15)) - 42..43: random(eg_md.lkp.inner_l4_dst_port(8..15)) - 20..29: random(eg_md.lkp.inner_l4_dst_port(8..15)) - 44..45: random(eg_md.lkp.inner_l4_dst_port(8..15)) - 30..39: random(eg_md.lkp.inner_l4_dst_port(8..15)) - 46..47: random(eg_md.lkp.inner_l4_dst_port(8..15)) - hash group 1: - table: [6, 7, 8, 9, 10, 11] - seed: 0x923c1cbfc7f - format: { action(0): 0..5, version(0): 88..91, match(0): [94..95, 32..71, 246..246, 160..239, 128..135, 288..295, 136..159, 296..367, 256..279, 72..79, 280..287, 368..383, 80..87 ] } - match: [ hdr.inner_ipv6.next_hdr(6..7), hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_dst_port(8..15), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.0-31(0..7), hdr.inner_ipv6.src_addr.0-31(8..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] - match_group_map: [ [ 0 ], [ 0 ], [ 0 ] ] - gateway: - name: cond-83 - input_xbar: - exact group 5: { 68: hdr.vlan_tag$0.$valid, 88: hdr.fabric.ig_port_type, 110: hdr.inner_ipv6.$valid } - row: 0 - bus: 0 - unit: 0 - match: { 0: hdr.fabric.ig_port_type, 12: hdr.vlan_tag$0.$valid, 22: hdr.inner_ipv6.$valid } - 0b*1*********1*********001: run_table - miss: END - condition: - expression: "(hdr.fabric.ig_port_type == 1 && hdr.vlan_tag[0].$valid == 1 && hdr.inner_ipv6.$valid == 1)" - true: in_ipv6_e_acl_2$st0 - false: END - hit: [ END ] - miss: in_ipv6_e_acl_2$st1 - action: in_ipv6_e_acl_2$st0$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_e_acl_2$st0(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000021 - - next_table: 0 - - { } - Eg_inner_2.in_ipv6_e.drop(2, 2): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000022 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.drop_and_count(4, 4): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000023 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } - - bitmasked-set W16, $data0, W16 - - bitmasked-set W17, $data1, W17 - Eg_inner_2.in_ipv6_e.redirect_port(6, 6): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000024 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.redirect_port_and_count(8, 8): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000025 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_to_eg(10, 10): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000026 - - next_table: 0 - - { } - - set W16(29..30), 3 - Eg_inner_2.in_ipv6_e.forward_and_modify_mac(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000027 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(14, 14): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000028 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.set_mc(16, 16): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000029 - - next_table: 0 - - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.mc_index.0-7, mc_idx.0-7 - - set hdr.fabric.mc_index.8-15, mc_idx.8-15 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir(18, 18): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000002a - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(20, 20): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000002b - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - - set W17(8..26), $data1 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(22, 22): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000002c - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(24, 24): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000002d - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - default_action: NoAction - action in_ipv6_e_acl_2$st0$action_data: - p4: { name: Eg_inner_2.in_ipv6_e.acl$action } - row: [ 9, 7, 5, 3, 2, 1, 0 ] - word: [ 0, 0, 0, 0, 0, 0, 0 ] - column: - - 5 - - 5 - - 5 - - [ 1, 2, 3, 4, 5 ] - - [ 2, 3, 4, 5 ] - - [ 0, 1, 2, 3, 4, 5 ] - - 3 - vpns: - - [ 0 ] - - [ 1 ] - - [ 2 ] - - [ 3, 4, 5, 6, 7 ] - - [ 8, 9, 10, 11 ] - - [ 12, 13, 14, 15, 16, 17 ] - - [ 18 ] - home_row: - - 9 - format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 120..123 : $adf_f2, 124..127 : $adf_f3, 64..67 : $adf_f0, 68..71 : $adf_f1 } -stage 1 egress: - dependency: match - ternary_match cn78_encap_inner_fabric_bfn_to_cn78 2: - p4: { name: Eg_inner_2.cn78_encap_inner.fabric_bfn_to_cn78, size: 1024 } - gateway: - name: cond-82 - input_xbar: - exact group 0: { 29: hdr.fabric.is_to_cn78 } - row: 4 - bus: 1 - unit: 0 - match: { 5: hdr.fabric.is_to_cn78 } - 0b**1: run_table - miss: END - condition: - expression: "(hdr.fabric.is_to_cn78 == 1)" - true: cn78_encap_inner_fabric_bfn_to_cn78 - false: END - hit: [ END ] - miss: END - indirect: cn78_encap_inner_fabric_bfn_to_cn78$tind - ternary_indirect cn78_encap_inner_fabric_bfn_to_cn78$tind: - row: 0 - bus: 1 - format: { action: 0..0 } - instruction: cn78_encap_inner_fabric_bfn_to_cn78$tind(action, $DEFAULT) - actions: - Eg_inner_2.cn78_encap_inner.bfn_to_cn78(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000020 - - next_table: 0 - - set hdr.fabric_to_cn78.$valid, 1 - - set hdr.fabric_to_cn78.ether_type, hdr.ethernet.ether_type - - set hdr.ethernet.ether_type, 33279 - default_action: Eg_inner_2.cn78_encap_inner.bfn_to_cn78 - exact_match in_ipv6_e_acl_2$st1 3: - p4: { name: Eg_inner_2.in_ipv6_e.acl, size: 38912 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } - hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } - eg_md.lkp.inner_l4_src_port: { type: exact, size: 16, full_size: 16, key_name: "in_l4_src_port" } - eg_md.lkp.inner_l4_dst_port: { type: exact, size: 16, full_size: 16, key_name: "in_l4_dst_port" } - hdr.inner_ipv6.next_hdr: { type: exact, size: 8, full_size: 8, key_name: "in_ip_proto" } - row: [ 5, 6, 7, 2, 3, 4 ] - bus: [ 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - stash: - row: [ 5, 6, 7 ] - col: [ 2, 2, 2 ] - unit: [ 0, 0, 0 ] - ways: - - [1, 0, 0x3, [7, 2], [6, 2], [5, 2], [7, 3], [6, 3], [5, 3], [7, 4], [6, 4], [5, 4], [7, 5], [6, 5], [5, 5]] - - [1, 1, 0xc, [7, 6], [6, 6], [5, 6], [7, 7], [6, 7], [5, 7], [7, 8], [6, 8], [5, 8], [7, 9], [6, 9], [5, 9]] - - [1, 2, 0x30, [7, 10], [6, 10], [5, 10], [7, 11], [6, 11], [5, 11], [4, 2], [3, 2], [2, 2], [4, 3], [3, 3], [2, 3]] - - [1, 3, 0xc0, [4, 4], [3, 4], [2, 4], [4, 5], [3, 5], [2, 5], [4, 6], [3, 6], [2, 6], [4, 7], [3, 7], [2, 7]] - - [1, 0, 0x1, [4, 8], [3, 8], [2, 8], [4, 9], [3, 9], [2, 9]] - - [1, 1, 0x0, [4, 10], [3, 10], [2, 10]] - input_xbar: - exact group 1: { 0: hdr.inner_ipv6.src_addr.0-31(0..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.src_addr.32-63(0..23), 56: hdr.inner_ipv6.src_addr.0-31(24..31), 64: hdr.inner_ipv6.src_addr.64-95(0..23), 88: hdr.inner_ipv6.src_addr.32-63(24..31), 96: hdr.inner_ipv6.src_addr.96-127(0..23), 120: hdr.inner_ipv6.src_addr.64-95(24..31) } - exact group 2: { 0: hdr.inner_ipv6.dst_addr.0-31(0..23), 24: hdr.inner_ipv6.src_addr.96-127(24..31), 32: hdr.inner_ipv6.dst_addr.32-63(0..23), 56: hdr.inner_ipv6.dst_addr.0-31(24..31), 64: hdr.inner_ipv6.dst_addr.64-95(0..23), 88: hdr.inner_ipv6.dst_addr.32-63(24..31), 96: hdr.inner_ipv6.dst_addr.96-127(0..23), 120: hdr.inner_ipv6.dst_addr.64-95(24..31) } - exact group 3: { 0: hdr.vlan_tag$0.vid, 16: eg_md.lkp.inner_l4_src_port(0..7), 24: hdr.inner_ipv6.dst_addr.96-127(24..31), 32: eg_md.lkp.inner_l4_dst_port(0..7), 40: eg_md.lkp.inner_l4_src_port(8..15), 48: hdr.inner_ipv6.next_hdr, 56: eg_md.lkp.inner_l4_dst_port(8..15) } - hash 2: - 0..9: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 40..41: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 10..19: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 42..43: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 20..29: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 44..45: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 30..39: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 46..47: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - hash 3: - 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 40..41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 42..43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 44..45: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 46..47: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - hash 4: - 0..9: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 40..41: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 42..43: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 44..45: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 46..47: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - hash 5: - 0..9: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 40..41: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 42..43: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 44..45: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 46..47: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - hash 6: - 0..3: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..11) - 4..9: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.inner_ipv6.next_hdr(0..5) - 40..41: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) - 11..14: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..11) - 15..19: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.inner_ipv6.next_hdr(0..4) - 10: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.inner_ipv6.next_hdr(5) - 42..43: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) - 22..25: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..11) - 26..29: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.inner_ipv6.next_hdr(0..3) - 20..21: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.inner_ipv6.next_hdr(4..5) - 44..45: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) - 33..36: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..11) - 37..39: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.inner_ipv6.next_hdr(0..2) - 30..32: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.inner_ipv6.next_hdr(3..5) - 46..47: random(hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), hdr.inner_ipv6.next_hdr(6..7), eg_md.lkp.inner_l4_dst_port(8..15)) - hash group 1: - table: [2, 3, 4, 5, 6] - seed: 0x1d01fd8930e - format: { action(0): 0..5, version(0): 80..83, match(0): [86..87, 32..71, 254..254, 160..239, 128..159, 240..247, 288..367, 256..287, 368..383, 72..79 ] } - match: [ hdr.inner_ipv6.next_hdr(6..7), hdr.vlan_tag$0.vid(0..7), eg_md.lkp.inner_l4_src_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_dst_port(8..15), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.0-31(0..7), hdr.inner_ipv6.src_addr.0-31(8..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] - match_group_map: [ [ 0 ], [ 0 ], [ 0 ] ] - hit: [ END ] - miss: in_ipv6_e_acl_1$st0 - action: in_ipv6_e_acl_2$st1$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_e_acl_2$st1(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000021 - - next_table_miss: in_ipv6_e_acl_1$st0 - - next_table: 0 - - { } - Eg_inner_2.in_ipv6_e.drop(2, 2): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000022 - - next_table_miss: in_ipv6_e_acl_1$st0 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.drop_and_count(4, 4): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000023 - - next_table_miss: in_ipv6_e_acl_1$st0 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } - - bitmasked-set W16, $data0, W16 - - bitmasked-set W17, $data1, W17 - Eg_inner_2.in_ipv6_e.redirect_port(6, 6): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000024 - - next_table_miss: in_ipv6_e_acl_1$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.redirect_port_and_count(8, 8): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000025 - - next_table_miss: in_ipv6_e_acl_1$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_to_eg(10, 10): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000026 - - next_table_miss: in_ipv6_e_acl_1$st0 - - next_table: 0 - - { } - - set W16(29..30), 3 - Eg_inner_2.in_ipv6_e.forward_and_modify_mac(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000027 - - next_table_miss: in_ipv6_e_acl_1$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(14, 14): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000028 - - next_table_miss: in_ipv6_e_acl_1$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.set_mc(16, 16): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000029 - - next_table_miss: in_ipv6_e_acl_1$st0 - - next_table: 0 - - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.mc_index.0-7, mc_idx.0-7 - - set hdr.fabric.mc_index.8-15, mc_idx.8-15 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir(18, 18): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000002a - - next_table_miss: in_ipv6_e_acl_1$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(20, 20): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000002b - - next_table_miss: in_ipv6_e_acl_1$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - - set W17(8..26), $data1 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(22, 22): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000002c - - next_table_miss: in_ipv6_e_acl_1$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(24, 24): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000002d - - next_table_miss: in_ipv6_e_acl_1$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - default_action: NoAction - action in_ipv6_e_acl_2$st1$action_data: - p4: { name: Eg_inner_2.in_ipv6_e.acl$action } - row: [ 7, 5, 3, 2, 1, 0 ] - word: [ 0, 0, 0, 0, 0, 0 ] - column: - - 5 - - 5 - - [ 1, 2, 3, 4, 5 ] - - [ 3, 4, 5 ] - - [ 0, 1, 2, 3, 4, 5 ] - - [ 3, 4, 5 ] - vpns: - - [ 0 ] - - [ 1 ] - - [ 2, 3, 4, 5, 6 ] - - [ 7, 8, 9 ] - - [ 10, 11, 12, 13, 14, 15 ] - - [ 16, 17, 18 ] - home_row: - - 7 - format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 120..123 : $adf_f2, 124..127 : $adf_f3, 64..67 : $adf_f0, 68..71 : $adf_f1 } -stage 2 egress: - dependency: match - exact_match in_ipv6_e_acl_1$st0 1: - p4: { name: Eg_inner_2.in_ipv6_e.acl_4, size: 38912 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } - hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } - eg_md.lkp.inner_l4_src_port: { type: exact, size: 16, full_size: 16, key_name: "in_l4_src_port" } - eg_md.lkp.inner_l4_dst_port: { type: exact, size: 16, full_size: 16, key_name: "in_l4_dst_port" } - row: [ 5, 6, 7, 2, 3, 4 ] - bus: [ 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - stash: - row: [ 5, 6, 7 ] - col: [ 2, 2, 2 ] - unit: [ 0, 0, 0 ] - ways: - - [0, 0, 0x3, [7, 2], [6, 2], [5, 2], [7, 3], [6, 3], [5, 3], [7, 4], [6, 4], [5, 4], [7, 5], [6, 5], [5, 5]] - - [0, 1, 0xc, [7, 6], [6, 6], [5, 6], [7, 7], [6, 7], [5, 7], [7, 8], [6, 8], [5, 8], [7, 9], [6, 9], [5, 9]] - - [0, 2, 0x30, [7, 10], [6, 10], [5, 10], [7, 11], [6, 11], [5, 11], [4, 2], [3, 2], [2, 2], [4, 3], [3, 3], [2, 3]] - - [0, 3, 0xc0, [4, 4], [3, 4], [2, 4], [4, 5], [3, 5], [2, 5], [4, 6], [3, 6], [2, 6], [4, 7], [3, 7], [2, 7]] - - [0, 0, 0x1, [4, 8], [3, 8], [2, 8], [4, 9], [3, 9], [2, 9]] - - [0, 1, 0x0, [4, 10], [3, 10], [2, 10]] - input_xbar: - exact group 0: { 0: hdr.inner_ipv6.src_addr.0-31(0..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.src_addr.32-63(0..23), 56: hdr.inner_ipv6.src_addr.0-31(24..31), 64: hdr.inner_ipv6.src_addr.64-95(0..23), 88: hdr.inner_ipv6.src_addr.32-63(24..31), 96: hdr.inner_ipv6.src_addr.96-127(0..23), 120: hdr.inner_ipv6.src_addr.64-95(24..31) } - exact group 1: { 0: hdr.inner_ipv6.dst_addr.0-31(0..23), 24: hdr.inner_ipv6.src_addr.96-127(24..31), 32: hdr.inner_ipv6.dst_addr.32-63(0..23), 56: hdr.inner_ipv6.dst_addr.0-31(24..31), 64: hdr.inner_ipv6.dst_addr.64-95(0..23), 88: hdr.inner_ipv6.dst_addr.32-63(24..31), 96: hdr.inner_ipv6.dst_addr.96-127(0..23), 120: hdr.inner_ipv6.dst_addr.64-95(24..31) } - exact group 2: { 0: hdr.vlan_tag$0.vid, 16: eg_md.lkp.inner_l4_src_port(0..7), 24: hdr.inner_ipv6.dst_addr.96-127(24..31), 32: eg_md.lkp.inner_l4_dst_port(0..7), 40: eg_md.lkp.inner_l4_src_port(8..15), 56: eg_md.lkp.inner_l4_dst_port(8..15) } - hash 0: - 0..9: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 40..41: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 10..19: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 42..43: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 20..29: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 44..45: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 30..39: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 46..47: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - hash 1: - 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 40..41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 42..43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 44..45: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 46..47: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - hash 2: - 0..9: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 40..41: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 42..43: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 44..45: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 46..47: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - hash 3: - 0..9: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 40..41: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 42..43: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 44..45: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 46..47: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - hash 4: - 0..5: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(0..5) - 6..9: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..11) - 40..41: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) - 11..16: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(0..5) - 17..19: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..10) - 10: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(11) - 42..43: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) - 22..27: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(0..5) - 28..29: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..9) - 20..21: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(10..11) - 44..45: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) - 33..38: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(0..5) - 39: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8) - 30..32: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(9..11) - 46..47: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) - hash group 0: - table: [0, 1, 2, 3, 4] - seed: 0x7f91152fffff - format: { action(0): 0..5, version(0): 72..75, match(0): [78..79, 32..63, 254..254, 160..239, 128..159, 240..247, 288..367, 256..287, 368..383, 64..71 ] } - match: [ hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_dst_port(8..15), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.0-31(0..7), hdr.inner_ipv6.src_addr.0-31(8..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] - match_group_map: [ [ 0 ], [ 0 ], [ 0 ] ] - hit: [ END ] - miss: in_ipv6_e_acl_1$st1 - action: in_ipv6_e_acl_1$st0$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_e_acl_1$st0(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x2000002e - - next_table: 0 - - { } - Eg_inner_2.in_ipv6_e.drop(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000002f - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.drop_and_count(2, 2): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000030 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } - - bitmasked-set W16, $data0, W16 - - bitmasked-set W17, $data1, W17 - Eg_inner_2.in_ipv6_e.redirect_port(4, 4): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000031 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.redirect_port_and_count(6, 6): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000032 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_to_eg(8, 8): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000033 - - next_table: 0 - - { } - - set W16(29..30), 3 - Eg_inner_2.in_ipv6_e.forward_and_modify_mac(10, 10): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000034 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000035 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.set_mc(14, 14): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000036 - - next_table: 0 - - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.mc_index.0-7, mc_idx.0-7 - - set hdr.fabric.mc_index.8-15, mc_idx.8-15 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir(16, 16): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000037 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(18, 18): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000038 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - - set W17(8..26), $data1 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(20, 20): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000039 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(22, 22): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000003a - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - default_action: NoAction - action in_ipv6_e_acl_1$st0$action_data: - p4: { name: Eg_inner_2.in_ipv6_e.acl_4$action } - row: [ 9, 7, 5, 3, 2, 1, 0 ] - word: [ 0, 0, 0, 0, 0, 0, 0 ] - column: - - 5 - - 5 - - 5 - - [ 1, 2, 3, 4, 5 ] - - [ 2, 3, 4, 5 ] - - [ 0, 1, 2, 3, 4, 5 ] - - 3 - vpns: - - [ 0 ] - - [ 1 ] - - [ 2 ] - - [ 3, 4, 5, 6, 7 ] - - [ 8, 9, 10, 11 ] - - [ 12, 13, 14, 15, 16, 17 ] - - [ 18 ] - home_row: - - 9 - format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 112..115 : $adf_f2, 116..119 : $adf_f3, 120..123 : $adf_f0, 124..127 : $adf_f1 } -stage 3 egress: - dependency: match - exact_match in_ipv6_e_acl_1$st1 1: - p4: { name: Eg_inner_2.in_ipv6_e.acl_4, size: 38912 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } - hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } - eg_md.lkp.inner_l4_src_port: { type: exact, size: 16, full_size: 16, key_name: "in_l4_src_port" } - eg_md.lkp.inner_l4_dst_port: { type: exact, size: 16, full_size: 16, key_name: "in_l4_dst_port" } - row: [ 5, 6, 7, 2, 3, 4 ] - bus: [ 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - stash: - row: [ 5, 6, 7 ] - col: [ 2, 2, 2 ] - unit: [ 0, 0, 0 ] - ways: - - [0, 0, 0x3, [7, 2], [6, 2], [5, 2], [7, 3], [6, 3], [5, 3], [7, 4], [6, 4], [5, 4], [7, 5], [6, 5], [5, 5]] - - [0, 1, 0xc, [7, 6], [6, 6], [5, 6], [7, 7], [6, 7], [5, 7], [7, 8], [6, 8], [5, 8], [7, 9], [6, 9], [5, 9]] - - [0, 2, 0x30, [7, 10], [6, 10], [5, 10], [7, 11], [6, 11], [5, 11], [4, 2], [3, 2], [2, 2], [4, 3], [3, 3], [2, 3]] - - [0, 3, 0xc0, [4, 4], [3, 4], [2, 4], [4, 5], [3, 5], [2, 5], [4, 6], [3, 6], [2, 6], [4, 7], [3, 7], [2, 7]] - - [0, 0, 0x1, [4, 8], [3, 8], [2, 8], [4, 9], [3, 9], [2, 9]] - - [0, 1, 0x0, [4, 10], [3, 10], [2, 10]] - input_xbar: - exact group 0: { 0: hdr.inner_ipv6.src_addr.0-31(0..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.src_addr.32-63(0..23), 56: hdr.inner_ipv6.src_addr.0-31(24..31), 64: hdr.inner_ipv6.src_addr.64-95(0..23), 88: hdr.inner_ipv6.src_addr.32-63(24..31), 96: hdr.inner_ipv6.src_addr.96-127(0..23), 120: hdr.inner_ipv6.src_addr.64-95(24..31) } - exact group 1: { 0: hdr.inner_ipv6.dst_addr.0-31(0..23), 24: hdr.inner_ipv6.src_addr.96-127(24..31), 32: hdr.inner_ipv6.dst_addr.32-63(0..23), 56: hdr.inner_ipv6.dst_addr.0-31(24..31), 64: hdr.inner_ipv6.dst_addr.64-95(0..23), 88: hdr.inner_ipv6.dst_addr.32-63(24..31), 96: hdr.inner_ipv6.dst_addr.96-127(0..23), 120: hdr.inner_ipv6.dst_addr.64-95(24..31) } - exact group 2: { 0: hdr.vlan_tag$0.vid, 16: eg_md.lkp.inner_l4_src_port(0..7), 24: hdr.inner_ipv6.dst_addr.96-127(24..31), 32: eg_md.lkp.inner_l4_dst_port(0..7), 40: eg_md.lkp.inner_l4_src_port(8..15), 56: eg_md.lkp.inner_l4_dst_port(8..15) } - hash 0: - 0..9: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 40..41: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 10..19: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 42..43: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 20..29: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 44..45: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 30..39: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 46..47: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - hash 1: - 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 40..41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 42..43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 44..45: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 46..47: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - hash 2: - 0..9: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 40..41: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 42..43: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 44..45: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 46..47: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - hash 3: - 0..9: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 40..41: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 42..43: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 44..45: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 46..47: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - hash 4: - 0..5: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(0..5) - 6..9: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..11) - 40..41: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) - 11..16: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(0..5) - 17..19: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..10) - 10: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(11) - 42..43: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) - 22..27: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(0..5) - 28..29: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8..9) - 20..21: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(10..11) - 44..45: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) - 33..38: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(0..5) - 39: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(8) - 30..32: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) ^ hdr.vlan_tag$0.vid(9..11) - 46..47: random(hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), hdr.inner_ipv6.dst_addr.96-127(24..31), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(8..15)) - hash group 0: - table: [0, 1, 2, 3, 4] - seed: 0x472a058ede7f - format: { action(0): 0..5, version(0): 72..75, match(0): [78..79, 32..63, 254..254, 160..239, 128..159, 240..247, 288..367, 256..287, 368..383, 64..71 ] } - match: [ hdr.vlan_tag$0.vid(6..7), eg_md.lkp.inner_l4_src_port(0..7), eg_md.lkp.inner_l4_src_port(8..15), eg_md.lkp.inner_l4_dst_port(0..7), eg_md.lkp.inner_l4_dst_port(8..15), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.0-31(0..7), hdr.inner_ipv6.src_addr.0-31(8..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] - match_group_map: [ [ 0 ], [ 0 ], [ 0 ] ] - hit: [ END ] - miss: in_ipv6_e_acl_0$st0 - action: in_ipv6_e_acl_1$st1$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_e_acl_1$st1(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x2000002e - - next_table_miss: in_ipv6_e_acl_0$st0 - - next_table: 0 - - { } - Eg_inner_2.in_ipv6_e.drop(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000002f - - next_table_miss: in_ipv6_e_acl_0$st0 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.drop_and_count(2, 2): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000030 - - next_table_miss: in_ipv6_e_acl_0$st0 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } - - bitmasked-set W16, $data0, W16 - - bitmasked-set W17, $data1, W17 - Eg_inner_2.in_ipv6_e.redirect_port(4, 4): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000031 - - next_table_miss: in_ipv6_e_acl_0$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.redirect_port_and_count(6, 6): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000032 - - next_table_miss: in_ipv6_e_acl_0$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_to_eg(8, 8): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000033 - - next_table_miss: in_ipv6_e_acl_0$st0 - - next_table: 0 - - { } - - set W16(29..30), 3 - Eg_inner_2.in_ipv6_e.forward_and_modify_mac(10, 10): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000034 - - next_table_miss: in_ipv6_e_acl_0$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000035 - - next_table_miss: in_ipv6_e_acl_0$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.set_mc(14, 14): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000036 - - next_table_miss: in_ipv6_e_acl_0$st0 - - next_table: 0 - - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.mc_index.0-7, mc_idx.0-7 - - set hdr.fabric.mc_index.8-15, mc_idx.8-15 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir(16, 16): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000037 - - next_table_miss: in_ipv6_e_acl_0$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(18, 18): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000038 - - next_table_miss: in_ipv6_e_acl_0$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - - set W17(8..26), $data1 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(20, 20): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000039 - - next_table_miss: in_ipv6_e_acl_0$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(22, 22): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000003a - - next_table_miss: in_ipv6_e_acl_0$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - default_action: NoAction - action in_ipv6_e_acl_1$st1$action_data: - p4: { name: Eg_inner_2.in_ipv6_e.acl_4$action } - row: [ 9, 7, 5, 3, 2, 1, 0 ] - word: [ 0, 0, 0, 0, 0, 0, 0 ] - column: - - 5 - - 5 - - 5 - - [ 1, 2, 3, 4, 5 ] - - [ 2, 3, 4, 5 ] - - [ 0, 1, 2, 3, 4, 5 ] - - 3 - vpns: - - [ 0 ] - - [ 1 ] - - [ 2 ] - - [ 3, 4, 5, 6, 7 ] - - [ 8, 9, 10, 11 ] - - [ 12, 13, 14, 15, 16, 17 ] - - [ 18 ] - home_row: - - 9 - format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 112..115 : $adf_f2, 116..119 : $adf_f3, 120..123 : $adf_f0, 124..127 : $adf_f1 } -stage 4 egress: - dependency: match - exact_match in_ipv6_e_acl_0$st0 1: - p4: { name: Eg_inner_2.in_ipv6_e.acl_3, size: 38912 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } - hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } - hdr.inner_ipv6.next_hdr: { type: exact, size: 8, full_size: 8, key_name: "in_ip_proto" } - row: [ 5, 6, 7, 2, 3, 4 ] - bus: [ 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - stash: - row: [ 5, 6, 7 ] - col: [ 2, 2, 2 ] - unit: [ 0, 0, 0 ] - ways: - - [0, 0, 0x3, [7, 2], [6, 2], [5, 2], [7, 3], [6, 3], [5, 3], [7, 4], [6, 4], [5, 4], [7, 5], [6, 5], [5, 5]] - - [0, 1, 0xc, [7, 6], [6, 6], [5, 6], [7, 7], [6, 7], [5, 7], [7, 8], [6, 8], [5, 8], [7, 9], [6, 9], [5, 9]] - - [0, 2, 0x30, [7, 10], [6, 10], [5, 10], [7, 11], [6, 11], [5, 11], [4, 2], [3, 2], [2, 2], [4, 3], [3, 3], [2, 3]] - - [0, 3, 0xc0, [4, 4], [3, 4], [2, 4], [4, 5], [3, 5], [2, 5], [4, 6], [3, 6], [2, 6], [4, 7], [3, 7], [2, 7]] - - [0, 0, 0x1, [4, 8], [3, 8], [2, 8], [4, 9], [3, 9], [2, 9]] - - [0, 1, 0x0, [4, 10], [3, 10], [2, 10]] - input_xbar: - exact group 0: { 0: hdr.inner_ipv6.src_addr.0-31(0..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.src_addr.32-63(0..23), 56: hdr.inner_ipv6.src_addr.0-31(24..31), 64: hdr.inner_ipv6.src_addr.64-95(0..23), 88: hdr.inner_ipv6.src_addr.32-63(24..31), 96: hdr.inner_ipv6.src_addr.96-127(0..23), 120: hdr.inner_ipv6.src_addr.64-95(24..31) } - exact group 1: { 0: hdr.inner_ipv6.dst_addr.0-31(0..23), 24: hdr.inner_ipv6.src_addr.96-127(24..31), 32: hdr.inner_ipv6.dst_addr.32-63(0..23), 56: hdr.inner_ipv6.dst_addr.0-31(24..31), 64: hdr.inner_ipv6.dst_addr.64-95(0..23), 88: hdr.inner_ipv6.dst_addr.32-63(24..31), 96: hdr.inner_ipv6.dst_addr.96-127(0..23), 120: hdr.inner_ipv6.dst_addr.64-95(24..31) } - exact group 2: { 0: hdr.vlan_tag$0.vid, 16: hdr.inner_ipv6.next_hdr, 24: hdr.inner_ipv6.dst_addr.96-127(24..31) } - hash 0: - 0..9: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 40..41: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 10..19: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 42..43: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 20..29: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 44..45: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 30..39: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 46..47: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - hash 1: - 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 40..41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 42..43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 44..45: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 46..47: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - hash 2: - 0..9: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 40..41: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 42..43: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 44..45: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 46..47: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - hash 3: - 0..9: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 40..41: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 42..43: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 44..45: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 46..47: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - hash 4: - 0..3: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) - 4..9: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..5) - 40..41: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - 11..14: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) - 15..19: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..4) - 10: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(5) - 42..43: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - 22..25: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) - 26..29: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..3) - 20..21: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(4..5) - 44..45: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - 33..36: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) - 37..39: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..2) - 30..32: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(3..5) - 46..47: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - hash group 0: - table: [0, 1, 2, 3, 4] - seed: 0xfd025c2f5bff - format: { action(0): 0..5, version(0): 48..51, match(0): [54..55, 32..39, 254..254, 160..239, 128..159, 240..247, 288..367, 256..287, 368..383, 40..47 ] } - match: [ hdr.inner_ipv6.next_hdr(6..7), hdr.vlan_tag$0.vid(0..7), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.0-31(0..7), hdr.inner_ipv6.src_addr.0-31(8..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] - match_group_map: [ [ 0 ], [ 0 ], [ 0 ] ] - hit: [ END ] - miss: in_ipv6_e_acl_0$st1 - action: in_ipv6_e_acl_0$st0$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_e_acl_0$st0(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x2000003b - - next_table: 0 - - { } - Eg_inner_2.in_ipv6_e.drop(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000003c - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.drop_and_count(2, 2): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000003d - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } - - bitmasked-set W16, $data0, W16 - - bitmasked-set W17, $data1, W17 - Eg_inner_2.in_ipv6_e.redirect_port(4, 4): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000003e - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.redirect_port_and_count(6, 6): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000003f - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_to_eg(8, 8): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000040 - - next_table: 0 - - { } - - set W16(29..30), 3 - Eg_inner_2.in_ipv6_e.forward_and_modify_mac(10, 10): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000041 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000042 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.set_mc(14, 14): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000043 - - next_table: 0 - - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.mc_index.0-7, mc_idx.0-7 - - set hdr.fabric.mc_index.8-15, mc_idx.8-15 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir(16, 16): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000044 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(18, 18): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000045 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - - set W17(8..26), $data1 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(20, 20): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000046 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(22, 22): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000047 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - default_action: NoAction - action in_ipv6_e_acl_0$st0$action_data: - p4: { name: Eg_inner_2.in_ipv6_e.acl_3$action } - row: [ 9, 7, 5, 3, 2, 1, 0 ] - word: [ 0, 0, 0, 0, 0, 0, 0 ] - column: - - 5 - - 5 - - 5 - - [ 1, 2, 3, 4, 5 ] - - [ 2, 3, 4, 5 ] - - [ 0, 1, 2, 3, 4, 5 ] - - 3 - vpns: - - [ 0 ] - - [ 1 ] - - [ 2 ] - - [ 3, 4, 5, 6, 7 ] - - [ 8, 9, 10, 11 ] - - [ 12, 13, 14, 15, 16, 17 ] - - [ 18 ] - home_row: - - 9 - format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 112..115 : $adf_f2, 116..119 : $adf_f3, 120..123 : $adf_f0, 124..127 : $adf_f1 } -stage 5 egress: - dependency: match - exact_match in_ipv6_e_acl_0$st1 1: - p4: { name: Eg_inner_2.in_ipv6_e.acl_3, size: 38912 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } - hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } - hdr.inner_ipv6.next_hdr: { type: exact, size: 8, full_size: 8, key_name: "in_ip_proto" } - row: [ 5, 6, 7, 2, 3, 4 ] - bus: [ 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - stash: - row: [ 5, 6, 7 ] - col: [ 2, 2, 2 ] - unit: [ 0, 0, 0 ] - ways: - - [0, 0, 0x3, [7, 2], [6, 2], [5, 2], [7, 3], [6, 3], [5, 3], [7, 4], [6, 4], [5, 4], [7, 5], [6, 5], [5, 5]] - - [0, 1, 0xc, [7, 6], [6, 6], [5, 6], [7, 7], [6, 7], [5, 7], [7, 8], [6, 8], [5, 8], [7, 9], [6, 9], [5, 9]] - - [0, 2, 0x30, [7, 10], [6, 10], [5, 10], [7, 11], [6, 11], [5, 11], [4, 2], [3, 2], [2, 2], [4, 3], [3, 3], [2, 3]] - - [0, 3, 0xc0, [4, 4], [3, 4], [2, 4], [4, 5], [3, 5], [2, 5], [4, 6], [3, 6], [2, 6], [4, 7], [3, 7], [2, 7]] - - [0, 0, 0x1, [4, 8], [3, 8], [2, 8], [4, 9], [3, 9], [2, 9]] - - [0, 1, 0x0, [4, 10], [3, 10], [2, 10]] - input_xbar: - exact group 0: { 0: hdr.inner_ipv6.src_addr.0-31(0..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.src_addr.32-63(0..23), 56: hdr.inner_ipv6.src_addr.0-31(24..31), 64: hdr.inner_ipv6.src_addr.64-95(0..23), 88: hdr.inner_ipv6.src_addr.32-63(24..31), 96: hdr.inner_ipv6.src_addr.96-127(0..23), 120: hdr.inner_ipv6.src_addr.64-95(24..31) } - exact group 1: { 0: hdr.inner_ipv6.dst_addr.0-31(0..23), 24: hdr.inner_ipv6.src_addr.96-127(24..31), 32: hdr.inner_ipv6.dst_addr.32-63(0..23), 56: hdr.inner_ipv6.dst_addr.0-31(24..31), 64: hdr.inner_ipv6.dst_addr.64-95(0..23), 88: hdr.inner_ipv6.dst_addr.32-63(24..31), 96: hdr.inner_ipv6.dst_addr.96-127(0..23), 120: hdr.inner_ipv6.dst_addr.64-95(24..31) } - exact group 2: { 0: hdr.vlan_tag$0.vid, 16: hdr.inner_ipv6.next_hdr, 24: hdr.inner_ipv6.dst_addr.96-127(24..31) } - hash 0: - 0..9: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 40..41: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 10..19: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 42..43: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 20..29: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 44..45: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 30..39: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 46..47: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - hash 1: - 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 40..41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 42..43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 44..45: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 46..47: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - hash 2: - 0..9: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 40..41: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 42..43: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 44..45: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 46..47: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - hash 3: - 0..9: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 40..41: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 42..43: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 44..45: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 46..47: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - hash 4: - 0..3: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) - 4..9: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..5) - 40..41: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - 11..14: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) - 15..19: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..4) - 10: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(5) - 42..43: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - 22..25: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) - 26..29: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..3) - 20..21: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(4..5) - 44..45: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - 33..36: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) - 37..39: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(0..2) - 30..32: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.inner_ipv6.next_hdr(3..5) - 46..47: random(hdr.vlan_tag$0.vid(0..7), hdr.inner_ipv6.next_hdr(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - hash group 0: - table: [0, 1, 2, 3, 4] - seed: 0xa77436bffcbf - format: { action(0): 0..5, version(0): 48..51, match(0): [54..55, 32..39, 254..254, 160..239, 128..159, 240..247, 288..367, 256..287, 368..383, 40..47 ] } - match: [ hdr.inner_ipv6.next_hdr(6..7), hdr.vlan_tag$0.vid(0..7), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.0-31(0..7), hdr.inner_ipv6.src_addr.0-31(8..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] - match_group_map: [ [ 0 ], [ 0 ], [ 0 ] ] - hit: [ END ] - miss: in_ipv6_e_acl$st0 - action: in_ipv6_e_acl_0$st1$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_e_acl_0$st1(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x2000003b - - next_table_miss: in_ipv6_e_acl$st0 - - next_table: 0 - - { } - Eg_inner_2.in_ipv6_e.drop(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000003c - - next_table_miss: in_ipv6_e_acl$st0 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.drop_and_count(2, 2): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000003d - - next_table_miss: in_ipv6_e_acl$st0 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } - - bitmasked-set W16, $data0, W16 - - bitmasked-set W17, $data1, W17 - Eg_inner_2.in_ipv6_e.redirect_port(4, 4): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000003e - - next_table_miss: in_ipv6_e_acl$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.redirect_port_and_count(6, 6): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000003f - - next_table_miss: in_ipv6_e_acl$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_to_eg(8, 8): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000040 - - next_table_miss: in_ipv6_e_acl$st0 - - next_table: 0 - - { } - - set W16(29..30), 3 - Eg_inner_2.in_ipv6_e.forward_and_modify_mac(10, 10): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000041 - - next_table_miss: in_ipv6_e_acl$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000042 - - next_table_miss: in_ipv6_e_acl$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.set_mc(14, 14): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000043 - - next_table_miss: in_ipv6_e_acl$st0 - - next_table: 0 - - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.mc_index.0-7, mc_idx.0-7 - - set hdr.fabric.mc_index.8-15, mc_idx.8-15 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir(16, 16): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000044 - - next_table_miss: in_ipv6_e_acl$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(18, 18): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000045 - - next_table_miss: in_ipv6_e_acl$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - - set W17(8..26), $data1 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(20, 20): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000046 - - next_table_miss: in_ipv6_e_acl$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(22, 22): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000047 - - next_table_miss: in_ipv6_e_acl$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - default_action: NoAction - action in_ipv6_e_acl_0$st1$action_data: - p4: { name: Eg_inner_2.in_ipv6_e.acl_3$action } - row: [ 9, 7, 5, 3, 2, 1, 0 ] - word: [ 0, 0, 0, 0, 0, 0, 0 ] - column: - - 5 - - 5 - - 5 - - [ 1, 2, 3, 4, 5 ] - - [ 2, 3, 4, 5 ] - - [ 0, 1, 2, 3, 4, 5 ] - - 3 - vpns: - - [ 0 ] - - [ 1 ] - - [ 2 ] - - [ 3, 4, 5, 6, 7 ] - - [ 8, 9, 10, 11 ] - - [ 12, 13, 14, 15, 16, 17 ] - - [ 18 ] - home_row: - - 9 - format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 112..115 : $adf_f2, 116..119 : $adf_f3, 120..123 : $adf_f0, 124..127 : $adf_f1 } -stage 6 egress: - dependency: match - exact_match in_ipv6_e_acl$st0 1: - p4: { name: Eg_inner_2.in_ipv6_e.acl_2, size: 38912 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } - hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } - row: [ 5, 6, 7, 2, 3, 4 ] - bus: [ 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - stash: - row: [ 5, 6, 7 ] - col: [ 2, 2, 2 ] - unit: [ 0, 0, 0 ] - ways: - - [0, 0, 0x3, [7, 2], [6, 2], [5, 2], [7, 3], [6, 3], [5, 3], [7, 4], [6, 4], [5, 4], [7, 5], [6, 5], [5, 5]] - - [0, 1, 0xc, [7, 6], [6, 6], [5, 6], [7, 7], [6, 7], [5, 7], [7, 8], [6, 8], [5, 8], [7, 9], [6, 9], [5, 9]] - - [0, 2, 0x30, [7, 10], [6, 10], [5, 10], [7, 11], [6, 11], [5, 11], [4, 2], [3, 2], [2, 2], [4, 3], [3, 3], [2, 3]] - - [0, 3, 0xc0, [4, 4], [3, 4], [2, 4], [4, 5], [3, 5], [2, 5], [4, 6], [3, 6], [2, 6], [4, 7], [3, 7], [2, 7]] - - [0, 0, 0x1, [4, 8], [3, 8], [2, 8], [4, 9], [3, 9], [2, 9]] - - [0, 1, 0x0, [4, 10], [3, 10], [2, 10]] - input_xbar: - exact group 0: { 0: hdr.inner_ipv6.src_addr.0-31(0..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.src_addr.32-63(0..23), 56: hdr.inner_ipv6.src_addr.0-31(24..31), 64: hdr.inner_ipv6.src_addr.64-95(0..23), 88: hdr.inner_ipv6.src_addr.32-63(24..31), 96: hdr.inner_ipv6.src_addr.96-127(0..23), 120: hdr.inner_ipv6.src_addr.64-95(24..31) } - exact group 1: { 0: hdr.inner_ipv6.dst_addr.0-31(0..23), 24: hdr.inner_ipv6.src_addr.96-127(24..31), 32: hdr.inner_ipv6.dst_addr.32-63(0..23), 56: hdr.inner_ipv6.dst_addr.0-31(24..31), 64: hdr.inner_ipv6.dst_addr.64-95(0..23), 88: hdr.inner_ipv6.dst_addr.32-63(24..31), 96: hdr.inner_ipv6.dst_addr.96-127(0..23), 120: hdr.inner_ipv6.dst_addr.64-95(24..31) } - exact group 2: { 0: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.dst_addr.96-127(24..31) } - hash 0: - 0..9: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 40..41: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 10..19: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 42..43: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 20..29: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 44..45: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 30..39: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 46..47: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - hash 1: - 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 40..41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 42..43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 44..45: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 46..47: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - hash 2: - 0..9: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 40..41: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 42..43: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 44..45: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 46..47: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - hash 3: - 0..9: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 40..41: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 42..43: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 44..45: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 46..47: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - hash 4: - 0..5: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) - 6..9: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) - 40..41: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - 11..16: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) - 17..19: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..10) - 10: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(11) - 42..43: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - 22..27: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) - 28..29: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..9) - 20..21: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(10..11) - 44..45: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - 33..38: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) - 39: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8) - 30..32: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(9..11) - 46..47: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - hash group 0: - table: [0, 1, 2, 3, 4] - seed: 0x93751dcdffef - format: { action(0): 0..5, version(0): 40..43, match(0): [46..47, 254..254, 160..239, 128..159, 240..247, 288..367, 256..287, 368..383, 32..39 ] } - match: [ hdr.vlan_tag$0.vid(6..7), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.0-31(0..7), hdr.inner_ipv6.src_addr.0-31(8..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] - match_group_map: [ [ 0 ], [ 0 ], [ 0 ] ] - hit: [ END ] - miss: in_ipv6_e_acl$st1 - action: in_ipv6_e_acl$st0$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_e_acl$st0(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000048 - - next_table: 0 - - { } - Eg_inner_2.in_ipv6_e.drop(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000049 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.drop_and_count(2, 2): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000004a - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } - - bitmasked-set W16, $data0, W16 - - bitmasked-set W17, $data1, W17 - Eg_inner_2.in_ipv6_e.redirect_port(4, 4): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000004b - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.redirect_port_and_count(6, 6): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000004c - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_to_eg(8, 8): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000004d - - next_table: 0 - - { } - - set W16(29..30), 3 - Eg_inner_2.in_ipv6_e.forward_and_modify_mac(10, 10): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000004e - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000004f - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.set_mc(14, 14): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000050 - - next_table: 0 - - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.mc_index.0-7, mc_idx.0-7 - - set hdr.fabric.mc_index.8-15, mc_idx.8-15 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir(16, 16): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000051 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(18, 18): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000052 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - - set W17(8..26), $data1 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(20, 20): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000053 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(22, 22): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000054 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - default_action: NoAction - action in_ipv6_e_acl$st0$action_data: - p4: { name: Eg_inner_2.in_ipv6_e.acl_2$action } - row: [ 9, 7, 5, 3, 2, 1, 0 ] - word: [ 0, 0, 0, 0, 0, 0, 0 ] - column: - - 5 - - 5 - - 5 - - [ 1, 2, 3, 4, 5 ] - - [ 2, 3, 4, 5 ] - - [ 0, 1, 2, 3, 4, 5 ] - - 3 - vpns: - - [ 0 ] - - [ 1 ] - - [ 2 ] - - [ 3, 4, 5, 6, 7 ] - - [ 8, 9, 10, 11 ] - - [ 12, 13, 14, 15, 16, 17 ] - - [ 18 ] - home_row: - - 9 - format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 112..115 : $adf_f2, 116..119 : $adf_f3, 120..123 : $adf_f0, 124..127 : $adf_f1 } -stage 7 egress: - dependency: match - exact_match in_ipv6_e_acl$st1 1: - p4: { name: Eg_inner_2.in_ipv6_e.acl_2, size: 38912 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } - hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } - row: [ 5, 6, 7, 2, 3, 4 ] - bus: [ 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ] - stash: - row: [ 5, 6, 7 ] - col: [ 2, 2, 2 ] - unit: [ 0, 0, 0 ] - ways: - - [0, 0, 0x3, [7, 2], [6, 2], [5, 2], [7, 3], [6, 3], [5, 3], [7, 4], [6, 4], [5, 4], [7, 5], [6, 5], [5, 5]] - - [0, 1, 0xc, [7, 6], [6, 6], [5, 6], [7, 7], [6, 7], [5, 7], [7, 8], [6, 8], [5, 8], [7, 9], [6, 9], [5, 9]] - - [0, 2, 0x30, [7, 10], [6, 10], [5, 10], [7, 11], [6, 11], [5, 11], [4, 2], [3, 2], [2, 2], [4, 3], [3, 3], [2, 3]] - - [0, 3, 0xc0, [4, 4], [3, 4], [2, 4], [4, 5], [3, 5], [2, 5], [4, 6], [3, 6], [2, 6], [4, 7], [3, 7], [2, 7]] - - [0, 0, 0x1, [4, 8], [3, 8], [2, 8], [4, 9], [3, 9], [2, 9]] - - [0, 1, 0x0, [4, 10], [3, 10], [2, 10]] - input_xbar: - exact group 0: { 0: hdr.inner_ipv6.src_addr.0-31(0..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.src_addr.32-63(0..23), 56: hdr.inner_ipv6.src_addr.0-31(24..31), 64: hdr.inner_ipv6.src_addr.64-95(0..23), 88: hdr.inner_ipv6.src_addr.32-63(24..31), 96: hdr.inner_ipv6.src_addr.96-127(0..23), 120: hdr.inner_ipv6.src_addr.64-95(24..31) } - exact group 1: { 0: hdr.inner_ipv6.dst_addr.0-31(0..23), 24: hdr.inner_ipv6.src_addr.96-127(24..31), 32: hdr.inner_ipv6.dst_addr.32-63(0..23), 56: hdr.inner_ipv6.dst_addr.0-31(24..31), 64: hdr.inner_ipv6.dst_addr.64-95(0..23), 88: hdr.inner_ipv6.dst_addr.32-63(24..31), 96: hdr.inner_ipv6.dst_addr.96-127(0..23), 120: hdr.inner_ipv6.dst_addr.64-95(24..31) } - exact group 2: { 0: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.dst_addr.96-127(24..31) } - hash 0: - 0..9: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 40..41: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 10..19: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 42..43: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 20..29: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 44..45: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 30..39: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 46..47: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - hash 1: - 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 40..41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 42..43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 44..45: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 46..47: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - hash 2: - 0..9: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 40..41: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 42..43: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 44..45: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 46..47: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - hash 3: - 0..9: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 40..41: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 42..43: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 44..45: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 46..47: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - hash 4: - 0..5: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) - 6..9: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) - 40..41: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - 11..16: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) - 17..19: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..10) - 10: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(11) - 42..43: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - 22..27: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) - 28..29: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..9) - 20..21: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(10..11) - 44..45: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - 33..38: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) - 39: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8) - 30..32: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(9..11) - 46..47: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - hash group 0: - table: [0, 1, 2, 3, 4] - seed: 0x84055d6bf57e - format: { action(0): 0..5, version(0): 40..43, match(0): [46..47, 254..254, 160..239, 128..159, 240..247, 288..367, 256..287, 368..383, 32..39 ] } - match: [ hdr.vlan_tag$0.vid(6..7), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.0-31(0..7), hdr.inner_ipv6.src_addr.0-31(8..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31), hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] - match_group_map: [ [ 0 ], [ 0 ], [ 0 ] ] - hit: [ END ] - miss: in_ipv6_e_acl_dip$st0 - action: in_ipv6_e_acl$st1$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_e_acl$st1(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000048 - - next_table_miss: in_ipv6_e_acl_dip$st0 - - next_table: 0 - - { } - Eg_inner_2.in_ipv6_e.drop(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000049 - - next_table_miss: in_ipv6_e_acl_dip$st0 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.drop_and_count(2, 2): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000004a - - next_table_miss: in_ipv6_e_acl_dip$st0 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } - - bitmasked-set W16, $data0, W16 - - bitmasked-set W17, $data1, W17 - Eg_inner_2.in_ipv6_e.redirect_port(4, 4): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000004b - - next_table_miss: in_ipv6_e_acl_dip$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.redirect_port_and_count(6, 6): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000004c - - next_table_miss: in_ipv6_e_acl_dip$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_to_eg(8, 8): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000004d - - next_table_miss: in_ipv6_e_acl_dip$st0 - - next_table: 0 - - { } - - set W16(29..30), 3 - Eg_inner_2.in_ipv6_e.forward_and_modify_mac(10, 10): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000004e - - next_table_miss: in_ipv6_e_acl_dip$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000004f - - next_table_miss: in_ipv6_e_acl_dip$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.set_mc(14, 14): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000050 - - next_table_miss: in_ipv6_e_acl_dip$st0 - - next_table: 0 - - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.mc_index.0-7, mc_idx.0-7 - - set hdr.fabric.mc_index.8-15, mc_idx.8-15 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir(16, 16): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000051 - - next_table_miss: in_ipv6_e_acl_dip$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(18, 18): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000052 - - next_table_miss: in_ipv6_e_acl_dip$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - - set W17(8..26), $data1 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(20, 20): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000053 - - next_table_miss: in_ipv6_e_acl_dip$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(22, 22): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000054 - - next_table_miss: in_ipv6_e_acl_dip$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - default_action: NoAction - action in_ipv6_e_acl$st1$action_data: - p4: { name: Eg_inner_2.in_ipv6_e.acl_2$action } - row: [ 9, 7, 5, 3, 2, 1, 0 ] - word: [ 0, 0, 0, 0, 0, 0, 0 ] - column: - - 5 - - 5 - - 5 - - [ 1, 2, 3, 4, 5 ] - - [ 2, 3, 4, 5 ] - - [ 0, 1, 2, 3, 4, 5 ] - - 3 - vpns: - - [ 0 ] - - [ 1 ] - - [ 2 ] - - [ 3, 4, 5, 6, 7 ] - - [ 8, 9, 10, 11 ] - - [ 12, 13, 14, 15, 16, 17 ] - - [ 18 ] - home_row: - - 9 - format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 112..115 : $adf_f2, 116..119 : $adf_f3, 120..123 : $adf_f0, 124..127 : $adf_f1 } -stage 8 egress: - dependency: match - exact_match in_ipv6_e_acl_dip$st0 1: - p4: { name: Eg_inner_2.in_ipv6_e.acl_dip, size: 38912 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } - row: [ 6, 7, 4, 5, 2, 3, 0, 1 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 6, 7, 8, 9, 10 ] - - [ 2, 3, 6, 7, 8, 9, 10 ] - - [ 2, 3, 6, 7, 8, 9, 10 ] - - [ 2, 3, 6, 7, 8, 9, 10 ] - - [ 2, 3, 6, 7, 8, 9, 10 ] - - [ 2, 3, 6, 7, 8, 9, 10 ] - - [ 2, 3, 6, 7, 8 ] - - [ 2, 3, 6, 7, 8 ] - stash: - row: [ 6, 7 ] - col: [ 2, 2 ] - unit: [ 0, 0 ] - ways: - - [0, 0, 0x3, [7, 2], [6, 2], [7, 3], [6, 3], [7, 6], [6, 6], [7, 7], [6, 7]] - - [0, 1, 0xc, [7, 8], [6, 8], [7, 9], [6, 9], [7, 10], [6, 10], [5, 2], [4, 2]] - - [0, 2, 0x30, [5, 3], [4, 3], [5, 6], [4, 6], [5, 7], [4, 7], [5, 8], [4, 8]] - - [0, 3, 0xc0, [5, 9], [4, 9], [5, 10], [4, 10], [3, 2], [2, 2], [3, 3], [2, 3]] - - [0, 0, 0x3, [3, 6], [2, 6], [3, 7], [2, 7], [3, 8], [2, 8], [3, 9], [2, 9]] - - [0, 1, 0xc, [3, 10], [2, 10], [1, 2], [0, 2], [1, 3], [0, 3], [1, 6], [0, 6]] - - [0, 2, 0x10, [1, 7], [0, 7], [1, 8], [0, 8]] - input_xbar: - exact group 0: { 0: hdr.inner_ipv6.dst_addr.0-31(0..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.dst_addr.32-63(0..23), 56: hdr.inner_ipv6.dst_addr.0-31(24..31), 64: hdr.inner_ipv6.dst_addr.64-95(0..23), 88: hdr.inner_ipv6.dst_addr.32-63(24..31), 96: hdr.inner_ipv6.dst_addr.96-127(0..23), 120: hdr.inner_ipv6.dst_addr.64-95(24..31) } - exact group 1: { 0: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.dst_addr.96-127(24..31) } - hash 0: - 0..9: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 40..41: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 42..43: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 44..45: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 46..47: random(hdr.inner_ipv6.dst_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.32-63(0..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - hash 1: - 0..9: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 40..41: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 42..43: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 44..45: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 46..47: random(hdr.inner_ipv6.dst_addr.64-95(0..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.96-127(0..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - hash 2: - 0..6: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..6) - 7..9: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..10) - 41: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - 40: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(11) - 11..17: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..6) - 18..19: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..9) - 10: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(11) - 43: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - 42: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(10) - 22..28: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..6) - 29: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8) - 20..21: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(10..11) - 45: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - 44: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(9) - 33..39: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..6) - 30..32: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(9..11) - 47: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) - 46: random(hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8) - hash group 0: - table: [0, 1, 2] - seed: 0x457c7df0a5eb - format: { action(0): 0..5, version(0): 40..43, match(0): [47..47, 254..254, 160..239, 128..159, 240..247, 32..39 ] } - match: [ hdr.vlan_tag$0.vid(7), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] - match_group_map: [ [ 0 ], [ 0 ] ] - hit: [ END ] - miss: in_ipv6_e_acl_dip$st1 - action: in_ipv6_e_acl_dip$st0$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_e_acl_dip$st0(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000055 - - next_table: 0 - - { } - Eg_inner_2.in_ipv6_e.drop(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000056 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.drop_and_count(2, 2): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000057 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } - - bitmasked-set W16, $data0, W16 - - bitmasked-set W17, $data1, W17 - Eg_inner_2.in_ipv6_e.redirect_port(4, 4): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000058 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.redirect_port_and_count(6, 6): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000059 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_to_eg(8, 8): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000005a - - next_table: 0 - - { } - - set W16(29..30), 3 - Eg_inner_2.in_ipv6_e.forward_and_modify_mac(10, 10): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000005b - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000005c - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.set_mc(14, 14): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000005d - - next_table: 0 - - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.mc_index.0-7, mc_idx.0-7 - - set hdr.fabric.mc_index.8-15, mc_idx.8-15 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir(16, 16): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000005e - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(18, 18): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000005f - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - - set W17(8..26), $data1 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(20, 20): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000060 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(22, 22): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000061 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - default_action: NoAction - action in_ipv6_e_acl_dip$st0$action_data: - p4: { name: Eg_inner_2.in_ipv6_e.acl_dip$action } - row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ] - word: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - 5 - - 5 - - 5 - - [ 4, 5 ] - - 5 - - [ 4, 5 ] - - 5 - - [ 4, 5 ] - - 5 - - [ 4, 5 ] - - 5 - - [ 4, 5 ] - - [ 3, 4, 5 ] - - [ 4, 5 ] - - [ 3, 4, 5 ] - - 5 - vpns: - - [ 0 ] - - [ 1 ] - - [ 2 ] - - [ 3, 4 ] - - [ 5 ] - - [ 6, 7 ] - - [ 8 ] - - [ 9, 10 ] - - [ 11 ] - - [ 12, 13 ] - - [ 14 ] - - [ 15, 16 ] - - [ 17, 18, 19 ] - - [ 20, 21 ] - - [ 22, 23, 24 ] - - [ 25 ] - home_row: - - [ 15, 3 ] - format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 112..115 : $adf_f2, 116..119 : $adf_f3, 120..123 : $adf_f0, 124..127 : $adf_f1 } -stage 9 egress: - dependency: match - exact_match in_ipv6_e_acl_dip$st1 3: - p4: { name: Eg_inner_2.in_ipv6_e.acl_dip, size: 38912 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.dst_addr: { type: exact, size: 128, full_size: 128, key_name: "in_dst_addr" } - row: [ 6, 7, 4, 5 ] - bus: [ 0, 0, 0, 0 ] - column: - - [ 2, 3, 6, 7, 8, 9, 10 ] - - [ 2, 3, 6, 7, 8, 9, 10 ] - - [ 2, 3, 6, 7, 8 ] - - [ 2, 3, 6, 7, 8 ] - stash: - row: [ 6, 7 ] - col: [ 2, 2 ] - unit: [ 0, 0 ] - ways: - - [0, 0, 0x1, [7, 2], [6, 2], [7, 3], [6, 3]] - - [0, 1, 0x2, [7, 6], [6, 6], [7, 7], [6, 7]] - - [0, 2, 0x4, [7, 8], [6, 8], [7, 9], [6, 9]] - - [0, 3, 0x8, [7, 10], [6, 10], [5, 2], [4, 2]] - - [0, 0, 0x1, [5, 3], [4, 3], [5, 6], [4, 6]] - - [0, 1, 0x2, [5, 7], [4, 7], [5, 8], [4, 8]] - input_xbar: - exact group 0: { 8: hdr.inner_ipv6.dst_addr.0-31(8..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.dst_addr.0-31(0..7), 40: hdr.inner_ipv6.dst_addr.32-63(8..23), 56: hdr.inner_ipv6.dst_addr.0-31(24..31), 64: hdr.inner_ipv6.dst_addr.32-63(0..7), 72: hdr.inner_ipv6.dst_addr.64-95(8..23), 88: hdr.inner_ipv6.dst_addr.32-63(24..31), 96: hdr.inner_ipv6.dst_addr.64-95(0..7), 104: hdr.inner_ipv6.dst_addr.96-127(8..23), 120: hdr.inner_ipv6.dst_addr.64-95(24..31) } - exact group 1: { 0: hdr.inner_ipv6.dst_addr.96-127(0..7), 8: hdr.vlan_tag$0.vid(8..11), 16: hdr.vlan_tag$0.vid(0..7), 24: hdr.inner_ipv6.dst_addr.96-127(24..31) } - hash 0: - 0..9: random(hdr.inner_ipv6.dst_addr.0-31(8..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.32-63(8..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 40: random(hdr.inner_ipv6.dst_addr.0-31(8..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.32-63(8..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.0-31(8..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.32-63(8..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 41: random(hdr.inner_ipv6.dst_addr.0-31(8..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.32-63(8..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.0-31(8..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.32-63(8..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 42: random(hdr.inner_ipv6.dst_addr.0-31(8..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.32-63(8..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.0-31(8..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.32-63(8..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - 43: random(hdr.inner_ipv6.dst_addr.0-31(8..23), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.32-63(8..23), hdr.inner_ipv6.dst_addr.0-31(24..31)) - hash 1: - 0..9: random(hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.64-95(8..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.96-127(8..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 40: random(hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.64-95(8..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.96-127(8..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 10..19: random(hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.64-95(8..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.96-127(8..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 41: random(hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.64-95(8..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.96-127(8..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 20..29: random(hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.64-95(8..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.96-127(8..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 42: random(hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.64-95(8..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.96-127(8..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 30..39: random(hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.64-95(8..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.96-127(8..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - 43: random(hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.64-95(8..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.96-127(8..23), hdr.inner_ipv6.dst_addr.64-95(24..31)) - hash 2: - 0..3: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) - 4..9: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) - 40: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(6) - 11..14: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) - 15..19: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..4) - 10: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(6) - 41: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(5) - 22..25: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) - 26..29: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..3) - 20..21: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(5..6) - 42: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(4) - 33..36: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) - 37..39: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..2) - 30..32: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(4..6) - 43: random(hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.vlan_tag$0.vid(7), hdr.inner_ipv6.dst_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(3) - hash group 0: - table: [0, 1, 2] - seed: 0x74b6340977c - format: { action(0): 0..5, version(0): 48..51, match(0): [55..55, 246..246, 160..239, 128..143, 32..39, 144..159, 40..47 ] } - match: [ hdr.vlan_tag$0.vid(7), hdr.fabric.is_hit, hdr.inner_ipv6.dst_addr.0-31(0..7), hdr.inner_ipv6.dst_addr.0-31(8..15), hdr.inner_ipv6.dst_addr.0-31(16..23), hdr.inner_ipv6.dst_addr.0-31(24..31), hdr.inner_ipv6.dst_addr.32-63(0..7), hdr.inner_ipv6.dst_addr.32-63(8..15), hdr.inner_ipv6.dst_addr.32-63(16..23), hdr.inner_ipv6.dst_addr.32-63(24..31), hdr.inner_ipv6.dst_addr.64-95(0..7), hdr.inner_ipv6.dst_addr.64-95(8..15), hdr.inner_ipv6.dst_addr.64-95(16..23), hdr.inner_ipv6.dst_addr.64-95(24..31), hdr.inner_ipv6.dst_addr.96-127(0..7), hdr.inner_ipv6.dst_addr.96-127(8..15), hdr.inner_ipv6.dst_addr.96-127(16..23), hdr.inner_ipv6.dst_addr.96-127(24..31) ] - match_group_map: [ [ 0 ], [ 0 ] ] - hit: [ END ] - miss: in_ipv6_e_acl_sip$st0 - action: in_ipv6_e_acl_dip$st1$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_e_acl_dip$st1(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000055 - - next_table_miss: in_ipv6_e_acl_sip$st0 - - next_table: 0 - - { } - Eg_inner_2.in_ipv6_e.drop(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000056 - - next_table_miss: in_ipv6_e_acl_sip$st0 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.drop_and_count(2, 2): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000057 - - next_table_miss: in_ipv6_e_acl_sip$st0 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } - - bitmasked-set W16, $data0, W16 - - bitmasked-set W17, $data1, W17 - Eg_inner_2.in_ipv6_e.redirect_port(4, 4): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000058 - - next_table_miss: in_ipv6_e_acl_sip$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.redirect_port_and_count(6, 6): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000059 - - next_table_miss: in_ipv6_e_acl_sip$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_to_eg(8, 8): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000005a - - next_table_miss: in_ipv6_e_acl_sip$st0 - - next_table: 0 - - { } - - set W16(29..30), 3 - Eg_inner_2.in_ipv6_e.forward_and_modify_mac(10, 10): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000005b - - next_table_miss: in_ipv6_e_acl_sip$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000005c - - next_table_miss: in_ipv6_e_acl_sip$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.set_mc(14, 14): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000005d - - next_table_miss: in_ipv6_e_acl_sip$st0 - - next_table: 0 - - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.mc_index.0-7, mc_idx.0-7 - - set hdr.fabric.mc_index.8-15, mc_idx.8-15 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir(16, 16): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000005e - - next_table_miss: in_ipv6_e_acl_sip$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(18, 18): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000005f - - next_table_miss: in_ipv6_e_acl_sip$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - - set W17(8..26), $data1 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(20, 20): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000060 - - next_table_miss: in_ipv6_e_acl_sip$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(22, 22): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000061 - - next_table_miss: in_ipv6_e_acl_sip$st0 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - default_action: NoAction - action in_ipv6_e_acl_dip$st1$action_data: - p4: { name: Eg_inner_2.in_ipv6_e.acl_dip$action } - row: [ 6, 5, 4, 3, 2, 1 ] - word: [ 0, 0, 0, 0, 0, 0 ] - column: - - 5 - - 5 - - [ 4, 5 ] - - [ 2, 3, 4, 5 ] - - 5 - - [ 2, 3, 4 ] - vpns: - - [ 0 ] - - [ 1 ] - - [ 2, 3 ] - - [ 4, 5, 6, 7 ] - - [ 8 ] - - [ 9, 10, 11 ] - home_row: - - 6 - format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 1 : $adf_b1, 36..37 : $adf_h0, 112..115 : $adf_f2, 116..119 : $adf_f3, 120..123 : $adf_f0, 124..127 : $adf_f1 } - exact_match in_ipv6_e_acl_sip$st0 4: - p4: { name: Eg_inner_2.in_ipv6_e.acl_sip, size: 38912 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } - row: [ 4, 5, 2, 3, 0, 1 ] - bus: [ 1, 1, 0, 0, 0, 0 ] - column: - - [ 9, 10 ] - - [ 9, 10 ] - - [ 2, 3, 6, 7, 8, 9, 10 ] - - [ 2, 3, 6, 7, 8, 9, 10 ] - - [ 2, 3, 6, 7 ] - - [ 2, 3, 6, 7 ] - stash: - row: [ 4, 5 ] - col: [ 9, 9 ] - unit: [ 0, 0 ] - ways: - - [1, 0, 0x1, [5, 9], [4, 9], [5, 10], [4, 10]] - - [1, 1, 0x2, [3, 2], [2, 2], [3, 3], [2, 3]] - - [1, 2, 0x4, [3, 6], [2, 6], [3, 7], [2, 7]] - - [1, 3, 0x8, [3, 8], [2, 8], [3, 9], [2, 9]] - - [1, 0, 0x1, [3, 10], [2, 10], [1, 2], [0, 2]] - - [1, 1, 0x2, [1, 3], [0, 3], [1, 6], [0, 6]] - - [1, 2, 0x0, [1, 7], [0, 7]] - input_xbar: - exact group 1: { 64: hdr.inner_ipv6.src_addr.0-31(0..23), 94: hdr.fabric.is_hit, 96: hdr.inner_ipv6.src_addr.32-63(0..23), 120: hdr.inner_ipv6.src_addr.0-31(24..31) } - exact group 2: { 0: hdr.inner_ipv6.src_addr.64-95(0..23), 24: hdr.inner_ipv6.src_addr.32-63(24..31), 32: hdr.inner_ipv6.src_addr.96-127(0..23), 56: hdr.inner_ipv6.src_addr.64-95(24..31), 64: hdr.vlan_tag$0.vid, 88: hdr.inner_ipv6.src_addr.96-127(24..31) } - hash 3: - 0..7: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.inner_ipv6.src_addr.0-31(0..7) - 8: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.inner_ipv6.src_addr.0-31(8) - 9: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.fabric.is_hit - 40: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 11..18: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.inner_ipv6.src_addr.0-31(0..7) - 19: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.inner_ipv6.src_addr.0-31(8) - 10: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.fabric.is_hit - 41: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 22..29: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.inner_ipv6.src_addr.0-31(0..7) - 20: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.inner_ipv6.src_addr.0-31(8) - 21: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.fabric.is_hit - 42: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 33..39: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.inner_ipv6.src_addr.0-31(0..6) - 30: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.inner_ipv6.src_addr.0-31(7) - 31: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.inner_ipv6.src_addr.0-31(8) - 32: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) ^ hdr.fabric.is_hit - 43: random(hdr.inner_ipv6.src_addr.0-31(9..23), hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - hash 4: - 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 40: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 42: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - hash 5: - 0..9: random(hdr.vlan_tag$0.vid, hdr.inner_ipv6.src_addr.96-127(24..31)) - 40: random(hdr.vlan_tag$0.vid, hdr.inner_ipv6.src_addr.96-127(24..31)) - 10..19: random(hdr.vlan_tag$0.vid, hdr.inner_ipv6.src_addr.96-127(24..31)) - 41: random(hdr.vlan_tag$0.vid, hdr.inner_ipv6.src_addr.96-127(24..31)) - 20..29: random(hdr.vlan_tag$0.vid, hdr.inner_ipv6.src_addr.96-127(24..31)) - 42: random(hdr.vlan_tag$0.vid, hdr.inner_ipv6.src_addr.96-127(24..31)) - 30..39: random(hdr.vlan_tag$0.vid, hdr.inner_ipv6.src_addr.96-127(24..31)) - 43: random(hdr.vlan_tag$0.vid, hdr.inner_ipv6.src_addr.96-127(24..31)) - hash group 1: - table: [3, 4, 5] - seed: 0x93dbbf23750 - format: { action(0): 0..5, version(0): 112..115, match(0): [160..167, 128..131, 73..79, 32..71, 168..239 ] } - match: [ hdr.vlan_tag$0.vid(0..7), hdr.vlan_tag$0.vid(8..11), hdr.inner_ipv6.src_addr.0-31(9..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31) ] - match_group_map: [ [ 0 ], [ 0 ] ] - hit: [ END ] - miss: in_ipv6_e_acl_sip$st1 - action: in_ipv6_e_acl_sip$st0$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_e_acl_sip$st0(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000062 - - next_table: 0 - - { } - Eg_inner_2.in_ipv6_e.drop(24, 24): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000063 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.drop_and_count(26, 26): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000064 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } - - bitmasked-set W16, $data0, W16 - - bitmasked-set W17, $data1, W17 - Eg_inner_2.in_ipv6_e.redirect_port(28, 28): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000065 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.redirect_port_and_count(30, 30): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000066 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_to_eg(32, 32): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000067 - - next_table: 0 - - { } - - set W16(29..30), 3 - Eg_inner_2.in_ipv6_e.forward_and_modify_mac(34, 34): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000068 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(36, 36): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000069 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.set_mc(38, 38): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000006a - - next_table: 0 - - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.mc_index.0-7, mc_idx.0-7 - - set hdr.fabric.mc_index.8-15, mc_idx.8-15 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir(40, 40): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000006b - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(42, 42): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000006c - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - - set W17(8..26), $data1 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(44, 44): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000006d - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(46, 46): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000006e - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - default_action: NoAction - action in_ipv6_e_acl_sip$st0$action_data: - p4: { name: Eg_inner_2.in_ipv6_e.acl_sip$action } - row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6 ] - word: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - 5 - - 5 - - 5 - - [ 4, 5 ] - - 5 - - [ 4, 5 ] - - 5 - - [ 4, 5 ] - - 5 - - 4 - vpns: - - [ 0 ] - - [ 1 ] - - [ 2 ] - - [ 3, 4 ] - - [ 5 ] - - [ 6, 7 ] - - [ 8 ] - - [ 9, 10 ] - - [ 11 ] - - [ 12 ] - home_row: - - 15 - format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 5 : $adf_b1, 40..41 : $adf_h0, 64..67 : $adf_f2, 68..71 : $adf_f3, 72..75 : $adf_f0, 76..79 : $adf_f1 } -stage 10 egress: - dependency: match - exact_match in_ipv6_e_acl_sip$st1 0: - p4: { name: Eg_inner_2.in_ipv6_e.acl_sip, size: 38912 } - p4_param_order: - hdr.fabric.is_hit: { type: exact, size: 1, full_size: 1, key_name: "is_hit" } - hdr.vlan_tag$0.vid: { type: exact, size: 12, full_size: 12, key_name: "vid" } - hdr.inner_ipv6.src_addr: { type: exact, size: 128, full_size: 128, key_name: "in_src_addr" } - row: [ 6, 7, 4, 5, 2, 3, 0, 1 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 5, 6, 7, 8 ] - - [ 2, 3, 4, 5, 6, 7, 8 ] - - [ 2, 3, 4, 5, 6, 7, 8 ] - - [ 2, 3, 4, 5, 6, 7, 8 ] - - [ 2, 3, 4, 5, 6, 7, 8 ] - - [ 2, 3, 4, 5, 6, 7, 8 ] - - [ 2, 3, 4, 5 ] - - [ 2, 3, 4, 5 ] - stash: - row: [ 6, 7 ] - col: [ 2, 2 ] - unit: [ 0, 0 ] - ways: - - [0, 0, 0x3, [7, 2], [6, 2], [7, 3], [6, 3], [7, 4], [6, 4], [7, 5], [6, 5]] - - [0, 1, 0xc, [7, 6], [6, 6], [7, 7], [6, 7], [7, 8], [6, 8], [5, 2], [4, 2]] - - [0, 2, 0x30, [5, 3], [4, 3], [5, 4], [4, 4], [5, 5], [4, 5], [5, 6], [4, 6]] - - [0, 3, 0xc0, [5, 7], [4, 7], [5, 8], [4, 8], [3, 2], [2, 2], [3, 3], [2, 3]] - - [0, 0, 0x3, [3, 4], [2, 4], [3, 5], [2, 5], [3, 6], [2, 6], [3, 7], [2, 7]] - - [0, 1, 0xc, [3, 8], [2, 8], [1, 2], [0, 2], [1, 3], [0, 3], [1, 4], [0, 4]] - - [0, 2, 0x0, [1, 5], [0, 5]] - input_xbar: - exact group 0: { 0: hdr.inner_ipv6.src_addr.0-31(0..23), 30: hdr.fabric.is_hit, 32: hdr.inner_ipv6.src_addr.32-63(0..23), 56: hdr.inner_ipv6.src_addr.0-31(24..31), 64: hdr.inner_ipv6.src_addr.64-95(0..23), 88: hdr.inner_ipv6.src_addr.32-63(24..31), 96: hdr.inner_ipv6.src_addr.96-127(0..23), 120: hdr.inner_ipv6.src_addr.64-95(24..31) } - exact group 1: { 0: hdr.vlan_tag$0.vid, 24: hdr.inner_ipv6.src_addr.96-127(24..31) } - hash 0: - 0..9: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 40..41: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 10..19: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 42..43: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 20..29: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 44..45: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 30..39: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - 46..47: random(hdr.inner_ipv6.src_addr.0-31(0..23), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.32-63(0..23), hdr.inner_ipv6.src_addr.0-31(24..31)) - hash 1: - 0..9: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 40..41: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 10..19: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 42..43: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 20..29: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 44..45: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 30..39: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - 46..47: random(hdr.inner_ipv6.src_addr.64-95(0..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.96-127(0..23), hdr.inner_ipv6.src_addr.64-95(24..31)) - hash 2: - 0..5: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) - 6..9: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..11) - 40..41: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) - 11..16: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) - 17..19: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..10) - 10: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(11) - 42..43: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) - 22..27: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) - 28..29: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8..9) - 20..21: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(10..11) - 44..45: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) - 33..38: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(0..5) - 39: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(8) - 30..32: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) ^ hdr.vlan_tag$0.vid(9..11) - 46..47: random(hdr.vlan_tag$0.vid(6..7), hdr.inner_ipv6.src_addr.96-127(24..31)) - hash group 0: - table: [0, 1, 2] - seed: 0xa950ff70f805 - format: { action(0): 0..5, version(0): 40..43, match(0): [46..47, 254..254, 160..239, 128..159, 240..247, 32..39 ] } - match: [ hdr.vlan_tag$0.vid(6..7), hdr.fabric.is_hit, hdr.inner_ipv6.src_addr.0-31(0..7), hdr.inner_ipv6.src_addr.0-31(8..15), hdr.inner_ipv6.src_addr.0-31(16..23), hdr.inner_ipv6.src_addr.0-31(24..31), hdr.inner_ipv6.src_addr.32-63(0..7), hdr.inner_ipv6.src_addr.32-63(8..15), hdr.inner_ipv6.src_addr.32-63(16..23), hdr.inner_ipv6.src_addr.32-63(24..31), hdr.inner_ipv6.src_addr.64-95(0..7), hdr.inner_ipv6.src_addr.64-95(8..15), hdr.inner_ipv6.src_addr.64-95(16..23), hdr.inner_ipv6.src_addr.64-95(24..31), hdr.inner_ipv6.src_addr.96-127(0..7), hdr.inner_ipv6.src_addr.96-127(8..15), hdr.inner_ipv6.src_addr.96-127(16..23), hdr.inner_ipv6.src_addr.96-127(24..31) ] - match_group_map: [ [ 0 ], [ 0 ] ] - hit: [ END ] - miss: END - action: in_ipv6_e_acl_sip$st1$action_data($DIRECT, $DEFAULT) - instruction: in_ipv6_e_acl_sip$st1(action, $DEFAULT) - actions: - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000062 - - next_table: 0 - - { } - Eg_inner_2.in_ipv6_e.drop(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000063 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.flags_drop, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.drop_and_count(2, 2): - - p4_param_order: { count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000064 - - next_table: 0 - - { $data0: $adf_f0(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f1(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f2(8..27), count_idx: $data1(0..17), $constant4: $data1(19..19), $constant4: 1, $mask1: $adf_f3(8..27), $constant5: $mask1(0..17), $constant5: 262143, $constant6: $mask1(19..19), $constant6: 1 } - - bitmasked-set W16, $data0, W16 - - bitmasked-set W17, $data1, W17 - Eg_inner_2.in_ipv6_e.redirect_port(4, 4): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000065 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.redirect_port_and_count(6, 6): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000066 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_to_eg(8, 8): - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000067 - - next_table: 0 - - { } - - set W16(29..30), 3 - Eg_inner_2.in_ipv6_e.forward_and_modify_mac(10, 10): - - p4_param_order: { mac_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000068 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count(12, 12): - - p4_param_order: { mac_idx: 18, vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x20000069 - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(0..30), mac_idx: $data0(0..17), $constant1: $data0(28..28), $constant1: 1, $constant0: $data0(30..30), $constant0: 1, $mask0: $adf_f3(0..30), $constant2: $mask0(0..17), $constant2: 262143, $constant3: $mask0(28..28), $constant3: 1, $constant4: $mask0(30..30), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.set_mc(14, 14): - - p4_param_order: { mc_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000006a - - next_table: 0 - - { mc_idx.8-15: $adf_f0(0..7), mc_idx.0-7: $adf_b1(0..7), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.mc_index.0-7, mc_idx.0-7 - - set hdr.fabric.mc_index.8-15, mc_idx.8-15 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir(16, 16): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000006b - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.is_trunc_mir, 1 - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt(18, 18): - - p4_param_order: { count_idx: 18, vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000006c - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(28..30), $constant1: $data0(0..0), $constant1: 1, $constant0: $data0(2..2), $constant0: 1, $mask0: $adf_f3(28..30), $constant2: $mask0(0..0), $constant2: 1, $constant3: $mask0(2..2), $constant3: 1, $data1: $adf_f1(0..18), count_idx: $data1(0..17), $constant4: $data1(18..18), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - - set W17(8..26), $data1 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr(20, 20): - - p4_param_order: { vlan_idx: 16 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000006d - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1 } - - set hdr.fabric.vlan_index, vlan_idx - - bitmasked-set W16, $data0, W16 - Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt(22, 22): - - p4_param_order: { vlan_idx: 16, count_idx: 18 } - - hit_allowed: { allowed: true } - - default_action: { allowed: false, reason: has_const_default_action } - - handle: 0x2000006e - - next_table: 0 - - { vlan_idx: $adf_h0(0..15), $data0: $adf_f2(27..30), $constant1: $data0(0..0), $constant1: 1, $constant2: $data0(1..1), $constant2: 1, $constant0: $data0(3..3), $constant0: 1, $mask0: $adf_f3(27..30), $constant3: $mask0(0..1), $constant3: 3, $constant4: $mask0(3..3), $constant4: 1, count_idx: $adf_f1(0..17) } - - set hdr.fabric.vlan_index, vlan_idx - - set hdr.fabric.count_index, count_idx - - bitmasked-set W16, $data0, W16 - default_action: NoAction - action in_ipv6_e_acl_sip$st1$action_data: - p4: { name: Eg_inner_2.in_ipv6_e.acl_sip$action } - row: [ 15, 13, 11, 9, 7, 5, 3, 1 ] - word: [ 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - 5 - - [ 4, 5 ] - - [ 3, 4, 5 ] - - [ 3, 4, 5 ] - - [ 3, 4, 5 ] - - [ 3, 4, 5 ] - - [ 1, 2, 3, 4, 5 ] - - [ 0, 1, 2, 3, 4 ] - vpns: - - [ 0 ] - - [ 1, 2 ] - - [ 3, 4, 5 ] - - [ 6, 7, 8 ] - - [ 9, 10, 11 ] - - [ 12, 13, 14 ] - - [ 15, 16, 17, 18, 19 ] - - [ 20, 21, 22, 23, 24 ] - home_row: - - [ 15, 3 ] - format Eg_inner_2.in_ipv6_e.drop: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.drop_and_count: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.redirect_port_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_modify_mac: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_modify_mac_and_count: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.set_mc: { $adf_f0: 0..31, $adf_b1: 8..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_trunc_mir_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127 } - format Eg_inner_2.in_ipv6_e.forward_and_decap_pkt_hdr_and_cnt: { $adf_h0: 0..15, $adf_f2: 64..95, $adf_f3: 96..127, $adf_f1: 32..63 } - action_bus: { 1 : $adf_b1, 32..33 : $adf_h0, 96..99 : $adf_f2, 100..103 : $adf_f3, 104..107 : $adf_f0, 108..111 : $adf_f1 } - - -primitives: "./network_tap/pp_inner_2//network_tap.prim.json" -dynhash: "./network_tap/pp_inner_2//network_tap.dynhash.json" diff --git a/backends/tofino/bf-asm/test/asm/p4c-2257.bfa b/backends/tofino/bf-asm/test/asm/p4c-2257.bfa deleted file mode 100644 index 99aa0db048e..00000000000 --- a/backends/tofino/bf-asm/test/asm/p4c-2257.bfa +++ /dev/null @@ -1,16228 +0,0 @@ -version: - version: 1.0.1 - run_id: "e8fcabd5512471f2" - target: Tofino -phv ingress: - HillTop.Lamona.Fristoe: W14(8..21) - HillTop.Lamona.Traverse: H1(0..11) - HillTop.Lamona.Pachuta: B34(0) - HillTop.Lamona.Whitefish: W0(0..1) - Millston.Belgrade.Roachdale: H6(8..15) - Millston.Belgrade.Rugby: H6(5..7) - Millston.Belgrade.Davie: H6(4) - Millston.Belgrade.Cacao: H6(0..3) - Millston.Belgrade.Mankato: B36 - Millston.Belgrade.Virgil: W13(8..31) - Millston.Belgrade.Florin.0-15: H63 - Millston.Belgrade.Florin.16-23: W13(0..7) - Millston.Belgrade.Ronan: TW12 - Millston.Belgrade.Corinth: H51 - Millston.Belgrade.__pad_0: B11(4..7) - Millston.Belgrade.Union: B11(1..3) - Millston.Belgrade.Rockport: B11(0) - Millston.Belgrade.__pad_1: B9(6..7) - Millston.Belgrade.Anacortes: B9(5) - Millston.Belgrade.Shabbona: B9(4) - Millston.Belgrade.Allgood: B9(1..3) - Millston.Belgrade.Waipahu: B9(0) - Millston.Belgrade.__pad_2: B34(1..7) - Millston.Belgrade.Freeburg: B34(0) - Millston.Belgrade.__pad_3: W1(8..31) - Millston.Belgrade.Sudbury: W1(2..7) - Millston.Belgrade.Selawik: W1(0..1) - Millston.Belgrade.__pad_4: B7(3..7) - Millston.Belgrade.Willard: B7(0..2) - Millston.Belgrade.__pad_5: H90(6..15) - Millston.Belgrade.Matheson: H90(0..5) - Millston.Belgrade.__pad_6: H48(9..15) - Millston.Belgrade.Chaska: H48(0..8) - Millston.Belgrade.__pad_7: H2(12..15) - Millston.Belgrade.Requa: H2(0..11) - Millston.Belgrade.__pad_8: H4(12..15) - Millston.Belgrade.Bayshore: H4(0..11) - Millston.Belgrade.__pad_9: H3(12..15) - Millston.Belgrade.Florien: H3(0..11) - HillTop.Tiburon.Arnold: H53(0..8) - Millston.Hayfield.Blitchton: W48(26..31) - Millston.Hayfield.Avondale: W48(16..25) - Millston.Hayfield.Glassboro: W48(12..15) - Millston.Hayfield.Grabill: W48(0..11) - Millston.Hayfield.AquaPark: B47(6..7) - Millston.Hayfield.Vichy: B47(3..5) - Millston.Calabash.Adona: W12(8..31) - Millston.Calabash.Connell.0-15: H54 - Millston.Calabash.Connell.16-23: W12(0..7) - Millston.Calabash.Goldsboro.0-7: W6(24..31) - Millston.Calabash.Goldsboro.8-23: H36 - Millston.Calabash.Fabens: W6(0..23) - Millston.Calabash.McCaulley.0-7: B50 - Millston.Calabash.McCaulley.8-15: B53 - Millston.Wondervu$0.Higginson: H0(13..15) - Millston.Wondervu$0.Oriskany: H0(12) - Millston.Wondervu$0.Bowden: H0(0..11) - Millston.Wondervu$0.McCaulley.0-7: B48 - Millston.Wondervu$0.McCaulley.8-15: B51 - Millston.Wondervu$1.Higginson: TH24(13..15) - Millston.Wondervu$1.Oriskany: TH24(12) - Millston.Wondervu$1.Bowden: TH24(0..11) - Millston.Wondervu$1.McCaulley.0-7: B49 - Millston.Wondervu$1.McCaulley.8-15: B52 - Millston.Rainelle.Conner: TW1(16..31) - Millston.Rainelle.Ledoux: TW1(0..15) - Millston.Rainelle.Steger: TH0(8..15) - Millston.Rainelle.Quogue: TH0(0..7) - Millston.Rainelle.Findlay: H35 - Millston.GlenAvon.Fayette: H89(12..15) - Millston.GlenAvon.Osterdock: H89(8..11) - Millston.GlenAvon.PineCity: H89(2..7) - Millston.GlenAvon.Alameda: H89(0..1) - Millston.GlenAvon.Rexville: H38 - Millston.GlenAvon.Quinwood: TW0(16..31) - Millston.GlenAvon.Marfa: TW0(15) - Millston.GlenAvon.Palatine: TW0(14) - Millston.GlenAvon.Mabelle: TW0(13) - Millston.GlenAvon.Hoagland: TW0(0..12) - Millston.GlenAvon.Exton: TB1 - Millston.GlenAvon.Ocoee: B33 - Millston.GlenAvon.Hackett: TH25 - Millston.GlenAvon.Kaluaaha: W32 - Millston.GlenAvon.Calcasieu: W33 - HillTop.Aldan.Vinemont: B42 - HillTop.Aldan.Kenbridge: B58 - HillTop.Aldan.Parkville: B13(0..3) - HillTop.Aldan.Mystic.0-1: B10(4..5) - HillTop.Aldan.Mystic.2-2: B14(0) - HillTop.Aldan.Kearns.0-0: B7(0) - HillTop.Aldan.Kearns.1-2: H50(0..1) - HillTop.Aldan.Malinta.0-0: B8(0) - HillTop.Aldan.Malinta.1-2: H56(0..1) - HillTop.Aldan.Blakeley: H63(0) - HillTop.Aldan.Poulan: H48(0) - HillTop.RossFork.Adona: W0(2..25) - HillTop.RossFork.Connell.0-15: H55 - HillTop.RossFork.Connell.16-23: W14(0..7) - HillTop.RossFork.Goldsboro.0-7: W8(0..7) - HillTop.RossFork.Goldsboro.8-23: H37 - HillTop.RossFork.Fabens: W7(0..23) - HillTop.RossFork.McCaulley.0-7: B56 - HillTop.RossFork.McCaulley.8-15: B57 - HillTop.RossFork.CeeVee: H4(0..11) - HillTop.RossFork.Quebrada: W4(0..19) - HillTop.RossFork.Bicknell: H3(0..11) - HillTop.RossFork.Ocoee: B44 - HillTop.RossFork.Exton: B59 - HillTop.RossFork.Naruna.0-1: B8(3..4) - HillTop.RossFork.Naruna.2-2: B13(5) - HillTop.RossFork.Suttle: B2(0) - HillTop.RossFork.Ankeny: B45 - HillTop.RossFork.Denhoff.0-0: B7(3) - HillTop.RossFork.Denhoff.1-2: H62(2..3) - HillTop.RossFork.Joslin: H34(5..7) - HillTop.RossFork.Weyauwega: B12(5) - HillTop.RossFork.Powderly: B11(6) - HillTop.RossFork.Welcome: H85(6) - HillTop.RossFork.Teigen: B38(0) - HillTop.RossFork.Lowes: B15(5) - HillTop.RossFork.Almedia: H14(12) - HillTop.RossFork.Chugwater: B15(6) - HillTop.RossFork.Charco: B12(6) - HillTop.RossFork.Daphne: B12(7) - HillTop.RossFork.Level: B15(4) - HillTop.RossFork.Algoa: W11(1) - HillTop.RossFork.Thayne: B5(0) - HillTop.RossFork.Parkland: H62(1) - HillTop.RossFork.Kapalua: W10(8) - HillTop.RossFork.Halaula: W1(8) - HillTop.RossFork.Uvalde: W9(9) - HillTop.RossFork.Tenino: H66(14) - HillTop.RossFork.Pridgen: H66(15) - HillTop.RossFork.Juniata: H95(11) - HillTop.RossFork.Beaverdam: W1(18) - HillTop.RossFork.ElVerano: B12(2) - HillTop.RossFork.Brinkman: B8(5) - HillTop.RossFork.Boerne: B3(0) - HillTop.RossFork.Alamosa: B12(3) - HillTop.RossFork.Knierim: W1(19..30) - HillTop.RossFork.Montross: W39(0..11) - HillTop.RossFork.Glenmora: H11 - HillTop.RossFork.DonaAna: H40 - HillTop.RossFork.Altus: H61 - HillTop.RossFork.Merrill: H41 - HillTop.RossFork.Hickox: H42 - HillTop.RossFork.Tehachapi: H43 - HillTop.RossFork.Sewaren: H90(12..13) - HillTop.RossFork.WindGap: H90(14) - HillTop.RossFork.Caroleen: H3(14..15) - HillTop.RossFork.Lordstown: H90(15) - HillTop.RossFork.Belfair: H14(14) - HillTop.RossFork.Luzerne: H65(0..13) - HillTop.RossFork.Devers: H66(0..13) - HillTop.RossFork.Crozet: H5 - HillTop.RossFork.Laxon: W38 - HillTop.RossFork.Chaffee: H14(0..7) - HillTop.RossFork.Brinklow: W1(9..16) - HillTop.RossFork.Everton: W49(0..15) - HillTop.RossFork.Lafayette: B55 - HillTop.RossFork.Chevak: H9 - HillTop.RossFork.Mendocino: H32 - HillTop.RossFork.Kremlin: B40 - HillTop.RossFork.TroutRun: H65(14..15) - HillTop.RossFork.Bradner: H3(12..13) - HillTop.RossFork.Ravena: H4(12) - HillTop.RossFork.Redden: B6(0) - HillTop.RossFork.Yaurel: B9(0) - HillTop.RossFork.Bucktown: W51 - HillTop.RossFork.Hulbert: H62(12..13) - Millston.Ramos.Fayette: TW1(28..31) - Millston.Ramos.Osterdock: TW1(24..27) - Millston.Ramos.PineCity: TW1(18..23) - Millston.Ramos.Alameda: TW1(16..17) - Millston.Ramos.Rexville: TW1(0..15) - Millston.Ramos.Quinwood: TW2(16..31) - Millston.Ramos.Marfa: TW2(15) - Millston.Ramos.Palatine: TW2(14) - Millston.Ramos.Mabelle: TW2(13) - Millston.Ramos.Hoagland: TW2(0..12) - Millston.Ramos.Exton: TH1(8..15) - Millston.Ramos.Ocoee: TH1(0..7) - Millston.Ramos.Hackett: TH2 - Millston.Ramos.Kaluaaha: TW13 - Millston.Ramos.Calcasieu: TW14 - HillTop.Maddock.Kaluaaha: W37 - HillTop.Maddock.Calcasieu: W36 - HillTop.Maddock.PineCity: H83(2..7) - Millston.Bergton.Chevak: W47(16..31) - Millston.Bergton.Mendocino: W47(0..15) - Millston.Pawtucket.StarLake: TH5 - Millston.Buckhorn.SoapLake: TH26 - Millston.Cassa.Chloride: TW15 - Millston.Cassa.Garibaldi.0-15: TH5 - Millston.Cassa.Garibaldi.16-31: TH18 - Millston.Cassa.Weinert: TW3(28..31) - Millston.Cassa.Cornell: TW3(24..27) - Millston.Cassa.Noyes: TW3(16..23) - Millston.Cassa.Helton: TW3(0..15) - Millston.Provencal.Fayette: TB3(4..7) - Millston.Provencal.PineCity.0-1: H35(14..15) - Millston.Provencal.PineCity.2-5: TB3(0..3) - Millston.Provencal.Alameda: H35(12..13) - Millston.Provencal.Maryhill.0-7: B39 - Millston.Provencal.Maryhill.8-19: H35(0..11) - Millston.Provencal.Norwood: TW1(16..31) - Millston.Provencal.Dassel: TW1(8..15) - Millston.Provencal.Bushland: TW1(0..7) - Millston.Provencal.Kaluaaha.0-31: TW2 - Millston.Provencal.Kaluaaha.32-63: TW13 - Millston.Provencal.Kaluaaha.64-95: TW14 - Millston.Provencal.Kaluaaha.96-111: TH1 - Millston.Provencal.Kaluaaha.112-127: TH2 - Millston.Provencal.Calcasieu.0-15: TH19 - Millston.Provencal.Calcasieu.16-31: TH20 - Millston.Provencal.Calcasieu.32-47: TH21 - Millston.Provencal.Calcasieu.48-63: TH22 - Millston.Provencal.Calcasieu.64-71: TB12 - Millston.Provencal.Calcasieu.72-79: TB13 - Millston.Provencal.Calcasieu.80-95: TH23 - Millston.Provencal.Calcasieu.96-127: TW16 - HillTop.Sublett.Kaluaaha.0-31: W37 - HillTop.Sublett.Kaluaaha.32-63: W3 - HillTop.Sublett.Kaluaaha.64-95: W39 - HillTop.Sublett.Kaluaaha.96-127: W40 - HillTop.Sublett.Calcasieu.0-31: W44 - HillTop.Sublett.Calcasieu.32-63: W45 - HillTop.Sublett.Calcasieu.64-95: W46 - HillTop.Sublett.Calcasieu.96-127: W36 - HillTop.Sublett.PineCity: H84(6..11) - Millston.Grays.Chevak: H10 - Millston.Grays.Mendocino: H33 - Millston.Gotham.StarLake.0-7: TB2 - Millston.Gotham.StarLake.8-15: TB14 - Millston.Brookneal.SoapLake: W50(0..15) - Millston.Hoven.Noyes: TB0 - Millston.Hoven.Allison.0-7: TH3(8..15) - Millston.Hoven.Allison.8-23: TH4 - Millston.Hoven.Petrey.0-15: TH27 - Millston.Hoven.Petrey.16-23: TH3(0..7) - Millston.Hoven.Roosville: B32 - Millston.Shirley.Adona: W15(8..31) - Millston.Shirley.Connell.0-15: H39 - Millston.Shirley.Connell.16-23: W15(0..7) - Millston.Shirley.Goldsboro.0-7: B35 - Millston.Shirley.Goldsboro.8-23: H92 - Millston.Shirley.Fabens.0-7: B37 - Millston.Shirley.Fabens.8-23: H93 - Millston.Shirley.McCaulley: H94 - Millston.Osyka.Chloride: TW1 - Millston.Osyka.Garibaldi: TW2 - Millston.Osyka.Weinert: TB0(4..7) - Millston.Osyka.Cornell: TB0(0..3) - Millston.Osyka.Noyes: B32 - Millston.Osyka.Helton: TH0 - Millston.Broadwell.Palmhurst: TH0(15) - Millston.Broadwell.Comfrey: TH0(14) - Millston.Broadwell.Kalida: TH0(13) - Millston.Broadwell.Wallula: TH0(12) - Millston.Broadwell.Dennison: TH0(11) - Millston.Broadwell.Fairhaven: TH0(8..10) - Millston.Broadwell.Noyes: TH0(3..7) - Millston.Broadwell.Woodfield: TH0(0..2) - Millston.Broadwell.LasVegas.0-7: TB0 - Millston.Broadwell.LasVegas.8-15: TB2 - Millston.Maumee.Fayette: H89(12..15) - Millston.Maumee.PineCity: H89(6..11) - Millston.Maumee.Alameda: H89(4..5) - Millston.Maumee.Maryhill.0-15: H38 - Millston.Maumee.Maryhill.16-19: H89(0..3) - Millston.Maumee.Norwood.0-7: B37 - Millston.Maumee.Norwood.8-15: B35 - Millston.Maumee.Dassel: B33 - Millston.Maumee.Bushland: TB1 - Millston.Maumee.Kaluaaha.0-31: W33 - Millston.Maumee.Kaluaaha.32-63: W15 - Millston.Maumee.Kaluaaha.64-95: W34 - Millston.Maumee.Kaluaaha.96-127: W35 - Millston.Maumee.Calcasieu.0-31: W41 - Millston.Maumee.Calcasieu.32-63: W42 - Millston.Maumee.Calcasieu.64-95: W43 - Millston.Maumee.Calcasieu.96-127: W32 - HillTop.Cutten.Pathfork: H59 - HillTop.Cutten.Tombstone: H56 - HillTop.Cutten.Subiaco: H58 - HillTop.Cutten.Marcus: H60 - HillTop.Cutten.Pittsboro: H57 - HillTop.Wisdom.Adona: W13(8..31) - HillTop.Wisdom.Connell.0-15: H63 - HillTop.Wisdom.Connell.16-23: W13(0..7) - HillTop.Wisdom.Dyess: B11(0) - HillTop.Wisdom.Westhoff: B9(1..3) - HillTop.Wisdom.Havana: W11(0) - HillTop.Wisdom.Nenana: H2(0..11) - HillTop.Wisdom.Morstein: W3(0..19) - HillTop.Wisdom.Waubun: W1(2..7) - HillTop.Wisdom.Onycha: B11(1..3) - HillTop.Wisdom.Blencoe: B36 - HillTop.Wisdom.Delavan: B15(7) - HillTop.Wisdom.Miller: H48(0..8) - HillTop.Wisdom.Piqua: B9(4) - HillTop.Wisdom.RioPecos: B9(0) - HillTop.Wisdom.Dolores: W1(0..1) - HillTop.Edwards.AquaPark: B14(5..6) - HillTop.Edwards.LaConner: H86(0..5) - HillTop.Edwards.McGrady: B14(2..4) - HillTop.Edwards.Oilmont: B7(4) - HillTop.Edwards.Tornillo: B7(5) - HillTop.Edwards.Satolah: W1(17) - HillTop.Edwards.RedElm: H6(5..7) - HillTop.Edwards.Oriskany: H6(4) - HillTop.Edwards.PineCity: H90(0..5) - HillTop.Edwards.Pajaros: B56(0..4) - HillTop.Murphy.Standish: B15(3) - HillTop.Murphy.Blairsden: H64(14) - HillTop.Bessie.Kaluaaha: H48 - HillTop.Bessie.Calcasieu: H46 - HillTop.Bessie.Heuvelton: W11(2..17) - HillTop.Bessie.Chavies: H8 - HillTop.Bessie.Chevak: H12 - HillTop.Bessie.Mendocino: H44 - HillTop.Bessie.LasVegas: B43 - HillTop.Bessie.Exton: B60 - HillTop.Bessie.Noyes: B41 - HillTop.Bessie.Miranda: H62(4..11) - HillTop.Bessie.Peebles: B9(5) - HillTop.Bessie.PineCity: H90(6..11) - HillTop.Ovett.Manilla: B4 - HillTop.Ovett.Hammond.0-0: H14(11) - HillTop.Ovett.Hammond.1-3: H14(8..10) - HillTop.Ovett.Hematite: H4(13) - HillTop.Mausdale.Kenney: W5 - HillTop.Quinault.Foster: B11(4..5) - HillTop.Savery.Kaluaaha: H49 - HillTop.Savery.Calcasieu: H47 - HillTop.Savery.Chevak: H13 - HillTop.Savery.Mendocino: H45 - HillTop.Savery.LasVegas: B42 - HillTop.Savery.Exton: B58 - HillTop.Savery.Noyes: B40 - HillTop.Savery.Peebles: B10(5) - HillTop.Savery.PineCity: H85(6..11) - HillTop.Naubinway.Ayden: B9(6..7) - HillTop.Naubinway.Bonduel: H64(0..13) - HillTop.Naubinway.Sardinia: H64(0..13) - HillTop.Lewiston.Staunton: H51 - HillTop.Lewiston.Lugert: H61 - HillTop.Salix.Hueytown: H15 - HillTop.Komatke.Townville.0-11: H1(0..11) - HillTop.Komatke.Townville.12-15: H5(12..15) - HillTop.Komatke.Monahans: B12(4) - HillTop.Komatke.Pinole: H62(0) - HillTop.Freeny.Dunedin: B8(0..2) - ig_intr_md_for_tm.ucast_egress_port: W2(0..8) - ig_intr_md_for_tm.ingress_cos: B8(0..2) - ig_intr_md_for_tm.qid: B13(0..4) - ig_intr_md_for_tm.copy_to_cpu: H52(0) - ig_intr_md_for_tm.mcast_grp_a: H7 - ig_intr_md_for_tm.level2_mcast_hash: H50(0..12) - ig_intr_md_for_tm.level1_exclusion_id: H8 - ig_intr_md_for_tm.level2_exclusion_id: W9(0..8) - ig_intr_md_for_tm.rid: H5 - HillTop.Minturn.Grassflat: H34(0..9) - HillTop.Minturn.Whitewood: H34(0..9) - HillTop.Minturn.Tilton: B14(0..1) - HillTop.Moose.Townville: H8 - HillTop.Moose.Monahans: H14(13) - HillTop.Moose.Pinole: H56(0) - ig_intr_md_for_dprsr.drop_ctl: B15(0..2) - ig_intr_md_for_dprsr.digest_type: B0(0..2) - ig_intr_md_for_dprsr.mirror_type: B1(0..2) - HillTop.Plains.Roachdale: B38 - HillTop.Plains.Miller: H57(0..8) - Millston.Belgrade.$valid: B54(0) - Millston.Hayfield.$valid: B54(1) - Millston.Calabash.$valid: B54(2) - Millston.Rainelle.$valid: B54(3) - Millston.GlenAvon.$valid: B54(4) - Millston.Ramos.$valid: B54(5) - Millston.Bergton.$valid: B54(6) - Millston.Pawtucket.$valid: B54(7) - Millston.Buckhorn.$valid: H95(0) - Millston.Cassa.$valid: H95(1) - Millston.Provencal.$valid: H95(2) - Millston.Grays.$valid: H95(3) - Millston.Gotham.$valid: H95(4) - Millston.Brookneal.$valid: H95(5) - Millston.Hoven.$valid: H95(7) - Millston.Shirley.$valid: H95(8) - Millston.Osyka.$valid: H95(6) - Millston.Broadwell.$valid: H95(9) - Millston.Maumee.$valid: H95(10) - Millston.Wondervu.$stkvalid: B12(0..1) - Millston.Wondervu$0.$valid: B12(1) - Millston.Wondervu$1.$valid: B12(0) - context_json: - TB0: - Millston.Osyka.Cornell: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Hoven.Noyes, Millston.Broadwell.LasVegas ] - Millston.Osyka.Weinert: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Hoven.Noyes, Millston.Broadwell.LasVegas ] - Millston.Hoven.Noyes: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Osyka.Cornell, Millston.Osyka.Weinert, Millston.Broadwell.LasVegas ] - Millston.Broadwell.LasVegas: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Osyka.Cornell, Millston.Osyka.Weinert, Millston.Hoven.Noyes ] - TB1: - Millston.Maumee.Bushland: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.GlenAvon.Exton ] - Millston.GlenAvon.Exton: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Bushland ] - TB2: - Millston.Broadwell.LasVegas: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Gotham.StarLake ] - Millston.Gotham.StarLake: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Broadwell.LasVegas ] - TB3: - Millston.Provencal.PineCity: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Provencal.Fayette: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TB12: - Millston.Provencal.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TB13: - Millston.Provencal.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TB14: - Millston.Gotham.StarLake: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH0: - Millston.Osyka.Helton: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Broadwell.Woodfield, Millston.Broadwell.Noyes, Millston.Broadwell.Fairhaven, Millston.Broadwell.Dennison, Millston.Broadwell.Wallula, Millston.Broadwell.Kalida, Millston.Broadwell.Comfrey, Millston.Broadwell.Palmhurst, Millston.Rainelle.Quogue, Millston.Rainelle.Steger ] - Millston.Broadwell.Woodfield: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Rainelle.Quogue, Millston.Rainelle.Steger ] - Millston.Broadwell.Noyes: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Rainelle.Quogue, Millston.Rainelle.Steger ] - Millston.Broadwell.Fairhaven: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Rainelle.Quogue, Millston.Rainelle.Steger ] - Millston.Broadwell.Dennison: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Rainelle.Quogue, Millston.Rainelle.Steger ] - Millston.Broadwell.Wallula: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Rainelle.Quogue, Millston.Rainelle.Steger ] - Millston.Broadwell.Kalida: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Rainelle.Quogue, Millston.Rainelle.Steger ] - Millston.Broadwell.Comfrey: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Rainelle.Quogue, Millston.Rainelle.Steger ] - Millston.Broadwell.Palmhurst: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Rainelle.Quogue, Millston.Rainelle.Steger ] - Millston.Rainelle.Quogue: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Broadwell.Woodfield, Millston.Broadwell.Noyes, Millston.Broadwell.Fairhaven, Millston.Broadwell.Dennison, Millston.Broadwell.Wallula, Millston.Broadwell.Kalida, Millston.Broadwell.Comfrey, Millston.Broadwell.Palmhurst ] - Millston.Rainelle.Steger: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Broadwell.Woodfield, Millston.Broadwell.Noyes, Millston.Broadwell.Fairhaven, Millston.Broadwell.Dennison, Millston.Broadwell.Wallula, Millston.Broadwell.Kalida, Millston.Broadwell.Comfrey, Millston.Broadwell.Palmhurst ] - TH1: - Millston.Ramos.Ocoee: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] - Millston.Ramos.Exton: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] - Millston.Provencal.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Ocoee, Millston.Ramos.Exton ] - TH2: - Millston.Ramos.Hackett: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] - Millston.Provencal.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Hackett ] - TH3: - Millston.Hoven.Petrey: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Hoven.Allison: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH4: - Millston.Hoven.Allison: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH5: - Millston.Cassa.Garibaldi: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Pawtucket.StarLake ] - Millston.Pawtucket.StarLake: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Cassa.Garibaldi ] - TH18: - Millston.Cassa.Garibaldi: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH19: - Millston.Provencal.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH20: - Millston.Provencal.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH21: - Millston.Provencal.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH22: - Millston.Provencal.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH23: - Millston.Provencal.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH24: - Millston.Wondervu$1.Bowden: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Wondervu$1.Oriskany: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Wondervu$1.Higginson: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH25: - Millston.GlenAvon.Hackett: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH26: - Millston.Buckhorn.SoapLake: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH27: - Millston.Hoven.Petrey: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TW0: - Millston.GlenAvon.Hoagland: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.GlenAvon.Mabelle: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.GlenAvon.Palatine: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.GlenAvon.Marfa: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.GlenAvon.Quinwood: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TW1: - Millston.Ramos.Rexville: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Chloride ] - Millston.Ramos.Alameda: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Chloride ] - Millston.Ramos.PineCity: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Chloride ] - Millston.Ramos.Osterdock: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Chloride ] - Millston.Ramos.Fayette: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Chloride ] - Millston.Provencal.Bushland: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Rexville, Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Chloride ] - Millston.Provencal.Dassel: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Rexville, Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Chloride ] - Millston.Provencal.Norwood: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Rexville, Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Chloride ] - Millston.Rainelle.Ledoux: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Rexville, Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] - Millston.Rainelle.Conner: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Rexville, Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] - Millston.Osyka.Chloride: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Rexville, Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner ] - TW2: - Millston.Ramos.Hoagland: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Kaluaaha, Millston.Osyka.Garibaldi ] - Millston.Ramos.Mabelle: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Kaluaaha, Millston.Osyka.Garibaldi ] - Millston.Ramos.Palatine: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Kaluaaha, Millston.Osyka.Garibaldi ] - Millston.Ramos.Marfa: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Kaluaaha, Millston.Osyka.Garibaldi ] - Millston.Ramos.Quinwood: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Kaluaaha, Millston.Osyka.Garibaldi ] - Millston.Provencal.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Hoagland, Millston.Ramos.Mabelle, Millston.Ramos.Palatine, Millston.Ramos.Marfa, Millston.Ramos.Quinwood, Millston.Osyka.Garibaldi ] - Millston.Osyka.Garibaldi: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Hoagland, Millston.Ramos.Mabelle, Millston.Ramos.Palatine, Millston.Ramos.Marfa, Millston.Ramos.Quinwood, Millston.Provencal.Kaluaaha ] - TW3: - Millston.Cassa.Helton: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Cassa.Noyes: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Cassa.Cornell: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Cassa.Weinert: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TW12: - Millston.Belgrade.Ronan: - mutually_exclusive_with: [ ] - TW13: - Millston.Ramos.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] - Millston.Provencal.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Kaluaaha ] - TW14: - Millston.Ramos.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] - Millston.Provencal.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Calcasieu ] - TW15: - Millston.Cassa.Chloride: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TW16: - Millston.Provencal.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - B0: - ig_intr_md_for_dprsr.digest_type: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - B1: - ig_intr_md_for_dprsr.mirror_type: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - B2: - HillTop.RossFork.Suttle: - live_start: parser - live_end: 9 - mutually_exclusive_with: [ ] - B3: - HillTop.RossFork.Boerne: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - B4: - HillTop.Ovett.Manilla: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - B5: - HillTop.RossFork.Thayne: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - B6: - HillTop.RossFork.Redden: - live_start: parser - live_end: 10 - mutually_exclusive_with: [ ] - B7: - Millston.Belgrade.Willard: - live_start: 8 - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Belgrade.__pad_4: - mutually_exclusive_with: [ ] - HillTop.RossFork.Denhoff: - live_start: 0 - live_end: 6 - mutually_exclusive_with: [ ] - HillTop.Aldan.Kearns: - live_start: parser - live_end: 0 - mutually_exclusive_with: [ ] - HillTop.Edwards.Oilmont: - live_start: 7 - live_end: 8 - mutually_exclusive_with: [ ] - HillTop.Edwards.Tornillo: - live_start: 7 - live_end: 8 - mutually_exclusive_with: [ ] - B8: - ig_intr_md_for_tm.ingress_cos: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - HillTop.Aldan.Malinta: - live_start: parser - live_end: 0 - mutually_exclusive_with: [ ] - HillTop.RossFork.Naruna: - live_start: 0 - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.RossFork.Brinkman: - live_start: 2 - live_end: 10 - mutually_exclusive_with: [ ] - HillTop.Freeny.Dunedin: - live_start: 7 - live_end: 8 - mutually_exclusive_with: [ ] - B9: - Millston.Belgrade.Waipahu: - mutually_exclusive_with: [ ] - Millston.Belgrade.Allgood: - mutually_exclusive_with: [ ] - Millston.Belgrade.Shabbona: - mutually_exclusive_with: [ ] - Millston.Belgrade.Anacortes: - mutually_exclusive_with: [ ] - Millston.Belgrade.__pad_1: - mutually_exclusive_with: [ ] - HillTop.Naubinway.Ayden: - live_start: parser - live_end: 6 - mutually_exclusive_with: [ ] - HillTop.RossFork.Yaurel: - live_start: parser - live_end: 10 - mutually_exclusive_with: [ ] - HillTop.Bessie.Peebles: - live_start: 0 - live_end: 9 - mutually_exclusive_with: [ ] - HillTop.Wisdom.Piqua: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.Wisdom.Westhoff: - live_start: parser - live_end: 10 - mutually_exclusive_with: [ ] - HillTop.Wisdom.RioPecos: - mutually_exclusive_with: [ ] - B10: - HillTop.Savery.Peebles: - live_start: 2 - live_end: 10 - mutually_exclusive_with: [ ] - HillTop.Aldan.Mystic: - live_start: parser - live_end: 0 - mutually_exclusive_with: [ ] - B11: - Millston.Belgrade.Rockport: - mutually_exclusive_with: [ ] - Millston.Belgrade.Union: - mutually_exclusive_with: [ ] - Millston.Belgrade.__pad_0: - mutually_exclusive_with: [ ] - HillTop.Quinault.Foster: - live_start: parser - live_end: 8 - mutually_exclusive_with: [ ] - HillTop.RossFork.Powderly: - live_start: parser - live_end: 8 - mutually_exclusive_with: [ ] - HillTop.Wisdom.Onycha: - live_start: 0 - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.Wisdom.Dyess: - mutually_exclusive_with: [ ] - B12: - Millston.Wondervu.$stkvalid: - mutually_exclusive_with: [ ] - HillTop.RossFork.ElVerano: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.RossFork.Alamosa: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.Komatke.Monahans: - live_start: parser - live_end: 10 - mutually_exclusive_with: [ ] - HillTop.RossFork.Weyauwega: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.RossFork.Charco: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.RossFork.Daphne: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - Millston.Wondervu$0.$valid: - live_start: 7 - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Wondervu$1.$valid: - mutually_exclusive_with: [ ] - B13: - ig_intr_md_for_tm.qid: - live_start: 7 - live_end: deparser - mutually_exclusive_with: [ ] - HillTop.Aldan.Parkville: - live_start: parser - live_end: 1 - mutually_exclusive_with: [ ] - HillTop.RossFork.Naruna: - live_start: 0 - live_end: 11 - mutually_exclusive_with: [ ] - B14: - HillTop.Aldan.Mystic: - live_start: parser - live_end: 0 - mutually_exclusive_with: [ ] - HillTop.Minturn.Tilton: - live_start: 10 - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.Edwards.McGrady: - live_start: 0 - live_end: 7 - mutually_exclusive_with: [ ] - HillTop.Edwards.AquaPark: - live_start: 0 - live_end: 8 - mutually_exclusive_with: [ ] - B15: - ig_intr_md_for_dprsr.drop_ctl: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - HillTop.Murphy.Standish: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.RossFork.Level: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.RossFork.Lowes: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.RossFork.Chugwater: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.Wisdom.Delavan: - live_start: parser - live_end: 6 - mutually_exclusive_with: [ ] - B32: - Millston.Osyka.Noyes: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Hoven.Roosville ] - Millston.Hoven.Roosville: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Osyka.Noyes ] - B33: - Millston.Maumee.Dassel: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.GlenAvon.Ocoee ] - Millston.GlenAvon.Ocoee: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Dassel ] - B34: - Millston.Belgrade.Freeburg: - mutually_exclusive_with: [ ] - Millston.Belgrade.__pad_2: - mutually_exclusive_with: [ ] - HillTop.Lamona.Pachuta: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - B35: - Millston.Maumee.Norwood: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Shirley.Goldsboro ] - Millston.Shirley.Goldsboro: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Norwood ] - B36: - Millston.Belgrade.Mankato: - mutually_exclusive_with: [ ] - HillTop.Wisdom.Blencoe: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - B37: - Millston.Shirley.Fabens: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Norwood ] - Millston.Maumee.Norwood: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Shirley.Fabens ] - B38: - HillTop.Plains.Roachdale: - live_start: 8 - live_end: deparser - mutually_exclusive_with: [ ] - HillTop.RossFork.Teigen: - live_start: parser - live_end: 1 - mutually_exclusive_with: [ ] - B39: - Millston.Provencal.Maryhill: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - B40: - HillTop.RossFork.Kremlin: - live_start: parser - live_end: 1 - mutually_exclusive_with: [ ] - HillTop.Savery.Noyes: - live_start: 2 - live_end: 10 - mutually_exclusive_with: [ ] - B41: - HillTop.Bessie.Noyes: - live_start: parser - live_end: 9 - mutually_exclusive_with: [ ] - B42: - HillTop.Aldan.Vinemont: - live_start: parser - live_end: 0 - mutually_exclusive_with: [ ] - HillTop.Savery.LasVegas: - live_start: 2 - live_end: 10 - mutually_exclusive_with: [ ] - B43: - HillTop.Bessie.LasVegas: - live_start: parser - live_end: 9 - mutually_exclusive_with: [ ] - B44: - HillTop.RossFork.Ocoee: - live_start: 0 - live_end: 10 - mutually_exclusive_with: [ ] - B45: - HillTop.RossFork.Ankeny: - live_start: 0 - live_end: 9 - mutually_exclusive_with: [ ] - B47: - Millston.Hayfield.Vichy: - live_start: parser - live_end: 7 - mutually_exclusive_with: [ ] - Millston.Hayfield.AquaPark: - live_start: parser - live_end: 7 - mutually_exclusive_with: [ ] - B48: - Millston.Wondervu$0.McCaulley: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - B49: - Millston.Wondervu$1.McCaulley: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - B50: - Millston.Calabash.McCaulley: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - B51: - Millston.Wondervu$0.McCaulley: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - B52: - Millston.Wondervu$1.McCaulley: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - B53: - Millston.Calabash.McCaulley: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - B54: - Millston.Belgrade.$valid: - live_start: 8 - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Hayfield.$valid: - live_start: parser - live_end: 7 - mutually_exclusive_with: [ ] - Millston.Calabash.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Rainelle.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.GlenAvon.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Ramos.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Bergton.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Pawtucket.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - B55: - HillTop.RossFork.Lafayette: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - B56: - HillTop.RossFork.McCaulley: - live_start: parser - live_end: 7 - mutually_exclusive_with: [ ] - HillTop.Edwards.Pajaros: - live_start: 10 - live_end: 11 - mutually_exclusive_with: [ ] - B57: - HillTop.RossFork.McCaulley: - live_start: parser - live_end: 7 - mutually_exclusive_with: [ ] - B58: - HillTop.Aldan.Kenbridge: - live_start: parser - live_end: 0 - mutually_exclusive_with: [ ] - HillTop.Savery.Exton: - live_start: 2 - live_end: 10 - mutually_exclusive_with: [ ] - B59: - HillTop.RossFork.Exton: - live_start: parser - live_end: 7 - mutually_exclusive_with: [ ] - B60: - HillTop.Bessie.Exton: - live_start: parser - live_end: 9 - mutually_exclusive_with: [ ] - H0: - Millston.Wondervu$0.Bowden: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Wondervu$0.Oriskany: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Wondervu$0.Higginson: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H1: - HillTop.Lamona.Traverse: - live_start: parser - live_end: 0 - mutually_exclusive_with: [ ] - HillTop.Komatke.Townville: - live_start: parser - live_end: 10 - mutually_exclusive_with: [ ] - H2: - Millston.Belgrade.Requa: - mutually_exclusive_with: [ ] - Millston.Belgrade.__pad_7: - mutually_exclusive_with: [ ] - HillTop.Wisdom.Nenana: - live_start: parser - live_end: 10 - mutually_exclusive_with: [ ] - H3: - Millston.Belgrade.Florien: - mutually_exclusive_with: [ ] - Millston.Belgrade.__pad_9: - mutually_exclusive_with: [ ] - HillTop.RossFork.Bradner: - live_start: parser - live_end: 9 - mutually_exclusive_with: [ ] - HillTop.RossFork.Caroleen: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - HillTop.RossFork.Bicknell: - live_start: parser - live_end: 6 - mutually_exclusive_with: [ ] - H4: - Millston.Belgrade.Bayshore: - mutually_exclusive_with: [ ] - Millston.Belgrade.__pad_8: - mutually_exclusive_with: [ ] - HillTop.RossFork.Ravena: - live_start: parser - live_end: 9 - mutually_exclusive_with: [ ] - HillTop.Ovett.Hematite: - live_start: parser - live_end: 10 - mutually_exclusive_with: [ ] - HillTop.RossFork.CeeVee: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H5: - ig_intr_md_for_tm.rid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - HillTop.Komatke.Townville: - live_start: parser - live_end: 10 - mutually_exclusive_with: [ ] - HillTop.RossFork.Crozet: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - H6: - Millston.Belgrade.Cacao: - mutually_exclusive_with: [ ] - Millston.Belgrade.Davie: - mutually_exclusive_with: [ ] - Millston.Belgrade.Rugby: - mutually_exclusive_with: [ ] - Millston.Belgrade.Roachdale: - mutually_exclusive_with: [ ] - HillTop.Edwards.Oriskany: - mutually_exclusive_with: [ ] - HillTop.Edwards.RedElm: - live_start: parser - live_end: 7 - mutually_exclusive_with: [ ] - H7: - ig_intr_md_for_tm.mcast_grp_a: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H8: - HillTop.Moose.Townville: - live_start: parser - live_end: 10 - mutually_exclusive_with: [ ] - ig_intr_md_for_tm.level1_exclusion_id: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - HillTop.Bessie.Chavies: - live_start: parser - live_end: 7 - mutually_exclusive_with: [ ] - H9: - HillTop.RossFork.Chevak: - live_start: parser - live_end: 10 - mutually_exclusive_with: [ ] - H10: - Millston.Grays.Chevak: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H11: - HillTop.RossFork.Glenmora: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - H12: - HillTop.Bessie.Chevak: - live_start: 0 - live_end: 9 - mutually_exclusive_with: [ ] - H13: - HillTop.Savery.Chevak: - live_start: 2 - live_end: 10 - mutually_exclusive_with: [ ] - H14: - HillTop.RossFork.Chaffee: - live_start: parser - live_end: 9 - mutually_exclusive_with: [ ] - HillTop.Ovett.Hammond: - live_start: parser - live_end: 10 - mutually_exclusive_with: [ ] - HillTop.RossFork.Almedia: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.Moose.Monahans: - live_start: parser - live_end: 10 - mutually_exclusive_with: [ ] - HillTop.RossFork.Belfair: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - H15: - HillTop.Salix.Hueytown: - live_start: parser - live_end: 8 - mutually_exclusive_with: [ ] - H32: - HillTop.RossFork.Mendocino: - live_start: parser - live_end: 10 - mutually_exclusive_with: [ ] - H33: - Millston.Grays.Mendocino: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H34: - HillTop.Minturn.Whitewood: - live_start: parser - live_end: 10 - mutually_exclusive_with: [ ] - HillTop.RossFork.Joslin: - live_start: parser - live_end: 7 - mutually_exclusive_with: [ ] - HillTop.Minturn.Grassflat: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H35: - Millston.Provencal.Maryhill: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Rainelle.Findlay ] - Millston.Provencal.Alameda: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Rainelle.Findlay ] - Millston.Provencal.PineCity: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Rainelle.Findlay ] - Millston.Rainelle.Findlay: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Maryhill, Millston.Provencal.Alameda, Millston.Provencal.PineCity ] - H36: - Millston.Calabash.Goldsboro: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H37: - HillTop.RossFork.Goldsboro: - live_start: 0 - live_end: deparser - mutually_exclusive_with: [ ] - H38: - Millston.GlenAvon.Rexville: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Maryhill ] - Millston.Maumee.Maryhill: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.GlenAvon.Rexville ] - H39: - Millston.Shirley.Connell: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H40: - HillTop.RossFork.DonaAna: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - H41: - HillTop.RossFork.Merrill: - live_start: parser - live_end: 9 - mutually_exclusive_with: [ ] - H42: - HillTop.RossFork.Hickox: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - H43: - HillTop.RossFork.Tehachapi: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - H44: - HillTop.Bessie.Mendocino: - live_start: parser - live_end: 9 - mutually_exclusive_with: [ ] - H45: - HillTop.Savery.Mendocino: - live_start: 2 - live_end: 10 - mutually_exclusive_with: [ ] - H46: - HillTop.Bessie.Calcasieu: - live_start: parser - live_end: 9 - mutually_exclusive_with: [ ] - H47: - HillTop.Savery.Calcasieu: - live_start: 2 - live_end: 10 - mutually_exclusive_with: [ ] - H48: - HillTop.Bessie.Kaluaaha: - live_start: parser - live_end: 9 - mutually_exclusive_with: [ ] - HillTop.Aldan.Poulan: - live_start: parser - live_end: 0 - mutually_exclusive_with: [ ] - Millston.Belgrade.Chaska: - mutually_exclusive_with: [ ] - Millston.Belgrade.__pad_6: - mutually_exclusive_with: [ ] - HillTop.Wisdom.Miller: - mutually_exclusive_with: [ ] - H49: - HillTop.Savery.Kaluaaha: - live_start: 2 - live_end: 10 - mutually_exclusive_with: [ ] - H50: - ig_intr_md_for_tm.level2_mcast_hash: - live_start: 8 - live_end: deparser - mutually_exclusive_with: [ ] - HillTop.Aldan.Kearns: - live_start: parser - live_end: 0 - mutually_exclusive_with: [ ] - H51: - Millston.Belgrade.Corinth: - mutually_exclusive_with: [ ] - HillTop.Lewiston.Staunton: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - H52: - ig_intr_md_for_tm.copy_to_cpu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H53: - HillTop.Tiburon.Arnold: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - H54: - Millston.Calabash.Connell: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H55: - HillTop.RossFork.Connell: - live_start: 0 - live_end: 6 - mutually_exclusive_with: [ ] - H56: - HillTop.Cutten.Tombstone: - live_start: 3 - live_end: 6 - mutually_exclusive_with: [ ] - HillTop.Moose.Pinole: - live_start: 6 - live_end: 10 - mutually_exclusive_with: [ ] - HillTop.Aldan.Malinta: - live_start: parser - live_end: 0 - mutually_exclusive_with: [ ] - H57: - HillTop.Cutten.Pittsboro: - live_start: 3 - live_end: 6 - mutually_exclusive_with: [ ] - HillTop.Plains.Miller: - live_start: 8 - live_end: deparser - mutually_exclusive_with: [ ] - H58: - HillTop.Cutten.Subiaco: - live_start: 2 - live_end: 6 - mutually_exclusive_with: [ ] - H59: - HillTop.Cutten.Pathfork: - live_start: 2 - live_end: 6 - mutually_exclusive_with: [ ] - H60: - HillTop.Cutten.Marcus: - live_start: parser - live_end: 6 - mutually_exclusive_with: [ ] - H61: - HillTop.Lewiston.Lugert: - live_start: parser - live_end: 6 - mutually_exclusive_with: [ ] - HillTop.RossFork.Altus: - live_start: parser - live_end: 1 - mutually_exclusive_with: [ ] - H62: - HillTop.Komatke.Pinole: - live_start: parser - live_end: 10 - mutually_exclusive_with: [ ] - HillTop.RossFork.Parkland: - live_start: 2 - live_end: 8 - mutually_exclusive_with: [ ] - HillTop.RossFork.Denhoff: - live_start: 0 - live_end: 6 - mutually_exclusive_with: [ ] - HillTop.Bessie.Miranda: - live_start: parser - live_end: 10 - mutually_exclusive_with: [ ] - HillTop.RossFork.Hulbert: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - H63: - HillTop.Aldan.Blakeley: - live_start: parser - live_end: 1 - mutually_exclusive_with: [ ] - Millston.Belgrade.Florin: - live_start: 2 - live_end: deparser - mutually_exclusive_with: [ ] - HillTop.Wisdom.Connell: - live_start: parser - live_end: 8 - mutually_exclusive_with: [ ] - H64: - HillTop.Naubinway.Sardinia: - live_start: parser - live_end: 6 - mutually_exclusive_with: [ HillTop.Naubinway.Bonduel ] - HillTop.Naubinway.Bonduel: - live_start: parser - live_end: 7 - mutually_exclusive_with: [ HillTop.Naubinway.Sardinia ] - HillTop.Murphy.Blairsden: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - H65: - HillTop.RossFork.Luzerne: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - HillTop.RossFork.TroutRun: - live_start: parser - live_end: 9 - mutually_exclusive_with: [ ] - H66: - HillTop.RossFork.Devers: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - HillTop.RossFork.Tenino: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.RossFork.Pridgen: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - H83: - HillTop.Maddock.PineCity: - live_start: parser - live_end: 3 - mutually_exclusive_with: [ ] - H84: - HillTop.Sublett.PineCity: - live_start: parser - live_end: 3 - mutually_exclusive_with: [ ] - H85: - HillTop.Savery.PineCity: - live_start: 2 - live_end: 10 - mutually_exclusive_with: [ ] - HillTop.RossFork.Welcome: - live_start: parser - live_end: 1 - mutually_exclusive_with: [ ] - H86: - HillTop.Edwards.LaConner: - live_start: 0 - live_end: 3 - mutually_exclusive_with: [ ] - H89: - Millston.GlenAvon.Alameda: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Maryhill, Millston.Maumee.Alameda, Millston.Maumee.PineCity, Millston.Maumee.Fayette ] - Millston.GlenAvon.PineCity: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Maryhill, Millston.Maumee.Alameda, Millston.Maumee.PineCity, Millston.Maumee.Fayette ] - Millston.GlenAvon.Osterdock: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Maryhill, Millston.Maumee.Alameda, Millston.Maumee.PineCity, Millston.Maumee.Fayette ] - Millston.GlenAvon.Fayette: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Maryhill, Millston.Maumee.Alameda, Millston.Maumee.PineCity, Millston.Maumee.Fayette ] - Millston.Maumee.Maryhill: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.GlenAvon.Alameda, Millston.GlenAvon.PineCity, Millston.GlenAvon.Osterdock, Millston.GlenAvon.Fayette ] - Millston.Maumee.Alameda: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.GlenAvon.Alameda, Millston.GlenAvon.PineCity, Millston.GlenAvon.Osterdock, Millston.GlenAvon.Fayette ] - Millston.Maumee.PineCity: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.GlenAvon.Alameda, Millston.GlenAvon.PineCity, Millston.GlenAvon.Osterdock, Millston.GlenAvon.Fayette ] - Millston.Maumee.Fayette: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.GlenAvon.Alameda, Millston.GlenAvon.PineCity, Millston.GlenAvon.Osterdock, Millston.GlenAvon.Fayette ] - H90: - Millston.Belgrade.Matheson: - mutually_exclusive_with: [ ] - Millston.Belgrade.__pad_5: - mutually_exclusive_with: [ ] - HillTop.Bessie.PineCity: - live_start: parser - live_end: 9 - mutually_exclusive_with: [ ] - HillTop.RossFork.Sewaren: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - HillTop.RossFork.WindGap: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - HillTop.RossFork.Lordstown: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - HillTop.Edwards.PineCity: - live_start: parser - live_end: 7 - mutually_exclusive_with: [ ] - H92: - Millston.Shirley.Goldsboro: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H93: - Millston.Shirley.Fabens: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H94: - Millston.Shirley.McCaulley: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H95: - Millston.Buckhorn.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Cassa.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Provencal.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Grays.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Gotham.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Brookneal.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Osyka.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Hoven.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Shirley.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Broadwell.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Maumee.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - HillTop.RossFork.Juniata: - live_start: parser - live_end: 10 - mutually_exclusive_with: [ ] - W0: - HillTop.Lamona.Whitefish: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.RossFork.Adona: - live_start: 0 - live_end: 6 - mutually_exclusive_with: [ ] - W1: - Millston.Belgrade.Selawik: - mutually_exclusive_with: [ ] - Millston.Belgrade.Sudbury: - mutually_exclusive_with: [ ] - Millston.Belgrade.__pad_3: - mutually_exclusive_with: [ ] - HillTop.RossFork.Halaula: - live_start: parser - live_end: 6 - mutually_exclusive_with: [ ] - HillTop.RossFork.Brinklow: - live_start: parser - live_end: 9 - mutually_exclusive_with: [ ] - HillTop.Edwards.Satolah: - live_start: parser - live_end: 7 - mutually_exclusive_with: [ ] - HillTop.RossFork.Beaverdam: - live_start: parser - live_end: 8 - mutually_exclusive_with: [ ] - HillTop.RossFork.Knierim: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - HillTop.Wisdom.Dolores: - mutually_exclusive_with: [ ] - HillTop.Wisdom.Waubun: - mutually_exclusive_with: [ ] - W2: - ig_intr_md_for_tm.ucast_egress_port: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - W3: - HillTop.Wisdom.Morstein: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.Sublett.Kaluaaha: - live_start: parser - live_end: 1 - mutually_exclusive_with: [ ] - W4: - HillTop.RossFork.Quebrada: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - W5: - HillTop.Mausdale.Kenney: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - W6: - Millston.Calabash.Fabens: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Calabash.Goldsboro: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - W7: - HillTop.RossFork.Fabens: - live_start: 0 - live_end: deparser - mutually_exclusive_with: [ ] - W8: - HillTop.RossFork.Goldsboro: - live_start: 0 - live_end: deparser - mutually_exclusive_with: [ ] - W9: - ig_intr_md_for_tm.level2_exclusion_id: - live_start: 8 - live_end: deparser - mutually_exclusive_with: [ ] - HillTop.RossFork.Uvalde: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - W10: - HillTop.RossFork.Kapalua: - live_start: parser - live_end: 7 - mutually_exclusive_with: [ ] - W11: - HillTop.Wisdom.Havana: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.RossFork.Algoa: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.Bessie.Heuvelton: - live_start: parser - live_end: 7 - mutually_exclusive_with: [ ] - W12: - Millston.Calabash.Connell: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Calabash.Adona: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - W13: - Millston.Belgrade.Florin: - live_start: 2 - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Belgrade.Virgil: - mutually_exclusive_with: [ ] - HillTop.Wisdom.Adona: - live_start: parser - live_end: 8 - mutually_exclusive_with: [ ] - HillTop.Wisdom.Connell: - live_start: parser - live_end: 8 - mutually_exclusive_with: [ ] - W14: - HillTop.RossFork.Connell: - live_start: 0 - live_end: 6 - mutually_exclusive_with: [ ] - HillTop.Lamona.Fristoe: - live_start: parser - live_end: 7 - mutually_exclusive_with: [ ] - W15: - Millston.Maumee.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Shirley.Connell, Millston.Shirley.Adona ] - Millston.Shirley.Connell: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] - Millston.Shirley.Adona: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] - W32: - Millston.Maumee.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.GlenAvon.Kaluaaha ] - Millston.GlenAvon.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Calcasieu ] - W33: - Millston.GlenAvon.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] - Millston.Maumee.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.GlenAvon.Calcasieu ] - W34: - Millston.Maumee.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - W35: - Millston.Maumee.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - W36: - HillTop.Sublett.Calcasieu: - live_start: parser - live_end: 6 - mutually_exclusive_with: [ HillTop.Maddock.Calcasieu ] - HillTop.Maddock.Calcasieu: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ HillTop.Sublett.Calcasieu ] - W37: - HillTop.Maddock.Kaluaaha: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ HillTop.Sublett.Kaluaaha ] - HillTop.Sublett.Kaluaaha: - live_start: parser - live_end: 1 - mutually_exclusive_with: [ HillTop.Maddock.Kaluaaha ] - W38: - HillTop.RossFork.Laxon: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - W39: - HillTop.Sublett.Kaluaaha: - live_start: parser - live_end: 1 - mutually_exclusive_with: [ ] - HillTop.RossFork.Montross: - live_start: 6 - live_end: 9 - mutually_exclusive_with: [ ] - W40: - HillTop.Sublett.Kaluaaha: - live_start: parser - live_end: 1 - mutually_exclusive_with: [ ] - W41: - Millston.Maumee.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - W42: - Millston.Maumee.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - W43: - Millston.Maumee.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - W44: - HillTop.Sublett.Calcasieu: - live_start: parser - live_end: 6 - mutually_exclusive_with: [ ] - W45: - HillTop.Sublett.Calcasieu: - live_start: parser - live_end: 6 - mutually_exclusive_with: [ ] - W46: - HillTop.Sublett.Calcasieu: - live_start: parser - live_end: 6 - mutually_exclusive_with: [ ] - W47: - Millston.Bergton.Mendocino: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Bergton.Chevak: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - W48: - Millston.Hayfield.Grabill: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - Millston.Hayfield.Glassboro: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - Millston.Hayfield.Avondale: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - Millston.Hayfield.Blitchton: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - W49: - HillTop.RossFork.Everton: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - W50: - Millston.Brookneal.SoapLake: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - W51: - HillTop.RossFork.Bucktown: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] -phv egress: - eg_intr_md.egress_port: H16(0..8) - eg_intr_md.egress_rid: W27(0..15) - eg_intr_md.egress_qid: W31(0..4) - HillTop.Sonoma.Iberia: H17 - HillTop.Wisdom.Adona.0-7: B21 - HillTop.Wisdom.Adona.8-23: H91 - HillTop.Wisdom.Connell.0-7: B30 - HillTop.Wisdom.Connell.8-23: H67 - HillTop.Wisdom.Dyess: W29(0) - HillTop.Wisdom.Westhoff: W28(1..3) - HillTop.Wisdom.Nenana: H21(0..11) - HillTop.Wisdom.Waubun: W30(2..7) - HillTop.Wisdom.Bowden: H23(0..11) - HillTop.Wisdom.Onycha: W29(1..3) - HillTop.Wisdom.Blencoe: B27 - HillTop.Wisdom.Bennet.0-15: TW23(0..15) - HillTop.Wisdom.Bennet.16-23: W25(0..7) - HillTop.Wisdom.Bennet.24-31: TB10 - HillTop.Wisdom.Jenners: H23(14..15) - HillTop.Wisdom.Miller.0-7: W24(8..15) - HillTop.Wisdom.Miller.8-8: B25(0) - HillTop.Wisdom.Toklat: H23(12..13) - HillTop.Wisdom.Piqua: W28(4) - HillTop.Wisdom.Stratford: B63(0) - HillTop.Wisdom.RioPecos: W28(0) - HillTop.Wisdom.Weatherby: B19(5) - HillTop.Wisdom.Lathrop: B20(3) - HillTop.Wisdom.DeGraff: B20(4..5) - HillTop.Wisdom.Dolores: W30(0..1) - Millston.Belgrade.Rugby: H20(5..7) - Millston.Belgrade.Davie: H20(4) - Millston.Belgrade.Mankato: B27 - Millston.Belgrade.Virgil.0-7: B21 - Millston.Belgrade.Virgil.8-23: H91 - Millston.Belgrade.Florin.0-7: B30 - Millston.Belgrade.Florin.8-23: H67 - Millston.Belgrade.Ronan.0-15: TW23(0..15) - Millston.Belgrade.Ronan.16-23: W25(0..7) - Millston.Belgrade.Ronan.24-31: TB10 - Millston.Belgrade.Corinth: W26(0..15) - Millston.Belgrade.Union: W29(1..3) - Millston.Belgrade.Rockport: W29(0) - Millston.Belgrade.Anacortes: W28(5) - Millston.Belgrade.Shabbona: W28(4) - Millston.Belgrade.Allgood: W28(1..3) - Millston.Belgrade.Waipahu: W28(0) - Millston.Belgrade.Freeburg: B61(0) - Millston.Belgrade.Sudbury: W30(2..7) - Millston.Belgrade.Selawik: W30(0..1) - Millston.Belgrade.Willard: B62(0..2) - Millston.Belgrade.Matheson: H80(0..5) - Millston.Belgrade.Chaska.0-7: W24(8..15) - Millston.Belgrade.Chaska.8-8: B25(0) - Millston.Belgrade.Requa: H21(0..11) - Millston.Belgrade.Bayshore: H29(0..11) - Millston.Belgrade.Florien: H27(0..11) - Millston.Calabash.Adona.0-7: B22 - Millston.Calabash.Adona.8-23: H87 - Millston.Calabash.Connell.0-7: B31 - Millston.Calabash.Connell.8-23: H68 - Millston.Calabash.Goldsboro.0-15: H73 - Millston.Calabash.Goldsboro.16-23: B29 - Millston.Calabash.Fabens.0-15: H26 - Millston.Calabash.Fabens.16-23: B24 - Millston.Calabash.McCaulley: H25 - Millston.Wondervu$0.Higginson: H22(13..15) - Millston.Wondervu$0.Oriskany: H22(12) - Millston.Wondervu$0.Bowden: H22(0..11) - Millston.Wondervu$0.McCaulley: H24 - Millston.Wondervu$1.Higginson: TW5(29..31) - Millston.Wondervu$1.Oriskany: TW5(28) - Millston.Wondervu$1.Bowden: TW5(16..27) - Millston.Wondervu$1.McCaulley: TW5(0..15) - Millston.Rainelle.Conner: TW6(16..31) - Millston.Rainelle.Ledoux: TW6(0..15) - Millston.Rainelle.Steger: TW4(24..31) - Millston.Rainelle.Quogue: TW4(16..23) - Millston.Rainelle.Findlay: TW4(0..15) - Millston.GlenAvon.Fayette: H81(12..15) - Millston.GlenAvon.Osterdock: H81(8..11) - Millston.GlenAvon.PineCity: H81(2..7) - Millston.GlenAvon.Alameda: H81(0..1) - Millston.GlenAvon.Rexville: H18 - Millston.GlenAvon.Quinwood: W16(16..31) - Millston.GlenAvon.Marfa: W16(15) - Millston.GlenAvon.Palatine: W16(14) - Millston.GlenAvon.Mabelle: W16(13) - Millston.GlenAvon.Hoagland: W16(0..12) - Millston.GlenAvon.Exton: B16 - Millston.GlenAvon.Ocoee: B23 - Millston.GlenAvon.Hackett.0-7: TB11 - Millston.GlenAvon.Hackett.8-15: TB20 - Millston.GlenAvon.Kaluaaha: W17 - Millston.GlenAvon.Calcasieu: W18 - Millston.Ramos.Fayette: H82(12..15) - Millston.Ramos.Osterdock: H82(8..11) - Millston.Ramos.PineCity: H82(2..7) - Millston.Ramos.Alameda: H82(0..1) - Millston.Ramos.Rexville: TH15 - Millston.Ramos.Quinwood: TW4(16..31) - Millston.Ramos.Marfa: TW4(15) - Millston.Ramos.Palatine: TW4(14) - Millston.Ramos.Mabelle: TW4(13) - Millston.Ramos.Hoagland: TW4(0..12) - Millston.Ramos.Exton: TH6(8..15) - Millston.Ramos.Ocoee: TH6(0..7) - Millston.Ramos.Hackett.0-7: TB6 - Millston.Ramos.Hackett.8-15: TB7 - Millston.Ramos.Kaluaaha: TW10 - Millston.Ramos.Calcasieu: TW11 - Millston.Bergton.Chevak: TH8 - Millston.Bergton.Mendocino: TH7 - Millston.Pawtucket.StarLake: TH11 - Millston.Buckhorn.SoapLake: TH31 - Millston.Cassa.Chloride.0-15: TH11 - Millston.Cassa.Chloride.16-31: TH12 - Millston.Cassa.Garibaldi.0-15: TH13 - Millston.Cassa.Garibaldi.16-31: TH14 - Millston.Cassa.Weinert: TW6(28..31) - Millston.Cassa.Cornell: TW6(24..27) - Millston.Cassa.Noyes: TW6(16..23) - Millston.Cassa.Helton: TW6(0..15) - Millston.Provencal.Fayette: H82(12..15) - Millston.Provencal.PineCity: H82(6..11) - Millston.Provencal.Alameda: H82(4..5) - Millston.Provencal.Maryhill.0-15: TH30 - Millston.Provencal.Maryhill.16-19: H82(0..3) - Millston.Provencal.Norwood: TW4(16..31) - Millston.Provencal.Dassel: TW4(8..15) - Millston.Provencal.Bushland: TW4(0..7) - Millston.Provencal.Kaluaaha.0-31: TW10 - Millston.Provencal.Kaluaaha.32-63: TW11 - Millston.Provencal.Kaluaaha.64-71: TB6 - Millston.Provencal.Kaluaaha.72-79: TB7 - Millston.Provencal.Kaluaaha.80-95: TH6 - Millston.Provencal.Kaluaaha.96-111: TH15 - Millston.Provencal.Kaluaaha.112-127: TH16 - Millston.Provencal.Calcasieu.0-7: TB8 - Millston.Provencal.Calcasieu.8-15: TB9 - Millston.Provencal.Calcasieu.16-31: TH17 - Millston.Provencal.Calcasieu.32-63: TW20 - Millston.Provencal.Calcasieu.64-95: TW21 - Millston.Provencal.Calcasieu.96-127: TW22 - Millston.Grays.Chevak: H70 - Millston.Grays.Mendocino: H69 - Millston.Gotham.StarLake: TH32 - Millston.Brookneal.SoapLake: TH33 - Millston.Hoven.Noyes: TW7(24..31) - Millston.Hoven.Allison: TW7(0..23) - Millston.Hoven.Petrey.0-7: TH9(8..15) - Millston.Hoven.Petrey.8-23: TH10 - Millston.Hoven.Roosville: TH9(0..7) - Millston.Shirley.Adona.0-7: TB4 - Millston.Shirley.Adona.8-23: TH34 - Millston.Shirley.Connell: TW8(8..31) - Millston.Shirley.Goldsboro.0-15: TH35 - Millston.Shirley.Goldsboro.16-23: TW8(0..7) - Millston.Shirley.Fabens: TW9(8..31) - Millston.Shirley.McCaulley.0-7: TB5 - Millston.Shirley.McCaulley.8-15: TW9(0..7) - Millston.Osyka.Chloride: TW4 - Millston.Osyka.Garibaldi: TW6 - Millston.Osyka.Weinert: TB4(4..7) - Millston.Osyka.Cornell: TB4(0..3) - Millston.Osyka.Noyes: B46 - Millston.Osyka.Helton.0-7: TB5 - Millston.Osyka.Helton.8-15: TB6 - Millston.Broadwell.Palmhurst: TB5(7) - Millston.Broadwell.Comfrey: TB5(6) - Millston.Broadwell.Kalida: TB5(5) - Millston.Broadwell.Wallula: TB5(4) - Millston.Broadwell.Dennison: TB5(3) - Millston.Broadwell.Fairhaven: TB5(0..2) - Millston.Broadwell.Noyes: TB4(3..7) - Millston.Broadwell.Woodfield: TB4(0..2) - Millston.Broadwell.LasVegas: H69 - Millston.Maumee.Fayette: H81(12..15) - Millston.Maumee.PineCity: H81(6..11) - Millston.Maumee.Alameda: H81(4..5) - Millston.Maumee.Maryhill.0-15: TW7(16..31) - Millston.Maumee.Maryhill.16-19: H81(0..3) - Millston.Maumee.Norwood: TW7(0..15) - Millston.Maumee.Dassel: B23 - Millston.Maumee.Bushland: B16 - Millston.Maumee.Kaluaaha.0-31: W16 - Millston.Maumee.Kaluaaha.32-63: W17 - Millston.Maumee.Kaluaaha.64-95: W18 - Millston.Maumee.Kaluaaha.96-111: H18 - Millston.Maumee.Kaluaaha.112-127: H71 - Millston.Maumee.Calcasieu.0-31: W19 - Millston.Maumee.Calcasieu.32-63: W20 - Millston.Maumee.Calcasieu.64-95: W21 - Millston.Maumee.Calcasieu.96-127: W22 - HillTop.Freeny.Dunedin: B62(0..2) - HillTop.Edwards.RedElm: H20(5..7) - HillTop.Edwards.Oriskany: H20(4) - HillTop.Edwards.PineCity: H80(0..5) - HillTop.Edwards.Renick: H88(0..5) - HillTop.Edwards.SomesBar: B62(0) - HillTop.McCaskill.Grassflat: H19(0..9) - HillTop.McCaskill.Whitewood: H19(0..9) - HillTop.McCaskill.Tilton: B19(2..3) - HillTop.McGonigle.Buncombe: B18 - HillTop.Lamona.Pachuta: B61(0) - Millston.Hayfield.Blitchton: H72(10..15) - Millston.Hayfield.Avondale: H72(0..9) - Millston.Hayfield.Glassboro: H31(12..15) - Millston.Hayfield.Grabill: H31(0..11) - Millston.Hayfield.Moorcroft: H30(14..15) - Millston.Hayfield.Toklat: H30(12..13) - Millston.Hayfield.Bledsoe: H30(0..11) - Millston.Hayfield.Blencoe: B28 - Millston.Hayfield.AquaPark: B26(6..7) - Millston.Hayfield.Vichy: B26(3..5) - Millston.Hayfield.Lathrop: B26(2) - Millston.Hayfield.Clyde: B26(1) - Millston.Hayfield.Clarion: B26(0) - Millston.Hayfield.Aguilita: H28(12..15) - Millston.Hayfield.Harbor: H28(0..11) - HillTop.Lewiston.Staunton: W26(0..15) - eg_intr_md_for_dprsr.drop_ctl: B20(0..2) - eg_intr_md_for_dprsr.mirror_type: B17(0..2) - HillTop.RossFork.CeeVee: H29(0..11) - HillTop.RossFork.Bicknell: H27(0..11) - HillTop.Bessie.Peebles: W28(5) - HillTop.Stennett.Standish: B19(4) - HillTop.Stennett.Blairsden: H74(11) - HillTop.Plains.Roachdale: B25 - HillTop.Plains.Miller: H17(0..8) - Millston.Belgrade.$valid: W23(0) - Millston.Calabash.$valid: W23(1) - Millston.Rainelle.$valid: W23(2) - Millston.GlenAvon.$valid: W23(3) - Millston.Ramos.$valid: W23(4) - Millston.Bergton.$valid: W23(5) - Millston.Pawtucket.$valid: W23(6) - Millston.Buckhorn.$valid: W23(7) - Millston.Cassa.$valid: H74(0) - Millston.Provencal.$valid: H74(1) - Millston.Grays.$valid: H74(2) - Millston.Gotham.$valid: H74(3) - Millston.Brookneal.$valid: H74(4) - Millston.Hoven.$valid: H74(6) - Millston.Shirley.$valid: H74(7) - Millston.Osyka.$valid: H74(5) - Millston.Broadwell.$valid: H74(8) - Millston.Maumee.$valid: H74(9) - Millston.Hayfield.$valid: H74(10) - Millston.Wondervu.$stkvalid: B19(0..1) - Millston.Wondervu$0.$valid: B19(1) - Millston.Wondervu$1.$valid: B19(0) - context_json: - TB4: - Millston.Shirley.Adona: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Broadwell.Woodfield, Millston.Broadwell.Noyes, Millston.Osyka.Cornell, Millston.Osyka.Weinert ] - Millston.Broadwell.Woodfield: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Shirley.Adona, Millston.Osyka.Cornell, Millston.Osyka.Weinert ] - Millston.Broadwell.Noyes: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Shirley.Adona, Millston.Osyka.Cornell, Millston.Osyka.Weinert ] - Millston.Osyka.Cornell: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Shirley.Adona, Millston.Broadwell.Woodfield, Millston.Broadwell.Noyes ] - Millston.Osyka.Weinert: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Shirley.Adona, Millston.Broadwell.Woodfield, Millston.Broadwell.Noyes ] - TB5: - Millston.Shirley.McCaulley: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Broadwell.Fairhaven, Millston.Broadwell.Dennison, Millston.Broadwell.Wallula, Millston.Broadwell.Kalida, Millston.Broadwell.Comfrey, Millston.Broadwell.Palmhurst, Millston.Osyka.Helton ] - Millston.Broadwell.Fairhaven: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Shirley.McCaulley, Millston.Osyka.Helton ] - Millston.Broadwell.Dennison: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Shirley.McCaulley, Millston.Osyka.Helton ] - Millston.Broadwell.Wallula: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Shirley.McCaulley, Millston.Osyka.Helton ] - Millston.Broadwell.Kalida: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Shirley.McCaulley, Millston.Osyka.Helton ] - Millston.Broadwell.Comfrey: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Shirley.McCaulley, Millston.Osyka.Helton ] - Millston.Broadwell.Palmhurst: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Shirley.McCaulley, Millston.Osyka.Helton ] - Millston.Osyka.Helton: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Shirley.McCaulley, Millston.Broadwell.Fairhaven, Millston.Broadwell.Dennison, Millston.Broadwell.Wallula, Millston.Broadwell.Kalida, Millston.Broadwell.Comfrey, Millston.Broadwell.Palmhurst ] - TB6: - Millston.Osyka.Helton: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Hackett, Millston.Provencal.Kaluaaha ] - Millston.Ramos.Hackett: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Provencal.Kaluaaha ] - Millston.Provencal.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Osyka.Helton, Millston.Ramos.Hackett ] - TB7: - Millston.Ramos.Hackett: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] - Millston.Provencal.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Hackett ] - TB8: - Millston.Provencal.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TB9: - Millston.Provencal.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TB10: - Millston.Belgrade.Ronan: - mutually_exclusive_with: [ ] - HillTop.Wisdom.Bennet: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TB11: - Millston.GlenAvon.Hackett: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TB20: - Millston.GlenAvon.Hackett: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH6: - Millston.Ramos.Ocoee: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] - Millston.Ramos.Exton: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] - Millston.Provencal.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Ocoee, Millston.Ramos.Exton ] - TH7: - Millston.Bergton.Mendocino: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH8: - Millston.Bergton.Chevak: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH9: - Millston.Hoven.Roosville: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Hoven.Petrey: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH10: - Millston.Hoven.Petrey: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH11: - Millston.Cassa.Chloride: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Pawtucket.StarLake ] - Millston.Pawtucket.StarLake: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Cassa.Chloride ] - TH12: - Millston.Cassa.Chloride: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH13: - Millston.Cassa.Garibaldi: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH14: - Millston.Cassa.Garibaldi: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH15: - Millston.Provencal.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Rexville ] - Millston.Ramos.Rexville: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] - TH16: - Millston.Provencal.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH17: - Millston.Provencal.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH30: - Millston.Provencal.Maryhill: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH31: - Millston.Buckhorn.SoapLake: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH32: - Millston.Gotham.StarLake: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH33: - Millston.Brookneal.SoapLake: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH34: - Millston.Shirley.Adona: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TH35: - Millston.Shirley.Goldsboro: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TW4: - Millston.Ramos.Hoagland: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Rainelle.Findlay, Millston.Rainelle.Quogue, Millston.Rainelle.Steger, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] - Millston.Ramos.Mabelle: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Rainelle.Findlay, Millston.Rainelle.Quogue, Millston.Rainelle.Steger, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] - Millston.Ramos.Palatine: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Rainelle.Findlay, Millston.Rainelle.Quogue, Millston.Rainelle.Steger, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] - Millston.Ramos.Marfa: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Rainelle.Findlay, Millston.Rainelle.Quogue, Millston.Rainelle.Steger, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] - Millston.Ramos.Quinwood: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Rainelle.Findlay, Millston.Rainelle.Quogue, Millston.Rainelle.Steger, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] - Millston.Rainelle.Findlay: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Hoagland, Millston.Ramos.Mabelle, Millston.Ramos.Palatine, Millston.Ramos.Marfa, Millston.Ramos.Quinwood, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] - Millston.Rainelle.Quogue: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Hoagland, Millston.Ramos.Mabelle, Millston.Ramos.Palatine, Millston.Ramos.Marfa, Millston.Ramos.Quinwood, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] - Millston.Rainelle.Steger: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Hoagland, Millston.Ramos.Mabelle, Millston.Ramos.Palatine, Millston.Ramos.Marfa, Millston.Ramos.Quinwood, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood, Millston.Osyka.Chloride ] - Millston.Provencal.Bushland: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Hoagland, Millston.Ramos.Mabelle, Millston.Ramos.Palatine, Millston.Ramos.Marfa, Millston.Ramos.Quinwood, Millston.Rainelle.Findlay, Millston.Rainelle.Quogue, Millston.Rainelle.Steger, Millston.Osyka.Chloride ] - Millston.Provencal.Dassel: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Hoagland, Millston.Ramos.Mabelle, Millston.Ramos.Palatine, Millston.Ramos.Marfa, Millston.Ramos.Quinwood, Millston.Rainelle.Findlay, Millston.Rainelle.Quogue, Millston.Rainelle.Steger, Millston.Osyka.Chloride ] - Millston.Provencal.Norwood: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Hoagland, Millston.Ramos.Mabelle, Millston.Ramos.Palatine, Millston.Ramos.Marfa, Millston.Ramos.Quinwood, Millston.Rainelle.Findlay, Millston.Rainelle.Quogue, Millston.Rainelle.Steger, Millston.Osyka.Chloride ] - Millston.Osyka.Chloride: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Hoagland, Millston.Ramos.Mabelle, Millston.Ramos.Palatine, Millston.Ramos.Marfa, Millston.Ramos.Quinwood, Millston.Rainelle.Findlay, Millston.Rainelle.Quogue, Millston.Rainelle.Steger, Millston.Provencal.Bushland, Millston.Provencal.Dassel, Millston.Provencal.Norwood ] - TW5: - Millston.Wondervu$1.McCaulley: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Wondervu$1.Bowden: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Wondervu$1.Oriskany: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Wondervu$1.Higginson: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TW6: - Millston.Cassa.Helton: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Garibaldi ] - Millston.Cassa.Noyes: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Garibaldi ] - Millston.Cassa.Cornell: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Garibaldi ] - Millston.Cassa.Weinert: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Rainelle.Ledoux, Millston.Rainelle.Conner, Millston.Osyka.Garibaldi ] - Millston.Rainelle.Ledoux: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Cassa.Helton, Millston.Cassa.Noyes, Millston.Cassa.Cornell, Millston.Cassa.Weinert, Millston.Osyka.Garibaldi ] - Millston.Rainelle.Conner: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Cassa.Helton, Millston.Cassa.Noyes, Millston.Cassa.Cornell, Millston.Cassa.Weinert, Millston.Osyka.Garibaldi ] - Millston.Osyka.Garibaldi: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Cassa.Helton, Millston.Cassa.Noyes, Millston.Cassa.Cornell, Millston.Cassa.Weinert, Millston.Rainelle.Ledoux, Millston.Rainelle.Conner ] - TW7: - Millston.Maumee.Norwood: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Hoven.Allison, Millston.Hoven.Noyes ] - Millston.Maumee.Maryhill: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Hoven.Allison, Millston.Hoven.Noyes ] - Millston.Hoven.Allison: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Norwood, Millston.Maumee.Maryhill ] - Millston.Hoven.Noyes: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Norwood, Millston.Maumee.Maryhill ] - TW8: - Millston.Shirley.Goldsboro: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Shirley.Connell: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TW9: - Millston.Shirley.McCaulley: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Shirley.Fabens: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TW10: - Millston.Ramos.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] - Millston.Provencal.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Kaluaaha ] - TW11: - Millston.Ramos.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Kaluaaha ] - Millston.Provencal.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Calcasieu ] - TW20: - Millston.Provencal.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TW21: - Millston.Provencal.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TW22: - Millston.Provencal.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - TW23: - Millston.Belgrade.Ronan: - mutually_exclusive_with: [ ] - HillTop.Wisdom.Bennet: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - B16: - Millston.GlenAvon.Exton: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Bushland ] - Millston.Maumee.Bushland: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.GlenAvon.Exton ] - B17: - eg_intr_md_for_dprsr.mirror_type: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - B18: - HillTop.McGonigle.Buncombe: - live_start: parser - live_end: 10 - mutually_exclusive_with: [ ] - B19: - Millston.Wondervu.$stkvalid: - mutually_exclusive_with: [ ] - HillTop.McCaskill.Tilton: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.Stennett.Standish: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.Wisdom.Weatherby: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - Millston.Wondervu$0.$valid: - live_start: 5 - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Wondervu$1.$valid: - mutually_exclusive_with: [ ] - B20: - eg_intr_md_for_dprsr.drop_ctl: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - HillTop.Wisdom.Lathrop: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - HillTop.Wisdom.DeGraff: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - B21: - Millston.Belgrade.Virgil: - mutually_exclusive_with: [ ] - HillTop.Wisdom.Adona: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - B22: - Millston.Calabash.Adona: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - B23: - Millston.Maumee.Dassel: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.GlenAvon.Ocoee ] - Millston.GlenAvon.Ocoee: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Dassel ] - B24: - Millston.Calabash.Fabens: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - B25: - HillTop.Plains.Roachdale: - live_start: 5 - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Belgrade.Chaska: - mutually_exclusive_with: [ ] - HillTop.Wisdom.Miller: - live_start: parser - live_end: 4 - mutually_exclusive_with: [ ] - B26: - Millston.Hayfield.Clarion: - mutually_exclusive_with: [ ] - Millston.Hayfield.Clyde: - mutually_exclusive_with: [ ] - Millston.Hayfield.Lathrop: - live_start: 5 - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Hayfield.Vichy: - mutually_exclusive_with: [ ] - Millston.Hayfield.AquaPark: - mutually_exclusive_with: [ ] - B27: - Millston.Belgrade.Mankato: - mutually_exclusive_with: [ ] - HillTop.Wisdom.Blencoe: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - B28: - Millston.Hayfield.Blencoe: - live_start: 5 - live_end: deparser - mutually_exclusive_with: [ ] - B29: - Millston.Calabash.Goldsboro: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - B30: - Millston.Belgrade.Florin: - mutually_exclusive_with: [ ] - HillTop.Wisdom.Connell: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - B31: - Millston.Calabash.Connell: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - B46: - Millston.Osyka.Noyes: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - B61: - Millston.Belgrade.Freeburg: - mutually_exclusive_with: [ ] - HillTop.Lamona.Pachuta: - live_start: parser - live_end: 4 - mutually_exclusive_with: [ ] - B62: - Millston.Belgrade.Willard: - mutually_exclusive_with: [ ] - HillTop.Edwards.SomesBar: - live_start: 5 - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.Freeny.Dunedin: - live_start: parser - live_end: 4 - mutually_exclusive_with: [ ] - B63: - HillTop.Wisdom.Stratford: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - H16: - eg_intr_md.egress_port: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H17: - HillTop.Plains.Miller: - live_start: 5 - live_end: deparser - mutually_exclusive_with: [ ] - HillTop.Sonoma.Iberia: - live_start: parser - live_end: 0 - mutually_exclusive_with: [ ] - H18: - Millston.GlenAvon.Rexville: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] - Millston.Maumee.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.GlenAvon.Rexville ] - H19: - HillTop.McCaskill.Whitewood: - live_start: parser - live_end: 4 - mutually_exclusive_with: [ ] - HillTop.McCaskill.Grassflat: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H20: - Millston.Belgrade.Davie: - mutually_exclusive_with: [ ] - Millston.Belgrade.Rugby: - mutually_exclusive_with: [ ] - HillTop.Edwards.RedElm: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.Edwards.Oriskany: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - H21: - Millston.Belgrade.Requa: - mutually_exclusive_with: [ ] - HillTop.Wisdom.Nenana: - live_start: parser - live_end: 4 - mutually_exclusive_with: [ ] - H22: - Millston.Wondervu$0.Bowden: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Wondervu$0.Oriskany: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Wondervu$0.Higginson: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H23: - HillTop.Wisdom.Bowden: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.Wisdom.Toklat: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - HillTop.Wisdom.Jenners: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - H24: - Millston.Wondervu$0.McCaulley: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H25: - Millston.Calabash.McCaulley: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H26: - Millston.Calabash.Fabens: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H27: - Millston.Belgrade.Florien: - mutually_exclusive_with: [ ] - HillTop.RossFork.Bicknell: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - H28: - Millston.Hayfield.Harbor: - live_start: 5 - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Hayfield.Aguilita: - live_start: 4 - live_end: deparser - mutually_exclusive_with: [ ] - H29: - Millston.Belgrade.Bayshore: - mutually_exclusive_with: [ ] - HillTop.RossFork.CeeVee: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - H30: - Millston.Hayfield.Bledsoe: - live_start: 5 - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Hayfield.Toklat: - live_start: 5 - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Hayfield.Moorcroft: - live_start: 5 - live_end: deparser - mutually_exclusive_with: [ ] - H31: - Millston.Hayfield.Grabill: - live_start: 4 - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Hayfield.Glassboro: - live_start: 4 - live_end: deparser - mutually_exclusive_with: [ ] - H67: - Millston.Belgrade.Florin: - mutually_exclusive_with: [ ] - HillTop.Wisdom.Connell: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - H68: - Millston.Calabash.Connell: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H69: - Millston.Broadwell.LasVegas: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Grays.Mendocino ] - Millston.Grays.Mendocino: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Broadwell.LasVegas ] - H70: - Millston.Grays.Chevak: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H71: - Millston.Maumee.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H72: - Millston.Hayfield.Avondale: - live_start: 4 - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Hayfield.Blitchton: - live_start: 4 - live_end: deparser - mutually_exclusive_with: [ ] - H73: - Millston.Calabash.Goldsboro: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H74: - Millston.Cassa.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Provencal.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Grays.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Gotham.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Brookneal.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Osyka.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Hoven.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Shirley.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Broadwell.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Maumee.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Hayfield.$valid: - live_start: 5 - live_end: deparser - mutually_exclusive_with: [ ] - HillTop.Stennett.Blairsden: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - H80: - Millston.Belgrade.Matheson: - mutually_exclusive_with: [ ] - HillTop.Edwards.PineCity: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - H81: - Millston.Maumee.Maryhill: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.GlenAvon.Alameda, Millston.GlenAvon.PineCity, Millston.GlenAvon.Osterdock, Millston.GlenAvon.Fayette ] - Millston.Maumee.Alameda: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.GlenAvon.Alameda, Millston.GlenAvon.PineCity, Millston.GlenAvon.Osterdock, Millston.GlenAvon.Fayette ] - Millston.Maumee.PineCity: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.GlenAvon.Alameda, Millston.GlenAvon.PineCity, Millston.GlenAvon.Osterdock, Millston.GlenAvon.Fayette ] - Millston.Maumee.Fayette: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.GlenAvon.Alameda, Millston.GlenAvon.PineCity, Millston.GlenAvon.Osterdock, Millston.GlenAvon.Fayette ] - Millston.GlenAvon.Alameda: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Maryhill, Millston.Maumee.Alameda, Millston.Maumee.PineCity, Millston.Maumee.Fayette ] - Millston.GlenAvon.PineCity: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Maryhill, Millston.Maumee.Alameda, Millston.Maumee.PineCity, Millston.Maumee.Fayette ] - Millston.GlenAvon.Osterdock: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Maryhill, Millston.Maumee.Alameda, Millston.Maumee.PineCity, Millston.Maumee.Fayette ] - Millston.GlenAvon.Fayette: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Maryhill, Millston.Maumee.Alameda, Millston.Maumee.PineCity, Millston.Maumee.Fayette ] - H82: - Millston.Ramos.Alameda: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Maryhill, Millston.Provencal.Alameda, Millston.Provencal.PineCity, Millston.Provencal.Fayette ] - Millston.Ramos.PineCity: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Maryhill, Millston.Provencal.Alameda, Millston.Provencal.PineCity, Millston.Provencal.Fayette ] - Millston.Ramos.Osterdock: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Maryhill, Millston.Provencal.Alameda, Millston.Provencal.PineCity, Millston.Provencal.Fayette ] - Millston.Ramos.Fayette: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Provencal.Maryhill, Millston.Provencal.Alameda, Millston.Provencal.PineCity, Millston.Provencal.Fayette ] - Millston.Provencal.Maryhill: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette ] - Millston.Provencal.Alameda: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette ] - Millston.Provencal.PineCity: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette ] - Millston.Provencal.Fayette: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Ramos.Alameda, Millston.Ramos.PineCity, Millston.Ramos.Osterdock, Millston.Ramos.Fayette ] - H87: - Millston.Calabash.Adona: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - H88: - HillTop.Edwards.Renick: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - H91: - Millston.Belgrade.Virgil: - mutually_exclusive_with: [ ] - HillTop.Wisdom.Adona: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - W16: - Millston.GlenAvon.Hoagland: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] - Millston.GlenAvon.Mabelle: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] - Millston.GlenAvon.Palatine: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] - Millston.GlenAvon.Marfa: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] - Millston.GlenAvon.Quinwood: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] - Millston.Maumee.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.GlenAvon.Hoagland, Millston.GlenAvon.Mabelle, Millston.GlenAvon.Palatine, Millston.GlenAvon.Marfa, Millston.GlenAvon.Quinwood ] - W17: - Millston.GlenAvon.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] - Millston.Maumee.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.GlenAvon.Kaluaaha ] - W18: - Millston.GlenAvon.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.Maumee.Kaluaaha ] - Millston.Maumee.Kaluaaha: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ Millston.GlenAvon.Calcasieu ] - W19: - Millston.Maumee.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - W20: - Millston.Maumee.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - W21: - Millston.Maumee.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - W22: - Millston.Maumee.Calcasieu: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - W23: - Millston.Belgrade.$valid: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - Millston.Calabash.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Rainelle.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.GlenAvon.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Ramos.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Bergton.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Pawtucket.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - Millston.Buckhorn.$valid: - live_start: parser - live_end: deparser - mutually_exclusive_with: [ ] - W24: - Millston.Belgrade.Chaska: - mutually_exclusive_with: [ ] - HillTop.Wisdom.Miller: - live_start: parser - live_end: 4 - mutually_exclusive_with: [ ] - W25: - Millston.Belgrade.Ronan: - mutually_exclusive_with: [ ] - HillTop.Wisdom.Bennet: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - W26: - Millston.Belgrade.Corinth: - mutually_exclusive_with: [ ] - HillTop.Lewiston.Staunton: - live_start: parser - live_end: 6 - mutually_exclusive_with: [ ] - W27: - eg_intr_md.egress_rid: - live_start: parser - live_end: 0 - mutually_exclusive_with: [ ] - W28: - Millston.Belgrade.Waipahu: - mutually_exclusive_with: [ ] - Millston.Belgrade.Allgood: - mutually_exclusive_with: [ ] - Millston.Belgrade.Shabbona: - mutually_exclusive_with: [ ] - Millston.Belgrade.Anacortes: - mutually_exclusive_with: [ ] - HillTop.Wisdom.Piqua: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - HillTop.Wisdom.Westhoff: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.Wisdom.RioPecos: - live_start: parser - live_end: 4 - mutually_exclusive_with: [ ] - HillTop.Bessie.Peebles: - live_start: parser - live_end: 6 - mutually_exclusive_with: [ ] - W29: - Millston.Belgrade.Rockport: - mutually_exclusive_with: [ ] - Millston.Belgrade.Union: - mutually_exclusive_with: [ ] - HillTop.Wisdom.Onycha: - live_start: parser - live_end: 11 - mutually_exclusive_with: [ ] - HillTop.Wisdom.Dyess: - live_start: parser - live_end: 4 - mutually_exclusive_with: [ ] - W30: - Millston.Belgrade.Selawik: - mutually_exclusive_with: [ ] - Millston.Belgrade.Sudbury: - mutually_exclusive_with: [ ] - HillTop.Wisdom.Waubun: - live_start: parser - live_end: 2 - mutually_exclusive_with: [ ] - HillTop.Wisdom.Dolores: - live_start: parser - live_end: 5 - mutually_exclusive_with: [ ] - W31: - eg_intr_md.egress_qid: - live_start: parser - live_end: 4 - mutually_exclusive_with: [ ] -parser ingress: - start: $entry_point - init_zero: [ W14, H1, W0, H53, B42, B58, B13, B10, B14, H50, B7, B8, H56, H63, H48, H55, W8, H37, W7, B56, B57, H4, W4, H3, B44, B59, B2, B45, H62, H34, B12, B11, H85, B38, B15, H14, W11, B5, W10, W1, W9, H66, H95, B3, W39, H11, H40, H61, H41, H42, H43, H90, H65, H5, W38, W49, B55, H9, H32, B40, B6, B9, W51, W37, W36, H83, W3, W40, W44, W45, W46, H84, H59, H58, H60, H2, B36, H86, H64, H46, H8, H12, H44, B43, B60, B41, B4, W5, H49, H47, H13, H45, H15, H52, B54 ] - bitwise_or: [ B12, B54, H95 ] - hdr_len_adj: 16 - states: - $entry_point: # from state ingress::$entry_point - *: - save: { half : 0..1 } - buf_req: 2 - next: start - start: # from state ingress::start - match: [ half ] - value_set Guion 2: - handle: 511 - field_mapping: - ig_intr_md.ingress_port(0..8) : half(0..8) - 0..1: H53 # bit[7..15] -> H53 bit[8..0]: ingress::HillTop.Tiburon.Arnold - 7..10: W14 # bit[66..79] -> W14 bit[21..8]: ingress::HillTop.Lamona.Fristoe - 10..11: H1 # bit[84..95] -> H1 bit[11..0]: ingress::HillTop.Lamona.Traverse - 10..13: W0 # bit[110..111] -> W0 bit[1..0]: ingress::HillTop.Lamona.Whitefish - 12: B34 # bit[103] -> B34 bit[0]: ingress::HillTop.Lamona.Pachuta - shift: 16 - buf_req: 16 - next: Nuyaka - 0x****: - 0..1: H53 # bit[7..15] -> H53 bit[8..0]: ingress::HillTop.Tiburon.Arnold - 7..10: W14 # bit[66..79] -> W14 bit[21..8]: ingress::HillTop.Lamona.Fristoe - 10..11: H1 # bit[84..95] -> H1 bit[11..0]: ingress::HillTop.Lamona.Traverse - 10..13: W0 # bit[110..111] -> W0 bit[1..0]: ingress::HillTop.Lamona.Whitefish - 12: B34 # bit[103] -> B34 bit[0]: ingress::HillTop.Lamona.Pachuta - save: { half : 28..29, byte0 : 30 } - shift: 16 - buf_req: 31 - next: Mentone - Nuyaka: # from state ingress::Nuyaka - *: - 14..17: W48 - # - bit[112..117] -> W48 bit[31..26]: ingress::Millston.Hayfield.Blitchton - # - bit[118..127] -> W48 bit[25..16]: ingress::Millston.Hayfield.Avondale - # - bit[128..131] -> W48 bit[15..12]: ingress::Millston.Hayfield.Glassboro - # - bit[132..143] -> W48 bit[11..0]: ingress::Millston.Hayfield.Grabill - 21: B47 - # - bit[168..169] -> B47 bit[7..6]: ingress::Millston.Hayfield.AquaPark - # - bit[170..172] -> B47 bit[5..3]: ingress::Millston.Hayfield.Vichy - B54: 2 # value 1 -> B54 bit[1]: ingress::Millston.Hayfield.$valid - shift: 24 - buf_req: 24 - next: Nuyaka.$oob_stall_0 - Nuyaka.$oob_stall_0: # from state ingress::Nuyaka.$oob_stall_0 - *: - save: { half : 12..13, byte0 : 14 } - buf_req: 15 - next: Mentone - Mentone: # from state ingress::Mentone - match: [ byte0, half ] - 0x**9100: - 0..3: W12 - # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona - # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 - 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 - 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 - 8..11: W6 - # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 - # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens - 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 - 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 - B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid - save: { half : 16..17, byte0 : 18 } - shift: 14 - buf_req: 19 - next: Elvaston - 0x**88a8: - 0..3: W12 - # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona - # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 - 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 - 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 - 8..11: W6 - # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 - # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens - 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 - 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 - B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid - save: { half : 16..17, byte0 : 18 } - shift: 14 - buf_req: 19 - next: Elvaston - 0x**8100: - 0..3: W12 - # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona - # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 - 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 - 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 - 8..11: W6 - # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 - # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens - 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 - 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 - B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid - save: { half : 16..17, byte0 : 18 } - shift: 14 - buf_req: 19 - next: Elvaston - 0x**0806: - 0..3: W12 - # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona - # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 - 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 - 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 - 8..11: W6 - # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 - # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens - 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 - 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 - B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid - save: { half : 14..15, byte0 : 16, byte1 : 17 } - shift: 14 - buf_req: 18 - next: Corvallis - 0x450800: - 0..3: W12 - # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona - # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 - 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 - 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 - 8..11: W6 - # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 - # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens - 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 - 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 - B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid - shift: 14 - buf_req: 14 - next: Belmont - 0x*50800: - 0..3: W12 - # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona - # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 - 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 - 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 - 8..11: W6 - # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 - # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens - 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 - 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 - B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid - shift: 14 - buf_req: 14 - next: Gastonia - 0x**0800: - 0..3: W12 - # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona - # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 - 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 - 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 - 8..11: W6 - # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 - # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens - 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 - 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 - B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid - shift: 14 - buf_req: 14 - next: Hillsview - 0x6*86dd: - 0..3: W12 - # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona - # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 - 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 - 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 - 8..11: W6 - # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 - # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens - 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 - 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 - B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid - shift: 14 - buf_req: 14 - next: Westbury - 0x**86dd: - 0..3: W12 - # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona - # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 - 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 - 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 - 8..11: W6 - # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 - # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens - 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 - 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 - B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid - shift: 14 - buf_req: 14 - next: Gambrills - 0x**8808: - 0..3: W12 - # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona - # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 - 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 - 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 - 8..11: W6 - # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 - # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens - 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 - 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 - B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid - shift: 14 - buf_req: 14 - next: Masontown - 0x******: - 0..3: W12 - # - bit[0..23] -> W12 bit[31..8]: ingress::Millston.Calabash.Adona - # - bit[24..31] -> W12 bit[7..0]: ingress::Millston.Calabash.Connell[23:16].16-23 - 4..5: H54 # ingress::Millston.Calabash.Connell[15:0].0-15 - 6..7: H36 # ingress::Millston.Calabash.Goldsboro[23:8].8-23 - 8..11: W6 - # - bit[64..71] -> W6 bit[31..24]: ingress::Millston.Calabash.Goldsboro[7:0].0-7 - # - bit[72..95] -> W6 bit[23..0]: ingress::Millston.Calabash.Fabens - 12: B53 # ingress::Millston.Calabash.McCaulley[15:8].8-15 - 13: B50 # ingress::Millston.Calabash.McCaulley[7:0].0-7 - B54: 4 # value 1 -> B54 bit[2]: ingress::Millston.Calabash.$valid - shift: 14 - buf_req: 14 - next: end - Elvaston: # from state ingress::Elvaston - match: [ byte0, half ] - 0x**8100: - 0..1: H0 - # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson - # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden - 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 - 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 - B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid - save: { half : 6..7, byte0 : 8 } - shift: 4 - buf_req: 9 - next: Elkville - 0x**0806: - 0..1: H0 - # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson - # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden - 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 - 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 - B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid - save: { half : 4..5, byte0 : 6, byte1 : 7 } - shift: 4 - buf_req: 8 - next: Corvallis - 0x450800: - 0..1: H0 - # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson - # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden - 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 - 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 - B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Belmont - 0x*50800: - 0..1: H0 - # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson - # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden - 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 - 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 - B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Gastonia - 0x**0800: - 0..1: H0 - # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson - # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden - 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 - 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 - B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Hillsview - 0x6*86dd: - 0..1: H0 - # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson - # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden - 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 - 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 - B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Westbury - 0x6*86dd: - 0..1: H0 - # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson - # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden - 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 - 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 - B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Westbury - 0x**86dd: - 0..1: H0 - # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson - # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden - 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 - 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 - B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Gambrills - 0x**8808: - 0..1: H0 - # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson - # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden - 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 - 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 - B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Masontown - 0x******: - 0..1: H0 - # - bit[0..2] -> H0 bit[15..13]: ingress::Millston.Wondervu[0].Higginson - # - bit[3] -> H0 bit[12]: ingress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H0 bit[11..0]: ingress::Millston.Wondervu[0].Bowden - 2: B51 # ingress::Millston.Wondervu[0].McCaulley[15:8].8-15 - 3: B48 # ingress::Millston.Wondervu[0].McCaulley[7:0].0-7 - B12: 2 # value 2 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: end - Elkville: # from state ingress::Elkville - match: [ byte0, half ] - 0x**0806: - 0..1: TH24 - # - bit[0..2] -> TH24 bit[15..13]: ingress::Millston.Wondervu[1].Higginson - # - bit[3] -> TH24 bit[12]: ingress::Millston.Wondervu[1].Oriskany - # - bit[4..15] -> TH24 bit[11..0]: ingress::Millston.Wondervu[1].Bowden - 2: B52 # ingress::Millston.Wondervu[1].McCaulley[15:8].8-15 - 3: B49 # ingress::Millston.Wondervu[1].McCaulley[7:0].0-7 - B12: 1 # value 1 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid - save: { half : 4..5, byte0 : 6, byte1 : 7 } - shift: 4 - buf_req: 8 - next: Corvallis - 0x450800: - 0..1: TH24 - # - bit[0..2] -> TH24 bit[15..13]: ingress::Millston.Wondervu[1].Higginson - # - bit[3] -> TH24 bit[12]: ingress::Millston.Wondervu[1].Oriskany - # - bit[4..15] -> TH24 bit[11..0]: ingress::Millston.Wondervu[1].Bowden - 2: B52 # ingress::Millston.Wondervu[1].McCaulley[15:8].8-15 - 3: B49 # ingress::Millston.Wondervu[1].McCaulley[7:0].0-7 - B12: 1 # value 1 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Belmont - 0x*50800: - 0..1: TH24 - # - bit[0..2] -> TH24 bit[15..13]: ingress::Millston.Wondervu[1].Higginson - # - bit[3] -> TH24 bit[12]: ingress::Millston.Wondervu[1].Oriskany - # - bit[4..15] -> TH24 bit[11..0]: ingress::Millston.Wondervu[1].Bowden - 2: B52 # ingress::Millston.Wondervu[1].McCaulley[15:8].8-15 - 3: B49 # ingress::Millston.Wondervu[1].McCaulley[7:0].0-7 - B12: 1 # value 1 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Gastonia - 0x**0800: - 0..1: TH24 - # - bit[0..2] -> TH24 bit[15..13]: ingress::Millston.Wondervu[1].Higginson - # - bit[3] -> TH24 bit[12]: ingress::Millston.Wondervu[1].Oriskany - # - bit[4..15] -> TH24 bit[11..0]: ingress::Millston.Wondervu[1].Bowden - 2: B52 # ingress::Millston.Wondervu[1].McCaulley[15:8].8-15 - 3: B49 # ingress::Millston.Wondervu[1].McCaulley[7:0].0-7 - B12: 1 # value 1 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Hillsview - 0x6*86dd: - 0..1: TH24 - # - bit[0..2] -> TH24 bit[15..13]: ingress::Millston.Wondervu[1].Higginson - # - bit[3] -> TH24 bit[12]: ingress::Millston.Wondervu[1].Oriskany - # - bit[4..15] -> TH24 bit[11..0]: ingress::Millston.Wondervu[1].Bowden - 2: B52 # ingress::Millston.Wondervu[1].McCaulley[15:8].8-15 - 3: B49 # ingress::Millston.Wondervu[1].McCaulley[7:0].0-7 - B12: 1 # value 1 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Westbury - 0x6*86dd: - 0..1: TH24 - # - bit[0..2] -> TH24 bit[15..13]: ingress::Millston.Wondervu[1].Higginson - # - bit[3] -> TH24 bit[12]: ingress::Millston.Wondervu[1].Oriskany - # - bit[4..15] -> TH24 bit[11..0]: ingress::Millston.Wondervu[1].Bowden - 2: B52 # ingress::Millston.Wondervu[1].McCaulley[15:8].8-15 - 3: B49 # ingress::Millston.Wondervu[1].McCaulley[7:0].0-7 - B12: 1 # value 1 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Westbury - 0x**86dd: - 0..1: TH24 - # - bit[0..2] -> TH24 bit[15..13]: ingress::Millston.Wondervu[1].Higginson - # - bit[3] -> TH24 bit[12]: ingress::Millston.Wondervu[1].Oriskany - # - bit[4..15] -> TH24 bit[11..0]: ingress::Millston.Wondervu[1].Bowden - 2: B52 # ingress::Millston.Wondervu[1].McCaulley[15:8].8-15 - 3: B49 # ingress::Millston.Wondervu[1].McCaulley[7:0].0-7 - B12: 1 # value 1 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Gambrills - 0x**8808: - 0..1: TH24 - # - bit[0..2] -> TH24 bit[15..13]: ingress::Millston.Wondervu[1].Higginson - # - bit[3] -> TH24 bit[12]: ingress::Millston.Wondervu[1].Oriskany - # - bit[4..15] -> TH24 bit[11..0]: ingress::Millston.Wondervu[1].Bowden - 2: B52 # ingress::Millston.Wondervu[1].McCaulley[15:8].8-15 - 3: B49 # ingress::Millston.Wondervu[1].McCaulley[7:0].0-7 - B12: 1 # value 1 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Masontown - 0x******: - 0..1: TH24 - # - bit[0..2] -> TH24 bit[15..13]: ingress::Millston.Wondervu[1].Higginson - # - bit[3] -> TH24 bit[12]: ingress::Millston.Wondervu[1].Oriskany - # - bit[4..15] -> TH24 bit[11..0]: ingress::Millston.Wondervu[1].Bowden - 2: B52 # ingress::Millston.Wondervu[1].McCaulley[15:8].8-15 - 3: B49 # ingress::Millston.Wondervu[1].McCaulley[7:0].0-7 - B12: 1 # value 1 -> B12 bit[1..0]: ingress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: end - Corvallis: # from state ingress::Corvallis - match: [ half, byte0, byte1 ] - 0x00010800: - 0..3: TW1 - # - bit[0..15] -> TW1 bit[31..16]: ingress::Millston.Rainelle.Conner - # - bit[16..31] -> TW1 bit[15..0]: ingress::Millston.Rainelle.Ledoux - 4..5: TH0 - # - bit[32..39] -> TH0 bit[15..8]: ingress::Millston.Rainelle.Steger - # - bit[40..47] -> TH0 bit[7..0]: ingress::Millston.Rainelle.Quogue - 6..7: H35 # ingress::Millston.Rainelle.Findlay - B54: 8 # value 1 -> B54 bit[3]: ingress::Millston.Rainelle.$valid - shift: 8 - buf_req: 8 - next: end - 0x********: - buf_req: 0 - next: end - Belmont: # from state ingress::Belmont - *: - checksum 0: - type: VERIFY - mask: [ 0, 1, 2..3, 4..5, 6, 6..7, 8, 9, 10..11, 12..15, 16..19 ] - swap: 0 - start: 1 - end: 1 - dest: H63(0) - 0..1: H89 - # - bit[0..3] -> H89 bit[15..12]: ingress::Millston.GlenAvon.Fayette - # - bit[4..7] -> H89 bit[11..8]: ingress::Millston.GlenAvon.Osterdock - # - bit[8..13] -> H89 bit[7..2]: ingress::Millston.GlenAvon.PineCity - # - bit[14..15] -> H89 bit[1..0]: ingress::Millston.GlenAvon.Alameda - 2..3: H38 # ingress::Millston.GlenAvon.Rexville - 4..7: TW0 - # - bit[32..47] -> TW0 bit[31..16]: ingress::Millston.GlenAvon.Quinwood - # - bit[48] -> TW0 bit[15]: ingress::Millston.GlenAvon.Marfa - # - bit[49] -> TW0 bit[14]: ingress::Millston.GlenAvon.Palatine - # - bit[50] -> TW0 bit[13]: ingress::Millston.GlenAvon.Mabelle - # - bit[51..63] -> TW0 bit[12..0]: ingress::Millston.GlenAvon.Hoagland - 8: TB1 # ingress::Millston.GlenAvon.Exton - 8: B59 # ingress::HillTop.RossFork.Exton - 9: B33 # ingress::Millston.GlenAvon.Ocoee - 10..11: TH25 # ingress::Millston.GlenAvon.Hackett - 12..15: W32 # ingress::Millston.GlenAvon.Kaluaaha - 16..19: W33 # ingress::Millston.GlenAvon.Calcasieu - B54: 16 # value 1 -> B54 bit[4]: ingress::Millston.GlenAvon.$valid - save: { half : 6..7, byte0 : 9 } - shift: 20 - buf_req: 20 - next: Belmont.$split_0 - Belmont.$split_0: # from state ingress::Belmont.$split_0 - match: [ half, byte0 ] - 0o*0000004: - B13: 1 # value 1 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville - save: { byte1 : 0 } - buf_req: 1 - next: Baytown - 0o*0000051: - B13: 1 # value 1 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville - buf_req: 0 - next: Lynch - 0o*0000001: - B13: 1 # value 1 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville - buf_req: 0 - next: BealCity - 0o*0000021: - B13: 1 # value 1 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville - save: { half : 2..3 } - buf_req: 4 - next: Toluca - 0o*0000006: - B13: 1 # value 1 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville - buf_req: 0 - next: Readsboro - 0o*0000057: - B13: 1 # value 1 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville - save: { half : 0..1, byte0 : 2, byte1 : 3 } - buf_req: 4 - next: Astor - 0o*0000000: - B13: 1 # value 1 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville - buf_req: 0 - next: end - 0x****06: - B13: 1 # value 1 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville - buf_req: 0 - next: Greenland - 0x******: - B13: 1 # value 1 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville - buf_req: 0 - next: Shingler - Baytown: # from state ingress::Baytown - match: [ byte1 ] - 0x45: - B57: 8 # value 8 -> B57 bit[7..0]: ingress::HillTop.RossFork.McCaulley[15:8].8-15 - H34: 128 # value 4 -> H34 bit[7..5]: ingress::HillTop.RossFork.Joslin - buf_req: 0 - next: McBrides - 0x**: - B57: 8 # value 8 -> B57 bit[7..0]: ingress::HillTop.RossFork.McCaulley[15:8].8-15 - H34: 128 # value 4 -> H34 bit[7..5]: ingress::HillTop.RossFork.Joslin - buf_req: 0 - next: Ocracoke - McBrides: # from state ingress::McBrides - *: - checksum 0: - type: VERIFY - mask: [ 0, 1, 2..3, 4..5, 6, 6..7, 8, 9, 10..11, 12..15, 16..19 ] - swap: 0 - start: 1 - end: 1 - dest: H48(0) - 0..1: H83 # bit[8..13] -> H83 bit[7..2]: ingress::HillTop.Maddock.PineCity - 0..3: TW1 - # - bit[0..3] -> TW1 bit[31..28]: ingress::Millston.Ramos.Fayette - # - bit[4..7] -> TW1 bit[27..24]: ingress::Millston.Ramos.Osterdock - # - bit[8..13] -> TW1 bit[23..18]: ingress::Millston.Ramos.PineCity - # - bit[14..15] -> TW1 bit[17..16]: ingress::Millston.Ramos.Alameda - # - bit[16..31] -> TW1 bit[15..0]: ingress::Millston.Ramos.Rexville - 4..7: TW2 - # - bit[32..47] -> TW2 bit[31..16]: ingress::Millston.Ramos.Quinwood - # - bit[48] -> TW2 bit[15]: ingress::Millston.Ramos.Marfa - # - bit[49] -> TW2 bit[14]: ingress::Millston.Ramos.Palatine - # - bit[50] -> TW2 bit[13]: ingress::Millston.Ramos.Mabelle - # - bit[51..63] -> TW2 bit[12..0]: ingress::Millston.Ramos.Hoagland - 8: B58 # ingress::HillTop.Aldan.Kenbridge - 8..9: TH1 - # - bit[64..71] -> TH1 bit[15..8]: ingress::Millston.Ramos.Exton - # - bit[72..79] -> TH1 bit[7..0]: ingress::Millston.Ramos.Ocoee - 9: B42 # ingress::HillTop.Aldan.Vinemont - 10..11: TH2 # ingress::Millston.Ramos.Hackett - 12..15: TW13 # ingress::Millston.Ramos.Kaluaaha - 12..15: W37 # ingress::HillTop.Maddock.Kaluaaha - B10: 16 # value 1 -> B10 bit[5..4]: ingress::HillTop.Aldan.Mystic[1:0].0-1 - B54: 32 # value 1 -> B54 bit[5]: ingress::Millston.Ramos.$valid - save: { half : 6..7, byte0 : 9 } - shift: 16 - buf_req: 20 - next: McBrides.$split_0 - McBrides.$split_0: # from state ingress::McBrides.$split_0 - match: [ half, byte0 ] - 0o*0000001: - 0..3: TW14 # ingress::Millston.Ramos.Calcasieu - 0..3: W36 # ingress::HillTop.Maddock.Calcasieu - shift: 4 - buf_req: 4 - next: Hapeville - 0o*0000021: - 0..3: TW14 # ingress::Millston.Ramos.Calcasieu - 0..3: W36 # ingress::HillTop.Maddock.Calcasieu - shift: 4 - buf_req: 4 - next: Barnhill - 0o*0000006: - 0..3: TW14 # ingress::Millston.Ramos.Calcasieu - 0..3: W36 # ingress::HillTop.Maddock.Calcasieu - shift: 4 - buf_req: 4 - next: NantyGlo - 0o*0000000: - 0..3: TW14 # ingress::Millston.Ramos.Calcasieu - 0..3: W36 # ingress::HillTop.Maddock.Calcasieu - shift: 4 - buf_req: 4 - next: end - 0x****06: - 0..3: TW14 # ingress::Millston.Ramos.Calcasieu - 0..3: W36 # ingress::HillTop.Maddock.Calcasieu - shift: 4 - buf_req: 4 - next: Wildorado - 0x******: - 0..3: TW14 # ingress::Millston.Ramos.Calcasieu - 0..3: W36 # ingress::HillTop.Maddock.Calcasieu - shift: 4 - buf_req: 4 - next: Dozier - Hapeville: # from state ingress::Hapeville - *: - 0..1: H9 # ingress::HillTop.RossFork.Chevak - 0..3: W47 - # - bit[0..15] -> W47 bit[31..16]: ingress::Millston.Bergton.Chevak - # - bit[16..31] -> W47 bit[15..0]: ingress::Millston.Bergton.Mendocino - B54: 64 # value 1 -> B54 bit[6]: ingress::Millston.Bergton.$valid - shift: 4 - buf_req: 4 - next: end - Barnhill: # from state ingress::Barnhill - *: - 0..1: H9 # ingress::HillTop.RossFork.Chevak - 0..3: W47 - # - bit[0..15] -> W47 bit[31..16]: ingress::Millston.Bergton.Chevak - # - bit[16..31] -> W47 bit[15..0]: ingress::Millston.Bergton.Mendocino - 2..3: H32 # ingress::HillTop.RossFork.Mendocino - 4..5: TH5 # ingress::Millston.Pawtucket.StarLake - 6..7: TH26 # ingress::Millston.Buckhorn.SoapLake - B54: 192 - # - value 1 -> B54 bit[6]: ingress::Millston.Bergton.$valid - # - value 1 -> B54 bit[7]: ingress::Millston.Pawtucket.$valid - shift: 8 - buf_req: 8 - next: Barnhill.$split_0 - Barnhill.$split_0: # from state ingress::Barnhill.$split_0 - *: - H50: 1 # value 1 -> H50 bit[1..0]: ingress::HillTop.Aldan.Kearns[2:1].1-2 - H95: 1 # value 1 -> H95 bit[0]: ingress::Millston.Buckhorn.$valid - buf_req: 0 - next: end - NantyGlo: # from state ingress::NantyGlo - *: - 0..1: H9 # ingress::HillTop.RossFork.Chevak - 0..3: W47 - # - bit[0..15] -> W47 bit[31..16]: ingress::Millston.Bergton.Chevak - # - bit[16..31] -> W47 bit[15..0]: ingress::Millston.Bergton.Mendocino - 2..3: H32 # ingress::HillTop.RossFork.Mendocino - 4..7: TW15 # ingress::Millston.Cassa.Chloride - 8..9: TH18 # ingress::Millston.Cassa.Garibaldi[31:16].16-31 - 10..11: TH5 # ingress::Millston.Cassa.Garibaldi[15:0].0-15 - 12..15: TW3 - # - bit[96..99] -> TW3 bit[31..28]: ingress::Millston.Cassa.Weinert - # - bit[100..103] -> TW3 bit[27..24]: ingress::Millston.Cassa.Cornell - # - bit[104..111] -> TW3 bit[23..16]: ingress::Millston.Cassa.Noyes - # - bit[112..127] -> TW3 bit[15..0]: ingress::Millston.Cassa.Helton - 13: B40 # ingress::HillTop.RossFork.Kremlin - B54: 64 # value 1 -> B54 bit[6]: ingress::Millston.Bergton.$valid - shift: 16 - buf_req: 16 - next: NantyGlo.$split_0 - NantyGlo.$split_0: # from state ingress::NantyGlo.$split_0 - *: - 0..1: TH26 # ingress::Millston.Buckhorn.SoapLake - H50: 3 # value 3 -> H50 bit[1..0]: ingress::HillTop.Aldan.Kearns[2:1].1-2 - H95: 3 - # - value 1 -> H95 bit[1]: ingress::Millston.Cassa.$valid - # - value 1 -> H95 bit[0]: ingress::Millston.Buckhorn.$valid - shift: 2 - buf_req: 2 - next: end - Wildorado: # from state ingress::Wildorado - *: - B7: 1 # value 1 -> B7 bit[0]: ingress::HillTop.Aldan.Kearns[0:0].0-0 - H50: 2 # value 2 -> H50 bit[1..0]: ingress::HillTop.Aldan.Kearns[2:1].1-2 - buf_req: 0 - next: end - Dozier: # from state ingress::Dozier - *: - B7: 1 # value 1 -> B7 bit[0]: ingress::HillTop.Aldan.Kearns[0:0].0-0 - buf_req: 0 - next: end - Ocracoke: # from state ingress::Ocracoke - *: - 0..1: H83 # bit[8..13] -> H83 bit[7..2]: ingress::HillTop.Maddock.PineCity - B10: 48 # value 3 -> B10 bit[5..4]: ingress::HillTop.Aldan.Mystic[1:0].0-1 - buf_req: 2 - next: end - Lynch: # from state ingress::Lynch - *: - B56: 221 # value 221 -> B56 bit[7..0]: ingress::HillTop.RossFork.McCaulley[7:0].0-7 - B57: 134 # value 134 -> B57 bit[7..0]: ingress::HillTop.RossFork.McCaulley[15:8].8-15 - H34: 128 # value 4 -> H34 bit[7..5]: ingress::HillTop.RossFork.Joslin - buf_req: 0 - next: Sanford - Sanford: # from state ingress::Sanford - *: - 0: TB3 - # - bit[0..3] -> TB3 bit[7..4]: ingress::Millston.Provencal.Fayette - # - bit[4..7] -> TB3 bit[3..0]: ingress::Millston.Provencal.PineCity[5:2].2-5 - 0..1: H84 # bit[4..9] -> H84 bit[11..6]: ingress::HillTop.Sublett.PineCity - 1..2: H35 - # - bit[8..9] -> H35 bit[15..14]: ingress::Millston.Provencal.PineCity[1:0].0-1 - # - bit[10..11] -> H35 bit[13..12]: ingress::Millston.Provencal.Alameda - # - bit[12..23] -> H35 bit[11..0]: ingress::Millston.Provencal.Maryhill[19:8].8-19 - 3: B39 # ingress::Millston.Provencal.Maryhill[7:0].0-7 - 4..7: TW1 - # - bit[32..47] -> TW1 bit[31..16]: ingress::Millston.Provencal.Norwood - # - bit[48..55] -> TW1 bit[15..8]: ingress::Millston.Provencal.Dassel - # - bit[56..63] -> TW1 bit[7..0]: ingress::Millston.Provencal.Bushland - 6: B42 # ingress::HillTop.Aldan.Vinemont - 7: B58 # ingress::HillTop.Aldan.Kenbridge - 8..9: TH2 # ingress::Millston.Provencal.Kaluaaha[127:112].112-127 - 8..11: W40 # ingress::HillTop.Sublett.Kaluaaha[127:96].96-127 - 10..11: TH1 # ingress::Millston.Provencal.Kaluaaha[111:96].96-111 - 12..15: TW14 # ingress::Millston.Provencal.Kaluaaha[95:64].64-95 - 12..15: W39 # ingress::HillTop.Sublett.Kaluaaha[95:64].64-95 - save: { byte1 : 6 } - shift: 16 - buf_req: 16 - next: Sanford.$split_0 - Sanford.$split_0: # from state ingress::Sanford.$split_0 - *: - 0..3: TW13 # ingress::Millston.Provencal.Kaluaaha[63:32].32-63 - 0..3: W3 # ingress::HillTop.Sublett.Kaluaaha[63:32].32-63 - 4..7: TW2 # ingress::Millston.Provencal.Kaluaaha[31:0].0-31 - 4..7: W37 # ingress::HillTop.Sublett.Kaluaaha[31:0].0-31 - 12..13: TH23 # ingress::Millston.Provencal.Calcasieu[95:80].80-95 - 14: TB13 # ingress::Millston.Provencal.Calcasieu[79:72].72-79 - 15: TB12 # ingress::Millston.Provencal.Calcasieu[71:64].64-71 - 16..17: TH22 # ingress::Millston.Provencal.Calcasieu[63:48].48-63 - 18..19: TH21 # ingress::Millston.Provencal.Calcasieu[47:32].32-47 - 20..21: TH20 # ingress::Millston.Provencal.Calcasieu[31:16].16-31 - B10: 32 # value 2 -> B10 bit[5..4]: ingress::HillTop.Aldan.Mystic[1:0].0-1 - shift: 8 - buf_req: 22 - next: Sanford.$split_1 - Sanford.$split_1: # from state ingress::Sanford.$split_1 - *: - 0..3: TW16 # ingress::Millston.Provencal.Calcasieu[127:96].96-127 - 0..3: W36 # ingress::HillTop.Sublett.Calcasieu[127:96].96-127 - 4..7: W46 # ingress::HillTop.Sublett.Calcasieu[95:64].64-95 - 8..11: W45 # ingress::HillTop.Sublett.Calcasieu[63:32].32-63 - 14..15: TH19 # ingress::Millston.Provencal.Calcasieu[15:0].0-15 - H95: 4 # value 1 -> H95 bit[2]: ingress::Millston.Provencal.$valid - shift: 12 - buf_req: 16 - next: Sanford.$split_2 - Sanford.$split_2: # from state ingress::Sanford.$split_2 - match: [ byte1 ] - 0x3a: - 0..3: W44 # ingress::HillTop.Sublett.Calcasieu[31:0].0-31 - shift: 4 - buf_req: 4 - next: Hapeville - 0x11: - 0..3: W44 # ingress::HillTop.Sublett.Calcasieu[31:0].0-31 - shift: 4 - buf_req: 4 - next: Barnhill - 0x06: - 0..3: W44 # ingress::HillTop.Sublett.Calcasieu[31:0].0-31 - shift: 4 - buf_req: 4 - next: NantyGlo - 0x**: - 0..3: W44 # ingress::HillTop.Sublett.Calcasieu[31:0].0-31 - shift: 4 - buf_req: 4 - next: end - BealCity: # from state ingress::BealCity - *: - 0..1: H10 # ingress::Millston.Grays.Chevak - 2..3: H33 # ingress::Millston.Grays.Mendocino - H95: 8 # value 1 -> H95 bit[3]: ingress::Millston.Grays.$valid - shift: 4 - buf_req: 4 - next: end - Toluca: # from state ingress::Toluca - match: [ half ] - 0x12b5: - 0..1: H10 # ingress::Millston.Grays.Chevak - 2..3: H33 # ingress::Millston.Grays.Mendocino - 4: TB14 # ingress::Millston.Gotham.StarLake[15:8].8-15 - 4..7: W50 # bit[48..63] -> W50 bit[15..0]: ingress::Millston.Brookneal.SoapLake - 5: TB2 # ingress::Millston.Gotham.StarLake[7:0].0-7 - H56: 1 # value 1 -> H56 bit[1..0]: ingress::HillTop.Aldan.Malinta[2:1].1-2 - H95: 56 - # - value 1 -> H95 bit[3]: ingress::Millston.Grays.$valid - # - value 1 -> H95 bit[4]: ingress::Millston.Gotham.$valid - # - value 1 -> H95 bit[5]: ingress::Millston.Brookneal.$valid - shift: 8 - buf_req: 8 - next: Goodwin - 0xff32: - 0..1: H10 # ingress::Millston.Grays.Chevak - 2..3: H33 # ingress::Millston.Grays.Mendocino - 4: TB14 # ingress::Millston.Gotham.StarLake[15:8].8-15 - 4..7: W50 # bit[48..63] -> W50 bit[15..0]: ingress::Millston.Brookneal.SoapLake - 5: TB2 # ingress::Millston.Gotham.StarLake[7:0].0-7 - H56: 1 # value 1 -> H56 bit[1..0]: ingress::HillTop.Aldan.Malinta[2:1].1-2 - H95: 56 - # - value 1 -> H95 bit[3]: ingress::Millston.Grays.$valid - # - value 1 -> H95 bit[4]: ingress::Millston.Gotham.$valid - # - value 1 -> H95 bit[5]: ingress::Millston.Brookneal.$valid - shift: 8 - buf_req: 8 - next: Goodwin - 0x****: - 0..1: H10 # ingress::Millston.Grays.Chevak - 2..3: H33 # ingress::Millston.Grays.Mendocino - 4: TB14 # ingress::Millston.Gotham.StarLake[15:8].8-15 - 4..7: W50 # bit[48..63] -> W50 bit[15..0]: ingress::Millston.Brookneal.SoapLake - 5: TB2 # ingress::Millston.Gotham.StarLake[7:0].0-7 - H56: 1 # value 1 -> H56 bit[1..0]: ingress::HillTop.Aldan.Malinta[2:1].1-2 - H95: 56 - # - value 1 -> H95 bit[3]: ingress::Millston.Grays.$valid - # - value 1 -> H95 bit[4]: ingress::Millston.Gotham.$valid - # - value 1 -> H95 bit[5]: ingress::Millston.Brookneal.$valid - shift: 8 - buf_req: 8 - next: end - Goodwin: # from state ingress::Goodwin - *: - 0: TB0 # ingress::Millston.Hoven.Noyes - 1..2: TH4 # ingress::Millston.Hoven.Allison[23:8].8-23 - 2..5: W49 # bit[32..47] -> W49 bit[15..0]: ingress::HillTop.RossFork.Everton - 3..4: TH3 - # - bit[24..31] -> TH3 bit[15..8]: ingress::Millston.Hoven.Allison[7:0].0-7 - # - bit[32..39] -> TH3 bit[7..0]: ingress::Millston.Hoven.Petrey[23:16].16-23 - 5..6: TH27 # ingress::Millston.Hoven.Petrey[15:0].0-15 - 6: B55 # ingress::HillTop.RossFork.Lafayette - 7: B32 # ingress::Millston.Hoven.Roosville - 8..11: W15 - # - bit[64..87] -> W15 bit[31..8]: ingress::Millston.Shirley.Adona - # - bit[88..95] -> W15 bit[7..0]: ingress::Millston.Shirley.Connell[23:16].16-23 - 12..13: H39 # ingress::Millston.Shirley.Connell[15:0].0-15 - 16: B35 # ingress::Millston.Shirley.Goldsboro[7:0].0-7 - shift: 14 - buf_req: 17 - next: Goodwin.$split_0 - Goodwin.$split_0: # from state ingress::Goodwin.$split_0 - *: - 0..1: H92 # ingress::Millston.Shirley.Goldsboro[23:8].8-23 - 3..4: H93 # ingress::Millston.Shirley.Fabens[23:8].8-23 - 5: B37 # ingress::Millston.Shirley.Fabens[7:0].0-7 - 6: B57 # ingress::HillTop.RossFork.McCaulley[15:8].8-15 - 6..7: H94 # ingress::Millston.Shirley.McCaulley - 7: B56 # ingress::HillTop.RossFork.McCaulley[7:0].0-7 - H34: 32 # value 1 -> H34 bit[7..5]: ingress::HillTop.RossFork.Joslin - save: { byte1 : 8, half : 6..7 } - shift: 8 - buf_req: 9 - next: Goodwin.$split_1 - Goodwin.$split_1: # from state ingress::Goodwin.$split_1 - match: [ byte1, half ] - 0x**0806: - H95: 384 - # - value 1 -> H95 bit[7]: ingress::Millston.Hoven.$valid - # - value 1 -> H95 bit[8]: ingress::Millston.Shirley.$valid - save: { half : 0..1, byte0 : 2, byte1 : 3 } - buf_req: 4 - next: Corvallis - 0x450800: - H95: 384 - # - value 1 -> H95 bit[7]: ingress::Millston.Hoven.$valid - # - value 1 -> H95 bit[8]: ingress::Millston.Shirley.$valid - buf_req: 0 - next: McBrides - 0x*50800: - H95: 384 - # - value 1 -> H95 bit[7]: ingress::Millston.Hoven.$valid - # - value 1 -> H95 bit[8]: ingress::Millston.Shirley.$valid - buf_req: 0 - next: Bernice - 0x**0800: - H95: 384 - # - value 1 -> H95 bit[7]: ingress::Millston.Hoven.$valid - # - value 1 -> H95 bit[8]: ingress::Millston.Shirley.$valid - buf_req: 0 - next: Ocracoke - 0x6*86dd: - H95: 384 - # - value 1 -> H95 bit[7]: ingress::Millston.Hoven.$valid - # - value 1 -> H95 bit[8]: ingress::Millston.Shirley.$valid - buf_req: 0 - next: Sanford - 0x**86dd: - H95: 384 - # - value 1 -> H95 bit[7]: ingress::Millston.Hoven.$valid - # - value 1 -> H95 bit[8]: ingress::Millston.Shirley.$valid - buf_req: 0 - next: Greenwood - 0x******: - H95: 384 - # - value 1 -> H95 bit[7]: ingress::Millston.Hoven.$valid - # - value 1 -> H95 bit[8]: ingress::Millston.Shirley.$valid - buf_req: 0 - next: end - Bernice: # from state ingress::Bernice - *: - B10: 16 # value 1 -> B10 bit[5..4]: ingress::HillTop.Aldan.Mystic[1:0].0-1 - B14: 1 # value 1 -> B14 bit[0]: ingress::HillTop.Aldan.Mystic[2:2].2-2 - buf_req: 0 - next: end - Greenwood: # from state ingress::Greenwood - *: - B10: 32 # value 2 -> B10 bit[5..4]: ingress::HillTop.Aldan.Mystic[1:0].0-1 - B14: 1 # value 1 -> B14 bit[0]: ingress::HillTop.Aldan.Mystic[2:2].2-2 - buf_req: 0 - next: end - Readsboro: # from state ingress::Readsboro - *: - 0..1: H10 # ingress::Millston.Grays.Chevak - 2..3: H33 # ingress::Millston.Grays.Mendocino - 4..7: TW1 # ingress::Millston.Osyka.Chloride - 8..11: TW2 # ingress::Millston.Osyka.Garibaldi - 12: TB0 - # - bit[96..99] -> TB0 bit[7..4]: ingress::Millston.Osyka.Weinert - # - bit[100..103] -> TB0 bit[3..0]: ingress::Millston.Osyka.Cornell - 13: B32 # ingress::Millston.Osyka.Noyes - 14..15: TH0 # ingress::Millston.Osyka.Helton - 14..17: W50 # bit[128..143] -> W50 bit[15..0]: ingress::Millston.Brookneal.SoapLake - H56: 3 # value 3 -> H56 bit[1..0]: ingress::HillTop.Aldan.Malinta[2:1].1-2 - shift: 18 - buf_req: 18 - next: Readsboro.$split_0 - Readsboro.$split_0: # from state ingress::Readsboro.$split_0 - *: - H95: 104 - # - value 1 -> H95 bit[3]: ingress::Millston.Grays.$valid - # - value 1 -> H95 bit[6]: ingress::Millston.Osyka.$valid - # - value 1 -> H95 bit[5]: ingress::Millston.Brookneal.$valid - buf_req: 0 - next: end - Astor: # from state ingress::Astor - match: [ half, byte0, byte1 ] - 0x00000800: - 0..1: TH0 - # - bit[0] -> TH0 bit[15]: ingress::Millston.Broadwell.Palmhurst - # - bit[1] -> TH0 bit[14]: ingress::Millston.Broadwell.Comfrey - # - bit[2] -> TH0 bit[13]: ingress::Millston.Broadwell.Kalida - # - bit[3] -> TH0 bit[12]: ingress::Millston.Broadwell.Wallula - # - bit[4] -> TH0 bit[11]: ingress::Millston.Broadwell.Dennison - # - bit[5..7] -> TH0 bit[10..8]: ingress::Millston.Broadwell.Fairhaven - # - bit[8..12] -> TH0 bit[7..3]: ingress::Millston.Broadwell.Noyes - # - bit[13..15] -> TH0 bit[2..0]: ingress::Millston.Broadwell.Woodfield - 2: TB2 # ingress::Millston.Broadwell.LasVegas[15:8].8-15 - 3: TB0 # ingress::Millston.Broadwell.LasVegas[7:0].0-7 - H95: 512 # value 1 -> H95 bit[9]: ingress::Millston.Broadwell.$valid - save: { byte1 : 4 } - shift: 4 - buf_req: 5 - next: Hohenwald - 0x000086dd: - 0..1: TH0 - # - bit[0] -> TH0 bit[15]: ingress::Millston.Broadwell.Palmhurst - # - bit[1] -> TH0 bit[14]: ingress::Millston.Broadwell.Comfrey - # - bit[2] -> TH0 bit[13]: ingress::Millston.Broadwell.Kalida - # - bit[3] -> TH0 bit[12]: ingress::Millston.Broadwell.Wallula - # - bit[4] -> TH0 bit[11]: ingress::Millston.Broadwell.Dennison - # - bit[5..7] -> TH0 bit[10..8]: ingress::Millston.Broadwell.Fairhaven - # - bit[8..12] -> TH0 bit[7..3]: ingress::Millston.Broadwell.Noyes - # - bit[13..15] -> TH0 bit[2..0]: ingress::Millston.Broadwell.Woodfield - 2: TB2 # ingress::Millston.Broadwell.LasVegas[15:8].8-15 - 3: TB0 # ingress::Millston.Broadwell.LasVegas[7:0].0-7 - H95: 512 # value 1 -> H95 bit[9]: ingress::Millston.Broadwell.$valid - save: { byte1 : 4 } - shift: 4 - buf_req: 5 - next: Eolia - 0x********: - 0..1: TH0 - # - bit[0] -> TH0 bit[15]: ingress::Millston.Broadwell.Palmhurst - # - bit[1] -> TH0 bit[14]: ingress::Millston.Broadwell.Comfrey - # - bit[2] -> TH0 bit[13]: ingress::Millston.Broadwell.Kalida - # - bit[3] -> TH0 bit[12]: ingress::Millston.Broadwell.Wallula - # - bit[4] -> TH0 bit[11]: ingress::Millston.Broadwell.Dennison - # - bit[5..7] -> TH0 bit[10..8]: ingress::Millston.Broadwell.Fairhaven - # - bit[8..12] -> TH0 bit[7..3]: ingress::Millston.Broadwell.Noyes - # - bit[13..15] -> TH0 bit[2..0]: ingress::Millston.Broadwell.Woodfield - 2: TB2 # ingress::Millston.Broadwell.LasVegas[15:8].8-15 - 3: TB0 # ingress::Millston.Broadwell.LasVegas[7:0].0-7 - H95: 512 # value 1 -> H95 bit[9]: ingress::Millston.Broadwell.$valid - shift: 4 - buf_req: 4 - next: end - Hohenwald: # from state ingress::Hohenwald - match: [ byte1 ] - 0x4*: - save: { byte1 : 0 } - buf_req: 1 - next: Sumner - 0x**: - buf_req: 0 - next: end - Sumner: # from state ingress::Sumner - match: [ byte1 ] - 0x*5: - H34: 64 # value 2 -> H34 bit[7..5]: ingress::HillTop.RossFork.Joslin - buf_req: 0 - next: McBrides - 0x**: - H34: 64 # value 2 -> H34 bit[7..5]: ingress::HillTop.RossFork.Joslin - buf_req: 0 - next: Ocracoke - Eolia: # from state ingress::Eolia - match: [ byte1 ] - 0x6*: - H34: 64 # value 2 -> H34 bit[7..5]: ingress::HillTop.RossFork.Joslin - buf_req: 0 - next: Sanford - 0x**: - buf_req: 0 - next: end - Greenland: # from state ingress::Greenland - *: - B8: 1 # value 1 -> B8 bit[0]: ingress::HillTop.Aldan.Malinta[0:0].0-0 - H56: 2 # value 2 -> H56 bit[1..0]: ingress::HillTop.Aldan.Malinta[2:1].1-2 - buf_req: 0 - next: end - Shingler: # from state ingress::Shingler - *: - B8: 1 # value 1 -> B8 bit[0]: ingress::HillTop.Aldan.Malinta[0:0].0-0 - buf_req: 0 - next: end - Gastonia: # from state ingress::Gastonia - *: - B13: 5 # value 5 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville - buf_req: 0 - next: end - Hillsview: # from state ingress::Hillsview - *: - 0..1: H89 # bit[8..13] -> H89 bit[7..2]: ingress::Millston.GlenAvon.PineCity - 8: B59 # ingress::HillTop.RossFork.Exton - 9: B33 # ingress::Millston.GlenAvon.Ocoee - 16..19: W33 # ingress::Millston.GlenAvon.Calcasieu - B13: 3 # value 3 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville - buf_req: 20 - next: end - Westbury: # from state ingress::Westbury - *: - 0..1: H89 - # - bit[0..3] -> H89 bit[15..12]: ingress::Millston.Maumee.Fayette - # - bit[4..9] -> H89 bit[11..6]: ingress::Millston.Maumee.PineCity - # - bit[10..11] -> H89 bit[5..4]: ingress::Millston.Maumee.Alameda - # - bit[12..15] -> H89 bit[3..0]: ingress::Millston.Maumee.Maryhill[19:16].16-19 - 2..3: H38 # ingress::Millston.Maumee.Maryhill[15:0].0-15 - 4: B35 # ingress::Millston.Maumee.Norwood[15:8].8-15 - 5: B37 # ingress::Millston.Maumee.Norwood[7:0].0-7 - 6: B33 # ingress::Millston.Maumee.Dassel - 7: TB1 # ingress::Millston.Maumee.Bushland - 8..11: W35 # ingress::Millston.Maumee.Kaluaaha[127:96].96-127 - 12..15: W34 # ingress::Millston.Maumee.Kaluaaha[95:64].64-95 - 16..19: W15 # ingress::Millston.Maumee.Kaluaaha[63:32].32-63 - 20..23: W33 # ingress::Millston.Maumee.Kaluaaha[31:0].0-31 - H95: 1024 # value 1 -> H95 bit[10]: ingress::Millston.Maumee.$valid - save: { byte1 : 6 } - shift: 7 - buf_req: 24 - next: Westbury.$split_0 - Westbury.$split_0: # from state ingress::Westbury.$split_0 - *: - 0: B59 # ingress::HillTop.RossFork.Exton - 17..20: W32 # ingress::Millston.Maumee.Calcasieu[127:96].96-127 - 21..24: W43 # ingress::Millston.Maumee.Calcasieu[95:64].64-95 - 25..28: W42 # ingress::Millston.Maumee.Calcasieu[63:32].32-63 - B13: 2 # value 2 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville - shift: 29 - buf_req: 29 - next: Westbury.$split_1 - Westbury.$split_1: # from state ingress::Westbury.$split_1 - match: [ byte1 ] - 0x3a: - 0..3: W41 # ingress::Millston.Maumee.Calcasieu[31:0].0-31 - shift: 4 - buf_req: 4 - next: BealCity - 0x11: - 0..3: W41 # ingress::Millston.Maumee.Calcasieu[31:0].0-31 - save: { half : 6..7 } - shift: 4 - buf_req: 8 - next: Makawao - 0x06: - 0..3: W41 # ingress::Millston.Maumee.Calcasieu[31:0].0-31 - shift: 4 - buf_req: 4 - next: Readsboro - 0x04: - 0..3: W41 # ingress::Millston.Maumee.Calcasieu[31:0].0-31 - save: { byte1 : 4 } - shift: 4 - buf_req: 5 - next: Baytown - 0x29: - 0..3: W41 # ingress::Millston.Maumee.Calcasieu[31:0].0-31 - shift: 4 - buf_req: 4 - next: Mather - 0x**: - 0..3: W41 # ingress::Millston.Maumee.Calcasieu[31:0].0-31 - shift: 4 - buf_req: 4 - next: end - Makawao: # from state ingress::Makawao - match: [ half ] - 0x****: - 0..1: H10 # ingress::Millston.Grays.Chevak - 2..3: H33 # ingress::Millston.Grays.Mendocino - 4: TB14 # ingress::Millston.Gotham.StarLake[15:8].8-15 - 4..7: W50 # bit[48..63] -> W50 bit[15..0]: ingress::Millston.Brookneal.SoapLake - 5: TB2 # ingress::Millston.Gotham.StarLake[7:0].0-7 - H56: 1 # value 1 -> H56 bit[1..0]: ingress::HillTop.Aldan.Malinta[2:1].1-2 - H95: 56 - # - value 1 -> H95 bit[3]: ingress::Millston.Grays.$valid - # - value 1 -> H95 bit[4]: ingress::Millston.Gotham.$valid - # - value 1 -> H95 bit[5]: ingress::Millston.Brookneal.$valid - shift: 8 - buf_req: 8 - next: end - Mather: # from state ingress::Mather - *: - B56: 221 # value 221 -> B56 bit[7..0]: ingress::HillTop.RossFork.McCaulley[7:0].0-7 - B57: 134 # value 134 -> B57 bit[7..0]: ingress::HillTop.RossFork.McCaulley[15:8].8-15 - H34: 128 # value 4 -> H34 bit[7..5]: ingress::HillTop.RossFork.Joslin - buf_req: 0 - next: Sanford - Gambrills: # from state ingress::Gambrills - *: - B13: 6 # value 6 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville - buf_req: 0 - next: end - Masontown: # from state ingress::Masontown - *: - B13: 8 # value 8 -> B13 bit[3..0]: ingress::HillTop.Aldan.Parkville - buf_req: 0 - next: end -deparser ingress: - dictionary: - H6: B54(0) - # - bit[15..8]: ingress::Millston.Belgrade.Roachdale if ingress::Millston.Belgrade.$valid - # - bit[7..5]: ingress::Millston.Belgrade.Rugby if ingress::Millston.Belgrade.$valid - # - bit[4]: ingress::Millston.Belgrade.Davie if ingress::Millston.Belgrade.$valid - # - bit[3..0]: ingress::Millston.Belgrade.Cacao if ingress::Millston.Belgrade.$valid - B36: B54(0) # ingress::Millston.Belgrade.Mankato if ingress::Millston.Belgrade.$valid - W13: B54(0) - # - bit[31..8]: ingress::Millston.Belgrade.Virgil if ingress::Millston.Belgrade.$valid - # - bit[7..0]: ingress::Millston.Belgrade.Florin.16-23 if ingress::Millston.Belgrade.$valid - H63: B54(0) # ingress::Millston.Belgrade.Florin.0-15 if ingress::Millston.Belgrade.$valid - TW12: B54(0) # ingress::Millston.Belgrade.Ronan if ingress::Millston.Belgrade.$valid - H51: B54(0) # ingress::Millston.Belgrade.Corinth if ingress::Millston.Belgrade.$valid - B11: B54(0) - # - bit[7..4]: ingress::Millston.Belgrade.__pad_0 if ingress::Millston.Belgrade.$valid - # - bit[3..1]: ingress::Millston.Belgrade.Union if ingress::Millston.Belgrade.$valid - # - bit[0]: ingress::Millston.Belgrade.Rockport if ingress::Millston.Belgrade.$valid - B9: B54(0) - # - bit[7..6]: ingress::Millston.Belgrade.__pad_1 if ingress::Millston.Belgrade.$valid - # - bit[5]: ingress::Millston.Belgrade.Anacortes if ingress::Millston.Belgrade.$valid - # - bit[4]: ingress::Millston.Belgrade.Shabbona if ingress::Millston.Belgrade.$valid - # - bit[3..1]: ingress::Millston.Belgrade.Allgood if ingress::Millston.Belgrade.$valid - # - bit[0]: ingress::Millston.Belgrade.Waipahu if ingress::Millston.Belgrade.$valid - B34: B54(0) - # - bit[7..1]: ingress::Millston.Belgrade.__pad_2 if ingress::Millston.Belgrade.$valid - # - bit[0]: ingress::Millston.Belgrade.Freeburg if ingress::Millston.Belgrade.$valid - W1: B54(0) - # - bit[31..8]: ingress::Millston.Belgrade.__pad_3 if ingress::Millston.Belgrade.$valid - # - bit[7..2]: ingress::Millston.Belgrade.Sudbury if ingress::Millston.Belgrade.$valid - # - bit[1..0]: ingress::Millston.Belgrade.Selawik if ingress::Millston.Belgrade.$valid - B7: B54(0) - # - bit[7..3]: ingress::Millston.Belgrade.__pad_4 if ingress::Millston.Belgrade.$valid - # - bit[2..0]: ingress::Millston.Belgrade.Willard if ingress::Millston.Belgrade.$valid - H90: B54(0) - # - bit[15..6]: ingress::Millston.Belgrade.__pad_5 if ingress::Millston.Belgrade.$valid - # - bit[5..0]: ingress::Millston.Belgrade.Matheson if ingress::Millston.Belgrade.$valid - H48: B54(0) - # - bit[15..9]: ingress::Millston.Belgrade.__pad_6 if ingress::Millston.Belgrade.$valid - # - bit[8..0]: ingress::Millston.Belgrade.Chaska if ingress::Millston.Belgrade.$valid - H2: B54(0) - # - bit[15..12]: ingress::Millston.Belgrade.__pad_7 if ingress::Millston.Belgrade.$valid - # - bit[11..0]: ingress::Millston.Belgrade.Requa if ingress::Millston.Belgrade.$valid - H4: B54(0) - # - bit[15..12]: ingress::Millston.Belgrade.__pad_8 if ingress::Millston.Belgrade.$valid - # - bit[11..0]: ingress::Millston.Belgrade.Bayshore if ingress::Millston.Belgrade.$valid - H3: B54(0) - # - bit[15..12]: ingress::Millston.Belgrade.__pad_9 if ingress::Millston.Belgrade.$valid - # - bit[11..0]: ingress::Millston.Belgrade.Florien if ingress::Millston.Belgrade.$valid - W12: B54(2) - # - bit[31..8]: ingress::Millston.Calabash.Adona if ingress::Millston.Calabash.$valid - # - bit[7..0]: ingress::Millston.Calabash.Connell.16-23 if ingress::Millston.Calabash.$valid - H54: B54(2) # ingress::Millston.Calabash.Connell.0-15 if ingress::Millston.Calabash.$valid - H36: B54(2) # ingress::Millston.Calabash.Goldsboro.8-23 if ingress::Millston.Calabash.$valid - W6: B54(2) - # - bit[31..24]: ingress::Millston.Calabash.Goldsboro.0-7 if ingress::Millston.Calabash.$valid - # - bit[23..0]: ingress::Millston.Calabash.Fabens if ingress::Millston.Calabash.$valid - B53: B54(2) # ingress::Millston.Calabash.McCaulley.8-15 if ingress::Millston.Calabash.$valid - B50: B54(2) # ingress::Millston.Calabash.McCaulley.0-7 if ingress::Millston.Calabash.$valid - H0: B12(1) - # - bit[15..13]: ingress::Millston.Wondervu[0].Higginson if ingress::Millston.Wondervu[0].$valid - # - bit[12]: ingress::Millston.Wondervu[0].Oriskany if ingress::Millston.Wondervu[0].$valid - # - bit[11..0]: ingress::Millston.Wondervu[0].Bowden if ingress::Millston.Wondervu[0].$valid - B51: B12(1) # ingress::Millston.Wondervu[0].McCaulley.8-15 if ingress::Millston.Wondervu[0].$valid - B48: B12(1) # ingress::Millston.Wondervu[0].McCaulley.0-7 if ingress::Millston.Wondervu[0].$valid - TH24: B12(0) - # - bit[15..13]: ingress::Millston.Wondervu[1].Higginson if ingress::Millston.Wondervu[1].$valid - # - bit[12]: ingress::Millston.Wondervu[1].Oriskany if ingress::Millston.Wondervu[1].$valid - # - bit[11..0]: ingress::Millston.Wondervu[1].Bowden if ingress::Millston.Wondervu[1].$valid - B52: B12(0) # ingress::Millston.Wondervu[1].McCaulley.8-15 if ingress::Millston.Wondervu[1].$valid - B49: B12(0) # ingress::Millston.Wondervu[1].McCaulley.0-7 if ingress::Millston.Wondervu[1].$valid - H89: B54(4) - # - bit[15..12]: ingress::Millston.GlenAvon.Fayette if ingress::Millston.GlenAvon.$valid - # - bit[11..8]: ingress::Millston.GlenAvon.Osterdock if ingress::Millston.GlenAvon.$valid - # - bit[7..2]: ingress::Millston.GlenAvon.PineCity if ingress::Millston.GlenAvon.$valid - # - bit[1..0]: ingress::Millston.GlenAvon.Alameda if ingress::Millston.GlenAvon.$valid - H38: B54(4) # ingress::Millston.GlenAvon.Rexville if ingress::Millston.GlenAvon.$valid - TW0: B54(4) - # - bit[31..16]: ingress::Millston.GlenAvon.Quinwood if ingress::Millston.GlenAvon.$valid - # - bit[15]: ingress::Millston.GlenAvon.Marfa if ingress::Millston.GlenAvon.$valid - # - bit[14]: ingress::Millston.GlenAvon.Palatine if ingress::Millston.GlenAvon.$valid - # - bit[13]: ingress::Millston.GlenAvon.Mabelle if ingress::Millston.GlenAvon.$valid - # - bit[12..0]: ingress::Millston.GlenAvon.Hoagland if ingress::Millston.GlenAvon.$valid - TB1: B54(4) # ingress::Millston.GlenAvon.Exton if ingress::Millston.GlenAvon.$valid - B33: B54(4) # ingress::Millston.GlenAvon.Ocoee if ingress::Millston.GlenAvon.$valid - TH25: B54(4) # ingress::Millston.GlenAvon.Hackett if ingress::Millston.GlenAvon.$valid - W32: B54(4) # ingress::Millston.GlenAvon.Kaluaaha if ingress::Millston.GlenAvon.$valid - W33: B54(4) # ingress::Millston.GlenAvon.Calcasieu if ingress::Millston.GlenAvon.$valid - H89: H95(10) - # - bit[15..12]: ingress::Millston.Maumee.Fayette if ingress::Millston.Maumee.$valid - # - bit[11..6]: ingress::Millston.Maumee.PineCity if ingress::Millston.Maumee.$valid - # - bit[5..4]: ingress::Millston.Maumee.Alameda if ingress::Millston.Maumee.$valid - # - bit[3..0]: ingress::Millston.Maumee.Maryhill.16-19 if ingress::Millston.Maumee.$valid - H38: H95(10) # ingress::Millston.Maumee.Maryhill.0-15 if ingress::Millston.Maumee.$valid - B35: H95(10) # ingress::Millston.Maumee.Norwood.8-15 if ingress::Millston.Maumee.$valid - B37: H95(10) # ingress::Millston.Maumee.Norwood.0-7 if ingress::Millston.Maumee.$valid - B33: H95(10) # ingress::Millston.Maumee.Dassel if ingress::Millston.Maumee.$valid - TB1: H95(10) # ingress::Millston.Maumee.Bushland if ingress::Millston.Maumee.$valid - W35: H95(10) # ingress::Millston.Maumee.Kaluaaha.96-127 if ingress::Millston.Maumee.$valid - W34: H95(10) # ingress::Millston.Maumee.Kaluaaha.64-95 if ingress::Millston.Maumee.$valid - W15: H95(10) # ingress::Millston.Maumee.Kaluaaha.32-63 if ingress::Millston.Maumee.$valid - W33: H95(10) # ingress::Millston.Maumee.Kaluaaha.0-31 if ingress::Millston.Maumee.$valid - W32: H95(10) # ingress::Millston.Maumee.Calcasieu.96-127 if ingress::Millston.Maumee.$valid - W43: H95(10) # ingress::Millston.Maumee.Calcasieu.64-95 if ingress::Millston.Maumee.$valid - W42: H95(10) # ingress::Millston.Maumee.Calcasieu.32-63 if ingress::Millston.Maumee.$valid - W41: H95(10) # ingress::Millston.Maumee.Calcasieu.0-31 if ingress::Millston.Maumee.$valid - TH0: H95(9) - # - bit[15]: ingress::Millston.Broadwell.Palmhurst if ingress::Millston.Broadwell.$valid - # - bit[14]: ingress::Millston.Broadwell.Comfrey if ingress::Millston.Broadwell.$valid - # - bit[13]: ingress::Millston.Broadwell.Kalida if ingress::Millston.Broadwell.$valid - # - bit[12]: ingress::Millston.Broadwell.Wallula if ingress::Millston.Broadwell.$valid - # - bit[11]: ingress::Millston.Broadwell.Dennison if ingress::Millston.Broadwell.$valid - # - bit[10..8]: ingress::Millston.Broadwell.Fairhaven if ingress::Millston.Broadwell.$valid - # - bit[7..3]: ingress::Millston.Broadwell.Noyes if ingress::Millston.Broadwell.$valid - # - bit[2..0]: ingress::Millston.Broadwell.Woodfield if ingress::Millston.Broadwell.$valid - TB2: H95(9) # ingress::Millston.Broadwell.LasVegas.8-15 if ingress::Millston.Broadwell.$valid - TB0: H95(9) # ingress::Millston.Broadwell.LasVegas.0-7 if ingress::Millston.Broadwell.$valid - H10: H95(3) # ingress::Millston.Grays.Chevak if ingress::Millston.Grays.$valid - H33: H95(3) # ingress::Millston.Grays.Mendocino if ingress::Millston.Grays.$valid - TB14: H95(4) # ingress::Millston.Gotham.StarLake.8-15 if ingress::Millston.Gotham.$valid - TB2: H95(4) # ingress::Millston.Gotham.StarLake.0-7 if ingress::Millston.Gotham.$valid - TW1: H95(6) # ingress::Millston.Osyka.Chloride if ingress::Millston.Osyka.$valid - TW2: H95(6) # ingress::Millston.Osyka.Garibaldi if ingress::Millston.Osyka.$valid - TB0: H95(6) - # - bit[7..4]: ingress::Millston.Osyka.Weinert if ingress::Millston.Osyka.$valid - # - bit[3..0]: ingress::Millston.Osyka.Cornell if ingress::Millston.Osyka.$valid - B32: H95(6) # ingress::Millston.Osyka.Noyes if ingress::Millston.Osyka.$valid - TH0: H95(6) # ingress::Millston.Osyka.Helton if ingress::Millston.Osyka.$valid - checksum 0: H95(5) # ingress::Millston.Brookneal.$valid - TB0: H95(7) # ingress::Millston.Hoven.Noyes if ingress::Millston.Hoven.$valid - TH4: H95(7) # ingress::Millston.Hoven.Allison.8-23 if ingress::Millston.Hoven.$valid - TH3: H95(7) - # - bit[15..8]: ingress::Millston.Hoven.Allison.0-7 if ingress::Millston.Hoven.$valid - # - bit[7..0]: ingress::Millston.Hoven.Petrey.16-23 if ingress::Millston.Hoven.$valid - TH27: H95(7) # ingress::Millston.Hoven.Petrey.0-15 if ingress::Millston.Hoven.$valid - B32: H95(7) # ingress::Millston.Hoven.Roosville if ingress::Millston.Hoven.$valid - W15: H95(8) - # - bit[31..8]: ingress::Millston.Shirley.Adona if ingress::Millston.Shirley.$valid - # - bit[7..0]: ingress::Millston.Shirley.Connell.16-23 if ingress::Millston.Shirley.$valid - H39: H95(8) # ingress::Millston.Shirley.Connell.0-15 if ingress::Millston.Shirley.$valid - H92: H95(8) # ingress::Millston.Shirley.Goldsboro.8-23 if ingress::Millston.Shirley.$valid - B35: H95(8) # ingress::Millston.Shirley.Goldsboro.0-7 if ingress::Millston.Shirley.$valid - H93: H95(8) # ingress::Millston.Shirley.Fabens.8-23 if ingress::Millston.Shirley.$valid - B37: H95(8) # ingress::Millston.Shirley.Fabens.0-7 if ingress::Millston.Shirley.$valid - H94: H95(8) # ingress::Millston.Shirley.McCaulley if ingress::Millston.Shirley.$valid - TW1: B54(5) - # - bit[31..28]: ingress::Millston.Ramos.Fayette if ingress::Millston.Ramos.$valid - # - bit[27..24]: ingress::Millston.Ramos.Osterdock if ingress::Millston.Ramos.$valid - # - bit[23..18]: ingress::Millston.Ramos.PineCity if ingress::Millston.Ramos.$valid - # - bit[17..16]: ingress::Millston.Ramos.Alameda if ingress::Millston.Ramos.$valid - # - bit[15..0]: ingress::Millston.Ramos.Rexville if ingress::Millston.Ramos.$valid - TW2: B54(5) - # - bit[31..16]: ingress::Millston.Ramos.Quinwood if ingress::Millston.Ramos.$valid - # - bit[15]: ingress::Millston.Ramos.Marfa if ingress::Millston.Ramos.$valid - # - bit[14]: ingress::Millston.Ramos.Palatine if ingress::Millston.Ramos.$valid - # - bit[13]: ingress::Millston.Ramos.Mabelle if ingress::Millston.Ramos.$valid - # - bit[12..0]: ingress::Millston.Ramos.Hoagland if ingress::Millston.Ramos.$valid - TH1: B54(5) - # - bit[15..8]: ingress::Millston.Ramos.Exton if ingress::Millston.Ramos.$valid - # - bit[7..0]: ingress::Millston.Ramos.Ocoee if ingress::Millston.Ramos.$valid - TH2: B54(5) # ingress::Millston.Ramos.Hackett if ingress::Millston.Ramos.$valid - TW13: B54(5) # ingress::Millston.Ramos.Kaluaaha if ingress::Millston.Ramos.$valid - TW14: B54(5) # ingress::Millston.Ramos.Calcasieu if ingress::Millston.Ramos.$valid - TB3: H95(2) - # - bit[7..4]: ingress::Millston.Provencal.Fayette if ingress::Millston.Provencal.$valid - # - bit[3..0]: ingress::Millston.Provencal.PineCity.2-5 if ingress::Millston.Provencal.$valid - H35: H95(2) - # - bit[15..14]: ingress::Millston.Provencal.PineCity.0-1 if ingress::Millston.Provencal.$valid - # - bit[13..12]: ingress::Millston.Provencal.Alameda if ingress::Millston.Provencal.$valid - # - bit[11..0]: ingress::Millston.Provencal.Maryhill.8-19 if ingress::Millston.Provencal.$valid - B39: H95(2) # ingress::Millston.Provencal.Maryhill.0-7 if ingress::Millston.Provencal.$valid - TW1: H95(2) - # - bit[31..16]: ingress::Millston.Provencal.Norwood if ingress::Millston.Provencal.$valid - # - bit[15..8]: ingress::Millston.Provencal.Dassel if ingress::Millston.Provencal.$valid - # - bit[7..0]: ingress::Millston.Provencal.Bushland if ingress::Millston.Provencal.$valid - TH2: H95(2) # ingress::Millston.Provencal.Kaluaaha.112-127 if ingress::Millston.Provencal.$valid - TH1: H95(2) # ingress::Millston.Provencal.Kaluaaha.96-111 if ingress::Millston.Provencal.$valid - TW14: H95(2) # ingress::Millston.Provencal.Kaluaaha.64-95 if ingress::Millston.Provencal.$valid - TW13: H95(2) # ingress::Millston.Provencal.Kaluaaha.32-63 if ingress::Millston.Provencal.$valid - TW2: H95(2) # ingress::Millston.Provencal.Kaluaaha.0-31 if ingress::Millston.Provencal.$valid - TW16: H95(2) # ingress::Millston.Provencal.Calcasieu.96-127 if ingress::Millston.Provencal.$valid - TH23: H95(2) # ingress::Millston.Provencal.Calcasieu.80-95 if ingress::Millston.Provencal.$valid - TB13: H95(2) # ingress::Millston.Provencal.Calcasieu.72-79 if ingress::Millston.Provencal.$valid - TB12: H95(2) # ingress::Millston.Provencal.Calcasieu.64-71 if ingress::Millston.Provencal.$valid - TH22: H95(2) # ingress::Millston.Provencal.Calcasieu.48-63 if ingress::Millston.Provencal.$valid - TH21: H95(2) # ingress::Millston.Provencal.Calcasieu.32-47 if ingress::Millston.Provencal.$valid - TH20: H95(2) # ingress::Millston.Provencal.Calcasieu.16-31 if ingress::Millston.Provencal.$valid - TH19: H95(2) # ingress::Millston.Provencal.Calcasieu.0-15 if ingress::Millston.Provencal.$valid - W47: B54(6) - # - bit[31..16]: ingress::Millston.Bergton.Chevak if ingress::Millston.Bergton.$valid - # - bit[15..0]: ingress::Millston.Bergton.Mendocino if ingress::Millston.Bergton.$valid - TW15: H95(1) # ingress::Millston.Cassa.Chloride if ingress::Millston.Cassa.$valid - TH18: H95(1) # ingress::Millston.Cassa.Garibaldi.16-31 if ingress::Millston.Cassa.$valid - TH5: H95(1) # ingress::Millston.Cassa.Garibaldi.0-15 if ingress::Millston.Cassa.$valid - TW3: H95(1) - # - bit[31..28]: ingress::Millston.Cassa.Weinert if ingress::Millston.Cassa.$valid - # - bit[27..24]: ingress::Millston.Cassa.Cornell if ingress::Millston.Cassa.$valid - # - bit[23..16]: ingress::Millston.Cassa.Noyes if ingress::Millston.Cassa.$valid - # - bit[15..0]: ingress::Millston.Cassa.Helton if ingress::Millston.Cassa.$valid - TH5: B54(7) # ingress::Millston.Pawtucket.StarLake if ingress::Millston.Pawtucket.$valid - TH26: H95(0) # ingress::Millston.Buckhorn.SoapLake if ingress::Millston.Buckhorn.$valid - TW1: B54(3) - # - bit[31..16]: ingress::Millston.Rainelle.Conner if ingress::Millston.Rainelle.$valid - # - bit[15..0]: ingress::Millston.Rainelle.Ledoux if ingress::Millston.Rainelle.$valid - TH0: B54(3) - # - bit[15..8]: ingress::Millston.Rainelle.Steger if ingress::Millston.Rainelle.$valid - # - bit[7..0]: ingress::Millston.Rainelle.Quogue if ingress::Millston.Rainelle.$valid - H35: B54(3) # ingress::Millston.Rainelle.Findlay if ingress::Millston.Rainelle.$valid - checksum 0: - - W51: { } # ingress::HillTop.RossFork.Bucktown - - W50(0..15): { } # bit[15..0]: ingress::Millston.Brookneal.SoapLake - egress_unicast_port: W2(0..8) # bit[8..0]: ingress::ig_intr_md_for_tm.ucast_egress_port - icos: B8(0..2) # bit[2..0]: ingress::ig_intr_md_for_tm.ingress_cos - qid: B13(0..4) # bit[4..0]: ingress::ig_intr_md_for_tm.qid - copy_to_cpu: H52(0..0) # bit[0]: ingress::ig_intr_md_for_tm.copy_to_cpu - xid: H8 # ingress::ig_intr_md_for_tm.level1_exclusion_id - yid: W9(0..8) # bit[8..0]: ingress::ig_intr_md_for_tm.level2_exclusion_id - rid: H5 # ingress::ig_intr_md_for_tm.rid - drop_ctl: B15(0..2) # bit[2..0]: ingress::ig_intr_md_for_dprsr.drop_ctl - egress_multicast_group_0: - - H7 # ingress::ig_intr_md_for_tm.mcast_grp_a - hash_lag_ecmp_mcast_1: - - H50(0..12) # bit[12..0]: ingress::ig_intr_md_for_tm.level2_mcast_hash - learning: - select: B0(0..2) # bit[2..0]: ingress::ig_intr_md_for_dprsr.digest_type - 1: - - B0(0..2) # bit[2..0]: ingress::ig_intr_md_for_dprsr.digest_type - - H37 # ingress::HillTop.RossFork.Goldsboro.8-23 - - W8(0..7) # bit[7..0]: ingress::HillTop.RossFork.Goldsboro.0-7 - - W7(0..23) # bit[23..0]: ingress::HillTop.RossFork.Fabens - - H4(0..11) # bit[11..0]: ingress::HillTop.RossFork.CeeVee - - W4(0..19) # bit[19..0]: ingress::HillTop.RossFork.Quebrada - 2: - - B0(0..2) # bit[2..0]: ingress::ig_intr_md_for_dprsr.digest_type - - H4(0..11) # bit[11..0]: ingress::HillTop.RossFork.CeeVee - - H92 # ingress::Millston.Shirley.Goldsboro.8-23 - - B35 # ingress::Millston.Shirley.Goldsboro.0-7 - - H93 # ingress::Millston.Shirley.Fabens.8-23 - - B37 # ingress::Millston.Shirley.Fabens.0-7 - - W32 # ingress::Millston.GlenAvon.Kaluaaha - - W35 # ingress::Millston.Maumee.Kaluaaha.96-127 - - W34 # ingress::Millston.Maumee.Kaluaaha.64-95 - - W15 # ingress::Millston.Maumee.Kaluaaha.32-63 - - W33 # ingress::Millston.Maumee.Kaluaaha.0-31 - - B53 # ingress::Millston.Calabash.McCaulley.8-15 - - B50 # ingress::Millston.Calabash.McCaulley.0-7 - - W49(0..15) # bit[15..0]: ingress::HillTop.RossFork.Everton - - B55 # ingress::HillTop.RossFork.Lafayette - - B32 # ingress::Millston.Hoven.Roosville - context_json: - 1: - - [ HillTop.RossFork.Goldsboro, 1, 16, 7, 8] - - [ HillTop.RossFork.Goldsboro, 6, 8, 7, 0] - - [ HillTop.RossFork.Fabens, 8, 24, 7, 0] - - [ HillTop.RossFork.CeeVee, 11, 12, 3, 0] - - [ HillTop.RossFork.Quebrada, 14, 20, 3, 0] - 2: - - [ HillTop.RossFork.CeeVee, 1, 12, 3, 0] - - [ Millston.Shirley.Goldsboro, 3, 16, 7, 8] - - [ Millston.Shirley.Goldsboro, 5, 8, 7, 0] - - [ Millston.Shirley.Fabens, 6, 16, 7, 8] - - [ Millston.Shirley.Fabens, 8, 8, 7, 0] - - [ Millston.GlenAvon.Kaluaaha, 9, 32, 7, 0] - - [ Millston.Maumee.Kaluaaha, 13, 32, 7, 96] - - [ Millston.Maumee.Kaluaaha, 17, 32, 7, 64] - - [ Millston.Maumee.Kaluaaha, 21, 32, 7, 32] - - [ Millston.Maumee.Kaluaaha, 25, 32, 7, 0] - - [ Millston.Calabash.McCaulley, 29, 8, 7, 8] - - [ Millston.Calabash.McCaulley, 30, 8, 7, 0] - - [ HillTop.RossFork.Everton, 33, 16, 7, 0] - - [ HillTop.RossFork.Lafayette, 35, 8, 7, 0] - - [ Millston.Hoven.Roosville, 36, 8, 7, 0] - name: [ Newhalem, Westville ] - mirror: - select: B1(0..2) # bit[2..0]: ingress::ig_intr_md_for_dprsr.mirror_type - 1: - - H34(0..9) # bit[9..0]: ingress::HillTop.Minturn.Grassflat - - B38 # ingress::HillTop.Plains.Roachdale - - H57(0..8) # bit[8..0]: ingress::HillTop.Plains.Miller -parser egress: - start: $entry_point - init_zero: [ B21, H91, B30, H67, W29, W28, H21, W30, H23, B27, TW23, W25, TB10, W24, B25, B63, B19, B20, B62, H20, H80, H88, H19, B18, B61, W26, H29, H27, H74, W23 ] - bitwise_or: [ B19, H74, W23 ] - hdr_len_adj: 27 - meta_opt: 8191 - states: - $entry_point: # from state egress::$entry_point - *: - save: { half : 0..1, byte0 : 27 } - buf_req: 28 - next: start - start: # from state egress::start - match: [ half, byte0 ] - 0b*******00100001*********: - 0..1: H16 # bit[7..15] -> H16 bit[8..0]: egress::eg_intr_md.egress_port - 17..20: W27 # bit[152..167] -> W27 bit[15..0]: egress::eg_intr_md.egress_rid - 19..22: W31 # bit[179..183] -> W31 bit[4..0]: egress::eg_intr_md.egress_qid - 25..26: H17 # egress::HillTop.Sonoma.Iberia - save: { byte1 : 27 } - shift: 27 - buf_req: 28 - next: Rumson - 0x****00: - 0..1: H16 # bit[7..15] -> H16 bit[8..0]: egress::eg_intr_md.egress_port - 17..20: W27 # bit[152..167] -> W27 bit[15..0]: egress::eg_intr_md.egress_rid - 19..22: W31 # bit[179..183] -> W31 bit[4..0]: egress::eg_intr_md.egress_qid - 25..26: H17 # egress::HillTop.Sonoma.Iberia - shift: 27 - buf_req: 27 - next: Moxley - 0x******: - 0..1: H16 # bit[7..15] -> H16 bit[8..0]: egress::eg_intr_md.egress_port - 17..20: W27 # bit[152..167] -> W27 bit[15..0]: egress::eg_intr_md.egress_rid - 19..22: W31 # bit[179..183] -> W31 bit[4..0]: egress::eg_intr_md.egress_qid - 25..26: H17 # egress::HillTop.Sonoma.Iberia - save: { byte1 : 27 } - shift: 27 - buf_req: 28 - next: Stout - Rumson: # from state egress::Rumson - match: [ byte1 ] - 0x00: - B63: 1 # value 1 -> B63 bit[0]: egress::HillTop.Wisdom.Stratford - buf_req: 0 - next: Moxley - 0x**: - B63: 1 # value 1 -> B63 bit[0]: egress::HillTop.Wisdom.Stratford - save: { byte1 : 0 } - buf_req: 1 - next: Stout - Moxley: # from state egress::Moxley - *: - 0..1: H20 - # - bit[8..10] -> H20 bit[7..5]: egress::Millston.Belgrade.Rugby - # - bit[11] -> H20 bit[4]: egress::Millston.Belgrade.Davie - 2: B27 # egress::Millston.Belgrade.Mankato - 3..4: H91 # egress::Millston.Belgrade.Virgil[23:8].8-23 - 5: B21 # egress::Millston.Belgrade.Virgil[7:0].0-7 - 6..7: H67 # egress::Millston.Belgrade.Florin[23:8].8-23 - 7..10: W25 # bit[80..87] -> W25 bit[7..0]: egress::Millston.Belgrade.Ronan[23:16].16-23 - 8: B30 # egress::Millston.Belgrade.Florin[7:0].0-7 - 9: TB10 # egress::Millston.Belgrade.Ronan[31:24].24-31 - 9..12: TW23 # bit[88..103] -> TW23 bit[15..0]: egress::Millston.Belgrade.Ronan[15:0].0-15 - 11..14: W26 # bit[104..119] -> W26 bit[15..0]: egress::Millston.Belgrade.Corinth - 12..15: W29 - # - bit[124..126] -> W29 bit[3..1]: egress::Millston.Belgrade.Union - # - bit[127] -> W29 bit[0]: egress::Millston.Belgrade.Rockport - 23..24: H80 # bit[194..199] -> H80 bit[5..0]: egress::Millston.Belgrade.Matheson - shift: 13 - buf_req: 25 - next: Moxley.$oob_stall_0 - Moxley.$oob_stall_0: # from state egress::Moxley.$oob_stall_0 - *: - save: { byte1 : 23 } - buf_req: 24 - next: Moxley.$split_0 - Moxley.$split_0: # from state egress::Moxley.$split_0 - match: [ byte1 ] - 0x00: - 0..3: W28 - # - bit[26] -> W28 bit[5]: egress::Millston.Belgrade.Anacortes - # - bit[27] -> W28 bit[4]: egress::Millston.Belgrade.Shabbona - # - bit[28..30] -> W28 bit[3..1]: egress::Millston.Belgrade.Allgood - # - bit[31] -> W28 bit[0]: egress::Millston.Belgrade.Waipahu - 4: B61 # bit[39] -> B61 bit[0]: egress::Millston.Belgrade.Freeburg - 5..8: W30 - # - bit[64..69] -> W30 bit[7..2]: egress::Millston.Belgrade.Sudbury - # - bit[70..71] -> W30 bit[1..0]: egress::Millston.Belgrade.Selawik - 9: B62 # bit[77..79] -> B62 bit[2..0]: egress::Millston.Belgrade.Willard - 11..14: W24 # bit[104..111] -> W24 bit[15..8]: egress::Millston.Belgrade.Chaska[7:0].0-7 - 12: B25 # bit[103] -> B25 bit[0]: egress::Millston.Belgrade.Chaska[8:8].8-8 - 14..15: H21 # bit[116..127] -> H21 bit[11..0]: egress::Millston.Belgrade.Requa - 16..17: H29 # bit[132..143] -> H29 bit[11..0]: egress::Millston.Belgrade.Bayshore - 18..19: H27 # bit[148..159] -> H27 bit[11..0]: egress::Millston.Belgrade.Florien - W23: 1 # value 1 -> W23 bit[0]: egress::Millston.Belgrade.$valid - shift: 20 - buf_req: 20 - next: Decorah - 0x**: - 0..3: W28 - # - bit[26] -> W28 bit[5]: egress::Millston.Belgrade.Anacortes - # - bit[27] -> W28 bit[4]: egress::Millston.Belgrade.Shabbona - # - bit[28..30] -> W28 bit[3..1]: egress::Millston.Belgrade.Allgood - # - bit[31] -> W28 bit[0]: egress::Millston.Belgrade.Waipahu - 4: B61 # bit[39] -> B61 bit[0]: egress::Millston.Belgrade.Freeburg - 5..8: W30 - # - bit[64..69] -> W30 bit[7..2]: egress::Millston.Belgrade.Sudbury - # - bit[70..71] -> W30 bit[1..0]: egress::Millston.Belgrade.Selawik - 9: B62 # bit[77..79] -> B62 bit[2..0]: egress::Millston.Belgrade.Willard - 11..14: W24 # bit[104..111] -> W24 bit[15..8]: egress::Millston.Belgrade.Chaska[7:0].0-7 - 12: B25 # bit[103] -> B25 bit[0]: egress::Millston.Belgrade.Chaska[8:8].8-8 - 14..15: H21 # bit[116..127] -> H21 bit[11..0]: egress::Millston.Belgrade.Requa - 16..17: H29 # bit[132..143] -> H29 bit[11..0]: egress::Millston.Belgrade.Bayshore - 18..19: H27 # bit[148..159] -> H27 bit[11..0]: egress::Millston.Belgrade.Florien - W23: 1 # value 1 -> W23 bit[0]: egress::Millston.Belgrade.$valid - shift: 20 - buf_req: 20 - next: Decorah - Decorah: # from state egress::Decorah - *: - 0..1: H87 # egress::Millston.Calabash.Adona[23:8].8-23 - 2: B22 # egress::Millston.Calabash.Adona[7:0].0-7 - 3..4: H68 # egress::Millston.Calabash.Connell[23:8].8-23 - 5: B31 # egress::Millston.Calabash.Connell[7:0].0-7 - 6: B29 # egress::Millston.Calabash.Goldsboro[23:16].16-23 - 7..8: H73 # egress::Millston.Calabash.Goldsboro[15:0].0-15 - 9: B24 # egress::Millston.Calabash.Fabens[23:16].16-23 - 10..11: H26 # egress::Millston.Calabash.Fabens[15:0].0-15 - W23: 2 # value 1 -> W23 bit[1]: egress::Millston.Calabash.$valid - save: { half : 12..13, byte0 : 14 } - shift: 12 - buf_req: 15 - next: Decorah.$split_0 - Decorah.$split_0: # from state egress::Decorah.$split_0 - match: [ byte0, half ] - 0x**9100: - 0..1: H25 # egress::Millston.Calabash.McCaulley - save: { half : 4..5, byte0 : 6 } - shift: 2 - buf_req: 7 - next: Elvaston - 0x**88a8: - 0..1: H25 # egress::Millston.Calabash.McCaulley - save: { half : 4..5, byte0 : 6 } - shift: 2 - buf_req: 7 - next: Elvaston - 0x**8100: - 0..1: H25 # egress::Millston.Calabash.McCaulley - save: { half : 4..5, byte0 : 6 } - shift: 2 - buf_req: 7 - next: Elvaston - 0x**0806: - 0..1: H25 # egress::Millston.Calabash.McCaulley - save: { half : 2..3, byte0 : 4, byte1 : 5 } - shift: 2 - buf_req: 6 - next: Corvallis - 0x450800: - 0..1: H25 # egress::Millston.Calabash.McCaulley - save: { half : 8..9, byte0 : 11 } - shift: 2 - buf_req: 12 - next: Belmont - 0x*50800: - 0..1: H25 # egress::Millston.Calabash.McCaulley - shift: 2 - buf_req: 2 - next: end - 0x**0800: - 0..1: H25 # egress::Millston.Calabash.McCaulley - shift: 2 - buf_req: 2 - next: Hillsview - 0x6*86dd: - 0..1: H25 # egress::Millston.Calabash.McCaulley - shift: 2 - buf_req: 2 - next: Westbury - 0x**86dd: - 0..1: H25 # egress::Millston.Calabash.McCaulley - shift: 2 - buf_req: 2 - next: end - 0x**8808: - 0..1: H25 # egress::Millston.Calabash.McCaulley - shift: 2 - buf_req: 2 - next: end - 0x******: - 0..1: H25 # egress::Millston.Calabash.McCaulley - shift: 2 - buf_req: 2 - next: end - Elvaston: # from state egress::Elvaston - match: [ byte0, half ] - 0x**8100: - 0..1: H22 - # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson - # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden - 2..3: H24 # egress::Millston.Wondervu[0].McCaulley - B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid - save: { half : 6..7, byte0 : 8 } - shift: 4 - buf_req: 9 - next: Elkville - 0x**0806: - 0..1: H22 - # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson - # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden - 2..3: H24 # egress::Millston.Wondervu[0].McCaulley - B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid - save: { half : 4..5, byte0 : 6, byte1 : 7 } - shift: 4 - buf_req: 8 - next: Corvallis - 0x450800: - 0..1: H22 - # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson - # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden - 2..3: H24 # egress::Millston.Wondervu[0].McCaulley - B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid - save: { half : 10..11, byte0 : 13 } - shift: 4 - buf_req: 14 - next: Belmont - 0x*50800: - 0..1: H22 - # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson - # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden - 2..3: H24 # egress::Millston.Wondervu[0].McCaulley - B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: end - 0x**0800: - 0..1: H22 - # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson - # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden - 2..3: H24 # egress::Millston.Wondervu[0].McCaulley - B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Hillsview - 0x6*86dd: - 0..1: H22 - # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson - # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden - 2..3: H24 # egress::Millston.Wondervu[0].McCaulley - B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Westbury - 0x6*86dd: - 0..1: H22 - # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson - # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden - 2..3: H24 # egress::Millston.Wondervu[0].McCaulley - B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Westbury - 0x**86dd: - 0..1: H22 - # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson - # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden - 2..3: H24 # egress::Millston.Wondervu[0].McCaulley - B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: end - 0x**8808: - 0..1: H22 - # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson - # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden - 2..3: H24 # egress::Millston.Wondervu[0].McCaulley - B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: end - 0x******: - 0..1: H22 - # - bit[0..2] -> H22 bit[15..13]: egress::Millston.Wondervu[0].Higginson - # - bit[3] -> H22 bit[12]: egress::Millston.Wondervu[0].Oriskany - # - bit[4..15] -> H22 bit[11..0]: egress::Millston.Wondervu[0].Bowden - 2..3: H24 # egress::Millston.Wondervu[0].McCaulley - B19: 2 # value 2 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: end - Elkville: # from state egress::Elkville - match: [ byte0, half ] - 0x**0806: - 0..3: TW5 - # - bit[0..2] -> TW5 bit[31..29]: egress::Millston.Wondervu[1].Higginson - # - bit[3] -> TW5 bit[28]: egress::Millston.Wondervu[1].Oriskany - # - bit[4..15] -> TW5 bit[27..16]: egress::Millston.Wondervu[1].Bowden - # - bit[16..31] -> TW5 bit[15..0]: egress::Millston.Wondervu[1].McCaulley - B19: 1 # value 1 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid - save: { half : 4..5, byte0 : 6, byte1 : 7 } - shift: 4 - buf_req: 8 - next: Corvallis - 0x450800: - 0..3: TW5 - # - bit[0..2] -> TW5 bit[31..29]: egress::Millston.Wondervu[1].Higginson - # - bit[3] -> TW5 bit[28]: egress::Millston.Wondervu[1].Oriskany - # - bit[4..15] -> TW5 bit[27..16]: egress::Millston.Wondervu[1].Bowden - # - bit[16..31] -> TW5 bit[15..0]: egress::Millston.Wondervu[1].McCaulley - B19: 1 # value 1 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid - save: { half : 10..11, byte0 : 13 } - shift: 4 - buf_req: 14 - next: Belmont - 0x*50800: - 0..3: TW5 - # - bit[0..2] -> TW5 bit[31..29]: egress::Millston.Wondervu[1].Higginson - # - bit[3] -> TW5 bit[28]: egress::Millston.Wondervu[1].Oriskany - # - bit[4..15] -> TW5 bit[27..16]: egress::Millston.Wondervu[1].Bowden - # - bit[16..31] -> TW5 bit[15..0]: egress::Millston.Wondervu[1].McCaulley - B19: 1 # value 1 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: end - 0x**0800: - 0..3: TW5 - # - bit[0..2] -> TW5 bit[31..29]: egress::Millston.Wondervu[1].Higginson - # - bit[3] -> TW5 bit[28]: egress::Millston.Wondervu[1].Oriskany - # - bit[4..15] -> TW5 bit[27..16]: egress::Millston.Wondervu[1].Bowden - # - bit[16..31] -> TW5 bit[15..0]: egress::Millston.Wondervu[1].McCaulley - B19: 1 # value 1 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Hillsview - 0x6*86dd: - 0..3: TW5 - # - bit[0..2] -> TW5 bit[31..29]: egress::Millston.Wondervu[1].Higginson - # - bit[3] -> TW5 bit[28]: egress::Millston.Wondervu[1].Oriskany - # - bit[4..15] -> TW5 bit[27..16]: egress::Millston.Wondervu[1].Bowden - # - bit[16..31] -> TW5 bit[15..0]: egress::Millston.Wondervu[1].McCaulley - B19: 1 # value 1 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Westbury - 0x6*86dd: - 0..3: TW5 - # - bit[0..2] -> TW5 bit[31..29]: egress::Millston.Wondervu[1].Higginson - # - bit[3] -> TW5 bit[28]: egress::Millston.Wondervu[1].Oriskany - # - bit[4..15] -> TW5 bit[27..16]: egress::Millston.Wondervu[1].Bowden - # - bit[16..31] -> TW5 bit[15..0]: egress::Millston.Wondervu[1].McCaulley - B19: 1 # value 1 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: Westbury - 0x**86dd: - 0..3: TW5 - # - bit[0..2] -> TW5 bit[31..29]: egress::Millston.Wondervu[1].Higginson - # - bit[3] -> TW5 bit[28]: egress::Millston.Wondervu[1].Oriskany - # - bit[4..15] -> TW5 bit[27..16]: egress::Millston.Wondervu[1].Bowden - # - bit[16..31] -> TW5 bit[15..0]: egress::Millston.Wondervu[1].McCaulley - B19: 1 # value 1 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: end - 0x**8808: - 0..3: TW5 - # - bit[0..2] -> TW5 bit[31..29]: egress::Millston.Wondervu[1].Higginson - # - bit[3] -> TW5 bit[28]: egress::Millston.Wondervu[1].Oriskany - # - bit[4..15] -> TW5 bit[27..16]: egress::Millston.Wondervu[1].Bowden - # - bit[16..31] -> TW5 bit[15..0]: egress::Millston.Wondervu[1].McCaulley - B19: 1 # value 1 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: end - 0x******: - 0..3: TW5 - # - bit[0..2] -> TW5 bit[31..29]: egress::Millston.Wondervu[1].Higginson - # - bit[3] -> TW5 bit[28]: egress::Millston.Wondervu[1].Oriskany - # - bit[4..15] -> TW5 bit[27..16]: egress::Millston.Wondervu[1].Bowden - # - bit[16..31] -> TW5 bit[15..0]: egress::Millston.Wondervu[1].McCaulley - B19: 1 # value 1 -> B19 bit[1..0]: egress::Millston.Wondervu.$stkvalid - shift: 4 - buf_req: 4 - next: end - Corvallis: # from state egress::Corvallis - match: [ half, byte0, byte1 ] - 0x00010800: - 0..3: TW6 - # - bit[0..15] -> TW6 bit[31..16]: egress::Millston.Rainelle.Conner - # - bit[16..31] -> TW6 bit[15..0]: egress::Millston.Rainelle.Ledoux - 4..7: TW4 - # - bit[32..39] -> TW4 bit[31..24]: egress::Millston.Rainelle.Steger - # - bit[40..47] -> TW4 bit[23..16]: egress::Millston.Rainelle.Quogue - # - bit[48..63] -> TW4 bit[15..0]: egress::Millston.Rainelle.Findlay - W23: 4 # value 1 -> W23 bit[2]: egress::Millston.Rainelle.$valid - shift: 8 - buf_req: 8 - next: end - 0x********: - buf_req: 0 - next: end - Belmont: # from state egress::Belmont - match: [ half, byte0 ] - 0o*0000004: - 0..1: H81 - # - bit[0..3] -> H81 bit[15..12]: egress::Millston.GlenAvon.Fayette - # - bit[4..7] -> H81 bit[11..8]: egress::Millston.GlenAvon.Osterdock - # - bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity - # - bit[14..15] -> H81 bit[1..0]: egress::Millston.GlenAvon.Alameda - 2..3: H18 # egress::Millston.GlenAvon.Rexville - 4..7: W16 - # - bit[32..47] -> W16 bit[31..16]: egress::Millston.GlenAvon.Quinwood - # - bit[48] -> W16 bit[15]: egress::Millston.GlenAvon.Marfa - # - bit[49] -> W16 bit[14]: egress::Millston.GlenAvon.Palatine - # - bit[50] -> W16 bit[13]: egress::Millston.GlenAvon.Mabelle - # - bit[51..63] -> W16 bit[12..0]: egress::Millston.GlenAvon.Hoagland - 8: B16 # egress::Millston.GlenAvon.Exton - 9: B23 # egress::Millston.GlenAvon.Ocoee - 10: TB20 # egress::Millston.GlenAvon.Hackett[15:8].8-15 - 11: TB11 # egress::Millston.GlenAvon.Hackett[7:0].0-7 - 12..15: W17 # egress::Millston.GlenAvon.Kaluaaha - 16..19: W18 # egress::Millston.GlenAvon.Calcasieu - W23: 8 # value 1 -> W23 bit[3]: egress::Millston.GlenAvon.$valid - save: { byte1 : 20 } - shift: 20 - buf_req: 21 - next: Baytown - 0o*0000051: - 0..1: H81 - # - bit[0..3] -> H81 bit[15..12]: egress::Millston.GlenAvon.Fayette - # - bit[4..7] -> H81 bit[11..8]: egress::Millston.GlenAvon.Osterdock - # - bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity - # - bit[14..15] -> H81 bit[1..0]: egress::Millston.GlenAvon.Alameda - 2..3: H18 # egress::Millston.GlenAvon.Rexville - 4..7: W16 - # - bit[32..47] -> W16 bit[31..16]: egress::Millston.GlenAvon.Quinwood - # - bit[48] -> W16 bit[15]: egress::Millston.GlenAvon.Marfa - # - bit[49] -> W16 bit[14]: egress::Millston.GlenAvon.Palatine - # - bit[50] -> W16 bit[13]: egress::Millston.GlenAvon.Mabelle - # - bit[51..63] -> W16 bit[12..0]: egress::Millston.GlenAvon.Hoagland - 8: B16 # egress::Millston.GlenAvon.Exton - 9: B23 # egress::Millston.GlenAvon.Ocoee - 10: TB20 # egress::Millston.GlenAvon.Hackett[15:8].8-15 - 11: TB11 # egress::Millston.GlenAvon.Hackett[7:0].0-7 - 12..15: W17 # egress::Millston.GlenAvon.Kaluaaha - 16..19: W18 # egress::Millston.GlenAvon.Calcasieu - W23: 8 # value 1 -> W23 bit[3]: egress::Millston.GlenAvon.$valid - shift: 20 - buf_req: 20 - next: Sanford - 0o*0000001: - 0..1: H81 - # - bit[0..3] -> H81 bit[15..12]: egress::Millston.GlenAvon.Fayette - # - bit[4..7] -> H81 bit[11..8]: egress::Millston.GlenAvon.Osterdock - # - bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity - # - bit[14..15] -> H81 bit[1..0]: egress::Millston.GlenAvon.Alameda - 2..3: H18 # egress::Millston.GlenAvon.Rexville - 4..7: W16 - # - bit[32..47] -> W16 bit[31..16]: egress::Millston.GlenAvon.Quinwood - # - bit[48] -> W16 bit[15]: egress::Millston.GlenAvon.Marfa - # - bit[49] -> W16 bit[14]: egress::Millston.GlenAvon.Palatine - # - bit[50] -> W16 bit[13]: egress::Millston.GlenAvon.Mabelle - # - bit[51..63] -> W16 bit[12..0]: egress::Millston.GlenAvon.Hoagland - 8: B16 # egress::Millston.GlenAvon.Exton - 9: B23 # egress::Millston.GlenAvon.Ocoee - 10: TB20 # egress::Millston.GlenAvon.Hackett[15:8].8-15 - 11: TB11 # egress::Millston.GlenAvon.Hackett[7:0].0-7 - 12..15: W17 # egress::Millston.GlenAvon.Kaluaaha - 16..19: W18 # egress::Millston.GlenAvon.Calcasieu - W23: 8 # value 1 -> W23 bit[3]: egress::Millston.GlenAvon.$valid - shift: 20 - buf_req: 20 - next: BealCity - 0o*0000021: - 0..1: H81 - # - bit[0..3] -> H81 bit[15..12]: egress::Millston.GlenAvon.Fayette - # - bit[4..7] -> H81 bit[11..8]: egress::Millston.GlenAvon.Osterdock - # - bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity - # - bit[14..15] -> H81 bit[1..0]: egress::Millston.GlenAvon.Alameda - 2..3: H18 # egress::Millston.GlenAvon.Rexville - 4..7: W16 - # - bit[32..47] -> W16 bit[31..16]: egress::Millston.GlenAvon.Quinwood - # - bit[48] -> W16 bit[15]: egress::Millston.GlenAvon.Marfa - # - bit[49] -> W16 bit[14]: egress::Millston.GlenAvon.Palatine - # - bit[50] -> W16 bit[13]: egress::Millston.GlenAvon.Mabelle - # - bit[51..63] -> W16 bit[12..0]: egress::Millston.GlenAvon.Hoagland - 8: B16 # egress::Millston.GlenAvon.Exton - 9: B23 # egress::Millston.GlenAvon.Ocoee - 10: TB20 # egress::Millston.GlenAvon.Hackett[15:8].8-15 - 11: TB11 # egress::Millston.GlenAvon.Hackett[7:0].0-7 - 12..15: W17 # egress::Millston.GlenAvon.Kaluaaha - 16..19: W18 # egress::Millston.GlenAvon.Calcasieu - W23: 8 # value 1 -> W23 bit[3]: egress::Millston.GlenAvon.$valid - shift: 20 - buf_req: 20 - next: Toluca - 0o*0000006: - 0..1: H81 - # - bit[0..3] -> H81 bit[15..12]: egress::Millston.GlenAvon.Fayette - # - bit[4..7] -> H81 bit[11..8]: egress::Millston.GlenAvon.Osterdock - # - bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity - # - bit[14..15] -> H81 bit[1..0]: egress::Millston.GlenAvon.Alameda - 2..3: H18 # egress::Millston.GlenAvon.Rexville - 4..7: W16 - # - bit[32..47] -> W16 bit[31..16]: egress::Millston.GlenAvon.Quinwood - # - bit[48] -> W16 bit[15]: egress::Millston.GlenAvon.Marfa - # - bit[49] -> W16 bit[14]: egress::Millston.GlenAvon.Palatine - # - bit[50] -> W16 bit[13]: egress::Millston.GlenAvon.Mabelle - # - bit[51..63] -> W16 bit[12..0]: egress::Millston.GlenAvon.Hoagland - 8: B16 # egress::Millston.GlenAvon.Exton - 9: B23 # egress::Millston.GlenAvon.Ocoee - 10: TB20 # egress::Millston.GlenAvon.Hackett[15:8].8-15 - 11: TB11 # egress::Millston.GlenAvon.Hackett[7:0].0-7 - 12..15: W17 # egress::Millston.GlenAvon.Kaluaaha - 16..19: W18 # egress::Millston.GlenAvon.Calcasieu - W23: 8 # value 1 -> W23 bit[3]: egress::Millston.GlenAvon.$valid - shift: 20 - buf_req: 20 - next: Readsboro - 0o*0000057: - 0..1: H81 - # - bit[0..3] -> H81 bit[15..12]: egress::Millston.GlenAvon.Fayette - # - bit[4..7] -> H81 bit[11..8]: egress::Millston.GlenAvon.Osterdock - # - bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity - # - bit[14..15] -> H81 bit[1..0]: egress::Millston.GlenAvon.Alameda - 2..3: H18 # egress::Millston.GlenAvon.Rexville - 4..7: W16 - # - bit[32..47] -> W16 bit[31..16]: egress::Millston.GlenAvon.Quinwood - # - bit[48] -> W16 bit[15]: egress::Millston.GlenAvon.Marfa - # - bit[49] -> W16 bit[14]: egress::Millston.GlenAvon.Palatine - # - bit[50] -> W16 bit[13]: egress::Millston.GlenAvon.Mabelle - # - bit[51..63] -> W16 bit[12..0]: egress::Millston.GlenAvon.Hoagland - 8: B16 # egress::Millston.GlenAvon.Exton - 9: B23 # egress::Millston.GlenAvon.Ocoee - 10: TB20 # egress::Millston.GlenAvon.Hackett[15:8].8-15 - 11: TB11 # egress::Millston.GlenAvon.Hackett[7:0].0-7 - 12..15: W17 # egress::Millston.GlenAvon.Kaluaaha - 16..19: W18 # egress::Millston.GlenAvon.Calcasieu - W23: 8 # value 1 -> W23 bit[3]: egress::Millston.GlenAvon.$valid - save: { half : 20..21, byte0 : 22, byte1 : 23 } - shift: 20 - buf_req: 24 - next: Astor - 0o*0000000: - 0..1: H81 - # - bit[0..3] -> H81 bit[15..12]: egress::Millston.GlenAvon.Fayette - # - bit[4..7] -> H81 bit[11..8]: egress::Millston.GlenAvon.Osterdock - # - bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity - # - bit[14..15] -> H81 bit[1..0]: egress::Millston.GlenAvon.Alameda - 2..3: H18 # egress::Millston.GlenAvon.Rexville - 4..7: W16 - # - bit[32..47] -> W16 bit[31..16]: egress::Millston.GlenAvon.Quinwood - # - bit[48] -> W16 bit[15]: egress::Millston.GlenAvon.Marfa - # - bit[49] -> W16 bit[14]: egress::Millston.GlenAvon.Palatine - # - bit[50] -> W16 bit[13]: egress::Millston.GlenAvon.Mabelle - # - bit[51..63] -> W16 bit[12..0]: egress::Millston.GlenAvon.Hoagland - 8: B16 # egress::Millston.GlenAvon.Exton - 9: B23 # egress::Millston.GlenAvon.Ocoee - 10: TB20 # egress::Millston.GlenAvon.Hackett[15:8].8-15 - 11: TB11 # egress::Millston.GlenAvon.Hackett[7:0].0-7 - 12..15: W17 # egress::Millston.GlenAvon.Kaluaaha - 16..19: W18 # egress::Millston.GlenAvon.Calcasieu - W23: 8 # value 1 -> W23 bit[3]: egress::Millston.GlenAvon.$valid - shift: 20 - buf_req: 20 - next: end - 0x****06: - 0..1: H81 - # - bit[0..3] -> H81 bit[15..12]: egress::Millston.GlenAvon.Fayette - # - bit[4..7] -> H81 bit[11..8]: egress::Millston.GlenAvon.Osterdock - # - bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity - # - bit[14..15] -> H81 bit[1..0]: egress::Millston.GlenAvon.Alameda - 2..3: H18 # egress::Millston.GlenAvon.Rexville - 4..7: W16 - # - bit[32..47] -> W16 bit[31..16]: egress::Millston.GlenAvon.Quinwood - # - bit[48] -> W16 bit[15]: egress::Millston.GlenAvon.Marfa - # - bit[49] -> W16 bit[14]: egress::Millston.GlenAvon.Palatine - # - bit[50] -> W16 bit[13]: egress::Millston.GlenAvon.Mabelle - # - bit[51..63] -> W16 bit[12..0]: egress::Millston.GlenAvon.Hoagland - 8: B16 # egress::Millston.GlenAvon.Exton - 9: B23 # egress::Millston.GlenAvon.Ocoee - 10: TB20 # egress::Millston.GlenAvon.Hackett[15:8].8-15 - 11: TB11 # egress::Millston.GlenAvon.Hackett[7:0].0-7 - 12..15: W17 # egress::Millston.GlenAvon.Kaluaaha - 16..19: W18 # egress::Millston.GlenAvon.Calcasieu - W23: 8 # value 1 -> W23 bit[3]: egress::Millston.GlenAvon.$valid - shift: 20 - buf_req: 20 - next: end - 0x******: - 0..1: H81 - # - bit[0..3] -> H81 bit[15..12]: egress::Millston.GlenAvon.Fayette - # - bit[4..7] -> H81 bit[11..8]: egress::Millston.GlenAvon.Osterdock - # - bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity - # - bit[14..15] -> H81 bit[1..0]: egress::Millston.GlenAvon.Alameda - 2..3: H18 # egress::Millston.GlenAvon.Rexville - 4..7: W16 - # - bit[32..47] -> W16 bit[31..16]: egress::Millston.GlenAvon.Quinwood - # - bit[48] -> W16 bit[15]: egress::Millston.GlenAvon.Marfa - # - bit[49] -> W16 bit[14]: egress::Millston.GlenAvon.Palatine - # - bit[50] -> W16 bit[13]: egress::Millston.GlenAvon.Mabelle - # - bit[51..63] -> W16 bit[12..0]: egress::Millston.GlenAvon.Hoagland - 8: B16 # egress::Millston.GlenAvon.Exton - 9: B23 # egress::Millston.GlenAvon.Ocoee - 10: TB20 # egress::Millston.GlenAvon.Hackett[15:8].8-15 - 11: TB11 # egress::Millston.GlenAvon.Hackett[7:0].0-7 - 12..15: W17 # egress::Millston.GlenAvon.Kaluaaha - 16..19: W18 # egress::Millston.GlenAvon.Calcasieu - W23: 8 # value 1 -> W23 bit[3]: egress::Millston.GlenAvon.$valid - shift: 20 - buf_req: 20 - next: end - Baytown: # from state egress::Baytown - match: [ byte1 ] - 0x45: - save: { half : 6..7, byte0 : 9 } - buf_req: 10 - next: McBrides - 0x**: - buf_req: 0 - next: end - McBrides: # from state egress::McBrides - match: [ half, byte0 ] - 0o*0000001: - 0..1: H82 - # - bit[0..3] -> H82 bit[15..12]: egress::Millston.Ramos.Fayette - # - bit[4..7] -> H82 bit[11..8]: egress::Millston.Ramos.Osterdock - # - bit[8..13] -> H82 bit[7..2]: egress::Millston.Ramos.PineCity - # - bit[14..15] -> H82 bit[1..0]: egress::Millston.Ramos.Alameda - 2..3: TH15 # egress::Millston.Ramos.Rexville - 4..7: TW4 - # - bit[32..47] -> TW4 bit[31..16]: egress::Millston.Ramos.Quinwood - # - bit[48] -> TW4 bit[15]: egress::Millston.Ramos.Marfa - # - bit[49] -> TW4 bit[14]: egress::Millston.Ramos.Palatine - # - bit[50] -> TW4 bit[13]: egress::Millston.Ramos.Mabelle - # - bit[51..63] -> TW4 bit[12..0]: egress::Millston.Ramos.Hoagland - 8..9: TH6 - # - bit[64..71] -> TH6 bit[15..8]: egress::Millston.Ramos.Exton - # - bit[72..79] -> TH6 bit[7..0]: egress::Millston.Ramos.Ocoee - 10: TB7 # egress::Millston.Ramos.Hackett[15:8].8-15 - 11: TB6 # egress::Millston.Ramos.Hackett[7:0].0-7 - 12..15: TW10 # egress::Millston.Ramos.Kaluaaha - 16..19: TW11 # egress::Millston.Ramos.Calcasieu - W23: 16 # value 1 -> W23 bit[4]: egress::Millston.Ramos.$valid - shift: 20 - buf_req: 20 - next: Hapeville - 0o*0000021: - 0..1: H82 - # - bit[0..3] -> H82 bit[15..12]: egress::Millston.Ramos.Fayette - # - bit[4..7] -> H82 bit[11..8]: egress::Millston.Ramos.Osterdock - # - bit[8..13] -> H82 bit[7..2]: egress::Millston.Ramos.PineCity - # - bit[14..15] -> H82 bit[1..0]: egress::Millston.Ramos.Alameda - 2..3: TH15 # egress::Millston.Ramos.Rexville - 4..7: TW4 - # - bit[32..47] -> TW4 bit[31..16]: egress::Millston.Ramos.Quinwood - # - bit[48] -> TW4 bit[15]: egress::Millston.Ramos.Marfa - # - bit[49] -> TW4 bit[14]: egress::Millston.Ramos.Palatine - # - bit[50] -> TW4 bit[13]: egress::Millston.Ramos.Mabelle - # - bit[51..63] -> TW4 bit[12..0]: egress::Millston.Ramos.Hoagland - 8..9: TH6 - # - bit[64..71] -> TH6 bit[15..8]: egress::Millston.Ramos.Exton - # - bit[72..79] -> TH6 bit[7..0]: egress::Millston.Ramos.Ocoee - 10: TB7 # egress::Millston.Ramos.Hackett[15:8].8-15 - 11: TB6 # egress::Millston.Ramos.Hackett[7:0].0-7 - 12..15: TW10 # egress::Millston.Ramos.Kaluaaha - 16..19: TW11 # egress::Millston.Ramos.Calcasieu - W23: 16 # value 1 -> W23 bit[4]: egress::Millston.Ramos.$valid - shift: 20 - buf_req: 20 - next: Barnhill - 0o*0000006: - 0..1: H82 - # - bit[0..3] -> H82 bit[15..12]: egress::Millston.Ramos.Fayette - # - bit[4..7] -> H82 bit[11..8]: egress::Millston.Ramos.Osterdock - # - bit[8..13] -> H82 bit[7..2]: egress::Millston.Ramos.PineCity - # - bit[14..15] -> H82 bit[1..0]: egress::Millston.Ramos.Alameda - 2..3: TH15 # egress::Millston.Ramos.Rexville - 4..7: TW4 - # - bit[32..47] -> TW4 bit[31..16]: egress::Millston.Ramos.Quinwood - # - bit[48] -> TW4 bit[15]: egress::Millston.Ramos.Marfa - # - bit[49] -> TW4 bit[14]: egress::Millston.Ramos.Palatine - # - bit[50] -> TW4 bit[13]: egress::Millston.Ramos.Mabelle - # - bit[51..63] -> TW4 bit[12..0]: egress::Millston.Ramos.Hoagland - 8..9: TH6 - # - bit[64..71] -> TH6 bit[15..8]: egress::Millston.Ramos.Exton - # - bit[72..79] -> TH6 bit[7..0]: egress::Millston.Ramos.Ocoee - 10: TB7 # egress::Millston.Ramos.Hackett[15:8].8-15 - 11: TB6 # egress::Millston.Ramos.Hackett[7:0].0-7 - 12..15: TW10 # egress::Millston.Ramos.Kaluaaha - 16..19: TW11 # egress::Millston.Ramos.Calcasieu - W23: 16 # value 1 -> W23 bit[4]: egress::Millston.Ramos.$valid - shift: 20 - buf_req: 20 - next: NantyGlo - 0o*0000000: - 0..1: H82 - # - bit[0..3] -> H82 bit[15..12]: egress::Millston.Ramos.Fayette - # - bit[4..7] -> H82 bit[11..8]: egress::Millston.Ramos.Osterdock - # - bit[8..13] -> H82 bit[7..2]: egress::Millston.Ramos.PineCity - # - bit[14..15] -> H82 bit[1..0]: egress::Millston.Ramos.Alameda - 2..3: TH15 # egress::Millston.Ramos.Rexville - 4..7: TW4 - # - bit[32..47] -> TW4 bit[31..16]: egress::Millston.Ramos.Quinwood - # - bit[48] -> TW4 bit[15]: egress::Millston.Ramos.Marfa - # - bit[49] -> TW4 bit[14]: egress::Millston.Ramos.Palatine - # - bit[50] -> TW4 bit[13]: egress::Millston.Ramos.Mabelle - # - bit[51..63] -> TW4 bit[12..0]: egress::Millston.Ramos.Hoagland - 8..9: TH6 - # - bit[64..71] -> TH6 bit[15..8]: egress::Millston.Ramos.Exton - # - bit[72..79] -> TH6 bit[7..0]: egress::Millston.Ramos.Ocoee - 10: TB7 # egress::Millston.Ramos.Hackett[15:8].8-15 - 11: TB6 # egress::Millston.Ramos.Hackett[7:0].0-7 - 12..15: TW10 # egress::Millston.Ramos.Kaluaaha - 16..19: TW11 # egress::Millston.Ramos.Calcasieu - W23: 16 # value 1 -> W23 bit[4]: egress::Millston.Ramos.$valid - shift: 20 - buf_req: 20 - next: end - 0x****06: - 0..1: H82 - # - bit[0..3] -> H82 bit[15..12]: egress::Millston.Ramos.Fayette - # - bit[4..7] -> H82 bit[11..8]: egress::Millston.Ramos.Osterdock - # - bit[8..13] -> H82 bit[7..2]: egress::Millston.Ramos.PineCity - # - bit[14..15] -> H82 bit[1..0]: egress::Millston.Ramos.Alameda - 2..3: TH15 # egress::Millston.Ramos.Rexville - 4..7: TW4 - # - bit[32..47] -> TW4 bit[31..16]: egress::Millston.Ramos.Quinwood - # - bit[48] -> TW4 bit[15]: egress::Millston.Ramos.Marfa - # - bit[49] -> TW4 bit[14]: egress::Millston.Ramos.Palatine - # - bit[50] -> TW4 bit[13]: egress::Millston.Ramos.Mabelle - # - bit[51..63] -> TW4 bit[12..0]: egress::Millston.Ramos.Hoagland - 8..9: TH6 - # - bit[64..71] -> TH6 bit[15..8]: egress::Millston.Ramos.Exton - # - bit[72..79] -> TH6 bit[7..0]: egress::Millston.Ramos.Ocoee - 10: TB7 # egress::Millston.Ramos.Hackett[15:8].8-15 - 11: TB6 # egress::Millston.Ramos.Hackett[7:0].0-7 - 12..15: TW10 # egress::Millston.Ramos.Kaluaaha - 16..19: TW11 # egress::Millston.Ramos.Calcasieu - W23: 16 # value 1 -> W23 bit[4]: egress::Millston.Ramos.$valid - shift: 20 - buf_req: 20 - next: end - 0x******: - 0..1: H82 - # - bit[0..3] -> H82 bit[15..12]: egress::Millston.Ramos.Fayette - # - bit[4..7] -> H82 bit[11..8]: egress::Millston.Ramos.Osterdock - # - bit[8..13] -> H82 bit[7..2]: egress::Millston.Ramos.PineCity - # - bit[14..15] -> H82 bit[1..0]: egress::Millston.Ramos.Alameda - 2..3: TH15 # egress::Millston.Ramos.Rexville - 4..7: TW4 - # - bit[32..47] -> TW4 bit[31..16]: egress::Millston.Ramos.Quinwood - # - bit[48] -> TW4 bit[15]: egress::Millston.Ramos.Marfa - # - bit[49] -> TW4 bit[14]: egress::Millston.Ramos.Palatine - # - bit[50] -> TW4 bit[13]: egress::Millston.Ramos.Mabelle - # - bit[51..63] -> TW4 bit[12..0]: egress::Millston.Ramos.Hoagland - 8..9: TH6 - # - bit[64..71] -> TH6 bit[15..8]: egress::Millston.Ramos.Exton - # - bit[72..79] -> TH6 bit[7..0]: egress::Millston.Ramos.Ocoee - 10: TB7 # egress::Millston.Ramos.Hackett[15:8].8-15 - 11: TB6 # egress::Millston.Ramos.Hackett[7:0].0-7 - 12..15: TW10 # egress::Millston.Ramos.Kaluaaha - 16..19: TW11 # egress::Millston.Ramos.Calcasieu - W23: 16 # value 1 -> W23 bit[4]: egress::Millston.Ramos.$valid - shift: 20 - buf_req: 20 - next: end - Hapeville: # from state egress::Hapeville - *: - 0..1: TH8 # egress::Millston.Bergton.Chevak - 2..3: TH7 # egress::Millston.Bergton.Mendocino - W23: 32 # value 1 -> W23 bit[5]: egress::Millston.Bergton.$valid - shift: 4 - buf_req: 4 - next: end - Barnhill: # from state egress::Barnhill - *: - 0..1: TH8 # egress::Millston.Bergton.Chevak - 2..3: TH7 # egress::Millston.Bergton.Mendocino - 4..5: TH11 # egress::Millston.Pawtucket.StarLake - 6..7: TH31 # egress::Millston.Buckhorn.SoapLake - W23: 224 - # - value 1 -> W23 bit[5]: egress::Millston.Bergton.$valid - # - value 1 -> W23 bit[6]: egress::Millston.Pawtucket.$valid - # - value 1 -> W23 bit[7]: egress::Millston.Buckhorn.$valid - shift: 8 - buf_req: 8 - next: end - NantyGlo: # from state egress::NantyGlo - *: - 0..1: TH8 # egress::Millston.Bergton.Chevak - 2..3: TH7 # egress::Millston.Bergton.Mendocino - 4..5: TH12 # egress::Millston.Cassa.Chloride[31:16].16-31 - 6..7: TH11 # egress::Millston.Cassa.Chloride[15:0].0-15 - 12..15: TW6 - # - bit[96..99] -> TW6 bit[31..28]: egress::Millston.Cassa.Weinert - # - bit[100..103] -> TW6 bit[27..24]: egress::Millston.Cassa.Cornell - # - bit[104..111] -> TW6 bit[23..16]: egress::Millston.Cassa.Noyes - # - bit[112..127] -> TW6 bit[15..0]: egress::Millston.Cassa.Helton - W23: 160 - # - value 1 -> W23 bit[5]: egress::Millston.Bergton.$valid - # - value 1 -> W23 bit[7]: egress::Millston.Buckhorn.$valid - shift: 8 - buf_req: 16 - next: NantyGlo.$split_0 - NantyGlo.$split_0: # from state egress::NantyGlo.$split_0 - *: - 0..1: TH14 # egress::Millston.Cassa.Garibaldi[31:16].16-31 - 2..3: TH13 # egress::Millston.Cassa.Garibaldi[15:0].0-15 - 8..9: TH31 # egress::Millston.Buckhorn.SoapLake - H74: 1 # value 1 -> H74 bit[0]: egress::Millston.Cassa.$valid - shift: 10 - buf_req: 10 - next: end - Sanford: # from state egress::Sanford - *: - 0..1: H82 - # - bit[0..3] -> H82 bit[15..12]: egress::Millston.Provencal.Fayette - # - bit[4..9] -> H82 bit[11..6]: egress::Millston.Provencal.PineCity - # - bit[10..11] -> H82 bit[5..4]: egress::Millston.Provencal.Alameda - # - bit[12..15] -> H82 bit[3..0]: egress::Millston.Provencal.Maryhill[19:16].16-19 - 2..3: TH30 # egress::Millston.Provencal.Maryhill[15:0].0-15 - 4..7: TW4 - # - bit[32..47] -> TW4 bit[31..16]: egress::Millston.Provencal.Norwood - # - bit[48..55] -> TW4 bit[15..8]: egress::Millston.Provencal.Dassel - # - bit[56..63] -> TW4 bit[7..0]: egress::Millston.Provencal.Bushland - 8..9: TH16 # egress::Millston.Provencal.Kaluaaha[127:112].112-127 - 10..11: TH15 # egress::Millston.Provencal.Kaluaaha[111:96].96-111 - 14: TB7 # egress::Millston.Provencal.Kaluaaha[79:72].72-79 - 15: TB6 # egress::Millston.Provencal.Kaluaaha[71:64].64-71 - 16..19: TW11 # egress::Millston.Provencal.Kaluaaha[63:32].32-63 - 20..23: TW10 # egress::Millston.Provencal.Kaluaaha[31:0].0-31 - 24..27: TW22 # egress::Millston.Provencal.Calcasieu[127:96].96-127 - save: { byte1 : 6 } - shift: 12 - buf_req: 28 - next: Sanford.$split_0 - Sanford.$split_0: # from state egress::Sanford.$split_0 - match: [ byte1 ] - 0x3a: - 0..1: TH6 # egress::Millston.Provencal.Kaluaaha[95:80].80-95 - 16..19: TW21 # egress::Millston.Provencal.Calcasieu[95:64].64-95 - 20..23: TW20 # egress::Millston.Provencal.Calcasieu[63:32].32-63 - 24..25: TH17 # egress::Millston.Provencal.Calcasieu[31:16].16-31 - 26: TB9 # egress::Millston.Provencal.Calcasieu[15:8].8-15 - 27: TB8 # egress::Millston.Provencal.Calcasieu[7:0].0-7 - H74: 2 # value 1 -> H74 bit[1]: egress::Millston.Provencal.$valid - shift: 28 - buf_req: 28 - next: Hapeville - 0x11: - 0..1: TH6 # egress::Millston.Provencal.Kaluaaha[95:80].80-95 - 16..19: TW21 # egress::Millston.Provencal.Calcasieu[95:64].64-95 - 20..23: TW20 # egress::Millston.Provencal.Calcasieu[63:32].32-63 - 24..25: TH17 # egress::Millston.Provencal.Calcasieu[31:16].16-31 - 26: TB9 # egress::Millston.Provencal.Calcasieu[15:8].8-15 - 27: TB8 # egress::Millston.Provencal.Calcasieu[7:0].0-7 - H74: 2 # value 1 -> H74 bit[1]: egress::Millston.Provencal.$valid - shift: 28 - buf_req: 28 - next: Barnhill - 0x06: - 0..1: TH6 # egress::Millston.Provencal.Kaluaaha[95:80].80-95 - 16..19: TW21 # egress::Millston.Provencal.Calcasieu[95:64].64-95 - 20..23: TW20 # egress::Millston.Provencal.Calcasieu[63:32].32-63 - 24..25: TH17 # egress::Millston.Provencal.Calcasieu[31:16].16-31 - 26: TB9 # egress::Millston.Provencal.Calcasieu[15:8].8-15 - 27: TB8 # egress::Millston.Provencal.Calcasieu[7:0].0-7 - H74: 2 # value 1 -> H74 bit[1]: egress::Millston.Provencal.$valid - shift: 28 - buf_req: 28 - next: NantyGlo - 0x**: - 0..1: TH6 # egress::Millston.Provencal.Kaluaaha[95:80].80-95 - 16..19: TW21 # egress::Millston.Provencal.Calcasieu[95:64].64-95 - 20..23: TW20 # egress::Millston.Provencal.Calcasieu[63:32].32-63 - 24..25: TH17 # egress::Millston.Provencal.Calcasieu[31:16].16-31 - 26: TB9 # egress::Millston.Provencal.Calcasieu[15:8].8-15 - 27: TB8 # egress::Millston.Provencal.Calcasieu[7:0].0-7 - H74: 2 # value 1 -> H74 bit[1]: egress::Millston.Provencal.$valid - shift: 28 - buf_req: 28 - next: end - BealCity: # from state egress::BealCity - *: - 0..1: H70 # egress::Millston.Grays.Chevak - 2..3: H69 # egress::Millston.Grays.Mendocino - H74: 4 # value 1 -> H74 bit[2]: egress::Millston.Grays.$valid - shift: 4 - buf_req: 4 - next: end - Toluca: # from state egress::Toluca - *: - 0..1: H70 # egress::Millston.Grays.Chevak - 2..3: H69 # egress::Millston.Grays.Mendocino - 4..5: TH32 # egress::Millston.Gotham.StarLake - 6..7: TH33 # egress::Millston.Brookneal.SoapLake - save: { half : 2..3 } - shift: 8 - buf_req: 8 - next: Toluca.$split_0 - Toluca.$split_0: # from state egress::Toluca.$split_0 - match: [ half ] - 0x12b5: - H74: 28 - # - value 1 -> H74 bit[2]: egress::Millston.Grays.$valid - # - value 1 -> H74 bit[3]: egress::Millston.Gotham.$valid - # - value 1 -> H74 bit[4]: egress::Millston.Brookneal.$valid - buf_req: 0 - next: Goodwin - 0xff32: - H74: 28 - # - value 1 -> H74 bit[2]: egress::Millston.Grays.$valid - # - value 1 -> H74 bit[3]: egress::Millston.Gotham.$valid - # - value 1 -> H74 bit[4]: egress::Millston.Brookneal.$valid - buf_req: 0 - next: Goodwin - 0x****: - H74: 28 - # - value 1 -> H74 bit[2]: egress::Millston.Grays.$valid - # - value 1 -> H74 bit[3]: egress::Millston.Gotham.$valid - # - value 1 -> H74 bit[4]: egress::Millston.Brookneal.$valid - buf_req: 0 - next: end - Goodwin: # from state egress::Goodwin - *: - 0..3: TW7 - # - bit[0..7] -> TW7 bit[31..24]: egress::Millston.Hoven.Noyes - # - bit[8..31] -> TW7 bit[23..0]: egress::Millston.Hoven.Allison - 4..5: TH10 # egress::Millston.Hoven.Petrey[23:8].8-23 - 6..7: TH9 - # - bit[48..55] -> TH9 bit[15..8]: egress::Millston.Hoven.Petrey[7:0].0-7 - # - bit[56..63] -> TH9 bit[7..0]: egress::Millston.Hoven.Roosville - 8..9: TH34 # egress::Millston.Shirley.Adona[23:8].8-23 - 10: TB4 # egress::Millston.Shirley.Adona[7:0].0-7 - 11..14: TW8 - # - bit[88..111] -> TW8 bit[31..8]: egress::Millston.Shirley.Connell - # - bit[112..119] -> TW8 bit[7..0]: egress::Millston.Shirley.Goldsboro[23:16].16-23 - 15..16: TH35 # egress::Millston.Shirley.Goldsboro[15:0].0-15 - 17..20: TW9 - # - bit[136..159] -> TW9 bit[31..8]: egress::Millston.Shirley.Fabens - # - bit[160..167] -> TW9 bit[7..0]: egress::Millston.Shirley.McCaulley[15:8].8-15 - 21: TB5 # egress::Millston.Shirley.McCaulley[7:0].0-7 - save: { byte1 : 22, half : 20..21 } - shift: 22 - buf_req: 23 - next: Goodwin.$split_0 - Goodwin.$split_0: # from state egress::Goodwin.$split_0 - match: [ byte1, half ] - 0x**0806: - H74: 192 - # - value 1 -> H74 bit[6]: egress::Millston.Hoven.$valid - # - value 1 -> H74 bit[7]: egress::Millston.Shirley.$valid - save: { half : 0..1, byte0 : 2, byte1 : 3 } - buf_req: 4 - next: Corvallis - 0x450800: - H74: 192 - # - value 1 -> H74 bit[6]: egress::Millston.Hoven.$valid - # - value 1 -> H74 bit[7]: egress::Millston.Shirley.$valid - save: { half : 6..7, byte0 : 9 } - buf_req: 10 - next: McBrides - 0x*50800: - H74: 192 - # - value 1 -> H74 bit[6]: egress::Millston.Hoven.$valid - # - value 1 -> H74 bit[7]: egress::Millston.Shirley.$valid - buf_req: 0 - next: end - 0x**0800: - H74: 192 - # - value 1 -> H74 bit[6]: egress::Millston.Hoven.$valid - # - value 1 -> H74 bit[7]: egress::Millston.Shirley.$valid - buf_req: 0 - next: end - 0x6*86dd: - H74: 192 - # - value 1 -> H74 bit[6]: egress::Millston.Hoven.$valid - # - value 1 -> H74 bit[7]: egress::Millston.Shirley.$valid - buf_req: 0 - next: Sanford - 0x**86dd: - H74: 192 - # - value 1 -> H74 bit[6]: egress::Millston.Hoven.$valid - # - value 1 -> H74 bit[7]: egress::Millston.Shirley.$valid - buf_req: 0 - next: end - 0x******: - H74: 192 - # - value 1 -> H74 bit[6]: egress::Millston.Hoven.$valid - # - value 1 -> H74 bit[7]: egress::Millston.Shirley.$valid - buf_req: 0 - next: end - Readsboro: # from state egress::Readsboro - *: - 0..1: H70 # egress::Millston.Grays.Chevak - 2..3: H69 # egress::Millston.Grays.Mendocino - 4..7: TW4 # egress::Millston.Osyka.Chloride - 8..11: TW6 # egress::Millston.Osyka.Garibaldi - 12: TB4 - # - bit[96..99] -> TB4 bit[7..4]: egress::Millston.Osyka.Weinert - # - bit[100..103] -> TB4 bit[3..0]: egress::Millston.Osyka.Cornell - 13: B46 # egress::Millston.Osyka.Noyes - 14: TB6 # egress::Millston.Osyka.Helton[15:8].8-15 - 15: TB5 # egress::Millston.Osyka.Helton[7:0].0-7 - 16..17: TH33 # egress::Millston.Brookneal.SoapLake - H74: 52 - # - value 1 -> H74 bit[2]: egress::Millston.Grays.$valid - # - value 1 -> H74 bit[5]: egress::Millston.Osyka.$valid - # - value 1 -> H74 bit[4]: egress::Millston.Brookneal.$valid - shift: 18 - buf_req: 18 - next: end - Astor: # from state egress::Astor - match: [ half, byte0, byte1 ] - 0x00000800: - 0: TB5 - # - bit[0] -> TB5 bit[7]: egress::Millston.Broadwell.Palmhurst - # - bit[1] -> TB5 bit[6]: egress::Millston.Broadwell.Comfrey - # - bit[2] -> TB5 bit[5]: egress::Millston.Broadwell.Kalida - # - bit[3] -> TB5 bit[4]: egress::Millston.Broadwell.Wallula - # - bit[4] -> TB5 bit[3]: egress::Millston.Broadwell.Dennison - # - bit[5..7] -> TB5 bit[2..0]: egress::Millston.Broadwell.Fairhaven - 1: TB4 - # - bit[8..12] -> TB4 bit[7..3]: egress::Millston.Broadwell.Noyes - # - bit[13..15] -> TB4 bit[2..0]: egress::Millston.Broadwell.Woodfield - 2..3: H69 # egress::Millston.Broadwell.LasVegas - H74: 256 # value 1 -> H74 bit[8]: egress::Millston.Broadwell.$valid - save: { byte1 : 4 } - shift: 4 - buf_req: 5 - next: Hohenwald - 0x000086dd: - 0: TB5 - # - bit[0] -> TB5 bit[7]: egress::Millston.Broadwell.Palmhurst - # - bit[1] -> TB5 bit[6]: egress::Millston.Broadwell.Comfrey - # - bit[2] -> TB5 bit[5]: egress::Millston.Broadwell.Kalida - # - bit[3] -> TB5 bit[4]: egress::Millston.Broadwell.Wallula - # - bit[4] -> TB5 bit[3]: egress::Millston.Broadwell.Dennison - # - bit[5..7] -> TB5 bit[2..0]: egress::Millston.Broadwell.Fairhaven - 1: TB4 - # - bit[8..12] -> TB4 bit[7..3]: egress::Millston.Broadwell.Noyes - # - bit[13..15] -> TB4 bit[2..0]: egress::Millston.Broadwell.Woodfield - 2..3: H69 # egress::Millston.Broadwell.LasVegas - H74: 256 # value 1 -> H74 bit[8]: egress::Millston.Broadwell.$valid - save: { byte1 : 4 } - shift: 4 - buf_req: 5 - next: Eolia - 0x********: - 0: TB5 - # - bit[0] -> TB5 bit[7]: egress::Millston.Broadwell.Palmhurst - # - bit[1] -> TB5 bit[6]: egress::Millston.Broadwell.Comfrey - # - bit[2] -> TB5 bit[5]: egress::Millston.Broadwell.Kalida - # - bit[3] -> TB5 bit[4]: egress::Millston.Broadwell.Wallula - # - bit[4] -> TB5 bit[3]: egress::Millston.Broadwell.Dennison - # - bit[5..7] -> TB5 bit[2..0]: egress::Millston.Broadwell.Fairhaven - 1: TB4 - # - bit[8..12] -> TB4 bit[7..3]: egress::Millston.Broadwell.Noyes - # - bit[13..15] -> TB4 bit[2..0]: egress::Millston.Broadwell.Woodfield - 2..3: H69 # egress::Millston.Broadwell.LasVegas - H74: 256 # value 1 -> H74 bit[8]: egress::Millston.Broadwell.$valid - shift: 4 - buf_req: 4 - next: end - Hohenwald: # from state egress::Hohenwald - match: [ byte1 ] - 0x4*: - save: { byte1 : 0 } - buf_req: 1 - next: Sumner - 0x**: - buf_req: 0 - next: end - Sumner: # from state egress::Sumner - match: [ byte1 ] - 0x*5: - save: { half : 6..7, byte0 : 9 } - buf_req: 10 - next: McBrides - 0x**: - buf_req: 0 - next: end - Eolia: # from state egress::Eolia - match: [ byte1 ] - 0x6*: - 0..1: H82 - # - bit[0..3] -> H82 bit[15..12]: egress::Millston.Provencal.Fayette - # - bit[4..9] -> H82 bit[11..6]: egress::Millston.Provencal.PineCity - # - bit[10..11] -> H82 bit[5..4]: egress::Millston.Provencal.Alameda - # - bit[12..15] -> H82 bit[3..0]: egress::Millston.Provencal.Maryhill[19:16].16-19 - 2..3: TH30 # egress::Millston.Provencal.Maryhill[15:0].0-15 - 4..7: TW4 - # - bit[32..47] -> TW4 bit[31..16]: egress::Millston.Provencal.Norwood - # - bit[48..55] -> TW4 bit[15..8]: egress::Millston.Provencal.Dassel - # - bit[56..63] -> TW4 bit[7..0]: egress::Millston.Provencal.Bushland - 8..9: TH16 # egress::Millston.Provencal.Kaluaaha[127:112].112-127 - 10..11: TH15 # egress::Millston.Provencal.Kaluaaha[111:96].96-111 - 14: TB7 # egress::Millston.Provencal.Kaluaaha[79:72].72-79 - 15: TB6 # egress::Millston.Provencal.Kaluaaha[71:64].64-71 - 16..19: TW11 # egress::Millston.Provencal.Kaluaaha[63:32].32-63 - 20..23: TW10 # egress::Millston.Provencal.Kaluaaha[31:0].0-31 - 24..27: TW22 # egress::Millston.Provencal.Calcasieu[127:96].96-127 - save: { byte1 : 6 } - shift: 12 - buf_req: 28 - next: Sanford.$split_0 - 0x**: - buf_req: 0 - next: end - Hillsview: # from state egress::Hillsview - *: - 0..1: H81 # bit[8..13] -> H81 bit[7..2]: egress::Millston.GlenAvon.PineCity - 9: B23 # egress::Millston.GlenAvon.Ocoee - 16..19: W18 # egress::Millston.GlenAvon.Calcasieu - buf_req: 20 - next: end - Westbury: # from state egress::Westbury - *: - 0..1: H81 - # - bit[0..3] -> H81 bit[15..12]: egress::Millston.Maumee.Fayette - # - bit[4..9] -> H81 bit[11..6]: egress::Millston.Maumee.PineCity - # - bit[10..11] -> H81 bit[5..4]: egress::Millston.Maumee.Alameda - # - bit[12..15] -> H81 bit[3..0]: egress::Millston.Maumee.Maryhill[19:16].16-19 - 2..5: TW7 - # - bit[16..31] -> TW7 bit[31..16]: egress::Millston.Maumee.Maryhill[15:0].0-15 - # - bit[32..47] -> TW7 bit[15..0]: egress::Millston.Maumee.Norwood - 6: B23 # egress::Millston.Maumee.Dassel - 7: B16 # egress::Millston.Maumee.Bushland - 8..9: H71 # egress::Millston.Maumee.Kaluaaha[127:112].112-127 - 10..11: H18 # egress::Millston.Maumee.Kaluaaha[111:96].96-111 - 12..15: W18 # egress::Millston.Maumee.Kaluaaha[95:64].64-95 - 16..19: W17 # egress::Millston.Maumee.Kaluaaha[63:32].32-63 - 20..23: W16 # egress::Millston.Maumee.Kaluaaha[31:0].0-31 - H74: 512 # value 1 -> H74 bit[9]: egress::Millston.Maumee.$valid - save: { byte1 : 6 } - shift: 24 - buf_req: 24 - next: Westbury.$split_0 - Westbury.$split_0: # from state egress::Westbury.$split_0 - match: [ byte1 ] - 0x3a: - 0..3: W22 # egress::Millston.Maumee.Calcasieu[127:96].96-127 - 4..7: W21 # egress::Millston.Maumee.Calcasieu[95:64].64-95 - 8..11: W20 # egress::Millston.Maumee.Calcasieu[63:32].32-63 - 12..15: W19 # egress::Millston.Maumee.Calcasieu[31:0].0-31 - shift: 16 - buf_req: 16 - next: BealCity - 0x11: - 0..3: W22 # egress::Millston.Maumee.Calcasieu[127:96].96-127 - 4..7: W21 # egress::Millston.Maumee.Calcasieu[95:64].64-95 - 8..11: W20 # egress::Millston.Maumee.Calcasieu[63:32].32-63 - 12..15: W19 # egress::Millston.Maumee.Calcasieu[31:0].0-31 - shift: 16 - buf_req: 16 - next: Makawao - 0x06: - 0..3: W22 # egress::Millston.Maumee.Calcasieu[127:96].96-127 - 4..7: W21 # egress::Millston.Maumee.Calcasieu[95:64].64-95 - 8..11: W20 # egress::Millston.Maumee.Calcasieu[63:32].32-63 - 12..15: W19 # egress::Millston.Maumee.Calcasieu[31:0].0-31 - shift: 16 - buf_req: 16 - next: Readsboro - 0x04: - 0..3: W22 # egress::Millston.Maumee.Calcasieu[127:96].96-127 - 4..7: W21 # egress::Millston.Maumee.Calcasieu[95:64].64-95 - 8..11: W20 # egress::Millston.Maumee.Calcasieu[63:32].32-63 - 12..15: W19 # egress::Millston.Maumee.Calcasieu[31:0].0-31 - save: { byte1 : 16 } - shift: 16 - buf_req: 17 - next: Baytown - 0x29: - 0..3: W22 # egress::Millston.Maumee.Calcasieu[127:96].96-127 - 4..7: W21 # egress::Millston.Maumee.Calcasieu[95:64].64-95 - 8..11: W20 # egress::Millston.Maumee.Calcasieu[63:32].32-63 - 12..15: W19 # egress::Millston.Maumee.Calcasieu[31:0].0-31 - shift: 16 - buf_req: 16 - next: Sanford - 0x**: - 0..3: W22 # egress::Millston.Maumee.Calcasieu[127:96].96-127 - 4..7: W21 # egress::Millston.Maumee.Calcasieu[95:64].64-95 - 8..11: W20 # egress::Millston.Maumee.Calcasieu[63:32].32-63 - 12..15: W19 # egress::Millston.Maumee.Calcasieu[31:0].0-31 - shift: 16 - buf_req: 16 - next: end - Makawao: # from state egress::Makawao - *: - 0..1: H70 # egress::Millston.Grays.Chevak - 2..3: H69 # egress::Millston.Grays.Mendocino - 4..5: TH32 # egress::Millston.Gotham.StarLake - 6..7: TH33 # egress::Millston.Brookneal.SoapLake - save: { half : 2..3 } - shift: 8 - buf_req: 8 - next: Makawao.$split_0 - Makawao.$split_0: # from state egress::Makawao.$split_0 - match: [ half ] - 0x****: - H74: 28 - # - value 1 -> H74 bit[2]: egress::Millston.Grays.$valid - # - value 1 -> H74 bit[3]: egress::Millston.Gotham.$valid - # - value 1 -> H74 bit[4]: egress::Millston.Brookneal.$valid - buf_req: 0 - next: end - Stout: # from state egress::Stout - match: [ byte1 ] - 0x01: - 0..3: W24 # bit[16..23] -> W24 bit[15..8]: egress::HillTop.Wisdom.Miller[7:0].0-7 - 1: B25 # bit[15] -> B25 bit[0]: egress::HillTop.Wisdom.Miller[8:8].8-8 - shift: 3 - buf_req: 4 - next: end - 0x02: - 0..3: W24 # bit[16..23] -> W24 bit[15..8]: egress::HillTop.Wisdom.Miller[7:0].0-7 - 1: B25 # bit[15] -> B25 bit[0]: egress::HillTop.Wisdom.Miller[8:8].8-8 - shift: 3 - buf_req: 4 - next: end - 0x**: - 0..3: W24 # bit[16..23] -> W24 bit[15..8]: egress::HillTop.Wisdom.Miller[7:0].0-7 - 1: B25 # bit[15] -> B25 bit[0]: egress::HillTop.Wisdom.Miller[8:8].8-8 - shift: 3 - buf_req: 4 - next: end -deparser egress: - dictionary: - H72: H74(10) - # - bit[15..10]: egress::Millston.Hayfield.Blitchton if egress::Millston.Hayfield.$valid - # - bit[9..0]: egress::Millston.Hayfield.Avondale if egress::Millston.Hayfield.$valid - H31: H74(10) - # - bit[15..12]: egress::Millston.Hayfield.Glassboro if egress::Millston.Hayfield.$valid - # - bit[11..0]: egress::Millston.Hayfield.Grabill if egress::Millston.Hayfield.$valid - H30: H74(10) - # - bit[15..14]: egress::Millston.Hayfield.Moorcroft if egress::Millston.Hayfield.$valid - # - bit[13..12]: egress::Millston.Hayfield.Toklat if egress::Millston.Hayfield.$valid - # - bit[11..0]: egress::Millston.Hayfield.Bledsoe if egress::Millston.Hayfield.$valid - B28: H74(10) # egress::Millston.Hayfield.Blencoe if egress::Millston.Hayfield.$valid - B26: H74(10) - # - bit[7..6]: egress::Millston.Hayfield.AquaPark if egress::Millston.Hayfield.$valid - # - bit[5..3]: egress::Millston.Hayfield.Vichy if egress::Millston.Hayfield.$valid - # - bit[2]: egress::Millston.Hayfield.Lathrop if egress::Millston.Hayfield.$valid - # - bit[1]: egress::Millston.Hayfield.Clyde if egress::Millston.Hayfield.$valid - # - bit[0]: egress::Millston.Hayfield.Clarion if egress::Millston.Hayfield.$valid - H28: H74(10) - # - bit[15..12]: egress::Millston.Hayfield.Aguilita if egress::Millston.Hayfield.$valid - # - bit[11..0]: egress::Millston.Hayfield.Harbor if egress::Millston.Hayfield.$valid - H87: W23(1) # egress::Millston.Calabash.Adona.8-23 if egress::Millston.Calabash.$valid - B22: W23(1) # egress::Millston.Calabash.Adona.0-7 if egress::Millston.Calabash.$valid - H68: W23(1) # egress::Millston.Calabash.Connell.8-23 if egress::Millston.Calabash.$valid - B31: W23(1) # egress::Millston.Calabash.Connell.0-7 if egress::Millston.Calabash.$valid - B29: W23(1) # egress::Millston.Calabash.Goldsboro.16-23 if egress::Millston.Calabash.$valid - H73: W23(1) # egress::Millston.Calabash.Goldsboro.0-15 if egress::Millston.Calabash.$valid - B24: W23(1) # egress::Millston.Calabash.Fabens.16-23 if egress::Millston.Calabash.$valid - H26: W23(1) # egress::Millston.Calabash.Fabens.0-15 if egress::Millston.Calabash.$valid - H25: W23(1) # egress::Millston.Calabash.McCaulley if egress::Millston.Calabash.$valid - H22: B19(1) - # - bit[15..13]: egress::Millston.Wondervu[0].Higginson if egress::Millston.Wondervu[0].$valid - # - bit[12]: egress::Millston.Wondervu[0].Oriskany if egress::Millston.Wondervu[0].$valid - # - bit[11..0]: egress::Millston.Wondervu[0].Bowden if egress::Millston.Wondervu[0].$valid - H24: B19(1) # egress::Millston.Wondervu[0].McCaulley if egress::Millston.Wondervu[0].$valid - TW5: B19(0) - # - bit[31..29]: egress::Millston.Wondervu[1].Higginson if egress::Millston.Wondervu[1].$valid - # - bit[28]: egress::Millston.Wondervu[1].Oriskany if egress::Millston.Wondervu[1].$valid - # - bit[27..16]: egress::Millston.Wondervu[1].Bowden if egress::Millston.Wondervu[1].$valid - # - bit[15..0]: egress::Millston.Wondervu[1].McCaulley if egress::Millston.Wondervu[1].$valid - H81: W23(3) - # - bit[15..12]: egress::Millston.GlenAvon.Fayette if egress::Millston.GlenAvon.$valid - # - bit[11..8]: egress::Millston.GlenAvon.Osterdock if egress::Millston.GlenAvon.$valid - # - bit[7..2]: egress::Millston.GlenAvon.PineCity if egress::Millston.GlenAvon.$valid - # - bit[1..0]: egress::Millston.GlenAvon.Alameda if egress::Millston.GlenAvon.$valid - H18: W23(3) # egress::Millston.GlenAvon.Rexville if egress::Millston.GlenAvon.$valid - W16: W23(3) - # - bit[31..16]: egress::Millston.GlenAvon.Quinwood if egress::Millston.GlenAvon.$valid - # - bit[15]: egress::Millston.GlenAvon.Marfa if egress::Millston.GlenAvon.$valid - # - bit[14]: egress::Millston.GlenAvon.Palatine if egress::Millston.GlenAvon.$valid - # - bit[13]: egress::Millston.GlenAvon.Mabelle if egress::Millston.GlenAvon.$valid - # - bit[12..0]: egress::Millston.GlenAvon.Hoagland if egress::Millston.GlenAvon.$valid - B16: W23(3) # egress::Millston.GlenAvon.Exton if egress::Millston.GlenAvon.$valid - B23: W23(3) # egress::Millston.GlenAvon.Ocoee if egress::Millston.GlenAvon.$valid - checksum 0: W23(3) # egress::Millston.GlenAvon.$valid - W17: W23(3) # egress::Millston.GlenAvon.Kaluaaha if egress::Millston.GlenAvon.$valid - W18: W23(3) # egress::Millston.GlenAvon.Calcasieu if egress::Millston.GlenAvon.$valid - H81: H74(9) - # - bit[15..12]: egress::Millston.Maumee.Fayette if egress::Millston.Maumee.$valid - # - bit[11..6]: egress::Millston.Maumee.PineCity if egress::Millston.Maumee.$valid - # - bit[5..4]: egress::Millston.Maumee.Alameda if egress::Millston.Maumee.$valid - # - bit[3..0]: egress::Millston.Maumee.Maryhill.16-19 if egress::Millston.Maumee.$valid - TW7: H74(9) - # - bit[31..16]: egress::Millston.Maumee.Maryhill.0-15 if egress::Millston.Maumee.$valid - # - bit[15..0]: egress::Millston.Maumee.Norwood if egress::Millston.Maumee.$valid - B23: H74(9) # egress::Millston.Maumee.Dassel if egress::Millston.Maumee.$valid - B16: H74(9) # egress::Millston.Maumee.Bushland if egress::Millston.Maumee.$valid - H71: H74(9) # egress::Millston.Maumee.Kaluaaha.112-127 if egress::Millston.Maumee.$valid - H18: H74(9) # egress::Millston.Maumee.Kaluaaha.96-111 if egress::Millston.Maumee.$valid - W18: H74(9) # egress::Millston.Maumee.Kaluaaha.64-95 if egress::Millston.Maumee.$valid - W17: H74(9) # egress::Millston.Maumee.Kaluaaha.32-63 if egress::Millston.Maumee.$valid - W16: H74(9) # egress::Millston.Maumee.Kaluaaha.0-31 if egress::Millston.Maumee.$valid - W22: H74(9) # egress::Millston.Maumee.Calcasieu.96-127 if egress::Millston.Maumee.$valid - W21: H74(9) # egress::Millston.Maumee.Calcasieu.64-95 if egress::Millston.Maumee.$valid - W20: H74(9) # egress::Millston.Maumee.Calcasieu.32-63 if egress::Millston.Maumee.$valid - W19: H74(9) # egress::Millston.Maumee.Calcasieu.0-31 if egress::Millston.Maumee.$valid - TB5: H74(8) - # - bit[7]: egress::Millston.Broadwell.Palmhurst if egress::Millston.Broadwell.$valid - # - bit[6]: egress::Millston.Broadwell.Comfrey if egress::Millston.Broadwell.$valid - # - bit[5]: egress::Millston.Broadwell.Kalida if egress::Millston.Broadwell.$valid - # - bit[4]: egress::Millston.Broadwell.Wallula if egress::Millston.Broadwell.$valid - # - bit[3]: egress::Millston.Broadwell.Dennison if egress::Millston.Broadwell.$valid - # - bit[2..0]: egress::Millston.Broadwell.Fairhaven if egress::Millston.Broadwell.$valid - TB4: H74(8) - # - bit[7..3]: egress::Millston.Broadwell.Noyes if egress::Millston.Broadwell.$valid - # - bit[2..0]: egress::Millston.Broadwell.Woodfield if egress::Millston.Broadwell.$valid - H69: H74(8) # egress::Millston.Broadwell.LasVegas if egress::Millston.Broadwell.$valid - H70: H74(2) # egress::Millston.Grays.Chevak if egress::Millston.Grays.$valid - H69: H74(2) # egress::Millston.Grays.Mendocino if egress::Millston.Grays.$valid - TH32: H74(3) # egress::Millston.Gotham.StarLake if egress::Millston.Gotham.$valid - TW4: H74(5) # egress::Millston.Osyka.Chloride if egress::Millston.Osyka.$valid - TW6: H74(5) # egress::Millston.Osyka.Garibaldi if egress::Millston.Osyka.$valid - TB4: H74(5) - # - bit[7..4]: egress::Millston.Osyka.Weinert if egress::Millston.Osyka.$valid - # - bit[3..0]: egress::Millston.Osyka.Cornell if egress::Millston.Osyka.$valid - B46: H74(5) # egress::Millston.Osyka.Noyes if egress::Millston.Osyka.$valid - TB6: H74(5) # egress::Millston.Osyka.Helton.8-15 if egress::Millston.Osyka.$valid - TB5: H74(5) # egress::Millston.Osyka.Helton.0-7 if egress::Millston.Osyka.$valid - TH33: H74(4) # egress::Millston.Brookneal.SoapLake if egress::Millston.Brookneal.$valid - TW7: H74(6) - # - bit[31..24]: egress::Millston.Hoven.Noyes if egress::Millston.Hoven.$valid - # - bit[23..0]: egress::Millston.Hoven.Allison if egress::Millston.Hoven.$valid - TH10: H74(6) # egress::Millston.Hoven.Petrey.8-23 if egress::Millston.Hoven.$valid - TH9: H74(6) - # - bit[15..8]: egress::Millston.Hoven.Petrey.0-7 if egress::Millston.Hoven.$valid - # - bit[7..0]: egress::Millston.Hoven.Roosville if egress::Millston.Hoven.$valid - TH34: H74(7) # egress::Millston.Shirley.Adona.8-23 if egress::Millston.Shirley.$valid - TB4: H74(7) # egress::Millston.Shirley.Adona.0-7 if egress::Millston.Shirley.$valid - TW8: H74(7) - # - bit[31..8]: egress::Millston.Shirley.Connell if egress::Millston.Shirley.$valid - # - bit[7..0]: egress::Millston.Shirley.Goldsboro.16-23 if egress::Millston.Shirley.$valid - TH35: H74(7) # egress::Millston.Shirley.Goldsboro.0-15 if egress::Millston.Shirley.$valid - TW9: H74(7) - # - bit[31..8]: egress::Millston.Shirley.Fabens if egress::Millston.Shirley.$valid - # - bit[7..0]: egress::Millston.Shirley.McCaulley.8-15 if egress::Millston.Shirley.$valid - TB5: H74(7) # egress::Millston.Shirley.McCaulley.0-7 if egress::Millston.Shirley.$valid - H82: W23(4) - # - bit[15..12]: egress::Millston.Ramos.Fayette if egress::Millston.Ramos.$valid - # - bit[11..8]: egress::Millston.Ramos.Osterdock if egress::Millston.Ramos.$valid - # - bit[7..2]: egress::Millston.Ramos.PineCity if egress::Millston.Ramos.$valid - # - bit[1..0]: egress::Millston.Ramos.Alameda if egress::Millston.Ramos.$valid - TH15: W23(4) # egress::Millston.Ramos.Rexville if egress::Millston.Ramos.$valid - TW4: W23(4) - # - bit[31..16]: egress::Millston.Ramos.Quinwood if egress::Millston.Ramos.$valid - # - bit[15]: egress::Millston.Ramos.Marfa if egress::Millston.Ramos.$valid - # - bit[14]: egress::Millston.Ramos.Palatine if egress::Millston.Ramos.$valid - # - bit[13]: egress::Millston.Ramos.Mabelle if egress::Millston.Ramos.$valid - # - bit[12..0]: egress::Millston.Ramos.Hoagland if egress::Millston.Ramos.$valid - TH6: W23(4) - # - bit[15..8]: egress::Millston.Ramos.Exton if egress::Millston.Ramos.$valid - # - bit[7..0]: egress::Millston.Ramos.Ocoee if egress::Millston.Ramos.$valid - checksum 1: W23(4) # egress::Millston.Ramos.$valid - TW10: W23(4) # egress::Millston.Ramos.Kaluaaha if egress::Millston.Ramos.$valid - TW11: W23(4) # egress::Millston.Ramos.Calcasieu if egress::Millston.Ramos.$valid - H82: H74(1) - # - bit[15..12]: egress::Millston.Provencal.Fayette if egress::Millston.Provencal.$valid - # - bit[11..6]: egress::Millston.Provencal.PineCity if egress::Millston.Provencal.$valid - # - bit[5..4]: egress::Millston.Provencal.Alameda if egress::Millston.Provencal.$valid - # - bit[3..0]: egress::Millston.Provencal.Maryhill.16-19 if egress::Millston.Provencal.$valid - TH30: H74(1) # egress::Millston.Provencal.Maryhill.0-15 if egress::Millston.Provencal.$valid - TW4: H74(1) - # - bit[31..16]: egress::Millston.Provencal.Norwood if egress::Millston.Provencal.$valid - # - bit[15..8]: egress::Millston.Provencal.Dassel if egress::Millston.Provencal.$valid - # - bit[7..0]: egress::Millston.Provencal.Bushland if egress::Millston.Provencal.$valid - TH16: H74(1) # egress::Millston.Provencal.Kaluaaha.112-127 if egress::Millston.Provencal.$valid - TH15: H74(1) # egress::Millston.Provencal.Kaluaaha.96-111 if egress::Millston.Provencal.$valid - TH6: H74(1) # egress::Millston.Provencal.Kaluaaha.80-95 if egress::Millston.Provencal.$valid - TB7: H74(1) # egress::Millston.Provencal.Kaluaaha.72-79 if egress::Millston.Provencal.$valid - TB6: H74(1) # egress::Millston.Provencal.Kaluaaha.64-71 if egress::Millston.Provencal.$valid - TW11: H74(1) # egress::Millston.Provencal.Kaluaaha.32-63 if egress::Millston.Provencal.$valid - TW10: H74(1) # egress::Millston.Provencal.Kaluaaha.0-31 if egress::Millston.Provencal.$valid - TW22: H74(1) # egress::Millston.Provencal.Calcasieu.96-127 if egress::Millston.Provencal.$valid - TW21: H74(1) # egress::Millston.Provencal.Calcasieu.64-95 if egress::Millston.Provencal.$valid - TW20: H74(1) # egress::Millston.Provencal.Calcasieu.32-63 if egress::Millston.Provencal.$valid - TH17: H74(1) # egress::Millston.Provencal.Calcasieu.16-31 if egress::Millston.Provencal.$valid - TB9: H74(1) # egress::Millston.Provencal.Calcasieu.8-15 if egress::Millston.Provencal.$valid - TB8: H74(1) # egress::Millston.Provencal.Calcasieu.0-7 if egress::Millston.Provencal.$valid - TH8: W23(5) # egress::Millston.Bergton.Chevak if egress::Millston.Bergton.$valid - TH7: W23(5) # egress::Millston.Bergton.Mendocino if egress::Millston.Bergton.$valid - TH12: H74(0) # egress::Millston.Cassa.Chloride.16-31 if egress::Millston.Cassa.$valid - TH11: H74(0) # egress::Millston.Cassa.Chloride.0-15 if egress::Millston.Cassa.$valid - TH14: H74(0) # egress::Millston.Cassa.Garibaldi.16-31 if egress::Millston.Cassa.$valid - TH13: H74(0) # egress::Millston.Cassa.Garibaldi.0-15 if egress::Millston.Cassa.$valid - TW6: H74(0) - # - bit[31..28]: egress::Millston.Cassa.Weinert if egress::Millston.Cassa.$valid - # - bit[27..24]: egress::Millston.Cassa.Cornell if egress::Millston.Cassa.$valid - # - bit[23..16]: egress::Millston.Cassa.Noyes if egress::Millston.Cassa.$valid - # - bit[15..0]: egress::Millston.Cassa.Helton if egress::Millston.Cassa.$valid - TH11: W23(6) # egress::Millston.Pawtucket.StarLake if egress::Millston.Pawtucket.$valid - TH31: W23(7) # egress::Millston.Buckhorn.SoapLake if egress::Millston.Buckhorn.$valid - TW6: W23(2) - # - bit[31..16]: egress::Millston.Rainelle.Conner if egress::Millston.Rainelle.$valid - # - bit[15..0]: egress::Millston.Rainelle.Ledoux if egress::Millston.Rainelle.$valid - TW4: W23(2) - # - bit[31..24]: egress::Millston.Rainelle.Steger if egress::Millston.Rainelle.$valid - # - bit[23..16]: egress::Millston.Rainelle.Quogue if egress::Millston.Rainelle.$valid - # - bit[15..0]: egress::Millston.Rainelle.Findlay if egress::Millston.Rainelle.$valid - checksum 0: - - H81: { } - # - bit[15..12]: egress::Millston.GlenAvon.Fayette - # - bit[11..8]: egress::Millston.GlenAvon.Osterdock - # - bit[7..2]: egress::Millston.GlenAvon.PineCity - # - bit[1..0]: egress::Millston.GlenAvon.Alameda - - H18: { } # egress::Millston.GlenAvon.Rexville - - W16: { } - # - bit[31..16]: egress::Millston.GlenAvon.Quinwood - # - bit[15]: egress::Millston.GlenAvon.Marfa - # - bit[14]: egress::Millston.GlenAvon.Palatine - # - bit[13]: egress::Millston.GlenAvon.Mabelle - # - bit[12..0]: egress::Millston.GlenAvon.Hoagland - - B16: { swap: 1 } # egress::Millston.GlenAvon.Exton - - B23: { } # egress::Millston.GlenAvon.Ocoee - - W17: { } # egress::Millston.GlenAvon.Kaluaaha - - W18: { } # egress::Millston.GlenAvon.Calcasieu - checksum 1: - - H82: { } - # - bit[15..12]: egress::Millston.Ramos.Fayette - # - bit[11..8]: egress::Millston.Ramos.Osterdock - # - bit[7..2]: egress::Millston.Ramos.PineCity - # - bit[1..0]: egress::Millston.Ramos.Alameda - - TH15: { } # egress::Millston.Ramos.Rexville - - TW4: { } - # - bit[31..16]: egress::Millston.Ramos.Quinwood - # - bit[15]: egress::Millston.Ramos.Marfa - # - bit[14]: egress::Millston.Ramos.Palatine - # - bit[13]: egress::Millston.Ramos.Mabelle - # - bit[12..0]: egress::Millston.Ramos.Hoagland - - TH6: { } - # - bit[15..8]: egress::Millston.Ramos.Exton - # - bit[7..0]: egress::Millston.Ramos.Ocoee - - TW10: { } # egress::Millston.Ramos.Kaluaaha - - TW11: { } # egress::Millston.Ramos.Calcasieu - drop_ctl: B20(0..2) # bit[2..0]: egress::eg_intr_md_for_dprsr.drop_ctl - egress_unicast_port: H16(0..8) # bit[8..0]: egress::eg_intr_md.egress_port - mirror: - select: B17(0..2) # bit[2..0]: egress::eg_intr_md_for_dprsr.mirror_type - 2: - - H19(0..9) # bit[9..0]: egress::HillTop.McCaskill.Grassflat - - B25 # egress::HillTop.Plains.Roachdale - - H17(0..8) # bit[8..0]: egress::HillTop.Plains.Miller -stage 0 ingress: - phase0_match Thaxton.$PORT_METADATA: - p4: - name: Thaxton.$PORT_METADATA - size: 288 - preferred_match_type: exact - match_type: exact - size: 288 - p4_param_order: - Tiburon.ingress_port: { type: exact, size: 9 } - format: {Fristoe: 48..61, Traverse: 32..43, Pachuta: 24..24, Sopris: 16..17} - constant_value: 0 - actions: - set_port_metadata: - - handle: 0x20000000 - - p4_param_order: { Fristoe: 14, Traverse: 12, Pachuta: 1, Sopris: 2 } - ternary_match Rotonda_0 0: - p4: { name: Rotonda, size: 2, disable_atomic_modify : true } - p4_param_order: - Millston.Ramos.$valid: { type: exact, size: 1, full_size: 1, key_name: "Ramos" } - Millston.Provencal.$valid: { type: exact, size: 1, full_size: 1, key_name: "Provencal" } - row: 11 - bus: 1 - column: 1 - hash_dist: - 0: { hash: 0, mask: 0xffff, shift: 0 } - 1: { hash: 0, mask: 0xffff, shift: 0 } - input_xbar: - ternary group 0: { 2: Millston.Provencal.$valid, 13: Millston.Ramos.$valid } - exact group 0: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.Maddock.Kaluaaha, 64: HillTop.Aldan.Vinemont } - hash 0: - 0..15: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 72, { 8: HillTop.Maddock.Calcasieu, 40: HillTop.Maddock.Kaluaaha }, { })), 0..15) - hash 1: - 0..15: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 72, { 0: HillTop.Aldan.Vinemont }, { })), 0..15) - hash group 0: - table: [0, 1] - seed: 0x0 - exact group 0: { 0: HillTop.Sublett.Calcasieu.96-127, 32: HillTop.Sublett.Kaluaaha.0-31, 64: HillTop.Aldan.Vinemont, 72: HillTop.Sublett.Kaluaaha.32-63(8..31), 96: HillTop.Sublett.Kaluaaha.32-63(0..7), 104: HillTop.Sublett.Kaluaaha.64-95(8..31) } - exact group 1: { 0: HillTop.Sublett.Kaluaaha.64-95(0..7), 8: HillTop.Sublett.Kaluaaha.96-127(8..31), 32: HillTop.Sublett.Kaluaaha.96-127(0..7), 40: HillTop.Sublett.Calcasieu.0-31(8..31), 64: HillTop.Sublett.Calcasieu.0-31(0..7), 72: HillTop.Sublett.Calcasieu.32-63(8..31), 96: HillTop.Sublett.Calcasieu.32-63(0..7), 104: HillTop.Sublett.Calcasieu.64-95(8..31) } - exact group 2: { 0: HillTop.Sublett.Calcasieu.64-95(0..7), 8: Millston.Provencal.Maryhill.8-19(8..11), 16: Millston.Provencal.Maryhill.8-19(0..7), 24: Millston.Provencal.Maryhill.0-7 } - hash 0: - 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 124: HillTop.Sublett.Calcasieu.96-127, 156: HillTop.Sublett.Kaluaaha.0-31 }, { })), 0..15) - hash 1: - 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 0: HillTop.Aldan.Vinemont, 188: HillTop.Sublett.Kaluaaha.32-63(0..7), 196: HillTop.Sublett.Kaluaaha.32-63(8..31), 228: HillTop.Sublett.Kaluaaha.64-95(8..31) }, { })), 0..15) - hash 2: - 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 36: HillTop.Sublett.Calcasieu.0-31(8..31), 220: HillTop.Sublett.Kaluaaha.64-95(0..7), 252: HillTop.Sublett.Kaluaaha.96-127(0..7), 260: HillTop.Sublett.Kaluaaha.96-127(8..31) }, { })), 0..15) - hash 3: - 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 28: HillTop.Sublett.Calcasieu.0-31(0..7), 60: HillTop.Sublett.Calcasieu.32-63(0..7), 68: HillTop.Sublett.Calcasieu.32-63(8..31), 100: HillTop.Sublett.Calcasieu.64-95(8..31) }, { })), 0..15) - hash 4: - 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 8: Millston.Provencal.Maryhill.0-7, 16: Millston.Provencal.Maryhill.8-19(0..7), 24: Millston.Provencal.Maryhill.8-19(8..11), 92: HillTop.Sublett.Calcasieu.64-95(0..7) }, { })), 0..15) - hash group 0: - table: [0, 1, 2, 3, 4] - seed: 0x0 - match: - - { group: 0, byte_config: 3, dirtcam: 0x5 } - hit: [ _Cheyenne ] - miss: _Cheyenne - indirect: Rotonda_0$tind - ternary_indirect Rotonda_0$tind: - row: 4 - bus: 0 - column: 5 - hash_dist: - 0: { hash: 0, mask: 0xffff, shift: 0 } - 1: { hash: 0, mask: 0xffff, shift: 0 } - input_xbar: - ternary group 0: { 2: Millston.Provencal.$valid, 13: Millston.Ramos.$valid } - exact group 0: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.Maddock.Kaluaaha, 64: HillTop.Aldan.Vinemont } - hash 0: - 0..15: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 72, { 8: HillTop.Maddock.Calcasieu, 40: HillTop.Maddock.Kaluaaha }, { })), 0..15) - hash 1: - 0..15: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 72, { 0: HillTop.Aldan.Vinemont }, { })), 0..15) - hash group 0: - table: [0, 1] - seed: 0x0 - exact group 0: { 0: HillTop.Sublett.Calcasieu.96-127, 32: HillTop.Sublett.Kaluaaha.0-31, 64: HillTop.Aldan.Vinemont, 72: HillTop.Sublett.Kaluaaha.32-63(8..31), 96: HillTop.Sublett.Kaluaaha.32-63(0..7), 104: HillTop.Sublett.Kaluaaha.64-95(8..31) } - exact group 1: { 0: HillTop.Sublett.Kaluaaha.64-95(0..7), 8: HillTop.Sublett.Kaluaaha.96-127(8..31), 32: HillTop.Sublett.Kaluaaha.96-127(0..7), 40: HillTop.Sublett.Calcasieu.0-31(8..31), 64: HillTop.Sublett.Calcasieu.0-31(0..7), 72: HillTop.Sublett.Calcasieu.32-63(8..31), 96: HillTop.Sublett.Calcasieu.32-63(0..7), 104: HillTop.Sublett.Calcasieu.64-95(8..31) } - exact group 2: { 0: HillTop.Sublett.Calcasieu.64-95(0..7), 8: Millston.Provencal.Maryhill.8-19(8..11), 16: Millston.Provencal.Maryhill.8-19(0..7), 24: Millston.Provencal.Maryhill.0-7 } - hash 0: - 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 124: HillTop.Sublett.Calcasieu.96-127, 156: HillTop.Sublett.Kaluaaha.0-31 }, { })), 0..15) - hash 1: - 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 0: HillTop.Aldan.Vinemont, 188: HillTop.Sublett.Kaluaaha.32-63(0..7), 196: HillTop.Sublett.Kaluaaha.32-63(8..31), 228: HillTop.Sublett.Kaluaaha.64-95(8..31) }, { })), 0..15) - hash 2: - 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 36: HillTop.Sublett.Calcasieu.0-31(8..31), 220: HillTop.Sublett.Kaluaaha.64-95(0..7), 252: HillTop.Sublett.Kaluaaha.96-127(0..7), 260: HillTop.Sublett.Kaluaaha.96-127(8..31) }, { })), 0..15) - hash 3: - 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 28: HillTop.Sublett.Calcasieu.0-31(0..7), 60: HillTop.Sublett.Calcasieu.32-63(0..7), 68: HillTop.Sublett.Calcasieu.32-63(8..31), 100: HillTop.Sublett.Calcasieu.64-95(8..31) }, { })), 0..15) - hash 4: - 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 8: Millston.Provencal.Maryhill.0-7, 16: Millston.Provencal.Maryhill.8-19(0..7), 24: Millston.Provencal.Maryhill.8-19(8..11), 92: HillTop.Sublett.Calcasieu.64-95(0..7) }, { })), 0..15) - hash group 0: - table: [0, 1, 2, 3, 4] - seed: 0x0 - format: { action: 0..0 } - action_bus: { 64..65 : hash_dist(0, lo), 66..67 : hash_dist(1, hi) } - instruction: Rotonda_0$tind(action, $DEFAULT) - actions: - Kinard(0, 1): - - default_action: { allowed: true } - - handle: 0x20000001 - - next_table: 0 - - set H60, hash_dist(0, 0..15) - Pendleton(1, 2): - - default_action: { allowed: true } - - handle: 0x20000002 - - next_table: 0 - - set H60, hash_dist(1, 0..15) - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x20000003 - - next_table: 0 - default_only_action: NoAction - ternary_match _Cheyenne 1: - p4: { name: Cheyenne, size: 512, disable_atomic_modify : true } - p4_param_order: - Millston.Calabash.Adona: { type: ternary, size: 24, full_size: 24, key_name: "Calabash.Adona" } - Millston.Calabash.Connell: { type: ternary, size: 24, full_size: 24, key_name: "Calabash.Connell" } - Millston.GlenAvon.Calcasieu: { type: ternary, size: 32, full_size: 32, key_name: "GlenAvon.Calcasieu" } - Millston.Maumee.Calcasieu: { type: ternary, size: 128, full_size: 128, key_name: "Maumee.Calcasieu" } - HillTop.RossFork.Joslin: { type: ternary, size: 3, full_size: 3, key_name: "RossFork.Joslin" } - Millston.Maumee.$valid: { type: exact, size: 1, full_size: 1, key_name: "Maumee" } - row: [ 0, 1, 2, 3, 4 ] - bus: [ 0, 0, 0, 0, 0 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - input_xbar: - ternary group 1: { 0: Millston.Calabash.Adona(8..15), 8: Millston.Maumee.Calcasieu.96-127(24..31), 16: Millston.Maumee.Calcasieu.96-127(0..7), 24: Millston.Calabash.Adona(0..7), 32: Millston.Maumee.Calcasieu.96-127(16..23) } - ternary group 2: { 0: Millston.Maumee.Calcasieu.0-31(24..31), 8: Millston.Maumee.Calcasieu.0-31(0..23), 32: Millston.Maumee.Calcasieu.32-63(24..31) } - ternary group 3: { 0: Millston.Maumee.Calcasieu.96-127(8..15), 8: Millston.GlenAvon.Calcasieu(16..31), 24: Millston.GlenAvon.Calcasieu(0..15) } - ternary group 4: { 0: Millston.Maumee.Calcasieu.32-63(16..23), 8: Millston.Maumee.Calcasieu.64-95(24..31), 16: Millston.Maumee.Calcasieu.32-63(0..15), 32: Millston.Maumee.Calcasieu.64-95(16..23) } - ternary group 5: { 0: Millston.Maumee.Calcasieu.64-95(0..15), 21: HillTop.RossFork.Joslin, 24: Millston.Calabash.Connell.0-15(8..15), 32: Millston.Calabash.Connell.0-15(0..7) } - byte group 0: { 2: Millston.Maumee.$valid } - byte group 1: { 0: Millston.Calabash.Connell.16-23 } - byte group 2: { 0: Millston.Calabash.Adona(16..23) } - match: - - { group: 1, byte_group: 1, byte_config: 0, dirtcam: 0x555 } - - { group: 2, byte_group: 1, byte_config: 1, dirtcam: 0x555 } - - { group: 3, byte_group: 2, byte_config: 0, dirtcam: 0x555 } - - { group: 4, byte_group: 2, byte_config: 1, dirtcam: 0x555 } - - { group: 5, byte_group: 0, byte_config: 0, dirtcam: 0x555 } - hit: [ _Pacifica ] - miss: _Pacifica - indirect: _Cheyenne$tind - ternary_indirect _Cheyenne$tind: - row: 3 - bus: 0 - column: 5 - input_xbar: - ternary group 1: { 0: Millston.Calabash.Adona(8..15), 8: Millston.Maumee.Calcasieu.96-127(24..31), 16: Millston.Maumee.Calcasieu.96-127(0..7), 24: Millston.Calabash.Adona(0..7), 32: Millston.Maumee.Calcasieu.96-127(16..23) } - ternary group 2: { 0: Millston.Maumee.Calcasieu.0-31(24..31), 8: Millston.Maumee.Calcasieu.0-31(0..23), 32: Millston.Maumee.Calcasieu.32-63(24..31) } - ternary group 3: { 0: Millston.Maumee.Calcasieu.96-127(8..15), 8: Millston.GlenAvon.Calcasieu(16..31), 24: Millston.GlenAvon.Calcasieu(0..15) } - ternary group 4: { 0: Millston.Maumee.Calcasieu.32-63(16..23), 8: Millston.Maumee.Calcasieu.64-95(24..31), 16: Millston.Maumee.Calcasieu.32-63(0..15), 32: Millston.Maumee.Calcasieu.64-95(16..23) } - ternary group 5: { 0: Millston.Maumee.Calcasieu.64-95(0..15), 21: HillTop.RossFork.Joslin, 24: Millston.Calabash.Connell.0-15(8..15), 32: Millston.Calabash.Connell.0-15(0..7) } - byte group 0: { 2: Millston.Maumee.$valid } - byte group 1: { 0: Millston.Calabash.Connell.16-23 } - byte group 2: { 0: Millston.Calabash.Adona(16..23) } - format: { action: 0..0 } - instruction: _Cheyenne$tind(action, $DEFAULT) - actions: - Aguila(0, 3): - - default_action: { allowed: true } - - handle: 0x20000013 - - next_table: 0 - - set HillTop.Wisdom.Onycha, 5 - - set HillTop.RossFork.Adona, Millston.Calabash.Adona - - set HillTop.RossFork.Connell.0-15, Millston.Calabash.Connell.0-15 - - set HillTop.RossFork.Connell.16-23, Millston.Calabash.Connell.16-23 - - set HillTop.RossFork.Goldsboro.0-7, Millston.Calabash.Goldsboro.0-7 - - set HillTop.RossFork.Goldsboro.8-23, Millston.Calabash.Goldsboro.8-23 - - set HillTop.RossFork.Fabens, Millston.Calabash.Fabens - - set Millston.Calabash.McCaulley.0-7, HillTop.RossFork.McCaulley.0-7 - - set Millston.Calabash.McCaulley.8-15, HillTop.RossFork.McCaulley.8-15 - - set HillTop.Edwards.Oriskany, 0 - - set HillTop.RossFork.Denhoff.0-0, HillTop.Aldan.Kearns.0-0 - - set HillTop.RossFork.Denhoff.1-2, HillTop.Aldan.Kearns.1-2 - - set HillTop.RossFork.Ocoee, HillTop.Aldan.Vinemont - - set HillTop.RossFork.Exton, HillTop.Aldan.Kenbridge - - set HillTop.RossFork.Naruna.0-1, HillTop.Aldan.Mystic.0-1 - - set HillTop.RossFork.Naruna.2-2, HillTop.Aldan.Mystic.2-2 - - set HillTop.Bessie.Chevak, HillTop.RossFork.Chevak - - set HillTop.Bessie.Peebles, HillTop.Aldan.Kearns.0-0 - - or H63, H48, H63 - Kapowsin(1, 4): - - default_action: { allowed: true } - - handle: 0x20000014 - - next_table: 0 - - set HillTop.Wisdom.Onycha, 0 - - set HillTop.Edwards.Oriskany, Millston.Wondervu$0.Oriskany - - set HillTop.RossFork.ElVerano, Millston.Wondervu$0.$valid - - set HillTop.RossFork.Joslin, 0 - - set HillTop.RossFork.Adona, Millston.Calabash.Adona - - set HillTop.RossFork.Connell.0-15, Millston.Calabash.Connell.0-15 - - set HillTop.RossFork.Connell.16-23, Millston.Calabash.Connell.16-23 - - set HillTop.RossFork.Goldsboro.0-7, Millston.Calabash.Goldsboro.0-7 - - set HillTop.RossFork.Goldsboro.8-23, Millston.Calabash.Goldsboro.8-23 - - set HillTop.RossFork.Fabens, Millston.Calabash.Fabens - - set HillTop.RossFork.Naruna.0-1, HillTop.Aldan.Parkville(0..1) - - set HillTop.RossFork.Naruna.2-2, HillTop.Aldan.Parkville(2..2) - - set HillTop.RossFork.McCaulley.0-7, Millston.Calabash.McCaulley.0-7 - - set HillTop.RossFork.McCaulley.8-15, Millston.Calabash.McCaulley.8-15 - - set HillTop.Sublett.Kaluaaha.0-31, Millston.Maumee.Kaluaaha.0-31 - - set HillTop.Sublett.Kaluaaha.32-63, Millston.Maumee.Kaluaaha.32-63 - - set HillTop.Sublett.Kaluaaha.64-95, Millston.Maumee.Kaluaaha.64-95 - - set HillTop.Sublett.Kaluaaha.96-127, Millston.Maumee.Kaluaaha.96-127 - - set HillTop.Sublett.Calcasieu.0-31, Millston.Maumee.Calcasieu.0-31 - - set HillTop.Sublett.Calcasieu.32-63, Millston.Maumee.Calcasieu.32-63 - - set HillTop.Sublett.Calcasieu.64-95, Millston.Maumee.Calcasieu.64-95 - - set HillTop.Sublett.Calcasieu.96-127, Millston.Maumee.Calcasieu.96-127 - - set HillTop.Sublett.PineCity, Millston.Maumee.PineCity - - set HillTop.RossFork.Ocoee, Millston.Maumee.Dassel - - set HillTop.RossFork.Chevak, Millston.Grays.Chevak - - set HillTop.RossFork.Mendocino, Millston.Grays.Mendocino - - set HillTop.RossFork.Kremlin, Millston.Osyka.Noyes - - set HillTop.RossFork.Denhoff.0-0, HillTop.Aldan.Malinta.0-0 - - set HillTop.RossFork.Denhoff.1-2, HillTop.Aldan.Malinta.1-2 - - set HillTop.RossFork.Glenmora, Millston.Grays.Chevak - - set HillTop.RossFork.DonaAna, Millston.Grays.Mendocino - - set HillTop.Bessie.Chevak, Millston.Grays.Chevak - - set HillTop.Bessie.Peebles, HillTop.Aldan.Malinta.0-0 - Crown(-1, 6): - - default_only_action: { allowed: true } - - handle: 0x20000015 - - next_table: 0 - - set HillTop.Wisdom.Onycha, 0 - - set HillTop.Edwards.Oriskany, Millston.Wondervu$0.Oriskany - - set HillTop.RossFork.ElVerano, Millston.Wondervu$0.$valid - - set HillTop.RossFork.Joslin, 0 - - set HillTop.RossFork.Adona, Millston.Calabash.Adona - - set HillTop.RossFork.Connell.0-15, Millston.Calabash.Connell.0-15 - - set HillTop.RossFork.Connell.16-23, Millston.Calabash.Connell.16-23 - - set HillTop.RossFork.Goldsboro.0-7, Millston.Calabash.Goldsboro.0-7 - - set HillTop.RossFork.Goldsboro.8-23, Millston.Calabash.Goldsboro.8-23 - - set HillTop.RossFork.Fabens, Millston.Calabash.Fabens - - set HillTop.RossFork.Naruna.0-1, HillTop.Aldan.Parkville(0..1) - - set HillTop.RossFork.Naruna.2-2, HillTop.Aldan.Parkville(2..2) - - set HillTop.RossFork.McCaulley.0-7, Millston.Calabash.McCaulley.0-7 - - set HillTop.RossFork.McCaulley.8-15, Millston.Calabash.McCaulley.8-15 - - set HillTop.Maddock.Kaluaaha, Millston.GlenAvon.Kaluaaha - - set HillTop.Maddock.Calcasieu, Millston.GlenAvon.Calcasieu - - set HillTop.Maddock.PineCity, Millston.GlenAvon.PineCity - - set HillTop.RossFork.Ocoee, Millston.GlenAvon.Ocoee - - set HillTop.RossFork.Chevak, Millston.Grays.Chevak - - set HillTop.RossFork.Mendocino, Millston.Grays.Mendocino - - set HillTop.RossFork.Kremlin, Millston.Osyka.Noyes - - set HillTop.RossFork.Denhoff.0-0, HillTop.Aldan.Malinta.0-0 - - set HillTop.RossFork.Denhoff.1-2, HillTop.Aldan.Malinta.1-2 - - set HillTop.RossFork.Glenmora, Millston.Grays.Chevak - - set HillTop.RossFork.DonaAna, Millston.Grays.Mendocino - - set HillTop.Bessie.Chevak, Millston.Grays.Chevak - - set HillTop.Bessie.Peebles, HillTop.Aldan.Malinta.0-0 - default_only_action: Crown - ternary_match _Pacifica 2: - p4: { name: Pacifica, size: 3072, disable_atomic_modify : true } - p4_param_order: - HillTop.Lamona.Pachuta: { type: exact, size: 1, full_size: 1, key_name: "Lamona.Pachuta" } - HillTop.Lamona.Fristoe: { type: exact, size: 14, full_size: 14, key_name: "Lamona.Fristoe" } - Millston.Wondervu$0.$valid: { type: exact, size: 1, full_size: 1, key_name: "Wondervu$0" } - Millston.Wondervu$0.Bowden: { type: ternary, size: 12, full_size: 12, key_name: "Wondervu$0.Bowden" } - row: [ 2, 3, 4, 5, 6, 7 ] - bus: [ 1, 1, 1, 1, 1, 1 ] - column: - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - input_xbar: - ternary group 6: { 0: HillTop.Lamona.Fristoe, 17: Millston.Wondervu$0.$valid, 24: Millston.Wondervu$0.Bowden(0..7), 32: HillTop.Lamona.Pachuta } - byte group 4: { 0: Millston.Wondervu$0.Bowden(8..11) } - match: - - { group: 6, byte_group: 4, byte_config: 0, dirtcam: 0x555 } - hit: [ _Mogadore ] - miss: _Mogadore - indirect: _Pacifica$tind - ternary_indirect _Pacifica$tind: - row: 0 - bus: 0 - column: [ 2, 3 ] - input_xbar: - ternary group 6: { 0: HillTop.Lamona.Fristoe, 17: Millston.Wondervu$0.$valid, 24: Millston.Wondervu$0.Bowden(0..7), 32: HillTop.Lamona.Pachuta } - byte group 4: { 0: Millston.Wondervu$0.Bowden(8..11) } - format: { action: 0..1, immediate: 2..33 } - action_bus: { 34..35 : immediate(16..31), 96..99 : immediate(0..31) } - instruction: _Pacifica$tind(action, $DEFAULT) - actions: - Vanoss(0, 5): - - p4_param_order: { Potosi: 20 } - - default_action: { allowed: true } - - handle: 0x20000016 - - next_table: 0 - - { Potosi: immediate(0..19) } - - set HillTop.RossFork.CeeVee, HillTop.Lamona.Traverse - - set HillTop.RossFork.Quebrada, Potosi - Mulvane(1, 7): - - p4_param_order: { Luning: 12, Potosi: 20 } - - default_action: { allowed: true } - - handle: 0x20000017 - - next_table: 0 - - { Potosi: immediate(0..19), Luning: immediate(20..31) } - - set HillTop.RossFork.CeeVee, Luning - - set HillTop.RossFork.Quebrada, Potosi - - set HillTop.Lamona.Pachuta, 1 - Flippen(2, 8): - - p4_param_order: { Potosi: 20 } - - default_action: { allowed: true } - - handle: 0x20000018 - - next_table: 0 - - { Potosi: immediate(0..19) } - - set HillTop.RossFork.CeeVee, Millston.Wondervu$0.Bowden - - set HillTop.RossFork.Quebrada, Potosi - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x20000019 - - next_table: 0 - - { } - default_only_action: NoAction - exact_match _Mogadore 3: - p4: { name: Mogadore, size: 1024, disable_atomic_modify : true } - p4_param_order: - HillTop.Lamona.Fristoe: { type: exact, size: 14, full_size: 14, key_name: "Lamona.Fristoe" } - Millston.Wondervu$0.Bowden: { type: exact, size: 12, full_size: 12, key_name: "Wondervu$0.Bowden" } - row: [ 2, 1 ] - bus: [ 1, 0 ] - column: - - 6 - - [ 2, 3, 4 ] - stash: - row: [ 2 ] - col: [ 6 ] - unit: [ 1 ] - ways: - - [1, 0, 0x0, [2, 6]] - - [1, 1, 0x0, [1, 2]] - - [1, 2, 0x0, [1, 3]] - - [1, 3, 0x0, [1, 4]] - input_xbar: - exact group 2: { 64: Millston.Wondervu$0.Bowden(0..7), 72: HillTop.Lamona.Fristoe, 88: Millston.Wondervu$0.Bowden(8..11) } - hash 5: - 0..5: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ HillTop.Lamona.Fristoe(8..13) - 6..9: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ Millston.Wondervu$0.Bowden(8..11) - 11..16: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ HillTop.Lamona.Fristoe(8..13) - 17..19: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ Millston.Wondervu$0.Bowden(8..10) - 10: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ Millston.Wondervu$0.Bowden(11) - 22..27: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ HillTop.Lamona.Fristoe(8..13) - 28..29: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ Millston.Wondervu$0.Bowden(8..9) - 20..21: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ Millston.Wondervu$0.Bowden(10..11) - 33..38: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ HillTop.Lamona.Fristoe(8..13) - 39: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ Millston.Wondervu$0.Bowden(8) - 30..32: random(Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7)) ^ Millston.Wondervu$0.Bowden(9..11) - hash group 1: - table: [5] - seed: 0x73aa5b9aca - format: { action(0): 0..0, immediate(0): 1..28, version(0): 112..115, match(0): 32..47 } - match: [ Millston.Wondervu$0.Bowden(0..7), HillTop.Lamona.Fristoe(0..7) ] - gateway: - name: cond-2 - input_xbar: - exact group 2: { 64: Millston.Wondervu$0.Bowden(0..7), 88: Millston.Wondervu$0.Bowden(8..11), 97: Millston.Wondervu$0.$valid } - row: 2 - bus: 1 - unit: 1 - match: { 17: Millston.Wondervu$0.$valid, 0: Millston.Wondervu$0.Bowden(0..7), 8: Millston.Wondervu$0.Bowden(8..11) } - 0b******0*****************: _Judson - 0x***000: _Judson - miss: run_table - condition: - expression: "(Millston.Wondervu[0].$valid == 1 && Millston.Wondervu[0].Bowden != 0)" - true: _Mogadore - false: _Judson - hit: [ [], _Florahome ] - miss: _Florahome - action_bus: { 68..69 : immediate(0..15), 70..71 : immediate(16..27) } - action: _Mogadore$action_data($DIRECT, $DEFAULT) - instruction: _Mogadore(action, $DEFAULT) - actions: - Micro(1, 9): - - p4_param_order: { Luning: 12, Boring: 32, Manilla: 8, Hammond: 4, Panaca: 16 } - - default_action: { allowed: true } - - handle: 0x2000001c - - next_table: 1 - - { Manilla: $adf_b0(0..7), Luning: immediate(0..11), $data0: immediate(16..27), Panaca.0-7: $data0(0..7), Hammond.1-3: $data0(8..10), Hammond.0-0: $data0(11..11) } - - set HillTop.RossFork.Bicknell, Luning - - set HillTop.Ovett.Manilla, Manilla - - set H14(0..11), $data0 - Sequim(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x2000001d - - next_table_miss: _Westview - - { } - default_only_action: Sequim - action _Mogadore$action_data: - p4: { name: Mogadore$action } - row: 5 - column: 1 - vpns: [ 0 ] - home_row: - - 5 - format Micro: { $adf_b0: 0..7 } - action_bus: { 0 : $adf_b0 } - exact_match _Judson 5: - p4: { name: Judson, size: 4096, disable_atomic_modify : true } - p4_param_order: - HillTop.Lamona.Traverse: { type: exact, size: 12, full_size: 12, key_name: "Lamona.Traverse" } - row: 6 - bus: 1 - column: [ 4, 6 ] - stash: - row: [ 6 ] - col: [ 4 ] - unit: [ 0 ] - ways: - - [2, 1, 0x2, [6, 4], [6, 6]] - input_xbar: - exact group 3: { 16: HillTop.Lamona.Traverse } - hash 6: - 10..16: random(HillTop.Lamona.Traverse(7)) ^ HillTop.Lamona.Traverse(0..6) - 17..19: random(HillTop.Lamona.Traverse(7)) ^ HillTop.Lamona.Traverse(8..10) - 41: random(HillTop.Lamona.Traverse(7)) ^ HillTop.Lamona.Traverse(11) - hash group 2: - table: [6] - seed: 0xc7c00 - format: { immediate(0): 0..23, version(0): 112..115, match(0): 55..55, immediate(1): 24..47, version(1): 116..119, match(1): 63..63 } - match: [ HillTop.Lamona.Traverse(7) ] - hit: [ _Florahome ] - miss: _Florahome - action_bus: { 6 : immediate(16..23), 36..37 : immediate(0..15) } - instruction: _Judson($DEFAULT, $DEFAULT) - actions: - Tillson(0, 12): - - p4_param_order: { Boring: 32, Manilla: 8, Hammond: 4, Panaca: 16 } - - default_action: { allowed: true } - - handle: 0x2000001a - - next_table: 0 - - { $data0: immediate(0..11), Panaca.0-7: $data0(0..7), Hammond.1-3: $data0(8..10), Hammond.0-0: $data0(11..11), Manilla: immediate(16..23) } - - set HillTop.RossFork.Bicknell, HillTop.Lamona.Traverse - - set HillTop.Ovett.Manilla, Manilla - - set H14(0..11), $data0 - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x2000001b - - next_table: 0 - - { } - default_only_action: NoAction - exact_match _Westview 4: - p4: { name: Westview, size: 4096, disable_atomic_modify : true } - p4_param_order: - Millston.Wondervu$0.Bowden: { type: exact, size: 12, full_size: 12, key_name: "Wondervu$0.Bowden" } - row: 6 - bus: 0 - column: [ 2, 3 ] - stash: - row: [ 6 ] - col: [ 2 ] - unit: [ 1 ] - ways: - - [2, 0, 0x1, [6, 2], [6, 3]] - input_xbar: - exact group 3: { 0: Millston.Wondervu$0.Bowden } - hash 6: - 0..6: random(Millston.Wondervu$0.Bowden(7)) ^ Millston.Wondervu$0.Bowden(0..6) - 7..9: random(Millston.Wondervu$0.Bowden(7)) ^ Millston.Wondervu$0.Bowden(8..10) - 40: random(Millston.Wondervu$0.Bowden(7)) ^ Millston.Wondervu$0.Bowden(11) - hash group 2: - table: [6] - seed: 0x182 - format: { immediate(0): 0..23, version(0): 112..115, match(0): 55..55, immediate(1): 24..47, version(1): 116..119, match(1): 63..63 } - match: [ Millston.Wondervu$0.Bowden(7) ] - hit: [ _Florahome ] - miss: _Florahome - action_bus: { 2 : immediate(16..23), 32..33 : immediate(0..15) } - instruction: _Westview($DEFAULT, $DEFAULT) - actions: - Lattimore(0, 10): - - p4_param_order: { Boring: 32, Manilla: 8, Hammond: 4, Panaca: 16 } - - default_action: { allowed: true } - - handle: 0x2000001e - - next_table: 0 - - { $data0: immediate(0..11), Panaca.0-7: $data0(0..7), Hammond.1-3: $data0(8..10), Hammond.0-0: $data0(11..11), Manilla: immediate(16..23) } - - set HillTop.RossFork.Bicknell, Millston.Wondervu$0.Bowden - - set HillTop.Ovett.Manilla, Manilla - - set H14(0..11), $data0 - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x2000001f - - next_table: 0 - - { } - default_only_action: NoAction - ternary_match _Florahome 6: - p4: { name: Florahome, size: 2048, disable_atomic_modify : true } - p4_param_order: - HillTop.Tiburon.Arnold: { type: exact, size: 7, full_size: 9, key_name: "Tiburon.Arnold" } - Millston.Calabash.Adona: { type: ternary, size: 24, full_size: 24, key_name: "Calabash.Adona" } - Millston.Calabash.Connell: { type: ternary, size: 24, full_size: 24, key_name: "Calabash.Connell" } - row: [ 6, 7, 8, 9, 10, 11, 0, 1 ] - bus: [ 0, 0, 0, 0, 0, 0, 1, 1 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 1 - - 1 - input_xbar: - ternary group 0: { 16: Millston.Calabash.Adona(8..23), 32: Millston.Calabash.Connell.16-23 } - ternary group 7: { 0: Millston.Calabash.Connell.0-15(8..15), 8: HillTop.Tiburon.Arnold(0..6), 16: Millston.Calabash.Adona(0..7), 24: Millston.Calabash.Connell.0-15(0..7) } - match: - - { group: 0, dirtcam: 0x150 } - - { group: 7, dirtcam: 0x55 } - gateway: - name: cond-1 - input_xbar: - exact group 2: { 105: Millston.Hayfield.$valid } - row: 1 - bus: 0 - unit: 0 - match: { 1: Millston.Hayfield.$valid } - 0b******0: run_table - miss: _Leacock - condition: - expression: "(Millston.Hayfield.$valid == 1 == 0)" - true: _Florahome - false: _Leacock - hit: [ _McIntyre_0, _Newtonia ] - miss: _McIntyre_0 - indirect: _Florahome$tind - counter _Florahome$stats.Meyers: - p4: { name: Meyers } - row: 13 - column: [ 1, 2 ] - maprams: [ 1, 2 ] - count: packets_and_bytes - format: {packets(0): 64..91, bytes(0): 92..127, packets(1): 0..27, bytes(1): 28..63} - lrt: - - { threshold: 404246592, interval: 25265664 } - - { threshold: 404246592, interval: 25265664 } - - { threshold: 404246592, interval: 25265664 } - ternary_indirect _Florahome$tind: - row: 2 - bus: 0 - column: 5 - input_xbar: - ternary group 0: { 16: Millston.Calabash.Adona(8..23), 32: Millston.Calabash.Connell.16-23 } - ternary group 7: { 0: Millston.Calabash.Connell.0-15(8..15), 8: HillTop.Tiburon.Arnold(0..6), 16: Millston.Calabash.Adona(0..7), 24: Millston.Calabash.Connell.0-15(0..7) } - format: { next: 0..0, action: 1..6, immediate: 7..16 } - action_bus: { 4 : immediate(0..7), 100..103 : immediate(0..9) } - stats: _Florahome$stats.Meyers($DIRECT, $DEFAULT) - instruction: _Florahome$tind(action, $DEFAULT) - actions: - Earlham(11, 11): - - p4_param_order: { Blencoe: 8, Satolah: 1 } - - default_action: { allowed: true } - - handle: 0x20000004 - - next_table: 1 - - { Blencoe: immediate(0..7), $data0: immediate(8..9), Satolah: $data0(0..0), $constant0: $data0(1..1), $constant0: 1 } - - set HillTop.Wisdom.Havana, 1 - - set HillTop.Wisdom.Blencoe, Blencoe - - set HillTop.RossFork.Tenino, 1 - - set W1(17..18), $data0 - - _Florahome$stats.Meyers($DIRECT) - Lewellen(13, 13): - - default_action: { allowed: true } - - handle: 0x20000005 - - next_table: 0 - - { } - - set HillTop.RossFork.Welcome, 1 - - _Florahome$stats.Meyers($DIRECT) - Absecon(14, 14): - - default_action: { allowed: true } - - handle: 0x20000006 - - next_table: 0 - - { } - - set HillTop.RossFork.Tenino, 1 - - _Florahome$stats.Meyers($DIRECT) - Brodnax(16, 16): - - default_action: { allowed: true } - - handle: 0x20000007 - - next_table: 0 - - { } - - set HillTop.RossFork.Pridgen, 1 - - _Florahome$stats.Meyers($DIRECT) - Bowers(0, 0): - - default_action: { allowed: true } - - handle: 0x20000008 - - next_table: 0 - - { } - - _Florahome$stats.Meyers($DIRECT) - Skene(18, 18): - - default_action: { allowed: true } - - handle: 0x20000009 - - next_table: 0 - - { } - - set HillTop.RossFork.Tenino, 1 - - set HillTop.RossFork.Juniata, 1 - - _Florahome$stats.Meyers($DIRECT) - Scottdale(20, 20): - - p4_param_order: { Blencoe: 8, Satolah: 1 } - - default_action: { allowed: true } - - handle: 0x2000000a - - next_table: 0 - - { Blencoe: immediate(0..7), Satolah: immediate(8..8) } - - set HillTop.Wisdom.Blencoe, Blencoe - - set HillTop.RossFork.Tenino, 1 - - set HillTop.Edwards.Satolah, Satolah - - _Florahome$stats.Meyers($DIRECT) - Camargo(15, 15): - - default_action: { allowed: true } - - handle: 0x2000000b - - next_table: 0 - - { } - - _Florahome$stats.Meyers($DIRECT) - default_action: Camargo - ternary_match _Newtonia 9: - p4: { name: Newtonia, size: 512, disable_atomic_modify : true } - p4_param_order: - Millston.Calabash.Goldsboro: { type: ternary, size: 24, full_size: 24, key_name: "Calabash.Goldsboro" } - Millston.Calabash.Fabens: { type: ternary, size: 24, full_size: 24, key_name: "Calabash.Fabens" } - row: [ 8, 9 ] - bus: [ 1, 1 ] - column: - - 1 - - 1 - indirect_bus: 3 - input_xbar: - ternary group 8: { 0: Millston.Calabash.Fabens, 24: Millston.Calabash.Goldsboro.0-7, 32: Millston.Calabash.Goldsboro.8-23(0..7) } - ternary group 9: { 8: Millston.Calabash.Goldsboro.8-23(8..15) } - match: - - { group: 8, dirtcam: 0x155 } - - { group: 9, dirtcam: 0x4 } - hit: [ _Leacock ] - miss: _Leacock - instruction: _Newtonia($DEFAULT, $DEFAULT) - actions: - Pioche(0, 21): - - default_action: { allowed: true } - - handle: 0x2000000e - - next_table: 0 - - set HillTop.RossFork.Teigen, 1 - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x2000000f - - next_table: 0 - default_only_action: NoAction - hash_action _McIntyre_0 7: - p4: { name: McIntyre, size: 1, disable_atomic_modify : true } - row: 4 - bus: 1 - hash_dist: - 3: { hash: 3, mask: 0x7ffff, shift: 0, expand: 0 } - input_xbar: - exact group 3: { 64: Millston.Wondervu$0.Bowden, 80: HillTop.Tiburon.Arnold } - hash 7: - 0..11: stripe(Millston.Wondervu$0.Bowden) - 12..15: stripe(HillTop.Tiburon.Arnold(0..3)) - 32..34: stripe(HillTop.Tiburon.Arnold(4..6)) - hash group 3: - table: [7] - seed: 0x0 - gateway: - name: _McIntyre_0-gateway - row: 3 - bus: 0 - unit: 0 - 0x0: _Aynor_0 - miss: _Aynor_0 - condition: - expression: "true(always hit)" - true: _Aynor_0 - false: _Aynor_0 - next: [] - action_bus: { 40..41 : _McIntyre_0$salu..McDonough(0..15) } - stateful: _McIntyre_0$salu..McDonough(hash_dist 3, $DEFAULT, $DEFAULT) - instruction: _McIntyre_0($DEFAULT, $DEFAULT) - actions: - Leland(0, 17): - - default_action: { allowed: true } - - handle: 0x2000000d - - next_table: 0 - - set HillTop.Murphy.Blairsden, _McIntyre_0$salu..McDonough - - _McIntyre_0$salu..McDonough(_Ozona_0, $hash_dist) - default_action: Leland - stateful _McIntyre_0$salu..McDonough: - p4: { name: McDonough, size: 294912 } - row: 11 - column: [ 1, 2, 3, 4 ] - maprams: [ 1, 2, 3, 4 ] - format: { lo: 1 } - actions: - _Ozona_0: - - read_bit - - output alu_lo - set_bit_alu$0: - - set_bit - clr_bit_alu$0: - - clr_bit - hash_action _Aynor_0 8: - p4: { name: Aynor, size: 1, disable_atomic_modify : true } - row: 0 - bus: 1 - hash_dist: - 4: { hash: 3, mask: 0x7ffff, shift: 0, expand: 7 } - input_xbar: - exact group 3: { 64: Millston.Wondervu$0.Bowden, 80: HillTop.Tiburon.Arnold } - hash 7: - 16..27: stripe(Millston.Wondervu$0.Bowden) - 28..31: stripe(HillTop.Tiburon.Arnold(0..3)) - 39..41: stripe(HillTop.Tiburon.Arnold(4..6)) - hash group 3: - table: [7] - seed: 0x0 - gateway: - name: _Aynor_0-gateway - row: 1 - bus: 0 - unit: 1 - 0x0: _Newtonia - miss: _Newtonia - condition: - expression: "true(always hit)" - true: _Newtonia - false: _Newtonia - next: [] - action_bus: { 8 : _Aynor_0$salu..Exeter(0..7) } - stateful: _Aynor_0$salu..Exeter(hash_dist 4, $DEFAULT, $DEFAULT) - instruction: _Aynor_0($DEFAULT, $DEFAULT) - actions: - Dahlgren(0, 19): - - default_action: { allowed: true } - - handle: 0x2000000c - - next_table: 0 - - set HillTop.Murphy.Standish, _Aynor_0$salu..Exeter - - _Aynor_0$salu..Exeter(_Yulee_0, $hash_dist) - default_action: Dahlgren - stateful _Aynor_0$salu..Exeter: - p4: { name: Exeter, size: 294912 } - row: 15 - column: [ 1, 2, 3, 4 ] - maprams: [ 1, 2, 3, 4 ] - format: { lo: 1 } - actions: - _Yulee_0: - - read_bitc - - output alu_lo - set_bit_alu$0: - - set_bit - clr_bit_alu$0: - - clr_bit - hash_action _Leacock 10: - p4: { name: Leacock, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.Tiburon.Arnold: { type: exact, size: 9, full_size: 9, key_name: "Tiburon.Arnold" } - row: 0 - bus: 0 - hash_dist: - 2: { hash: 0, mask: 0x1ff, shift: 2 } - input_xbar: - exact group 4: { 0: HillTop.Tiburon.Arnold } - hash 8: - 32..40: stripe(HillTop.Tiburon.Arnold) - hash group 0: - table: [8] - seed: 0x0 - gateway: - name: _Leacock-gateway - row: 0 - bus: 0 - unit: 1 - 0x0: _Armagh - miss: _Armagh - condition: - expression: "true(always hit)" - true: _Armagh - false: _Armagh - next: [] - action: _Leacock$action_data(hash_dist 2, $DEFAULT) - instruction: _Leacock($DEFAULT, $DEFAULT) - actions: - Burmah(0, 22): - - p4_param_order: { McGrady: 3, LaConner: 6, AquaPark: 2 } - - default_action: { allowed: true } - - handle: 0x2000005b - - next_table: 0 - - { $data0: $adf_b0(0..4), McGrady: $data0(0..2), AquaPark: $data0(3..4), LaConner: $adf_h0(5..10) } - - set HillTop.Edwards.LaConner, LaConner - - set B14(2..6), $data0 - default_action: Burmah - default_action_parameters: - McGrady: "0x0" - LaConner: "0x0" - AquaPark: "0x0" - action _Leacock$action_data: - p4: { name: Leacock$action, how_referenced: direct } - row: 7 - column: 1 - vpns: [ 0 ] - home_row: - - 7 - format Burmah: { $adf_b0: 0..7, $adf_h0: 0..15 } - action_bus: { 10 : $adf_b0, 44..45 : $adf_h0 } - exact_match _Armagh 11: - p4: { name: Armagh, size: 20480, disable_atomic_modify : true } - p4_param_order: - Millston.GlenAvon.Kaluaaha: { type: exact, size: 32, full_size: 32, key_name: "GlenAvon.Kaluaaha" } - Millston.GlenAvon.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "GlenAvon.Calcasieu" } - row: [ 5, 4, 3 ] - bus: [ 0, 0, 0 ] - column: - - [ 2, 3, 4, 6 ] - - [ 2, 3, 4, 6 ] - - [ 2, 3 ] - stash: - row: [ 3 ] - col: [ 2 ] - unit: [ 0 ] - ways: - - [4, 0, 0x1, [3, 2], [3, 3]] - - [4, 1, 0x2, [4, 4], [4, 6]] - - [4, 2, 0x4, [4, 2], [4, 3]] - - [4, 3, 0x8, [5, 4], [5, 6]] - - [4, 0, 0x1, [5, 2], [5, 3]] - input_xbar: - exact group 5: { 0: Millston.GlenAvon.Kaluaaha, 32: Millston.GlenAvon.Calcasieu } - hash 10: - 0..7: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(0..7) - 8..9: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(8..9) - 40: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(10) - 11..18: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(0..7) - 19: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(8) - 10: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(10) - 41: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(9) - 22..29: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(0..7) - 20..21: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(9..10) - 42: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(8) - 33..39: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(0..6) - 30..32: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(8..10) - 43: random(Millston.GlenAvon.Kaluaaha(11..31), Millston.GlenAvon.Calcasieu) ^ Millston.GlenAvon.Kaluaaha(7) - hash group 4: - table: [10] - seed: 0x66d75f86f49 - format: { action(0): 0..1, version(0): 112..115, match(0): [83..87, 32..79 ], action(1): 2..3, version(1): 116..119, match(1): [123..127, 88..111, 8..31 ] } - match: [ Millston.GlenAvon.Kaluaaha(11..15), Millston.GlenAvon.Kaluaaha(16..23), Millston.GlenAvon.Kaluaaha(24..31), Millston.GlenAvon.Calcasieu(0..7), Millston.GlenAvon.Calcasieu(8..15), Millston.GlenAvon.Calcasieu(16..23), Millston.GlenAvon.Calcasieu(24..31) ] - hit: [ _Ankeny ] - miss: _Ankeny - action: _Armagh$action_data($DIRECT, $DEFAULT) - instruction: _Armagh(action, $DEFAULT) - actions: - Knights(0, 23): - - p4_param_order: { Lookeba: 16, Alstown: 16, Longwood: 2, Yorkshire: 1, Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x20000010 - - next_table: 0 - - { Alstown: $adf_h0(0..15), Lookeba: $adf_h1(0..15), Bonduel: $adf_h2(0..13), $data0: $adf_h3(0..2), Longwood: $data0(0..1), Yorkshire: $data0(2..2) } - - set HillTop.RossFork.Altus, Lookeba - - set HillTop.RossFork.Hickox, Alstown - - set HillTop.RossFork.Luzerne, Bonduel - - set H90(12..14), $data0 - Humeston(1, 24): - - p4_param_order: { Lookeba: 16, Alstown: 16, Longwood: 2, Yorkshire: 1, Sardinia: 14 } - - default_action: { allowed: true } - - handle: 0x20000011 - - next_table: 0 - - { Alstown: $adf_h0(0..15), Lookeba: $adf_h1(0..15), Sardinia: $adf_h2(0..13), $data0: $adf_h3(0..3), Longwood: $data0(0..1), Yorkshire: $data0(2..2), $constant0: $data0(3..3), $constant0: 1 } - - set HillTop.RossFork.Altus, Lookeba - - set HillTop.RossFork.Hickox, Alstown - - set HillTop.RossFork.Luzerne, Sardinia - - set H90(12..15), $data0 - Sequim(2, 0): - - default_action: { allowed: true } - - handle: 0x20000012 - - next_table: 0 - - { } - default_action: Sequim - action _Armagh$action_data: - p4: { name: Armagh$action } - row: [ 14, 13, 12, 11, 10, 9 ] - word: [ 0, 0, 0, 0, 0, 0 ] - column: - - 5 - - [ 4, 5 ] - - 5 - - 5 - - 5 - - [ 2, 3, 4, 5 ] - vpns: - - [ 0 ] - - [ 1, 2 ] - - [ 3 ] - - [ 4 ] - - [ 5 ] - - [ 6, 7, 8, 9 ] - home_row: - - 14 - format Knights: { $adf_h0: 0..15, $adf_h1: 16..31, $adf_h2: 32..47, $adf_h3: 48..63 } - format Humeston: { $adf_h0: 0..15, $adf_h1: 16..31, $adf_h2: 32..47, $adf_h3: 48..63 } - action_bus: { 72..73 : $adf_h0, 74..75 : $adf_h1, 76..77 : $adf_h2, 78..79 : $adf_h3 } - ternary_match _Ankeny 12: - p4: { name: Ankeny, size: 512, disable_atomic_modify : true } - p4_param_order: - Millston.Osyka.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Osyka" } - Millston.Osyka.Noyes: { type: ternary, size: 8, full_size: 8, key_name: "Osyka.Noyes" } - row: 10 - bus: 1 - column: 1 - input_xbar: - ternary group 9: { 6: Millston.Osyka.$valid, 16: Millston.Osyka.Noyes } - match: - - { group: 9, dirtcam: 0x11 } - hit: [ Turney_0 ] - miss: Turney_0 - indirect: _Ankeny$tind - ternary_indirect _Ankeny$tind: - row: 1 - bus: 0 - column: 5 - input_xbar: - ternary group 9: { 6: Millston.Osyka.$valid, 16: Millston.Osyka.Noyes } - format: { action: 0..0 } - instruction: _Ankeny$tind(action, $DEFAULT) - actions: - Funston(0, 25): - - default_action: { allowed: true } - - handle: 0x200000c9 - - next_table: 0 - - set HillTop.RossFork.Ankeny, 25 - Mayflower(1, 26): - - default_action: { allowed: true } - - handle: 0x200000ca - - next_table: 0 - - set HillTop.RossFork.Ankeny, 10 - default_action: Mayflower -stage 1 ingress: - exact_match Turney_0 0: - p4: { name: Turney, size: 1024, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Chaffee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Chaffee" } - HillTop.RossFork.Ocoee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } - row: 1 - bus: 1 - column: 7 - stash: - row: [ 1 ] - col: [ 7 ] - unit: [ 1 ] - ways: - - [0, 0, 0x0, [1, 7]] - input_xbar: - exact group 0: { 0: HillTop.RossFork.Chaffee, 8: HillTop.RossFork.Ocoee } - hash 0: - 0..1: random(HillTop.RossFork.Chaffee(2..7)) ^ HillTop.RossFork.Chaffee(0..1) - 2..9: random(HillTop.RossFork.Chaffee(2..7)) ^ HillTop.RossFork.Ocoee - hash group 0: - table: [0] - seed: 0x2e8 - format: { action(0): 0..0, version(0): 112..115, match(0): 34..39 } - match: [ HillTop.RossFork.Chaffee(2..7) ] - hit: [ _TinCity_0 ] - miss: _TinCity_0 - instruction: Turney_0(action, $DEFAULT) - actions: - Bodcaw(0, 1): - - default_action: { allowed: true } - - handle: 0x20000042 - - next_table: 0 - - set HillTop.RossFork.Laxon, HillTop.Maddock.Kaluaaha - - set HillTop.RossFork.Crozet, Millston.Grays.Chevak - Weimar(1, 2): - - default_action: { allowed: true } - - handle: 0x20000043 - - next_table: 0 - - set HillTop.RossFork.Crozet(0..7), HillTop.RossFork.Chaffee - default_action: Bodcaw - ternary_match _TinCity_0 1: - p4: { name: TinCity, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.Maddock.Calcasieu: { type: ternary, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } - row: 1 - bus: 1 - column: 1 - input_xbar: - ternary group 0: { 0: HillTop.Maddock.Calcasieu } - match: - - { group: 0, dirtcam: 0x55 } - gateway: - name: cond-4 - input_xbar: - exact group 0: { 21: HillTop.RossFork.Naruna.2-2, 27: HillTop.RossFork.Naruna.0-1 } - row: 5 - bus: 1 - unit: 0 - match: { 3: HillTop.RossFork.Naruna.0-1, 13: HillTop.RossFork.Naruna.2-2 } - 0b**0********01: run_table - miss: _Comunas_0 - condition: - expression: "(HillTop.RossFork.Naruna == 1)" - true: _TinCity_0 - false: _Comunas_0 - hit: [ _Stone_0 ] - miss: _Stone_0 - indirect: _TinCity_0$tind - ternary_indirect _TinCity_0$tind: - row: 6 - bus: 0 - column: 2 - input_xbar: - ternary group 0: { 0: HillTop.Maddock.Calcasieu } - format: { action: 0..1, immediate: 2..33 } - action_bus: { 64..65 : immediate(0..15), 66..67 : immediate(16..31) } - instruction: _TinCity_0$tind(action, $DEFAULT) - actions: - Bagwell(1, 3): - - p4_param_order: { Liberal: 16, Doyline: 16 } - - default_action: { allowed: true } - - handle: 0x20000026 - - next_table: 0 - - { Doyline: immediate(0..15), Liberal: immediate(16..31) } - - set HillTop.Bessie.Calcasieu, Liberal - - set HillTop.Bessie.Chavies, Doyline - Wright(2, 4): - - default_action: { allowed: true } - - handle: 0x20000027 - - next_table: 0 - - { } - - set HillTop.RossFork.Halaula, 1 - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x20000028 - - next_table: 0 - - { } - default_only_action: NoAction - ternary_match _Comunas_0 3: - p4: { name: Comunas, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.Sublett.Calcasieu: { type: ternary, size: 128, full_size: 128, key_name: "Sublett.Calcasieu" } - row: [ 5, 4, 3 ] - bus: [ 0, 0, 0 ] - column: - - 0 - - 0 - - 0 - input_xbar: - ternary group 2: { 0: HillTop.Sublett.Calcasieu.96-127(24..31), 8: HillTop.Sublett.Calcasieu.96-127(0..7), 16: HillTop.Sublett.Calcasieu.0-31(8..15), 24: HillTop.Sublett.Calcasieu.96-127(16..23), 32: HillTop.Sublett.Calcasieu.0-31(24..31) } - ternary group 4: { 0: HillTop.Sublett.Calcasieu.0-31(16..23), 8: HillTop.Sublett.Calcasieu.32-63(24..31), 16: HillTop.Sublett.Calcasieu.0-31(0..7), 24: HillTop.Sublett.Calcasieu.32-63(8..23) } - ternary group 5: { 0: HillTop.Sublett.Calcasieu.32-63(0..7), 8: HillTop.Sublett.Calcasieu.64-95(8..31), 32: HillTop.Sublett.Calcasieu.64-95(0..7) } - byte group 0: { 0: HillTop.Sublett.Calcasieu.96-127(8..15) } - match: - - { group: 2, byte_group: 0, byte_config: 0, dirtcam: 0x555 } - - { group: 4, byte_group: 0, byte_config: 1, dirtcam: 0x555 } - - { group: 5, dirtcam: 0x155 } - gateway: - name: cond-5 - input_xbar: - exact group 0: { 21: HillTop.RossFork.Naruna.2-2, 27: HillTop.RossFork.Naruna.0-1 } - row: 4 - bus: 1 - unit: 0 - match: { 3: HillTop.RossFork.Naruna.0-1, 13: HillTop.RossFork.Naruna.2-2 } - 0b**0********10: run_table - miss: _Virginia - condition: - expression: "(HillTop.RossFork.Naruna == 2)" - true: _Comunas_0 - false: _Virginia - hit: [ _Milltown_0 ] - miss: _Milltown_0 - indirect: _Comunas_0$tind - ternary_indirect _Comunas_0$tind: - row: 4 - bus: 0 - column: 2 - input_xbar: - ternary group 2: { 0: HillTop.Sublett.Calcasieu.96-127(24..31), 8: HillTop.Sublett.Calcasieu.96-127(0..7), 16: HillTop.Sublett.Calcasieu.0-31(8..15), 24: HillTop.Sublett.Calcasieu.96-127(16..23), 32: HillTop.Sublett.Calcasieu.0-31(24..31) } - ternary group 4: { 0: HillTop.Sublett.Calcasieu.0-31(16..23), 8: HillTop.Sublett.Calcasieu.32-63(24..31), 16: HillTop.Sublett.Calcasieu.0-31(0..7), 24: HillTop.Sublett.Calcasieu.32-63(8..23) } - ternary group 5: { 0: HillTop.Sublett.Calcasieu.32-63(0..7), 8: HillTop.Sublett.Calcasieu.64-95(8..31), 32: HillTop.Sublett.Calcasieu.64-95(0..7) } - byte group 0: { 0: HillTop.Sublett.Calcasieu.96-127(8..15) } - format: { action: 0..1, immediate: 2..33 } - action_bus: { 68..69 : immediate(0..15), 70..71 : immediate(16..31) } - instruction: _Comunas_0$tind(action, $DEFAULT) - actions: - Bagwell(1, 7): - - p4_param_order: { Liberal: 16, Doyline: 16 } - - default_action: { allowed: true } - - handle: 0x2000002c - - next_table: 0 - - { Doyline: immediate(0..15), Liberal: immediate(16..31) } - - set HillTop.Bessie.Calcasieu, Liberal - - set HillTop.Bessie.Chavies, Doyline - Wright(2, 9): - - default_action: { allowed: true } - - handle: 0x2000002d - - next_table: 0 - - { } - - set HillTop.RossFork.Halaula, 1 - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x2000002e - - next_table: 0 - - { } - default_only_action: NoAction - ternary_match _Milltown_0 4: - p4: { name: Milltown, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.Sublett.Kaluaaha: { type: ternary, size: 128, full_size: 128, key_name: "Sublett.Kaluaaha" } - row: [ 0, 1, 2 ] - bus: [ 0, 0, 0 ] - column: - - 0 - - 0 - - 0 - input_xbar: - ternary group 3: { 0: HillTop.Sublett.Kaluaaha.32-63(8..31), 24: HillTop.Sublett.Kaluaaha.0-31(0..15) } - ternary group 7: { 0: HillTop.Sublett.Kaluaaha.0-31(24..31), 8: HillTop.Sublett.Kaluaaha.64-95(0..15), 24: HillTop.Sublett.Kaluaaha.0-31(16..23), 32: HillTop.Sublett.Kaluaaha.64-95(24..31) } - ternary group 9: { 0: HillTop.Sublett.Kaluaaha.64-95(16..23), 8: HillTop.Sublett.Kaluaaha.96-127(24..31), 16: HillTop.Sublett.Kaluaaha.96-127(0..23) } - byte group 1: { 0: HillTop.Sublett.Kaluaaha.32-63(0..7) } - match: - - { group: 3, byte_group: 1, byte_config: 0, dirtcam: 0x555 } - - { group: 7, byte_group: 1, byte_config: 1, dirtcam: 0x555 } - - { group: 9, dirtcam: 0x155 } - hit: [ _Virginia ] - miss: _Virginia - indirect: _Milltown_0$tind - ternary_indirect _Milltown_0$tind: - row: 3 - bus: 0 - column: 2 - input_xbar: - ternary group 3: { 0: HillTop.Sublett.Kaluaaha.32-63(8..31), 24: HillTop.Sublett.Kaluaaha.0-31(0..15) } - ternary group 7: { 0: HillTop.Sublett.Kaluaaha.0-31(24..31), 8: HillTop.Sublett.Kaluaaha.64-95(0..15), 24: HillTop.Sublett.Kaluaaha.0-31(16..23), 32: HillTop.Sublett.Kaluaaha.64-95(24..31) } - ternary group 9: { 0: HillTop.Sublett.Kaluaaha.64-95(16..23), 8: HillTop.Sublett.Kaluaaha.96-127(24..31), 16: HillTop.Sublett.Kaluaaha.96-127(0..23) } - byte group 1: { 0: HillTop.Sublett.Kaluaaha.32-63(0..7) } - format: { action: 0..1, immediate: 2..33 } - action_bus: { 38..39 : immediate(16..31), 100..103 : immediate(0..31) } - instruction: _Milltown_0$tind(action, $DEFAULT) - actions: - Parmelee(0, 10): - - p4_param_order: { Liberal: 16, Doyline: 16 } - - default_action: { allowed: true } - - handle: 0x20000029 - - next_table: 0 - - { Doyline: immediate(0..15), Liberal: immediate(16..31) } - - set HillTop.RossFork.Kapalua, 0 - - set HillTop.Bessie.LasVegas, HillTop.RossFork.Ocoee - - set HillTop.Bessie.PineCity, HillTop.Sublett.PineCity - - set HillTop.Bessie.Exton, HillTop.RossFork.Exton - - set HillTop.Bessie.Noyes, HillTop.RossFork.Kremlin - - set HillTop.Bessie.Kaluaaha, Liberal - - set HillTop.Bessie.Heuvelton, Doyline - Belcourt(1, 12): - - default_action: { allowed: true } - - handle: 0x2000002a - - next_table: 0 - - { } - - set HillTop.RossFork.Kapalua, 1 - Moorman(2, 14): - - default_action: { allowed: true } - - handle: 0x2000002b - - next_table: 0 - - { } - - set HillTop.RossFork.Kapalua, 0 - - set HillTop.Bessie.LasVegas, HillTop.RossFork.Ocoee - - set HillTop.Bessie.PineCity, HillTop.Sublett.PineCity - - set HillTop.Bessie.Exton, HillTop.RossFork.Exton - - set HillTop.Bessie.Noyes, HillTop.RossFork.Kremlin - default_action: Moorman - ternary_match _Stone_0 2: - p4: { name: Stone, size: 2048, disable_atomic_modify : true } - p4_param_order: - HillTop.Maddock.Kaluaaha: { type: ternary, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } - row: [ 9, 10, 11, 0 ] - bus: [ 0, 0, 0, 1 ] - column: - - 0 - - 0 - - 0 - - 1 - input_xbar: - ternary group 1: { 0: HillTop.Maddock.Kaluaaha(16..31), 16: HillTop.Maddock.Kaluaaha(0..15) } - match: - - { group: 1, dirtcam: 0x55 } - hit: [ _Virginia ] - miss: _Virginia - indirect: _Stone_0$tind - ternary_indirect _Stone_0$tind: - row: 5 - bus: 0 - column: 2 - input_xbar: - ternary group 1: { 0: HillTop.Maddock.Kaluaaha(16..31), 16: HillTop.Maddock.Kaluaaha(0..15) } - format: { action: 0..1, immediate: 2..33 } - action_bus: { 34..35 : immediate(16..31), 96..99 : immediate(0..31) } - instruction: _Stone_0$tind(action, $DEFAULT) - actions: - Capitola(0, 5): - - p4_param_order: { Liberal: 16, Doyline: 16 } - - default_action: { allowed: true } - - handle: 0x20000023 - - next_table: 0 - - { Doyline: immediate(0..15), Liberal: immediate(16..31) } - - set HillTop.RossFork.Kapalua, 0 - - set HillTop.Bessie.LasVegas, HillTop.RossFork.Ocoee - - set HillTop.Bessie.PineCity, HillTop.Maddock.PineCity - - set HillTop.Bessie.Exton, HillTop.RossFork.Exton - - set HillTop.Bessie.Noyes, HillTop.RossFork.Kremlin - - set HillTop.Bessie.Kaluaaha, Liberal - - set HillTop.Bessie.Heuvelton, Doyline - Belcourt(1, 6): - - default_action: { allowed: true } - - handle: 0x20000024 - - next_table: 0 - - { } - - set HillTop.RossFork.Kapalua, 1 - Council(2, 8): - - default_action: { allowed: true } - - handle: 0x20000025 - - next_table: 0 - - { } - - set HillTop.RossFork.Kapalua, 0 - - set HillTop.Bessie.LasVegas, HillTop.RossFork.Ocoee - - set HillTop.Bessie.PineCity, HillTop.Maddock.PineCity - - set HillTop.Bessie.Exton, HillTop.RossFork.Exton - - set HillTop.Bessie.Noyes, HillTop.RossFork.Kremlin - default_action: Council - exact_match _Virginia 5: - p4: { name: Virginia, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Naruna: { type: exact, size: 2, full_size: 3, key_name: "RossFork.Naruna" } - HillTop.Tiburon.Arnold: { type: exact, size: 7, full_size: 9, key_name: "Tiburon.Arnold" } - row: 1 - bus: 0 - column: 6 - stash: - row: [ 1 ] - col: [ 6 ] - unit: [ 0 ] - ways: - - [0, 1, 0x0, [1, 6]] - input_xbar: - exact group 0: { 27: HillTop.RossFork.Naruna.0-1, 32: HillTop.Tiburon.Arnold(0..6) } - hash 0: - 10..11: HillTop.RossFork.Naruna.0-1 - 12..18: HillTop.Tiburon.Arnold(0..6) - hash group 0: - table: [0] - seed: 0x0 - format: { action(0): 0..1, immediate(0): 2..25, version(0): 112..115 } - gateway: - name: cond-7 - input_xbar: - exact group 0: { 41: HillTop.Wisdom.Onycha } - row: 3 - bus: 1 - unit: 1 - match: { 1: HillTop.Wisdom.Onycha } - 0b****000: run_table - miss: _Cornish - condition: - expression: "(HillTop.Wisdom.Onycha == 0)" - true: _Virginia - false: _Cornish - hit: [ [], _Archer, _Cornish ] - miss: _Archer - action_bus: { 42..43 : immediate(16..23), 104..107 : immediate(0..23) } - instruction: _Virginia(action, $DEFAULT) - actions: - Bluff(1, 11): - - p4_param_order: { Miranda: 8, Bedrock: 32 } - - default_action: { allowed: true } - - handle: 0x20000033 - - next_table: 1 - - { Bedrock.0-15: immediate(0..15), Miranda: immediate(16..23) } - - set HillTop.Mausdale.Kenney(0..15), Bedrock.0-15 - - set HillTop.Bessie.Miranda, Miranda - Sequim(2, 0): - - default_action: { allowed: true } - - handle: 0x20000034 - - next_table: 2 - - { } - default_action: Sequim - exact_match _Cornish 6: - p4: { name: Cornish, size: 8192, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Naruna: { type: exact, size: 2, full_size: 3, key_name: "RossFork.Naruna" } - HillTop.RossFork.Bicknell: { type: exact, size: 12, full_size: 12, key_name: "RossFork.Bicknell" } - row: [ 3, 2 ] - bus: [ 1, 1 ] - column: - - [ 7, 8, 9 ] - - 8 - stash: - row: [ 3 ] - col: [ 7 ] - unit: [ 0 ] - ways: - - [1, 0, 0x1, [3, 7], [3, 8]] - - [1, 1, 0x0, [3, 9]] - - [1, 2, 0x0, [2, 8]] - input_xbar: - exact group 0: { 64: HillTop.RossFork.Bicknell, 83: HillTop.RossFork.Naruna.0-1 } - hash 1: - 0..3: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Bicknell(0..3) - 4..7: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Bicknell(8..11) - 8..9: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Naruna.0-1 - 40: random(HillTop.RossFork.Bicknell(4..7)) - 11..14: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Bicknell(0..3) - 15..18: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Bicknell(8..11) - 19: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Naruna.0-1(0) - 10: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Naruna.0-1(1) - 22..25: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Bicknell(0..3) - 26..29: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Bicknell(8..11) - 20..21: random(HillTop.RossFork.Bicknell(4..7)) ^ HillTop.RossFork.Naruna.0-1 - hash group 1: - table: [1] - seed: 0x2f4d580e - format: { immediate(0): 0..23, version(0): 112..115, match(0): 52..55, immediate(1): 24..47, version(1): 116..119, match(1): 60..63 } - match: [ HillTop.RossFork.Bicknell(4..7) ] - hit: [ _Archer ] - miss: _Archer - action_bus: { 46..47 : immediate(16..23), 108..111 : immediate(0..23) } - instruction: _Cornish($DEFAULT, $DEFAULT) - actions: - Silvertip(0, 13): - - p4_param_order: { Miranda: 8, Bedrock: 32 } - - default_action: { allowed: true } - - handle: 0x20000035 - - next_table: 0 - - { Bedrock.0-15: immediate(0..15), Miranda: immediate(16..23) } - - set HillTop.Mausdale.Kenney(0..15), Bedrock.0-15 - - set HillTop.Bessie.Miranda, Miranda - - set HillTop.RossFork.Yaurel, 1 - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x20000036 - - next_table: 0 - - { } - default_only_action: NoAction - ternary_match _Archer 7: - p4: { name: Archer, size: 1024, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Mendocino: { type: ternary, size: 16, full_size: 16, key_name: "RossFork.Mendocino" } - row: [ 4, 5 ] - bus: [ 1, 1 ] - column: - - 1 - - 1 - input_xbar: - ternary group 6: { 0: HillTop.RossFork.Mendocino(8..15), 8: HillTop.RossFork.Mendocino(0..7) } - match: - - { group: 6, byte_config: 3, dirtcam: 0x5 } - gateway: - name: cond-6 - input_xbar: - exact group 0: { 50: HillTop.RossFork.Denhoff.1-2(0) } - row: 2 - bus: 1 - unit: 0 - match: { 2: HillTop.RossFork.Denhoff.1-2(0) } - 0b*****1: run_table - miss: _Thawville - condition: - expression: "(HillTop.RossFork.Denhoff & 2 == 2)" - true: _Archer - false: _Thawville - hit: [ _Hatchel ] - miss: _Hatchel - indirect: _Archer$tind - ternary_indirect _Archer$tind: - row: 2 - bus: 0 - column: 2 - input_xbar: - ternary group 6: { 0: HillTop.RossFork.Mendocino(8..15), 8: HillTop.RossFork.Mendocino(0..7) } - format: { action: 0..0 } - action: _Archer$action_data($DIRECT, $DEFAULT) - instruction: _Archer$tind(action, $DEFAULT) - actions: - Kilbourne(1, 15): - - p4_param_order: { Liberal: 16 } - - default_action: { allowed: true } - - handle: 0x20000031 - - next_table: 0 - - { Liberal: $adf_h0(0..15) } - - set HillTop.Bessie.Mendocino, Liberal - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x20000032 - - next_table: 0 - - { } - default_only_action: NoAction - action _Archer$action_data: - p4: { name: Archer$action } - row: 13 - column: 5 - vpns: [ 0 ] - home_row: - - 13 - format Kilbourne: { $adf_h0: 0..15 } - action_bus: { 32..33 : $adf_h0 } - ternary_match _Hatchel 8: - p4: { name: Hatchel, size: 1024, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Chevak: { type: ternary, size: 16, full_size: 16, key_name: "RossFork.Chevak" } - row: [ 2, 3 ] - bus: [ 1, 1 ] - column: - - 1 - - 1 - indirect_bus: 1 - input_xbar: - ternary group 6: { 16: HillTop.RossFork.Chevak(8..15), 24: HillTop.RossFork.Chevak(0..7) } - match: - - { group: 6, byte_config: 3, dirtcam: 0x50 } - hit: [ _Thawville ] - miss: _Thawville - action: _Hatchel$action_data($DIRECT, $DEFAULT) - instruction: _Hatchel($DEFAULT, $DEFAULT) - actions: - Thatcher(0, 16): - - p4_param_order: { Liberal: 16 } - - default_action: { allowed: true } - - handle: 0x2000002f - - next_table: 0 - - { Liberal: $adf_h0(0..15) } - - set HillTop.Bessie.Chevak, Liberal - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x20000030 - - next_table: 0 - - { } - default_only_action: NoAction - action _Hatchel$action_data: - p4: { name: Hatchel$action } - row: 14 - column: 3 - vpns: [ 0 ] - home_row: - - 14 - format Thatcher: { $adf_h0: 0..15 } - action_bus: { 36..37 : $adf_h0 } - exact_match _Thawville 9: - p4: { name: Thawville, size: 20480, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Altus: { type: exact, size: 16, full_size: 16, key_name: "RossFork.Altus" } - Millston.Grays.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Grays.Chevak" } - Millston.Grays.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Grays.Mendocino" } - row: [ 7, 5, 4, 3 ] - bus: [ 1, 0, 0, 0 ] - column: - - 9 - - [ 6, 7, 8, 9 ] - - [ 6, 7, 8, 9 ] - - 6 - stash: - row: [ 7 ] - col: [ 9 ] - unit: [ 1 ] - ways: - - [2, 0, 0x1, [7, 9], [5, 6]] - - [2, 1, 0x2, [5, 7], [5, 8]] - - [2, 2, 0x4, [5, 9], [4, 6]] - - [2, 3, 0x8, [4, 7], [4, 8]] - - [2, 0, 0x1, [4, 9], [3, 6]] - input_xbar: - exact group 1: { 0: Millston.Grays.Chevak, 16: Millston.Grays.Mendocino, 32: HillTop.RossFork.Altus } - hash 2: - 0..7: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(0..7) - 8..9: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(8..9) - 40: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(10) - 11..18: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(0..7) - 19: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(8) - 10: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(10) - 41: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(9) - 22..29: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(0..7) - 20..21: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(9..10) - 42: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(8) - 33..39: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(0..6) - 30..32: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(8..10) - 43: random(Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino, HillTop.RossFork.Altus) ^ Millston.Grays.Chevak(7) - hash group 2: - table: [2] - seed: 0x474c02dbdc8 - format: { action(0): 0..1, immediate(0): 4..19, version(0): 112..115, match(0): [75..79, 40..71 ], action(1): 2..3, immediate(1): 20..35, version(1): 116..119, match(1): [123..127, 80..111 ] } - match: [ Millston.Grays.Chevak(11..15), Millston.Grays.Mendocino(0..7), Millston.Grays.Mendocino(8..15), HillTop.RossFork.Altus(0..7), HillTop.RossFork.Altus(8..15) ] - gateway: - name: cond-3 - input_xbar: - exact group 1: { 32: HillTop.RossFork.Altus } - row: 3 - bus: 0 - unit: 0 - match: { 0: HillTop.RossFork.Altus(0..7), 8: HillTop.RossFork.Altus(8..15) } - 0x0000: _Nevis - miss: run_table - condition: - expression: "(HillTop.RossFork.Altus != 0)" - true: _Thawville - false: _Nevis - hit: [ _Nevis ] - miss: _Nevis - action_bus: { 40..41 : immediate(0..15) } - action: _Thawville$action_data($DIRECT, $DEFAULT) - instruction: _Thawville(action, $DEFAULT) - actions: - Orting(1, 17): - - p4_param_order: { Alstown: 16, Longwood: 2, Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x20000020 - - next_table: 0 - - { Bonduel: $adf_h0(0..13), Longwood: $adf_h0(14..15), Alstown: immediate(0..15) } - - set HillTop.RossFork.Tehachapi, Alstown - - set HillTop.RossFork.Caroleen, Longwood - - set HillTop.RossFork.Devers, Bonduel - SanRemo(2, 18): - - p4_param_order: { Alstown: 16, Longwood: 2, Sardinia: 14 } - - default_action: { allowed: true } - - handle: 0x20000021 - - next_table: 0 - - { Sardinia: $adf_h0(0..13), Longwood: $adf_h0(14..15), Alstown: immediate(0..15) } - - set HillTop.RossFork.Tehachapi, Alstown - - set HillTop.RossFork.Caroleen, Longwood - - set HillTop.RossFork.Belfair, 1 - - set HillTop.RossFork.Devers, Sardinia - Sequim(3, 0): - - default_action: { allowed: true } - - handle: 0x20000022 - - next_table: 0 - - { } - default_action: Sequim - action _Thawville$action_data: - p4: { name: Thawville$action } - row: [ 15, 14 ] - word: [ 0, 0 ] - column: - - [ 4, 5 ] - - 2 - vpns: - - [ 0, 1 ] - - [ 2 ] - home_row: - - 15 - format Orting: { $adf_h0: 0..15 } - format SanRemo: { $adf_h0: 0..15 } - action_bus: { 44..45 : $adf_h0 } - ternary_match _Nevis 10: - p4: { name: Nevis, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.Tiburon.Arnold: { type: exact, size: 7, full_size: 9, key_name: "Tiburon.Arnold" } - HillTop.RossFork.Powderly: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Powderly" } - HillTop.RossFork.Teigen: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Teigen" } - HillTop.RossFork.Welcome: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Welcome" } - HillTop.Aldan.Parkville: { type: ternary, size: 1, full_size: 4, key_name: "Aldan.Parkville", start_bit: 3 } - HillTop.Aldan.Blakeley: { type: ternary, size: 1, full_size: 1, key_name: "Aldan.Blakeley" } - row: 8 - bus: 0 - column: 0 - input_xbar: - ternary group 8: { 0: HillTop.Tiburon.Arnold(0..6), 14: HillTop.RossFork.Powderly, 22: HillTop.RossFork.Welcome, 27: HillTop.Aldan.Parkville(3), 32: HillTop.RossFork.Teigen } - byte group 3: { 0: HillTop.Aldan.Blakeley } - match: - - { group: 8, byte_group: 3, byte_config: 0, dirtcam: 0x555 } - gateway: - name: cond-8 - input_xbar: - exact group 0: { 57: Millston.Hayfield.$valid } - row: 1 - bus: 1 - unit: 1 - match: { 1: Millston.Hayfield.$valid } - 0b******0: run_table - miss: _Redfield - condition: - expression: "(Millston.Hayfield.$valid == 1 == 0)" - true: _Nevis - false: _Redfield - hit: [ [], _Redfield, _Lindsborg ] - miss: _Redfield - indirect: _Nevis$tind - counter _Nevis$stats.Hallwood: - p4: { name: Hallwood } - row: 13 - column: [ 3, 4 ] - maprams: [ 3, 4 ] - count: packets - format: {packets(0): 64..127, packets(1): 0..63} - ternary_indirect _Nevis$tind: - row: 1 - bus: 0 - column: 2 - input_xbar: - ternary group 8: { 0: HillTop.Tiburon.Arnold(0..6), 14: HillTop.RossFork.Powderly, 22: HillTop.RossFork.Welcome, 27: HillTop.Aldan.Parkville(3), 32: HillTop.RossFork.Teigen } - byte group 3: { 0: HillTop.Aldan.Blakeley } - format: { action: 0..1 } - stats: _Nevis$stats.Hallwood($DIRECT, $DEFAULT) - instruction: _Nevis$tind(action, $DEFAULT) - actions: - Empire(1, 19): - - default_action: { allowed: true } - - handle: 0x20000037 - - next_table: 1 - - set HillTop.RossFork.Weyauwega, 1 - - _Nevis$stats.Hallwood($DIRECT) - Daisytown(2, 0): - - default_action: { allowed: true } - - handle: 0x20000038 - - next_table: 2 - - _Nevis$stats.Hallwood($DIRECT) - default_action: Daisytown - exact_match _Lindsborg 11: - p4: { name: Lindsborg, size: 4096, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Goldsboro: { type: exact, size: 24, full_size: 24, key_name: "RossFork.Goldsboro" } - HillTop.RossFork.Fabens: { type: exact, size: 24, full_size: 24, key_name: "RossFork.Fabens" } - HillTop.RossFork.CeeVee: { type: exact, size: 12, full_size: 12, key_name: "RossFork.CeeVee" } - row: 2 - bus: 0 - column: [ 6, 7 ] - stash: - row: [ 2 ] - col: [ 6 ] - unit: [ 0 ] - ways: - - [0, 2, 0x0, [2, 6]] - - [0, 3, 0x0, [2, 7]] - input_xbar: - exact group 2: { 0: HillTop.RossFork.Fabens, 24: HillTop.RossFork.Goldsboro.8-23(8..15), 32: HillTop.RossFork.Goldsboro.0-7, 40: HillTop.RossFork.CeeVee(8..11), 48: HillTop.RossFork.Goldsboro.8-23(0..7), 64: HillTop.RossFork.CeeVee(0..7) } - hash 4: - 20..23: random(HillTop.RossFork.Fabens, HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(6..7)) ^ HillTop.RossFork.CeeVee(8..11) - 24..29: random(HillTop.RossFork.Fabens, HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(6..7)) ^ HillTop.RossFork.Goldsboro.8-23(0..5) - 31..34: random(HillTop.RossFork.Fabens, HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(6..7)) ^ HillTop.RossFork.CeeVee(8..11) - 35..39: random(HillTop.RossFork.Fabens, HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(6..7)) ^ HillTop.RossFork.Goldsboro.8-23(0..4) - 30: random(HillTop.RossFork.Fabens, HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(6..7)) ^ HillTop.RossFork.Goldsboro.8-23(5) - hash 5: - 20..29: random(HillTop.RossFork.CeeVee(0..7)) - 30..39: random(HillTop.RossFork.CeeVee(0..7)) - hash group 0: - table: [4, 5] - seed: 0x8cb1300000 - format: { action(0): 0..1, version(0): 112..115, match(0): [86..87, 32..79 ], action(1): 2..3, version(1): 116..119, match(1): [6..7, 88..111, 8..31 ] } - match: [ HillTop.RossFork.Goldsboro.8-23(6..7), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.CeeVee(0..7), HillTop.RossFork.Fabens(0..7), HillTop.RossFork.Fabens(8..15), HillTop.RossFork.Fabens(16..23), HillTop.RossFork.Goldsboro.0-7 ] - gateway: - name: cond-9 - input_xbar: - exact group 2: { 40: HillTop.RossFork.CeeVee(8..11), 64: HillTop.RossFork.CeeVee(0..7) } - row: 0 - bus: 1 - unit: 0 - match: { 0: HillTop.RossFork.CeeVee(0..7), 8: HillTop.RossFork.CeeVee(8..11) } - 0x*000: _Boonsboro - miss: run_table - condition: - expression: "(HillTop.RossFork.CeeVee != 0)" - true: _Lindsborg - false: _Boonsboro - hit: [ [], _Redfield, _Magasco ] - miss: _Redfield - instruction: _Lindsborg(action, $DEFAULT) - actions: - Balmorhea(1, 20): - - default_action: { allowed: true } - - handle: 0x2000003e - - next_table: 1 - - set HillTop.RossFork.Lowes, 1 - Sequim(2, 0): - - default_action: { allowed: true } - - handle: 0x2000003f - - next_table: 2 - default_action: Sequim - ternary_match _Boonsboro 14: - p4: { name: Boonsboro, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Bicknell: { type: ternary, size: 12, full_size: 12, key_name: "RossFork.Bicknell" } - HillTop.RossFork.Adona: { type: ternary, size: 24, full_size: 24, key_name: "RossFork.Adona" } - HillTop.RossFork.Connell: { type: ternary, size: 24, full_size: 24, key_name: "RossFork.Connell" } - HillTop.RossFork.Naruna: { type: ternary, size: 3, full_size: 3, key_name: "RossFork.Naruna" } - HillTop.Lamona.Whitefish: { type: ternary, size: 2, full_size: 2, key_name: "Lamona.Whitefish" } - row: [ 6, 7 ] - bus: [ 0, 0 ] - column: - - 0 - - 0 - input_xbar: - ternary group 10: { 0: HillTop.RossFork.Adona(22..23), 8: HillTop.RossFork.Connell.16-23, 16: HillTop.RossFork.Adona(6..21), 32: HillTop.RossFork.Bicknell(8..11) } - ternary group 11: { 0: HillTop.RossFork.Connell.0-15(8..15), 8: HillTop.RossFork.Bicknell(0..7), 21: HillTop.RossFork.Naruna.2-2, 24: HillTop.RossFork.Connell.0-15(0..7), 35: HillTop.RossFork.Naruna.0-1 } - byte group 5: { 0: HillTop.Lamona.Whitefish, 2: HillTop.RossFork.Adona(0..5) } - match: - - { group: 10, byte_group: 5, byte_config: 0, dirtcam: 0x555 } - - { group: 11, byte_group: 5, byte_config: 1, dirtcam: 0x555 } - hit: [ _Redfield, _Redfield, _Twain ] - miss: _Redfield - indirect: _Boonsboro$tind - ternary_indirect _Boonsboro$tind: - row: 0 - bus: 0 - column: 2 - input_xbar: - ternary group 10: { 0: HillTop.RossFork.Adona(22..23), 8: HillTop.RossFork.Connell.16-23, 16: HillTop.RossFork.Adona(6..21), 32: HillTop.RossFork.Bicknell(8..11) } - ternary group 11: { 0: HillTop.RossFork.Connell.0-15(8..15), 8: HillTop.RossFork.Bicknell(0..7), 21: HillTop.RossFork.Naruna.2-2, 24: HillTop.RossFork.Connell.0-15(0..7), 35: HillTop.RossFork.Naruna.0-1 } - byte group 5: { 0: HillTop.Lamona.Whitefish, 2: HillTop.RossFork.Adona(0..5) } - format: { action: 0..1 } - instruction: _Boonsboro$tind(action, $DEFAULT) - actions: - Aniak(0, 0): - - default_action: { allowed: true } - - handle: 0x20000039 - - next_table: 0 - Crannell(1, 22): - - default_action: { allowed: true } - - handle: 0x2000003a - - next_table: 1 - - set HillTop.Ovett.Hematite, 1 - Sequim(2, 23): - - default_action: { allowed: true } - - handle: 0x2000003b - - next_table: 2 - default_action: Sequim - exact_match _Twain 15: - p4: { name: Twain, size: 2048, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Bicknell: { type: exact, size: 12, full_size: 12, key_name: "RossFork.Bicknell" } - HillTop.RossFork.Adona: { type: exact, size: 24, full_size: 24, key_name: "RossFork.Adona" } - HillTop.RossFork.Connell: { type: exact, size: 24, full_size: 24, key_name: "RossFork.Connell" } - row: 0 - bus: 0 - column: [ 6, 7 ] - stash: - row: [ 0 ] - col: [ 6 ] - unit: [ 0 ] - ways: - - [3, 2, 0x0, [0, 6]] - - [3, 3, 0x0, [0, 7]] - input_xbar: - exact group 4: { 2: HillTop.RossFork.Adona, 32: HillTop.RossFork.Connell.16-23, 40: HillTop.RossFork.Bicknell(8..11), 48: HillTop.RossFork.Bicknell(0..7), 56: HillTop.RossFork.Connell.0-15(8..15), 64: HillTop.RossFork.Connell.0-15(0..7) } - hash 8: - 20..23: random(HillTop.RossFork.Adona(4..21), HillTop.RossFork.Connell.16-23, HillTop.RossFork.Bicknell(0..7), HillTop.RossFork.Connell.0-15(8..15)) ^ HillTop.RossFork.Adona(0..3) - 24..25: random(HillTop.RossFork.Adona(4..21), HillTop.RossFork.Connell.16-23, HillTop.RossFork.Bicknell(0..7), HillTop.RossFork.Connell.0-15(8..15)) ^ HillTop.RossFork.Adona(22..23) - 26..29: random(HillTop.RossFork.Adona(4..21), HillTop.RossFork.Connell.16-23, HillTop.RossFork.Bicknell(0..7), HillTop.RossFork.Connell.0-15(8..15)) ^ HillTop.RossFork.Bicknell(8..11) - 31..34: random(HillTop.RossFork.Adona(4..21), HillTop.RossFork.Connell.16-23, HillTop.RossFork.Bicknell(0..7), HillTop.RossFork.Connell.0-15(8..15)) ^ HillTop.RossFork.Adona(0..3) - 35..36: random(HillTop.RossFork.Adona(4..21), HillTop.RossFork.Connell.16-23, HillTop.RossFork.Bicknell(0..7), HillTop.RossFork.Connell.0-15(8..15)) ^ HillTop.RossFork.Adona(22..23) - 37..39: random(HillTop.RossFork.Adona(4..21), HillTop.RossFork.Connell.16-23, HillTop.RossFork.Bicknell(0..7), HillTop.RossFork.Connell.0-15(8..15)) ^ HillTop.RossFork.Bicknell(8..10) - 30: random(HillTop.RossFork.Adona(4..21), HillTop.RossFork.Connell.16-23, HillTop.RossFork.Bicknell(0..7), HillTop.RossFork.Connell.0-15(8..15)) ^ HillTop.RossFork.Bicknell(11) - hash 9: - 20..29: random(HillTop.RossFork.Connell.0-15(0..7)) - 30..39: random(HillTop.RossFork.Connell.0-15(0..7)) - hash group 3: - table: [8, 9] - seed: 0x51fe300000 - format: { version(0): 112..115, match(0): [32..55, 86..87, 56..79 ] } - match: [ HillTop.RossFork.Bicknell(0..7), HillTop.RossFork.Connell.0-15(0..7), HillTop.RossFork.Connell.0-15(8..15), HillTop.RossFork.Adona(4..5), HillTop.RossFork.Adona(6..13), HillTop.RossFork.Adona(14..21), HillTop.RossFork.Connell.16-23 ] - hit: [ _Redfield ] - miss: _Redfield - instruction: _Twain($DEFAULT, $DEFAULT) - actions: - Crannell(0, 24): - - default_action: { allowed: true } - - handle: 0x2000003c - - next_table: 0 - - set HillTop.Ovett.Hematite, 1 - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x2000003d - - next_table: 0 - default_only_action: NoAction - exact_match _Magasco 12: - p4: { name: Magasco, size: 8192, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Goldsboro: { type: exact, size: 24, full_size: 24, key_name: "RossFork.Goldsboro" } - HillTop.RossFork.Fabens: { type: exact, size: 24, full_size: 24, key_name: "RossFork.Fabens" } - HillTop.RossFork.CeeVee: { type: exact, size: 12, full_size: 12, key_name: "RossFork.CeeVee" } - HillTop.RossFork.Quebrada: { type: exact, size: 20, full_size: 20, key_name: "RossFork.Quebrada" } - row: [ 6, 7 ] - bus: [ 0, 0 ] - column: - - [ 6, 7, 8 ] - - [ 6, 7, 8 ] - stash: - row: [ 6, 7 ] - col: [ 6, 6 ] - unit: [ 0, 0 ] - ways: - - [3, 0, 0x1, [7, 6], [6, 6], [7, 7], [6, 7]] - - [3, 1, 0x0, [7, 8], [6, 8]] - input_xbar: - exact group 3: { 0: HillTop.RossFork.Quebrada, 24: HillTop.RossFork.Goldsboro.8-23(8..15), 32: HillTop.RossFork.Fabens, 56: HillTop.RossFork.CeeVee(8..11), 64: HillTop.RossFork.Goldsboro.0-7, 80: HillTop.RossFork.Goldsboro.8-23(0..7), 96: HillTop.RossFork.CeeVee(0..7) } - hash 6: - 8..9: random(HillTop.RossFork.Quebrada(0..15), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Fabens) - 0..3: random(HillTop.RossFork.Quebrada(0..15), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Fabens) ^ HillTop.RossFork.Quebrada(16..19) - 4..7: random(HillTop.RossFork.Quebrada(0..15), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Fabens) ^ HillTop.RossFork.CeeVee(8..11) - 40: random(HillTop.RossFork.Quebrada(0..15), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Fabens) - 10: random(HillTop.RossFork.Quebrada(0..15), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Fabens) - 19: random(HillTop.RossFork.Quebrada(0..15), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Fabens) - 11..14: random(HillTop.RossFork.Quebrada(0..15), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Fabens) ^ HillTop.RossFork.Quebrada(16..19) - 15..18: random(HillTop.RossFork.Quebrada(0..15), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.Fabens) ^ HillTop.RossFork.CeeVee(8..11) - hash 7: - 0..7: random(HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(2..7), HillTop.RossFork.CeeVee(0..7)) - 8..9: random(HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(2..7), HillTop.RossFork.CeeVee(0..7)) ^ HillTop.RossFork.Goldsboro.8-23(0..1) - 40: random(HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(2..7), HillTop.RossFork.CeeVee(0..7)) - 11..18: random(HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(2..7), HillTop.RossFork.CeeVee(0..7)) - 19: random(HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(2..7), HillTop.RossFork.CeeVee(0..7)) ^ HillTop.RossFork.Goldsboro.8-23(0) - 10: random(HillTop.RossFork.Goldsboro.0-7, HillTop.RossFork.Goldsboro.8-23(2..7), HillTop.RossFork.CeeVee(0..7)) ^ HillTop.RossFork.Goldsboro.8-23(1) - hash group 3: - table: [6, 7] - seed: 0x24a4e - format: { action(0): 0..1, version(0): 4..7, match(0): [74..79, 8..71 ], action(1): 2..3, version(1): 244..247, match(1): [218..223, 80..127, 200..215 ], action(2): 128..129, version(2): 240..243, match(2): 130..199 } - match: [ HillTop.RossFork.Goldsboro.8-23(2..7), HillTop.RossFork.Goldsboro.8-23(8..15), HillTop.RossFork.CeeVee(0..7), HillTop.RossFork.Quebrada(0..7), HillTop.RossFork.Quebrada(8..15), HillTop.RossFork.Fabens(0..7), HillTop.RossFork.Fabens(8..15), HillTop.RossFork.Fabens(16..23), HillTop.RossFork.Goldsboro.0-7 ] - gateway: - name: cond-10 - input_xbar: - exact group 0: { 44: HillTop.Quinault.Foster, 88: HillTop.Lamona.Pachuta, 102: HillTop.RossFork.Welcome, 104: HillTop.RossFork.Teigen } - row: 1 - bus: 0 - unit: 0 - match: { 4: HillTop.Quinault.Foster, 8: HillTop.Lamona.Pachuta, 16: HillTop.RossFork.Teigen, 30: HillTop.RossFork.Welcome } - 0b*0*************0*******1**00: run_table - miss: _Boonsboro - condition: - expression: "(HillTop.Quinault.Foster == 0 && HillTop.Lamona.Pachuta == 1 && HillTop.RossFork.Teigen == 0 && HillTop.RossFork.Welcome == 0)" - true: _Magasco - false: _Boonsboro - hit: [ _Boonsboro ] - miss: _Boonsboro - instruction: _Magasco(action, $DEFAULT) - actions: - Swisshome(1, 0): - - default_action: { allowed: true } - - handle: 0x20000040 - - next_table: 0 - Earling(2, 21): - - default_action: { allowed: true } - - handle: 0x20000041 - - next_table: 0 - - set HillTop.Quinault.Foster, 2 - default_action: Earling - idletime: - row: 0 - bus: 0 - column: [ 0, 1, 2, 3, 4 ] - precision: 3 - sweep_interval: 7 - notification: two_way - per_flow_enable: true -stage 2 ingress: - hash_action _Redfield 0: - p4: { name: Redfield, size: 256, disable_atomic_modify : true } - p4_param_order: - HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } - row: 5 - bus: 1 - hash_dist: - 0: { hash: 0, mask: 0xff, shift: 5 } - input_xbar: - exact group 0: { 4: HillTop.Bessie.Miranda } - hash 0: - 0..7: stripe(HillTop.Bessie.Miranda) - hash group 0: - table: [0] - seed: 0x0 - gateway: - name: _Redfield-gateway - row: 3 - bus: 0 - unit: 1 - 0x0: _Covert - miss: _Covert - condition: - expression: "true(always hit)" - true: _Covert - false: _Covert - next: [] - action: _Redfield$action_data(hash_dist 0, $DEFAULT) - instruction: _Redfield($DEFAULT, $DEFAULT) - actions: - Rockfield(0, 1): - - p4_param_order: { Kaluaaha: 16, Calcasieu: 16, Chevak: 16, Mendocino: 16, LasVegas: 8, PineCity: 6, Exton: 8, Noyes: 8, Peebles: 1 } - - default_action: { allowed: true } - - handle: 0x20000044 - - next_table: 0 - - { Peebles: $adf_b0(5..5), Noyes: $adf_b1(0..7), LasVegas: $adf_b2(0..7), Exton: $adf_b3(0..7), Chevak: $adf_h2(0..15), Mendocino: $adf_h3(0..15), Calcasieu: $adf_h4(0..15), Kaluaaha: $adf_h5(0..15), PineCity: $adf_h6(6..11) } - - and HillTop.Savery.Kaluaaha, HillTop.Bessie.Kaluaaha, Kaluaaha - - and HillTop.Savery.Calcasieu, HillTop.Bessie.Calcasieu, Calcasieu - - and HillTop.Savery.Chevak, HillTop.Bessie.Chevak, Chevak - - and HillTop.Savery.Mendocino, HillTop.Bessie.Mendocino, Mendocino - - and HillTop.Savery.LasVegas, HillTop.Bessie.LasVegas, LasVegas - - and HillTop.Savery.Exton, HillTop.Bessie.Exton, Exton - - and HillTop.Savery.Noyes, HillTop.Bessie.Noyes, Noyes - - set Millston.Belgrade.Florin.0-15, 0 - - and B10, Peebles, B9 - - and H85, PineCity, H90 - default_action: Rockfield - default_action_parameters: - Kaluaaha: "0xffff" - Calcasieu: "0xffff" - Chevak: "0xffff" - Mendocino: "0xffff" - LasVegas: "0xff" - PineCity: "0x3f" - Exton: "0xff" - Noyes: "0xff" - Peebles: "0x1" - action _Redfield$action_data: - p4: { name: Redfield$action, how_referenced: direct } - row: 12 - column: 4 - vpns: [ 0 ] - home_row: - - 12 - format Rockfield: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_b2: 16..23, $adf_b3: 24..31, $adf_h2: 32..47, $adf_h3: 48..63, $adf_h4: 64..79, $adf_h5: 80..95, $adf_h6: 96..111 } - action_bus: { 16 : $adf_b0, 17 : $adf_b1, 18 : $adf_b2, 19 : $adf_b3, 64..65 : $adf_h4, 66..67 : $adf_h5, 68..69 : $adf_h6, 32..33 : $adf_h2, 34..35 : $adf_h3 } - hash_action _Covert 1: - p4: { name: Covert, size: 4096, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.CeeVee: { type: exact, size: 12, full_size: 12, key_name: "RossFork.CeeVee" } - row: 4 - bus: 1 - hash_dist: - 1: { hash: 0, mask: 0xfff, shift: 2 } - input_xbar: - exact group 0: { 16: HillTop.RossFork.CeeVee } - hash 0: - 16..27: stripe(HillTop.RossFork.CeeVee) - hash group 0: - table: [0] - seed: 0x0 - gateway: - name: _Covert-gateway - row: 2 - bus: 0 - unit: 1 - 0x0: _Bucklin - miss: _Bucklin - condition: - expression: "true(always hit)" - true: _Bucklin - false: _Bucklin - next: [] - action: _Covert$action_data(hash_dist 1, $DEFAULT) - instruction: _Covert($DEFAULT, $DEFAULT) - actions: - Terral(0, 2): - - p4_param_order: { Brinkman: 1, HighRock: 1, WebbCity: 1 } - - default_action: { allowed: true } - - handle: 0x20000047 - - next_table: 0 - - { HighRock: $adf_h0(0..0), Brinkman: $adf_b0(1..1) } - - set HillTop.RossFork.Brinkman, Brinkman - - set HillTop.RossFork.Parkland, HighRock - default_action: Terral - default_action_parameters: - Brinkman: "0x0" - HighRock: "0x0" - WebbCity: "0x0" - action _Covert$action_data: - p4: { name: Covert$action, how_referenced: direct } - row: 14 - column: 4 - vpns: [ 0 ] - home_row: - - 14 - format Terral: { $adf_h0: 0..15, $adf_b0: 0..7 } - action_bus: { 0 : $adf_b0, 36..37 : $adf_h0 } - hash_action _Bucklin 2: - p4: { name: Bucklin, size: 1, disable_atomic_modify : true } - row: 0 - bus: 1 - hash_dist: - 2: { hash: 0, mask: 0xffff, shift: 0 } - input_xbar: - exact group 0: { 32: Millston.Maumee.Kaluaaha.32-63, 64: Millston.Maumee.Calcasieu.96-127, 96: Millston.Maumee.Kaluaaha.0-31 } - exact group 1: { 0: Millston.Maumee.Kaluaaha.64-95, 32: Millston.Maumee.Kaluaaha.96-127, 64: Millston.Maumee.Calcasieu.0-31, 96: Millston.Maumee.Calcasieu.32-63 } - exact group 2: { 0: Millston.Maumee.Calcasieu.64-95, 32: Millston.Maumee.Maryhill.0-15, 48: Millston.Maumee.Maryhill.16-19, 56: Millston.Maumee.Dassel } - hash 0: - 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 188: Millston.Maumee.Kaluaaha.32-63 }, { })), 0..15) - hash 1: - 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 124: Millston.Maumee.Calcasieu.96-127, 156: Millston.Maumee.Kaluaaha.0-31 }, { })), 0..15) - hash 2: - 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 220: Millston.Maumee.Kaluaaha.64-95, 252: Millston.Maumee.Kaluaaha.96-127 }, { })), 0..15) - hash 3: - 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 28: Millston.Maumee.Calcasieu.0-31, 60: Millston.Maumee.Calcasieu.32-63 }, { })), 0..15) - hash 4: - 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 284, { 0: Millston.Maumee.Dassel, 8: Millston.Maumee.Maryhill.0-15, 24: Millston.Maumee.Maryhill.16-19, 92: Millston.Maumee.Calcasieu.64-95 }, { })), 0..15) - hash group 0: - table: [0, 1, 2, 3, 4] - seed: 0x0 - gateway: - name: cond-11 - input_xbar: - exact group 2: { 68: Millston.GlenAvon.$valid } - row: 0 - bus: 1 - unit: 0 - payload: 0x1 - format: { action: 0..0 } - match: { 4: Millston.GlenAvon.$valid } - 0b***1: run_table - miss: _Forepaugh - condition: - expression: "(Millston.GlenAvon.$valid == 1)" - true: _Decherd - false: _Forepaugh - next: _Decherd - action_bus: { 40..41 : hash_dist(2, lo) } - instruction: _Bucklin(action, $DEFAULT) - actions: - McKenney(1, 3): - - default_action: { allowed: true } - - handle: 0x20000046 - - next_table: 0 - - set H59, hash_dist(2, 0..15) - default_action: McKenney - hash_action _Decherd 3: - p4: { name: Decherd, size: 1, disable_atomic_modify : true } - row: 3 - bus: 1 - hash_dist: - 3: { hash: 1, mask: 0xffff, shift: 0 } - input_xbar: - exact group 3: { 0: Millston.GlenAvon.Kaluaaha, 32: Millston.GlenAvon.Calcasieu, 64: Millston.GlenAvon.Ocoee } - hash 6: - 0..15: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 72, { 0: Millston.GlenAvon.Calcasieu, 32: Millston.GlenAvon.Kaluaaha }, { })), 0..15) - hash 7: - 0..15: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 72, { 64: Millston.GlenAvon.Ocoee }, { })), 0..15) - hash group 1: - table: [6, 7] - seed: 0x0 - gateway: - name: _Decherd-gateway - row: 1 - bus: 0 - unit: 1 - 0x0: _Forepaugh - miss: _Forepaugh - condition: - expression: "true(always hit)" - true: _Forepaugh - false: _Forepaugh - next: [] - action_bus: { 44..45 : hash_dist(3, lo) } - instruction: _Decherd($DEFAULT, $DEFAULT) - actions: - Kellner(0, 4): - - default_action: { allowed: true } - - handle: 0x20000045 - - next_table: 0 - - set H59, hash_dist(3, 0..15) - default_action: Kellner - hash_action _Forepaugh 4: - p4: { name: Forepaugh, size: 1, disable_atomic_modify : true } - row: 2 - bus: 1 - hash_dist: - 4: { hash: 1, mask: 0xffff, shift: 0 } - input_xbar: - exact group 4: { 0: Millston.Shirley.Connell.16-23, 8: Millston.Shirley.Adona, 32: Millston.Shirley.Connell.0-15, 48: Millston.Shirley.Goldsboro.8-23, 64: Millston.Shirley.Fabens.8-23, 80: Millston.Shirley.McCaulley, 96: Millston.Shirley.Goldsboro.0-7, 104: Millston.Shirley.Fabens.0-7 } - hash 8: - 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 112, { 48: Millston.Shirley.Goldsboro.8-23, 64: Millston.Shirley.Connell.0-15, 80: Millston.Shirley.Connell.16-23, 88: Millston.Shirley.Adona }, { })), 0..15) - hash 9: - 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 112, { 0: Millston.Shirley.McCaulley, 16: Millston.Shirley.Fabens.0-7, 24: Millston.Shirley.Fabens.8-23, 40: Millston.Shirley.Goldsboro.0-7 }, { })), 0..15) - hash group 1: - table: [8, 9] - seed: 0x0 - gateway: - name: _Forepaugh-gateway - row: 0 - bus: 0 - unit: 1 - 0x0: cond-12 - miss: cond-12 - condition: - expression: "true(always hit)" - true: cond-12 - false: cond-12 - next: [] - action_bus: { 48..49 : hash_dist(4, lo) } - instruction: _Forepaugh($DEFAULT, $DEFAULT) - actions: - SanPablo(0, 5): - - default_action: { allowed: true } - - handle: 0x20000057 - - next_table: 0 - - set H58, hash_dist(4, 0..15) - default_action: SanPablo - gateway cond-12 5: - name: cond-12 - input_xbar: - exact group 2: { 77: HillTop.Ovett.Hematite, 85: HillTop.RossFork.Weyauwega, 94: HillTop.Murphy.Blairsden, 99: HillTop.Murphy.Standish } - row: 3 - bus: 1 - unit: 0 - match: { 5: HillTop.RossFork.Weyauwega, 13: HillTop.Ovett.Hematite, 19: HillTop.Murphy.Standish, 30: HillTop.Murphy.Blairsden } - 0b*0**********0*****1*******0: _Levasy$st0 - miss: _Bigspring - condition: - expression: "(HillTop.RossFork.Weyauwega == 0 && HillTop.Ovett.Hematite == 1 && HillTop.Murphy.Standish == 0 && HillTop.Murphy.Blairsden == 0)" - true: _Levasy$st0 - false: _Bigspring - ternary_match _Levasy$st0 6: - p4: { name: Levasy, size: 4096, disable_atomic_modify : true } - p4_param_order: - HillTop.Ovett.Manilla: { type: exact, size: 8, full_size: 8, key_name: "Ovett.Manilla" } - HillTop.Sublett.Calcasieu: { type: lpm, size: 128, full_size: 128, key_name: "Sublett.Calcasieu" } - row: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - input_xbar: - ternary group 0: { 0: HillTop.Sublett.Calcasieu.96-127(0..7), 8: HillTop.Sublett.Calcasieu.0-31(8..15), 16: HillTop.Sublett.Calcasieu.96-127(16..31), 32: HillTop.Sublett.Calcasieu.0-31(0..7) } - ternary group 1: { 0: HillTop.Sublett.Calcasieu.0-31(16..31), 16: HillTop.Sublett.Calcasieu.32-63(0..23) } - ternary group 2: { 0: HillTop.Sublett.Calcasieu.32-63(24..31), 8: HillTop.Sublett.Calcasieu.64-95 } - ternary group 3: { 0: HillTop.Ovett.Manilla } - byte group 0: { 0: HillTop.Sublett.Calcasieu.96-127(8..15) } - match: - - { group: 0, byte_group: 0, byte_config: 0, dirtcam: 0x555 } - - { group: 1, byte_group: 0, byte_config: 1, dirtcam: 0x555 } - - { group: 2, byte_config: 3, dirtcam: 0x155 } - - { group: 3, dirtcam: 0x1 } - gateway: - name: cond-13 - input_xbar: - exact group 5: { 5: HillTop.RossFork.Naruna.2-2, 8: HillTop.Ovett.Hammond.1-3(0), 19: HillTop.RossFork.Naruna.0-1 } - row: 2 - bus: 1 - unit: 0 - match: { 16: HillTop.Ovett.Hammond.1-3(0), 3: HillTop.RossFork.Naruna.0-1, 13: HillTop.RossFork.Naruna.2-2 } - 0b*******1**0********10: run_table - miss: _Glenoma_0 - condition: - expression: "(HillTop.Ovett.Hammond & 2 == 2 && HillTop.RossFork.Naruna == 2)" - true: _Levasy$st0 - false: _Glenoma_0 - hit: [ _Bigspring ] - miss: _Levasy$st1 - indirect: _Levasy$st0$tind - idletime: - row: 0 - bus: 0 - column: 0 - precision: 1 - sweep_interval: 7 - notification: enable - per_flow_enable: false - ternary_indirect _Levasy$st0$tind: - row: 0 - bus: 0 - column: 4 - input_xbar: - ternary group 0: { 0: HillTop.Sublett.Calcasieu.96-127(0..7), 8: HillTop.Sublett.Calcasieu.0-31(8..15), 16: HillTop.Sublett.Calcasieu.96-127(16..31), 32: HillTop.Sublett.Calcasieu.0-31(0..7) } - ternary group 1: { 0: HillTop.Sublett.Calcasieu.0-31(16..31), 16: HillTop.Sublett.Calcasieu.32-63(0..23) } - ternary group 2: { 0: HillTop.Sublett.Calcasieu.32-63(24..31), 8: HillTop.Sublett.Calcasieu.64-95 } - ternary group 3: { 0: HillTop.Ovett.Manilla } - byte group 0: { 0: HillTop.Sublett.Calcasieu.96-127(8..15) } - format: { action: 0..2, immediate: 3..16 } - action_bus: { 52..53 : immediate(0..13) } - instruction: _Levasy$st0$tind(action, $DEFAULT) - actions: - Tofte(1, 6): - - p4_param_order: { Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x20000048 - - next_table: 0 - - { Bonduel: immediate(0..13) } - - set HillTop.Naubinway.Bonduel, Bonduel - Jerico(2, 8): - - p4_param_order: { Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x20000049 - - next_table: 0 - - { Bonduel: immediate(0..13) } - - set HillTop.Naubinway.Ayden, 2 - - set HillTop.Naubinway.Bonduel, Bonduel - Wabbaseka(3, 10): - - p4_param_order: { Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x2000004a - - next_table: 0 - - { Bonduel: immediate(0..13) } - - set HillTop.Naubinway.Ayden, 3 - - set HillTop.Naubinway.Bonduel, Bonduel - Clearmont(4, 12): - - p4_param_order: { Sardinia: 14 } - - default_action: { allowed: true } - - handle: 0x2000004b - - next_table: 0 - - { Sardinia: immediate(0..13) } - - set HillTop.Naubinway.Sardinia, Sardinia - - set HillTop.Naubinway.Ayden, 1 - Ponder(-1, 14): - - default_only_action: { allowed: true } - - handle: 0x2000004c - - next_table: 0 - - { } - - set HillTop.Naubinway.Bonduel, 1 - default_only_action: Ponder - exact_match _Glenoma_0 7: - p4: { name: Glenoma, size: 97280, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Ocoee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } - HillTop.RossFork.Laxon: { type: exact, size: 32, full_size: 32, key_name: "RossFork.Laxon" } - HillTop.RossFork.Crozet: { type: exact, size: 16, full_size: 16, key_name: "RossFork.Crozet" } - HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } - Millston.Grays.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Grays.Mendocino" } - row: [ 6, 7, 4, 5, 2, 3, 0, 1 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 6, 7, 8, 9, 10 ] - - [ 2, 3, 6, 7, 8, 9, 10 ] - - [ 2, 3, 6, 7, 8, 9, 10 ] - - [ 2, 3, 6, 7, 8, 9, 10 ] - - [ 2, 3, 6, 7, 8, 9, 10 ] - - [ 2, 3, 6, 7, 8, 9, 10 ] - - [ 2, 3, 6, 7 ] - - [ 2, 3, 6, 7 ] - stash: - row: [ 6, 7 ] - col: [ 2, 2 ] - unit: [ 0, 0 ] - ways: - - [2, 0, 0x3, [7, 2], [6, 2], [7, 3], [6, 3], [7, 6], [6, 6], [7, 7], [6, 7]] - - [2, 1, 0xc, [7, 8], [6, 8], [7, 9], [6, 9], [7, 10], [6, 10], [5, 2], [4, 2]] - - [2, 2, 0x30, [5, 3], [4, 3], [5, 6], [4, 6], [5, 7], [4, 7], [5, 8], [4, 8]] - - [2, 3, 0xc0, [5, 9], [4, 9], [5, 10], [4, 10], [3, 2], [2, 2], [3, 3], [2, 3]] - - [2, 0, 0x3, [3, 6], [2, 6], [3, 7], [2, 7], [3, 8], [2, 8], [3, 9], [2, 9]] - - [2, 1, 0xc, [3, 10], [2, 10], [1, 2], [0, 2], [1, 3], [0, 3], [1, 6], [0, 6]] - - [2, 2, 0x0, [1, 7], [0, 7]] - input_xbar: - exact group 6: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.RossFork.Laxon, 64: Millston.Grays.Mendocino, 80: HillTop.RossFork.Crozet, 96: HillTop.RossFork.Ocoee } - hash 12: - 0..9: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 40..41: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 10..19: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 42..43: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 20..29: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 44..45: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 30..39: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 46..47: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - hash 13: - 0..1: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) - 2..9: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee - 40..41: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) - 11..12: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) - 13..19: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..6) - 10: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(7) - 42..43: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) - 22..23: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) - 24..29: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..5) - 20..21: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(6..7) - 44..45: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) - 33..34: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) - 35..39: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..4) - 30..32: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(5..7) - 46..47: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) - hash group 2: - table: [12, 13] - seed: 0x22703fbf7838 - format: { action(0): 0..2, immediate(0): 3..16, version(0): 112..115, match(0): [18..23, 32..111, 24..31 ], action(1): 128..130, immediate(1): 131..144, version(1): 240..243, match(1): [146..151, 160..239, 152..159 ] } - match: [ Millston.Grays.Mendocino(2..7), Millston.Grays.Mendocino(8..15), HillTop.RossFork.Crozet(0..7), HillTop.RossFork.Crozet(8..15), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31), HillTop.RossFork.Laxon(0..7), HillTop.RossFork.Laxon(8..15), HillTop.RossFork.Laxon(16..23), HillTop.RossFork.Laxon(24..31) ] - gateway: - name: cond-14 - input_xbar: - exact group 5: { 5: HillTop.RossFork.Naruna.2-2, 11: HillTop.Ovett.Hammond.0-0, 19: HillTop.RossFork.Naruna.0-1 } - row: 1 - bus: 1 - unit: 0 - match: { 19: HillTop.Ovett.Hammond.0-0, 3: HillTop.RossFork.Naruna.0-1, 13: HillTop.RossFork.Naruna.2-2 } - 0b****1*****0********01: run_table - miss: _Indios - condition: - expression: "(HillTop.Ovett.Hammond & 1 == 1 && HillTop.RossFork.Naruna == 1)" - true: _Glenoma_0 - false: _Indios - hit: [ [], _Bigspring, _Bigspring, _Bigspring, _Bigspring, _Bigspring, _Bigspring, _Baker_0 ] - miss: _Glenoma_0$st1 - action_bus: { 56..57 : immediate(0..13) } - action: _Glenoma_0$action_data($DIRECT, $DEFAULT) - instruction: _Glenoma_0(action, $DEFAULT) - actions: - Callao(1, 16): - - p4_param_order: { Calcasieu: 32, Bratt: 32, Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x2000004d - - next_table: 1 - - { Bratt.0-15: $adf_f0(0..15), Bonduel: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Bonduel, Bonduel - - set HillTop.RossFork.Suttle, 1 - Ambler(2, 18): - - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x2000004e - - next_table: 2 - - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Bonduel: immediate(0..13) } - - set HillTop.RossFork.DonaAna, Avondale - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Bonduel, Bonduel - - set HillTop.RossFork.Suttle, 1 - Wagener(3, 20): - - p4_param_order: { Calcasieu: 32, Bratt: 32, Sardinia: 14 } - - default_action: { allowed: true } - - handle: 0x2000004f - - next_table: 3 - - { Bratt.0-15: $adf_f0(0..15), Sardinia: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 1 - - set HillTop.Naubinway.Sardinia, Sardinia - - set HillTop.RossFork.Suttle, 1 - Olmitz(4, 22): - - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Sardinia: 14 } - - default_action: { allowed: true } - - handle: 0x20000050 - - next_table: 4 - - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Sardinia: immediate(0..13) } - - set HillTop.RossFork.DonaAna, Avondale - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 1 - - set HillTop.Naubinway.Sardinia, Sardinia - - set HillTop.RossFork.Suttle, 1 - Milano(5, 7): - - p4_param_order: { Kaluaaha: 32, Bratt: 32 } - - default_action: { allowed: true } - - handle: 0x20000051 - - next_table: 5 - - { Kaluaaha: $adf_f0(0..31), Bratt.0-15: $adf_f1(0..15) } - - set HillTop.Maddock.Kaluaaha, Kaluaaha - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Boerne, 1 - - set HillTop.RossFork.Suttle, 1 - Biggers(6, 9): - - p4_param_order: { Kaluaaha: 32, Avondale: 16, Bratt: 32 } - - default_action: { allowed: true } - - handle: 0x20000052 - - next_table: 6 - - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Kaluaaha: $adf_f1(0..31) } - - set HillTop.RossFork.Glenmora, Avondale - - set HillTop.Maddock.Kaluaaha, Kaluaaha - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Boerne, 1 - - set HillTop.RossFork.Suttle, 1 - Sequim(7, 0): - - default_action: { allowed: true } - - handle: 0x20000053 - - next_table: 7 - - { } - default_action: Sequim - idletime: - row: [ 4, 5 ] - bus: [ 0, 0 ] - column: - - [ 0, 1, 2, 3, 4, 5 ] - - 0 - precision: 1 - sweep_interval: 7 - notification: enable - per_flow_enable: false - action _Glenoma_0$action_data: - p4: { name: Glenoma$action } - row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ] - word: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - 5 - - 5 - - 5 - - 5 - - 5 - - [ 4, 5 ] - - 5 - - [ 4, 5 ] - - 5 - - [ 4, 5 ] - - 5 - - [ 4, 5 ] - - [ 4, 5 ] - - [ 4, 5 ] - - [ 2, 3, 4, 5 ] - - 5 - vpns: - - [ 0 ] - - [ 1 ] - - [ 2 ] - - [ 3 ] - - [ 4 ] - - [ 5, 6 ] - - [ 7 ] - - [ 8, 9 ] - - [ 10 ] - - [ 11, 12 ] - - [ 13 ] - - [ 14, 15 ] - - [ 16, 17 ] - - [ 18, 19 ] - - [ 20, 21, 22, 23 ] - - [ 24 ] - home_row: - - [ 15, 3 ] - format Callao: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - format Ambler: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - format Wagener: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - format Olmitz: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - format Milano: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Biggers: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - action_bus: { 62..63 : $adf_h1, 100..103 : $adf_f1, 60..63 : $adf_f0 } -stage 3 ingress: - exact_match _Indios 3: - p4: { name: Indios, size: 2, disable_atomic_modify : true } - p4_param_order: - HillTop.Ovett.Hammond: { type: exact, size: 1, full_size: 4, key_name: "Ovett.Hammond" } - HillTop.RossFork.Naruna: { type: exact, size: 3, full_size: 3, key_name: "RossFork.Naruna" } - row: 1 - bus: 1 - column: 7 - stash: - row: [ 1 ] - col: [ 7 ] - unit: [ 0 ] - ways: - - [1, 0, 0x0, [1, 7]] - input_xbar: - exact group 1: { 5: HillTop.RossFork.Naruna.2-2, 11: HillTop.Ovett.Hammond.0-0, 19: HillTop.RossFork.Naruna.0-1 } - hash 2: - 0: HillTop.RossFork.Naruna.2-2 - 1: HillTop.Ovett.Hammond.0-0 - 2..3: HillTop.RossFork.Naruna.0-1 - hash group 1: - table: [2] - seed: 0x0 - format: { action(0): 0..0, immediate(0): 1..14, version(0): 112..115 } - gateway: - name: cond-15 - input_xbar: - exact group 1: { 5: HillTop.RossFork.Naruna.2-2, 11: HillTop.Ovett.Hammond.0-0, 19: HillTop.RossFork.Naruna.0-1, 32: HillTop.Wisdom.Havana, 49: HillTop.RossFork.Parkland } - hash 2: - 40: HillTop.Ovett.Hammond.0-0 - hash group 1: - table: [2] - seed: 0x0 - row: 0 - bus: 0 - unit: 0 - match: { 16: HillTop.Wisdom.Havana, 25: HillTop.RossFork.Parkland, 32: HillTop.Ovett.Hammond.0-0, 3: HillTop.RossFork.Naruna.0-1, 13: HillTop.RossFork.Naruna.2-2 } - 0b*******1********0*************: run_table - 0b1***************0**0********11: run_table - miss: _Bigspring - condition: - expression: "(HillTop.Wisdom.Havana == 0 && (HillTop.RossFork.Parkland == 1 || HillTop.Ovett.Hammond & 1 == 1 && HillTop.RossFork.Naruna == 3))" - true: _Indios - false: _Bigspring - hit: [ _Bigspring ] - miss: _Bigspring - action_bus: { 44..45 : immediate(0..13) } - instruction: _Indios(action, $DEFAULT) - actions: - Fishers(1, 18): - - p4_param_order: { Philip: 14 } - - default_action: { allowed: true } - - handle: 0x20000056 - - next_table: 0 - - { Philip: immediate(0..13) } - - set HillTop.Naubinway.Bonduel, Philip - default_action: Fishers - default_action_parameters: - Philip: "0x0" - ternary_match _Baker_0 2: - p4: { name: Baker, size: 4096, disable_atomic_modify : true } - p4_param_order: - HillTop.Maddock.Kaluaaha: { type: ternary, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } - HillTop.RossFork.Ocoee: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } - HillTop.Bessie.Peebles: { type: ternary, size: 1, full_size: 1, key_name: "Bessie.Peebles" } - row: [ 8, 9, 10, 11, 0, 1, 2, 3 ] - bus: [ 0, 0, 0, 0, 1, 1, 1, 1 ] - column: - - 0 - - 0 - - 0 - - 0 - - 1 - - 1 - - 1 - - 1 - input_xbar: - ternary group 4: { 0: HillTop.Maddock.Kaluaaha(16..31), 16: HillTop.Maddock.Kaluaaha(0..15), 32: HillTop.RossFork.Ocoee } - byte group 1: { 5: HillTop.Bessie.Peebles } - match: - - { group: 4, byte_group: 1, byte_config: 1, dirtcam: 0x555 } - hit: [ _Bigspring ] - miss: _Bigspring - indirect: _Baker_0$tind - ternary_indirect _Baker_0$tind: - row: 0 - bus: 1 - column: 4 - input_xbar: - ternary group 4: { 0: HillTop.Maddock.Kaluaaha(16..31), 16: HillTop.Maddock.Kaluaaha(0..15), 32: HillTop.RossFork.Ocoee } - byte group 1: { 5: HillTop.Bessie.Peebles } - format: { action: 0..0, immediate: 1..12 } - action_bus: { 104..107 : immediate(0..11) } - instruction: _Baker_0$tind(action, $DEFAULT) - actions: - Recluse(0, 3): - - p4_param_order: { Moultrie: 12 } - - default_action: { allowed: true } - - handle: 0x20000054 - - next_table: 0 - - { Moultrie: immediate(0..11) } - - set HillTop.RossFork.Knierim, Moultrie - Arapahoe(1, 0): - - default_action: { allowed: true } - - handle: 0x20000055 - - next_table: 0 - - { } - default_action: Arapahoe - exact_match _Glenoma_0$st1 0: - p4: { name: Glenoma, size: 97280, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Ocoee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } - HillTop.RossFork.Laxon: { type: exact, size: 32, full_size: 32, key_name: "RossFork.Laxon" } - HillTop.RossFork.Crozet: { type: exact, size: 16, full_size: 16, key_name: "RossFork.Crozet" } - HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } - Millston.Grays.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Grays.Mendocino" } - row: [ 6, 7, 4, 5, 2, 3 ] - bus: [ 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 6, 7, 8, 9, 10 ] - - [ 2, 3, 6, 7, 8, 9, 10 ] - stash: - row: [ 6, 7 ] - col: [ 2, 2 ] - unit: [ 0, 0 ] - ways: - - [0, 0, 0x3, [7, 2], [6, 2], [7, 3], [6, 3], [7, 6], [6, 6], [7, 7], [6, 7]] - - [0, 1, 0xc, [7, 8], [6, 8], [7, 9], [6, 9], [7, 10], [6, 10], [7, 11], [6, 11]] - - [0, 2, 0x30, [5, 2], [4, 2], [5, 3], [4, 3], [5, 6], [4, 6], [5, 7], [4, 7]] - - [0, 3, 0xc0, [5, 8], [4, 8], [5, 9], [4, 9], [5, 10], [4, 10], [5, 11], [4, 11]] - - [0, 0, 0x3, [3, 2], [2, 2], [3, 3], [2, 3], [3, 6], [2, 6], [3, 7], [2, 7]] - - [0, 1, 0x4, [3, 8], [2, 8], [3, 9], [2, 9]] - - [0, 2, 0x0, [3, 10], [2, 10]] - input_xbar: - exact group 0: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.RossFork.Laxon, 64: Millston.Grays.Mendocino, 80: HillTop.RossFork.Crozet, 96: HillTop.RossFork.Ocoee } - hash 0: - 0..9: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 40..41: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 10..19: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 42..43: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 20..29: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 44..45: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 30..39: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 46..47: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - hash 1: - 0..1: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) - 2..9: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee - 40..41: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) - 11..12: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) - 13..19: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..6) - 10: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(7) - 42..43: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) - 22..23: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) - 24..29: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..5) - 20..21: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(6..7) - 44..45: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) - 33..34: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) - 35..39: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..4) - 30..32: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(5..7) - 46..47: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) - hash group 0: - table: [0, 1] - seed: 0x2db23bf76022 - format: { action(0): 0..2, immediate(0): 3..16, version(0): 112..115, match(0): [18..23, 32..111, 24..31 ], action(1): 128..130, immediate(1): 131..144, version(1): 240..243, match(1): [146..151, 160..239, 152..159 ] } - match: [ Millston.Grays.Mendocino(2..7), Millston.Grays.Mendocino(8..15), HillTop.RossFork.Crozet(0..7), HillTop.RossFork.Crozet(8..15), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31), HillTop.RossFork.Laxon(0..7), HillTop.RossFork.Laxon(8..15), HillTop.RossFork.Laxon(16..23), HillTop.RossFork.Laxon(24..31) ] - hit: [ _Bigspring, _Bigspring, _Bigspring, _Bigspring, _Bigspring, _Bigspring, _Baker_0 ] - miss: _Bigspring - action_bus: { 32..33 : immediate(0..13) } - action: _Glenoma_0$st1$action_data($DIRECT, $DEFAULT) - instruction: _Glenoma_0$st1(action, $DEFAULT) - actions: - Callao(0, 1): - - p4_param_order: { Calcasieu: 32, Bratt: 32, Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x2000004d - - next_table: 0 - - { Bratt.0-15: $adf_f0(0..15), Bonduel: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Bonduel, Bonduel - - set HillTop.RossFork.Suttle, 1 - Ambler(1, 2): - - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x2000004e - - next_table: 1 - - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Bonduel: immediate(0..13) } - - set HillTop.RossFork.DonaAna, Avondale - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Bonduel, Bonduel - - set HillTop.RossFork.Suttle, 1 - Wagener(2, 4): - - p4_param_order: { Calcasieu: 32, Bratt: 32, Sardinia: 14 } - - default_action: { allowed: true } - - handle: 0x2000004f - - next_table: 2 - - { Bratt.0-15: $adf_f0(0..15), Sardinia: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 1 - - set HillTop.Naubinway.Sardinia, Sardinia - - set HillTop.RossFork.Suttle, 1 - Olmitz(3, 6): - - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Sardinia: 14 } - - default_action: { allowed: true } - - handle: 0x20000050 - - next_table: 3 - - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Sardinia: immediate(0..13) } - - set HillTop.RossFork.DonaAna, Avondale - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 1 - - set HillTop.Naubinway.Sardinia, Sardinia - - set HillTop.RossFork.Suttle, 1 - Milano(4, 8): - - p4_param_order: { Kaluaaha: 32, Bratt: 32 } - - default_action: { allowed: true } - - handle: 0x20000051 - - next_table: 4 - - { Kaluaaha: $adf_f0(0..31), Bratt.0-15: $adf_f1(0..15) } - - set HillTop.Maddock.Kaluaaha, Kaluaaha - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Boerne, 1 - - set HillTop.RossFork.Suttle, 1 - Biggers(5, 10): - - p4_param_order: { Kaluaaha: 32, Avondale: 16, Bratt: 32 } - - default_action: { allowed: true } - - handle: 0x20000052 - - next_table: 5 - - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Kaluaaha: $adf_f1(0..31) } - - set HillTop.RossFork.Glenmora, Avondale - - set HillTop.Maddock.Kaluaaha, Kaluaaha - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Boerne, 1 - - set HillTop.RossFork.Suttle, 1 - Sequim(6, 0): - - default_action: { allowed: true } - - handle: 0x20000053 - - next_table: 6 - - { } - default_action: Sequim - idletime: - row: 4 - bus: 0 - column: [ 0, 1, 2, 3, 4, 5 ] - precision: 1 - sweep_interval: 7 - notification: enable - per_flow_enable: false - action _Glenoma_0$st1$action_data: - p4: { name: Glenoma$action } - row: [ 14, 12, 10, 8, 6, 5, 4, 3, 2, 1, 0 ] - word: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - [ 4, 5 ] - - 5 - - 5 - - [ 4, 5 ] - - [ 4, 5 ] - - 5 - - [ 4, 5 ] - - [ 2, 3, 4, 5 ] - - 5 - - [ 0, 1, 2, 3, 4, 5 ] - - 5 - vpns: - - [ 0, 1 ] - - [ 2 ] - - [ 3 ] - - [ 4, 5 ] - - [ 6, 7 ] - - [ 8 ] - - [ 9, 10 ] - - [ 11, 12, 13, 14 ] - - [ 15 ] - - [ 16, 17, 18, 19, 20, 21 ] - - [ 22 ] - home_row: - - [ 14, 3 ] - format Callao: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - format Ambler: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - format Wagener: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - format Olmitz: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - format Milano: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Biggers: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - action_bus: { 38..39 : $adf_h1, 100..103 : $adf_f1, 36..39 : $adf_f0 } - ternary_match _Levasy$st1 1: - p4: { name: Levasy, size: 4096, disable_atomic_modify : true } - p4_param_order: - HillTop.Ovett.Manilla: { type: exact, size: 8, full_size: 8, key_name: "Ovett.Manilla" } - HillTop.Sublett.Calcasieu: { type: lpm, size: 128, full_size: 128, key_name: "Sublett.Calcasieu" } - row: [ 0, 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - input_xbar: - ternary group 0: { 0: HillTop.Sublett.Calcasieu.96-127(0..7), 8: HillTop.Sublett.Calcasieu.0-31(8..15), 16: HillTop.Sublett.Calcasieu.96-127(16..31), 32: HillTop.Sublett.Calcasieu.0-31(0..7) } - ternary group 1: { 0: HillTop.Sublett.Calcasieu.0-31(16..31), 16: HillTop.Sublett.Calcasieu.32-63(0..23) } - ternary group 2: { 0: HillTop.Sublett.Calcasieu.32-63(24..31), 8: HillTop.Sublett.Calcasieu.64-95 } - ternary group 3: { 0: HillTop.Ovett.Manilla } - byte group 0: { 0: HillTop.Sublett.Calcasieu.96-127(8..15) } - match: - - { group: 0, byte_group: 0, byte_config: 0, dirtcam: 0x555 } - - { group: 1, byte_group: 0, byte_config: 1, dirtcam: 0x555 } - - { group: 2, byte_config: 3, dirtcam: 0x155 } - - { group: 3, dirtcam: 0x1 } - hit: [ _Bigspring ] - miss: _Bigspring - indirect: _Levasy$st1$tind - idletime: - row: 0 - bus: 0 - column: 0 - precision: 1 - sweep_interval: 7 - notification: enable - per_flow_enable: false - ternary_indirect _Levasy$st1$tind: - row: 1 - bus: 0 - column: 4 - input_xbar: - ternary group 0: { 0: HillTop.Sublett.Calcasieu.96-127(0..7), 8: HillTop.Sublett.Calcasieu.0-31(8..15), 16: HillTop.Sublett.Calcasieu.96-127(16..31), 32: HillTop.Sublett.Calcasieu.0-31(0..7) } - ternary group 1: { 0: HillTop.Sublett.Calcasieu.0-31(16..31), 16: HillTop.Sublett.Calcasieu.32-63(0..23) } - ternary group 2: { 0: HillTop.Sublett.Calcasieu.32-63(24..31), 8: HillTop.Sublett.Calcasieu.64-95 } - ternary group 3: { 0: HillTop.Ovett.Manilla } - byte group 0: { 0: HillTop.Sublett.Calcasieu.96-127(8..15) } - format: { action: 0..1, immediate: 2..15 } - action_bus: { 40..41 : immediate(0..13) } - instruction: _Levasy$st1$tind(action, $DEFAULT) - actions: - Tofte(0, 9): - - p4_param_order: { Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x20000048 - - next_table: 0 - - { Bonduel: immediate(0..13) } - - set HillTop.Naubinway.Bonduel, Bonduel - Jerico(1, 11): - - p4_param_order: { Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x20000049 - - next_table: 0 - - { Bonduel: immediate(0..13) } - - set HillTop.Naubinway.Ayden, 2 - - set HillTop.Naubinway.Bonduel, Bonduel - Wabbaseka(2, 12): - - p4_param_order: { Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x2000004a - - next_table: 0 - - { Bonduel: immediate(0..13) } - - set HillTop.Naubinway.Ayden, 3 - - set HillTop.Naubinway.Bonduel, Bonduel - Clearmont(3, 14): - - p4_param_order: { Sardinia: 14 } - - default_action: { allowed: true } - - handle: 0x2000004b - - next_table: 0 - - { Sardinia: immediate(0..13) } - - set HillTop.Naubinway.Sardinia, Sardinia - - set HillTop.Naubinway.Ayden, 1 - Ponder(-1, 16): - - default_only_action: { allowed: true } - - handle: 0x2000004c - - next_table: 0 - - { } - - set HillTop.Naubinway.Bonduel, 1 - default_only_action: Ponder - exact_match _Bigspring 4: - p4: { name: Bigspring, size: 4096, disable_atomic_modify : true } - p4_param_order: - HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } - HillTop.Savery.Kaluaaha: { type: exact, size: 16, full_size: 16, key_name: "Savery.Kaluaaha" } - HillTop.Savery.Calcasieu: { type: exact, size: 16, full_size: 16, key_name: "Savery.Calcasieu" } - HillTop.Savery.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Savery.Chevak" } - HillTop.Savery.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Savery.Mendocino" } - HillTop.Savery.LasVegas: { type: exact, size: 8, full_size: 8, key_name: "Savery.LasVegas" } - HillTop.Savery.PineCity: { type: exact, size: 6, full_size: 6, key_name: "Savery.PineCity" } - HillTop.Savery.Exton: { type: exact, size: 8, full_size: 8, key_name: "Savery.Exton" } - HillTop.Savery.Noyes: { type: exact, size: 8, full_size: 8, key_name: "Savery.Noyes" } - HillTop.Savery.Peebles: { type: exact, size: 1, full_size: 1, key_name: "Savery.Peebles" } - row: [ 3, 1 ] - bus: [ 1, 0 ] - column: - - 11 - - [ 2, 3, 6 ] - stash: - row: [ 3 ] - col: [ 11 ] - unit: [ 0 ] - ways: - - [1, 1, 0x6, [3, 11], [1, 2], [1, 3], [1, 6]] - input_xbar: - exact group 2: { 0: HillTop.Savery.Chevak, 16: HillTop.Savery.Mendocino, 32: HillTop.Savery.Calcasieu, 48: HillTop.Savery.Kaluaaha, 68: HillTop.Bessie.Miranda, 86: HillTop.Savery.PineCity, 101: HillTop.Savery.Peebles, 104: HillTop.Savery.Noyes, 112: HillTop.Savery.LasVegas, 120: HillTop.Savery.Exton } - hash 4: - 10..19: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) - 41..42: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) - hash 5: - 10..13: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(0..3) - 14..17: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(4..7) - 18..19: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(0..1) - 41: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(2) - 42: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.Peebles - hash group 1: - table: [4, 5] - seed: 0x20000072000 - format: { version(0): 112..115, match(0): [32..111, 0..7, 9..11 ] } - match: [ HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton, HillTop.Savery.Chevak(0..7), HillTop.Savery.Chevak(8..15), HillTop.Savery.Mendocino(0..7), HillTop.Savery.Mendocino(8..15), HillTop.Savery.Calcasieu(0..7), HillTop.Savery.Calcasieu(8..15), HillTop.Savery.Kaluaaha(0..7), HillTop.Savery.Kaluaaha(8..15), HillTop.Savery.PineCity(3..5) ] - hit: [ _LasLomas ] - miss: _LasLomas - action: _Bigspring$action_data($DIRECT, $DEFAULT) - instruction: _Bigspring($DEFAULT, $DEFAULT) - actions: - Unionvale(0, 5): - - p4_param_order: { Cornell: 32 } - - default_action: { allowed: true } - - handle: 0x20000058 - - next_table: 0 - - { Cornell: $adf_f0(0..31) } - - maxu HillTop.Mausdale.Kenney, HillTop.Mausdale.Kenney, Cornell - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x20000059 - - next_table: 0 - - { } - default_only_action: NoAction - action _Bigspring$action_data: - p4: { name: Bigspring$action } - row: 10 - column: 4 - vpns: [ 0 ] - home_row: - - 10 - format Unionvale: { $adf_f0: 0..31 } - action_bus: { 112..115 : $adf_f0 } - hash_action _LasLomas 5: - p4: { name: LasLomas, size: 256, disable_atomic_modify : true } - p4_param_order: - HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } - row: 2 - bus: 1 - hash_dist: - 0: { hash: 2, mask: 0xff, shift: 5 } - input_xbar: - exact group 1: { 68: HillTop.Bessie.Miranda } - hash 3: - 0..7: stripe(HillTop.Bessie.Miranda) - hash group 2: - table: [3] - seed: 0x0 - gateway: - name: _LasLomas-gateway - row: 1 - bus: 0 - unit: 0 - 0x0: _Anita - miss: _Anita - condition: - expression: "true(always hit)" - true: _Anita - false: _Anita - next: [] - action: _LasLomas$action_data(hash_dist 0, $DEFAULT) - instruction: _LasLomas($DEFAULT, $DEFAULT) - actions: - Crystola(0, 7): - - p4_param_order: { Kaluaaha: 16, Calcasieu: 16, Chevak: 16, Mendocino: 16, LasVegas: 8, PineCity: 6, Exton: 8, Noyes: 8, Peebles: 1 } - - default_action: { allowed: true } - - handle: 0x2000005a - - next_table: 0 - - { Peebles: $adf_b0(5..5), Noyes: $adf_b1(0..7), LasVegas: $adf_b2(0..7), Exton: $adf_b3(0..7), Chevak: $adf_h2(0..15), Mendocino: $adf_h3(0..15), Calcasieu: $adf_h4(0..15), Kaluaaha: $adf_h5(0..15), PineCity: $adf_h6(6..11) } - - and HillTop.Savery.Kaluaaha, HillTop.Bessie.Kaluaaha, Kaluaaha - - and HillTop.Savery.Calcasieu, HillTop.Bessie.Calcasieu, Calcasieu - - and HillTop.Savery.Chevak, HillTop.Bessie.Chevak, Chevak - - and HillTop.Savery.Mendocino, HillTop.Bessie.Mendocino, Mendocino - - and HillTop.Savery.LasVegas, HillTop.Bessie.LasVegas, LasVegas - - and HillTop.Savery.Exton, HillTop.Bessie.Exton, Exton - - and HillTop.Savery.Noyes, HillTop.Bessie.Noyes, Noyes - - and B10, Peebles, B9 - - and H85, PineCity, H90 - default_action: Crystola - default_action_parameters: - Kaluaaha: "0xffff" - Calcasieu: "0xffff" - Chevak: "0xffff" - Mendocino: "0xffff" - LasVegas: "0xff" - PineCity: "0x3f" - Exton: "0xff" - Noyes: "0xff" - Peebles: "0x1" - action _LasLomas$action_data: - p4: { name: LasLomas$action, how_referenced: direct } - row: 12 - column: 4 - vpns: [ 0 ] - home_row: - - 12 - format Crystola: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_b2: 16..23, $adf_b3: 24..31, $adf_h2: 32..47, $adf_h3: 48..63, $adf_h4: 64..79, $adf_h5: 80..95, $adf_h6: 96..111 } - action_bus: { 16 : $adf_b0, 17 : $adf_b1, 18 : $adf_b2, 19 : $adf_b3, 64..65 : $adf_h4, 66..67 : $adf_h5, 68..69 : $adf_h6, 48..49 : $adf_h2, 50..51 : $adf_h3 } - hash_action _Anita 6: - p4: { name: Anita, size: 1, disable_atomic_modify : true } - row: 0 - bus: 1 - hash_dist: - 1: { hash: 2, mask: 0xffff, shift: 0 } - 2: { hash: 2, mask: 0xffff, shift: 0 } - input_xbar: - exact group 3: { 0: Millston.Grays.Chevak, 16: Millston.Grays.Mendocino, 32: HillTop.Cutten.Pathfork } - hash 6: - 16..31: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 48, { 0: Millston.Grays.Mendocino, 16: Millston.Grays.Chevak, 32: HillTop.Cutten.Pathfork }, { })), 0..15) - hash group 2: - table: [6] - seed: 0x0 - exact group 3: { 48: Millston.Bergton.Chevak, 64: Millston.Bergton.Mendocino, 80: HillTop.Cutten.Marcus } - hash 6: - 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 48, { 16: Millston.Bergton.Chevak }, { })), 0..15) - hash 7: - 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 48, { 0: Millston.Bergton.Mendocino, 32: HillTop.Cutten.Marcus }, { })), 0..15) - hash group 2: - table: [6, 7] - seed: 0x0 - gateway: - name: _Anita-gateway - row: 0 - bus: 0 - unit: 1 - 0x0: _Plano - miss: _Plano - condition: - expression: "true(always hit)" - true: _Plano - false: _Plano - next: [] - action_bus: { 72..73 : hash_dist(1, lo), 74..75 : hash_dist(2, hi) } - instruction: _Anita($DEFAULT, $DEFAULT) - actions: - Baranof(0, 13): - - default_action: { allowed: true } - - handle: 0x2000005c - - next_table: 0 - - set H56, hash_dist(1, 0..15) - - set H57, hash_dist(2, 0..15) - default_action: Baranof - ternary_match _Plano 7: - p4: { name: Plano, size: 256, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.ElVerano: { type: exact, size: 1, full_size: 1, key_name: "RossFork.ElVerano" } - HillTop.Edwards.McGrady: { type: exact, size: 3, full_size: 3, key_name: "Edwards.McGrady" } - Millston.Wondervu$0.Higginson: { type: exact, size: 3, full_size: 3, key_name: "Wondervu$0.Higginson" } - Millston.Wondervu$1.$valid: { type: exact, size: 1, full_size: 1, key_name: "Wondervu$1" } - row: 4 - bus: 1 - column: 1 - input_xbar: - ternary group 3: { 8: Millston.Wondervu$1.$valid, 10: HillTop.RossFork.ElVerano, 21: Millston.Wondervu$0.Higginson, 26: HillTop.Edwards.McGrady } - match: - - { group: 3, byte_config: 3, dirtcam: 0x54 } - hit: [ _Leoma ] - miss: _Leoma - indirect: _Plano$tind - ternary_indirect _Plano$tind: - row: 0 - bus: 0 - column: 3 - input_xbar: - ternary group 3: { 8: Millston.Wondervu$1.$valid, 10: HillTop.RossFork.ElVerano, 21: Millston.Wondervu$0.Higginson, 26: HillTop.Edwards.McGrady } - format: { action: 0..1, immediate: 2..4 } - action_bus: { 52..53 : immediate(0..2) } - instruction: _Plano$tind(action, $DEFAULT) - actions: - WestEnd(0, 15): - - p4_param_order: { RedElm: 3 } - - default_action: { allowed: true } - - handle: 0x2000007c - - next_table: 0 - - { RedElm: immediate(0..2) } - - set HillTop.Edwards.RedElm, RedElm - Jenifer(1, 17): - - p4_param_order: { Willey: 3 } - - default_action: { allowed: true } - - handle: 0x2000007d - - next_table: 0 - - { Willey: immediate(0..2) } - - set HillTop.Edwards.RedElm, Willey - - set HillTop.RossFork.McCaulley.0-7, Millston.Wondervu$0.McCaulley.0-7 - - set HillTop.RossFork.McCaulley.8-15, Millston.Wondervu$0.McCaulley.8-15 - Endicott(2, 19): - - p4_param_order: { Willey: 3 } - - default_action: { allowed: true } - - handle: 0x2000007e - - next_table: 0 - - { Willey: immediate(0..2) } - - set HillTop.Edwards.RedElm, Willey - - set HillTop.RossFork.McCaulley.0-7, Millston.Wondervu$1.McCaulley.0-7 - - set HillTop.RossFork.McCaulley.8-15, Millston.Wondervu$1.McCaulley.8-15 - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x2000007f - - next_table: 0 - - { } - default_only_action: NoAction - exact_match _Leoma 8: - p4: { name: Leoma, size: 1024, disable_atomic_modify : true } - p4_param_order: - HillTop.Wisdom.Onycha: { type: exact, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } - HillTop.RossFork.Naruna: { type: exact, size: 3, full_size: 3, key_name: "RossFork.Naruna" } - row: 0 - bus: 0 - column: 2 - stash: - row: [ 0 ] - col: [ 2 ] - unit: [ 0 ] - ways: - - [1, 2, 0x0, [0, 2]] - input_xbar: - exact group 1: { 5: HillTop.RossFork.Naruna.2-2, 19: HillTop.RossFork.Naruna.0-1, 25: HillTop.Wisdom.Onycha } - hash 2: - 20: HillTop.RossFork.Naruna.2-2 - 21..22: HillTop.RossFork.Naruna.0-1 - 23..25: HillTop.Wisdom.Onycha - hash group 1: - table: [2] - seed: 0x0 - format: { action(0): 0..2, version(0): 112..115 } - hit: [ _Wakenda ] - miss: _Wakenda - instruction: _Leoma(action, $DEFAULT) - actions: - BigRock(0, 20): - - default_action: { allowed: true } - - handle: 0x20000080 - - next_table: 0 - - set HillTop.Edwards.PineCity, HillTop.Edwards.LaConner - Timnath(1, 22): - - default_action: { allowed: true } - - handle: 0x20000081 - - next_table: 0 - - set HillTop.Edwards.PineCity, 0 - Woodsboro(2, 24): - - default_action: { allowed: true } - - handle: 0x20000082 - - next_table: 0 - - set HillTop.Edwards.PineCity, HillTop.Maddock.PineCity - Amherst(3, 26): - - default_action: { allowed: true } - - handle: 0x20000083 - - next_table: 0 - - set HillTop.Edwards.PineCity, HillTop.Maddock.PineCity - Luttrell(4, 28): - - default_action: { allowed: true } - - handle: 0x20000084 - - next_table: 0 - - set HillTop.Edwards.PineCity, HillTop.Sublett.PineCity - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x20000085 - - next_table: 0 - default_only_action: NoAction -stage 4 ingress: - exact_match _Wakenda 0: - p4: { name: Wakenda, size: 4096, disable_atomic_modify : true } - p4_param_order: - HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } - HillTop.Savery.Kaluaaha: { type: exact, size: 16, full_size: 16, key_name: "Savery.Kaluaaha" } - HillTop.Savery.Calcasieu: { type: exact, size: 16, full_size: 16, key_name: "Savery.Calcasieu" } - HillTop.Savery.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Savery.Chevak" } - HillTop.Savery.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Savery.Mendocino" } - HillTop.Savery.LasVegas: { type: exact, size: 8, full_size: 8, key_name: "Savery.LasVegas" } - HillTop.Savery.PineCity: { type: exact, size: 6, full_size: 6, key_name: "Savery.PineCity" } - HillTop.Savery.Exton: { type: exact, size: 8, full_size: 8, key_name: "Savery.Exton" } - HillTop.Savery.Noyes: { type: exact, size: 8, full_size: 8, key_name: "Savery.Noyes" } - HillTop.Savery.Peebles: { type: exact, size: 1, full_size: 1, key_name: "Savery.Peebles" } - row: 1 - bus: 1 - column: [ 4, 6, 7, 8 ] - stash: - row: [ 1 ] - col: [ 4 ] - unit: [ 0 ] - ways: - - [0, 0, 0x3, [1, 4], [1, 6], [1, 7], [1, 8]] - input_xbar: - exact group 0: { 0: HillTop.Savery.Chevak, 16: HillTop.Savery.Mendocino, 32: HillTop.Savery.Calcasieu, 48: HillTop.Savery.Kaluaaha, 68: HillTop.Bessie.Miranda, 86: HillTop.Savery.PineCity, 101: HillTop.Savery.Peebles, 104: HillTop.Savery.Noyes, 112: HillTop.Savery.LasVegas, 120: HillTop.Savery.Exton } - hash 0: - 0..9: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) - 40..41: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) - hash 1: - 0..3: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(0..3) - 4..7: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(4..7) - 8..9: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(0..1) - 40: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(2) - 41: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.Peebles - hash group 0: - table: [0, 1] - seed: 0x3000000037c - format: { version(0): 112..115, match(0): [32..111, 0..7, 9..11 ] } - match: [ HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton, HillTop.Savery.Chevak(0..7), HillTop.Savery.Chevak(8..15), HillTop.Savery.Mendocino(0..7), HillTop.Savery.Mendocino(8..15), HillTop.Savery.Calcasieu(0..7), HillTop.Savery.Calcasieu(8..15), HillTop.Savery.Kaluaaha(0..7), HillTop.Savery.Kaluaaha(8..15), HillTop.Savery.PineCity(3..5) ] - hit: [ cond-16 ] - miss: cond-16 - action: _Wakenda$action_data($DIRECT, $DEFAULT) - instruction: _Wakenda($DEFAULT, $DEFAULT) - actions: - Unionvale(0, 1): - - p4_param_order: { Cornell: 32 } - - default_action: { allowed: true } - - handle: 0x2000005d - - next_table: 0 - - { Cornell: $adf_f0(0..31) } - - maxu HillTop.Mausdale.Kenney, HillTop.Mausdale.Kenney, Cornell - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x2000005e - - next_table: 0 - - { } - default_only_action: NoAction - action _Wakenda$action_data: - p4: { name: Wakenda$action } - row: 5 - column: 3 - vpns: [ 0 ] - home_row: - - 5 - format Unionvale: { $adf_f0: 0..31 } - action_bus: { 96..99 : $adf_f0 } - gateway cond-16 1: - name: cond-16 - input_xbar: - exact group 1: { 5: HillTop.RossFork.Weyauwega, 13: HillTop.Ovett.Hematite, 19: HillTop.Murphy.Standish, 30: HillTop.Murphy.Blairsden } - row: 4 - bus: 1 - unit: 0 - match: { 5: HillTop.RossFork.Weyauwega, 13: HillTop.Ovett.Hematite, 19: HillTop.Murphy.Standish, 30: HillTop.Murphy.Blairsden } - 0b*0**********0*****1*******0: cond-17 - miss: English_0 - condition: - expression: "(HillTop.RossFork.Weyauwega == 0 && HillTop.Ovett.Hematite == 1 && HillTop.Murphy.Standish == 0 && HillTop.Murphy.Blairsden == 0)" - true: cond-17 - false: English_0 - gateway cond-17 2: - name: cond-17 - input_xbar: - exact group 1: { 37: HillTop.RossFork.Naruna.2-2, 43: HillTop.Ovett.Hammond.0-0, 51: HillTop.RossFork.Naruna.0-1 } - row: 3 - bus: 1 - unit: 0 - match: { 19: HillTop.Ovett.Hammond.0-0, 3: HillTop.RossFork.Naruna.0-1, 13: HillTop.RossFork.Naruna.2-2 } - 0b****1*****0********01: _Brady_0 - miss: English_0 - condition: - expression: "(HillTop.Ovett.Hammond & 1 == 1 && HillTop.RossFork.Naruna == 1)" - true: _Brady_0 - false: English_0 - exact_match _Brady_0 3: - p4: { name: Brady, size: 75776, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Ocoee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } - HillTop.RossFork.Laxon: { type: exact, size: 32, full_size: 32, key_name: "RossFork.Laxon" } - HillTop.RossFork.Crozet: { type: exact, size: 16, full_size: 16, key_name: "RossFork.Crozet" } - HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } - Millston.Grays.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Grays.Mendocino" } - row: [ 6, 7, 4, 5, 2, 3, 0, 1 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 6, 7, 8 ] - - [ 2, 3, 4, 6, 7, 8 ] - - [ 2, 3, 4, 6, 7, 8 ] - - [ 2, 3, 4, 6, 7, 8 ] - - [ 2, 3, 4, 6, 7, 8 ] - - [ 2, 3, 4, 6, 7, 8 ] - - [ 2, 3 ] - - [ 2, 3 ] - stash: - row: [ 6, 7 ] - col: [ 2, 2 ] - unit: [ 0, 0 ] - ways: - - [1, 0, 0x3, [7, 2], [6, 2], [7, 3], [6, 3], [7, 4], [6, 4], [7, 6], [6, 6]] - - [1, 1, 0xc, [7, 7], [6, 7], [7, 8], [6, 8], [5, 2], [4, 2], [5, 3], [4, 3]] - - [1, 2, 0x30, [5, 4], [4, 4], [5, 6], [4, 6], [5, 7], [4, 7], [5, 8], [4, 8]] - - [1, 3, 0xc0, [3, 2], [2, 2], [3, 3], [2, 3], [3, 4], [2, 4], [3, 6], [2, 6]] - - [1, 0, 0x3, [3, 7], [2, 7], [3, 8], [2, 8], [1, 2], [0, 2], [1, 3], [0, 3]] - input_xbar: - exact group 2: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.RossFork.Laxon, 64: Millston.Grays.Mendocino, 80: HillTop.RossFork.Crozet, 96: HillTop.RossFork.Ocoee } - hash 4: - 0..9: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 40..41: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 10..19: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 42..43: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 20..29: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 44..45: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 30..39: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 46..47: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - hash 5: - 0..3: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..3) - 4..9: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..5) - 40..41: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(6..7) - 11..14: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..3) - 15..19: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..4) - 10: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(7) - 42..43: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(5..6) - 22..25: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..3) - 26..29: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..3) - 20..21: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(6..7) - 44..45: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(4..5) - 33..36: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..3) - 37..39: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..2) - 30..32: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(5..7) - 46..47: random(Millston.Grays.Mendocino(4..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(3..4) - hash group 1: - table: [4, 5] - seed: 0xb94f5d19db47 - format: { action(0): 0..2, immediate(0): 3..16, version(0): 112..115, match(0): [20..23, 32..111, 24..31 ], action(1): 128..130, immediate(1): 131..144, version(1): 240..243, match(1): [148..151, 160..239, 152..159 ] } - match: [ Millston.Grays.Mendocino(4..7), Millston.Grays.Mendocino(8..15), HillTop.RossFork.Crozet(0..7), HillTop.RossFork.Crozet(8..15), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31), HillTop.RossFork.Laxon(0..7), HillTop.RossFork.Laxon(8..15), HillTop.RossFork.Laxon(16..23), HillTop.RossFork.Laxon(24..31) ] - gateway: - name: cond-18 - input_xbar: - exact group 1: { 3: HillTop.RossFork.Alamosa } - row: 0 - bus: 1 - unit: 0 - match: { 3: HillTop.RossFork.Alamosa } - 0b****0: run_table - miss: English_0 - condition: - expression: "(HillTop.RossFork.Alamosa == 0)" - true: _Brady_0 - false: English_0 - hit: [ [], English_0, English_0, English_0, English_0, _Lindy_0 ] - miss: _Brady_0$st1 - action_bus: { 32..33 : immediate(0..13) } - action: _Brady_0$action_data($DIRECT, $DEFAULT) - instruction: _Brady_0(action, $DEFAULT) - actions: - Callao(1, 2): - - p4_param_order: { Calcasieu: 32, Bratt: 32, Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x20000062 - - next_table: 1 - - { Bratt.0-15: $adf_f0(0..15), Bonduel: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 0 - - set HillTop.Naubinway.Bonduel, Bonduel - - set HillTop.RossFork.Suttle, 1 - Ambler(2, 4): - - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x20000063 - - next_table: 2 - - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Bonduel: immediate(0..13) } - - set HillTop.RossFork.DonaAna, Avondale - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 0 - - set HillTop.Naubinway.Bonduel, Bonduel - - set HillTop.RossFork.Suttle, 1 - Wagener(3, 6): - - p4_param_order: { Calcasieu: 32, Bratt: 32, Sardinia: 14 } - - default_action: { allowed: true } - - handle: 0x20000064 - - next_table: 3 - - { Bratt.0-15: $adf_f0(0..15), Sardinia: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 1 - - set HillTop.Naubinway.Sardinia, Sardinia - - set HillTop.RossFork.Suttle, 1 - Olmitz(4, 8): - - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Sardinia: 14 } - - default_action: { allowed: true } - - handle: 0x20000065 - - next_table: 4 - - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Sardinia: immediate(0..13) } - - set HillTop.RossFork.DonaAna, Avondale - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 1 - - set HillTop.Naubinway.Sardinia, Sardinia - - set HillTop.RossFork.Suttle, 1 - Sequim(5, 0): - - default_action: { allowed: true } - - handle: 0x20000066 - - next_table: 5 - - { } - default_action: Sequim - idletime: - row: 0 - bus: 0 - column: [ 0, 1, 2, 3, 4 ] - precision: 1 - sweep_interval: 7 - notification: enable - per_flow_enable: false - action _Brady_0$action_data: - p4: { name: Brady$action } - row: [ 15, 14, 12, 11, 10, 9, 8, 7, 5, 3, 1 ] - word: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - 5 - - 5 - - 5 - - 5 - - 5 - - [ 4, 5 ] - - 5 - - [ 4, 5 ] - - [ 4, 5 ] - - [ 3, 4, 5 ] - - [ 1, 2, 3, 4, 5 ] - vpns: - - [ 0 ] - - [ 1 ] - - [ 2 ] - - [ 3 ] - - [ 4 ] - - [ 5, 6 ] - - [ 7 ] - - [ 8, 9 ] - - [ 10, 11 ] - - [ 12, 13, 14 ] - - [ 15, 16, 17, 18, 19 ] - home_row: - - [ 15, 11 ] - format Callao: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - format Ambler: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - format Wagener: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - format Olmitz: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - action_bus: { 38..39 : $adf_h1, 108..111 : $adf_f1, 36..39 : $adf_f0 } -stage 5 ingress: - ternary_match _Lindy_0 1: - p4: { name: Lindy, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Lordstown: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Lordstown" } - HillTop.RossFork.Sewaren: { type: ternary, size: 2, full_size: 2, key_name: "RossFork.Sewaren" } - HillTop.RossFork.WindGap: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.WindGap" } - HillTop.RossFork.Belfair: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Belfair" } - HillTop.RossFork.Caroleen: { type: ternary, size: 2, full_size: 2, key_name: "RossFork.Caroleen" } - HillTop.RossFork.Ocoee: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } - HillTop.Bessie.Peebles: { type: ternary, size: 1, full_size: 1, key_name: "Bessie.Peebles" } - row: 8 - bus: 1 - column: 1 - input_xbar: - ternary group 2: { 6: HillTop.RossFork.Belfair, 8: HillTop.RossFork.Ocoee, 22: HillTop.RossFork.Caroleen, 29: HillTop.Bessie.Peebles, 36: HillTop.RossFork.Sewaren, 38: HillTop.RossFork.WindGap, 39: HillTop.RossFork.Lordstown } - match: - - { group: 2, dirtcam: 0x155 } - hit: [ English_0, English_0, English_0, English_0, _Geistown_0 ] - miss: English_0 - indirect: _Lindy_0$tind - ternary_indirect _Lindy_0$tind: - row: 4 - bus: 0 - column: 2 - input_xbar: - ternary group 2: { 6: HillTop.RossFork.Belfair, 8: HillTop.RossFork.Ocoee, 22: HillTop.RossFork.Caroleen, 29: HillTop.Bessie.Peebles, 36: HillTop.RossFork.Sewaren, 38: HillTop.RossFork.WindGap, 39: HillTop.RossFork.Lordstown } - format: { action: 0..2 } - instruction: _Lindy_0$tind(action, $DEFAULT) - actions: - Lauada(0, 8): - - default_action: { allowed: true } - - handle: 0x20000067 - - next_table: 0 - - set HillTop.RossFork.Merrill, HillTop.RossFork.Hickox - - set HillTop.Naubinway.Ayden, 0 - - set HillTop.Naubinway.Bonduel, HillTop.RossFork.Luzerne - RichBar(1, 10): - - default_action: { allowed: true } - - handle: 0x20000068 - - next_table: 1 - - set HillTop.RossFork.Merrill, HillTop.RossFork.Hickox - - set HillTop.Naubinway.Ayden, 1 - - set HillTop.Naubinway.Sardinia, HillTop.RossFork.Luzerne - Harding(2, 12): - - default_action: { allowed: true } - - handle: 0x20000069 - - next_table: 2 - - set HillTop.RossFork.Merrill, HillTop.RossFork.Tehachapi - - set HillTop.Naubinway.Ayden, 0 - - set HillTop.Naubinway.Bonduel, HillTop.RossFork.Devers - Nephi(3, 14): - - default_action: { allowed: true } - - handle: 0x2000006a - - next_table: 3 - - set HillTop.RossFork.Merrill, HillTop.RossFork.Tehachapi - - set HillTop.Naubinway.Ayden, 1 - - set HillTop.Naubinway.Sardinia, HillTop.RossFork.Devers - Sequim(4, 0): - - default_action: { allowed: true } - - handle: 0x2000006b - - next_table: 4 - default_action: Sequim - exact_match _Geistown_0 2: - p4: { name: Geistown, size: 4096, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Knierim: { type: exact, size: 12, full_size: 12, key_name: "RossFork.Knierim" } - HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } - Millston.Grays.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Grays.Mendocino" } - HillTop.RossFork.Chaffee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Chaffee" } - row: 0 - bus: 1 - column: [ 8, 9, 10, 11 ] - stash: - row: [ 0 ] - col: [ 8 ] - unit: [ 1 ] - ways: - - [1, 0, 0x0, [0, 8]] - - [1, 1, 0x0, [0, 9]] - - [1, 2, 0x0, [0, 10]] - - [1, 3, 0x0, [0, 11]] - input_xbar: - exact group 1: { 0: HillTop.Maddock.Calcasieu(0..15), 19: HillTop.RossFork.Knierim, 32: HillTop.RossFork.Chaffee, 40: Millston.Grays.Mendocino(8..15), 48: HillTop.Maddock.Calcasieu(16..31), 64: Millston.Grays.Mendocino(0..7) } - hash 2: - 0..4: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(0..4) - 5..9: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(5..9) - 11..15: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(0..4) - 16..19: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(5..8) - 10: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(9) - 22..26: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(0..4) - 27..29: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(5..7) - 20..21: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(8..9) - 33..37: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(0..4) - 38..39: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(5..6) - 30..32: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(7..9) - hash 3: - 0..9: random(Millston.Grays.Mendocino(0..7)) - 10..19: random(Millston.Grays.Mendocino(0..7)) - 20..29: random(Millston.Grays.Mendocino(0..7)) - 30..39: random(Millston.Grays.Mendocino(0..7)) - hash group 1: - table: [2, 3] - seed: 0xce0e6f30b6 - format: { action(0): 0..2, immediate(0): 3..16, version(0): 112..115, match(0): [32..55, 93..94, 56..87 ] } - match: [ HillTop.RossFork.Chaffee, Millston.Grays.Mendocino(0..7), Millston.Grays.Mendocino(8..15), HillTop.RossFork.Knierim(10..11), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31) ] - hit: [ English_0, English_0, English_0, English_0, _Swanlake_0 ] - miss: English_0 - action_bus: { 40..41 : immediate(0..13) } - action: _Geistown_0$action_data($DIRECT, $DEFAULT) - instruction: _Geistown_0(action, $DEFAULT) - actions: - Palouse(0, 16): - - p4_param_order: { Calcasieu: 32, Bratt: 32, Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x2000006c - - next_table: 0 - - { Bratt.0-15: $adf_f0(0..15), Bonduel: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 0 - - set HillTop.Naubinway.Bonduel, Bonduel - Monrovia(1, 18): - - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x2000006d - - next_table: 1 - - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Bonduel: immediate(0..13) } - - set HillTop.RossFork.DonaAna, Avondale - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 0 - - set HillTop.Naubinway.Bonduel, Bonduel - Sespe(2, 20): - - p4_param_order: { Calcasieu: 32, Bratt: 32, Sardinia: 14 } - - default_action: { allowed: true } - - handle: 0x2000006e - - next_table: 2 - - { Bratt.0-15: $adf_f0(0..15), Sardinia: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 1 - - set HillTop.Naubinway.Sardinia, Sardinia - Rienzi(3, 22): - - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Sardinia: 14 } - - default_action: { allowed: true } - - handle: 0x2000006f - - next_table: 3 - - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Sardinia: immediate(0..13) } - - set HillTop.RossFork.DonaAna, Avondale - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 1 - - set HillTop.Naubinway.Sardinia, Sardinia - Sequim(4, 0): - - default_action: { allowed: true } - - handle: 0x20000070 - - next_table: 4 - - { } - default_action: Sequim - action _Geistown_0$action_data: - p4: { name: Geistown$action } - row: 12 - column: [ 2, 3 ] - vpns: [ 0, 1 ] - home_row: - - 12 - format Palouse: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - format Monrovia: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - format Sespe: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - format Rienzi: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - action_bus: { 46..47 : $adf_h1, 108..111 : $adf_f1, 44..47 : $adf_f0 } - exact_match _Swanlake_0 3: - p4: { name: Swanlake, size: 1024, disable_atomic_modify : true } - p4_param_order: - HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } - HillTop.RossFork.Chaffee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Chaffee" } - row: [ 1, 0 ] - bus: [ 1, 0 ] - column: - - [ 10, 11 ] - - [ 6, 7 ] - stash: - row: [ 0 ] - col: [ 7 ] - unit: [ 0 ] - ways: - - [2, 0, 0x0, [0, 7]] - - [2, 1, 0x0, [1, 10]] - - [2, 2, 0x0, [1, 11]] - - [2, 3, 0x0, [0, 6]] - input_xbar: - exact group 2: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.RossFork.Chaffee } - hash 4: - 0..1: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.Maddock.Calcasieu(0..1) - 2..9: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.RossFork.Chaffee - 11..12: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.Maddock.Calcasieu(0..1) - 13..19: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.RossFork.Chaffee(0..6) - 10: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.RossFork.Chaffee(7) - 22..23: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.Maddock.Calcasieu(0..1) - 24..29: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.RossFork.Chaffee(0..5) - 20..21: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.RossFork.Chaffee(6..7) - 33..34: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.Maddock.Calcasieu(0..1) - 35..39: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.RossFork.Chaffee(0..4) - 30..32: random(HillTop.Maddock.Calcasieu(2..31)) ^ HillTop.RossFork.Chaffee(5..7) - hash group 2: - table: [4] - seed: 0xee1f27531a - format: { action(0): 0..1, immediate(0): 2..31, version(0): 112..115, match(0): [58..63, 32..55 ] } - match: [ HillTop.Maddock.Calcasieu(2..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31) ] - hit: [ English_0, English_0, _Rochert_0 ] - miss: English_0 - action_bus: { 34..35 : immediate(16..29), 112..115 : immediate(0..29) } - action: _Swanlake_0$action_data($DIRECT, $DEFAULT) - instruction: _Swanlake_0(action, $DEFAULT) - actions: - Callao(0, 24): - - p4_param_order: { Calcasieu: 32, Bratt: 32, Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x20000071 - - next_table: 0 - - { Calcasieu: $adf_f0(0..31), Bratt.0-15: immediate(0..15), Bonduel: immediate(16..29) } - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 0 - - set HillTop.Naubinway.Bonduel, Bonduel - - set HillTop.RossFork.Suttle, 1 - Wagener(1, 26): - - p4_param_order: { Calcasieu: 32, Bratt: 32, Sardinia: 14 } - - default_action: { allowed: true } - - handle: 0x20000072 - - next_table: 1 - - { Calcasieu: $adf_f0(0..31), Bratt.0-15: immediate(0..15), Sardinia: immediate(16..29) } - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 1 - - set HillTop.Naubinway.Sardinia, Sardinia - - set HillTop.RossFork.Suttle, 1 - Sequim(2, 0): - - default_action: { allowed: true } - - handle: 0x20000073 - - next_table: 2 - - { } - default_action: Sequim - idletime: - row: 0 - bus: 1 - column: 1 - precision: 1 - sweep_interval: 7 - notification: enable - per_flow_enable: false - action _Swanlake_0$action_data: - p4: { name: Swanlake$action } - row: 8 - column: 3 - vpns: [ 0 ] - home_row: - - 8 - format Callao: { $adf_f0: 0..31 } - format Wagener: { $adf_f0: 0..31 } - action_bus: { 120..123 : $adf_f0 } - exact_match _Rochert_0 4: - p4: { name: Rochert, size: 10240, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Knierim: { type: exact, size: 12, full_size: 12, key_name: "RossFork.Knierim" } - HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } - HillTop.RossFork.Chaffee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Chaffee" } - row: [ 3, 1 ] - bus: [ 1, 0 ] - column: - - 11 - - [ 6, 7, 8, 9 ] - stash: - row: [ 3 ] - col: [ 11 ] - unit: [ 0 ] - ways: - - [3, 0, 0x1, [3, 11], [1, 6]] - - [3, 1, 0x0, [1, 9]] - - [3, 2, 0x0, [1, 8]] - - [3, 3, 0x0, [1, 7]] - input_xbar: - exact group 2: { 64: HillTop.Maddock.Calcasieu(0..15), 83: HillTop.RossFork.Knierim, 96: HillTop.RossFork.Chaffee, 112: HillTop.Maddock.Calcasieu(16..31) } - hash 5: - 0..4: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(0..4) - 5..9: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(5..9) - 40: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) - 11..15: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(0..4) - 16..19: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(5..8) - 10: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(9) - 22..26: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(0..4) - 27..29: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(5..7) - 20..21: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(8..9) - 33..37: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(0..4) - 38..39: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(5..6) - 30..32: random(HillTop.Maddock.Calcasieu(0..15), HillTop.RossFork.Knierim(10..11), HillTop.RossFork.Chaffee, HillTop.Maddock.Calcasieu(16..31)) ^ HillTop.RossFork.Knierim(7..9) - hash group 3: - table: [5] - seed: 0x15431402ade - format: { action(0): 0..1, version(0): 112..115, match(0): [32..39, 77..78, 40..71 ], action(1): 2..3, version(1): 116..119, match(1): [80..87, 5..6, 88..111, 8..15 ] } - match: [ HillTop.RossFork.Chaffee, HillTop.RossFork.Knierim(10..11), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31) ] - hit: [ English_0, English_0, _Emden_0 ] - miss: English_0 - action: _Rochert_0$action_data($DIRECT, $DEFAULT) - instruction: _Rochert_0(action, $DEFAULT) - actions: - Palouse(0, 28): - - p4_param_order: { Calcasieu: 32, Bratt: 32, Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x20000074 - - next_table: 0 - - { Bratt.0-15: $adf_f0(0..15), Bonduel: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 0 - - set HillTop.Naubinway.Bonduel, Bonduel - Sespe(1, 30): - - p4_param_order: { Calcasieu: 32, Bratt: 32, Sardinia: 14 } - - default_action: { allowed: true } - - handle: 0x20000075 - - next_table: 1 - - { Bratt.0-15: $adf_f0(0..15), Sardinia: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 1 - - set HillTop.Naubinway.Sardinia, Sardinia - Sequim(2, 0): - - default_action: { allowed: true } - - handle: 0x20000076 - - next_table: 2 - - { } - default_action: Sequim - action _Rochert_0$action_data: - p4: { name: Rochert$action } - row: [ 2, 0 ] - word: [ 0, 0 ] - column: - - [ 3, 4, 5 ] - - [ 4, 5 ] - vpns: - - [ 0, 1, 2 ] - - [ 3, 4 ] - home_row: - - 2 - format Palouse: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - format Sespe: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - action_bus: { 50..51 : $adf_h1, 68..71 : $adf_f1, 48..51 : $adf_f0 } - ternary_match _Emden_0 5: - p4: { name: Emden, size: 8192, disable_atomic_modify : true } - p4_param_order: - HillTop.Ovett.Manilla: { type: exact, size: 8, full_size: 8, key_name: "Ovett.Manilla" } - HillTop.Maddock.Calcasieu: { type: lpm, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } - row: [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - input_xbar: - ternary group 0: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.Ovett.Manilla } - match: - - { group: 0, byte_config: 3, dirtcam: 0x155 } - hit: [ English_0 ] - miss: English_0 - indirect: _Emden_0$tind - idletime: - row: 0 - bus: 0 - column: 0 - precision: 1 - sweep_interval: 7 - notification: enable - per_flow_enable: false - ternary_indirect _Emden_0$tind: - row: 3 - bus: 0 - column: 2 - input_xbar: - ternary group 0: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.Ovett.Manilla } - format: { action: 0..1, immediate: 2..15 } - action_bus: { 52..53 : immediate(0..13) } - instruction: _Emden_0$tind(action, $DEFAULT) - actions: - Tofte(0, 32): - - p4_param_order: { Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x20000077 - - next_table: 0 - - { Bonduel: immediate(0..13) } - - set HillTop.Naubinway.Ayden, 0 - - set HillTop.Naubinway.Bonduel, Bonduel - Jerico(1, 34): - - p4_param_order: { Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x20000078 - - next_table: 0 - - { Bonduel: immediate(0..13) } - - set HillTop.Naubinway.Ayden, 2 - - set HillTop.Naubinway.Bonduel, Bonduel - Wabbaseka(2, 36): - - p4_param_order: { Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x20000079 - - next_table: 0 - - { Bonduel: immediate(0..13) } - - set HillTop.Naubinway.Ayden, 3 - - set HillTop.Naubinway.Bonduel, Bonduel - Clearmont(3, 38): - - p4_param_order: { Sardinia: 14 } - - default_action: { allowed: true } - - handle: 0x2000007a - - next_table: 0 - - { Sardinia: immediate(0..13) } - - set HillTop.Naubinway.Sardinia, Sardinia - - set HillTop.Naubinway.Ayden, 1 - Ruffin(-1, 40): - - default_only_action: { allowed: true } - - handle: 0x2000007b - - next_table: 0 - - { } - - set HillTop.Naubinway.Ayden, 0 - - set HillTop.Naubinway.Bonduel, 1 - default_only_action: Ruffin - exact_match _Brady_0$st1 0: - p4: { name: Brady, size: 75776, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Ocoee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } - HillTop.RossFork.Laxon: { type: exact, size: 32, full_size: 32, key_name: "RossFork.Laxon" } - HillTop.RossFork.Crozet: { type: exact, size: 16, full_size: 16, key_name: "RossFork.Crozet" } - HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } - Millston.Grays.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Grays.Mendocino" } - row: [ 6, 7, 4, 5, 2, 3 ] - bus: [ 0, 0, 0, 0, 0, 0 ] - column: - - [ 6, 7, 8, 9, 10, 11 ] - - [ 6, 7, 8, 9, 10, 11 ] - - [ 6, 7, 8, 9, 10, 11 ] - - [ 6, 7, 8, 9, 10, 11 ] - - [ 6, 7, 8, 9, 10 ] - - [ 6, 7, 8, 9, 10 ] - stash: - row: [ 2, 3 ] - col: [ 6, 6 ] - unit: [ 1, 1 ] - ways: - - [0, 0, 0x3, [3, 6], [2, 6], [3, 7], [2, 7], [3, 8], [2, 8], [3, 9], [2, 9]] - - [0, 1, 0xc, [5, 8], [4, 8], [5, 9], [4, 9], [5, 10], [4, 10], [5, 11], [4, 11]] - - [0, 2, 0x30, [7, 10], [6, 10], [7, 11], [6, 11], [5, 6], [4, 6], [5, 7], [4, 7]] - - [0, 3, 0xc0, [7, 6], [6, 6], [7, 7], [6, 7], [7, 8], [6, 8], [7, 9], [6, 9]] - - [0, 0, 0x0, [3, 10], [2, 10]] - input_xbar: - exact group 0: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.RossFork.Laxon, 64: Millston.Grays.Mendocino, 80: HillTop.RossFork.Crozet, 96: HillTop.RossFork.Ocoee } - hash 0: - 0..9: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 40..41: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 10..19: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 42..43: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 20..29: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 44..45: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 30..39: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - 46..47: random(HillTop.Maddock.Calcasieu, HillTop.RossFork.Laxon) - hash 1: - 0..1: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) - 2..9: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee - 40..41: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) - 11..12: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) - 13..19: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..6) - 10: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(7) - 42..43: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) - 22..23: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) - 24..29: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..5) - 20..21: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(6..7) - 44..45: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) - 33..34: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ Millston.Grays.Mendocino(0..1) - 35..39: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(0..4) - 30..32: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) ^ HillTop.RossFork.Ocoee(5..7) - 46..47: random(Millston.Grays.Mendocino(2..15), HillTop.RossFork.Crozet) - hash group 0: - table: [0, 1] - seed: 0x7971b8f945b3 - format: { action(0): 0..2, immediate(0): 3..16, version(0): 112..115, match(0): [18..23, 32..111, 24..31 ], action(1): 128..130, immediate(1): 131..144, version(1): 240..243, match(1): [146..151, 160..239, 152..159 ] } - match: [ Millston.Grays.Mendocino(2..7), Millston.Grays.Mendocino(8..15), HillTop.RossFork.Crozet(0..7), HillTop.RossFork.Crozet(8..15), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31), HillTop.RossFork.Laxon(0..7), HillTop.RossFork.Laxon(8..15), HillTop.RossFork.Laxon(16..23), HillTop.RossFork.Laxon(24..31) ] - hit: [ English_0, English_0, English_0, English_0, _Lindy_0 ] - miss: English_0 - action_bus: { 32..33 : immediate(0..13) } - action: _Brady_0$st1$action_data($DIRECT, $DEFAULT) - instruction: _Brady_0$st1(action, $DEFAULT) - actions: - Callao(0, 1): - - p4_param_order: { Calcasieu: 32, Bratt: 32, Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x20000062 - - next_table: 0 - - { Bratt.0-15: $adf_f0(0..15), Bonduel: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 0 - - set HillTop.Naubinway.Bonduel, Bonduel - - set HillTop.RossFork.Suttle, 1 - Ambler(1, 2): - - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x20000063 - - next_table: 1 - - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Bonduel: immediate(0..13) } - - set HillTop.RossFork.DonaAna, Avondale - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 0 - - set HillTop.Naubinway.Bonduel, Bonduel - - set HillTop.RossFork.Suttle, 1 - Wagener(2, 4): - - p4_param_order: { Calcasieu: 32, Bratt: 32, Sardinia: 14 } - - default_action: { allowed: true } - - handle: 0x20000064 - - next_table: 2 - - { Bratt.0-15: $adf_f0(0..15), Sardinia: $adf_h1(0..13), Calcasieu: $adf_f1(0..31) } - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 1 - - set HillTop.Naubinway.Sardinia, Sardinia - - set HillTop.RossFork.Suttle, 1 - Olmitz(3, 6): - - p4_param_order: { Calcasieu: 32, Avondale: 16, Bratt: 32, Sardinia: 14 } - - default_action: { allowed: true } - - handle: 0x20000065 - - next_table: 3 - - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Calcasieu: $adf_f1(0..31), Sardinia: immediate(0..13) } - - set HillTop.RossFork.DonaAna, Avondale - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.Naubinway.Ayden, 1 - - set HillTop.Naubinway.Sardinia, Sardinia - - set HillTop.RossFork.Suttle, 1 - Sequim(4, 0): - - default_action: { allowed: true } - - handle: 0x20000066 - - next_table: 4 - - { } - default_action: Sequim - idletime: - row: 4 - bus: 0 - column: [ 0, 1, 2, 3, 4 ] - precision: 1 - sweep_interval: 7 - notification: enable - per_flow_enable: false - action _Brady_0$st1$action_data: - p4: { name: Brady$action } - row: [ 14, 12, 10, 8, 6, 4, 0 ] - word: [ 0, 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 5 ] - - [ 4, 5 ] - - [ 4, 5 ] - - [ 4, 5 ] - - [ 3, 4, 5 ] - - [ 3, 4, 5 ] - - 3 - vpns: - - [ 0, 1, 2, 3 ] - - [ 4, 5 ] - - [ 6, 7 ] - - [ 8, 9 ] - - [ 10, 11, 12 ] - - [ 13, 14, 15 ] - - [ 16 ] - home_row: - - [ 14, 0 ] - format Callao: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - format Ambler: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - format Wagener: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - format Olmitz: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - action_bus: { 38..39 : $adf_h1, 100..103 : $adf_f1, 36..39 : $adf_f0 } - ternary_match English_0 6: - p4: { name: English, size: 512, disable_atomic_modify : true } - p4_param_order: - Millston.Bergton.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Bergton" } - Millston.Ramos.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Ramos" } - Millston.Provencal.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Provencal" } - Millston.Shirley.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Shirley" } - Millston.Grays.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Grays" } - Millston.Maumee.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Maumee" } - Millston.GlenAvon.$valid: { type: ternary, size: 1, full_size: 1, key_name: "GlenAvon" } - row: 10 - bus: 1 - column: 1 - input_xbar: - ternary group 1: { 2: Millston.Provencal.$valid, 3: Millston.Grays.$valid, 8: Millston.Shirley.$valid, 10: Millston.Maumee.$valid, 20: Millston.GlenAvon.$valid, 21: Millston.Ramos.$valid, 22: Millston.Bergton.$valid } - match: - - { group: 1, dirtcam: 0x15 } - hit: [ cond-19 ] - miss: cond-19 - indirect: English_0$tind - ternary_indirect English_0$tind: - row: 2 - bus: 0 - column: 2 - input_xbar: - ternary group 1: { 2: Millston.Provencal.$valid, 3: Millston.Grays.$valid, 8: Millston.Shirley.$valid, 10: Millston.Maumee.$valid, 20: Millston.GlenAvon.$valid, 21: Millston.Ramos.$valid, 22: Millston.Bergton.$valid } - format: { action: 0..2 } - instruction: English_0$tind(action, $DEFAULT) - actions: - Dresden(0, 3): - - default_action: { allowed: true } - - handle: 0x20000089 - - next_table: 0 - - set HillTop.Lewiston.Lugert, HillTop.Cutten.Pathfork - Lorane(1, 5): - - default_action: { allowed: true } - - handle: 0x2000008a - - next_table: 0 - - set HillTop.Lewiston.Lugert, HillTop.Cutten.Tombstone - Dundalk(2, 7): - - default_action: { allowed: true } - - handle: 0x2000008b - - next_table: 0 - - set HillTop.Lewiston.Lugert, HillTop.Cutten.Marcus - Bellville(3, 9): - - default_action: { allowed: true } - - handle: 0x2000008c - - next_table: 0 - - set HillTop.Lewiston.Lugert, HillTop.Cutten.Pittsboro - DeerPark(4, 11): - - default_action: { allowed: true } - - handle: 0x2000008d - - next_table: 0 - - set HillTop.Lewiston.Lugert, HillTop.Cutten.Subiaco - Sequim(5, 0): - - default_action: { allowed: true } - - handle: 0x2000008e - - next_table: 0 - NoAction(-1, 13): - - default_only_action: { allowed: true } - - handle: 0x2000008f - - next_table: 0 - default_only_action: NoAction - gateway cond-19 7: - name: cond-19 - input_xbar: - exact group 0: { 105: Millston.Hayfield.$valid } - row: 6 - bus: 1 - unit: 0 - match: { 1: Millston.Hayfield.$valid } - 0b******0: _Sardinia - miss: _Jemison - condition: - expression: "(Millston.Hayfield.$valid == 1 == 0)" - true: _Sardinia - false: _Jemison - ternary_match _Jemison 8: - p4: { name: Jemison, size: 1024, disable_atomic_modify : true } - p4_param_order: - Millston.Hayfield.Blitchton: { type: exact, size: 6, full_size: 6, key_name: "Hayfield.Blitchton" } - Millston.Hayfield.Avondale: { type: exact, size: 10, full_size: 10, key_name: "Hayfield.Avondale" } - Millston.Hayfield.Glassboro: { type: exact, size: 4, full_size: 4, key_name: "Hayfield.Glassboro" } - Millston.Hayfield.Grabill: { type: exact, size: 12, full_size: 12, key_name: "Hayfield.Grabill" } - HillTop.Wisdom.Onycha: { type: ternary, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } - row: [ 6, 7 ] - bus: [ 1, 1 ] - column: - - 1 - - 1 - input_xbar: - ternary group 3: { 0: Millston.Hayfield.Grabill(8..11), 4: Millston.Hayfield.Glassboro, 8: Millston.Hayfield.Avondale, 18: Millston.Hayfield.Blitchton, 24: Millston.Hayfield.Grabill(0..7), 33: HillTop.Wisdom.Onycha } - match: - - { group: 3, dirtcam: 0x155 } - gateway: - name: cond-21 - input_xbar: - exact group 0: { 105: Millston.Hayfield.$valid } - row: 5 - bus: 1 - unit: 0 - match: { 1: Millston.Hayfield.$valid } - 0b******1: run_table - miss: _Romeo - condition: - expression: "(Millston.Hayfield.$valid == 1)" - true: _Jemison - false: _Romeo - hit: [ _Romeo ] - miss: _Romeo - indirect: _Jemison$tind - ternary_indirect _Jemison$tind: - row: 1 - bus: 0 - column: 2 - input_xbar: - ternary group 3: { 0: Millston.Hayfield.Grabill(8..11), 4: Millston.Hayfield.Glassboro, 8: Millston.Hayfield.Avondale, 18: Millston.Hayfield.Blitchton, 24: Millston.Hayfield.Grabill(0..7), 33: HillTop.Wisdom.Onycha } - format: { action: 0..2, immediate: 3..22 } - action_bus: { 116..119 : immediate(0..19) } - instruction: _Jemison$tind(action, $DEFAULT) - actions: - Neosho(1, 15): - - p4_param_order: { Stilwell: 20 } - - default_action: { allowed: true } - - handle: 0x20000092 - - next_table: 0 - - { Stilwell: immediate(0..19) } - - set HillTop.Wisdom.Onycha, 2 - - set HillTop.Wisdom.Morstein, Stilwell - - set HillTop.Wisdom.Nenana, HillTop.RossFork.CeeVee - Islen(2, 17): - - default_action: { allowed: true } - - handle: 0x20000093 - - next_table: 0 - - { } - - set HillTop.Wisdom.Onycha, 3 - - set HillTop.RossFork.Brinkman, 0 - - set HillTop.RossFork.Parkland, 0 - BarNunn(3, 19): - - default_action: { allowed: true } - - handle: 0x20000094 - - next_table: 0 - - { } - - set HillTop.RossFork.Chugwater, 1 - Swandale(4, 0): - - default_action: { allowed: true } - - handle: 0x20000095 - - next_table: 0 - - { } - default_action: BarNunn -stage 6 ingress: - exact_match _Sardinia 0: - p4: { name: Sardinia, size: 256, action_profile: Coryville, disable_atomic_modify : true } - p4_param_order: - HillTop.Naubinway.Sardinia: { type: exact, size: 8, full_size: 14, key_name: "Naubinway.Sardinia" } - row: 2 - bus: 1 - column: 7 - stash: - row: [ 2 ] - col: [ 7 ] - unit: [ 1 ] - ways: - - [0, 0, 0x0, [2, 7]] - input_xbar: - exact group 0: { 0: HillTop.Naubinway.Sardinia(0..7) } - hash 0: - 0..7: HillTop.Naubinway.Sardinia(0..7) - hash group 0: - table: [0] - seed: 0x0 - exact group 1: { 0: HillTop.Tiburon.Arnold, 16: HillTop.Lewiston.Lugert } - hash 2: - 0..9: slice(stripe(crc_rev(0x18005, 0x0, 0x0, 25, { 0: HillTop.Tiburon.Arnold, 9: HillTop.Lewiston.Lugert }, { })), 0..9) - hash group 2: - table: [2] - seed: 0x0 - format: { action(0): 2..2, version(0): 112..115, meter_addr(0): 3..12, meter_pfe(0): 13..13, action_addr(0): 14..28, sel_len_mod(0): 0..1 } - gateway: - name: cond-20 - input_xbar: - exact group 1: { 70: HillTop.Naubinway.Ayden } - row: 1 - bus: 0 - unit: 1 - match: { 6: HillTop.Naubinway.Ayden } - 0x1: run_table - miss: _Romeo - condition: - expression: "(HillTop.Naubinway.Ayden == 1)" - true: _Sardinia - false: _Romeo - hit: [ _Romeo ] - miss: _Romeo - selector: _Sardinia$selector.Bellamy(meter_addr, meter_pfe, $DEFAULT) - selector_length: _Sardinia$selector.Bellamy(sel_len_mod, $DEFAULT) - action: _Sardinia$action_data.Coryville(action_addr, $DEFAULT) - instruction: _Sardinia(action, $DEFAULT) - actions: - Ackerly(1, 1): - - p4_param_order: { Ayden: 2, Bonduel: 14 } - - default_action: { allowed: true } - - handle: 0x20000090 - - next_table: 0 - - { Bonduel: $adf_h0(0..13) } - - set HillTop.Naubinway.Bonduel, Bonduel - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x20000091 - - next_table: 0 - - { } - default_only_action: NoAction - selection _Sardinia$selector.Bellamy: - p4: { name: Bellamy, size: 192 } - row: 15 - column: [ 2, 3 ] - maprams: [ 2, 3 ] - input_xbar: - exact group 0: { 64: HillTop.Tiburon.Arnold, 80: HillTop.Lewiston.Lugert } - hash 1: - 0..50: slice(stripe(crc_rev(0x18005, 0x0, 0x0, 25, { 0: HillTop.Tiburon.Arnold, 9: HillTop.Lewiston.Lugert })), 0..50) - hash group 1: - table: [1] - seed: 0x0 - mode: resilient 0 - non_linear: true - pool_sizes: [256] - hash_dist: - 0: { hash: 2, mask: 0x3ff, shift: 0 } - action _Sardinia$action_data.Coryville: - p4: { name: Coryville, size: 16384 } - row: 5 - column: [ 2, 3 ] - vpns: [ 0, 1 ] - home_row: - - 5 - format Ackerly: { $adf_h0: 0..15 } - action_bus: { 32..33 : $adf_h0 } - stateful _Sardinia$salu.Bellamy$salu: - p4: { name: Bellamy$salu, size: 122880, hidden: true } - selection_table: _Sardinia$selector.Bellamy - row: 15 - column: [ 2, 3 ] - maprams: [ 2, 3 ] - format: { lo: 1 } - actions: - set_bit_at_alu$0: - - set_bit_at - clr_bit_at_alu$0: - - clr_bit_at - set_bit_alu$0: - - set_bit - clr_bit_alu$0: - - clr_bit - exact_match _Romeo 1: - p4: { name: Romeo, size: 16384, disable_atomic_modify : true } - p4_param_order: - HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } - HillTop.RossFork.Bicknell: { type: exact, size: 12, full_size: 12, key_name: "RossFork.Bicknell" } - row: [ 1, 2 ] - bus: [ 0, 0 ] - column: - - [ 2, 3, 4, 6 ] - - [ 2, 3, 4, 6 ] - stash: - row: [ 1, 2 ] - col: [ 2, 2 ] - unit: [ 0, 0 ] - ways: - - [3, 0, 0x0, [2, 2], [1, 2]] - - [3, 1, 0x0, [2, 3], [1, 3]] - - [3, 2, 0x0, [2, 4], [1, 4]] - - [3, 3, 0x0, [2, 6], [1, 6]] - input_xbar: - exact group 1: { 72: HillTop.Maddock.Calcasieu(8..31), 96: HillTop.Maddock.Calcasieu(0..7), 104: HillTop.RossFork.Bicknell(8..11), 112: HillTop.RossFork.Bicknell(0..7) } - hash 3: - 0..3: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(8..11) - 4..9: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(0..5) - 11..14: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(8..11) - 15..19: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(0..4) - 10: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(5) - 22..25: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(8..11) - 26..29: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(0..3) - 20..21: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(4..5) - 33..36: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(8..11) - 37..39: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(0..2) - 30..32: random(HillTop.Maddock.Calcasieu(8..31), HillTop.Maddock.Calcasieu(0..7), HillTop.RossFork.Bicknell(6..7)) ^ HillTop.RossFork.Bicknell(3..5) - hash group 3: - table: [3] - seed: 0x957f7806d9 - format: { action(0): 0..0, immediate(0): 3..4, version(0): 112..115, match(0): 14..47, action(1): 1..1, immediate(1): 5..6, version(1): 116..119, match(1): [86..87, 48..79 ], action(2): 2..2, immediate(2): 7..8, version(2): 248..251, match(2): [214..215, 88..111, 120..127 ], action(3): 128..128, immediate(3): 130..131, version(3): 240..243, match(3): 134..167, action(4): 129..129, immediate(4): 132..133, version(4): 244..247, match(4): [206..207, 168..199 ] } - match: [ HillTop.RossFork.Bicknell(6..7), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31) ] - gateway: - name: cond-23 - input_xbar: - exact group 0: { 9: HillTop.Ovett.Hammond.1-3(1), 21: HillTop.RossFork.Weyauwega, 30: HillTop.Murphy.Blairsden, 37: HillTop.RossFork.Naruna.2-2, 43: HillTop.RossFork.Juniata, 51: HillTop.Murphy.Standish, 59: HillTop.RossFork.Naruna.0-1 } - hash 0: - 40: HillTop.Murphy.Blairsden - 41: HillTop.Ovett.Hammond.1-3(1) - 42: HillTop.RossFork.Juniata - hash group 0: - table: [0] - seed: 0x0 - row: 1 - bus: 1 - unit: 0 - match: { 21: HillTop.RossFork.Weyauwega, 27: HillTop.Murphy.Standish, 32: HillTop.Murphy.Blairsden, 33: HillTop.Ovett.Hammond.1-3(1), 34: HillTop.RossFork.Juniata, 3: HillTop.RossFork.Naruna.0-1, 13: HillTop.RossFork.Naruna.2-2 } - 0b110****0*****0*******0********01: run_table - miss: _Elkton - condition: - expression: "(HillTop.RossFork.Weyauwega == 0 && HillTop.Murphy.Standish == 0 && HillTop.Murphy.Blairsden == 0 && HillTop.Ovett.Hammond & 4 == 4 && HillTop.RossFork.Juniata == 1 && HillTop.RossFork.Naruna == 1)" - true: _Romeo - false: _Elkton - hit: [ _Elkton ] - miss: _Elkton - action_bus: { 0 : immediate(0..1), 36..37 : immediate(0..1) } - action: _Romeo$action_data($DIRECT, $DEFAULT) - instruction: _Romeo(action, $DEFAULT) - actions: - Catlin(1, 2): - - p4_param_order: { Antoine: 16, Townville: 16, Monahans: 1, Pinole: 1 } - - default_action: { allowed: true } - - handle: 0x200000a1 - - next_table: 0 - - { Antoine: $adf_h0(0..15), Townville.12-15: $adf_h1(0..3), Townville.0-11: $adf_h1(4..15), Pinole: immediate(0..0), Monahans: immediate(1..1) } - - set HillTop.Salix.Hueytown, Antoine - - set HillTop.Komatke.Monahans, Monahans - - set HillTop.Komatke.Townville.0-11, Townville.0-11 - - set HillTop.Komatke.Townville.12-15, Townville.12-15 - - set HillTop.Komatke.Pinole, Pinole - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x200000a2 - - next_table: 0 - - { } - default_only_action: NoAction - idletime: - row: 4 - bus: 0 - column: [ 0, 1, 4 ] - precision: 1 - sweep_interval: 7 - notification: enable - per_flow_enable: false - action _Romeo$action_data: - p4: { name: Romeo$action } - row: [ 3, 1 ] - word: [ 0, 0 ] - column: - - [ 3, 4, 5 ] - - [ 4, 5 ] - vpns: - - [ 0, 1, 2 ] - - [ 3, 4 ] - home_row: - - 3 - format Catlin: { $adf_h0: 0..15, $adf_h1: 16..31 } - action_bus: { 40..41 : $adf_h0, 42..43 : $adf_h1 } - hash_action _Elkton 2: - p4: { name: Elkton, size: 2, disable_atomic_modify : true } - p4_param_order: - Millston.Calabash.$valid: { type: exact, size: 1, full_size: 1, key_name: "Calabash" } - row: 3 - bus: 1 - hash_dist: - 1: { hash: 2, mask: 0x1, shift: 3 } - input_xbar: - exact group 1: { 34: Millston.Calabash.$valid } - hash 2: - 16..16: stripe(Millston.Calabash.$valid) - hash group 2: - table: [2] - seed: 0x0 - gateway: - name: cond-22 - input_xbar: - exact group 0: { 97: HillTop.Wisdom.Onycha } - row: 2 - bus: 1 - unit: 0 - payload: 0x1 - format: { action: 0..0 } - match: { 1: HillTop.Wisdom.Onycha } - 0b****010: run_table - miss: Fittstown_0 - condition: - expression: "(HillTop.Wisdom.Onycha != 2)" - true: Fittstown_0 - false: Fittstown_0 - next: Fittstown_0 - action: _Elkton$action_data(hash_dist 1, $DEFAULT) - instruction: _Elkton(action, $DEFAULT) - actions: - Beatrice(1, 3): - - p4_param_order: { Avondale: 20 } - - default_action: { allowed: true } - - handle: 0x200000a0 - - next_table: 0 - - { Avondale: $adf_f0(0..19) } - - set HillTop.Wisdom.Dolores, HillTop.Lamona.Whitefish - - set HillTop.Wisdom.Connell.0-15, HillTop.RossFork.Connell.0-15 - - set HillTop.Wisdom.Nenana, HillTop.RossFork.CeeVee - - set HillTop.Wisdom.Morstein, Avondale - - or W10, W1, W10 - - deposit-field W13(8..31), W0(2..25), W14 - default_action: Beatrice - default_action_parameters: - Avondale: "0x1ff" - action _Elkton$action_data: - p4: { name: Elkton$action, how_referenced: direct } - row: 13 - column: 4 - vpns: [ 0 ] - home_row: - - 13 - format Beatrice: { $adf_f0: 0..31 } - action_bus: { 96..99 : $adf_f0 } - ternary_match Fittstown_0 3: - p4: { name: Fittstown, size: 256, disable_atomic_modify : true } - p4_param_order: - Millston.Bergton.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Bergton" } - Millston.Ramos.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Ramos" } - Millston.Provencal.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Provencal" } - Millston.Shirley.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Shirley" } - Millston.Grays.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Grays" } - Millston.GlenAvon.$valid: { type: ternary, size: 1, full_size: 1, key_name: "GlenAvon" } - Millston.Maumee.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Maumee" } - Millston.Calabash.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Calabash" } - row: 6 - bus: 1 - column: 1 - hash_dist: - 2: { hash: 2, mask: 0xffff, shift: 0 } - input_xbar: - ternary group 0: { 2: Millston.Provencal.$valid, 3: Millston.Grays.$valid, 8: Millston.Shirley.$valid, 10: Millston.Maumee.$valid, 18: Millston.Calabash.$valid, 20: Millston.GlenAvon.$valid, 21: Millston.Ramos.$valid, 22: Millston.Bergton.$valid } - exact group 2: { 0: Millston.Calabash.Connell.16-23, 8: Millston.Calabash.Adona, 32: Millston.Calabash.Fabens, 56: Millston.Calabash.Goldsboro.0-7, 64: Millston.Calabash.Goldsboro.8-23, 80: Millston.Calabash.Connell.0-15, 96: HillTop.RossFork.McCaulley.0-7, 104: HillTop.RossFork.McCaulley.8-15 } - hash 4: - 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 112, { 16: Millston.Calabash.Fabens, 40: Millston.Calabash.Goldsboro.0-7, 80: Millston.Calabash.Connell.16-23, 88: Millston.Calabash.Adona }, { })), 0..15) - hash 5: - 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 112, { 0: HillTop.RossFork.McCaulley.0-7, 8: HillTop.RossFork.McCaulley.8-15, 48: Millston.Calabash.Goldsboro.8-23, 64: Millston.Calabash.Connell.0-15 }, { })), 0..15) - hash group 2: - table: [4, 5] - seed: 0x0 - match: - - { group: 0, dirtcam: 0x15 } - hit: [ _Havana ] - miss: _Havana - indirect: Fittstown_0$tind - ternary_indirect Fittstown_0$tind: - row: 1 - bus: 0 - column: 5 - hash_dist: - 2: { hash: 2, mask: 0xffff, shift: 0 } - input_xbar: - ternary group 0: { 2: Millston.Provencal.$valid, 3: Millston.Grays.$valid, 8: Millston.Shirley.$valid, 10: Millston.Maumee.$valid, 18: Millston.Calabash.$valid, 20: Millston.GlenAvon.$valid, 21: Millston.Ramos.$valid, 22: Millston.Bergton.$valid } - exact group 2: { 0: Millston.Calabash.Connell.16-23, 8: Millston.Calabash.Adona, 32: Millston.Calabash.Fabens, 56: Millston.Calabash.Goldsboro.0-7, 64: Millston.Calabash.Goldsboro.8-23, 80: Millston.Calabash.Connell.0-15, 96: HillTop.RossFork.McCaulley.0-7, 104: HillTop.RossFork.McCaulley.8-15 } - hash 4: - 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 112, { 16: Millston.Calabash.Fabens, 40: Millston.Calabash.Goldsboro.0-7, 80: Millston.Calabash.Connell.16-23, 88: Millston.Calabash.Adona }, { })), 0..15) - hash 5: - 32..47: slice(stripe(crc_rev(0xc002, 0x0, 0x0, 112, { 0: HillTop.RossFork.McCaulley.0-7, 8: HillTop.RossFork.McCaulley.8-15, 48: Millston.Calabash.Goldsboro.8-23, 64: Millston.Calabash.Connell.0-15 }, { })), 0..15) - hash group 2: - table: [4, 5] - seed: 0x0 - format: { action: 0..2 } - action_bus: { 44..45 : hash_dist(2, lo) } - instruction: Fittstown_0$tind(action, $DEFAULT) - actions: - Watters(0, 4): - - default_action: { allowed: true } - - handle: 0x20000096 - - next_table: 0 - - set H51, hash_dist(2, 0..15) - Burmester(1, 6): - - default_action: { allowed: true } - - handle: 0x20000097 - - next_table: 0 - - set HillTop.Lewiston.Staunton, HillTop.Cutten.Pathfork - Petrolia(2, 8): - - default_action: { allowed: true } - - handle: 0x20000098 - - next_table: 0 - - set HillTop.Lewiston.Staunton, HillTop.Cutten.Tombstone - Aguada(3, 10): - - default_action: { allowed: true } - - handle: 0x20000099 - - next_table: 0 - - set HillTop.Lewiston.Staunton, HillTop.Cutten.Subiaco - Brush(4, 12): - - default_action: { allowed: true } - - handle: 0x2000009a - - next_table: 0 - - set HillTop.Lewiston.Staunton, HillTop.Cutten.Marcus - Ceiba(5, 14): - - default_action: { allowed: true } - - handle: 0x2000009b - - next_table: 0 - - set HillTop.Lewiston.Staunton, HillTop.Cutten.Pittsboro - Sequim(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x2000009c - - next_table: 0 - default_only_action: Sequim - ternary_match _Havana 4: - p4: { name: Havana, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.McCaulley: { type: ternary, size: 16, full_size: 16, key_name: "RossFork.McCaulley" } - HillTop.RossFork.Pridgen: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Pridgen" } - HillTop.RossFork.Tenino: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Tenino" } - HillTop.RossFork.Denhoff: { type: ternary, size: 3, full_size: 3, key_name: "RossFork.Denhoff" } - HillTop.RossFork.Chevak: { type: ternary, size: 16, full_size: 16, key_name: "RossFork.Chevak" } - HillTop.RossFork.Mendocino: { type: ternary, size: 16, full_size: 16, key_name: "RossFork.Mendocino" } - HillTop.Lamona.Fristoe: { type: ternary, size: 14, full_size: 14, key_name: "Lamona.Fristoe" } - HillTop.RossFork.Bicknell: { type: ternary, size: 12, full_size: 12, key_name: "RossFork.Bicknell" } - HillTop.Ovett.Hematite: { type: ternary, size: 1, full_size: 1, key_name: "Ovett.Hematite" } - HillTop.RossFork.Exton: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Exton" } - Millston.Rainelle.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Rainelle" } - Millston.Rainelle.Findlay: { type: ternary, size: 16, full_size: 16, key_name: "Rainelle.Findlay" } - HillTop.RossFork.Brinkman: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Brinkman" } - HillTop.Maddock.Calcasieu: { type: ternary, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } - HillTop.RossFork.Ocoee: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } - HillTop.Wisdom.Delavan: { type: ternary, size: 1, full_size: 1, key_name: "Wisdom.Delavan" } - HillTop.Wisdom.Onycha: { type: ternary, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } - HillTop.Sublett.Calcasieu: { type: ternary, size: 16, full_size: 128, key_name: "Sublett.Calcasieu", start_bit: 112 } - HillTop.RossFork.Parkland: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Parkland" } - HillTop.Wisdom.Blencoe: { type: ternary, size: 8, full_size: 8, key_name: "Wisdom.Blencoe" } - row: [ 0, 1, 2, 3, 4, 5 ] - bus: [ 0, 0, 0, 0, 0, 0 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - input_xbar: - ternary group 1: { 0: HillTop.Lamona.Fristoe(8..13), 8: HillTop.Maddock.Calcasieu(24..31), 16: HillTop.Maddock.Calcasieu(0..7), 24: HillTop.Lamona.Fristoe(0..7), 32: HillTop.Maddock.Calcasieu(16..23) } - ternary group 2: { 0: HillTop.Sublett.Calcasieu.96-127(24..31), 8: HillTop.RossFork.Bicknell(0..7), 16: HillTop.Maddock.Calcasieu(8..15), 24: HillTop.Sublett.Calcasieu.96-127(16..23), 32: HillTop.RossFork.Bicknell(8..11) } - ternary group 3: { 0: HillTop.RossFork.Mendocino(8..15), 8: HillTop.RossFork.Mendocino(0..7), 16: Millston.Rainelle.Findlay(8..15), 24: Millston.Rainelle.Findlay(0..7), 37: HillTop.Ovett.Hematite } - ternary group 4: { 0: HillTop.RossFork.Chevak(0..7), 14: HillTop.RossFork.Tenino, 15: HillTop.RossFork.Pridgen, 17: HillTop.Wisdom.Onycha, 24: HillTop.RossFork.Chevak(8..15), 39: HillTop.Wisdom.Delavan } - ternary group 5: { 0: HillTop.Wisdom.Blencoe, 8: HillTop.RossFork.Ocoee, 19: Millston.Rainelle.$valid, 24: HillTop.RossFork.McCaulley.0-7, 32: HillTop.RossFork.McCaulley.8-15 } - ternary group 6: { 0: HillTop.RossFork.Exton, 11: HillTop.RossFork.Denhoff.0-0, 21: HillTop.RossFork.Brinkman } - byte group 3: { 1: HillTop.RossFork.Parkland, 2: HillTop.RossFork.Denhoff.1-2 } - match: - - { group: 1, byte_group: 3, byte_config: 0, dirtcam: 0x555 } - - { group: 2, dirtcam: 0x155 } - - { group: 3, dirtcam: 0x155 } - - { group: 4, dirtcam: 0x155 } - - { group: 5, dirtcam: 0x155 } - - { group: 6, dirtcam: 0x15 } - hit: [ _Nooksack ] - miss: _Nooksack - indirect: _Havana$tind - counter _Havana$stats.Palco: - p4: { name: Palco } - row: 13 - column: [ 2, 3 ] - maprams: [ 2, 3 ] - count: packets_and_bytes - format: {packets(0): 0..63, bytes(0): 64..127} - ternary_indirect _Havana$tind: - row: 0 - bus: 1 - column: 3 - input_xbar: - ternary group 1: { 0: HillTop.Lamona.Fristoe(8..13), 8: HillTop.Maddock.Calcasieu(24..31), 16: HillTop.Maddock.Calcasieu(0..7), 24: HillTop.Lamona.Fristoe(0..7), 32: HillTop.Maddock.Calcasieu(16..23) } - ternary group 2: { 0: HillTop.Sublett.Calcasieu.96-127(24..31), 8: HillTop.RossFork.Bicknell(0..7), 16: HillTop.Maddock.Calcasieu(8..15), 24: HillTop.Sublett.Calcasieu.96-127(16..23), 32: HillTop.RossFork.Bicknell(8..11) } - ternary group 3: { 0: HillTop.RossFork.Mendocino(8..15), 8: HillTop.RossFork.Mendocino(0..7), 16: Millston.Rainelle.Findlay(8..15), 24: Millston.Rainelle.Findlay(0..7), 37: HillTop.Ovett.Hematite } - ternary group 4: { 0: HillTop.RossFork.Chevak(0..7), 14: HillTop.RossFork.Tenino, 15: HillTop.RossFork.Pridgen, 17: HillTop.Wisdom.Onycha, 24: HillTop.RossFork.Chevak(8..15), 39: HillTop.Wisdom.Delavan } - ternary group 5: { 0: HillTop.Wisdom.Blencoe, 8: HillTop.RossFork.Ocoee, 19: Millston.Rainelle.$valid, 24: HillTop.RossFork.McCaulley.0-7, 32: HillTop.RossFork.McCaulley.8-15 } - ternary group 6: { 0: HillTop.RossFork.Exton, 11: HillTop.RossFork.Denhoff.0-0, 21: HillTop.RossFork.Brinkman } - byte group 3: { 1: HillTop.RossFork.Parkland, 2: HillTop.RossFork.Denhoff.1-2 } - format: { action: 0..1, immediate: 2..17 } - action_bus: { 16 : immediate(0..7), 17 : immediate(8..15) } - stats: _Havana$stats.Palco($DIRECT, $DEFAULT) - instruction: _Havana$tind(action, $DEFAULT) - actions: - Melder(0, 5): - - p4_param_order: { Blencoe: 8 } - - default_action: { allowed: true } - - handle: 0x200000a7 - - next_table: 0 - - { Blencoe: immediate(0..7) } - - set ig_intr_md_for_tm.mcast_grp_a, 0 - - set HillTop.Wisdom.Havana, 1 - - set HillTop.Wisdom.Blencoe, Blencoe - - set HillTop.RossFork.Montross, 0 - - set HillTop.Moose.Pinole, 0 - - _Havana$stats.Palco($DIRECT) - FourTown(1, 7): - - p4_param_order: { Blencoe: 8, Redden: 1 } - - default_action: { allowed: true } - - handle: 0x200000a8 - - next_table: 0 - - { Redden: immediate(0..0), Blencoe: immediate(8..15) } - - set ig_intr_md_for_tm.copy_to_cpu, 1 - - set HillTop.Wisdom.Blencoe, Blencoe - - set HillTop.RossFork.Redden, Redden - - set HillTop.RossFork.Montross, 0 - - set HillTop.Moose.Pinole, 0 - - _Havana$stats.Palco($DIRECT) - Hyrum(2, 9): - - default_action: { allowed: true } - - handle: 0x200000a9 - - next_table: 0 - - { } - - set HillTop.RossFork.Redden, 1 - - set HillTop.RossFork.Montross, 0 - - set HillTop.Moose.Pinole, 0 - - _Havana$stats.Palco($DIRECT) - Farner(3, 11): - - default_action: { allowed: true } - - handle: 0x200000aa - - next_table: 0 - - { } - - set HillTop.RossFork.Montross, 0 - - set HillTop.Moose.Pinole, 0 - - _Havana$stats.Palco($DIRECT) - NoAction(-1, 13): - - default_only_action: { allowed: true } - - handle: 0x200000ab - - next_table: 0 - - { } - - set HillTop.RossFork.Montross, 0 - - set HillTop.Moose.Pinole, 0 - default_only_action: NoAction - exact_match _Nooksack 5: - p4: { name: Nooksack, size: 67584, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Ocoee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } - HillTop.Maddock.Kaluaaha: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } - Millston.Grays.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Grays.Chevak" } - HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } - Millston.Grays.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Grays.Mendocino" } - row: [ 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 6, 7 ] - - [ 2, 3, 4, 6, 7 ] - - [ 2, 3, 4, 6, 7 ] - - [ 2, 3, 4, 6, 7 ] - - [ 2, 3, 4, 6, 7 ] - stash: - row: [ 3, 4, 5, 6, 7 ] - col: [ 2, 2, 2, 2, 2 ] - unit: [ 0, 0, 0, 0, 0 ] - ways: - - [4, 0, 0x1, [7, 2], [6, 2], [5, 2], [4, 2], [3, 2], [7, 3], [6, 3], [5, 3], [4, 3], [3, 3]] - - [4, 1, 0x0, [7, 4], [6, 4], [5, 4], [4, 4], [3, 4]] - - [4, 2, 0x0, [7, 6], [6, 6], [5, 6], [4, 6], [3, 6]] - - [4, 3, 0x0, [7, 7], [6, 7], [5, 7], [4, 7], [3, 7]] - input_xbar: - exact group 3: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.Maddock.Kaluaaha, 64: Millston.Grays.Chevak, 80: Millston.Grays.Mendocino, 96: HillTop.RossFork.Ocoee } - hash 6: - 0..9: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) - 40: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) - 10..19: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) - 20..29: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) - 30..39: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) - hash 7: - 0..1: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) - 2..9: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee - 40: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) - 11..12: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) - 13..19: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(0..6) - 10: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(7) - 22..23: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) - 24..29: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(0..5) - 20..21: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(6..7) - 33..34: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) - 35..39: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(0..4) - 30..32: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(5..7) - hash group 4: - table: [6, 7] - seed: 0x15ad646b5e0 - format: { action(0): 2..3, version(0): 4..7, match(0): [98..103, 8..95 ], action(1): 0..1, version(1): 244..247, match(1): [506..511, 104..127, 224..239, 248..255, 352..367, 376..383, 480..495 ], action(2): 128..129, version(2): 240..243, match(2): 130..223, action(3): 256..257, version(3): 368..371, match(3): 258..351, action(4): 384..385, version(4): 496..499, match(4): 386..479, action(5): 512..513, version(5): 624..627, match(5): 514..607 } - match: [ Millston.Grays.Chevak(2..7), Millston.Grays.Chevak(8..15), Millston.Grays.Mendocino(0..7), Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31), HillTop.Maddock.Kaluaaha(0..7), HillTop.Maddock.Kaluaaha(8..15), HillTop.Maddock.Kaluaaha(16..23), HillTop.Maddock.Kaluaaha(24..31) ] - gateway: - name: cond-24 - input_xbar: - exact group 4: { 0: HillTop.RossFork.Merrill(0..7), 11: HillTop.Ovett.Hammond.0-0, 19: HillTop.RossFork.Alamosa, 21: HillTop.RossFork.Weyauwega, 29: HillTop.Ovett.Hematite, 37: HillTop.RossFork.Naruna.2-2, 40: HillTop.RossFork.Merrill(8..15), 51: HillTop.Murphy.Standish, 62: HillTop.Murphy.Blairsden, 67: HillTop.RossFork.Naruna.0-1 } - hash 8: - 44: HillTop.RossFork.Weyauwega - 45: HillTop.Ovett.Hematite - 46: HillTop.Murphy.Standish - 47: HillTop.Murphy.Blairsden - 48: HillTop.Ovett.Hammond.0-0 - 49: HillTop.RossFork.Alamosa - hash 9: - hash group 0: - table: [8, 9] - seed: 0x0 - row: 0 - bus: 1 - unit: 1 - match: { 36: HillTop.RossFork.Weyauwega, 37: HillTop.Ovett.Hematite, 38: HillTop.Murphy.Standish, 39: HillTop.Murphy.Blairsden, 40: HillTop.Ovett.Hammond.0-0, 19: HillTop.RossFork.Naruna.0-1, 29: HillTop.RossFork.Naruna.2-2, 0: HillTop.RossFork.Merrill(0..7), 8: HillTop.RossFork.Merrill(8..15), 41: HillTop.RossFork.Alamosa } - 0b010010******0********01***0000000000000000: run_table - miss: _Buras - condition: - expression: "(HillTop.RossFork.Weyauwega == 0 && HillTop.Ovett.Hematite == 1 && HillTop.Murphy.Standish == 0 && HillTop.Murphy.Blairsden == 0 && (HillTop.Ovett.Hammond & 1 == 1 && HillTop.RossFork.Naruna == 1 && HillTop.RossFork.Merrill == 0 && HillTop.RossFork.Alamosa == 0))" - true: _Nooksack - false: _Buras - hit: [ [], _Buras, _Buras, _Pineville ] - miss: _Nooksack$st1 - action: _Nooksack$action_data($DIRECT, $DEFAULT) - instruction: _Nooksack(action, $DEFAULT) - actions: - Milano(1, 15): - - p4_param_order: { Kaluaaha: 32, Bratt: 32 } - - default_action: { allowed: true } - - handle: 0x200000ac - - next_table: 1 - - { Kaluaaha: $adf_f0(0..31), Bratt.0-15: $adf_f1(0..15) } - - set HillTop.Maddock.Kaluaaha, Kaluaaha - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Boerne, 1 - - set HillTop.RossFork.Suttle, 1 - Biggers(2, 16): - - p4_param_order: { Kaluaaha: 32, Avondale: 16, Bratt: 32 } - - default_action: { allowed: true } - - handle: 0x200000ad - - next_table: 2 - - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Kaluaaha: $adf_f1(0..31) } - - set HillTop.RossFork.Glenmora, Avondale - - set HillTop.Maddock.Kaluaaha, Kaluaaha - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Boerne, 1 - - set HillTop.RossFork.Suttle, 1 - Sequim(3, 0): - - default_action: { allowed: true } - - handle: 0x200000ae - - next_table: 3 - - { } - default_action: Sequim - idletime: - row: 0 - bus: 0 - column: [ 0, 1, 2, 3 ] - precision: 1 - sweep_interval: 7 - notification: enable - per_flow_enable: false - action _Nooksack$action_data: - p4: { name: Nooksack$action } - row: [ 15, 14, 13, 12, 10, 9, 8, 6, 5, 1 ] - word: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - [ 4, 5 ] - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - [ 4, 5 ] - - [ 0, 1, 2, 3 ] - vpns: - - [ 0, 1 ] - - [ 2 ] - - [ 3 ] - - [ 4 ] - - [ 5 ] - - [ 6 ] - - [ 7 ] - - [ 8 ] - - [ 9, 10 ] - - [ 11, 12, 13, 14 ] - home_row: - - [ 15, 1 ] - format Milano: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Biggers: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - action_bus: { 50..51 : $adf_h1, 108..111 : $adf_f1, 48..51 : $adf_f0 } -stage 7 ingress: - ternary_match _Pineville 1: - p4: { name: Pineville, size: 4096, disable_atomic_modify : true } - p4_param_order: - HillTop.Maddock.Calcasieu: { type: ternary, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } - HillTop.RossFork.Ocoee: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } - HillTop.Bessie.Peebles: { type: ternary, size: 1, full_size: 1, key_name: "Bessie.Peebles" } - row: [ 10, 11, 0, 1, 2, 3, 4, 5 ] - bus: [ 0, 0, 1, 1, 1, 1, 1, 1 ] - column: - - 0 - - 0 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - input_xbar: - ternary group 0: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.RossFork.Ocoee } - byte group 0: { 5: HillTop.Bessie.Peebles } - match: - - { group: 0, byte_group: 0, byte_config: 1, dirtcam: 0x555 } - hit: [ _Buras ] - miss: _Buras - indirect: _Pineville$tind - ternary_indirect _Pineville$tind: - row: 2 - bus: 0 - column: 3 - input_xbar: - ternary group 0: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.RossFork.Ocoee } - byte group 0: { 5: HillTop.Bessie.Peebles } - format: { action: 0..0, immediate: 1..12 } - action_bus: { 104..107 : immediate(0..11) } - instruction: _Pineville$tind(action, $DEFAULT) - actions: - Hearne(0, 3): - - p4_param_order: { Moultrie: 12 } - - default_action: { allowed: true } - - handle: 0x200000af - - next_table: 0 - - { Moultrie: immediate(0..11) } - - set HillTop.RossFork.Montross, Moultrie - Pinetop(1, 0): - - default_action: { allowed: true } - - handle: 0x200000b0 - - next_table: 0 - - { } - default_action: Pinetop - exact_match _Nooksack$st1 0: - p4: { name: Nooksack, size: 67584, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Ocoee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } - HillTop.Maddock.Kaluaaha: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } - Millston.Grays.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Grays.Chevak" } - HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } - Millston.Grays.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Grays.Mendocino" } - row: [ 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0 ] - column: - - [ 2, 6, 7, 8, 9, 10 ] - - [ 2, 6, 7, 8, 9, 10 ] - - [ 2, 6, 7, 8, 9, 10 ] - - [ 2, 6, 7, 8, 9, 10 ] - - [ 2, 6, 7, 8, 9, 10 ] - stash: - row: [ 3, 4, 5, 6, 7 ] - col: [ 2, 2, 2, 2, 2 ] - unit: [ 0, 0, 0, 0, 0 ] - ways: - - [0, 0, 0x1, [7, 2], [6, 2], [5, 2], [4, 2], [3, 2], [7, 6], [6, 6], [5, 6], [4, 6], [3, 6]] - - [0, 1, 0x2, [7, 7], [6, 7], [5, 7], [4, 7], [3, 7], [7, 8], [6, 8], [5, 8], [4, 8], [3, 8]] - - [0, 2, 0x0, [7, 9], [6, 9], [5, 9], [4, 9], [3, 9]] - - [0, 3, 0x0, [7, 10], [6, 10], [5, 10], [4, 10], [3, 10]] - input_xbar: - exact group 0: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.Maddock.Kaluaaha, 64: Millston.Grays.Chevak, 80: Millston.Grays.Mendocino, 96: HillTop.RossFork.Ocoee } - hash 0: - 0..9: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) - 40: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) - 10..19: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) - 41: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) - 20..29: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) - 30..39: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) - hash 1: - 0..1: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) - 2..9: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee - 40: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) - 11..12: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) - 13..19: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(0..6) - 10: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(7) - 41: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) - 22..23: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) - 24..29: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(0..5) - 20..21: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(6..7) - 33..34: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) - 35..39: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(0..4) - 30..32: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(5..7) - hash group 0: - table: [0, 1] - seed: 0xe86e73c23b - format: { action(0): 2..3, version(0): 4..7, match(0): [98..103, 8..95 ], action(1): 0..1, version(1): 244..247, match(1): [506..511, 104..127, 224..239, 248..255, 352..367, 376..383, 480..495 ], action(2): 128..129, version(2): 240..243, match(2): 130..223, action(3): 256..257, version(3): 368..371, match(3): 258..351, action(4): 384..385, version(4): 496..499, match(4): 386..479, action(5): 512..513, version(5): 624..627, match(5): 514..607 } - match: [ Millston.Grays.Chevak(2..7), Millston.Grays.Chevak(8..15), Millston.Grays.Mendocino(0..7), Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31), HillTop.Maddock.Kaluaaha(0..7), HillTop.Maddock.Kaluaaha(8..15), HillTop.Maddock.Kaluaaha(16..23), HillTop.Maddock.Kaluaaha(24..31) ] - hit: [ _Buras, _Buras, _Pineville ] - miss: _Buras - action: _Nooksack$st1$action_data($DIRECT, $DEFAULT) - instruction: _Nooksack$st1(action, $DEFAULT) - actions: - Milano(0, 1): - - p4_param_order: { Kaluaaha: 32, Bratt: 32 } - - default_action: { allowed: true } - - handle: 0x200000ac - - next_table: 0 - - { Kaluaaha: $adf_f0(0..31), Bratt.0-15: $adf_f1(0..15) } - - set HillTop.Maddock.Kaluaaha, Kaluaaha - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Boerne, 1 - - set HillTop.RossFork.Suttle, 1 - Biggers(1, 2): - - p4_param_order: { Kaluaaha: 32, Avondale: 16, Bratt: 32 } - - default_action: { allowed: true } - - handle: 0x200000ad - - next_table: 1 - - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Kaluaaha: $adf_f1(0..31) } - - set HillTop.RossFork.Glenmora, Avondale - - set HillTop.Maddock.Kaluaaha, Kaluaaha - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Boerne, 1 - - set HillTop.RossFork.Suttle, 1 - Sequim(2, 0): - - default_action: { allowed: true } - - handle: 0x200000ae - - next_table: 2 - - { } - default_action: Sequim - idletime: - row: 4 - bus: 0 - column: [ 0, 1, 2, 3, 4 ] - precision: 1 - sweep_interval: 7 - notification: enable - per_flow_enable: false - action _Nooksack$st1$action_data: - p4: { name: Nooksack$action } - row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4 ] - word: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - 5 - - 5 - - 5 - - [ 4, 5 ] - - 5 - - [ 4, 5 ] - - 5 - - [ 3, 4, 5 ] - - 5 - - [ 3, 4, 5 ] - - 5 - - 4 - vpns: - - [ 0 ] - - [ 1 ] - - [ 2 ] - - [ 3, 4 ] - - [ 5 ] - - [ 6, 7 ] - - [ 8 ] - - [ 9, 10, 11 ] - - [ 12 ] - - [ 13, 14, 15 ] - - [ 16 ] - - [ 17 ] - home_row: - - 15 - format Milano: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Biggers: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - action_bus: { 34..35 : $adf_h1, 100..103 : $adf_f1, 32..35 : $adf_f0 } - hash_action _Buras 2: - p4: { name: Buras, size: 256, disable_atomic_modify : true } - p4_param_order: - HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } - row: 3 - bus: 1 - hash_dist: - 0: { hash: 1, mask: 0xff, shift: 5 } - input_xbar: - exact group 1: { 4: HillTop.Bessie.Miranda } - hash 2: - 0..7: stripe(HillTop.Bessie.Miranda) - hash group 1: - table: [2] - seed: 0x0 - gateway: - name: _Buras-gateway - row: 2 - bus: 0 - unit: 1 - 0x0: _Mabana - miss: _Mabana - condition: - expression: "true(always hit)" - true: _Mabana - false: _Mabana - next: [] - action: _Buras$action_data(hash_dist 0, $DEFAULT) - instruction: _Buras($DEFAULT, $DEFAULT) - actions: - Eudora(0, 4): - - p4_param_order: { Kaluaaha: 16, Calcasieu: 16, Chevak: 16, Mendocino: 16, LasVegas: 8, PineCity: 6, Exton: 8, Noyes: 8, Peebles: 1 } - - default_action: { allowed: true } - - handle: 0x2000005f - - next_table: 0 - - { Peebles: $adf_b0(5..5), Noyes: $adf_b1(0..7), LasVegas: $adf_b2(0..7), Exton: $adf_b3(0..7), Chevak: $adf_h2(0..15), Mendocino: $adf_h3(0..15), Calcasieu: $adf_h4(0..15), Kaluaaha: $adf_h5(0..15), PineCity: $adf_h6(6..11) } - - and HillTop.Savery.Kaluaaha, HillTop.Bessie.Kaluaaha, Kaluaaha - - and HillTop.Savery.Calcasieu, HillTop.Bessie.Calcasieu, Calcasieu - - and HillTop.Savery.Chevak, HillTop.Bessie.Chevak, Chevak - - and HillTop.Savery.Mendocino, HillTop.Bessie.Mendocino, Mendocino - - and HillTop.Savery.LasVegas, HillTop.Bessie.LasVegas, LasVegas - - and HillTop.Savery.Exton, HillTop.Bessie.Exton, Exton - - and HillTop.Savery.Noyes, HillTop.Bessie.Noyes, Noyes - - and B10, Peebles, B9 - - and H85, PineCity, H90 - default_action: Eudora - default_action_parameters: - Kaluaaha: "0xffff" - Calcasieu: "0xffff" - Chevak: "0xffff" - Mendocino: "0xffff" - LasVegas: "0xff" - PineCity: "0x3f" - Exton: "0xff" - Noyes: "0xff" - Peebles: "0x1" - action _Buras$action_data: - p4: { name: Buras$action, how_referenced: direct } - row: 10 - column: 3 - vpns: [ 0 ] - home_row: - - 10 - format Eudora: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_b2: 16..23, $adf_b3: 24..31, $adf_h2: 32..47, $adf_h3: 48..63, $adf_h4: 64..79, $adf_h5: 80..95, $adf_h6: 96..111 } - action_bus: { 16 : $adf_b0, 17 : $adf_b1, 18 : $adf_b2, 19 : $adf_b3, 64..65 : $adf_h4, 66..67 : $adf_h5, 68..69 : $adf_h6, 36..37 : $adf_h2, 38..39 : $adf_h3 } - ternary_match _Mabana 3: - p4: { name: Mabana, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Naruna: { type: exact, size: 3, full_size: 3, key_name: "RossFork.Naruna" } - HillTop.RossFork.Joslin: { type: exact, size: 3, full_size: 3, key_name: "RossFork.Joslin" } - Millston.GlenAvon.$valid: { type: exact, size: 1, full_size: 1, key_name: "GlenAvon" } - Millston.GlenAvon.Rexville: { type: ternary, size: 14, full_size: 16, key_name: "GlenAvon.Rexville" } - Millston.Maumee.Norwood: { type: ternary, size: 14, full_size: 16, key_name: "Maumee.Norwood" } - row: [ 8, 9 ] - bus: [ 0, 0 ] - column: - - 0 - - 0 - input_xbar: - ternary group 1: { 5: HillTop.RossFork.Joslin, 8: Millston.GlenAvon.Rexville(8..13), 16: Millston.GlenAvon.Rexville(0..7), 29: HillTop.RossFork.Naruna.2-2, 32: Millston.Maumee.Norwood.8-15(0..5) } - ternary group 2: { 0: Millston.Maumee.Norwood.0-7, 12: Millston.GlenAvon.$valid, 19: HillTop.RossFork.Naruna.0-1 } - match: - - { group: 1, dirtcam: 0x155 } - - { group: 2, dirtcam: 0x15 } - hit: [ _Somis ] - miss: _Somis - indirect: _Mabana$tind - ternary_indirect _Mabana$tind: - row: 1 - bus: 0 - column: 3 - input_xbar: - ternary group 1: { 5: HillTop.RossFork.Joslin, 8: Millston.GlenAvon.Rexville(8..13), 16: Millston.GlenAvon.Rexville(0..7), 29: HillTop.RossFork.Naruna.2-2, 32: Millston.Maumee.Norwood.8-15(0..5) } - ternary group 2: { 0: Millston.Maumee.Norwood.0-7, 12: Millston.GlenAvon.$valid, 19: HillTop.RossFork.Naruna.0-1 } - format: { action: 0..0, immediate: 1..2 } - action_bus: { 40..41 : immediate(0..1) } - instruction: _Mabana$tind(action, $DEFAULT) - actions: - Sneads(0, 5): - - p4_param_order: { Bradner: 2 } - - default_action: { allowed: true } - - handle: 0x20000060 - - next_table: 0 - - { Bradner: immediate(0..1) } - - set HillTop.RossFork.Bradner, Bradner - Hemlock(1, 6): - - default_action: { allowed: true } - - handle: 0x20000061 - - next_table: 0 - - { } - - set HillTop.RossFork.Ravena, 1 - default_action: Hemlock - ternary_match _Somis 4: - p4: { name: Somis, size: 1024, disable_atomic_modify : true } - p4_param_order: - HillTop.Lamona.Fristoe: { type: ternary, size: 14, full_size: 14, key_name: "Lamona.Fristoe" } - HillTop.Tiburon.Arnold: { type: ternary, size: 9, full_size: 9, key_name: "Tiburon.Arnold" } - HillTop.Edwards.PineCity: { type: ternary, size: 6, full_size: 6, key_name: "Edwards.PineCity" } - HillTop.Bessie.Heuvelton: { type: ternary, size: 16, full_size: 16, key_name: "Bessie.Heuvelton" } - HillTop.Bessie.Chavies: { type: ternary, size: 16, full_size: 16, key_name: "Bessie.Chavies" } - HillTop.RossFork.Ocoee: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } - HillTop.RossFork.Exton: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Exton" } - Millston.Grays.Chevak: { type: ternary, size: 16, full_size: 16, key_name: "Grays.Chevak" } - Millston.Grays.Mendocino: { type: ternary, size: 16, full_size: 16, key_name: "Grays.Mendocino" } - Millston.Grays.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Grays" } - HillTop.Bessie.Peebles: { type: ternary, size: 1, full_size: 1, key_name: "Bessie.Peebles" } - HillTop.Bessie.Noyes: { type: ternary, size: 8, full_size: 8, key_name: "Bessie.Noyes" } - HillTop.RossFork.Naruna: { type: ternary, size: 3, full_size: 3, key_name: "RossFork.Naruna" } - row: [ 0, 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - input_xbar: - ternary group 3: { 0: HillTop.Bessie.Heuvelton(6..13), 8: HillTop.Lamona.Fristoe(8..13), 16: Millston.Grays.Chevak(8..15), 26: HillTop.Bessie.Heuvelton(0..5), 32: HillTop.Lamona.Fristoe(0..7) } - ternary group 4: { 0: Millston.Grays.Chevak(0..7), 8: Millston.Grays.Mendocino(8..15), 16: Millston.Grays.Mendocino(0..7), 24: HillTop.Tiburon.Arnold(8), 32: HillTop.Tiburon.Arnold(0..7) } - ternary group 5: { 0: HillTop.Bessie.Chavies, 16: HillTop.Edwards.PineCity, 29: HillTop.RossFork.Naruna.2-2, 35: Millston.Grays.$valid } - ternary group 6: { 0: HillTop.Bessie.Noyes, 8: HillTop.RossFork.Ocoee, 16: HillTop.RossFork.Exton, 27: HillTop.RossFork.Naruna.0-1 } - byte group 0: { 5: HillTop.Bessie.Peebles } - byte group 3: { 0: HillTop.Bessie.Heuvelton(14..15) } - match: - - { group: 3, byte_group: 0, byte_config: 1, dirtcam: 0x555 } - - { group: 4, dirtcam: 0x155 } - - { group: 5, byte_group: 3, byte_config: 0, dirtcam: 0x555 } - - { group: 6, dirtcam: 0x55 } - hit: [ _Sanborn ] - miss: _Sanborn - indirect: _Somis$tind - ternary_indirect _Somis$tind: - row: 0 - bus: 0 - column: 3 - input_xbar: - ternary group 3: { 0: HillTop.Bessie.Heuvelton(6..13), 8: HillTop.Lamona.Fristoe(8..13), 16: Millston.Grays.Chevak(8..15), 26: HillTop.Bessie.Heuvelton(0..5), 32: HillTop.Lamona.Fristoe(0..7) } - ternary group 4: { 0: Millston.Grays.Chevak(0..7), 8: Millston.Grays.Mendocino(8..15), 16: Millston.Grays.Mendocino(0..7), 24: HillTop.Tiburon.Arnold(8), 32: HillTop.Tiburon.Arnold(0..7) } - ternary group 5: { 0: HillTop.Bessie.Chavies, 16: HillTop.Edwards.PineCity, 29: HillTop.RossFork.Naruna.2-2, 35: Millston.Grays.$valid } - ternary group 6: { 0: HillTop.Bessie.Noyes, 8: HillTop.RossFork.Ocoee, 16: HillTop.RossFork.Exton, 27: HillTop.RossFork.Naruna.0-1 } - byte group 0: { 5: HillTop.Bessie.Peebles } - byte group 3: { 0: HillTop.Bessie.Heuvelton(14..15) } - format: { action: 0..0, immediate: 1..10 } - action_bus: { 44..45 : immediate(0..9) } - instruction: _Somis$tind(action, $DEFAULT) - actions: - Level(0, 7): - - default_action: { allowed: true } - - handle: 0x200000a4 - - next_table: 0 - - { } - - set HillTop.RossFork.Level, 1 - Tullytown(1, 8): - - p4_param_order: { Heaton: 10 } - - default_action: { allowed: true } - - handle: 0x200000a5 - - next_table: 0 - - { Heaton: immediate(0..9) } - - set HillTop.Minturn.Grassflat, Heaton - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x200000a6 - - next_table: 0 - - { } - default_only_action: NoAction - exact_match _Sanborn 5: - p4: { name: Sanborn, size: 16384, disable_atomic_modify : true } - p4_param_order: - HillTop.Wisdom.Adona: { type: exact, size: 24, full_size: 24, key_name: "Wisdom.Adona" } - HillTop.Wisdom.Connell: { type: exact, size: 24, full_size: 24, key_name: "Wisdom.Connell" } - HillTop.Wisdom.Nenana: { type: exact, size: 12, full_size: 12, key_name: "Wisdom.Nenana" } - row: [ 2, 1 ] - bus: [ 0, 0 ] - column: - - [ 2, 6, 7, 8, 9, 10 ] - - [ 2, 6 ] - stash: - row: [ 2 ] - col: [ 2 ] - unit: [ 0 ] - ways: - - [2, 0, 0x1, [2, 2], [2, 6]] - - [2, 1, 0x2, [2, 7], [2, 8]] - - [2, 2, 0x4, [2, 9], [2, 10]] - - [2, 3, 0x8, [1, 2], [1, 6]] - input_xbar: - exact group 2: { 0: HillTop.Wisdom.Connell.16-23, 8: HillTop.Wisdom.Adona, 32: HillTop.Wisdom.Nenana, 48: HillTop.Wisdom.Connell.0-15 } - hash 4: - 0..6: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(0..6) - 7..9: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(8..10) - 40: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(11) - 11..17: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(0..6) - 18..19: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(8..9) - 10: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(11) - 41: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(10) - 22..28: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(0..6) - 29: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(8) - 20..21: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(10..11) - 42: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(9) - 33..39: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(0..6) - 30..32: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(9..11) - 43: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(8) - hash group 2: - table: [4] - seed: 0x158d36c8b1b - format: { action(0): 0..0, immediate(0): 2..3, version(0): 112..115, match(0): [87..87, 32..79 ], action(1): 1..1, immediate(1): 4..5, version(1): 116..119, match(1): [7..7, 88..111, 8..31 ] } - match: [ HillTop.Wisdom.Nenana(7), HillTop.Wisdom.Connell.0-15(0..7), HillTop.Wisdom.Connell.0-15(8..15), HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona(0..7), HillTop.Wisdom.Adona(8..15), HillTop.Wisdom.Adona(16..23) ] - gateway: - name: cond-25 - input_xbar: - exact group 0: { 110: HillTop.RossFork.Tenino } - row: 2 - bus: 1 - unit: 0 - match: { 6: HillTop.RossFork.Tenino } - 0b*1: run_table - miss: _Uvalde - condition: - expression: "(HillTop.RossFork.Tenino == 1)" - true: _Sanborn - false: _Uvalde - hit: [ _Uvalde ] - miss: _Uvalde - action_bus: { 48..49 : immediate(0..1) } - action: _Sanborn$action_data($DIRECT, $DEFAULT) - instruction: _Sanborn(action, $DEFAULT) - actions: - CassCity(1, 9): - - p4_param_order: { Townville: 16, Monahans: 1, Pinole: 1 } - - default_action: { allowed: true } - - handle: 0x200000b1 - - next_table: 0 - - { Townville: $adf_h0(0..15), Pinole: immediate(0..0), Monahans: immediate(1..1) } - - set HillTop.Moose.Townville, Townville - - set HillTop.Moose.Monahans, Monahans - - set HillTop.Moose.Pinole, Pinole - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x200000b2 - - next_table: 0 - - { } - default_only_action: NoAction - action _Sanborn$action_data: - p4: { name: Sanborn$action } - row: 14 - column: [ 3, 4 ] - vpns: [ 0, 1 ] - home_row: - - 14 - format CassCity: { $adf_h0: 0..15 } - action_bus: { 52..53 : $adf_h0 } - ternary_match _Uvalde 6: - p4: { name: Uvalde, size: 1, disable_atomic_modify : true } - gateway: - name: cond-26 - input_xbar: - exact group 1: { 64: HillTop.Naubinway.Bonduel } - row: 0 - bus: 1 - unit: 1 - match: { 0: HillTop.Naubinway.Bonduel(0..7), 8: HillTop.Naubinway.Bonduel(8..13) } - 0b**00000000000000: Sodaville_0 - miss: run_table - condition: - expression: "(HillTop.Naubinway.Bonduel != 0)" - true: _Uvalde - false: Sodaville_0 - hit: [ _Bonduel ] - miss: _Bonduel - indirect: _Uvalde$tind - ternary_indirect _Uvalde$tind: - row: 2 - bus: 1 - format: { action: 0..0 } - instruction: _Uvalde$tind(action, $DEFAULT) - actions: - Uniopolis(1, 10): - - default_action: { allowed: true } - - handle: 0x200000b5 - - next_table: 0 - - set HillTop.RossFork.Uvalde, HillTop.RossFork.Kapalua - default_action: Uniopolis - hash_action _Bonduel 7: - p4: { name: Bonduel, size: 16384, disable_atomic_modify : true } - p4_param_order: - HillTop.Naubinway.Bonduel: { type: exact, size: 14, full_size: 14, key_name: "Naubinway.Bonduel" } - row: 0 - bus: 1 - hash_dist: - 1: { hash: 1, mask: 0x3fff, shift: 4 } - input_xbar: - exact group 1: { 64: HillTop.Naubinway.Bonduel } - hash 3: - 16..29: stripe(HillTop.Naubinway.Bonduel) - hash group 1: - table: [3] - seed: 0x0 - gateway: - name: cond-27 - input_xbar: - exact group 2: { 68: HillTop.Naubinway.Bonduel(4..13) } - row: 0 - bus: 0 - unit: 0 - payload: 0x1 - format: { action: 0..0 } - match: { 4: HillTop.Naubinway.Bonduel(4..7), 8: HillTop.Naubinway.Bonduel(8..13) } - 0b**0000000000: run_table - miss: _GunnCity - condition: - expression: "(HillTop.Naubinway.Bonduel & 16368 == 0)" - true: _Kempton - false: _GunnCity - next: _Kempton - action: _Bonduel$action_data(hash_dist 1, $DEFAULT) - instruction: _Bonduel(action, $DEFAULT) - actions: - Ossining(1, 11): - - p4_param_order: { Adona: 24, Connell: 24, Nason: 12 } - - default_action: { allowed: true } - - handle: 0x200000b9 - - next_table: 0 - - { Nason: $adf_h0(0..11), Connell.0-15: $adf_h1(0..15), $data0: $adf_f1(0..31), Connell.16-23: $data0(0..7), Adona: $data0(8..31) } - - set HillTop.Wisdom.Connell.0-15, Connell.0-15 - - set HillTop.Wisdom.Nenana, Nason - - set W13, $data0 - default_action: Ossining - default_action_parameters: - Adona: "0x0" - Connell: "0x0" - Nason: "0x0" - action _Bonduel$action_data: - p4: { name: Bonduel$action, how_referenced: direct } - row: [ 4, 3, 2, 1 ] - word: [ 0, 0, 0, 0 ] - column: - - 5 - - [ 2, 3, 4, 5 ] - - [ 4, 5 ] - - 0 - vpns: - - [ 0 ] - - [ 1, 2, 3, 4 ] - - [ 5, 6 ] - - [ 7 ] - home_row: - - 4 - format Ossining: { $adf_h0: 0..15, $adf_h1: 16..31, $adf_f1: 32..63 } - action_bus: { 56..57 : $adf_h0, 58..59 : $adf_h1, 116..119 : $adf_f1 } - exact_match _Kempton 8: - p4: { name: Kempton, size: 16, disable_atomic_modify : true } - p4_param_order: - HillTop.Naubinway.Bonduel: { type: exact, size: 4, full_size: 14, key_name: "Naubinway.Bonduel" } - row: 0 - bus: 0 - column: 2 - stash: - row: [ 0 ] - col: [ 2 ] - unit: [ 0 ] - ways: - - [3, 0, 0x0, [0, 2]] - input_xbar: - exact group 2: { 64: HillTop.Naubinway.Bonduel(0..3) } - hash 5: - 0..3: HillTop.Naubinway.Bonduel(0..3) - hash group 3: - table: [5] - seed: 0x0 - format: { immediate(0): 0..7, version(0): 112..115 } - hit: [ Sodaville_0 ] - miss: Sodaville_0 - action_bus: { 0 : immediate(0..7) } - instruction: _Kempton($DEFAULT, $DEFAULT) - actions: - Moosic(0, 12): - - p4_param_order: { Blencoe: 8 } - - default_action: { allowed: true } - - handle: 0x200000b6 - - next_table: 0 - - { Blencoe: immediate(0..7) } - - set HillTop.Wisdom.Havana, 1 - - set HillTop.Wisdom.Blencoe, Blencoe - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x200000b7 - - next_table: 0 - - { } - default_only_action: NoAction - hash_action _GunnCity 9: - p4: { name: GunnCity, size: 16384, disable_atomic_modify : true } - p4_param_order: - HillTop.Naubinway.Bonduel: { type: exact, size: 14, full_size: 14, key_name: "Naubinway.Bonduel" } - row: 2 - bus: 1 - hash_dist: - 2: { hash: 1, mask: 0x3fff, shift: 3 } - input_xbar: - exact group 1: { 64: HillTop.Naubinway.Bonduel } - hash 3: - 32..45: stripe(HillTop.Naubinway.Bonduel) - hash group 1: - table: [3] - seed: 0x0 - gateway: - name: _GunnCity-gateway - row: 1 - bus: 0 - unit: 1 - 0x0: Sodaville_0 - miss: Sodaville_0 - condition: - expression: "true(always hit)" - true: Sodaville_0 - false: Sodaville_0 - next: [] - action: _GunnCity$action_data(hash_dist 2, $DEFAULT) - instruction: _GunnCity($DEFAULT, $DEFAULT) - actions: - Marquand(0, 13): - - p4_param_order: { Morstein: 20, Placedo: 10, TroutRun: 2 } - - default_action: { allowed: true } - - handle: 0x200000b8 - - next_table: 0 - - { Morstein: $adf_f0(0..19), TroutRun: $adf_h1(4..5) } - - set HillTop.Wisdom.Piqua, 1 - - set HillTop.Wisdom.Morstein, Morstein - - set HillTop.RossFork.TroutRun, TroutRun - default_action: Marquand - default_action_parameters: - Morstein: "0x1ff" - Placedo: "0x0" - TroutRun: "0x0" - action _GunnCity$action_data: - p4: { name: GunnCity$action, how_referenced: direct } - row: 1 - column: [ 1, 2, 3, 4 ] - vpns: [ 0, 1, 2, 3 ] - home_row: - - 1 - format Marquand: { $adf_f0: 0..31, $adf_h1: 16..31 } - action_bus: { 62..63 : $adf_h1, 60..63 : $adf_f0 } - exact_match Sodaville_0 10: - p4: { name: Sodaville, size: 1024, disable_atomic_modify : true } - p4_param_order: - HillTop.Wisdom.Onycha: { type: exact, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } - HillTop.RossFork.Ocoee: { type: exact, size: 1, full_size: 8, key_name: "RossFork.Ocoee", start_bit: 7 } - Millston.GlenAvon.$valid: { type: exact, size: 1, full_size: 1, key_name: "GlenAvon" } - Millston.Maumee.$valid: { type: exact, size: 1, full_size: 1, key_name: "Maumee" } - row: 1 - bus: 1 - column: 7 - stash: - row: [ 1 ] - col: [ 7 ] - unit: [ 0 ] - ways: - - [3, 1, 0x0, [1, 7]] - input_xbar: - exact group 2: { 81: HillTop.Wisdom.Onycha, 90: Millston.Maumee.$valid, 103: HillTop.RossFork.Ocoee(7), 108: Millston.GlenAvon.$valid } - hash 5: - 10..12: HillTop.Wisdom.Onycha - 13: Millston.Maumee.$valid - 14: HillTop.RossFork.Ocoee(7) - 15: Millston.GlenAvon.$valid - hash group 3: - table: [5] - seed: 0x0 - format: { action(0): 0..1, immediate(0): 2..17, version(0): 112..115 } - hit: [ _Weissert ] - miss: _Weissert - action_bus: { 20 : immediate(0..7), 21 : immediate(8..15) } - instruction: Sodaville_0(action, $DEFAULT) - actions: - Boyes(0, 14): - - p4_param_order: { Renfroe: 1 } - - default_action: { allowed: true } - - handle: 0x200000e3 - - next_table: 0 - - { Renfroe: immediate(0..0), $constant0: immediate(8..15), $constant0: 128 } - - set HillTop.Wisdom.Dyess, Renfroe - - or Millston.GlenAvon.Ocoee, Millston.GlenAvon.Ocoee, $constant0 - McCallum(1, 16): - - p4_param_order: { Renfroe: 1 } - - default_action: { allowed: true } - - handle: 0x200000e4 - - next_table: 0 - - { Renfroe: immediate(0..0), $constant0: immediate(8..15), $constant0: 128 } - - set HillTop.Wisdom.Dyess, Renfroe - - or Millston.Maumee.Dassel, Millston.Maumee.Dassel, $constant0 - Waucousta(2, 15): - - default_action: { allowed: true } - - handle: 0x200000e5 - - next_table: 0 - - { } - - set Millston.GlenAvon.$valid, 0 - - set Millston.Wondervu$0.$valid, 0 - - set Millston.Calabash.McCaulley.0-7, HillTop.RossFork.McCaulley.0-7 - - set Millston.Calabash.McCaulley.8-15, HillTop.RossFork.McCaulley.8-15 - Selvin(3, 17): - - default_action: { allowed: true } - - handle: 0x200000e6 - - next_table: 0 - - { } - - set Millston.Maumee.$valid, 0 - - set Millston.Wondervu$0.$valid, 0 - - set Millston.Calabash.McCaulley.0-7, HillTop.RossFork.McCaulley.0-7 - - set Millston.Calabash.McCaulley.8-15, HillTop.RossFork.McCaulley.8-15 - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x200000e7 - - next_table: 0 - - { } - default_only_action: NoAction - ternary_match _Weissert 11: - p4: { name: Weissert, size: 306, disable_atomic_modify : true } - p4_param_order: - HillTop.Edwards.AquaPark: { type: ternary, size: 2, full_size: 2, key_name: "Edwards.AquaPark" } - HillTop.Edwards.McGrady: { type: ternary, size: 3, full_size: 3, key_name: "Edwards.McGrady" } - HillTop.Edwards.RedElm: { type: ternary, size: 3, full_size: 3, key_name: "Edwards.RedElm" } - HillTop.Edwards.PineCity: { type: ternary, size: 6, full_size: 6, key_name: "Edwards.PineCity" } - HillTop.Edwards.Satolah: { type: ternary, size: 1, full_size: 1, key_name: "Edwards.Satolah" } - HillTop.Wisdom.Onycha: { type: ternary, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } - Millston.Hayfield.AquaPark: { type: ternary, size: 2, full_size: 2, key_name: "Hayfield.AquaPark" } - Millston.Hayfield.Vichy: { type: ternary, size: 3, full_size: 3, key_name: "Hayfield.Vichy" } - row: 6 - bus: 1 - column: 1 - indirect_bus: 3 - input_xbar: - ternary group 7: { 1: HillTop.Wisdom.Onycha, 8: HillTop.Edwards.PineCity, 18: HillTop.Edwards.McGrady, 21: HillTop.Edwards.AquaPark, 25: HillTop.Edwards.Satolah, 35: Millston.Hayfield.Vichy, 38: Millston.Hayfield.AquaPark } - byte group 1: { 5: HillTop.Edwards.RedElm } - match: - - { group: 7, byte_group: 1, byte_config: 1, dirtcam: 0x555 } - hit: [ _Barnsboro ] - miss: _Barnsboro - action: _Weissert$action_data($DIRECT, $DEFAULT) - instruction: _Weissert($DEFAULT, $DEFAULT) - actions: - Anawalt(0, 18): - - p4_param_order: { Vichy: 3, Asharoken: 5 } - - default_action: { allowed: true } - - handle: 0x200000a3 - - next_table: 0 - - { Asharoken: $adf_b0(0..4), Vichy: $adf_b0(5..7) } - - set HillTop.Freeny.Dunedin, Vichy - - set ig_intr_md_for_tm.qid, Asharoken - default_action: Anawalt - default_action_parameters: - Vichy: "0x0" - Asharoken: "0x0" - action _Weissert$action_data: - p4: { name: Weissert$action } - row: 12 - column: 3 - vpns: [ 0 ] - home_row: - - 12 - format Anawalt: { $adf_b0: 0..7 } - action_bus: { 2 : $adf_b0 } - ternary_match _Barnsboro 12: - p4: { name: Barnsboro, size: 1, disable_atomic_modify : true } - gateway: - name: cond-40 - input_xbar: - exact group 2: { 105: Millston.Hayfield.$valid } - row: 1 - bus: 1 - unit: 0 - match: { 1: Millston.Hayfield.$valid } - 0b******0: run_table - miss: _Lowemont - condition: - expression: "(Millston.Hayfield.$valid == 1 == 0)" - true: _Barnsboro - false: _Lowemont - hit: [ _Standard ] - miss: _Standard - indirect: _Barnsboro$tind - ternary_indirect _Barnsboro$tind: - row: 3 - bus: 0 - format: { action: 0..0, immediate: 1..2 } - action_bus: { 4 : immediate(0..1) } - instruction: _Barnsboro$tind(action, $DEFAULT) - actions: - NorthRim(1, 19): - - p4_param_order: { Oilmont: 1, Tornillo: 1 } - - default_action: { allowed: true } - - handle: 0x200000f3 - - next_table: 0 - - { $data0: immediate(0..1), Oilmont: $data0(0..0), Tornillo: $data0(1..1) } - - set B7(4..5), $data0 - default_action: NorthRim - default_action_parameters: - Oilmont: "0x0" - Tornillo: "0x0" -stage 8 ingress: - exact_match _Standard 0: - p4: { name: Standard, size: 1024, disable_atomic_modify : true } - p4_param_order: - HillTop.Edwards.AquaPark: { type: exact, size: 2, full_size: 2, key_name: "Edwards.AquaPark" } - HillTop.Edwards.Oilmont: { type: exact, size: 1, full_size: 1, key_name: "Edwards.Oilmont" } - HillTop.Edwards.Tornillo: { type: exact, size: 1, full_size: 1, key_name: "Edwards.Tornillo" } - HillTop.Freeny.Dunedin: { type: exact, size: 3, full_size: 3, key_name: "Freeny.Dunedin" } - HillTop.Wisdom.Onycha: { type: exact, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } - row: 5 - bus: 1 - column: 7 - stash: - row: [ 5 ] - col: [ 7 ] - unit: [ 0 ] - ways: - - [0, 0, 0x0, [5, 7]] - input_xbar: - exact group 0: { 1: HillTop.Wisdom.Onycha, 13: HillTop.Edwards.AquaPark, 20: HillTop.Edwards.Oilmont, 21: HillTop.Edwards.Tornillo, 24: HillTop.Freeny.Dunedin } - hash 0: - 0..2: HillTop.Wisdom.Onycha - 3..4: HillTop.Edwards.AquaPark - 5: HillTop.Edwards.Oilmont - 6: HillTop.Edwards.Tornillo - 7..9: HillTop.Freeny.Dunedin - hash group 0: - table: [0] - seed: 0x0 - format: { action(0): 0..1, immediate(0): 2..10, version(0): 112..115 } - hit: [ _Lowemont ] - miss: _Lowemont - action_bus: { 32..33 : immediate(0..8) } - instruction: _Standard(action, $DEFAULT) - actions: - Wardville(0, 1): - - p4_param_order: { PineCity: 6 } - - default_action: { allowed: true } - - handle: 0x200000f4 - - next_table: 0 - - { PineCity: immediate(0..5) } - - set HillTop.Edwards.PineCity, PineCity - Oregon(1, 2): - - p4_param_order: { RedElm: 3 } - - default_action: { allowed: true } - - handle: 0x200000f5 - - next_table: 0 - - { RedElm: immediate(0..2) } - - set HillTop.Edwards.RedElm, RedElm - Ranburne(2, 4): - - p4_param_order: { RedElm: 3, PineCity: 6 } - - default_action: { allowed: true } - - handle: 0x200000f6 - - next_table: 0 - - { PineCity: immediate(0..5), RedElm: immediate(6..8) } - - set HillTop.Edwards.RedElm, RedElm - - set HillTop.Edwards.PineCity, PineCity - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x200000f7 - - next_table: 0 - - { } - default_only_action: NoAction - exact_match _Lowemont 1: - p4: { name: Lowemont, size: 16384, disable_atomic_modify : true } - p4_param_order: - HillTop.Maddock.Kaluaaha: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } - HillTop.Salix.Hueytown: { type: exact, size: 16, full_size: 16, key_name: "Salix.Hueytown" } - row: 0 - bus: 0 - column: [ 2, 3, 4, 6, 7, 8, 9, 10 ] - stash: - row: [ 0 ] - col: [ 2 ] - unit: [ 0 ] - ways: - - [0, 1, 0x3, [0, 2], [0, 3], [0, 4], [0, 6]] - - [0, 2, 0xc, [0, 7], [0, 8], [0, 9], [0, 10]] - input_xbar: - exact group 0: { 32: HillTop.Maddock.Kaluaaha, 64: HillTop.Salix.Hueytown } - hash 0: - 10..19: random(HillTop.Maddock.Kaluaaha) - 40..41: random(HillTop.Maddock.Kaluaaha) - 20..29: random(HillTop.Maddock.Kaluaaha) - 42..43: random(HillTop.Maddock.Kaluaaha) - hash 1: - 10..17: random(HillTop.Salix.Hueytown(12..15)) ^ HillTop.Salix.Hueytown(0..7) - 18..19: random(HillTop.Salix.Hueytown(12..15)) ^ HillTop.Salix.Hueytown(8..9) - 40..41: random(HillTop.Salix.Hueytown(12..15)) ^ HillTop.Salix.Hueytown(10..11) - 21..28: random(HillTop.Salix.Hueytown(12..15)) ^ HillTop.Salix.Hueytown(0..7) - 29: random(HillTop.Salix.Hueytown(12..15)) ^ HillTop.Salix.Hueytown(8) - 20: random(HillTop.Salix.Hueytown(12..15)) ^ HillTop.Salix.Hueytown(11) - 42..43: random(HillTop.Salix.Hueytown(12..15)) ^ HillTop.Salix.Hueytown(9..10) - hash group 0: - table: [0, 1] - seed: 0xc0032cb5c00 - format: { action(0): 0..0, immediate(0): 2..2, version(0): 112..115, match(0): [68..71, 32..63 ], action(1): 1..1, immediate(1): 3..3, version(1): 116..119, match(1): [108..111, 72..103 ] } - match: [ HillTop.Salix.Hueytown(12..15), HillTop.Maddock.Kaluaaha(0..7), HillTop.Maddock.Kaluaaha(8..15), HillTop.Maddock.Kaluaaha(16..23), HillTop.Maddock.Kaluaaha(24..31) ] - gateway: - name: cond-28 - input_xbar: - exact group 0: { 27: HillTop.RossFork.Naruna.0-1, 64: HillTop.Salix.Hueytown, 85: HillTop.RossFork.Naruna.2-2 } - row: 3 - bus: 1 - unit: 0 - match: { 0: HillTop.Salix.Hueytown(0..7), 8: HillTop.Salix.Hueytown(8..15), 19: HillTop.RossFork.Naruna.0-1, 29: HillTop.RossFork.Naruna.2-2 } - 0x****0000: _Cranbury - 0b**0********01*******************: run_table - miss: _Cranbury - condition: - expression: "(HillTop.Salix.Hueytown != 0 && HillTop.RossFork.Naruna == 1)" - true: _Lowemont - false: _Cranbury - hit: [ _Cranbury ] - miss: _Cranbury - action_bus: { 36..37 : immediate(0..0) } - action: _Lowemont$action_data($DIRECT, $DEFAULT) - instruction: _Lowemont(action, $DEFAULT) - actions: - Norridge(1, 3): - - p4_param_order: { Townville: 16, Pinole: 1 } - - default_action: { allowed: true } - - handle: 0x200000ba - - next_table: 0 - - { Townville.12-15: $adf_h0(0..3), Townville.0-11: $adf_h0(4..15), Pinole: immediate(0..0) } - - set HillTop.Komatke.Townville.0-11, Townville.0-11 - - set HillTop.Komatke.Townville.12-15, Townville.12-15 - - set HillTop.Komatke.Monahans, 1 - - set HillTop.Komatke.Pinole, Pinole - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x200000bb - - next_table: 0 - - { } - default_only_action: NoAction - idletime: - row: 4 - bus: 1 - column: [ 0, 1 ] - precision: 1 - sweep_interval: 7 - notification: enable - per_flow_enable: false - action _Lowemont$action_data: - p4: { name: Lowemont$action } - row: 9 - column: [ 1, 2 ] - vpns: [ 0, 1 ] - home_row: - - 9 - format Norridge: { $adf_h0: 0..15 } - action_bus: { 40..41 : $adf_h0 } - exact_match _Cranbury 2: - p4: { name: Cranbury, size: 32768, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Ocoee: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } - HillTop.Maddock.Kaluaaha: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } - Millston.Grays.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Grays.Chevak" } - HillTop.Maddock.Calcasieu: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } - Millston.Grays.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Grays.Mendocino" } - row: [ 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 6 ] - - [ 2, 3, 4, 6 ] - - [ 2, 3, 4, 6 ] - - [ 2, 3, 4, 6 ] - - [ 2, 3, 4, 6 ] - - [ 2, 3, 4, 6 ] - - [ 2, 3, 4, 6 ] - stash: - row: [ 1, 2, 3, 4, 5, 6, 7 ] - col: [ 2, 2, 2, 2, 2, 2, 2 ] - unit: [ 1, 1, 1, 1, 1, 1, 1 ] - ways: - - [1, 0, 0x0, [7, 2], [6, 2], [5, 2], [4, 2], [3, 2], [2, 2], [1, 2]] - - [1, 1, 0x0, [7, 3], [6, 3], [5, 3], [4, 3], [3, 3], [2, 3], [1, 3]] - - [1, 2, 0x0, [7, 4], [6, 4], [5, 4], [4, 4], [3, 4], [2, 4], [1, 4]] - - [1, 3, 0x0, [7, 6], [6, 6], [5, 6], [4, 6], [3, 6], [2, 6], [1, 6]] - input_xbar: - exact group 1: { 0: HillTop.Maddock.Calcasieu, 32: HillTop.Maddock.Kaluaaha, 64: Millston.Grays.Chevak, 80: Millston.Grays.Mendocino, 96: HillTop.RossFork.Ocoee } - hash 2: - 0..9: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) - 10..19: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) - 20..29: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) - 30..39: random(HillTop.Maddock.Calcasieu, HillTop.Maddock.Kaluaaha) - hash 3: - 0..1: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) - 2..9: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee - 11..12: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) - 13..19: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(0..6) - 10: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(7) - 22..23: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) - 24..29: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(0..5) - 20..21: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(6..7) - 33..34: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ Millston.Grays.Chevak(0..1) - 35..39: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(0..4) - 30..32: random(Millston.Grays.Chevak(2..15), Millston.Grays.Mendocino) ^ HillTop.RossFork.Ocoee(5..7) - hash group 1: - table: [2, 3] - seed: 0x62805adaf2 - format: { action(0): 2..3, version(0): 4..7, match(0): [98..103, 8..95 ], action(1): 0..1, version(1): 244..247, match(1): [506..511, 104..127, 224..239, 248..255, 352..367, 376..383, 480..495 ], action(2): 128..129, version(2): 240..243, match(2): 130..223, action(3): 256..257, version(3): 368..371, match(3): 258..351, action(4): 384..385, version(4): 496..499, match(4): 386..479, action(5): 512..513, version(5): 624..627, match(5): 514..607, action(6): 640..641, version(6): 752..755, match(6): 642..735, action(7): 768..769, version(7): 880..883, match(7): 770..863 } - match: [ Millston.Grays.Chevak(2..7), Millston.Grays.Chevak(8..15), Millston.Grays.Mendocino(0..7), Millston.Grays.Mendocino(8..15), HillTop.Maddock.Calcasieu(0..7), HillTop.Maddock.Calcasieu(8..15), HillTop.Maddock.Calcasieu(16..23), HillTop.Maddock.Calcasieu(24..31), HillTop.Maddock.Kaluaaha(0..7), HillTop.Maddock.Kaluaaha(8..15), HillTop.Maddock.Kaluaaha(16..23), HillTop.Maddock.Kaluaaha(24..31) ] - gateway: - name: cond-32 - input_xbar: - exact group 2: { 0: HillTop.RossFork.Merrill(0..7), 11: HillTop.Ovett.Hammond.0-0, 19: HillTop.RossFork.Alamosa, 21: HillTop.RossFork.Weyauwega, 29: HillTop.Ovett.Hematite, 37: HillTop.RossFork.Naruna.2-2, 40: HillTop.RossFork.Merrill(8..15), 48: HillTop.RossFork.Boerne, 59: HillTop.RossFork.Naruna.0-1 } - hash 4: - 44: HillTop.RossFork.Weyauwega - 45: HillTop.Ovett.Hematite - 46: HillTop.Ovett.Hammond.0-0 - 47: HillTop.RossFork.Boerne - 48: HillTop.RossFork.Alamosa - hash group 0: - table: [4] - seed: 0x0 - row: 2 - bus: 1 - unit: 0 - match: { 36: HillTop.RossFork.Weyauwega, 37: HillTop.Ovett.Hematite, 38: HillTop.Ovett.Hammond.0-0, 19: HillTop.RossFork.Naruna.0-1, 29: HillTop.RossFork.Naruna.2-2, 0: HillTop.RossFork.Merrill(0..7), 8: HillTop.RossFork.Merrill(8..15), 39: HillTop.RossFork.Boerne, 40: HillTop.RossFork.Alamosa } - 0b00110******0********01***0000000000000000: run_table - miss: _Devola - condition: - expression: "(HillTop.RossFork.Weyauwega == 0 && HillTop.Ovett.Hematite == 1 && HillTop.Ovett.Hammond & 1 == 1 && HillTop.RossFork.Naruna == 1 && HillTop.RossFork.Merrill == 0 && HillTop.RossFork.Boerne == 0 && HillTop.RossFork.Alamosa == 0)" - true: _Cranbury - false: _Devola - hit: [ [], _Devola, _Devola, _PeaRidge ] - miss: _Devola - action: _Cranbury$action_data($DIRECT, $DEFAULT) - instruction: _Cranbury(action, $DEFAULT) - actions: - Milano(1, 5): - - p4_param_order: { Kaluaaha: 32, Bratt: 32 } - - default_action: { allowed: true } - - handle: 0x200000cb - - next_table: 1 - - { Kaluaaha: $adf_f0(0..31), Bratt.0-15: $adf_f1(0..15) } - - set HillTop.Maddock.Kaluaaha, Kaluaaha - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Boerne, 1 - - set HillTop.RossFork.Suttle, 1 - Biggers(2, 6): - - p4_param_order: { Kaluaaha: 32, Avondale: 16, Bratt: 32 } - - default_action: { allowed: true } - - handle: 0x200000cc - - next_table: 2 - - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Kaluaaha: $adf_f1(0..31) } - - set HillTop.RossFork.Glenmora, Avondale - - set HillTop.Maddock.Kaluaaha, Kaluaaha - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Boerne, 1 - - set HillTop.RossFork.Suttle, 1 - Sequim(3, 0): - - default_action: { allowed: true } - - handle: 0x200000cd - - next_table: 3 - - { } - default_action: Sequim - idletime: - row: 0 - bus: 0 - column: [ 0, 1, 2, 3 ] - precision: 1 - sweep_interval: 7 - notification: enable - per_flow_enable: false - action _Cranbury$action_data: - p4: { name: Cranbury$action } - row: [ 14, 12, 11, 10, 9, 8, 7, 6, 5 ] - word: [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - 5 - - 5 - - [ 4, 5 ] - - 5 - - [ 3, 4, 5 ] - - 5 - - [ 2, 3, 4, 5 ] - - 5 - - [ 1, 2 ] - vpns: - - [ 0 ] - - [ 1 ] - - [ 2, 3 ] - - [ 4 ] - - [ 5, 6, 7 ] - - [ 8 ] - - [ 9, 10, 11, 12 ] - - [ 13 ] - - [ 14, 15 ] - home_row: - - [ 14, 12 ] - format Milano: { $adf_f0: 0..31, $adf_f1: 32..63 } - format Biggers: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_f1: 32..63 } - action_bus: { 46..47 : $adf_h1, 100..103 : $adf_f1, 44..47 : $adf_f0 } - hash_action _PeaRidge 3: - p4: { name: PeaRidge, size: 4096, disable_atomic_modify : true } - p4_param_order: - HillTop.Wisdom.Nenana: { type: exact, size: 12, full_size: 12, key_name: "Wisdom.Nenana" } - row: 1 - bus: 1 - hash_dist: - 0: { hash: 2, mask: 0xfff, shift: 3 } - input_xbar: - exact group 2: { 64: HillTop.Wisdom.Nenana } - hash 5: - 0..11: stripe(HillTop.Wisdom.Nenana) - hash group 2: - table: [5] - seed: 0x0 - gateway: - name: _PeaRidge-gateway - row: 2 - bus: 0 - unit: 1 - 0x0: _Devola - miss: _Devola - condition: - expression: "true(always hit)" - true: _Devola - false: _Devola - next: [] - action: _PeaRidge$action_data(hash_dist 0, $DEFAULT) - instruction: _PeaRidge($DEFAULT, $DEFAULT) - actions: - Swifton(0, 7): - - p4_param_order: { Panaca: 8 } - - default_action: { allowed: true } - - handle: 0x200000ce - - next_table: 0 - - { Panaca: $adf_f0(0..7) } - - set HillTop.RossFork.Brinklow, Panaca - default_action: Swifton - default_action_parameters: - Panaca: "0x0" - action _PeaRidge$action_data: - p4: { name: PeaRidge$action, how_referenced: direct } - row: 3 - column: 1 - vpns: [ 0 ] - home_row: - - 3 - format Swifton: { $adf_f0: 0..31 } - action_bus: { 104..107 : $adf_f0 } - exact_match _Devola 4: - p4: { name: Devola, size: 4096, disable_atomic_modify : true } - p4_param_order: - HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } - HillTop.Savery.Kaluaaha: { type: exact, size: 16, full_size: 16, key_name: "Savery.Kaluaaha" } - HillTop.Savery.Calcasieu: { type: exact, size: 16, full_size: 16, key_name: "Savery.Calcasieu" } - HillTop.Savery.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Savery.Chevak" } - HillTop.Savery.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Savery.Mendocino" } - HillTop.Savery.LasVegas: { type: exact, size: 8, full_size: 8, key_name: "Savery.LasVegas" } - HillTop.Savery.PineCity: { type: exact, size: 6, full_size: 6, key_name: "Savery.PineCity" } - HillTop.Savery.Exton: { type: exact, size: 8, full_size: 8, key_name: "Savery.Exton" } - HillTop.Savery.Noyes: { type: exact, size: 8, full_size: 8, key_name: "Savery.Noyes" } - HillTop.Savery.Peebles: { type: exact, size: 1, full_size: 1, key_name: "Savery.Peebles" } - row: 7 - bus: 1 - column: [ 7, 8, 9, 10 ] - stash: - row: [ 7 ] - col: [ 7 ] - unit: [ 0 ] - ways: - - [0, 3, 0x600, [7, 7], [7, 8], [7, 9], [7, 10]] - input_xbar: - exact group 3: { 0: HillTop.Savery.Chevak, 16: HillTop.Savery.Mendocino, 32: HillTop.Savery.Calcasieu, 48: HillTop.Savery.Kaluaaha, 68: HillTop.Bessie.Miranda, 86: HillTop.Savery.PineCity, 101: HillTop.Savery.Peebles, 104: HillTop.Savery.Noyes, 112: HillTop.Savery.LasVegas, 120: HillTop.Savery.Exton } - hash 6: - 30..39: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) - 49..50: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) - hash 7: - 30..33: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(0..3) - 34..37: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(4..7) - 38..39: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(0..1) - 49: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(2) - 50: random(HillTop.Savery.PineCity(3..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.Peebles - hash group 0: - table: [6, 7] - seed: 0x4000200000000 - format: { version(0): 112..115, match(0): [32..111, 0..7, 9..11 ] } - match: [ HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton, HillTop.Savery.Chevak(0..7), HillTop.Savery.Chevak(8..15), HillTop.Savery.Mendocino(0..7), HillTop.Savery.Mendocino(8..15), HillTop.Savery.Calcasieu(0..7), HillTop.Savery.Calcasieu(8..15), HillTop.Savery.Kaluaaha(0..7), HillTop.Savery.Kaluaaha(8..15), HillTop.Savery.PineCity(3..5) ] - hit: [ _Ammon ] - miss: _Ammon - action: _Devola$action_data($DIRECT, $DEFAULT) - instruction: _Devola($DEFAULT, $DEFAULT) - actions: - Unionvale(0, 8): - - p4_param_order: { Cornell: 32 } - - default_action: { allowed: true } - - handle: 0x20000086 - - next_table: 0 - - { Cornell: $adf_f0(0..31) } - - maxu HillTop.Mausdale.Kenney, HillTop.Mausdale.Kenney, Cornell - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x20000087 - - next_table: 0 - - { } - default_only_action: NoAction - action _Devola$action_data: - p4: { name: Devola$action } - row: 4 - column: 5 - vpns: [ 0 ] - home_row: - - 4 - format Unionvale: { $adf_f0: 0..31 } - action_bus: { 112..115 : $adf_f0 } - hash_action _Ammon 5: - p4: { name: Ammon, size: 256, disable_atomic_modify : true } - p4_param_order: - HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } - row: 0 - bus: 1 - hash_dist: - 1: { hash: 2, mask: 0xff, shift: 5 } - input_xbar: - exact group 2: { 84: HillTop.Bessie.Miranda } - hash 5: - 16..23: stripe(HillTop.Bessie.Miranda) - hash group 2: - table: [5] - seed: 0x0 - gateway: - name: _Ammon-gateway - row: 1 - bus: 0 - unit: 1 - 0x0: cond-29 - miss: cond-29 - condition: - expression: "true(always hit)" - true: cond-29 - false: cond-29 - next: [] - action: _Ammon$action_data(hash_dist 1, $DEFAULT) - instruction: _Ammon($DEFAULT, $DEFAULT) - actions: - Angeles(0, 9): - - p4_param_order: { Kaluaaha: 16, Calcasieu: 16, Chevak: 16, Mendocino: 16, LasVegas: 8, PineCity: 6, Exton: 8, Noyes: 8, Peebles: 1 } - - default_action: { allowed: true } - - handle: 0x20000088 - - next_table: 0 - - { Peebles: $adf_b0(5..5), Noyes: $adf_b1(0..7), LasVegas: $adf_b2(0..7), Exton: $adf_b3(0..7), Chevak: $adf_h2(0..15), Mendocino: $adf_h3(0..15), Calcasieu: $adf_h4(0..15), Kaluaaha: $adf_h5(0..15), PineCity: $adf_h6(6..11) } - - and HillTop.Savery.Kaluaaha, HillTop.Bessie.Kaluaaha, Kaluaaha - - and HillTop.Savery.Calcasieu, HillTop.Bessie.Calcasieu, Calcasieu - - and HillTop.Savery.Chevak, HillTop.Bessie.Chevak, Chevak - - and HillTop.Savery.Mendocino, HillTop.Bessie.Mendocino, Mendocino - - and HillTop.Savery.LasVegas, HillTop.Bessie.LasVegas, LasVegas - - and HillTop.Savery.Exton, HillTop.Bessie.Exton, Exton - - and HillTop.Savery.Noyes, HillTop.Bessie.Noyes, Noyes - - and B10, Peebles, B9 - - and H85, PineCity, H90 - default_action: Angeles - default_action_parameters: - Kaluaaha: "0xffff" - Calcasieu: "0xffff" - Chevak: "0xffff" - Mendocino: "0xffff" - LasVegas: "0xff" - PineCity: "0x3f" - Exton: "0xff" - Noyes: "0xff" - Peebles: "0x1" - action _Ammon$action_data: - p4: { name: Ammon$action, how_referenced: direct } - row: 5 - column: 3 - vpns: [ 0 ] - home_row: - - 5 - format Angeles: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_b2: 16..23, $adf_b3: 24..31, $adf_h2: 32..47, $adf_h3: 48..63, $adf_h4: 64..79, $adf_h5: 80..95, $adf_h6: 96..111 } - action_bus: { 16 : $adf_b0, 17 : $adf_b1, 18 : $adf_b2, 19 : $adf_b3, 64..65 : $adf_h4, 66..67 : $adf_h5, 68..69 : $adf_h6, 48..49 : $adf_h2, 50..51 : $adf_h3 } - gateway cond-29 6: - name: cond-29 - input_xbar: - exact group 0: { 1: HillTop.Wisdom.Onycha, 93: HillTop.RossFork.Weyauwega, 96: HillTop.Wisdom.Havana, 107: HillTop.Murphy.Standish } - row: 1 - bus: 1 - unit: 0 - match: { 8: HillTop.Wisdom.Havana, 1: HillTop.Wisdom.Onycha, 21: HillTop.RossFork.Weyauwega, 27: HillTop.Murphy.Standish } - 0b***********************1*******: _Circle - 0b****************************010: _Circle - 0b**********1********************: _Circle - 0b****1**************************: _Circle - miss: cond-29$split - condition: - expression: "(HillTop.Wisdom.Havana == 0 && HillTop.Wisdom.Onycha != 2 && HillTop.RossFork.Weyauwega == 0 && HillTop.Murphy.Standish == 0 && HillTop.Murphy.Blairsden == 0)" - true: cond-29$split - false: _Circle - gateway cond-29$split 7: - name: cond-29$split - input_xbar: - exact group 0: { 126: HillTop.Murphy.Blairsden } - row: 5 - bus: 1 - unit: 0 - match: { 6: HillTop.Murphy.Blairsden } - 0b*1: _Circle - miss: _Horatio - condition: - expression: "(HillTop.Wisdom.Havana == 0 && HillTop.Wisdom.Onycha != 2 && HillTop.RossFork.Weyauwega == 0 && HillTop.Murphy.Standish == 0 && HillTop.Murphy.Blairsden == 0)" - true: _Horatio - false: _Circle - exact_match _Horatio 8: - p4: { name: Horatio, size: 8192, disable_atomic_modify : true } - p4_param_order: - HillTop.Wisdom.Adona: { type: exact, size: 24, full_size: 24, key_name: "Wisdom.Adona" } - HillTop.Wisdom.Connell: { type: exact, size: 24, full_size: 24, key_name: "Wisdom.Connell" } - HillTop.Wisdom.Nenana: { type: exact, size: 12, full_size: 12, key_name: "Wisdom.Nenana" } - row: 6 - bus: 1 - column: [ 7, 8, 9, 10 ] - stash: - row: [ 6 ] - col: [ 7 ] - unit: [ 0 ] - ways: - - [3, 0, 0x0, [6, 7]] - - [3, 1, 0x0, [6, 8]] - - [3, 2, 0x0, [6, 9]] - - [3, 3, 0x0, [6, 10]] - input_xbar: - exact group 4: { 0: HillTop.Wisdom.Connell.16-23, 8: HillTop.Wisdom.Adona, 32: HillTop.Wisdom.Nenana, 48: HillTop.Wisdom.Connell.0-15 } - hash 8: - 0..5: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(0..5) - 6..9: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(8..11) - 11..16: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(0..5) - 17..19: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(8..10) - 10: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(11) - 22..27: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(0..5) - 28..29: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(8..9) - 20..21: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(10..11) - 33..38: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(0..5) - 39: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(8) - 30..32: random(HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona, HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15) ^ HillTop.Wisdom.Nenana(9..11) - hash group 3: - table: [8] - seed: 0xac1adff564 - format: { action(0): 0..2, version(0): 112..115, match(0): [86..87, 32..79 ], action(1): 3..5, version(1): 116..119, match(1): [6..7, 88..111, 8..31 ] } - match: [ HillTop.Wisdom.Nenana(6..7), HillTop.Wisdom.Connell.0-15(0..7), HillTop.Wisdom.Connell.0-15(8..15), HillTop.Wisdom.Connell.16-23, HillTop.Wisdom.Adona(0..7), HillTop.Wisdom.Adona(8..15), HillTop.Wisdom.Adona(16..23) ] - gateway: - name: cond-30 - input_xbar: - exact group 4: { 64: HillTop.Wisdom.Morstein } - row: 0 - bus: 1 - unit: 1 - match: { 0: HillTop.Wisdom.Morstein(0..7), 8: HillTop.Wisdom.Morstein(8..15), 16: HillTop.Wisdom.Morstein(16..19) } - 0x*001ff: run_table - miss: _Circle - condition: - expression: "(HillTop.Wisdom.Morstein == 511)" - true: _Horatio - false: _Circle - hit: [ [], _Circle, _Circle, _Circle, _Circle, _DeepGap ] - miss: _Circle - action: _Horatio$action_data($DIRECT, $DEFAULT) - instruction: _Horatio(action, $DEFAULT) - actions: - Laclede(1, 10): - - p4_param_order: { Stilwell: 20 } - - default_action: { allowed: true } - - handle: 0x200000bc - - next_table: 1 - - { Stilwell: $adf_f0(0..19) } - - set HillTop.Wisdom.Morstein, Stilwell - RedLake(2, 11): - - p4_param_order: { Minto: 16 } - - default_action: { allowed: true } - - handle: 0x200000bd - - next_table: 2 - - { Minto: $adf_h0(0..15) } - - set ig_intr_md_for_tm.mcast_grp_a, Minto - Ruston(3, 12): - - p4_param_order: { Stilwell: 20, Placedo: 10 } - - default_action: { allowed: true } - - handle: 0x200000be - - next_table: 3 - - { Stilwell: $adf_f0(0..19) } - - set HillTop.Wisdom.Morstein, Stilwell - - set HillTop.Wisdom.Westhoff, 5 - LaPlant(4, 13): - - default_action: { allowed: true } - - handle: 0x200000bf - - next_table: 4 - - { } - - set HillTop.RossFork.Almedia, 1 - Sequim(5, 0): - - default_action: { allowed: true } - - handle: 0x200000c0 - - next_table: 5 - - { } - default_action: Sequim - action _Horatio$action_data: - p4: { name: Horatio$action } - row: 11 - column: [ 2, 3 ] - vpns: [ 0, 1 ] - home_row: - - 11 - format Laclede: { $adf_f0: 0..31 } - format RedLake: { $adf_h0: 0..15 } - format Ruston: { $adf_f0: 0..31 } - action_bus: { 52..53 : $adf_h0, 52..55 : $adf_f0 } - ternary_match _DeepGap 9: - p4: { name: DeepGap, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.Tiburon.Arnold: { type: ternary, size: 7, full_size: 9, key_name: "Tiburon.Arnold" } - HillTop.Wisdom.Adona: { type: ternary, size: 24, full_size: 24, key_name: "Wisdom.Adona" } - HillTop.Wisdom.Connell: { type: ternary, size: 24, full_size: 24, key_name: "Wisdom.Connell" } - row: [ 2, 3 ] - bus: [ 0, 0 ] - column: - - 0 - - 0 - input_xbar: - ternary group 0: { 0: HillTop.Wisdom.Connell.16-23, 8: HillTop.Wisdom.Adona, 32: HillTop.Tiburon.Arnold(0..6) } - ternary group 1: { 0: HillTop.Wisdom.Connell.0-15 } - match: - - { group: 0, dirtcam: 0x155 } - - { group: 1, dirtcam: 0x5 } - hit: [ _Circle ] - miss: _Circle - indirect: _DeepGap$tind - meter _DeepGap$meter..Morrow: - p4: { name: Morrow } - row: [ 15, 13 ] - column: - - 5 - - 5 - maprams: - - 5 - - 5 - color_maprams: - row: 7 - bus: 0 - column: 0 - address: idletime - type: standard - count: bytes - ternary_indirect _DeepGap$tind: - row: 1 - bus: 0 - column: 5 - input_xbar: - ternary group 0: { 0: HillTop.Wisdom.Connell.16-23, 8: HillTop.Wisdom.Adona, 32: HillTop.Tiburon.Arnold(0..6) } - ternary group 1: { 0: HillTop.Wisdom.Connell.0-15 } - format: { action: 0..1 } - action_bus: { 3 : _DeepGap$meter..Morrow color } - meter: _DeepGap$meter..Morrow($DIRECT, $DEFAULT, $DEFAULT) - meter_color : _DeepGap$meter..Morrow($DIRECT, $DEFAULT) - action: _DeepGap$action_data($DIRECT, $DEFAULT) - instruction: _DeepGap$tind(action, $DEFAULT) - actions: - Shasta(0, 14): - - default_action: { allowed: true } - - handle: 0x200000c1 - - next_table: 0 - - { } - - set HillTop.RossFork.Thayne, _DeepGap$meter..Morrow color(0..0) - - set ig_intr_md_for_tm.copy_to_cpu, HillTop.RossFork.Parkland - - deposit-field H7(12..15), 0, H2 - - _DeepGap$meter..Morrow(2, $DIRECT) - Weathers(1, 16): - - default_action: { allowed: true } - - handle: 0x200000c2 - - next_table: 0 - - { $constant0: $adf_h0(0..15), $constant0: 4096 } - - set HillTop.RossFork.Thayne, _DeepGap$meter..Morrow color(0..0) - - add ig_intr_md_for_tm.mcast_grp_a, HillTop.Wisdom.Nenana, $constant0 - - set HillTop.RossFork.Tenino, 1 - - _DeepGap$meter..Morrow(2, $DIRECT) - Coupland(2, 18): - - default_action: { allowed: true } - - handle: 0x200000c3 - - next_table: 0 - - { } - - set HillTop.RossFork.Thayne, _DeepGap$meter..Morrow color(0..0) - - deposit-field H7(12..15), 0, H2 - - _DeepGap$meter..Morrow(2, $DIRECT) - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x200000c4 - - next_table: 0 - - { } - default_only_action: NoAction - action _DeepGap$action_data: - p4: { name: DeepGap$action } - row: 7 - column: 1 - vpns: [ 0 ] - home_row: - - 7 - format Weathers: { $adf_h0: 0..15 } - action_bus: { 56..57 : $adf_h0 } - ternary_match _Circle 10: - p4: { name: Circle, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.Quinault.Foster: { type: exact, size: 2, full_size: 2, key_name: "Quinault.Foster" } - HillTop.RossFork.Powderly: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Powderly" } - HillTop.Tiburon.Arnold: { type: ternary, size: 9, full_size: 9, key_name: "Tiburon.Arnold" } - HillTop.RossFork.Quebrada: { type: ternary, size: 1, full_size: 20, key_name: "RossFork.Quebrada", start_bit: 19 } - HillTop.Murphy.Blairsden: { type: ternary, size: 1, full_size: 1, key_name: "Murphy.Blairsden" } - HillTop.Murphy.Standish: { type: ternary, size: 1, full_size: 1, key_name: "Murphy.Standish" } - HillTop.RossFork.Beaverdam: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Beaverdam" } - row: [ 0, 1 ] - bus: [ 0, 0 ] - column: - - 0 - - 0 - input_xbar: - ternary group 1: { 16: HillTop.Tiburon.Arnold, 35: HillTop.RossFork.Quebrada(19) } - ternary group 2: { 6: HillTop.Murphy.Blairsden, 12: HillTop.Quinault.Foster, 14: HillTop.RossFork.Powderly, 19: HillTop.Murphy.Standish } - byte group 3: { 2: HillTop.RossFork.Beaverdam } - match: - - { group: 1, byte_group: 3, byte_config: 0, dirtcam: 0x550 } - - { group: 2, dirtcam: 0x15 } - gateway: - name: cond-31 - input_xbar: - exact group 0: { 4: HillTop.Quinault.Foster } - row: 0 - bus: 0 - unit: 0 - match: { 4: HillTop.Quinault.Foster } - 0b**00: _Mapleton - miss: run_table - condition: - expression: "(HillTop.Quinault.Foster != 0)" - true: _Circle - false: _Mapleton - hit: [ _Mapleton ] - miss: _Mapleton - indirect: _Circle$tind - ternary_indirect _Circle$tind: - row: 0 - bus: 0 - column: 5 - input_xbar: - ternary group 1: { 16: HillTop.Tiburon.Arnold, 35: HillTop.RossFork.Quebrada(19) } - ternary group 2: { 6: HillTop.Murphy.Blairsden, 12: HillTop.Quinault.Foster, 14: HillTop.RossFork.Powderly, 19: HillTop.Murphy.Standish } - byte group 3: { 2: HillTop.RossFork.Beaverdam } - format: { action: 0..2 } - instruction: _Circle$tind(action, $DEFAULT) - actions: - Wyndmoor(1, 15): - - default_action: { allowed: true } - - handle: 0x200000c5 - - next_table: 0 - - set ig_intr_md_for_dprsr.digest_type, 1 - Picabo(2, 17): - - default_action: { allowed: true } - - handle: 0x200000c6 - - next_table: 0 - - set HillTop.Wisdom.Havana, 1 - - set HillTop.Wisdom.Blencoe, 22 - - set HillTop.Murphy.Blairsden, 0 - - set HillTop.Murphy.Standish, 0 - Algoa(3, 19): - - default_action: { allowed: true } - - handle: 0x200000c7 - - next_table: 0 - - set HillTop.RossFork.Algoa, 1 - Crump(4, 0): - - default_action: { allowed: true } - - handle: 0x200000c8 - - next_table: 0 - default_action: Crump - ternary_match _Mapleton 11: - p4: { name: Mapleton, disable_atomic_modify : true } - hit: [ _Nowlin ] - miss: _Nowlin - indirect: _Mapleton$tind - ternary_indirect _Mapleton$tind: - row: 0 - bus: 1 - format: { action: 0..0 } - instruction: _Mapleton$tind(action, $DEFAULT) - actions: - Claypool(0, 20): - - default_action: { allowed: true } - - handle: 0x2000011b - - next_table: 0 - - set HillTop.Plains.Roachdale, 1 - - set HillTop.Plains.Miller, HillTop.Tiburon.Arnold - - set Millston.Belgrade.$valid, 1 - - set Millston.Belgrade.Willard, HillTop.Freeny.Dunedin - default_action: Claypool - hash_action _Nowlin 12: - p4: { name: Nowlin, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.Tiburon.Arnold: { type: exact, size: 9, full_size: 9, key_name: "Tiburon.Arnold" } - row: 2 - bus: 1 - hash_dist: - 2: { hash: 2, mask: 0x1ff, shift: 3 } - input_xbar: - exact group 2: { 96: HillTop.Tiburon.Arnold } - hash 5: - 32..40: stripe(HillTop.Tiburon.Arnold) - hash group 2: - table: [5] - seed: 0x0 - gateway: - name: _Nowlin-gateway - row: 3 - bus: 0 - unit: 1 - 0x0: _Walland - miss: _Walland - condition: - expression: "true(always hit)" - true: _Walland - false: _Walland - next: [] - action: _Nowlin$action_data(hash_dist 2, $DEFAULT) - instruction: _Nowlin($DEFAULT, $DEFAULT) - actions: - Newland(0, 21): - - p4_param_order: { Waumandee: 9 } - - default_action: { allowed: true } - - handle: 0x200000f8 - - next_table: 0 - - { Waumandee: $adf_f0(0..8) } - - set ig_intr_md_for_tm.level2_mcast_hash, HillTop.Lewiston.Staunton(0..12) - - set ig_intr_md_for_tm.level2_exclusion_id, Waumandee - default_action: Newland - default_action_parameters: - Waumandee: "0x0" - action _Nowlin$action_data: - p4: { name: Nowlin$action, how_referenced: direct } - row: 1 - column: 5 - vpns: [ 0 ] - home_row: - - 1 - format Newland: { $adf_f0: 0..31 } - action_bus: { 120..123 : $adf_f0 } -stage 9 ingress: - exact_match _Walland 0: - p4: { name: Walland, size: 8192, disable_atomic_modify : true } - p4_param_order: - HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } - HillTop.Savery.Kaluaaha: { type: exact, size: 16, full_size: 16, key_name: "Savery.Kaluaaha" } - HillTop.Savery.Calcasieu: { type: exact, size: 16, full_size: 16, key_name: "Savery.Calcasieu" } - HillTop.Savery.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Savery.Chevak" } - HillTop.Savery.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Savery.Mendocino" } - HillTop.Savery.LasVegas: { type: exact, size: 8, full_size: 8, key_name: "Savery.LasVegas" } - HillTop.Savery.PineCity: { type: exact, size: 6, full_size: 6, key_name: "Savery.PineCity" } - HillTop.Savery.Exton: { type: exact, size: 8, full_size: 8, key_name: "Savery.Exton" } - HillTop.Savery.Noyes: { type: exact, size: 8, full_size: 8, key_name: "Savery.Noyes" } - HillTop.Savery.Peebles: { type: exact, size: 1, full_size: 1, key_name: "Savery.Peebles" } - row: [ 7, 4, 3 ] - bus: [ 1, 0, 0 ] - column: - - [ 4, 6 ] - - [ 2, 3, 4, 6 ] - - [ 2, 3 ] - stash: - row: [ 7 ] - col: [ 4 ] - unit: [ 1 ] - ways: - - [0, 0, 0x7, [7, 4], [7, 6], [4, 2], [4, 3], [4, 4], [4, 6], [3, 2], [3, 3]] - input_xbar: - exact group 0: { 0: HillTop.Savery.Chevak, 16: HillTop.Savery.Mendocino, 32: HillTop.Savery.Calcasieu, 48: HillTop.Savery.Kaluaaha, 68: HillTop.Bessie.Miranda, 86: HillTop.Savery.PineCity, 101: HillTop.Savery.Peebles, 104: HillTop.Savery.Noyes, 112: HillTop.Savery.LasVegas, 120: HillTop.Savery.Exton } - hash 0: - 0..9: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) - 40..42: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) - hash 1: - 0..3: random(HillTop.Savery.PineCity(4..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(0..3) - 4..7: random(HillTop.Savery.PineCity(4..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(4..7) - 8..9: random(HillTop.Savery.PineCity(4..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(0..1) - 40..41: random(HillTop.Savery.PineCity(4..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(2..3) - 42: random(HillTop.Savery.PineCity(4..5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.Peebles - hash group 0: - table: [0, 1] - seed: 0x30 - format: { version(0): 112..115, match(0): [32..111, 0..7, 10..11 ] } - match: [ HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton, HillTop.Savery.Chevak(0..7), HillTop.Savery.Chevak(8..15), HillTop.Savery.Mendocino(0..7), HillTop.Savery.Mendocino(8..15), HillTop.Savery.Calcasieu(0..7), HillTop.Savery.Calcasieu(8..15), HillTop.Savery.Kaluaaha(0..7), HillTop.Savery.Kaluaaha(8..15), HillTop.Savery.PineCity(4..5) ] - hit: [ _Ferndale ] - miss: _Ferndale - action: _Walland$action_data($DIRECT, $DEFAULT) - instruction: _Walland($DEFAULT, $DEFAULT) - actions: - Unionvale(0, 1): - - p4_param_order: { Cornell: 32 } - - default_action: { allowed: true } - - handle: 0x2000009d - - next_table: 0 - - { Cornell: $adf_f0(0..31) } - - maxu HillTop.Mausdale.Kenney, HillTop.Mausdale.Kenney, Cornell - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x2000009e - - next_table: 0 - - { } - default_only_action: NoAction - action _Walland$action_data: - p4: { name: Walland$action } - row: 11 - column: [ 0, 1 ] - vpns: [ 0, 1 ] - home_row: - - 11 - format Unionvale: { $adf_f0: 0..31 } - action_bus: { 96..99 : $adf_f0 } - hash_action _Ferndale 1: - p4: { name: Ferndale, size: 256, disable_atomic_modify : true } - p4_param_order: - HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } - row: 4 - bus: 1 - hash_dist: - 0: { hash: 1, mask: 0xff, shift: 5 } - input_xbar: - exact group 1: { 4: HillTop.Bessie.Miranda } - hash 2: - 0..7: stripe(HillTop.Bessie.Miranda) - hash group 1: - table: [2] - seed: 0x0 - gateway: - name: _Ferndale-gateway - row: 0 - bus: 0 - unit: 1 - 0x0: _Chilson - miss: _Chilson - condition: - expression: "true(always hit)" - true: _Chilson - false: _Chilson - next: [] - action: _Ferndale$action_data(hash_dist 0, $DEFAULT) - instruction: _Ferndale($DEFAULT, $DEFAULT) - actions: - Twichell(0, 2): - - p4_param_order: { Kaluaaha: 16, Calcasieu: 16, Chevak: 16, Mendocino: 16, LasVegas: 8, PineCity: 6, Exton: 8, Noyes: 8, Peebles: 1 } - - default_action: { allowed: true } - - handle: 0x2000009f - - next_table: 0 - - { Peebles: $adf_b0(5..5), Noyes: $adf_b1(0..7), LasVegas: $adf_b2(0..7), Exton: $adf_b3(0..7), Chevak: $adf_h2(0..15), Mendocino: $adf_h3(0..15), Calcasieu: $adf_h4(0..15), Kaluaaha: $adf_h5(0..15), PineCity: $adf_h6(6..11) } - - and HillTop.Savery.Kaluaaha, HillTop.Bessie.Kaluaaha, Kaluaaha - - and HillTop.Savery.Calcasieu, HillTop.Bessie.Calcasieu, Calcasieu - - and HillTop.Savery.Chevak, HillTop.Bessie.Chevak, Chevak - - and HillTop.Savery.Mendocino, HillTop.Bessie.Mendocino, Mendocino - - and HillTop.Savery.LasVegas, HillTop.Bessie.LasVegas, LasVegas - - and HillTop.Savery.Exton, HillTop.Bessie.Exton, Exton - - and HillTop.Savery.Noyes, HillTop.Bessie.Noyes, Noyes - - and B10, Peebles, B9 - - and H85, PineCity, H90 - default_action: Twichell - default_action_parameters: - Kaluaaha: "0xffff" - Calcasieu: "0xffff" - Chevak: "0xffff" - Mendocino: "0xffff" - LasVegas: "0xff" - PineCity: "0x3f" - Exton: "0xff" - Noyes: "0xff" - Peebles: "0x1" - action _Ferndale$action_data: - p4: { name: Ferndale$action, how_referenced: direct } - row: 6 - column: 5 - vpns: [ 0 ] - home_row: - - 6 - format Twichell: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_b2: 16..23, $adf_b3: 24..31, $adf_h2: 32..47, $adf_h3: 48..63, $adf_h4: 64..79, $adf_h5: 80..95, $adf_h6: 96..111 } - action_bus: { 16 : $adf_b0, 17 : $adf_b1, 18 : $adf_b2, 19 : $adf_b3, 64..65 : $adf_h4, 66..67 : $adf_h5, 68..69 : $adf_h6, 32..33 : $adf_h2, 34..35 : $adf_h3 } - exact_match _Chilson 2: - p4: { name: Chilson, size: 128, action_profile: Wakeman, disable_atomic_modify : true } - p4_param_order: - HillTop.Minturn.Grassflat: { type: exact, size: 7, full_size: 10, key_name: "Minturn.Grassflat" } - row: 0 - bus: 1 - column: 4 - stash: - row: [ 0 ] - col: [ 4 ] - unit: [ 0 ] - ways: - - [0, 1, 0x0, [0, 4]] - input_xbar: - exact group 1: { 64: HillTop.Minturn.Grassflat(0..6) } - hash 3: - 10..16: HillTop.Minturn.Grassflat(0..6) - hash group 0: - table: [3] - seed: 0x0 - format: { version(0): 112..115, meter_addr(0): 0..9, meter_pfe(0): 10..10, action_addr(0): 11..21 } - hit: [ _Sedan_0 ] - miss: _Sedan_0 - selector: _Chilson$selector.Wakeman_sel(meter_addr, meter_pfe, $DEFAULT) - selector_length: _Chilson$selector.Wakeman_sel($DEFAULT, $DEFAULT) - action: _Chilson$action_data.Wakeman(action_addr, $DEFAULT) - instruction: _Chilson($DEFAULT, $DEFAULT) - actions: - Froid(0, 3): - - p4_param_order: { Hector: 10 } - - default_action: { allowed: true } - - handle: 0x200000b3 - - next_table: 0 - - { Hector: $adf_h0(0..9) } - - or H34, Hector, H34 - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x200000b4 - - next_table: 0 - - { } - default_only_action: NoAction - selection _Chilson$selector.Wakeman_sel: - p4: { name: Wakeman_sel, size: 4 } - row: 15 - column: [ 1, 2 ] - maprams: [ 1, 2 ] - input_xbar: - exact group 2: { 0: HillTop.Lewiston.Staunton } - hash 4: - 0..50: slice(stripe(crc_rev(0x18005, 0x0, 0x0, 16, { 0: HillTop.Lewiston.Staunton })), 0..50) - hash group 2: - table: [4] - seed: 0x0 - mode: resilient 0 - non_linear: true - pool_sizes: [120] - action _Chilson$action_data.Wakeman: - p4: { name: Wakeman, size: 1024 } - row: 4 - column: 5 - vpns: [ 0 ] - home_row: - - 4 - format Froid: { $adf_h0: 0..15 } - action_bus: { 36..37 : $adf_h0 } - stateful _Chilson$salu.Wakeman_sel$salu: - p4: { name: Wakeman_sel$salu, size: 122880, hidden: true } - selection_table: _Chilson$selector.Wakeman_sel - row: 15 - column: [ 1, 2 ] - maprams: [ 1, 2 ] - format: { lo: 1 } - actions: - set_bit_at_alu$0: - - set_bit_at - clr_bit_at_alu$0: - - clr_bit_at - set_bit_alu$0: - - set_bit - clr_bit_alu$0: - - clr_bit - exact_match _Sedan_0 3: - p4: { name: Sedan, size: 20480, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Merrill: { type: exact, size: 16, full_size: 16, key_name: "RossFork.Merrill" } - row: [ 1, 0 ] - bus: [ 1, 0 ] - column: - - [ 4, 6 ] - - [ 2, 3 ] - stash: - row: [ 1 ] - col: [ 4 ] - unit: [ 0 ] - ways: - - [3, 0, 0x0, [1, 4]] - - [3, 1, 0x0, [1, 6]] - - [3, 2, 0x0, [0, 2]] - - [3, 3, 0x0, [0, 3]] - input_xbar: - exact group 2: { 64: HillTop.RossFork.Merrill } - hash 5: - 0..7: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(0..7) - 8..9: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(8..9) - 11..18: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(0..7) - 19: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(8) - 10: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(9) - 22..29: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(0..7) - 20..21: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(8..9) - 33..39: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(0..6) - 30: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(7) - 31..32: random(HillTop.RossFork.Merrill(10..15)) ^ HillTop.RossFork.Merrill(8..9) - hash group 3: - table: [5] - seed: 0x506b8ed1a4 - format: { action(0): 0..1, version(0): 112..115, match(0): 34..39, action(1): 2..3, version(1): 116..119, match(1): 42..47, action(2): 4..5, version(2): 120..123, match(2): 50..55, action(3): 6..7, version(3): 124..127, match(3): 58..63, action(4): 8..9, version(4): 16..19, match(4): 66..71 } - match: [ HillTop.RossFork.Merrill(10..15) ] - gateway: - name: cond-33 - input_xbar: - exact group 1: { 75: HillTop.Ovett.Hammond.0-0, 80: ig_intr_md_for_tm.copy_to_cpu, 93: HillTop.Ovett.Hematite, 101: HillTop.RossFork.Weyauwega, 109: HillTop.RossFork.Naruna.2-2, 115: HillTop.RossFork.Naruna.0-1 } - hash 3: - 44: HillTop.Ovett.Hammond.0-0 - 45: ig_intr_md_for_tm.copy_to_cpu - hash group 0: - table: [3] - seed: 0x0 - row: 0 - bus: 1 - unit: 0 - match: { 21: HillTop.RossFork.Weyauwega, 29: HillTop.Ovett.Hematite, 36: HillTop.Ovett.Hammond.0-0, 3: HillTop.RossFork.Naruna.0-1, 13: HillTop.RossFork.Naruna.2-2, 37: ig_intr_md_for_tm.copy_to_cpu } - 0b01******1*******0*******0********01: run_table - miss: _Lemont_0 - condition: - expression: "(HillTop.RossFork.Weyauwega == 0 && HillTop.Ovett.Hematite == 1 && HillTop.Ovett.Hammond & 1 == 1 && HillTop.RossFork.Naruna == 1 && ig_intr_md_for_tm.copy_to_cpu == 0)" - true: _Sedan_0 - false: _Lemont_0 - hit: [ [], _OldTown, _OldTown, _Casnovia_0 ] - miss: _OldTown - action: _Sedan_0$action_data($DIRECT, $DEFAULT) - instruction: _Sedan_0(action, $DEFAULT) - actions: - Bronwood(1, 4): - - p4_param_order: { Kaluaaha: 32, Calcasieu: 32, Cotter: 32 } - - default_action: { allowed: true } - - handle: 0x200000cf - - next_table: 1 - - { Calcasieu: $adf_f0(0..31), Kaluaaha: $adf_f1(0..31), Cotter.0-15: $adf_f2(0..15) } - - set HillTop.Maddock.Kaluaaha, Kaluaaha - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Cotter.0-15 - - set HillTop.RossFork.Boerne, 1 - - set HillTop.RossFork.Alamosa, 1 - Kinde(2, 6): - - p4_param_order: { Kaluaaha: 32, Calcasieu: 32, Hillside: 16, Wanamassa: 16, Cotter: 32 } - - default_action: { allowed: true } - - handle: 0x200000d0 - - next_table: 2 - - { Cotter.0-15: $adf_f0(0..15), Hillside: $adf_h1(0..15), Wanamassa: $adf_h2(0..15), Calcasieu: $adf_f2(0..31), Kaluaaha: $adf_f3(0..31) } - - set HillTop.Maddock.Kaluaaha, Kaluaaha - - set HillTop.Maddock.Calcasieu, Calcasieu - - set HillTop.RossFork.Bucktown(0..15), Cotter.0-15 - - set HillTop.RossFork.Boerne, 1 - - set HillTop.RossFork.Alamosa, 1 - - set HillTop.RossFork.Glenmora, Hillside - - set HillTop.RossFork.DonaAna, Wanamassa - Sequim(3, 0): - - default_action: { allowed: true } - - handle: 0x200000d1 - - next_table: 3 - - { } - default_action: Sequim - action _Sedan_0$action_data: - p4: { name: Sedan$action } - row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7 ] - word: [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - [ 3, 4, 5 ] - - 5 - - 5 - - 5 - - [ 2, 3, 4, 5 ] - - 5 - - [ 2, 3, 4, 5 ] - - 5 - - [ 2, 3, 4, 5 ] - vpns: - - [ 0, 1, 2 ] - - [ 3 ] - - [ 4 ] - - [ 5 ] - - [ 6, 7, 8, 9 ] - - [ 10 ] - - [ 11, 12, 13, 14 ] - - [ 15 ] - - [ 16, 17, 18, 19 ] - home_row: - - 15 - format Bronwood: { $adf_f0: 0..31, $adf_f1: 32..63, $adf_f2: 64..95 } - format Kinde: { $adf_f0: 0..31, $adf_h1: 16..31, $adf_h2: 32..47, $adf_f2: 64..95, $adf_f3: 96..127 } - action_bus: { 74..75 : $adf_h1, 76..77 : $adf_h2, 104..107 : $adf_f2, 108..111 : $adf_f3, 72..75 : $adf_f0, 76..79 : $adf_f1 } - ternary_match _Lemont_0 8: - p4: { name: Lemont, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Ravena: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Ravena" } - HillTop.RossFork.Bradner: { type: ternary, size: 2, full_size: 2, key_name: "RossFork.Bradner" } - HillTop.RossFork.TroutRun: { type: ternary, size: 2, full_size: 2, key_name: "RossFork.TroutRun" } - HillTop.Wisdom.Piqua: { type: exact, size: 1, full_size: 1, key_name: "Wisdom.Piqua" } - HillTop.Wisdom.Morstein: { type: ternary, size: 1, full_size: 20, key_name: "Wisdom.Morstein", start_bit: 19 } - row: 4 - bus: 1 - column: 1 - input_xbar: - ternary group 6: { 4: HillTop.RossFork.Bradner, 11: HillTop.Wisdom.Morstein(19), 20: HillTop.RossFork.Ravena, 28: HillTop.Wisdom.Piqua, 38: HillTop.RossFork.TroutRun } - match: - - { group: 6, dirtcam: 0x155 } - hit: [ _OldTown ] - miss: _OldTown - indirect: _Lemont_0$tind - ternary_indirect _Lemont_0$tind: - row: 5 - bus: 0 - column: 4 - input_xbar: - ternary group 6: { 4: HillTop.RossFork.Bradner, 11: HillTop.Wisdom.Morstein(19), 20: HillTop.RossFork.Ravena, 28: HillTop.Wisdom.Piqua, 38: HillTop.RossFork.TroutRun } - format: { action: 0..0, immediate: 1..8 } - action_bus: { 0 : immediate(0..7) } - instruction: _Lemont_0$tind(action, $DEFAULT) - actions: - Frederika(0, 7): - - p4_param_order: { Blencoe: 8 } - - default_action: { allowed: true } - - handle: 0x200000db - - next_table: 0 - - { Blencoe: immediate(0..7) } - - set HillTop.Wisdom.Havana, 1 - - set HillTop.Wisdom.Blencoe, Blencoe - Saugatuck(1, 0): - - default_action: { allowed: true } - - handle: 0x200000dc - - next_table: 0 - - { } - NoAction(-1, 9): - - default_only_action: { allowed: true } - - handle: 0x200000dd - - next_table: 0 - - { } - default_only_action: NoAction - exact_match _Casnovia_0 4: - p4: { name: Casnovia, size: 4096, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Montross: { type: exact, size: 12, full_size: 12, key_name: "RossFork.Montross" } - HillTop.Maddock.Kaluaaha: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } - Millston.Grays.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Grays.Chevak" } - HillTop.RossFork.Brinklow: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Brinklow" } - row: [ 2, 1 ] - bus: [ 1, 0 ] - column: - - [ 4, 6 ] - - [ 2, 3 ] - stash: - row: [ 2 ] - col: [ 4 ] - unit: [ 0 ] - ways: - - [4, 0, 0x0, [2, 4]] - - [4, 1, 0x0, [2, 6]] - - [4, 2, 0x0, [1, 2]] - - [4, 3, 0x0, [1, 3]] - input_xbar: - exact group 3: { 0: HillTop.Maddock.Kaluaaha(0..7), 9: HillTop.RossFork.Brinklow, 24: HillTop.Maddock.Kaluaaha(24..31), 32: HillTop.RossFork.Montross(0..7), 40: HillTop.Maddock.Kaluaaha(8..23), 56: Millston.Grays.Chevak(8..15), 64: Millston.Grays.Chevak(0..7), 72: HillTop.RossFork.Montross(8..11) } - hash 6: - 6..9: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) - 0..4: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) ^ HillTop.RossFork.Brinklow(0..4) - 5: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) ^ HillTop.RossFork.Brinklow(7) - 10: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) - 17..19: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) - 11..15: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) ^ HillTop.RossFork.Brinklow(0..4) - 16: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) ^ HillTop.RossFork.Brinklow(7) - 20..21: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) - 28..29: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) - 22..26: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) ^ HillTop.RossFork.Brinklow(0..4) - 27: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) ^ HillTop.RossFork.Brinklow(7) - 30..32: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) - 39: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) - 33..37: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) ^ HillTop.RossFork.Brinklow(0..4) - 38: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23), Millston.Grays.Chevak(8..15)) ^ HillTop.RossFork.Brinklow(7) - hash 7: - 0..5: random(Millston.Grays.Chevak(0..7)) - 6..9: random(Millston.Grays.Chevak(0..7)) ^ HillTop.RossFork.Montross(8..11) - 11..16: random(Millston.Grays.Chevak(0..7)) - 17..19: random(Millston.Grays.Chevak(0..7)) ^ HillTop.RossFork.Montross(8..10) - 10: random(Millston.Grays.Chevak(0..7)) ^ HillTop.RossFork.Montross(11) - 22..27: random(Millston.Grays.Chevak(0..7)) - 28..29: random(Millston.Grays.Chevak(0..7)) ^ HillTop.RossFork.Montross(8..9) - 20..21: random(Millston.Grays.Chevak(0..7)) ^ HillTop.RossFork.Montross(10..11) - 33..38: random(Millston.Grays.Chevak(0..7)) - 39: random(Millston.Grays.Chevak(0..7)) ^ HillTop.RossFork.Montross(8) - 30..32: random(Millston.Grays.Chevak(0..7)) ^ HillTop.RossFork.Montross(9..11) - hash group 4: - table: [6, 7] - seed: 0x67c3de1bef - format: { action(0): 0..1, immediate(0): 2..33, version(0): 112..115, match(0): [40..55, 38..39, 56..95 ] } - match: [ Millston.Grays.Chevak(0..7), Millston.Grays.Chevak(8..15), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(0..7), HillTop.Maddock.Kaluaaha(8..15), HillTop.Maddock.Kaluaaha(16..23), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7) ] - hit: [ _OldTown, _OldTown, _Sunbury_0 ] - miss: _OldTown - action_bus: { 100..103 : immediate(0..31) } - action: _Casnovia_0$action_data($DIRECT, $DEFAULT) - instruction: _Casnovia_0(action, $DEFAULT) - actions: - Garrison(0, 8): - - p4_param_order: { Kaluaaha: 32, Bratt: 32 } - - default_action: { allowed: true } - - handle: 0x200000d2 - - next_table: 0 - - { Kaluaaha: $adf_f0(0..31), Bratt.0-15: immediate(0..15) } - - set HillTop.Maddock.Kaluaaha, Kaluaaha - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Boerne, 1 - Dacono(1, 10): - - p4_param_order: { Kaluaaha: 32, Avondale: 16, Bratt: 32 } - - default_action: { allowed: true } - - handle: 0x200000d3 - - next_table: 1 - - { Bratt.0-15: $adf_f0(0..15), Avondale: $adf_h1(0..15), Kaluaaha: immediate(0..31) } - - set HillTop.RossFork.Glenmora, Avondale - - set HillTop.Maddock.Kaluaaha, Kaluaaha - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Boerne, 1 - Sequim(2, 0): - - default_action: { allowed: true } - - handle: 0x200000d4 - - next_table: 2 - - { } - default_action: Sequim - action _Casnovia_0$action_data: - p4: { name: Casnovia$action } - row: 7 - column: 1 - vpns: [ 0 ] - home_row: - - 7 - format Garrison: { $adf_f0: 0..31 } - format Dacono: { $adf_f0: 0..31, $adf_h1: 16..31 } - action_bus: { 42..43 : $adf_h1, 40..43 : $adf_f0 } - exact_match _Sunbury_0 5: - p4: { name: Sunbury, size: 1024, disable_atomic_modify : true } - p4_param_order: - HillTop.Maddock.Kaluaaha: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } - HillTop.RossFork.Brinklow: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Brinklow" } - Millston.Osyka.Noyes: { type: exact, size: 3, full_size: 8, key_name: "Osyka.Noyes" } - row: [ 3, 2 ] - bus: [ 1, 0 ] - column: - - [ 4, 6 ] - - [ 2, 3 ] - stash: - row: [ 3 ] - col: [ 4 ] - unit: [ 0 ] - ways: - - [5, 0, 0x0, [3, 4]] - - [5, 1, 0x0, [3, 6]] - - [5, 2, 0x0, [2, 2]] - - [5, 3, 0x0, [2, 3]] - input_xbar: - exact group 4: { 0: HillTop.Maddock.Kaluaaha(0..7), 9: HillTop.RossFork.Brinklow, 24: HillTop.Maddock.Kaluaaha(24..31), 32: Millston.Osyka.Noyes(0..2), 40: HillTop.Maddock.Kaluaaha(8..23) } - hash 8: - 0..5: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(0..5) - 6: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(7) - 7..9: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ Millston.Osyka.Noyes(0..2) - 11..16: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(0..5) - 17: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(7) - 18..19: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ Millston.Osyka.Noyes(0..1) - 10: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ Millston.Osyka.Noyes(2) - 22..27: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(0..5) - 28: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(7) - 29: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ Millston.Osyka.Noyes(0) - 20..21: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ Millston.Osyka.Noyes(1..2) - 33..38: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(0..5) - 39: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(7) - 30..32: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(24..31), HillTop.Maddock.Kaluaaha(8..23)) ^ Millston.Osyka.Noyes(0..2) - hash group 5: - table: [8] - seed: 0x9ee4d2fffa - format: { action(0): 0..0, immediate(0): 1..16, version(0): 112..115, match(0): [71..71, 32..63 ] } - match: [ HillTop.RossFork.Brinklow(6), HillTop.Maddock.Kaluaaha(0..7), HillTop.Maddock.Kaluaaha(8..15), HillTop.Maddock.Kaluaaha(16..23), HillTop.Maddock.Kaluaaha(24..31) ] - hit: [ _OldTown, _Flaherty_0 ] - miss: _OldTown - action_bus: { 112..115 : immediate(0..15) } - action: _Sunbury_0$action_data($DIRECT, $DEFAULT) - instruction: _Sunbury_0(action, $DEFAULT) - actions: - Milano(0, 12): - - p4_param_order: { Kaluaaha: 32, Bratt: 32 } - - default_action: { allowed: true } - - handle: 0x200000d5 - - next_table: 0 - - { Kaluaaha: $adf_f0(0..31), Bratt.0-15: immediate(0..15) } - - set HillTop.Maddock.Kaluaaha, Kaluaaha - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Boerne, 1 - Sequim(1, 0): - - default_action: { allowed: true } - - handle: 0x200000d6 - - next_table: 1 - - { } - default_action: Sequim - idletime: - row: 0 - bus: 0 - column: 0 - precision: 1 - sweep_interval: 7 - notification: enable - per_flow_enable: false - action _Sunbury_0$action_data: - p4: { name: Sunbury$action } - row: 9 - column: 1 - vpns: [ 0 ] - home_row: - - 9 - format Milano: { $adf_f0: 0..31 } - action_bus: { 120..123 : $adf_f0 } - exact_match _Flaherty_0 6: - p4: { name: Flaherty, size: 10240, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Montross: { type: exact, size: 12, full_size: 12, key_name: "RossFork.Montross" } - HillTop.Maddock.Kaluaaha: { type: exact, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } - HillTop.RossFork.Brinklow: { type: exact, size: 8, full_size: 8, key_name: "RossFork.Brinklow" } - row: [ 5, 6, 7 ] - bus: [ 0, 0, 0 ] - column: - - [ 2, 3 ] - - [ 2, 3 ] - - [ 2, 3 ] - stash: - row: [ 5, 6, 7 ] - col: [ 2, 2, 2 ] - unit: [ 0, 0, 0 ] - ways: - - [0, 2, 0x0, [7, 2], [6, 2], [5, 2]] - - [0, 3, 0x0, [7, 3], [6, 3], [5, 3]] - input_xbar: - exact group 5: { 0: HillTop.Maddock.Kaluaaha(0..7), 9: HillTop.RossFork.Brinklow, 24: HillTop.Maddock.Kaluaaha(24..31), 32: HillTop.RossFork.Montross(0..7), 40: HillTop.Maddock.Kaluaaha(8..23), 72: HillTop.RossFork.Montross(8..11) } - hash 10: - 26..29: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23)) - 20..24: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(0..4) - 25: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(7) - 30: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23)) - 37..39: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23)) - 31..35: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(0..4) - 36: random(HillTop.Maddock.Kaluaaha(0..7), HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7), HillTop.Maddock.Kaluaaha(8..23)) ^ HillTop.RossFork.Brinklow(7) - hash 11: - 26..29: HillTop.RossFork.Montross(8..11) - 37..39: HillTop.RossFork.Montross(8..10) - 30: HillTop.RossFork.Montross(11) - hash group 0: - table: [10, 11] - seed: 0x57fe600000 - format: { action(0): 1..1, immediate(0): 2..17, version(0): 112..115, match(0): 38..79, action(1): 0..0, immediate(1): 18..33, version(1): 244..247, match(1): [118..119, 80..111, 120..127 ], action(2): 129..129, immediate(2): 130..145, version(2): 240..243, match(2): 166..207, action(3): 128..128, immediate(3): 146..161, version(3): 372..375, match(3): [326..327, 208..239, 248..255 ], action(4): 256..256, immediate(4): 257..272, version(4): 368..371, match(4): 278..319 } - match: [ HillTop.RossFork.Brinklow(5..6), HillTop.Maddock.Kaluaaha(0..7), HillTop.Maddock.Kaluaaha(8..15), HillTop.Maddock.Kaluaaha(16..23), HillTop.Maddock.Kaluaaha(24..31), HillTop.RossFork.Montross(0..7) ] - hit: [ _OldTown, _Almota_0 ] - miss: _OldTown - action_bus: { 116..119 : immediate(0..15) } - action: _Flaherty_0$action_data($DIRECT, $DEFAULT) - instruction: _Flaherty_0(action, $DEFAULT) - actions: - Garrison(0, 14): - - p4_param_order: { Kaluaaha: 32, Bratt: 32 } - - default_action: { allowed: true } - - handle: 0x200000d7 - - next_table: 0 - - { Kaluaaha: $adf_f0(0..31), Bratt.0-15: immediate(0..15) } - - set HillTop.Maddock.Kaluaaha, Kaluaaha - - set HillTop.RossFork.Bucktown(0..15), Bratt.0-15 - - set HillTop.RossFork.Boerne, 1 - Sequim(1, 0): - - default_action: { allowed: true } - - handle: 0x200000d8 - - next_table: 1 - - { } - default_action: Sequim - action _Flaherty_0$action_data: - p4: { name: Flaherty$action } - row: 13 - column: [ 2, 3, 4 ] - vpns: [ 0, 1, 2 ] - home_row: - - 13 - format Garrison: { $adf_f0: 0..31 } - action_bus: { 80..83 : $adf_f0 } - ternary_match _Almota_0 7: - p4: { name: Almota, size: 1024, disable_atomic_modify : true } - p4_param_order: - HillTop.RossFork.Chaffee: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Chaffee" } - HillTop.RossFork.Brinklow: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Brinklow" } - HillTop.Maddock.Kaluaaha: { type: ternary, size: 32, full_size: 32, key_name: "Maddock.Kaluaaha" } - HillTop.Maddock.Calcasieu: { type: ternary, size: 32, full_size: 32, key_name: "Maddock.Calcasieu" } - HillTop.RossFork.Chevak: { type: ternary, size: 16, full_size: 16, key_name: "RossFork.Chevak" } - HillTop.RossFork.Mendocino: { type: ternary, size: 16, full_size: 16, key_name: "RossFork.Mendocino" } - HillTop.RossFork.Ocoee: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } - HillTop.RossFork.Suttle: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Suttle" } - Millston.Osyka.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Osyka" } - Millston.Osyka.Noyes: { type: ternary, size: 8, full_size: 8, key_name: "Osyka.Noyes" } - row: [ 8, 9, 10, 11, 0, 1, 2, 3 ] - bus: [ 0, 0, 0, 0, 1, 1, 1, 1 ] - column: - - 0 - - 0 - - 0 - - 0 - - 1 - - 1 - - 1 - - 1 - input_xbar: - ternary group 0: { 0: HillTop.Maddock.Kaluaaha, 32: HillTop.RossFork.Chaffee } - ternary group 1: { 0: HillTop.RossFork.Mendocino, 16: HillTop.RossFork.Chevak, 38: Millston.Osyka.$valid } - ternary group 2: { 0: Millston.Osyka.Noyes, 8: HillTop.RossFork.Ocoee } - ternary group 3: { 1: HillTop.RossFork.Brinklow(0..6), 8: HillTop.Maddock.Calcasieu(16..31), 24: HillTop.Maddock.Calcasieu(0..15) } - byte group 0: { 0: HillTop.RossFork.Suttle } - byte group 3: { 0: HillTop.RossFork.Brinklow(7) } - match: - - { group: 0, byte_group: 0, byte_config: 0, dirtcam: 0x555 } - - { group: 1, dirtcam: 0x155 } - - { group: 2, byte_group: 3, byte_config: 0, dirtcam: 0x405 } - - { group: 3, dirtcam: 0x155 } - gateway: - name: cond-34 - input_xbar: - exact group 3: { 83: HillTop.Murphy.Standish, 94: HillTop.Murphy.Blairsden } - row: 1 - bus: 0 - unit: 0 - match: { 3: HillTop.Murphy.Standish, 14: HillTop.Murphy.Blairsden } - 0b*0**********0: run_table - miss: _OldTown - condition: - expression: "(HillTop.Murphy.Standish == 0 && HillTop.Murphy.Blairsden == 0)" - true: _Almota_0 - false: _OldTown - hit: [ [], _OldTown, _Lemont_0 ] - miss: _OldTown - indirect: _Almota_0$tind - ternary_indirect _Almota_0$tind: - row: 6 - bus: 0 - column: 4 - input_xbar: - ternary group 0: { 0: HillTop.Maddock.Kaluaaha, 32: HillTop.RossFork.Chaffee } - ternary group 1: { 0: HillTop.RossFork.Mendocino, 16: HillTop.RossFork.Chevak, 38: Millston.Osyka.$valid } - ternary group 2: { 0: Millston.Osyka.Noyes, 8: HillTop.RossFork.Ocoee } - ternary group 3: { 1: HillTop.RossFork.Brinklow(0..6), 8: HillTop.Maddock.Calcasieu(16..31), 24: HillTop.Maddock.Calcasieu(0..15) } - byte group 0: { 0: HillTop.RossFork.Suttle } - byte group 3: { 0: HillTop.RossFork.Brinklow(7) } - format: { action: 0..1, immediate: 2..21 } - action_bus: { 124..127 : immediate(0..19) } - instruction: _Almota_0$tind(action, $DEFAULT) - actions: - Peoria(1, 5): - - default_action: { allowed: true } - - handle: 0x200000d9 - - next_table: 1 - - { $constant0: immediate(0..19), $constant0: 511 } - - set HillTop.Wisdom.Havana, 1 - - set HillTop.Wisdom.Blencoe, HillTop.RossFork.Ankeny - - set HillTop.Wisdom.Morstein, $constant0 - Sequim(2, 0): - - default_action: { allowed: true } - - handle: 0x200000da - - next_table: 2 - - { } - default_action: Sequim -stage 10 ingress: - ternary_match _OldTown 1: - p4: { name: OldTown, size: 512, disable_atomic_modify : true } - p4_param_order: - Millston.Rainelle.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Rainelle" } - HillTop.Wisdom.Blencoe: { type: ternary, size: 8, full_size: 8, key_name: "Wisdom.Blencoe" } - HillTop.Wisdom.Havana: { type: ternary, size: 1, full_size: 1, key_name: "Wisdom.Havana" } - HillTop.RossFork.Pridgen: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Pridgen" } - HillTop.RossFork.Ocoee: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } - HillTop.RossFork.Chevak: { type: ternary, size: 16, full_size: 16, key_name: "RossFork.Chevak" } - HillTop.RossFork.Mendocino: { type: ternary, size: 16, full_size: 16, key_name: "RossFork.Mendocino" } - row: [ 8, 9 ] - bus: [ 0, 0 ] - column: - - 0 - - 0 - indirect_bus: 1 - input_xbar: - ternary group 8: { 0: HillTop.RossFork.Chevak(0..7), 8: HillTop.Wisdom.Blencoe, 16: HillTop.RossFork.Ocoee, 27: Millston.Rainelle.$valid } - ternary group 10: { 0: HillTop.RossFork.Mendocino(8..15), 8: HillTop.Wisdom.Havana, 23: HillTop.RossFork.Pridgen, 24: HillTop.RossFork.Mendocino(0..7), 32: HillTop.RossFork.Chevak(8..15) } - match: - - { group: 8, dirtcam: 0x55 } - - { group: 10, dirtcam: 0x155 } - hit: [ _Trevorton ] - miss: _Trevorton - action: _OldTown$action_data($DIRECT, $DEFAULT) - instruction: _OldTown($DEFAULT, $DEFAULT) - actions: - Lynne(0, 1): - - p4_param_order: { Pajaros: 5 } - - default_action: { allowed: true } - - handle: 0x200000e8 - - next_table: 0 - - { Pajaros: $adf_b0(0..4) } - - set HillTop.Edwards.Pajaros, Pajaros - default_action: Lynne - default_action_parameters: - Pajaros: "0x0" - action _OldTown$action_data: - p4: { name: OldTown$action } - row: 13 - column: 4 - vpns: [ 0 ] - home_row: - - 13 - format Lynne: { $adf_b0: 0..7 } - action_bus: { 2 : $adf_b0 } - exact_match _Trevorton 2: - p4: { name: Trevorton, size: 1024, disable_atomic_modify : true } - p4_param_order: - HillTop.Minturn.Whitewood: { type: exact, size: 10, full_size: 10, key_name: "Minturn.Whitewood" } - row: 4 - bus: 1 - column: 3 - stash: - row: [ 4 ] - col: [ 3 ] - unit: [ 0 ] - ways: - - [0, 0, 0x0, [4, 3]] - input_xbar: - exact group 0: { 0: HillTop.Minturn.Whitewood } - hash 0: - 0..7: HillTop.Minturn.Whitewood(0..7) - 8..9: HillTop.Minturn.Whitewood(8..9) - hash group 0: - table: [0] - seed: 0x0 - format: { action(0): 0..0, version(0): 112..115, meter_addr(0): 1..10, meter_pfe(0): 11..11 } - hit: [ _Ivanpah ] - miss: _Ivanpah - action_bus: { 3 : _Trevorton$meter..Lacombe color } - meter: _Trevorton$meter..Lacombe(meter_addr, meter_pfe, $DEFAULT) - meter_color : _Trevorton$meter..Lacombe(meter_addr, meter_pfe) - instruction: _Trevorton(action, $DEFAULT) - actions: - Clifton(0, 2): - - p4_param_order: { Kingsland: 32 } - - default_action: { allowed: true } - - handle: 0x200000de - - next_table: 0 - - { Kingsland: meter_addr } - - set HillTop.Minturn.Tilton, _Trevorton$meter..Lacombe color(0..1) - - _Trevorton$meter..Lacombe(2, Kingsland) - Eaton(1, 4): - - default_action: { allowed: true } - - handle: 0x200000df - - next_table: 0 - - set HillTop.Minturn.Tilton, 2 - default_action: Eaton - meter _Trevorton$meter..Lacombe: - p4: { name: Lacombe, size: 128 } - row: 15 - column: [ 2, 3 ] - maprams: [ 2, 3 ] - color_maprams: - row: 7 - bus: 0 - column: 0 - address: idletime - type: standard - count: bytes - per_flow_enable: meter_pfe - ternary_match _Ivanpah 3: - p4: { name: Ivanpah, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.Komatke.Monahans: { type: ternary, size: 1, full_size: 1, key_name: "Komatke.Monahans" } - HillTop.Moose.Monahans: { type: ternary, size: 1, full_size: 1, key_name: "Moose.Monahans" } - HillTop.RossFork.Ocoee: { type: ternary, size: 8, full_size: 8, key_name: "RossFork.Ocoee" } - HillTop.RossFork.Juniata: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Juniata" } - HillTop.RossFork.Brinkman: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Brinkman" } - HillTop.RossFork.Redden: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Redden" } - HillTop.Wisdom.Havana: { type: ternary, size: 1, full_size: 1, key_name: "Wisdom.Havana" } - HillTop.Ovett.Hammond: { type: ternary, size: 4, full_size: 4, key_name: "Ovett.Hammond" } - row: [ 10, 11 ] - bus: [ 0, 0 ] - column: - - 0 - - 0 - input_xbar: - ternary group 7: { 16: HillTop.Ovett.Hammond.1-3, 19: HillTop.Ovett.Hammond.0-0, 21: HillTop.Moose.Monahans, 28: HillTop.Komatke.Monahans, 35: HillTop.RossFork.Juniata } - ternary group 9: { 0: HillTop.RossFork.Ocoee, 8: HillTop.RossFork.Redden, 16: HillTop.Wisdom.Havana, 29: HillTop.RossFork.Brinkman } - match: - - { group: 7, dirtcam: 0x150 } - - { group: 9, dirtcam: 0x55 } - gateway: - name: cond-38 - input_xbar: - exact group 0: { 17: HillTop.Wisdom.Onycha } - row: 1 - bus: 0 - unit: 0 - match: { 1: HillTop.Wisdom.Onycha } - 0b****010: _Edinburgh - miss: run_table - condition: - expression: "(HillTop.Wisdom.Onycha != 2)" - true: _Ivanpah - false: _Edinburgh - hit: [ _Edinburgh ] - miss: _Edinburgh - indirect: _Ivanpah$tind - ternary_indirect _Ivanpah$tind: - row: 0 - bus: 0 - column: 2 - input_xbar: - ternary group 7: { 16: HillTop.Ovett.Hammond.1-3, 19: HillTop.Ovett.Hammond.0-0, 21: HillTop.Moose.Monahans, 28: HillTop.Komatke.Monahans, 35: HillTop.RossFork.Juniata } - ternary group 9: { 0: HillTop.RossFork.Ocoee, 8: HillTop.RossFork.Redden, 16: HillTop.Wisdom.Havana, 29: HillTop.RossFork.Brinkman } - format: { action: 0..2, immediate: 3..34 } - action_bus: { 64..65 : immediate(0..15), 66..67 : immediate(16..31) } - instruction: _Ivanpah$tind(action, $DEFAULT) - actions: - Langford(1, 3): - - p4_param_order: { Pinole: 1 } - - default_action: { allowed: true } - - handle: 0x200000e9 - - next_table: 0 - - { Pinole: immediate(0..0) } - - deposit-field H7(0..11), H1(0..11), H5 - - or H52, Pinole, H62 - Cowley(2, 5): - - p4_param_order: { Pinole: 1 } - - default_action: { allowed: true } - - handle: 0x200000ea - - next_table: 0 - - { Pinole: immediate(0..0) } - - set ig_intr_md_for_tm.mcast_grp_a, HillTop.Moose.Townville - - or H52, Pinole, H56 - Lackey(3, 6): - - p4_param_order: { Pinole: 1 } - - default_action: { allowed: true } - - handle: 0x200000eb - - next_table: 0 - - { Pinole: immediate(0..0), $constant0: immediate(16..31), $constant0: 4096 } - - add ig_intr_md_for_tm.mcast_grp_a, HillTop.Wisdom.Nenana, $constant0 - - set ig_intr_md_for_tm.copy_to_cpu, Pinole - Trion(4, 8): - - p4_param_order: { Pinole: 1 } - - default_action: { allowed: true } - - handle: 0x200000ec - - next_table: 0 - - { Pinole: immediate(0..0) } - - set ig_intr_md_for_tm.mcast_grp_a, 0 - - set ig_intr_md_for_tm.copy_to_cpu, Pinole - Baldridge(5, 10): - - p4_param_order: { Pinole: 1 } - - default_action: { allowed: true } - - handle: 0x200000ed - - next_table: 0 - - { Pinole: immediate(0..0) } - - deposit-field H7(12..15), 0, H2 - - or H52, Pinole, H52 - Carlson(6, 12): - - default_action: { allowed: true } - - handle: 0x200000ee - - next_table: 0 - - { $constant0: immediate(0..15), $constant0: 4096 } - - add ig_intr_md_for_tm.mcast_grp_a, HillTop.Wisdom.Nenana, $constant0 - - set ig_intr_md_for_tm.copy_to_cpu, 1 - - set HillTop.Wisdom.Blencoe, 26 - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x200000ef - - next_table: 0 - - { } - default_only_action: NoAction - exact_match _Edinburgh 4: - p4: { name: Edinburgh, size: 16384, disable_atomic_modify : true } - p4_param_order: - HillTop.Bessie.Miranda: { type: exact, size: 8, full_size: 8, key_name: "Bessie.Miranda" } - HillTop.Savery.Kaluaaha: { type: exact, size: 16, full_size: 16, key_name: "Savery.Kaluaaha" } - HillTop.Savery.Calcasieu: { type: exact, size: 16, full_size: 16, key_name: "Savery.Calcasieu" } - HillTop.Savery.Chevak: { type: exact, size: 16, full_size: 16, key_name: "Savery.Chevak" } - HillTop.Savery.Mendocino: { type: exact, size: 16, full_size: 16, key_name: "Savery.Mendocino" } - HillTop.Savery.LasVegas: { type: exact, size: 8, full_size: 8, key_name: "Savery.LasVegas" } - HillTop.Savery.PineCity: { type: exact, size: 6, full_size: 6, key_name: "Savery.PineCity" } - HillTop.Savery.Exton: { type: exact, size: 8, full_size: 8, key_name: "Savery.Exton" } - HillTop.Savery.Noyes: { type: exact, size: 8, full_size: 8, key_name: "Savery.Noyes" } - HillTop.Savery.Peebles: { type: exact, size: 1, full_size: 1, key_name: "Savery.Peebles" } - row: [ 7, 6, 5, 4 ] - bus: [ 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 6, 7 ] - - [ 2, 3, 4, 6, 7 ] - - [ 2, 3, 4, 6, 7 ] - - 2 - stash: - row: [ 7 ] - col: [ 2 ] - unit: [ 0 ] - ways: - - [0, 1, 0xf, [7, 2], [7, 3], [7, 4], [7, 6], [7, 7], [6, 2], [6, 3], [6, 4], [6, 6], [6, 7], [5, 2], [5, 3], [5, 4], [5, 6], [5, 7], [4, 2]] - input_xbar: - exact group 1: { 0: HillTop.Savery.Chevak, 16: HillTop.Savery.Mendocino, 32: HillTop.Savery.Calcasieu, 48: HillTop.Savery.Kaluaaha, 68: HillTop.Bessie.Miranda, 86: HillTop.Savery.PineCity, 101: HillTop.Savery.Peebles, 104: HillTop.Savery.Noyes, 112: HillTop.Savery.LasVegas, 120: HillTop.Savery.Exton } - hash 2: - 10..19: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) - 40..43: random(HillTop.Savery.Chevak, HillTop.Savery.Mendocino, HillTop.Savery.Calcasieu, HillTop.Savery.Kaluaaha) - hash 3: - 10..13: random(HillTop.Savery.PineCity(5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(0..3) - 14..17: random(HillTop.Savery.PineCity(5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Bessie.Miranda(4..7) - 18..19: random(HillTop.Savery.PineCity(5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(0..1) - 40..42: random(HillTop.Savery.PineCity(5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.PineCity(2..4) - 43: random(HillTop.Savery.PineCity(5), HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton) ^ HillTop.Savery.Peebles - hash group 0: - table: [2, 3] - seed: 0x10000068400 - format: { action(0): 0..0, version(0): 112..115, match(0): [32..111, 8..15, 3..3 ] } - match: [ HillTop.Savery.Noyes, HillTop.Savery.LasVegas, HillTop.Savery.Exton, HillTop.Savery.Chevak(0..7), HillTop.Savery.Chevak(8..15), HillTop.Savery.Mendocino(0..7), HillTop.Savery.Mendocino(8..15), HillTop.Savery.Calcasieu(0..7), HillTop.Savery.Calcasieu(8..15), HillTop.Savery.Kaluaaha(0..7), HillTop.Savery.Kaluaaha(8..15), HillTop.Savery.PineCity(5) ] - gateway: - name: cond-39 - input_xbar: - exact group 0: { 29: HillTop.Ovett.Hematite, 32: HillTop.RossFork.Yaurel } - row: 0 - bus: 1 - unit: 1 - match: { 0: HillTop.RossFork.Yaurel, 13: HillTop.Ovett.Hematite } - 0b**0************1: Newcomb_0 - miss: run_table - condition: - expression: "(HillTop.RossFork.Yaurel == 1 && HillTop.Ovett.Hematite == 0)" - true: Newcomb_0 - false: _Edinburgh - hit: [ cond-35 ] - miss: cond-35 - action: _Edinburgh$action_data($DIRECT, $DEFAULT) - instruction: _Edinburgh(action, $DEFAULT) - actions: - Unionvale(1, 7): - - p4_param_order: { Cornell: 32 } - - default_action: { allowed: true } - - handle: 0x200000f1 - - next_table: 0 - - { Cornell: $adf_f0(0..31) } - - maxu HillTop.Mausdale.Kenney, HillTop.Mausdale.Kenney, Cornell - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x200000f2 - - next_table: 0 - - { } - default_only_action: NoAction - action _Edinburgh$action_data: - p4: { name: Edinburgh$action } - row: [ 15, 14, 13 ] - word: [ 0, 0, 0 ] - column: - - [ 4, 5 ] - - 5 - - 5 - vpns: - - [ 0, 1 ] - - [ 2 ] - - [ 3 ] - home_row: - - 15 - format Unionvale: { $adf_f0: 0..31 } - action_bus: { 96..99 : $adf_f0 } - ternary_match Newcomb_0 5: - p4: { name: Newcomb, size: 1, disable_atomic_modify : true } - hit: [ cond-35 ] - miss: cond-35 - indirect: Newcomb_0$tind - ternary_indirect Newcomb_0$tind: - row: 2 - bus: 0 - format: { action: 0..0 } - instruction: Newcomb_0$tind(action, $DEFAULT) - actions: - Terry(0, 9): - - default_action: { allowed: true } - - handle: 0x200000f0 - - next_table: 0 - - set HillTop.Mausdale.Kenney, 0 - default_action: Terry - gateway cond-35 6: - name: cond-35 - input_xbar: - exact group 0: { 36: HillTop.Wisdom.Piqua, 46: HillTop.Murphy.Blairsden, 53: HillTop.RossFork.Weyauwega, 62: HillTop.RossFork.Tenino, 63: HillTop.RossFork.Pridgen, 64: HillTop.Wisdom.Havana, 75: HillTop.Murphy.Standish } - hash 0: - 44: HillTop.RossFork.Pridgen - 46: HillTop.Murphy.Blairsden - hash 1: - 45: HillTop.Murphy.Standish - hash group 0: - table: [0, 1] - seed: 0x0 - row: 4 - bus: 1 - unit: 0 - match: { 0: HillTop.Wisdom.Havana, 13: HillTop.RossFork.Weyauwega, 20: HillTop.Wisdom.Piqua, 30: HillTop.RossFork.Tenino, 36: HillTop.RossFork.Pridgen, 37: HillTop.Murphy.Standish, 38: HillTop.Murphy.Blairsden } - 0b000*****0*********0******0************0: _Felton - miss: _RockHill - condition: - expression: "(HillTop.Wisdom.Havana == 0 && HillTop.RossFork.Weyauwega == 0 && HillTop.Wisdom.Piqua == 0 && HillTop.RossFork.Tenino == 0 && HillTop.RossFork.Pridgen == 0 && HillTop.Murphy.Standish == 0 && HillTop.Murphy.Blairsden == 0)" - true: _Felton - false: _RockHill - ternary_match _Felton 7: - p4: { name: Felton, size: 1, disable_atomic_modify : true } - gateway: - name: cond-36 - input_xbar: - exact group 2: { 0: HillTop.Wisdom.Morstein, 25: HillTop.Wisdom.Onycha, 32: HillTop.RossFork.Quebrada, 57: HillTop.Wisdom.Westhoff } - hash 4: - 48..50: HillTop.Wisdom.Westhoff - hash group 0: - table: [4] - seed: 0x0 - row: 0 - bus: 0 - unit: 0 - match: { 0: HillTop.RossFork.Quebrada(0..7), 8: HillTop.RossFork.Quebrada(8..15), 16: HillTop.RossFork.Quebrada(16..19), 25: HillTop.Wisdom.Onycha, 40: HillTop.Wisdom.Westhoff } - xor: { 0: HillTop.Wisdom.Morstein(0..7), 8: HillTop.Wisdom.Morstein(8..15), 16: HillTop.Wisdom.Morstein(16..19) } - 0b***********************00000000000000000000: run_table - 0b101************001*************************: run_table - miss: _Arial - condition: - expression: "(HillTop.RossFork.Quebrada == HillTop.Wisdom.Morstein || HillTop.Wisdom.Onycha == 1 && HillTop.Wisdom.Westhoff == 5)" - true: _Felton - false: _Arial - hit: [ _RockHill ] - miss: _RockHill - indirect: _Felton$tind - ternary_indirect _Felton$tind: - row: 1 - bus: 1 - format: { action: 0..0 } - instruction: _Felton$tind(action, $DEFAULT) - actions: - Sedona(1, 11): - - default_action: { allowed: true } - - handle: 0x200000e0 - - next_table: 0 - - set HillTop.RossFork.Charco, 1 - default_action: Sedona - exact_match _Arial 8: - p4: { name: Arial, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.Wisdom.Morstein: { type: exact, size: 11, full_size: 20, key_name: "Wisdom.Morstein" } - row: 3 - bus: 0 - column: 2 - stash: - row: [ 3 ] - col: [ 2 ] - unit: [ 0 ] - ways: - - [0, 2, 0x0, [3, 2]] - input_xbar: - exact group 2: { 0: HillTop.Wisdom.Morstein(0..10) } - hash 4: - 20..26: random(HillTop.Wisdom.Morstein(7)) ^ HillTop.Wisdom.Morstein(0..6) - 27..29: random(HillTop.Wisdom.Morstein(7)) ^ HillTop.Wisdom.Morstein(8..10) - hash group 0: - table: [4] - seed: 0x30500000 - format: { action(0): 0..1, version(0): 112..115, match(0): 39..39 } - match: [ HillTop.Wisdom.Morstein(7) ] - gateway: - name: cond-37 - input_xbar: - exact group 2: { 11: HillTop.Wisdom.Morstein(11..19), 64: HillTop.Lamona.Whitefish } - row: 3 - bus: 0 - unit: 0 - match: { 16: HillTop.Lamona.Whitefish, 3: HillTop.Wisdom.Morstein(11..15), 8: HillTop.Wisdom.Morstein(16..19) } - 0b******10****000000111: run_table - miss: _RockHill - condition: - expression: "(HillTop.Lamona.Whitefish == 2 && HillTop.Wisdom.Morstein & 1046528 == 14336)" - true: _Arial - false: _RockHill - hit: [ _RockHill ] - miss: _RockHill - instruction: _Arial(action, $DEFAULT) - actions: - Swisshome(1, 0): - - default_action: { allowed: true } - - handle: 0x200000e1 - - next_table: 0 - Kotzebue(2, 13): - - default_action: { allowed: true } - - handle: 0x200000e2 - - next_table: 0 - - set HillTop.RossFork.Daphne, 1 - default_action: Swisshome -stage 11 ingress: - ternary_match _RockHill 0: - p4: { name: RockHill, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.Wisdom.Blencoe: { type: ternary, size: 8, full_size: 8, key_name: "Wisdom.Blencoe" } - HillTop.RossFork.Alamosa: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Alamosa" } - HillTop.RossFork.Boerne: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Boerne" } - HillTop.RossFork.Bucktown: { type: ternary, size: 16, full_size: 32, key_name: "RossFork.Bucktown" } - Millston.GlenAvon.$valid: { type: ternary, size: 1, full_size: 1, key_name: "GlenAvon" } - Millston.Brookneal.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Brookneal" } - Millston.Gotham.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Gotham" } - Millston.Brookneal.SoapLake: { type: ternary, size: 16, full_size: 16, key_name: "Brookneal.SoapLake" } - HillTop.Wisdom.Onycha: { type: ternary, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } - row: [ 0, 1 ] - bus: [ 1, 1 ] - column: - - 1 - - 1 - input_xbar: - ternary group 0: { 0: Millston.Brookneal.SoapLake, 17: HillTop.Wisdom.Onycha, 27: HillTop.RossFork.Alamosa, 32: HillTop.RossFork.Bucktown(0..7) } - ternary group 1: { 0: HillTop.RossFork.Boerne, 8: HillTop.Wisdom.Blencoe, 20: Millston.GlenAvon.$valid, 24: HillTop.RossFork.Bucktown(8..15) } - byte group 1: { 4: Millston.Gotham.$valid, 5: Millston.Brookneal.$valid } - match: - - { group: 0, byte_group: 1, byte_config: 1, dirtcam: 0x555 } - - { group: 1, dirtcam: 0x55 } - hit: [ _Lignite ] - miss: _Lignite - indirect: _RockHill$tind - ternary_indirect _RockHill$tind: - row: 5 - bus: 0 - column: 2 - input_xbar: - ternary group 0: { 0: Millston.Brookneal.SoapLake, 17: HillTop.Wisdom.Onycha, 27: HillTop.RossFork.Alamosa, 32: HillTop.RossFork.Bucktown(0..7) } - ternary group 1: { 0: HillTop.RossFork.Boerne, 8: HillTop.Wisdom.Blencoe, 20: Millston.GlenAvon.$valid, 24: HillTop.RossFork.Bucktown(8..15) } - byte group 1: { 4: Millston.Gotham.$valid, 5: Millston.Brookneal.$valid } - format: { action: 0..2 } - instruction: _RockHill$tind(action, $DEFAULT) - actions: - Swisshome(0, 0): - - default_action: { allowed: true } - - handle: 0x20000114 - - next_table: 0 - Olcott(1, 1): - - default_action: { allowed: true } - - handle: 0x20000115 - - next_table: 0 - - set Millston.GlenAvon.Kaluaaha, HillTop.Maddock.Kaluaaha - - set Millston.GlenAvon.Calcasieu, HillTop.Maddock.Calcasieu - Lefor(2, 2): - - default_action: { allowed: true } - - handle: 0x20000116 - - next_table: 0 - - set Millston.GlenAvon.Kaluaaha, HillTop.Maddock.Kaluaaha - - set Millston.GlenAvon.Calcasieu, HillTop.Maddock.Calcasieu - - set Millston.Grays.Chevak, HillTop.RossFork.Glenmora - - set Millston.Grays.Mendocino, HillTop.RossFork.DonaAna - - not W50, W50 - Volens(3, 4): - - default_action: { allowed: true } - - handle: 0x20000117 - - next_table: 0 - - set Millston.GlenAvon.Kaluaaha, HillTop.Maddock.Kaluaaha - - set Millston.GlenAvon.Calcasieu, HillTop.Maddock.Calcasieu - - set HillTop.RossFork.Bucktown, 0 - - set Millston.Grays.Chevak, HillTop.RossFork.Glenmora - - set Millston.Grays.Mendocino, HillTop.RossFork.DonaAna - - set W50(0..15), 4294967295 - Virgilina(4, 6): - - default_action: { allowed: true } - - handle: 0x20000118 - - next_table: 0 - - set Millston.Brookneal.SoapLake, 0 - - set HillTop.RossFork.Bucktown, 0 - - set Millston.GlenAvon.Kaluaaha, HillTop.Maddock.Kaluaaha - - set Millston.GlenAvon.Calcasieu, HillTop.Maddock.Calcasieu - - set Millston.Grays.Chevak, HillTop.RossFork.Glenmora - - set Millston.Grays.Mendocino, HillTop.RossFork.DonaAna - Dwight(5, 8): - - default_action: { allowed: true } - - handle: 0x20000119 - - next_table: 0 - - set HillTop.RossFork.Bucktown, 0 - - not W50, W50 - NoAction(-1, 3): - - default_only_action: { allowed: true } - - handle: 0x2000011a - - next_table: 0 - default_only_action: NoAction - hash_action _Lignite 1: - p4: { name: Lignite, size: 32768, disable_atomic_modify : true } - p4_param_order: - HillTop.Mausdale.Kenney: { type: exact, size: 15, full_size: 32, key_name: "Mausdale.Kenney" } - row: 0 - bus: 0 - hash_dist: - 0: { hash: 0, mask: 0x7fff, shift: 1 } - input_xbar: - exact group 0: { 0: HillTop.Mausdale.Kenney(0..14) } - hash 0: - 0..14: stripe(HillTop.Mausdale.Kenney(0..14)) - hash group 0: - table: [0] - seed: 0x0 - gateway: - name: _Lignite-gateway - row: 1 - bus: 0 - unit: 0 - 0x0: _Rhodell - miss: _Rhodell - condition: - expression: "true(always hit)" - true: _Rhodell - false: _Rhodell - next: [] - stats: _Lignite$stats.Encinitas(hash_dist 0, $DEFAULT) - instruction: _Lignite($DEFAULT, $DEFAULT) - actions: - Issaquah(0, 0): - - default_action: { allowed: true } - - handle: 0x20000107 - - next_table: 0 - - _Lignite$stats.Encinitas($DIRECT) - default_action: Issaquah - counter _Lignite$stats.Encinitas: - p4: { name: Encinitas, how_referenced: direct } - row: [ 13, 11 ] - column: - - [ 0, 1, 2, 3, 4, 5 ] - - [ 0, 1, 2 ] - maprams: - - [ 0, 1, 2, 3, 4, 5 ] - - [ 0, 1, 2 ] - count: packets - format: {packets(0): 96..127, packets(1): 64..95, packets(2): 32..63, packets(3): 0..31} - lrt: - - { threshold: 20036672, interval: 268435200 } - - { threshold: 20036672, interval: 268435200 } - - { threshold: 20036672, interval: 268435200 } - exact_match _Rhodell 2: - p4: { name: Rhodell, size: 2048, disable_atomic_modify : true } - p4_param_order: - HillTop.Minturn.Tilton: { type: exact, size: 1, full_size: 2, key_name: "Minturn.Tilton", start_bit: 1 } - HillTop.Minturn.Grassflat: { type: exact, size: 10, full_size: 10, key_name: "Minturn.Grassflat" } - row: 7 - bus: 1 - column: 4 - stash: - row: [ 7 ] - col: [ 4 ] - unit: [ 1 ] - ways: - - [1, 0, 0x0, [7, 4]] - input_xbar: - exact group 0: { 64: HillTop.Minturn.Grassflat, 81: HillTop.Minturn.Tilton(1) } - hash 1: - 0..6: HillTop.Minturn.Grassflat(0..6) - 7..8: HillTop.Minturn.Grassflat(8..9) - 9: HillTop.Minturn.Tilton(1) - hash group 1: - table: [1] - seed: 0x0 - format: { immediate(0): 0..9, version(0): 112..115, match(0): 39..39, immediate(1): 10..19, version(1): 116..119, match(1): 47..47 } - match: [ HillTop.Minturn.Grassflat(7) ] - hit: [ _Clarkdale ] - miss: _Clarkdale - action_bus: { 32..33 : immediate(0..9) } - instruction: _Rhodell($DEFAULT, $DEFAULT) - actions: - Ugashik(0, 5): - - p4_param_order: { Grassflat: 32 } - - default_action: { allowed: true } - - handle: 0x20000105 - - next_table: 0 - - { Grassflat.0-9: immediate(0..9) } - - set ig_intr_md_for_dprsr.mirror_type, 1 - - set HillTop.Minturn.Grassflat, Grassflat.0-9 - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x20000106 - - next_table: 0 - - { } - default_only_action: NoAction - ternary_match _Clarkdale 3: - p4: { name: Clarkdale, size: 1536, disable_atomic_modify : true } - p4_param_order: - HillTop.Tiburon.Arnold: { type: ternary, size: 7, full_size: 9, key_name: "Tiburon.Arnold" } - HillTop.Mausdale.Kenney: { type: ternary, size: 2, full_size: 32, key_name: "Mausdale.Kenney", start_bit: 15 } - HillTop.RossFork.Weyauwega: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Weyauwega" } - HillTop.RossFork.Lowes: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Lowes" } - HillTop.RossFork.Almedia: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Almedia" } - HillTop.RossFork.Chugwater: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Chugwater" } - HillTop.RossFork.Charco: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Charco" } - HillTop.RossFork.Uvalde: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Uvalde" } - HillTop.RossFork.Daphne: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Daphne" } - HillTop.RossFork.Naruna: { type: ternary, size: 1, full_size: 3, key_name: "RossFork.Naruna", start_bit: 2 } - HillTop.Wisdom.Morstein: { type: ternary, size: 20, full_size: 20, key_name: "Wisdom.Morstein" } - ig_intr_md_for_tm.mcast_grp_a: { type: ternary, size: 16, full_size: 16, key_name: "Freeny.mcast_grp_a" } - HillTop.Wisdom.Piqua: { type: ternary, size: 1, full_size: 1, key_name: "Wisdom.Piqua" } - HillTop.Wisdom.Havana: { type: ternary, size: 1, full_size: 1, key_name: "Wisdom.Havana" } - HillTop.RossFork.Level: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Level" } - HillTop.RossFork.Hulbert: { type: ternary, size: 2, full_size: 2, key_name: "RossFork.Hulbert" } - HillTop.Murphy.Blairsden: { type: ternary, size: 1, full_size: 1, key_name: "Murphy.Blairsden" } - HillTop.Murphy.Standish: { type: ternary, size: 1, full_size: 1, key_name: "Murphy.Standish" } - HillTop.RossFork.Algoa: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Algoa" } - ig_intr_md_for_tm.copy_to_cpu: { type: ternary, size: 1, full_size: 1, key_name: "Freeny.copy_to_cpu" } - HillTop.RossFork.Thayne: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Thayne" } - HillTop.RossFork.Pridgen: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Pridgen" } - HillTop.RossFork.Tenino: { type: ternary, size: 1, full_size: 1, key_name: "RossFork.Tenino" } - row: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - input_xbar: - ternary group 2: { 4: HillTop.RossFork.Hulbert, 8: HillTop.Wisdom.Morstein(0..7), 22: HillTop.Murphy.Blairsden, 24: ig_intr_md_for_tm.copy_to_cpu, 38: HillTop.RossFork.Tenino, 39: HillTop.RossFork.Pridgen } - ternary group 3: { 0: HillTop.Wisdom.Morstein(8..15), 8: HillTop.Mausdale.Kenney(16), 20: HillTop.RossFork.Almedia, 24: HillTop.Wisdom.Havana, 25: HillTop.RossFork.Algoa, 33: HillTop.RossFork.Uvalde } - ternary group 4: { 0: HillTop.Tiburon.Arnold(0..6), 8: ig_intr_md_for_tm.mcast_grp_a(8..15), 16: ig_intr_md_for_tm.mcast_grp_a(0..7), 29: HillTop.RossFork.Weyauwega, 30: HillTop.RossFork.Charco, 31: HillTop.RossFork.Daphne, 37: HillTop.RossFork.Naruna.2-2 } - ternary group 5: { 3: HillTop.Murphy.Standish, 4: HillTop.RossFork.Level, 5: HillTop.RossFork.Lowes, 6: HillTop.RossFork.Chugwater, 8: HillTop.RossFork.Thayne, 20: HillTop.Wisdom.Piqua } - byte group 0: { 7: HillTop.Mausdale.Kenney(15) } - byte group 3: { 0: HillTop.Wisdom.Morstein(16..19) } - match: - - { group: 2, byte_group: 0, byte_config: 1, dirtcam: 0x555 } - - { group: 3, dirtcam: 0x155 } - - { group: 4, byte_group: 3, byte_config: 0, dirtcam: 0x555 } - - { group: 5, dirtcam: 0x15 } - hit: [ _Talbert, _Talbert, _Luverne, _Luverne, _Luverne ] - miss: _Talbert - indirect: _Clarkdale$tind - counter _Clarkdale$stats.Herring: - p4: { name: Herring } - row: 1 - column: [ 0, 1 ] - maprams: [ 0, 1 ] - count: packets - format: {packets(0): 64..127, packets(1): 0..63} - ternary_indirect _Clarkdale$tind: - row: 4 - bus: 0 - column: 2 - input_xbar: - ternary group 2: { 4: HillTop.RossFork.Hulbert, 8: HillTop.Wisdom.Morstein(0..7), 22: HillTop.Murphy.Blairsden, 24: ig_intr_md_for_tm.copy_to_cpu, 38: HillTop.RossFork.Tenino, 39: HillTop.RossFork.Pridgen } - ternary group 3: { 0: HillTop.Wisdom.Morstein(8..15), 8: HillTop.Mausdale.Kenney(16), 20: HillTop.RossFork.Almedia, 24: HillTop.Wisdom.Havana, 25: HillTop.RossFork.Algoa, 33: HillTop.RossFork.Uvalde } - ternary group 4: { 0: HillTop.Tiburon.Arnold(0..6), 8: ig_intr_md_for_tm.mcast_grp_a(8..15), 16: ig_intr_md_for_tm.mcast_grp_a(0..7), 29: HillTop.RossFork.Weyauwega, 30: HillTop.RossFork.Charco, 31: HillTop.RossFork.Daphne, 37: HillTop.RossFork.Naruna.2-2 } - ternary group 5: { 3: HillTop.Murphy.Standish, 4: HillTop.RossFork.Level, 5: HillTop.RossFork.Lowes, 6: HillTop.RossFork.Chugwater, 8: HillTop.RossFork.Thayne, 20: HillTop.Wisdom.Piqua } - byte group 0: { 7: HillTop.Mausdale.Kenney(15) } - byte group 3: { 0: HillTop.Wisdom.Morstein(16..19) } - format: { action: 0..2 } - stats: _Clarkdale$stats.Herring($DIRECT, $DEFAULT) - instruction: _Clarkdale$tind(action, $DEFAULT) - actions: - Wattsburg(0, 0): - - default_action: { allowed: true } - - handle: 0x20000108 - - next_table: 0 - - _Clarkdale$stats.Herring($DIRECT) - DeBeque(1, 7): - - default_action: { allowed: true } - - handle: 0x20000109 - - next_table: 1 - - set ig_intr_md_for_tm.copy_to_cpu, 1 - - _Clarkdale$stats.Herring($DIRECT) - Plush(2, 9): - - default_action: { allowed: true } - - handle: 0x2000010a - - next_table: 2 - - set ig_intr_md_for_dprsr.drop_ctl(0..1), 3 - - _Clarkdale$stats.Herring($DIRECT) - Bethune(3, 10): - - default_action: { allowed: true } - - handle: 0x2000010b - - next_table: 3 - - set ig_intr_md_for_tm.copy_to_cpu, 1 - - set ig_intr_md_for_dprsr.drop_ctl(0..1), 3 - - _Clarkdale$stats.Herring($DIRECT) - Truro(4, 12): - - default_action: { allowed: true } - - handle: 0x2000010c - - next_table: 4 - - set ig_intr_md_for_dprsr.drop_ctl(0..1), 3 - - _Clarkdale$stats.Herring($DIRECT) - default_action: Wattsburg - exact_match _Talbert 4: - p4: { name: Talbert, size: 4096, disable_atomic_modify : true } - p4_param_order: - HillTop.Tiburon.Arnold: { type: exact, size: 7, full_size: 9, key_name: "Tiburon.Arnold" } - HillTop.Edwards.Pajaros: { type: exact, size: 5, full_size: 5, key_name: "Edwards.Pajaros" } - row: 7 - bus: 0 - column: [ 2, 3 ] - stash: - row: [ 7 ] - col: [ 2 ] - unit: [ 0 ] - ways: - - [1, 1, 0x1, [7, 2], [7, 3]] - input_xbar: - exact group 0: { 88: HillTop.Edwards.Pajaros, 96: HillTop.Tiburon.Arnold(0..6) } - hash 1: - 10..14: HillTop.Edwards.Pajaros - 15..19: HillTop.Tiburon.Arnold(0..4) - 40: HillTop.Tiburon.Arnold(5) - hash group 1: - table: [1] - seed: 0x0 - format: { action(0): 0..0, version(0): 112..115, counter_addr(0): 2..13, meter_addr(0): 14..25, meter_pfe(0): 26..26, match(0): 54..54, action(1): 1..1, version(1): 116..119, counter_addr(1): 27..38, meter_addr(1): 39..50, meter_pfe(1): 51..51, match(1): 62..62 } - match: [ HillTop.Tiburon.Arnold(6) ] - hit: [ _Luverne ] - miss: _Luverne - action_bus: { 3 : _Talbert$meter..Comobabi color } - stats: _Talbert$stats..PawCreek(counter_addr, $DEFAULT) - meter: _Talbert$meter..Comobabi(meter_addr, meter_pfe, $DEFAULT) - meter_color : _Talbert$meter..Comobabi(meter_addr, meter_pfe) - instruction: _Talbert(action, $DEFAULT) - actions: - Cornwall(0, 0): - - p4_param_order: { Langhorne: 32 } - - default_action: { allowed: true } - - handle: 0x2000010d - - next_table: 0 - - { Langhorne: counter_addr } - - _Talbert$stats..PawCreek(Langhorne) - Natalbany(1, 14): - - p4_param_order: { Langhorne: 32 } - - default_action: { allowed: true } - - handle: 0x2000010e - - next_table: 0 - - { Langhorne: counter_addr } - - set ig_intr_md_for_dprsr.drop_ctl, _Talbert$meter..Comobabi color(0..2) - - _Talbert$meter..Comobabi(2, Langhorne) - - _Talbert$stats..PawCreek(Langhorne) - NoAction(-1, 11): - - default_only_action: { allowed: true } - - handle: 0x2000010f - - next_table: 0 - default_only_action: NoAction - counter _Talbert$stats..PawCreek: - p4: { name: PawCreek, size: 4096 } - row: 9 - column: [ 0, 1, 2 ] - maprams: [ 0, 1, 2 ] - count: packets - format: {packets(0): 64..127, packets(1): 0..63} - meter _Talbert$meter..Comobabi: - p4: { name: Comobabi, size: 4096 } - row: [ 11, 9 ] - column: - - [ 3, 4, 5 ] - - [ 3, 4 ] - maprams: - - [ 3, 4, 5 ] - - [ 3, 4 ] - color_maprams: - row: 4 - bus: 0 - column: 5 - address: idletime - type: standard - green: 0 - yellow: 2 - red: 2 - count: bytes - per_flow_enable: meter_pfe - ternary_match _Luverne 5: - p4: { name: Luverne, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.Wisdom.Onycha: { type: ternary, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } - HillTop.Wisdom.Piqua: { type: ternary, size: 1, full_size: 1, key_name: "Wisdom.Piqua" } - HillTop.Lamona.Whitefish: { type: ternary, size: 2, full_size: 2, key_name: "Lamona.Whitefish" } - HillTop.Wisdom.Morstein: { type: ternary, size: 4, full_size: 20, key_name: "Wisdom.Morstein", start_bit: 16 } - ig_intr_md_for_tm.mcast_grp_a: { type: ternary, size: 4, full_size: 16, key_name: "Freeny.mcast_grp_a", start_bit: 12 } - row: 3 - bus: 1 - column: 1 - hash_dist: - 1: { hash: 0, mask: 0xffff, shift: 0 } - input_xbar: - ternary group 6: { 4: ig_intr_md_for_tm.mcast_grp_a(12..15), 8: HillTop.Wisdom.Morstein(16..19), 17: HillTop.Wisdom.Onycha, 24: HillTop.Lamona.Whitefish, 36: HillTop.Wisdom.Piqua } - exact group 0: { 16: HillTop.Wisdom.Morstein(16..19), 32: HillTop.Wisdom.Morstein(0..15) } - hash 0: - 16..31: stripe(HillTop.Wisdom.Morstein(0..15)) - hash group 0: - table: [0] - seed: 0x0 - match: - - { group: 6, dirtcam: 0x155 } - gateway: - name: cond-42 - input_xbar: - exact group 1: { 0: HillTop.Wisdom.Havana } - row: 0 - bus: 0 - unit: 0 - match: { 0: HillTop.Wisdom.Havana } - 0b*******0: run_table - miss: _Kingman - condition: - expression: "(HillTop.Wisdom.Havana == 0)" - true: _Luverne - false: _Kingman - hit: [ _Kingman ] - miss: _Kingman - indirect: _Luverne$tind - ternary_indirect _Luverne$tind: - row: 3 - bus: 0 - column: 2 - hash_dist: - 1: { hash: 0, mask: 0xffff, shift: 0 } - input_xbar: - ternary group 6: { 4: ig_intr_md_for_tm.mcast_grp_a(12..15), 8: HillTop.Wisdom.Morstein(16..19), 17: HillTop.Wisdom.Onycha, 24: HillTop.Lamona.Whitefish, 36: HillTop.Wisdom.Piqua } - exact group 0: { 16: HillTop.Wisdom.Morstein(16..19), 32: HillTop.Wisdom.Morstein(0..15) } - hash 0: - 16..31: stripe(HillTop.Wisdom.Morstein(0..15)) - hash group 0: - table: [0] - seed: 0x0 - format: { action: 0..2 } - action_bus: { 36..37 : hash_dist(1, lo) } - action: _Luverne$action_data($DIRECT, $DEFAULT) - instruction: _Luverne$tind(action, $DEFAULT) - actions: - Ragley(1, 13): - - p4_param_order: { Dunkerton: 16 } - - default_action: { allowed: true } - - handle: 0x20000110 - - next_table: 0 - - { Dunkerton: $adf_h0(0..15) } - - set ig_intr_md_for_tm.level1_exclusion_id, Dunkerton - - set ig_intr_md_for_tm.rid, ig_intr_md_for_tm.mcast_grp_a - Gunder(2, 15): - - p4_param_order: { Dunkerton: 16 } - - default_action: { allowed: true } - - handle: 0x20000111 - - next_table: 0 - - { Dunkerton: $adf_h0(0..15) } - - set ig_intr_md_for_tm.level1_exclusion_id, Dunkerton - - set ig_intr_md_for_tm.rid, ig_intr_md_for_tm.mcast_grp_a - Maury(3, 16): - - p4_param_order: { Dunkerton: 16 } - - default_action: { allowed: true } - - handle: 0x20000112 - - next_table: 0 - - { Dunkerton: $adf_h0(0..15) } - - set ig_intr_md_for_tm.rid, 65535 - - set ig_intr_md_for_tm.level1_exclusion_id, Dunkerton - Estrella(4, 18): - - default_action: { allowed: true } - - handle: 0x20000113 - - next_table: 0 - - { } - - set ig_intr_md_for_tm.rid, 65535 - - set ig_intr_md_for_tm.level1_exclusion_id, 0 - - set H7, hash_dist(1, 0..15) - default_action: Gunder - default_action_parameters: - Dunkerton: "0x0" - action _Luverne$action_data: - p4: { name: Luverne$action } - row: 12 - column: 4 - vpns: [ 0 ] - home_row: - - 12 - format Ragley: { $adf_h0: 0..15 } - format Gunder: { $adf_h0: 0..15 } - format Maury: { $adf_h0: 0..15 } - action_bus: { 40..41 : $adf_h0 } - ternary_match _Kingman 6: - p4: { name: Kingman, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.Wisdom.Havana: { type: exact, size: 1, full_size: 1, key_name: "Wisdom.Havana" } - HillTop.RossFork.ElVerano: { type: exact, size: 1, full_size: 1, key_name: "RossFork.ElVerano" } - HillTop.Lamona.Pachuta: { type: ternary, size: 1, full_size: 1, key_name: "Lamona.Pachuta" } - HillTop.Wisdom.Blencoe: { type: ternary, size: 8, full_size: 8, key_name: "Wisdom.Blencoe" } - Millston.Wondervu$0.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Wondervu$0" } - row: 4 - bus: 1 - column: 1 - input_xbar: - ternary group 7: { 1: Millston.Wondervu$0.$valid, 2: HillTop.RossFork.ElVerano, 8: HillTop.Wisdom.Havana, 16: HillTop.Lamona.Pachuta, 24: HillTop.Wisdom.Blencoe } - match: - - { group: 7, dirtcam: 0x55 } - hit: [ _Woolwine, _Willette_0, _Woolwine, _Willette_0, _Woolwine, _Willette_0 ] - miss: _Willette_0 - indirect: _Kingman$tind - ternary_indirect _Kingman$tind: - row: 2 - bus: 0 - column: 2 - input_xbar: - ternary group 7: { 1: Millston.Wondervu$0.$valid, 2: HillTop.RossFork.ElVerano, 8: HillTop.Wisdom.Havana, 16: HillTop.Lamona.Pachuta, 24: HillTop.Wisdom.Blencoe } - format: { action: 0..2, immediate: 3..16 } - action_bus: { 16 : immediate(0..7), 17 : immediate(8..13), 96..99 : immediate(0..13) } - instruction: _Kingman$tind(action, $DEFAULT) - actions: - Bigfork(0, 17): - - p4_param_order: { Rumson: 9, McKee: 5 } - - default_action: { allowed: true } - - handle: 0x200000f9 - - next_table: 0 - - { Rumson: immediate(0..8), McKee: immediate(9..13) } - - set HillTop.Wisdom.Miller, HillTop.Tiburon.Arnold - - set ig_intr_md_for_tm.ucast_egress_port, Rumson - - set ig_intr_md_for_tm.qid, McKee - - set HillTop.Wisdom.RioPecos, 0 - Punaluu(1, 19): - - p4_param_order: { Brownson: 5 } - - default_action: { allowed: true } - - handle: 0x200000fa - - next_table: 1 - - { Brownson.3-4: immediate(0..1) } - - set HillTop.Wisdom.Miller, HillTop.Tiburon.Arnold - - set ig_intr_md_for_tm.qid(3..4), Brownson.3-4 - - set HillTop.Wisdom.RioPecos, 0 - Linville(2, 20): - - p4_param_order: { Rumson: 9, McKee: 5 } - - default_action: { allowed: true } - - handle: 0x200000fb - - next_table: 2 - - { Rumson: immediate(0..8), McKee: immediate(9..13) } - - set HillTop.Wisdom.Miller, HillTop.Tiburon.Arnold - - set ig_intr_md_for_tm.ucast_egress_port, Rumson - - set ig_intr_md_for_tm.qid, McKee - - set HillTop.Wisdom.RioPecos, 1 - Kelliher(3, 22): - - p4_param_order: { Brownson: 5 } - - default_action: { allowed: true } - - handle: 0x200000fc - - next_table: 3 - - { Brownson.3-4: immediate(0..1) } - - set HillTop.Wisdom.Miller, HillTop.Tiburon.Arnold - - set ig_intr_md_for_tm.qid(3..4), Brownson.3-4 - - set HillTop.Wisdom.RioPecos, 1 - Hopeton(4, 24): - - p4_param_order: { Rumson: 9, McKee: 5 } - - default_action: { allowed: true } - - handle: 0x200000fd - - next_table: 4 - - { Rumson: immediate(0..8), McKee: immediate(9..13) } - - set HillTop.Wisdom.Miller, HillTop.Tiburon.Arnold - - set ig_intr_md_for_tm.ucast_egress_port, Rumson - - set ig_intr_md_for_tm.qid, McKee - - set HillTop.Wisdom.RioPecos, 1 - - set HillTop.RossFork.CeeVee, Millston.Wondervu$0.Bowden - Bernstein(5, 26): - - p4_param_order: { Brownson: 5 } - - default_action: { allowed: true } - - handle: 0x200000fe - - next_table: 5 - - { Brownson.3-4: immediate(0..1) } - - set HillTop.Wisdom.Miller, HillTop.Tiburon.Arnold - - set ig_intr_md_for_tm.qid(3..4), Brownson.3-4 - - set HillTop.Wisdom.RioPecos, 1 - - set HillTop.RossFork.CeeVee, Millston.Wondervu$0.Bowden - default_action: Kelliher - default_action_parameters: - Brownson: "0x0" - ternary_match _Willette_0 7: - p4: { name: Willette, size: 512, action_profile: Franktown, disable_atomic_modify : true } - p4_param_order: - HillTop.Wisdom.Morstein: { type: ternary, size: 20, full_size: 20, key_name: "Wisdom.Morstein" } - row: 5 - bus: 1 - column: 1 - input_xbar: - ternary group 8: { 0: HillTop.Wisdom.Morstein } - match: - - { group: 8, dirtcam: 0x15 } - hit: [ _Woolwine ] - miss: _Woolwine - indirect: _Willette_0$tind - selection _Willette_0$selector.Franktown_sel: - p4: { name: Franktown_sel, size: 4 } - row: 15 - column: [ 0, 1 ] - maprams: [ 0, 1 ] - input_xbar: - exact group 1: { 8: HillTop.Lewiston.Staunton(8..15), 16: HillTop.Lewiston.Staunton(0..7), 24: HillTop.Tiburon.Arnold(8), 32: HillTop.Tiburon.Arnold(0..7) } - hash 2: - 0..50: slice(stripe(crc_rev(0x18005, 0x0, 0x0, 25, { 0: HillTop.Lewiston.Staunton(0..7), 8: HillTop.Lewiston.Staunton(8..15), 16: HillTop.Tiburon.Arnold(0..7), 24: HillTop.Tiburon.Arnold(8) })), 0..50) - hash group 2: - table: [2] - seed: 0x0 - mode: resilient 0 - non_linear: true - pool_sizes: [120] - action _Willette_0$action_data.Franktown: - p4: { name: Franktown, size: 32768 } - row: [ 15, 14, 12, 10 ] - word: [ 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 5 ] - - 5 - - 5 - - [ 3, 4 ] - vpns: - - [ 0, 1, 2, 3 ] - - [ 4 ] - - [ 5 ] - - [ 6, 7 ] - home_row: - - [ 15, 10 ] - format Ihlen: { $adf_f0: 0..31 } - action_bus: { 104..107 : $adf_f0 } - stateful _Willette_0$salu.Franktown_sel$salu: - p4: { name: Franktown_sel$salu, size: 122880, hidden: true } - selection_table: _Willette_0$selector.Franktown_sel - row: 15 - column: [ 0, 1 ] - maprams: [ 0, 1 ] - format: { lo: 1 } - actions: - set_bit_at_alu$0: - - set_bit_at - clr_bit_at_alu$0: - - clr_bit_at - set_bit_alu$0: - - set_bit - clr_bit_alu$0: - - clr_bit - ternary_indirect _Willette_0$tind: - row: 1 - bus: 0 - column: 2 - input_xbar: - ternary group 8: { 0: HillTop.Wisdom.Morstein } - format: { action: 0..2, meter_addr: 3..12, meter_pfe: 13..13, action_addr: 14..29 } - selector: _Willette_0$selector.Franktown_sel(meter_addr, meter_pfe, $DEFAULT) - selector_length: _Willette_0$selector.Franktown_sel($DEFAULT, $DEFAULT) - action: _Willette_0$action_data.Franktown(action_addr, $DEFAULT) - instruction: _Willette_0$tind(action, $DEFAULT) - actions: - Ihlen(0, 23): - - p4_param_order: { Faulkton: 9 } - - default_action: { allowed: true } - - handle: 0x200000ff - - next_table: 0 - - { Faulkton: $adf_f0(0..8) } - - set ig_intr_md_for_tm.ucast_egress_port, Faulkton - - set HillTop.Wisdom.Waubun, 0 - Philmont(1, 27): - - default_action: { allowed: true } - - handle: 0x20000100 - - next_table: 0 - - { } - - set ig_intr_md_for_tm.ucast_egress_port, HillTop.Wisdom.Morstein(0..8) - - set HillTop.Wisdom.Waubun, HillTop.Wisdom.Morstein(9..14) - Twinsburg(2, 28): - - default_action: { allowed: true } - - handle: 0x20000101 - - next_table: 0 - - { } - - set W2(0..8), 4294967295 - ElCentro(3, 30): - - default_action: { allowed: true } - - handle: 0x20000102 - - next_table: 0 - - { } - - set W2(0..8), 4294967295 - Redvale(4, 0): - - default_action: { allowed: true } - - handle: 0x20000103 - - next_table: 0 - - { } - default_action: Twinsburg - ternary_match _Woolwine 8: - p4: { name: Woolwine, size: 1, disable_atomic_modify : true } - gateway: - name: cond-41 - input_xbar: - exact group 0: { 105: HillTop.Wisdom.Onycha, 113: Millston.Wondervu$0.$valid } - row: 7 - bus: 0 - unit: 0 - match: { 9: Millston.Wondervu$0.$valid, 1: HillTop.Wisdom.Onycha } - 0b******0********: END - 0o****2: END - miss: run_table - condition: - expression: "(Millston.Wondervu[0].$valid == 1 && HillTop.Wisdom.Onycha != 2)" - true: _Woolwine - false: END - hit: [ END ] - miss: END - indirect: _Woolwine$tind - ternary_indirect _Woolwine$tind: - row: 1 - bus: 1 - format: { action: 0..0 } - instruction: _Woolwine$tind(action, $DEFAULT) - actions: - Basye(1, 21): - - default_action: { allowed: true } - - handle: 0x20000104 - - next_table: 0 - - set Millston.Calabash.McCaulley.0-7, Millston.Wondervu$0.McCaulley.0-7 - - set Millston.Calabash.McCaulley.8-15, Millston.Wondervu$0.McCaulley.8-15 - - set Millston.Wondervu$0.$valid, 0 - default_action: Basye -stage 0 egress: - ternary_match _Mendoza 13: - p4: { name: Mendoza, size: 512, disable_atomic_modify : true } - p4_param_order: - eg_intr_md.egress_rid: { type: exact, size: 16, full_size: 16, key_name: "Sonoma.egress_rid" } - eg_intr_md.egress_port: { type: exact, size: 9, full_size: 9, key_name: "Sonoma.egress_port" } - row: 5 - bus: 0 - column: 0 - input_xbar: - ternary group 10: { 0: eg_intr_md.egress_port(8), 8: eg_intr_md.egress_rid, 24: eg_intr_md.egress_port(0..7) } - match: - - { group: 10, byte_config: 3, dirtcam: 0x55 } - gateway: - name: cond-43 - input_xbar: - exact group 6: { 0: Millston.Belgrade.$valid } - row: 0 - bus: 0 - unit: 0 - match: { 0: Millston.Belgrade.$valid } - 0b*******1: _Brookwood - miss: run_table - condition: - expression: "(Millston.Belgrade.$valid == 1 == 1)" - true: _Brookwood - false: _Mendoza - hit: [ _Protivin ] - miss: _Protivin - indirect: _Mendoza$tind - ternary_indirect _Mendoza$tind: - row: 0 - bus: 1 - column: 4 - input_xbar: - ternary group 10: { 0: eg_intr_md.egress_port(8), 8: eg_intr_md.egress_rid, 24: eg_intr_md.egress_port(0..7) } - format: { action: 0..1 } - action: _Mendoza$action_data($DIRECT, $DEFAULT) - instruction: _Mendoza$tind(action, $DEFAULT) - actions: - Kosmos(1, 1): - - default_action: { allowed: true } - - handle: 0x2000012b - - next_table: 0 - - { } - - set HillTop.Wisdom.Onycha, 0 - - set HillTop.Wisdom.Westhoff, 3 - Ironia(2, 2): - - p4_param_order: { BigFork: 8 } - - default_action: { allowed: true } - - handle: 0x2000012c - - next_table: 0 - - { BigFork: $adf_b0(0..7) } - - set HillTop.Wisdom.Blencoe, BigFork - - set HillTop.Wisdom.Lathrop, 1 - - set HillTop.Wisdom.Onycha, 0 - - set HillTop.Wisdom.Stratford, 1 - - set W28(1..4), 2 - Kenvil(3, 4): - - p4_param_order: { Rhine: 32, LaJara: 32, Exton: 8, PineCity: 6, Bammel: 16, Bowden: 12, Adona: 24, Connell: 24 } - - default_action: { allowed: true } - - handle: 0x2000012d - - next_table: 0 - - { Exton: $adf_b0(0..7), Adona.0-7: $adf_b1(0..7), Connell.0-7: $adf_b2(0..7), $constant0: $adf_h2(0..15), $constant0: 17, Bowden: $adf_h3(0..11), Connell.8-23: $adf_h8(0..15), Bammel: $adf_h9(0..15), $data0: $adf_h10(0..13), PineCity: $data0(0..5), $constant2: $data0(6..9), $constant2: 5, $constant1: $data0(10..13), $constant1: 4, Adona.8-23: $adf_h11(0..15), Rhine: $adf_f2(0..31), LaJara: $adf_f3(0..31) } - - set HillTop.Wisdom.Onycha, 0 - - set Millston.GlenAvon.$valid, 1 - - set Millston.GlenAvon.Ocoee, 47 - - set Millston.GlenAvon.Exton, Exton - - set Millston.GlenAvon.Kaluaaha, Rhine - - set Millston.GlenAvon.Calcasieu, LaJara - - add Millston.GlenAvon.Rexville, HillTop.Sonoma.Iberia, $constant0 - - set Millston.Broadwell.$valid, 1 - - set Millston.Broadwell.LasVegas, Bammel - - set HillTop.Wisdom.Bowden, Bowden - - set HillTop.Wisdom.Adona.0-7, Adona.0-7 - - set HillTop.Wisdom.Adona.8-23, Adona.8-23 - - set HillTop.Wisdom.Connell.0-7, Connell.0-7 - - set HillTop.Wisdom.Connell.8-23, Connell.8-23 - - set H81(2..15), $data0 - - set W16, 0 - - set W28(1..4), 4 - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x2000012e - - next_table: 0 - - { } - default_only_action: NoAction - action _Mendoza$action_data: - p4: { name: Mendoza$action } - row: [ 13, 9 ] - word: [ 0, 1 ] - column: - - 3 - - 1 - vpns: - - [ 0 ] - - [ 0 ] - home_row: - - 13 - - 9 - format Ironia: { $adf_b0: 0..7 } - format Kenvil: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_b2: 16..23, $adf_h2: 32..47, $adf_h3: 48..63, $adf_h8: 128..143, $adf_h9: 144..159, $adf_h10: 160..175, $adf_h11: 176..191, $adf_f2: 64..95, $adf_f3: 96..127 } - action_bus: { 16 : $adf_b0, 17 : $adf_b1, 18 : $adf_b2, 48..49 : $adf_h2, 50..51 : $adf_h3, 80..81 : $adf_h8, 82..83 : $adf_h9, 84..85 : $adf_h10, 86..87 : $adf_h11, 104..107 : $adf_f2, 108..111 : $adf_f3 } - exact_match _Brookwood 14: - p4: { name: Brookwood, size: 32768, disable_atomic_modify : true } - p4_param_order: - eg_intr_md.egress_rid: { type: exact, size: 16, full_size: 16, key_name: "Sonoma.egress_rid" } - row: [ 7, 3, 2 ] - bus: [ 0, 1, 0 ] - column: - - [ 2, 3, 4, 6 ] - - [ 4, 6 ] - - [ 2, 3, 4 ] - stash: - row: [ 2 ] - col: [ 2 ] - unit: [ 0 ] - ways: - - [5, 0, 0x1, [2, 2], [2, 3]] - - [5, 1, 0x2, [7, 2], [7, 3]] - - [5, 2, 0x4, [3, 4], [3, 6]] - - [5, 3, 0x8, [7, 4], [7, 6]] - - [5, 0, 0x0, [2, 4]] - input_xbar: - exact group 4: { 64: eg_intr_md.egress_rid } - hash 9: - 0..7: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(0..7) - 8..9: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(8..9) - 40: random(eg_intr_md.egress_rid(10..15)) - 11..18: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(0..7) - 19: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(8) - 10: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(9) - 41: random(eg_intr_md.egress_rid(10..15)) - 22..29: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(0..7) - 20..21: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(8..9) - 42: random(eg_intr_md.egress_rid(10..15)) - 33..39: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(0..6) - 30: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(7) - 31..32: random(eg_intr_md.egress_rid(10..15)) ^ eg_intr_md.egress_rid(8..9) - 43: random(eg_intr_md.egress_rid(10..15)) - hash group 5: - table: [9] - seed: 0x407ac5830f7 - format: { action(0): 0..0, immediate(0): 4..15, version(0): 112..115, match(0): 58..63, action(1): 1..1, immediate(1): 16..27, version(1): 116..119, match(1): 66..71, action(2): 2..2, immediate(2): 28..39, version(2): 120..123, match(2): 74..79, action(3): 3..3, immediate(3): 40..51, version(3): 124..127, match(3): 82..87 } - match: [ eg_intr_md.egress_rid(10..15) ] - gateway: - name: cond-44 - input_xbar: - exact group 4: { 64: eg_intr_md.egress_rid } - row: 2 - bus: 0 - unit: 0 - match: { 0: eg_intr_md.egress_rid(0..7), 8: eg_intr_md.egress_rid(8..15) } - 0x0000: _Bechyn - miss: run_table - condition: - expression: "(eg_intr_md.egress_rid != 0)" - true: _Brookwood - false: _Bechyn - hit: [ _Bechyn ] - miss: _Bechyn - action_bus: { 52..53 : immediate(0..11) } - instruction: _Brookwood(action, $DEFAULT) - actions: - Gwynn(1, 6): - - p4_param_order: { Rolla: 12 } - - default_action: { allowed: true } - - handle: 0x2000011f - - next_table: 0 - - { Rolla: immediate(0..11) } - - set HillTop.Wisdom.Nenana, Rolla - - set HillTop.Wisdom.Piqua, 1 - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x20000120 - - next_table: 0 - - { } - default_only_action: NoAction - exact_match _Bechyn 15: - p4: { name: Bechyn, size: 128, disable_atomic_modify : true } - p4_param_order: - eg_intr_md.egress_port: { type: exact, size: 9, full_size: 9, key_name: "Sonoma.egress_port" } - row: 1 - bus: 1 - column: 6 - stash: - row: [ 1 ] - col: [ 6 ] - unit: [ 0 ] - ways: - - [2, 2, 0x0, [1, 6]] - input_xbar: - exact group 3: { 32: eg_intr_md.egress_port } - hash 6: - 20..27: eg_intr_md.egress_port(0..7) - 28: eg_intr_md.egress_port(8) - hash group 2: - table: [6] - seed: 0x0 - format: { immediate(0): 0..9, version(0): 112..115 } - hit: [ _Pound ] - miss: _Pound - action_bus: { 56..57 : immediate(0..9) } - instruction: _Bechyn($DEFAULT, $DEFAULT) - actions: - DeRidder(0, 3): - - p4_param_order: { Heaton: 10 } - - default_action: { allowed: true } - - handle: 0x20000121 - - next_table: 0 - - { Heaton: immediate(0..9) } - - set HillTop.McCaskill.Grassflat, Heaton - default_action: DeRidder - default_action_parameters: - Heaton: "0x0" -stage 2 egress: - exact_match _Pound 8: - p4: { name: Pound, size: 4096, disable_atomic_modify : true } - p4_param_order: - eg_intr_md.egress_port: { type: exact, size: 7, full_size: 9, key_name: "Sonoma.egress_port" } - HillTop.Wisdom.Nenana: { type: exact, size: 12, full_size: 12, key_name: "Wisdom.Nenana" } - HillTop.Wisdom.Waubun: { type: exact, size: 6, full_size: 6, key_name: "Wisdom.Waubun" } - row: 1 - bus: 1 - column: [ 8, 9 ] - stash: - row: [ 1 ] - col: [ 8 ] - unit: [ 0 ] - ways: - - [3, 0, 0x0, [1, 8]] - - [3, 1, 0x0, [1, 9]] - input_xbar: - exact group 5: { 24: HillTop.Wisdom.Nenana(8..11), 34: HillTop.Wisdom.Waubun, 48: eg_intr_md.egress_port(0..6), 64: HillTop.Wisdom.Nenana(0..7) } - hash 10: - 0..3: random(eg_intr_md.egress_port(0..6)) ^ HillTop.Wisdom.Nenana(8..11) - 4..9: random(eg_intr_md.egress_port(0..6)) ^ HillTop.Wisdom.Waubun - 11..14: random(eg_intr_md.egress_port(0..6)) ^ HillTop.Wisdom.Nenana(8..11) - 15..19: random(eg_intr_md.egress_port(0..6)) ^ HillTop.Wisdom.Waubun(0..4) - 10: random(eg_intr_md.egress_port(0..6)) ^ HillTop.Wisdom.Waubun(5) - hash 11: - 0..9: random(HillTop.Wisdom.Nenana(0..7)) - 10..19: random(HillTop.Wisdom.Nenana(0..7)) - hash group 3: - table: [10, 11] - seed: 0x6acf0 - format: { action(0): 0..1, immediate(0): 4..15, version(0): 112..115, match(0): [40..46, 32..39 ], action(1): 2..3, immediate(1): 16..27, version(1): 116..119, match(1): [56..62, 48..55 ] } - match: [ eg_intr_md.egress_port(0..6), HillTop.Wisdom.Nenana(0..7) ] - hit: [ _MoonRun ] - miss: _MoonRun - action_bus: { 72..73 : immediate(0..11) } - instruction: _Pound(action, $DEFAULT) - actions: - Dundee(0, 1): - - p4_param_order: { Bowden: 12 } - - default_action: { allowed: true } - - handle: 0x20000128 - - next_table: 0 - - { Bowden: immediate(0..11) } - - set HillTop.Wisdom.Bowden, Bowden - RedBay(1, 2): - - p4_param_order: { Bowden: 12 } - - default_action: { allowed: true } - - handle: 0x20000129 - - next_table: 0 - - { Bowden: immediate(0..11) } - - set HillTop.Wisdom.Bowden, Bowden - - set HillTop.Wisdom.Weatherby, 1 - Tunis(2, 4): - - default_action: { allowed: true } - - handle: 0x2000012a - - next_table: 0 - - { } - - set HillTop.Wisdom.Bowden, HillTop.Wisdom.Nenana - default_action: Tunis -stage 4 egress: - exact_match _MoonRun 4: - p4: { name: MoonRun, size: 8192, disable_atomic_modify : true } - p4_param_order: - HillTop.Wisdom.Piqua: { type: exact, size: 1, full_size: 1, key_name: "Wisdom.Piqua" } - Millston.Maumee.$valid: { type: exact, size: 1, full_size: 1, key_name: "Maumee" } - Millston.GlenAvon.$valid: { type: exact, size: 1, full_size: 1, key_name: "GlenAvon" } - HillTop.Wisdom.Nenana: { type: exact, size: 12, full_size: 12, key_name: "Wisdom.Nenana" } - row: 0 - bus: 1 - column: [ 4, 6 ] - stash: - row: [ 0 ] - col: [ 4 ] - unit: [ 0 ] - ways: - - [0, 1, 0x0, [0, 4]] - - [0, 2, 0x0, [0, 6]] - input_xbar: - exact group 1: { 56: HillTop.Wisdom.Nenana(8..11), 67: Millston.GlenAvon.$valid, 73: Millston.Maumee.$valid, 80: HillTop.Wisdom.Nenana(0..7), 100: HillTop.Wisdom.Piqua } - hash 2: - 10..13: HillTop.Wisdom.Nenana(8..11) - 21..24: HillTop.Wisdom.Nenana(8..11) - hash 3: - 10..13: random(HillTop.Wisdom.Nenana(3..7)) - 14: random(HillTop.Wisdom.Nenana(3..7)) ^ Millston.GlenAvon.$valid - 15: random(HillTop.Wisdom.Nenana(3..7)) ^ Millston.Maumee.$valid - 16..18: random(HillTop.Wisdom.Nenana(3..7)) ^ HillTop.Wisdom.Nenana(0..2) - 19: random(HillTop.Wisdom.Nenana(3..7)) ^ HillTop.Wisdom.Piqua - 21..24: random(HillTop.Wisdom.Nenana(3..7)) - 25: random(HillTop.Wisdom.Nenana(3..7)) ^ Millston.GlenAvon.$valid - 26: random(HillTop.Wisdom.Nenana(3..7)) ^ Millston.Maumee.$valid - 27..29: random(HillTop.Wisdom.Nenana(3..7)) ^ HillTop.Wisdom.Nenana(0..2) - 20: random(HillTop.Wisdom.Nenana(3..7)) ^ HillTop.Wisdom.Piqua - hash group 0: - table: [2, 3] - seed: 0x393c5c00 - format: { immediate(0): 0..7, version(0): 112..115, match(0): 35..39, immediate(1): 8..15, version(1): 116..119, match(1): 43..47, immediate(2): 16..23, version(2): 120..123, match(2): 51..55, immediate(3): 24..31, version(3): 124..127, match(3): 59..63 } - match: [ HillTop.Wisdom.Nenana(3..7) ] - hit: [ _Monse ] - miss: _Monse - action_bus: { 0 : immediate(0..7) } - instruction: _MoonRun($DEFAULT, $DEFAULT) - actions: - GlenDean(0, 1): - - p4_param_order: { Buncombe: 8 } - - default_action: { allowed: true } - - handle: 0x20000125 - - next_table: 0 - - { Buncombe: immediate(0..7) } - - set HillTop.McGonigle.Buncombe, Buncombe - default_action: GlenDean - default_action_parameters: - Buncombe: "0x0" - ternary_match _Monse 5: - p4: { name: Monse, size: 8, disable_atomic_modify : true } - p4_param_order: - HillTop.Freeny.Dunedin: { type: exact, size: 3, full_size: 3, key_name: "Freeny.Dunedin" } - row: 6 - bus: 0 - column: 0 - indirect_bus: 3 - input_xbar: - ternary group 0: { 0: HillTop.Freeny.Dunedin } - match: - - { group: 0, byte_config: 3, dirtcam: 0x1 } - hit: [ Dyess_0 ] - miss: Dyess_0 - action: _Monse$action_data($DIRECT, $DEFAULT) - instruction: _Monse($DEFAULT, $DEFAULT) - actions: - Danbury(0, 2): - - p4_param_order: { PineCity: 6 } - - default_action: { allowed: true } - - handle: 0x2000011d - - next_table: 0 - - { PineCity: $adf_h0(0..5) } - - set HillTop.Edwards.Renick, PineCity - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x2000011e - - next_table: 0 - - { } - default_only_action: NoAction - action _Monse$action_data: - p4: { name: Monse$action } - row: 7 - column: 3 - vpns: [ 0 ] - home_row: - - 7 - format Danbury: { $adf_h0: 0..15 } - action_bus: { 40..41 : $adf_h0 } - ternary_match Dyess_0 6: - p4: { name: Dyess, size: 16, disable_atomic_modify : true } - p4_param_order: - HillTop.Wisdom.Dyess: { type: exact, size: 1, full_size: 1, key_name: "Wisdom.Dyess" } - Millston.GlenAvon.$valid: { type: exact, size: 1, full_size: 1, key_name: "GlenAvon" } - Millston.Maumee.$valid: { type: exact, size: 1, full_size: 1, key_name: "Maumee" } - row: 2 - bus: 0 - column: 0 - input_xbar: - ternary group 5: { 3: Millston.GlenAvon.$valid, 9: Millston.Maumee.$valid, 32: HillTop.Wisdom.Dyess } - match: - - { group: 5, byte_config: 3, dirtcam: 0x105 } - gateway: - name: cond-45 - input_xbar: - exact group 3: { 1: HillTop.Wisdom.Onycha } - row: 2 - bus: 1 - unit: 0 - match: { 1: HillTop.Wisdom.Onycha } - 0b****000: run_table - 0b****011: run_table - miss: _Lebanon - condition: - expression: "(HillTop.Wisdom.Onycha == 0 || HillTop.Wisdom.Onycha == 3)" - true: Dyess_0 - false: _Lebanon - hit: [ _Lebanon ] - miss: _Lebanon - indirect: Dyess_0$tind - ternary_indirect Dyess_0$tind: - row: 3 - bus: 0 - column: 5 - input_xbar: - ternary group 5: { 3: Millston.GlenAvon.$valid, 9: Millston.Maumee.$valid, 32: HillTop.Wisdom.Dyess } - format: { action: 0..1 } - instruction: Dyess_0$tind(action, $DEFAULT) - actions: - Daguao(1, 3): - - default_action: { allowed: true } - - handle: 0x20000122 - - next_table: 0 - - set Millston.GlenAvon.Ocoee(7..7), 0 - Ripley(2, 4): - - default_action: { allowed: true } - - handle: 0x20000123 - - next_table: 0 - - set Millston.Maumee.Dassel(7..7), 0 - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x20000124 - - next_table: 0 - default_only_action: NoAction - ternary_match _Lebanon 7: - p4: { name: Lebanon, size: 1024, disable_atomic_modify : true } - p4_param_order: - HillTop.McCaskill.Whitewood: { type: exact, size: 10, full_size: 10, key_name: "McCaskill.Whitewood" } - row: [ 3, 4 ] - bus: [ 0, 0 ] - column: - - 0 - - 0 - input_xbar: - ternary group 0: { 8: HillTop.McCaskill.Whitewood(8..9), 16: HillTop.McCaskill.Whitewood(0..7) } - match: - - { group: 0, byte_config: 3, dirtcam: 0x14 } - hit: [ _Protivin ] - miss: _Protivin - indirect: _Lebanon$tind - meter _Lebanon$meter..Slinger: - p4: { name: Slinger, size: 128 } - row: 15 - column: [ 3, 4 ] - maprams: [ 3, 4 ] - color_maprams: - row: 7 - bus: 0 - column: 0 - address: idletime - type: standard - count: bytes - per_flow_enable: meter_pfe - ternary_indirect _Lebanon$tind: - row: 2 - bus: 0 - column: 5 - input_xbar: - ternary group 0: { 8: HillTop.McCaskill.Whitewood(8..9), 16: HillTop.McCaskill.Whitewood(0..7) } - format: { action: 0..0, meter_addr: 1..10, meter_pfe: 11..11 } - action_bus: { 3 : _Lebanon$meter..Slinger color } - meter: _Lebanon$meter..Slinger(meter_addr, meter_pfe, $DEFAULT) - meter_color : _Lebanon$meter..Slinger(meter_addr, meter_pfe) - instruction: _Lebanon$tind(action, $DEFAULT) - actions: - Lovelady(0, 5): - - p4_param_order: { Kingsland: 32 } - - default_action: { allowed: true } - - handle: 0x20000126 - - next_table: 0 - - { Kingsland: meter_addr } - - set HillTop.McCaskill.Tilton, _Lebanon$meter..Slinger color(0..1) - - _Lebanon$meter..Slinger(2, Kingsland) - PellCity(1, 6): - - default_action: { allowed: true } - - handle: 0x20000127 - - next_table: 0 - - set HillTop.McCaskill.Tilton, 2 - default_action: PellCity - ternary_match _Protivin 8: - p4: { name: Protivin, size: 128, disable_atomic_modify : true } - p4_param_order: - eg_intr_md.egress_port: { type: exact, size: 9, full_size: 9, key_name: "Sonoma.egress_port" } - HillTop.Lamona.Pachuta: { type: exact, size: 1, full_size: 1, key_name: "Lamona.Pachuta" } - HillTop.Wisdom.RioPecos: { type: exact, size: 1, full_size: 1, key_name: "Wisdom.RioPecos" } - HillTop.Wisdom.Onycha: { type: exact, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } - row: 0 - bus: 0 - column: 0 - input_xbar: - ternary group 8: { 0: HillTop.Wisdom.RioPecos, 8: eg_intr_md.egress_port(8), 16: eg_intr_md.egress_port(0..7), 24: HillTop.Lamona.Pachuta, 33: HillTop.Wisdom.Onycha } - match: - - { group: 8, byte_config: 3, dirtcam: 0x155 } - hit: [ _Medart, _Ghent ] - miss: _Medart - indirect: _Protivin$tind - ternary_indirect _Protivin$tind: - row: 1 - bus: 0 - column: 5 - input_xbar: - ternary group 8: { 0: HillTop.Wisdom.RioPecos, 8: eg_intr_md.egress_port(8), 16: eg_intr_md.egress_port(0..7), 24: HillTop.Lamona.Pachuta, 33: HillTop.Wisdom.Onycha } - format: { action: 0..0, immediate: 1..2 } - action_bus: { 44..45 : immediate(0..1) } - instruction: _Protivin$tind(action, $DEFAULT) - actions: - Chappell(0, 7): - - p4_param_order: { Toklat: 2 } - - default_action: { allowed: true } - - handle: 0x2000012f - - next_table: 0 - - { Toklat: immediate(0..1) } - - set HillTop.Wisdom.Stratford, 1 - - set HillTop.Wisdom.Westhoff, 2 - - set HillTop.Wisdom.Toklat, Toklat - - set Millston.Hayfield.Aguilita, 0 - Sequim(1, 0): - - default_action: { allowed: true } - - handle: 0x20000130 - - next_table: 1 - - { } - default_action: Sequim - ternary_match _Ghent 9: - p4: { name: Ghent, size: 16, disable_atomic_modify : true } - p4_param_order: - HillTop.Wisdom.Onycha: { type: ternary, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } - HillTop.Wisdom.Westhoff: { type: exact, size: 3, full_size: 3, key_name: "Wisdom.Westhoff" } - HillTop.Wisdom.RioPecos: { type: ternary, size: 1, full_size: 1, key_name: "Wisdom.RioPecos" } - HillTop.Wisdom.Bennet: { type: ternary, size: 1, full_size: 32, key_name: "Wisdom.Bennet", start_bit: 16 } - HillTop.Wisdom.Bennet: { type: ternary, size: 1, full_size: 32, key_name: "Wisdom.Bennet", start_bit: 18 } - row: 1 - bus: 0 - column: 0 - input_xbar: - ternary group 8: { 0: HillTop.Wisdom.RioPecos, 1: HillTop.Wisdom.Westhoff, 33: HillTop.Wisdom.Onycha } - byte group 1: { 0: HillTop.Wisdom.Bennet.16-23(0), 2: HillTop.Wisdom.Bennet.16-23(2) } - match: - - { group: 8, byte_group: 1, byte_config: 0, dirtcam: 0x501 } - hit: [ _Medart ] - miss: _Medart - indirect: _Ghent$tind - ternary_indirect _Ghent$tind: - row: 0 - bus: 0 - column: 5 - input_xbar: - ternary group 8: { 0: HillTop.Wisdom.RioPecos, 1: HillTop.Wisdom.Westhoff, 33: HillTop.Wisdom.Onycha } - byte group 1: { 0: HillTop.Wisdom.Bennet.16-23(0), 2: HillTop.Wisdom.Bennet.16-23(2) } - format: { action: 0..2, immediate: 3..18 } - action_bus: { 100..103 : immediate(0..15) } - instruction: _Ghent$tind(action, $DEFAULT) - actions: - Westend(0, 8): - - p4_param_order: { Mendocino: 16, Scotland: 16, Addicks: 16 } - - default_action: { allowed: true } - - handle: 0x20000131 - - next_table: 0 - - { Addicks: immediate(0..15) } - - and W26, Addicks, W26 - Wyandanch(1, 10): - - p4_param_order: { RockPort: 32, Mendocino: 16, Scotland: 16, Addicks: 16 } - - default_action: { allowed: true } - - handle: 0x20000132 - - next_table: 0 - - { Addicks: immediate(0..15) } - - and W26, Addicks, W26 - Vananda(2, 12): - - p4_param_order: { RockPort: 32, Mendocino: 16, Scotland: 16, Addicks: 16 } - - default_action: { allowed: true } - - handle: 0x20000133 - - next_table: 0 - - { Addicks: immediate(0..15) } - - and W26, Addicks, W26 - Yorklyn(3, 0): - - p4_param_order: { Mendocino: 16, Scotland: 16 } - - default_action: { allowed: true } - - handle: 0x20000134 - - next_table: 0 - - { } - Botna(4, 9): - - p4_param_order: { Scotland: 16 } - - default_action: { allowed: true } - - handle: 0x20000135 - - next_table: 0 - - { } - NoAction(-1, 11): - - default_only_action: { allowed: true } - - handle: 0x20000136 - - next_table: 0 - - { } - default_only_action: NoAction - ternary_match _Medart 10: - p4: { name: Medart, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.Wisdom.Miller: { type: exact, size: 9, full_size: 9, key_name: "Wisdom.Miller" } - row: 5 - bus: 0 - column: 0 - indirect_bus: 1 - input_xbar: - ternary group 1: { 0: HillTop.Wisdom.Miller.8-8, 24: HillTop.Wisdom.Miller.0-7 } - match: - - { group: 1, byte_config: 3, dirtcam: 0x41 } - hit: [ _McDougal ] - miss: _McDougal - action: _Medart$action_data($DIRECT, $DEFAULT) - instruction: _Medart($DEFAULT, $DEFAULT) - actions: - Estero(0, 13): - - p4_param_order: { Inkom: 6, Gowanda: 10, BurrOak: 4, Gardena: 12 } - - default_action: { allowed: true } - - handle: 0x20000137 - - next_table: 0 - - { $data0: $adf_h0(0..15), Gardena: $data0(0..11), BurrOak: $data0(12..15), $data1: $adf_h1(0..15), Gowanda: $data1(0..9), Inkom: $data1(10..15) } - - set H31, $data0 - - set H72, $data1 - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x20000138 - - next_table: 0 - - { } - default_only_action: NoAction - action _Medart$action_data: - p4: { name: Medart$action } - row: 9 - column: 3 - vpns: [ 0 ] - home_row: - - 9 - format Estero: { $adf_h0: 0..15, $adf_h1: 16..31 } - action_bus: { 48..49 : $adf_h0, 50..51 : $adf_h1 } - hash_action _McDougal 11: - p4: { name: McDougal, size: 1, disable_atomic_modify : true } - row: 2 - bus: 1 - hash_dist: - 0: { hash: 2, mask: 0xfff, shift: 3 } - input_xbar: - exact group 3: { 8: eg_intr_md.egress_port(8), 16: eg_intr_md.egress_port(0..7), 32: eg_intr_md.egress_qid } - hash 6: - 0..4: stripe(eg_intr_md.egress_qid) - 5..11: stripe(eg_intr_md.egress_port(0..6)) - hash group 2: - table: [6] - seed: 0x0 - gateway: - name: _McDougal-gateway - row: 0 - bus: 0 - unit: 1 - 0x0: _Waseca - miss: _Waseca - condition: - expression: "true(always hit)" - true: _Waseca - false: _Waseca - next: [] - stats: _McDougal$stats..Tillicum(hash_dist 0, $DEFAULT) - instruction: _McDougal($DEFAULT, $DEFAULT) - actions: - Magazine(0, 0): - - default_action: { allowed: true } - - handle: 0x2000011c - - next_table: 0 - - _McDougal$stats..Tillicum($hash_dist) - default_action: Magazine - counter _McDougal$stats..Tillicum: - p4: { name: Tillicum, size: 4096 } - row: [ 13, 11 ] - column: - - [ 3, 4, 5 ] - - [ 3, 4 ] - maprams: - - [ 3, 4, 5 ] - - [ 3, 4 ] - count: packets_and_bytes - format: {packets(0): 0..63, bytes(0): 64..127} -stage 5 egress: - ternary_match _Waseca 9: - p4: { name: Waseca, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.Wisdom.Onycha: { type: exact, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } - HillTop.Wisdom.Westhoff: { type: exact, size: 3, full_size: 3, key_name: "Wisdom.Westhoff" } - HillTop.Wisdom.Piqua: { type: exact, size: 1, full_size: 1, key_name: "Wisdom.Piqua" } - Millston.GlenAvon.$valid: { type: ternary, size: 1, full_size: 1, key_name: "GlenAvon" } - Millston.Maumee.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Maumee" } - Millston.Ramos.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Ramos" } - Millston.Provencal.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Provencal" } - HillTop.Wisdom.Bennet: { type: ternary, size: 2, full_size: 32, key_name: "Wisdom.Bennet", start_bit: 18 } - row: [ 0, 1 ] - bus: [ 0, 0 ] - column: - - 0 - - 0 - input_xbar: - ternary group 4: { 17: HillTop.Wisdom.Onycha } - ternary group 5: { 3: Millston.GlenAvon.$valid, 4: Millston.Ramos.$valid, 9: Millston.Maumee.$valid, 17: Millston.Provencal.$valid, 33: HillTop.Wisdom.Westhoff, 36: HillTop.Wisdom.Piqua } - byte group 1: { 2: HillTop.Wisdom.Bennet.16-23(2..3) } - match: - - { group: 4, byte_group: 1, byte_config: 0, dirtcam: 0x410 } - - { group: 5, dirtcam: 0x115 } - hit: [ _Haugen ] - miss: _Haugen - indirect: _Waseca$tind - ternary_indirect _Waseca$tind: - row: 0 - bus: 0 - column: 2 - input_xbar: - ternary group 4: { 17: HillTop.Wisdom.Onycha } - ternary group 5: { 3: Millston.GlenAvon.$valid, 4: Millston.Ramos.$valid, 9: Millston.Maumee.$valid, 17: Millston.Provencal.$valid, 33: HillTop.Wisdom.Westhoff, 36: HillTop.Wisdom.Piqua } - byte group 1: { 2: HillTop.Wisdom.Bennet.16-23(2..3) } - format: { action: 0..5 } - action: _Waseca$action_data($DIRECT, $DEFAULT) - instruction: _Waseca$tind(action, $DEFAULT) - actions: - Durant(1, 1): - - p4_param_order: { Onamia: 24, Brule: 24 } - - default_action: { allowed: true } - - handle: 0x2000013b - - next_table: 0 - - { Brule.16-23: $adf_b0(0..7), Onamia.16-23: $adf_b1(0..7), Brule.0-15: $adf_h1(0..15), Onamia.0-15: $adf_h2(0..15) } - - set Millston.Calabash.Adona.0-7, HillTop.Wisdom.Adona.0-7 - - set Millston.Calabash.Adona.8-23, HillTop.Wisdom.Adona.8-23 - - set Millston.Calabash.Connell.0-7, HillTop.Wisdom.Connell.0-7 - - set Millston.Calabash.Connell.8-23, HillTop.Wisdom.Connell.8-23 - - set Millston.Calabash.Goldsboro.0-15, Onamia.0-15 - - set Millston.Calabash.Goldsboro.16-23, Onamia.16-23 - - set Millston.Calabash.Fabens.0-15, Brule.0-15 - - set Millston.Calabash.Fabens.16-23, Brule.16-23 - - add Millston.GlenAvon.Exton, Millston.GlenAvon.Exton, 255 - - set HillTop.Plains.Roachdale, 0 - - set HillTop.Plains.Miller, 0 - Kingsdale(2, 2): - - p4_param_order: { Onamia: 24, Brule: 24 } - - default_action: { allowed: true } - - handle: 0x2000013c - - next_table: 0 - - { Brule.16-23: $adf_b0(0..7), Onamia.16-23: $adf_b1(0..7), Brule.0-15: $adf_h1(0..15), Onamia.0-15: $adf_h2(0..15) } - - set Millston.Calabash.Adona.0-7, HillTop.Wisdom.Adona.0-7 - - set Millston.Calabash.Adona.8-23, HillTop.Wisdom.Adona.8-23 - - set Millston.Calabash.Connell.0-7, HillTop.Wisdom.Connell.0-7 - - set Millston.Calabash.Connell.8-23, HillTop.Wisdom.Connell.8-23 - - set Millston.Calabash.Goldsboro.0-15, Onamia.0-15 - - set Millston.Calabash.Goldsboro.16-23, Onamia.16-23 - - set Millston.Calabash.Fabens.0-15, Brule.0-15 - - set Millston.Calabash.Fabens.16-23, Brule.16-23 - - add Millston.Maumee.Bushland, Millston.Maumee.Bushland, 255 - - set HillTop.Plains.Roachdale, 0 - - set HillTop.Plains.Miller, 0 - Tekonsha(4, 4): - - default_action: { allowed: true } - - handle: 0x2000013d - - next_table: 0 - - { } - - set Millston.Calabash.Adona.0-7, HillTop.Wisdom.Adona.0-7 - - set Millston.Calabash.Adona.8-23, HillTop.Wisdom.Adona.8-23 - - set Millston.Calabash.Connell.0-7, HillTop.Wisdom.Connell.0-7 - - set Millston.Calabash.Connell.8-23, HillTop.Wisdom.Connell.8-23 - - set HillTop.Plains.Roachdale, 0 - - set HillTop.Plains.Miller, 0 - Clermont(6, 6): - - default_action: { allowed: true } - - handle: 0x2000013e - - next_table: 0 - - { } - - set Millston.Calabash.Adona.0-7, HillTop.Wisdom.Adona.0-7 - - set Millston.Calabash.Adona.8-23, HillTop.Wisdom.Adona.8-23 - - set Millston.Calabash.Connell.0-7, HillTop.Wisdom.Connell.0-7 - - set Millston.Calabash.Connell.8-23, HillTop.Wisdom.Connell.8-23 - - set HillTop.Plains.Roachdale, 0 - - set HillTop.Plains.Miller, 0 - Blanding(8, 8): - - default_action: { allowed: true } - - handle: 0x2000013f - - next_table: 0 - - { } - - set Millston.Wondervu$0.$valid, 1 - - set Millston.Wondervu$0.McCaulley, Millston.Calabash.McCaulley - - set Millston.Calabash.McCaulley, 33024 - - set HillTop.Plains.Roachdale, 0 - - set HillTop.Plains.Miller, 0 - - deposit-field H22(12..15), H20(4..7), H23 - Shelby(10, 10): - - default_action: { allowed: true } - - handle: 0x20000140 - - next_table: 0 - - { } - - set Millston.Hayfield.$valid, 1 - - set Millston.Hayfield.Lathrop, HillTop.Wisdom.Lathrop - - set Millston.Hayfield.Blencoe, HillTop.Wisdom.Blencoe - - set Millston.Hayfield.Harbor, HillTop.RossFork.Bicknell - - set HillTop.Plains.Roachdale, 0 - - set HillTop.Plains.Miller, 0 - - deposit-field H30(12..15), H23(12..15), H29 - Chambers(12, 12): - - default_action: { allowed: true } - - handle: 0x20000141 - - next_table: 0 - - { } - - set HillTop.Plains.Roachdale, 0 - - set HillTop.Plains.Miller, 0 - Ardenvoir(14, 14): - - p4_param_order: { Onamia: 24, Brule: 24 } - - default_action: { allowed: true } - - handle: 0x20000142 - - next_table: 0 - - { Brule.16-23: $adf_b0(0..7), Onamia.16-23: $adf_b1(0..7), Brule.0-15: $adf_h1(0..15), Onamia.0-15: $adf_h2(0..15) } - - set Millston.Calabash.$valid, 1 - - set Millston.Calabash.Adona.0-7, HillTop.Wisdom.Adona.0-7 - - set Millston.Calabash.Adona.8-23, HillTop.Wisdom.Adona.8-23 - - set Millston.Calabash.Connell.0-7, HillTop.Wisdom.Connell.0-7 - - set Millston.Calabash.Connell.8-23, HillTop.Wisdom.Connell.8-23 - - set Millston.Calabash.Goldsboro.0-15, Onamia.0-15 - - set Millston.Calabash.Goldsboro.16-23, Onamia.16-23 - - set Millston.Calabash.Fabens.0-15, Brule.0-15 - - set Millston.Calabash.Fabens.16-23, Brule.16-23 - - set Millston.Calabash.McCaulley, 2048 - - set HillTop.Plains.Roachdale, 0 - - set HillTop.Plains.Miller, 0 - Clinchco(16, 16): - - default_action: { allowed: true } - - handle: 0x20000143 - - next_table: 0 - - { } - - set Millston.Calabash.Adona.0-7, HillTop.Wisdom.Adona.0-7 - - set Millston.Calabash.Adona.8-23, HillTop.Wisdom.Adona.8-23 - - set Millston.Calabash.Connell.0-7, HillTop.Wisdom.Connell.0-7 - - set Millston.Calabash.Connell.8-23, HillTop.Wisdom.Connell.8-23 - - set HillTop.Plains.Roachdale, 0 - - set HillTop.Plains.Miller, 0 - Snook(18, 18): - - default_action: { allowed: true } - - handle: 0x20000144 - - next_table: 0 - - { } - - set Millston.Calabash.McCaulley, 2048 - - set Millston.Hayfield.$valid, 1 - - set Millston.Hayfield.Lathrop, HillTop.Wisdom.Lathrop - - set Millston.Hayfield.Blencoe, HillTop.Wisdom.Blencoe - - set Millston.Hayfield.Harbor, HillTop.RossFork.Bicknell - - set HillTop.Plains.Roachdale, 0 - - set HillTop.Plains.Miller, 0 - - deposit-field H30(12..15), H23(12..15), H29 - OjoFeliz(20, 20): - - default_action: { allowed: true } - - handle: 0x20000145 - - next_table: 0 - - { } - - set Millston.Calabash.McCaulley, 34525 - - set Millston.Hayfield.$valid, 1 - - set Millston.Hayfield.Lathrop, HillTop.Wisdom.Lathrop - - set Millston.Hayfield.Blencoe, HillTop.Wisdom.Blencoe - - set Millston.Hayfield.Harbor, HillTop.RossFork.Bicknell - - set HillTop.Plains.Roachdale, 0 - - set HillTop.Plains.Miller, 0 - - deposit-field H30(12..15), H23(12..15), H29 - Havertown(22, 22): - - p4_param_order: { Onamia: 24, Brule: 24 } - - default_action: { allowed: true } - - handle: 0x20000146 - - next_table: 0 - - { Brule.16-23: $adf_b0(0..7), Onamia.16-23: $adf_b1(0..7), Brule.0-15: $adf_h1(0..15), Onamia.0-15: $adf_h2(0..15) } - - set Millston.Calabash.Adona.0-7, HillTop.Wisdom.Adona.0-7 - - set Millston.Calabash.Adona.8-23, HillTop.Wisdom.Adona.8-23 - - set Millston.Calabash.Connell.0-7, HillTop.Wisdom.Connell.0-7 - - set Millston.Calabash.Connell.8-23, HillTop.Wisdom.Connell.8-23 - - set Millston.Calabash.Goldsboro.0-15, Onamia.0-15 - - set Millston.Calabash.Goldsboro.16-23, Onamia.16-23 - - set Millston.Calabash.Fabens.0-15, Brule.0-15 - - set Millston.Calabash.Fabens.16-23, Brule.16-23 - - set Millston.Calabash.McCaulley, 2048 - - add Millston.GlenAvon.Exton, Millston.GlenAvon.Exton, 255 - - set HillTop.Plains.Roachdale, 0 - - set HillTop.Plains.Miller, 0 - Napanoch(24, 24): - - p4_param_order: { Onamia: 24, Brule: 24 } - - default_action: { allowed: true } - - handle: 0x20000147 - - next_table: 0 - - { Brule.16-23: $adf_b0(0..7), Onamia.16-23: $adf_b1(0..7), Brule.0-15: $adf_h1(0..15), Onamia.0-15: $adf_h2(0..15) } - - set Millston.Calabash.Adona.0-7, HillTop.Wisdom.Adona.0-7 - - set Millston.Calabash.Adona.8-23, HillTop.Wisdom.Adona.8-23 - - set Millston.Calabash.Connell.0-7, HillTop.Wisdom.Connell.0-7 - - set Millston.Calabash.Connell.8-23, HillTop.Wisdom.Connell.8-23 - - set Millston.Calabash.Goldsboro.0-15, Onamia.0-15 - - set Millston.Calabash.Goldsboro.16-23, Onamia.16-23 - - set Millston.Calabash.Fabens.0-15, Brule.0-15 - - set Millston.Calabash.Fabens.16-23, Brule.16-23 - - set Millston.Calabash.McCaulley, 34525 - - add Millston.Maumee.Bushland, Millston.Maumee.Bushland, 255 - - set HillTop.Plains.Roachdale, 0 - - set HillTop.Plains.Miller, 0 - NoAction(-1, 26): - - default_only_action: { allowed: true } - - handle: 0x20000148 - - next_table: 0 - - { } - - set HillTop.Plains.Roachdale, 0 - - set HillTop.Plains.Miller, 0 - default_only_action: NoAction - action _Waseca$action_data: - p4: { name: Waseca$action } - row: 10 - column: 3 - vpns: [ 0 ] - home_row: - - 10 - format Durant: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_h1: 16..31, $adf_h2: 32..47 } - format Kingsdale: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_h1: 16..31, $adf_h2: 32..47 } - format Ardenvoir: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_h1: 16..31, $adf_h2: 32..47 } - format Havertown: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_h1: 16..31, $adf_h2: 32..47 } - format Napanoch: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_h1: 16..31, $adf_h2: 32..47 } - action_bus: { 0 : $adf_b0, 1 : $adf_b1, 74..75 : $adf_h1, 76..77 : $adf_h2 } - exact_match _Haugen 10: - p4: { name: Haugen, size: 512, disable_atomic_modify : true } - p4_param_order: - HillTop.Wisdom.Dolores: { type: exact, size: 2, full_size: 2, key_name: "Wisdom.Dolores" } - eg_intr_md.egress_port: { type: exact, size: 7, full_size: 9, key_name: "Sonoma.egress_port" } - row: 2 - bus: 1 - column: 11 - stash: - row: [ 2 ] - col: [ 11 ] - unit: [ 0 ] - ways: - - [4, 0, 0x0, [2, 11]] - input_xbar: - exact group 3: { 0: HillTop.Wisdom.Dolores, 16: eg_intr_md.egress_port(0..6) } - hash 6: - 0..1: HillTop.Wisdom.Dolores - 2..8: eg_intr_md.egress_port(0..6) - hash group 4: - table: [6] - seed: 0x0 - format: { action(0): 0..0, version(0): 112..115 } - gateway: - name: cond-46 - input_xbar: - exact group 4: { 1: HillTop.Wisdom.Westhoff, 4: HillTop.Wisdom.Piqua, 33: HillTop.Wisdom.Onycha } - row: 4 - bus: 1 - unit: 0 - match: { 20: HillTop.Wisdom.Piqua, 1: HillTop.Wisdom.Onycha, 9: HillTop.Wisdom.Westhoff } - 0b***0********000*****000: run_table - miss: _Papeton - condition: - expression: "(HillTop.Wisdom.Piqua == 0 && HillTop.Wisdom.Onycha == 0 && HillTop.Wisdom.Westhoff == 0)" - true: _Haugen - false: _Papeton - hit: [ _Papeton ] - miss: _Papeton - instruction: _Haugen(action, $DEFAULT) - actions: - Pearcy(1, 3): - - default_action: { allowed: true } - - handle: 0x20000139 - - next_table: 0 - - set eg_intr_md_for_dprsr.drop_ctl, 7 - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x2000013a - - next_table: 0 - default_only_action: NoAction - ternary_match _Papeton 11: - p4: { name: Papeton, size: 14, disable_atomic_modify : true } - p4_param_order: - HillTop.Wisdom.Westhoff: { type: ternary, size: 3, full_size: 3, key_name: "Wisdom.Westhoff" } - HillTop.Wisdom.Onycha: { type: ternary, size: 3, full_size: 3, key_name: "Wisdom.Onycha" } - HillTop.Wisdom.Piqua: { type: ternary, size: 1, full_size: 1, key_name: "Wisdom.Piqua" } - Millston.GlenAvon.$valid: { type: ternary, size: 1, full_size: 1, key_name: "GlenAvon" } - Millston.Maumee.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Maumee" } - Millston.Ramos.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Ramos" } - Millston.Provencal.$valid: { type: ternary, size: 1, full_size: 1, key_name: "Provencal" } - row: 9 - bus: 1 - column: 1 - input_xbar: - ternary group 8: { 3: Millston.GlenAvon.$valid, 4: Millston.Ramos.$valid, 9: Millston.Maumee.$valid, 17: Millston.Provencal.$valid, 33: HillTop.Wisdom.Westhoff, 36: HillTop.Wisdom.Piqua } - byte group 5: { 1: HillTop.Wisdom.Onycha } - match: - - { group: 8, byte_group: 5, byte_config: 0, dirtcam: 0x515 } - gateway: - name: cond-47 - input_xbar: - exact group 5: { 0: Millston.Belgrade.$valid, 8: HillTop.Wisdom.Stratford } - row: 7 - bus: 1 - unit: 0 - match: { 0: Millston.Belgrade.$valid, 8: HillTop.Wisdom.Stratford } - 0b*******0*******1: run_table - miss: _Astatula - condition: - expression: "(Millston.Belgrade.$valid == 1 == 1 && HillTop.Wisdom.Stratford == 0)" - true: _Papeton - false: _Astatula - hit: [ _Cropper ] - miss: _Cropper - indirect: _Papeton$tind - ternary_indirect _Papeton$tind: - row: 5 - bus: 0 - column: 2 - input_xbar: - ternary group 8: { 3: Millston.GlenAvon.$valid, 4: Millston.Ramos.$valid, 9: Millston.Maumee.$valid, 17: Millston.Provencal.$valid, 33: HillTop.Wisdom.Westhoff, 36: HillTop.Wisdom.Piqua } - byte group 5: { 1: HillTop.Wisdom.Onycha } - format: { action: 0..2 } - instruction: _Papeton$tind(action, $DEFAULT) - actions: - Ravenwood(1, 5): - - default_action: { allowed: true } - - handle: 0x20000151 - - next_table: 0 - - set Millston.GlenAvon.PineCity, HillTop.Edwards.PineCity - - set HillTop.Edwards.SomesBar, 0 - Poneto(2, 7): - - default_action: { allowed: true } - - handle: 0x20000152 - - next_table: 0 - - set Millston.Maumee.PineCity, HillTop.Edwards.PineCity - - set HillTop.Edwards.SomesBar, 0 - Lurton(3, 9): - - default_action: { allowed: true } - - handle: 0x20000153 - - next_table: 0 - - set Millston.Ramos.PineCity, HillTop.Edwards.PineCity - - set HillTop.Edwards.SomesBar, 0 - Quijotoa(4, 11): - - default_action: { allowed: true } - - handle: 0x20000154 - - next_table: 0 - - set Millston.Provencal.PineCity, HillTop.Edwards.PineCity - - set HillTop.Edwards.SomesBar, 0 - Frontenac(5, 13): - - default_action: { allowed: true } - - handle: 0x20000155 - - next_table: 0 - - set Millston.GlenAvon.PineCity, HillTop.Edwards.Renick - - set HillTop.Edwards.SomesBar, 0 - Gilman(6, 15): - - default_action: { allowed: true } - - handle: 0x20000156 - - next_table: 0 - - set Millston.GlenAvon.PineCity, HillTop.Edwards.Renick - - set Millston.Ramos.PineCity, HillTop.Edwards.PineCity - - set HillTop.Edwards.SomesBar, 0 - Kalaloch(7, 17): - - default_action: { allowed: true } - - handle: 0x20000157 - - next_table: 0 - - set Millston.GlenAvon.PineCity, HillTop.Edwards.Renick - - set Millston.Provencal.PineCity, HillTop.Edwards.PineCity - - set HillTop.Edwards.SomesBar, 0 - NoAction(-1, 19): - - default_only_action: { allowed: true } - - handle: 0x20000158 - - next_table: 0 - - set HillTop.Edwards.SomesBar, 0 - default_only_action: NoAction -stage 6 egress: - ternary_match _Cropper 6: - p4: { name: Cropper, size: 128, action_profile: Tulsa, disable_atomic_modify : true } - p4_param_order: - HillTop.McCaskill.Grassflat: { type: exact, size: 7, full_size: 10, key_name: "McCaskill.Grassflat" } - row: 7 - bus: 1 - column: 1 - input_xbar: - ternary group 0: { 32: HillTop.McCaskill.Grassflat(0..6) } - match: - - { group: 0, byte_config: 3, dirtcam: 0x100 } - hit: [ _Ranier ] - miss: _Ranier - indirect: _Cropper$tind - selection _Cropper$selector.Tulsa_sel: - p4: { name: Tulsa_sel, size: 4 } - row: 3 - column: [ 1, 2 ] - maprams: [ 1, 2 ] - input_xbar: - exact group 5: { 0: HillTop.Lewiston.Staunton } - hash 10: - 0..50: slice(stripe(crc_rev(0x18005, 0x0, 0x0, 16, { 0: HillTop.Lewiston.Staunton })), 0..50) - hash group 5: - table: [10] - seed: 0x0 - mode: resilient 0 - non_linear: true - pool_sizes: [120] - action _Cropper$action_data.Tulsa: - p4: { name: Tulsa, size: 1024 } - row: 0 - column: 4 - vpns: [ 0 ] - home_row: - - 0 - format Centre: { $adf_h0: 0..15 } - action_bus: { 52..53 : $adf_h0 } - stateful _Cropper$salu.Tulsa_sel$salu: - p4: { name: Tulsa_sel$salu, size: 122880, hidden: true } - selection_table: _Cropper$selector.Tulsa_sel - row: 3 - column: [ 1, 2 ] - maprams: [ 1, 2 ] - format: { lo: 1 } - actions: - set_bit_at_alu$0: - - set_bit_at - clr_bit_at_alu$0: - - clr_bit_at - set_bit_alu$0: - - set_bit - clr_bit_alu$0: - - clr_bit - ternary_indirect _Cropper$tind: - row: 0 - bus: 0 - column: 2 - input_xbar: - ternary group 0: { 32: HillTop.McCaskill.Grassflat(0..6) } - format: { meter_addr: 0..9, meter_pfe: 10..10, action_addr: 11..21 } - selector: _Cropper$selector.Tulsa_sel(meter_addr, meter_pfe, $DEFAULT) - selector_length: _Cropper$selector.Tulsa_sel($DEFAULT, $DEFAULT) - action: _Cropper$action_data.Tulsa(action_addr, $DEFAULT) - instruction: _Cropper$tind($DEFAULT, $DEFAULT) - actions: - Centre(0, 1): - - p4_param_order: { Hector: 10 } - - default_action: { allowed: true } - - handle: 0x2000014f - - next_table: 0 - - { Hector: $adf_h0(0..9) } - - or H19, Hector, H19 - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x20000150 - - next_table: 0 - - { } - default_only_action: NoAction - hash_action _Ranier 7: - p4: { name: Ranier, size: 1, disable_atomic_modify : true } - row: 1 - bus: 1 - hash_dist: - 3: { hash: 6, mask: 0x7ffff, shift: 0, expand: 0 } - input_xbar: - exact group 5: { 64: eg_intr_md.egress_port, 80: HillTop.Wisdom.Bowden } - hash 11: - 0..11: stripe(HillTop.Wisdom.Bowden) - 12..15: stripe(eg_intr_md.egress_port(0..3)) - 32..34: stripe(eg_intr_md.egress_port(4..6)) - hash group 6: - table: [11] - seed: 0x0 - gateway: - name: cond-50 - input_xbar: - exact group 6: { 1: HillTop.Wisdom.Onycha, 13: HillTop.Wisdom.Weatherby } - row: 0 - bus: 0 - unit: 0 - payload: 0x300001 - format: { action: 0..0, meter_addr: 1..19, meter_pfe: 20..20, meter_type: 21..23 } - match: { 1: HillTop.Wisdom.Onycha, 13: HillTop.Wisdom.Weatherby } - 0o****2: run_table - 0b**1************: run_table - miss: _Osakis - condition: - expression: "(HillTop.Wisdom.Onycha != 2 && HillTop.Wisdom.Weatherby == 0)" - true: _Osakis - false: _Charters - next: _Charters - action_bus: { 56..57 : _Ranier$salu..Nordland(0..15) } - stateful: _Ranier$salu..Nordland(hash_dist 3, $DEFAULT, $DEFAULT) - instruction: _Ranier(action, $DEFAULT) - actions: - Alnwick(1, 2): - - default_action: { allowed: true } - - handle: 0x2000014e - - next_table: 0 - - set HillTop.Stennett.Blairsden, _Ranier$salu..Nordland - - _Ranier$salu..Nordland(_Upalco, $hash_dist) - default_action: Alnwick - stateful _Ranier$salu..Nordland: - p4: { name: Nordland, size: 294912 } - row: 7 - column: [ 2, 3, 4, 5 ] - maprams: [ 2, 3, 4, 5 ] - format: { lo: 1 } - actions: - _Upalco: - - read_bit - - output alu_lo - set_bit_alu$0: - - set_bit - clr_bit_alu$0: - - clr_bit - hash_action _Osakis 8: - p4: { name: Osakis, size: 1, disable_atomic_modify : true } - row: 0 - bus: 0 - hash_dist: - 4: { hash: 6, mask: 0x7ffff, shift: 0, expand: 7 } - input_xbar: - exact group 5: { 64: eg_intr_md.egress_port, 80: HillTop.Wisdom.Bowden } - hash 11: - 16..27: stripe(HillTop.Wisdom.Bowden) - 28..31: stripe(eg_intr_md.egress_port(0..3)) - 39..41: stripe(eg_intr_md.egress_port(4..6)) - hash group 6: - table: [11] - seed: 0x0 - gateway: - name: _Osakis-gateway - row: 2 - bus: 0 - unit: 1 - 0x0: _Charters - miss: _Charters - condition: - expression: "true(always hit)" - true: _Charters - false: _Charters - next: [] - action_bus: { 2 : _Osakis$salu..Ontonagon(0..7) } - stateful: _Osakis$salu..Ontonagon(hash_dist 4, $DEFAULT, $DEFAULT) - instruction: _Osakis($DEFAULT, $DEFAULT) - actions: - Olivet(0, 3): - - default_action: { allowed: true } - - handle: 0x2000014d - - next_table: 0 - - set HillTop.Stennett.Standish, _Osakis$salu..Ontonagon - - _Osakis$salu..Ontonagon(_Ickesburg, $hash_dist) - default_action: Olivet - stateful _Osakis$salu..Ontonagon: - p4: { name: Ontonagon, size: 294912 } - row: 11 - column: [ 2, 3, 4, 5 ] - maprams: [ 2, 3, 4, 5 ] - format: { lo: 1 } - actions: - _Ickesburg: - - read_bitc - - output alu_lo - set_bit_alu$0: - - set_bit - clr_bit_alu$0: - - clr_bit - ternary_match _Charters 9: - p4: { name: Charters, size: 2048, disable_atomic_modify : true } - p4_param_order: - HillTop.McGonigle.Buncombe: { type: ternary, size: 8, full_size: 8, key_name: "McGonigle.Buncombe" } - Millston.GlenAvon.Kaluaaha: { type: ternary, size: 32, full_size: 32, key_name: "GlenAvon.Kaluaaha" } - Millston.GlenAvon.Calcasieu: { type: ternary, size: 32, full_size: 32, key_name: "GlenAvon.Calcasieu" } - Millston.GlenAvon.Ocoee: { type: ternary, size: 8, full_size: 8, key_name: "GlenAvon.Ocoee" } - Millston.Grays.Chevak: { type: ternary, size: 16, full_size: 16, key_name: "Grays.Chevak" } - Millston.Grays.Mendocino: { type: ternary, size: 16, full_size: 16, key_name: "Grays.Mendocino" } - Millston.Osyka.Noyes: { type: ternary, size: 8, full_size: 8, key_name: "Osyka.Noyes" } - HillTop.Bessie.Peebles: { type: ternary, size: 1, full_size: 1, key_name: "Bessie.Peebles" } - row: [ 6, 7, 8, 11, 10, 9, 0, 1, 2, 5, 4, 3 ] - bus: [ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 1 - - 1 - - 1 - - 1 - - 1 - - 1 - input_xbar: - ternary group 7: { 0: Millston.GlenAvon.Kaluaaha(24..31), 8: Millston.GlenAvon.Calcasieu(0..7), 16: Millston.GlenAvon.Kaluaaha(8..23), 32: Millston.GlenAvon.Calcasieu(24..31) } - ternary group 8: { 5: HillTop.Bessie.Peebles, 8: Millston.GlenAvon.Calcasieu(8..23), 24: Millston.Grays.Mendocino(8..15), 32: Millston.Grays.Mendocino(0..7) } - ternary group 9: { 0: Millston.Grays.Chevak, 16: HillTop.McGonigle.Buncombe, 24: Millston.GlenAvon.Ocoee, 32: Millston.Osyka.Noyes } - byte group 1: { 0: Millston.GlenAvon.Kaluaaha(0..7) } - match: - - { group: 7, byte_group: 1, byte_config: 0, dirtcam: 0x555 } - - { group: 8, byte_group: 1, byte_config: 1, dirtcam: 0x555 } - - { group: 9, byte_config: 3, dirtcam: 0x155 } - gateway: - name: cond-49 - input_xbar: - exact group 7: { 3: Millston.GlenAvon.$valid } - row: 3 - bus: 1 - unit: 0 - match: { 3: Millston.GlenAvon.$valid } - 0b****1: run_table - miss: _Keltys$st0 - condition: - expression: "(Millston.GlenAvon.$valid == 1)" - true: _Charters - false: _Keltys$st0 - hit: [ _Keltys$st0 ] - miss: _Keltys$st0 - indirect: _Charters$tind - counter _Charters$stats..Keller: - p4: { name: Keller } - row: 9 - column: [ 2, 3 ] - maprams: [ 2, 3 ] - count: packets - format: {packets(0): 64..127, packets(1): 0..63} - ternary_indirect _Charters$tind: - row: 2 - bus: 0 - column: 5 - input_xbar: - ternary group 7: { 0: Millston.GlenAvon.Kaluaaha(24..31), 8: Millston.GlenAvon.Calcasieu(0..7), 16: Millston.GlenAvon.Kaluaaha(8..23), 32: Millston.GlenAvon.Calcasieu(24..31) } - ternary group 8: { 5: HillTop.Bessie.Peebles, 8: Millston.GlenAvon.Calcasieu(8..23), 24: Millston.Grays.Mendocino(8..15), 32: Millston.Grays.Mendocino(0..7) } - ternary group 9: { 0: Millston.Grays.Chevak, 16: HillTop.McGonigle.Buncombe, 24: Millston.GlenAvon.Ocoee, 32: Millston.Osyka.Noyes } - byte group 1: { 0: Millston.GlenAvon.Kaluaaha(0..7) } - format: { action: 0..0 } - stats: _Charters$stats..Keller($DIRECT, $DEFAULT) - action: _Charters$action_data($DIRECT, $DEFAULT) - instruction: _Charters$tind(action, $DEFAULT) - actions: - Elysburg(1, 4): - - p4_param_order: { Cornell: 2 } - - default_action: { allowed: true } - - handle: 0x2000014b - - next_table: 0 - - { Cornell: $adf_b0(0..1) } - - set HillTop.Wisdom.DeGraff, Cornell - - _Charters$stats..Keller($DIRECT) - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x2000014c - - next_table: 0 - - { } - default_only_action: NoAction - action _Charters$action_data: - p4: { name: Charters$action } - row: 9 - column: 4 - vpns: [ 0 ] - home_row: - - 9 - format Elysburg: { $adf_b0: 0..7 } - action_bus: { 4 : $adf_b0 } -stage 9 egress: - ternary_match _Keltys$st0 9: - p4: { name: Keltys, size: 1024 } - p4_param_order: - HillTop.McGonigle.Buncombe: { type: ternary, size: 8, full_size: 8, key_name: "McGonigle.Buncombe" } - Millston.Maumee.Kaluaaha: { type: ternary, size: 128, full_size: 128, key_name: "Maumee.Kaluaaha" } - Millston.Maumee.Calcasieu: { type: ternary, size: 128, full_size: 128, key_name: "Maumee.Calcasieu" } - Millston.Maumee.Dassel: { type: ternary, size: 8, full_size: 8, key_name: "Maumee.Dassel" } - Millston.Grays.Chevak: { type: ternary, size: 16, full_size: 16, key_name: "Grays.Chevak" } - Millston.Grays.Mendocino: { type: ternary, size: 16, full_size: 16, key_name: "Grays.Mendocino" } - Millston.Osyka.Noyes: { type: ternary, size: 8, full_size: 8, key_name: "Osyka.Noyes" } - row: [ 0, 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - input_xbar: - ternary group 2: { 16: Millston.Osyka.Noyes } - ternary group 4: { 0: Millston.Maumee.Kaluaaha.0-31(16..23), 8: Millston.Maumee.Kaluaaha.32-63(24..31), 16: Millston.Maumee.Kaluaaha.32-63(0..23) } - ternary group 5: { 0: Millston.Maumee.Kaluaaha.64-95, 32: Millston.Maumee.Calcasieu.0-31(0..7) } - ternary group 7: { 0: Millston.Maumee.Calcasieu.0-31(24..31), 8: Millston.Maumee.Calcasieu.32-63(0..7), 16: Millston.Maumee.Calcasieu.0-31(8..23), 32: Millston.Maumee.Calcasieu.32-63(24..31) } - ternary group 8: { 0: Millston.Maumee.Kaluaaha.96-111, 16: Millston.Grays.Mendocino, 32: Millston.Grays.Chevak(0..7) } - ternary group 9: { 0: Millston.Maumee.Calcasieu.32-63(16..23), 8: Millston.Maumee.Calcasieu.64-95(24..31), 16: Millston.Maumee.Calcasieu.64-95(0..7), 24: Millston.Maumee.Calcasieu.32-63(8..15), 32: Millston.Maumee.Calcasieu.64-95(16..23) } - ternary group 10: { 0: Millston.Grays.Chevak(8..15), 8: Millston.Maumee.Kaluaaha.112-127, 24: HillTop.McGonigle.Buncombe, 32: Millston.Maumee.Dassel } - ternary group 11: { 0: Millston.Maumee.Calcasieu.64-95(8..15), 8: Millston.Maumee.Calcasieu.96-127(16..31), 24: Millston.Maumee.Calcasieu.96-127(0..15) } - byte group 1: { 0: Millston.Maumee.Kaluaaha.0-31(0..7) } - byte group 2: { 0: Millston.Maumee.Kaluaaha.0-31(24..31) } - byte group 4: { 0: Millston.Maumee.Kaluaaha.0-31(8..15) } - match: - - { group: 2, byte_group: 1, byte_config: 0, dirtcam: 0x410 } - - { group: 4, byte_group: 1, byte_config: 1, dirtcam: 0x555 } - - { group: 5, byte_group: 2, byte_config: 0, dirtcam: 0x555 } - - { group: 7, byte_group: 2, byte_config: 1, dirtcam: 0x555 } - - { group: 8, byte_group: 4, byte_config: 0, dirtcam: 0x555 } - - { group: 9, byte_group: 4, byte_config: 1, dirtcam: 0x555 } - - { group: 10, byte_config: 3, dirtcam: 0x155 } - - { group: 11, dirtcam: 0x155 } - gateway: - name: cond-48 - input_xbar: - exact group 3: { 105: Millston.Maumee.$valid } - row: 2 - bus: 1 - unit: 0 - match: { 1: Millston.Maumee.$valid } - 0b******1: run_table - miss: _Newsoms - condition: - expression: "(Millston.Maumee.$valid == 1)" - true: _Keltys$st0 - false: _Newsoms - hit: [ _Newsoms ] - miss: _Keltys$st1 - indirect: _Keltys$st0$tind - counter _Keltys$st0$stats..Kinter: - p4: { name: Kinter } - row: 13 - column: [ 0, 1 ] - maprams: [ 0, 1 ] - count: packets - format: {packets(0): 64..127, packets(1): 0..63} - ternary_indirect _Keltys$st0$tind: - row: 0 - bus: 0 - column: 5 - input_xbar: - ternary group 2: { 16: Millston.Osyka.Noyes } - ternary group 4: { 0: Millston.Maumee.Kaluaaha.0-31(16..23), 8: Millston.Maumee.Kaluaaha.32-63(24..31), 16: Millston.Maumee.Kaluaaha.32-63(0..23) } - ternary group 5: { 0: Millston.Maumee.Kaluaaha.64-95, 32: Millston.Maumee.Calcasieu.0-31(0..7) } - ternary group 7: { 0: Millston.Maumee.Calcasieu.0-31(24..31), 8: Millston.Maumee.Calcasieu.32-63(0..7), 16: Millston.Maumee.Calcasieu.0-31(8..23), 32: Millston.Maumee.Calcasieu.32-63(24..31) } - ternary group 8: { 0: Millston.Maumee.Kaluaaha.96-111, 16: Millston.Grays.Mendocino, 32: Millston.Grays.Chevak(0..7) } - ternary group 9: { 0: Millston.Maumee.Calcasieu.32-63(16..23), 8: Millston.Maumee.Calcasieu.64-95(24..31), 16: Millston.Maumee.Calcasieu.64-95(0..7), 24: Millston.Maumee.Calcasieu.32-63(8..15), 32: Millston.Maumee.Calcasieu.64-95(16..23) } - ternary group 10: { 0: Millston.Grays.Chevak(8..15), 8: Millston.Maumee.Kaluaaha.112-127, 24: HillTop.McGonigle.Buncombe, 32: Millston.Maumee.Dassel } - ternary group 11: { 0: Millston.Maumee.Calcasieu.64-95(8..15), 8: Millston.Maumee.Calcasieu.96-127(16..31), 24: Millston.Maumee.Calcasieu.96-127(0..15) } - byte group 1: { 0: Millston.Maumee.Kaluaaha.0-31(0..7) } - byte group 2: { 0: Millston.Maumee.Kaluaaha.0-31(24..31) } - byte group 4: { 0: Millston.Maumee.Kaluaaha.0-31(8..15) } - format: { action: 0..0 } - stats: _Keltys$st0$stats..Kinter($DIRECT, $DEFAULT) - action: _Keltys$st0$action_data($DIRECT, $DEFAULT) - instruction: _Keltys$st0$tind(action, $DEFAULT) - actions: - Elysburg(1, 1): - - p4_param_order: { Cornell: 2 } - - default_action: { allowed: true } - - handle: 0x20000149 - - next_table: 0 - - { Cornell: $adf_b0(0..1) } - - set HillTop.Wisdom.DeGraff, Cornell - - _Keltys$st0$stats..Kinter($DIRECT) - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x2000014a - - next_table: 0 - - { } - default_only_action: NoAction - action _Keltys$st0$action_data: - p4: { name: Keltys$action } - row: 5 - column: 1 - vpns: [ 0 ] - home_row: - - 5 - format Elysburg: { $adf_b0: 0..7 } - action_bus: { 2 : $adf_b0 } -stage 10 egress: - ternary_match _Keltys$st1 0: - p4: { name: Keltys, size: 1024 } - p4_param_order: - HillTop.McGonigle.Buncombe: { type: ternary, size: 8, full_size: 8, key_name: "McGonigle.Buncombe" } - Millston.Maumee.Kaluaaha: { type: ternary, size: 128, full_size: 128, key_name: "Maumee.Kaluaaha" } - Millston.Maumee.Calcasieu: { type: ternary, size: 128, full_size: 128, key_name: "Maumee.Calcasieu" } - Millston.Maumee.Dassel: { type: ternary, size: 8, full_size: 8, key_name: "Maumee.Dassel" } - Millston.Grays.Chevak: { type: ternary, size: 16, full_size: 16, key_name: "Grays.Chevak" } - Millston.Grays.Mendocino: { type: ternary, size: 16, full_size: 16, key_name: "Grays.Mendocino" } - Millston.Osyka.Noyes: { type: ternary, size: 8, full_size: 8, key_name: "Osyka.Noyes" } - row: [ 0, 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - indirect_bus: 2 - input_xbar: - ternary group 0: { 0: Millston.Maumee.Calcasieu.0-31, 32: Millston.Maumee.Calcasieu.32-63(0..7) } - ternary group 1: { 0: Millston.Maumee.Kaluaaha.0-31(16..31), 16: Millston.Maumee.Kaluaaha.32-63(0..23) } - ternary group 2: { 0: Millston.Maumee.Kaluaaha.32-63(24..31), 8: Millston.Maumee.Kaluaaha.64-95 } - ternary group 3: { 0: Millston.Maumee.Calcasieu.32-63(8..31), 24: Millston.Maumee.Calcasieu.64-95(0..15) } - ternary group 4: { 0: Millston.Maumee.Calcasieu.64-95(16..31), 16: Millston.Maumee.Calcasieu.96-127(0..23) } - ternary group 5: { 0: Millston.Maumee.Kaluaaha.96-111, 16: Millston.Grays.Mendocino(0..7), 24: Millston.Maumee.Calcasieu.96-127(24..31), 32: Millston.Grays.Chevak(0..7) } - ternary group 6: { 0: Millston.Grays.Mendocino(8..15), 8: Millston.Maumee.Kaluaaha.112-127(0..7), 16: Millston.Grays.Chevak(8..15), 24: HillTop.McGonigle.Buncombe, 32: Millston.Maumee.Kaluaaha.112-127(8..15) } - ternary group 7: { 0: Millston.Maumee.Dassel, 8: Millston.Osyka.Noyes } - byte group 0: { 0: Millston.Maumee.Kaluaaha.0-31(8..15) } - byte group 1: { 0: Millston.Maumee.Kaluaaha.0-31(0..7) } - match: - - { group: 0, byte_group: 0, byte_config: 0, dirtcam: 0x555 } - - { group: 1, byte_group: 0, byte_config: 1, dirtcam: 0x555 } - - { group: 2, byte_group: 1, byte_config: 0, dirtcam: 0x555 } - - { group: 3, byte_group: 1, byte_config: 1, dirtcam: 0x555 } - - { group: 4, byte_config: 3, dirtcam: 0x155 } - - { group: 5, dirtcam: 0x155 } - - { group: 6, dirtcam: 0x155 } - - { group: 7, dirtcam: 0x5 } - hit: [ _Newsoms ] - miss: _Newsoms - stats: _Keltys$st1$stats..Kinter($DIRECT, $DEFAULT) - action: _Keltys$st1$action_data($DIRECT, $DEFAULT) - instruction: _Keltys$st1($DEFAULT, $DEFAULT) - actions: - Elysburg(0, 1): - - p4_param_order: { Cornell: 2 } - - default_action: { allowed: true } - - handle: 0x20000149 - - next_table: 0 - - { Cornell: $adf_b0(0..1) } - - set HillTop.Wisdom.DeGraff, Cornell - - _Keltys$st1$stats..Kinter($DIRECT) - NoAction(-1, 0): - - default_only_action: { allowed: true } - - handle: 0x2000014a - - next_table: 0 - - { } - default_only_action: NoAction - counter _Keltys$st1$stats..Kinter: - p4: { name: Kinter } - row: 13 - column: [ 2, 3 ] - maprams: [ 2, 3 ] - count: packets - format: {packets(0): 64..127, packets(1): 0..63} - action _Keltys$st1$action_data: - p4: { name: Keltys$action } - row: 12 - column: 5 - vpns: [ 0 ] - home_row: - - 12 - format Elysburg: { $adf_b0: 0..7 } - action_bus: { 0 : $adf_b0 } -stage 11 egress: - ternary_match _Newsoms 9: - p4: { name: Newsoms, size: 512, disable_atomic_modify : true } - p4_param_order: - eg_intr_md.egress_port: { type: exact, size: 7, full_size: 9, key_name: "Sonoma.egress_port" } - HillTop.Stennett.Blairsden: { type: ternary, size: 1, full_size: 1, key_name: "Stennett.Blairsden" } - HillTop.Stennett.Standish: { type: ternary, size: 1, full_size: 1, key_name: "Stennett.Standish" } - HillTop.Edwards.SomesBar: { type: ternary, size: 1, full_size: 1, key_name: "Edwards.SomesBar" } - HillTop.Wisdom.DeGraff: { type: ternary, size: 2, full_size: 2, key_name: "Wisdom.DeGraff" } - row: 2 - bus: 1 - column: 1 - input_xbar: - ternary group 9: { 0: eg_intr_md.egress_port(0..6), 11: HillTop.Stennett.Blairsden, 20: HillTop.Stennett.Standish, 28: HillTop.Wisdom.DeGraff, 32: HillTop.Edwards.SomesBar } - match: - - { group: 9, dirtcam: 0x155 } - hit: [ _Astatula, _Hagewood_0 ] - miss: _Astatula - indirect: _Newsoms$tind - counter _Newsoms$stats.Corum: - p4: { name: Corum } - row: 5 - column: [ 0, 1 ] - maprams: [ 0, 1 ] - count: packets - format: {packets(0): 64..127, packets(1): 0..63} - ternary_indirect _Newsoms$tind: - row: 0 - bus: 0 - column: 2 - input_xbar: - ternary group 9: { 0: eg_intr_md.egress_port(0..6), 11: HillTop.Stennett.Blairsden, 20: HillTop.Stennett.Standish, 28: HillTop.Wisdom.DeGraff, 32: HillTop.Edwards.SomesBar } - format: { action: 0..0 } - stats: _Newsoms$stats.Corum($DIRECT, $DEFAULT) - instruction: _Newsoms$tind(action, $DEFAULT) - actions: - Nicollet(0, 1): - - default_action: { allowed: true } - - handle: 0x20000159 - - next_table: 0 - - set eg_intr_md_for_dprsr.drop_ctl, 7 - - _Newsoms$stats.Corum($DIRECT) - Fosston(1, 0): - - default_action: { allowed: true } - - handle: 0x2000015a - - next_table: 1 - - _Newsoms$stats.Corum($DIRECT) - default_action: Fosston - ternary_match _Hagewood_0 10: - p4: { name: Hagewood, size: 1, disable_atomic_modify : true } - gateway: - name: cond-51 - input_xbar: - exact group 1: { 40: HillTop.McCaskill.Grassflat(8..9), 48: HillTop.McCaskill.Grassflat(0..7), 58: HillTop.McCaskill.Tilton } - row: 6 - bus: 0 - unit: 0 - match: { 0: HillTop.McCaskill.Grassflat(0..7), 8: HillTop.McCaskill.Grassflat(8..9), 18: HillTop.McCaskill.Tilton } - 0b**************0000000000: _Astatula - 0b****00******************: run_table - miss: _Astatula - condition: - expression: "(HillTop.McCaskill.Grassflat != 0 && HillTop.McCaskill.Tilton == 0)" - true: _Hagewood_0 - false: _Astatula - hit: [ _Astatula ] - miss: _Astatula - indirect: _Hagewood_0$tind - ternary_indirect _Hagewood_0$tind: - row: 0 - bus: 1 - format: { action: 0..0 } - instruction: _Hagewood_0$tind(action, $DEFAULT) - actions: - Ozark(1, 2): - - default_action: { allowed: true } - - handle: 0x2000015b - - next_table: 0 - - set eg_intr_md_for_dprsr.mirror_type, 2 - - set HillTop.Plains.Miller, eg_intr_md.egress_port - default_action: Ozark - exact_match _Astatula 11: - p4: { name: Astatula, size: 128, disable_atomic_modify : true } - p4_param_order: - HillTop.Wisdom.Bowden: { type: exact, size: 12, full_size: 12, key_name: "Wisdom.Bowden" } - eg_intr_md.egress_port: { type: exact, size: 7, full_size: 9, key_name: "Sonoma.egress_port" } - HillTop.Wisdom.Weatherby: { type: exact, size: 1, full_size: 1, key_name: "Wisdom.Weatherby" } - row: 6 - bus: 0 - column: [ 2, 3 ] - stash: - row: [ 6 ] - col: [ 2 ] - unit: [ 0 ] - ways: - - [1, 2, 0x0, [6, 2]] - - [1, 3, 0x0, [6, 3]] - input_xbar: - exact group 1: { 64: eg_intr_md.egress_port(0..6), 72: HillTop.Wisdom.Bowden(8..11), 80: HillTop.Wisdom.Bowden(0..7), 93: HillTop.Wisdom.Weatherby } - hash 3: - 20..24: random(eg_intr_md.egress_port(5..6), HillTop.Wisdom.Bowden(0..7)) ^ eg_intr_md.egress_port(0..4) - 25..28: random(eg_intr_md.egress_port(5..6), HillTop.Wisdom.Bowden(0..7)) ^ HillTop.Wisdom.Bowden(8..11) - 29: random(eg_intr_md.egress_port(5..6), HillTop.Wisdom.Bowden(0..7)) ^ HillTop.Wisdom.Weatherby - 31..35: random(eg_intr_md.egress_port(5..6), HillTop.Wisdom.Bowden(0..7)) ^ eg_intr_md.egress_port(0..4) - 36..39: random(eg_intr_md.egress_port(5..6), HillTop.Wisdom.Bowden(0..7)) ^ HillTop.Wisdom.Bowden(8..11) - 30: random(eg_intr_md.egress_port(5..6), HillTop.Wisdom.Bowden(0..7)) ^ HillTop.Wisdom.Weatherby - hash group 1: - table: [3] - seed: 0xc2ae600000 - format: { action(0): 0..1, version(0): 112..115, match(0): [45..46, 32..39 ] } - match: [ eg_intr_md.egress_port(5..6), HillTop.Wisdom.Bowden(0..7) ] - gateway: - name: cond-52 - input_xbar: - exact group 2: { 1: HillTop.Wisdom.Westhoff, 8: HillTop.Wisdom.Stratford, 33: HillTop.Wisdom.Onycha } - row: 0 - bus: 1 - unit: 1 - match: { 16: HillTop.Wisdom.Stratford, 1: HillTop.Wisdom.Onycha, 9: HillTop.Wisdom.Westhoff } - 0b*******1***************: END - 0b********************010: END - 0b************011********: END - miss: run_table - condition: - expression: "(HillTop.Wisdom.Stratford == 0 && HillTop.Wisdom.Onycha != 2 && HillTop.Wisdom.Westhoff != 3)" - true: _Astatula - false: END - hit: [ END ] - miss: END - instruction: _Astatula(action, $DEFAULT) - actions: - Berlin(1, 0): - - default_action: { allowed: true } - - handle: 0x2000015c - - next_table: 0 - Ardsley(2, 3): - - default_action: { allowed: true } - - handle: 0x2000015d - - next_table: 0 - - set Millston.Wondervu$0.$valid, 1 - - set Millston.Wondervu$0.McCaulley, Millston.Calabash.McCaulley - - set Millston.Calabash.McCaulley, 33024 - - deposit-field H22(12..15), H20(4..7), H23 - default_action: Ardsley - -flexible_headers: [ - - { name: "Millston.Belgrade", - fields: [ - - { name: "Roachdale", slice: { start_bit: 0, bit_width: 8 } }, - { name: "Rugby", slice: { start_bit: 0, bit_width: 3 } }, - { name: "Davie", slice: { start_bit: 0, bit_width: 1 } }, - { name: "Cacao", slice: { start_bit: 0, bit_width: 4 } }, - { name: "Mankato", slice: { start_bit: 0, bit_width: 8 } }, - { name: "Virgil", slice: { start_bit: 0, bit_width: 24 } }, - { name: "Florin", slice: { start_bit: 0, bit_width: 24 } }, - { name: "Ronan", slice: { start_bit: 0, bit_width: 32 } }, - { name: "Corinth", slice: { start_bit: 0, bit_width: 16 } }, - { name: "__pad_0", slice: { start_bit: 0, bit_width: 4 } }, - { name: "Union", slice: { start_bit: 0, bit_width: 3 } }, - { name: "Rockport", slice: { start_bit: 0, bit_width: 1 } }, - { name: "__pad_1", slice: { start_bit: 0, bit_width: 25 } }, - { name: "Sudbury", slice: { start_bit: 0, bit_width: 6 } }, - { name: "Waipahu", slice: { start_bit: 0, bit_width: 1 } }, - { name: "Willard", slice: { start_bit: 0, bit_width: 3 } }, - { name: "Anacortes", slice: { start_bit: 0, bit_width: 1 } }, - { name: "Allgood", slice: { start_bit: 0, bit_width: 3 } }, - { name: "Shabbona", slice: { start_bit: 0, bit_width: 1 } }, - { name: "__pad_2", slice: { start_bit: 0, bit_width: 7 } }, - { name: "Freeburg", slice: { start_bit: 0, bit_width: 1 } }, - { name: "__pad_3", slice: { start_bit: 0, bit_width: 6 } }, - { name: "Selawik", slice: { start_bit: 0, bit_width: 2 } }, - { name: "__pad_4", slice: { start_bit: 0, bit_width: 10 } }, - { name: "Matheson", slice: { start_bit: 0, bit_width: 6 } }, - { name: "__pad_5", slice: { start_bit: 0, bit_width: 7 } }, - { name: "Chaska", slice: { start_bit: 0, bit_width: 9 } }, - { name: "__pad_6", slice: { start_bit: 0, bit_width: 4 } }, - { name: "Requa", slice: { start_bit: 0, bit_width: 12 } }, - { name: "__pad_7", slice: { start_bit: 0, bit_width: 4 } }, - { name: "Bayshore", slice: { start_bit: 0, bit_width: 12 } }, - { name: "__pad_8", slice: { start_bit: 0, bit_width: 4 } }, - { name: "Florien", slice: { start_bit: 0, bit_width: 12 } } ] - }, - { name: "HillTop.Plains", - fields: [ - - { name: "Roachdale", slice: { start_bit: 0, bit_width: 8 } }, - { name: "__pad_0", slice: { start_bit: 0, bit_width: 7 } }, - { name: "Miller", slice: { start_bit: 0, bit_width: 9 } } ] - }, - { name: "Plains_0", - fields: [ - - { name: "Roachdale", slice: { start_bit: 0, bit_width: 8 } }, - { name: "__pad_0", slice: { start_bit: 0, bit_width: 7 } }, - { name: "Miller", slice: { start_bit: 0, bit_width: 9 } } ] - }] - -primitives: "tcam_issue2.tofino/pipe//tcam_issue2.prim.json" -dynhash: "tcam_issue2.tofino/pipe//tcam_issue2.dynhash.json" diff --git a/backends/tofino/bf-asm/test/asm/p4c-4021.bfa b/backends/tofino/bf-asm/test/asm/p4c-4021.bfa deleted file mode 100644 index b3c4890c634..00000000000 --- a/backends/tofino/bf-asm/test/asm/p4c-4021.bfa +++ /dev/null @@ -1,2381 +0,0 @@ -version: - version: 1.0.1 - run_id: "1c65bbeecfecdbc9" - target: Tofino -phv ingress: - ig_intr_md.ingress_port: { stage 0..1: W1(16..24) } - ig_intr_md.ingress_mac_tstamp.0-31: { stage 0..1: W3 } - ig_intr_md.ingress_mac_tstamp.32-39: { stage 0..1: B5 } - ig_intr_md.ingress_mac_tstamp.40-47: { stage 0..1: W1(8..15) } - meta.mirror_session: H2(0..9) - meta.mac_timestamp: W2 - meta.pkt_type: B2 - hdr.bridge.rich_register: TB0 - hdr.bridge.pkt_type: TB9 - hdr.bridge.__pad_0: { stage 12: B3(4..7) } - hdr.bridge.rich_register_v: B3(3) - hdr.bridge.l23_rxtstmp_insert: B3(2) - hdr.bridge.l23_txtstmp_insert: B3(1) - hdr.bridge.l47_timestamp_insert: B3(0) - hdr.capture.seq_no: W0(8..31) - hdr.capture.reserved: W0(0..7) - hdr.capture.timestamp: TW0 - hdr.ethernet.dst_addr.0-31: TW9 - hdr.ethernet.dst_addr.32-47: TH20 - hdr.ethernet.src_addr.0-31: TW8 - hdr.ethernet.src_addr.32-47: TH19 - hdr.ethernet.ether_type: TH18 - hdr.vlan_tag.pcp: TW0(29..31) - hdr.vlan_tag.cfi: TW0(28) - hdr.vlan_tag.vid: TW0(16..27) - hdr.vlan_tag.ether_type: TW0(0..15) - hdr.ipv4.version: TW1(28..31) - hdr.ipv4.ihl: TW1(24..27) - hdr.ipv4.diffserv: TW1(16..23) - hdr.ipv4.total_len: TW1(0..15) - hdr.ipv4.identification: TH1 - hdr.ipv4.flags: TH0(13..15) - hdr.ipv4.frag_offset: TH0(0..12) - hdr.ipv4.ttl: TW3(24..31) - hdr.ipv4.protocol: TW3(16..23) - hdr.ipv4.hdr_checksum: TW3(0..15) - hdr.ipv4.src_addr: TW11 - hdr.ipv4.dst_addr: TW10 - hdr.tcp.src_port: TH5 - hdr.tcp.dst_port: TH4 - hdr.tcp.seq_no.0-15: TH14 - hdr.tcp.seq_no.16-31: TH15 - hdr.tcp.ack_no.0-15: TH12 - hdr.tcp.ack_no.16-31: TH13 - hdr.tcp.data_offset: TW2(28..31) - hdr.tcp.res: TW2(24..27) - hdr.tcp.flags: TW2(16..23) - hdr.tcp.window: TW2(0..15) - hdr.tcp.checksum: TH3 - hdr.tcp.urgent_ptr: TH2 - hdr.first_payload.signature_top: TW15 - hdr.first_payload.signature_bot: TW14 - hdr.first_payload.rx_timestamp: TW13 - hdr.first_payload.pgid: TW12 - hdr.first_payload.sequence.0-7: TB1 - hdr.first_payload.sequence.8-15: TB2 - hdr.first_payload.sequence.16-23: TB3 - hdr.first_payload.sequence.24-31: TB8 - hdr.first_payload.txtstamp.0-15: TH16 - hdr.first_payload.txtstamp.16-31: TH17 - hdr.udp.src_port: TH3 - hdr.udp.dst_port: TH2 - hdr.udp.hdr_length: TW2(16..31) - hdr.udp.checksum: TW2(0..15) - capture_port_1: { stage 1: W1(0..7) } - seq_no_0: { stage 1: H3 } - ig_intr_md_for_tm.ucast_egress_port: H0(0..8) - ig_intr_md_for_tm.mcast_grp_a: H1 - ig_intr_md_for_dprsr.drop_ctl: { stage 1..12: B1(0..2) } - ig_intr_md_for_dprsr.mirror_type: B0(0..2) - hdr.bridge.$valid: B4(0) - hdr.capture.$valid: B4(1) - hdr.ethernet.$valid: B4(2) - hdr.vlan_tag.$valid: B4(3) - hdr.ipv4.$valid: B4(4) - hdr.tcp.$valid: B4(5) - hdr.first_payload.$valid: B4(6) - hdr.udp.$valid: B4(7) -phv egress: - eg_intr_md_from_prsr.global_tstamp.0-31: { stage 0..10: W16 } - eg_intr_md_from_prsr.global_tstamp.32-47: { stage 0..10: TH33 } - eg_intr_md.egress_port: H24(0..8) - eg_intr_md.pkt_length: { stage 0..1: H16 } - meta.ing_port_mirror.pkt_type: { stage 0..10: B23 } - meta.ing_port_mirror.mac_timestamp: W17 - hdr.ethernet.dst_addr.0-31: TW16 - hdr.ethernet.dst_addr.32-47: TH32 - hdr.ethernet.src_addr.0-15: TH11 - hdr.ethernet.src_addr.16-23: TB6 - hdr.ethernet.src_addr.24-31: TB7 - hdr.ethernet.src_addr.32-47: TH31 - hdr.ethernet.ether_type: TH30 - meta.mirror_session: { stage 11..12: H16(0..9) } - meta.pkt_type: B17 - hdr.vlan_tag.pcp: TB4(5..7) - hdr.vlan_tag.cfi: TB4(4) - hdr.vlan_tag.vid.0-7: TB5 - hdr.vlan_tag.vid.8-11: TB4(0..3) - hdr.vlan_tag.ether_type: TH6 - hdr.ipv4.version: TW4(28..31) - hdr.ipv4.ihl: TW4(24..27) - hdr.ipv4.diffserv: TW4(16..23) - hdr.ipv4.total_len: TW4(0..15) - hdr.ipv4.identification: TW7(16..31) - hdr.ipv4.flags: TW7(13..15) - hdr.ipv4.frag_offset: TW7(0..12) - hdr.ipv4.ttl: TW6(24..31) - hdr.ipv4.protocol: TW6(16..23) - hdr.ipv4.hdr_checksum: TW6(0..15) - hdr.ipv4.src_addr: TW18 - hdr.ipv4.dst_addr: TW17 - hdr.tcp.src_port: TH10 - hdr.tcp.dst_port: TH9 - hdr.tcp.seq_no.0-15: TH24 - hdr.tcp.seq_no.16-31: TH25 - hdr.tcp.ack_no: TW19 - hdr.tcp.data_offset: TW5(28..31) - hdr.tcp.res: TW5(24..27) - hdr.tcp.flags: TW5(16..23) - hdr.tcp.window: TW5(0..15) - hdr.tcp.checksum: TH8 - hdr.tcp.urgent_ptr: TH7 - hdr.first_payload.signature_top: TW22 - hdr.first_payload.signature_bot: TW21 - hdr.first_payload.rx_timestamp: TW20 - hdr.first_payload.pgid.0-7: TB16 - hdr.first_payload.pgid.8-15: TB17 - hdr.first_payload.pgid.16-23: TB18 - hdr.first_payload.pgid.24-31: TB19 - hdr.first_payload.sequence.0-15: TH28 - hdr.first_payload.sequence.16-31: TH29 - hdr.first_payload.txtstamp.0-15: TH26 - hdr.first_payload.txtstamp.16-31: TH27 - hdr.udp.src_port: TH8 - hdr.udp.dst_port: TH7 - hdr.udp.hdr_length: TW5(16..31) - hdr.udp.checksum: TW5(0..15) - hdr.capture.seq_no.0-15: TH6 - hdr.capture.seq_no.16-23: TB4 - hdr.capture.reserved: B18 - hdr.capture.timestamp: W18 - update_register_portion: { stage 1: H17 } - update_register_capture_port: { stage 2..9: B20 } - update_register_padded_length: { stage 2..3: H16 } - update_register_negated_length: { stage 3: H18 } - update_register_load_length: { stage 3: H17 } - update_register_cap_length: { stage 0..4: H23 } - update_register_cap_length_0: { stage 0..5: H19 } - update_register_cap_length_1: { stage 0..6: H20 } - update_register_cap_length_2: { stage 0..7: H21 } - update_register_cap_length_3: { stage 0..8: H22 } - update_register_debt0: { stage 5..6: H16 } - update_register_debt1: { stage 6..7: H17 } - update_register_debt2: { stage 7..8: H16 } - update_register_debt3: { stage 8..9: H17 } - update_register_debt4: { stage 9: H16 } - update_register_reg0.0-3: { stage 0..7: B19(4..7) } - update_register_reg0.4-7: { stage 0..7: B21(4..7) } - update_register_reg1.0-3: { stage 8: B19(4..7) } - update_register_reg1.4-7: { stage 8: B21(4..7) } - update_register_reg2.0-3: { stage 9: B19(4..7) } - update_register_reg2.4-7: { stage 9: B21(4..7) } - rich_register_0.0-3: { stage 0..10: B19(0..3) } - rich_register_0.4-7: { stage 0..10: B21(0..3) } - eg_intr_md_for_dprsr.mirror_type: B16(0..2) - hdr.ethernet.$valid: B22(0) - hdr.vlan_tag.$valid: B22(1) - hdr.ipv4.$valid: B22(2) - hdr.tcp.$valid: B22(3) - hdr.first_payload.$valid: B22(4) - hdr.udp.$valid: B22(5) - hdr.capture.$valid: B22(6) -parser ingress: - start: $entry_point - init_zero: [ H2, W2, B2, TB0, B3, B4 ] - bitwise_or: [ TB9, B2, B4 ] - hdr_len_adj: 16 - states: - $entry_point: - *: - load: { byte1 : 12 } - buf_req: 13 - next: start - start: - match: [ byte1 ] - 0x*4: - 0..3: W1 - # - bit[7..15] -> W1 bit[24..16]: ingress::ig_intr_md.ingress_port - # - bit[16..23] -> W1 bit[15..8]: ingress::ig_intr_md.ingress_mac_tstamp[47:40].40-47 - 3: B5 # ingress::ig_intr_md.ingress_mac_tstamp[39:32].32-39 - 4..7: W3 # ingress::ig_intr_md.ingress_mac_tstamp[31:0].0-31 - B2: 1 # value 1 -> B2 bit[7..0]: ingress::meta.pkt_type - B4: 1 # value 1 -> B4 bit[0]: ingress::hdr.bridge.$valid - TB9: 1 # value 1 -> TB9 bit[7..0]: ingress::hdr.bridge.pkt_type - shift: 16 - buf_req: 16 - next: parse_capture_depth - 0x*5: - 0..3: W1 - # - bit[7..15] -> W1 bit[24..16]: ingress::ig_intr_md.ingress_port - # - bit[16..23] -> W1 bit[15..8]: ingress::ig_intr_md.ingress_mac_tstamp[47:40].40-47 - 3: B5 # ingress::ig_intr_md.ingress_mac_tstamp[39:32].32-39 - 4..7: W3 # ingress::ig_intr_md.ingress_mac_tstamp[31:0].0-31 - B2: 1 # value 1 -> B2 bit[7..0]: ingress::meta.pkt_type - B4: 1 # value 1 -> B4 bit[0]: ingress::hdr.bridge.$valid - TB9: 1 # value 1 -> TB9 bit[7..0]: ingress::hdr.bridge.pkt_type - shift: 16 - buf_req: 16 - next: parse_capture - 0x**: - 0..3: W1 - # - bit[7..15] -> W1 bit[24..16]: ingress::ig_intr_md.ingress_port - # - bit[16..23] -> W1 bit[15..8]: ingress::ig_intr_md.ingress_mac_tstamp[47:40].40-47 - 3: B5 # ingress::ig_intr_md.ingress_mac_tstamp[39:32].32-39 - 4..7: W3 # ingress::ig_intr_md.ingress_mac_tstamp[31:0].0-31 - B2: 1 # value 1 -> B2 bit[7..0]: ingress::meta.pkt_type - B4: 1 # value 1 -> B4 bit[0]: ingress::hdr.bridge.$valid - TB9: 1 # value 1 -> TB9 bit[7..0]: ingress::hdr.bridge.pkt_type - load: { half : 28..29 } - shift: 16 - buf_req: 30 - next: parse_ethernet - parse_capture_depth: - *: - 0..3: W0 - # - bit[0..23] -> W0 bit[31..8]: ingress::hdr.capture.seq_no - # - bit[24..31] -> W0 bit[7..0]: ingress::hdr.capture.reserved - 4..7: TW0 # ingress::hdr.capture.timestamp - B4: 2 # value 1 -> B4 bit[1]: ingress::hdr.capture.$valid - shift: 8 - buf_req: 8 - next: end - parse_capture: - *: - 0..3: W0 - # - bit[0..23] -> W0 bit[31..8]: ingress::hdr.capture.seq_no - # - bit[24..31] -> W0 bit[7..0]: ingress::hdr.capture.reserved - 4..7: TW0 # ingress::hdr.capture.timestamp - B4: 2 # value 1 -> B4 bit[1]: ingress::hdr.capture.$valid - B2: 3 # value 3 -> B2 bit[7..0]: ingress::meta.pkt_type - TB9: 5 # value 5 -> TB9 bit[7..0]: ingress::hdr.bridge.pkt_type - shift: 8 - buf_req: 8 - next: end - parse_ethernet: - match: [ half ] - 0x8100: - 0..1: TH20 # ingress::hdr.ethernet.dst_addr[47:32].32-47 - 2..5: TW9 # ingress::hdr.ethernet.dst_addr[31:0].0-31 - 6..7: TH19 # ingress::hdr.ethernet.src_addr[47:32].32-47 - 8..11: TW8 # ingress::hdr.ethernet.src_addr[31:0].0-31 - 12..13: TH18 # ingress::hdr.ethernet.ether_type - B4: 4 # value 1 -> B4 bit[2]: ingress::hdr.ethernet.$valid - load: { half : 16..17 } - shift: 14 - buf_req: 18 - next: parse_vlan_tag - 0x0800: - 0..1: TH20 # ingress::hdr.ethernet.dst_addr[47:32].32-47 - 2..5: TW9 # ingress::hdr.ethernet.dst_addr[31:0].0-31 - 6..7: TH19 # ingress::hdr.ethernet.src_addr[47:32].32-47 - 8..11: TW8 # ingress::hdr.ethernet.src_addr[31:0].0-31 - 12..13: TH18 # ingress::hdr.ethernet.ether_type - B4: 4 # value 1 -> B4 bit[2]: ingress::hdr.ethernet.$valid - load: { byte1 : 23 } - shift: 14 - buf_req: 24 - next: parse_ipv4 - 0x****: - 0..1: TH20 # ingress::hdr.ethernet.dst_addr[47:32].32-47 - 2..5: TW9 # ingress::hdr.ethernet.dst_addr[31:0].0-31 - 6..7: TH19 # ingress::hdr.ethernet.src_addr[47:32].32-47 - 8..11: TW8 # ingress::hdr.ethernet.src_addr[31:0].0-31 - 12..13: TH18 # ingress::hdr.ethernet.ether_type - B4: 4 # value 1 -> B4 bit[2]: ingress::hdr.ethernet.$valid - shift: 14 - buf_req: 14 - next: end - parse_vlan_tag: - match: [ half ] - 0x0800: - 0..3: TW0 - # - bit[0..2] -> TW0 bit[31..29]: ingress::hdr.vlan_tag.pcp - # - bit[3] -> TW0 bit[28]: ingress::hdr.vlan_tag.cfi - # - bit[4..15] -> TW0 bit[27..16]: ingress::hdr.vlan_tag.vid - # - bit[16..31] -> TW0 bit[15..0]: ingress::hdr.vlan_tag.ether_type - B4: 8 # value 1 -> B4 bit[3]: ingress::hdr.vlan_tag.$valid - load: { byte1 : 13 } - shift: 4 - buf_req: 14 - next: parse_ipv4 - 0x****: - 0..3: TW0 - # - bit[0..2] -> TW0 bit[31..29]: ingress::hdr.vlan_tag.pcp - # - bit[3] -> TW0 bit[28]: ingress::hdr.vlan_tag.cfi - # - bit[4..15] -> TW0 bit[27..16]: ingress::hdr.vlan_tag.vid - # - bit[16..31] -> TW0 bit[15..0]: ingress::hdr.vlan_tag.ether_type - B4: 8 # value 1 -> B4 bit[3]: ingress::hdr.vlan_tag.$valid - shift: 4 - buf_req: 4 - next: end - parse_ipv4: - match: [ byte1 ] - 0x06: - 0..3: TW1 - # - bit[0..3] -> TW1 bit[31..28]: ingress::hdr.ipv4.version - # - bit[4..7] -> TW1 bit[27..24]: ingress::hdr.ipv4.ihl - # - bit[8..15] -> TW1 bit[23..16]: ingress::hdr.ipv4.diffserv - # - bit[16..31] -> TW1 bit[15..0]: ingress::hdr.ipv4.total_len - 4..5: TH1 # ingress::hdr.ipv4.identification - 6..7: TH0 - # - bit[48..50] -> TH0 bit[15..13]: ingress::hdr.ipv4.flags - # - bit[51..63] -> TH0 bit[12..0]: ingress::hdr.ipv4.frag_offset - 8..11: TW3 - # - bit[64..71] -> TW3 bit[31..24]: ingress::hdr.ipv4.ttl - # - bit[72..79] -> TW3 bit[23..16]: ingress::hdr.ipv4.protocol - # - bit[80..95] -> TW3 bit[15..0]: ingress::hdr.ipv4.hdr_checksum - 12..15: TW11 # ingress::hdr.ipv4.src_addr - 16..19: TW10 # ingress::hdr.ipv4.dst_addr - B4: 16 # value 1 -> B4 bit[4]: ingress::hdr.ipv4.$valid - shift: 20 - buf_req: 20 - next: parseTcp - 0x11: - 0..3: TW1 - # - bit[0..3] -> TW1 bit[31..28]: ingress::hdr.ipv4.version - # - bit[4..7] -> TW1 bit[27..24]: ingress::hdr.ipv4.ihl - # - bit[8..15] -> TW1 bit[23..16]: ingress::hdr.ipv4.diffserv - # - bit[16..31] -> TW1 bit[15..0]: ingress::hdr.ipv4.total_len - 4..5: TH1 # ingress::hdr.ipv4.identification - 6..7: TH0 - # - bit[48..50] -> TH0 bit[15..13]: ingress::hdr.ipv4.flags - # - bit[51..63] -> TH0 bit[12..0]: ingress::hdr.ipv4.frag_offset - 8..11: TW3 - # - bit[64..71] -> TW3 bit[31..24]: ingress::hdr.ipv4.ttl - # - bit[72..79] -> TW3 bit[23..16]: ingress::hdr.ipv4.protocol - # - bit[80..95] -> TW3 bit[15..0]: ingress::hdr.ipv4.hdr_checksum - 12..15: TW11 # ingress::hdr.ipv4.src_addr - 16..19: TW10 # ingress::hdr.ipv4.dst_addr - B4: 16 # value 1 -> B4 bit[4]: ingress::hdr.ipv4.$valid - shift: 20 - buf_req: 20 - next: parseUdp - 0x**: - 0..3: TW1 - # - bit[0..3] -> TW1 bit[31..28]: ingress::hdr.ipv4.version - # - bit[4..7] -> TW1 bit[27..24]: ingress::hdr.ipv4.ihl - # - bit[8..15] -> TW1 bit[23..16]: ingress::hdr.ipv4.diffserv - # - bit[16..31] -> TW1 bit[15..0]: ingress::hdr.ipv4.total_len - 4..5: TH1 # ingress::hdr.ipv4.identification - 6..7: TH0 - # - bit[48..50] -> TH0 bit[15..13]: ingress::hdr.ipv4.flags - # - bit[51..63] -> TH0 bit[12..0]: ingress::hdr.ipv4.frag_offset - 8..11: TW3 - # - bit[64..71] -> TW3 bit[31..24]: ingress::hdr.ipv4.ttl - # - bit[72..79] -> TW3 bit[23..16]: ingress::hdr.ipv4.protocol - # - bit[80..95] -> TW3 bit[15..0]: ingress::hdr.ipv4.hdr_checksum - 12..15: TW11 # ingress::hdr.ipv4.src_addr - 16..19: TW10 # ingress::hdr.ipv4.dst_addr - B4: 16 # value 1 -> B4 bit[4]: ingress::hdr.ipv4.$valid - shift: 20 - buf_req: 20 - next: parseL23 - parseTcp: - *: - 0..1: TH5 # ingress::hdr.tcp.src_port - 2..3: TH4 # ingress::hdr.tcp.dst_port - 4..5: TH15 # ingress::hdr.tcp.seq_no[31:16].16-31 - 6..7: TH14 # ingress::hdr.tcp.seq_no[15:0].0-15 - 12..15: TW2 - # - bit[96..99] -> TW2 bit[31..28]: ingress::hdr.tcp.data_offset - # - bit[100..103] -> TW2 bit[27..24]: ingress::hdr.tcp.res - # - bit[104..111] -> TW2 bit[23..16]: ingress::hdr.tcp.flags - # - bit[112..127] -> TW2 bit[15..0]: ingress::hdr.tcp.window - 20..23: TW15 # ingress::hdr.first_payload.signature_top - 24..27: TW14 # ingress::hdr.first_payload.signature_bot - 28..31: TW13 # ingress::hdr.first_payload.rx_timestamp - B4: 96 - # - value 1 -> B4 bit[5]: ingress::hdr.tcp.$valid - # - value 1 -> B4 bit[6]: ingress::hdr.first_payload.$valid - shift: 8 - buf_req: 32 - next: parseTcp.$split_0 - parseTcp.$split_0: - *: - 0..1: TH13 # ingress::hdr.tcp.ack_no[31:16].16-31 - 2..3: TH12 # ingress::hdr.tcp.ack_no[15:0].0-15 - 8..9: TH3 # ingress::hdr.tcp.checksum - 10..11: TH2 # ingress::hdr.tcp.urgent_ptr - 24..27: TW12 # ingress::hdr.first_payload.pgid - 28: TB8 # ingress::hdr.first_payload.sequence[31:24].24-31 - 29: TB3 # ingress::hdr.first_payload.sequence[23:16].16-23 - 30: TB2 # ingress::hdr.first_payload.sequence[15:8].8-15 - 31: TB1 # ingress::hdr.first_payload.sequence[7:0].0-7 - shift: 32 - buf_req: 32 - next: parseTcp.$split_1 - parseTcp.$split_1: - *: - 0..1: TH17 # ingress::hdr.first_payload.txtstamp[31:16].16-31 - 2..3: TH16 # ingress::hdr.first_payload.txtstamp[15:0].0-15 - shift: 4 - buf_req: 4 - next: end - parseUdp: - *: - 0..1: TH3 # ingress::hdr.udp.src_port - 2..3: TH2 # ingress::hdr.udp.dst_port - 4..7: TW2 - # - bit[32..47] -> TW2 bit[31..16]: ingress::hdr.udp.hdr_length - # - bit[48..63] -> TW2 bit[15..0]: ingress::hdr.udp.checksum - 8..11: TW15 # ingress::hdr.first_payload.signature_top - 12..15: TW14 # ingress::hdr.first_payload.signature_bot - 16..19: TW13 # ingress::hdr.first_payload.rx_timestamp - 24: TB8 # ingress::hdr.first_payload.sequence[31:24].24-31 - 25: TB3 # ingress::hdr.first_payload.sequence[23:16].16-23 - 26: TB2 # ingress::hdr.first_payload.sequence[15:8].8-15 - 27: TB1 # ingress::hdr.first_payload.sequence[7:0].0-7 - 28..29: TH17 # ingress::hdr.first_payload.txtstamp[31:16].16-31 - 30..31: TH16 # ingress::hdr.first_payload.txtstamp[15:0].0-15 - shift: 20 - buf_req: 32 - next: parseUdp.$split_0 - parseUdp.$split_0: - *: - 0..3: TW12 # ingress::hdr.first_payload.pgid - B4: 192 - # - value 1 -> B4 bit[7]: ingress::hdr.udp.$valid - # - value 1 -> B4 bit[6]: ingress::hdr.first_payload.$valid - shift: 12 - buf_req: 12 - next: end - parseL23: - *: - 0..3: TW15 # ingress::hdr.first_payload.signature_top - 4..7: TW14 # ingress::hdr.first_payload.signature_bot - 8..11: TW13 # ingress::hdr.first_payload.rx_timestamp - 12..15: TW12 # ingress::hdr.first_payload.pgid - 16: TB8 # ingress::hdr.first_payload.sequence[31:24].24-31 - 17: TB3 # ingress::hdr.first_payload.sequence[23:16].16-23 - 18: TB2 # ingress::hdr.first_payload.sequence[15:8].8-15 - 19: TB1 # ingress::hdr.first_payload.sequence[7:0].0-7 - 20..21: TH17 # ingress::hdr.first_payload.txtstamp[31:16].16-31 - 22..23: TH16 # ingress::hdr.first_payload.txtstamp[15:0].0-15 - shift: 24 - buf_req: 24 - next: parseL23.$split_0 - parseL23.$split_0: - *: - B4: 64 # value 1 -> B4 bit[6]: ingress::hdr.first_payload.$valid - buf_req: 0 - next: end -deparser ingress: - dictionary: - TB0: B4(0) # ingress::hdr.bridge.rich_register if ingress::hdr.bridge.$valid - TB9: B4(0) # ingress::hdr.bridge.pkt_type if ingress::hdr.bridge.$valid - B3: B4(0) - # - bit[7..4]: ingress::hdr.bridge.__pad_0 if ingress::hdr.bridge.$valid - # - bit[3]: ingress::hdr.bridge.rich_register_v if ingress::hdr.bridge.$valid - # - bit[2]: ingress::hdr.bridge.l23_rxtstmp_insert if ingress::hdr.bridge.$valid - # - bit[1]: ingress::hdr.bridge.l23_txtstmp_insert if ingress::hdr.bridge.$valid - # - bit[0]: ingress::hdr.bridge.l47_timestamp_insert if ingress::hdr.bridge.$valid - W0: B4(1) - # - bit[31..8]: ingress::hdr.capture.seq_no if ingress::hdr.capture.$valid - # - bit[7..0]: ingress::hdr.capture.reserved if ingress::hdr.capture.$valid - TW0: B4(1) # ingress::hdr.capture.timestamp if ingress::hdr.capture.$valid - TH20: B4(2) # ingress::hdr.ethernet.dst_addr.32-47 if ingress::hdr.ethernet.$valid - TW9: B4(2) # ingress::hdr.ethernet.dst_addr.0-31 if ingress::hdr.ethernet.$valid - TH19: B4(2) # ingress::hdr.ethernet.src_addr.32-47 if ingress::hdr.ethernet.$valid - TW8: B4(2) # ingress::hdr.ethernet.src_addr.0-31 if ingress::hdr.ethernet.$valid - TH18: B4(2) # ingress::hdr.ethernet.ether_type if ingress::hdr.ethernet.$valid - TW0: B4(3) - # - bit[31..29]: ingress::hdr.vlan_tag.pcp if ingress::hdr.vlan_tag.$valid - # - bit[28]: ingress::hdr.vlan_tag.cfi if ingress::hdr.vlan_tag.$valid - # - bit[27..16]: ingress::hdr.vlan_tag.vid if ingress::hdr.vlan_tag.$valid - # - bit[15..0]: ingress::hdr.vlan_tag.ether_type if ingress::hdr.vlan_tag.$valid - TW1: B4(4) - # - bit[31..28]: ingress::hdr.ipv4.version if ingress::hdr.ipv4.$valid - # - bit[27..24]: ingress::hdr.ipv4.ihl if ingress::hdr.ipv4.$valid - # - bit[23..16]: ingress::hdr.ipv4.diffserv if ingress::hdr.ipv4.$valid - # - bit[15..0]: ingress::hdr.ipv4.total_len if ingress::hdr.ipv4.$valid - TH1: B4(4) # ingress::hdr.ipv4.identification if ingress::hdr.ipv4.$valid - TH0: B4(4) - # - bit[15..13]: ingress::hdr.ipv4.flags if ingress::hdr.ipv4.$valid - # - bit[12..0]: ingress::hdr.ipv4.frag_offset if ingress::hdr.ipv4.$valid - TW3: B4(4) - # - bit[31..24]: ingress::hdr.ipv4.ttl if ingress::hdr.ipv4.$valid - # - bit[23..16]: ingress::hdr.ipv4.protocol if ingress::hdr.ipv4.$valid - # - bit[15..0]: ingress::hdr.ipv4.hdr_checksum if ingress::hdr.ipv4.$valid - TW11: B4(4) # ingress::hdr.ipv4.src_addr if ingress::hdr.ipv4.$valid - TW10: B4(4) # ingress::hdr.ipv4.dst_addr if ingress::hdr.ipv4.$valid - TH5: B4(5) # ingress::hdr.tcp.src_port if ingress::hdr.tcp.$valid - TH4: B4(5) # ingress::hdr.tcp.dst_port if ingress::hdr.tcp.$valid - TH15: B4(5) # ingress::hdr.tcp.seq_no.16-31 if ingress::hdr.tcp.$valid - TH14: B4(5) # ingress::hdr.tcp.seq_no.0-15 if ingress::hdr.tcp.$valid - TH13: B4(5) # ingress::hdr.tcp.ack_no.16-31 if ingress::hdr.tcp.$valid - TH12: B4(5) # ingress::hdr.tcp.ack_no.0-15 if ingress::hdr.tcp.$valid - TW2: B4(5) - # - bit[31..28]: ingress::hdr.tcp.data_offset if ingress::hdr.tcp.$valid - # - bit[27..24]: ingress::hdr.tcp.res if ingress::hdr.tcp.$valid - # - bit[23..16]: ingress::hdr.tcp.flags if ingress::hdr.tcp.$valid - # - bit[15..0]: ingress::hdr.tcp.window if ingress::hdr.tcp.$valid - TH3: B4(5) # ingress::hdr.tcp.checksum if ingress::hdr.tcp.$valid - TH2: B4(5) # ingress::hdr.tcp.urgent_ptr if ingress::hdr.tcp.$valid - TH3: B4(7) # ingress::hdr.udp.src_port if ingress::hdr.udp.$valid - TH2: B4(7) # ingress::hdr.udp.dst_port if ingress::hdr.udp.$valid - TW2: B4(7) - # - bit[31..16]: ingress::hdr.udp.hdr_length if ingress::hdr.udp.$valid - # - bit[15..0]: ingress::hdr.udp.checksum if ingress::hdr.udp.$valid - TW15: B4(6) # ingress::hdr.first_payload.signature_top if ingress::hdr.first_payload.$valid - TW14: B4(6) # ingress::hdr.first_payload.signature_bot if ingress::hdr.first_payload.$valid - TW13: B4(6) # ingress::hdr.first_payload.rx_timestamp if ingress::hdr.first_payload.$valid - TW12: B4(6) # ingress::hdr.first_payload.pgid if ingress::hdr.first_payload.$valid - TB8: B4(6) # ingress::hdr.first_payload.sequence.24-31 if ingress::hdr.first_payload.$valid - TB3: B4(6) # ingress::hdr.first_payload.sequence.16-23 if ingress::hdr.first_payload.$valid - TB2: B4(6) # ingress::hdr.first_payload.sequence.8-15 if ingress::hdr.first_payload.$valid - TB1: B4(6) # ingress::hdr.first_payload.sequence.0-7 if ingress::hdr.first_payload.$valid - TH17: B4(6) # ingress::hdr.first_payload.txtstamp.16-31 if ingress::hdr.first_payload.$valid - TH16: B4(6) # ingress::hdr.first_payload.txtstamp.0-15 if ingress::hdr.first_payload.$valid - egress_unicast_port: H0(0..8) # bit[8..0]: ingress::ig_intr_md_for_tm.ucast_egress_port - drop_ctl: B1(0..2) # bit[2..0]: ingress::ig_intr_md_for_dprsr.drop_ctl - egress_multicast_group_0: - - H1 # ingress::ig_intr_md_for_tm.mcast_grp_a - mirror: - select: B0(0..2) # bit[2..0]: ingress::ig_intr_md_for_dprsr.mirror_type - 1: - - H2(0..9) # bit[9..0]: ingress::meta.mirror_session - - B2 # ingress::meta.pkt_type - - W2 # ingress::meta.mac_timestamp -parser egress: - start: $entry_point - init_zero: [ W16, TH33, B17, H23, H19, H20, H21, H22, B19, B21, B22 ] - bitwise_or: [ B22 ] - hdr_len_adj: 27 - meta_opt: 8191 - states: - $entry_point: - *: - 56..59: W16 # buffer mapped I/O: bit[448..479] -> W16 bit[31..0]: egress::eg_intr_md_from_prsr.global_tstamp[31:0].0-31 - 54..55: TH33 # buffer mapped I/O: bit[432..447] -> TH33 bit[15..0]: egress::eg_intr_md_from_prsr.global_tstamp[47:32].32-47 - intr_md: 48 - load: { byte1 : 27 } - buf_req: 28 - next: start - start: - match: [ byte1 ] - 0x02: - 0..1: H24 # bit[7..15] -> H24 bit[8..0]: egress::eg_intr_md.egress_port - 25..26: H16 # egress::eg_intr_md.pkt_length - intr_md: 25 - shift: 27 - buf_req: 27 - next: parse_mirror - 0x01: - 0..1: H24 # bit[7..15] -> H24 bit[8..0]: egress::eg_intr_md.egress_port - 25..26: H16 # egress::eg_intr_md.pkt_length - intr_md: 25 - shift: 27 - buf_req: 27 - next: parse_bridge - 0x03: - 0..1: H24 # bit[7..15] -> H24 bit[8..0]: egress::eg_intr_md.egress_port - 25..26: H16 # egress::eg_intr_md.pkt_length - intr_md: 25 - shift: 27 - buf_req: 27 - next: parse_capture - 0x05: - 0..1: H24 # bit[7..15] -> H24 bit[8..0]: egress::eg_intr_md.egress_port - 25..26: H16 # egress::eg_intr_md.pkt_length - intr_md: 25 - shift: 27 - buf_req: 27 - next: parse_capture_final - 0x**: - 0..1: H24 # bit[7..15] -> H24 bit[8..0]: egress::eg_intr_md.egress_port - 25..26: H16 # egress::eg_intr_md.pkt_length - intr_md: 25 - shift: 27 - buf_req: 27 - next: end - parse_mirror: - *: - 0: B23 # egress::meta.ing_port_mirror.pkt_type - 1..4: W17 # egress::meta.ing_port_mirror.mac_timestamp - 5..6: TH32 # egress::hdr.ethernet.dst_addr[47:32].32-47 - 7..10: TW16 # egress::hdr.ethernet.dst_addr[31:0].0-31 - 11..12: TH31 # egress::hdr.ethernet.src_addr[47:32].32-47 - 13: TB7 # egress::hdr.ethernet.src_addr[31:24].24-31 - 14: TB6 # egress::hdr.ethernet.src_addr[23:16].16-23 - 15..16: TH11 # egress::hdr.ethernet.src_addr[15:0].0-15 - 17..18: TH30 # egress::hdr.ethernet.ether_type - B22: 1 # value 1 -> B22 bit[0]: egress::hdr.ethernet.$valid - load: { half : 17..18 } - shift: 19 - buf_req: 19 - next: parse_mirror.$split_0 - parse_mirror.$split_0: - match: [ half ] - 0x8100: - B17: 1 # value 1 -> B17 bit[7..0]: egress::meta.pkt_type - load: { half : 2..3 } - buf_req: 4 - next: parse_vlan_tag - 0x0800: - B17: 1 # value 1 -> B17 bit[7..0]: egress::meta.pkt_type - buf_req: 0 - next: parse_ipv4 - 0x****: - B17: 1 # value 1 -> B17 bit[7..0]: egress::meta.pkt_type - buf_req: 0 - next: end - parse_vlan_tag: - match: [ half ] - 0x0800: - 0: TB4 - # - bit[0..2] -> TB4 bit[7..5]: egress::hdr.vlan_tag.pcp - # - bit[3] -> TB4 bit[4]: egress::hdr.vlan_tag.cfi - # - bit[4..7] -> TB4 bit[3..0]: egress::hdr.vlan_tag.vid[11:8].8-11 - 1: TB5 # egress::hdr.vlan_tag.vid[7:0].0-7 - 2..3: TH6 # egress::hdr.vlan_tag.ether_type - B22: 2 # value 1 -> B22 bit[1]: egress::hdr.vlan_tag.$valid - shift: 4 - buf_req: 4 - next: parse_ipv4 - 0x****: - 0: TB4 - # - bit[0..2] -> TB4 bit[7..5]: egress::hdr.vlan_tag.pcp - # - bit[3] -> TB4 bit[4]: egress::hdr.vlan_tag.cfi - # - bit[4..7] -> TB4 bit[3..0]: egress::hdr.vlan_tag.vid[11:8].8-11 - 1: TB5 # egress::hdr.vlan_tag.vid[7:0].0-7 - 2..3: TH6 # egress::hdr.vlan_tag.ether_type - B22: 2 # value 1 -> B22 bit[1]: egress::hdr.vlan_tag.$valid - shift: 4 - buf_req: 4 - next: end - parse_ipv4: - *: - 0..3: TW4 - # - bit[0..3] -> TW4 bit[31..28]: egress::hdr.ipv4.version - # - bit[4..7] -> TW4 bit[27..24]: egress::hdr.ipv4.ihl - # - bit[8..15] -> TW4 bit[23..16]: egress::hdr.ipv4.diffserv - # - bit[16..31] -> TW4 bit[15..0]: egress::hdr.ipv4.total_len - 4..7: TW7 - # - bit[32..47] -> TW7 bit[31..16]: egress::hdr.ipv4.identification - # - bit[48..50] -> TW7 bit[15..13]: egress::hdr.ipv4.flags - # - bit[51..63] -> TW7 bit[12..0]: egress::hdr.ipv4.frag_offset - 8..11: TW6 - # - bit[64..71] -> TW6 bit[31..24]: egress::hdr.ipv4.ttl - # - bit[72..79] -> TW6 bit[23..16]: egress::hdr.ipv4.protocol - # - bit[80..95] -> TW6 bit[15..0]: egress::hdr.ipv4.hdr_checksum - 12..15: TW18 # egress::hdr.ipv4.src_addr - B22: 4 # value 1 -> B22 bit[2]: egress::hdr.ipv4.$valid - load: { byte1 : 9 } - shift: 16 - buf_req: 16 - next: parse_ipv4.$split_0 - parse_ipv4.$split_0: - match: [ byte1 ] - 0x06: - 0..3: TW17 # egress::hdr.ipv4.dst_addr - shift: 4 - buf_req: 4 - next: parseTcp - 0x11: - 0..3: TW17 # egress::hdr.ipv4.dst_addr - shift: 4 - buf_req: 4 - next: parseUdp - 0x**: - 0..3: TW17 # egress::hdr.ipv4.dst_addr - shift: 4 - buf_req: 4 - next: parseL23 - parseTcp: - *: - 0..1: TH10 # egress::hdr.tcp.src_port - 2..3: TH9 # egress::hdr.tcp.dst_port - 4..5: TH25 # egress::hdr.tcp.seq_no[31:16].16-31 - 6..7: TH24 # egress::hdr.tcp.seq_no[15:0].0-15 - 8..11: TW19 # egress::hdr.tcp.ack_no - 12..15: TW5 - # - bit[96..99] -> TW5 bit[31..28]: egress::hdr.tcp.data_offset - # - bit[100..103] -> TW5 bit[27..24]: egress::hdr.tcp.res - # - bit[104..111] -> TW5 bit[23..16]: egress::hdr.tcp.flags - # - bit[112..127] -> TW5 bit[15..0]: egress::hdr.tcp.window - 20..23: TW22 # egress::hdr.first_payload.signature_top - 24..27: TW21 # egress::hdr.first_payload.signature_bot - B22: 24 - # - value 1 -> B22 bit[3]: egress::hdr.tcp.$valid - # - value 1 -> B22 bit[4]: egress::hdr.first_payload.$valid - shift: 16 - buf_req: 28 - next: parseTcp.$split_0 - parseTcp.$split_0: - *: - 0..1: TH8 # egress::hdr.tcp.checksum - 2..3: TH7 # egress::hdr.tcp.urgent_ptr - 12..15: TW20 # egress::hdr.first_payload.rx_timestamp - 16: TB19 # egress::hdr.first_payload.pgid[31:24].24-31 - 17: TB18 # egress::hdr.first_payload.pgid[23:16].16-23 - 18: TB17 # egress::hdr.first_payload.pgid[15:8].8-15 - 19: TB16 # egress::hdr.first_payload.pgid[7:0].0-7 - 20..21: TH29 # egress::hdr.first_payload.sequence[31:16].16-31 - 22..23: TH28 # egress::hdr.first_payload.sequence[15:0].0-15 - shift: 24 - buf_req: 24 - next: parseTcp.$split_1 - parseTcp.$split_1: - *: - 0..1: TH27 # egress::hdr.first_payload.txtstamp[31:16].16-31 - 2..3: TH26 # egress::hdr.first_payload.txtstamp[15:0].0-15 - shift: 4 - buf_req: 4 - next: end - parseUdp: - *: - 0..1: TH8 # egress::hdr.udp.src_port - 2..3: TH7 # egress::hdr.udp.dst_port - 4..7: TW5 - # - bit[32..47] -> TW5 bit[31..16]: egress::hdr.udp.hdr_length - # - bit[48..63] -> TW5 bit[15..0]: egress::hdr.udp.checksum - 8..11: TW22 # egress::hdr.first_payload.signature_top - 12..15: TW21 # egress::hdr.first_payload.signature_bot - 16..19: TW20 # egress::hdr.first_payload.rx_timestamp - 20: TB19 # egress::hdr.first_payload.pgid[31:24].24-31 - 21: TB18 # egress::hdr.first_payload.pgid[23:16].16-23 - 22: TB17 # egress::hdr.first_payload.pgid[15:8].8-15 - 23: TB16 # egress::hdr.first_payload.pgid[7:0].0-7 - 24..25: TH29 # egress::hdr.first_payload.sequence[31:16].16-31 - 26..27: TH28 # egress::hdr.first_payload.sequence[15:0].0-15 - shift: 28 - buf_req: 28 - next: parseUdp.$split_0 - parseUdp.$split_0: - *: - 0..1: TH27 # egress::hdr.first_payload.txtstamp[31:16].16-31 - 2..3: TH26 # egress::hdr.first_payload.txtstamp[15:0].0-15 - B22: 48 - # - value 1 -> B22 bit[5]: egress::hdr.udp.$valid - # - value 1 -> B22 bit[4]: egress::hdr.first_payload.$valid - shift: 4 - buf_req: 4 - next: end - parseL23: - *: - 0..3: TW22 # egress::hdr.first_payload.signature_top - 4..7: TW21 # egress::hdr.first_payload.signature_bot - 8..11: TW20 # egress::hdr.first_payload.rx_timestamp - 12: TB19 # egress::hdr.first_payload.pgid[31:24].24-31 - 13: TB18 # egress::hdr.first_payload.pgid[23:16].16-23 - 14: TB17 # egress::hdr.first_payload.pgid[15:8].8-15 - 15: TB16 # egress::hdr.first_payload.pgid[7:0].0-7 - 16..17: TH29 # egress::hdr.first_payload.sequence[31:16].16-31 - 18..19: TH28 # egress::hdr.first_payload.sequence[15:0].0-15 - 20..21: TH27 # egress::hdr.first_payload.txtstamp[31:16].16-31 - 22..23: TH26 # egress::hdr.first_payload.txtstamp[15:0].0-15 - shift: 24 - buf_req: 24 - next: parseL23.$split_0 - parseL23.$split_0: - *: - B22: 16 # value 1 -> B22 bit[4]: egress::hdr.first_payload.$valid - buf_req: 0 - next: end - parse_bridge: - *: - 3..4: TH32 # egress::hdr.ethernet.dst_addr[47:32].32-47 - 5..8: TW16 # egress::hdr.ethernet.dst_addr[31:0].0-31 - 9..10: TH31 # egress::hdr.ethernet.src_addr[47:32].32-47 - 11: TB7 # egress::hdr.ethernet.src_addr[31:24].24-31 - 12: TB6 # egress::hdr.ethernet.src_addr[23:16].16-23 - 13..14: TH11 # egress::hdr.ethernet.src_addr[15:0].0-15 - 15..16: TH30 # egress::hdr.ethernet.ether_type - B23: 1 # value 1 -> B23 bit[7..0]: egress::meta.ing_port_mirror.pkt_type - B17: 1 # value 1 -> B17 bit[7..0]: egress::meta.pkt_type - load: { half : 15..16 } - shift: 17 - buf_req: 17 - next: parse_bridge.$split_0 - parse_bridge.$split_0: - match: [ half ] - 0x8100: - B22: 1 # value 1 -> B22 bit[0]: egress::hdr.ethernet.$valid - load: { half : 2..3 } - buf_req: 4 - next: parse_vlan_tag - 0x0800: - B22: 1 # value 1 -> B22 bit[0]: egress::hdr.ethernet.$valid - buf_req: 0 - next: parse_ipv4 - 0x****: - B22: 1 # value 1 -> B22 bit[0]: egress::hdr.ethernet.$valid - buf_req: 0 - next: end - parse_capture: - *: - 0: B23 # egress::meta.ing_port_mirror.pkt_type - 1..4: W17 # egress::meta.ing_port_mirror.mac_timestamp - B22: 64 # value 1 -> B22 bit[6]: egress::hdr.capture.$valid - B17: 3 # value 3 -> B17 bit[7..0]: egress::meta.pkt_type - shift: 5 - buf_req: 5 - next: end - parse_capture_final: - *: - 3: TB4 # egress::hdr.capture.seq_no[23:16].16-23 - 4..5: TH6 # egress::hdr.capture.seq_no[15:0].0-15 - 6: B18 # egress::hdr.capture.reserved - 7..10: W18 # egress::hdr.capture.timestamp - B22: 64 # value 1 -> B22 bit[6]: egress::hdr.capture.$valid - B17: 5 # value 5 -> B17 bit[7..0]: egress::meta.pkt_type - shift: 11 - buf_req: 11 - next: end -deparser egress: - dictionary: - TB4: B22(6) # egress::hdr.capture.seq_no.16-23 if egress::hdr.capture.$valid - TH6: B22(6) # egress::hdr.capture.seq_no.0-15 if egress::hdr.capture.$valid - B18: B22(6) # egress::hdr.capture.reserved if egress::hdr.capture.$valid - W18: B22(6) # egress::hdr.capture.timestamp if egress::hdr.capture.$valid - TH32: B22(0) # egress::hdr.ethernet.dst_addr.32-47 if egress::hdr.ethernet.$valid - TW16: B22(0) # egress::hdr.ethernet.dst_addr.0-31 if egress::hdr.ethernet.$valid - TH31: B22(0) # egress::hdr.ethernet.src_addr.32-47 if egress::hdr.ethernet.$valid - TB7: B22(0) # egress::hdr.ethernet.src_addr.24-31 if egress::hdr.ethernet.$valid - TB6: B22(0) # egress::hdr.ethernet.src_addr.16-23 if egress::hdr.ethernet.$valid - TH11: B22(0) # egress::hdr.ethernet.src_addr.0-15 if egress::hdr.ethernet.$valid - TH30: B22(0) # egress::hdr.ethernet.ether_type if egress::hdr.ethernet.$valid - TB4: B22(1) - # - bit[7..5]: egress::hdr.vlan_tag.pcp if egress::hdr.vlan_tag.$valid - # - bit[4]: egress::hdr.vlan_tag.cfi if egress::hdr.vlan_tag.$valid - # - bit[3..0]: egress::hdr.vlan_tag.vid.8-11 if egress::hdr.vlan_tag.$valid - TB5: B22(1) # egress::hdr.vlan_tag.vid.0-7 if egress::hdr.vlan_tag.$valid - TH6: B22(1) # egress::hdr.vlan_tag.ether_type if egress::hdr.vlan_tag.$valid - TW4: B22(2) - # - bit[31..28]: egress::hdr.ipv4.version if egress::hdr.ipv4.$valid - # - bit[27..24]: egress::hdr.ipv4.ihl if egress::hdr.ipv4.$valid - # - bit[23..16]: egress::hdr.ipv4.diffserv if egress::hdr.ipv4.$valid - # - bit[15..0]: egress::hdr.ipv4.total_len if egress::hdr.ipv4.$valid - TW7: B22(2) - # - bit[31..16]: egress::hdr.ipv4.identification if egress::hdr.ipv4.$valid - # - bit[15..13]: egress::hdr.ipv4.flags if egress::hdr.ipv4.$valid - # - bit[12..0]: egress::hdr.ipv4.frag_offset if egress::hdr.ipv4.$valid - TW6: B22(2) - # - bit[31..24]: egress::hdr.ipv4.ttl if egress::hdr.ipv4.$valid - # - bit[23..16]: egress::hdr.ipv4.protocol if egress::hdr.ipv4.$valid - # - bit[15..0]: egress::hdr.ipv4.hdr_checksum if egress::hdr.ipv4.$valid - TW18: B22(2) # egress::hdr.ipv4.src_addr if egress::hdr.ipv4.$valid - TW17: B22(2) # egress::hdr.ipv4.dst_addr if egress::hdr.ipv4.$valid - TH10: B22(3) # egress::hdr.tcp.src_port if egress::hdr.tcp.$valid - TH9: B22(3) # egress::hdr.tcp.dst_port if egress::hdr.tcp.$valid - TH25: B22(3) # egress::hdr.tcp.seq_no.16-31 if egress::hdr.tcp.$valid - TH24: B22(3) # egress::hdr.tcp.seq_no.0-15 if egress::hdr.tcp.$valid - TW19: B22(3) # egress::hdr.tcp.ack_no if egress::hdr.tcp.$valid - TW5: B22(3) - # - bit[31..28]: egress::hdr.tcp.data_offset if egress::hdr.tcp.$valid - # - bit[27..24]: egress::hdr.tcp.res if egress::hdr.tcp.$valid - # - bit[23..16]: egress::hdr.tcp.flags if egress::hdr.tcp.$valid - # - bit[15..0]: egress::hdr.tcp.window if egress::hdr.tcp.$valid - TH8: B22(3) # egress::hdr.tcp.checksum if egress::hdr.tcp.$valid - TH7: B22(3) # egress::hdr.tcp.urgent_ptr if egress::hdr.tcp.$valid - TH8: B22(5) # egress::hdr.udp.src_port if egress::hdr.udp.$valid - TH7: B22(5) # egress::hdr.udp.dst_port if egress::hdr.udp.$valid - TW5: B22(5) - # - bit[31..16]: egress::hdr.udp.hdr_length if egress::hdr.udp.$valid - # - bit[15..0]: egress::hdr.udp.checksum if egress::hdr.udp.$valid - TW22: B22(4) # egress::hdr.first_payload.signature_top if egress::hdr.first_payload.$valid - TW21: B22(4) # egress::hdr.first_payload.signature_bot if egress::hdr.first_payload.$valid - TW20: B22(4) # egress::hdr.first_payload.rx_timestamp if egress::hdr.first_payload.$valid - TB19: B22(4) # egress::hdr.first_payload.pgid.24-31 if egress::hdr.first_payload.$valid - TB18: B22(4) # egress::hdr.first_payload.pgid.16-23 if egress::hdr.first_payload.$valid - TB17: B22(4) # egress::hdr.first_payload.pgid.8-15 if egress::hdr.first_payload.$valid - TB16: B22(4) # egress::hdr.first_payload.pgid.0-7 if egress::hdr.first_payload.$valid - TH29: B22(4) # egress::hdr.first_payload.sequence.16-31 if egress::hdr.first_payload.$valid - TH28: B22(4) # egress::hdr.first_payload.sequence.0-15 if egress::hdr.first_payload.$valid - TH27: B22(4) # egress::hdr.first_payload.txtstamp.16-31 if egress::hdr.first_payload.$valid - TH26: B22(4) # egress::hdr.first_payload.txtstamp.0-15 if egress::hdr.first_payload.$valid - egress_unicast_port: H24(0..8) # bit[8..0]: egress::eg_intr_md.egress_port - mirror: - select: B16(0..2) # bit[2..0]: egress::eg_intr_md_for_dprsr.mirror_type - 2: - - H16(0..9) # bit[9..0]: egress::meta.mirror_session - - B17 # egress::meta.pkt_type - - W17 # egress::meta.ing_port_mirror.mac_timestamp -stage 0 ingress: - phase0_match IngressParser.$PORT_METADATA: - p4: - name: IngressParser.$PORT_METADATA - size: 288 - preferred_match_type: exact - match_type: exact - size: 288 - p4_param_order: - ig_intr_md.ingress_port: { type: exact, size: 9 } - format: {port_signature: 32..63, port_type: 24..27, capture_port: 16..23} - constant_value: 0 - actions: - set_port_metadata: - - handle: 0x20000000 - - p4_param_order: { port_signature: 32, port_type: 4, capture_port: 8 } - exact_match setEgPortTbl_0 1: - p4: { name: Ingress.setEgPortTbl, size: 8 } - p4_param_order: - ig_intr_md.ingress_port: { type: exact, size: 9, full_size: 9 } - row: 7 - bus: 0 - column: 2 - stash: - row: [ 7 ] - col: [ 2 ] - unit: [ 0 ] - ways: - - [0, 0, 0x0, [7, 2]] - input_xbar: - exact group 0: { 16: ig_intr_md.ingress_port } - hash 0: - 0..7: ig_intr_md.ingress_port(0..7) - 8: ig_intr_md.ingress_port(8) - hash group 0: - table: [0] - seed: 0x0 - format: { action(0): 0..1, immediate(0): 2..10, version(0): 112..115 } - match_group_map: [ [ 0 ] ] - gateway: - name: cond-9 - input_xbar: - exact group 0: { 9: hdr.capture.$valid } - row: 0 - bus: 0 - unit: 0 - match: { 1: hdr.capture.$valid } - 0b******1: tbl_p4c2719l881 - miss: run_table - condition: - expression: "(hdr.capture.$valid == 1)" - true: tbl_p4c2719l881 - false: setEgPortTbl_0 - hit: [ ingressMirrorTbl_0 ] - miss: ingressMirrorTbl_0 - action_bus: { 32..33 : immediate(0..8) } - instruction: setEgPortTbl_0(action, $DEFAULT) - actions: - Ingress.setEgPort(1, 1): - - p4_param_order: { egress_port: 9 } - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000008 - - next_table: 0 - - { egress_port_2: immediate(0..8), egress_port: egress_port_2 } - - set ig_intr_md_for_tm.ucast_egress_port, egress_port - NoAction(2, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000009 - - next_table: 0 - - { } - default_action: NoAction - ternary_match tbl_p4c2719l881 2: - p4: { name: tbl_p4c2719l881, hidden: true } - gateway: - name: cond-10 - input_xbar: - exact group 0: { 32: meta.pkt_type } - row: 7 - bus: 0 - unit: 0 - match: { 0: meta.pkt_type } - 0x03: run_table - miss: tbl_p4c2719l886 - condition: - expression: "(meta.pkt_type == 3)" - true: tbl_p4c2719l881 - false: tbl_p4c2719l886 - hit: [ tbl_lookupCapturePort ] - miss: tbl_lookupCapturePort - indirect: tbl_p4c2719l881$tind - stateful tbl_p4c2719l881$salu.Ingress.sequence_no: - p4: { name: Ingress.sequence_no, size: 1 } - row: 15 - logical_bus: S - column: [ 0, 1 ] - maprams: [ 0, 1 ] - home_row: 15 - format: { lo: 16 } - actions: - update_seq_no_0: - - equ lo, lo, -2047 - - alu_a cmplo, lo, 0 - - add !cmplo, lo, lo, 1 - - output mem_lo - ternary_indirect tbl_p4c2719l881$tind: - row: 0 - bus: 1 - format: { action: 0..0, meter_addr: 1..10, meter_pfe: 11..11, meter_type: 12..14 } - action_bus: { 36..37 : tbl_p4c2719l881$salu.Ingress.sequence_no(0..15) } - stateful: tbl_p4c2719l881$salu.Ingress.sequence_no(meter_addr, meter_pfe, meter_type) - instruction: tbl_p4c2719l881$tind(action, $DEFAULT) - actions: - p4c2719l881(1, 2): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000002 - - next_table: 0 - - set seq_no_0, tbl_p4c2719l881$salu.Ingress.sequence_no - - tbl_p4c2719l881$salu.Ingress.sequence_no(update_seq_no_0, 0) - default_action: p4c2719l881 - ternary_match tbl_p4c2719l886 4: - p4: { name: tbl_p4c2719l886, hidden: true } - hit: [ ingressMirrorTbl_0 ] - miss: ingressMirrorTbl_0 - indirect: tbl_p4c2719l886$tind - ternary_indirect tbl_p4c2719l886$tind: - row: 1 - bus: 1 - format: { action: 0..0 } - instruction: tbl_p4c2719l886$tind(action, $DEFAULT) - actions: - p4c2719l886(0, 4): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000007 - - next_table: 0 - - set ig_intr_md_for_dprsr.drop_ctl, 1 - default_action: p4c2719l886 - ternary_match tbl_lookupCapturePort 3: - p4: { name: tbl_lookupCapturePort, hidden: true } - hit: [ setCaptureTbl_0 ] - miss: setCaptureTbl_0 - indirect: tbl_lookupCapturePort$tind - ternary_indirect tbl_lookupCapturePort$tind: - row: 0 - bus: 0 - format: { action: 0..0 } - instruction: tbl_lookupCapturePort$tind(action, $DEFAULT) - actions: - Ingress.lookupCapturePort(0, 3): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000001 - - next_table: 0 - - set capture_port_1, hdr.capture.reserved - default_action: Ingress.lookupCapturePort -stage 1 ingress: - dependency: match - ternary_match setCaptureTbl_0 1: - p4: { name: Ingress.setCaptureTbl, size: 8 } - p4_param_order: - capture_port_1: { type: ternary, size: 8, full_size: 8, key_name: "capture_port" } - row: 0 - bus: 0 - column: 0 - input_xbar: - ternary group 0: { 0: capture_port_1 } - match: - - { group: 0, byte_config: 3, dirtcam: 0x1 } - hit: [ insertOverheadTbl_0 ] - miss: insertOverheadTbl_0 - indirect: setCaptureTbl_0$tind - ternary_indirect setCaptureTbl_0$tind: - row: 0 - bus: 0 - column: 2 - input_xbar: - ternary group 0: { 0: capture_port_1 } - format: { action: 0..0, immediate: 1..9 } - action_bus: { 32..33 : immediate(0..8) } - instruction: setCaptureTbl_0$tind(action, $DEFAULT) - actions: - Ingress.setCaptureEgPort(0, 1): - - p4_param_order: { egress_port: 9 } - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000005 - - next_table: 0 - - { egress_port_3: immediate(0..8), egress_port: egress_port_3 } - - set ig_intr_md_for_tm.ucast_egress_port, egress_port - NoAction(1, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000006 - - next_table: 0 - - { } - default_action: NoAction - exact_match insertOverheadTbl_0 2: - p4: { name: Ingress.insertOverheadTbl, size: 2048 } - p4_param_order: - seq_no_0: { type: exact, size: 16, full_size: 16, key_name: "seq_no" } - row: 7 - bus: 0 - column: [ 2, 3, 4, 6 ] - stash: - row: [ 7 ] - col: [ 2 ] - unit: [ 0 ] - ways: - - [1, 0, 0x0, [7, 2]] - - [1, 1, 0x0, [7, 3]] - - [1, 2, 0x0, [7, 4]] - - [1, 3, 0x0, [7, 6]] - input_xbar: - exact group 0: { 64: seq_no_0 } - hash 1: - 0..7: random(seq_no_0(10..15)) ^ seq_no_0(0..7) - 8..9: random(seq_no_0(10..15)) ^ seq_no_0(8..9) - 11..18: random(seq_no_0(10..15)) ^ seq_no_0(0..7) - 19: random(seq_no_0(10..15)) ^ seq_no_0(8) - 10: random(seq_no_0(10..15)) ^ seq_no_0(9) - 22..29: random(seq_no_0(10..15)) ^ seq_no_0(0..7) - 20..21: random(seq_no_0(10..15)) ^ seq_no_0(8..9) - 33..39: random(seq_no_0(10..15)) ^ seq_no_0(0..6) - 30: random(seq_no_0(10..15)) ^ seq_no_0(7) - 31..32: random(seq_no_0(10..15)) ^ seq_no_0(8..9) - hash group 1: - table: [1] - seed: 0xc92687df45 - format: { immediate(0): 0..23, version(0): 112..115, match(0): 34..39 } - match: [ seq_no_0(10..15) ] - match_group_map: [ [ 0 ] ] - hit: [ ingressMirrorTbl_0 ] - miss: ingressMirrorTbl_0 - action_bus: { 96..99 : immediate(0..23) } - instruction: insertOverheadTbl_0($DEFAULT, $DEFAULT) - actions: - Ingress.insert_seq_no(0, 2): - - p4_param_order: { calculated_ov: 24 } - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000003 - - next_table: 0 - - { calculated_ov: immediate(0..23) } - - set hdr.capture.seq_no, calculated_ov - NoAction(-1, 0): - - hit_allowed: { allowed: false, reason: user_indicated_default_only } - - default_only_action: { allowed: true } - - handle: 0x20000004 - - next_table: 0 - - { } - default_only_action: NoAction - exact_match ingressMirrorTbl_0 3: - p4: { name: Ingress.ingressMirrorTbl, size: 1 } - p4_param_order: - ig_intr_md.ingress_port: { type: exact, size: 9, full_size: 9 } - row: 6 - bus: 0 - column: 2 - stash: - row: [ 6 ] - col: [ 2 ] - unit: [ 0 ] - ways: - - [0, 1, 0x0, [6, 2]] - hash_dist: - 0: { hash: 2, mask: 0xffff, shift: 0 } - 1: { hash: 2, mask: 0xffff, shift: 0 } - input_xbar: - exact group 0: { 16: ig_intr_md.ingress_port } - hash 0: - 10..17: ig_intr_md.ingress_port(0..7) - 18: ig_intr_md.ingress_port(8) - hash group 0: - table: [0] - seed: 0x0 - exact group 1: { 0: ig_intr_md.ingress_mac_tstamp.0-31(0..7), 8: ig_intr_md.ingress_mac_tstamp.40-47, 16: ig_intr_md.ingress_mac_tstamp.0-31(16..31), 32: ig_intr_md.ingress_mac_tstamp.32-39, 40: ig_intr_md.ingress_mac_tstamp.0-31(8..15) } - hash 2: - 0..7: ig_intr_md.ingress_mac_tstamp.0-31(0..7) - 8..15: ig_intr_md.ingress_mac_tstamp.0-31(8..15) - hash group 2: - table: [2] - seed: 0x0 - exact group 1: { 0: ig_intr_md.ingress_mac_tstamp.0-31(0..7), 8: ig_intr_md.ingress_mac_tstamp.40-47, 16: ig_intr_md.ingress_mac_tstamp.0-31(16..31), 32: ig_intr_md.ingress_mac_tstamp.32-39, 40: ig_intr_md.ingress_mac_tstamp.0-31(8..15) } - hash 2: - 16..31: ig_intr_md.ingress_mac_tstamp.0-31(16..31) - hash group 2: - table: [2] - seed: 0x0 - format: { action(0): 0..0, version(0): 112..115 } - match_group_map: [ [ 0 ] ] - hit: [ END ] - miss: END - action_bus: { 100..103 : hash_dist(0, 1) } - action: ingressMirrorTbl_0$action_data($DIRECT, $DEFAULT) - instruction: ingressMirrorTbl_0(action, $DEFAULT) - actions: - Ingress.set_mirror_session_capture(0, 3): - - p4_param_order: { mirror_session: 10 } - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x2000000a - - next_table: 0 - - { mirror_session_2: $adf_h0(0..9), mirror_session: mirror_session_2 } - - set ig_intr_md_for_dprsr.mirror_type, 1 - - set ig_intr_md_for_tm.mcast_grp_a, 0 - - set meta.mirror_session, mirror_session - - set meta.pkt_type, 3 - - set W2, hash_dist(0, 1, 0..31) - NoAction(1, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x2000000b - - next_table: 0 - - { } - default_action: NoAction - action ingressMirrorTbl_0$action_data: - p4: { name: Ingress.ingressMirrorTbl$action } - row: 14 - logical_bus: A - column: 5 - vpns: [ 0 ] - home_row: - - 14 - format Ingress.set_mirror_session_capture: { $adf_h0: 0..15 } - action_bus: { 36..37 : $adf_h0 } -stage 0 egress: - ternary_match tbl_update_register_partial_length 0: - p4: { name: tbl_update_register_partial_length, hidden: true } - gateway: - name: cond-11 - input_xbar: - exact group 0: { 6: hdr.capture.$valid } - row: 0 - bus: 1 - unit: 1 - match: { 6: hdr.capture.$valid } - 0b*1: run_table - miss: tbl_insert_capture - condition: - expression: "(hdr.capture.$valid == 1)" - true: tbl_update_register_partial_length - false: tbl_insert_capture - hit: [ update_register_captureLookupTbl ] - miss: update_register_captureLookupTbl - indirect: tbl_update_register_partial_length$tind - ternary_indirect tbl_update_register_partial_length$tind: - row: 1 - bus: 0 - format: { action: 0..0 } - instruction: tbl_update_register_partial_length$tind(action, $DEFAULT) - actions: - Egress.update_register.partial_length(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x2000000c - - next_table: 0 - - shru update_register_portion, eg_intr_md.pkt_length, 2 - default_action: Egress.update_register.partial_length -stage 1 egress: - dependency: action - exact_match update_register_captureLookupTbl 0: - p4: { name: Egress.update_register.captureLookupTbl, size: 32 } - p4_param_order: - eg_intr_md.egress_port: { type: exact, size: 9, full_size: 9, key_name: "inport" } - row: 7 - bus: 1 - column: 7 - stash: - row: [ 7 ] - col: [ 7 ] - unit: [ 1 ] - ways: - - [0, 0, 0x0, [7, 7]] - input_xbar: - exact group 0: { 0: eg_intr_md.egress_port } - hash 0: - 0..7: eg_intr_md.egress_port(0..7) - 8: eg_intr_md.egress_port(8) - hash group 0: - table: [0] - seed: 0x0 - format: { action(0): 0..0, version(0): 112..115, counter_addr(0): 1..10, counter_pfe(0): 11..11, meter_addr(0): 12..21, meter_pfe(0): 22..22 } - match_group_map: [ [ 0 ] ] - hit: [ tbl_update_register_negate_pad ] - miss: tbl_update_register_negate_pad - action_bus: { 0 : update_register_captureLookupTbl$salu.Egress.update_register.random_assign(0..7) } - stats: update_register_captureLookupTbl$stats.Egress.update_register.debug_stats(counter_addr, counter_pfe) - stateful: update_register_captureLookupTbl$salu.Egress.update_register.random_assign(meter_addr, meter_pfe, $DEFAULT) - instruction: update_register_captureLookupTbl(action, $DEFAULT) - actions: - Egress.update_register.lookupIndex(0, 1): - - p4_param_order: { port: 8 } - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x2000000d - - next_table: 0 - - { port: counter_addr } - - set update_register_capture_port, hdr.capture.reserved - - add update_register_padded_length, eg_intr_md.pkt_length, update_register_portion - - update_register_captureLookupTbl$stats.Egress.update_register.debug_stats(port) - Egress.update_register.lookupCapturePort(1, 2): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x2000000e - - next_table: 0 - - set update_register_capture_port, update_register_captureLookupTbl$salu.Egress.update_register.random_assign - - set update_register_padded_length, update_register_portion - - update_register_captureLookupTbl$salu.Egress.update_register.random_assign(update_register_random_assign_reg, 0) - default_action: Egress.update_register.lookupCapturePort - counter update_register_captureLookupTbl$stats.Egress.update_register.debug_stats: - p4: { name: Egress.update_register.debug_stats, size: 8 } - row: 13 - logical_bus: S - column: [ 0, 1 ] - maprams: [ 0, 1 ] - vpns: [ 0, 1 ] - home_row: 13 - count: packets - format: {packets(0): 64..127, packets(1): 0..63} - per_flow_enable: counter_pfe - stateful update_register_captureLookupTbl$salu.Egress.update_register.random_assign: - p4: { name: Egress.update_register.random_assign, size: 1 } - row: 15 - logical_bus: S - column: [ 2, 3 ] - maprams: [ 2, 3 ] - home_row: 15 - format: { lo: 8 } - actions: - update_register_random_assign_reg: - - equ lo, lo, -4 - - alu_a cmplo, lo, 0 - - add !cmplo, lo, lo, 1 - - output mem_lo -stage 2 egress: - dependency: action - ternary_match tbl_update_register_negate_pad 0: - p4: { name: tbl_update_register_negate_pad, hidden: true } - hit: [ update_register_LengthLookupTbl ] - miss: update_register_LengthLookupTbl - indirect: tbl_update_register_negate_pad$tind - ternary_indirect tbl_update_register_negate_pad$tind: - row: 0 - bus: 0 - format: { action: 0..0 } - instruction: tbl_update_register_negate_pad$tind(action, $DEFAULT) - actions: - Egress.update_register.negate_pad(0, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x2000000f - - next_table: 0 - - not update_register_negated_length, update_register_padded_length - - shl update_register_load_length, update_register_padded_length, 2 - default_action: Egress.update_register.negate_pad -stage 3 egress: - dependency: match - ternary_match update_register_LengthLookupTbl 0: - p4: { name: Egress.update_register.LengthLookupTbl, size: 32 } - p4_param_order: - meta.pkt_type: { type: exact, size: 8, full_size: 8, key_name: "pkt_type" } - update_register_capture_port: { type: ternary, size: 8, full_size: 8, key_name: "capture_port" } - row: 0 - bus: 0 - column: 0 - input_xbar: - ternary group 0: { 0: meta.pkt_type, 8: update_register_capture_port } - match: - - { group: 0, byte_config: 3, dirtcam: 0x5 } - hit: [ tbl_p4c2719l720 ] - miss: tbl_p4c2719l720 - context_json: - static_entries: - - priority: 0 - match_key_fields_values: - - field_name: pkt_type - value: "0x3" - - field_name: capture_port - value: "0x0" - mask: "0x7" - action_handle: 0x20000010 - is_default_entry: false - action_parameters_values: [] - - priority: 1 - match_key_fields_values: - - field_name: pkt_type - value: "0x3" - - field_name: capture_port - value: "0x1" - mask: "0x7" - action_handle: 0x20000011 - is_default_entry: false - action_parameters_values: [] - - priority: 2 - match_key_fields_values: - - field_name: pkt_type - value: "0x3" - - field_name: capture_port - value: "0x2" - mask: "0x7" - action_handle: 0x20000012 - is_default_entry: false - action_parameters_values: [] - - priority: 3 - match_key_fields_values: - - field_name: pkt_type - value: "0x3" - - field_name: capture_port - value: "0x3" - mask: "0x7" - action_handle: 0x20000013 - is_default_entry: false - action_parameters_values: [] - - priority: 4 - match_key_fields_values: - - field_name: pkt_type - value: "0x3" - - field_name: capture_port - value: "0x4" - mask: "0x7" - action_handle: 0x20000014 - is_default_entry: false - action_parameters_values: [] - - priority: 5 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x4" - mask: "0xFF" - action_handle: 0x20000018 - is_default_entry: false - action_parameters_values: [] - - priority: 6 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x3" - mask: "0xFF" - action_handle: 0x20000017 - is_default_entry: false - action_parameters_values: [] - - priority: 7 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x2" - mask: "0xFF" - action_handle: 0x20000016 - is_default_entry: false - action_parameters_values: [] - - priority: 8 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x1" - mask: "0xFF" - action_handle: 0x20000015 - is_default_entry: false - action_parameters_values: [] - - priority: 9 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x14" - mask: "0xFF" - action_handle: 0x2000001c - is_default_entry: false - action_parameters_values: [] - - priority: 10 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x13" - mask: "0xFF" - action_handle: 0x2000001b - is_default_entry: false - action_parameters_values: [] - - priority: 11 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x12" - mask: "0xFF" - action_handle: 0x2000001a - is_default_entry: false - action_parameters_values: [] - - priority: 12 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x10" - mask: "0xFF" - action_handle: 0x20000019 - is_default_entry: false - action_parameters_values: [] - - priority: 13 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x24" - mask: "0xFF" - action_handle: 0x20000020 - is_default_entry: false - action_parameters_values: [] - - priority: 14 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x23" - mask: "0xFF" - action_handle: 0x2000001f - is_default_entry: false - action_parameters_values: [] - - priority: 15 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x21" - mask: "0xFF" - action_handle: 0x2000001e - is_default_entry: false - action_parameters_values: [] - - priority: 16 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x20" - mask: "0xFF" - action_handle: 0x2000001d - is_default_entry: false - action_parameters_values: [] - - priority: 17 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x34" - mask: "0xFF" - action_handle: 0x20000024 - is_default_entry: false - action_parameters_values: [] - - priority: 18 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x32" - mask: "0xFF" - action_handle: 0x20000023 - is_default_entry: false - action_parameters_values: [] - - priority: 19 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x31" - mask: "0xFF" - action_handle: 0x20000022 - is_default_entry: false - action_parameters_values: [] - - priority: 20 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x30" - mask: "0xFF" - action_handle: 0x20000021 - is_default_entry: false - action_parameters_values: [] - - priority: 21 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x43" - mask: "0xFF" - action_handle: 0x20000028 - is_default_entry: false - action_parameters_values: [] - - priority: 22 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x42" - mask: "0xFF" - action_handle: 0x20000027 - is_default_entry: false - action_parameters_values: [] - - priority: 23 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x41" - mask: "0xFF" - action_handle: 0x20000026 - is_default_entry: false - action_parameters_values: [] - - priority: 24 - match_key_fields_values: - - field_name: pkt_type - value: "0x5" - - field_name: capture_port - value: "0x40" - mask: "0xFF" - action_handle: 0x20000025 - is_default_entry: false - action_parameters_values: [] - indirect: update_register_LengthLookupTbl$tind - ternary_indirect update_register_LengthLookupTbl$tind: - row: 0 - bus: 0 - column: 2 - input_xbar: - ternary group 0: { 0: meta.pkt_type, 8: update_register_capture_port } - format: { action: 0..5 } - instruction: update_register_LengthLookupTbl$tind(action, $DEFAULT) - actions: - Egress.update_register.capture_port_1(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000010 - - next_table: 0 - - set update_register_cap_length, update_register_load_length - - add update_register_cap_length_0, update_register_negated_length, 1 - - add update_register_cap_length_1, update_register_negated_length, 1 - - add update_register_cap_length_2, update_register_negated_length, 1 - - add update_register_cap_length_3, update_register_negated_length, 1 - Egress.update_register.capture_port_2(2, 2): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000011 - - next_table: 0 - - set update_register_cap_length_0, update_register_load_length - - add update_register_cap_length, update_register_negated_length, 1 - - add update_register_cap_length_1, update_register_negated_length, 1 - - add update_register_cap_length_2, update_register_negated_length, 1 - - add update_register_cap_length_3, update_register_negated_length, 1 - Egress.update_register.capture_port_3(4, 4): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000012 - - next_table: 0 - - set update_register_cap_length_1, update_register_load_length - - add update_register_cap_length_0, update_register_negated_length, 1 - - add update_register_cap_length, update_register_negated_length, 1 - - add update_register_cap_length_2, update_register_negated_length, 1 - - add update_register_cap_length_3, update_register_negated_length, 1 - Egress.update_register.capture_port_4(6, 6): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000013 - - next_table: 0 - - set update_register_cap_length_2, update_register_load_length - - add update_register_cap_length_0, update_register_negated_length, 1 - - add update_register_cap_length_1, update_register_negated_length, 1 - - add update_register_cap_length, update_register_negated_length, 1 - - add update_register_cap_length_3, update_register_negated_length, 1 - Egress.update_register.capture_port_5(8, 8): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000014 - - next_table: 0 - - set update_register_cap_length_3, update_register_load_length - - add update_register_cap_length_0, update_register_negated_length, 1 - - add update_register_cap_length_1, update_register_negated_length, 1 - - add update_register_cap_length_2, update_register_negated_length, 1 - - add update_register_cap_length, update_register_negated_length, 1 - Egress.update_register.comp_port_1_2(10, 10): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000015 - - next_table: 0 - - add update_register_cap_length, update_register_negated_length, 1 - - set update_register_cap_length_0, update_register_padded_length - - set update_register_cap_length_1, 0 - - set update_register_cap_length_2, 0 - - set update_register_cap_length_3, 0 - Egress.update_register.comp_port_1_3(12, 12): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000016 - - next_table: 0 - - add update_register_cap_length, update_register_negated_length, 1 - - set update_register_cap_length_0, 0 - - set update_register_cap_length_1, update_register_padded_length - - set update_register_cap_length_2, 0 - - set update_register_cap_length_3, 0 - Egress.update_register.comp_port_1_4(14, 14): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000017 - - next_table: 0 - - add update_register_cap_length, update_register_negated_length, 1 - - set update_register_cap_length_0, 0 - - set update_register_cap_length_1, 0 - - set update_register_cap_length_2, update_register_padded_length - - set update_register_cap_length_3, 0 - Egress.update_register.comp_port_1_5(16, 16): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000018 - - next_table: 0 - - add update_register_cap_length, update_register_negated_length, 1 - - set update_register_cap_length_0, 0 - - set update_register_cap_length_1, 0 - - set update_register_cap_length_2, 0 - - set update_register_cap_length_3, update_register_padded_length - Egress.update_register.comp_port_2_1(18, 18): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000019 - - next_table: 0 - - set update_register_cap_length, update_register_padded_length - - add update_register_cap_length_0, update_register_negated_length, 1 - - set update_register_cap_length_1, 0 - - set update_register_cap_length_2, 0 - - set update_register_cap_length_3, 0 - Egress.update_register.comp_port_2_3(20, 20): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x2000001a - - next_table: 0 - - set update_register_cap_length, 0 - - add update_register_cap_length_0, update_register_negated_length, 1 - - set update_register_cap_length_1, update_register_padded_length - - set update_register_cap_length_2, 0 - - set update_register_cap_length_3, 0 - Egress.update_register.comp_port_2_4(22, 22): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x2000001b - - next_table: 0 - - set update_register_cap_length, 0 - - add update_register_cap_length_0, update_register_negated_length, 1 - - set update_register_cap_length_1, 0 - - set update_register_cap_length_2, update_register_padded_length - - set update_register_cap_length_3, 0 - Egress.update_register.comp_port_2_5(24, 24): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x2000001c - - next_table: 0 - - set update_register_cap_length, 0 - - add update_register_cap_length_0, update_register_negated_length, 1 - - set update_register_cap_length_1, 0 - - set update_register_cap_length_2, 0 - - set update_register_cap_length_3, update_register_padded_length - Egress.update_register.comp_port_3_1(26, 26): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x2000001d - - next_table: 0 - - set update_register_cap_length, update_register_padded_length - - set update_register_cap_length_0, 0 - - add update_register_cap_length_1, update_register_negated_length, 1 - - set update_register_cap_length_2, 0 - - set update_register_cap_length_3, 0 - Egress.update_register.comp_port_3_2(28, 28): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x2000001e - - next_table: 0 - - set update_register_cap_length, 0 - - set update_register_cap_length_0, update_register_padded_length - - add update_register_cap_length_1, update_register_negated_length, 1 - - set update_register_cap_length_2, 0 - - set update_register_cap_length_3, 0 - Egress.update_register.comp_port_3_4(30, 30): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x2000001f - - next_table: 0 - - set update_register_cap_length, 0 - - set update_register_cap_length_0, 0 - - add update_register_cap_length_1, update_register_negated_length, 1 - - set update_register_cap_length_2, update_register_padded_length - - set update_register_cap_length_3, 0 - Egress.update_register.comp_port_3_5(32, 32): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000020 - - next_table: 0 - - set update_register_cap_length, 0 - - set update_register_cap_length_0, 0 - - add update_register_cap_length_1, update_register_negated_length, 1 - - set update_register_cap_length_2, 0 - - set update_register_cap_length_3, update_register_padded_length - Egress.update_register.comp_port_4_1(34, 34): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000021 - - next_table: 0 - - set update_register_cap_length, update_register_padded_length - - set update_register_cap_length_0, 0 - - set update_register_cap_length_1, 0 - - add update_register_cap_length_2, update_register_negated_length, 1 - - set update_register_cap_length_3, 0 - Egress.update_register.comp_port_4_2(36, 36): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000022 - - next_table: 0 - - set update_register_cap_length, 0 - - set update_register_cap_length_0, update_register_padded_length - - set update_register_cap_length_1, 0 - - add update_register_cap_length_2, update_register_negated_length, 1 - - set update_register_cap_length_3, 0 - Egress.update_register.comp_port_4_3(38, 38): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000023 - - next_table: 0 - - set update_register_cap_length, 0 - - set update_register_cap_length_0, 0 - - set update_register_cap_length_1, update_register_padded_length - - add update_register_cap_length_2, update_register_negated_length, 1 - - set update_register_cap_length_3, 0 - Egress.update_register.comp_port_4_5(40, 40): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000024 - - next_table: 0 - - set update_register_cap_length, 0 - - set update_register_cap_length_0, 0 - - set update_register_cap_length_1, 0 - - add update_register_cap_length_2, update_register_negated_length, 1 - - set update_register_cap_length_3, update_register_padded_length - Egress.update_register.comp_port_5_1(42, 42): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000025 - - next_table: 0 - - set update_register_cap_length, update_register_padded_length - - set update_register_cap_length_0, 0 - - set update_register_cap_length_1, 0 - - set update_register_cap_length_2, 0 - - add update_register_cap_length_3, update_register_negated_length, 1 - Egress.update_register.comp_port_5_2(44, 44): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000026 - - next_table: 0 - - set update_register_cap_length, 0 - - set update_register_cap_length_0, update_register_padded_length - - set update_register_cap_length_1, 0 - - set update_register_cap_length_2, 0 - - add update_register_cap_length_3, update_register_negated_length, 1 - Egress.update_register.comp_port_5_3(46, 46): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000027 - - next_table: 0 - - set update_register_cap_length, 0 - - set update_register_cap_length_0, 0 - - set update_register_cap_length_1, update_register_padded_length - - set update_register_cap_length_2, 0 - - add update_register_cap_length_3, update_register_negated_length, 1 - Egress.update_register.comp_port_5_4(48, 48): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000028 - - next_table: 0 - - set update_register_cap_length, 0 - - set update_register_cap_length_0, 0 - - set update_register_cap_length_1, 0 - - set update_register_cap_length_2, update_register_padded_length - - add update_register_cap_length_3, update_register_negated_length, 1 - NoAction(0, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000029 - - next_table: 0 - default_action: NoAction -stage 4 egress: - dependency: match - ternary_match tbl_p4c2719l720 0: - p4: { name: tbl_p4c2719l720, hidden: true } - hit: [ tbl_p4c2719l721 ] - miss: tbl_p4c2719l721 - indirect: tbl_p4c2719l720$tind - stateful tbl_p4c2719l720$salu.Egress.update_register.active_debt_reg0: - p4: { name: Egress.update_register.active_debt_reg0, size: 1 } - row: 15 - logical_bus: S - column: [ 0, 1 ] - maprams: [ 0, 1 ] - home_row: 15 - input_xbar: - exact group 0: { 64: update_register_cap_length } - data_bytemask: 3 - format: { lo: 16 } - initial_value: { lo: 4095 , hi: 0 } - actions: - update_register_increase_reg0: - - add lo, phv_lo, lo - - output mem_lo - ternary_indirect tbl_p4c2719l720$tind: - row: 0 - bus: 0 - format: { action: 0..0, meter_addr: 1..10 } - action_bus: { 32..33 : tbl_p4c2719l720$salu.Egress.update_register.active_debt_reg0(0..15) } - stateful: tbl_p4c2719l720$salu.Egress.update_register.active_debt_reg0(meter_addr, $DEFAULT, $DEFAULT) - instruction: tbl_p4c2719l720$tind(action, $DEFAULT) - actions: - p4c2719l720(0, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x2000002a - - next_table: 0 - - set update_register_debt0, tbl_p4c2719l720$salu.Egress.update_register.active_debt_reg0 - - tbl_p4c2719l720$salu.Egress.update_register.active_debt_reg0(update_register_increase_reg0, 0) - default_action: p4c2719l720 -stage 5 egress: - dependency: match - ternary_match tbl_p4c2719l721 0: - p4: { name: tbl_p4c2719l721, hidden: true } - hit: [ tbl_p4c2719l722 ] - miss: tbl_p4c2719l722 - indirect: tbl_p4c2719l721$tind - stateful tbl_p4c2719l721$salu.Egress.update_register.active_debt_reg1: - p4: { name: Egress.update_register.active_debt_reg1, size: 1 } - row: 15 - logical_bus: S - column: [ 0, 1 ] - maprams: [ 0, 1 ] - home_row: 15 - input_xbar: - exact group 0: { 64: update_register_debt0, 80: update_register_cap_length_0 } - data_bytemask: 15 - format: { lo: 16 } - initial_value: { lo: 4095 , hi: 0 } - actions: - update_register_increase_reg1: - - minu hi, phv_lo, lo - - add lo, phv_hi, lo - - output alu_hi - ternary_indirect tbl_p4c2719l721$tind: - row: 0 - bus: 0 - format: { action: 0..0, meter_addr: 1..10 } - action_bus: { 32..33 : tbl_p4c2719l721$salu.Egress.update_register.active_debt_reg1(0..15) } - stateful: tbl_p4c2719l721$salu.Egress.update_register.active_debt_reg1(meter_addr, $DEFAULT, $DEFAULT) - instruction: tbl_p4c2719l721$tind(action, $DEFAULT) - actions: - p4c2719l721(0, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x2000002b - - next_table: 0 - - set update_register_debt1, tbl_p4c2719l721$salu.Egress.update_register.active_debt_reg1 - - tbl_p4c2719l721$salu.Egress.update_register.active_debt_reg1(update_register_increase_reg1, 0) - default_action: p4c2719l721 -stage 6 egress: - dependency: match - ternary_match tbl_p4c2719l722 0: - p4: { name: tbl_p4c2719l722, hidden: true } - hit: [ tbl_p4c2719l732 ] - miss: tbl_p4c2719l732 - indirect: tbl_p4c2719l722$tind - stateful tbl_p4c2719l722$salu.Egress.update_register.active_debt_reg2: - p4: { name: Egress.update_register.active_debt_reg2, size: 1 } - row: 15 - logical_bus: S - column: [ 0, 1 ] - maprams: [ 0, 1 ] - home_row: 15 - input_xbar: - exact group 0: { 64: update_register_debt1, 80: update_register_cap_length_1 } - data_bytemask: 15 - format: { lo: 16 } - initial_value: { lo: 4095 , hi: 0 } - actions: - update_register_increase_reg2: - - minu hi, phv_lo, lo - - add lo, phv_hi, lo - - output alu_hi - ternary_indirect tbl_p4c2719l722$tind: - row: 0 - bus: 0 - format: { action: 0..0, meter_addr: 1..10 } - action_bus: { 32..33 : tbl_p4c2719l722$salu.Egress.update_register.active_debt_reg2(0..15) } - stateful: tbl_p4c2719l722$salu.Egress.update_register.active_debt_reg2(meter_addr, $DEFAULT, $DEFAULT) - instruction: tbl_p4c2719l722$tind(action, $DEFAULT) - actions: - p4c2719l722(0, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x2000002c - - next_table: 0 - - set update_register_debt2, tbl_p4c2719l722$salu.Egress.update_register.active_debt_reg2 - - tbl_p4c2719l722$salu.Egress.update_register.active_debt_reg2(update_register_increase_reg2, 0) - default_action: p4c2719l722 - ternary_match tbl_p4c2719l732 1: - p4: { name: tbl_p4c2719l732, hidden: true } - gateway: - name: cond-12 - input_xbar: - exact group 0: { 0: update_register_debt0, 64: update_register_debt1 } - row: 0 - bus: 0 - unit: 0 - match: { 0: update_register_debt1(0..7), 8: update_register_debt1(8..15) } - xor: { 0: update_register_debt0(0..7), 8: update_register_debt0(8..15) } - 0x0000: tbl_p4c2719l723 - miss: run_table - condition: - expression: "(update_register_debt1 == update_register_debt0)" - true: tbl_p4c2719l723 - false: tbl_p4c2719l732 - hit: [ tbl_p4c2719l723 ] - miss: tbl_p4c2719l723 - indirect: tbl_p4c2719l732$tind - ternary_indirect tbl_p4c2719l732$tind: - row: 0 - bus: 1 - format: { action: 0..0 } - instruction: tbl_p4c2719l732$tind(action, $DEFAULT) - actions: - p4c2719l732(1, 2): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x2000002f - - next_table: 0 - - set update_register_reg0.0-3, 1 - - set update_register_reg0.4-7, 0 - default_action: p4c2719l732 -stage 7 egress: - dependency: match - ternary_match tbl_p4c2719l723 0: - p4: { name: tbl_p4c2719l723, hidden: true } - hit: [ tbl_p4c2719l737 ] - miss: tbl_p4c2719l737 - indirect: tbl_p4c2719l723$tind - stateful tbl_p4c2719l723$salu.Egress.update_register.active_debt_reg3: - p4: { name: Egress.update_register.active_debt_reg3, size: 1 } - row: 15 - logical_bus: S - column: [ 0, 1 ] - maprams: [ 0, 1 ] - home_row: 15 - input_xbar: - exact group 0: { 64: update_register_debt2, 80: update_register_cap_length_2 } - data_bytemask: 15 - format: { lo: 16 } - initial_value: { lo: 4095 , hi: 0 } - actions: - update_register_increase_reg3: - - minu hi, phv_lo, lo - - add lo, phv_hi, lo - - output alu_hi - ternary_indirect tbl_p4c2719l723$tind: - row: 0 - bus: 1 - format: { action: 0..0, meter_addr: 1..10 } - action_bus: { 32..33 : tbl_p4c2719l723$salu.Egress.update_register.active_debt_reg3(0..15) } - stateful: tbl_p4c2719l723$salu.Egress.update_register.active_debt_reg3(meter_addr, $DEFAULT, $DEFAULT) - instruction: tbl_p4c2719l723$tind(action, $DEFAULT) - actions: - p4c2719l723(0, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x2000002d - - next_table: 0 - - set update_register_debt3, tbl_p4c2719l723$salu.Egress.update_register.active_debt_reg3 - - tbl_p4c2719l723$salu.Egress.update_register.active_debt_reg3(update_register_increase_reg3, 0) - default_action: p4c2719l723 - ternary_match tbl_p4c2719l737 1: - p4: { name: tbl_p4c2719l737, hidden: true } - gateway: - name: cond-13 - input_xbar: - exact group 0: { 0: update_register_debt1, 64: update_register_debt2 } - row: 0 - bus: 0 - unit: 0 - match: { 0: update_register_debt2(0..7), 8: update_register_debt2(8..15) } - xor: { 0: update_register_debt1(0..7), 8: update_register_debt1(8..15) } - 0x0000: run_table - miss: tbl_p4c2719l741 - condition: - expression: "(update_register_debt2 == update_register_debt1)" - true: tbl_p4c2719l737 - false: tbl_p4c2719l741 - hit: [ tbl_p4c2719l724 ] - miss: tbl_p4c2719l724 - indirect: tbl_p4c2719l737$tind - ternary_indirect tbl_p4c2719l737$tind: - row: 0 - bus: 0 - format: { action: 0..0 } - instruction: tbl_p4c2719l737$tind(action, $DEFAULT) - actions: - p4c2719l737(1, 2): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000030 - - next_table: 0 - - set update_register_reg1.0-3, update_register_reg0.0-3 - - set update_register_reg1.4-7, update_register_reg0.4-7 - default_action: p4c2719l737 - ternary_match tbl_p4c2719l741 2: - p4: { name: tbl_p4c2719l741, hidden: true } - hit: [ tbl_p4c2719l724 ] - miss: tbl_p4c2719l724 - indirect: tbl_p4c2719l741$tind - ternary_indirect tbl_p4c2719l741$tind: - row: 1 - bus: 0 - format: { action: 0..0 } - instruction: tbl_p4c2719l741$tind(action, $DEFAULT) - actions: - p4c2719l741(0, 4): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000031 - - next_table: 0 - - set update_register_reg1.0-3, 2 - - set update_register_reg1.4-7, 0 - default_action: p4c2719l741 -stage 8 egress: - dependency: match - ternary_match tbl_p4c2719l724 0: - p4: { name: tbl_p4c2719l724, hidden: true } - hit: [ tbl_p4c2719l746 ] - miss: tbl_p4c2719l746 - indirect: tbl_p4c2719l724$tind - stateful tbl_p4c2719l724$salu.Egress.update_register.active_debt_reg4: - p4: { name: Egress.update_register.active_debt_reg4, size: 1 } - row: 15 - logical_bus: S - column: [ 0, 1 ] - maprams: [ 0, 1 ] - home_row: 15 - input_xbar: - exact group 0: { 64: update_register_debt3, 80: update_register_cap_length_3 } - data_bytemask: 15 - format: { lo: 16 } - initial_value: { lo: 4095 , hi: 0 } - actions: - update_register_increase_reg4: - - minu hi, phv_lo, lo - - add lo, phv_hi, lo - - output alu_hi - ternary_indirect tbl_p4c2719l724$tind: - row: 0 - bus: 1 - format: { action: 0..0, meter_addr: 1..10 } - action_bus: { 32..33 : tbl_p4c2719l724$salu.Egress.update_register.active_debt_reg4(0..15) } - stateful: tbl_p4c2719l724$salu.Egress.update_register.active_debt_reg4(meter_addr, $DEFAULT, $DEFAULT) - instruction: tbl_p4c2719l724$tind(action, $DEFAULT) - actions: - p4c2719l724(0, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x2000002e - - next_table: 0 - - set update_register_debt4, tbl_p4c2719l724$salu.Egress.update_register.active_debt_reg4 - - tbl_p4c2719l724$salu.Egress.update_register.active_debt_reg4(update_register_increase_reg4, 0) - default_action: p4c2719l724 - ternary_match tbl_p4c2719l746 1: - p4: { name: tbl_p4c2719l746, hidden: true } - gateway: - name: cond-14 - input_xbar: - exact group 0: { 0: update_register_debt2, 64: update_register_debt3 } - row: 0 - bus: 0 - unit: 0 - match: { 0: update_register_debt3(0..7), 8: update_register_debt3(8..15) } - xor: { 0: update_register_debt2(0..7), 8: update_register_debt2(8..15) } - 0x0000: run_table - miss: tbl_p4c2719l750 - condition: - expression: "(update_register_debt3 == update_register_debt2)" - true: tbl_p4c2719l746 - false: tbl_p4c2719l750 - hit: [ tbl_update_register_map_last ] - miss: tbl_update_register_map_last - indirect: tbl_p4c2719l746$tind - ternary_indirect tbl_p4c2719l746$tind: - row: 0 - bus: 0 - format: { action: 0..0 } - instruction: tbl_p4c2719l746$tind(action, $DEFAULT) - actions: - p4c2719l746(1, 2): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000032 - - next_table: 0 - - set update_register_reg2.0-3, update_register_reg1.0-3 - - set update_register_reg2.4-7, update_register_reg1.4-7 - default_action: p4c2719l746 - ternary_match tbl_p4c2719l750 2: - p4: { name: tbl_p4c2719l750, hidden: true } - hit: [ tbl_update_register_map_last ] - miss: tbl_update_register_map_last - indirect: tbl_p4c2719l750$tind - ternary_indirect tbl_p4c2719l750$tind: - row: 1 - bus: 0 - format: { action: 0..0 } - instruction: tbl_p4c2719l750$tind(action, $DEFAULT) - actions: - p4c2719l750(0, 4): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000033 - - next_table: 0 - - set update_register_reg2.0-3, 3 - - set update_register_reg2.4-7, 0 - default_action: p4c2719l750 -stage 9 egress: - dependency: match - ternary_match tbl_update_register_map_last 0: - p4: { name: tbl_update_register_map_last, hidden: true } - gateway: - name: cond-15 - input_xbar: - exact group 0: { 0: update_register_debt3, 16: update_register_debt4 } - row: 0 - bus: 0 - unit: 0 - match: { 0: update_register_debt4(0..7), 8: update_register_debt4(8..15) } - xor: { 0: update_register_debt3(0..7), 8: update_register_debt3(8..15) } - 0x0000: run_table - miss: tbl_update_register_map_last_0 - condition: - expression: "(update_register_debt4 == update_register_debt3)" - true: tbl_update_register_map_last - false: tbl_update_register_map_last_0 - hit: [ tbl_insert_capture ] - miss: tbl_insert_capture - indirect: tbl_update_register_map_last$tind - ternary_indirect tbl_update_register_map_last$tind: - row: 0 - bus: 0 - format: { action: 0..0 } - instruction: tbl_update_register_map_last$tind(action, $DEFAULT) - actions: - Egress.update_register.map_last_2(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000034 - - next_table: 0 - - set rich_register_0.4-7, update_register_capture_port(0..3) - - set rich_register_0.0-3, update_register_reg2.0-3 - default_action: Egress.update_register.map_last_2 - ternary_match tbl_update_register_map_last_0 1: - p4: { name: tbl_update_register_map_last_0, hidden: true } - hit: [ tbl_insert_capture ] - miss: tbl_insert_capture - indirect: tbl_update_register_map_last_0$tind - ternary_indirect tbl_update_register_map_last_0$tind: - row: 0 - bus: 1 - format: { action: 0..0 } - instruction: tbl_update_register_map_last_0$tind(action, $DEFAULT) - actions: - Egress.update_register.map_last_4(0, 2): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000035 - - next_table: 0 - - set rich_register_0.4-7, update_register_capture_port(0..3) - - set rich_register_0.0-3, 4 - default_action: Egress.update_register.map_last_4 -stage 10 egress: - dependency: action - ternary_match tbl_insert_capture 0: - p4: { name: tbl_insert_capture, hidden: true } - gateway: - name: cond-16 - input_xbar: - exact group 0: { 0: meta.ing_port_mirror.pkt_type } - row: 7 - bus: 0 - unit: 0 - match: { 0: meta.ing_port_mirror.pkt_type } - 0x03: run_table - miss: egressCaptureTbl_0 - condition: - expression: "(meta.ing_port_mirror.pkt_type == 3)" - true: tbl_insert_capture - false: egressCaptureTbl_0 - hit: [ egressCaptureTbl_0 ] - miss: egressCaptureTbl_0 - indirect: tbl_insert_capture$tind - ternary_indirect tbl_insert_capture$tind: - row: 0 - bus: 0 - format: { action: 0..0 } - instruction: tbl_insert_capture$tind(action, $DEFAULT) - actions: - Egress.insert_capture(1, 1): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000036 - - next_table: 0 - - set hdr.capture.timestamp, meta.ing_port_mirror.mac_timestamp - - deposit-field B18(4..7), B21(0..3), B19 - default_action: Egress.insert_capture - exact_match egressCaptureTbl_0 1: - p4: { name: Egress.egressCaptureTbl, size: 64 } - p4_param_order: - eg_intr_md.egress_port: { type: exact, size: 9, full_size: 9 } - row: 7 - bus: 0 - column: 2 - stash: - row: [ 7 ] - col: [ 2 ] - unit: [ 0 ] - ways: - - [0, 0, 0x0, [7, 2]] - input_xbar: - exact group 0: { 8: eg_intr_md.egress_port(8), 16: eg_intr_md.egress_port(0..7) } - hash 0: - 0: eg_intr_md.egress_port(8) - 1..8: eg_intr_md.egress_port(0..7) - hash group 0: - table: [0] - seed: 0x0 - format: { action(0): 0..0, immediate(0): 1..10, version(0): 112..115 } - match_group_map: [ [ 0 ] ] - hit: [ END ] - miss: END - action_bus: { 32..33 : immediate(0..9) } - instruction: egressCaptureTbl_0(action, $DEFAULT) - actions: - Egress.set_mirror_session_capture(0, 2): - - p4_param_order: { mirror_session: 10 } - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000037 - - next_table: 0 - - { mirror_session_3: immediate(0..9), mirror_session: mirror_session_3 } - - set eg_intr_md_for_dprsr.mirror_type, 2 - - set meta.mirror_session, mirror_session - - set meta.pkt_type, 3 - - set meta.ing_port_mirror.mac_timestamp, eg_intr_md_from_prsr.global_tstamp.0-31 - NoAction(1, 0): - - hit_allowed: { allowed: true } - - default_action: { allowed: true } - - handle: 0x20000038 - - next_table: 0 - - { } - default_action: NoAction - -flexible_headers: [ - - { name: "hdr.bridge", - fields: [ - - { name: "rich_register", slice: { start_bit: 0, bit_width: 8 } }, - { name: "pkt_type", slice: { start_bit: 0, bit_width: 8 } }, - { name: "__pad_0", slice: { start_bit: 0, bit_width: 4 } }, - { name: "rich_register_v", slice: { start_bit: 0, bit_width: 1 } }, - { name: "l23_rxtstmp_insert", slice: { start_bit: 0, bit_width: 1 } }, - { name: "l23_txtstmp_insert", slice: { start_bit: 0, bit_width: 1 } }, - { name: "l47_timestamp_insert", slice: { start_bit: 0, bit_width: 1 } } ] - }, - { name: "meta.bridge", - fields: [ - - { name: "rich_register", slice: { start_bit: 0, bit_width: 8 } }, - { name: "pkt_type", slice: { start_bit: 0, bit_width: 8 } }, - { name: "__pad_0", slice: { start_bit: 0, bit_width: 4 } }, - { name: "rich_register_v", slice: { start_bit: 0, bit_width: 1 } }, - { name: "l23_rxtstmp_insert", slice: { start_bit: 0, bit_width: 1 } }, - { name: "l23_txtstmp_insert", slice: { start_bit: 0, bit_width: 1 } }, - { name: "l47_timestamp_insert", slice: { start_bit: 0, bit_width: 1 } } ] - }] diff --git a/backends/tofino/bf-asm/test/asm/parser_value_set.tfa b/backends/tofino/bf-asm/test/asm/parser_value_set.tfa deleted file mode 100644 index 103da840f17..00000000000 --- a/backends/tofino/bf-asm/test/asm/parser_value_set.tfa +++ /dev/null @@ -1,23 +0,0 @@ -parser ingress: - start: state1 - multi_write: [ B0 ] - state1: - save: { byte0: 0, byte1: 1 } - shift: 2 - next: state2 - state2: - match: [ byte0 ] - value_set set1 5: - 0..3: W0 - B0: 1 - shift: 4 - next: end - 0x**: - next: state3 - state3: - match: [ byte1 ] - value_set set2 10: - 0..3: W1 - 4..7: W2 - B0: 2 - shift: 8 diff --git a/backends/tofino/bf-asm/test/asm/parser_zero_write.jba b/backends/tofino/bf-asm/test/asm/parser_zero_write.jba deleted file mode 100644 index 77347bc0493..00000000000 --- a/backends/tofino/bf-asm/test/asm/parser_zero_write.jba +++ /dev/null @@ -1,6 +0,0 @@ -parser ingress: - start: - B0: 0 - H0: 0 - W0: 0 - next: end diff --git a/backends/tofino/bf-asm/test/asm/rng.tfa b/backends/tofino/bf-asm/test/asm/rng.tfa deleted file mode 100644 index a57dae5103b..00000000000 --- a/backends/tofino/bf-asm/test/asm/rng.tfa +++ /dev/null @@ -1,22 +0,0 @@ -stage 0 ingress: - ternary_match test: - row: 11 - column: 0 - input_xbar: - group 0: { 0: W0 } - indirect: tind - ternary_indirect tind: - row: 0 - column: 2 - format: { action: 2, data: 8..15 } - action: atab(action) - action atab: - row: 15 - column: 0 - format: { misc : 8 } - actions: - act0: - - add B0, B0, rng(0, 0..7) - - add B1, B1, rng(0, 16..23) - act1: - - add H0, H0, rng(0, 0..15) diff --git a/backends/tofino/bf-asm/test/asm/stateful_multiple_output_error.tfa b/backends/tofino/bf-asm/test/asm/stateful_multiple_output_error.tfa deleted file mode 100644 index 301a780a7f0..00000000000 --- a/backends/tofino/bf-asm/test/asm/stateful_multiple_output_error.tfa +++ /dev/null @@ -1,348 +0,0 @@ -version: 1.0.0 -phv ingress: - ipv4.version: R288(4..7) - ipv4.ihl: R288(0..3) - ipv4.diffserv: R289 - ipv4.totalLen: R320 - ipv4.identification: R321 - ipv4.flags: R322(13..15) - ipv4.fragOffset: R322(0..12) - ipv4.ttl: R256(24..31) - ipv4.protocol: R256(16..23) - ipv4.hdrChecksum: R256(0..15) - ipv4.srcAddr: R257 - ipv4.dstAddr: R258 - ethernet.dstAddr.40-47: R290 - ethernet.dstAddr.8-39: R259 - ethernet.dstAddr.0-7: R323(8..15) - ethernet.srcAddr.40-47: R323(0..7) - ethernet.srcAddr.32-39: R291 - ethernet.srcAddr.0-31: R264 - ethernet.etherType: R324 - ig_intr_md.resubmit_flag: R128(15) - ig_intr_md._pad1: R128(14) - ig_intr_md._pad2: R128(12..13) - ig_intr_md._pad3: R128(9..11) - ig_intr_md.ingress_port: R128(0..8) - meta.bfd_discriminator: R129 - meta.bfd_timeout_detected: R128(8..15) - meta.bfd_tx_or_rx: R65 - ig_intr_md_for_tm.drop_ctl: R66(5..7) - __md_ingress.__init_0: R128(8..15) - POV-ethernet: R64(0) - POV-ipv4: R64(1) - POV-metadata_bridge: R64(2) -phv egress: - ipv4.version: R292(4..7) - ipv4.ihl: R292(0..3) - ipv4.diffserv: R293 - ipv4.totalLen: R326 - ipv4.identification: R327 - ipv4.flags: R328(13..15) - ipv4.fragOffset: R328(0..12) - ipv4.ttl: R260(24..31) - ipv4.protocol: R260(16..23) - ipv4.hdrChecksum: R260(0..15) - ipv4.srcAddr: R261 - ipv4.dstAddr: R262 - ethernet.dstAddr.40-47: R294 - ethernet.dstAddr.8-39: R263 - ethernet.dstAddr.0-7: R329(8..15) - ethernet.srcAddr.40-47: R329(0..7) - ethernet.srcAddr.32-39: R295 - ethernet.srcAddr.0-31: R268 - ethernet.etherType: R330 - eg_intr_md._pad0: R144(9..15) - eg_intr_md.egress_port: R144(0..8) - eg_intr_md._pad7: R80(3..7) - eg_intr_md.egress_cos: R80(0..2) - POV-ethernet: R81(0) - POV-ipv4: R81(1) -parser ingress: - start: [Shim_start_state, Shim_start_state, Shim_start_state, Shim_start_state] - Shim_start_state 0: - 0x0: - next: POV_initialization - offset: 0 - buf_req: 0 - parse_ethernet 1: - match: half - 0x800: - next: END - shift: 20 - offset: 0 - buf_req: 20 - R64: 2 - 8..11: R256 - 12..15: ipv4.srcAddr - 16..19: ipv4.dstAddr - 0: R288 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: R322 - 0x****: - next: END - offset: 0 - buf_req: 0 - Ingress_intrinsic_metadata 3: - match: byte0 - 0b0*******: - next: Phase_0 - save: {byte0: 0} - shift: 8 - offset: 0 - buf_req: 8 - Phase_0 4: - match: byte0 - 0x**: - next: start$ - offset: 0 - buf_req: 0 - R64: 4 - POV_initialization 5: - 0x0: - next: Ingress_intrinsic_metadata - save: {byte0: 0} - shift: 8 - offset: 0 - buf_req: 8 - 0..1: R128 - start$ 6: - 0x0: - next: parse_ethernet - save: {half: 12..13} - shift: 14 - offset: 0 - buf_req: 14 - R64: 1 - 1..4: ethernet.dstAddr.8-39 - 8..11: ethernet.srcAddr.0-31 - 0: ethernet.dstAddr.40-47 - 7: ethernet.srcAddr.32-39 - 5..6: R323 - 12..13: ethernet.etherType - multi_write: [R64, meta.bfd_tx_or_rx, R128, meta.bfd_discriminator] - init_zero: [R64, meta.bfd_tx_or_rx, R128, meta.bfd_discriminator] - hdr_len_adj: 16 -deparser ingress: - pov: [R64] - dictionary: - - R64: POV-metadata_bridge - - ethernet.dstAddr.40-47: POV-ethernet - - ethernet.dstAddr.8-39: POV-ethernet - - R323: POV-ethernet - - ethernet.srcAddr.32-39: POV-ethernet - - ethernet.srcAddr.0-31: POV-ethernet - - ethernet.etherType: POV-ethernet - - R288: POV-ipv4 - - ipv4.diffserv: POV-ipv4 - - ipv4.totalLen: POV-ipv4 - - ipv4.identification: POV-ipv4 - - R322: POV-ipv4 - - R256: POV-ipv4 - - ipv4.srcAddr: POV-ipv4 - - ipv4.dstAddr: POV-ipv4 - drop_ctl: ig_intr_md_for_tm.drop_ctl -parser egress: - start: [Shim_start_state, Shim_start_state, Shim_start_state, Shim_start_state] - Shim_start_state 0: - 0x0: - next: POV_initialization - offset: 0 - buf_req: 0 - parse_ethernet 1: - match: half - 0x800: - next: END - shift: 20 - offset: 0 - buf_req: 20 - R81: 2 - 8..11: R260 - 12..15: ipv4.srcAddr - 16..19: ipv4.dstAddr - 0: R292 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: R328 - 0x****: - next: END - offset: 0 - buf_req: 0 - POV_skip 3: - 0x0: - next: start$ - offset: 0 - buf_req: 0 - Egress_intrinsic_metadata 4: - match: byte0 - 0x**: - next: POV_skip - shift: 1 - offset: 0 - buf_req: 1 - POV_initialization 5: - 0x0: - next: Egress_intrinsic_metadata - save: {byte0: 3} - shift: 3 - offset: 0 - buf_req: 4 - 2: R80 - 0..1: R144 - start$ 6: - 0x0: - next: parse_ethernet - save: {half: 12..13} - shift: 14 - offset: 0 - buf_req: 14 - R81: 1 - 1..4: ethernet.dstAddr.8-39 - 8..11: ethernet.srcAddr.0-31 - 0: ethernet.dstAddr.40-47 - 7: ethernet.srcAddr.32-39 - 5..6: R329 - 12..13: ethernet.etherType - multi_write: [R81] - init_zero: [R81] - hdr_len_adj: 3 - meta_opt: 1024 -deparser egress: - pov: [R81] - dictionary: - - ethernet.dstAddr.40-47: POV-ethernet - - ethernet.dstAddr.8-39: POV-ethernet - - R329: POV-ethernet - - ethernet.srcAddr.32-39: POV-ethernet - - ethernet.srcAddr.0-31: POV-ethernet - - ethernet.etherType: POV-ethernet - - R292: POV-ipv4 - - ipv4.diffserv: POV-ipv4 - - ipv4.totalLen: POV-ipv4 - - ipv4.identification: POV-ipv4 - - R328: POV-ipv4 - - R260: POV-ipv4 - - ipv4.srcAddr: POV-ipv4 - - ipv4.dstAddr: POV-ipv4 - egress_unicast_port: eg_intr_md.egress_port - ecos: eg_intr_md.egress_cos -stage 0 ingress: - exact_match bfd 0: - p4: - name: bfd - handle: 16777217 - size: 1024 - match_type: exact - row: 7 - bus: 0 - column: [2, 3, 4] - ways: - - [0, 0, 0, [7, 2]] - - [0, 1, 0, [7, 3]] - - [0, 2, 0, [7, 4]] - input_xbar: - group 0: {0: meta.bfd_discriminator, 16: meta.bfd_tx_or_rx} - hash 0: - 0: 0xa98401 - 1: 0xd3a002 - 2: 0xdcd404 - 3: 0xd03808 - 4: 0xdc0810 - 5: 0xe2420 - 6: 0x3ef440 - 7: 0x7d8c80 - 8: 0x127900 - 9: 0x30ee00 - 10: 0xf07a00 - 11: 0x545c01 - 12: 0x629402 - 13: 0x47b404 - 14: 0xa5fc08 - 15: 0xee4810 - 16: 0xf1b420 - 17: 0xd7b440 - 18: 0x62ec80 - 19: 0x122900 - 20: 0xe04500 - 21: 0xd10600 - 22: 0x338401 - 23: 0x7c0c02 - 24: 0x8d4c04 - 25: 0xc22c08 - 26: 0x17d010 - 27: 0x6c0820 - 28: 0xdc7440 - 29: 0x5cf880 - hash group 0: - table: 0 - seed: 0x17b88dac - table_counter: table_hit - stateful: bfd_cnt(state_ptr) - format: {action(0): 1, state_ptr(0): 23, match(0): [24..31, 34..39], version(0): 120..123} - match: [meta.bfd_tx_or_rx, meta.bfd_discriminator(10..15)] - next: check_needs - actions: - bfd_tx 0: - - 1 - - deposit-field meta.bfd_timeout_detected, A0(0..7), R128 - bfd_rx 1: - - 2 - - deposit-field meta.bfd_timeout_detected, 0, R128 - stateful bfd_cnt: - p4: - name: bfd_cnt - handle: 100663297 - size: 1024 - row: 15 - bus: 0 - column: [0, 1] - maprams: [0, 1] - global_binding: true - format: {lo: 8} - actions: - 0: - - grt.u lo, lo, -3 - - equ hi, 1 - - add lo, lo, 1 - - a hi, 1 - - output cmplo, alu_hi - - output !cmplo, alu_lo - 1: - - equ lo, 1 - - equ hi, 1 - - a lo, 0 -stage 1 ingress: - dependency: match - exact_match check_needs 0: - p4: - name: check_needs - handle: 16777218 - size: 256 - match_type: exact - row: 7 - bus: 0 - column: 2 - ways: - - [0, 0, 0, [7, 2]] - input_xbar: - group 0: {8: meta.bfd_timeout_detected} - hash 0: - 0..7: meta.bfd_timeout_detected - hash group 0: 0 - table_counter: table_hit - format: {action(0): 1, match(0): 8..15, version(0): 120..123} - match: [meta.bfd_timeout_detected] - next: END - actions: - drop_me 0: - - 1 - - deposit-field ig_intr_md_for_tm.drop_ctl, 1, R66 - on_miss 1: - - 0 -stage 6 ingress: - dependency: match -stage 6 egress: - dependency: match diff --git a/backends/tofino/bf-asm/test/asm/switch_l2_profile_tofino.tfa b/backends/tofino/bf-asm/test/asm/switch_l2_profile_tofino.tfa deleted file mode 100644 index 3a381d8ddc9..00000000000 --- a/backends/tofino/bf-asm/test/asm/switch_l2_profile_tofino.tfa +++ /dev/null @@ -1,5453 +0,0 @@ -version: 1.0.0 -phv ingress: - standard_metadata.ingress_port: H14(0..8) - standard_metadata.egress_spec: H5(0..8) - standard_metadata.resubmit_flag: TW11(31) - $always_deparse: B9(7) - ingress_metadata.ingress_port: H15(0..8) - ingress_metadata.ifindex: H0 - ingress_metadata.egress_ifindex: H79 - ingress_metadata.port_type: H72(14..15) - ingress_metadata.bd: H3(0..13) - ingress_metadata.drop_flag: B61(6) - ingress_metadata.drop_reason: B8 - ingress_metadata.control_frame: B61(5) - ingress_metadata.bypass_lookups: H70 - ethernet.dstAddr.32-47: H10 - ethernet.dstAddr.16-31: H9 - ethernet.dstAddr.0-15: H8 - ethernet.srcAddr.32-47: H82 - ethernet.srcAddr.16-31: H81 - ethernet.srcAddr.0-15: H80 - ethernet.etherType: H86 - llc_header.dsap: TB10 - llc_header.ssap: TB9 - llc_header.control_: TB8 - snap_header.oui.16-23: TB2 - snap_header.oui.8-15: TB1 - snap_header.oui.0-7: TB0 - snap_header.type_: TH15 - vlan_tag_$0.pcp: H42(13..15) - vlan_tag_$0.cfi: H42(12) - vlan_tag_$0.vid: H42(0..11) - vlan_tag_$0.etherType: H87 - vlan_tag_$1.pcp: H32(13..15) - vlan_tag_$1.cfi: H32(12) - vlan_tag_$1.vid: H32(0..11) - vlan_tag_$1.etherType: H88 - ipv4.version: B49(4..7) - ipv4.ihl: B49(0..3) - ipv4.diffserv: B48 - ipv4.totalLen: H41 - ipv4.identification: H40 - ipv4.flags: H39(13..15) - ipv4.fragOffset: H39(0..12) - ipv4.ttl: B2 - ipv4.protocol: B4 - ipv4.hdrChecksum: H38 - ipv4.srcAddr: W10 - ipv4.dstAddr: W8 - icmp.typeCode: H67 - icmp.hdrChecksum: TH14 - l3_metadata.lkp_ip_type: H15(9..10) - l3_metadata.lkp_ip_version: B1(2..5) - l3_metadata.lkp_ip_proto: B5 - l3_metadata.lkp_ip_ttl: B3 - l3_metadata.lkp_l4_sport: H68 - l3_metadata.lkp_l4_dport: H64 - l3_metadata.lkp_outer_l4_sport: H69 - l3_metadata.lkp_outer_l4_dport: H65 - l3_metadata.rmac_group: H73(0..9) - l3_metadata.rmac_hit: B61(4) - l3_metadata.urpf_check_fail: B60(6) - l3_metadata.fib_hit: B60(5) - l3_metadata.same_bd_check: H4(0..13) - l3_metadata.nexthop_index: H91 - l3_metadata.routed: B60(4) - l3_metadata.l3_copy: B59(6) - ig_prsr_ctrl.priority: TW7(29..31) - tcp.srcPort: H67 - tcp.dstPort: H66 - tcp.seqNo: TW3 - tcp.ackNo: TW2 - tcp.dataOffset: TB6(4..7) - tcp.res: TB6(0..3) - tcp.flags: B15 - tcp.window: TH13 - tcp.checksum: TH12 - tcp.urgentPtr: TH11 - udp.srcPort: H67 - udp.dstPort: H66 - udp.length_: TH10 - udp.checksum: TH9 - ipv6.version: W12(28..31) - ipv6.trafficClass: W12(20..27) - ipv6.flowLabel: W12(0..19) - ipv6.payloadLen: H37 - ipv6.nextHdr: B14 - ipv6.hopLimit: B13 - ipv6.srcAddr.96-127: W7 - ipv6.srcAddr.64-95: W6 - ipv6.srcAddr.32-63: W5 - ipv6.srcAddr.0-31: W4 - ipv6.dstAddr.96-127: W3 - ipv6.dstAddr.64-95: W2 - ipv6.dstAddr.32-63: W1 - ipv6.dstAddr.0-31: W0 - tunnel_metadata.ingress_tunnel_type: B9(2..6) - tunnel_metadata.tunnel_terminate: B9(1) - tunnel_metadata.tunnel_if_check: B9(0) - inner_ipv4.version: B12(4..7) - inner_ipv4.ihl: B12(0..3) - inner_ipv4.diffserv: B11 - inner_ipv4.totalLen: H36 - inner_ipv4.identification: H35 - inner_ipv4.flags: H34(13..15) - inner_ipv4.fragOffset: H34(0..12) - inner_ipv4.ttl: B2 - inner_ipv4.protocol: B4 - inner_ipv4.hdrChecksum: H33 - inner_ipv4.srcAddr: W10 - inner_ipv4.dstAddr: W8 - ipv4_metadata.lkp_ipv4_sa: W11 - ipv4_metadata.lkp_ipv4_da: W9 - ipv4_metadata.ipv4_unicast_enabled: B59(5) - inner_icmp.typeCode: H67 - inner_icmp.hdrChecksum: TH8 - inner_tcp.srcPort: H67 - inner_tcp.dstPort: H66 - inner_tcp.seqNo: TW1 - inner_tcp.ackNo: TW0 - inner_tcp.dataOffset: TB5(4..7) - inner_tcp.res: TB5(0..3) - inner_tcp.flags: TB7 - inner_tcp.window: TH7 - inner_tcp.checksum: TH6 - inner_tcp.urgentPtr: TH5 - inner_udp.srcPort: H67 - inner_udp.dstPort: H66 - inner_udp.length_: TH4 - inner_udp.checksum: TH3 - fabric_header.packetType: TB4(5..7) - fabric_header.headerVersion: TB4(3..4) - fabric_header.packetVersion: TB4(1..2) - fabric_header.pad1: TB4(0) - fabric_header.fabricColor: TB3(5..7) - fabric_header.fabricQos: TB3(0..4) - fabric_header.dstDevice: B10 - fabric_header.dstPortOrGroup: H6 - fabric_header_cpu.egressQueue: B0(3..7) - fabric_header_cpu.txBypass: B0(2) - fabric_header_cpu.reserved: B0(0..1) - fabric_header_cpu.ingressPort: TH2 - fabric_header_cpu.ingressIfindex: TH1 - fabric_header_cpu.ingressBd: TH0 - fabric_header_cpu.reasonCode: H71 - fabric_payload_header.etherType: H89 - acl_metadata.acl_deny: B59(4) - acl_metadata.racl_deny: B58(6) - acl_metadata.acl_nexthop: H92 - acl_metadata.acl_nexthop_type: H73(14..15) - acl_metadata.acl_redirect: B58(5) - acl_metadata.racl_redirect: B58(4) - acl_metadata.if_label: H78 - acl_metadata.bd_label: H77 - acl_metadata.acl_stats_index: H75(0..13) - acl_metadata.ingress_src_port_range_id: B7 - acl_metadata.ingress_dst_port_range_id: B6 - l2_metadata.lkp_mac_sa.32-47: H85 - l2_metadata.lkp_mac_sa.16-31: H84 - l2_metadata.lkp_mac_sa.0-15: H83 - l2_metadata.lkp_mac_da.32-47: H13 - l2_metadata.lkp_mac_da.16-31: H12 - l2_metadata.lkp_mac_da.0-15: H11 - l2_metadata.lkp_pkt_type: H15(11..13) - l2_metadata.lkp_mac_type: H90 - l2_metadata.l2_nexthop: H93 - l2_metadata.l2_nexthop_type: H74(14..15) - l2_metadata.l2_redirect: B57(6) - l2_metadata.l2_src_miss: B57(5) - l2_metadata.l2_src_move: H1 - l2_metadata.stp_group: H72(0..9) - l2_metadata.stp_state: B63(4..6) - l2_metadata.bd_stats_idx: H7 - l2_metadata.learning_enabled: B57(4) - l2_metadata.port_vlan_mapping_miss: B56(6) - l2_metadata.same_if_check: H2 - ipv6_metadata.ipv6_unicast_enabled: H14(15) - ipv6_metadata.ipv6_src_is_link_local: H14(14) - multicast_metadata.mcast_route_hit: B56(5) - multicast_metadata.mcast_bridge_hit: B56(4) - multicast_metadata.igmp_snooping_enabled: B55(6) - multicast_metadata.mld_snooping_enabled: B55(5) - multicast_metadata.mcast_rpf_group: H74(0..13) - multicast_metadata.mcast_mode: H14(12..13) - egress_metadata.bypass: B1(0) - fabric_metadata.reason_code: H76 - nat_metadata.nat_hit: B55(4) - hash_metadata.hash1: H94 - hash_metadata.hash2: H95 - nexthop_metadata.nexthop_type: H75(14..15) - $learning: B62(0..2) - security_metadata.ipsg_check_fail: B54(6) - ethernet.$valid: B1(7) - fabric_header.$valid: B1(6) - fabric_header_cpu.$valid: B63(7) - fabric_payload_header.$valid: B62(7) - icmp.$valid: B61(7) - ig_prsr_ctrl.$valid: B60(7) - inner_icmp.$valid: B59(7) - inner_ipv4.$valid: B58(7) - inner_tcp.$valid: B57(7) - inner_udp.$valid: B56(7) - ipv4.$valid: B55(7) - ipv6.$valid: B54(7) - llc_header.$valid: B53(7) - snap_header.$valid: B52(7) - tcp.$valid: B51(7) - udp.$valid: B50(7) - vlan_tag_$0.$valid: H15(15) - vlan_tag_$1.$valid: H15(14) -phv egress: - standard_metadata.egress_port: H16(0..8) - ingress_metadata.ingress_port: H25(0..8) - ingress_metadata.ifindex: H26 - ingress_metadata.bd: H22(0..13) - l2_metadata.lkp_pkt_type: B22(2..4) - egress_metadata.bypass: B36(4) - egress_metadata.port_type: B21(3..4) - egress_metadata.bd: H23(0..13) - egress_metadata.routed: B18(6) - egress_metadata.ifindex: H48 - acl_metadata.acl_deny: H49(15) - fabric_metadata.fabric_header_present: B22(1) - fabric_metadata.reason_code: H28 - l3_metadata.nexthop_index: H31 - l3_metadata.l3_mtu_check: H30 - ethernet.dstAddr.32-47: TH29 - ethernet.dstAddr.16-31: TH28 - ethernet.dstAddr.0-15: TH27 - ethernet.srcAddr.32-47: TH26 - ethernet.srcAddr.16-31: TH25 - ethernet.srcAddr.0-15: TH24 - ethernet.etherType: H17 - llc_header.dsap: B31 - llc_header.ssap: B47 - llc_header.control_: B30 - snap_header.oui.16-23: TB18 - snap_header.oui.8-15: TB17 - snap_header.oui.0-7: TB16 - snap_header.type_: H63 - vlan_tag_$0.pcp: H51(13..15) - vlan_tag_$0.cfi: H51(12) - vlan_tag_$0.vid: H51(0..11) - vlan_tag_$0.etherType: H18 - vlan_tag_$1.pcp: H50(13..15) - vlan_tag_$1.cfi: H50(12) - vlan_tag_$1.vid: H50(0..11) - vlan_tag_$1.etherType: H19 - ipv4.version: B46(4..7) - ipv4.ihl: B46(0..3) - ipv4.diffserv: B45 - ipv4.totalLen: H62 - ipv4.identification: H61 - ipv4.flags: TH33(13..15) - ipv4.fragOffset: TH33(0..12) - ipv4.ttl: B29 - ipv4.protocol: B44 - ipv4.hdrChecksum: H60 - ipv4.srcAddr.16-31: TH31 - ipv4.srcAddr.0-15: TH30 - ipv4.dstAddr: TW31 - icmp.typeCode: H59 - icmp.hdrChecksum: H58 - tcp.srcPort: H57 - tcp.dstPort: H56 - tcp.seqNo: TW30 - tcp.ackNo: TW29 - tcp.dataOffset: B28(4..7) - tcp.res: B28(0..3) - tcp.flags: B43 - tcp.window: H55 - tcp.checksum: H54 - tcp.urgentPtr: H53 - udp.srcPort.8-15: TB31 - udp.srcPort.0-7: TB30 - udp.dstPort.8-15: TB29 - udp.dstPort.0-7: TB28 - udp.length_.8-15: TB27 - udp.length_.0-7: TB26 - udp.checksum.8-15: TB25 - udp.checksum.0-7: TB24 - ipv6.version: TW24(28..31) - ipv6.trafficClass: TW24(20..27) - ipv6.flowLabel: TW24(0..19) - ipv6.payloadLen.8-15: TB23 - ipv6.payloadLen.0-7: TB22 - ipv6.nextHdr: B27 - ipv6.hopLimit: B42 - ipv6.srcAddr.96-127: TW23 - ipv6.srcAddr.64-95: TW22 - ipv6.srcAddr.32-63: TW21 - ipv6.srcAddr.0-31: TW20 - ipv6.dstAddr.96-127: TW19 - ipv6.dstAddr.64-95: TW18 - ipv6.dstAddr.32-63: TW17 - ipv6.dstAddr.0-31: TW16 - inner_ipv4.version: B26(4..7) - inner_ipv4.ihl: B26(0..3) - inner_ipv4.diffserv: B41 - inner_ipv4.totalLen.8-15: TB21 - inner_ipv4.totalLen.0-7: TB20 - inner_ipv4.identification: TH47 - inner_ipv4.flags: TH32(13..15) - inner_ipv4.fragOffset: TH32(0..12) - inner_ipv4.ttl: B25 - inner_ipv4.protocol: B40 - inner_ipv4.hdrChecksum: TH46 - inner_ipv4.srcAddr: TW28 - inner_ipv4.dstAddr: TW27 - inner_icmp.typeCode: TH45 - inner_icmp.hdrChecksum: TH44 - inner_tcp.srcPort: TH43 - inner_tcp.dstPort: TH42 - inner_tcp.seqNo: TW26 - inner_tcp.ackNo: TW25 - inner_tcp.dataOffset: B24(4..7) - inner_tcp.res: B24(0..3) - inner_tcp.flags: B39 - inner_tcp.window: TH41 - inner_tcp.checksum: TH40 - inner_tcp.urgentPtr: TH39 - inner_udp.srcPort: TH38 - inner_udp.dstPort: TH37 - inner_udp.length_: TH36 - inner_udp.checksum: TH35 - fabric_header.packetType: B19(5..7) - fabric_header.headerVersion: B19(3..4) - fabric_header.packetVersion: B19(1..2) - fabric_header.pad1: B19(0) - fabric_header.fabricColor: TB19(5..7) - fabric_header.fabricQos: TB19(0..4) - fabric_header.dstDevice: B23 - fabric_header.dstPortOrGroup: TH34 - fabric_header_cpu.egressQueue: B38(3..7) - fabric_header_cpu.txBypass: B38(2) - fabric_header_cpu.reserved: B38(0..1) - fabric_header_cpu.ingressPort: H24 - fabric_header_cpu.ingressIfindex: H27 - fabric_header_cpu.ingressBd: H21 - fabric_header_cpu.reasonCode: H29 - fabric_payload_header.etherType: H20 - eg_intr_md.deflection_flag: B37(1) - eg_intr_md_from_parser_aux.clone_src: B17 - tunnel_metadata.egress_tunnel_type: B18(0..4) - tunnel_metadata.tunnel_index: H49(0..13) - tunnel_metadata.egress_header_count: H25(10..13) - multicast_metadata.replica: H25(15) - $mirror_id: B16 - $mirror: B37(2..4) - eg_intr_md.$valid: B18(7) - eg_intr_md_from_parser_aux.$valid: B22(7) - ethernet.$valid: B37(7) - fabric_header.$valid: B21(7) - fabric_header_cpu.$valid: B36(7) - fabric_payload_header.$valid: B20(7) - icmp.$valid: B35(7) - inner_icmp.$valid: B34(7) - inner_ipv4.$valid: B33(7) - inner_tcp.$valid: B32(7) - inner_udp.$valid: B22(6) - ipv4.$valid: B22(5) - ipv6.$valid: B37(6) - llc_header.$valid: B37(5) - snap_header.$valid: B21(6) - tcp.$valid: B21(5) - udp.$valid: B36(6) - vlan_tag_$0.$valid: B36(5) - vlan_tag_$1.$valid: B20(6) -parser ingress: - start: $ingress_metadata_shim - $ingress_metadata_shim: - match: [ 0 ] - 0b0*******: - $always_deparse: 1 - 0..3: TW11 - next: $ingress_metadata - 0b1*******: - $always_deparse: 1 - 0..3: TW11 - shift: 16 - next: start$ - $ingress_metadata: - 0x*: - 0..1: H14 - shift: 8 - next: $phase0 - $phase0: - 0x*: - next: $phase0_extract - $phase0_extract: - 0x*: - 0..1: ingress_metadata.ifindex - 2..3: H72 - shift: 8 - next: start$ - start$: - match: [ /* packet.lookahead>()[15:0]; */ ] - 0x*: - next: parse_ethernet - parse_ethernet: - match: [ 12..13 ] - 0o000***: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.0 - 0b00000*0*********: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.1 - 0x9000: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.2 - 0x8100: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.3 - 0x9100: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.4 - 0x8847: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.5 - 0x0800: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.6 - 0x86dd: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.7 - 0x0806: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.8 - 0x88cc: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.9 - 0x8809: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.10 - 0x*: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.11 - parse_ethernet.0: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: parse_llc_header - parse_llc_header: - match: [ 0, 1 ] - 0xaaaa: - 0: llc_header.dsap - 1: llc_header.ssap - 2: llc_header.control_ - llc_header.$valid: 1 - shift: 3 - next: parse_snap_header - 0xfefe: - 0: llc_header.dsap - 1: llc_header.ssap - 2: llc_header.control_ - llc_header.$valid: 1 - shift: 3 - next: parse_set_prio_med - 0x*: - 0: llc_header.dsap - 1: llc_header.ssap - 2: llc_header.control_ - llc_header.$valid: 1 - shift: 3 - next: end - parse_snap_header: - match: [ 3..4 ] - 0x8100: - 0: snap_header.oui.16-23 - 1: snap_header.oui.8-15 - 2: snap_header.oui.0-7 - 3..4: snap_header.type_ - snap_header.$valid: 1 - shift: 5 - next: parse_vlan - 0x9100: - 0: snap_header.oui.16-23 - 1: snap_header.oui.8-15 - 2: snap_header.oui.0-7 - 3..4: snap_header.type_ - snap_header.$valid: 1 - shift: 5 - next: parse_qinq - 0x8847: - 0: snap_header.oui.16-23 - 1: snap_header.oui.8-15 - 2: snap_header.oui.0-7 - 3..4: snap_header.type_ - snap_header.$valid: 1 - shift: 5 - next: end - 0x0800: - 0: snap_header.oui.16-23 - 1: snap_header.oui.8-15 - 2: snap_header.oui.0-7 - 3..4: snap_header.type_ - snap_header.$valid: 1 - shift: 5 - next: parse_ipv4 - 0x86dd: - 0: snap_header.oui.16-23 - 1: snap_header.oui.8-15 - 2: snap_header.oui.0-7 - 3..4: snap_header.type_ - snap_header.$valid: 1 - shift: 5 - next: parse_ipv6 - 0x0806: - 0: snap_header.oui.16-23 - 1: snap_header.oui.8-15 - 2: snap_header.oui.0-7 - 3..4: snap_header.type_ - snap_header.$valid: 1 - shift: 5 - next: parse_arp_rarp - 0x88cc: - 0: snap_header.oui.16-23 - 1: snap_header.oui.8-15 - 2: snap_header.oui.0-7 - 3..4: snap_header.type_ - snap_header.$valid: 1 - shift: 5 - next: parse_set_prio_high - 0x8809: - 0: snap_header.oui.16-23 - 1: snap_header.oui.8-15 - 2: snap_header.oui.0-7 - 3..4: snap_header.type_ - snap_header.$valid: 1 - shift: 5 - next: parse_set_prio_high - 0x*: - 0: snap_header.oui.16-23 - 1: snap_header.oui.8-15 - 2: snap_header.oui.0-7 - 3..4: snap_header.type_ - snap_header.$valid: 1 - shift: 5 - next: end - parse_vlan: - match: [ 2..3 ] - 0x8847: - 0..1: H42 - 2..3: vlan_tag_$0.etherType - vlan_tag_$0.$valid: 1 - shift: 4 - next: end - 0x0800: - 0..1: H42 - 2..3: vlan_tag_$0.etherType - vlan_tag_$0.$valid: 1 - shift: 4 - next: parse_ipv4 - 0x86dd: - 0..1: H42 - 2..3: vlan_tag_$0.etherType - vlan_tag_$0.$valid: 1 - shift: 4 - next: parse_ipv6 - 0x0806: - 0..1: H42 - 2..3: vlan_tag_$0.etherType - vlan_tag_$0.$valid: 1 - shift: 4 - next: parse_arp_rarp - 0x88cc: - 0..1: H42 - 2..3: vlan_tag_$0.etherType - vlan_tag_$0.$valid: 1 - shift: 4 - next: parse_set_prio_high - 0x8809: - 0..1: H42 - 2..3: vlan_tag_$0.etherType - vlan_tag_$0.$valid: 1 - shift: 4 - next: parse_set_prio_high - 0x*: - 0..1: H42 - 2..3: vlan_tag_$0.etherType - vlan_tag_$0.$valid: 1 - shift: 4 - next: end - parse_ipv4: - match: [ 6..7, 0, 9 ] - 0x0000501: - 0: B49 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: H39 - 8: ipv4.ttl - 9: ipv4.protocol - 10..11: ipv4.hdrChecksum - 12..15: ipv4.srcAddr - 16..19: ipv4.dstAddr - shift: 20 - next: parse_ipv4.0 - 0x0000506: - 0: B49 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: H39 - 8: ipv4.ttl - 9: ipv4.protocol - 10..11: ipv4.hdrChecksum - 12..15: ipv4.srcAddr - 16..19: ipv4.dstAddr - shift: 20 - next: parse_ipv4.1 - 0x0000511: - 0: B49 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: H39 - 8: ipv4.ttl - 9: ipv4.protocol - 10..11: ipv4.hdrChecksum - 12..15: ipv4.srcAddr - 16..19: ipv4.dstAddr - shift: 20 - next: parse_ipv4.2 - 0x0000002: - 0: B49 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: H39 - 8: ipv4.ttl - 9: ipv4.protocol - 10..11: ipv4.hdrChecksum - 12..15: ipv4.srcAddr - 16..19: ipv4.dstAddr - shift: 20 - next: parse_ipv4.3 - 0x0000058: - 0: B49 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: H39 - 8: ipv4.ttl - 9: ipv4.protocol - 10..11: ipv4.hdrChecksum - 12..15: ipv4.srcAddr - 16..19: ipv4.dstAddr - shift: 20 - next: parse_ipv4.4 - 0x0000059: - 0: B49 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: H39 - 8: ipv4.ttl - 9: ipv4.protocol - 10..11: ipv4.hdrChecksum - 12..15: ipv4.srcAddr - 16..19: ipv4.dstAddr - shift: 20 - next: parse_ipv4.5 - 0x0000067: - 0: B49 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: H39 - 8: ipv4.ttl - 9: ipv4.protocol - 10..11: ipv4.hdrChecksum - 12..15: ipv4.srcAddr - 16..19: ipv4.dstAddr - shift: 20 - next: parse_ipv4.6 - 0x0000070: - 0: B49 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: H39 - 8: ipv4.ttl - 9: ipv4.protocol - 10..11: ipv4.hdrChecksum - 12..15: ipv4.srcAddr - 16..19: ipv4.dstAddr - shift: 20 - next: parse_ipv4.7 - 0x*: - 0: B49 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: H39 - 8: ipv4.ttl - 9: ipv4.protocol - 10..11: ipv4.hdrChecksum - 12..15: ipv4.srcAddr - 16..19: ipv4.dstAddr - shift: 20 - next: parse_ipv4.8 - parse_ipv4.0: - 0x*: - ipv4.$valid: 1 - next: parse_icmp - parse_icmp: - match: [ 0..1 ] - 0o101***: - 0..1: icmp.typeCode - 2..3: icmp.hdrChecksum - icmp.$valid: 1 - l3_metadata.lkp_outer_l4_sport: 0 /* ingress::icmp.typeCode; */ - shift: 4 - next: parse_set_prio_med - 0b100001**********: - 0..1: icmp.typeCode - 2..3: icmp.hdrChecksum - icmp.$valid: 1 - l3_metadata.lkp_outer_l4_sport: 0 /* ingress::icmp.typeCode; */ - shift: 4 - next: parse_set_prio_med - 0x88**: - 0..1: icmp.typeCode - 2..3: icmp.hdrChecksum - icmp.$valid: 1 - l3_metadata.lkp_outer_l4_sport: 0 /* ingress::icmp.typeCode; */ - shift: 4 - next: parse_set_prio_med - 0x*: - 0..1: icmp.typeCode - 2..3: icmp.hdrChecksum - icmp.$valid: 1 - l3_metadata.lkp_outer_l4_sport: 0 /* ingress::icmp.typeCode; */ - shift: 4 - next: end - parse_set_prio_med: - 0x*: - ig_prsr_ctrl.priority: 3 - next: end - parse_ipv4.1: - 0x*: - ipv4.$valid: 1 - next: parse_tcp - parse_tcp: - match: [ 2..3 ] - 0x00b3: - 0..1: tcp.srcPort - 2..3: tcp.dstPort - 4..7: tcp.seqNo - 8..11: tcp.ackNo - 12: TB6 - 13: tcp.flags - 14..15: tcp.window - 16..17: tcp.checksum - shift: 18 - next: parse_tcp.0 - 0x027f: - 0..1: tcp.srcPort - 2..3: tcp.dstPort - 4..7: tcp.seqNo - 8..11: tcp.ackNo - 12: TB6 - 13: tcp.flags - 14..15: tcp.window - 16..17: tcp.checksum - shift: 18 - next: parse_tcp.1 - 0x*: - 0..1: tcp.srcPort - 2..3: tcp.dstPort - 4..7: tcp.seqNo - 8..11: tcp.ackNo - 12: TB6 - 13: tcp.flags - 14..15: tcp.window - 16..17: tcp.checksum - shift: 18 - next: parse_tcp.2 - parse_tcp.0: - 0x*: - 0..1: tcp.urgentPtr - tcp.$valid: 1 - l3_metadata.lkp_outer_l4_sport: 0 /* ingress::tcp.srcPort; */ - l3_metadata.lkp_outer_l4_dport: 0 /* ingress::tcp.dstPort; */ - shift: 2 - next: parse_set_prio_med - parse_tcp.1: - 0x*: - 0..1: tcp.urgentPtr - tcp.$valid: 1 - l3_metadata.lkp_outer_l4_sport: 0 /* ingress::tcp.srcPort; */ - l3_metadata.lkp_outer_l4_dport: 0 /* ingress::tcp.dstPort; */ - shift: 2 - next: parse_set_prio_med - parse_tcp.2: - 0x*: - 0..1: tcp.urgentPtr - tcp.$valid: 1 - l3_metadata.lkp_outer_l4_sport: 0 /* ingress::tcp.srcPort; */ - l3_metadata.lkp_outer_l4_dport: 0 /* ingress::tcp.dstPort; */ - shift: 2 - next: end - parse_ipv4.2: - 0x*: - ipv4.$valid: 1 - next: parse_udp - parse_udp: - match: [ 2..3 ] - 0x0043: - 0..1: udp.srcPort - 2..3: udp.dstPort - 4..5: udp.length_ - 6..7: udp.checksum - udp.$valid: 1 - shift: 9 - next: parse_udp.0 - 0x0044: - 0..1: udp.srcPort - 2..3: udp.dstPort - 4..5: udp.length_ - 6..7: udp.checksum - udp.$valid: 1 - shift: 9 - next: parse_udp.1 - 0x0222: - 0..1: udp.srcPort - 2..3: udp.dstPort - 4..5: udp.length_ - 6..7: udp.checksum - udp.$valid: 1 - shift: 9 - next: parse_udp.2 - 0x0223: - 0..1: udp.srcPort - 2..3: udp.dstPort - 4..5: udp.length_ - 6..7: udp.checksum - udp.$valid: 1 - shift: 9 - next: parse_udp.3 - 0x0208: - 0..1: udp.srcPort - 2..3: udp.dstPort - 4..5: udp.length_ - 6..7: udp.checksum - udp.$valid: 1 - shift: 9 - next: parse_udp.4 - 0x0209: - 0..1: udp.srcPort - 2..3: udp.dstPort - 4..5: udp.length_ - 6..7: udp.checksum - udp.$valid: 1 - shift: 9 - next: parse_udp.5 - 0x07c1: - 0..1: udp.srcPort - 2..3: udp.dstPort - 4..5: udp.length_ - 6..7: udp.checksum - udp.$valid: 1 - shift: 9 - next: parse_udp.6 - 0x18c7: - 0..1: udp.srcPort - 2..3: udp.dstPort - 4..5: udp.length_ - 6..7: udp.checksum - udp.$valid: 1 - shift: 9 - next: parse_udp.7 - 0x*: - 0..1: udp.srcPort - 2..3: udp.dstPort - 4..5: udp.length_ - 6..7: udp.checksum - udp.$valid: 1 - shift: 9 - next: parse_udp.8 - parse_udp.0: - 0x*: - l3_metadata.lkp_outer_l4_sport: 0 /* ingress::udp.srcPort; */ - l3_metadata.lkp_outer_l4_dport: 0 /* ingress::udp.dstPort; */ - # shift: -1 - next: parse_set_prio_med - parse_udp.1: - 0x*: - l3_metadata.lkp_outer_l4_sport: 0 /* ingress::udp.srcPort; */ - l3_metadata.lkp_outer_l4_dport: 0 /* ingress::udp.dstPort; */ - # shift: -1 - next: parse_set_prio_med - parse_udp.2: - 0x*: - l3_metadata.lkp_outer_l4_sport: 0 /* ingress::udp.srcPort; */ - l3_metadata.lkp_outer_l4_dport: 0 /* ingress::udp.dstPort; */ - # shift: -1 - next: parse_set_prio_med - parse_udp.3: - 0x*: - l3_metadata.lkp_outer_l4_sport: 0 /* ingress::udp.srcPort; */ - l3_metadata.lkp_outer_l4_dport: 0 /* ingress::udp.dstPort; */ - # shift: -1 - next: parse_set_prio_med - parse_udp.4: - 0x*: - l3_metadata.lkp_outer_l4_sport: 0 /* ingress::udp.srcPort; */ - l3_metadata.lkp_outer_l4_dport: 0 /* ingress::udp.dstPort; */ - # shift: -1 - next: parse_set_prio_med - parse_udp.5: - 0x*: - l3_metadata.lkp_outer_l4_sport: 0 /* ingress::udp.srcPort; */ - l3_metadata.lkp_outer_l4_dport: 0 /* ingress::udp.dstPort; */ - # shift: -1 - next: parse_set_prio_med - parse_udp.6: - 0x*: - l3_metadata.lkp_outer_l4_sport: 0 /* ingress::udp.srcPort; */ - l3_metadata.lkp_outer_l4_dport: 0 /* ingress::udp.dstPort; */ - # shift: -1 - next: parse_set_prio_med - parse_udp.7: - 0x*: - l3_metadata.lkp_outer_l4_sport: 0 /* ingress::udp.srcPort; */ - l3_metadata.lkp_outer_l4_dport: 0 /* ingress::udp.dstPort; */ - # shift: -1 - next: end - parse_udp.8: - 0x*: - l3_metadata.lkp_outer_l4_sport: 0 /* ingress::udp.srcPort; */ - l3_metadata.lkp_outer_l4_dport: 0 /* ingress::udp.dstPort; */ - # shift: -1 - next: end - parse_ipv4.3: - 0x*: - ipv4.$valid: 1 - next: parse_set_prio_med - parse_ipv4.4: - 0x*: - ipv4.$valid: 1 - next: parse_set_prio_med - parse_ipv4.5: - 0x*: - ipv4.$valid: 1 - next: parse_set_prio_med - parse_ipv4.6: - 0x*: - ipv4.$valid: 1 - next: parse_set_prio_med - parse_ipv4.7: - 0x*: - ipv4.$valid: 1 - next: parse_set_prio_med - parse_ipv4.8: - 0x*: - ipv4.$valid: 1 - next: end - parse_ipv6: - match: [ 6 ] - 0x3a: - 0..3: W12 - 4..5: ipv6.payloadLen - 6: ipv6.nextHdr - 7: ipv6.hopLimit - 8..11: ipv6.srcAddr.96-127 - 12..15: ipv6.srcAddr.64-95 - 16..19: ipv6.srcAddr.32-63 - shift: 20 - next: parse_ipv6.0 - 0x06: - 0..3: W12 - 4..5: ipv6.payloadLen - 6: ipv6.nextHdr - 7: ipv6.hopLimit - 8..11: ipv6.srcAddr.96-127 - 12..15: ipv6.srcAddr.64-95 - 16..19: ipv6.srcAddr.32-63 - shift: 20 - next: parse_ipv6.1 - 0x04: - 0..3: W12 - 4..5: ipv6.payloadLen - 6: ipv6.nextHdr - 7: ipv6.hopLimit - 8..11: ipv6.srcAddr.96-127 - 12..15: ipv6.srcAddr.64-95 - 16..19: ipv6.srcAddr.32-63 - shift: 20 - next: parse_ipv6.2 - 0x58: - 0..3: W12 - 4..5: ipv6.payloadLen - 6: ipv6.nextHdr - 7: ipv6.hopLimit - 8..11: ipv6.srcAddr.96-127 - 12..15: ipv6.srcAddr.64-95 - 16..19: ipv6.srcAddr.32-63 - shift: 20 - next: parse_ipv6.3 - 0x59: - 0..3: W12 - 4..5: ipv6.payloadLen - 6: ipv6.nextHdr - 7: ipv6.hopLimit - 8..11: ipv6.srcAddr.96-127 - 12..15: ipv6.srcAddr.64-95 - 16..19: ipv6.srcAddr.32-63 - shift: 20 - next: parse_ipv6.4 - 0x67: - 0..3: W12 - 4..5: ipv6.payloadLen - 6: ipv6.nextHdr - 7: ipv6.hopLimit - 8..11: ipv6.srcAddr.96-127 - 12..15: ipv6.srcAddr.64-95 - 16..19: ipv6.srcAddr.32-63 - shift: 20 - next: parse_ipv6.5 - 0x70: - 0..3: W12 - 4..5: ipv6.payloadLen - 6: ipv6.nextHdr - 7: ipv6.hopLimit - 8..11: ipv6.srcAddr.96-127 - 12..15: ipv6.srcAddr.64-95 - 16..19: ipv6.srcAddr.32-63 - shift: 20 - next: parse_ipv6.6 - 0x*: - 0..3: W12 - 4..5: ipv6.payloadLen - 6: ipv6.nextHdr - 7: ipv6.hopLimit - 8..11: ipv6.srcAddr.96-127 - 12..15: ipv6.srcAddr.64-95 - 16..19: ipv6.srcAddr.32-63 - shift: 20 - next: parse_ipv6.7 - parse_ipv6.0: - 0x*: - 0..3: ipv6.srcAddr.0-31 - 4..7: ipv6.dstAddr.96-127 - 8..11: ipv6.dstAddr.64-95 - 12..15: ipv6.dstAddr.32-63 - shift: 16 - next: parse_ipv6.0.0 - parse_ipv6.0.0: - 0x*: - 0..3: ipv6.dstAddr.0-31 - ipv6.$valid: 1 - shift: 4 - next: parse_icmp - parse_ipv6.1: - 0x*: - 0..3: ipv6.srcAddr.0-31 - 4..7: ipv6.dstAddr.96-127 - 8..11: ipv6.dstAddr.64-95 - 12..15: ipv6.dstAddr.32-63 - shift: 16 - next: parse_ipv6.1.0 - parse_ipv6.1.0: - 0x*: - 0..3: ipv6.dstAddr.0-31 - ipv6.$valid: 1 - shift: 4 - next: parse_tcp - parse_ipv6.2: - 0x*: - 0..3: ipv6.srcAddr.0-31 - 4..7: ipv6.dstAddr.96-127 - 8..11: ipv6.dstAddr.64-95 - 12..15: ipv6.dstAddr.32-63 - shift: 16 - next: parse_ipv6.2.0 - parse_ipv6.2.0: - 0x*: - 0..3: ipv6.dstAddr.0-31 - ipv6.$valid: 1 - shift: 4 - next: parse_ipv4_in_ip - parse_ipv4_in_ip: - 0x*: - tunnel_metadata.ingress_tunnel_type: 3 - next: parse_inner_ipv4 - parse_inner_ipv4: - match: [ 6..7, 0, 9 ] - 0x0000501: - 0: B12 - 1: inner_ipv4.diffserv - 2..3: inner_ipv4.totalLen - 4..5: inner_ipv4.identification - 6..7: H34 - 8: inner_ipv4.ttl - 9: inner_ipv4.protocol - 10..11: inner_ipv4.hdrChecksum - 12..15: inner_ipv4.srcAddr - 16..19: inner_ipv4.dstAddr - shift: 20 - next: parse_inner_ipv4.0 - 0x0000506: - 0: B12 - 1: inner_ipv4.diffserv - 2..3: inner_ipv4.totalLen - 4..5: inner_ipv4.identification - 6..7: H34 - 8: inner_ipv4.ttl - 9: inner_ipv4.protocol - 10..11: inner_ipv4.hdrChecksum - 12..15: inner_ipv4.srcAddr - 16..19: inner_ipv4.dstAddr - shift: 20 - next: parse_inner_ipv4.1 - 0x0000511: - 0: B12 - 1: inner_ipv4.diffserv - 2..3: inner_ipv4.totalLen - 4..5: inner_ipv4.identification - 6..7: H34 - 8: inner_ipv4.ttl - 9: inner_ipv4.protocol - 10..11: inner_ipv4.hdrChecksum - 12..15: inner_ipv4.srcAddr - 16..19: inner_ipv4.dstAddr - shift: 20 - next: parse_inner_ipv4.2 - 0x*: - 0: B12 - 1: inner_ipv4.diffserv - 2..3: inner_ipv4.totalLen - 4..5: inner_ipv4.identification - 6..7: H34 - 8: inner_ipv4.ttl - 9: inner_ipv4.protocol - 10..11: inner_ipv4.hdrChecksum - 12..15: inner_ipv4.srcAddr - 16..19: inner_ipv4.dstAddr - shift: 20 - next: parse_inner_ipv4.3 - parse_inner_ipv4.0: - 0x*: - inner_ipv4.$valid: 1 - ipv4_metadata.lkp_ipv4_sa: 0 /* ingress::inner_ipv4.srcAddr; */ - ipv4_metadata.lkp_ipv4_da: 0 /* ingress::inner_ipv4.dstAddr; */ - l3_metadata.lkp_ip_proto: 0 /* ingress::inner_ipv4.protocol; */ - l3_metadata.lkp_ip_ttl: 0 /* ingress::inner_ipv4.ttl; */ - next: parse_inner_icmp - parse_inner_icmp: - 0x*: - 0..1: inner_icmp.typeCode - 2..3: inner_icmp.hdrChecksum - inner_icmp.$valid: 1 - l3_metadata.lkp_l4_sport: 0 /* ingress::inner_icmp.typeCode; */ - shift: 4 - next: end - parse_inner_ipv4.1: - 0x*: - inner_ipv4.$valid: 1 - ipv4_metadata.lkp_ipv4_sa: 0 /* ingress::inner_ipv4.srcAddr; */ - ipv4_metadata.lkp_ipv4_da: 0 /* ingress::inner_ipv4.dstAddr; */ - l3_metadata.lkp_ip_proto: 0 /* ingress::inner_ipv4.protocol; */ - l3_metadata.lkp_ip_ttl: 0 /* ingress::inner_ipv4.ttl; */ - next: parse_inner_tcp - parse_inner_tcp: - 0x*: - 0..1: inner_tcp.srcPort - 2..3: inner_tcp.dstPort - 4..7: inner_tcp.seqNo - 8..11: inner_tcp.ackNo - 12: TB5 - 13: inner_tcp.flags - 14..15: inner_tcp.window - 16..17: inner_tcp.checksum - shift: 18 - next: parse_inner_tcp.0 - parse_inner_tcp.0: - 0x*: - 0..1: inner_tcp.urgentPtr - inner_tcp.$valid: 1 - l3_metadata.lkp_l4_sport: 0 /* ingress::inner_tcp.srcPort; */ - l3_metadata.lkp_l4_dport: 0 /* ingress::inner_tcp.dstPort; */ - shift: 2 - next: end - parse_inner_ipv4.2: - 0x*: - inner_ipv4.$valid: 1 - ipv4_metadata.lkp_ipv4_sa: 0 /* ingress::inner_ipv4.srcAddr; */ - ipv4_metadata.lkp_ipv4_da: 0 /* ingress::inner_ipv4.dstAddr; */ - l3_metadata.lkp_ip_proto: 0 /* ingress::inner_ipv4.protocol; */ - l3_metadata.lkp_ip_ttl: 0 /* ingress::inner_ipv4.ttl; */ - next: parse_inner_udp - parse_inner_udp: - 0x*: - 0..1: inner_udp.srcPort - 2..3: inner_udp.dstPort - 4..5: inner_udp.length_ - 6..7: inner_udp.checksum - inner_udp.$valid: 1 - shift: 9 - next: parse_inner_udp.0 - parse_inner_udp.0: - 0x*: - l3_metadata.lkp_l4_sport: 0 /* ingress::inner_udp.srcPort; */ - l3_metadata.lkp_l4_dport: 0 /* ingress::inner_udp.dstPort; */ - # shift: -1 - next: end - parse_inner_ipv4.3: - 0x*: - inner_ipv4.$valid: 1 - ipv4_metadata.lkp_ipv4_sa: 0 /* ingress::inner_ipv4.srcAddr; */ - ipv4_metadata.lkp_ipv4_da: 0 /* ingress::inner_ipv4.dstAddr; */ - l3_metadata.lkp_ip_proto: 0 /* ingress::inner_ipv4.protocol; */ - l3_metadata.lkp_ip_ttl: 0 /* ingress::inner_ipv4.ttl; */ - next: end - parse_ipv6.3: - 0x*: - 0..3: ipv6.srcAddr.0-31 - 4..7: ipv6.dstAddr.96-127 - 8..11: ipv6.dstAddr.64-95 - 12..15: ipv6.dstAddr.32-63 - shift: 16 - next: parse_ipv6.3.0 - parse_ipv6.3.0: - 0x*: - 0..3: ipv6.dstAddr.0-31 - ipv6.$valid: 1 - shift: 4 - next: parse_set_prio_med - parse_ipv6.4: - 0x*: - 0..3: ipv6.srcAddr.0-31 - 4..7: ipv6.dstAddr.96-127 - 8..11: ipv6.dstAddr.64-95 - 12..15: ipv6.dstAddr.32-63 - shift: 16 - next: parse_ipv6.4.0 - parse_ipv6.4.0: - 0x*: - 0..3: ipv6.dstAddr.0-31 - ipv6.$valid: 1 - shift: 4 - next: parse_set_prio_med - parse_ipv6.5: - 0x*: - 0..3: ipv6.srcAddr.0-31 - 4..7: ipv6.dstAddr.96-127 - 8..11: ipv6.dstAddr.64-95 - 12..15: ipv6.dstAddr.32-63 - shift: 16 - next: parse_ipv6.5.0 - parse_ipv6.5.0: - 0x*: - 0..3: ipv6.dstAddr.0-31 - ipv6.$valid: 1 - shift: 4 - next: parse_set_prio_med - parse_ipv6.6: - 0x*: - 0..3: ipv6.srcAddr.0-31 - 4..7: ipv6.dstAddr.96-127 - 8..11: ipv6.dstAddr.64-95 - 12..15: ipv6.dstAddr.32-63 - shift: 16 - next: parse_ipv6.6.0 - parse_ipv6.6.0: - 0x*: - 0..3: ipv6.dstAddr.0-31 - ipv6.$valid: 1 - shift: 4 - next: parse_set_prio_med - parse_ipv6.7: - 0x*: - 0..3: ipv6.srcAddr.0-31 - 4..7: ipv6.dstAddr.96-127 - 8..11: ipv6.dstAddr.64-95 - 12..15: ipv6.dstAddr.32-63 - shift: 16 - next: parse_ipv6.7.0 - parse_ipv6.7.0: - 0x*: - 0..3: ipv6.dstAddr.0-31 - ipv6.$valid: 1 - shift: 4 - next: end - parse_arp_rarp: - 0x*: - next: parse_set_prio_med - parse_set_prio_high: - 0x*: - ig_prsr_ctrl.priority: 5 - next: end - parse_qinq: - match: [ 2..3 ] - 0x8100: - 0..1: H42 - 2..3: vlan_tag_$0.etherType - vlan_tag_$0.$valid: 1 - shift: 4 - next: parse_qinq_vlan - 0x*: - 0..1: H42 - 2..3: vlan_tag_$0.etherType - vlan_tag_$0.$valid: 1 - shift: 4 - next: end - parse_qinq_vlan: - match: [ 2..3 ] - 0x8847: - 0..1: H32 - 2..3: vlan_tag_$1.etherType - vlan_tag_$1.$valid: 1 - shift: 4 - next: end - 0x0800: - 0..1: H32 - 2..3: vlan_tag_$1.etherType - vlan_tag_$1.$valid: 1 - shift: 4 - next: parse_ipv4 - 0x86dd: - 0..1: H32 - 2..3: vlan_tag_$1.etherType - vlan_tag_$1.$valid: 1 - shift: 4 - next: parse_ipv6 - 0x0806: - 0..1: H32 - 2..3: vlan_tag_$1.etherType - vlan_tag_$1.$valid: 1 - shift: 4 - next: parse_arp_rarp - 0x88cc: - 0..1: H32 - 2..3: vlan_tag_$1.etherType - vlan_tag_$1.$valid: 1 - shift: 4 - next: parse_set_prio_high - 0x8809: - 0..1: H32 - 2..3: vlan_tag_$1.etherType - vlan_tag_$1.$valid: 1 - shift: 4 - next: parse_set_prio_high - 0x*: - 0..1: H32 - 2..3: vlan_tag_$1.etherType - vlan_tag_$1.$valid: 1 - shift: 4 - next: end - parse_ethernet.1: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: parse_llc_header - parse_ethernet.2: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: parse_fabric_header - parse_fabric_header: - match: [ 0 ] - 0x5: - 0: TB4 - 1: TB3 - 2: fabric_header.dstDevice - 3..4: fabric_header.dstPortOrGroup - fabric_header.$valid: 1 - shift: 5 - next: parse_fabric_header_cpu - 0x*: - 0: TB4 - 1: TB3 - 2: fabric_header.dstDevice - 3..4: fabric_header.dstPortOrGroup - fabric_header.$valid: 1 - shift: 5 - next: end - parse_fabric_header_cpu: - match: [ 7..8 ] - 0x*: - 0: B0 - 1..2: fabric_header_cpu.ingressPort - 3..4: fabric_header_cpu.ingressIfindex - 5..6: fabric_header_cpu.ingressBd - 7..8: fabric_header_cpu.reasonCode - fabric_header_cpu.$valid: 1 - shift: 10 - next: parse_fabric_header_cpu.0 - parse_fabric_header_cpu.0: - 0x*: - ingress_metadata.bypass_lookups: 0 /* ingress::fabric_header_cpu.reasonCode; */ - # shift: -1 - next: parse_fabric_payload_header - parse_fabric_payload_header: - match: [ 0..1 ] - 0o000***: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: parse_llc_header - 0b00000*0*********: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: parse_llc_header - 0x8100: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: parse_vlan - 0x9100: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: parse_qinq - 0x8847: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: end - 0x0800: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: parse_ipv4 - 0x86dd: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: parse_ipv6 - 0x0806: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: parse_arp_rarp - 0x88cc: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: parse_set_prio_high - 0x8809: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: parse_set_prio_high - 0x*: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: end - parse_ethernet.3: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: parse_vlan - parse_ethernet.4: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: parse_qinq - parse_ethernet.5: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: end - parse_ethernet.6: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: parse_ipv4 - parse_ethernet.7: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: parse_ipv6 - parse_ethernet.8: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: parse_arp_rarp - parse_ethernet.9: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: parse_set_prio_high - parse_ethernet.10: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: parse_set_prio_high - parse_ethernet.11: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: end -deparser ingress: - dictionary: - ingress_metadata.ifindex: $always_deparse - H15: $always_deparse - H3: $always_deparse - B1: $always_deparse - B59: $always_deparse - fabric_metadata.reason_code: $always_deparse - l3_metadata.nexthop_index: $always_deparse - ethernet.dstAddr.32-47: ethernet.$valid - ethernet.dstAddr.16-31: ethernet.$valid - ethernet.dstAddr.0-15: ethernet.$valid - ethernet.srcAddr.32-47: ethernet.$valid - ethernet.srcAddr.16-31: ethernet.$valid - ethernet.srcAddr.0-15: ethernet.$valid - ethernet.etherType: ethernet.$valid - TB4: fabric_header.$valid - TB3: fabric_header.$valid - fabric_header.dstDevice: fabric_header.$valid - fabric_header.dstPortOrGroup: fabric_header.$valid - B0: fabric_header_cpu.$valid - fabric_header_cpu.ingressPort: fabric_header_cpu.$valid - fabric_header_cpu.ingressIfindex: fabric_header_cpu.$valid - fabric_header_cpu.ingressBd: fabric_header_cpu.$valid - fabric_header_cpu.reasonCode: fabric_header_cpu.$valid - fabric_payload_header.etherType: fabric_payload_header.$valid - llc_header.dsap: llc_header.$valid - llc_header.ssap: llc_header.$valid - llc_header.control_: llc_header.$valid - snap_header.oui.16-23: snap_header.$valid - snap_header.oui.8-15: snap_header.$valid - snap_header.oui.0-7: snap_header.$valid - snap_header.type_: snap_header.$valid - H42: vlan_tag_$0.$valid - vlan_tag_$0.etherType: vlan_tag_$0.$valid - H32: vlan_tag_$1.$valid - vlan_tag_$1.etherType: vlan_tag_$1.$valid - W12: ipv6.$valid - ipv6.payloadLen: ipv6.$valid - ipv6.nextHdr: ipv6.$valid - ipv6.hopLimit: ipv6.$valid - ipv6.srcAddr.96-127: ipv6.$valid - ipv6.srcAddr.64-95: ipv6.$valid - ipv6.srcAddr.32-63: ipv6.$valid - ipv6.srcAddr.0-31: ipv6.$valid - ipv6.dstAddr.96-127: ipv6.$valid - ipv6.dstAddr.64-95: ipv6.$valid - ipv6.dstAddr.32-63: ipv6.$valid - ipv6.dstAddr.0-31: ipv6.$valid - B12: inner_ipv4.$valid - inner_ipv4.diffserv: inner_ipv4.$valid - inner_ipv4.totalLen: inner_ipv4.$valid - inner_ipv4.identification: inner_ipv4.$valid - H34: inner_ipv4.$valid - inner_ipv4.ttl: inner_ipv4.$valid - inner_ipv4.protocol: inner_ipv4.$valid - inner_ipv4.hdrChecksum: inner_ipv4.$valid - inner_ipv4.srcAddr: inner_ipv4.$valid - inner_ipv4.dstAddr: inner_ipv4.$valid - inner_udp.srcPort: inner_udp.$valid - inner_udp.dstPort: inner_udp.$valid - inner_udp.length_: inner_udp.$valid - inner_udp.checksum: inner_udp.$valid - inner_tcp.srcPort: inner_tcp.$valid - inner_tcp.dstPort: inner_tcp.$valid - inner_tcp.seqNo: inner_tcp.$valid - inner_tcp.ackNo: inner_tcp.$valid - TB5: inner_tcp.$valid - inner_tcp.flags: inner_tcp.$valid - inner_tcp.window: inner_tcp.$valid - inner_tcp.checksum: inner_tcp.$valid - inner_tcp.urgentPtr: inner_tcp.$valid - inner_icmp.typeCode: inner_icmp.$valid - inner_icmp.hdrChecksum: inner_icmp.$valid - B49: ipv4.$valid - ipv4.diffserv: ipv4.$valid - ipv4.totalLen: ipv4.$valid - ipv4.identification: ipv4.$valid - H39: ipv4.$valid - ipv4.ttl: ipv4.$valid - ipv4.protocol: ipv4.$valid - ipv4.hdrChecksum: ipv4.$valid - ipv4.srcAddr: ipv4.$valid - ipv4.dstAddr: ipv4.$valid - udp.srcPort: udp.$valid - udp.dstPort: udp.$valid - udp.length_: udp.$valid - udp.checksum: udp.$valid - tcp.srcPort: tcp.$valid - tcp.dstPort: tcp.$valid - tcp.seqNo: tcp.$valid - tcp.ackNo: tcp.$valid - TB6: tcp.$valid - tcp.flags: tcp.$valid - tcp.window: tcp.$valid - tcp.checksum: tcp.$valid - tcp.urgentPtr: tcp.$valid - icmp.typeCode: icmp.$valid - icmp.hdrChecksum: icmp.$valid - egress_unicast_port: standard_metadata.egress_spec - learning: - 0: [ $learning, H3, l2_metadata.lkp_mac_sa.32-47, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.0-15, ingress_metadata.ifindex ] - select: $learning -parser egress: - start: $egress_metadata_shim - $egress_metadata_shim: - 0x*: - 0..1: H16 - shift: 2 - next: $bridge_metadata_extract - $bridge_metadata_extract: - 0x*: - 0..1: ingress_metadata.ifindex - 2..3: H25 - shift: 4 - next: $bridge_metadata_extract.0 - $bridge_metadata_extract.0: - 0x*: - 0: B22 - shift: 1 - next: $bridge_metadata_extract.1 - $bridge_metadata_extract.1: - 0x*: - 0..1: H22 - shift: 2 - next: $bridge_metadata_extract.2 - $bridge_metadata_extract.2: - 0x*: - 0: B36 - shift: 1 - next: $bridge_metadata_extract.3 - $bridge_metadata_extract.3: - 0x*: - 0..1: H49 - shift: 1 - next: $bridge_metadata_extract.4 - $bridge_metadata_extract.4: - 0x*: - 0..1: fabric_metadata.reason_code - 2..3: l3_metadata.nexthop_index - shift: 4 - next: start$ - start$: - match: [ /* packet.lookahead>()[15:0]; */ ] - 0x*: - next: parse_ethernet - parse_ethernet: - match: [ 12..13 ] - 0o000***: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.0 - 0b00000*0*********: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.1 - 0x9000: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.2 - 0x8100: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.3 - 0x9100: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.4 - 0x8847: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.5 - 0x0800: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.6 - 0x86dd: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.7 - 0x0806: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.8 - 0x88cc: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.9 - 0x8809: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.10 - 0x*: - 0..1: ethernet.dstAddr.32-47 - 2..3: ethernet.dstAddr.16-31 - 4..5: ethernet.dstAddr.0-15 - 6..7: ethernet.srcAddr.32-47 - shift: 8 - next: parse_ethernet.11 - parse_ethernet.0: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: parse_llc_header - parse_llc_header: - match: [ 0, 1 ] - 0xaaaa: - 0: llc_header.dsap - 1: llc_header.ssap - 2: llc_header.control_ - llc_header.$valid: 1 - shift: 3 - next: parse_snap_header - 0xfefe: - 0: llc_header.dsap - 1: llc_header.ssap - 2: llc_header.control_ - llc_header.$valid: 1 - shift: 3 - next: end - 0x*: - 0: llc_header.dsap - 1: llc_header.ssap - 2: llc_header.control_ - llc_header.$valid: 1 - shift: 3 - next: end - parse_snap_header: - match: [ 3..4 ] - 0x8100: - 0: snap_header.oui.16-23 - 1: snap_header.oui.8-15 - 2: snap_header.oui.0-7 - 3..4: snap_header.type_ - snap_header.$valid: 1 - shift: 5 - next: parse_vlan - 0x9100: - 0: snap_header.oui.16-23 - 1: snap_header.oui.8-15 - 2: snap_header.oui.0-7 - 3..4: snap_header.type_ - snap_header.$valid: 1 - shift: 5 - next: parse_qinq - 0x8847: - 0: snap_header.oui.16-23 - 1: snap_header.oui.8-15 - 2: snap_header.oui.0-7 - 3..4: snap_header.type_ - snap_header.$valid: 1 - shift: 5 - next: end - 0x0800: - 0: snap_header.oui.16-23 - 1: snap_header.oui.8-15 - 2: snap_header.oui.0-7 - 3..4: snap_header.type_ - snap_header.$valid: 1 - shift: 5 - next: parse_ipv4 - 0x86dd: - 0: snap_header.oui.16-23 - 1: snap_header.oui.8-15 - 2: snap_header.oui.0-7 - 3..4: snap_header.type_ - snap_header.$valid: 1 - shift: 5 - next: parse_ipv6 - 0x0806: - 0: snap_header.oui.16-23 - 1: snap_header.oui.8-15 - 2: snap_header.oui.0-7 - 3..4: snap_header.type_ - snap_header.$valid: 1 - shift: 5 - next: end - 0x88cc: - 0: snap_header.oui.16-23 - 1: snap_header.oui.8-15 - 2: snap_header.oui.0-7 - 3..4: snap_header.type_ - snap_header.$valid: 1 - shift: 5 - next: end - 0x8809: - 0: snap_header.oui.16-23 - 1: snap_header.oui.8-15 - 2: snap_header.oui.0-7 - 3..4: snap_header.type_ - snap_header.$valid: 1 - shift: 5 - next: end - 0x*: - 0: snap_header.oui.16-23 - 1: snap_header.oui.8-15 - 2: snap_header.oui.0-7 - 3..4: snap_header.type_ - snap_header.$valid: 1 - shift: 5 - next: end - parse_vlan: - match: [ 2..3 ] - 0x8847: - 0..1: H51 - 2..3: vlan_tag_$0.etherType - vlan_tag_$0.$valid: 1 - shift: 4 - next: end - 0x0800: - 0..1: H51 - 2..3: vlan_tag_$0.etherType - vlan_tag_$0.$valid: 1 - shift: 4 - next: parse_ipv4 - 0x86dd: - 0..1: H51 - 2..3: vlan_tag_$0.etherType - vlan_tag_$0.$valid: 1 - shift: 4 - next: parse_ipv6 - 0x0806: - 0..1: H51 - 2..3: vlan_tag_$0.etherType - vlan_tag_$0.$valid: 1 - shift: 4 - next: end - 0x88cc: - 0..1: H51 - 2..3: vlan_tag_$0.etherType - vlan_tag_$0.$valid: 1 - shift: 4 - next: end - 0x8809: - 0..1: H51 - 2..3: vlan_tag_$0.etherType - vlan_tag_$0.$valid: 1 - shift: 4 - next: end - 0x*: - 0..1: H51 - 2..3: vlan_tag_$0.etherType - vlan_tag_$0.$valid: 1 - shift: 4 - next: end - parse_ipv4: - match: [ 6..7, 0, 9 ] - 0x0000501: - 0: B46 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: TH33 - 8: ipv4.ttl - 9: ipv4.protocol - 10..11: ipv4.hdrChecksum - shift: 12 - next: parse_ipv4.0 - 0x0000506: - 0: B46 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: TH33 - 8: ipv4.ttl - 9: ipv4.protocol - 10..11: ipv4.hdrChecksum - shift: 12 - next: parse_ipv4.1 - 0x0000511: - 0: B46 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: TH33 - 8: ipv4.ttl - 9: ipv4.protocol - 10..11: ipv4.hdrChecksum - shift: 12 - next: parse_ipv4.2 - 0x0000002: - 0: B46 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: TH33 - 8: ipv4.ttl - 9: ipv4.protocol - 10..11: ipv4.hdrChecksum - shift: 12 - next: parse_ipv4.3 - 0x0000058: - 0: B46 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: TH33 - 8: ipv4.ttl - 9: ipv4.protocol - 10..11: ipv4.hdrChecksum - shift: 12 - next: parse_ipv4.4 - 0x0000059: - 0: B46 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: TH33 - 8: ipv4.ttl - 9: ipv4.protocol - 10..11: ipv4.hdrChecksum - shift: 12 - next: parse_ipv4.5 - 0x0000067: - 0: B46 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: TH33 - 8: ipv4.ttl - 9: ipv4.protocol - 10..11: ipv4.hdrChecksum - shift: 12 - next: parse_ipv4.6 - 0x0000070: - 0: B46 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: TH33 - 8: ipv4.ttl - 9: ipv4.protocol - 10..11: ipv4.hdrChecksum - shift: 12 - next: parse_ipv4.7 - 0x*: - 0: B46 - 1: ipv4.diffserv - 2..3: ipv4.totalLen - 4..5: ipv4.identification - 6..7: TH33 - 8: ipv4.ttl - 9: ipv4.protocol - 10..11: ipv4.hdrChecksum - shift: 12 - next: parse_ipv4.8 - parse_ipv4.0: - 0x*: - 0..1: ipv4.srcAddr.16-31 - 2..3: ipv4.srcAddr.0-15 - 4..7: ipv4.dstAddr - ipv4.$valid: 1 - shift: 8 - next: parse_icmp - parse_icmp: - match: [ 0..1 ] - 0o101***: - 0..1: icmp.typeCode - 2..3: icmp.hdrChecksum - icmp.$valid: 1 - shift: 4 - next: end - 0b100001**********: - 0..1: icmp.typeCode - 2..3: icmp.hdrChecksum - icmp.$valid: 1 - shift: 4 - next: end - 0x88**: - 0..1: icmp.typeCode - 2..3: icmp.hdrChecksum - icmp.$valid: 1 - shift: 4 - next: end - 0x*: - 0..1: icmp.typeCode - 2..3: icmp.hdrChecksum - icmp.$valid: 1 - shift: 4 - next: end - parse_ipv4.1: - 0x*: - 0..1: ipv4.srcAddr.16-31 - 2..3: ipv4.srcAddr.0-15 - 4..7: ipv4.dstAddr - ipv4.$valid: 1 - shift: 8 - next: parse_tcp - parse_tcp: - match: [ 2..3 ] - 0x00b3: - 0..1: tcp.srcPort - 2..3: tcp.dstPort - 4..7: tcp.seqNo - 8..11: tcp.ackNo - 12: B28 - 13: tcp.flags - 14..15: tcp.window - 16..17: tcp.checksum - shift: 18 - next: parse_tcp.0 - 0x027f: - 0..1: tcp.srcPort - 2..3: tcp.dstPort - 4..7: tcp.seqNo - 8..11: tcp.ackNo - 12: B28 - 13: tcp.flags - 14..15: tcp.window - 16..17: tcp.checksum - shift: 18 - next: parse_tcp.1 - 0x*: - 0..1: tcp.srcPort - 2..3: tcp.dstPort - 4..7: tcp.seqNo - 8..11: tcp.ackNo - 12: B28 - 13: tcp.flags - 14..15: tcp.window - 16..17: tcp.checksum - shift: 18 - next: parse_tcp.2 - parse_tcp.0: - 0x*: - 0..1: tcp.urgentPtr - tcp.$valid: 1 - shift: 2 - next: end - parse_tcp.1: - 0x*: - 0..1: tcp.urgentPtr - tcp.$valid: 1 - shift: 2 - next: end - parse_tcp.2: - 0x*: - 0..1: tcp.urgentPtr - tcp.$valid: 1 - shift: 2 - next: end - parse_ipv4.2: - 0x*: - 0..1: ipv4.srcAddr.16-31 - 2..3: ipv4.srcAddr.0-15 - 4..7: ipv4.dstAddr - ipv4.$valid: 1 - shift: 8 - next: parse_udp - parse_udp: - match: [ 2..3 ] - 0x0043: - 0: udp.srcPort.8-15 - 1: udp.srcPort.0-7 - 2: udp.dstPort.8-15 - 3: udp.dstPort.0-7 - shift: 4 - next: parse_udp.0 - 0x0044: - 0: udp.srcPort.8-15 - 1: udp.srcPort.0-7 - 2: udp.dstPort.8-15 - 3: udp.dstPort.0-7 - shift: 4 - next: parse_udp.1 - 0x0222: - 0: udp.srcPort.8-15 - 1: udp.srcPort.0-7 - 2: udp.dstPort.8-15 - 3: udp.dstPort.0-7 - shift: 4 - next: parse_udp.2 - 0x0223: - 0: udp.srcPort.8-15 - 1: udp.srcPort.0-7 - 2: udp.dstPort.8-15 - 3: udp.dstPort.0-7 - shift: 4 - next: parse_udp.3 - 0x0208: - 0: udp.srcPort.8-15 - 1: udp.srcPort.0-7 - 2: udp.dstPort.8-15 - 3: udp.dstPort.0-7 - shift: 4 - next: parse_udp.4 - 0x0209: - 0: udp.srcPort.8-15 - 1: udp.srcPort.0-7 - 2: udp.dstPort.8-15 - 3: udp.dstPort.0-7 - shift: 4 - next: parse_udp.5 - 0x07c1: - 0: udp.srcPort.8-15 - 1: udp.srcPort.0-7 - 2: udp.dstPort.8-15 - 3: udp.dstPort.0-7 - shift: 4 - next: parse_udp.6 - 0x18c7: - 0: udp.srcPort.8-15 - 1: udp.srcPort.0-7 - 2: udp.dstPort.8-15 - 3: udp.dstPort.0-7 - shift: 4 - next: parse_udp.7 - 0x*: - 0: udp.srcPort.8-15 - 1: udp.srcPort.0-7 - 2: udp.dstPort.8-15 - 3: udp.dstPort.0-7 - shift: 4 - next: parse_udp.8 - parse_udp.0: - 0x*: - 0: udp.length_.8-15 - 1: udp.length_.0-7 - 2: udp.checksum.8-15 - 3: udp.checksum.0-7 - shift: 4 - next: parse_udp.0.0 - parse_udp.0.0: - 0x*: - udp.$valid: 1 - next: end - parse_udp.1: - 0x*: - 0: udp.length_.8-15 - 1: udp.length_.0-7 - 2: udp.checksum.8-15 - 3: udp.checksum.0-7 - shift: 4 - next: parse_udp.1.0 - parse_udp.1.0: - 0x*: - udp.$valid: 1 - next: end - parse_udp.2: - 0x*: - 0: udp.length_.8-15 - 1: udp.length_.0-7 - 2: udp.checksum.8-15 - 3: udp.checksum.0-7 - shift: 4 - next: parse_udp.2.0 - parse_udp.2.0: - 0x*: - udp.$valid: 1 - next: end - parse_udp.3: - 0x*: - 0: udp.length_.8-15 - 1: udp.length_.0-7 - 2: udp.checksum.8-15 - 3: udp.checksum.0-7 - shift: 4 - next: parse_udp.3.0 - parse_udp.3.0: - 0x*: - udp.$valid: 1 - next: end - parse_udp.4: - 0x*: - 0: udp.length_.8-15 - 1: udp.length_.0-7 - 2: udp.checksum.8-15 - 3: udp.checksum.0-7 - shift: 4 - next: parse_udp.4.0 - parse_udp.4.0: - 0x*: - udp.$valid: 1 - next: end - parse_udp.5: - 0x*: - 0: udp.length_.8-15 - 1: udp.length_.0-7 - 2: udp.checksum.8-15 - 3: udp.checksum.0-7 - shift: 4 - next: parse_udp.5.0 - parse_udp.5.0: - 0x*: - udp.$valid: 1 - next: end - parse_udp.6: - 0x*: - 0: udp.length_.8-15 - 1: udp.length_.0-7 - 2: udp.checksum.8-15 - 3: udp.checksum.0-7 - shift: 4 - next: parse_udp.6.0 - parse_udp.6.0: - 0x*: - udp.$valid: 1 - next: end - parse_udp.7: - 0x*: - 0: udp.length_.8-15 - 1: udp.length_.0-7 - 2: udp.checksum.8-15 - 3: udp.checksum.0-7 - shift: 4 - next: parse_udp.7.0 - parse_udp.7.0: - 0x*: - udp.$valid: 1 - next: end - parse_udp.8: - 0x*: - 0: udp.length_.8-15 - 1: udp.length_.0-7 - 2: udp.checksum.8-15 - 3: udp.checksum.0-7 - shift: 4 - next: parse_udp.8.0 - parse_udp.8.0: - 0x*: - udp.$valid: 1 - next: end - parse_ipv4.3: - 0x*: - 0..1: ipv4.srcAddr.16-31 - 2..3: ipv4.srcAddr.0-15 - 4..7: ipv4.dstAddr - ipv4.$valid: 1 - shift: 8 - next: end - parse_ipv4.4: - 0x*: - 0..1: ipv4.srcAddr.16-31 - 2..3: ipv4.srcAddr.0-15 - 4..7: ipv4.dstAddr - ipv4.$valid: 1 - shift: 8 - next: end - parse_ipv4.5: - 0x*: - 0..1: ipv4.srcAddr.16-31 - 2..3: ipv4.srcAddr.0-15 - 4..7: ipv4.dstAddr - ipv4.$valid: 1 - shift: 8 - next: end - parse_ipv4.6: - 0x*: - 0..1: ipv4.srcAddr.16-31 - 2..3: ipv4.srcAddr.0-15 - 4..7: ipv4.dstAddr - ipv4.$valid: 1 - shift: 8 - next: end - parse_ipv4.7: - 0x*: - 0..1: ipv4.srcAddr.16-31 - 2..3: ipv4.srcAddr.0-15 - 4..7: ipv4.dstAddr - ipv4.$valid: 1 - shift: 8 - next: end - parse_ipv4.8: - 0x*: - 0..1: ipv4.srcAddr.16-31 - 2..3: ipv4.srcAddr.0-15 - 4..7: ipv4.dstAddr - ipv4.$valid: 1 - shift: 8 - next: end - parse_ipv6: - match: [ 6 ] - 0x3a: - 0..3: TW24 - 4: ipv6.payloadLen.8-15 - 5: ipv6.payloadLen.0-7 - 6: ipv6.nextHdr - 7: ipv6.hopLimit - 8..11: ipv6.srcAddr.96-127 - 12..15: ipv6.srcAddr.64-95 - 16..19: ipv6.srcAddr.32-63 - shift: 20 - next: parse_ipv6.0 - 0x06: - 0..3: TW24 - 4: ipv6.payloadLen.8-15 - 5: ipv6.payloadLen.0-7 - 6: ipv6.nextHdr - 7: ipv6.hopLimit - 8..11: ipv6.srcAddr.96-127 - 12..15: ipv6.srcAddr.64-95 - 16..19: ipv6.srcAddr.32-63 - shift: 20 - next: parse_ipv6.1 - 0x04: - 0..3: TW24 - 4: ipv6.payloadLen.8-15 - 5: ipv6.payloadLen.0-7 - 6: ipv6.nextHdr - 7: ipv6.hopLimit - 8..11: ipv6.srcAddr.96-127 - 12..15: ipv6.srcAddr.64-95 - 16..19: ipv6.srcAddr.32-63 - shift: 20 - next: parse_ipv6.2 - 0x58: - 0..3: TW24 - 4: ipv6.payloadLen.8-15 - 5: ipv6.payloadLen.0-7 - 6: ipv6.nextHdr - 7: ipv6.hopLimit - 8..11: ipv6.srcAddr.96-127 - 12..15: ipv6.srcAddr.64-95 - 16..19: ipv6.srcAddr.32-63 - shift: 20 - next: parse_ipv6.3 - 0x59: - 0..3: TW24 - 4: ipv6.payloadLen.8-15 - 5: ipv6.payloadLen.0-7 - 6: ipv6.nextHdr - 7: ipv6.hopLimit - 8..11: ipv6.srcAddr.96-127 - 12..15: ipv6.srcAddr.64-95 - 16..19: ipv6.srcAddr.32-63 - shift: 20 - next: parse_ipv6.4 - 0x67: - 0..3: TW24 - 4: ipv6.payloadLen.8-15 - 5: ipv6.payloadLen.0-7 - 6: ipv6.nextHdr - 7: ipv6.hopLimit - 8..11: ipv6.srcAddr.96-127 - 12..15: ipv6.srcAddr.64-95 - 16..19: ipv6.srcAddr.32-63 - shift: 20 - next: parse_ipv6.5 - 0x70: - 0..3: TW24 - 4: ipv6.payloadLen.8-15 - 5: ipv6.payloadLen.0-7 - 6: ipv6.nextHdr - 7: ipv6.hopLimit - 8..11: ipv6.srcAddr.96-127 - 12..15: ipv6.srcAddr.64-95 - 16..19: ipv6.srcAddr.32-63 - shift: 20 - next: parse_ipv6.6 - 0x*: - 0..3: TW24 - 4: ipv6.payloadLen.8-15 - 5: ipv6.payloadLen.0-7 - 6: ipv6.nextHdr - 7: ipv6.hopLimit - 8..11: ipv6.srcAddr.96-127 - 12..15: ipv6.srcAddr.64-95 - 16..19: ipv6.srcAddr.32-63 - shift: 20 - next: parse_ipv6.7 - parse_ipv6.0: - 0x*: - 0..3: ipv6.srcAddr.0-31 - 4..7: ipv6.dstAddr.96-127 - 8..11: ipv6.dstAddr.64-95 - 12..15: ipv6.dstAddr.32-63 - shift: 16 - next: parse_ipv6.0.0 - parse_ipv6.0.0: - 0x*: - 0..3: ipv6.dstAddr.0-31 - ipv6.$valid: 1 - shift: 4 - next: parse_icmp - parse_ipv6.1: - 0x*: - 0..3: ipv6.srcAddr.0-31 - 4..7: ipv6.dstAddr.96-127 - 8..11: ipv6.dstAddr.64-95 - 12..15: ipv6.dstAddr.32-63 - shift: 16 - next: parse_ipv6.1.0 - parse_ipv6.1.0: - 0x*: - 0..3: ipv6.dstAddr.0-31 - ipv6.$valid: 1 - shift: 4 - next: parse_tcp - parse_ipv6.2: - 0x*: - 0..3: ipv6.srcAddr.0-31 - 4..7: ipv6.dstAddr.96-127 - 8..11: ipv6.dstAddr.64-95 - 12..15: ipv6.dstAddr.32-63 - shift: 16 - next: parse_ipv6.2.0 - parse_ipv6.2.0: - 0x*: - 0..3: ipv6.dstAddr.0-31 - ipv6.$valid: 1 - shift: 4 - next: parse_ipv4_in_ip - parse_ipv4_in_ip: - 0x*: - next: parse_inner_ipv4 - parse_inner_ipv4: - match: [ 6..7, 0, 9 ] - 0x0000501: - 0: B26 - 1: inner_ipv4.diffserv - 2: inner_ipv4.totalLen.8-15 - 3: inner_ipv4.totalLen.0-7 - 4..5: inner_ipv4.identification - 6..7: TH32 - shift: 8 - next: parse_inner_ipv4.0 - 0x0000506: - 0: B26 - 1: inner_ipv4.diffserv - 2: inner_ipv4.totalLen.8-15 - 3: inner_ipv4.totalLen.0-7 - 4..5: inner_ipv4.identification - 6..7: TH32 - shift: 8 - next: parse_inner_ipv4.1 - 0x0000511: - 0: B26 - 1: inner_ipv4.diffserv - 2: inner_ipv4.totalLen.8-15 - 3: inner_ipv4.totalLen.0-7 - 4..5: inner_ipv4.identification - 6..7: TH32 - shift: 8 - next: parse_inner_ipv4.2 - 0x*: - 0: B26 - 1: inner_ipv4.diffserv - 2: inner_ipv4.totalLen.8-15 - 3: inner_ipv4.totalLen.0-7 - 4..5: inner_ipv4.identification - 6..7: TH32 - shift: 8 - next: parse_inner_ipv4.3 - parse_inner_ipv4.0: - 0x*: - 0: inner_ipv4.ttl - 1: inner_ipv4.protocol - 2..3: inner_ipv4.hdrChecksum - 4..7: inner_ipv4.srcAddr - 8..11: inner_ipv4.dstAddr - inner_ipv4.$valid: 1 - shift: 12 - next: parse_inner_icmp - parse_inner_icmp: - 0x*: - 0..1: inner_icmp.typeCode - 2..3: inner_icmp.hdrChecksum - inner_icmp.$valid: 1 - shift: 4 - next: end - parse_inner_ipv4.1: - 0x*: - 0: inner_ipv4.ttl - 1: inner_ipv4.protocol - 2..3: inner_ipv4.hdrChecksum - 4..7: inner_ipv4.srcAddr - 8..11: inner_ipv4.dstAddr - inner_ipv4.$valid: 1 - shift: 12 - next: parse_inner_tcp - parse_inner_tcp: - 0x*: - 0..1: inner_tcp.srcPort - 2..3: inner_tcp.dstPort - 4..7: inner_tcp.seqNo - 8..11: inner_tcp.ackNo - 12: B24 - 13: inner_tcp.flags - 14..15: inner_tcp.window - 16..17: inner_tcp.checksum - shift: 18 - next: parse_inner_tcp.0 - parse_inner_tcp.0: - 0x*: - 0..1: inner_tcp.urgentPtr - inner_tcp.$valid: 1 - shift: 2 - next: end - parse_inner_ipv4.2: - 0x*: - 0: inner_ipv4.ttl - 1: inner_ipv4.protocol - 2..3: inner_ipv4.hdrChecksum - 4..7: inner_ipv4.srcAddr - 8..11: inner_ipv4.dstAddr - inner_ipv4.$valid: 1 - shift: 12 - next: parse_inner_udp - parse_inner_udp: - 0x*: - 0..1: inner_udp.srcPort - 2..3: inner_udp.dstPort - 4..5: inner_udp.length_ - 6..7: inner_udp.checksum - inner_udp.$valid: 1 - shift: 8 - next: end - parse_inner_ipv4.3: - 0x*: - 0: inner_ipv4.ttl - 1: inner_ipv4.protocol - 2..3: inner_ipv4.hdrChecksum - 4..7: inner_ipv4.srcAddr - 8..11: inner_ipv4.dstAddr - inner_ipv4.$valid: 1 - shift: 12 - next: end - parse_ipv6.3: - 0x*: - 0..3: ipv6.srcAddr.0-31 - 4..7: ipv6.dstAddr.96-127 - 8..11: ipv6.dstAddr.64-95 - 12..15: ipv6.dstAddr.32-63 - shift: 16 - next: parse_ipv6.3.0 - parse_ipv6.3.0: - 0x*: - 0..3: ipv6.dstAddr.0-31 - ipv6.$valid: 1 - shift: 4 - next: end - parse_ipv6.4: - 0x*: - 0..3: ipv6.srcAddr.0-31 - 4..7: ipv6.dstAddr.96-127 - 8..11: ipv6.dstAddr.64-95 - 12..15: ipv6.dstAddr.32-63 - shift: 16 - next: parse_ipv6.4.0 - parse_ipv6.4.0: - 0x*: - 0..3: ipv6.dstAddr.0-31 - ipv6.$valid: 1 - shift: 4 - next: end - parse_ipv6.5: - 0x*: - 0..3: ipv6.srcAddr.0-31 - 4..7: ipv6.dstAddr.96-127 - 8..11: ipv6.dstAddr.64-95 - 12..15: ipv6.dstAddr.32-63 - shift: 16 - next: parse_ipv6.5.0 - parse_ipv6.5.0: - 0x*: - 0..3: ipv6.dstAddr.0-31 - ipv6.$valid: 1 - shift: 4 - next: end - parse_ipv6.6: - 0x*: - 0..3: ipv6.srcAddr.0-31 - 4..7: ipv6.dstAddr.96-127 - 8..11: ipv6.dstAddr.64-95 - 12..15: ipv6.dstAddr.32-63 - shift: 16 - next: parse_ipv6.6.0 - parse_ipv6.6.0: - 0x*: - 0..3: ipv6.dstAddr.0-31 - ipv6.$valid: 1 - shift: 4 - next: end - parse_ipv6.7: - 0x*: - 0..3: ipv6.srcAddr.0-31 - 4..7: ipv6.dstAddr.96-127 - 8..11: ipv6.dstAddr.64-95 - 12..15: ipv6.dstAddr.32-63 - shift: 16 - next: parse_ipv6.7.0 - parse_ipv6.7.0: - 0x*: - 0..3: ipv6.dstAddr.0-31 - ipv6.$valid: 1 - shift: 4 - next: end - parse_qinq: - match: [ 2..3 ] - 0x8100: - 0..1: H51 - 2..3: vlan_tag_$0.etherType - vlan_tag_$0.$valid: 1 - shift: 4 - next: parse_qinq_vlan - 0x*: - 0..1: H51 - 2..3: vlan_tag_$0.etherType - vlan_tag_$0.$valid: 1 - shift: 4 - next: end - parse_qinq_vlan: - match: [ 2..3 ] - 0x8847: - 0..1: H50 - 2..3: vlan_tag_$1.etherType - vlan_tag_$1.$valid: 1 - shift: 4 - next: end - 0x0800: - 0..1: H50 - 2..3: vlan_tag_$1.etherType - vlan_tag_$1.$valid: 1 - shift: 4 - next: parse_ipv4 - 0x86dd: - 0..1: H50 - 2..3: vlan_tag_$1.etherType - vlan_tag_$1.$valid: 1 - shift: 4 - next: parse_ipv6 - 0x0806: - 0..1: H50 - 2..3: vlan_tag_$1.etherType - vlan_tag_$1.$valid: 1 - shift: 4 - next: end - 0x88cc: - 0..1: H50 - 2..3: vlan_tag_$1.etherType - vlan_tag_$1.$valid: 1 - shift: 4 - next: end - 0x8809: - 0..1: H50 - 2..3: vlan_tag_$1.etherType - vlan_tag_$1.$valid: 1 - shift: 4 - next: end - 0x*: - 0..1: H50 - 2..3: vlan_tag_$1.etherType - vlan_tag_$1.$valid: 1 - shift: 4 - next: end - parse_ethernet.1: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: parse_llc_header - parse_ethernet.2: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: parse_fabric_header - parse_fabric_header: - match: [ 0 ] - 0x5: - 0: B19 - 1: TB19 - 2: fabric_header.dstDevice - 3..4: fabric_header.dstPortOrGroup - fabric_header.$valid: 1 - shift: 5 - next: parse_fabric_header_cpu - 0x*: - 0: B19 - 1: TB19 - 2: fabric_header.dstDevice - 3..4: fabric_header.dstPortOrGroup - fabric_header.$valid: 1 - shift: 5 - next: end - parse_fabric_header_cpu: - match: [ 7..8 ] - 0x*: - 0: B38 - 1..2: fabric_header_cpu.ingressPort - 3..4: fabric_header_cpu.ingressIfindex - 5..6: fabric_header_cpu.ingressBd - 7..8: fabric_header_cpu.reasonCode - fabric_header_cpu.$valid: 1 - shift: 9 - next: parse_fabric_payload_header - parse_fabric_payload_header: - match: [ 0..1 ] - 0o000***: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: parse_llc_header - 0b00000*0*********: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: parse_llc_header - 0x8100: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: parse_vlan - 0x9100: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: parse_qinq - 0x8847: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: end - 0x0800: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: parse_ipv4 - 0x86dd: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: parse_ipv6 - 0x0806: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: end - 0x88cc: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: end - 0x8809: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: end - 0x*: - 0..1: fabric_payload_header.etherType - fabric_payload_header.$valid: 1 - shift: 2 - next: end - parse_ethernet.3: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: parse_vlan - parse_ethernet.4: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: parse_qinq - parse_ethernet.5: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: end - parse_ethernet.6: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: parse_ipv4 - parse_ethernet.7: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: parse_ipv6 - parse_ethernet.8: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: end - parse_ethernet.9: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: end - parse_ethernet.10: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: end - parse_ethernet.11: - 0x*: - 0..1: ethernet.srcAddr.16-31 - 2..3: ethernet.srcAddr.0-15 - 4..5: ethernet.etherType - ethernet.$valid: 1 - shift: 6 - next: end -deparser egress: - dictionary: - ethernet.dstAddr.32-47: ethernet.$valid - ethernet.dstAddr.16-31: ethernet.$valid - ethernet.dstAddr.0-15: ethernet.$valid - ethernet.srcAddr.32-47: ethernet.$valid - ethernet.srcAddr.16-31: ethernet.$valid - ethernet.srcAddr.0-15: ethernet.$valid - ethernet.etherType: ethernet.$valid - B19: fabric_header.$valid - TB19: fabric_header.$valid - fabric_header.dstDevice: fabric_header.$valid - fabric_header.dstPortOrGroup: fabric_header.$valid - B38: fabric_header_cpu.$valid - fabric_header_cpu.ingressPort: fabric_header_cpu.$valid - fabric_header_cpu.ingressIfindex: fabric_header_cpu.$valid - fabric_header_cpu.ingressBd: fabric_header_cpu.$valid - fabric_header_cpu.reasonCode: fabric_header_cpu.$valid - fabric_payload_header.etherType: fabric_payload_header.$valid - llc_header.dsap: llc_header.$valid - llc_header.ssap: llc_header.$valid - llc_header.control_: llc_header.$valid - snap_header.oui.16-23: snap_header.$valid - snap_header.oui.8-15: snap_header.$valid - snap_header.oui.0-7: snap_header.$valid - snap_header.type_: snap_header.$valid - H51: vlan_tag_$0.$valid - vlan_tag_$0.etherType: vlan_tag_$0.$valid - H51: vlan_tag_$0.$valid - vlan_tag_$0.etherType: vlan_tag_$0.$valid - H50: vlan_tag_$1.$valid - vlan_tag_$1.etherType: vlan_tag_$1.$valid - B46: ipv4.$valid - ipv4.diffserv: ipv4.$valid - ipv4.totalLen: ipv4.$valid - ipv4.identification: ipv4.$valid - TH33: ipv4.$valid - ipv4.ttl: ipv4.$valid - ipv4.protocol: ipv4.$valid - ipv4.hdrChecksum: ipv4.$valid - ipv4.srcAddr.16-31: ipv4.$valid - ipv4.srcAddr.0-15: ipv4.$valid - ipv4.dstAddr: ipv4.$valid - udp.srcPort.8-15: udp.$valid - udp.srcPort.0-7: udp.$valid - udp.dstPort.8-15: udp.$valid - udp.dstPort.0-7: udp.$valid - udp.length_.8-15: udp.$valid - udp.length_.0-7: udp.$valid - udp.checksum.8-15: udp.$valid - udp.checksum.0-7: udp.$valid - TW24: ipv6.$valid - ipv6.payloadLen.8-15: ipv6.$valid - ipv6.payloadLen.0-7: ipv6.$valid - ipv6.nextHdr: ipv6.$valid - ipv6.hopLimit: ipv6.$valid - ipv6.srcAddr.96-127: ipv6.$valid - ipv6.srcAddr.64-95: ipv6.$valid - ipv6.srcAddr.32-63: ipv6.$valid - ipv6.srcAddr.0-31: ipv6.$valid - ipv6.dstAddr.96-127: ipv6.$valid - ipv6.dstAddr.64-95: ipv6.$valid - ipv6.dstAddr.32-63: ipv6.$valid - ipv6.dstAddr.0-31: ipv6.$valid - tcp.srcPort: tcp.$valid - tcp.dstPort: tcp.$valid - tcp.seqNo: tcp.$valid - tcp.ackNo: tcp.$valid - B28: tcp.$valid - tcp.flags: tcp.$valid - tcp.window: tcp.$valid - tcp.checksum: tcp.$valid - tcp.urgentPtr: tcp.$valid - icmp.typeCode: icmp.$valid - icmp.hdrChecksum: icmp.$valid - B26: inner_ipv4.$valid - inner_ipv4.diffserv: inner_ipv4.$valid - inner_ipv4.totalLen.8-15: inner_ipv4.$valid - inner_ipv4.totalLen.0-7: inner_ipv4.$valid - inner_ipv4.identification: inner_ipv4.$valid - TH32: inner_ipv4.$valid - inner_ipv4.ttl: inner_ipv4.$valid - inner_ipv4.protocol: inner_ipv4.$valid - inner_ipv4.hdrChecksum: inner_ipv4.$valid - inner_ipv4.srcAddr: inner_ipv4.$valid - inner_ipv4.dstAddr: inner_ipv4.$valid - inner_icmp.typeCode: inner_icmp.$valid - inner_icmp.hdrChecksum: inner_icmp.$valid - inner_tcp.srcPort: inner_tcp.$valid - inner_tcp.dstPort: inner_tcp.$valid - inner_tcp.seqNo: inner_tcp.$valid - inner_tcp.ackNo: inner_tcp.$valid - B24: inner_tcp.$valid - inner_tcp.flags: inner_tcp.$valid - inner_tcp.window: inner_tcp.$valid - inner_tcp.checksum: inner_tcp.$valid - inner_tcp.urgentPtr: inner_tcp.$valid - inner_udp.srcPort: inner_udp.$valid - inner_udp.dstPort: inner_udp.$valid - inner_udp.length_: inner_udp.$valid - inner_udp.checksum: inner_udp.$valid - egress_unicast_port: standard_metadata.egress_port - mirror: - 0: [ $mirror, $mirror_id, H22, ingress_metadata.ifindex, fabric_metadata.reason_code, H25 ] - 1: [ $mirror, $mirror_id, H22, ingress_metadata.ifindex, fabric_metadata.reason_code, H25 ] - 2: [ $mirror, $mirror_id, H22, ingress_metadata.ifindex, fabric_metadata.reason_code, H25 ] - 3: [ $mirror, $mirror_id, H22, ingress_metadata.ifindex, fabric_metadata.reason_code, H25 ] - select: $mirror -stage 0 ingress: - phase0_match ingress_port_mapping: - p4: - name: ingress_port_mapping - size: 288 - preferred_match_type: exact - match_type: exact - size: 288 - width: 1 - format: {ifindex: 48..63, port_type: 46..47} - constant_value: 0 - exact_match _switch_config_params_0 0: - p4: { name: switch_config_params, size: 1 } - row: 0 - bus: 0 - column: [ ] - next: _validate_outer_ethernet_0 - action_bus: { } - actions: - set_config_parameters: - - p4_param_order: {enable_dod: 1, enable_flowlet: 8, switch_id: 32 } - - { $constant0: immediate(0..8), $constant0: 511 } - - set ingress_metadata.ingress_port, standard_metadata.ingress_port - - set l2_metadata.same_if_check, ingress_metadata.ifindex - - set standard_metadata.egress_spec, $constant0 - NoAction: - - { } - default_action: NoAction - ternary_match _validate_outer_ethernet_0 1: - p4: { name: validate_outer_ethernet, size: 64 } - p4_param_order: - ethernet.srcAddr: { type: ternary, size: 48} - ethernet.dstAddr: { type: ternary, size: 48} - vlan_tag_$0.$valid: { type: exact, size: 1} - vlan_tag_$1.$valid: { type: exact, size: 1} - row: [ 0, 1, 2 ] - bus: [ 0, 0, 0 ] - column: - - 0 - - 0 - - 0 - input_xbar: - group 0: { 0: ethernet.dstAddr.0-15, 16: ethernet.dstAddr.16-31, 32: ethernet.dstAddr.32-47(0..7) } - group 1: { 0: ethernet.srcAddr.0-15(0..7), 8: ethernet.dstAddr.32-47(8..15), 16: ethernet.srcAddr.16-31(0..7), 24: ethernet.srcAddr.0-15(8..15), 32: ethernet.srcAddr.32-47(0..7), 43: vlan_tag_$0.$valid } - group 2: { 0: ethernet.srcAddr.16-31(8..15), 16: ethernet.srcAddr.32-47(8..15), 38: vlan_tag_$1.$valid } - next: _adjust_lkp_fields_0 - action_bus: { } - indirect: _validate_outer_ethernet_0$tind - ternary_indirect _validate_outer_ethernet_0$tind: - row: 0 - bus: 0 - column: 2 - format: { action: 8..13, immediate: 0..7} - actions: - malformed_outer_ethernet_packet: - - p4_param_order: {drop_reason: 8 } - - { drop_reason: immediate(0..7) } - - set ingress_metadata.drop_flag, 1 - - set ingress_metadata.drop_reason, drop_reason - set_valid_outer_unicast_packet_untagged: - - { } - - set l2_metadata.lkp_pkt_type, 1 - - set l2_metadata.lkp_mac_type, ethernet.etherType - set_valid_outer_unicast_packet_single_tagged: - - { } - - set l2_metadata.lkp_pkt_type, 1 - - set l2_metadata.lkp_mac_type, vlan_tag_$0.etherType - set_valid_outer_unicast_packet_double_tagged: - - { } - - set l2_metadata.lkp_pkt_type, 1 - - set l2_metadata.lkp_mac_type, vlan_tag_$1.etherType - set_valid_outer_unicast_packet_qinq_tagged: - - { } - - set l2_metadata.lkp_pkt_type, 1 - - set l2_metadata.lkp_mac_type, ethernet.etherType - set_valid_outer_multicast_packet_untagged: - - { } - - set l2_metadata.lkp_pkt_type, 2 - - set l2_metadata.lkp_mac_type, ethernet.etherType - set_valid_outer_multicast_packet_single_tagged: - - { } - - set l2_metadata.lkp_pkt_type, 2 - - set l2_metadata.lkp_mac_type, vlan_tag_$0.etherType - set_valid_outer_multicast_packet_double_tagged: - - { } - - set l2_metadata.lkp_pkt_type, 2 - - set l2_metadata.lkp_mac_type, vlan_tag_$1.etherType - set_valid_outer_multicast_packet_qinq_tagged: - - { } - - set l2_metadata.lkp_pkt_type, 2 - - set l2_metadata.lkp_mac_type, ethernet.etherType - set_valid_outer_broadcast_packet_untagged: - - { } - - set l2_metadata.lkp_pkt_type, 4 - - set l2_metadata.lkp_mac_type, ethernet.etherType - set_valid_outer_broadcast_packet_single_tagged: - - { } - - set l2_metadata.lkp_pkt_type, 4 - - set l2_metadata.lkp_mac_type, vlan_tag_$0.etherType - set_valid_outer_broadcast_packet_double_tagged: - - { } - - set l2_metadata.lkp_pkt_type, 4 - - set l2_metadata.lkp_mac_type, vlan_tag_$1.etherType - set_valid_outer_broadcast_packet_qinq_tagged: - - { } - - set l2_metadata.lkp_pkt_type, 4 - - set l2_metadata.lkp_mac_type, ethernet.etherType - NoAction: - - { } - default_action: NoAction - exact_match _adjust_lkp_fields_0 2: - p4: { name: adjust_lkp_fields } - p4_param_order: - ipv4.$valid: { type: exact, size: 1} - ipv6.$valid: { type: exact, size: 1} - row: 2 - bus: 0 - column: [ 2, 3, 4 ] - ways: - - [0, 0, 0x0, [2, 2]] - - [0, 1, 0x0, [2, 3]] - - [0, 2, 0x0, [2, 4]] - input_xbar: - group 0: { 7: ipv4.$valid, 15: ipv6.$valid } - hash 0: - 0..9: stripe(ipv4.$valid, ipv6.$valid) - 10..19: stripe(ipv4.$valid, ipv6.$valid) - 20..29: stripe(ipv4.$valid, ipv6.$valid) - hash group 0: - table: [0] - format: { action(0): 0..1, version(0): 112..115 } - next: _port_vlan_mapping_0 - actions: - non_ip_lkp: - - set l2_metadata.lkp_mac_da.0-15, ethernet.dstAddr.0-15 - - set l2_metadata.lkp_mac_da.16-31, ethernet.dstAddr.16-31 - - set l2_metadata.lkp_mac_da.32-47, ethernet.dstAddr.32-47 - - set l2_metadata.lkp_mac_sa.0-15, ethernet.srcAddr.0-15 - - set l2_metadata.lkp_mac_sa.16-31, ethernet.srcAddr.16-31 - - set l2_metadata.lkp_mac_sa.32-47, ethernet.srcAddr.32-47 - ipv4_lkp: - - set ipv4_metadata.lkp_ipv4_sa, ipv4.srcAddr - - set ipv4_metadata.lkp_ipv4_da, ipv4.dstAddr - - set l3_metadata.lkp_ip_proto, ipv4.protocol - - set l3_metadata.lkp_ip_ttl, ipv4.ttl - - set l3_metadata.lkp_l4_sport, l3_metadata.lkp_outer_l4_sport - - set l3_metadata.lkp_l4_dport, l3_metadata.lkp_outer_l4_dport - - set l2_metadata.lkp_mac_da.0-15, ethernet.dstAddr.0-15 - - set l2_metadata.lkp_mac_da.16-31, ethernet.dstAddr.16-31 - - set l2_metadata.lkp_mac_da.32-47, ethernet.dstAddr.32-47 - - set l2_metadata.lkp_mac_sa.0-15, ethernet.srcAddr.0-15 - - set l2_metadata.lkp_mac_sa.16-31, ethernet.srcAddr.16-31 - - set l2_metadata.lkp_mac_sa.32-47, ethernet.srcAddr.32-47 - NoAction: - - 0 - default_action: NoAction - exact_match _port_vlan_mapping_0 4: - p4: { name: port_vlan_mapping, size: 32768, action_profile: bd_action_profile } - p4_param_order: - ingress_metadata.ifindex: { type: exact, size: 16} - vlan_tag_$0.$valid: { type: exact, size: 1} - vlan_tag_$0.vid: { type: exact, size: 12} - vlan_tag_$1.$valid: { type: exact, size: 1} - vlan_tag_$1.vid: { type: exact, size: 12} - row: [ 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - ways: - - [2, 0, 0x7, [7, 2], [7, 3], [7, 4], [7, 6], [7, 7], [7, 8], [7, 9], [7, 10]] - - [2, 1, 0x38, [6, 2], [6, 3], [6, 4], [6, 6], [6, 7], [6, 8], [6, 9], [6, 10]] - - [2, 2, 0x1c0, [5, 2], [5, 3], [5, 4], [5, 6], [5, 7], [5, 8], [5, 9], [5, 10]] - - [2, 3, 0xe00, [4, 2], [4, 3], [4, 4], [4, 6], [4, 7], [4, 8], [4, 9], [4, 10]] - input_xbar: - group 1: { 0: ingress_metadata.ifindex, 16: vlan_tag_$0.vid(0..7), 31: vlan_tag_$0.$valid, 32: vlan_tag_$1.vid(0..7), 40: vlan_tag_$0.vid(8..11), 62: vlan_tag_$1.$valid, 72: vlan_tag_$1.vid(8..11) } - hash 2: - 0..9: random(ingress_metadata.ifindex, vlan_tag_$0.vid(0..7), vlan_tag_$1.vid(3..7)) ^ stripe(vlan_tag_$0.$valid, vlan_tag_$1.vid(0..2), vlan_tag_$0.vid(8..11), vlan_tag_$1.$valid) - 10..19: random(ingress_metadata.ifindex, vlan_tag_$0.vid(0..7), vlan_tag_$1.vid(3..7)) ^ stripe(vlan_tag_$0.$valid, vlan_tag_$1.vid(0..2), vlan_tag_$0.vid(8..11), vlan_tag_$1.$valid) - 20..29: random(ingress_metadata.ifindex, vlan_tag_$0.vid(0..7), vlan_tag_$1.vid(3..7)) ^ stripe(vlan_tag_$0.$valid, vlan_tag_$1.vid(0..2), vlan_tag_$0.vid(8..11), vlan_tag_$1.$valid) - 30..39: random(ingress_metadata.ifindex, vlan_tag_$0.vid(0..7), vlan_tag_$1.vid(3..7)) ^ stripe(vlan_tag_$0.$valid, vlan_tag_$1.vid(0..2), vlan_tag_$0.vid(8..11), vlan_tag_$1.$valid) - 40..51: random(ingress_metadata.ifindex, vlan_tag_$0.vid(0..7), vlan_tag_$1.vid(3..7)) ^ stripe(vlan_tag_$0.$valid, vlan_tag_$1.vid(0..2), vlan_tag_$0.vid(8..11), vlan_tag_$1.$valid) - hash 3: - 0..9: stripe(vlan_tag_$1.vid(8..11)) - 10..19: stripe(vlan_tag_$1.vid(8..11)) - 20..29: stripe(vlan_tag_$1.vid(8..11)) - 30..39: stripe(vlan_tag_$1.vid(8..11)) - 40..51: stripe(vlan_tag_$1.vid(8..11)) - hash group 2: - table: [2, 3] - format: { action(0): 15..16, version(0): 112..115, action_addr(0): 0..14, match(0): [40..47, 32..39, 48..55, 59..63 ] } - match: [ ingress_metadata.ifindex, vlan_tag_$0.vid(0..7), vlan_tag_$1.vid(3..7) ] - next: _ingress_port_properties_0 - action: _port_vlan_mapping_0$act_prof..bd_action_profile(action, action_addr) - default_action: NoAction - action _port_vlan_mapping_0$act_prof..bd_action_profile: - row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4 ] - column: - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - [ 3, 4, 5 ] - - 5 - - [ 3, 4, 5 ] - - 5 - home_row: [ 15, 5 ] - format set_bd_properties: { $adf_b0: 0..7, $adf_b1: 8..15, $adf_b2: 16..23, $adf_h0: 32..47, $adf_h1: 48..63, $adf_h2: 64..79, $adf_h3: 80..95, $adf_h4: 96..111, $adf_h5: 112..127 } - action_bus: { 16 : $adf_b0, 17 : $adf_b1, 18 : $adf_b2, 64..65 : $adf_h2, 66..67 : $adf_h3, 68..69 : $adf_h4, 70..71 : $adf_h5, 40..41 : $adf_h0, 42..43 : $adf_h1 } - actions: - set_bd_properties: - - p4_param_order: {bd: 14, vrf: 14, stp_group: 10, learning_enabled: 1, bd_label: 16, stats_idx: 16, rmac_group: 10, ipv4_unicast_enabled: 1, ipv6_unicast_enabled: 1, ipv4_urpf_mode: 2, ipv6_urpf_mode: 2, igmp_snooping_enabled: 1, mld_snooping_enabled: 1, ipv4_multicast_enabled: 1, ipv6_multicast_enabled: 1, mrpf_group: 14, ipv4_mcast_key: 14, ipv4_mcast_key_type: 1, ipv6_mcast_key: 14, ipv6_mcast_key_type: 1, ingress_rid: 16 } - - { $data0: $adf_b0, igmp_snooping_enabled: $data0(6..6), mld_snooping_enabled: $data0(5..5), learning_enabled: $adf_b1, ipv4_unicast_enabled: $adf_b2, bd: $adf_h0, stats_idx: $adf_h1, ipv6_unicast_enabled: $adf_h2, stp_group: $adf_h3, rmac_group: $adf_h4, bd_label: $adf_h5 } - - set ingress_metadata.bd, bd - - set acl_metadata.bd_label, bd_label - - set l2_metadata.stp_group, stp_group - - set l2_metadata.bd_stats_idx, stats_idx - - set l2_metadata.learning_enabled, learning_enabled - - set ipv4_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled - - set ipv6_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled - - set l3_metadata.rmac_group, rmac_group - - set B55(5..6), $data0(5..6) - port_vlan_mapping_miss: - - { } - - set l2_metadata.port_vlan_mapping_miss, 1 - NoAction: - - { } - exact_match _ingress_port_properties_0 6: - p4: { name: ingress_port_properties, size: 288 } - p4_param_order: - standard_metadata.ingress_port: { type: exact, size: 9} - row: 3 - bus: 0 - column: [ 2, 3, 4 ] - ways: - - [4, 0, 0x0, [3, 2]] - - [4, 1, 0x0, [3, 3]] - - [4, 2, 0x0, [3, 4]] - input_xbar: - group 2: { 64: standard_metadata.ingress_port } - hash 5: - 0..9: random(standard_metadata.ingress_port(1..7)) ^ stripe(standard_metadata.ingress_port(0), standard_metadata.ingress_port(8)) - 10..19: random(standard_metadata.ingress_port(1..7)) ^ stripe(standard_metadata.ingress_port(0), standard_metadata.ingress_port(8)) - 20..29: random(standard_metadata.ingress_port(1..7)) ^ stripe(standard_metadata.ingress_port(0), standard_metadata.ingress_port(8)) - hash group 4: - table: [5] - format: { action(0): 16..16, immediate(0): 0..15, version(0): 112..115, match(0): 33..39 } - match: [ standard_metadata.ingress_port(1..7) ] - next: _compute_ipv4_hashes_0 - action_bus: { } - actions: - set_ingress_port_properties: - - p4_param_order: {if_label: 16, exclusion_id: 9, qos_group: 5, tc_qos_group: 5, tc: 8, color: 2, trust_dscp: 1, trust_pcp: 1 } - - { if_label: immediate(0..15) } - - set acl_metadata.if_label, if_label - NoAction: - - { } - default_action: NoAction -stage 1 ingress: - exact_match _compute_ipv4_hashes_0 0: - p4: { name: compute_ipv4_hashes } - p4_param_order: - ethernet.$valid: { type: exact, size: 1} - row: 0 - bus: 0 - column: [ 2, 3, 4 ] - ways: - - [0, 0, 0x0, [0, 2]] - - [0, 1, 0x0, [0, 3]] - - [0, 2, 0x0, [0, 4]] - hash_dist: - 2: {hash: 1, mask: 0xffff, shift: 0} - 1: {hash: 1, mask: 0xffff, shift: 0} - input_xbar: - group 0: { 7: ethernet.$valid } - hash 0: - 0..9: stripe(ethernet.$valid) - 10..19: stripe(ethernet.$valid) - 20..29: stripe(ethernet.$valid) - hash group 0: - table: [0] - exact group 1: { 0: ipv4_metadata.lkp_ipv4_da, 32: ipv4_metadata.lkp_ipv4_sa, 64: l3_metadata.lkp_l4_dport, 80: l3_metadata.lkp_l4_sport, 96: l3_metadata.lkp_ip_proto } - hash 2: - 32..47: stripe(crc(0x8fdb, ipv4_metadata.lkp_ipv4_da, ipv4_metadata.lkp_ipv4_sa)) - hash 3: - 32..47: stripe(crc(0x8fdb, l3_metadata.lkp_l4_dport, l3_metadata.lkp_l4_sport, l3_metadata.lkp_ip_proto)) - hash group 1: - table: [2, 3] - exact group 2: { 0: ipv4_metadata.lkp_ipv4_da, 32: ipv4_metadata.lkp_ipv4_sa, 64: l2_metadata.lkp_mac_da.0-15, 80: l2_metadata.lkp_mac_da.16-31, 96: l2_metadata.lkp_mac_da.32-47, 112: l2_metadata.lkp_mac_sa.0-15 } - exact group 3: { 0: l2_metadata.lkp_mac_sa.16-31, 16: l2_metadata.lkp_mac_sa.32-47, 32: l3_metadata.lkp_l4_dport, 48: l3_metadata.lkp_l4_sport, 64: l3_metadata.lkp_ip_proto } - hash 4: - 16..31: stripe(crc(0x8fdb, ipv4_metadata.lkp_ipv4_da, ipv4_metadata.lkp_ipv4_sa)) - hash 5: - 16..31: stripe(crc(0x8fdb, l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47, l2_metadata.lkp_mac_sa.0-15)) - hash 6: - 16..31: stripe(crc(0x8fdb, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47, l3_metadata.lkp_l4_dport, l3_metadata.lkp_l4_sport)) - hash 7: - 16..31: stripe(crc(0x8fdb, l3_metadata.lkp_ip_proto)) - hash group 1: - table: [4, 5, 6, 7] - format: { action(0): 0..0, version(0): 112..115 } - gateway: - input_xbar: - group 0: { 15: inner_ipv4.$valid, 23: ipv4.$valid, 25: tunnel_metadata.tunnel_terminate } - hash 0: - 40: inner_ipv4.$valid - 41: ipv4.$valid - hash group 0: - table: [0] - row: 1 - bus: 1 - match: { 1: tunnel_metadata.tunnel_terminate, 32: inner_ipv4.$valid, 33: ipv4.$valid } - 0b1*******************************0: run_table - 0b*1******************************1: run_table - miss: _compute_non_ip_hashes_0 - next: _fabric_ingress_dst_lkp - actions: - compute_lkp_ipv4_hash: - - set hash_metadata.hash1, hash_dist(2, 1) - - set hash_metadata.hash2, hash_dist(2, 1) - NoAction: - - 0 - default_action: NoAction - exact_match _compute_non_ip_hashes_0 1: - p4: { name: compute_non_ip_hashes } - p4_param_order: - ethernet.$valid: { type: exact, size: 1} - row: 1 - bus: 1 - column: [ 6, 7, 8 ] - ways: - - [2, 0, 0x0, [1, 6]] - - [2, 1, 0x0, [1, 7]] - - [2, 2, 0x0, [1, 8]] - hash_dist: - 0: {hash: 1, mask: 0xffff, shift: 0} - input_xbar: - group 0: { 71: ethernet.$valid } - hash 1: - 0..9: stripe(ethernet.$valid) - 10..19: stripe(ethernet.$valid) - 20..29: stripe(ethernet.$valid) - hash group 2: - table: [1] - exact group 4: { 0: ingress_metadata.ifindex, 16: l2_metadata.lkp_mac_da.0-15, 32: l2_metadata.lkp_mac_da.16-31, 48: l2_metadata.lkp_mac_da.32-47, 64: l2_metadata.lkp_mac_sa.0-15, 80: l2_metadata.lkp_mac_sa.16-31, 96: l2_metadata.lkp_mac_sa.32-47, 112: l2_metadata.lkp_mac_type } - hash 8: - 0..15: stripe(crc(0x8fdb, ingress_metadata.ifindex, l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47)) - hash 9: - 0..15: stripe(crc(0x8fdb, l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47, l2_metadata.lkp_mac_type)) - hash group 1: - table: [8, 9] - format: { action(0): 0..0, version(0): 112..115 } - next: _fabric_ingress_dst_lkp - actions: - compute_lkp_non_ip_hash: - - set hash_metadata.hash2, hash_dist(0) - NoAction: - - 0 - default_action: NoAction - exact_match _fabric_ingress_dst_lkp 2: - p4: { name: fabric_ingress_dst_lkp } - p4_param_order: - fabric_header.dstDevice: { type: exact, size: 8} - row: 1 - bus: 0 - column: [ 2, 3, 4 ] - ways: - - [3, 0, 0x0, [1, 2]] - - [3, 1, 0x0, [1, 3]] - - [3, 2, 0x0, [1, 4]] - input_xbar: - group 5: { 0: fabric_header.dstDevice } - hash 10: - 0..9: random(fabric_header.dstDevice(2..7)) ^ stripe(fabric_header.dstDevice(0..1)) - 10..19: random(fabric_header.dstDevice(2..7)) ^ stripe(fabric_header.dstDevice(0..1)) - 20..29: random(fabric_header.dstDevice(2..7)) ^ stripe(fabric_header.dstDevice(0..1)) - hash group 3: - table: [10] - format: { action(0): 0..1, version(0): 112..115, match(0): 34..39 } - match: [ fabric_header.dstDevice(2..7) ] - gateway: - input_xbar: - group 0: { 46: ingress_metadata.port_type } - row: 1 - bus: 0 - match: { 6: ingress_metadata.port_type } - 0x0: rmac - miss: run_table - next: rmac - actions: - nop: - - 0 - terminate_cpu_packet: - - set standard_metadata.egress_spec, fabric_header.dstPortOrGroup - - set egress_metadata.bypass, fabric_header_cpu.txBypass - - set ethernet.etherType, fabric_payload_header.etherType - NoAction: - - 0 - default_action: NoAction - exact_match rmac 3: - p4: { name: rmac, size: 512 } - p4_param_order: - l3_metadata.rmac_group: { type: exact, size: 10} - l2_metadata.lkp_mac_da: { type: exact, size: 48} - row: [ 0, 2 ] - bus: [ 1, 1 ] - column: - - [ 6, 7 ] - - 11 - ways: - - [4, 0, 0x0, [2, 11]] - - [4, 1, 0x0, [0, 6]] - - [4, 2, 0x0, [0, 7]] - input_xbar: - group 5: { 64: l2_metadata.lkp_mac_da.0-15, 80: l2_metadata.lkp_mac_da.16-31, 96: l2_metadata.lkp_mac_da.32-47, 112: l3_metadata.rmac_group } - hash 11: - 0..9: random(l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47, l3_metadata.rmac_group(1..7)) ^ stripe(l3_metadata.rmac_group(0), l3_metadata.rmac_group(8..9)) - 10..19: random(l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47, l3_metadata.rmac_group(1..7)) ^ stripe(l3_metadata.rmac_group(0), l3_metadata.rmac_group(8..9)) - 20..29: random(l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47, l3_metadata.rmac_group(1..7)) ^ stripe(l3_metadata.rmac_group(0), l3_metadata.rmac_group(8..9)) - hash group 4: - table: [11] - format: { action(0): 0..1, version(0): 112..115, match(0): [56..63, 32..39, 64..71, 40..47, 72..79, 48..55, 80..87 ] } - match: [ l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47, l3_metadata.rmac_group(0..7) ] - gateway: - input_xbar: - group 0: { 46: ingress_metadata.port_type } - row: 0 - bus: 1 - match: { 6: ingress_metadata.port_type } - 0x1: _compute_other_hashes_0 - miss: run_table - next: _validate_packet_0 - actions: - rmac_hit: - - set l3_metadata.rmac_hit, 1 - rmac_miss: - - set l3_metadata.rmac_hit, 0 - NoAction: - - 0 - default_action: NoAction - ternary_match _validate_packet_0 4: - p4: { name: validate_packet, size: 64 } - p4_param_order: - l2_metadata.lkp_mac_sa: { type: ternary, size: 48} - l2_metadata.lkp_mac_da: { type: ternary, size: 48} - l3_metadata.lkp_ip_type: { type: ternary, size: 2} - l3_metadata.lkp_ip_ttl: { type: ternary, size: 8} - l3_metadata.lkp_ip_version: { type: ternary, size: 4} - ipv4_metadata.lkp_ipv4_sa: { type: ternary, size: 8} - row: [ 0, 1, 2, 3 ] - bus: [ 0, 0, 0, 0 ] - column: - - 0 - - 0 - - 0 - - 0 - input_xbar: - group 0: { 0: ipv4_metadata.lkp_ipv4_sa, 32: l2_metadata.lkp_mac_da.0-15(0..7), 41: l3_metadata.lkp_ip_type } - group 1: { 0: l2_metadata.lkp_mac_da.16-31(0..7), 8: l2_metadata.lkp_mac_da.0-15(8..15), 16: l2_metadata.lkp_mac_da.32-47(0..7), 24: l2_metadata.lkp_mac_da.16-31(8..15), 32: l2_metadata.lkp_mac_sa.0-15(0..7) } - group 2: { 0: l2_metadata.lkp_mac_da.32-47(8..15), 8: l2_metadata.lkp_mac_sa.16-31(0..7), 16: l2_metadata.lkp_mac_sa.0-15(8..15), 24: l2_metadata.lkp_mac_sa.32-47(0..7), 32: l2_metadata.lkp_mac_sa.16-31(8..15) } - group 3: { 0: l2_metadata.lkp_mac_sa.32-47(8..15), 8: l3_metadata.lkp_ip_ttl, 18: l3_metadata.lkp_ip_version } - gateway: - input_xbar: - group 5: { 8: ingress_metadata.bypass_lookups(8..15), 16: ingress_metadata.bypass_lookups(0..7), 30: ingress_metadata.drop_flag } - row: 0 - bus: 0 - match: { 0: ingress_metadata.bypass_lookups(0..7), 8: ingress_metadata.bypass_lookups(8..15), 22: ingress_metadata.drop_flag } - 0b*0***************0******: run_table - miss: _smac_0.1 - next: _smac_0.1 - action_bus: { } - indirect: _validate_packet_0$tind - ternary_indirect _validate_packet_0$tind: - row: 0 - bus: 0 - column: 5 - format: { action: 8..10, immediate: 0..7} - actions: - nop: - - { } - set_unicast: - - { } - - set l2_metadata.lkp_pkt_type, 1 - set_unicast_and_ipv6_src_is_link_local: - - { } - - set l2_metadata.lkp_pkt_type, 1 - - set ipv6_metadata.ipv6_src_is_link_local, 1 - set_multicast: - - { } - - set l2_metadata.lkp_pkt_type, 2 - - add l2_metadata.bd_stats_idx, l2_metadata.bd_stats_idx, 1 - set_multicast_and_ipv6_src_is_link_local: - - { } - - set l2_metadata.lkp_pkt_type, 2 - - set ipv6_metadata.ipv6_src_is_link_local, 1 - - add l2_metadata.bd_stats_idx, l2_metadata.bd_stats_idx, 1 - set_broadcast: - - { } - - set l2_metadata.lkp_pkt_type, 4 - - add l2_metadata.bd_stats_idx, l2_metadata.bd_stats_idx, 2 - set_malformed_packet: - - p4_param_order: {drop_reason: 8 } - - { drop_reason: immediate(0..7) } - - set ingress_metadata.drop_flag, 1 - - set ingress_metadata.drop_reason, drop_reason - NoAction: - - { } - default_action: NoAction - exact_match _smac_0.1 5: - p4: { name: smac, size: 440000 } - p4_param_order: - ingress_metadata.bd: { type: exact, size: 14} - l2_metadata.lkp_mac_sa: { type: exact, size: 48} - row: [ 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10, 11 ] - ways: - - [5, 0, 0x7, [7, 2], [7, 3], [7, 4], [7, 6], [7, 7], [7, 8], [7, 9], [7, 10]] - - [5, 1, 0x38, [7, 11], [6, 2], [6, 3], [6, 4], [6, 6], [6, 7], [6, 8], [6, 9]] - - [5, 2, 0x1c0, [6, 10], [6, 11], [5, 2], [5, 3], [5, 4], [5, 6], [5, 7], [5, 8]] - - [5, 3, 0xe00, [5, 9], [5, 10], [5, 11], [4, 2], [4, 3], [4, 4], [4, 6], [4, 7]] - - [5, 0, 0x7, [4, 8], [4, 9], [4, 10], [4, 11], [3, 2], [3, 3], [3, 4], [3, 6]] - - [5, 1, 0x38, [3, 7], [3, 8], [3, 9], [3, 10], [3, 11], [2, 2], [2, 3], [2, 4]] - - [5, 2, 0xc0, [2, 6], [2, 7], [2, 8], [2, 9]] - - [5, 3, 0x0, [2, 10]] - input_xbar: - group 6: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_sa.0-15, 32: l2_metadata.lkp_mac_sa.16-31, 48: l2_metadata.lkp_mac_sa.32-47 } - hash 12: - 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..3)) - 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..3)) - 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..3)) - 30..39: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..3)) - 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..3)) - hash group 5: - table: [12] - format: { action(0): 0..1, version(0): 112..115, match(0): [56..71, 32..39, 72..79, 40..47, 4..7, 48..55 ], action(1): 2..3, version(1): 116..119, match(1): [104..111, 8..15, 80..87, 16..23, 88..95, 28..31, 96..103 ] } - match: [ ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(4..15) ] - gateway: - input_xbar: - group 0: { 32: ingress_metadata.bypass_lookups(0..7), 46: ingress_metadata.port_type, 56: ingress_metadata.bypass_lookups(8..15) } - row: 2 - bus: 0 - match: { 0: ingress_metadata.bypass_lookups(0..7), 8: ingress_metadata.bypass_lookups(8..15), 22: ingress_metadata.port_type } - 0b00**************0*******: run_table - miss: _dmac_0.1 - hit: _dmac_0.1 - miss: _smac_0.2 - action: _smac_0.1$action - default_action: NoAction - action _smac_0.1$action: - p4: { name: _smac_0$action } - row: [ 14, 12, 10, 8, 6, 4, 3, 2, 1 ] - column: - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - [ 3, 4, 5 ] - - 5 - - [ 2, 3, 4, 5 ] - home_row: [ 14, 4 ] - format smac_hit: { $adf_h0: 0..15 } - action_bus: { 32..33 : $adf_h0 } - actions: - nop: - - { } - smac_miss: - - { } - - set l2_metadata.l2_src_miss, 1 - smac_hit: - - p4_param_order: {ifindex: 16 } - - { ifindex: $adf_h0 } - - xor l2_metadata.l2_src_move, ingress_metadata.ifindex, ifindex - NoAction: - - { } -stage 2 ingress: - exact_match _smac_0.2 0: - p4: { name: smac, size: 440000 } - p4_param_order: - ingress_metadata.bd: { type: exact, size: 14} - l2_metadata.lkp_mac_sa: { type: exact, size: 48} - row: [ 0, 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - ways: - - [0, 0, 0xf, [7, 2], [7, 3], [7, 4], [7, 6], [7, 7], [7, 8], [7, 9], [7, 10], [6, 2], [6, 3], [6, 4], [6, 6], [6, 7], [6, 8], [6, 9], [6, 10]] - - [0, 1, 0xf0, [5, 2], [5, 3], [5, 4], [5, 6], [5, 7], [5, 8], [5, 9], [5, 10], [4, 2], [4, 3], [4, 4], [4, 6], [4, 7], [4, 8], [4, 9], [4, 10]] - - [0, 2, 0xf00, [3, 2], [3, 3], [3, 4], [3, 6], [3, 7], [3, 8], [3, 9], [3, 10], [2, 2], [2, 3], [2, 4], [2, 6], [2, 7], [2, 8], [2, 9], [2, 10]] - - [1, 0, 0xf, [1, 2], [1, 3], [1, 4], [1, 6], [1, 7], [1, 8], [1, 9], [1, 10], [0, 2], [0, 3], [0, 4], [0, 6], [0, 7], [0, 8], [0, 9], [0, 10]] - input_xbar: - group 0: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_sa.0-15, 32: l2_metadata.lkp_mac_sa.16-31, 48: l2_metadata.lkp_mac_sa.32-47 } - group 1: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_sa.0-15, 32: l2_metadata.lkp_mac_sa.16-31, 48: l2_metadata.lkp_mac_sa.32-47 } - hash 0: - 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) - 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) - 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) - 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) - hash group 0: - table: [0] - hash 2: - 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) - 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) - 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) - 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) - hash group 1: - table: [2] - format: { action(0): 0..1, version(0): 120..123, match(0): [56..71, 32..39, 72..79, 40..47, 24..31, 48..55 ], action(1): 2..3, version(1): 124..127, match(1): [104..111, 8..15, 80..87, 16..23, 88..95, 112..119, 96..103 ] } - match: [ ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47 ] - hit: _dmac_0.1 - miss: _smac_0.3 - action: _smac_0.2$action - default_action: NoAction - action _smac_0.2$action: - p4: { name: _smac_0$action } - row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ] - column: - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - home_row: [ 15, 5 ] - format smac_hit: { $adf_h0: 0..15 } - action_bus: { 32..33 : $adf_h0 } - actions: - nop: - - { } - smac_miss: - - { } - - set l2_metadata.l2_src_miss, 1 - smac_hit: - - p4_param_order: {ifindex: 16 } - - { ifindex: $adf_h0 } - - xor l2_metadata.l2_src_move, ingress_metadata.ifindex, ifindex - NoAction: - - { } -stage 3 ingress: - exact_match _smac_0.3 0: - p4: { name: smac, size: 440000 } - p4_param_order: - ingress_metadata.bd: { type: exact, size: 14} - l2_metadata.lkp_mac_sa: { type: exact, size: 48} - row: [ 0, 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - ways: - - [0, 0, 0xf, [7, 2], [7, 3], [7, 4], [7, 6], [7, 7], [7, 8], [7, 9], [7, 10], [6, 2], [6, 3], [6, 4], [6, 6], [6, 7], [6, 8], [6, 9], [6, 10]] - - [0, 1, 0xf0, [5, 2], [5, 3], [5, 4], [5, 6], [5, 7], [5, 8], [5, 9], [5, 10], [4, 2], [4, 3], [4, 4], [4, 6], [4, 7], [4, 8], [4, 9], [4, 10]] - - [0, 2, 0xf00, [3, 2], [3, 3], [3, 4], [3, 6], [3, 7], [3, 8], [3, 9], [3, 10], [2, 2], [2, 3], [2, 4], [2, 6], [2, 7], [2, 8], [2, 9], [2, 10]] - - [1, 0, 0xf, [1, 2], [1, 3], [1, 4], [1, 6], [1, 7], [1, 8], [1, 9], [1, 10], [0, 2], [0, 3], [0, 4], [0, 6], [0, 7], [0, 8], [0, 9], [0, 10]] - input_xbar: - group 0: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_sa.0-15, 32: l2_metadata.lkp_mac_sa.16-31, 48: l2_metadata.lkp_mac_sa.32-47 } - group 1: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_sa.0-15, 32: l2_metadata.lkp_mac_sa.16-31, 48: l2_metadata.lkp_mac_sa.32-47 } - hash 0: - 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) - 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) - 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) - 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) - hash group 0: - table: [0] - hash 2: - 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) - 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) - 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) - 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31(0..14), l2_metadata.lkp_mac_sa.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.16-31(15..16), l2_metadata.lkp_mac_sa.16-31(15..16)) - hash group 1: - table: [2] - format: { action(0): 0..1, version(0): 120..123, match(0): [56..71, 32..39, 72..79, 40..47, 24..31, 48..55 ], action(1): 2..3, version(1): 124..127, match(1): [104..111, 8..15, 80..87, 16..23, 88..95, 112..119, 96..103 ] } - match: [ ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47 ] - hit: _dmac_0.1 - miss: _smac_0.4 - action: _smac_0.3$action - default_action: NoAction - action _smac_0.3$action: - p4: { name: _smac_0$action } - row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ] - column: - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - home_row: [ 15, 5 ] - format smac_hit: { $adf_h0: 0..15 } - action_bus: { 32..33 : $adf_h0 } - actions: - nop: - - { } - smac_miss: - - { } - - set l2_metadata.l2_src_miss, 1 - smac_hit: - - p4_param_order: {ifindex: 16 } - - { ifindex: $adf_h0 } - - xor l2_metadata.l2_src_move, ingress_metadata.ifindex, ifindex - NoAction: - - { } -stage 4 ingress: - exact_match _smac_0.4 0: - p4: { name: smac, size: 440000 } - p4_param_order: - ingress_metadata.bd: { type: exact, size: 14} - l2_metadata.lkp_mac_sa: { type: exact, size: 48} - row: [ 0, 4, 5, 6, 7 ] - bus: [ 1, 0, 0, 0, 0 ] - column: - - [ 8, 9 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - ways: - - [0, 0, 0x7, [7, 2], [7, 3], [7, 4], [7, 6], [7, 7], [7, 8], [7, 9], [7, 10]] - - [0, 1, 0x38, [6, 2], [6, 3], [6, 4], [6, 6], [6, 7], [6, 8], [6, 9], [6, 10]] - - [0, 2, 0x1c0, [5, 2], [5, 3], [5, 4], [5, 6], [5, 7], [5, 8], [5, 9], [5, 10]] - - [0, 3, 0xe00, [4, 2], [4, 3], [4, 4], [4, 6], [4, 7], [4, 8], [4, 9], [4, 10]] - - [0, 0, 0x1, [0, 8], [0, 9]] - input_xbar: - group 0: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_sa.0-15, 32: l2_metadata.lkp_mac_sa.16-31, 48: l2_metadata.lkp_mac_sa.32-47 } - hash 0: - 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..4)) - 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..4)) - 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..4)) - 30..39: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..4)) - 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_sa.32-47(0..4)) - hash group 0: - table: [0] - format: { action(0): 0..1, version(0): 112..115, match(0): [56..71, 32..39, 72..79, 40..47, 5..7, 48..55 ], action(1): 2..3, version(1): 116..119, match(1): [104..111, 8..15, 80..87, 16..23, 88..95, 29..31, 96..103 ] } - match: [ ingress_metadata.bd(0..7), l2_metadata.lkp_mac_sa.0-15, l2_metadata.lkp_mac_sa.16-31, l2_metadata.lkp_mac_sa.32-47(5..15) ] - next: _dmac_0.1 - action: _smac_0.4$action - default_action: NoAction - action _smac_0.4$action: - p4: { name: _smac_0$action } - row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7 ] - column: - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - home_row: 15 - format smac_hit: { $adf_h0: 0..15 } - action_bus: { 32..33 : $adf_h0 } - actions: - nop: - - { } - smac_miss: - - { } - - set l2_metadata.l2_src_miss, 1 - smac_hit: - - p4_param_order: {ifindex: 16 } - - { ifindex: $adf_h0 } - - xor l2_metadata.l2_src_move, ingress_metadata.ifindex, ifindex - NoAction: - - { } - exact_match _dmac_0.1 1: - p4: { name: dmac, size: 440000 } - p4_param_order: - ingress_metadata.bd: { type: exact, size: 14} - l2_metadata.lkp_mac_da: { type: exact, size: 48} - row: [ 0, 1, 2, 3 ] - bus: [ 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 6, 7 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - ways: - - [1, 0, 0x3, [3, 2], [3, 3], [3, 4], [3, 6]] - - [1, 1, 0xc, [3, 7], [3, 8], [3, 9], [3, 10]] - - [1, 2, 0x30, [2, 2], [2, 3], [2, 4], [2, 6]] - - [1, 3, 0xc0, [2, 7], [2, 8], [2, 9], [2, 10]] - - [1, 0, 0x3, [1, 2], [1, 3], [1, 4], [1, 6]] - - [1, 1, 0xc, [1, 7], [1, 8], [1, 9], [1, 10]] - - [1, 2, 0x30, [0, 2], [0, 3], [0, 4], [0, 6]] - - [1, 3, 0x0, [0, 7]] - input_xbar: - group 1: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_da.0-15, 32: l2_metadata.lkp_mac_da.16-31, 48: l2_metadata.lkp_mac_da.32-47 } - hash 2: - 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..3)) - 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..3)) - 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..3)) - 30..39: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..3)) - 40..47: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(4..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..3)) - hash group 1: - table: [2] - format: { action(0): 0..2, version(0): 112..115, match(0): [56..71, 32..39, 72..79, 40..47, 28..31, 48..55 ], action(1): 3..5, version(1): 120..123, match(1): [104..111, 8..15, 80..87, 16..23, 88..95, 116..119, 96..103 ] } - match: [ ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(4..15) ] - gateway: - input_xbar: - group 0: { 64: ingress_metadata.bypass_lookups } - row: 0 - bus: 1 - match: { 0: ingress_metadata.bypass_lookups(0..7), 8: ingress_metadata.bypass_lookups(8..15) } - 0b***************0: run_table - miss: cond-8 - hit: cond-8 - miss: _dmac_0.2 - action: _dmac_0.1$action - default_action: NoAction - action _dmac_0.1$action: - p4: { name: _dmac_0$action } - row: [ 6, 5, 4, 3, 2, 1, 0 ] - column: - - 5 - - 5 - - 5 - - 5 - - 5 - - [ 4, 5 ] - - 5 - home_row: 6 - format dmac_hit: { $adf_h0: 0..15 } - format dmac_redirect_nexthop: { $adf_h0: 0..15 } - format dmac_redirect_ecmp: { $adf_h0: 0..15 } - action_bus: { 36..37 : $adf_h0 } - actions: - nop: - - { } - dmac_hit: - - p4_param_order: {ifindex: 16 } - - { ifindex: $adf_h0 } - - set ingress_metadata.egress_ifindex, ifindex - - xor l2_metadata.same_if_check, l2_metadata.same_if_check, ifindex - dmac_multicast_hit: - - p4_param_order: {mc_index: 16 } - - { } - dmac_miss: - - { } - - set ingress_metadata.egress_ifindex, 65535 - dmac_redirect_nexthop: - - p4_param_order: {nexthop_index: 16 } - - { nexthop_index: $adf_h0 } - - set l2_metadata.l2_redirect, 1 - - set l2_metadata.l2_nexthop, nexthop_index - - set l2_metadata.l2_nexthop_type, 0 - dmac_redirect_ecmp: - - p4_param_order: {ecmp_index: 16 } - - { ecmp_index: $adf_h0 } - - set l2_metadata.l2_redirect, 1 - - set l2_metadata.l2_nexthop, ecmp_index - - set l2_metadata.l2_nexthop_type, 1 - dmac_drop: - - { } - - invalidate standard_metadata.egress_spec - NoAction: - - { } -stage 5 ingress: - exact_match _dmac_0.2 0: - p4: { name: dmac, size: 440000 } - p4_param_order: - ingress_metadata.bd: { type: exact, size: 14} - l2_metadata.lkp_mac_da: { type: exact, size: 48} - row: [ 0, 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - ways: - - [0, 0, 0xf, [7, 2], [7, 3], [7, 4], [7, 6], [7, 7], [7, 8], [7, 9], [7, 10], [6, 2], [6, 3], [6, 4], [6, 6], [6, 7], [6, 8], [6, 9], [6, 10]] - - [0, 1, 0xf0, [5, 2], [5, 3], [5, 4], [5, 6], [5, 7], [5, 8], [5, 9], [5, 10], [4, 2], [4, 3], [4, 4], [4, 6], [4, 7], [4, 8], [4, 9], [4, 10]] - - [0, 2, 0xf00, [3, 2], [3, 3], [3, 4], [3, 6], [3, 7], [3, 8], [3, 9], [3, 10], [2, 2], [2, 3], [2, 4], [2, 6], [2, 7], [2, 8], [2, 9], [2, 10]] - - [1, 0, 0xf, [1, 2], [1, 3], [1, 4], [1, 6], [1, 7], [1, 8], [1, 9], [1, 10], [0, 2], [0, 3], [0, 4], [0, 6], [0, 7], [0, 8], [0, 9], [0, 10]] - input_xbar: - group 0: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_da.0-15, 32: l2_metadata.lkp_mac_da.16-31, 48: l2_metadata.lkp_mac_da.32-47 } - group 1: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_da.0-15, 32: l2_metadata.lkp_mac_da.16-31, 48: l2_metadata.lkp_mac_da.32-47 } - hash 0: - 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) - 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) - 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) - 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) - hash group 0: - table: [0] - hash 2: - 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) - 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) - 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) - 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) - hash group 1: - table: [2] - format: { action(0): 0..2, version(0): 120..123, match(0): [56..71, 32..39, 72..79, 40..47, 24..31, 48..55 ], action(1): 3..5, version(1): 124..127, match(1): [104..111, 8..15, 80..87, 16..23, 88..95, 112..119, 96..103 ] } - match: [ ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47 ] - hit: cond-8 - miss: _dmac_0.3 - action: _dmac_0.2$action - default_action: NoAction - action _dmac_0.2$action: - p4: { name: _dmac_0$action } - row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ] - column: - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - home_row: [ 15, 5 ] - format dmac_hit: { $adf_h0: 0..15 } - format dmac_redirect_nexthop: { $adf_h0: 0..15 } - format dmac_redirect_ecmp: { $adf_h0: 0..15 } - action_bus: { 32..33 : $adf_h0 } - actions: - nop: - - { } - dmac_hit: - - p4_param_order: {ifindex: 16 } - - { ifindex: $adf_h0 } - - set ingress_metadata.egress_ifindex, ifindex - - xor l2_metadata.same_if_check, l2_metadata.same_if_check, ifindex - dmac_multicast_hit: - - p4_param_order: {mc_index: 16 } - - { } - dmac_miss: - - { } - - set ingress_metadata.egress_ifindex, 65535 - dmac_redirect_nexthop: - - p4_param_order: {nexthop_index: 16 } - - { nexthop_index: $adf_h0 } - - set l2_metadata.l2_redirect, 1 - - set l2_metadata.l2_nexthop, nexthop_index - - set l2_metadata.l2_nexthop_type, 0 - dmac_redirect_ecmp: - - p4_param_order: {ecmp_index: 16 } - - { ecmp_index: $adf_h0 } - - set l2_metadata.l2_redirect, 1 - - set l2_metadata.l2_nexthop, ecmp_index - - set l2_metadata.l2_nexthop_type, 1 - dmac_drop: - - { } - - invalidate standard_metadata.egress_spec - NoAction: - - { } -stage 6 ingress: - exact_match _dmac_0.3 0: - p4: { name: dmac, size: 440000 } - p4_param_order: - ingress_metadata.bd: { type: exact, size: 14} - l2_metadata.lkp_mac_da: { type: exact, size: 48} - row: [ 0, 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - - [ 2, 3, 4, 6, 7, 8, 9, 10 ] - ways: - - [0, 0, 0xf, [7, 2], [7, 3], [7, 4], [7, 6], [7, 7], [7, 8], [7, 9], [7, 10], [6, 2], [6, 3], [6, 4], [6, 6], [6, 7], [6, 8], [6, 9], [6, 10]] - - [0, 1, 0xf0, [5, 2], [5, 3], [5, 4], [5, 6], [5, 7], [5, 8], [5, 9], [5, 10], [4, 2], [4, 3], [4, 4], [4, 6], [4, 7], [4, 8], [4, 9], [4, 10]] - - [0, 2, 0xf00, [3, 2], [3, 3], [3, 4], [3, 6], [3, 7], [3, 8], [3, 9], [3, 10], [2, 2], [2, 3], [2, 4], [2, 6], [2, 7], [2, 8], [2, 9], [2, 10]] - - [1, 0, 0xf, [1, 2], [1, 3], [1, 4], [1, 6], [1, 7], [1, 8], [1, 9], [1, 10], [0, 2], [0, 3], [0, 4], [0, 6], [0, 7], [0, 8], [0, 9], [0, 10]] - input_xbar: - group 0: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_da.0-15, 32: l2_metadata.lkp_mac_da.16-31, 48: l2_metadata.lkp_mac_da.32-47 } - group 1: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_da.0-15, 32: l2_metadata.lkp_mac_da.16-31, 48: l2_metadata.lkp_mac_da.32-47 } - hash 0: - 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) - 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) - 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) - 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) - hash group 0: - table: [0] - hash 2: - 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) - 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) - 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) - 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31(0..14), l2_metadata.lkp_mac_da.32-47(1..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.16-31(15..16), l2_metadata.lkp_mac_da.16-31(15..16)) - hash group 1: - table: [2] - format: { action(0): 0..2, version(0): 120..123, match(0): [56..71, 32..39, 72..79, 40..47, 24..31, 48..55 ], action(1): 3..5, version(1): 124..127, match(1): [104..111, 8..15, 80..87, 16..23, 88..95, 112..119, 96..103 ] } - match: [ ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47 ] - hit: cond-8 - miss: _dmac_0.4 - action: _dmac_0.3$action - default_action: NoAction - action _dmac_0.3$action: - p4: { name: _dmac_0$action } - row: [ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ] - column: - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - - 5 - home_row: [ 15, 5 ] - format dmac_hit: { $adf_h0: 0..15 } - format dmac_redirect_nexthop: { $adf_h0: 0..15 } - format dmac_redirect_ecmp: { $adf_h0: 0..15 } - action_bus: { 32..33 : $adf_h0 } - actions: - nop: - - { } - dmac_hit: - - p4_param_order: {ifindex: 16 } - - { ifindex: $adf_h0 } - - set ingress_metadata.egress_ifindex, ifindex - - xor l2_metadata.same_if_check, l2_metadata.same_if_check, ifindex - dmac_multicast_hit: - - p4_param_order: {mc_index: 16 } - - { } - dmac_miss: - - { } - - set ingress_metadata.egress_ifindex, 65535 - dmac_redirect_nexthop: - - p4_param_order: {nexthop_index: 16 } - - { nexthop_index: $adf_h0 } - - set l2_metadata.l2_redirect, 1 - - set l2_metadata.l2_nexthop, nexthop_index - - set l2_metadata.l2_nexthop_type, 0 - dmac_redirect_ecmp: - - p4_param_order: {ecmp_index: 16 } - - { ecmp_index: $adf_h0 } - - set l2_metadata.l2_redirect, 1 - - set l2_metadata.l2_nexthop, ecmp_index - - set l2_metadata.l2_nexthop_type, 1 - dmac_drop: - - { } - - invalidate standard_metadata.egress_spec - NoAction: - - { } -stage 7 ingress: - exact_match _dmac_0.4 0: - p4: { name: dmac, size: 440000 } - p4_param_order: - ingress_metadata.bd: { type: exact, size: 14} - l2_metadata.lkp_mac_da: { type: exact, size: 48} - row: [ 0, 1, 2, 3, 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - [ 2, 3 ] - - [ 2, 3, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 6, 7, 8, 9, 10, 11 ] - - [ 2, 3, 6, 7, 8, 9, 10, 11 ] - ways: - - [0, 0, 0x7, [7, 2], [7, 3], [7, 6], [7, 7], [7, 8], [7, 9], [7, 10], [7, 11]] - - [0, 1, 0x38, [6, 2], [6, 3], [6, 6], [6, 7], [6, 8], [6, 9], [6, 10], [6, 11]] - - [0, 2, 0x1c0, [5, 2], [5, 3], [5, 6], [5, 7], [5, 8], [5, 9], [5, 10], [5, 11]] - - [0, 3, 0xe00, [4, 2], [4, 3], [4, 6], [4, 7], [4, 8], [4, 9], [4, 10], [4, 11]] - - [0, 0, 0x7, [3, 2], [3, 3], [3, 6], [3, 7], [3, 8], [3, 9], [3, 10], [3, 11]] - - [0, 1, 0x38, [2, 2], [2, 3], [2, 6], [2, 7], [2, 8], [2, 9], [2, 10], [2, 11]] - - [0, 2, 0x1c0, [1, 2], [1, 3], [1, 6], [1, 7], [1, 8], [1, 9], [1, 10], [1, 11]] - - [0, 3, 0x200, [0, 2], [0, 3]] - input_xbar: - group 0: { 0: ingress_metadata.bd, 16: l2_metadata.lkp_mac_da.0-15, 32: l2_metadata.lkp_mac_da.16-31, 48: l2_metadata.lkp_mac_da.32-47 } - hash 0: - 0..9: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..4)) - 10..19: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..4)) - 20..29: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..4)) - 30..39: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..4)) - 40..51: random(ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(5..15)) ^ stripe(ingress_metadata.bd(8..13), l2_metadata.lkp_mac_da.32-47(0..4)) - hash group 0: - table: [0] - format: { action(0): 0..2, version(0): 112..115, match(0): [56..71, 32..39, 72..79, 40..47, 29..31, 48..55 ], action(1): 3..5, version(1): 120..123, match(1): [104..111, 8..15, 80..87, 16..23, 88..95, 117..119, 96..103 ] } - match: [ ingress_metadata.bd(0..7), l2_metadata.lkp_mac_da.0-15, l2_metadata.lkp_mac_da.16-31, l2_metadata.lkp_mac_da.32-47(5..15) ] - next: cond-8 - action: _dmac_0.4$action - default_action: NoAction - action _dmac_0.4$action: - p4: { name: _dmac_0$action } - row: [ 14, 12, 10, 8, 6, 4, 2, 1, 0 ] - column: - - [ 4, 5 ] - - 5 - - 5 - - [ 4, 5 ] - - [ 4, 5 ] - - [ 4, 5 ] - - 5 - - [ 3, 4, 5 ] - - 5 - home_row: [ 14, 4 ] - format dmac_hit: { $adf_h0: 0..15 } - format dmac_redirect_nexthop: { $adf_h0: 0..15 } - format dmac_redirect_ecmp: { $adf_h0: 0..15 } - action_bus: { 32..33 : $adf_h0 } - actions: - nop: - - { } - dmac_hit: - - p4_param_order: {ifindex: 16 } - - { ifindex: $adf_h0 } - - set ingress_metadata.egress_ifindex, ifindex - - xor l2_metadata.same_if_check, l2_metadata.same_if_check, ifindex - dmac_multicast_hit: - - p4_param_order: {mc_index: 16 } - - { } - dmac_miss: - - { } - - set ingress_metadata.egress_ifindex, 65535 - dmac_redirect_nexthop: - - p4_param_order: {nexthop_index: 16 } - - { nexthop_index: $adf_h0 } - - set l2_metadata.l2_redirect, 1 - - set l2_metadata.l2_nexthop, nexthop_index - - set l2_metadata.l2_nexthop_type, 0 - dmac_redirect_ecmp: - - p4_param_order: {ecmp_index: 16 } - - { ecmp_index: $adf_h0 } - - set l2_metadata.l2_redirect, 1 - - set l2_metadata.l2_nexthop, ecmp_index - - set l2_metadata.l2_nexthop_type, 1 - dmac_drop: - - { } - - invalidate standard_metadata.egress_spec - NoAction: - - { } - gateway cond-8 1: - input_xbar: - group 0: { 89: l3_metadata.lkp_ip_type } - row: 1 - bus: 1 - match: { 1: l3_metadata.lkp_ip_type } - 0b*****00: _mac_acl_0 - miss: cond-10 - ternary_match _mac_acl_0 2: - p4: { name: mac_acl, size: 128 } - p4_param_order: - acl_metadata.if_label: { type: ternary, size: 16} - acl_metadata.bd_label: { type: ternary, size: 16} - l2_metadata.lkp_mac_sa: { type: ternary, size: 48} - l2_metadata.lkp_mac_da: { type: ternary, size: 48} - l2_metadata.lkp_mac_type: { type: ternary, size: 16} - row: [ 0, 1, 2, 3 ] - bus: [ 0, 0, 0, 0 ] - column: - - 0 - - 0 - - 0 - - 0 - input_xbar: - group 0: { 0: acl_metadata.bd_label, 16: acl_metadata.if_label, 32: l2_metadata.lkp_mac_da.0-15(0..7), 40: l2_metadata.lkp_mac_da.32-47(8..15) } - group 1: { 0: l2_metadata.lkp_mac_da.16-31(0..7), 8: l2_metadata.lkp_mac_da.0-15(8..15), 16: l2_metadata.lkp_mac_da.32-47(0..7), 24: l2_metadata.lkp_mac_da.16-31(8..15), 32: l2_metadata.lkp_mac_sa.0-15(0..7) } - group 2: { 0: l2_metadata.lkp_mac_sa.0-15(8..15), 8: l2_metadata.lkp_mac_sa.16-31, 24: l2_metadata.lkp_mac_sa.32-47 } - group 3: { 0: l2_metadata.lkp_mac_type(8..15), 8: l2_metadata.lkp_mac_type(0..7) } - gateway: - input_xbar: - group 0: { 64: ingress_metadata.bypass_lookups } - row: 1 - bus: 0 - match: { 0: ingress_metadata.bypass_lookups(0..7), 8: ingress_metadata.bypass_lookups(8..15) } - 0b*************0**: run_table - miss: _compute_other_hashes_0 - next: _compute_other_hashes_0 - indirect: _mac_acl_0$tind - ternary_indirect _mac_acl_0$tind: - row: 0 - bus: 0 - column: 4 - format: { action: 0..2} - action: _mac_acl_0$action - default_action: NoAction - action _mac_acl_0$action: - p4: { name: _mac_acl_0$action } - row: 10 - column: 4 - home_row: 10 - format acl_deny: { $adf_h1: 32..47, $adf_h2: 48..63 } - format acl_permit: { $adf_h1: 32..47, $adf_h2: 48..63 } - format acl_redirect_nexthop: { $adf_h0: 16..31, $adf_h1: 32..47, $adf_h2: 48..63 } - format acl_redirect_ecmp: { $adf_h0: 16..31, $adf_h1: 32..47, $adf_h2: 48..63 } - action_bus: { 66..67 : $adf_h0, 68..69 : $adf_h1, 70..71 : $adf_h2 } - actions: - nop: - - { } - acl_deny: - - p4_param_order: {acl_stats_index: 14, acl_meter_index: 16, acl_copy_reason: 16, nat_mode: 2, ingress_cos: 8, tc: 8, color: 8 } - - { acl_stats_index: $adf_h1, acl_copy_reason: $adf_h2 } - - set acl_metadata.acl_deny, 1 - - set acl_metadata.acl_stats_index, acl_stats_index - - set fabric_metadata.reason_code, acl_copy_reason - acl_permit: - - p4_param_order: {acl_stats_index: 14, acl_meter_index: 16, acl_copy_reason: 16, nat_mode: 2, ingress_cos: 8, tc: 8, color: 8 } - - { acl_stats_index: $adf_h1, acl_copy_reason: $adf_h2 } - - set acl_metadata.acl_stats_index, acl_stats_index - - set fabric_metadata.reason_code, acl_copy_reason - acl_redirect_nexthop: - - p4_param_order: {nexthop_index: 16, acl_stats_index: 14, acl_meter_index: 16, acl_copy_reason: 16, nat_mode: 2, ingress_cos: 8, tc: 8, color: 8 } - - { acl_stats_index: $adf_h0, acl_copy_reason: $adf_h1, nexthop_index: $adf_h2 } - - set acl_metadata.acl_redirect, 1 - - set acl_metadata.acl_nexthop, nexthop_index - - set acl_metadata.acl_nexthop_type, 0 - - set acl_metadata.acl_stats_index, acl_stats_index - - set fabric_metadata.reason_code, acl_copy_reason - acl_redirect_ecmp: - - p4_param_order: {ecmp_index: 16, acl_stats_index: 14, acl_meter_index: 16, acl_copy_reason: 16, nat_mode: 2, ingress_cos: 8, tc: 8, color: 8 } - - { acl_stats_index: $adf_h0, acl_copy_reason: $adf_h1, ecmp_index: $adf_h2 } - - set acl_metadata.acl_redirect, 1 - - set acl_metadata.acl_nexthop, ecmp_index - - set acl_metadata.acl_nexthop_type, 1 - - set acl_metadata.acl_stats_index, acl_stats_index - - set fabric_metadata.reason_code, acl_copy_reason - NoAction: - - { } - gateway cond-10 3: - input_xbar: - group 0: { 64: ingress_metadata.bypass_lookups } - row: 0 - bus: 1 - match: { 0: ingress_metadata.bypass_lookups(0..7), 8: ingress_metadata.bypass_lookups(8..15) } - 0b*************0**: _ip_acl_0 - miss: _compute_other_hashes_0 - ternary_match _ip_acl_0 4: - p4: { name: ip_acl, size: 128 } - p4_param_order: - acl_metadata.if_label: { type: ternary, size: 16} - acl_metadata.bd_label: { type: ternary, size: 16} - ipv4_metadata.lkp_ipv4_sa: { type: ternary, size: 32} - ipv4_metadata.lkp_ipv4_da: { type: ternary, size: 32} - l3_metadata.lkp_ip_proto: { type: ternary, size: 8} - acl_metadata.ingress_src_port_range_id: { type: exact, size: 8} - acl_metadata.ingress_dst_port_range_id: { type: exact, size: 8} - tcp.flags: { type: ternary, size: 8} - l3_metadata.lkp_ip_ttl: { type: ternary, size: 8} - row: [ 4, 5, 6, 7 ] - bus: [ 0, 0, 0, 0 ] - column: - - 0 - - 0 - - 0 - - 0 - input_xbar: - group 3: { 16: acl_metadata.if_label(8..15), 24: acl_metadata.ingress_dst_port_range_id, 32: acl_metadata.ingress_src_port_range_id } - group 4: { 0: ipv4_metadata.lkp_ipv4_da(16..31), 16: ipv4_metadata.lkp_ipv4_da(0..15), 32: ipv4_metadata.lkp_ipv4_sa(16..23), 40: acl_metadata.bd_label(8..15) } - group 5: { 0: ipv4_metadata.lkp_ipv4_sa(0..15), 16: acl_metadata.bd_label(0..7), 24: ipv4_metadata.lkp_ipv4_sa(24..31), 32: acl_metadata.if_label(0..7) } - group 6: { 0: l3_metadata.lkp_ip_proto, 8: l3_metadata.lkp_ip_ttl, 16: tcp.flags } - gateway: - input_xbar: - group 0: { 89: l3_metadata.lkp_ip_type } - row: 0 - bus: 0 - match: { 1: l3_metadata.lkp_ip_type } - 0b*****01: run_table - miss: _compute_other_hashes_0 - next: _compute_other_hashes_0 - indirect: _ip_acl_0$tind - ternary_indirect _ip_acl_0$tind: - row: 1 - bus: 0 - column: 4 - format: { action: 0..2} - action: _ip_acl_0$action - default_action: NoAction - action _ip_acl_0$action: - p4: { name: _ip_acl_0$action } - row: 12 - column: 4 - home_row: 12 - format acl_deny: { $adf_h1: 32..47, $adf_h2: 48..63 } - format acl_permit: { $adf_h1: 32..47, $adf_h2: 48..63 } - format acl_redirect_nexthop: { $adf_h0: 16..31, $adf_h1: 32..47, $adf_h2: 48..63 } - format acl_redirect_ecmp: { $adf_h0: 16..31, $adf_h1: 32..47, $adf_h2: 48..63 } - action_bus: { 74..75 : $adf_h0, 76..77 : $adf_h1, 78..79 : $adf_h2 } - actions: - nop: - - { } - acl_deny: - - p4_param_order: {acl_stats_index: 14, acl_meter_index: 16, acl_copy_reason: 16, nat_mode: 2, ingress_cos: 8, tc: 8, color: 8 } - - { acl_stats_index: $adf_h1, acl_copy_reason: $adf_h2 } - - set acl_metadata.acl_deny, 1 - - set acl_metadata.acl_stats_index, acl_stats_index - - set fabric_metadata.reason_code, acl_copy_reason - acl_permit: - - p4_param_order: {acl_stats_index: 14, acl_meter_index: 16, acl_copy_reason: 16, nat_mode: 2, ingress_cos: 8, tc: 8, color: 8 } - - { acl_stats_index: $adf_h1, acl_copy_reason: $adf_h2 } - - set acl_metadata.acl_stats_index, acl_stats_index - - set fabric_metadata.reason_code, acl_copy_reason - acl_redirect_nexthop: - - p4_param_order: {nexthop_index: 16, acl_stats_index: 14, acl_meter_index: 16, acl_copy_reason: 16, nat_mode: 2, ingress_cos: 8, tc: 8, color: 8 } - - { acl_stats_index: $adf_h0, acl_copy_reason: $adf_h1, nexthop_index: $adf_h2 } - - set acl_metadata.acl_redirect, 1 - - set acl_metadata.acl_nexthop, nexthop_index - - set acl_metadata.acl_nexthop_type, 0 - - set acl_metadata.acl_stats_index, acl_stats_index - - set fabric_metadata.reason_code, acl_copy_reason - acl_redirect_ecmp: - - p4_param_order: {ecmp_index: 16, acl_stats_index: 14, acl_meter_index: 16, acl_copy_reason: 16, nat_mode: 2, ingress_cos: 8, tc: 8, color: 8 } - - { acl_stats_index: $adf_h0, acl_copy_reason: $adf_h1, ecmp_index: $adf_h2 } - - set acl_metadata.acl_redirect, 1 - - set acl_metadata.acl_nexthop, ecmp_index - - set acl_metadata.acl_nexthop_type, 1 - - set acl_metadata.acl_stats_index, acl_stats_index - - set fabric_metadata.reason_code, acl_copy_reason - NoAction: - - { } - exact_match _compute_other_hashes_0 5: - p4: { name: compute_other_hashes } - p4_param_order: - hash_metadata.hash1: { type: exact, size: 16} - row: 0 - bus: 1 - column: [ 6, 7, 8 ] - ways: - - [1, 0, 0x0, [0, 6]] - - [1, 1, 0x0, [0, 7]] - - [1, 2, 0x0, [0, 8]] - input_xbar: - group 0: { 80: hash_metadata.hash1(0..7), 104: hash_metadata.hash1(8..15) } - hash 1: - 0..9: random(hash_metadata.hash1(10..15)) ^ stripe(hash_metadata.hash1(0..7), hash_metadata.hash1(8..9)) - 10..19: random(hash_metadata.hash1(10..15)) ^ stripe(hash_metadata.hash1(0..7), hash_metadata.hash1(8..9)) - 20..29: random(hash_metadata.hash1(10..15)) ^ stripe(hash_metadata.hash1(0..7), hash_metadata.hash1(8..9)) - hash group 1: - table: [1] - format: { action(0): 0..1, version(0): 112..115, match(0): 34..39 } - match: [ hash_metadata.hash1(10..15) ] - next: _spanning_tree_0 - actions: - computed_two_hashes: - - 0 - computed_one_hash: - - set hash_metadata.hash1, hash_metadata.hash2 - NoAction: - - 0 - default_action: NoAction -stage 8 ingress: - exact_match _spanning_tree_0 0: - p4: { name: spanning_tree, size: 4096 } - p4_param_order: - ingress_metadata.ifindex: { type: exact, size: 16} - l2_metadata.stp_group: { type: exact, size: 10} - row: [ 5, 6 ] - bus: [ 0, 0 ] - column: - - 2 - - [ 2, 3, 4 ] - ways: - - [0, 0, 0x0, [6, 2]] - - [0, 1, 0x0, [6, 3]] - - [0, 2, 0x0, [6, 4]] - - [0, 3, 0x0, [5, 2]] - input_xbar: - group 0: { 0: ingress_metadata.ifindex, 16: l2_metadata.stp_group } - hash 0: - 0..9: random(ingress_metadata.ifindex, l2_metadata.stp_group(1..7)) ^ stripe(l2_metadata.stp_group(0), l2_metadata.stp_group(8..9)) - 10..19: random(ingress_metadata.ifindex, l2_metadata.stp_group(1..7)) ^ stripe(l2_metadata.stp_group(0), l2_metadata.stp_group(8..9)) - 20..29: random(ingress_metadata.ifindex, l2_metadata.stp_group(1..7)) ^ stripe(l2_metadata.stp_group(0), l2_metadata.stp_group(8..9)) - 30..39: random(ingress_metadata.ifindex, l2_metadata.stp_group(1..7)) ^ stripe(l2_metadata.stp_group(0), l2_metadata.stp_group(8..9)) - hash group 0: - table: [0] - format: { action(0): 7..7, immediate(0): 0..6, version(0): 112..115, match(0): [40..47, 32..39, 48..55 ] } - match: [ ingress_metadata.ifindex, l2_metadata.stp_group(0..7) ] - gateway: - input_xbar: - group 0: { 16: l2_metadata.stp_group, 46: ingress_metadata.port_type } - row: 1 - bus: 0 - match: { 0: l2_metadata.stp_group(0..7), 8: l2_metadata.stp_group(8..9), 22: ingress_metadata.port_type } - 0b******00********00000000: _ingress_bd_stats_2 - 0b00**********************: run_table - miss: _ingress_bd_stats_2 - next: _ingress_bd_stats_2 - action_bus: { } - actions: - set_stp_state: - - p4_param_order: {stp_state: 3 } - - { stp_state: immediate(0..6) } - - set l2_metadata.stp_state, stp_state - NoAction: - - { } - default_action: NoAction - hash_action _ingress_bd_stats_2 1: - p4: { name: ingress_bd_stats, size: 16384 } - row: 0 - bus: 0 - column: [ ] - hash_dist: - 0: {hash: 1, mask: 0xffff, shift: 3} - input_xbar: - exact group 0: { 64: l2_metadata.bd_stats_idx } - hash 1: - 0..15: l2_metadata.bd_stats_idx - hash group 1: - table: [1] - gateway: - input_xbar: - group 0: { 46: ingress_metadata.port_type } - row: 0 - bus: 1 - payload: 1 - match: { 6: ingress_metadata.port_type } - 0x1: run_table - miss: _fwd_result_0 - next: cond-18 - stats: _ingress_bd_stats_2$counter..ingress_bd_stats(hash_dist 0) - actions: - update_ingress_bd_stats: - - 0 - NoAction: - - 0 - default_action: NoAction - counter _ingress_bd_stats_2$counter..ingress_bd_stats: - p4: { name: ingress_bd_stats } - row: [ 9, 7 ] - column: - - [ 0, 1, 2, 3, 4, 5 ] - - 0 - maprams: - - [ 0, 1, 2, 3, 4, 5 ] - - 0 - count: packets_and_bytes - format: {packets(0): 85..101, bytes(0): 102..126, packets(1): 42..58, bytes(1): 59..83, packets(2): 0..16, bytes(2): 17..41} - ternary_match _fwd_result_0 2: - p4: { name: fwd_result, size: 512 } - p4_param_order: - l2_metadata.l2_redirect: { type: ternary, size: 1} - acl_metadata.acl_redirect: { type: ternary, size: 1} - acl_metadata.racl_redirect: { type: ternary, size: 1} - l3_metadata.rmac_hit: { type: ternary, size: 1} - l3_metadata.fib_hit: { type: ternary, size: 1} - nat_metadata.nat_hit: { type: ternary, size: 1} - l2_metadata.lkp_pkt_type: { type: ternary, size: 3} - l3_metadata.lkp_ip_type: { type: ternary, size: 2} - multicast_metadata.igmp_snooping_enabled: { type: ternary, size: 1} - multicast_metadata.mld_snooping_enabled: { type: ternary, size: 1} - multicast_metadata.mcast_route_hit: { type: ternary, size: 1} - multicast_metadata.mcast_bridge_hit: { type: ternary, size: 1} - multicast_metadata.mcast_rpf_group: { type: ternary, size: 14} - multicast_metadata.mcast_mode: { type: ternary, size: 2} - row: [ 0, 1, 2 ] - bus: [ 0, 0, 0 ] - column: - - 0 - - 0 - - 0 - input_xbar: - group 0: { 0: multicast_metadata.mcast_rpf_group(0..7), 9: l3_metadata.lkp_ip_type, 21: acl_metadata.acl_redirect, 28: multicast_metadata.mcast_mode, 36: acl_metadata.racl_redirect, 43: l2_metadata.lkp_pkt_type } - group 1: { 6: l2_metadata.l2_redirect, 8: multicast_metadata.mcast_rpf_group(8..13), 21: l3_metadata.fib_hit, 28: l3_metadata.rmac_hit, 38: multicast_metadata.igmp_snooping_enabled } - group 2: { 4: multicast_metadata.mcast_bridge_hit, 13: multicast_metadata.mcast_route_hit, 21: multicast_metadata.mld_snooping_enabled, 28: nat_metadata.nat_hit } - gateway: - input_xbar: - group 0: { 32: ingress_metadata.bypass_lookups(0..7), 56: ingress_metadata.bypass_lookups(8..15) } - row: 0 - bus: 0 - match: { 0: ingress_metadata.bypass_lookups(0..7), 8: ingress_metadata.bypass_lookups(8..15) } - 0x**ff: _acl_stats_2 - miss: run_table - next: _acl_stats_2 - action_bus: { } - indirect: _fwd_result_0$tind - ternary_indirect _fwd_result_0$tind: - row: 0 - bus: 0 - column: 2 - format: { action: 9..11, immediate: 0..8} - actions: - nop: - - { } - set_l2_redirect_action: - - { } - - set l3_metadata.nexthop_index, l2_metadata.l2_nexthop - - set nexthop_metadata.nexthop_type, l2_metadata.l2_nexthop_type - - set ingress_metadata.egress_ifindex, 0 - set_fib_redirect_action: - - { } - - set l3_metadata.nexthop_index, 0 - - set nexthop_metadata.nexthop_type, 0 - - set l3_metadata.routed, 1 - - set fabric_metadata.reason_code, 535 - set_cpu_redirect_action: - - { $constant0: immediate(0..8), $constant0: 64 } - - set l3_metadata.routed, 0 - - set standard_metadata.egress_spec, $constant0 - - set ingress_metadata.egress_ifindex, 0 - set_acl_redirect_action: - - { } - - set l3_metadata.nexthop_index, acl_metadata.acl_nexthop - - set nexthop_metadata.nexthop_type, acl_metadata.acl_nexthop_type - - set ingress_metadata.egress_ifindex, 0 - set_racl_redirect_action: - - { } - - set l3_metadata.nexthop_index, 0 - - set nexthop_metadata.nexthop_type, 0 - - set l3_metadata.routed, 1 - - set ingress_metadata.egress_ifindex, 0 - NoAction: - - { } - default_action: NoAction - hash_action _acl_stats_2 3: - p4: { name: acl_stats, size: 128 } - row: 1 - bus: 0 - column: [ ] - hash_dist: - 1: {hash: 1, mask: 0x3fff, shift: 3} - input_xbar: - exact group 0: { 80: acl_metadata.acl_stats_index } - hash 1: - 16..29: acl_metadata.acl_stats_index - hash group 1: - table: [1] - gateway: - row: 2 - bus: 0 - 0x0: _ecmp_group_0 - miss: _ecmp_group_0 - next: _ecmp_group_0 - stats: _acl_stats_2$counter..acl_stats(hash_dist 1) - actions: - acl_stats_update: - - 0 - NoAction: - - 0 - default_action: NoAction - counter _acl_stats_2$counter..acl_stats: - p4: { name: acl_stats } - row: 5 - column: [ 0, 1 ] - maprams: [ 0, 1 ] - count: packets_and_bytes - format: {packets(0): 85..101, bytes(0): 102..126, packets(1): 42..58, bytes(1): 59..83, packets(2): 0..16, bytes(2): 17..41} -stage 9 ingress: - exact_match _ecmp_group_0 0: - p4: { name: ecmp_group, size: 1024, action_profile: ecmp_action_profile } - p4_param_order: - l3_metadata.nexthop_index: { type: exact, size: 16} - row: 7 - bus: 0 - column: [ 2, 3, 4 ] - ways: - - [0, 0, 0x0, [7, 2]] - - [0, 1, 0x0, [7, 3]] - - [0, 2, 0x0, [7, 4]] - input_xbar: - group 0: { 0: l3_metadata.nexthop_index } - hash 0: - 0..9: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) - 10..19: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) - 20..29: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) - hash group 0: - table: [0] - format: { action(0): 26..27, version(0): 112..115, meter_addr(0): 0..9, meter_pfe(0): 10..10, action_addr(0): 11..25, match(0): 34..39 } - match: [ l3_metadata.nexthop_index(10..15) ] - gateway: - input_xbar: - group 0: { 30: nexthop_metadata.nexthop_type } - row: 0 - bus: 0 - match: { 6: nexthop_metadata.nexthop_type } - 0x1: run_table - miss: _nexthop_0 - next: _learn_notify_0 - action: _ecmp_group_0$act_prof..ecmp_action_profile(action, action_addr) - selector: _ecmp_group_0$act_sel..ecmp_action_profile(meter_addr) - default_action: NoAction - action _ecmp_group_0$act_prof..ecmp_action_profile: - row: [ 11, 10 ] - column: - - [ 1, 2, 3, 4, 5 ] - - [ 2, 3, 4 ] - home_row: 11 - format set_ecmp_nexthop_details: { $adf_b0: 0..7, $adf_h0: 16..31, $adf_h1: 32..47, $adf_h2: 48..63 } - format set_ecmp_nexthop_details_for_post_routed_flood: { $adf_h1: 32..47, $adf_h2: 48..63 } - action_bus: { 0 : $adf_b0, 66..67 : $adf_h0, 68..69 : $adf_h1, 70..71 : $adf_h2 } - actions: - nop: - - { } - set_ecmp_nexthop_details: - - p4_param_order: {ifindex: 16, bd: 14, nhop_index: 16, tunnel: 1 } - - { $data0: $adf_b0, $constant0: $data0(0..0), $constant0: 0, tunnel: $data0(0..0), bd: $adf_h0, ifindex: $adf_h1, nhop_index: $adf_h2 } - - set ingress_metadata.egress_ifindex, ifindex - - set l3_metadata.nexthop_index, nhop_index - - xor l3_metadata.same_bd_check, ingress_metadata.bd, bd - - xor l2_metadata.same_if_check, l2_metadata.same_if_check, ifindex - - xor tunnel_metadata.tunnel_if_check, $constant0, tunnel - set_ecmp_nexthop_details_for_post_routed_flood: - - p4_param_order: {bd: 14, uuc_mc_index: 16, nhop_index: 16 } - - { bd: $adf_h1, nhop_index: $adf_h2 } - - set l3_metadata.nexthop_index, nhop_index - - set ingress_metadata.egress_ifindex, 0 - - xor l3_metadata.same_bd_check, ingress_metadata.bd, bd - NoAction: - - { } - selection _ecmp_group_0$act_sel..ecmp_action_profile: - p4: { name: ecmp_action_profile } - row: 15 - column: [ 4, 5 ] - maprams: [ 4, 5 ] - input_xbar: - group 0: { 64: hash_metadata.hash1 } - hash 1: - 0..13: random(hash_metadata.hash1) - hash group 1: - table: [1] - mode: fair 0 - per_flow_enable: meter_pfe - non_linear: true - pool_sizes: [4, 120] - exact_match _nexthop_0 1: - p4: { name: nexthop, size: 16384 } - p4_param_order: - l3_metadata.nexthop_index: { type: exact, size: 16} - row: 6 - bus: 0 - column: [ 2, 3, 4, 6 ] - ways: - - [2, 0, 0x0, [6, 2]] - - [2, 1, 0x0, [6, 3]] - - [2, 2, 0x0, [6, 4]] - - [2, 3, 0x0, [6, 6]] - input_xbar: - group 1: { 0: l3_metadata.nexthop_index } - hash 2: - 0..9: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) - 10..19: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) - 20..29: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) - 30..39: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) - hash group 2: - table: [2] - format: { action(0): 0..1, version(0): 112..115, match(0): 34..39, action(1): 2..3, version(1): 116..119, match(1): 42..47, action(2): 4..5, version(2): 120..123, match(2): 50..55, action(3): 6..7, version(3): 124..127, match(3): 58..63 } - match: [ l3_metadata.nexthop_index(10..15) ] - next: _learn_notify_0 - action: _nexthop_0$action - default_action: NoAction - action _nexthop_0$action: - p4: { name: _nexthop_0$action } - row: [ 14, 13, 12, 11 ] - column: - - 5 - - [ 1, 2, 3, 4, 5 ] - - 5 - - 0 - home_row: 14 - format set_nexthop_details: { $adf_b0: 0..7, $adf_h0: 32..47, $adf_h1: 48..63 } - format set_nexthop_details_for_post_routed_flood: { $adf_h1: 48..63 } - action_bus: { 2 : $adf_b0, 32..33 : $adf_h0, 34..35 : $adf_h1 } - actions: - nop: - - { } - set_nexthop_details: - - p4_param_order: {ifindex: 16, bd: 14, tunnel: 1 } - - { $data0: $adf_b0, $constant0: $data0(0..0), $constant0: 0, tunnel: $data0(0..0), bd: $adf_h0, ifindex: $adf_h1 } - - set ingress_metadata.egress_ifindex, ifindex - - xor l3_metadata.same_bd_check, ingress_metadata.bd, bd - - xor l2_metadata.same_if_check, l2_metadata.same_if_check, ifindex - - xor tunnel_metadata.tunnel_if_check, $constant0, tunnel - set_nexthop_details_for_post_routed_flood: - - p4_param_order: {bd: 14, uuc_mc_index: 16 } - - { bd: $adf_h1 } - - set ingress_metadata.egress_ifindex, 0 - - xor l3_metadata.same_bd_check, ingress_metadata.bd, bd - NoAction: - - { } - ternary_match _learn_notify_0 3: - p4: { name: learn_notify, size: 512 } - p4_param_order: - l2_metadata.l2_src_miss: { type: ternary, size: 1} - l2_metadata.l2_src_move: { type: ternary, size: 16} - l2_metadata.stp_state: { type: ternary, size: 3} - row: 0 - bus: 0 - column: 0 - input_xbar: - group 0: { 0: l2_metadata.l2_src_move, 21: l2_metadata.l2_src_miss, 28: l2_metadata.stp_state } - gateway: - input_xbar: - group 0: { 20: l2_metadata.learning_enabled } - row: 0 - bus: 1 - match: { 4: l2_metadata.learning_enabled } - 0b***1: run_table - miss: _lag_group_0 - next: _lag_group_0 - indirect: _learn_notify_0$tind - ternary_indirect _learn_notify_0$tind: - row: 0 - bus: 0 - column: 2 - format: { action: 0..1} - actions: - nop: - - 0 - generate_learn_notify: - - set $learning, 1 - NoAction: - - 0 - default_action: NoAction -stage 10 ingress: - exact_match _lag_group_0 0: - p4: { name: lag_group, size: 1024, action_profile: lag_action_profile } - p4_param_order: - ingress_metadata.egress_ifindex: { type: exact, size: 16} - row: 6 - bus: 1 - column: [ 3, 4, 6 ] - ways: - - [0, 0, 0x0, [6, 3]] - - [0, 1, 0x0, [6, 4]] - - [0, 2, 0x0, [6, 6]] - input_xbar: - group 0: { 0: ingress_metadata.egress_ifindex } - hash 0: - 0..9: random(ingress_metadata.egress_ifindex(10..15)) ^ stripe(ingress_metadata.egress_ifindex(0..7), ingress_metadata.egress_ifindex(8..9)) - 10..19: random(ingress_metadata.egress_ifindex(10..15)) ^ stripe(ingress_metadata.egress_ifindex(0..7), ingress_metadata.egress_ifindex(8..9)) - 20..29: random(ingress_metadata.egress_ifindex(10..15)) ^ stripe(ingress_metadata.egress_ifindex(0..7), ingress_metadata.egress_ifindex(8..9)) - hash group 0: - table: [0] - format: { action(0): 22..23, version(0): 112..115, meter_addr(0): 0..9, meter_pfe(0): 10..10, action_addr(0): 11..21, match(0): 34..39 } - match: [ ingress_metadata.egress_ifindex(10..15) ] - gateway: - input_xbar: - group 0: { 0: ingress_metadata.egress_ifindex } - row: 1 - bus: 0 - match: { 0: ingress_metadata.egress_ifindex(0..7), 8: ingress_metadata.egress_ifindex(8..15) } - 0x**ff: cond-18 - miss: run_table - next: cond-18 - action: _lag_group_0$act_prof..lag_action_profile(action, action_addr) - selector: _lag_group_0$act_sel..lag_action_profile(meter_addr) - default_action: NoAction - action _lag_group_0$act_prof..lag_action_profile: - row: 14 - column: 5 - home_row: 14 - format set_lag_port: { $adf_h0: 0..15 } - action_bus: { 32..33 : $adf_h0 } - actions: - set_lag_miss: - - { } - set_lag_port: - - p4_param_order: {port: 9 } - - { port: $adf_h0 } - - set standard_metadata.egress_spec, port - NoAction: - - { } - selection _lag_group_0$act_sel..lag_action_profile: - p4: { name: lag_action_profile } - row: 15 - column: [ 4, 5 ] - maprams: [ 4, 5 ] - input_xbar: - group 0: { 64: hash_metadata.hash2 } - hash 1: - 0..13: random(hash_metadata.hash2) - hash group 1: - table: [1] - mode: fair 0 - per_flow_enable: meter_pfe - non_linear: true - pool_sizes: [4, 120] - gateway cond-18 1: - input_xbar: - group 0: { 30: ingress_metadata.port_type } - row: 0 - bus: 1 - match: { 6: ingress_metadata.port_type } - 0x1: END - miss: _system_acl_0 -stage 11 ingress: - ternary_match _system_acl_0 0: - p4: { name: system_acl, size: 512 } - p4_param_order: - acl_metadata.if_label: { type: ternary, size: 16} - acl_metadata.bd_label: { type: ternary, size: 16} - ingress_metadata.ifindex: { type: ternary, size: 16} - l2_metadata.lkp_mac_type: { type: ternary, size: 16} - l2_metadata.port_vlan_mapping_miss: { type: ternary, size: 1} - security_metadata.ipsg_check_fail: { type: ternary, size: 1} - acl_metadata.acl_deny: { type: ternary, size: 1} - acl_metadata.racl_deny: { type: ternary, size: 1} - l3_metadata.urpf_check_fail: { type: ternary, size: 1} - ingress_metadata.drop_flag: { type: ternary, size: 1} - l3_metadata.l3_copy: { type: ternary, size: 1} - l3_metadata.rmac_hit: { type: ternary, size: 1} - l3_metadata.routed: { type: ternary, size: 1} - ipv6_metadata.ipv6_src_is_link_local: { type: ternary, size: 1} - l2_metadata.same_if_check: { type: ternary, size: 16} - tunnel_metadata.tunnel_if_check: { type: ternary, size: 1} - l3_metadata.same_bd_check: { type: ternary, size: 14} - l3_metadata.lkp_ip_ttl: { type: ternary, size: 8} - l2_metadata.stp_state: { type: ternary, size: 3} - ingress_metadata.control_frame: { type: ternary, size: 1} - ipv4_metadata.ipv4_unicast_enabled: { type: ternary, size: 1} - ipv6_metadata.ipv6_unicast_enabled: { type: ternary, size: 1} - ingress_metadata.egress_ifindex: { type: ternary, size: 16} - fabric_metadata.reason_code: { type: ternary, size: 16} - row: [ 0, 1, 2, 3, 4, 5 ] - bus: [ 0, 0, 0, 0, 0, 0 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - input_xbar: - group 0: { 0: acl_metadata.bd_label, 16: acl_metadata.if_label, 32: fabric_metadata.reason_code(0..7) } - group 1: { 0: ingress_metadata.egress_ifindex(0..7), 8: fabric_metadata.reason_code(8..15), 16: ingress_metadata.ifindex(0..7), 24: ingress_metadata.egress_ifindex(8..15), 32: l2_metadata.lkp_mac_type(0..7), 42: ipv6_metadata.ipv6_src_is_link_local } - group 2: { 0: ingress_metadata.ifindex(8..15), 8: l2_metadata.same_if_check(0..7), 23: ipv6_metadata.ipv6_unicast_enabled, 24: l3_metadata.same_bd_check(0..7), 32: l2_metadata.lkp_mac_type(8..15) } - group 3: { 0: l2_metadata.same_if_check(8..15), 12: acl_metadata.acl_deny, 16: l3_metadata.same_bd_check(8..13), 30: acl_metadata.racl_deny, 37: ingress_metadata.control_frame, 42: ingress_metadata.drop_flag } - group 4: { 5: ipv4_metadata.ipv4_unicast_enabled, 14: l2_metadata.port_vlan_mapping_miss, 20: l2_metadata.stp_state, 30: l3_metadata.l3_copy, 32: l3_metadata.lkp_ip_ttl } - group 5: { 4: l3_metadata.rmac_hit, 12: l3_metadata.routed, 22: l3_metadata.urpf_check_fail, 30: security_metadata.ipsg_check_fail, 32: tunnel_metadata.tunnel_if_check } - gateway: - input_xbar: - group 0: { 0: ingress_metadata.bypass_lookups } - row: 0 - bus: 0 - match: { 0: ingress_metadata.bypass_lookups(0..7), 8: ingress_metadata.bypass_lookups(8..15) } - 0b**********0*****: run_table - miss: END - next: _drop_stats_4 - action_bus: { } - indirect: _system_acl_0$tind - counter _system_acl_0$counter..drop_stats: - p4: { name: drop_stats } - row: 13 - column: [ 0, 1 ] - maprams: [ 0, 1 ] - count: packets - format: {packets(0): 106..126, packets(1): 85..105, packets(2): 64..84, packets(3): 42..62, packets(4): 21..41, packets(5): 0..20} - per_flow_enable: counter_pfe - ternary_indirect _system_acl_0$tind: - row: 0 - bus: 0 - column: 2 - format: { action: 27..29, immediate: 11..26, counter_addr: 0..9, counter_pfe: 10..10} - stats: _system_acl_0$counter..drop_stats(counter_addr) - actions: - nop: - - { } - redirect_to_cpu: - - p4_param_order: {qid: 5, meter_id: 8, icos: 3 } - - { } - - invalidate standard_metadata.egress_spec - redirect_to_cpu_with_reason: - - p4_param_order: {reason_code: 16, qid: 5, meter_id: 8, icos: 3 } - - { reason_code: immediate(0..15) } - - set fabric_metadata.reason_code, reason_code - - invalidate standard_metadata.egress_spec - copy_to_cpu: - - p4_param_order: {qid: 5, meter_id: 8, icos: 3 } - - { } - copy_to_cpu_with_reason: - - p4_param_order: {reason_code: 16, qid: 5, meter_id: 8, icos: 3 } - - { reason_code: immediate(0..15) } - - set fabric_metadata.reason_code, reason_code - drop_packet: - - { } - - invalidate standard_metadata.egress_spec - drop_packet_with_reason: - - p4_param_order: {drop_reason: 32 } - - { } - - { drop_reason: counter_addr } - - invalidate standard_metadata.egress_spec - NoAction: - - { } - default_action: NoAction - hash_action _drop_stats_4 1: - p4: { name: drop_stats, size: 256 } - row: 0 - bus: 0 - column: [ ] - hash_dist: - 0: {hash: 0, mask: 0xff, shift: 3} - input_xbar: - exact group 0: { 16: ingress_metadata.drop_reason } - hash 0: - 0..7: ingress_metadata.drop_reason - hash group 0: - table: [0] - gateway: - input_xbar: - group 0: { 70: ingress_metadata.drop_flag } - row: 0 - bus: 1 - payload: 1 - match: { 6: ingress_metadata.drop_flag } - 0b*1: END - miss: run_table - next: END - stats: _drop_stats_4$counter..drop_stats_2(hash_dist 0) - actions: - drop_stats_update: - - 0 - NoAction: - - 0 - default_action: NoAction - counter _drop_stats_4$counter..drop_stats_2: - p4: { name: drop_stats_2 } - row: 9 - column: [ 0, 1 ] - maprams: [ 0, 1 ] - count: packets - format: {packets(0): 106..126, packets(1): 85..105, packets(2): 64..84, packets(3): 42..62, packets(4): 21..41, packets(5): 0..20} -stage 0 egress: - exact_match egress_port_mapping 3: - p4: { name: egress_port_mapping, size: 288 } - p4_param_order: - standard_metadata.egress_port: { type: exact, size: 9} - row: 2 - bus: 1 - column: [ 6, 7, 8 ] - ways: - - [1, 0, 0x0, [2, 6]] - - [1, 1, 0x0, [2, 7]] - - [1, 2, 0x0, [2, 8]] - input_xbar: - group 0: { 64: standard_metadata.egress_port } - hash 1: - 0..9: random(standard_metadata.egress_port(1..7)) ^ stripe(standard_metadata.egress_port(0), standard_metadata.egress_port(8)) - 10..19: random(standard_metadata.egress_port(1..7)) ^ stripe(standard_metadata.egress_port(0), standard_metadata.egress_port(8)) - 20..29: random(standard_metadata.egress_port(1..7)) ^ stripe(standard_metadata.egress_port(0), standard_metadata.egress_port(8)) - hash group 1: - table: [1] - format: { action(0): 0..1, immediate(0): 2..22, version(0): 112..115, match(0): 33..39 } - match: [ standard_metadata.egress_port(1..7) ] - gateway: - input_xbar: - group 0: { 17: eg_intr_md.deflection_flag, 28: egress_metadata.bypass } - row: 0 - bus: 1 - match: { 1: eg_intr_md.deflection_flag, 12: egress_metadata.bypass } - 0b***0**********0: run_table - miss: _egress_system_acl_0 - hit: [ _vlan_decap_0, _tunnel_encap_process_outer_0, _tunnel_encap_process_outer_0, _tunnel_encap_process_outer_0 ] - miss: _tunnel_encap_process_outer_0 - action_bus: { } - actions: - egress_port_type_normal: - - p4_param_order: {ifindex: 16, qos_group: 5, if_label: 16 } - - { ifindex: immediate(0..15) } - - set egress_metadata.port_type, 0 - - set egress_metadata.ifindex, ifindex - egress_port_type_fabric: - - p4_param_order: {ifindex: 16 } - - { ifindex: immediate(0..15), $constant0: immediate(16..20), $constant0: 15 } - - set egress_metadata.port_type, 1 - - set egress_metadata.ifindex, ifindex - - set tunnel_metadata.egress_tunnel_type, $constant0 - egress_port_type_cpu: - - p4_param_order: {ifindex: 16 } - - { ifindex: immediate(0..15), $constant0: immediate(16..20), $constant0: 16 } - - set egress_metadata.port_type, 2 - - set egress_metadata.ifindex, ifindex - - set tunnel_metadata.egress_tunnel_type, $constant0 - NoAction: - - { } - default_action: NoAction - exact_match _vlan_decap_0 5: - p4: { name: vlan_decap, size: 256 } - p4_param_order: - vlan_tag_$0.$valid: { type: exact, size: 1} - vlan_tag_$1.$valid: { type: exact, size: 1} - row: 3 - bus: 1 - column: [ 6, 7, 8 ] - ways: - - [3, 0, 0x0, [3, 6]] - - [3, 1, 0x0, [3, 7]] - - [3, 2, 0x0, [3, 8]] - input_xbar: - group 2: { 5: vlan_tag_$0.$valid, 14: vlan_tag_$1.$valid } - hash 4: - 0..9: stripe(vlan_tag_$0.$valid, vlan_tag_$1.$valid) - 10..19: stripe(vlan_tag_$0.$valid, vlan_tag_$1.$valid) - 20..29: stripe(vlan_tag_$0.$valid, vlan_tag_$1.$valid) - hash group 3: - table: [4] - format: { action(0): 0..1, version(0): 112..115 } - gateway: - input_xbar: - group 1: { 48: eg_intr_md_from_parser_aux.clone_src } - row: 0 - bus: 0 - match: { 0: eg_intr_md_from_parser_aux.clone_src } - 0x00: run_table - miss: _rewrite_0 - next: _rewrite_0 - actions: - nop: - - 0 - remove_vlan_single_tagged: - - set ethernet.etherType, vlan_tag_$0.etherType - remove_vlan_double_tagged: - - set ethernet.etherType, vlan_tag_$1.etherType - NoAction: - - 0 - default_action: NoAction - exact_match _rewrite_0 7: - p4: { name: rewrite, size: 16384 } - p4_param_order: - l3_metadata.nexthop_index: { type: exact, size: 16} - row: 1 - bus: 0 - column: [ 2, 3, 4, 6 ] - ways: - - [5, 0, 0x0, [1, 2]] - - [5, 1, 0x0, [1, 3]] - - [5, 2, 0x0, [1, 4]] - - [5, 3, 0x0, [1, 6]] - input_xbar: - group 3: { 0: l3_metadata.nexthop_index } - hash 6: - 0..9: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) - 10..19: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) - 20..29: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) - 30..39: random(l3_metadata.nexthop_index(10..15)) ^ stripe(l3_metadata.nexthop_index(0..7), l3_metadata.nexthop_index(8..9)) - hash group 5: - table: [6] - format: { action(0): 0..1, version(0): 112..115, match(0): 34..39, action(1): 2..3, version(1): 116..119, match(1): 42..47, action(2): 4..5, version(2): 120..123, match(2): 50..55, action(3): 6..7, version(3): 124..127, match(3): 58..63 } - match: [ l3_metadata.nexthop_index(10..15) ] - gateway: - input_xbar: - group 1: { 64: l3_metadata.nexthop_index(0..7), 86: egress_metadata.routed, 88: l3_metadata.nexthop_index(8..15) } - row: 1 - bus: 0 - match: { 22: egress_metadata.routed, 0: l3_metadata.nexthop_index(0..7), 8: l3_metadata.nexthop_index(8..15) } - 0b*0**********************: run_table - 0x00**00: _egress_bd_stats_2 - miss: run_table - next: _egress_bd_stats_2 - actions: - nop: - - 0 - set_l2_rewrite: - - set egress_metadata.bd, ingress_metadata.bd - NoAction: - - 0 - default_action: NoAction -stage 8 egress: - exact_match _egress_bd_stats_2 4: - p4: { name: egress_bd_stats, size: 16384 } - p4_param_order: - egress_metadata.bd: { type: exact, size: 14} - l2_metadata.lkp_pkt_type: { type: exact, size: 3} - row: [ 3, 4 ] - bus: [ 1, 0 ] - column: - - 4 - - [ 2, 3, 4 ] - ways: - - [2, 0, 0x0, [4, 2]] - - [2, 1, 0x0, [4, 3]] - - [2, 2, 0x0, [4, 4]] - - [2, 3, 0x0, [3, 4]] - input_xbar: - group 1: { 0: egress_metadata.bd, 18: l2_metadata.lkp_pkt_type } - hash 2: - 0..9: random(egress_metadata.bd(1..7)) ^ stripe(egress_metadata.bd(0), egress_metadata.bd(8..13), l2_metadata.lkp_pkt_type) - 10..19: random(egress_metadata.bd(1..7)) ^ stripe(egress_metadata.bd(0), egress_metadata.bd(8..13), l2_metadata.lkp_pkt_type) - 20..29: random(egress_metadata.bd(1..7)) ^ stripe(egress_metadata.bd(0), egress_metadata.bd(8..13), l2_metadata.lkp_pkt_type) - 30..39: random(egress_metadata.bd(1..7)) ^ stripe(egress_metadata.bd(0), egress_metadata.bd(8..13), l2_metadata.lkp_pkt_type) - hash group 2: - table: [2] - format: { action(0): 0..0, version(0): 112..115, match(0): 33..39, action(1): 1..1, version(1): 116..119, match(1): 41..47, action(2): 2..2, version(2): 120..123, match(2): 49..55, action(3): 3..3, version(3): 124..127, match(3): 57..63 } - match: [ egress_metadata.bd(1..7) ] - next: _egress_bd_map_0 - stats: _egress_bd_stats_2$counter..egress_bd_stats - actions: - nop: - - 0 - NoAction: - - 0 - default_action: NoAction - counter _egress_bd_stats_2$counter..egress_bd_stats: - p4: { name: egress_bd_stats } - row: [ 13, 11 ] - column: - - [ 0, 1, 2, 3, 4, 5 ] - - 0 - maprams: - - [ 0, 1, 2, 3, 4, 5 ] - - 0 - count: packets_and_bytes - format: {packets(0): 85..101, bytes(0): 102..126, packets(1): 42..58, bytes(1): 59..83, packets(2): 0..16, bytes(2): 17..41} - exact_match _egress_bd_map_0 5: - p4: { name: egress_bd_map, size: 16384 } - p4_param_order: - egress_metadata.bd: { type: exact, size: 14} - row: [ 3, 5 ] - bus: [ 0, 1 ] - column: - - [ 2, 3 ] - - [ 3, 4 ] - ways: - - [3, 0, 0x0, [5, 3]] - - [3, 1, 0x0, [5, 4]] - - [3, 2, 0x0, [3, 2]] - - [3, 3, 0x0, [3, 3]] - input_xbar: - group 1: { 64: egress_metadata.bd } - hash 3: - 0..9: random(egress_metadata.bd(4..7)) ^ stripe(egress_metadata.bd(0..3), egress_metadata.bd(8..13)) - 10..19: random(egress_metadata.bd(4..7)) ^ stripe(egress_metadata.bd(0..3), egress_metadata.bd(8..13)) - 20..29: random(egress_metadata.bd(4..7)) ^ stripe(egress_metadata.bd(0..3), egress_metadata.bd(8..13)) - 30..39: random(egress_metadata.bd(4..7)) ^ stripe(egress_metadata.bd(0..3), egress_metadata.bd(8..13)) - hash group 3: - table: [3] - format: { action(0): 0..1, version(0): 112..115, match(0): 36..39, action(1): 2..3, version(1): 116..119, match(1): 44..47, action(2): 4..5, version(2): 120..123, match(2): 52..55, action(3): 6..7, version(3): 124..127, match(3): 60..63 } - match: [ egress_metadata.bd(4..7) ] - next: _tunnel_encap_process_outer_0 - actions: - nop: - - 0 - set_egress_bd_properties: - - p4_param_order: {smac_idx: 9, nat_mode: 2, bd_label: 16 } - - 0 - NoAction: - - 0 - default_action: NoAction - exact_match _tunnel_encap_process_outer_0 6: - p4: { name: tunnel_encap_process_outer, size: 256 } - p4_param_order: - tunnel_metadata.egress_tunnel_type: { type: exact, size: 5} - tunnel_metadata.egress_header_count: { type: exact, size: 4} - multicast_metadata.replica: { type: exact, size: 1} - row: 7 - bus: 0 - column: [ 2, 3, 4 ] - ways: - - [4, 0, 0x0, [7, 2]] - - [4, 1, 0x0, [7, 3]] - - [4, 2, 0x0, [7, 4]] - input_xbar: - group 2: { 0: tunnel_metadata.egress_tunnel_type, 15: multicast_metadata.replica, 26: tunnel_metadata.egress_header_count } - hash 4: - 0..9: stripe(tunnel_metadata.egress_tunnel_type, multicast_metadata.replica, tunnel_metadata.egress_header_count) - 10..19: stripe(tunnel_metadata.egress_tunnel_type, multicast_metadata.replica, tunnel_metadata.egress_header_count) - 20..29: stripe(tunnel_metadata.egress_tunnel_type, multicast_metadata.replica, tunnel_metadata.egress_header_count) - hash group 4: - table: [4] - format: { action(0): 14..15, immediate(0): 0..13, version(0): 112..115 } - gateway: - input_xbar: - group 1: { 25: fabric_metadata.fabric_header_present, 32: tunnel_metadata.egress_tunnel_type } - row: 1 - bus: 1 - match: { 0: tunnel_metadata.egress_tunnel_type, 9: fabric_metadata.fabric_header_present } - 0b***********00000: _egress_vlan_xlate_0 - 0b******0*********: run_table - miss: _egress_vlan_xlate_0 - next: _tunnel_rewrite_0 - action_bus: { } - actions: - nop: - - { } - fabric_rewrite: - - p4_param_order: {tunnel_index: 14 } - - { tunnel_index: immediate(0..13) } - - set tunnel_metadata.tunnel_index, tunnel_index - NoAction: - - { } - default_action: NoAction -stage 9 egress: - exact_match _tunnel_rewrite_0 2: - p4: { name: tunnel_rewrite, size: 16384 } - p4_param_order: - tunnel_metadata.tunnel_index: { type: exact, size: 14} - row: 7 - bus: 1 - column: [ 6, 7, 8, 9 ] - ways: - - [3, 0, 0x0, [7, 6]] - - [3, 1, 0x0, [7, 7]] - - [3, 2, 0x0, [7, 8]] - - [3, 3, 0x0, [7, 9]] - input_xbar: - group 1: { 64: tunnel_metadata.tunnel_index } - hash 3: - 0..9: random(tunnel_metadata.tunnel_index(4..7)) ^ stripe(tunnel_metadata.tunnel_index(0..3), tunnel_metadata.tunnel_index(8..13)) - 10..19: random(tunnel_metadata.tunnel_index(4..7)) ^ stripe(tunnel_metadata.tunnel_index(0..3), tunnel_metadata.tunnel_index(8..13)) - 20..29: random(tunnel_metadata.tunnel_index(4..7)) ^ stripe(tunnel_metadata.tunnel_index(0..3), tunnel_metadata.tunnel_index(8..13)) - 30..39: random(tunnel_metadata.tunnel_index(4..7)) ^ stripe(tunnel_metadata.tunnel_index(0..3), tunnel_metadata.tunnel_index(8..13)) - hash group 3: - table: [3] - format: { action(0): 32..33, immediate(0): 0..7, version(0): 112..115, match(0): 44..47, action(1): 34..35, immediate(1): 8..15, version(1): 116..119, match(1): 52..55, action(2): 36..37, immediate(2): 16..23, version(2): 120..123, match(2): 60..63, action(3): 38..39, immediate(3): 24..31, version(3): 124..127, match(3): 68..71 } - match: [ tunnel_metadata.tunnel_index(4..7) ] - next: _egress_vlan_xlate_0 - action_bus: { } - actions: - nop: - - { } - cpu_rx_rewrite: - - { $data0: immediate(0..7), $constant0: $data0(3..4), $constant0: 0, $constant1: $data0(1..2), $constant1: 0, $constant2: $data0(0..0), $constant2: 0, $constant3: $data0(5..7), $constant3: 5 } - - set fabric_header_cpu.ingressPort, ingress_metadata.ingress_port - - set fabric_header_cpu.ingressIfindex, ingress_metadata.ifindex - - set fabric_header_cpu.ingressBd, ingress_metadata.bd - - set fabric_header_cpu.reasonCode, fabric_metadata.reason_code - - set fabric_payload_header.etherType, ethernet.etherType - - set ethernet.etherType, 36864 - - set B19, $data0 - NoAction: - - { } - default_action: NoAction -stage 10 egress: - exact_match _egress_vlan_xlate_0 2: - p4: { name: egress_vlan_xlate, size: 32768 } - p4_param_order: - egress_metadata.ifindex: { type: exact, size: 16} - egress_metadata.bd: { type: exact, size: 14} - row: [ 6, 7 ] - bus: [ 0, 0 ] - column: - - 2 - - [ 2, 3, 4, 6, 7, 8, 9 ] - ways: - - [2, 0, 0x1, [7, 2], [7, 3]] - - [2, 1, 0x2, [7, 4], [7, 6]] - - [2, 2, 0x4, [7, 7], [7, 8]] - - [2, 3, 0x8, [7, 9], [6, 2]] - input_xbar: - group 1: { 0: egress_metadata.bd, 16: egress_metadata.ifindex } - hash 2: - 0..9: random(egress_metadata.bd(0..7), egress_metadata.ifindex(5..15)) ^ stripe(egress_metadata.bd(8..13), egress_metadata.ifindex(0..4)) - 10..19: random(egress_metadata.bd(0..7), egress_metadata.ifindex(5..15)) ^ stripe(egress_metadata.bd(8..13), egress_metadata.ifindex(0..4)) - 20..29: random(egress_metadata.bd(0..7), egress_metadata.ifindex(5..15)) ^ stripe(egress_metadata.bd(8..13), egress_metadata.ifindex(0..4)) - 30..39: random(egress_metadata.bd(0..7), egress_metadata.ifindex(5..15)) ^ stripe(egress_metadata.bd(8..13), egress_metadata.ifindex(0..4)) - 40..43: random(egress_metadata.bd(0..7), egress_metadata.ifindex(5..15)) ^ stripe(egress_metadata.bd(8..13), egress_metadata.ifindex(0..4)) - hash group 2: - table: [2] - format: { action(0): 0..1, version(0): 112..115, match(0): [40..47, 101..103, 32..39 ], action(1): 2..3, version(1): 116..119, match(1): [56..63, 109..111, 48..55 ], action(2): 4..5, version(2): 120..123, match(2): [72..79, 13..15, 64..71 ], action(3): 6..7, version(3): 124..127, match(3): [88..95, 21..23, 80..87 ] } - match: [ egress_metadata.bd(0..7), egress_metadata.ifindex(5..15) ] - gateway: - input_xbar: - group 0: { 19: egress_metadata.port_type } - row: 0 - bus: 0 - match: { 3: egress_metadata.port_type } - 0b***00: run_table - miss: _egress_system_acl_0 - next: _egress_system_acl_0 - action: _egress_vlan_xlate_0$action - default_action: NoAction - action _egress_vlan_xlate_0$action: - p4: { name: _egress_vlan_xlate_0$action } - row: [ 13, 12, 11 ] - column: - - [ 1, 2, 3, 4, 5 ] - - 5 - - [ 0, 1 ] - home_row: 13 - format set_egress_packet_vlan_tagged: { $adf_h1: 16..31 } - format set_egress_packet_vlan_double_tagged: { $adf_h0: 0..15, $adf_h1: 16..31 } - action_bus: { 36..37 : $adf_h0, 38..39 : $adf_h1 } - actions: - set_egress_packet_vlan_untagged: - - { } - set_egress_packet_vlan_tagged: - - p4_param_order: {vlan_id: 12 } - - { vlan_id: $adf_h1 } - - set vlan_tag_$0.etherType, ethernet.etherType - - set vlan_tag_$0.vid, vlan_id - - set ethernet.etherType, 33024 - set_egress_packet_vlan_double_tagged: - - p4_param_order: {s_tag: 12, c_tag: 12 } - - { c_tag: $adf_h0, s_tag: $adf_h1 } - - set vlan_tag_$1.etherType, ethernet.etherType - - set vlan_tag_$1.vid, c_tag - - set vlan_tag_$0.etherType, 33024 - - set vlan_tag_$0.vid, s_tag - - set ethernet.etherType, 37120 - NoAction: - - { } - ternary_match _egress_system_acl_0 3: - p4: { name: egress_system_acl, size: 128 } - p4_param_order: - fabric_metadata.reason_code: { type: ternary, size: 16} - standard_metadata.egress_port: { type: ternary, size: 9} - eg_intr_md.deflection_flag: { type: ternary, size: 1} - l3_metadata.l3_mtu_check: { type: ternary, size: 16} - acl_metadata.acl_deny: { type: ternary, size: 1} - row: [ 0, 1 ] - bus: [ 0, 0 ] - column: - - 0 - - 0 - input_xbar: - group 0: { 0: fabric_metadata.reason_code(0..7), 15: acl_metadata.acl_deny, 16: l3_metadata.l3_mtu_check(0..7), 24: fabric_metadata.reason_code(8..15), 32: standard_metadata.egress_port(0..7) } - group 1: { 1: eg_intr_md.deflection_flag, 8: l3_metadata.l3_mtu_check(8..15), 24: standard_metadata.egress_port(8) } - gateway: - input_xbar: - group 0: { 36: egress_metadata.bypass } - row: 1 - bus: 1 - match: { 4: egress_metadata.bypass } - 0b***0: run_table - miss: END - next: END - action_bus: { } - indirect: _egress_system_acl_0$tind - ternary_indirect _egress_system_acl_0$tind: - row: 0 - bus: 0 - column: 2 - format: { action: 16..18, immediate: 0..15} - actions: - nop: - - { } - drop_packet: - - { } - - invalidate standard_metadata.egress_port - egress_copy_to_cpu: - - { } - - set $mirror_id, 250 - - set $mirror, 1 - egress_redirect_to_cpu: - - { } - - set $mirror_id, 250 - - set $mirror, 2 - - invalidate standard_metadata.egress_port - egress_copy_to_cpu_with_reason: - - p4_param_order: {reason_code: 16 } - - { reason_code: immediate(0..15) } - - set fabric_metadata.reason_code, reason_code - - set $mirror_id, 250 - - set $mirror, 3 - egress_redirect_to_cpu_with_reason: - - p4_param_order: {reason_code: 16 } - - { reason_code: immediate(0..15) } - - set fabric_metadata.reason_code, reason_code - - set $mirror_id, 250 - - set $mirror, 4 - - invalidate standard_metadata.egress_port - egress_mirror_coal_hdr: - - p4_param_order: {session_id: 8, id: 8 } - - { } - NoAction: - - { } - default_action: NoAction diff --git a/backends/tofino/bf-asm/test/asm/table_action_alias.tfa b/backends/tofino/bf-asm/test/asm/table_action_alias.tfa deleted file mode 100644 index 01b6f4248b3..00000000000 --- a/backends/tofino/bf-asm/test/asm/table_action_alias.tfa +++ /dev/null @@ -1,66 +0,0 @@ -version: 1.0.0 -phv ingress: - standard_metadata.egress_spec: H0(0..8) - data.f1: W0 - data.n1: B0(4..7) - data.n2: B0(0..3) - data.$valid: B47(7) -phv egress: - standard_metadata.egress_port: H16(0..8) -parser ingress: - start: $ingress_metadata_shim - $ingress_metadata_shim: - 0x*: - shift: 16 - next: start$ - start$: - 0x*: - 0..3: data.f1 - 4: B0 - data.$valid: 1 - shift: 5 - next: end -deparser ingress: - dictionary: - data.f1: data.$valid - B0: data.$valid - egress_unicast_port: standard_metadata.egress_spec -parser egress: - start: $egress_metadata_shim - $egress_metadata_shim: - 0x*: - 0..1: H16 - shift: 2 - next: end -deparser egress: - dictionary: {} - egress_unicast_port: standard_metadata.egress_port -stage 0 ingress: - exact_match test1 0: - p4: { name: test1 } - row: 7 - bus: 0 - column: [ 2, 3, 4 ] - ways: - - [0, 0, 0x0, [7, 2]] - - [0, 1, 0x0, [7, 3]] - - [0, 2, 0x0, [7, 4]] - input_xbar: - group 0: { 0: data.f1 } - hash 0: - 0..9: random(data.f1(0..15), data.f1(18..23)) ^ stripe(data.f1(16..17), data.f1(24..31)) - 10..19: random(data.f1(0..15), data.f1(18..23)) ^ stripe(data.f1(16..17), data.f1(24..31)) - 20..29: random(data.f1(0..15), data.f1(18..23)) ^ stripe(data.f1(16..17), data.f1(24..31)) - hash group 0: - table: [0] - format: { action(0): 8..8, immediate(0): 0..7, version(0): 112..115, match(0): [32..47, 50..55 ] } - match: [ data.f1(0..15), data.f1(18..23) ] - next: END - actions: - set_nibbles: - - { $data0: immediate(0..7) } - - set B0, $data0 - - { param1.0-3: $data0(4..7), param2.0-3: $data0(0..3) } - NoAction: - - { } - default_action: NoAction diff --git a/backends/tofino/bf-asm/test/asm/table_alias_fields_error.tfa b/backends/tofino/bf-asm/test/asm/table_alias_fields_error.tfa deleted file mode 100644 index 5940f502b0c..00000000000 --- a/backends/tofino/bf-asm/test/asm/table_alias_fields_error.tfa +++ /dev/null @@ -1,66 +0,0 @@ -version: 1.0.0 -phv ingress: - standard_metadata.egress_spec: H0(0..8) - data.f1: W0 - data.n1: B0(4..7) - data.n2: B0(0..3) - data.$valid: B47(7) -phv egress: - standard_metadata.egress_port: H16(0..8) -parser ingress: - start: $ingress_metadata_shim - $ingress_metadata_shim: - 0x*: - shift: 16 - next: start$ - start$: - 0x*: - 0..3: data.f1 - 4: B0 - data.$valid: 1 - shift: 5 - next: end -deparser ingress: - dictionary: - data.f1: data.$valid - B0: data.$valid - egress_unicast_port: standard_metadata.egress_spec -parser egress: - start: $egress_metadata_shim - $egress_metadata_shim: - 0x*: - 0..1: H16 - shift: 2 - next: end -deparser egress: - dictionary: {} - egress_unicast_port: standard_metadata.egress_port -stage 0 ingress: - exact_match test1 0: - p4: { name: test1 } - row: 7 - bus: 0 - column: [ 2, 3, 4 ] - ways: - - [0, 0, 0x0, [7, 2]] - - [0, 1, 0x0, [7, 3]] - - [0, 2, 0x0, [7, 4]] - input_xbar: - group 0: { 0: data.f1 } - hash 0: - 0..9: random(data.f1(0..15), data.f1(18..23)) ^ stripe(data.f1(16..17), data.f1(24..31)) - 10..19: random(data.f1(0..15), data.f1(18..23)) ^ stripe(data.f1(16..17), data.f1(24..31)) - 20..29: random(data.f1(0..15), data.f1(18..23)) ^ stripe(data.f1(16..17), data.f1(24..31)) - hash group 0: - table: [0] - format: { action(0): 8..8, immediate(0): 0..7, version(0): 112..115, match(0): [32..47, 50..55 ] } - match: [ data.f1(0..15), data.f1(18..23) ] - next: END - actions: - set_nibbles: - - { $data0: immediate(0..3) } - - set B0, $data0 - - { param1.0-3: $data0(4..7), param2.0-3: $data0(0..3) } - NoAction: - - { } - default_action: NoAction diff --git a/backends/tofino/bf-asm/test/asm/tor.tfa b/backends/tofino/bf-asm/test/asm/tor.tfa deleted file mode 100644 index 75e26a49239..00000000000 --- a/backends/tofino/bf-asm/test/asm/tor.tfa +++ /dev/null @@ -1,1587 +0,0 @@ -version: 1.0.0 -phv ingress: - standard_metadata.ingress_port: H13(0..8) - standard_metadata.egress_spec: H0(0..8) - $bridge-metadata: B63(6) - packet_out.egress_physical_port: H1(0..8) - packet_out.submit_to_ingress: H13(15) - ethernet.dst_addr.32-47: H5 - ethernet.dst_addr.16-31: H4 - ethernet.dst_addr.0-15: H3 - ethernet.src_addr.32-47: H8 - ethernet.src_addr.16-31: H7 - ethernet.src_addr.0-15: H6 - ethernet.ether_type: H82 - vlan_tag$0.pcp: H15(13..15) - vlan_tag$0.cfi: H15(12) - vlan_tag$0.vid: H15(0..11) - vlan_tag$0.ether_type: H81 - vlan_tag$1.pcp: TH3(13..15) - vlan_tag$1.cfi: TH3(12) - vlan_tag$1.vid: TH3(0..11) - vlan_tag$1.ether_type: H80 - ipv4_base.version: TB1(4..7) - ipv4_base.ihl: TB1(0..3) - ipv4_base.diffserv: B5 - ipv4_base.total_len: TH18 - ipv4_base.identification: TH17 - ipv4_base.flags: H14(13..15) - ipv4_base.frag_offset: H14(0..12) - ipv4_base.ttl: B0 - ipv4_base.protocol: B7 - ipv4_base.hdr_checksum: TH16 - ipv4_base.src_addr: W10 - ipv4_base.dst_addr: W12 - tcp.src_port: H11 - tcp.dst_port: H9 - tcp.seq_no: TW2 - tcp.ack_no: TW1 - tcp.data_offset: TB0(4..7) - tcp.res: TB0(0..3) - tcp.flags: TB4 - tcp.window: TH15 - tcp.checksum: TH14 - tcp.urgent_ptr: TH13 - local_metadata.vrf_id: W11 - local_metadata.class_id: B3 - local_metadata.skip_egress: B63(6) - local_metadata.egress_spec_at_punt_match: H2(0..8) - local_metadata.color: B47(5..6) - local_metadata.l4_src_port: H12 - local_metadata.l4_dst_port: H10 - local_metadata.icmp_code: B2 - udp.src_port: H11 - udp.dst_port: H9 - udp.hdr_length: TH12 - udp.checksum: TH11 - ipv6_base.version: W8(28..31) - ipv6_base.traffic_class: W8(20..27) - ipv6_base.flow_label: W8(0..19) - ipv6_base.payload_length: TH10 - ipv6_base.next_header: B6 - ipv6_base.hop_limit: B4 - ipv6_base.src_addr.96-127: W3 - ipv6_base.src_addr.64-95: W2 - ipv6_base.src_addr.32-63: W1 - ipv6_base.src_addr.0-31: W0 - ipv6_base.dst_addr.96-127: W7 - ipv6_base.dst_addr.64-95: W6 - ipv6_base.dst_addr.32-63: W5 - ipv6_base.dst_addr.0-31: W4 - arp.hw_type: TH9 - arp.proto_type: TH8 - arp.hw_addr_len: TB3 - arp.proto_addr_len: TB2 - arp.opcode: TH7 - arp.sender_hw_addr.32-47: TH6 - arp.sender_hw_addr.16-31: TH5 - arp.sender_hw_addr.0-15: TH4 - arp.sender_proto_addr: TW0 - arp.target_hw_addr.32-47: TH2 - arp.target_hw_addr.16-31: TH1 - arp.target_hw_addr.0-15: TH0 - arp.target_proto_addr: W9 - hasExited: B63(6) - $mirror_id: B1 - $mirror: B15(4..6) - arp.$valid: B15(7) - ethernet.$valid: B47(7) - ipv4_base.$valid: B63(7) - ipv6_base.$valid: B14(7) - packet_out.$valid: B46(7) - tcp.$valid: B45(7) - udp.$valid: B62(7) - vlan_tag$0.$valid: B61(7) - vlan_tag$1.$valid: B13(7) -phv egress: - standard_metadata.ingress_port: H19(0..8) - standard_metadata.egress_spec: H22(0..8) - standard_metadata.egress_port: H16(0..8) - local_metadata.skip_egress: B31(6) - local_metadata.egress_spec_at_punt_match: H17(0..8) - local_metadata.l4_dst_port: H21 - packet_out.egress_physical_port: TH27(0..8) - packet_out.submit_to_ingress: TW27(31) - ethernet.dst_addr.32-47: TH30 - ethernet.dst_addr.16-31: TH29 - ethernet.dst_addr.0-15: TH28 - ethernet.src_addr.32-47: TH26 - ethernet.src_addr.16-31: TH25 - ethernet.src_addr.0-15: TH24 - ethernet.ether_type: H26 - vlan_tag$0.pcp: TH32(13..15) - vlan_tag$0.cfi: TH32(12) - vlan_tag$0.vid: TH32(0..11) - vlan_tag$0.ether_type: H25 - vlan_tag$1.pcp: TH31(13..15) - vlan_tag$1.cfi: TH31(12) - vlan_tag$1.vid: TH31(0..11) - vlan_tag$1.ether_type: H24 - ipv4_base.version: TB16(4..7) - ipv4_base.ihl: TB16(0..3) - ipv4_base.diffserv: TB19 - ipv4_base.total_len: TH40 - ipv4_base.identification: TH39 - ipv4_base.flags: H23(13..15) - ipv4_base.frag_offset: H23(0..12) - ipv4_base.ttl: TB18 - ipv4_base.protocol: B17 - ipv4_base.hdr_checksum: TH38 - ipv4_base.src_addr: TW26 - ipv4_base.dst_addr: TW25 - udp.src_port: TH37 - udp.dst_port: TH36 - udp.hdr_length: TH35 - udp.checksum: TH34 - ipv6_base.version: TW24(28..31) - ipv6_base.traffic_class: TW24(20..27) - ipv6_base.flow_label: TW24(0..19) - ipv6_base.payload_length: TH33 - ipv6_base.next_header: B16 - ipv6_base.hop_limit: TB17 - ipv6_base.src_addr.96-127: TW23 - ipv6_base.src_addr.64-95: TW22 - ipv6_base.src_addr.32-63: TW21 - ipv6_base.src_addr.0-31: TW20 - ipv6_base.dst_addr.96-127: TW19 - ipv6_base.dst_addr.64-95: TW18 - ipv6_base.dst_addr.32-63: TW17 - ipv6_base.dst_addr.0-31: TW16 - hasExited_0: H22(15) - ethernet.$valid: B31(7) - ipv4_base.$valid: B30(7) - ipv6_base.$valid: B29(7) - packet_out.$valid: B28(7) - udp.$valid: B27(7) - vlan_tag$0.$valid: B26(7) - vlan_tag$1.$valid: B25(7) -parser ingress: - start: $ingress_metadata_shim - $ingress_metadata_shim: - 0x*: - 0..1: H13 - shift: 16 - next: $bridge-metadata - save: { half:0..1 } - $bridge-metadata: - 0x*: - $bridge-metadata: 1 - next: start$ - start$: - match: [ half ] - 0x0fd: - next: parse_cpu_header - 0x*: - next: parse_ethernet - parse_cpu_header: - 0x*: - 0..1: H1 - 2..3: H13 - packet_out.$valid: 1 - shift: 2 - next: parse_ethernet - parse_ethernet: - match: [ 12..13 ] - 0x8100: - 0..1: ethernet.dst_addr.32-47 - 2..3: ethernet.dst_addr.16-31 - 4..5: ethernet.dst_addr.0-15 - 6..7: ethernet.src_addr.32-47 - shift: 8 - next: parse_ethernet.0 - 0x9100: - 0..1: ethernet.dst_addr.32-47 - 2..3: ethernet.dst_addr.16-31 - 4..5: ethernet.dst_addr.0-15 - 6..7: ethernet.src_addr.32-47 - shift: 8 - next: parse_ethernet.1 - 0x9200: - 0..1: ethernet.dst_addr.32-47 - 2..3: ethernet.dst_addr.16-31 - 4..5: ethernet.dst_addr.0-15 - 6..7: ethernet.src_addr.32-47 - shift: 8 - next: parse_ethernet.2 - 0x9300: - 0..1: ethernet.dst_addr.32-47 - 2..3: ethernet.dst_addr.16-31 - 4..5: ethernet.dst_addr.0-15 - 6..7: ethernet.src_addr.32-47 - shift: 8 - next: parse_ethernet.3 - 0x0800: - 0..1: ethernet.dst_addr.32-47 - 2..3: ethernet.dst_addr.16-31 - 4..5: ethernet.dst_addr.0-15 - 6..7: ethernet.src_addr.32-47 - shift: 8 - next: parse_ethernet.4 - 0x86dd: - 0..1: ethernet.dst_addr.32-47 - 2..3: ethernet.dst_addr.16-31 - 4..5: ethernet.dst_addr.0-15 - 6..7: ethernet.src_addr.32-47 - shift: 8 - next: parse_ethernet.5 - 0x0806: - 0..1: ethernet.dst_addr.32-47 - 2..3: ethernet.dst_addr.16-31 - 4..5: ethernet.dst_addr.0-15 - 6..7: ethernet.src_addr.32-47 - shift: 8 - next: parse_ethernet.6 - 0x*: - 0..1: ethernet.dst_addr.32-47 - 2..3: ethernet.dst_addr.16-31 - 4..5: ethernet.dst_addr.0-15 - 6..7: ethernet.src_addr.32-47 - shift: 8 - next: parse_ethernet.7 - parse_ethernet.0: - 0x*: - 0..1: ethernet.src_addr.16-31 - 2..3: ethernet.src_addr.0-15 - 4..5: ethernet.ether_type - ethernet.$valid: 1 - shift: 6 - next: parse_vlan - parse_vlan: - match: [ 2..3 ] - 0x8100: - 0..1: H15 - 2..3: vlan_tag$0.ether_type - vlan_tag$0.$valid: 1 - shift: 4 - next: parse_vlan.0 - 0x9100: - 0..1: H15 - 2..3: vlan_tag$0.ether_type - vlan_tag$0.$valid: 1 - shift: 4 - next: parse_vlan.5 - 0x9200: - 0..1: H15 - 2..3: vlan_tag$0.ether_type - vlan_tag$0.$valid: 1 - shift: 4 - next: parse_vlan.10 - 0x9300: - 0..1: H15 - 2..3: vlan_tag$0.ether_type - vlan_tag$0.$valid: 1 - shift: 4 - next: parse_vlan.15 - 0x0800: - 0..1: H15 - 2..3: vlan_tag$0.ether_type - vlan_tag$0.$valid: 1 - shift: 4 - next: parse_ipv4 - 0x86dd: - 0..1: H15 - 2..3: vlan_tag$0.ether_type - vlan_tag$0.$valid: 1 - shift: 4 - next: parse_ipv6 - 0x*: - 0..1: H15 - 2..3: vlan_tag$0.ether_type - vlan_tag$0.$valid: 1 - shift: 4 - next: end - parse_vlan.0: - match: [ 2..3 ] - 0x8100: - next: end - 0x9100: - next: end - 0x9200: - next: end - 0x9300: - next: end - 0x0800: - 0..1: TH3 - 2..3: vlan_tag$1.ether_type - vlan_tag$1.$valid: 1 - shift: 4 - next: parse_ipv4 - 0x86dd: - 0..1: TH3 - 2..3: vlan_tag$1.ether_type - vlan_tag$1.$valid: 1 - shift: 4 - next: parse_ipv6 - 0x*: - next: end - parse_ipv4: - match: [ /* ingress::ipv4_base.frag_offset ++ ingress::ipv4_base.protocol; */ ] - 0x000001: - 0: TB1 - 1: ipv4_base.diffserv - 2..3: ipv4_base.total_len - 4..5: ipv4_base.identification - 6..7: H14 - 8: ipv4_base.ttl - 9: ipv4_base.protocol - 10..11: ipv4_base.hdr_checksum - 12..15: ipv4_base.src_addr - 16..19: ipv4_base.dst_addr - shift: 20 - next: parse_ipv4.0 - 0x000006: - 0: TB1 - 1: ipv4_base.diffserv - 2..3: ipv4_base.total_len - 4..5: ipv4_base.identification - 6..7: H14 - 8: ipv4_base.ttl - 9: ipv4_base.protocol - 10..11: ipv4_base.hdr_checksum - 12..15: ipv4_base.src_addr - 16..19: ipv4_base.dst_addr - shift: 20 - next: parse_ipv4.1 - 0x000011: - 0: TB1 - 1: ipv4_base.diffserv - 2..3: ipv4_base.total_len - 4..5: ipv4_base.identification - 6..7: H14 - 8: ipv4_base.ttl - 9: ipv4_base.protocol - 10..11: ipv4_base.hdr_checksum - 12..15: ipv4_base.src_addr - 16..19: ipv4_base.dst_addr - shift: 20 - next: parse_ipv4.2 - 0x*: - 0: TB1 - 1: ipv4_base.diffserv - 2..3: ipv4_base.total_len - 4..5: ipv4_base.identification - 6..7: H14 - 8: ipv4_base.ttl - 9: ipv4_base.protocol - 10..11: ipv4_base.hdr_checksum - 12..15: ipv4_base.src_addr - 16..19: ipv4_base.dst_addr - shift: 20 - next: parse_ipv4.3 - parse_ipv4.0: - 0x*: - ipv4_base.$valid: 1 - next: end - parse_ipv4.1: - 0x*: - ipv4_base.$valid: 1 - next: parse_tcp - parse_tcp: - 0x*: - 0..1: tcp.src_port - 2..3: tcp.dst_port - 4..7: tcp.seq_no - 8..11: tcp.ack_no - 12: TB0 - 13: tcp.flags - 14..15: tcp.window - 16..17: tcp.checksum - shift: 18 - next: parse_tcp.0 - parse_tcp.0: - 0x*: - 0..1: tcp.urgent_ptr - tcp.$valid: 1 - local_metadata.l4_src_port: 0 /* ingress::tcp.src_port; */ - local_metadata.l4_dst_port: 0 /* ingress::tcp.dst_port; */ - shift: 2 - next: end - parse_ipv4.2: - 0x*: - ipv4_base.$valid: 1 - next: parse_udp - parse_udp: - 0x*: - 0..1: udp.src_port - 2..3: udp.dst_port - 4..5: udp.hdr_length - 6..7: udp.checksum - udp.$valid: 1 - shift: 9 - next: parse_udp.0 - parse_udp.0: - 0x*: - local_metadata.l4_src_port: 0 /* ingress::udp.src_port; */ - local_metadata.l4_dst_port: 0 /* ingress::udp.dst_port; */ - # shift: -1 - next: end - parse_ipv4.3: - 0x*: - ipv4_base.$valid: 1 - next: end - parse_ipv6: - match: [ 6 ] - 0x3a: - 0..3: W8 - 4..5: ipv6_base.payload_length - 6: ipv6_base.next_header - 7: ipv6_base.hop_limit - 8..11: ipv6_base.src_addr.96-127 - 12..15: ipv6_base.src_addr.64-95 - 16..19: ipv6_base.src_addr.32-63 - shift: 20 - next: parse_ipv6.0 - 0x06: - 0..3: W8 - 4..5: ipv6_base.payload_length - 6: ipv6_base.next_header - 7: ipv6_base.hop_limit - 8..11: ipv6_base.src_addr.96-127 - 12..15: ipv6_base.src_addr.64-95 - 16..19: ipv6_base.src_addr.32-63 - shift: 20 - next: parse_ipv6.1 - 0x11: - 0..3: W8 - 4..5: ipv6_base.payload_length - 6: ipv6_base.next_header - 7: ipv6_base.hop_limit - 8..11: ipv6_base.src_addr.96-127 - 12..15: ipv6_base.src_addr.64-95 - 16..19: ipv6_base.src_addr.32-63 - shift: 20 - next: parse_ipv6.2 - 0x*: - 0..3: W8 - 4..5: ipv6_base.payload_length - 6: ipv6_base.next_header - 7: ipv6_base.hop_limit - 8..11: ipv6_base.src_addr.96-127 - 12..15: ipv6_base.src_addr.64-95 - 16..19: ipv6_base.src_addr.32-63 - shift: 20 - next: parse_ipv6.3 - parse_ipv6.0: - 0x*: - 0..3: ipv6_base.src_addr.0-31 - 4..7: ipv6_base.dst_addr.96-127 - 8..11: ipv6_base.dst_addr.64-95 - 12..15: ipv6_base.dst_addr.32-63 - shift: 16 - next: parse_ipv6.0.0 - parse_ipv6.0.0: - 0x*: - 0..3: ipv6_base.dst_addr.0-31 - ipv6_base.$valid: 1 - shift: 4 - next: end - parse_ipv6.1: - 0x*: - 0..3: ipv6_base.src_addr.0-31 - 4..7: ipv6_base.dst_addr.96-127 - 8..11: ipv6_base.dst_addr.64-95 - 12..15: ipv6_base.dst_addr.32-63 - shift: 16 - next: parse_ipv6.1.0 - parse_ipv6.1.0: - 0x*: - 0..3: ipv6_base.dst_addr.0-31 - ipv6_base.$valid: 1 - shift: 4 - next: parse_tcp - parse_ipv6.2: - 0x*: - 0..3: ipv6_base.src_addr.0-31 - 4..7: ipv6_base.dst_addr.96-127 - 8..11: ipv6_base.dst_addr.64-95 - 12..15: ipv6_base.dst_addr.32-63 - shift: 16 - next: parse_ipv6.2.0 - parse_ipv6.2.0: - 0x*: - 0..3: ipv6_base.dst_addr.0-31 - ipv6_base.$valid: 1 - shift: 4 - next: parse_udp - parse_ipv6.3: - 0x*: - 0..3: ipv6_base.src_addr.0-31 - 4..7: ipv6_base.dst_addr.96-127 - 8..11: ipv6_base.dst_addr.64-95 - 12..15: ipv6_base.dst_addr.32-63 - shift: 16 - next: parse_ipv6.3.0 - parse_ipv6.3.0: - 0x*: - 0..3: ipv6_base.dst_addr.0-31 - ipv6_base.$valid: 1 - shift: 4 - next: end - parse_vlan.5: - match: [ 2..3 ] - 0x8100: - next: end - 0x9100: - next: end - 0x9200: - next: end - 0x9300: - next: end - 0x0800: - 0..1: TH3 - 2..3: vlan_tag$1.ether_type - vlan_tag$1.$valid: 1 - shift: 4 - next: parse_ipv4 - 0x86dd: - 0..1: TH3 - 2..3: vlan_tag$1.ether_type - vlan_tag$1.$valid: 1 - shift: 4 - next: parse_ipv6 - 0x*: - next: end - parse_vlan.10: - match: [ 2..3 ] - 0x8100: - next: end - 0x9100: - next: end - 0x9200: - next: end - 0x9300: - next: end - 0x0800: - 0..1: TH3 - 2..3: vlan_tag$1.ether_type - vlan_tag$1.$valid: 1 - shift: 4 - next: parse_ipv4 - 0x86dd: - 0..1: TH3 - 2..3: vlan_tag$1.ether_type - vlan_tag$1.$valid: 1 - shift: 4 - next: parse_ipv6 - 0x*: - next: end - parse_vlan.15: - match: [ 2..3 ] - 0x8100: - next: end - 0x9100: - next: end - 0x9200: - next: end - 0x9300: - next: end - 0x0800: - 0..1: TH3 - 2..3: vlan_tag$1.ether_type - vlan_tag$1.$valid: 1 - shift: 4 - next: parse_ipv4 - 0x86dd: - 0..1: TH3 - 2..3: vlan_tag$1.ether_type - vlan_tag$1.$valid: 1 - shift: 4 - next: parse_ipv6 - 0x*: - next: end - parse_ethernet.1: - 0x*: - 0..1: ethernet.src_addr.16-31 - 2..3: ethernet.src_addr.0-15 - 4..5: ethernet.ether_type - ethernet.$valid: 1 - shift: 6 - next: parse_vlan - parse_ethernet.2: - 0x*: - 0..1: ethernet.src_addr.16-31 - 2..3: ethernet.src_addr.0-15 - 4..5: ethernet.ether_type - ethernet.$valid: 1 - shift: 6 - next: parse_vlan - parse_ethernet.3: - 0x*: - 0..1: ethernet.src_addr.16-31 - 2..3: ethernet.src_addr.0-15 - 4..5: ethernet.ether_type - ethernet.$valid: 1 - shift: 6 - next: parse_vlan - parse_ethernet.4: - 0x*: - 0..1: ethernet.src_addr.16-31 - 2..3: ethernet.src_addr.0-15 - 4..5: ethernet.ether_type - ethernet.$valid: 1 - shift: 6 - next: parse_ipv4 - parse_ethernet.5: - 0x*: - 0..1: ethernet.src_addr.16-31 - 2..3: ethernet.src_addr.0-15 - 4..5: ethernet.ether_type - ethernet.$valid: 1 - shift: 6 - next: parse_ipv6 - parse_ethernet.6: - 0x*: - 0..1: ethernet.src_addr.16-31 - 2..3: ethernet.src_addr.0-15 - 4..5: ethernet.ether_type - ethernet.$valid: 1 - shift: 6 - next: parse_arp - parse_arp: - 0x*: - 0..1: arp.hw_type - 2..3: arp.proto_type - 4: arp.hw_addr_len - 5: arp.proto_addr_len - 6..7: arp.opcode - 8..9: arp.sender_hw_addr.32-47 - shift: 10 - next: parse_arp.0 - parse_arp.0: - 0x*: - 0..1: arp.sender_hw_addr.16-31 - 2..3: arp.sender_hw_addr.0-15 - 4..7: arp.sender_proto_addr - 8..9: arp.target_hw_addr.32-47 - 10..11: arp.target_hw_addr.16-31 - shift: 12 - next: parse_arp.0.0 - parse_arp.0.0: - 0x*: - 0..1: arp.target_hw_addr.0-15 - 2..5: arp.target_proto_addr - arp.$valid: 1 - shift: 6 - next: end - parse_ethernet.7: - 0x*: - 0..1: ethernet.src_addr.16-31 - 2..3: ethernet.src_addr.0-15 - 4..5: ethernet.ether_type - ethernet.$valid: 1 - shift: 6 - next: end -deparser ingress: - dictionary: - H0: $bridge-metadata - B63: $bridge-metadata - H2: $bridge-metadata - local_metadata.l4_dst_port: $bridge-metadata - ethernet.dst_addr.32-47: ethernet.$valid - ethernet.dst_addr.16-31: ethernet.$valid - ethernet.dst_addr.0-15: ethernet.$valid - ethernet.src_addr.32-47: ethernet.$valid - ethernet.src_addr.16-31: ethernet.$valid - ethernet.src_addr.0-15: ethernet.$valid - ethernet.ether_type: ethernet.$valid - H15: vlan_tag$0.$valid - vlan_tag$0.ether_type: vlan_tag$0.$valid - TH3: vlan_tag$1.$valid - vlan_tag$1.ether_type: vlan_tag$1.$valid - TB1: ipv4_base.$valid - ipv4_base.diffserv: ipv4_base.$valid - ipv4_base.total_len: ipv4_base.$valid - ipv4_base.identification: ipv4_base.$valid - H14: ipv4_base.$valid - ipv4_base.ttl: ipv4_base.$valid - ipv4_base.protocol: ipv4_base.$valid - ipv4_base.hdr_checksum: ipv4_base.$valid - ipv4_base.src_addr: ipv4_base.$valid - ipv4_base.dst_addr: ipv4_base.$valid - W8: ipv6_base.$valid - ipv6_base.payload_length: ipv6_base.$valid - ipv6_base.next_header: ipv6_base.$valid - ipv6_base.hop_limit: ipv6_base.$valid - ipv6_base.src_addr.96-127: ipv6_base.$valid - ipv6_base.src_addr.64-95: ipv6_base.$valid - ipv6_base.src_addr.32-63: ipv6_base.$valid - ipv6_base.src_addr.0-31: ipv6_base.$valid - ipv6_base.dst_addr.96-127: ipv6_base.$valid - ipv6_base.dst_addr.64-95: ipv6_base.$valid - ipv6_base.dst_addr.32-63: ipv6_base.$valid - ipv6_base.dst_addr.0-31: ipv6_base.$valid - arp.hw_type: arp.$valid - arp.proto_type: arp.$valid - arp.hw_addr_len: arp.$valid - arp.proto_addr_len: arp.$valid - arp.opcode: arp.$valid - arp.sender_hw_addr.32-47: arp.$valid - arp.sender_hw_addr.16-31: arp.$valid - arp.sender_hw_addr.0-15: arp.$valid - arp.sender_proto_addr: arp.$valid - arp.target_hw_addr.32-47: arp.$valid - arp.target_hw_addr.16-31: arp.$valid - arp.target_hw_addr.0-15: arp.$valid - arp.target_proto_addr: arp.$valid - tcp.src_port: tcp.$valid - tcp.dst_port: tcp.$valid - tcp.seq_no: tcp.$valid - tcp.ack_no: tcp.$valid - TB0: tcp.$valid - tcp.flags: tcp.$valid - tcp.window: tcp.$valid - tcp.checksum: tcp.$valid - tcp.urgent_ptr: tcp.$valid - udp.src_port: udp.$valid - udp.dst_port: udp.$valid - udp.hdr_length: udp.$valid - udp.checksum: udp.$valid - egress_unicast_port: standard_metadata.egress_spec - mirror: - 0: [ $mirror, $mirror_id, H13 ] - select: $mirror -parser egress: - start: $egress_metadata_shim - $egress_metadata_shim: - 0x*: - 0..1: H16 - shift: 2 - next: $bridge-metadata - save: { half:0..1 } - $bridge-metadata: - 0x*: - 0..1: H22 - 2: B31 - 3..4: H17 - 5..6: local_metadata.l4_dst_port - shift: 7 - next: start$ - start$: - match: [ half ] - 0x0fd: - next: parse_cpu_header - 0x*: - next: parse_ethernet - parse_cpu_header: - 0x*: - 0..1: TH27 - 2..5: TW27 - packet_out.$valid: 1 - shift: 2 - next: parse_ethernet - parse_ethernet: - match: [ 12..13 ] - 0x8100: - 0..1: ethernet.dst_addr.32-47 - 2..3: ethernet.dst_addr.16-31 - 4..5: ethernet.dst_addr.0-15 - 6..7: ethernet.src_addr.32-47 - shift: 8 - next: parse_ethernet.0 - 0x9100: - 0..1: ethernet.dst_addr.32-47 - 2..3: ethernet.dst_addr.16-31 - 4..5: ethernet.dst_addr.0-15 - 6..7: ethernet.src_addr.32-47 - shift: 8 - next: parse_ethernet.1 - 0x9200: - 0..1: ethernet.dst_addr.32-47 - 2..3: ethernet.dst_addr.16-31 - 4..5: ethernet.dst_addr.0-15 - 6..7: ethernet.src_addr.32-47 - shift: 8 - next: parse_ethernet.2 - 0x9300: - 0..1: ethernet.dst_addr.32-47 - 2..3: ethernet.dst_addr.16-31 - 4..5: ethernet.dst_addr.0-15 - 6..7: ethernet.src_addr.32-47 - shift: 8 - next: parse_ethernet.3 - 0x0800: - 0..1: ethernet.dst_addr.32-47 - 2..3: ethernet.dst_addr.16-31 - 4..5: ethernet.dst_addr.0-15 - 6..7: ethernet.src_addr.32-47 - shift: 8 - next: parse_ethernet.4 - 0x86dd: - 0..1: ethernet.dst_addr.32-47 - 2..3: ethernet.dst_addr.16-31 - 4..5: ethernet.dst_addr.0-15 - 6..7: ethernet.src_addr.32-47 - shift: 8 - next: parse_ethernet.5 - 0x0806: - next: end - 0x*: - next: end - parse_ethernet.0: - 0x*: - 0..1: ethernet.src_addr.16-31 - 2..3: ethernet.src_addr.0-15 - 4..5: ethernet.ether_type - ethernet.$valid: 1 - shift: 6 - next: parse_vlan - parse_vlan: - match: [ 2..3 ] - 0x8100: - 0..1: TH32 - 2..3: vlan_tag$0.ether_type - vlan_tag$0.$valid: 1 - shift: 4 - next: parse_vlan.0 - 0x9100: - 0..1: TH32 - 2..3: vlan_tag$0.ether_type - vlan_tag$0.$valid: 1 - shift: 4 - next: parse_vlan.5 - 0x9200: - 0..1: TH32 - 2..3: vlan_tag$0.ether_type - vlan_tag$0.$valid: 1 - shift: 4 - next: parse_vlan.10 - 0x9300: - 0..1: TH32 - 2..3: vlan_tag$0.ether_type - vlan_tag$0.$valid: 1 - shift: 4 - next: parse_vlan.15 - 0x0800: - 0..1: TH32 - 2..3: vlan_tag$0.ether_type - vlan_tag$0.$valid: 1 - shift: 4 - next: parse_ipv4 - 0x86dd: - 0..1: TH32 - 2..3: vlan_tag$0.ether_type - vlan_tag$0.$valid: 1 - shift: 4 - next: parse_ipv6 - 0x*: - next: end - parse_vlan.0: - match: [ 2..3 ] - 0x8100: - next: end - 0x9100: - next: end - 0x9200: - next: end - 0x9300: - next: end - 0x0800: - 0..1: TH31 - 2..3: vlan_tag$1.ether_type - vlan_tag$1.$valid: 1 - shift: 4 - next: parse_ipv4 - 0x86dd: - 0..1: TH31 - 2..3: vlan_tag$1.ether_type - vlan_tag$1.$valid: 1 - shift: 4 - next: parse_ipv6 - 0x*: - next: end - parse_ipv4: - match: [ /* egress::ipv4_base.frag_offset ++ egress::ipv4_base.protocol; */ ] - 0x000001: - next: end - 0x000006: - next: end - 0x000011: - 0: TB16 - 1: ipv4_base.diffserv - 2..3: ipv4_base.total_len - 4..5: ipv4_base.identification - 6..7: H23 - 8: ipv4_base.ttl - 9: ipv4_base.protocol - 10..11: ipv4_base.hdr_checksum - 12..15: ipv4_base.src_addr - 16..19: ipv4_base.dst_addr - shift: 20 - next: parse_ipv4.0 - 0x*: - next: end - parse_ipv4.0: - 0x*: - ipv4_base.$valid: 1 - next: parse_udp - parse_udp: - 0x*: - 0..1: udp.src_port - 2..3: udp.dst_port - 4..5: udp.hdr_length - 6..7: udp.checksum - udp.$valid: 1 - shift: 8 - next: end - parse_ipv6: - match: [ 6 ] - 0x3a: - next: end - 0x06: - next: end - 0x11: - 0..3: TW24 - 4..5: ipv6_base.payload_length - 6: ipv6_base.next_header - 7: ipv6_base.hop_limit - 8..11: ipv6_base.src_addr.96-127 - 12..15: ipv6_base.src_addr.64-95 - 16..19: ipv6_base.src_addr.32-63 - shift: 20 - next: parse_ipv6.0 - 0x*: - next: end - parse_ipv6.0: - 0x*: - 0..3: ipv6_base.src_addr.0-31 - 4..7: ipv6_base.dst_addr.96-127 - 8..11: ipv6_base.dst_addr.64-95 - 12..15: ipv6_base.dst_addr.32-63 - shift: 16 - next: parse_ipv6.0.0 - parse_ipv6.0.0: - 0x*: - 0..3: ipv6_base.dst_addr.0-31 - ipv6_base.$valid: 1 - shift: 4 - next: parse_udp - parse_vlan.5: - match: [ 2..3 ] - 0x8100: - next: end - 0x9100: - next: end - 0x9200: - next: end - 0x9300: - next: end - 0x0800: - 0..1: TH31 - 2..3: vlan_tag$1.ether_type - vlan_tag$1.$valid: 1 - shift: 4 - next: parse_ipv4 - 0x86dd: - 0..1: TH31 - 2..3: vlan_tag$1.ether_type - vlan_tag$1.$valid: 1 - shift: 4 - next: parse_ipv6 - 0x*: - next: end - parse_vlan.10: - match: [ 2..3 ] - 0x8100: - next: end - 0x9100: - next: end - 0x9200: - next: end - 0x9300: - next: end - 0x0800: - 0..1: TH31 - 2..3: vlan_tag$1.ether_type - vlan_tag$1.$valid: 1 - shift: 4 - next: parse_ipv4 - 0x86dd: - 0..1: TH31 - 2..3: vlan_tag$1.ether_type - vlan_tag$1.$valid: 1 - shift: 4 - next: parse_ipv6 - 0x*: - next: end - parse_vlan.15: - match: [ 2..3 ] - 0x8100: - next: end - 0x9100: - next: end - 0x9200: - next: end - 0x9300: - next: end - 0x0800: - 0..1: TH31 - 2..3: vlan_tag$1.ether_type - vlan_tag$1.$valid: 1 - shift: 4 - next: parse_ipv4 - 0x86dd: - 0..1: TH31 - 2..3: vlan_tag$1.ether_type - vlan_tag$1.$valid: 1 - shift: 4 - next: parse_ipv6 - 0x*: - next: end - parse_ethernet.1: - 0x*: - 0..1: ethernet.src_addr.16-31 - 2..3: ethernet.src_addr.0-15 - 4..5: ethernet.ether_type - ethernet.$valid: 1 - shift: 6 - next: parse_vlan - parse_ethernet.2: - 0x*: - 0..1: ethernet.src_addr.16-31 - 2..3: ethernet.src_addr.0-15 - 4..5: ethernet.ether_type - ethernet.$valid: 1 - shift: 6 - next: parse_vlan - parse_ethernet.3: - 0x*: - 0..1: ethernet.src_addr.16-31 - 2..3: ethernet.src_addr.0-15 - 4..5: ethernet.ether_type - ethernet.$valid: 1 - shift: 6 - next: parse_vlan - parse_ethernet.4: - 0x*: - 0..1: ethernet.src_addr.16-31 - 2..3: ethernet.src_addr.0-15 - 4..5: ethernet.ether_type - ethernet.$valid: 1 - shift: 6 - next: parse_ipv4 - parse_ethernet.5: - 0x*: - 0..1: ethernet.src_addr.16-31 - 2..3: ethernet.src_addr.0-15 - 4..5: ethernet.ether_type - ethernet.$valid: 1 - shift: 6 - next: parse_ipv6 -deparser egress: - dictionary: - ethernet.dst_addr.32-47: ethernet.$valid - ethernet.dst_addr.16-31: ethernet.$valid - ethernet.dst_addr.0-15: ethernet.$valid - ethernet.src_addr.32-47: ethernet.$valid - ethernet.src_addr.16-31: ethernet.$valid - ethernet.src_addr.0-15: ethernet.$valid - ethernet.ether_type: ethernet.$valid - TH32: vlan_tag$0.$valid - vlan_tag$0.ether_type: vlan_tag$0.$valid - TH31: vlan_tag$1.$valid - vlan_tag$1.ether_type: vlan_tag$1.$valid - TB16: ipv4_base.$valid - ipv4_base.diffserv: ipv4_base.$valid - ipv4_base.total_len: ipv4_base.$valid - ipv4_base.identification: ipv4_base.$valid - H23: ipv4_base.$valid - ipv4_base.ttl: ipv4_base.$valid - ipv4_base.protocol: ipv4_base.$valid - ipv4_base.hdr_checksum: ipv4_base.$valid - ipv4_base.src_addr: ipv4_base.$valid - ipv4_base.dst_addr: ipv4_base.$valid - TW24: ipv6_base.$valid - ipv6_base.payload_length: ipv6_base.$valid - ipv6_base.next_header: ipv6_base.$valid - ipv6_base.hop_limit: ipv6_base.$valid - ipv6_base.src_addr.96-127: ipv6_base.$valid - ipv6_base.src_addr.64-95: ipv6_base.$valid - ipv6_base.src_addr.32-63: ipv6_base.$valid - ipv6_base.src_addr.0-31: ipv6_base.$valid - ipv6_base.dst_addr.96-127: ipv6_base.$valid - ipv6_base.dst_addr.64-95: ipv6_base.$valid - ipv6_base.dst_addr.32-63: ipv6_base.$valid - ipv6_base.dst_addr.0-31: ipv6_base.$valid - udp.src_port: udp.$valid - udp.dst_port: udp.$valid - udp.hdr_length: udp.$valid - udp.checksum: udp.$valid - egress_unicast_port: standard_metadata.egress_port -stage 0 ingress: - exact_match tbl_act 0: - p4: { name: tbl_act } - row: 0 - bus: 1 - column: [ ] - next: cond-1 - actions: - act_1: - - set hasExited, 0 - default_action: act_1 - gateway cond-1 2: - input_xbar: - group 0: { 7: packet_out.$valid } - hash 0: - 40: packet_out.$valid - hash group 0: - table: [0] - row: 0 - bus: 0 - match: { 32: packet_out.$valid } - 0x1: tbl_act_0 - miss: vrf_vrf_classifier_table_0 -stage 1 ingress: - exact_match tbl_act_0 0: - p4: { name: tbl_act_0 } - row: 1 - bus: 0 - column: [ ] - gateway: - input_xbar: - group 0: { 15: packet_out.submit_to_ingress } - row: 1 - bus: 1 - match: { 7: packet_out.submit_to_ingress } - 0x0: run_table - miss: tbl_act_1 - next: tbl_act_1 - action_bus: { } - actions: - act: - - { $data0: immediate(0..6), $constant0: $data0(6..6), $constant0: 1, $constant1: $data0(6..6), $constant1: 1 } - - set standard_metadata.egress_spec, packet_out.egress_physical_port - - set B63(6..6), $data0(6..6) - default_action: act - exact_match tbl_act_1 2: - p4: { name: tbl_act_1 } - row: 0 - bus: 0 - column: [ ] - gateway: - input_xbar: - group 0: { 22: hasExited } - row: 0 - bus: 1 - match: { 6: hasExited } - 0b*0: run_table - miss: vrf_vrf_classifier_table_0 - next: vrf_vrf_classifier_table_0 - actions: - act_0: - - 0 - default_action: act_0 - ternary_match vrf_vrf_classifier_table_0 3: - p4: { name: vrf.vrf_classifier_table } - row: [ 0, 1, 2, 3, 4, 5 ] - bus: [ 0, 0, 0, 0, 0, 0 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - input_xbar: - group 0: { 0: ipv4_base.dst_addr, 32: ipv6_base.dst_addr.0-31(0..7), 40: standard_metadata.ingress_port(8) } - group 1: { 0: ipv6_base.dst_addr.0-31(16..31), 16: ipv6_base.dst_addr.32-63(0..7), 24: ipv6_base.dst_addr.0-31(8..15), 32: ipv6_base.dst_addr.32-63(16..23) } - group 2: { 0: ipv6_base.dst_addr.32-63(24..31), 8: ipv6_base.dst_addr.64-95(0..7), 16: ipv6_base.dst_addr.32-63(8..15), 24: ipv6_base.dst_addr.64-95(16..31), 40: ethernet.ether_type(0..7) } - group 3: { 0: ipv6_base.dst_addr.64-95(8..15), 8: ipv6_base.dst_addr.96-127(16..31), 24: ipv6_base.dst_addr.96-127(0..15) } - group 4: { 4: ipv6_base.traffic_class, 16: ethernet.src_addr.0-15(0..7), 24: ethernet.ether_type(8..15), 32: ethernet.src_addr.16-31(0..7), 40: ethernet.src_addr.32-47(8..15) } - group 5: { 0: ethernet.src_addr.32-47(0..7), 8: ethernet.src_addr.0-15(8..15), 16: standard_metadata.ingress_port(0..7), 24: ethernet.src_addr.16-31(8..15), 32: ipv4_base.diffserv } - gateway: - input_xbar: - group 0: { 22: hasExited } - row: 0 - bus: 0 - match: { 6: hasExited } - 0b*0: run_table - miss: END - next: class_id_class_id_assignment_table_0 - action: vrf_vrf_classifier_table_0$action - default_action: vrf.set_vrf - default_action_parameters: - vrf_id: 0 - action vrf_vrf_classifier_table_0$action: - p4: { name: vrf_vrf_classifier_table_0$action } - row: 14 - column: 5 - home_row: 14 - format vrf.set_vrf: { $adf_f0: 0..31 } - action_bus: { 96..99 : $adf_f0 } - actions: - vrf.set_vrf: - - { vrf_id: $adf_f0 } - - set local_metadata.vrf_id, vrf_id - ternary_match class_id_class_id_assignment_table_0 4: - p4: { name: class_id.class_id_assignment_table } - row: [ 6, 7, 8, 9, 10, 11 ] - bus: [ 0, 0, 0, 0, 0, 0 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - input_xbar: - group 2: { 0: ipv6_base.dst_addr.32-63(24..31), 8: ipv6_base.dst_addr.64-95(0..7), 16: ipv6_base.dst_addr.32-63(8..15), 24: ipv6_base.dst_addr.64-95(16..31), 40: ethernet.ether_type(0..7) } - group 3: { 0: ipv6_base.dst_addr.64-95(8..15), 8: ipv6_base.dst_addr.96-127(16..31), 24: ipv6_base.dst_addr.96-127(0..15) } - group 8: { 0: ipv4_base.dst_addr, 32: ipv6_base.dst_addr.0-31(0..7) } - group 9: { 0: ipv6_base.dst_addr.0-31(16..31), 16: ipv6_base.dst_addr.32-63(0..7), 24: ipv6_base.dst_addr.0-31(8..15), 32: ipv6_base.dst_addr.32-63(16..23), 41: vlan_tag$0.pcp } - group 10: { 0: ethernet.ether_type(8..15), 8: local_metadata.l4_dst_port, 24: local_metadata.l4_src_port, 40: ipv6_base.next_header } - group 11: { 0: vlan_tag$0.vid(8..11), 8: vlan_tag$0.vid(0..7), 16: ipv4_base.protocol, 24: ipv4_base.ttl, 32: ipv6_base.hop_limit } - next: l3_fwd_l3_routing_classifier_table_0 - action: class_id_class_id_assignment_table_0$action - default_action: class_id.set_class_id - default_action_parameters: - class_id_value: 0 - action class_id_class_id_assignment_table_0$action: - p4: { name: class_id_class_id_assignment_table_0$action } - row: 15 - column: 0 - home_row: 15 - format class_id.set_class_id: { $adf_b0: 0..7 } - action_bus: { 2 : $adf_b0 } - actions: - class_id.set_class_id: - - { class_id_value: $adf_b0 } - - set local_metadata.class_id, class_id_value - exact_match l3_fwd_l3_routing_classifier_table_0 5: - p4: { name: l3_fwd.l3_routing_classifier_table } - row: 7 - bus: 0 - column: [ 2, 3, 4 ] - ways: - - [0, 0, 0x0, [7, 2]] - - [0, 1, 0x0, [7, 3]] - - [0, 2, 0x0, [7, 4]] - input_xbar: - group 0: { 24: ethernet.dst_addr.0-15(8..15), 32: ethernet.dst_addr.0-15(0..7), 40: ethernet.dst_addr.16-31(8..15), 48: ethernet.dst_addr.16-31(0..7), 56: ethernet.dst_addr.32-47(8..15), 64: ethernet.dst_addr.32-47(0..7) } - hash 0: - 0..9: random(ethernet.dst_addr.0-15(8..15), ethernet.dst_addr.0-15(0..7), ethernet.dst_addr.16-31(8..15), ethernet.dst_addr.16-31(2..7), ethernet.dst_addr.32-47(8..15)) ^ stripe(ethernet.dst_addr.16-31(0..1)) - 10..19: random(ethernet.dst_addr.0-15(8..15), ethernet.dst_addr.0-15(0..7), ethernet.dst_addr.16-31(8..15), ethernet.dst_addr.16-31(2..7), ethernet.dst_addr.32-47(8..15)) ^ stripe(ethernet.dst_addr.16-31(0..1)) - 20..29: random(ethernet.dst_addr.0-15(8..15), ethernet.dst_addr.0-15(0..7), ethernet.dst_addr.16-31(8..15), ethernet.dst_addr.16-31(2..7), ethernet.dst_addr.32-47(8..15)) ^ stripe(ethernet.dst_addr.16-31(0..1)) - hash 1: - 0..9: stripe(ethernet.dst_addr.32-47(0..7)) - 10..19: stripe(ethernet.dst_addr.32-47(0..7)) - 20..29: stripe(ethernet.dst_addr.32-47(0..7)) - hash group 0: - table: [0, 1] - format: { version(0): 112..115, match(0): [56..63, 32..39, 66..71, 40..55 ] } - match: [ ethernet.dst_addr.0-15, ethernet.dst_addr.16-31(2..15), ethernet.dst_addr.32-47(8..15) ] - hit: l3_fwd_l3_ipv4_override_table_0 - miss: punt_punt_table_0 - actions: - NoAction: - - 0 - default_action: NoAction -stage 2 ingress: - ternary_match l3_fwd_l3_ipv4_override_table_0 0: - p4: { name: l3_fwd.l3_ipv4_override_table, action_profile: l3_fwd.wcmp_action_profile } - row: 2 - bus: 0 - column: 0 - input_xbar: - group 0: { 0: ipv4_base.dst_addr } - gateway: - input_xbar: - group 1: { 7: ipv4_base.$valid } - hash 2: - 40: ipv4_base.$valid - hash group 1: - table: [2] - row: 5 - bus: 0 - match: { 32: ipv4_base.$valid } - 0x1: run_table - miss: punt_punt_table_0 - hit: tbl_act_2 - miss: l3_fwd_l3_ipv4_vrf_table_0 - indirect: l3_fwd_l3_ipv4_override_table_0$tind - ternary_indirect l3_fwd_l3_ipv4_override_table_0$tind: - row: 0 - bus: 0 - column: 2 - format: { action: 27..27, action_ptr: 0..9, select_ptr: 17} - action: l3_fwd_l3_ipv4_fallback_table_0$act_prof.l3_fwd.wcmp_action_profile(action, action_ptr) - selector: l3_fwd_l3_ipv4_fallback_table_0$act_sel.l3_fwd.wcmp_action_profile(select_ptr) - default_action: NoAction - ternary_match l3_fwd_l3_ipv4_vrf_table_0 1: - p4: { name: l3_fwd.l3_ipv4_vrf_table, action_profile: l3_fwd.wcmp_action_profile } - row: [ 0, 1 ] - bus: [ 0, 0 ] - column: - - 0 - - 0 - input_xbar: - group 0: { 0: ipv4_base.dst_addr, 32: local_metadata.vrf_id(0..7) } - group 1: { 0: local_metadata.vrf_id(16..31), 24: local_metadata.vrf_id(8..15) } - hit: tbl_act_2 - miss: l3_fwd_l3_ipv4_fallback_table_0 - indirect: l3_fwd_l3_ipv4_vrf_table_0$tind - ternary_indirect l3_fwd_l3_ipv4_vrf_table_0$tind: - row: 1 - bus: 0 - column: 2 - format: { action: 27..27, action_ptr: 0..9, select_ptr: 17} - action: l3_fwd_l3_ipv4_fallback_table_0$act_prof.l3_fwd.wcmp_action_profile(action, action_ptr) - selector: l3_fwd_l3_ipv4_fallback_table_0$act_sel.l3_fwd.wcmp_action_profile(select_ptr) - default_action: NoAction - ternary_match l3_fwd_l3_ipv4_fallback_table_0 2: - p4: { name: l3_fwd.l3_ipv4_fallback_table, action_profile: l3_fwd.wcmp_action_profile } - row: 3 - bus: 0 - column: 0 - input_xbar: - group 0: { 0: ipv4_base.dst_addr } - next: tbl_act_2 - indirect: l3_fwd_l3_ipv4_fallback_table_0$tind - action l3_fwd_l3_ipv4_fallback_table_0$act_prof.l3_fwd.wcmp_action_profile: - row: 15 - column: 2 - home_row: 15 - format l3_fwd.set_nexthop: { $adf_h0: 16..31, $adf_h1: 32..47, $adf_h2: 48..63, $adf_h3: 64..79, $adf_h4: 80..95, $adf_h5: 96..111, $adf_h6: 112..127 } - action_bus: { 32..33 : $adf_h3, 34..35 : $adf_h4, 36..37 : $adf_h5, 38..39 : $adf_h6, 42..43 : $adf_h0, 44..45 : $adf_h1, 46..47 : $adf_h2 } - actions: - l3_fwd.set_nexthop: - - { port: $adf_h0, dmac.0-15: $adf_h1, dmac.16-31: $adf_h2, dmac.32-47: $adf_h3, smac.0-15: $adf_h4, smac.16-31: $adf_h5, smac.32-47: $adf_h6 } - - set standard_metadata.egress_spec, port - - add ipv4_base.ttl, ipv4_base.ttl, 255 - - set ethernet.dst_addr.0-15, dmac.0-15 - - set ethernet.dst_addr.16-31, dmac.16-31 - - set ethernet.dst_addr.32-47, dmac.32-47 - - set ethernet.src_addr.0-15, smac.0-15 - - set ethernet.src_addr.16-31, smac.16-31 - - set ethernet.src_addr.32-47, smac.32-47 - NoAction: - - { } - selection l3_fwd_l3_ipv4_fallback_table_0$act_sel.l3_fwd.wcmp_action_profile: - p4: { name: l3_fwd.wcmp_action_profile } - row: 15 - column: [ 0, 1 ] - maprams: [ 0, 1 ] - input_xbar: - group 0: { 0: ipv4_base.dst_addr, 32: ipv4_base.src_addr, 64: local_metadata.l4_dst_port, 80: local_metadata.l4_src_port, 96: ipv4_base.protocol } - hash 0: - 0..50: random(ipv4_base.dst_addr, ipv4_base.src_addr) - hash 1: - 0..50: random(local_metadata.l4_dst_port, local_metadata.l4_src_port, ipv4_base.protocol) - hash group 0: - table: [0, 1] - mode: fair 0 - ternary_indirect l3_fwd_l3_ipv4_fallback_table_0$tind: - row: 2 - bus: 0 - column: 2 - format: { action: 27..27, action_ptr: 0..9, select_ptr: 17} - action: l3_fwd_l3_ipv4_fallback_table_0$act_prof.l3_fwd.wcmp_action_profile(action, action_ptr) - selector: l3_fwd_l3_ipv4_fallback_table_0$act_sel.l3_fwd.wcmp_action_profile(select_ptr) - default_action: NoAction -stage 3 ingress: - exact_match tbl_act_2 0: - p4: { name: tbl_act_2 } - row: 0 - bus: 0 - column: [ ] - gateway: - input_xbar: - group 0: { 0: ipv4_base.ttl } - row: 0 - bus: 0 - match: { 0: ipv4_base.ttl } - 0x00: run_table - miss: punt_punt_table_0 - next: punt_punt_table_0 - actions: - act_2: - - invalidate standard_metadata.egress_spec - default_action: act_2 -stage 4 ingress: - ternary_match punt_punt_table_0 0: - p4: { name: punt.punt_table } - row: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] - bus: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] - column: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - input_xbar: - group 0: { 0: arp.target_proto_addr, 32: ipv4_base.dst_addr(0..7), 40: standard_metadata.egress_spec(8) } - group 1: { 0: ipv4_base.dst_addr(16..31), 16: ipv4_base.src_addr(0..7), 24: ipv4_base.dst_addr(8..15), 32: ipv4_base.src_addr(16..23) } - group 2: { 0: ipv4_base.src_addr(24..31), 8: ipv6_base.dst_addr.0-31(0..7), 16: ipv4_base.src_addr(8..15), 24: ipv6_base.dst_addr.0-31(16..31), 40: ipv6_base.dst_addr.64-95(0..7) } - group 3: { 0: ipv6_base.dst_addr.0-31(8..15), 8: ipv6_base.dst_addr.32-63(16..31), 24: ipv6_base.dst_addr.32-63(0..15) } - group 4: { 0: ipv6_base.dst_addr.64-95(16..31), 16: ipv6_base.dst_addr.96-127(0..7), 24: ipv6_base.dst_addr.64-95(8..15), 32: ipv6_base.dst_addr.96-127(16..23), 40: ipv6_base.src_addr.0-31(24..31) } - group 5: { 0: ipv6_base.src_addr.0-31(0..7), 8: ipv6_base.dst_addr.96-127(8..15), 16: ipv6_base.src_addr.0-31(16..23), 24: ipv6_base.dst_addr.96-127(24..31), 32: ipv6_base.src_addr.32-63(0..7) } - group 6: { 0: ipv6_base.src_addr.0-31(8..15), 8: ipv6_base.src_addr.32-63(16..31), 24: ipv6_base.src_addr.64-95(0..7), 32: ipv6_base.src_addr.32-63(8..15), 40: ipv6_base.src_addr.96-127(16..23) } - group 7: { 0: ipv6_base.src_addr.64-95(24..31), 8: ipv6_base.src_addr.96-127(0..7), 16: ipv6_base.src_addr.64-95(8..23), 32: ipv6_base.src_addr.96-127(24..31) } - group 8: { 0: local_metadata.vrf_id(0..7), 8: ipv6_base.src_addr.96-127(8..15), 20: ipv6_base.traffic_class, 32: ethernet.ether_type } - group 9: { 0: local_metadata.vrf_id(16..31), 16: standard_metadata.egress_spec(0..7), 24: local_metadata.vrf_id(8..15), 32: standard_metadata.ingress_port(0..7) } - group 10: { 0: standard_metadata.ingress_port(8), 8: vlan_tag$0.vid(0..7), 21: vlan_tag$0.pcp, 24: ipv4_base.diffserv, 32: vlan_tag$0.vid(8..11), 40: local_metadata.icmp_code } - group 11: { 0: ipv4_base.protocol, 8: ipv4_base.ttl, 16: ipv6_base.hop_limit, 24: ipv6_base.next_header, 32: local_metadata.class_id } - next: tbl_act_3 - action_bus: { } - indirect: punt_punt_table_0$tind - meter punt_punt_table_0$meter.punt.ingress_port_meter: - p4: { name: punt.ingress_port_meter } - row: 15 - column: [ 0, 1 ] - maprams: [ 0, 1 ] - color_maprams: - row: 7 - bus: 0 - column: 2 - type: standard - count: bytes - counter punt_punt_table_0$counter.punt.punt_packet_counter: - p4: { name: punt.punt_packet_counter } - row: 13 - column: [ 0, 1 ] - maprams: [ 0, 1 ] - count: packets - format: {packets(0): 106..126, packets(1): 85..105, packets(2): 64..84, packets(3): 42..62, packets(4): 21..41, packets(5): 0..20} - ternary_indirect punt_punt_table_0$tind: - row: 0 - bus: 0 - column: 2 - format: { action: 9..10, immediate: 0..8} - meter: punt_punt_table_0$meter.punt.ingress_port_meter - stats: punt_punt_table_0$counter.punt.punt_packet_counter - actions: - punt.set_queue_and_clone_to_cpu: - - { } - - set local_metadata.egress_spec_at_punt_match, standard_metadata.egress_spec - # - set $mirror_id, 1024 - - set $mirror, 1 - punt.set_queue_and_send_to_cpu: - - { $constant0: immediate(0..8), $constant0: 253 } - - set local_metadata.egress_spec_at_punt_match, standard_metadata.egress_spec - - set standard_metadata.egress_spec, $constant0 - NoAction: - - { } - default_action: NoAction -stage 5 ingress: - exact_match tbl_act_3 0: - p4: { name: tbl_act_3 } - row: 0 - bus: 0 - column: [ ] - gateway: - input_xbar: - group 0: { 5: local_metadata.color } - row: 0 - bus: 0 - match: { 5: local_metadata.color } - 0b*00: END - miss: run_table - next: END - actions: - act_3: - - invalidate standard_metadata.egress_spec - default_action: act_3 -stage 0 egress: - exact_match tbl_act_4 1: - p4: { name: tbl_act_4 } - row: 0 - bus: 0 - column: [ ] - next: tbl_packetio_egress_encap_packet_in_header - actions: - act_4: - - set hasExited_0, 0 - default_action: act_4 - exact_match tbl_packetio_egress_encap_packet_in_header 3: - p4: { name: tbl_packetio_egress_encap_packet_in_header } - row: 1 - bus: 0 - column: [ ] - gateway: - input_xbar: - group 0: { 8: standard_metadata.egress_port(8), 16: standard_metadata.egress_port(0..7) } - row: 0 - bus: 1 - match: { 0: standard_metadata.egress_port(0..7), 8: standard_metadata.egress_port(8) } - 0x**fd: run_table - miss: tbl_act_5 - next: tbl_act_5 - actions: - packetio_egress.encap_packet_in_header: - - 0 - default_action: packetio_egress.encap_packet_in_header -stage 1 egress: - exact_match tbl_act_5 1: - p4: { name: tbl_act_5 } - row: 0 - bus: 1 - column: [ ] - gateway: - input_xbar: - group 0: { 6: local_metadata.skip_egress } - row: 1 - bus: 0 - match: { 6: local_metadata.skip_egress } - 0b*1: run_table - miss: cond-10 - next: cond-10 - actions: - act_5: - - set hasExited_0, 1 - default_action: act_5 -stage 2 egress: - gateway cond-10 3: - input_xbar: - group 0: { 111: hasExited_0 } - row: 0 - bus: 0 - match: { 7: hasExited_0 } - 0x0: spoof_protection_dhcp_spoof_protection_table_0 - miss: END - exact_match spoof_protection_dhcp_spoof_protection_table_0 4: - p4: { name: spoof_protection.dhcp_spoof_protection_table } - row: [ 5, 6, 7 ] - bus: [ 0, 0, 0 ] - column: - - 2 - - 2 - - 2 - ways: - - [1, 0, 0x0, [7, 2]] - - [1, 1, 0x0, [6, 2]] - - [1, 2, 0x0, [5, 2]] - input_xbar: - group 1: { 8: local_metadata.l4_dst_port(8..15), 16: local_metadata.l4_dst_port(0..7), 24: standard_metadata.egress_spec(8), 32: standard_metadata.egress_spec(0..7) } - hash 2: - 0..9: random(local_metadata.l4_dst_port(8..15), local_metadata.l4_dst_port(1..7)) ^ stripe(local_metadata.l4_dst_port(0), standard_metadata.egress_spec(8), standard_metadata.egress_spec(0..7)) - 10..19: random(local_metadata.l4_dst_port(8..15), local_metadata.l4_dst_port(1..7)) ^ stripe(local_metadata.l4_dst_port(0), standard_metadata.egress_spec(8), standard_metadata.egress_spec(0..7)) - 20..29: random(local_metadata.l4_dst_port(8..15), local_metadata.l4_dst_port(1..7)) ^ stripe(local_metadata.l4_dst_port(0), standard_metadata.egress_spec(8), standard_metadata.egress_spec(0..7)) - hash group 1: - table: [2] - format: { action(0): 1, version(0): 112..115, match(0): [41..47, 32..39 ] } - match: [ local_metadata.l4_dst_port(1..15) ] - gateway: - input_xbar: - group 2: { 7: udp.$valid } - hash 4: - 40: udp.$valid - hash group 2: - table: [4] - row: 0 - bus: 1 - match: { 32: udp.$valid } - 0x1: run_table - miss: END - next: END - actions: - spoof_protection.drop_packet: - - invalidate standard_metadata.egress_port - NoAction: - - 0 - default_action: NoAction diff --git a/backends/tofino/bf-asm/test/bfas_lookup_test/__init__.py b/backends/tofino/bf-asm/test/bfas_lookup_test/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_cases.py b/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_cases.py deleted file mode 100644 index 9912ea2c060..00000000000 --- a/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_cases.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python3 - -# The test line is a list of input data in following forma: -# * Input BFA file to translate, relative from this folder (string) -# * BFA parameters (list) -# * Expected results (dictionary) -# - name of the inspected match (string) -# - results for 8 and 16 bit extractions where the first one is for 8 bit -# and second one for 16 bit extractions (tuple) -# - -TEST_LIST = [ - [ - "../asm/network_tap.bfa", - [], - { - "ingress,parse_inner_ipv6": (68, 30), - "ingress,parse_ipv6.$split_1": (56, 18), - "ingress,parse_inner_tcp": (72, 34), - "ingress,parse_volte,0x6*": (68, 28), - "egress,parse_gtp_base,0x01****": (60, 36), - "egress,parse_imsi": (64, 38), - "egress,parse_volte,0x6*": (60, 36), - "egress,parse_inner_tcp": (64, 44), - "egress,parse_inner_ipv6": (64, 40), - "egress,parse_ipv6": (32, 18), - "egress,parse_mpls_bos,0x6*": (52, 26), - }, - ], -] diff --git a/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_test.py b/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_test.py deleted file mode 100755 index 6b327392c40..00000000000 --- a/backends/tofino/bf-asm/test/bfas_lookup_test/bfas_lookup_test.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env python3 - -import os -import pdb -import pprint -import re -import shlex -import subprocess -import sys -import traceback - -import bfas_lookup_cases - -# Path to the stability test folder -BFAS_LOOKUP_TEST_PATH = os.path.dirname(os.path.realpath(__file__)) -# Relative path to the bfas folder -BFAS_REL_PATH = os.path.join(BFAS_LOOKUP_TEST_PATH, "../../../build/bf-asm") -# Absolute path to the bfas folder -BFAS_ABS_PATH = os.path.abspath(BFAS_REL_PATH) -# Path to the bfas file -BFAS_TOOL_ABS = os.path.join(BFAS_ABS_PATH, "bfas") - - -class MatchCompareException(Exception): - def __init__(self, expected, received): - # Build the error message - err_msg = "Expected and received results are not same!\n" - err_msg += "\t* 8 bit - {} (expected), {} (received)\n".format(expected[0], received[0]) - err_msg += "\t* 16 bit - {} (expected), {} (received)\n".format(expected[1], received[1]) - super().__init__(err_msg) - - -def run_bfas_translation(bfa_file, bfa_options, log_file): - """ - Run the bfas tool with enabled verbose and file logging. - - Parameters: - * bfa_file - file to process - * bfa_options - list of additional options which will be extended - with logging into a logfile - * log_file - file we want to log into - """ - try: - bfa_command = ( - [BFAS_TOOL_ABS, "-v", "-v", "-v", "-v", "-l", log_file] + bfa_options + [bfa_file] - ) - cmd_concat = ' '.join(bfa_command) - p = subprocess.Popen(cmd_concat, shell=True) - p.wait() - ret_code = p.returncode - if ret_code != 0: - print("Return code: {}".format(ret_code)) - sys.exit(ret_code) - except Exception: - print("error invoking {}".format(bfa_command), file=sys.stderr) - print(traceback.format_exc(), file=sys.stderr) - sys.exit(1) - - -def parse_results(log_file): - """ - Parse the log file and return the dictionary in the form of: - * key - name of the match - * value - tuple with 8 bit extractions (index 0) and 16 bit extractions (index 1) - """ - if not os.path.exists(log_file): - raise RuntimeError("Log file {} doesn't exists!".format(log_file)) - - ret = {} - logf = open(log_file, 'r') - while True: - # Analyze the file line by line - line = logf.readline() - if line == "": - break - - matchobj = re.match(r"INFO: Used extractors for (.*) - 8bit:([0-9]+), 16bit:([0-9]+)", line) - if not matchobj: - continue - - match = matchobj.group(1) - ext8 = int(matchobj.group(2)) - ext16 = int(matchobj.group(3)) - ret[match] = (ext8, ext16) - logf.close() - return ret - - -def run_test(): - # Name of the file with bfas log file - log_file_path = os.path.join(BFAS_ABS_PATH, "bfas_translation.log") - try: - print("Starting the BFAS test of cache lookup test for Tofino ") - for test in bfas_lookup_cases.TEST_LIST: - bfa_file = os.path.join(BFAS_LOOKUP_TEST_PATH, test[0]) - bfa_options = test[1] - expected_results = test[2] - # Run the translation, parse output data and check results - run_bfas_translation(bfa_file, bfa_options, log_file_path) - translation_results = parse_results(log_file_path) - - # Check that both dictionaries contains same keys - same_key_set = set(expected_results.keys()) == set(translation_results.keys()) - if not same_key_set: - raise RuntimeError( - "Key sets are not same:\n\tExpected: {}\n\tReceived{}".format( - expected_results.keys(), translation_results.keys() - ) - ) - - # Iterate over the dictionary and check results - for match, values in expected_results.items(): - if translation_results[match] != values: - raise MatchCompareException(values, translation_results[match]) - - # Cleanup of generated files between runs - os.remove(log_file_path) - - files_to_remove = ["context.json", "mau.gfm.log", "tofino.bin"] - for f in files_to_remove: - os.remove(os.path.join(BFAS_LOOKUP_TEST_PATH, f)) - - print("All tests passed!") - except Exception: - print(traceback.format_exc(), file=sys.stderr) - sys.exit(1) - - -if __name__ == "__main__": - run_test() - sys.exit(0) diff --git a/backends/tofino/bf-asm/test/checksum1.p4 b/backends/tofino/bf-asm/test/checksum1.p4 deleted file mode 100644 index 2d132ecea02..00000000000 --- a/backends/tofino/bf-asm/test/checksum1.p4 +++ /dev/null @@ -1,120 +0,0 @@ -parser start { - return parse_ethernet; -} - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header ethernet_t ethernet; -#define ETHERTYPE_IPV4 0x0800 -#define ETHERTYPE_IPV6 0x86dd - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - ETHERTYPE_IPV4 : parse_ipv4; - ETHERTYPE_IPV6 : parse_ipv6; - default: ingress; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} -header ipv4_t ipv4; -field_list ipv4_checksum_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_checksum { - input { - ipv4_checksum_list; - } - algorithm : csum16; - output_width : 16; -} - -calculated_field ipv4.hdrChecksum { - verify ipv4_checksum; - update ipv4_checksum; -} - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -header_type ipv6_t { - fields { - version : 4; - trafficClass : 8; - flowLabel : 20; - payloadLen : 16; - nextHdr : 8; - hopLimit : 8; - srcAddr : 128; - dstAddr : 128; - } -} -header ipv6_t ipv6; - -parser parse_ipv6 { - extract(ipv6); - return ingress; -} - -action do_setup() { -} - -table setup { - reads { ethernet: valid; } - actions { do_setup; } -} - -action drop() { -} -action forward(to) { - modify_field(ethernet.dstAddr, to); - add_to_field(ipv4.ttl, -1); -} - -table route { - reads { ipv4.dstAddr : ternary; } - actions { - drop; - forward; - } -} - -control ingress { - apply(setup); - apply(route); -} diff --git a/backends/tofino/bf-asm/test/counter1.p4 b/backends/tofino/bf-asm/test/counter1.p4 deleted file mode 100644 index b81579347a9..00000000000 --- a/backends/tofino/bf-asm/test/counter1.p4 +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Simple stat program. - * Direct mapped, that does not go across stages - */ - -header_type ethernet_t { - fields { - dstAddr : 48; - } -} -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return ingress; -} -action act(idx) { - modify_field(ethernet.dstAddr, idx); -} -table tab1 { - reads { - ethernet.dstAddr : exact; - } - actions { - act; - } - size: 128; -} - -counter cnt { - type: packets; - direct: tab1; - -} -control ingress { - apply(tab1); -} -control egress { - -} diff --git a/backends/tofino/bf-asm/test/counter2.p4 b/backends/tofino/bf-asm/test/counter2.p4 deleted file mode 100644 index 4879b5a208e..00000000000 --- a/backends/tofino/bf-asm/test/counter2.p4 +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Simple stat program. - * Direct mapped, that does not go across stages - */ - -header_type ethernet_t { - fields { - dstAddr : 48; - } -} -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return ingress; -} -action act(idx) { - modify_field(ethernet.dstAddr, idx); -} -table tab1 { - reads { - ethernet.dstAddr : ternary; - } - actions { - act; - } - size: 128; -} - -counter cnt { - type: packets; - direct: tab1; - -} -control ingress { - apply(tab1); -} -control egress { - -} diff --git a/backends/tofino/bf-asm/test/counter3.p4 b/backends/tofino/bf-asm/test/counter3.p4 deleted file mode 100644 index 652e75c96cb..00000000000 --- a/backends/tofino/bf-asm/test/counter3.p4 +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Simple stat program. - * Statically mapped, that should be optimized away by the compiler - * because there isn't a count primitive in any of the actions - * - */ - -header_type ethernet_t { - fields { - dstAddr : 48; - } -} -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return ingress; -} -action act(idx) { - modify_field(ethernet.dstAddr, idx); -} -table tab1 { - reads { - ethernet.dstAddr : exact; - } - actions { - act; - } - size: 128; -} - -counter cnt { - type: packets; - direct: tab1; -} - -counter cnt2 { - type: bytes; - direct: tab1; - - -} - -control ingress { - apply(tab1); -} -control egress { - -} diff --git a/backends/tofino/bf-asm/test/counter4.p4 b/backends/tofino/bf-asm/test/counter4.p4 deleted file mode 100644 index ac0315b1f95..00000000000 --- a/backends/tofino/bf-asm/test/counter4.p4 +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Simple program, just a direct mapped RAM - */ - -header_type ethernet_t { - fields { - dstAddr : 48; - } -} -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return ingress; -} -action act(idx) { - modify_field(ethernet.dstAddr, idx); - count(cntDum, idx); -} -table tab1 { - reads { - ethernet.dstAddr : exact; - } - actions { - act; - } - size: 70000; -} - -counter cntDum { - type: packets; - static: tab1; - instance_count: 200; - -} -control ingress { - apply(tab1); -} -control egress { - -} diff --git a/backends/tofino/bf-asm/test/counter5.p4 b/backends/tofino/bf-asm/test/counter5.p4 deleted file mode 100644 index 79cdda0a20d..00000000000 --- a/backends/tofino/bf-asm/test/counter5.p4 +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Simple program, just a direct mapped RAM - */ - -header_type ethernet_t { - fields { - dstAddr : 48; - } -} -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return ingress; -} -action act(idx) { - count(cntDum, idx); -} -table tab1 { - reads { - ethernet.dstAddr : exact; - } - actions { - act; - } - size: 160000; -} - -counter cntDum { - type: packets; - static: tab1; - instance_count: 70000; - min_width:64; -} -control ingress { - apply(tab1); -} -control egress { - -} diff --git a/backends/tofino/bf-asm/test/ctx_json b/backends/tofino/bf-asm/test/ctx_json deleted file mode 120000 index 12eb7e788bb..00000000000 --- a/backends/tofino/bf-asm/test/ctx_json +++ /dev/null @@ -1 +0,0 @@ -../../glass/p4c_tofino/target/tofino/ctx_json \ No newline at end of file diff --git a/backends/tofino/bf-asm/test/ctxt_json_ignore b/backends/tofino/bf-asm/test/ctxt_json_ignore deleted file mode 100644 index e5ab774017e..00000000000 --- a/backends/tofino/bf-asm/test/ctxt_json_ignore +++ /dev/null @@ -1,94 +0,0 @@ -# FIXME -- need to figure out what should be in these and implement it -EntryFormatNode -HashJsonNode -ParserInfo -ProgramInfo -ContextJsonNode[2] -ContextJsonNode[3] -ContextJsonNode[4] - -actions -action_pack_format_map -action_parameter_map -action_to_constant_mapping -action_to_immediate_mapping -action_to_next_table_mapping -action_to_perform -ap_bind_indirect_res_to_match -bound_to_stateful_table -bound_to_selection_table -color_address_extract -color_aware_per_flow_enable_address_type_bit_position -constant_name_to_value -default_address_bits_provided -default_next_table -default_next_table_modifiable -default_only_action -enable_per_flow_enable -enable_sps_scrambling -entry_list -field_list -gateway_fields -hash_algorithm -hash_distribution_usage -hash_distribution_usage_for_pre_color -hash_output_width -hash_polynomial -hash_way_number -include_idletime -indirect -lpf_or_red_field -match_entry_vpns -match_fields_type_dictionary -match_group_resource_allocation -match_key_fields -max_port_pool_size -memory_units_depth -memory_units_width -min_port_pool_size -number_entries_with_ranges -number_hash_ways -number_selection_groups -pack_format_length -p4_meter_tables -p4_parameters -p4_primitives -p4_stateful_tables -#p4_statistics_tables -pack_format_length -per_flow_enable_bit_position -port_pool_sizes -pre_color_field -ram_enable_dictionary -range_field -reference_dictionary -result_field -saturating -selection_fields -stage_action_parameter_map -stage_gateway_table -#stage_idletime_table -stage_primitives -stage_table_type_handle -stage_table_type_handle_type -stash_resource_allocation -statistics_precision -sweep_interval -table_type -ternary_mode -timeout -uses_range -vliw_resource_allocation -way_match_group_map -& 0xff000000 == 0x21000000 -override_meter_addr_pfe -override_stat_addr_pfe -override_stateful_addr_pfe -override_meter_addr -override_meter_full_addr -override_stat_addr -override_stat_full_addr -override_stateful_addr -override_stateful_full_addr -all_hash_calculations -dynamic_selection diff --git a/backends/tofino/bf-asm/test/ctxt_json_ignore_new b/backends/tofino/bf-asm/test/ctxt_json_ignore_new deleted file mode 100644 index be242af4ef3..00000000000 --- a/backends/tofino/bf-asm/test/ctxt_json_ignore_new +++ /dev/null @@ -1,9 +0,0 @@ -build_date -compiler_version -learn_quanta -parser -phv_allocation -hash_bits -hash_function_id -handle -action_handle diff --git a/backends/tofino/bf-asm/test/exact_match0.p4 b/backends/tofino/bf-asm/test/exact_match0.p4 deleted file mode 100644 index 56eb381b7b0..00000000000 --- a/backends/tofino/bf-asm/test/exact_match0.p4 +++ /dev/null @@ -1,35 +0,0 @@ -#include - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } - -table test1 { - reads { - data.f1 : exact; - } - actions { - noop; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/exact_match1.p4 b/backends/tofino/bf-asm/test/exact_match1.p4 deleted file mode 100644 index 4403dd7c715..00000000000 --- a/backends/tofino/bf-asm/test/exact_match1.p4 +++ /dev/null @@ -1,40 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setb1(val, port) { - modify_field(data.b1, val); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -table test1 { - reads { - data.f1 : exact; - } - actions { - setb1; - noop; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/exact_match1.stf b/backends/tofino/bf-asm/test/exact_match1.stf deleted file mode 100644 index 6f504e3fb28..00000000000 --- a/backends/tofino/bf-asm/test/exact_match1.stf +++ /dev/null @@ -1,11 +0,0 @@ - -add test1 0 data.f1:0x01010101 setb1(val:0x7f, port:2) -add test1 1 data.f1:0x02020202 setb1(val:7, port:3) -add test1 2 data.f1:0x03030303 setb1(val:0, port:4) - -expect 2 01010101 ******** ******** ******** 7f 66 -expect 3 02020202 ******** ******** ******** 07 66 -expect 4 03030303 ******** ******** ******** 00 66 -packet 0 01010101 00000202 00000303 00000404 55 66 77 88 -packet 1 02020202 00000303 00000404 00000404 55 66 77 88 -packet 2 03030303 00000303 00000404 00000404 55 66 77 88 diff --git a/backends/tofino/bf-asm/test/exact_match2.p4 b/backends/tofino/bf-asm/test/exact_match2.p4 deleted file mode 100644 index 4184e360847..00000000000 --- a/backends/tofino/bf-asm/test/exact_match2.p4 +++ /dev/null @@ -1,41 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setb1(val, port) { - modify_field(data.b1, val); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -table test1 { - reads { - data.f1 : exact; - } - actions { - setb1; - noop; - } - size: 10000; -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/exact_match3.p4 b/backends/tofino/bf-asm/test/exact_match3.p4 deleted file mode 100644 index 7cc330c4253..00000000000 --- a/backends/tofino/bf-asm/test/exact_match3.p4 +++ /dev/null @@ -1,41 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setb1(val, port) { - modify_field(data.b1, val); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -table test1 { - reads { - data.f1 : exact; - } - actions { - setb1; - noop; - } - size: 300000; -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/exact_match4.p4 b/backends/tofino/bf-asm/test/exact_match4.p4 deleted file mode 100644 index 85a1c3dcd1c..00000000000 --- a/backends/tofino/bf-asm/test/exact_match4.p4 +++ /dev/null @@ -1,42 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type data_t { - fields { - f1 : 128; - f2 : 128; - f3 : 128; - f4 : 128; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setb1(val, port) { - modify_field(data.b1, val); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -table test1 { - reads { - data.f1 : exact; - data.f2 : exact; - data.f3 : exact; - } - actions { - setb1; - noop; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/exact_match5.p4 b/backends/tofino/bf-asm/test/exact_match5.p4 deleted file mode 100644 index 27df288f04e..00000000000 --- a/backends/tofino/bf-asm/test/exact_match5.p4 +++ /dev/null @@ -1,43 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type data_t { - fields { - f1 : 128; - f2 : 128; - f3 : 128; - f4 : 128; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setb1(val, port) { - modify_field(data.b1, val); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -table test1 { - reads { - data.f1 : exact; - data.f2 : exact; - data.f3 : exact; - } - actions { - setb1; - noop; - } - size: 50000; -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/exact_match6.p4 b/backends/tofino/bf-asm/test/exact_match6.p4 deleted file mode 100644 index 4c1c5c53b8a..00000000000 --- a/backends/tofino/bf-asm/test/exact_match6.p4 +++ /dev/null @@ -1,43 +0,0 @@ - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -header_type meta_t { - fields { - sum : 32; - } -} -metadata meta_t meta; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action addf2() { add(meta.sum, data.f2, 100); } - -table test1 { - reads { - data.f1 : exact; - } - actions { - addf2; - noop; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/exact_match7.p4 b/backends/tofino/bf-asm/test/exact_match7.p4 deleted file mode 100644 index eacc3338259..00000000000 --- a/backends/tofino/bf-asm/test/exact_match7.p4 +++ /dev/null @@ -1,41 +0,0 @@ - -header_type data_t { - fields { - x1 : 3; - f1 : 7; - x2 : 6; - f2 : 32; - x3 : 5; - f3 : 20; - x4 : 7; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setb1(val) { modify_field(data.b1, val); } - -table test1 { - reads { - data.f1 : exact; - data.f3 : exact; - } - actions { - setb1; - noop; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/exact_match8.p4 b/backends/tofino/bf-asm/test/exact_match8.p4 deleted file mode 100644 index 12ebf762f6d..00000000000 --- a/backends/tofino/bf-asm/test/exact_match8.p4 +++ /dev/null @@ -1,54 +0,0 @@ - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setb1(val) { modify_field(data.b1, val); } -action setb2(val) { modify_field(data.b2, val); } -action setb3(val) { modify_field(data.b3, val); } -action setb4(val) { modify_field(data.b4, val); } -action setb12(v1, v2) { modify_field(data.b1, v1); modify_field(data.b2, v2); } -action setb13(v1, v2) { modify_field(data.b1, v1); modify_field(data.b3, v2); } -action setb14(v1, v2) { modify_field(data.b1, v1); modify_field(data.b4, v2); } -action setb23(v1, v2) { modify_field(data.b2, v1); modify_field(data.b3, v2); } -action setb24(v1, v2) { modify_field(data.b2, v1); modify_field(data.b4, v2); } -action setb34(v1, v2) { modify_field(data.b3, v1); modify_field(data.b4, v2); } - -table test1 { - reads { - data.f1 : exact; - } - actions { - noop; - setb1; - setb2; - setb3; - setb4; - setb12; - setb13; - setb14; - setb23; - setb24; - setb34; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/exact_match9.p4 b/backends/tofino/bf-asm/test/exact_match9.p4 deleted file mode 100644 index b03da0ae6a1..00000000000 --- a/backends/tofino/bf-asm/test/exact_match9.p4 +++ /dev/null @@ -1,44 +0,0 @@ - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setb1(val) { modify_field(data.b1, val); } -action setb2(val) { modify_field(data.b2, val); } -action setb3(val) { modify_field(data.b3, val); } -action setb4(val) { modify_field(data.b4, val); } - -table test1 { - reads { - data.f1 : exact; - } - actions { - noop; - setb1; - setb2; - setb3; - setb4; - } -} - -control ingress { - if (data.f2 != 0) { - apply(test1); - } -} diff --git a/backends/tofino/bf-asm/test/exact_match_valid1.p4 b/backends/tofino/bf-asm/test/exact_match_valid1.p4 deleted file mode 100644 index 970a24629c0..00000000000 --- a/backends/tofino/bf-asm/test/exact_match_valid1.p4 +++ /dev/null @@ -1,44 +0,0 @@ -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; -header data_t data2; - -parser start { - extract(data); - return select(data.f2) { - 0xf0000000 mask 0xf0000000 : parse_data2; - default : ingress; - } -} -parser parse_data2 { - extract(data2); - return ingress; -} - -action noop() { } -action setb1(val) { modify_field(data2.b1, val); } - -table test1 { - reads { - data : valid; - data2 : valid; - } - actions { - setb1; - noop; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/expected_failures.txt b/backends/tofino/bf-asm/test/expected_failures.txt deleted file mode 100644 index 415da9ad345..00000000000 --- a/backends/tofino/bf-asm/test/expected_failures.txt +++ /dev/null @@ -1,41 +0,0 @@ -- current compiler failures on some tests. - -parser1.p4 compile -parser2.p4 compile -parser_dc_full.p4 compile -port_vlan_mapping.p4 compile -- glass fails to unroll parser loop properly (new problem with 3.3?) - -action_chain1.p4 bfas -- asm gen fails to include 'next' field in ternary indirect - -counter4.p4 mismatch -- compiler duplicates data on ixbar and programs byteswizzle to inconsistently - pull from either copy; assembler always pulls from first. - -counter5.p4 mismatch -- synth2port fabric is different -- not clear if it is a bug or where - -hash_index5.p4 mismatch -- control of stats table is different - -exact_match3.p4 mismatch -- vpn lsb encoding swapped (not a bug -- either way is fine) -- asm chooses different home rows for action table that needs multiple - (compiler should specify in asm output) - -exact_match5.p4 mismatch -- compiler duplicates data across ixbar groups and programs vh_xbar_select to - pull from either copy; assembler always pulls from first. - -hash_index2.p4 mismatch -hash_index3.p4 mismatch -- compiler fails to produce asm code for default action - -meter_test1.p4 mismatch -- vpn lsb encoding swapped (not a bug -- either way is fine) -- synth2port fabric is different -- not clear if it is a bug or where -- idletime missing from asm? - -mac_rewrite.p4 bfas -- glass generates invalid slice of immediate for action_bus. diff --git a/backends/tofino/bf-asm/test/gateway1.p4 b/backends/tofino/bf-asm/test/gateway1.p4 deleted file mode 100644 index 3821cde68d0..00000000000 --- a/backends/tofino/bf-asm/test/gateway1.p4 +++ /dev/null @@ -1,48 +0,0 @@ -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setb1(val) { modify_field(data.b1, val); } - -table test1 { - reads { - data.f1 : exact; - } - actions { - setb1; - noop; - } -} -table test2 { - reads { - data.f2 : exact; - } - actions { - setb1; - noop; - } -} - -control ingress { - if (data.b2 == 1) { - apply(test1); - } else { - apply(test2); - } -} diff --git a/backends/tofino/bf-asm/test/gateway2.p4 b/backends/tofino/bf-asm/test/gateway2.p4 deleted file mode 100644 index 9faa6bb7be2..00000000000 --- a/backends/tofino/bf-asm/test/gateway2.p4 +++ /dev/null @@ -1,48 +0,0 @@ -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setb1(val) { modify_field(data.b1, val); } - -table test1 { - reads { - data.f1 : exact; - } - actions { - setb1; - noop; - } -} -table test2 { - reads { - data.f2 : exact; - } - actions { - setb1; - noop; - } -} - -control ingress { - if (data.b2 == data.b3 and data.b4 == 10) { - apply(test1); - } else { - apply(test2); - } -} diff --git a/backends/tofino/bf-asm/test/gateway3.p4 b/backends/tofino/bf-asm/test/gateway3.p4 deleted file mode 100644 index 7b32b429044..00000000000 --- a/backends/tofino/bf-asm/test/gateway3.p4 +++ /dev/null @@ -1,51 +0,0 @@ - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setb1(val) { modify_field(data.b1, val); } - -table test1 { - reads { - data.f1 : exact; - } - actions { - setb1; - noop; - } -} -table test2 { - reads { - data.f2 : exact; - } - actions { - setb1; - noop; - } -} - -control ingress { - if (data.b2 == data.b3 and data.b4 == 10) { - if (data.b1 == data.b2) { - apply(test1); - } - } else { if (data.b1 != data.b2) { - apply(test2); - } } -} diff --git a/backends/tofino/bf-asm/test/gateway4.p4 b/backends/tofino/bf-asm/test/gateway4.p4 deleted file mode 100644 index 4cc8c677372..00000000000 --- a/backends/tofino/bf-asm/test/gateway4.p4 +++ /dev/null @@ -1,62 +0,0 @@ - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; -header_type data2_t { - fields { - x1 : 8; - x2 : 8; - } -} -header data2_t data2; - -parser start { - extract(data); - return select(data.b1) { - 0x01 : parse_data2; - default : ingress; - } -} - -parser parse_data2 { - extract(data2); - return ingress; -} - -action noop() { } -action setb1(val) { modify_field(data.b1, val); } - -table test1 { - reads { - data.f1 : exact; - } - actions { - setb1; - noop; - } -} -table test2 { - reads { - data.f2 : exact; - } - actions { - setb1; - noop; - } -} - -control ingress { - if (valid(data2)) { - apply(test1); } - apply(test2); -} diff --git a/backends/tofino/bf-asm/test/gateway5.p4 b/backends/tofino/bf-asm/test/gateway5.p4 deleted file mode 100644 index ea40aa542c1..00000000000 --- a/backends/tofino/bf-asm/test/gateway5.p4 +++ /dev/null @@ -1,54 +0,0 @@ -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - x1 : 2; - pad0 : 3; - x2 : 2; - pad1 : 5; - x3 : 1; - pad2 : 2; - skip : 32; - x4 : 1; - x5 : 1; - pad3 : 6; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setf4(val) { modify_field(data.f4, val); } - -table test1 { - reads { - data.f1 : exact; - } - actions { - setf4; - noop; - } -} -table test2 { - reads { - data.f2 : exact; - } - actions { - setf4; - noop; - } -} - -control ingress { - if (data.x1 == 1 and data.x4 == 0) { - apply(test1); - } else { - apply(test2); - } -} diff --git a/backends/tofino/bf-asm/test/gateway6.p4 b/backends/tofino/bf-asm/test/gateway6.p4 deleted file mode 100644 index 79b0114a759..00000000000 --- a/backends/tofino/bf-asm/test/gateway6.p4 +++ /dev/null @@ -1,48 +0,0 @@ -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setb1(val) { modify_field(data.b1, val); } - -table test1 { - reads { - data.f1 : exact; - } - actions { - setb1; - noop; - } -} -table test2 { - reads { - data.f2 : exact; - } - actions { - setb1; - noop; - } -} - -control ingress { - if (1 == (15 & data.b2)) { - apply(test1); - } else { - apply(test2); - } -} diff --git a/backends/tofino/bf-asm/test/gateway7.p4 b/backends/tofino/bf-asm/test/gateway7.p4 deleted file mode 100644 index d1aec5c6802..00000000000 --- a/backends/tofino/bf-asm/test/gateway7.p4 +++ /dev/null @@ -1,48 +0,0 @@ -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setb1(val) { modify_field(data.b1, val); } - -table test1 { - reads { - data.f1 : exact; - } - actions { - setb1; - noop; - } -} -table test2 { - reads { - data.f2 : exact; - } - actions { - setb1; - noop; - } -} - -control ingress { - if (data.b2 > 50) { - apply(test1); - } else { - apply(test2); - } -} diff --git a/backends/tofino/bf-asm/test/hash_index0.p4 b/backends/tofino/bf-asm/test/hash_index0.p4 deleted file mode 100644 index a134f631824..00000000000 --- a/backends/tofino/bf-asm/test/hash_index0.p4 +++ /dev/null @@ -1,36 +0,0 @@ -#include - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action setf1(val) { modify_field(data.f1, val); } - -table test1 { - reads { - data.b1 : exact; - } - actions { - setf1; - } - size : 256; -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/hash_index1.p4 b/backends/tofino/bf-asm/test/hash_index1.p4 deleted file mode 100644 index 60b67fa6744..00000000000 --- a/backends/tofino/bf-asm/test/hash_index1.p4 +++ /dev/null @@ -1,38 +0,0 @@ -#include - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action setf1(val) { modify_field(data.f1, val); } - -table test1 { - reads { - data.b1 : exact; - } - actions { - setf1; - } - size : 256; -} - -control ingress { - if (data.b2 == 4) { - apply(test1); - } -} diff --git a/backends/tofino/bf-asm/test/hash_index2.p4 b/backends/tofino/bf-asm/test/hash_index2.p4 deleted file mode 100644 index 2fdb0d00f89..00000000000 --- a/backends/tofino/bf-asm/test/hash_index2.p4 +++ /dev/null @@ -1,51 +0,0 @@ -#include - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action setf1(val) { modify_field(data.f1, val); } -action setf2(val) { modify_field(data.f2, val); } -action setf3(val) { modify_field(data.f3, val); } - -@pragma use_hash_action 1 -table test1 { - reads { - data.b1 : exact; - } - actions { - setf1; - } - default_action : setf1(0); - size : 256; -} - -table test2 { - reads { - data.f1 : ternary; - } - actions { - setf2; - setf3; - } -} - -control ingress { - apply(test1); - apply(test2); -} diff --git a/backends/tofino/bf-asm/test/hash_index3.p4 b/backends/tofino/bf-asm/test/hash_index3.p4 deleted file mode 100644 index f506cc186af..00000000000 --- a/backends/tofino/bf-asm/test/hash_index3.p4 +++ /dev/null @@ -1,63 +0,0 @@ -#include - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action setf1(val) { modify_field(data.f1, val); } -action setf2(val) { modify_field(data.f2, val); } -action setf3(val) { modify_field(data.f3, val); } - -@pragma use_hash_action 1 -table test1 { - reads { - data.b1 : exact; - } - actions { - setf1; - } - default_action : setf1(0); - size : 256; -} - -table test2 { - reads { - data.f2 : ternary; - } - actions { - setf3; - } -} - -table test3 { - reads { - data.f4 : ternary; - } - actions { - setf3; - } -} - -control ingress { - if (data.b2 == 10) { - apply(test1); - } else { - apply(test2); - } - apply(test3); -} diff --git a/backends/tofino/bf-asm/test/hash_index5.p4 b/backends/tofino/bf-asm/test/hash_index5.p4 deleted file mode 100644 index 553b33cd737..00000000000 --- a/backends/tofino/bf-asm/test/hash_index5.p4 +++ /dev/null @@ -1,37 +0,0 @@ -#include - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action countb2(val) { count(simple, data.b2); } - -counter simple { - type : packets; - instance_count : 256; -} - -table test1 { - actions { - countb2; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/instruct1.p4 b/backends/tofino/bf-asm/test/instruct1.p4 deleted file mode 100644 index e0f12c83018..00000000000 --- a/backends/tofino/bf-asm/test/instruct1.p4 +++ /dev/null @@ -1,61 +0,0 @@ - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; -header_type data2_t { - fields { - x1 : 16; - x2 : 16; - } -} -header data2_t hdr1; -header data2_t hdr2; - -parser start { - extract(data); - return select(data.b1) { - 0x00: parse_data2; - default: ingress; - } -} -parser parse_data2 { - extract(hdr1); - return select(hdr1.x1) { - 1 mask 1: parse_hdr2; - default: ingress; - } -} -parser parse_hdr2 { - extract(hdr2); - return ingress; -} - -action noop() { } -action decap() { - copy_header(hdr1, hdr2); - remove_header(hdr2); -} - -table test1 { - reads { - data.f1 : exact; - } - actions { - decap; - noop; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/instruct2.p4 b/backends/tofino/bf-asm/test/instruct2.p4 deleted file mode 100644 index 52eed14e2db..00000000000 --- a/backends/tofino/bf-asm/test/instruct2.p4 +++ /dev/null @@ -1,39 +0,0 @@ -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action do_xor() { bit_xor(data.b1, data.b2, data.b3); } -action do_and() { bit_and(data.b2, data.b3, data.b4); } -action do_or() { bit_or(data.b4, data.b3, data.b1); } -action do_add() { add(data.b3, data.b1, data.b2); } - -table test1 { - reads { - data.f1 : exact; - } - actions { - do_add; - do_and; - do_or; - do_xor; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/instruct3.p4 b/backends/tofino/bf-asm/test/instruct3.p4 deleted file mode 100644 index e8f0396137a..00000000000 --- a/backends/tofino/bf-asm/test/instruct3.p4 +++ /dev/null @@ -1,34 +0,0 @@ - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - x1 : 2; - x2 : 2; - x3 : 2; - x4 : 2; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setx() { modify_field(data.x2, 2); modify_field(data.x4,1); } - -table test1 { - reads { - data.f1 : exact; - } - actions { - setx; - noop; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/instruct4.p4 b/backends/tofino/bf-asm/test/instruct4.p4 deleted file mode 100644 index f4babaf63d4..00000000000 --- a/backends/tofino/bf-asm/test/instruct4.p4 +++ /dev/null @@ -1,35 +0,0 @@ -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setf4() { modify_field(data.f4, 0x70a50); } - -table test1 { - reads { - data.f1 : exact; - } - actions { - setf4; - noop; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/instruct5.p4 b/backends/tofino/bf-asm/test/instruct5.p4 deleted file mode 100644 index de60a960474..00000000000 --- a/backends/tofino/bf-asm/test/instruct5.p4 +++ /dev/null @@ -1,56 +0,0 @@ - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; -header_type data2_t { - fields { - x1 : 16; - x2 : 16; - } -} -header data2_t extra[4]; - -parser start { - extract(data); - return select(data.b1) { - 0x00: parse_extra; - default: ingress; - } -} -parser parse_extra { - extract(extra[next]); - return select(latest.x1) { - 1 mask 1: parse_extra; - default: ingress; - } -} - -action noop() { } -action push1() { push(extra, 1); } -action push2() { push(extra, 2); } - - -table test1 { - reads { - data.f1 : exact; - } - actions { - noop; - push1; - push2; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/internal/brig/expected_failures.txt b/backends/tofino/bf-asm/test/internal/brig/expected_failures.txt deleted file mode 100644 index cde3422c8a6..00000000000 --- a/backends/tofino/bf-asm/test/internal/brig/expected_failures.txt +++ /dev/null @@ -1,2 +0,0 @@ -test_config_123_meter_2.p4 bfas -- missing color_maprams diff --git a/backends/tofino/bf-asm/test/internal/brig/test_config_123_meter_2.p4 b/backends/tofino/bf-asm/test/internal/brig/test_config_123_meter_2.p4 deleted file mode 100644 index 490c6f499af..00000000000 --- a/backends/tofino/bf-asm/test/internal/brig/test_config_123_meter_2.p4 +++ /dev/null @@ -1,118 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - color_0 : 8; - pad_0 : 24; - pad_1 : 160; - pad_2 : 24; - color_1 : 8; - pad_3 : 24; - - lpf : 16; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -meter meter_0 { - type : bytes; - //static : table_0; - direct : table_0; - result : pkt.color_0; // Over-loading the meaning of result to be the input and output - //instance_count : 500; - //implementation : red; -} - - -meter meter_1 { - type : bytes; - static : table_1; - //direct : table_1; - result : pkt.color_1; - instance_count : 4097; -} - - -action action_0(param0){ - //modify_field(pkt.field_f_16, param0); - //execute_meter(meter_0, 7, pkt.color_0); -} - - -action action_1(param0){ - //modify_field(pkt.field_g_16, param0); - execute_meter(meter_1, 7, pkt.color_1); -} - - -action do_nothing(){ - no_op(); -// drop(); -} - - - -//@pragma include_idletime 1 -@pragma pa_solitare meter_result.color_0, meter_result.color_1 -@pragma include_stash 1 -@pragma action_default_only do_nothing -table table_0 { - reads { - pkt.field_e_16 : ternary; - pkt.color_0 : exact; //HACK - pkt.color_1 : exact; //HACK - pkt.lpf : exact; //HACK - } - actions { - action_0; - //do_nothing; - } - size : 6000; -} - - -//@pragma include_idletime 1 -@pragma idletime_two_way_notification 1 -@pragma include_stash 1 -table table_1 { - reads { - pkt.field_e_16: exact; - } - actions { - do_nothing; - action_1; - } - size : 32768; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_1); -} diff --git a/backends/tofino/bf-asm/test/internal/brig/test_config_223_simple_set_metadata.p4 b/backends/tofino/bf-asm/test/internal/brig/test_config_223_simple_set_metadata.p4 deleted file mode 100644 index d940d02eb15..00000000000 --- a/backends/tofino/bf-asm/test/internal/brig/test_config_223_simple_set_metadata.p4 +++ /dev/null @@ -1,82 +0,0 @@ -// #include "tofino/intrinsic_metadata.p4" - -header_type zero_byte_t { - fields { - a : 8; - } -} - -header_type one_byte_t { - fields { - a : 8; - } -} - -header_type meta_t { - fields { - a : 32; - b : 8; - c : 5; - d : 3; - } -} - -header zero_byte_t zero; -header one_byte_t one; -metadata meta_t meta; - -parser start { - return zerob; -} - -parser zerob { - extract(zero); - return select(zero.a) { - 0 : oneb; - default : twob; - } -} - - -parser oneb { - extract(one); - set_metadata(meta.b, latest.a); - set_metadata(meta.a, 0x7); - set_metadata(meta.c, 1); - set_metadata(meta.d, 2); //current(8, 1)); - return ingress; -} - -parser twob { - extract(one); - set_metadata(meta.c, 2); - return ingress; -} - - -action do_nothing(){} - -action action_0(p){ - add(one.a, one.a, 1); - add(meta.a, meta.a, p); -} - - -table table_i0 { - reads { - one.a : ternary; - meta.a : exact; - meta.b : exact; - meta.c : exact; - meta.d : exact; - } - actions { - do_nothing; - action_0; - } - size : 512; -} - -control ingress { - apply(table_i0); -} diff --git a/backends/tofino/bf-asm/test/internal/debug_issue_1_invalid_action_pack_format.p4 b/backends/tofino/bf-asm/test/internal/debug_issue_1_invalid_action_pack_format.p4 deleted file mode 100644 index bb8d5c9a5a1..00000000000 --- a/backends/tofino/bf-asm/test/internal/debug_issue_1_invalid_action_pack_format.p4 +++ /dev/null @@ -1,84 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - - -action nop(){ - no_op(); -} - -action mod_mac_adr(egress_port, srcmac, dstmac) { - //modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - - -@pragma immediate 1 -table tcam_tbl_stage_2 { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - mod_mac_adr; - } -} - - -control ingress{ - apply(tcam_tbl_stage_2); -} diff --git a/backends/tofino/bf-asm/test/internal/debug_issue_2_action_data_bus.PRAGMA b/backends/tofino/bf-asm/test/internal/debug_issue_2_action_data_bus.PRAGMA deleted file mode 100644 index c31981eb8a0..00000000000 --- a/backends/tofino/bf-asm/test/internal/debug_issue_2_action_data_bus.PRAGMA +++ /dev/null @@ -1,610 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm: csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - //modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop_ipv4(egress_port /*,srcmac, dstmac*/) { - hop(ipv4.ttl, egress_port); -// modify_field(ethernet.srcAddr, srcmac); -// modify_field(ethernet.dstAddr, dstmac); -} - -action drop_ipv4 () { - drop(); -} - -action next_hop_ipv4(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - //modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action ig_drop() { -// modify_field(routing_metadata.drop, 1); - add_to_field(ipv4.ttl, -1); - //modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); -} - -action mod_mac_adr(egress_port, srcmac, dstmac) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - //modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action udp_hdr_add (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - add_header(udp); - modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); - add_to_field(ipv4.totalLen, 8); -} - -action tcp_hdr_rm (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - remove_header(tcp); - modify_field(ipv4.protocol, 0); -// add_to_field(ipv4.totalLen, -20); -// modify_field(ipv4.totalLen, 66); -} - -action modify_tcp_dst_port(dstPort) { - modify_field(tcp.dstPort, dstPort); -} - -action modify_tcp_dst_port_1(dstPort, egress_port) { - modify_field(tcp.dstPort, dstPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ipv4.srcAddr, ipAddr); - modify_field(ethernet.dstAddr, dstAddr); - modify_field(tcp.dstPort, tcpPort); -} - -action custom_action_2(egress_port, ipAddr, tcpPort) -{ - modify_field(ipv4.srcAddr, ipAddr); - modify_field(tcp.dstPort, tcpPort); - hop(ipv4.ttl, egress_port); -} - -action custom_action_3(egress_port, dstAddr, dstIp) -{ - modify_field(ipv4.dstAddr, dstIp); - modify_field(ethernet.dstAddr, dstAddr); - hop(ipv4.ttl, egress_port); -} - -action modify_l2 (egress_port, srcAddr, dstAddr) { - // Trying for 128 bit action data - hop(ipv4.ttl, egress_port); - //modify_field(ethernet.srcAddr, srcAddr); - modify_field(ethernet.dstAddr, dstAddr); -} - -action switching_action_1(egress_port/*, vlan_id */) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - //modify_field(vlan_tag.vlan_id, vlan_id); -} - -@pragma immediate 1 -table ipv4_routing { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - hop_ipv4; - drop_ipv4; - } -} - -table ipv4_routing_exm_ways_3_pack_5 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - modify_tcp_dst_port_1; - } -} - - -table ipv4_routing_exm_ways_3_pack_3 { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - custom_action_1; - } -} - -table ipv4_routing_exm_ways_4_pack_3_stage_1 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma immediate 1 -table ipv4_routing_stage_1 { - reads { - ipv4.dstAddr : lpm; - ipv4.srcAddr : exact; - } - actions { - nop; - hop_ipv4; - } - size : 1024; -} - -@pragma immediate 1 -table tcam_tbl_stage_2 { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - mod_mac_adr; - } -} - -table ipv4_routing_exm_ways_4_pack_7_stage_2 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - tcp.dstPort : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -table ipv4_routing_exm_ways_3_pack_7_stage_2 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - -table ipv4_routing_exm_ways_5_pack_3_stage_3 { - reads { - ipv4.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma immediate 1 -table udp_add_tbl_stage_3 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - udp_hdr_add; - } -} - -table ipv4_routing_exm_ways_6_pack_3_stage_4 { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - - -@pragma immediate 1 -table tcp_rm_tbl_stage_4 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - tcp_hdr_rm; - } -} - -table ipv4_routing_exm_ways_3_pack_4_stage_5 { - reads { - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - modify_tcp_dst_port_1; - } -} - -table switching_exm_ways_3_pack_6_stage_5 { - reads { - ethernet.dstAddr : exact; - vlan_tag.vlan_id : exact; - } - actions { - nop; - switching_action_1; - } -} - -table ipv4_routing_exm_ways_4_pack_4_stage_6 { - reads { - ethernet.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_exm_ways_4_pack_6_stage_6 { - reads { - ethernet.srcAddr : exact; - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_exm_ways_5_pack_4_stage_7 { - reads { - ipv4.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - -table ipv4_routing_exm_ways_5_pack_6_stage_7 { - reads { - ipv4.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -table ipv4_routing_exm_ways_4_pack_5_stage_8 { - reads { - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.srcPort : exact; - tcp.dstPort : exact; - } - actions { - nop; - custom_action_2; - } -} - - -table ipv4_routing_exm_ways_5_pack_5_stage_9 { - reads { - ipv4.dstAddr : exact; - ethernet.srcAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - - -table ipv4_routing_exm_ways_6_pack_5_stage_10 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - custom_action_2; - } -} - -table ipv4_routing_exm_ways_5_pack_7_stage_10 { - reads { - ethernet.srcAddr : exact; - ipv4.dstAddr : exact; - } - actions { - nop; - tcp_hdr_rm; - } -} - -@pragma immediate 1 -table tcam_adt_deep_stage_10 { - reads { - ethernet.srcAddr : ternary; - ethernet.dstAddr : ternary; - ipv4.srcAddr : ternary; - ipv4.dstAddr : ternary; - } - actions { - nop; - modify_l2; - } - size : 2048; -} - -table ipv4_routing_exm_stage_11 { - reads { - ethernet.srcAddr : exact; - ethernet.dstAddr : exact; - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - custom_action_2; - } -} - -table ipv4_routing_exm_ways_6_pack_6_stage_11 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - -table ipv4_routing_exm_ways_6_pack_4_stage_11 { - reads { - ipv4.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - - -/* Main control flow */ -control ingress { - /* A general principle : Always keep the exact match tables ahead of the - * ternary tables in the same stage, except first stage. Logic relating to next-table - * will cause the Tofino model not to launch a lookup on th exact match - * tables if the order is reversed. - */ - apply(ipv4_routing); -/// apply(ipv4_routing_exm_ways_3_pack_5); -/// apply(ipv4_routing_exm_ways_3_pack_3); -/// apply(ipv4_routing_exm_ways_4_pack_3_stage_1); - apply(ipv4_routing_stage_1); - apply(tcam_tbl_stage_2); -/// apply(ipv4_routing_exm_ways_4_pack_7_stage_2); -/// apply(ipv4_routing_exm_ways_3_pack_7_stage_2); -/// apply(ipv4_routing_exm_ways_5_pack_3_stage_3); - /* Gateway not yet supported */ -// if (ipv4.protocol == 0) { - apply(udp_add_tbl_stage_3); -// } - apply(ipv4_routing_exm_ways_6_pack_3_stage_4); -// if (valid(tcp)) { - apply(tcp_rm_tbl_stage_4); -// } - apply(ipv4_routing_exm_ways_3_pack_4_stage_5); - apply(switching_exm_ways_3_pack_6_stage_5); - apply(ipv4_routing_exm_ways_4_pack_4_stage_6); - apply(ipv4_routing_exm_ways_4_pack_6_stage_6); - apply(ipv4_routing_exm_ways_5_pack_4_stage_7); - apply(ipv4_routing_exm_ways_5_pack_6_stage_7); - apply(ipv4_routing_exm_ways_4_pack_5_stage_8); - apply(ipv4_routing_exm_ways_5_pack_5_stage_9); - apply(ipv4_routing_exm_ways_6_pack_5_stage_10); - apply(tcam_adt_deep_stage_10); - //apply(ipv4_routing_exm_ways_6_pack_6_stage_11); - apply(ipv4_routing_exm_ways_6_pack_4_stage_11); -} - -action eg_drop() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); - modify_field(eg_intr_md.egress_port, 0); -} - -action permit() { -} - -table egress_acl { - reads { - routing_metadata.drop: ternary; - } - actions { - permit; - eg_drop; - } -} - - -control egress { -// apply(egress_acl); -} diff --git a/backends/tofino/bf-asm/test/internal/debug_issue_3_7_way_table.p4 b/backends/tofino/bf-asm/test/internal/debug_issue_3_7_way_table.p4 deleted file mode 100644 index 4d5d569cb10..00000000000 --- a/backends/tofino/bf-asm/test/internal/debug_issue_3_7_way_table.p4 +++ /dev/null @@ -1,82 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - - -action nop(){ - no_op(); -} - -action mod_mac_adr(dstmac) { - modify_field(ethernet.dstAddr, dstmac); -} - - -@pragma ways 7 -table table_0 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - mod_mac_adr; - } -} - - -control ingress{ - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/debug_issue_4_small_exact_match_key.p4 b/backends/tofino/bf-asm/test/internal/debug_issue_4_small_exact_match_key.p4 deleted file mode 100644 index b57539b97bf..00000000000 --- a/backends/tofino/bf-asm/test/internal/debug_issue_4_small_exact_match_key.p4 +++ /dev/null @@ -1,81 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - - -action nop(){ - no_op(); -} - -action mod_mac_adr(dstmac) { - modify_field(ethernet.dstAddr, dstmac); -} - - -table table_0 { - reads { - ipv4.hdrChecksum : exact; - } - actions { - nop; - mod_mac_adr; - } -} - - -control ingress{ - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/dileep.p4 b/backends/tofino/bf-asm/test/internal/dileep.p4 deleted file mode 100644 index 5de7d6a65f8..00000000000 --- a/backends/tofino/bf-asm/test/internal/dileep.p4 +++ /dev/null @@ -1,290 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm: csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop_ipv4(egress_port /*,srcmac, dstmac*/) { - hop(ipv4.ttl, egress_port); -// modify_field(ethernet.srcAddr, srcmac); -// modify_field(ethernet.dstAddr, dstmac); -} - -action next_hop_ipv4(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action ig_drop() { -// modify_field(routing_metadata.drop, 1); - add_to_field(ipv4.ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); -} - -action mod_mac_adr(egress_port, srcmac, dstmac) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action udp_hdr_add (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - add_header(udp); - modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); - add_to_field(ipv4.totalLen, 8); -} - -action tcp_hdr_rm (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - remove_header(tcp); - modify_field(ipv4.protocol, 0); -// add_to_field(ipv4.totalLen, -20); -// modify_field(ipv4.totalLen, 66); -} - -table ipv4_routing { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - hop_ipv4; - } -} - -table ipv4_routing_exm_stage_5 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } - - size : 28672; -} - -table ipv4_routing_exm_stage_6 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } - - size : 8192; -} - -table ipv4_routing_stage_1 { - reads { - ipv4.dstAddr : lpm; - ipv4.srcAddr : exact; - } - actions { - nop; - hop_ipv4; - } - size : 1024; -} - -table tcam_tbl_stage_2 { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - mod_mac_adr; - } -} - -table udp_add_tbl_stage_3 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - udp_hdr_add; - } -} - -table tcp_rm_tbl_stage_4 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - tcp_hdr_rm; - } -} - -/* Main control flow */ -control ingress { - apply(ipv4_routing); - apply(ipv4_routing_stage_1); - apply(tcam_tbl_stage_2); - /* Gateway not yet supported */ -// if (ipv4.protocol == 0) { - apply(udp_add_tbl_stage_3); -// } -// if (valid(tcp)) { - apply(tcp_rm_tbl_stage_4); -// } - apply(ipv4_routing_exm_stage_5); - apply(ipv4_routing_exm_stage_6); -} - -action eg_drop() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); - modify_field(eg_intr_md.egress_port, 0); -} - -action permit() { -} - -table egress_acl { - reads { - routing_metadata.drop: ternary; - } - actions { - permit; - eg_drop; - } -} - -control egress { -// apply(egress_acl); -} diff --git a/backends/tofino/bf-asm/test/internal/dileep10.p4 b/backends/tofino/bf-asm/test/internal/dileep10.p4 deleted file mode 100644 index 510c7c77132..00000000000 --- a/backends/tofino/bf-asm/test/internal/dileep10.p4 +++ /dev/null @@ -1,186 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm: csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action custom_action_3(egress_port, dstAddr, dstIp) -{ - modify_field(ipv4.dstAddr, dstIp); - modify_field(ethernet.dstAddr, dstAddr); - hop(ipv4.ttl, egress_port); -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -@pragma stage 2 - -table exm_3ways_32k { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - tcp.srcPort : exact; - tcp.dstPort : exact; - } - actions { - nop; - custom_action_3; - } - - size : 32768; -} - -control ingress { - apply(exm_3ways_32k); -} diff --git a/backends/tofino/bf-asm/test/internal/dileep11.p4 b/backends/tofino/bf-asm/test/internal/dileep11.p4 deleted file mode 100644 index e5d95ade07a..00000000000 --- a/backends/tofino/bf-asm/test/internal/dileep11.p4 +++ /dev/null @@ -1,183 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm: csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action next_hop_ipv4(egress_port, srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - - -@pragma stage 6 -@pragma ways 4 -@pragma pack 4 -table ipv4_routing_exm_ways_4_pack_4_stage_6 { - reads { - ethernet.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - - -control ingress { - apply(ipv4_routing_exm_ways_4_pack_4_stage_6); -} diff --git a/backends/tofino/bf-asm/test/internal/dileep12.p4 b/backends/tofino/bf-asm/test/internal/dileep12.p4 deleted file mode 100644 index 2fa4f419c37..00000000000 --- a/backends/tofino/bf-asm/test/internal/dileep12.p4 +++ /dev/null @@ -1,449 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type ipv6_t { - fields { - version : 4; - trafficClass : 8; - flowLabel : 20; - payloadLen : 16; - nextHdr : 8; - hopLimit : 8; - srcAddr : 128; - dstAddr : 128; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - 0x86dd : parse_ipv6; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; -header ipv6_t ipv6; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -parser parse_ipv6 { - extract(ipv6); - return select(latest.nextHdr) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default : ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm : csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action egress_port(egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop_ipv4(egress_port /*,srcmac, dstmac*/) { - hop(ipv4.ttl, egress_port); -// modify_field(ethernet.srcAddr, srcmac); -// modify_field(ethernet.dstAddr, dstmac); -} - -action drop_ipv4 () { - drop(); -} - -action next_hop_ipv4(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action next_hop_ipv6(egress_port ,srcmac, dstmac) { - hop(ipv6.hopLimit, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action ig_drop() { -// modify_field(routing_metadata.drop, 1); - add_to_field(ipv4.ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); -} - -action mod_mac_addr(egress_port, srcmac, dstmac) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action udp_hdr_add (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - add_header(udp); - modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); - add_to_field(ipv4.totalLen, 8); -} - -action tcp_hdr_rm (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - remove_header(tcp); - modify_field(ipv4.protocol, 0); -// add_to_field(ipv4.totalLen, -20); -// modify_field(ipv4.totalLen, 66); -} - -action modify_tcp_dst_port(dstPort) { - modify_field(tcp.dstPort, dstPort); -} - -action modify_tcp_dst_port_1(dstPort, egress_port) { - modify_field(tcp.dstPort, dstPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ipv4.srcAddr, ipAddr); - modify_field(ethernet.dstAddr, dstAddr); - modify_field(tcp.dstPort, tcpPort); -} - -action custom_action_2(egress_port, ipAddr, tcpPort) -{ - modify_field(ipv4.srcAddr, ipAddr); - modify_field(tcp.dstPort, tcpPort); - hop(ipv4.ttl, egress_port); -} - -action custom_action_3(egress_port, dstAddr, dstIp) -{ - modify_field(ipv4.dstAddr, dstIp); - modify_field(ethernet.dstAddr, dstAddr); - hop(ipv4.ttl, egress_port); -} - -action custom_action_4(egress_port, dstPort, srcPort) -{ - modify_field(tcp.dstPort, dstPort); - modify_field(tcp.srcPort, srcPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_5(dstPort, srcPort) -{ - modify_field(tcp.dstPort, dstPort); - modify_field(tcp.srcPort, srcPort); -} - -action switching_action_1(egress_port/*, vlan_id */) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - //modify_field(vlan_tag.vlan_id, vlan_id); -} - -action nhop_set(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action nhop_set_1(port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -@pragma stage 0 -@pragma pack 5 -@pragma ways 5 - -table exm_5ways_5Entries { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_3; - } - - size : 25600; -} - -@pragma stage 1 -@pragma pack 5 -@pragma ways 6 - -table exm_6ways_5Entries { - reads { - ethernet.dstAddr : exact; - ipv4.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - next_hop_ipv4; - } - size : 30720; -} - -@pragma stage 2 -@pragma pack 6 -@pragma ways 4 - -table exm_4ways_6Entries { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - custom_action_1; - } - size : 24576; -} - -@pragma stage 3 -@pragma pack 6 -@pragma ways 5 - -table exm_5ways_6Entries { - reads { - ethernet.dstAddr : exact; - } - actions { - nop; - custom_action_2; - } - size : 30720; -} - -@pragma stage 4 -@pragma pack 6 -@pragma ways 6 - -table exm_6ways_6Entries { - reads { - ethernet.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - mod_mac_addr; - } - size : 36864; -} - -@pragma stage 5 -@pragma pack 7 -@pragma ways 3 - -table exm_3ways_7Entries { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } - size : 21504; -} - -@pragma stage 6 -@pragma pack 8 -@pragma ways 4 - -table exm_4ways_8Entries { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - modify_tcp_dst_port_1; - } - size : 32768; -} - - -/* Main control flow */ -control ingress { - /* A general principle : Always keep the exact match tables ahead of the - * ternary tables in the same stage, except first stage. Logic relating to next-table - * will cause the Tofino model not to launch a lookup on th exact match - * tables if the order is reversed. - */ - - apply(exm_5ways_5Entries); - apply(exm_6ways_5Entries); - apply(exm_4ways_6Entries); - - apply(exm_5ways_6Entries); - - apply(exm_6ways_6Entries); - apply(exm_3ways_7Entries); - apply(exm_4ways_8Entries); - -} - -action eg_drop() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); - modify_field(eg_intr_md.egress_port, 0); -} - -action permit() { -} - -table egress_acl { - reads { - routing_metadata.drop: ternary; - } - actions { - permit; - eg_drop; - } -} - -control egress { -// apply(egress_acl); -} diff --git a/backends/tofino/bf-asm/test/internal/dileep2.p4 b/backends/tofino/bf-asm/test/internal/dileep2.p4 deleted file mode 100644 index 023d5d975d5..00000000000 --- a/backends/tofino/bf-asm/test/internal/dileep2.p4 +++ /dev/null @@ -1,329 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm: csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop_ipv4(egress_port /*,srcmac, dstmac*/) { - hop(ipv4.ttl, egress_port); -// modify_field(ethernet.srcAddr, srcmac); -// modify_field(ethernet.dstAddr, dstmac); -} - -action next_hop_ipv4(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action ig_drop() { -// modify_field(routing_metadata.drop, 1); - add_to_field(ipv4.ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); -} - -action mod_mac_adr(egress_port, srcmac, dstmac) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action udp_hdr_add (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - add_header(udp); - modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); - add_to_field(ipv4.totalLen, 8); -} - -action tcp_hdr_rm (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - remove_header(tcp); - modify_field(ipv4.protocol, 0); -// add_to_field(ipv4.totalLen, -20); -// modify_field(ipv4.totalLen, 66); -} - -table ipv4_routing { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - hop_ipv4; - } -} - -table ipv4_routing_exm_ways_3_pack_3 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_exm_ways_4_pack_3_stage_1 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_stage_1 { - reads { - ipv4.dstAddr : lpm; - ipv4.srcAddr : exact; - } - actions { - nop; - hop_ipv4; - } - size : 1024; -} - -table tcam_tbl_stage_2 { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - mod_mac_adr; - } -} - -table ipv4_routing_exm_ways_4_pack_7_stage_2 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_exm_ways_5_pack_3_stage_3 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table udp_add_tbl_stage_3 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - udp_hdr_add; - } -} - -table ipv4_routing_exm_ways_6_pack_3_stage_4 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table tcp_rm_tbl_stage_4 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - tcp_hdr_rm; - } -} - -table ipv4_routing_exm_ways_3_pack_4_stage_5 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -/* Main control flow */ -control ingress { - apply(ipv4_routing); - apply(ipv4_routing_exm_ways_3_pack_3); - apply(ipv4_routing_exm_ways_4_pack_3_stage_1); - apply(ipv4_routing_stage_1); - apply(tcam_tbl_stage_2); - apply(ipv4_routing_exm_ways_4_pack_7_stage_2); - apply(ipv4_routing_exm_ways_5_pack_3_stage_3); - /* Gateway not yet supported */ -// if (ipv4.protocol == 0) { - apply(udp_add_tbl_stage_3); -// } -// if (valid(tcp)) { - apply(tcp_rm_tbl_stage_4); -// } - apply(ipv4_routing_exm_ways_6_pack_3_stage_4); - apply(ipv4_routing_exm_ways_3_pack_4_stage_5); -} - -action eg_drop() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); - modify_field(eg_intr_md.egress_port, 0); -} - -action permit() { -} - -table egress_acl { - reads { - routing_metadata.drop: ternary; - } - actions { - permit; - eg_drop; - } -} - -control egress { -// apply(egress_acl); -} diff --git a/backends/tofino/bf-asm/test/internal/dileep3.p4 b/backends/tofino/bf-asm/test/internal/dileep3.p4 deleted file mode 100644 index 019e78359f9..00000000000 --- a/backends/tofino/bf-asm/test/internal/dileep3.p4 +++ /dev/null @@ -1,358 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm: csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop_ipv4(egress_port /*,srcmac, dstmac*/) { - hop(ipv4.ttl, egress_port); -// modify_field(ethernet.srcAddr, srcmac); -// modify_field(ethernet.dstAddr, dstmac); -} - -action next_hop_ipv4(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action ig_drop() { -// modify_field(routing_metadata.drop, 1); - add_to_field(ipv4.ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); -} - -action mod_mac_adr(egress_port, srcmac, dstmac) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action udp_hdr_add (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - add_header(udp); - modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); - add_to_field(ipv4.totalLen, 8); -} - -action tcp_hdr_rm (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - remove_header(tcp); - modify_field(ipv4.protocol, 0); -// add_to_field(ipv4.totalLen, -20); -// modify_field(ipv4.totalLen, 66); -} - -action modify_tcp_dst_port(dstPort) { - modify_field(tcp.dstPort, dstPort); -} - -table ipv4_routing { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - hop_ipv4; - } -} - -table ipv4_routing_exm_ways_3_pack_5 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - hop_ipv4; - } -} - -table ipv4_routing_exm_ways_3_pack_3 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_exm_ways_4_pack_3_stage_1 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_stage_1 { - reads { - ipv4.dstAddr : lpm; - ipv4.srcAddr : exact; - } - actions { - nop; - hop_ipv4; - } - size : 1024; -} - -table tcam_tbl_stage_2 { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - mod_mac_adr; - } -} - -table ipv4_routing_exm_ways_4_pack_7_stage_2 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_exm_ways_5_pack_3_stage_3 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table udp_add_tbl_stage_3 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - udp_hdr_add; - } -} - -table ipv4_routing_exm_ways_6_pack_3_stage_4 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table tcp_rm_tbl_stage_4 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - tcp_hdr_rm; - } -} - -table ipv4_routing_exm_ways_3_pack_4_stage_5 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_exm_ways_4_pack_4_stage_6 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_exm_ways_5_pack_4_stage_7 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_exm_ways_6_pack_4_stage_8 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -/* Main control flow */ -control ingress { - apply(ipv4_routing_exm_ways_3_pack_5); -} - -action eg_drop() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); - modify_field(eg_intr_md.egress_port, 0); -} - -action permit() { -} - -table egress_acl { - reads { - routing_metadata.drop: ternary; - } - actions { - permit; - eg_drop; - } -} - -control egress { -// apply(egress_acl); -} diff --git a/backends/tofino/bf-asm/test/internal/dileep4.p4 b/backends/tofino/bf-asm/test/internal/dileep4.p4 deleted file mode 100644 index e581e0a79dc..00000000000 --- a/backends/tofino/bf-asm/test/internal/dileep4.p4 +++ /dev/null @@ -1,412 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm: csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop_ipv4(egress_port /*,srcmac, dstmac*/) { - hop(ipv4.ttl, egress_port); -// modify_field(ethernet.srcAddr, srcmac); -// modify_field(ethernet.dstAddr, dstmac); -} - -action drop_ipv4 () { - drop(); -} - -action next_hop_ipv4(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action ig_drop() { -// modify_field(routing_metadata.drop, 1); - add_to_field(ipv4.ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); -} - -action mod_mac_adr(egress_port, srcmac, dstmac) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action udp_hdr_add (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - add_header(udp); - modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); - add_to_field(ipv4.totalLen, 8); -} - -action tcp_hdr_rm (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - remove_header(tcp); - modify_field(ipv4.protocol, 0); -// add_to_field(ipv4.totalLen, -20); -// modify_field(ipv4.totalLen, 66); -} - -action modify_tcp_dst_port(dstPort) { - modify_field(tcp.dstPort, dstPort); -} - -action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ipv4.srcAddr, ipAddr); - modify_field(ethernet.dstAddr, dstAddr); - modify_field(tcp.dstPort, tcpPort); -} - -action custom_action_2(egress_port, ipAddr, tcpPort) -{ - modify_field(ipv4.srcAddr, ipAddr); - modify_field(tcp.dstPort, tcpPort); - hop(ipv4.ttl, egress_port); -} - -table ipv4_routing { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - hop_ipv4; - drop_ipv4; - } -} - -table ipv4_routing_exm_ways_3_pack_5 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - modify_tcp_dst_port; - } -} - -table ipv4_routing_exm_ways_3_pack_3 { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - custom_action_1; - } -} - -table ipv4_routing_exm_ways_4_pack_3_stage_1 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_stage_1 { - reads { - ipv4.dstAddr : lpm; - ipv4.srcAddr : exact; - } - actions { - nop; - hop_ipv4; - } - size : 1024; -} - -table tcam_tbl_stage_2 { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - mod_mac_adr; - } -} - -table ipv4_routing_exm_ways_4_pack_7_stage_2 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - tcp.dstPort : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -table ipv4_routing_exm_ways_5_pack_3_stage_3 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table udp_add_tbl_stage_3 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - udp_hdr_add; - } -} - -table ipv4_routing_exm_ways_6_pack_3_stage_4 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table tcp_rm_tbl_stage_4 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - tcp_hdr_rm; - } -} - -table ipv4_routing_exm_ways_3_pack_4_stage_5 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_exm_ways_4_pack_4_stage_6 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_exm_ways_5_pack_4_stage_7 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_exm_ways_6_pack_4_stage_8 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -/* Main control flow */ -control ingress { - /* A general principle : Always keep the exact match tables ahead of the - * ternary tables in the same stage, except first stage. Logic relating to next-table - * will cause the Tofino model not to launch a lookup on th exact match - * tables if the order is reversed. - */ - apply(ipv4_routing); - apply(ipv4_routing_exm_ways_3_pack_5); - apply(ipv4_routing_exm_ways_3_pack_3); - apply(ipv4_routing_exm_ways_4_pack_3_stage_1); - apply(ipv4_routing_stage_1); - apply(tcam_tbl_stage_2); - apply(ipv4_routing_exm_ways_4_pack_7_stage_2); - apply(ipv4_routing_exm_ways_5_pack_3_stage_3); - /* Gateway not yet supported */ -// if (ipv4.protocol == 0) { - apply(udp_add_tbl_stage_3); -// } - apply(ipv4_routing_exm_ways_6_pack_3_stage_4); -// if (valid(tcp)) { - apply(tcp_rm_tbl_stage_4); -// } - /* Commenting this out, because of a compiler issue */ - //apply(ipv4_routing_exm_ways_3_pack_4_stage_5); - /* Commenting this out, because of a compiler issue */ - //apply(ipv4_routing_exm_ways_4_pack_4_stage_6); - /* Commenting this out, because of a compiler issue */ - //apply(ipv4_routing_exm_ways_5_pack_4_stage_7); - /* Commenting this out, because of a compiler issue */ - //apply(ipv4_routing_exm_ways_6_pack_4_stage_8); -} - -action eg_drop() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); - modify_field(eg_intr_md.egress_port, 0); -} - -action permit() { -} - -table egress_acl { - reads { - routing_metadata.drop: ternary; - } - actions { - permit; - eg_drop; - } -} - -control egress { -// apply(egress_acl); -} diff --git a/backends/tofino/bf-asm/test/internal/dileep5.PRAGMA b/backends/tofino/bf-asm/test/internal/dileep5.PRAGMA deleted file mode 100644 index ef5eeb8311f..00000000000 --- a/backends/tofino/bf-asm/test/internal/dileep5.PRAGMA +++ /dev/null @@ -1,487 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - vlan_id : 12; - pri : 3; - cfi : 1; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm: csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop_ipv4(egress_port /*,srcmac, dstmac*/) { - hop(ipv4.ttl, egress_port); -// modify_field(ethernet.srcAddr, srcmac); -// modify_field(ethernet.dstAddr, dstmac); -} - -action drop_ipv4 () { - drop(); -} - -action next_hop_ipv4(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action ig_drop() { -// modify_field(routing_metadata.drop, 1); - add_to_field(ipv4.ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); -} - -action mod_mac_adr(egress_port, srcmac, dstmac) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action udp_hdr_add (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - add_header(udp); - modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); - add_to_field(ipv4.totalLen, 8); -} - -action tcp_hdr_rm (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - remove_header(tcp); - modify_field(ipv4.protocol, 0); -// add_to_field(ipv4.totalLen, -20); -// modify_field(ipv4.totalLen, 66); -} - -action modify_tcp_dst_port(dstPort) { - modify_field(tcp.dstPort, dstPort); -} - -action modify_tcp_dst_port_1(dstPort, egress_port) { - modify_field(tcp.dstPort, dstPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ipv4.srcAddr, ipAddr); - modify_field(ethernet.dstAddr, dstAddr); - modify_field(tcp.dstPort, tcpPort); -} - -action custom_action_2(egress_port, ipAddr, tcpPort) -{ - modify_field(ipv4.srcAddr, ipAddr); - modify_field(tcp.dstPort, tcpPort); - hop(ipv4.ttl, egress_port); -} - -action custom_action_3(egress_port, dstAddr, dstIp) -{ - modify_field(ipv4.dstAddr, dstIp); - modify_field(ethernet.dstAddr, dstAddr); - hop(ipv4.ttl, egress_port); -} - -table ipv4_routing { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - hop_ipv4; - drop_ipv4; - } -} - -table ipv4_routing_exm_ways_3_pack_5 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - modify_tcp_dst_port_1; - } -} - - -table ipv4_routing_exm_ways_3_pack_3 { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - custom_action_1; - } -} - -table ipv4_routing_exm_ways_4_pack_3_stage_1 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_stage_1 { - reads { - ipv4.dstAddr : lpm; - ipv4.srcAddr : exact; - } - actions { - nop; - hop_ipv4; - } - size : 1024; -} - -table tcam_tbl_stage_2 { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - mod_mac_adr; - } -} - -table ipv4_routing_exm_ways_4_pack_7_stage_2 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - tcp.dstPort : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -table ipv4_routing_exm_ways_5_pack_3_stage_3 { - reads { - ipv4.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table udp_add_tbl_stage_3 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - udp_hdr_add; - } -} - -table ipv4_routing_exm_ways_6_pack_3_stage_4 { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table tcp_rm_tbl_stage_4 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - tcp_hdr_rm; - } -} - -table ipv4_routing_exm_ways_3_pack_4_stage_5 { - reads { - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - modify_tcp_dst_port_1; - } -} - -table ipv4_routing_exm_ways_4_pack_4_stage_6 { - reads { - ethernet.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_exm_ways_5_pack_4_stage_7 { - reads { - ipv4.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - -table ipv4_routing_exm_ways_4_pack_5_stage_8 { - reads { - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.srcPort : exact; - tcp.dstPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -table ipv4_routing_exm_ways_5_pack_5_stage_9 { - reads { - ipv4.dstAddr : exact; - ethernet.srcAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_exm_ways_6_pack_4_stage_9 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_exm_ways_6_pack_5_stage_10 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - custom_action_2; - } -} - -/* Main control flow */ -control ingress { - /* A general principle : Always keep the exact match tables ahead of the - * ternary tables in the same stage, except first stage. Logic relating to next-table - * will cause the Tofino model not to launch a lookup on th exact match - * tables if the order is reversed. - */ - apply(ipv4_routing); - apply(ipv4_routing_exm_ways_3_pack_5); - apply(ipv4_routing_exm_ways_3_pack_3); - apply(ipv4_routing_exm_ways_4_pack_3_stage_1); - apply(ipv4_routing_stage_1); - apply(tcam_tbl_stage_2); - apply(ipv4_routing_exm_ways_4_pack_7_stage_2); - apply(ipv4_routing_exm_ways_5_pack_3_stage_3); - /* Gateway not yet supported */ -// if (ipv4.protocol == 0) { - apply(udp_add_tbl_stage_3); -// } - apply(ipv4_routing_exm_ways_6_pack_3_stage_4); -// if (valid(tcp)) { - apply(tcp_rm_tbl_stage_4); -// } - apply(ipv4_routing_exm_ways_3_pack_4_stage_5); - apply(ipv4_routing_exm_ways_4_pack_4_stage_6); - apply(ipv4_routing_exm_ways_5_pack_4_stage_7); - apply(ipv4_routing_exm_ways_4_pack_5_stage_8); - apply(ipv4_routing_exm_ways_5_pack_5_stage_9); - apply(ipv4_routing_exm_ways_6_pack_5_stage_10); - //apply(ipv4_routing_exm_ways_6_pack_4_stage_9); -} - -action eg_drop() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); - modify_field(eg_intr_md.egress_port, 0); -} - -action permit() { -} - -table egress_acl { - reads { - routing_metadata.drop: ternary; - } - actions { - permit; - eg_drop; - } -} - -control egress { -// apply(egress_acl); -} diff --git a/backends/tofino/bf-asm/test/internal/dileep6.PHV_BUG b/backends/tofino/bf-asm/test/internal/dileep6.PHV_BUG deleted file mode 100644 index 7aa6836be1c..00000000000 --- a/backends/tofino/bf-asm/test/internal/dileep6.PHV_BUG +++ /dev/null @@ -1,592 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm: csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop_ipv4(egress_port /*,srcmac, dstmac*/) { - hop(ipv4.ttl, egress_port); -// modify_field(ethernet.srcAddr, srcmac); -// modify_field(ethernet.dstAddr, dstmac); -} - -action drop_ipv4 () { - drop(); -} - -action next_hop_ipv4(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action ig_drop() { -// modify_field(routing_metadata.drop, 1); - add_to_field(ipv4.ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); -} - -action mod_mac_adr(egress_port, srcmac, dstmac) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action udp_hdr_add (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - add_header(udp); - modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); - add_to_field(ipv4.totalLen, 8); -} - -action tcp_hdr_rm (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - remove_header(tcp); - modify_field(ipv4.protocol, 0); -// add_to_field(ipv4.totalLen, -20); -// modify_field(ipv4.totalLen, 66); -} - -action modify_tcp_dst_port(dstPort) { - modify_field(tcp.dstPort, dstPort); -} - -action modify_tcp_dst_port_1(dstPort, egress_port) { - modify_field(tcp.dstPort, dstPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ipv4.srcAddr, ipAddr); - modify_field(ethernet.dstAddr, dstAddr); - modify_field(tcp.dstPort, tcpPort); -} - -action custom_action_2(egress_port, ipAddr, tcpPort) -{ - modify_field(ipv4.srcAddr, ipAddr); - modify_field(tcp.dstPort, tcpPort); - hop(ipv4.ttl, egress_port); -} - -action custom_action_3(egress_port, dstAddr, dstIp) -{ - modify_field(ipv4.dstAddr, dstIp); - modify_field(ethernet.dstAddr, dstAddr); - hop(ipv4.ttl, egress_port); -} - -action switching_action_1(egress_port/*, vlan_id */) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - //modify_field(vlan_tag.vlan_id, vlan_id); -} - -table ipv4_routing { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - hop_ipv4; - drop_ipv4; - } -} - -table ipv4_routing_exm_ways_3_pack_5 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - modify_tcp_dst_port_1; - } -} - - -table ipv4_routing_exm_ways_3_pack_3 { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - custom_action_1; - } -} - -table ipv4_routing_exm_ways_4_pack_3_stage_1 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_stage_1 { - reads { - ipv4.dstAddr : lpm; - ipv4.srcAddr : exact; - } - actions { - nop; - hop_ipv4; - } - size : 1024; -} - -table tcam_tbl_stage_2 { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - mod_mac_adr; - } -} - -table ipv4_routing_exm_ways_4_pack_7_stage_2 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - tcp.dstPort : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -table ipv4_routing_exm_ways_3_pack_7_stage_2 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - -table ipv4_routing_exm_ways_5_pack_3_stage_3 { - reads { - ipv4.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table udp_add_tbl_stage_3 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - udp_hdr_add; - } -} - -table ipv4_routing_exm_ways_6_pack_3_stage_4 { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - - -table tcp_rm_tbl_stage_4 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - tcp_hdr_rm; - } -} - -table ipv4_routing_exm_ways_3_pack_4_stage_5 { - reads { - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - modify_tcp_dst_port_1; - } -} - -table switching_exm_ways_3_pack_6_stage_5 { - reads { - ethernet.dstAddr : exact; - vlan_tag.vlan_id : exact; - } - actions { - nop; - switching_action_1; - } -} - -table ipv4_routing_exm_ways_4_pack_4_stage_6 { - reads { - ethernet.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_exm_ways_4_pack_6_stage_6 { - reads { - ethernet.srcAddr : exact; - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_exm_ways_5_pack_4_stage_7 { - reads { - ipv4.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - -table ipv4_routing_exm_ways_5_pack_6_stage_7 { - reads { - ipv4.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -table ipv4_routing_exm_ways_4_pack_5_stage_8 { - reads { - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.srcPort : exact; - tcp.dstPort : exact; - } - actions { - nop; - custom_action_2; - } -} - - -table ipv4_routing_exm_ways_5_pack_5_stage_9 { - reads { - ipv4.dstAddr : exact; - ethernet.srcAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_exm_ways_6_pack_4_stage_9 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -table ipv4_routing_exm_ways_6_pack_5_stage_10 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - custom_action_2; - } -} - -table ipv4_routing_exm_ways_5_pack_7_stage_10 { - reads { - ethernet.srcAddr : exact; - ipv4.dstAddr : exact; - } - actions { - nop; - tcp_hdr_rm; - } -} - -table ipv4_routing_exm_stage_11 { - reads { - ethernet.srcAddr : exact; - ethernet.dstAddr : exact; - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - custom_action_2; - } -} - -table ipv4_routing_exm_ways_6_pack_6_stage_11 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - - -/* Main control flow */ -control ingress { - /* A general principle : Always keep the exact match tables ahead of the - * ternary tables in the same stage, except first stage. Logic relating to next-table - * will cause the Tofino model not to launch a lookup on th exact match - * tables if the order is reversed. - */ - apply(ipv4_routing); - apply(ipv4_routing_exm_ways_3_pack_5); - apply(ipv4_routing_exm_ways_3_pack_3); - apply(ipv4_routing_exm_ways_4_pack_3_stage_1); - apply(ipv4_routing_stage_1); - apply(tcam_tbl_stage_2); - apply(ipv4_routing_exm_ways_4_pack_7_stage_2); - apply(ipv4_routing_exm_ways_3_pack_7_stage_2); - apply(ipv4_routing_exm_ways_5_pack_3_stage_3); - /* Gateway not yet supported */ -// if (ipv4.protocol == 0) { - apply(udp_add_tbl_stage_3); -// } - apply(ipv4_routing_exm_ways_6_pack_3_stage_4); -// if (valid(tcp)) { - apply(tcp_rm_tbl_stage_4); -// } - apply(ipv4_routing_exm_ways_3_pack_4_stage_5); - apply(switching_exm_ways_3_pack_6_stage_5); - apply(ipv4_routing_exm_ways_4_pack_4_stage_6); - apply(ipv4_routing_exm_ways_4_pack_6_stage_6); - apply(ipv4_routing_exm_ways_5_pack_4_stage_7); - apply(ipv4_routing_exm_ways_5_pack_6_stage_7); - apply(ipv4_routing_exm_ways_4_pack_5_stage_8); - apply(ipv4_routing_exm_ways_5_pack_5_stage_9); - apply(ipv4_routing_exm_ways_6_pack_5_stage_10); - //apply(ipv4_routing_exm_ways_6_pack_6_stage_11); - //apply(ipv4_routing_exm_stage_11); - //apply(ipv4_routing_exm_ways_6_pack_4_stage_9); -} - -action eg_drop() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); - modify_field(eg_intr_md.egress_port, 0); -} - -action permit() { -} - -table egress_acl { - reads { - routing_metadata.drop: ternary; - } - actions { - permit; - eg_drop; - } -} - -table exm_5ways_7Entries { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - -control egress { -// apply(egress_acl); - apply(exm_5ways_7Entries); -} diff --git a/backends/tofino/bf-asm/test/internal/dileep7-b.p4 b/backends/tofino/bf-asm/test/internal/dileep7-b.p4 deleted file mode 100644 index 13985acb68b..00000000000 --- a/backends/tofino/bf-asm/test/internal/dileep7-b.p4 +++ /dev/null @@ -1,577 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm: csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop_ipv4(egress_port /*,srcmac, dstmac*/) { - hop(ipv4.ttl, egress_port); -// modify_field(ethernet.srcAddr, srcmac); -// modify_field(ethernet.dstAddr, dstmac); -} - -action drop_ipv4 () { - drop(); -} - -action next_hop_ipv4(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action ig_drop() { -// modify_field(routing_metadata.drop, 1); - add_to_field(ipv4.ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); -} - -action mod_mac_addr(egress_port, srcmac, dstmac) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action udp_hdr_add (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - add_header(udp); - modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); - add_to_field(ipv4.totalLen, 8); -} - -action tcp_hdr_rm (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - remove_header(tcp); - modify_field(ipv4.protocol, 0); -// add_to_field(ipv4.totalLen, -20); -// modify_field(ipv4.totalLen, 66); -} - -action modify_tcp_dst_port(dstPort) { - modify_field(tcp.dstPort, dstPort); -} - -action modify_tcp_dst_port_1(dstPort, egress_port) { - modify_field(tcp.dstPort, dstPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ipv4.srcAddr, ipAddr); - modify_field(ethernet.dstAddr, dstAddr); - modify_field(tcp.dstPort, tcpPort); -} - -action custom_action_2(egress_port, ipAddr, tcpPort) -{ - modify_field(ipv4.srcAddr, ipAddr); - modify_field(tcp.dstPort, tcpPort); - hop(ipv4.ttl, egress_port); -} - -action custom_action_3(egress_port, dstAddr, dstIp) -{ - modify_field(ipv4.dstAddr, dstIp); - modify_field(ethernet.dstAddr, dstAddr); - hop(ipv4.ttl, egress_port); -} - -action switching_action_1(egress_port/*, vlan_id */) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - //modify_field(vlan_tag.vlan_id, vlan_id); -} - -@pragma stage 0 -@pragma pack 7 -@pragma ways 5 - -table exm_5ways_7Entries { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - -@pragma pack 8 -@pragma ways 4 - -table exm_4ways_8Entries { - reads { - ipv4.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_3; - } -} - -@pragma ways 5 -@pragma pack 8 - -table exm_5ways_8Entries { - reads { - tcp.dstPort : exact; - } - actions { - nop; - tcp_hdr_rm; - } -} - -@pragma ways 3 -@pragma pack 1 - -table exm_3ways_1Entries { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma ways 4 -@pragma pack 1 - -table exm_4ways_1Entries { - reads { - ipv4.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - custom_action_2; - } -} - - -@pragma ways 6 -@pragma pack 7 - -table exm_6ways_7Entries_stage_1 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma ways 3 -@pragma pack 8 - -table exm_3ways_8Entries_stage_1 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - custom_action_2; - } -} - - - -@pragma ways 6 -@pragma pack 8 - -table exm_6ways_8Entries_stage_2 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - mod_mac_addr; - } -} - -@pragma pack 4 -@pragma ways 2 - -table exm_2ways_4Entries_stage_2 { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 5 -@pragma ways 2 - -table exm_2ways_5Entries_stage_2 { - reads { - tcp.srcPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -@pragma pack 6 -@pragma ways 2 - -table exm_2ways_6Entries_stage_2 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - -@pragma pack 1 -@pragma ways 5 - -table exm_5ways_1Entries_stage_2 { - reads { - ethernet.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_3; - } -} - -@pragma pack 1 -@pragma ways 6 - -table exm_6ways_1Entries_stage_2 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - tcp.dstPort : exact; - tcp.srcPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 7 -@pragma ways 2 - -table exm_2ways_7Entries_stage_3 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 8 -@pragma ways 2 - -table exm_2ways_8Entries_stage_3 { - reads { - tcp.dstPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 1 -@pragma ways 6 - -table exm_6ways_1Entries_stage_3 { - reads { - ethernet.dstAddr : exact; - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 2 -@pragma ways 3 - -table exm_3ways_2Entries_stage_3 { - reads { - ipv4.srcAddr : exact; - ipv4.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 2 -@pragma ways 4 - -table exm_4ways_2Entries_stage_4 { - reads { - ipv4.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 2 -@pragma ways 5 - -table exm_5ways_2Entries_stage_4 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - custom_action_3; - } -} - -@pragma pack 2 -@pragma ways 6 - -table exm_6ways_2Entries_stage_4 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - custom_action_2; - } -} - - -/* Main control flow */ -control ingress { - /* A general principle : Always keep the exact match tables ahead of the - * ternary tables in the same stage, except first stage. Logic relating to next-table - * will cause the Tofino model not to launch a lookup on th exact match - * tables if the order is reversed. - */ -/* - apply(exm_5ways_7Entries); - //apply(exm_4ways_8Entries); - apply(exm_5ways_8Entries); - apply(exm_3ways_1Entries); - apply(exm_4ways_1Entries); - apply(exm_6ways_7Entries_stage_1); - apply(exm_3ways_8Entries_stage_1); - apply(exm_6ways_8Entries_stage_2); - apply(exm_2ways_4Entries_stage_2); - apply(exm_2ways_5Entries_stage_2); - apply(exm_2ways_6Entries_stage_2); -*/ - apply(exm_5ways_1Entries_stage_2); -/* - apply(exm_2ways_7Entries_stage_3); - //apply(exm_2ways_8Entries_stage_3); - apply(exm_6ways_1Entries_stage_3); - apply(exm_3ways_2Entries_stage_3); - apply(exm_4ways_2Entries_stage_4); - apply(exm_5ways_2Entries_stage_4); - apply(exm_6ways_2Entries_stage_4); -*/ -} - -action eg_drop() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); - modify_field(eg_intr_md.egress_port, 0); -} - -action permit() { -} - -table egress_acl { - reads { - routing_metadata.drop: ternary; - } - actions { - permit; - eg_drop; - } -} - -control egress { -// apply(egress_acl); -} diff --git a/backends/tofino/bf-asm/test/internal/dileep7.PRAGMA b/backends/tofino/bf-asm/test/internal/dileep7.PRAGMA deleted file mode 100644 index d82e658d9fe..00000000000 --- a/backends/tofino/bf-asm/test/internal/dileep7.PRAGMA +++ /dev/null @@ -1,573 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm: csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop_ipv4(egress_port /*,srcmac, dstmac*/) { - hop(ipv4.ttl, egress_port); -// modify_field(ethernet.srcAddr, srcmac); -// modify_field(ethernet.dstAddr, dstmac); -} - -action drop_ipv4 () { - drop(); -} - -action next_hop_ipv4(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action ig_drop() { -// modify_field(routing_metadata.drop, 1); - add_to_field(ipv4.ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); -} - -action mod_mac_addr(egress_port, srcmac, dstmac) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action udp_hdr_add (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - add_header(udp); - modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); - add_to_field(ipv4.totalLen, 8); -} - -action tcp_hdr_rm (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - remove_header(tcp); - modify_field(ipv4.protocol, 0); -// add_to_field(ipv4.totalLen, -20); -// modify_field(ipv4.totalLen, 66); -} - -action modify_tcp_dst_port(dstPort) { - modify_field(tcp.dstPort, dstPort); -} - -action modify_tcp_dst_port_1(dstPort, egress_port) { - modify_field(tcp.dstPort, dstPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ipv4.srcAddr, ipAddr); - modify_field(ethernet.dstAddr, dstAddr); - modify_field(tcp.dstPort, tcpPort); -} - -action custom_action_2(egress_port, ipAddr, tcpPort) -{ - modify_field(ipv4.srcAddr, ipAddr); - modify_field(tcp.dstPort, tcpPort); - hop(ipv4.ttl, egress_port); -} - -action custom_action_3(egress_port, dstAddr, dstIp) -{ - modify_field(ipv4.dstAddr, dstIp); - modify_field(ethernet.dstAddr, dstAddr); - hop(ipv4.ttl, egress_port); -} - -action switching_action_1(egress_port/*, vlan_id */) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - //modify_field(vlan_tag.vlan_id, vlan_id); -} - -@pragma stage 0 -@pragma pack 7 -@pragma ways 5 - -table exm_5ways_7Entries { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - -@pragma pack 8 -@pragma ways 4 - -table exm_4ways_8Entries { - reads { - ipv4.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_3; - } -} - -@pragma ways 5 -@pragma pack 8 - -table exm_5ways_8Entries { - reads { - tcp.dstPort : exact; - } - actions { - nop; - tcp_hdr_rm; - } -} - -@pragma ways 3 -@pragma pack 1 - -table exm_3ways_1Entries { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma ways 4 -@pragma pack 1 - -table exm_4ways_1Entries { - reads { - ipv4.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - custom_action_2; - } -} - - -@pragma ways 6 -@pragma pack 7 - -table exm_6ways_7Entries_stage_1 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma ways 3 -@pragma pack 8 - -table exm_3ways_8Entries_stage_1 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - custom_action_2; - } -} - - - -@pragma ways 6 -@pragma pack 8 - -table exm_6ways_8Entries_stage_2 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - mod_mac_addr; - } -} - -@pragma pack 4 -@pragma ways 2 - -table exm_2ways_4Entries_stage_2 { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 5 -@pragma ways 2 - -table exm_2ways_5Entries_stage_2 { - reads { - tcp.srcPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -@pragma pack 6 -@pragma ways 2 - -table exm_2ways_6Entries_stage_2 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - -@pragma pack 1 -@pragma ways 5 - -table exm_5ways_1Entries_stage_2 { - reads { - ethernet.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_3; - } -} - -@pragma pack 1 -@pragma ways 6 - -table exm_6ways_1Entries_stage_2 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - tcp.dstPort : exact; - tcp.srcPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 7 -@pragma ways 2 - -table exm_2ways_7Entries_stage_3 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 8 -@pragma ways 2 - -table exm_2ways_8Entries_stage_3 { - reads { - tcp.dstPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 1 -@pragma ways 6 - -table exm_6ways_1Entries_stage_3 { - reads { - ethernet.dstAddr : exact; - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 2 -@pragma ways 3 - -table exm_3ways_2Entries_stage_3 { - reads { - ipv4.srcAddr : exact; - ipv4.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 2 -@pragma ways 4 - -table exm_4ways_2Entries_stage_4 { - reads { - ipv4.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 2 -@pragma ways 5 - -table exm_5ways_2Entries_stage_4 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - custom_action_3; - } -} - -@pragma pack 2 -@pragma ways 6 - -table exm_6ways_2Entries_stage_4 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - custom_action_2; - } -} - - -/* Main control flow */ -control ingress { - /* A general principle : Always keep the exact match tables ahead of the - * ternary tables in the same stage, except first stage. Logic relating to next-table - * will cause the Tofino model not to launch a lookup on th exact match - * tables if the order is reversed. - */ - apply(exm_5ways_7Entries); - //apply(exm_4ways_8Entries); - apply(exm_5ways_8Entries); - apply(exm_3ways_1Entries); - apply(exm_4ways_1Entries); - apply(exm_6ways_7Entries_stage_1); - apply(exm_3ways_8Entries_stage_1); - apply(exm_6ways_8Entries_stage_2); - apply(exm_2ways_4Entries_stage_2); - apply(exm_2ways_5Entries_stage_2); - apply(exm_2ways_6Entries_stage_2); - apply(exm_5ways_1Entries_stage_2); - apply(exm_2ways_7Entries_stage_3); - //apply(exm_2ways_8Entries_stage_3); - apply(exm_6ways_1Entries_stage_3); - apply(exm_3ways_2Entries_stage_3); - apply(exm_4ways_2Entries_stage_4); - apply(exm_5ways_2Entries_stage_4); - apply(exm_6ways_2Entries_stage_4); -} - -action eg_drop() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); - modify_field(eg_intr_md.egress_port, 0); -} - -action permit() { -} - -table egress_acl { - reads { - routing_metadata.drop: ternary; - } - actions { - permit; - eg_drop; - } -} - -control egress { -// apply(egress_acl); -} diff --git a/backends/tofino/bf-asm/test/internal/dileep8.p4 b/backends/tofino/bf-asm/test/internal/dileep8.p4 deleted file mode 100644 index b6f5b75530f..00000000000 --- a/backends/tofino/bf-asm/test/internal/dileep8.p4 +++ /dev/null @@ -1,593 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm: csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop_ipv4(egress_port /*,srcmac, dstmac*/) { - hop(ipv4.ttl, egress_port); -// modify_field(ethernet.srcAddr, srcmac); -// modify_field(ethernet.dstAddr, dstmac); -} - -action drop_ipv4 () { - drop(); -} - -action next_hop_ipv4(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action ig_drop() { -// modify_field(routing_metadata.drop, 1); - add_to_field(ipv4.ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); -} - -action mod_mac_addr(egress_port, srcmac, dstmac) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action udp_hdr_add (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - add_header(udp); - modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); - add_to_field(ipv4.totalLen, 8); -} - -action tcp_hdr_rm (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - remove_header(tcp); - modify_field(ipv4.protocol, 0); -// add_to_field(ipv4.totalLen, -20); -// modify_field(ipv4.totalLen, 66); -} - -action modify_tcp_dst_port(dstPort) { - modify_field(tcp.dstPort, dstPort); -} - -action modify_tcp_dst_port_1(dstPort, egress_port) { - modify_field(tcp.dstPort, dstPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ipv4.srcAddr, ipAddr); - modify_field(ethernet.dstAddr, dstAddr); - modify_field(tcp.dstPort, tcpPort); -} - -action custom_action_2(egress_port, ipAddr, tcpPort) -{ - modify_field(ipv4.srcAddr, ipAddr); - modify_field(tcp.dstPort, tcpPort); - hop(ipv4.ttl, egress_port); -} - -action custom_action_3(egress_port, dstAddr, dstIp) -{ - modify_field(ipv4.dstAddr, dstIp); - modify_field(ethernet.dstAddr, dstAddr); - hop(ipv4.ttl, egress_port); -} - -action switching_action_1(egress_port/*, vlan_id */) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - //modify_field(vlan_tag.vlan_id, vlan_id); -} - -@pragma stage 0 -@pragma pack 7 -@pragma ways 5 - -table exm_5ways_7Entries { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - -@pragma pack 8 -@pragma ways 4 - -table exm_4ways_8Entries { - reads { - ipv4.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_3; - } -} - -@pragma ways 5 -@pragma pack 8 - -table exm_5ways_8Entries { - reads { - tcp.dstPort : exact; - } - actions { - nop; - tcp_hdr_rm; - } -} - -@pragma ways 3 -@pragma pack 1 - -table exm_3ways_1Entries { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma ways 4 -@pragma pack 1 - -table exm_4ways_1Entries { - reads { - ipv4.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - custom_action_2; - } -} - - -@pragma ways 6 -@pragma pack 7 - -table exm_6ways_7Entries_stage_1 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma ways 3 -@pragma pack 8 - -table exm_3ways_8Entries_stage_1 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - custom_action_2; - } -} - - - -@pragma ways 5 //Not enough memory to allocate all action entries -@pragma pack 8 - -table exm_6ways_8Entries_stage_2 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - mod_mac_addr; - } -} - - - - - -@pragma pack 1 -@pragma ways 6 - -table exm_6ways_1Entries_stage_2 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - tcp.dstPort : exact; - tcp.srcPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 7 -@pragma ways 2 - -table exm_2ways_7Entries_stage_3 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 8 -@pragma ways 2 - -table exm_2ways_8Entries_stage_3 { - reads { - tcp.dstPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 1 -@pragma ways 6 - -table exm_6ways_1Entries_stage_3 { - reads { - ethernet.dstAddr : exact; - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 2 -@pragma ways 3 - -table exm_3ways_2Entries_stage_3 { - reads { - ipv4.srcAddr : exact; - ipv4.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 2 -@pragma ways 4 - -table exm_4ways_2Entries_stage_4 { - reads { - ipv4.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 2 -@pragma ways 5 - -table exm_5ways_2Entries_stage_4 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - custom_action_3; - } -} - -@pragma pack 2 -@pragma ways 6 - -table exm_6ways_2Entries_stage_4 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - custom_action_2; - } -} - -@pragma pack 4 -@pragma ways 2 - -table exm_2ways_4Entries_stage_5 { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 5 -@pragma ways 2 - -table exm_2ways_5Entries_stage_5 { - reads { - tcp.srcPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -@pragma ways 4 - -table exm_4ways_16k_stage_5 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } - - size : 16384; -} - -@pragma pack 6 -@pragma ways 2 - -table exm_2ways_6Entries_stage_6 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - -@pragma pack 1 -@pragma ways 5 -table exm_5ways_1Entries_stage_6 { - reads { - ethernet.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_3; - } -} - -/* Main control flow */ -control ingress { - /* A general principle : Always keep the exact match tables ahead of the - * ternary tables in the same stage, except first stage. Logic relating to next-table - * will cause the Tofino model not to launch a lookup on th exact match - * tables if the order is reversed. - */ - apply(exm_5ways_7Entries); - //apply(exm_4ways_8Entries); - //apply(exm_5ways_8Entries); - apply(exm_3ways_1Entries); - apply(exm_4ways_1Entries); - apply(exm_6ways_7Entries_stage_1); - //apply(exm_3ways_8Entries_stage_1); - apply(exm_6ways_8Entries_stage_2); - apply(exm_2ways_7Entries_stage_3); - //apply(exm_2ways_8Entries_stage_3); - apply(exm_6ways_1Entries_stage_3); - apply(exm_3ways_2Entries_stage_3); - apply(exm_4ways_2Entries_stage_4); - apply(exm_5ways_2Entries_stage_4); - apply(exm_6ways_2Entries_stage_4); - //apply(exm_2ways_4Entries_stage_5); - //apply(exm_2ways_5Entries_stage_5); - apply(exm_4ways_16k_stage_5); - //apply(exm_2ways_6Entries_stage_6); - //apply(exm_5ways_1Entries_stage_6); -} - -action eg_drop() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); - modify_field(eg_intr_md.egress_port, 0); -} - -action permit() { -} - -table egress_acl { - reads { - routing_metadata.drop: ternary; - } - actions { - permit; - eg_drop; - } -} - -control egress { -// apply(egress_acl); -} diff --git a/backends/tofino/bf-asm/test/internal/dileep9.PRAGMA b/backends/tofino/bf-asm/test/internal/dileep9.PRAGMA deleted file mode 100644 index f5c1c60f086..00000000000 --- a/backends/tofino/bf-asm/test/internal/dileep9.PRAGMA +++ /dev/null @@ -1,188 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm: csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action custom_action_3(egress_port, dstAddr, dstIp) -{ - modify_field(ipv4.dstAddr, dstIp); - modify_field(ethernet.dstAddr, dstAddr); - hop(ipv4.ttl, egress_port); -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - - -@pragma stage 0 -@pragma pack 7 -@pragma ways 5 -table exm_5ways_7Entries { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - custom_action_3; - } - size : 35840; -} - -control ingress { - /* A general principle : Always keep the exact match tables ahead of the - * ternary tables in the same stage, except first stage. Logic relating to next-table - * will cause the Tofino model not to launch a lookup on th exact match - * tables if the order is reversed. - */ - apply(exm_5ways_7Entries); -} diff --git a/backends/tofino/bf-asm/test/internal/google-tor/lag.p4 b/backends/tofino/bf-asm/test/internal/google-tor/lag.p4 deleted file mode 100644 index da634c3fa59..00000000000 --- a/backends/tofino/bf-asm/test/internal/google-tor/lag.p4 +++ /dev/null @@ -1,48 +0,0 @@ -// lag.p4 - -//----------------------------------- -// LAG egress port selection -//----------------------------------- - -action set_lag_egress_port(port) { - modify_field(standard_metadata.egress_spec, port); -} - -field_list lag_hash_fields { - ethernet.dstAddr; - ethernet.srcAddr; - ethernet.etherType; - standard_metadata.ingress_port; -} - -field_list_calculation lag_hash { - input { - lag_hash_fields; - } - algorithm : crc16; - output_width : 14; -} - -action_selector lag_selector { - selection_key : lag_hash; - selection_mode : fair; -} - -action_profile lag_action_profile { - actions { - set_lag_egress_port; - } - dynamic_action_selection: lag_selector; -} - -table lag_resolve_table { - reads { - standard_metadata.egress_spec: exact; - } - action_profile: lag_action_profile; -} - -control lag_handling { - apply(lag_resolve_table); -} - diff --git a/backends/tofino/bf-asm/test/internal/google-tor/tor.p4 b/backends/tofino/bf-asm/test/internal/google-tor/tor.p4 deleted file mode 100644 index 9cdbb026840..00000000000 --- a/backends/tofino/bf-asm/test/internal/google-tor/tor.p4 +++ /dev/null @@ -1,672 +0,0 @@ -// Copyright (c) 2016, Google Inc. -// -// P4 specification for a ToR (top-of-rack) switch. -// Status: WORK IN PROGRESS -// Note: This code has not been tested and is expected to contain bugs. - -//------------------------------------------------------------------------------ -// Global defines -//------------------------------------------------------------------------------ - -#define CPU_PORT 64 -#define INITIAL_CPU_PACKET_OFFSET 64 - -#define ARP_REASON 1 - -#define ETHERTYPE_VLAN 0x8100, 0x9100, 0x9200, 0x9300 -#define ETHERTYPE_IPV4 0x0800 -#define ETHERTYPE_IPV6 0x86dd -#define ETHERTYPE_ARP 0x0806 -#define ETHERTYPE_ND 0x6007 -#define ETHERTYPE_LLDP 0x88CC - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 -#define IP_PROTOCOLS_ICMP 1 -#define IP_PROTOCOLS_ICMPv6 58 - -#define DEFAULT_VRF0 0 - -#define L2_VLAN 4050 -#define VLAN_DEPTH 2 - -#define CPU_MIRROR_SESSION_ID 1024 - -#define PORT_COUNT 256 - -#ifdef P4_EXPLICIT_LAG -#include "lag.p4" -#endif - -//------------------------------------------------------------------------------ -// Protocol Header Definitions -//------------------------------------------------------------------------------ - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_base_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr : 32; - } -} - -// Fixed ipv6 header -header_type ipv6_base_t { - fields { - version : 4; - traffic_class : 8; - flowLabel : 20; - payloadLength : 16; - nextHeader : 8; - hopLimit : 8; - srcAddr : 128; - dstAddr : 128; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 4; - flags : 8; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -// Same for both ip v4 and v6 -header_type icmp_header_t { - fields { - icmpType: 8; - code: 8; - checksum: 16; - } -} - -header_type vlan_tag_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - -header_type arp_t { - fields { - hwType : 16; - protoType : 16; - hwAddrLen : 8; - protoAddrLen : 8; - opcode : 16; - hwSrcAddr : 48; - protoSrcAddr : 32; - hwDstAddr : 48; - protoDstAddr : 32; - } -} - -//------------------------------------------------------------------------------ -// Internal Header Definitions -//------------------------------------------------------------------------------ - -header_type cpu_header_t { - fields { - zeros : 64; - reason : 16; - port : 32; - } -} - -//------------------------------------------------------------------------------ -// Metadata Header and Field List Definitions -//------------------------------------------------------------------------------ - -// Local meta-data for each packet being processed. -header_type local_metadata_t { - fields { - vrf_id : 32; - class_id: 8; // Dst traffic class ID (IPSP) - qid: 5; // CPU COS queue ID - ingress_meter_index: 16; // per-port ingress rate-limiting (IPSP) - color: 2; - l4SrcPort: 16; - l4DstPort: 16; - icmp_code: 8; - reason: 8; // Reason to drop to CPU - src_mac: 48; - } -} - -// Field List for packets destined to CPU. -field_list cpu_info { - local_metadata.reason; - standard_metadata.ingress_port; -} - -//------------------------------------------------------------------------------ -// Headers and Metadata Declarations -//------------------------------------------------------------------------------ - -header ethernet_t ethernet; -header ipv4_base_t ipv4_base; -header ipv6_base_t ipv6_base; -header icmp_header_t icmp_header; -header tcp_t tcp; -header udp_t udp; -header vlan_tag_t vlan_tag[VLAN_DEPTH]; -header arp_t arp; - -header cpu_header_t cpu_header; - -metadata local_metadata_t local_metadata; - -//------------------------------------------------------------------------------ -// Parsers -//------------------------------------------------------------------------------ - -// Start with ethernet always. -parser start { - return select(current(0, INITIAL_CPU_PACKET_OFFSET)) { - 0 : parse_cpu_header; - default: parse_ethernet; - } -} - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - ETHERTYPE_VLAN: parse_vlan; - ETHERTYPE_IPV4: parse_ipv4; - ETHERTYPE_IPV6: parse_ipv6; - ETHERTYPE_ARP: parse_arp; - default: ingress; - } -} - -parser parse_vlan { - extract(vlan_tag[next]); - return select(latest.etherType) { - ETHERTYPE_VLAN : parse_vlan; - ETHERTYPE_IPV4 : parse_ipv4; - ETHERTYPE_IPV6 : parse_ipv6; - default: ingress; - } -} - -parser parse_ipv4 { - extract(ipv4_base); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_ICMP : parse_icmp; - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -parser parse_ipv6 { - extract(ipv6_base); - return select(ipv6_base.nextHeader) { - IP_PROTOCOLS_ICMPv6: parse_icmp; - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -parser parse_tcp { - extract(tcp); - // Normalize TCP port metadata to common port metadata - set_metadata(local_metadata.l4SrcPort, latest.srcPort); - set_metadata(local_metadata.l4DstPort, latest.dstPort); - return ingress; -} - -parser parse_udp { - extract(udp); - // Normalize UDP port metadata to common port metadata - set_metadata(local_metadata.l4SrcPort, latest.srcPort); - set_metadata(local_metadata.l4DstPort, latest.dstPort); - return ingress; -} - -parser parse_icmp { - extract(icmp_header); - return ingress; -} - -parser parse_arp { - extract(arp); - return ingress; -} - -parser parse_cpu_header { - extract(cpu_header); - return parse_ethernet; -} - -//------------------------------------------------------------------------------ -// Actions -//------------------------------------------------------------------------------ - -// Do nothing action. -action nop() { -} - -// Drops the packet. -action drop_packet() { - drop(); -} - -// TODO(wmohsin): Confirm this use-case. -// Sets the ’special' L2 Vlan that we allow (every other L2 packet forwarding is -// disabled). -action set_l2_vlan() { - modify_field(vlan_tag[0].vid, L2_VLAN); - modify_field(vlan_tag[0].etherType, 0x8100); -} - -action set_class_id(class_id) { - modify_field(local_metadata.class_id, class_id); -} - -action set_vrf(vrf_id) { - modify_field(local_metadata.vrf_id, vrf_id); -} - -action set_ecmp_nexthop_info_port(port, smac, dmac) { - modify_field(standard_metadata.egress_spec, port); - modify_field(ethernet.srcAddr, smac); - modify_field(ethernet.dstAddr, dmac); -} - -//----------------------------------- -// Send/Copy to CPU in a given queue -//----------------------------------- - -action set_queue_and_copy_to_cpu(qid, reason) { - modify_field(local_metadata.qid, qid); - modify_field(local_metadata.reason, reason); - clone_ingress_pkt_to_egress(CPU_MIRROR_SESSION_ID, cpu_info); -} - -action set_queue_and_send_to_cpu(qid, reason) { - modify_field(local_metadata.qid, qid); - add_header(cpu_header); - modify_field(cpu_header.reason, reason); - modify_field(cpu_header.port, standard_metadata.ingress_port); - modify_field(standard_metadata.egress_spec, CPU_PORT); -} - -//------------------------------------------------------------------------------ -// Receive from CPU -//------------------------------------------------------------------------------ - -action set_egress_port_and_decap_cpu_header() { - modify_field(standard_metadata.egress_spec, cpu_header.port); - remove_header(cpu_header); -} - -action meter_packet(meter_index) { - modify_field(local_metadata.ingress_meter_index, meter_index); - execute_meter(ingress_port_meter, meter_index, local_metadata.color); -} - -action meter_deny() { - drop(); -} - -action meter_permit() { -} - -//------------------------------------------------------------------------------ -// Tables and Control Flows -//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -// Packet Classification -//------------------------------------------------------------------------------ - -table class_id_assignment_table { - reads { - ethernet.etherType: exact; - - ipv4_base.ttl: ternary; - ipv6_base.hopLimit: ternary; - ipv4_base.dstAddr: ternary; - ipv6_base.dstAddr: ternary; - ipv4_base.protocol: exact; - ipv6_base.nextHeader: exact; - - local_metadata.l4SrcPort: exact; - local_metadata.l4DstPort: exact; - - vlan_tag[0].vid: exact; - vlan_tag[0].pcp: exact; - } - actions { - set_class_id; - } - default_action: set_class_id(0); -} - -//----------------------------------- -// Map traffic to a particular VRF -//----------------------------------- - -table vrf_classifier_table { - reads { - ethernet.etherType : exact; - ethernet.srcAddr : exact; - ethernet.dstAddr : exact; - standard_metadata.ingress_port: exact; - } - actions { - set_vrf; - } - default_action: set_vrf(DEFAULT_VRF0); -} - -//------------------------------------------------------------------------------ -// L3 Routing (My MAC check) -//------------------------------------------------------------------------------ - -// Drops packets that do not need to be part of L3 forwarding. -// Equivalent of BCM MY_STATION table ? -table l3_routing_classifier_table { - reads { - ethernet.dstAddr : exact; - } - actions { - nop; - drop_packet; - } - default_action: drop_packet(); -} - -//------------------------------------------------------------------------------ -// IPv4 and IPv6 L3 Forwarding -//------------------------------------------------------------------------------ - -//----------------------------------- -// IPv4 L3 Forwarding -//----------------------------------- - -table l3_ipv4_override_table { - reads { - ipv4_base.dstAddr : lpm; - } - action_profile: ecmp_action_profile; -} - -table l3_ipv4_vrf_table { - reads { - local_metadata.vrf_id: exact; - ipv4_base.dstAddr : lpm; - } - action_profile: ecmp_action_profile; -} - -table l3_ipv4_fallback_table { - reads { - ipv4_base.dstAddr : lpm; - } - action_profile: ecmp_action_profile; -} - -// LPM forwarding for IPV4 packets. -control ingress_ipv4_l3_forwarding { - apply(l3_ipv4_override_table) { - miss { - apply(l3_ipv4_vrf_table) { - miss { - apply(l3_ipv4_fallback_table); - } - } - } - } -} - -//----------------------------------- -// IPv6 L3 Forwarding -//----------------------------------- - -table l3_ipv6_override_table { - reads { - ipv6_base.dstAddr : lpm; - } - action_profile: ecmp_action_profile; -} - -table l3_ipv6_vrf_table { - reads { - local_metadata.vrf_id: exact; - ipv6_base.dstAddr : lpm; - } - action_profile: ecmp_action_profile; -} - -table l3_ipv6_fallback_table { - reads { - ipv6_base.dstAddr : lpm; - } - action_profile: ecmp_action_profile; -} - - -//----------------------------------- -// L3 ECMP nexthop selection -//----------------------------------- - -field_list l3_ip_hash_fields { - ipv6_base.dstAddr; - ipv6_base.srcAddr; - ipv6_base.flowLabel; - ipv4_base.dstAddr; - ipv4_base.srcAddr; - ipv4_base.protocol; - local_metadata.l4SrcPort; - local_metadata.l4DstPort; -} - -field_list_calculation ecmp_hash { - input { - l3_ip_hash_fields; - } - algorithm : crc16; - output_width : 14; -} - -action_selector ecmp_selector { - selection_key : ecmp_hash; - selection_mode : fair; -} - -action_profile ecmp_action_profile { - actions { - set_ecmp_nexthop_info_port; - } - dynamic_action_selection: ecmp_selector; -} - -// LPM forwarding for IPV6 packets. -control ingress_ipv6_l3_forwarding { - apply(l3_ipv6_override_table) { - miss { - apply(l3_ipv6_vrf_table) { - miss { - apply(l3_ipv6_fallback_table); - } - } - } - } -} - -//----------------------------------- -// IPv4/v6 L3 Forwarding -//----------------------------------- - -// Controls LPM forwarding. -control ingress_lpm_forwarding { - if (valid(ipv4_base)) { - ingress_ipv4_l3_forwarding(); - } else { - if (valid(ipv6_base)) { - ingress_ipv6_l3_forwarding(); - } - } -#ifdef P4_EXPLICIT_LAG - lag_handling(); -#endif -} - -// Combined punt table. -// TODO(wmohsin): target_egress_port in punted packet-io. -table punt_table { - reads { - standard_metadata.ingress_port: ternary; - standard_metadata.egress_spec: ternary; - - ethernet.etherType: ternary; - - ipv4_base: valid; - ipv6_base: valid; - ipv4_base.diffserv: ternary; - ipv6_base.traffic_class: ternary; - ipv4_base.ttl: ternary; - ipv6_base.hopLimit: ternary; - ipv4_base.srcAddr: ternary; - ipv4_base.dstAddr: ternary; - ipv6_base.srcAddr: ternary; - ipv6_base.dstAddr: ternary; - ipv4_base.protocol: ternary; - ipv6_base.nextHeader: ternary; - - arp.protoDstAddr: ternary; - local_metadata.icmp_code: ternary; - - vlan_tag[0].vid: ternary; - vlan_tag[0].pcp: ternary; - - local_metadata.class_id: ternary; - local_metadata.vrf_id: ternary; - } - actions { - set_queue_and_copy_to_cpu; - set_queue_and_send_to_cpu; - } -} - -table process_cpu_header { - actions { - set_egress_port_and_decap_cpu_header; - } - default_action: set_egress_port_and_decap_cpu_header(); -} - -//------------------------------------------------------------------------------ -// Meters -//------------------------------------------------------------------------------ - -// TODO(wmohsin): Evaluate this being direct: ingress_port_meter_table -meter ingress_port_meter { - type : bytes; - instance_count : PORT_COUNT; -} - -// Per-port ingress packet rate limiting. -table ingress_port_meter_table { - reads { - standard_metadata.ingress_port: exact; - standard_metadata.egress_spec: exact; - ethernet.etherType: exact; - ipv4_base.dstAddr: ternary; - arp.protoDstAddr: ternary; - local_metadata.class_id: exact; - } - actions { - meter_packet; - } -} - -//----------------------------------- -// Meter Stats -//----------------------------------- - -counter meter_stats { - type : packets; - direct : ingress_port_meter_policy_table; -} - -table ingress_port_meter_policy_table { - reads { - local_metadata.color : exact; - local_metadata.ingress_meter_index : exact; - } - - actions { - meter_permit; - meter_deny; - } -} - -//----------------------------------- -// Meter Control Flow -//----------------------------------- - -control process_punt_packets { - apply(punt_table); - apply(ingress_port_meter_table) { - hit { - apply(ingress_port_meter_policy_table); - } - } -} - -control ingress { - if (valid(cpu_header)) { - apply(process_cpu_header); - } else { - apply(class_id_assignment_table); - apply(vrf_classifier_table); - apply(l3_routing_classifier_table); - ingress_lpm_forwarding(); - process_punt_packets(); - } -} - -control egress { -} - diff --git a/backends/tofino/bf-asm/test/internal/test_7_storm_control.p4 b/backends/tofino/bf-asm/test/internal/test_7_storm_control.p4 deleted file mode 100644 index d7f8aa6c6fd..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_7_storm_control.p4 +++ /dev/null @@ -1,140 +0,0 @@ - - -header_type ingress_metadata_t { - fields { - bd : 16; - vrf : 12; - v6_vrf : 12; - ipv4_term : 1; - ipv6_term : 1; - igmp_snoop : 1; - tunnel_term : 1; - tunnel_vni : 32; - ing_meter : 16; - i_lif : 16; - i_tunnel_lif : 16; - o_lif : 16; - if_acl_label : 16; - - route_acl_label : 16; - - bd_flags : 16; - stp_instance : 8; - route : 1; - inner_route : 1; - l2_miss : 1; - l3_lpm_miss : 1; - mc_index : 16; - inner_mc_index : 16; - nhop : 16; - ecmp_index : 10; - - ecmp_offset : 14; - - nsh_value : 16; - lag_index : 8; - - lag_port : 15; - lag_offset : 14; - - flood : 1; - learn_type : 1; - learn_mac : 48; - learn_ipv4 : 32; - mcast_drop : 1; - drop_2 : 1; - drop_1 : 1; - drop_0 : 1; - drop_reason : 8; - copy_to_cpu : 1; - mirror_sesion_id: 10; - urpf : 1; - urpf_mode: 2; - urpf_strict: 16; - ingress_bypass: 1; - ipv4_dstaddr_24b: 24; - nhop_index: 16; - - if_drop : 1; - route_drop : 1; - - ipv4_dest : 32; - eth_dstAddr : 48; - eth_srcAddr : 48; - ipv4_ttl : 8; - dcsp : 3; - buffer_qos : 3; - ip_srcPort : 16; - ip_dstPort : 16; - - - mcast_pkt : 1; - inner_mcast_pkt : 1; - - if_copy_to_cpu : 1; - if_nhop : 16; - if_port : 9; - if_ecmp_index : 10; - if_lag_index : 8; - route_copy_to_cpu : 1; - route_nhop : 16; - route_port : 9; - route_ecmp_index : 10; - route_lag_index : 8; - - tun_type : 8; - nat_enable : 1; - - nat_source_index : 13; - nat_dest_index : 13; - - } -} - - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header ethernet_t ethernet; -metadata ingress_metadata_t ingress_metadata; - -parser start { - return parse_ethernet; -} - -parser parse_ethernet { - extract(ethernet); - return ingress; -} - - - -action no_action(){ - no_op(); -} - -action ing_meter_set(meter_) { - modify_field(ingress_metadata.ing_meter, meter_); -} - -table storm_control { - reads { - ingress_metadata.bd : exact; - ethernet.dstAddr : ternary; - } - actions { - no_action; - ing_meter_set; - } - size : 8192; -} - - -control ingress { - apply(storm_control); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_100_hash_action.p4 b/backends/tofino/bf-asm/test/internal/test_config_100_hash_action.p4 deleted file mode 100644 index 470d9e08ab9..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_100_hash_action.p4 +++ /dev/null @@ -1,105 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - color_0 : 8; - } -} - -header_type meta_t { - fields { - field_17 : 17; - pad_15 : 15; - } -} - -parser start { - return parse_pkt; -} - -header pkt_t pkt; -metadata meta_t meta; - -parser parse_pkt { - extract(pkt); - return ingress; -} - - -action action_0(param0){ - modify_field(pkt.field_c_32, param0); -} - -action action_1(param0){ - modify_field(pkt.field_f_16, param0); -} - -action action_2(){ - count(simple_stats, meta.field_17); -} - -action do_nothing(){ - no_op(); -} - -counter simple_stats { - type : packets; - instance_count : 32768; -} - -@pragma action_default_only do_nothing -table table_0 { - reads { - pkt.field_i_8 : exact; - } - actions { - do_nothing; - action_0; - } - size : 256; -} - -@pragma include_idletime 1 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 1 -table table_1 { - reads { - pkt.field_g_16 : exact; - } - actions { - action_1; - } - size : 65536; -} - -table table_2 { - actions { - action_2; - } -} - -/* Main control flow */ - -control ingress { - if (valid(pkt)){ - apply(table_0); - apply(table_1); - apply(table_2); - } -} - - diff --git a/backends/tofino/bf-asm/test/internal/test_config_101_switch_msdc.p4 b/backends/tofino/bf-asm/test/internal/test_config_101_switch_msdc.p4 deleted file mode 100644 index 527a1f52667..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_101_switch_msdc.p4 +++ /dev/null @@ -1,3838 +0,0 @@ -# 1 "p4src/switch.p4" -# 1 "" -# 1 "/usr/include/stdc-predef.h" 1 3 4 -# 1 "" 2 -# 1 "p4src/switch.p4" - -# 1 "/home/john/ws/p4f/submodules/p4c-tofino/p4c_tofino/target/tofino/p4_lib/tofino/intrinsic_metadata.p4" 1 -# 11 "/home/john/ws/p4f/submodules/p4c-tofino/p4c_tofino/target/tofino/p4_lib/tofino/intrinsic_metadata.p4" -header_type ingress_parser_control_signals { - fields { - priority : 3; - } -} - -@pragma not_deparsed ingress -@pragma not_deparsed egress -@pragma pa_gress ingress ig_prsr_ctrl -header ingress_parser_control_signals ig_prsr_ctrl; - - - -header_type ingress_intrinsic_metadata_t { - fields { - - resubmit_flag : 1; - - - _pad1 : 1; - - _pad2 : 2; - - _pad3 : 3; - - ingress_port : 9; - - - ingress_mac_tstamp : 48; - - } -} - -@pragma dont_trim -@pragma not_deparsed ingress -@pragma not_deparsed egress -@pragma pa_gress ingress ig_intr_md -@pragma pa_no_tagalong ingress ig_intr_md.ingress_port -header ingress_intrinsic_metadata_t ig_intr_md; - - - -header_type generator_metadata_t { - fields { - - app_id : 16; - - batch_id: 16; - - instance_id: 16; - } -} - -@pragma not_deparsed ingress -@pragma not_deparsed egress -header generator_metadata_t ig_pg_md; - - - - -header_type ingress_intrinsic_metadata_from_parser_aux_t { - fields { - ingress_global_tstamp : 48; - - - ingress_global_ver : 32; - - - ingress_parser_err : 16; - - } -} - -@pragma pa_fragment ingress ig_intr_md_from_parser_aux.ingress_parser_err -@pragma pa_atomic ingress ig_intr_md_from_parser_aux.ingress_parser_err -@pragma not_deparsed ingress -@pragma not_deparsed egress -@pragma pa_gress ingress ig_intr_md_from_parser_aux -header ingress_intrinsic_metadata_from_parser_aux_t ig_intr_md_from_parser_aux; - - - - -header_type ingress_intrinsic_metadata_for_tm_t { - fields { - - - - - _pad2 : 7; - ucast_egress_port : 9; - - - _pad3 : 7; - bypass_egress : 1; - - - _pad4 : 3; - qid : 5; - - - _pad5 : 7; - deflect_on_drop : 1; - - - - _pad6 : 5; - ingress_cos : 3; - - - - _pad7 : 6; - packet_color : 2; - - - - _pad8 : 7; - copy_to_cpu : 1; - - - _pad9 : 5; - icos_for_copy_to_cpu : 3; - - - - mcast_grp_a : 16; - - - - mcast_grp_b : 16; - - - _pad10 : 3; - level1_mcast_hash : 13; - - - - - - _pad11 : 3; - level2_mcast_hash : 13; - - - - - - level1_exclusion_id : 16; - - - - _pad12 : 7; - level2_exclusion_id : 9; - - - - rid : 16; - - - _pad13 : 7; - disable_ucast_cutthru : 1; - - - _pad14 : 7; - enable_mcast_cutthru : 1; - - } -} - - - - - - -@pragma pa_no_tagalong ingress ig_intr_md_for_tm.mcast_grp_a -@pragma pa_no_tagalong ingress ig_intr_md_for_tm.mcast_grp_b - - -@pragma pa_fragment ingress ig_intr_md_for_tm._pad2 -@pragma pa_atomic ingress ig_intr_md_for_tm.ucast_egress_port -@pragma pa_fragment ingress ig_intr_md_for_tm._pad2 -@pragma pa_fragment ingress ig_intr_md_for_tm._pad3 -@pragma pa_fragment ingress ig_intr_md_for_tm._pad4 -@pragma pa_fragment ingress ig_intr_md_for_tm._pad5 -@pragma pa_fragment ingress ig_intr_md_for_tm._pad6 -@pragma pa_fragment ingress ig_intr_md_for_tm._pad7 -@pragma pa_fragment ingress ig_intr_md_for_tm._pad8 -@pragma pa_fragment ingress ig_intr_md_for_tm._pad9 -@pragma pa_atomic ingress ig_intr_md_for_tm.mcast_grp_a -@pragma pa_fragment ingress ig_intr_md_for_tm.mcast_grp_a -@pragma pa_atomic ingress ig_intr_md_for_tm.mcast_grp_b -@pragma pa_fragment ingress ig_intr_md_for_tm.mcast_grp_b -@pragma pa_atomic ingress ig_intr_md_for_tm.level1_mcast_hash -@pragma pa_fragment ingress ig_intr_md_for_tm._pad10 -@pragma pa_atomic ingress ig_intr_md_for_tm.level2_mcast_hash -@pragma pa_fragment ingress ig_intr_md_for_tm._pad11 -@pragma pa_atomic ingress ig_intr_md_for_tm.level1_exclusion_id -@pragma pa_fragment ingress ig_intr_md_for_tm.level1_exclusion_id -@pragma pa_atomic ingress ig_intr_md_for_tm.level2_exclusion_id -@pragma pa_fragment ingress ig_intr_md_for_tm._pad12 -@pragma pa_atomic ingress ig_intr_md_for_tm.rid -@pragma pa_fragment ingress ig_intr_md_for_tm.rid -@pragma pa_fragment ingress ig_intr_md_for_tm._pad13 -@pragma pa_fragment ingress ig_intr_md_for_tm._pad14 -@pragma not_deparsed ingress -@pragma not_deparsed egress -@pragma pa_gress ingress ig_intr_md_for_tm -header ingress_intrinsic_metadata_for_tm_t ig_intr_md_for_tm; - - -header_type ingress_intrinsic_metadata_for_mirror_buffer_t { - fields { - _pad1 : 6; - ingress_mirror_id : 10; - - - } -} - -@pragma dont_trim -@pragma pa_gress ingress ig_intr_md_for_mb -@pragma pa_atomic ingress ig_intr_md_for_mb.ingress_mirror_id -@pragma pa_no_tagalong ingress ig_intr_md_for_mb.ingress_mirror_id -@pragma not_deparsed ingress -@pragma not_deparsed egress -header ingress_intrinsic_metadata_for_mirror_buffer_t ig_intr_md_for_mb; - - -header_type egress_intrinsic_metadata_t { - fields { - - egress_port : 16; - - - _pad1: 5; - enq_qdepth : 19; - - - _pad2: 6; - enq_congest_stat : 2; - - - enq_tstamp : 32; - - - _pad3: 5; - deq_qdepth : 19; - - - _pad4: 6; - deq_congest_stat : 2; - - - app_pool_congest_stat : 8; - - - - deq_timedelta : 32; - - - egress_rid : 16; - - - _pad5: 7; - egress_rid_first : 1; - - - _pad6: 3; - egress_qid : 5; - - - _pad7: 5; - egress_cos : 3; - - - _pad8: 7; - deflection_flag : 1; - - - pkt_length : 16; - } -} - -@pragma dont_trim -@pragma not_deparsed ingress -@pragma not_deparsed egress -@pragma pa_gress egress eg_intr_md -@pragma pa_no_tagalong egress eg_intr_md.egress_port -@pragma pa_no_tagalong egress eg_intr_md.egress_cos -header egress_intrinsic_metadata_t eg_intr_md; - - - -header_type egress_intrinsic_metadata_from_parser_aux_t { - fields { - egress_global_tstamp : 48; - - - egress_global_ver : 32; - - - egress_parser_err : 16; - - - } -} - -@pragma pa_fragment egress eg_intr_md_from_parser_aux.egress_parser_err -@pragma pa_atomic egress eg_intr_md_from_parser_aux.egress_parser_err -@pragma not_deparsed ingress -@pragma not_deparsed egress -@pragma pa_gress egress eg_intr_md_from_parser_aux -header egress_intrinsic_metadata_from_parser_aux_t eg_intr_md_from_parser_aux; -# 353 "/home/john/ws/p4f/submodules/p4c-tofino/p4c_tofino/target/tofino/p4_lib/tofino/intrinsic_metadata.p4" -header_type egress_intrinsic_metadata_for_mirror_buffer_t { - fields { - _pad1 : 6; - egress_mirror_id : 10; - - - coalesce_flush: 1; - coalesce_length: 7; - - - - } -} - -@pragma dont_trim -@pragma pa_gress egress eg_intr_md_for_mb -@pragma pa_atomic egress eg_intr_md_for_mb.egress_mirror_id -@pragma pa_no_tagalong ingress ig_intr_md.coalesce_length -@pragma pa_no_tagalong ingress ig_intr_md.coalesce_flush -@pragma pa_fragment ingress eg_intr_md_for_mb.coalesce_flush -@pragma not_deparsed ingress -@pragma not_deparsed egress -header egress_intrinsic_metadata_for_mirror_buffer_t eg_intr_md_for_mb; - - - - -header_type egress_intrinsic_metadata_for_output_port_t { - fields { - - _pad1 : 7; - capture_tstamp_on_tx : 1; - - - - _pad2 : 7; - update_delay_on_tx : 1; -# 400 "/home/john/ws/p4f/submodules/p4c-tofino/p4c_tofino/target/tofino/p4_lib/tofino/intrinsic_metadata.p4" - _pad3 : 7; - force_tx_error : 1; - } -} - -@pragma pa_fragment egress eg_intr_md_for_oport._pad2 -@pragma pa_fragment egress eg_intr_md_for_oport._pad3 -@pragma not_deparsed ingress -@pragma not_deparsed egress -@pragma pa_gress egress eg_intr_md_for_oport -header egress_intrinsic_metadata_for_output_port_t eg_intr_md_for_oport; -# 3 "p4src/switch.p4" 2 - - - - -# 1 "p4src/includes/p4features.h" 1 -# 8 "p4src/switch.p4" 2 -# 1 "p4src/includes/headers.p4" 1 -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type llc_header_t { - fields { - dsap : 8; - ssap : 8; - control_ : 8; - } -} - -header_type snap_header_t { - fields { - oui : 24; - type_ : 16; - } -} - -header_type roce_header_t { - fields { - ib_grh : 320; - ib_bth : 96; - } -} - -header_type roce_v2_header_t { - fields { - ib_bth : 96; - } -} - -header_type fcoe_header_t { - fields { - version : 4; - type_ : 4; - sof : 8; - rsvd1 : 32; - ts_upper : 32; - ts_lower : 32; - size_ : 32; - eof : 8; - rsvd2 : 24; - } -} - -header_type vlan_tag_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - -header_type vlan_tag_3b_t { - fields { - pcp : 3; - cfi : 1; - vid : 4; - etherType : 16; - } -} -header_type vlan_tag_5b_t { - fields { - pcp : 3; - cfi : 1; - vid : 20; - etherType : 16; - } -} - -header_type ieee802_1ah_t { - fields { - pcp : 3; - dei : 1; - uca : 1; - reserved : 3; - i_sid : 24; - } -} - -header_type mpls_t { - fields { - label : 20; - exp : 3; - bos : 1; - ttl : 8; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type ipv6_t { - fields { - version : 4; - trafficClass : 8; - flowLabel : 20; - payloadLen : 16; - nextHdr : 8; - hopLimit : 8; - srcAddr : 128; - dstAddr : 128; - } -} - -header_type icmp_t { - fields { - type_ : 8; - code : 8; - hdrChecksum : 16; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 4; - flags : 8; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - length_ : 16; - checksum : 16; - } -} - -header_type sctp_t { - fields { - srcPort : 16; - dstPort : 16; - verifTag : 32; - checksum : 32; - } -} - -header_type gre_t { - fields { - C : 1; - R : 1; - K : 1; - S : 1; - s : 1; - recurse : 3; - flags : 5; - ver : 3; - proto : 16; - } -} - -header_type nvgre_t { - fields { - tni : 24; - reserved : 8; - } -} - - -header_type erspan_header_v1_t { - fields { - version : 4; - vlan : 12; - priority : 6; - span_id : 10; - direction : 8; - truncated: 8; - } -} - - -header_type erspan_header_v2_t { - fields { - version : 4; - vlan : 12; - priority : 6; - span_id : 10; - unknown7 : 32; - } -} - -header_type ipsec_esp_t { - fields { - spi : 32; - seqNo : 32; - } -} - -header_type ipsec_ah_t { - fields { - nextHdr : 8; - length_ : 8; - zero : 16; - spi : 32; - seqNo : 32; - } -} - -header_type arp_rarp_t { - fields { - hwType : 16; - protoType : 16; - hwAddrLen : 8; - protoAddrLen : 8; - opcode : 16; - } -} - -header_type arp_rarp_ipv4_t { - fields { - srcHwAddr : 48; - srcProtoAddr : 32; - dstHwAddr : 48; - dstProtoAddr : 32; - } -} - -header_type eompls_t { - fields { - zero : 4; - reserved : 12; - seqNo : 16; - } -} - -header_type vxlan_t { - fields { - flags : 8; - reserved : 24; - vni : 24; - reserved2 : 8; - } -} - -header_type nsh_t { - fields { - oam : 1; - context : 1; - flags : 6; - reserved : 8; - protoType: 16; - spath : 24; - sindex : 8; - } -} - -header_type nsh_context_t { - fields { - network_platform : 32; - network_shared : 32; - service_platform : 32; - service_shared : 32; - } -} - - - - -header_type genv_t { - fields { - ver : 2; - optLen : 6; - oam : 1; - critical : 1; - reserved : 6; - protoType : 16; - vni : 24; - reserved2 : 8; - } -} - - - - - -header_type genv_opt_A_t { - fields { - optClass : 16; - optType : 8; - reserved : 3; - optLen : 5; - data : 32; - } -} - - - - -header_type genv_opt_B_t { - fields { - optClass : 16; - optType : 8; - reserved : 3; - optLen : 5; - data : 64; - } -} - - - - -header_type genv_opt_C_t { - fields { - optClass : 16; - optType : 8; - reserved : 3; - optLen : 5; - data : 32; - } -} - -header_type trill_t { - fields { - version : 2; - reserved : 2; - multiDestination : 1; - optLength : 5; - hopCount : 6; - egressRbridge : 16; - ingressRbridge : 16; - } -} - -header_type lisp_t { - fields { - flags : 8; - nonce : 24; - lsbsInstanceId : 32; - } -} - -header_type vntag_t { - fields { - direction : 1; - pointer : 1; - destVif : 14; - looped : 1; - reserved : 1; - version : 2; - srcVif : 12; - } -} - -header_type bfd_t { - fields { - version : 3; - diag : 5; - state : 2; - p : 1; - f : 1; - c : 1; - a : 1; - d : 1; - m : 1; - detectMult : 8; - len : 8; - myDiscriminator : 32; - yourDiscriminator : 32; - desiredMinTxInterval : 32; - requiredMinRxInterval : 32; - requiredMinEchoRxInterval : 32; - } -} - -header_type sflow_t { - fields { - version : 32; - ipVersion : 32; - ipAddress : 32; - subAgentId : 32; - seqNumber : 32; - uptime : 32; - numSamples : 32; - } -} - -header_type sflow_internal_ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type sflow_sample_t { - fields { - enterprise : 20; - format : 12; - sampleLength : 32; - seqNumer : 32; - srcIdClass : 8; - srcIdIndex : 24; - samplingRate : 32; - samplePool : 32; - numDrops : 32; - inputIfindex : 32; - outputIfindex : 32; - numFlowRecords : 32; - } -} - -header_type sflow_record_t { - fields { - enterprise : 20; - format : 12; - flowDataLength : 32; - headerProtocol : 32; - frameLength : 32; - bytesRemoved : 32; - headerSize : 32; - } -} -# 451 "p4src/includes/headers.p4" -header_type fabric_header_internal_t { - fields { - packetType : 3; - pad1 : 5; - ingress_tunnel_type : 8; - egress_bd : 16; - nexthop_index : 16; - lkp_mac_type : 16; - routed : 1; - outer_routed : 1; - tunnel_terminate : 1; - header_count : 4; - pad2 : 1; - - - - - } -} - -header_type fabric_header_t { - fields { - packetType : 3; - headerVersion : 2; - packetVersion : 2; - pad1 : 1; - - fabricColor : 3; - fabricQos : 5; - - dstDevice : 8; - dstPort : 16; - } -} - -header_type fabric_header_unicast_t { - fields { - headerCount : 4; - tunnelTerminate : 1; - routed : 1; - outerRouted : 1; - pad : 1; - ingressTunnelType : 8; - egressBd : 16; - lkpMacType : 16; - nexthopIndex : 16; - } -} - -header_type fabric_header_multicast_t { - fields { - tunnelTerminate : 1; - routed : 1; - outerRouted : 1; - pad1 : 5; - ingressTunnelType : 8; - egressBd : 16; - lkpMacType : 16; - - mcastGrpA : 16; - mcastGrpB : 16; - ingressRid : 16; - l1ExclusionId : 16; - l2ExclusionId : 9; - pad2 : 7; - l1McastHash : 13; - pad3 : 3; - l2McastHash : 13; - pad4 : 3; - } -} - -header_type fabric_header_mirror_t { - fields { - rewriteIndex : 16; - egressPort : 10; - egressQueue : 5; - pad : 1; - } -} - -header_type fabric_header_control_t { - fields { - egressPort : 10; - egressQueue : 5; - pad : 1; - type_ : 1; - dir : 1; - redirectToCpu : 1; - forwardingBypass : 1; - aclBypass : 1; - reserved : 3; - } -} - -header_type fabric_header_cpu_t { - fields { - reserved : 11; - egressQueue : 5; - port : 16; - } -} - -header_type fabric_payload_header_t { - fields { - etherType : 16; - } -} -# 9 "p4src/switch.p4" 2 -# 1 "p4src/includes/parser.p4" 1 - - - -parser start { - set_metadata(ingress_metadata.drop_0, 0); - return parse_ethernet; -} -# 71 "p4src/includes/parser.p4" -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0 mask 0xfe00: parse_llc_header; - 0 mask 0xfa00: parse_llc_header; - 0x9000 : parse_fabric_header; - 0x8100, 0x9100 : parse_vlan; 0x8847 : parse_mpls; 0x0800 : parse_ipv4; 0x86dd : parse_ipv6; 0x0806 : parse_arp_rarp; 0x8035 : parse_arp_rarp; 0x8915 : parse_roce; 0x8906 : parse_fcoe; 0x8926 : parse_vntag; 0x88cc : parse_set_prio_high; 0x8809 : parse_set_prio_high; default: ingress; - } -} - -header llc_header_t llc_header; - -parser parse_llc_header { - extract(llc_header); - return select(llc_header.dsap, llc_header.ssap) { - 0xAAAA : parse_snap_header; - 0xFEFE : parse_set_prio_med; - default: ingress; - } -} - -header snap_header_t snap_header; - -parser parse_snap_header { - extract(snap_header); - return select(latest.type_) { - 0x8100, 0x9100 : parse_vlan; 0x8847 : parse_mpls; 0x0800 : parse_ipv4; 0x86dd : parse_ipv6; 0x0806 : parse_arp_rarp; 0x8035 : parse_arp_rarp; 0x8915 : parse_roce; 0x8906 : parse_fcoe; 0x8926 : parse_vntag; 0x88cc : parse_set_prio_high; 0x8809 : parse_set_prio_high; default: ingress; - } -} - -header roce_header_t roce; - -parser parse_roce { - extract(roce); - return ingress; -} - -header fcoe_header_t fcoe; - -parser parse_fcoe { - extract(fcoe); - return ingress; -} - - -header vlan_tag_t vlan_tag_[2]; -header vlan_tag_3b_t vlan_tag_3b[2]; -header vlan_tag_5b_t vlan_tag_5b[2]; - -parser parse_vlan { - extract(vlan_tag_[next]); - return select(latest.etherType) { - 0x8100, 0x9100 : parse_vlan; 0x8847 : parse_mpls; 0x0800 : parse_ipv4; 0x86dd : parse_ipv6; 0x0806 : parse_arp_rarp; 0x8035 : parse_arp_rarp; 0x8915 : parse_roce; 0x8906 : parse_fcoe; 0x8926 : parse_vntag; 0x88cc : parse_set_prio_high; 0x8809 : parse_set_prio_high; default: ingress; - } -} - - - -header mpls_t mpls[3]; - - -parser parse_mpls { - extract(mpls[next]); - return select(latest.bos) { - 0 : parse_mpls; - 1 : parse_mpls_bos; - default: ingress; - } -} - -parser parse_mpls_bos { -# 158 "p4src/includes/parser.p4" - return select(current(0, 4)) { - 0x4 : parse_mpls_inner_ipv4; - 0x6 : parse_mpls_inner_ipv6; - default: parse_eompls; - } - -} - -parser parse_mpls_inner_ipv4 { - set_metadata(tunnel_metadata.ingress_tunnel_type, 6); - return parse_inner_ipv4; -} - -parser parse_mpls_inner_ipv6 { - set_metadata(tunnel_metadata.ingress_tunnel_type, 6); - return parse_inner_ipv6; -} - -parser parse_vpls { - return ingress; -} - -parser parse_pw { - return ingress; -} -# 206 "p4src/includes/parser.p4" -header ipv4_t ipv4; - -field_list ipv4_checksum_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_checksum { - input { - ipv4_checksum_list; - } - algorithm : csum16; - output_width : 16; -} - -calculated_field ipv4.hdrChecksum { - - verify ipv4_checksum; - update ipv4_checksum; - - - - -} - -parser parse_ipv4 { - extract(ipv4); - set_metadata(ingress_metadata.ipv4_dstaddr_24b, latest.dstAddr); - return select(latest.fragOffset, latest.ihl, latest.protocol) { - 0x501 : parse_icmp; - 0x506 : parse_tcp; - 0x511 : parse_udp; - 0x52f : parse_gre; - 0x504 : parse_inner_ipv4; - 0x529 : parse_inner_ipv6; - 2 : parse_set_prio_med; - 88 : parse_set_prio_med; - 89 : parse_set_prio_med; - 103 : parse_set_prio_med; - 112 : parse_set_prio_med; - default: ingress; - } -} - -header ipv6_t ipv6; - -parser parse_ipv6 { - extract(ipv6); - set_metadata(ipv6_metadata.lkp_ipv6_sa, latest.srcAddr); - set_metadata(ipv6_metadata.lkp_ipv6_da, latest.dstAddr); - return select(latest.nextHdr) { - 58 : parse_icmp; - 6 : parse_tcp; - 17 : parse_udp; - 47 : parse_gre; - 4 : parse_inner_ipv4; - 41 : parse_inner_ipv6; - - 88 : parse_set_prio_med; - 89 : parse_set_prio_med; - 103 : parse_set_prio_med; - 112 : parse_set_prio_med; - - default: ingress; - } -} - -header icmp_t icmp; - -parser parse_icmp { - extract(icmp); - set_metadata(ingress_metadata.lkp_icmp_type, latest.type_); - set_metadata(ingress_metadata.lkp_icmp_code, latest.code); - return select(latest.type_) { - - 0x82 mask 0xfe : parse_set_prio_med; - 0x84 mask 0xfc : parse_set_prio_med; - 0x88 : parse_set_prio_med; - default: ingress; - } -} - - - - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - set_metadata(ingress_metadata.lkp_l4_sport, latest.srcPort); - set_metadata(ingress_metadata.lkp_l4_dport, latest.dstPort); - return select(latest.dstPort) { - 179 : parse_set_prio_med; - 639 : parse_set_prio_med; - default: ingress; - } -} -# 327 "p4src/includes/parser.p4" -header udp_t udp; - -header roce_v2_header_t roce_v2; - -parser parse_roce_v2 { - extract(roce_v2); - return ingress; -} - -parser parse_udp { - extract(udp); - set_metadata(ingress_metadata.lkp_l4_sport, latest.srcPort); - set_metadata(ingress_metadata.lkp_l4_dport, latest.dstPort); - return select(latest.dstPort) { - 4789 : parse_vxlan; - 6081: parse_geneve; - 4791: parse_roce_v2; - - - - - - 67 : parse_set_prio_med; - 68 : parse_set_prio_med; - 546 : parse_set_prio_med; - 547 : parse_set_prio_med; - 520 : parse_set_prio_med; - 521 : parse_set_prio_med; - 1985 : parse_set_prio_med; - default: ingress; - } -} - -header sctp_t sctp; - -parser parse_sctp { - extract(sctp); - return ingress; -} - - - - - -header gre_t gre; - -parser parse_gre { - extract(gre); - return select(latest.C, latest.R, latest.K, latest.S, latest.s, - latest.recurse, latest.flags, latest.ver, latest.proto) { - 0x20006558 : parse_nvgre; - 0x0800 : parse_gre_ipv4; - 0x86dd : parse_gre_ipv6; - 0x88BE : parse_erspan_v1; - 0x22EB : parse_erspan_v2; - - - - default: ingress; - } -} - -parser parse_gre_ipv4 { - set_metadata(tunnel_metadata.ingress_tunnel_type, 2); - return parse_inner_ipv4; -} - -parser parse_gre_ipv6 { - set_metadata(tunnel_metadata.ingress_tunnel_type, 2); - return parse_inner_ipv6; -} - -header nvgre_t nvgre; -header ethernet_t inner_ethernet; - -header ipv4_t inner_ipv4; -header ipv6_t inner_ipv6; -header ipv4_t outer_ipv4; -header ipv6_t outer_ipv6; - -field_list inner_ipv4_checksum_list { - inner_ipv4.version; - inner_ipv4.ihl; - inner_ipv4.diffserv; - inner_ipv4.totalLen; - inner_ipv4.identification; - inner_ipv4.flags; - inner_ipv4.fragOffset; - inner_ipv4.ttl; - inner_ipv4.protocol; - inner_ipv4.srcAddr; - inner_ipv4.dstAddr; -} - -field_list_calculation inner_ipv4_checksum { - input { - inner_ipv4_checksum_list; - } - algorithm : csum16; - output_width : 16; -} - -calculated_field inner_ipv4.hdrChecksum { - - verify inner_ipv4_checksum; - update inner_ipv4_checksum; - - - - -} - -header udp_t outer_udp; - -parser parse_nvgre { - extract(nvgre); - set_metadata(tunnel_metadata.ingress_tunnel_type, 4); - set_metadata(tunnel_metadata.tunnel_vni, latest.tni); - return parse_inner_ethernet; -} - -header erspan_header_v1_t erspan_v1_header; - -parser parse_erspan_v1 { - extract(erspan_v1_header); - return ingress; -} - -header erspan_header_v2_t erspan_v2_header; - -parser parse_erspan_v2 { - extract(erspan_v2_header); - return ingress; -} - - - -header arp_rarp_t arp_rarp; - -parser parse_arp_rarp { - extract(arp_rarp); - return select(latest.protoType) { - 0x0800 : parse_arp_rarp_ipv4; - default: ingress; - } -} - -header arp_rarp_ipv4_t arp_rarp_ipv4; - -parser parse_arp_rarp_ipv4 { - extract(arp_rarp_ipv4); - return parse_set_prio_med; -} - -header eompls_t eompls; - -parser parse_eompls { - - set_metadata(tunnel_metadata.ingress_tunnel_type, 5); - return parse_inner_ethernet; -} - -header vxlan_t vxlan; - -parser parse_vxlan { - extract(vxlan); - set_metadata(tunnel_metadata.ingress_tunnel_type, 1); - set_metadata(tunnel_metadata.tunnel_vni, latest.vni); - return parse_inner_ethernet; -} - -header genv_t genv; - -parser parse_geneve { - extract(genv); - set_metadata(tunnel_metadata.tunnel_vni, latest.vni); - set_metadata(tunnel_metadata.ingress_tunnel_type, 3); - return select(genv.ver, genv.optLen, genv.protoType) { - 0x6558 : parse_inner_ethernet; - 0x0800 : parse_inner_ipv4; - 0x86dd : parse_inner_ipv6; - default : ingress; - } -} - -header nsh_t nsh; -header nsh_context_t nsh_context; - -parser parse_nsh { - extract(nsh); - extract(nsh_context); - return select(nsh.protoType) { - 0x0800 : parse_inner_ipv4; - 0x86dd : parse_inner_ipv6; - 0x6558 : parse_inner_ethernet; - default : ingress; - } -} - -header lisp_t lisp; - -parser parse_lisp { - extract(lisp); - return select(current(0, 4)) { - 0x4 : parse_inner_ipv4; - 0x6 : parse_inner_ipv6; - default : ingress; - } -} - -parser parse_inner_ipv4 { - extract(inner_ipv4); - return select(latest.fragOffset, latest.ihl, latest.protocol) { - 0x501 : parse_inner_icmp; - 0x506 : parse_inner_tcp; - 0x511 : parse_inner_udp; - default: ingress; - } -} - -header icmp_t inner_icmp; - -parser parse_inner_icmp { - extract(inner_icmp); - set_metadata(ingress_metadata.lkp_inner_icmp_type, latest.type_); - set_metadata(ingress_metadata.lkp_inner_icmp_code, latest.code); - return ingress; -} - -header tcp_t inner_tcp; - -parser parse_inner_tcp { - extract(inner_tcp); - set_metadata(ingress_metadata.lkp_inner_l4_sport, latest.srcPort); - set_metadata(ingress_metadata.lkp_inner_l4_dport, latest.dstPort); - return ingress; -} - -header udp_t inner_udp; - -parser parse_inner_udp { - extract(inner_udp); - set_metadata(ingress_metadata.lkp_inner_l4_sport, latest.srcPort); - set_metadata(ingress_metadata.lkp_inner_l4_dport, latest.dstPort); - return ingress; -} - -header sctp_t inner_sctp; - -parser parse_inner_sctp { - extract(inner_sctp); - return ingress; -} - -parser parse_inner_ipv6 { - extract(inner_ipv6); - return select(latest.nextHdr) { - 58 : parse_inner_icmp; - 6 : parse_inner_tcp; - 17 : parse_inner_udp; - default: ingress; - } -} - -parser parse_inner_ethernet { - extract(inner_ethernet); - return select(latest.etherType) { - 0x0800 : parse_inner_ipv4; - 0x86dd : parse_inner_ipv6; - default: ingress; - } -} - -header trill_t trill; - -parser parse_trill { - extract(trill); - return parse_inner_ethernet; -} - -header vntag_t vntag; - -parser parse_vntag { - extract(vntag); - return parse_inner_ethernet; -} - -header bfd_t bfd; - -parser parse_bfd { - extract(bfd); - return parse_set_prio_max; -} - -header sflow_t sflow; -header sflow_internal_ethernet_t sflow_internal_ethernet; -header sflow_sample_t sflow_sample; -header sflow_record_t sflow_record; - -parser parse_sflow { - extract(sflow); - return ingress; -} - -parser parse_bf_internal_sflow { - extract(sflow_internal_ethernet); - extract(sflow_sample); - extract(sflow_record); - return ingress; -} - -header fabric_header_t fabric_header; -header fabric_header_unicast_t fabric_header_unicast; -header fabric_header_multicast_t fabric_header_multicast; -header fabric_header_mirror_t fabric_header_mirror; -header fabric_header_control_t fabric_header_control; -header fabric_header_cpu_t fabric_header_cpu; -header fabric_payload_header_t fabric_payload_header; - -parser parse_fabric_header { - return select(current(0, 3)) { - 1 : parse_internal_fabric_header; - default : parse_external_fabric_header; - } -} - -parser parse_internal_fabric_header { - - - - - return ingress; - -} - -parser parse_external_fabric_header { - extract(fabric_header); - return select(latest.packetType) { - 2 : parse_fabric_header_unicast; - 3 : parse_fabric_header_multicast; - 4 : parse_fabric_header_mirror; - 5 : parse_fabric_header_control; - 6 : parse_fabric_header_cpu; - default : ingress; - } -} - -parser parse_fabric_header_unicast { - extract(fabric_header_unicast); - return parse_fabric_payload_header; -} - -parser parse_fabric_header_multicast { - extract(fabric_header_multicast); - return parse_fabric_payload_header; -} - -parser parse_fabric_header_mirror { - extract(fabric_header_mirror); - return parse_fabric_payload_header; -} - -parser parse_fabric_header_control { - extract(fabric_header_control); - return parse_fabric_payload_header; -} - -parser parse_fabric_header_cpu { - extract(fabric_header_cpu); - set_metadata(ig_intr_md_for_tm.ucast_egress_port, latest.port); - return parse_fabric_payload_header; -} - -parser parse_fabric_payload_header { - extract(fabric_payload_header); - return select(latest.etherType) { - 0 mask 0xfe00: parse_llc_header; - 0 mask 0xfa00: parse_llc_header; - 0x8100, 0x9100 : parse_vlan; 0x8847 : parse_mpls; 0x0800 : parse_ipv4; 0x86dd : parse_ipv6; 0x0806 : parse_arp_rarp; 0x8035 : parse_arp_rarp; 0x8915 : parse_roce; 0x8906 : parse_fcoe; 0x8926 : parse_vntag; 0x88cc : parse_set_prio_high; 0x8809 : parse_set_prio_high; default: ingress; - } -} -# 718 "p4src/includes/parser.p4" -parser parse_set_prio_med { - set_metadata(ig_prsr_ctrl.priority, 3); - return ingress; -} - -parser parse_set_prio_high { - set_metadata(ig_prsr_ctrl.priority, 5); - return ingress; -} - -parser parse_set_prio_max { - set_metadata(ig_prsr_ctrl.priority, 7); - return ingress; -} -# 10 "p4src/switch.p4" 2 -# 1 "p4src/includes/sizes.p4" 1 -# 11 "p4src/switch.p4" 2 -# 1 "p4src/includes/defines.p4" 1 -# 12 "p4src/switch.p4" 2 - - -header_type ingress_metadata_t { - fields { - lkp_l4_sport : 16; - lkp_l4_dport : 16; - lkp_inner_l4_sport : 16; - lkp_inner_l4_dport : 16; - - lkp_icmp_type : 8; - lkp_icmp_code : 8; - lkp_inner_icmp_type : 8; - lkp_inner_icmp_code : 8; - - ifindex : 16; - vrf : 2; - - outer_bd : 16; - outer_dscp : 8; - - src_is_link_local : 1; - bd : 16; - uuc_mc_index : 16; - umc_mc_index : 16; - bcast_mc_index : 16; - - if_label : 16; - bd_label : 16; - - ipsg_check_fail : 1; - - mirror_session_id : 10; - - marked_cos : 3; - marked_dscp : 8; - marked_exp : 3; - - egress_ifindex : 16; - same_bd_check : 16; - - ipv4_dstaddr_24b : 24; - drop_0 : 1; - drop_reason : 8; - control_frame: 1; - } -} - -header_type egress_metadata_t { - fields { - payload_length : 16; - smac_idx : 9; - bd : 16; - inner_replica : 1; - replica : 1; - mac_da : 48; - routed : 1; - same_bd_check : 16; - - header_count: 4; - - drop_reason : 8; - egress_bypass : 1; - fabric_bypass : 1; - drop_exception : 8; - } -} - -metadata ingress_metadata_t ingress_metadata; -metadata egress_metadata_t egress_metadata; - -# 1 "p4src/port.p4" 1 - -action set_valid_outer_unicast_packet_untagged() { - modify_field(l2_metadata.lkp_pkt_type, 1); - modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); - add_i_fabric_header(ethernet.etherType); -} - -action set_valid_outer_unicast_packet_single_tagged() { - modify_field(l2_metadata.lkp_pkt_type, 1); - modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); - add_i_fabric_header(vlan_tag_[0].etherType); -} - -action set_valid_outer_unicast_packet_double_tagged() { - modify_field(l2_metadata.lkp_pkt_type, 1); - modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); - add_i_fabric_header(vlan_tag_[1].etherType); -} - -action set_valid_outer_unicast_packet_qinq_tagged() { - modify_field(l2_metadata.lkp_pkt_type, 1); - modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); - add_i_fabric_header(ethernet.etherType); -} - -action set_valid_outer_multicast_packet_untagged() { - modify_field(l2_metadata.lkp_pkt_type, 2); - modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); - add_i_fabric_header(ethernet.etherType); -} - -action set_valid_outer_multicast_packet_single_tagged() { - modify_field(l2_metadata.lkp_pkt_type, 2); - modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); - add_i_fabric_header(vlan_tag_[0].etherType); -} - -action set_valid_outer_multicast_packet_double_tagged() { - modify_field(l2_metadata.lkp_pkt_type, 2); - modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); - add_i_fabric_header(vlan_tag_[1].etherType); -} - -action set_valid_outer_multicast_packet_qinq_tagged() { - modify_field(l2_metadata.lkp_pkt_type, 2); - modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); - add_i_fabric_header(ethernet.etherType); -} - -action set_valid_outer_broadcast_packet_untagged() { - modify_field(l2_metadata.lkp_pkt_type, 4); - modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); - add_i_fabric_header(ethernet.etherType); -} - -action set_valid_outer_broadcast_packet_single_tagged() { - modify_field(l2_metadata.lkp_pkt_type, 4); - modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); - add_i_fabric_header(vlan_tag_[0].etherType); -} - -action set_valid_outer_broadcast_packet_double_tagged() { - modify_field(l2_metadata.lkp_pkt_type, 4); - modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); - add_i_fabric_header(vlan_tag_[1].etherType); -} - -action set_valid_outer_broadcast_packet_qinq_tagged() { - modify_field(l2_metadata.lkp_pkt_type, 4); - modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 511); - add_i_fabric_header(ethernet.etherType); -} - -table validate_outer_ethernet { - reads { - ethernet.dstAddr : ternary; - vlan_tag_[0] : valid; - vlan_tag_[1] : valid; - } - actions { - set_valid_outer_unicast_packet_untagged; - set_valid_outer_unicast_packet_single_tagged; - set_valid_outer_unicast_packet_double_tagged; - set_valid_outer_unicast_packet_qinq_tagged; - set_valid_outer_multicast_packet_untagged; - set_valid_outer_multicast_packet_single_tagged; - set_valid_outer_multicast_packet_double_tagged; - set_valid_outer_multicast_packet_qinq_tagged; - set_valid_outer_broadcast_packet_untagged; - set_valid_outer_broadcast_packet_single_tagged; - set_valid_outer_broadcast_packet_double_tagged; - set_valid_outer_broadcast_packet_qinq_tagged; - } - size : 64; -} - -control validate_outer_ethernet_header { - apply(validate_outer_ethernet); -} -action set_ifindex(ifindex, if_label, exclusion_id) { - modify_field(ingress_metadata.ifindex, ifindex); - modify_field(ig_intr_md_for_tm.level2_exclusion_id, exclusion_id); - modify_field(ingress_metadata.if_label, if_label); -} - -table port_mapping { - reads { - ig_intr_md.ingress_port : exact; - } - actions { - set_ifindex; - } - size : 288; -} - -control process_port_mapping { - apply(port_mapping); -} - -action set_bd_ipv4_mcast_switch_ipv6_mcast_switch_flags(bd, vrf, - rmac_group, mrpf_group, - bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, - ipv4_unicast_enabled, ipv6_unicast_enabled, - ipv4_multicast_mode, ipv6_multicast_mode, - igmp_snooping_enabled, mld_snooping_enabled, - ipv4_urpf_mode, ipv6_urpf_mode, - stp_group, exclusion_id, stats_idx) { - modify_field(ingress_metadata.vrf, vrf); - modify_field(ingress_metadata.bd, bd); - modify_field(ingress_metadata.outer_bd, bd); - modify_field(multicast_metadata.outer_ipv4_mcast_key_type, 0); - modify_field(multicast_metadata.outer_ipv4_mcast_key, bd); - modify_field(multicast_metadata.outer_ipv6_mcast_key_type, 0); - modify_field(multicast_metadata.outer_ipv6_mcast_key, bd); - - modify_field(ipv4_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); - modify_field(ipv6_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled); - modify_field(multicast_metadata.ipv4_multicast_mode, ipv4_multicast_mode); - modify_field(multicast_metadata.ipv6_multicast_mode, ipv6_multicast_mode); - modify_field(multicast_metadata.igmp_snooping_enabled, igmp_snooping_enabled); - modify_field(multicast_metadata.mld_snooping_enabled, mld_snooping_enabled); - modify_field(ipv4_metadata.ipv4_urpf_mode, ipv4_urpf_mode); - modify_field(ipv6_metadata.ipv6_urpf_mode, ipv6_urpf_mode); - modify_field(l3_metadata.rmac_group, rmac_group); - modify_field(multicast_metadata.bd_mrpf_group, mrpf_group); - modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); - modify_field(ingress_metadata.umc_mc_index, umc_mc_index); - modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); - modify_field(ingress_metadata.bd_label, bd_label); - modify_field(l2_metadata.stp_group, stp_group); - modify_field(ig_intr_md_for_tm.level1_exclusion_id, exclusion_id); - modify_field(l2_metadata.bd_stats_idx, stats_idx); -} - -action set_bd_ipv4_mcast_switch_ipv6_mcast_route_flags(bd, vrf, - rmac_group, mrpf_group, - bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, - ipv4_unicast_enabled, ipv6_unicast_enabled, - ipv4_multicast_mode, ipv6_multicast_mode, - igmp_snooping_enabled, mld_snooping_enabled, - ipv4_urpf_mode, ipv6_urpf_mode, - stp_group, exclusion_id, stats_idx) { - modify_field(ingress_metadata.vrf, vrf); - modify_field(ingress_metadata.bd, bd); - modify_field(ingress_metadata.outer_bd, bd); - modify_field(multicast_metadata.outer_ipv4_mcast_key_type, 0); - modify_field(multicast_metadata.outer_ipv4_mcast_key, bd); - modify_field(multicast_metadata.outer_ipv6_mcast_key_type, 1); - modify_field(multicast_metadata.outer_ipv6_mcast_key, vrf); - - modify_field(ipv4_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); - modify_field(ipv6_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled); - modify_field(multicast_metadata.ipv4_multicast_mode, ipv4_multicast_mode); - modify_field(multicast_metadata.ipv6_multicast_mode, ipv6_multicast_mode); - modify_field(multicast_metadata.igmp_snooping_enabled, igmp_snooping_enabled); - modify_field(multicast_metadata.mld_snooping_enabled, mld_snooping_enabled); - modify_field(ipv4_metadata.ipv4_urpf_mode, ipv4_urpf_mode); - modify_field(ipv6_metadata.ipv6_urpf_mode, ipv6_urpf_mode); - modify_field(l3_metadata.rmac_group, rmac_group); - modify_field(multicast_metadata.bd_mrpf_group, mrpf_group); - modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); - modify_field(ingress_metadata.umc_mc_index, umc_mc_index); - modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); - modify_field(ingress_metadata.bd_label, bd_label); - modify_field(l2_metadata.stp_group, stp_group); - modify_field(ig_intr_md_for_tm.level1_exclusion_id, exclusion_id); - modify_field(l2_metadata.bd_stats_idx, stats_idx); -} - -action set_bd_ipv4_mcast_route_ipv6_mcast_switch_flags(bd, vrf, - rmac_group, mrpf_group, - bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, - ipv4_unicast_enabled, ipv6_unicast_enabled, - ipv4_multicast_mode, ipv6_multicast_mode, - igmp_snooping_enabled, mld_snooping_enabled, - ipv4_urpf_mode, ipv6_urpf_mode, - stp_group, exclusion_id, stats_idx) { - modify_field(ingress_metadata.vrf, vrf); - modify_field(ingress_metadata.bd, bd); - modify_field(ingress_metadata.outer_bd, bd); - modify_field(multicast_metadata.outer_ipv4_mcast_key_type, 1); - modify_field(multicast_metadata.outer_ipv4_mcast_key, vrf); - modify_field(multicast_metadata.outer_ipv6_mcast_key_type, 0); - modify_field(multicast_metadata.outer_ipv6_mcast_key, bd); - - modify_field(ipv4_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); - modify_field(ipv6_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled); - modify_field(multicast_metadata.ipv4_multicast_mode, ipv4_multicast_mode); - modify_field(multicast_metadata.ipv6_multicast_mode, ipv6_multicast_mode); - modify_field(multicast_metadata.igmp_snooping_enabled, igmp_snooping_enabled); - modify_field(multicast_metadata.mld_snooping_enabled, mld_snooping_enabled); - modify_field(ipv4_metadata.ipv4_urpf_mode, ipv4_urpf_mode); - modify_field(ipv6_metadata.ipv6_urpf_mode, ipv6_urpf_mode); - modify_field(l3_metadata.rmac_group, rmac_group); - modify_field(multicast_metadata.bd_mrpf_group, mrpf_group); - modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); - modify_field(ingress_metadata.umc_mc_index, umc_mc_index); - modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); - modify_field(ingress_metadata.bd_label, bd_label); - modify_field(l2_metadata.stp_group, stp_group); - modify_field(ig_intr_md_for_tm.level1_exclusion_id, exclusion_id); - modify_field(l2_metadata.bd_stats_idx, stats_idx); -} - -action set_bd_ipv4_mcast_route_ipv6_mcast_route_flags(bd, vrf, - rmac_group, mrpf_group, - bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, - ipv4_unicast_enabled, ipv6_unicast_enabled, - ipv4_multicast_mode, ipv6_multicast_mode, - igmp_snooping_enabled, mld_snooping_enabled, - ipv4_urpf_mode, ipv6_urpf_mode, - stp_group, exclusion_id, stats_idx) { - modify_field(ingress_metadata.vrf, vrf); - modify_field(ingress_metadata.bd, bd); - modify_field(ingress_metadata.outer_bd, bd); - modify_field(multicast_metadata.outer_ipv4_mcast_key_type, 1); - modify_field(multicast_metadata.outer_ipv4_mcast_key, vrf); - modify_field(multicast_metadata.outer_ipv6_mcast_key_type, 1); - modify_field(multicast_metadata.outer_ipv6_mcast_key, vrf); - - modify_field(ipv4_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); - modify_field(ipv6_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled); - modify_field(multicast_metadata.ipv4_multicast_mode, ipv4_multicast_mode); - modify_field(multicast_metadata.ipv6_multicast_mode, ipv6_multicast_mode); - modify_field(multicast_metadata.igmp_snooping_enabled, igmp_snooping_enabled); - modify_field(multicast_metadata.mld_snooping_enabled, mld_snooping_enabled); - modify_field(ipv4_metadata.ipv4_urpf_mode, ipv4_urpf_mode); - modify_field(ipv6_metadata.ipv6_urpf_mode, ipv6_urpf_mode); - modify_field(l3_metadata.rmac_group, rmac_group); - modify_field(multicast_metadata.bd_mrpf_group, mrpf_group); - modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); - modify_field(ingress_metadata.umc_mc_index, umc_mc_index); - modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); - modify_field(ingress_metadata.bd_label, bd_label); - modify_field(l2_metadata.stp_group, stp_group); - modify_field(ig_intr_md_for_tm.level1_exclusion_id, exclusion_id); - modify_field(l2_metadata.bd_stats_idx, stats_idx); -} - -action set_bd(bd, vrf, rmac_group, - bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, - ipv4_unicast_enabled, - igmp_snooping_enabled, - stp_group, exclusion_id, stats_idx) { - modify_field(ingress_metadata.vrf, vrf); - modify_field(ipv4_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); - modify_field(multicast_metadata.igmp_snooping_enabled, igmp_snooping_enabled); - modify_field(l3_metadata.rmac_group, rmac_group); - modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); - modify_field(ingress_metadata.umc_mc_index, umc_mc_index); - modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); - modify_field(ingress_metadata.bd_label, bd_label); - modify_field(ingress_metadata.bd, bd); - modify_field(ingress_metadata.outer_bd, bd); - modify_field(l2_metadata.stp_group, stp_group); - modify_field(ig_intr_md_for_tm.level1_exclusion_id, exclusion_id); - modify_field(l2_metadata.bd_stats_idx, stats_idx); -} - -action_profile bd_action_profile { - actions { - set_bd; - set_bd_ipv4_mcast_switch_ipv6_mcast_switch_flags; - set_bd_ipv4_mcast_switch_ipv6_mcast_route_flags; - set_bd_ipv4_mcast_route_ipv6_mcast_switch_flags; - set_bd_ipv4_mcast_route_ipv6_mcast_route_flags; - } - size : 16384; -} - -table port_vlan_mapping { - reads { - ingress_metadata.ifindex : exact; - vlan_tag_[0] : valid; - vlan_tag_[0].vid : exact; - vlan_tag_[1] : valid; - vlan_tag_[1].vid : exact; - } - - action_profile: bd_action_profile; - size : 32768; -} - -control process_port_vlan_mapping { - apply(port_vlan_mapping); -} - - -counter ingress_bd_stats { - type : packets_and_bytes; - instance_count : 16384; -} - -action update_ingress_bd_stats() { - count(ingress_bd_stats, l2_metadata.bd_stats_idx); -} - -table ingress_bd_stats { - actions { - update_ingress_bd_stats; - } - size : 64; -} - - -control process_ingress_bd_stats { - apply(ingress_bd_stats); -} - -field_list lag_hash_fields { - l2_metadata.lkp_mac_sa; - l2_metadata.lkp_mac_da; - i_fabric_header.lkp_mac_type; - ipv4_metadata.lkp_ipv4_sa; - ipv4_metadata.lkp_ipv4_da; - l3_metadata.lkp_ip_proto; - ingress_metadata.lkp_l4_sport; - ingress_metadata.lkp_l4_dport; -} - -field_list_calculation lag_hash { - input { - lag_hash_fields; - } - algorithm : crc16; - output_width : 8; -} - -action_selector lag_selector { - selection_key : lag_hash; -} - - - - - - - -action set_lag_port(port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - - -action_profile lag_action_profile { - actions { - nop; - set_lag_port; - } - size : 1024; - dynamic_action_selection : lag_selector; -} - -table lag_group { - reads { - ingress_metadata.egress_ifindex : exact; - } - action_profile: lag_action_profile; - size : 1024; -} - -control process_lag { - apply(lag_group); -} - -action set_egress_packet_vlan_tagged(vlan_id) { - add_header(vlan_tag_[0]); - modify_field(vlan_tag_[0].etherType, ethernet.etherType); - modify_field(vlan_tag_[0].vid, vlan_id); - modify_field(ethernet.etherType, 0x8100); -} - -action set_egress_packet_vlan_untagged() { -} - -table egress_vlan_xlate { - reads { - eg_intr_md.egress_port : exact; - egress_metadata.bd : exact; - } - actions { - set_egress_packet_vlan_tagged; - set_egress_packet_vlan_untagged; - } - size : 32768; -} - -control process_vlan_xlate { - apply(egress_vlan_xlate); -} -# 83 "p4src/switch.p4" 2 -# 1 "p4src/l2.p4" 1 -header_type l2_metadata_t { - fields { - lkp_pkt_type : 3; - lkp_mac_sa : 48; - lkp_mac_da : 48; - - l2_nexthop : 16; - l2_nexthop_type : 1; - l2_redirect : 1; - l2_src_miss : 1; - l2_src_move : 16; - stp_group: 10; - stp_state : 3; - bd_stats_idx : 16; - } -} - -metadata l2_metadata_t l2_metadata; -# 37 "p4src/l2.p4" -control process_spanning_tree { - - - - - -} -# 117 "p4src/l2.p4" -control process_mac { - - - - -} -# 149 "p4src/l2.p4" -control process_mac_learning { - - - -} - -action set_unicast() { -} - -action set_unicast_and_ipv6_src_is_link_local() { - modify_field(ingress_metadata.src_is_link_local, 1); -} - -action set_multicast() { - add_to_field(l2_metadata.bd_stats_idx, 1); -} - -action set_ip_multicast() { - modify_field(multicast_metadata.ip_multicast, 1); - add_to_field(l2_metadata.bd_stats_idx, 1); -} - -action set_ip_multicast_and_ipv6_src_is_link_local() { - modify_field(multicast_metadata.ip_multicast, 1); - modify_field(ingress_metadata.src_is_link_local, 1); - add_to_field(l2_metadata.bd_stats_idx, 1); -} - -action set_broadcast() { - add_to_field(l2_metadata.bd_stats_idx, 2); -} - -table validate_packet { - reads { - l2_metadata.lkp_mac_da : ternary; - - - - } - actions { - nop; - set_unicast; - set_unicast_and_ipv6_src_is_link_local; - set_multicast; - set_ip_multicast; - set_ip_multicast_and_ipv6_src_is_link_local; - set_broadcast; - } - size : 64; -} - -control process_validate_packet { - apply(validate_packet); -} - - -action rewrite_unicast_mac(smac) { - modify_field(ethernet.srcAddr, smac); - modify_field(ethernet.dstAddr, egress_metadata.mac_da); -} - -action rewrite_multicast_mac(smac) { - modify_field(ethernet.srcAddr, smac); - modify_field(ethernet.dstAddr, 0x01005E000000); - - - - add_to_field(ipv4.ttl, -1); -} - -table mac_rewrite { - reads { - egress_metadata.smac_idx : exact; - ipv4.dstAddr : ternary; - } - actions { - nop; - rewrite_unicast_mac; - rewrite_multicast_mac; - } - size : 512; -} - -control process_mac_rewrite { - if (i_fabric_header.routed == 1) { - apply(mac_rewrite); - } -} -# 286 "p4src/l2.p4" -control process_replication { -# 296 "p4src/l2.p4" -} - -action set_egress_bd_properties(nat_mode) { - modify_field(nat_metadata.egress_nat_mode, nat_mode); -} - -table egress_bd_map { - reads { - i_fabric_header.egress_bd : exact; - } - actions { - nop; - set_egress_bd_properties; - } - size : 16384; -} - -control process_egress_bd { - apply(egress_bd_map); -} - -action vlan_decap_nop() { - modify_field(ethernet.etherType, i_fabric_header.lkp_mac_type); -} - -action remove_vlan_single_tagged() { - remove_header(vlan_tag_[0]); - modify_field(ethernet.etherType, i_fabric_header.lkp_mac_type); -} - -action remove_vlan_double_tagged() { - remove_header(vlan_tag_[0]); - remove_header(vlan_tag_[1]); - modify_field(ethernet.etherType, i_fabric_header.lkp_mac_type); -} - -action remove_vlan_qinq_tagged() { - remove_header(vlan_tag_[0]); - remove_header(vlan_tag_[1]); - modify_field(ethernet.etherType, i_fabric_header.lkp_mac_type); -} - -table vlan_decap { - reads { - egress_metadata.drop_exception : exact; - vlan_tag_[0] : valid; - vlan_tag_[1] : valid; - } - actions { - vlan_decap_nop; - remove_vlan_single_tagged; - remove_vlan_double_tagged; - remove_vlan_qinq_tagged; - } - size: 256; -} - -control process_vlan_decap { - apply(vlan_decap); -} -# 84 "p4src/switch.p4" 2 -# 1 "p4src/l3.p4" 1 - - - - - header_type l3_metadata_t { - fields { - lkp_ip_type : 2; - lkp_ip_proto : 8; - lkp_ip_tc : 8; - lkp_ip_ttl : 8; - rmac_group : 10; - rmac_hit : 1; - urpf_mode : 2; - urpf_hit : 1; - urpf_check_fail :1; - urpf_bd_group : 16; - fib_hit : 1; - fib_nexthop : 16; - fib_nexthop_type : 1; - } - } - - metadata l3_metadata_t l3_metadata; - -action fib_hit_nexthop(nexthop_index) { - modify_field(l3_metadata.fib_hit, 1); - modify_field(l3_metadata.fib_nexthop, nexthop_index); - modify_field(l3_metadata.fib_nexthop_type, 0); -} - -action fib_hit_ecmp(ecmp_index) { - modify_field(l3_metadata.fib_hit, 1); - modify_field(l3_metadata.fib_nexthop, ecmp_index); - modify_field(l3_metadata.fib_nexthop_type, 1); -} - -action rmac_hit() { - modify_field(l3_metadata.rmac_hit, 1); - modify_field(ingress_metadata.egress_ifindex, 64); - modify_field(ig_intr_md_for_tm.mcast_grp_a, 0); - modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); - - - -} - -action rmac_miss() { - modify_field(l3_metadata.rmac_hit, 0); -} - -table rmac { - reads { - l3_metadata.rmac_group : exact; - l2_metadata.lkp_mac_da : exact; - } - actions { - rmac_hit; - rmac_miss; - } - size : 512; -} -# 85 "p4src/l3.p4" -control process_urpf_bd { - - - - - - -} -# 117 "p4src/l3.p4" -control process_mtu { - - - -} -# 85 "p4src/switch.p4" 2 -# 1 "p4src/ipv4.p4" 1 -# 18 "p4src/ipv4.p4" - header_type ipv4_metadata_t { - fields { - lkp_ipv4_sa : 32; - lkp_ipv4_da : 32; - ipv4_unicast_enabled : 1; - ipv4_urpf_mode : 2; - - fib_hit_exm_prefix_length_32 : 1; - fib_nexthop_exm_prefix_length_32 :10; - fib_nexthop_type_exm_prefix_length_32 : 1; - - fib_hit_exm_prefix_length_31 : 1; - fib_nexthop_exm_prefix_length_31 :10; - fib_nexthop_type_exm_prefix_length_31 : 1; - - fib_hit_exm_prefix_length_30 : 1; - fib_nexthop_exm_prefix_length_30 :10; - fib_nexthop_type_exm_prefix_length_30 : 1; - - fib_hit_exm_prefix_length_29 : 1; - fib_nexthop_exm_prefix_length_29 :10; - fib_nexthop_type_exm_prefix_length_29 : 1; - - fib_hit_exm_prefix_length_28 : 1; - fib_nexthop_exm_prefix_length_28 :10; - fib_nexthop_type_exm_prefix_length_28 : 1; - - fib_hit_exm_prefix_length_27 : 1; - fib_nexthop_exm_prefix_length_27 :10; - fib_nexthop_type_exm_prefix_length_27 : 1; - - fib_hit_exm_prefix_length_26 : 1; - fib_nexthop_exm_prefix_length_26 :10; - fib_nexthop_type_exm_prefix_length_26 : 1; - - fib_hit_exm_prefix_length_25 : 1; - fib_nexthop_exm_prefix_length_25 :10; - fib_nexthop_type_exm_prefix_length_25 : 1; - - fib_hit_exm_prefix_length_24 : 1; - fib_nexthop_exm_prefix_length_24 :10; - fib_nexthop_type_exm_prefix_length_24 : 1; - - fib_hit_exm_prefix_length_23 : 1; - fib_nexthop_exm_prefix_length_23 :10; - fib_nexthop_type_exm_prefix_length_23 : 1; - - fib_hit_lpm_prefix_range_22_to_0 : 1; - fib_nexthop_lpm_prefix_range_22_to_0 :10; - fib_nexthop_type_lpm_prefix_range_22_to_0 : 1; - - } - } - -metadata ipv4_metadata_t ipv4_metadata; - - - -action set_valid_outer_ipv4_packet() { - modify_field(l3_metadata.lkp_ip_type, 1); - modify_field(ipv4_metadata.lkp_ipv4_sa, ipv4.srcAddr); - modify_field(ipv4_metadata.lkp_ipv4_da, ipv4.dstAddr); - modify_field(l3_metadata.lkp_ip_proto, ipv4.protocol); - modify_field(l3_metadata.lkp_ip_tc, ipv4.diffserv); - modify_field(l3_metadata.lkp_ip_ttl, ipv4.ttl); -} - -action set_malformed_outer_ipv4_packet() { -} - -table validate_outer_ipv4_packet { - reads { - ipv4.version : exact; - ipv4.ihl : exact; - ipv4.ttl : exact; - ipv4.srcAddr : ternary; - ipv4.dstAddr : ternary; - } - actions { - set_valid_outer_ipv4_packet; - set_malformed_outer_ipv4_packet; - } - size : 64; -} - - -control validate_outer_ipv4_header { - - apply(validate_outer_ipv4_packet); - -} - - - -action fib_hit_exm_prefix_length_32_nexthop(nexthop_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_32, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_32, - nexthop_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_32, - 0); -} - -action fib_hit_exm_prefix_length_31_nexthop(nexthop_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_31, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_31, - nexthop_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_31, - 0); -} - -action fib_hit_exm_prefix_length_30_nexthop(nexthop_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_30, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_30, - nexthop_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_30, - 0); -} - -action fib_hit_exm_prefix_length_29_nexthop(nexthop_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_29, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_29, - nexthop_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_29, - 0); -} - -action fib_hit_exm_prefix_length_28_nexthop(nexthop_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_28, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_28, - nexthop_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_28, - 0); -} - -action fib_hit_exm_prefix_length_27_nexthop(nexthop_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_27, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_27, - nexthop_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_27, - 0); -} - -action fib_hit_exm_prefix_length_26_nexthop(nexthop_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_26, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_26, - nexthop_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_26, - 0); -} - -action fib_hit_exm_prefix_length_25_nexthop(nexthop_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_25, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_25, - nexthop_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_25, - 0); -} - -action fib_hit_exm_prefix_length_24_nexthop(nexthop_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_24, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_24, - nexthop_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_24, - 0); -} - -action fib_hit_exm_prefix_length_23_nexthop(nexthop_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_23, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_23, - nexthop_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_23, - 0); -} - -action fib_hit_lpm_prefix_range_22_to_0_nexthop(nexthop_index) { - modify_field(ipv4_metadata.fib_hit_lpm_prefix_range_22_to_0, 1); - modify_field(ipv4_metadata.fib_nexthop_lpm_prefix_range_22_to_0, - nexthop_index); - modify_field(ipv4_metadata.fib_nexthop_type_lpm_prefix_range_22_to_0, - 0); -} - -action fib_hit_exm_prefix_length_32_ecmp(ecmp_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_32, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_32, ecmp_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_32, - 1); -} - -action fib_hit_exm_prefix_length_31_ecmp(ecmp_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_31, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_31, ecmp_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_31, - 1); -} - -action fib_hit_exm_prefix_length_30_ecmp(ecmp_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_30, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_30, ecmp_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_30, - 1); -} - -action fib_hit_exm_prefix_length_29_ecmp(ecmp_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_29, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_29, ecmp_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_29, - 1); -} - -action fib_hit_exm_prefix_length_28_ecmp(ecmp_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_28, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_28, ecmp_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_28, - 1); -} - -action fib_hit_exm_prefix_length_27_ecmp(ecmp_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_27, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_27, ecmp_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_27, - 1); -} - -action fib_hit_exm_prefix_length_26_ecmp(ecmp_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_26, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_26, ecmp_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_26, - 1); -} - -action fib_hit_exm_prefix_length_25_ecmp(ecmp_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_25, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_25, ecmp_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_25, - 1); -} - -action fib_hit_exm_prefix_length_24_ecmp(ecmp_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_24, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_24, ecmp_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_24, - 1); -} - -action fib_hit_exm_prefix_length_23_ecmp(ecmp_index) { - modify_field(ipv4_metadata.fib_hit_exm_prefix_length_23, 1); - modify_field(ipv4_metadata.fib_nexthop_exm_prefix_length_23, ecmp_index); - modify_field(ipv4_metadata.fib_nexthop_type_exm_prefix_length_23, - 1); -} - -action fib_hit_lpm_prefix_range_22_to_0_ecmp(ecmp_index) { - modify_field(ipv4_metadata.fib_hit_lpm_prefix_range_22_to_0, 1); - modify_field(ipv4_metadata.fib_nexthop_lpm_prefix_range_22_to_0, - ecmp_index); - modify_field(ipv4_metadata.fib_nexthop_type_lpm_prefix_range_22_to_0, - 1); -} - -table ipv4_fib_exm_prefix_length_32 { - reads { - ingress_metadata.vrf : exact; - ipv4_metadata.lkp_ipv4_da : exact; - } - actions { - on_miss; - fib_hit_exm_prefix_length_32_nexthop; - fib_hit_exm_prefix_length_32_ecmp; - } - size : 19200; -} - -table ipv4_fib_exm_prefix_length_31 { - reads { - ingress_metadata.vrf : exact; - ipv4_metadata.lkp_ipv4_da mask 0xFFFFFFFE: exact; - } - actions { - on_miss; - fib_hit_exm_prefix_length_31_nexthop; - fib_hit_exm_prefix_length_31_ecmp; - } - size : 1024; -} - -table ipv4_fib_exm_prefix_length_30 { - reads { - ingress_metadata.vrf : exact; - ipv4_metadata.lkp_ipv4_da mask 0xFFFFFFFC: exact; - } - actions { - on_miss; - fib_hit_exm_prefix_length_30_nexthop; - fib_hit_exm_prefix_length_30_ecmp; - } - size : 23040; -} - -table ipv4_fib_exm_prefix_length_29 { - reads { - ingress_metadata.vrf : exact; - ipv4_metadata.lkp_ipv4_da mask 0xFFFFFFF8 : exact; - } - actions { - on_miss; - fib_hit_exm_prefix_length_29_nexthop; - fib_hit_exm_prefix_length_29_ecmp; - } - size : 15360; -} - -table ipv4_fib_exm_prefix_length_28 { - reads { - ingress_metadata.vrf : exact; - ipv4_metadata.lkp_ipv4_da mask 0xFFFFFFF0 : exact; - } - actions { - on_miss; - fib_hit_exm_prefix_length_28_nexthop; - fib_hit_exm_prefix_length_28_ecmp; - } - size : 30720; -} - -table ipv4_fib_exm_prefix_length_27 { - reads { - ingress_metadata.vrf : exact; - ipv4_metadata.lkp_ipv4_da mask 0xFFFFFFE0 : exact; - } - actions { - on_miss; - fib_hit_exm_prefix_length_27_nexthop; - fib_hit_exm_prefix_length_27_ecmp; - } - size : 7680; -} - -table ipv4_fib_exm_prefix_length_26 { - reads { - ingress_metadata.vrf : exact; - ipv4_metadata.lkp_ipv4_da mask 0xFFFFFFC0 : exact; - } - actions { - on_miss; - fib_hit_exm_prefix_length_26_nexthop; - fib_hit_exm_prefix_length_26_ecmp; - } - size : 7680; -} - -table ipv4_fib_exm_prefix_length_25 { - reads { - ingress_metadata.vrf : exact; - ipv4_metadata.lkp_ipv4_da mask 0xFFFFFF80 : exact; - } - actions { - on_miss; - fib_hit_exm_prefix_length_25_nexthop; - fib_hit_exm_prefix_length_25_ecmp; - } - size : 3840; -} - -table ipv4_fib_exm_prefix_length_24 { - reads { - ingress_metadata.vrf : exact; - ipv4_metadata.lkp_ipv4_da mask 0xFFFFFF00 : exact; - } - actions { - on_miss; - fib_hit_exm_prefix_length_24_nexthop; - fib_hit_exm_prefix_length_24_ecmp; - } - size : 38400; -} - -table ipv4_fib_exm_prefix_length_23 { - reads { - ingress_metadata.vrf : exact; - ipv4_metadata.lkp_ipv4_da mask 0xFFFFFE00 : exact; - } - actions { - on_miss; - fib_hit_exm_prefix_length_23_nexthop; - fib_hit_exm_prefix_length_23_ecmp; - } - size : 30720; -} - -table ipv4_fib_lpm_prefix_range_22_to_0 { - reads { - ingress_metadata.vrf : exact; - ipv4_metadata.lkp_ipv4_da : lpm; - } - actions { - on_miss; - fib_hit_lpm_prefix_range_22_to_0_nexthop; - fib_hit_lpm_prefix_range_22_to_0_ecmp; - } - size : 512; -} -# 449 "p4src/ipv4.p4" -control process_ipv4_fib { - - - - apply(ipv4_fib_exm_prefix_length_32); - apply(ipv4_fib_exm_prefix_length_31); - apply(ipv4_fib_exm_prefix_length_30); - apply(ipv4_fib_exm_prefix_length_29); - apply(ipv4_fib_exm_prefix_length_28); - apply(ipv4_fib_exm_prefix_length_27); - apply(ipv4_fib_exm_prefix_length_26); - apply(ipv4_fib_exm_prefix_length_25); - apply(ipv4_fib_exm_prefix_length_24); - apply(ipv4_fib_exm_prefix_length_23); - apply(ipv4_fib_lpm_prefix_range_22_to_0); -# 472 "p4src/ipv4.p4" -} -# 506 "p4src/ipv4.p4" -control process_ipv4_urpf { -# 517 "p4src/ipv4.p4" -} -# 86 "p4src/switch.p4" 2 -# 1 "p4src/ipv6.p4" 1 -# 11 "p4src/ipv6.p4" -header_type ipv6_metadata_t { - fields { - lkp_ipv6_sa : 128; - lkp_ipv6_da : 128; - ipv6_unicast_enabled : 1; - ipv6_urpf_mode : 2; - - fib_hit_exm_prefix_length_128 : 1; - fib_nexthop_exm_prefix_length_128 : 16; - fib_nexthop_type_exm_prefix_length_128 : 1; - - fib_hit_lpm_prefix_range_127_to_65 : 1; - fib_nexthop_lpm_prefix_range_127_to_65 : 16; - fib_nexthop_type_lpm_prefix_range_127_to_65 : 1; - - fib_hit_exm_prefix_length_64 : 1; - fib_nexthop_exm_prefix_length_64 : 16; - fib_nexthop_type_exm_prefix_length_64 : 1; - - fib_hit_lpm_prefix_range_63_to_0 : 1; - fib_nexthop_lpm_prefix_range_63_to_0 : 16; - fib_nexthop_type_lpm_prefix_range_63_to_0 : 1; - - } -} -metadata ipv6_metadata_t ipv6_metadata; -# 67 "p4src/ipv6.p4" -control validate_outer_ipv6_header { - - - -} -# 233 "p4src/ipv6.p4" -control process_ipv6_fib { -# 249 "p4src/ipv6.p4" -} -# 284 "p4src/ipv6.p4" -control process_ipv6_urpf { -# 295 "p4src/ipv6.p4" -} -# 87 "p4src/switch.p4" 2 -# 1 "p4src/tunnel.p4" 1 - - - -header_type tunnel_metadata_t { - fields { - ingress_tunnel_type : 8; - tunnel_vni : 24; - mpls_enabled : 1; - mpls_label: 20; - mpls_exp: 3; - mpls_ttl: 8; - egress_tunnel_type : 8; - tunnel_index: 14; - tunnel_src_index : 9; - tunnel_smac_index : 9; - tunnel_dst_index : 14; - tunnel_dmac_index : 14; - vnid : 24; - } -} -metadata tunnel_metadata_t tunnel_metadata; -# 107 "p4src/tunnel.p4" -control process_ipv4_vtep { - - - - - - - -} - -control process_ipv6_vtep { - - - - - - - -} -# 302 "p4src/tunnel.p4" -control process_tunnel { - - - -} -# 346 "p4src/tunnel.p4" -control validate_mpls_header { - - - -} -# 440 "p4src/tunnel.p4" -control process_mpls { - - - -} -# 747 "p4src/tunnel.p4" -control process_tunnel_decap { -# 757 "p4src/tunnel.p4" -} -# 1316 "p4src/tunnel.p4" -control process_tunnel_encap { -# 1333 "p4src/tunnel.p4" -} -# 88 "p4src/switch.p4" 2 -# 1 "p4src/acl.p4" 1 - - - -header_type acl_metadata_t { - fields { - acl_deny : 1; - racl_deny : 1; - acl_nexthop : 16; - racl_nexthop : 16; - acl_nexthop_type : 1; - racl_nexthop_type : 1; - acl_redirect : 1; - racl_redirect : 1; - } -} - -metadata acl_metadata_t acl_metadata; -# 78 "p4src/acl.p4" -control process_mac_acl { - - - - - -} -# 170 "p4src/acl.p4" -control process_ip_acl { -# 184 "p4src/acl.p4" -} -# 227 "p4src/acl.p4" -control process_qos { - - - - - -} - - -action racl_log() { -} - -action racl_deny() { - modify_field(acl_metadata.racl_deny, 1); -} - -action racl_permit() { -} - -action racl_set_nat_mode(nat_mode) { - modify_field(nat_metadata.ingress_nat_mode, nat_mode); -} - -action racl_redirect_nexthop(nexthop_index) { - modify_field(acl_metadata.racl_redirect, 1); - modify_field(acl_metadata.racl_nexthop, nexthop_index); - modify_field(acl_metadata.racl_nexthop_type, 0); -} - -action racl_redirect_ecmp(ecmp_index) { - modify_field(acl_metadata.racl_redirect, 1); - modify_field(acl_metadata.racl_nexthop, ecmp_index); - modify_field(acl_metadata.racl_nexthop_type, 1); -} -# 296 "p4src/acl.p4" -control process_ipv4_racl { - - - - - -} -# 330 "p4src/acl.p4" -control process_ipv6_racl { - - - - - -} - -field_list mirror_info { - ingress_metadata.ifindex; - ingress_metadata.drop_reason; - l3_metadata.lkp_ip_ttl; -} - -action negative_mirror(clone_spec, drop_reason) { - modify_field(ingress_metadata.drop_reason, drop_reason); - clone_ingress_pkt_to_egress(clone_spec, mirror_info); - drop(); -} - -action redirect_to_cpu() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 64); - modify_field(ig_intr_md_for_tm.mcast_grp_a, 0); - modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); - - - -} - -action copy_to_cpu() { - clone_ingress_pkt_to_egress(250); -} - -action drop_packet() { - drop(); -} - -table system_acl { - reads { - ingress_metadata.if_label : ternary; - ingress_metadata.bd_label : ternary; - - - ipv4_metadata.lkp_ipv4_sa : ternary; - ipv4_metadata.lkp_ipv4_da : ternary; - l3_metadata.lkp_ip_proto : ternary; - - - l2_metadata.lkp_mac_sa : ternary; - l2_metadata.lkp_mac_da : ternary; - i_fabric_header.lkp_mac_type : ternary; - - - ingress_metadata.ipsg_check_fail : ternary; - acl_metadata.acl_deny : ternary; - acl_metadata.racl_deny: ternary; - l3_metadata.urpf_check_fail : ternary; - - - - - - i_fabric_header.routed : ternary; - ingress_metadata.src_is_link_local : ternary; - ingress_metadata.same_bd_check : ternary; - l3_metadata.lkp_ip_ttl : ternary; - l2_metadata.stp_state : ternary; - ingress_metadata.control_frame: ternary; - ipv4_metadata.ipv4_unicast_enabled : ternary; - - - ig_intr_md_for_tm.ucast_egress_port : ternary; - } - actions { - nop; - redirect_to_cpu; - copy_to_cpu; - drop_packet; - negative_mirror; - } - size : 512; -} - -control process_system_acl { - apply(system_acl); -} -# 452 "p4src/acl.p4" -control process_egress_acl { - - - -} -# 89 "p4src/switch.p4" 2 -# 1 "p4src/nat.p4" 1 -header_type nat_metadata_t { - fields { - ingress_nat_mode : 2; - egress_nat_mode : 2; - nat_nexthop : 16; - nat_hit : 1; - nat_rewrite_index : 16; - } -} - -metadata nat_metadata_t nat_metadata; -# 79 "p4src/nat.p4" -control process_nat { -# 94 "p4src/nat.p4" -} -# 109 "p4src/nat.p4" -control process_egress_nat { -# 118 "p4src/nat.p4" -} -# 90 "p4src/switch.p4" 2 -# 1 "p4src/multicast.p4" 1 -header_type multicast_metadata_t { - fields { - outer_ipv4_mcast_key_type : 1; - outer_ipv4_mcast_key : 8; - outer_ipv6_mcast_key_type : 1; - outer_ipv6_mcast_key : 8; - outer_mcast_route_hit : 1; - outer_mcast_mode : 2; - ip_multicast : 1; - mcast_route_hit : 1; - mcast_bridge_hit : 1; - ipv4_multicast_mode : 2; - ipv6_multicast_mode : 2; - igmp_snooping_enabled : 1; - mld_snooping_enabled : 1; - bd_mrpf_group : 16; - mcast_rpf_group : 16; - mcast_mode : 2; - multicast_route_mc_index : 16; - multicast_bridge_mc_index : 16; - } -} - -metadata multicast_metadata_t multicast_metadata; -# 45 "p4src/multicast.p4" -control process_outer_multicast_rpf { -# 54 "p4src/multicast.p4" -} -# 145 "p4src/multicast.p4" -control process_outer_ipv4_multicast { -# 156 "p4src/multicast.p4" -} -# 192 "p4src/multicast.p4" -control process_outer_ipv6_multicast { -# 203 "p4src/multicast.p4" -} - -control process_outer_multicast { -# 216 "p4src/multicast.p4" -} -# 244 "p4src/multicast.p4" -control process_multicast_rpf { - - - - - - - -} -# 350 "p4src/multicast.p4" -control process_ipv4_multicast { -# 368 "p4src/multicast.p4" -} -# 427 "p4src/multicast.p4" -control process_ipv6_multicast { -# 444 "p4src/multicast.p4" -} - -control process_multicast { -# 459 "p4src/multicast.p4" -} -# 91 "p4src/switch.p4" 2 -# 1 "p4src/nexthop.p4" 1 - - - -header_type nexthop_metadata_t { - fields { - nexthop_type : 1; - } -} - -metadata nexthop_metadata_t nexthop_metadata; - -action set_l2_redirect_action() { - modify_field(i_fabric_header.nexthop_index, l2_metadata.l2_nexthop); - modify_field(nexthop_metadata.nexthop_type, - l2_metadata.l2_nexthop_type); -} - -action set_acl_redirect_action() { - modify_field(i_fabric_header.nexthop_index, acl_metadata.acl_nexthop); - modify_field(nexthop_metadata.nexthop_type, - acl_metadata.acl_nexthop_type); -} - -action set_racl_redirect_action() { - modify_field(i_fabric_header.nexthop_index, acl_metadata.racl_nexthop); - modify_field(nexthop_metadata.nexthop_type, - acl_metadata.racl_nexthop_type); - modify_field(i_fabric_header.routed, 1); -} - -action set_fib_redirect_action() { - modify_field(i_fabric_header.nexthop_index, l3_metadata.fib_nexthop); - modify_field(nexthop_metadata.nexthop_type, - l3_metadata.fib_nexthop_type); - modify_field(i_fabric_header.routed, 1); - modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); - - - -} - -action set_nat_redirect_action() { - modify_field(i_fabric_header.nexthop_index, nat_metadata.nat_nexthop); - modify_field(nexthop_metadata.nexthop_type, 0); - modify_field(i_fabric_header.routed, 1); -} - -action set_multicast_route_action() { - modify_field(ig_intr_md_for_tm.mcast_grp_b, - multicast_metadata.multicast_route_mc_index); - - - -} - -action set_multicast_bridge_action() { - modify_field(ig_intr_md_for_tm.mcast_grp_b, - multicast_metadata.multicast_bridge_mc_index); - - - -} - - - -action set_fib_exm_prefix_length_32_redirect_action() { - - modify_field(nexthop_metadata.nexthop_type, - ipv4_metadata.fib_nexthop_type_exm_prefix_length_32); - modify_field(i_fabric_header.routed, 1); - modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); - - - -} - -action set_fib_exm_prefix_length_31_redirect_action() { - - modify_field(nexthop_metadata.nexthop_type, - ipv4_metadata.fib_nexthop_type_exm_prefix_length_31); - modify_field(i_fabric_header.routed, 1); - modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); - - - -} - -action set_fib_exm_prefix_length_30_redirect_action() { - - modify_field(nexthop_metadata.nexthop_type, - ipv4_metadata.fib_nexthop_type_exm_prefix_length_30); - modify_field(i_fabric_header.routed, 1); - modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); - - - -} - -action set_fib_exm_prefix_length_29_redirect_action() { - - modify_field(nexthop_metadata.nexthop_type, - ipv4_metadata.fib_nexthop_type_exm_prefix_length_29); - modify_field(i_fabric_header.routed, 1); - modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); - - - -} - -action set_fib_exm_prefix_length_28_redirect_action() { - - modify_field(nexthop_metadata.nexthop_type, - ipv4_metadata.fib_nexthop_type_exm_prefix_length_28); - modify_field(i_fabric_header.routed, 1); - modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); - - - -} - -action set_fib_exm_prefix_length_27_redirect_action() { - - modify_field(nexthop_metadata.nexthop_type, - ipv4_metadata.fib_nexthop_type_exm_prefix_length_27); - modify_field(i_fabric_header.routed, 1); - modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); - - - -} - -action set_fib_exm_prefix_length_26_redirect_action() { - - modify_field(nexthop_metadata.nexthop_type, - ipv4_metadata.fib_nexthop_type_exm_prefix_length_26); - modify_field(i_fabric_header.routed, 1); - modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); - - - -} - -action set_fib_exm_prefix_length_25_redirect_action() { - - modify_field(nexthop_metadata.nexthop_type, - ipv4_metadata.fib_nexthop_type_exm_prefix_length_25); - modify_field(i_fabric_header.routed, 1); - modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); - - - -} - -action set_fib_exm_prefix_length_24_redirect_action() { - - modify_field(nexthop_metadata.nexthop_type, - ipv4_metadata.fib_nexthop_type_exm_prefix_length_24); - modify_field(i_fabric_header.routed, 1); - modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); - - - -} - -action set_fib_exm_prefix_length_23_redirect_action() { - - modify_field(nexthop_metadata.nexthop_type, - ipv4_metadata.fib_nexthop_type_exm_prefix_length_23); - modify_field(i_fabric_header.routed, 1); - modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); - - - -} - -action set_fib_lpm_prefix_range_22_to_0_redirect_action() { - - modify_field(nexthop_metadata.nexthop_type, - ipv4_metadata.fib_nexthop_type_lpm_prefix_range_22_to_0); - modify_field(i_fabric_header.routed, 1); - modify_field(ig_intr_md_for_tm.mcast_grp_b, 0); - - - -} -# 239 "p4src/nexthop.p4" -table fwd_result { - reads { -# 263 "p4src/nexthop.p4" - ipv4_metadata.fib_hit_exm_prefix_length_32 : ternary; - ipv4_metadata.fib_hit_exm_prefix_length_31 : ternary; - ipv4_metadata.fib_hit_exm_prefix_length_30 : ternary; - ipv4_metadata.fib_hit_exm_prefix_length_29 : ternary; - ipv4_metadata.fib_hit_exm_prefix_length_28 : ternary; - ipv4_metadata.fib_hit_exm_prefix_length_27 : ternary; - ipv4_metadata.fib_hit_exm_prefix_length_26 : ternary; - ipv4_metadata.fib_hit_exm_prefix_length_25 : ternary; - ipv4_metadata.fib_hit_exm_prefix_length_24 : ternary; - ipv4_metadata.fib_hit_exm_prefix_length_23 : ternary; - ipv4_metadata.fib_hit_lpm_prefix_range_22_to_0 : ternary; -# 282 "p4src/nexthop.p4" - } - actions { - nop; - set_l2_redirect_action; - set_acl_redirect_action; - set_racl_redirect_action; - set_fib_redirect_action; - set_nat_redirect_action; - - - - - - - set_fib_exm_prefix_length_32_redirect_action; - set_fib_exm_prefix_length_31_redirect_action; - set_fib_exm_prefix_length_30_redirect_action; - set_fib_exm_prefix_length_29_redirect_action; - set_fib_exm_prefix_length_28_redirect_action; - set_fib_exm_prefix_length_27_redirect_action; - set_fib_exm_prefix_length_26_redirect_action; - set_fib_exm_prefix_length_25_redirect_action; - set_fib_exm_prefix_length_24_redirect_action; - set_fib_exm_prefix_length_23_redirect_action; - set_fib_lpm_prefix_range_22_to_0_redirect_action; -# 315 "p4src/nexthop.p4" - } - size : 512; -} - -control process_merge_results { - apply(fwd_result); -} - -field_list l3_hash_fields { - ipv4_metadata.lkp_ipv4_sa; - ipv4_metadata.lkp_ipv4_da; - l3_metadata.lkp_ip_proto; - ingress_metadata.lkp_l4_sport; - ingress_metadata.lkp_l4_dport; -} - -field_list_calculation ecmp_hash { - input { - l3_hash_fields; - } - algorithm : crc16; - output_width : 10; -} - -action_selector ecmp_selector { - selection_key : ecmp_hash; -} - -action_profile ecmp_action_profile { - actions { - nop; - set_ecmp_nexthop_details; - set_ecmp_nexthop_details_for_post_routed_flood; - } - size : 16384; - dynamic_action_selection : ecmp_selector; -} - -table ecmp_group { - reads { - i_fabric_header.nexthop_index : exact; - } - action_profile: ecmp_action_profile; - size : 1024; -} - -action set_nexthop_details(ifindex, bd) { - modify_field(ingress_metadata.egress_ifindex, ifindex); - modify_field(i_fabric_header.egress_bd, bd); - bit_xor(ingress_metadata.same_bd_check, ingress_metadata.bd, bd); -} - -action set_ecmp_nexthop_details(ifindex, bd, nhop_index) { - modify_field(ingress_metadata.egress_ifindex, ifindex); - modify_field(i_fabric_header.egress_bd, bd); - modify_field(i_fabric_header.nexthop_index, nhop_index); - bit_xor(ingress_metadata.same_bd_check, ingress_metadata.bd, bd); -} - - - - - -action set_nexthop_details_for_post_routed_flood(bd, uuc_mc_index) { - modify_field(ig_intr_md_for_tm.mcast_grp_b, uuc_mc_index); - modify_field(i_fabric_header.egress_bd, bd); - bit_xor(ingress_metadata.same_bd_check, ingress_metadata.bd, bd); - - - -} - -action set_ecmp_nexthop_details_for_post_routed_flood(bd, uuc_mc_index, - nhop_index) { - modify_field(ig_intr_md_for_tm.mcast_grp_b, uuc_mc_index); - modify_field(i_fabric_header.egress_bd, bd); - modify_field(i_fabric_header.nexthop_index, nhop_index); - bit_xor(ingress_metadata.same_bd_check, ingress_metadata.bd, bd); - - - -} - -table nexthop { - reads { - i_fabric_header.nexthop_index : exact; - } - actions { - nop; - set_nexthop_details; - set_nexthop_details_for_post_routed_flood; - } - size : 1024; -} - -control process_nexthop { - if (nexthop_metadata.nexthop_type == 1) { - - apply(ecmp_group); - } else { - - apply(nexthop); - } -} -# 92 "p4src/switch.p4" 2 -# 1 "p4src/rewrite.p4" 1 -action set_l2_rewrite() { - modify_field(egress_metadata.routed, 0); - modify_field(egress_metadata.bd, i_fabric_header.egress_bd); -} - -action set_ipv4_unicast_rewrite(smac_idx, dmac) { - modify_field(egress_metadata.smac_idx, smac_idx); - modify_field(egress_metadata.mac_da, dmac); - modify_field(egress_metadata.routed, 1); - add_to_field(ipv4.ttl, -1); - modify_field(egress_metadata.bd, i_fabric_header.egress_bd); -} - -action set_ipv6_unicast_rewrite(smac_idx, dmac) { - modify_field(egress_metadata.smac_idx, smac_idx); - modify_field(egress_metadata.mac_da, dmac); - modify_field(egress_metadata.routed, 1); - add_to_field(ipv6.hopLimit, -1); - modify_field(egress_metadata.bd, i_fabric_header.egress_bd); -} - -action set_ipv4_vxlan_rewrite(outer_bd, tunnel_index, smac_idx, dmac) { - modify_field(egress_metadata.bd, outer_bd); - modify_field(egress_metadata.smac_idx, smac_idx); - modify_field(egress_metadata.mac_da, dmac); - modify_field(tunnel_metadata.tunnel_index, tunnel_index); - modify_field(tunnel_metadata.egress_tunnel_type, 1); -} - -action set_ipv6_vxlan_rewrite(outer_bd, tunnel_index, smac_idx, dmac) { - modify_field(egress_metadata.bd, outer_bd); - modify_field(egress_metadata.smac_idx, smac_idx); - modify_field(egress_metadata.mac_da, dmac); - modify_field(tunnel_metadata.tunnel_index, tunnel_index); - modify_field(tunnel_metadata.egress_tunnel_type, 2); -} - -action set_ipv4_geneve_rewrite(outer_bd, tunnel_index, smac_idx, dmac) { - modify_field(egress_metadata.bd, outer_bd); - modify_field(egress_metadata.smac_idx, smac_idx); - modify_field(egress_metadata.mac_da, dmac); - modify_field(tunnel_metadata.tunnel_index, tunnel_index); - modify_field(tunnel_metadata.egress_tunnel_type, 3); -} - -action set_ipv6_geneve_rewrite(outer_bd, tunnel_index, smac_idx, dmac) { - modify_field(egress_metadata.bd, outer_bd); - modify_field(egress_metadata.smac_idx, smac_idx); - modify_field(egress_metadata.mac_da, dmac); - modify_field(tunnel_metadata.tunnel_index, tunnel_index); - modify_field(tunnel_metadata.egress_tunnel_type, 4); -} - -action set_ipv4_nvgre_rewrite(outer_bd, tunnel_index, smac_idx, dmac) { - modify_field(egress_metadata.bd, outer_bd); - modify_field(egress_metadata.smac_idx, smac_idx); - modify_field(egress_metadata.mac_da, dmac); - modify_field(tunnel_metadata.tunnel_index, tunnel_index); - modify_field(tunnel_metadata.egress_tunnel_type, 5); -} - -action set_ipv6_nvgre_rewrite(outer_bd, tunnel_index, smac_idx, dmac) { - modify_field(egress_metadata.bd, outer_bd); - modify_field(egress_metadata.smac_idx, smac_idx); - modify_field(egress_metadata.mac_da, dmac); - modify_field(tunnel_metadata.tunnel_index, tunnel_index); - modify_field(tunnel_metadata.egress_tunnel_type, 6); -} - -action set_ipv4_erspan_v2_rewrite(outer_bd, tunnel_index, smac_idx, dmac) { - modify_field(egress_metadata.bd, outer_bd); - modify_field(egress_metadata.smac_idx, smac_idx); - modify_field(egress_metadata.mac_da, dmac); - modify_field(tunnel_metadata.tunnel_index, tunnel_index); - modify_field(tunnel_metadata.egress_tunnel_type, 7); -} - -action set_ipv6_erspan_v2_rewrite(outer_bd, tunnel_index, smac_idx, dmac) { - modify_field(egress_metadata.bd, outer_bd); - modify_field(egress_metadata.smac_idx, smac_idx); - modify_field(egress_metadata.mac_da, dmac); - modify_field(tunnel_metadata.tunnel_index, tunnel_index); - modify_field(tunnel_metadata.egress_tunnel_type, 8); -} -# 135 "p4src/rewrite.p4" -table rewrite { - reads { - i_fabric_header.nexthop_index : exact; - } - actions { - nop; - set_l2_rewrite; - set_ipv4_unicast_rewrite; -# 175 "p4src/rewrite.p4" - } - size : 1024; -} - -control process_rewrite { - apply(rewrite); -} -# 93 "p4src/switch.p4" 2 -# 1 "p4src/security.p4" 1 - - - -header_type security_metadata_t { - fields { - storm_control_color : 1; - ipsg_enabled : 1; - } -} - -metadata security_metadata_t security_metadata; -# 38 "p4src/security.p4" -control process_storm_control { - - - -} -# 75 "p4src/security.p4" -control process_ip_sourceguard { -# 86 "p4src/security.p4" -} -# 94 "p4src/switch.p4" 2 -# 1 "p4src/fabric.p4" 1 - - - -metadata fabric_header_internal_t i_fabric_header; - - -action add_i_fabric_header(etherType) { - - - - - - - modify_field(i_fabric_header.ingress_tunnel_type, - tunnel_metadata.ingress_tunnel_type); - modify_field(i_fabric_header.lkp_mac_type, etherType); - - - -} -# 135 "p4src/fabric.p4" -control process_fabric_ingress { - - - -} -# 267 "p4src/fabric.p4" -control process_fabric_lag { - - - -} - -action cpu_tx_rewrite() { - modify_field(ethernet.etherType, fabric_payload_header.etherType); - remove_header(fabric_header); - remove_header(fabric_header_cpu); - remove_header(fabric_payload_header); - modify_field(egress_metadata.fabric_bypass, 1); -} - -action cpu_rx_rewrite() { - add_header(fabric_header); - add_header(fabric_header_cpu); - modify_field(fabric_header.headerVersion, 0); - modify_field(fabric_header.packetVersion, 0); - modify_field(fabric_header.pad1, 0); - modify_field(fabric_header.packetType, 6); - modify_field(fabric_header_cpu.port, ig_intr_md.ingress_port); - modify_field(egress_metadata.fabric_bypass, 1); - - - - add_header(fabric_payload_header); - modify_field(fabric_payload_header.etherType, ethernet.etherType); - modify_field(ethernet.etherType, 0x9000); - -} - - - - - - - -table fabric_rewrite { - reads { - eg_intr_md.egress_port : ternary; - ig_intr_md.ingress_port : ternary; - } - actions { - nop; - cpu_tx_rewrite; - cpu_rx_rewrite; - - - - } - size : 512; -} - -control process_fabric_egress { - apply(fabric_rewrite); -} - -action strip_i_fabric_header() { - remove_header(i_fabric_header); - remove_header(fabric_payload_header); -} - -table egress_i_fabric_rewrite { - reads { - i_fabric_header : valid; - } - actions { - strip_i_fabric_header; - } -} - -control process_i_fabric_egress { - - - -} -# 95 "p4src/switch.p4" 2 -# 1 "p4src/egress_filter.p4" 1 -# 40 "p4src/egress_filter.p4" -control process_egress_filter { -# 51 "p4src/egress_filter.p4" -} -# 96 "p4src/switch.p4" 2 - -action nop() { -} - -action on_miss() { -} - -control ingress { - - if (valid(fabric_header)) { - - - process_fabric_ingress(); - } else { - - - validate_outer_ethernet_header(); - - - if (valid(ipv4)) { - validate_outer_ipv4_header(); - } else { - if (valid(ipv6)) { - validate_outer_ipv6_header(); - } - } - - if (valid(mpls[0])) { - validate_mpls_header(); - } - - - - - - - process_port_mapping(); - - process_storm_control(); - - - process_port_vlan_mapping(); - process_spanning_tree(); - process_ip_sourceguard(); -# 182 "p4src/switch.p4" - process_validate_packet(); - - - process_mac(); - - - if (l3_metadata.lkp_ip_type == 0) { - process_mac_acl(); - } else { - process_ip_acl(); - } - - process_qos(); - - apply(rmac) { - rmac_miss { - process_multicast(); - } - default { - if ((l3_metadata.lkp_ip_type == 1) and - (ipv4_metadata.ipv4_unicast_enabled == 1)) { - - process_ipv4_racl(); - process_nat(); - - process_ipv4_urpf(); - process_ipv4_fib(); - - } else { - if ((l3_metadata.lkp_ip_type == 2) and - (ipv6_metadata.ipv6_unicast_enabled == 1)) { - - - process_ipv6_racl(); - process_ipv6_urpf(); - process_ipv6_fib(); - } - } - process_urpf_bd(); - } - } - - - - - - - process_merge_results(); - - - process_nexthop(); - - - process_ingress_bd_stats(); - - - process_lag(); - - - process_mac_learning(); - } - - - process_fabric_lag(); - - - process_system_acl(); -} - -control egress { - - if (egress_metadata.egress_bypass == 0) { - - - process_fabric_egress(); - - if (egress_metadata.fabric_bypass == 0) { - - process_replication(); - - process_vlan_decap(); - - - process_tunnel_decap(); - - - process_egress_bd(); - - process_egress_nat(); - - - process_rewrite(); - - - process_mac_rewrite(); - - - process_tunnel_encap(); - - process_mtu(); - - - process_vlan_xlate(); - - - process_egress_filter(); - - - process_egress_acl(); - - - process_i_fabric_egress(); - } - } -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_102_clone.NOT_READY b/backends/tofino/bf-asm/test/internal/test_config_102_clone.NOT_READY deleted file mode 100644 index 3940590adf9..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_102_clone.NOT_READY +++ /dev/null @@ -1,97 +0,0 @@ -#include -#include -#include - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -parser start { - return select(current(0,1)) { - 0 mask 0: abc; - default: ingress; - } -} - -parser abc { - extract(ethernet); - return ingress; -} -header ethernet_t ethernet; - -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -header_type metadata_h { - fields { - foo : 8; - } -} -metadata metadata_h m; - -field_list mirror_list { - m.foo; -} - -action ingr_action () { - clone_i2e(5, mirror_list); -} -action ingr_action2 () { - clone_i2e(6); -} - -action egr_action () { - clone_e2e(7, mirror_list); -} -action egr_action2 () { - clone_e2e(8); -} - - -table ingr_null_table { - reads { - ig_intr_md_from_parser_aux.ingress_parser_err : exact; - } - actions { - ingr_action; - ingr_action2; - } -} - -table egr_null_table { - reads { - eg_intr_md_from_parser_aux.egress_parser_err : exact; - ethernet.dstAddr : exact; - m.foo : exact; - } - actions { - egr_action; - egr_action2; - } -} - - -control ingress { - apply(ingr_null_table); -} - -control egress { - apply(egr_null_table); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_102_clone.p4 b/backends/tofino/bf-asm/test/internal/test_config_102_clone.p4 deleted file mode 100644 index 3940590adf9..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_102_clone.p4 +++ /dev/null @@ -1,97 +0,0 @@ -#include -#include -#include - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -parser start { - return select(current(0,1)) { - 0 mask 0: abc; - default: ingress; - } -} - -parser abc { - extract(ethernet); - return ingress; -} -header ethernet_t ethernet; - -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -header_type metadata_h { - fields { - foo : 8; - } -} -metadata metadata_h m; - -field_list mirror_list { - m.foo; -} - -action ingr_action () { - clone_i2e(5, mirror_list); -} -action ingr_action2 () { - clone_i2e(6); -} - -action egr_action () { - clone_e2e(7, mirror_list); -} -action egr_action2 () { - clone_e2e(8); -} - - -table ingr_null_table { - reads { - ig_intr_md_from_parser_aux.ingress_parser_err : exact; - } - actions { - ingr_action; - ingr_action2; - } -} - -table egr_null_table { - reads { - eg_intr_md_from_parser_aux.egress_parser_err : exact; - ethernet.dstAddr : exact; - m.foo : exact; - } - actions { - egr_action; - egr_action2; - } -} - - -control ingress { - apply(ingr_null_table); -} - -control egress { - apply(egr_null_table); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_103_first_phase_0.p4 b/backends/tofino/bf-asm/test/internal/test_config_103_first_phase_0.p4 deleted file mode 100644 index 81322c48749..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_103_first_phase_0.p4 +++ /dev/null @@ -1,129 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - color_0 : 8; - } -} - -header_type meta_t { - fields { - field_a0_1 : 1; - field_a1_1 : 1; - field_a2_1 : 1; - field_a3_1 : 1; - field_b_4 : 4; - field_c_4 : 4; - field_d_4 : 4; - field_e_4 : 4; - field_f_4 : 4; - field_g_4 : 4; - field_h0_1 : 1; - field_h1_1 : 1; - field_h2_1 : 1; - field_h3_1 : 1; - } -} - -parser start { - return parse_pkt; -} - -header pkt_t pkt; -metadata meta_t meta; - -parser parse_pkt { - extract(pkt); - return ingress; -} - - -action action_0(param0, param1, param2, param3, param4, param5){ - modify_field(meta.field_a0_1, 0); - modify_field(meta.field_a1_1, param0); - modify_field(meta.field_a2_1, 1); - modify_field(meta.field_a3_1, param1); - modify_field(meta.field_b_4, 9); - modify_field(meta.field_c_4, param2); - modify_field(meta.field_d_4, 6); - modify_field(meta.field_e_4, 10); - modify_field(meta.field_f_4, 15, 0xf); - modify_field(meta.field_g_4, param3); - modify_field(meta.field_h0_1, param4); - modify_field(meta.field_h1_1, 0); - modify_field(meta.field_h2_1, param5); - modify_field(meta.field_h3_1, 1); -} - -action action_1(param0){ - modify_field(pkt.field_f_16, param0); -} - -action do_nothing(){ - no_op(); -} - -table table_0 { - reads { - ig_intr_md.ingress_port : exact; - } - actions { - action_0; - } - size : 128; -} - -@pragma include_idletime 1 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 1 -table table_1 { - reads { - pkt.field_g_16 : exact; - pkt.color_0 : exact; - - meta.field_a0_1 : exact; - meta.field_a1_1 : exact; - meta.field_a2_1 : exact; - meta.field_a3_1 : exact; - - meta.field_b_4 : exact; - meta.field_c_4 : exact; - meta.field_d_4 : exact; - meta.field_e_4 : exact; - meta.field_f_4 : exact; - meta.field_g_4 : exact; - - meta.field_h0_1 : exact; - meta.field_h1_1 : exact; - meta.field_h2_1 : exact; - meta.field_h3_1 : exact; - - } - actions { - action_1; - } - size : 65536; -} - -/* Main control flow */ - -control ingress { - if (0 == ig_intr_md.resubmit_flag){ - apply(table_0); - apply(table_1); - } -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_10_new_crossbar_allocation.p4 b/backends/tofino/bf-asm/test/internal/test_config_10_new_crossbar_allocation.p4 deleted file mode 100644 index 04d6ca8c5a6..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_10_new_crossbar_allocation.p4 +++ /dev/null @@ -1,120 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -action action_0(){ - modify_field(ipv4.diffserv, 1); -} - -action action_1() { - modify_field(ipv4.totalLen, 2); -} - -action action_2() { - modify_field(ipv4.identification, 3); -} - -action action_3(param_3) { - modify_field(ipv4.ttl, param_3); -} - -action action_4(param_4) { - modify_field(ipv4.protocol, param_4); -} - -action do_nothing(){ - no_op(); -} - - -table table_0 { - reads { - ethernet.etherType : ternary; - ethernet.srcAddr mask 0xffffffff00: ternary; - } - actions { - action_0; - do_nothing; - } - max_size : 1024; -} - -@pragma ways 6 -@pragma pack 3 -table table_1 { - reads { - ipv4.srcAddr : exact; - ipv4.dstAddr : exact; - ipv4.fragOffset : exact; - ethernet.srcAddr : exact; - ethernet.dstAddr : exact; - //ipv4.dstAddr mask 0xffff0000 : ternary; - //ethernet.srcAddr : ternary; - //ethernet.dstAddr : ternary; - } - actions { - action_1; - do_nothing; - } - max_size : 40960; -} - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_1); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_114_simple_drop.p4 b/backends/tofino/bf-asm/test/internal/test_config_114_simple_drop.p4 deleted file mode 100644 index 33985ed7a05..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_114_simple_drop.p4 +++ /dev/null @@ -1,71 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - - field_e : 32; - field_f : 32; - field_g : 32; - field_h : 32; - field_i : 32; - field_j : 32; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action nop(){ - no_op(); -} - -action action_0(){ - drop(); -} - -action action_1(){ - drop(); -} - -table table_0 { - reads { - pkt.field_b : exact; - } - actions { - action_0; - nop; - } - size : 256000; -} - -table table_1 { - reads { - pkt.field_d : exact; - } - actions { - action_1; - nop; - } -} - - -control ingress { - apply(table_0); -} - -control egress { - apply(table_1); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_115_hash_parity_groups.p4 b/backends/tofino/bf-asm/test/internal/test_config_115_hash_parity_groups.p4 deleted file mode 100644 index 693c57ae23b..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_115_hash_parity_groups.p4 +++ /dev/null @@ -1,103 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_m_32 : 32; - field_n_32 : 32; - } -} - - -parser start { - return parse_pkt; -} - -header pkt_t pkt; - -parser parse_pkt { - extract(pkt); - return ingress; -} - - -action do_nothing(){ - no_op(); -} - -table table_0 { - reads { - pkt.field_a_32 : exact; - pkt.field_b_32 : exact; - pkt.field_c_32 : exact; - pkt.field_d_32 : exact; - pkt.field_e_16 : exact; - } - actions { - do_nothing; - } - size : 4096; -} - -table table_1 { - reads { - pkt.field_i_8 : exact; - pkt.field_j_8 : exact; - pkt.field_k_8 : exact; - } - actions { - do_nothing; - } - size : 4096; -} - -table table_2 { - reads { - pkt.field_a_32 : exact; - pkt.field_b_32 : exact; - pkt.field_c_32 : exact; - pkt.field_d_32 : exact; - pkt.field_e_16 : exact; - pkt.field_j_8 : exact; -/* - pkt.field_c_32 : exact; - pkt.field_n_32 : exact; - pkt.field_f_16 : exact; - pkt.field_g_16 : exact; - pkt.field_h_16 : exact; - pkt.field_i_8 : exact; - pkt.field_k_8 : exact; - pkt.field_j_8 : exact; -*/ - } - actions { - do_nothing; - } -} - -/* Main control flow */ - -control ingress { - if (valid(pkt)){ - apply(table_0); - apply(table_1); - apply(table_2); - } -} - - diff --git a/backends/tofino/bf-asm/test/internal/test_config_116_predication_with_condition.p4 b/backends/tofino/bf-asm/test/internal/test_config_116_predication_with_condition.p4 deleted file mode 100644 index 3a8a97e22c8..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_116_predication_with_condition.p4 +++ /dev/null @@ -1,109 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_m_32 : 32; - field_n_32 : 32; - } -} - - -parser start { - return parse_pkt; -} - -header pkt_t pkt; - -parser parse_pkt { - extract(pkt); - return ingress; -} - -action action_0(param0){ - modify_field(pkt.field_f_16, param0); -} - -action action_1(param0){ - modify_field(pkt.field_f_16, param0); -} - -action action_2(param0){ - modify_field(pkt.field_f_16, param0); -} - -action do_nothing(){ - no_op(); -} - -action do_nothing_1(){ -} - -table table_0 { - reads { - pkt.field_a_32 : exact; - } - actions { - do_nothing; - action_0; - } - size : 4096; -} - -table table_1 { - reads { - pkt.field_b_32 : exact; - } - actions { - do_nothing_1; - action_1; - } - size : 4096; -} - -table table_2 { - reads { - pkt.field_b_32 : exact; - } - actions { - do_nothing; - action_2; - } - size : 4096; -} - - -/* Main control flow */ - -control ingress { - apply(table_0){ - do_nothing { - if (valid(pkt)){ - apply(table_1){ - do_nothing_1 { - if(valid(pkt)){ - apply(table_2); - } - } - } - } - } - } -} - - diff --git a/backends/tofino/bf-asm/test/internal/test_config_117_first_tcam_range.p4 b/backends/tofino/bf-asm/test/internal/test_config_117_first_tcam_range.p4 deleted file mode 100644 index 93a2504d488..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_117_first_tcam_range.p4 +++ /dev/null @@ -1,68 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_m_32 : 32; - field_n_32 : 32; - } -} - - -parser start { - return parse_pkt; -} - -header pkt_t pkt; - -parser parse_pkt { - extract(pkt); - return ingress; -} - -action action_0(){ - modify_field(pkt.field_f_16, 1); -} - -action do_nothing(){ - no_op(); -} - -action do_nothing_1(){ -} - -table table_0 { - reads { - pkt.field_e_16 : range; - pkt.field_f_16 : exact; - } - actions { - do_nothing; - action_0; - } - size : 1024; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} - - diff --git a/backends/tofino/bf-asm/test/internal/test_config_118_tcam_range_2.p4 b/backends/tofino/bf-asm/test/internal/test_config_118_tcam_range_2.p4 deleted file mode 100644 index 82c6b6703bb..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_118_tcam_range_2.p4 +++ /dev/null @@ -1,88 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_m_32 : 32; - field_n_32 : 32; - - field_o_4 : 4; - field_p_4 : 4; - } -} - - -parser start { - return parse_pkt; -} - -header pkt_t pkt; - -parser parse_pkt { - extract(pkt); - return ingress; -} - -action action_0(){ - modify_field(pkt.field_g_16, 1); -} - -action action_1(){ - modify_field(pkt.field_h_16, 1); -} - -action do_nothing(){ - no_op(); -} - -action do_nothing_1(){ -} - -table table_0 { - reads { - pkt.field_o_4 : range; - pkt.field_f_16 : exact; - } - actions { - do_nothing; - action_0; - } - size : 1024; -} - -table table_1 { - reads { - pkt.field_p_4 : range; - pkt.field_f_16 : exact; - } - actions { - do_nothing; - action_1; - } - size : 1024; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_1); -} - - diff --git a/backends/tofino/bf-asm/test/internal/test_config_119_tcam_range_3.p4 b/backends/tofino/bf-asm/test/internal/test_config_119_tcam_range_3.p4 deleted file mode 100644 index 495e3a68996..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_119_tcam_range_3.p4 +++ /dev/null @@ -1,88 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_m_32 : 32; - field_n_32 : 32; - - field_o_12 : 12; - field_p_12 : 12; - } -} - - -parser start { - return parse_pkt; -} - -header pkt_t pkt; - -parser parse_pkt { - extract(pkt); - return ingress; -} - -action action_0(){ - modify_field(pkt.field_g_16, 1); -} - -action action_1(){ - modify_field(pkt.field_h_16, 1); -} - -action do_nothing(){ - no_op(); -} - -action do_nothing_1(){ -} - -table table_0 { - reads { - pkt.field_o_12 : range; - pkt.field_f_16 : exact; - } - actions { - do_nothing; - action_0; - } - size : 1024; -} - -table table_1 { - reads { - pkt.field_p_12 : range; - pkt.field_f_16 : exact; - } - actions { - do_nothing; - action_1; - } - size : 1024; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_1); -} - - diff --git a/backends/tofino/bf-asm/test/internal/test_config_11_simple_gateway_table.p4 b/backends/tofino/bf-asm/test/internal/test_config_11_simple_gateway_table.p4 deleted file mode 100644 index 00ae5b66dd5..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_11_simple_gateway_table.p4 +++ /dev/null @@ -1,121 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -action action_0(){ - modify_field(ipv4.diffserv, 1); -} - -action action_1() { - modify_field(ipv4.totalLen, 2); -} - -action action_2() { - modify_field(ipv4.ttl, 3); -} - -action do_nothing(){ - no_op(); -} - - -table table_0 { - reads { - ethernet.etherType : lpm; - //ethernet.srcAddr : exact; - } - actions { - action_0; - do_nothing; - } - max_size : 1024; -} - -table table_1 { - reads { - ipv4.srcAddr : exact; - ipv4.dstAddr : exact; - } - actions { - action_1; - do_nothing; - } - max_size : 16384; -} - -table table_2 { - reads { - ipv4.srcAddr : exact; - } - actions { - action_2; - do_nothing; - } - max_size : 4096; -} - -/* Main control flow */ - -control ingress { - - if (ethernet.etherType == 0x0800){ - //if (ipv4.version == 4){ - apply(table_0); - } - - - if (valid(ipv4)){ - apply(table_1); - } - - - if (ethernet.etherType == ipv4.totalLen){ - apply(table_2); - } - -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_120_tcam_range_4.p4 b/backends/tofino/bf-asm/test/internal/test_config_120_tcam_range_4.p4 deleted file mode 100644 index 21264a5088c..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_120_tcam_range_4.p4 +++ /dev/null @@ -1,88 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_m_32 : 32; - field_n_32 : 32; - - field_o_4 : 4; - field_p_16 : 12; - } -} - - -parser start { - return parse_pkt; -} - -header pkt_t pkt; - -parser parse_pkt { - extract(pkt); - return ingress; -} - -action action_0(){ - modify_field(pkt.field_g_16, 1); -} - -action action_1(){ - modify_field(pkt.field_h_16, 1); -} - -action do_nothing(){ - no_op(); -} - -action do_nothing_1(){ -} - -table table_0 { - reads { - pkt.field_o_4 : range; - pkt.field_f_16 : exact; - } - actions { - do_nothing; - action_0; - } - size : 1024; -} - -table table_1 { - reads { - pkt.field_p_16 : range; - pkt.field_f_16 : exact; - } - actions { - do_nothing; - action_1; - } - size : 1024; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_1); -} - - diff --git a/backends/tofino/bf-asm/test/internal/test_config_121_tcam_range_5.p4 b/backends/tofino/bf-asm/test/internal/test_config_121_tcam_range_5.p4 deleted file mode 100644 index 8f3de5840fd..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_121_tcam_range_5.p4 +++ /dev/null @@ -1,88 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_m_32 : 32; - field_n_32 : 32; - - field_o_17 : 17; - field_p_15 : 15; - } -} - - -parser start { - return parse_pkt; -} - -header pkt_t pkt; - -parser parse_pkt { - extract(pkt); - return ingress; -} - -action action_0(){ - modify_field(pkt.field_g_16, 1); -} - -action action_1(){ - modify_field(pkt.field_h_16, 1); -} - -action do_nothing(){ - no_op(); -} - -action do_nothing_1(){ -} - -table table_0 { - reads { - pkt.field_o_17 : range; - pkt.field_f_16 : exact; - } - actions { - do_nothing; - action_0; - } - size : 1024; -} - -table table_1 { - reads { - pkt.field_p_15 : range; - pkt.field_f_16 : exact; - } - actions { - do_nothing; - action_1; - } - size : 1024; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_1); -} - - diff --git a/backends/tofino/bf-asm/test/internal/test_config_122_tcam_range_6.p4 b/backends/tofino/bf-asm/test/internal/test_config_122_tcam_range_6.p4 deleted file mode 100644 index c07a362641d..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_122_tcam_range_6.p4 +++ /dev/null @@ -1,70 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_m_32 : 32; - field_n_32 : 32; - } -} - - -parser start { - return parse_pkt; -} - -header pkt_t pkt; - -parser parse_pkt { - extract(pkt); - return ingress; -} - -action action_0(){ - modify_field(pkt.field_f_16, 1); -} - -action do_nothing(){ - no_op(); -} - -action do_nothing_1(){ -} - -@pragma entries_with_ranges 64 -table table_0 { - reads { - pkt.field_e_16 : range; - pkt.field_f_16 : range; - pkt.field_g_16 : exact; - } - actions { - do_nothing; - action_0; - } - size : 512; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} - - diff --git a/backends/tofino/bf-asm/test/internal/test_config_123_meter_2.p4 b/backends/tofino/bf-asm/test/internal/test_config_123_meter_2.p4 deleted file mode 100644 index 490c6f499af..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_123_meter_2.p4 +++ /dev/null @@ -1,118 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - color_0 : 8; - pad_0 : 24; - pad_1 : 160; - pad_2 : 24; - color_1 : 8; - pad_3 : 24; - - lpf : 16; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -meter meter_0 { - type : bytes; - //static : table_0; - direct : table_0; - result : pkt.color_0; // Over-loading the meaning of result to be the input and output - //instance_count : 500; - //implementation : red; -} - - -meter meter_1 { - type : bytes; - static : table_1; - //direct : table_1; - result : pkt.color_1; - instance_count : 4097; -} - - -action action_0(param0){ - //modify_field(pkt.field_f_16, param0); - //execute_meter(meter_0, 7, pkt.color_0); -} - - -action action_1(param0){ - //modify_field(pkt.field_g_16, param0); - execute_meter(meter_1, 7, pkt.color_1); -} - - -action do_nothing(){ - no_op(); -// drop(); -} - - - -//@pragma include_idletime 1 -@pragma pa_solitare meter_result.color_0, meter_result.color_1 -@pragma include_stash 1 -@pragma action_default_only do_nothing -table table_0 { - reads { - pkt.field_e_16 : ternary; - pkt.color_0 : exact; //HACK - pkt.color_1 : exact; //HACK - pkt.lpf : exact; //HACK - } - actions { - action_0; - //do_nothing; - } - size : 6000; -} - - -//@pragma include_idletime 1 -@pragma idletime_two_way_notification 1 -@pragma include_stash 1 -table table_1 { - reads { - pkt.field_e_16: exact; - } - actions { - do_nothing; - action_1; - } - size : 32768; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_1); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_124_meter_3.p4 b/backends/tofino/bf-asm/test/internal/test_config_124_meter_3.p4 deleted file mode 100644 index bb2bc26cace..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_124_meter_3.p4 +++ /dev/null @@ -1,113 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - color_0 : 8; - pad_0 : 24; - pad_1 : 16; - pad_2 : 24; - color_1 : 8; - pad_3 : 24; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -meter meter_0 { - type : bytes; - //static : table_0; - direct : table_0; - result : pkt.color_0; - //instance_count : 500; -} - - -meter meter_1 { - type : bytes; - static : table_1; - //direct : table_1; - result : pkt.color_1; - instance_count : 500; -} - - -action action_0(param0){ - //modify_field(pkt.field_f_16, param0); - //execute_meter(meter_0, 7, pkt.color_0); -} - - -action action_1(param0){ - //modify_field(pkt.field_g_16, param0); - execute_meter(meter_1, 7, pkt.color_1); -} - - -action do_nothing(){ - no_op(); -// drop(); -} - - - -//@pragma include_idletime 1 -@pragma pa_solitare meter_result.color_0, meter_result.color_1 -//@pragma include_stash 1 -table table_0 { - reads { - pkt.field_e_16 : ternary; - pkt.color_0 : exact; //HACK - pkt.color_1 : exact; //HACK - } - actions { - action_0; -// do_nothing; - } - size : 6000; -} - - -//@pragma include_idletime 1 -@pragma idletime_two_way_notification 1 -//@pragma include_stash 1 -table table_1 { - reads { - pkt.field_e_16: exact; - } - actions { - do_nothing; - action_1; - } - size : 32768; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_1); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_125_meter_pre_color.p4 b/backends/tofino/bf-asm/test/internal/test_config_125_meter_pre_color.p4 deleted file mode 100644 index ce09b191a27..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_125_meter_pre_color.p4 +++ /dev/null @@ -1,112 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - color_0 : 4; - pad_0 : 4; - color_1 : 8; - - pre_color_0 : 8; - pre_color_1 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -meter meter_0 { - type : bytes; - //static : table_0; - direct : table_0; - result : pkt.color_0; - pre_color : pkt.pre_color_0; - //instance_count : 500; -} - - -meter meter_1 { - type : bytes; - static : table_1; - //direct : table_1; - result : pkt.color_1; - instance_count : 500; -} - - -action action_0(param0){ - //modify_field(pkt.field_f_16, param0); - //execute_meter(meter_0, 7, pkt.color_0); -} - - -action action_1(param0){ - //modify_field(pkt.field_g_16, param0); - execute_meter(meter_1, 7, pkt.color_1, pkt.pre_color_1); -} - - -action do_nothing(){ - no_op(); -} - - -// @pragma include_stash 1 -table table_0 { - reads { - pkt.field_e_16 : ternary; - pkt.color_0 : exact; //HACK - pkt.color_1 : exact; //HACK - pkt.pre_color_0 : exact; //HACK - pkt.pre_color_1 : exact; //HACK - } - actions { - action_0; -// do_nothing; - } - size : 6000; -} - - -//@pragma include_idletime 1 -@pragma idletime_two_way_notification 1 -// @pragma include_stash 1 -table table_1 { - reads { - pkt.field_e_16: exact; - } - actions { - do_nothing; - action_1; - } - size : 32768; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_1); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_126_meter_pre_color_2.p4 b/backends/tofino/bf-asm/test/internal/test_config_126_meter_pre_color_2.p4 deleted file mode 100644 index 09b0daa741d..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_126_meter_pre_color_2.p4 +++ /dev/null @@ -1,114 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - color_0 : 4; - pad_0 : 4; - color_1 : 8; - pre_color_0 : 4; - pad_1 : 4; - pre_color_1 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -meter meter_0 { - type : bytes; - //static : table_0; - direct : table_0; - result : pkt.color_0; - pre_color : pkt.pre_color_0; - //instance_count : 500; -} - - -meter meter_1 { - type : bytes; - static : table_1; - //direct : table_1; - result : pkt.color_1; - instance_count : 500; -} - - -action action_0(param0){ - //modify_field(pkt.field_f_16, param0); - //execute_meter(meter_0, 7, pkt.color_0); -} - - -action action_1(param0){ - //modify_field(pkt.field_g_16, param0); - execute_meter(meter_1, 7, pkt.color_1, pkt.pre_color_1); -} - - -action do_nothing(){ - no_op(); -} - - -// @pragma include_stash 1 -table table_0 { - reads { - pkt.field_e_16 : ternary; - pkt.color_0 : exact; //HACK - pkt.color_1 : exact; //HACK - pkt.pre_color_0 : exact; //HACK - pkt.pre_color_1 : exact; //HACK - } - actions { - action_0; -// do_nothing; - } - size : 6000; -} - - -//@pragma include_idletime 1 -@pragma idletime_two_way_notification 1 -// @pragma include_stash 1 -table table_1 { - reads { - pkt.field_e_16: exact; - } - actions { - do_nothing; - action_1; - } - size : 32768; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} -control egress { - apply(table_1); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_127_meter_pre_color_3.p4 b/backends/tofino/bf-asm/test/internal/test_config_127_meter_pre_color_3.p4 deleted file mode 100644 index 7b280174053..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_127_meter_pre_color_3.p4 +++ /dev/null @@ -1,160 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - color_0 : 4; - pad_0 : 4; - color_1 : 8; - color_2 : 8; - pad_2 : 32; - color_3 : 8; - - pre_color_0 : 4; - pad_1 : 4; - pre_color_1 : 8; - pre_color_2 : 8; - pre_color_3 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -meter meter_0 { - type : bytes; - //static : table_0; - direct : table_0; - result : pkt.color_0; - pre_color : pkt.pre_color_0; - //instance_count : 500; -} - - -meter meter_1 { - type : bytes; - static : table_1; - //direct : table_1; - result : pkt.color_1; - instance_count : 500; -} - -meter meter_2 { - type : bytes; - direct : table_2; - result : pkt.color_2; - pre_color : pkt.pre_color_2; -} - -meter meter_3 { - type : bytes; - direct : table_3; - result : pkt.color_3; - pre_color : pkt.pre_color_3; -} - - -action action_0(param0){ - //modify_field(pkt.field_f_16, param0); - //execute_meter(meter_0, 7, pkt.color_0); -} - - -action action_1(param0){ - //modify_field(pkt.field_g_16, param0); - execute_meter(meter_1, 7, pkt.color_1, pkt.pre_color_1); -} - - -action do_nothing(){ - no_op(); -} - - -// @pragma include_stash 1 -table table_0 { - reads { - pkt.field_e_16 : ternary; - pkt.color_0 : exact; //HACK - pkt.color_1 : exact; //HACK - pkt.color_2 : exact; //HACK - pkt.color_3 : exact; //HACK - pkt.pre_color_0 : exact; //HACK - pkt.pre_color_1 : exact; //HACK - pkt.pre_color_2 : exact; //HACK - pkt.pre_color_3 : exact; //HACK - } - actions { - action_0; -// do_nothing; - } - size : 1024; -} - - -//@pragma include_idletime 1 -@pragma idletime_two_way_notification 1 -// @pragma include_stash 1 -table table_1 { - reads { - pkt.field_e_16: exact; - } - actions { - do_nothing; - action_1; - } - size : 32768; -} - -table table_2 { - reads { - pkt.field_e_16: ternary; - } - actions { - do_nothing; - } - size : 512; -} - -table table_3 { - reads { - pkt.field_e_16: ternary; - } - actions { - do_nothing; - } - size : 512; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_2); - apply(table_3); -} -control egress { - apply(table_1); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_128_table_placement_bug.p4 b/backends/tofino/bf-asm/test/internal/test_config_128_table_placement_bug.p4 deleted file mode 100644 index 662e40b6161..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_128_table_placement_bug.p4 +++ /dev/null @@ -1,101 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - color_0 : 4; - pad_0 : 4; - color_1 : 8; - color_2 : 8; - color_3 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -action action_0(param0){ - modify_field(pkt.field_f_16, param0); -} - - -action action_1(param0){ - modify_field(pkt.field_g_16, param0); -} - - -action do_nothing(){ - no_op(); -} - -table table_0 { - reads { - pkt.field_e_16 : ternary; - } - actions { - action_0; - do_nothing; - } - size : 1024; -} - -//@pragma no_versioning 1 -table table_1 { - reads { - pkt.field_e_16: exact; - pkt.field_f_16 mask 0xfffc : exact; - } - actions { - action_1; - do_nothing; - - } - size : 1024; -} - -table table_2 { - reads { - pkt.field_i_8: ternary; - } - actions { - do_nothing; - - } - size : 256; -} - - -/* Main control flow */ - -control ingress { - if (valid(pkt)){ - apply(table_0); - } else { - apply(table_1) { - action_1 { - apply(table_2); - } - } - } -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_12_no_overhead.p4 b/backends/tofino/bf-asm/test/internal/test_config_12_no_overhead.p4 deleted file mode 100644 index bb118c77605..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_12_no_overhead.p4 +++ /dev/null @@ -1,72 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -action action_0(){ - modify_field(ipv4.diffserv, 1); -} - - -table table_0 { - reads { - ethernet.etherType : exact; - } - actions { - action_0; - } - max_size : 1024; -} - -/* Main control flow */ - -control ingress { - - if (ethernet.etherType == 0x0800){ - apply(table_0); - } -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_130_test_default_action.p4 b/backends/tofino/bf-asm/test/internal/test_config_130_test_default_action.p4 deleted file mode 100644 index 435bef62abc..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_130_test_default_action.p4 +++ /dev/null @@ -1,115 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - color_0 : 4; - pad_0 : 4; - color_1 : 8; - color_2 : 8; - color_3 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -action action_0(param0){ - modify_field(pkt.field_f_16, param0); -} - - -action action_1(param0){ - modify_field(pkt.field_g_16, param0); -} - -action action_2(param0){ - modify_field(pkt.field_h_16, param0); -} - - -action do_nothing_0(){ - no_op(); -} - -action do_nothing_1(){ - no_op(); -} - -action do_nothing_2(){ - no_op(); -} - -table table_0 { - reads { - pkt.field_e_16 : ternary; - } - actions { - action_0; - do_nothing_0; - } - size : 1024; -} - -table table_1 { - reads { - pkt.field_e_16: exact; - pkt.field_f_16 mask 0xffff : exact; - } - actions { - //action_1; - do_nothing_1; - - } - default_action : action_1(0xf); - size : 1024; -} - -table table_2 { - reads { - pkt.field_i_8: ternary; - } - actions { - action_2; - do_nothing_2; - - } - default_action : do_nothing_2; - size : 256; -} - - -/* Main control flow */ - -control ingress { - if (valid(pkt)){ - apply(table_0); - } else { - apply(table_1) { - do_nothing_1 { - apply(table_2); - } - } - } -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_132_meter_pre_color_4.p4 b/backends/tofino/bf-asm/test/internal/test_config_132_meter_pre_color_4.p4 deleted file mode 100644 index 093fec76b9e..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_132_meter_pre_color_4.p4 +++ /dev/null @@ -1,172 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/wred_blackbox.p4" -#include "tofino/lpf_blackbox.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - color_0 : 4; - pad_0 : 4; - color_1 : 8; - color_2 : 8; - pad_2 : 32; - color_3 : 8; - - pre_color_0 : 4; - pad_1 : 4; - pre_color_1 : 8; - pre_color_2 : 8; - pre_color_3 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; - //return ACCEPT; -} - -@pragma meter_per_flow_enable 1 -meter meter_0 { - type : bytes; - static : table_0; - //direct : table_0; - result : pkt.color_0; - //pre_color : pkt.pre_color_0; - instance_count : 500; -} - - -@pragma meter_per_flow_enable 1 -@pragma meter_pre_color_aware_per_flow_enable 1 -meter meter_1 { - type : bytes; - static : table_1; - //direct : table_1; - result : pkt.color_1; - instance_count : 500; -} - -blackbox wred meter_2 { - wred_input: pkt.pre_color_2; - direct : table_2; - drop_value : 127; - no_drop_value : 63; -} - - -blackbox lpf meter_3 { - filter_input : pkt.pre_color_3; - direct : table_3; -} - - -action action_0(param0){ - //modify_field(pkt.field_f_16, param0); - execute_meter(meter_0, 7, pkt.color_0, pkt.pre_color_0); -} - - -action action_1(param0){ - //modify_field(pkt.field_g_16, param0); - execute_meter(meter_1, 7, pkt.color_1, pkt.pre_color_1); -} - - -action do_nothing(){ - no_op(); -} - -action do_nothing_2(){ - meter_2.execute(pkt.pre_color_2); -} - -action do_nothing_3(){ - meter_3.execute(pkt.color_3); -} - - -@pragma include_stash 1 -table table_0 { - reads { - pkt.field_e_16 : ternary; - pkt.color_0 : exact; //HACK - pkt.color_1 : exact; //HACK - pkt.color_2 : exact; //HACK - pkt.color_3 : exact; //HACK - pkt.pre_color_0 : exact; //HACK - pkt.pre_color_1 : exact; //HACK - pkt.pre_color_2 : exact; //HACK - pkt.pre_color_3 : exact; //HACK - } - actions { - action_0; -// do_nothing; - } - size : 1024; -} - - -//@pragma include_idletime 1 -@pragma idletime_two_way_notification 1 -@pragma include_stash 1 -table table_1 { - reads { - pkt.field_e_16: exact; - } - actions { - do_nothing; - action_1; - } - size : 32768; -} - -table table_2 { - reads { - pkt.field_e_16: ternary; - } - actions { - do_nothing_2; - } - size : 512; -} - -table table_3 { - reads { - pkt.field_e_16: ternary; - } - actions { - do_nothing_3; - } - size : 512; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_2); - apply(table_3); -} -control egress { - apply(table_1); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_134_stage_deps.p4 b/backends/tofino/bf-asm/test/internal/test_config_134_stage_deps.p4 deleted file mode 100644 index 662a12d61a5..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_134_stage_deps.p4 +++ /dev/null @@ -1,120 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - color_0 : 8; - } -} - -parser start { - return parse_pkt; -} - -header pkt_t pkt; - -parser parse_pkt { - extract(pkt); - return ingress; -} - - -action action_a(param0, param1, param2){ - modify_field(pkt.field_e_16, param0); - modify_field(pkt.field_f_16, param1); - modify_field(pkt.field_g_16, param2); -} - -action action_b(param0){ - modify_field(pkt.field_f_16, param0); -} - -action action_c(param0){ - modify_field(pkt.field_f_16, param0); -} - -action action_d(){ - no_op(); -} - -action action_e(){ - no_op(); -} - -table table_a { - reads { - pkt.field_a_32 : exact; - } - actions { - action_a; - } - size : 256; -} - -table table_b { - reads { - pkt.field_a_32 : exact; - } - actions { - action_b; - } - size : 256; -} - -table table_c { - reads { - pkt.field_a_32 : exact; - } - actions { - action_c; - } - size : 256; -} - -@pragma stage 3 -table table_d { - reads { - pkt.field_e_16 : exact; - } - actions { - action_d; - } - size : 256; -} - -@pragma stage 4 -table table_e { - reads { - pkt.field_g_16 : exact; - } - actions { - action_e; - } - size : 256; -} - - -/* Main control flow */ - -control ingress { - apply(table_a); - apply(table_b); - apply(table_c); - apply(table_d); - apply(table_e); -} - - diff --git a/backends/tofino/bf-asm/test/internal/test_config_135_tcam_range_7.p4 b/backends/tofino/bf-asm/test/internal/test_config_135_tcam_range_7.p4 deleted file mode 100644 index 6d2b9f2188f..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_135_tcam_range_7.p4 +++ /dev/null @@ -1,71 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_m_32 : 32; - field_n_32 : 32; - - field_o_10 : 10; - field_p_6 : 6; - } -} - - -parser start { - return parse_pkt; -} - -header pkt_t pkt; - -parser parse_pkt { - extract(pkt); - return ingress; -} - -action action_0(){ - modify_field(pkt.field_f_16, 1); -} - -action do_nothing(){ - no_op(); -} - -action do_nothing_1(){ -} - -@pragma entries_with_ranges 64 -table table_0 { - reads { - pkt.field_o_10 : range; - pkt.field_g_16 : exact; - } - actions { - do_nothing; - action_0; - } - size : 1024; -} - -/* Main control flow */ - -control ingress { - apply(table_0); -} - - diff --git a/backends/tofino/bf-asm/test/internal/test_config_136_tcam_error_detection.p4 b/backends/tofino/bf-asm/test/internal/test_config_136_tcam_error_detection.p4 deleted file mode 100644 index f0106c45264..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_136_tcam_error_detection.p4 +++ /dev/null @@ -1,73 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_m_32 : 32; - field_n_32 : 32; - - field_o_10 : 10; - field_p_6 : 6; - } -} - - -parser start { - return parse_pkt; -} - -header pkt_t pkt; - -parser parse_pkt { - extract(pkt); - return ingress; -} - -action action_0(){ - modify_field(pkt.field_f_16, 1); -} - -action do_nothing(){ - no_op(); -} - -action do_nothing_1(){ -} - -@pragma entries_with_ranges 64 -@pragma tcam_error_detect 1 -table table_0 { - reads { - pkt.field_o_10 : range; - pkt.field_g_16 : exact; - pkt.field_h_16 : exact; - } - actions { - do_nothing; - action_0; - } - size : 1024; -} - -/* Main control flow */ - -control ingress { - apply(table_0); -} - - diff --git a/backends/tofino/bf-asm/test/internal/test_config_137_tcam_error_detection_2.p4 b/backends/tofino/bf-asm/test/internal/test_config_137_tcam_error_detection_2.p4 deleted file mode 100644 index 16be2673158..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_137_tcam_error_detection_2.p4 +++ /dev/null @@ -1,131 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_m_32 : 32; - field_n_32 : 32; - - field_o_10 : 10; - field_p_6 : 6; - } -} - - -parser start { - return parse_pkt; -} - -header pkt_t pkt; - -parser parse_pkt { - extract(pkt); - return ingress; -} - -action action_0(){ - modify_field(pkt.field_f_16, 1); -} - -action do_nothing(){ - no_op(); -} - -action do_nothing_1(){ -} - -table table_a { - reads { - pkt.field_a_32 : ternary; - } - actions { - do_nothing; - } - size : 512; -} - -table table_b { - reads { - pkt.field_b_32 : ternary; - } - actions { - do_nothing; - } - size : 512; -} - -table table_c { - reads { - pkt.field_c_32 : ternary; - } - actions { - do_nothing; - } - size : 512; -} - -table table_d { - reads { - pkt.field_d_32 : ternary; - } - actions { - do_nothing; - } - size : 512; -} - - -@pragma entries_with_ranges 64 -@pragma tcam_error_detect 1 -table table_e { - reads { - pkt.field_o_10 : range; - pkt.field_g_16 : exact; - pkt.field_h_16 : exact; - } - actions { - do_nothing; - action_0; - } - size : 1024; -} - -@pragma tcam_error_detect 1 -table table_f { - reads { - pkt.field_g_16 : ternary; - } - actions { - do_nothing; - } - size : 1024; -} - -/* Main control flow */ - -// Should fit in one stage -control ingress { - apply(table_a); - apply(table_b); - apply(table_c); - apply(table_d); - apply(table_e); - apply(table_f); -} - - diff --git a/backends/tofino/bf-asm/test/internal/test_config_138_tcam_error_detection_3.p4 b/backends/tofino/bf-asm/test/internal/test_config_138_tcam_error_detection_3.p4 deleted file mode 100644 index 29cb55d5843..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_138_tcam_error_detection_3.p4 +++ /dev/null @@ -1,147 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_m_32 : 32; - field_n_32 : 32; - - field_o_10 : 10; - field_p_6 : 6; - } -} - - -parser start { - return parse_pkt; -} - -header pkt_t pkt; - -parser parse_pkt { - extract(pkt); - return ingress; -} - -action action_0(){ - modify_field(pkt.field_f_16, 1); -} - -action do_nothing(){ - no_op(); -} - -action do_nothing_1(){ -} - -table table_z { - reads { - pkt.field_l_8 : ternary; - } - actions { - do_nothing; - } - size : 512; -} - - -table table_a { - reads { - pkt.field_a_32 : ternary; - } - actions { - do_nothing; - } - size : 512; -} - -table table_b { - reads { - pkt.field_b_32 : ternary; - } - actions { - do_nothing; - } - size : 512; -} - -table table_c { - reads { - pkt.field_c_32 : ternary; - } - actions { - do_nothing; - } - size : 512; -} - -table table_d { - reads { - pkt.field_d_32 : ternary; - } - actions { - do_nothing; - } - size : 512; -} - - -@pragma entries_with_ranges 64 -@pragma tcam_error_detect 1 -table table_e { - reads { - pkt.field_o_10 : range; - pkt.field_g_16 : exact; - pkt.field_h_16 : exact; - } - actions { - do_nothing; - action_0; - } - size : 1024; -} - -@pragma tcam_error_detect 1 -table table_f { - reads { - pkt.field_g_16 : ternary; - } - actions { - do_nothing; - } - size : 1024; -} - -/* Main control flow */ - -// Should fit in two stages -control ingress { - apply(table_z); - apply(table_a); - apply(table_b); - apply(table_c); - apply(table_d); - apply(table_e); - apply(table_f); -} - - - - - - diff --git a/backends/tofino/bf-asm/test/internal/test_config_139_tcam_error_detection_4.p4 b/backends/tofino/bf-asm/test/internal/test_config_139_tcam_error_detection_4.p4 deleted file mode 100644 index cdb411333c9..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_139_tcam_error_detection_4.p4 +++ /dev/null @@ -1,140 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_m_32 : 32; - field_n_32 : 32; - - field_o_10 : 10; - field_p_6 : 6; - } -} - - -parser start { - return parse_pkt; -} - -header pkt_t pkt; - -parser parse_pkt { - extract(pkt); - return ingress; -} - -action action_0(){ - modify_field(pkt.field_f_16, 1); -} - -action do_nothing(){ - no_op(); -} - -action do_nothing_1(){ -} - -action count_it(){ - count(simple_stats, pkt.field_h_16); -} - -counter simple_stats { - type : packets; - instance_count : 16384; -} - -table table_a { - actions { - count_it; - } -} - -table table_b { - reads { - pkt.field_b_32 : ternary; - } - actions { - do_nothing; - } - size : 512; -} - -table table_c { - reads { - pkt.field_c_32 : ternary; - } - actions { - do_nothing; - } - size : 512; -} - -table table_d { - reads { - pkt.field_d_32 : ternary; - } - actions { - do_nothing; - } - size : 512; -} - - -@pragma entries_with_ranges 64 -@pragma tcam_error_detect 1 -table table_e { - reads { - pkt.field_o_10 : range; - pkt.field_g_16 : exact; - pkt.field_h_16 : exact; - } - actions { - do_nothing; - action_0; - } - size : 1024; -} - -@pragma tcam_error_detect 1 -table table_f { - reads { - pkt.field_g_16 : ternary; - } - actions { - do_nothing; - } - size : 1024; -} - -/* Main control flow */ - -// Should fit in one stages -control ingress { - apply(table_a); - apply(table_b); - apply(table_c); - apply(table_d); - apply(table_e); - apply(table_f); -} - - - - - - diff --git a/backends/tofino/bf-asm/test/internal/test_config_13_first_selection.p4 b/backends/tofino/bf-asm/test/internal/test_config_13_first_selection.p4 deleted file mode 100644 index 41464660316..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_13_first_selection.p4 +++ /dev/null @@ -1,152 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - - blah1 : 32; - blah2 : 8; - blah3 : 64; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - - -field_list first_field_list { - ipv4.blah1; - ipv4.blah2; - ipv4.blah3; -} - - -field_list_calculation first_hash { - input { - first_field_list; - } - algorithm : random; - output_width : 72; -} - - -action big_action(param0, param1, param2/*, param3*/){ - modify_field(ipv4.dstAddr, param0); - modify_field(ipv4.srcAddr, param1); - modify_field(ethernet.dstAddr, param2); - //modify_field(ethernet.srcAddr, param3); -} - -action action_0(param0){ - modify_field(ipv4.hdrChecksum, param0); -} - -action action_select(base, hash_size){ - modify_field_with_hash_based_offset(ipv4.blah2, base, first_hash, hash_size); -} - -action do_nothing(){ - no_op(); -} - -@pragma immediate 0 -@pragma selector_max_group_size 121 -table test_select { - reads { - ethernet.etherType : exact; - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - action_profile : some_action_profile; - size : 8192; -} - -action_profile some_action_profile { - actions { - action_0; - big_action; - do_nothing; - } - size : 512; - dynamic_action_selection : some_selector ; -} - -action_selector some_selector { - selection_key : first_hash; - selection_mode : resilient; -} - - - -/* -table table_select { - reads { - ethernet.etherType : exact; - } - actions { - do_nothing; - action_0; - //big_action; - } - max_size : 2048; -} -*/ - -table table_group { - reads { - ipv4.blah1 : ternary; - } - actions { - action_select; - } -} - - -/* Main control flow */ - -control ingress { - - apply(test_select); - - apply(table_group); -// apply(table_select); - -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_140_table_counter.p4 b/backends/tofino/bf-asm/test/internal/test_config_140_table_counter.p4 deleted file mode 100644 index e2c6ffdb2f6..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_140_table_counter.p4 +++ /dev/null @@ -1,103 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - color_0 : 4; - pad_0 : 4; - color_1 : 8; - color_2 : 8; - color_3 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -action action_0(param0){ - modify_field(pkt.field_f_16, param0); -} - -action action_1(param0){ - modify_field(pkt.field_g_16, param0); -} - -action action_2(param0){ - modify_field(pkt.field_h_16, param0); -} - - -action do_nothing(){ - no_op(); -} - -@pragma table_counter gateway_hit -table table_0 { - reads { - pkt.field_e_16 : ternary; - } - actions { - do_nothing; - } - size : 4096; -} - -@pragma table_counter table_miss -table table_1 { - reads { - pkt.field_e_16: exact; - pkt.field_f_16 mask 0xffff : exact; - } - actions { - do_nothing; - - } - default_action : action_1(0xf); - size : 16384; -} - -@pragma table_counter table_hit -table table_2 { - reads { - pkt.field_f_16: ternary; - } - actions { - do_nothing; - - } - default_action : do_nothing; - size : 2048; -} - - -/* Main control flow */ - -control ingress { - if (valid(pkt)){ - apply(table_0); - } else { - apply(table_1); - } - apply(table_2); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_142_stateful_bfd.p4 b/backends/tofino/bf-asm/test/internal/test_config_142_stateful_bfd.p4 deleted file mode 100644 index c8bc7973b08..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_142_stateful_bfd.p4 +++ /dev/null @@ -1,103 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - } -} - -header_type bfd_t { - fields { - bfd_tx_or_rx : 8; - bfd_discriminator : 8; - } -} - -header_type sample_t { - fields { - a : 8 ; - b : 8 ; - } -} - - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; -metadata bfd_t bfd_md; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -register bfd_cnt{ - /* - width : 8; - */ - layout : sample_t; - direct : bfd; - /* instance_count : 16384; */ -} - -/* -stateful_alu bfd_cnt_rx_alu { - register: bfd_cnt; - update_lo_1_value: 0; -} -stateful_alu bfd_cnt_tx_alu { - register: bfd_cnt; - condition_a: register > 3; - update_hi_1_value: 1; - update_lo_1_value: register + 1; - output_predicate: a; - output_expr: new_hi; - output_dst: egress_md.bfd_timeout_detected; -} -*/ - -action bfd_rx() { - /* execute_stateful_alu(bfd_cnt_rx_alu); */ -} - -action bfd_tx() { - /* execute_stateful_alu(bfd_cnt_tx_alu); */ -} - - -table bfd { - reads { - bfd_md.bfd_tx_or_rx : exact; - bfd_md.bfd_discriminator : exact; - } - actions { - bfd_rx; - bfd_tx; - } - size : 16384; -} - - - -/* Main control flow */ - -control ingress { - apply(bfd); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_143_packing_constants.p4 b/backends/tofino/bf-asm/test/internal/test_config_143_packing_constants.p4 deleted file mode 100644 index e971cc85ff7..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_143_packing_constants.p4 +++ /dev/null @@ -1,80 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_bit_7 : 1; - field_i_bit_6 : 1; - field_i_bit_5 : 1; - field_i_bit_4 : 1; - field_i_bit_3 : 1; - field_i_bit_2 : 1; - field_i_bit_1 : 1; - field_i_bit_0 : 1; - - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -action set_hi(){ - modify_field(pkt.field_i_bit_7, 1); - modify_field(pkt.field_i_bit_6, 0); - modify_field(pkt.field_i_bit_5, 1); -} - -action set_mid(){ - modify_field(pkt.field_i_bit_5, 1); - modify_field(pkt.field_i_bit_4, 0); - modify_field(pkt.field_i_bit_3, 1); -} - -action set_lo(){ - modify_field(pkt.field_i_bit_2, 1); - modify_field(pkt.field_i_bit_1, 0); - modify_field(pkt.field_i_bit_0, 1); -} - - - -table table_0 { - reads { - pkt.field_a_32 : ternary; - } - actions { - set_hi; - set_mid; - set_lo; - } - size : 512; -} - - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_144_recirculate.p4 b/backends/tofino/bf-asm/test/internal/test_config_144_recirculate.p4 deleted file mode 100644 index d65cdfcc40e..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_144_recirculate.p4 +++ /dev/null @@ -1,56 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -action action_0(port){ - recirculate(port); - //recirculate(15); -} - -table table_0 { - reads { - pkt.field_a_32 : ternary; - ig_intr_md_for_tm.ucast_egress_port : exact; - } - actions { - action_0; - } - size : 512; -} - - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_145_shift_primitives.p4 b/backends/tofino/bf-asm/test/internal/test_config_145_shift_primitives.p4 deleted file mode 100644 index fe9a5b620c6..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_145_shift_primitives.p4 +++ /dev/null @@ -1,69 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -action action_0(){ - shift_left(pkt.field_i_8, pkt.field_j_8, 2); -} - -action action_1(){ - shift_left(pkt.field_i_8, 1, 2); -} - -action action_2(){ - shift_right(pkt.field_i_8, pkt.field_j_8, 5); -} - -action action_3(){ - shift_right(pkt.field_i_8, 128, 5); -} - -table table_0 { - reads { - pkt.field_a_32 : ternary; - } - actions { - action_0; - action_1; - action_2; - action_3; - } - size : 512; -} - - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_146_two_drops.p4 b/backends/tofino/bf-asm/test/internal/test_config_146_two_drops.p4 deleted file mode 100644 index 85786e7c71f..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_146_two_drops.p4 +++ /dev/null @@ -1,69 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -action action_0() { - drop(); -} - -action action_1() { - drop(); -} - -table table_0 { - reads { - pkt.field_a_32 : ternary; - } - actions { - action_0; - } - size : 512; -} - -table table_1 { - reads { - pkt.field_b_32 : ternary; - } - actions { - action_1; - } - size : 512; -} - - - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_1); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_147_subtract_primitive.p4 b/backends/tofino/bf-asm/test/internal/test_config_147_subtract_primitive.p4 deleted file mode 100644 index 841db063e04..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_147_subtract_primitive.p4 +++ /dev/null @@ -1,69 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -action action_0() { - subtract(pkt.field_a_32, pkt.field_a_32, pkt.field_b_32); -} - -action action_1() { - subtract(pkt.field_i_8, pkt.field_j_8, pkt.field_k_8); -} - -table table_0 { - reads { - pkt.field_a_32 : ternary; - } - actions { - action_0; - } - size : 512; -} - -table table_1 { - reads { - pkt.field_b_32 : ternary; - } - actions { - action_1; - } - size : 512; -} - - - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_1); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_148_action_profile.p4 b/backends/tofino/bf-asm/test/internal/test_config_148_action_profile.p4 deleted file mode 100644 index 8128238bb98..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_148_action_profile.p4 +++ /dev/null @@ -1,67 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -action do_nothing(){ - no_op(); -} - -action action_0(param0) { - subtract(pkt.field_a_32, param0, pkt.field_a_32); -} - -action action_1() { - subtract(pkt.field_i_8, pkt.field_j_8, pkt.field_k_8); -} - -table table_0 { - reads { - pkt.field_a_32 : exact; - } - action_profile: table_0_action_profile; - size : 3072; -} - -action_profile table_0_action_profile { - actions { - do_nothing; - action_0; - action_1; - } - size : 3072; -} - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_149_signed_and_saturating_add_sub.p4 b/backends/tofino/bf-asm/test/internal/test_config_149_signed_and_saturating_add_sub.p4 deleted file mode 100644 index 990739a4cd1..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_149_signed_and_saturating_add_sub.p4 +++ /dev/null @@ -1,85 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_signed : 32 (signed); - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_sat : 16 (saturating); - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_signed_sat : 8 (signed, saturating); - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -//signed -action action_0() { - add(pkt.field_a_signed, pkt.field_a_signed, pkt.field_b_32); -} - -//saturating -action action_1() { - add_to_field(pkt.field_e_sat, pkt.field_f_16); -} - -//signed and saturating -action action_2() { - add(pkt.field_i_signed_sat, pkt.field_i_signed_sat, pkt.field_j_8); -} - -//signed -action action_3() { - subtract(pkt.field_a_signed, pkt.field_a_signed, pkt.field_b_32); -} - -//saturating -action action_4() { - subtract(pkt.field_e_sat, pkt.field_e_sat, pkt.field_f_16); -} - -//signed and saturating -action action_5() { - subtract(pkt.field_i_signed_sat, pkt.field_i_signed_sat, pkt.field_j_8); -} - - -table table_0 { - reads { - pkt.field_c_32 : ternary; - } - actions { - action_0; - action_1; - action_2; - action_3; - action_4; - action_5; - } - size : 512; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_14_auto_immediate_action_data.p4 b/backends/tofino/bf-asm/test/internal/test_config_14_auto_immediate_action_data.p4 deleted file mode 100644 index 80433917856..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_14_auto_immediate_action_data.p4 +++ /dev/null @@ -1,97 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - - -field_list first_field_list { - ipv4.protocol; - ipv4.srcAddr; -} - - -field_list_calculation first_hash { - input { - first_field_list; - } - algorithm : crc16; - output_width : 16; -} - -action big_action(param0, param1, param2, param3){ - modify_field(ipv4.dstAddr, param0); - modify_field(ipv4.srcAddr, param1); - modify_field(ethernet.dstAddr, param2); - modify_field(ethernet.srcAddr, param3); -} - -action action_0(){ - modify_field(ipv4.hdrChecksum, 1); -} - -action do_nothing(){ - no_op(); -} - -@pragma immediate 1 -table table_0 { - reads { - ipv4.dstAddr : exact ; - } - actions { - action_0; -// big_action; - do_nothing; - } -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_150_action_bus_allocation.p4 b/backends/tofino/bf-asm/test/internal/test_config_150_action_bus_allocation.p4 deleted file mode 100644 index e47869fff7a..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_150_action_bus_allocation.p4 +++ /dev/null @@ -1,90 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_signed : 32 (signed); - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_sat : 16 (saturating); - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_signed_sat : 8 (signed, saturating); - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -action action_0(param0){ - add(pkt.field_a_signed, pkt.field_a_signed, param0); -} - -action action_1(param0) { - add_to_field(pkt.field_e_sat, param0); -} - -action action_2(param0) { - add(pkt.field_i_signed_sat, pkt.field_i_signed_sat, param0); -} - -action action_3(param0) { - modify_field(pkt.field_c_32, param0); -} - -action action_4(param0) { - modify_field(pkt.field_g_16, param0); -} - -action action_5(param0) { - modify_field(pkt.field_k_8, param0); -} - - -table table_0 { - reads { - pkt.field_c_32 : ternary; - } - actions { - action_0; - action_1; - action_2; - } - size : 512; -} - -table table_1 { - reads { - pkt.field_d_32 : ternary; - } - actions { - action_3; - action_4; - action_5; - } - size : 512; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_1); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_151_action_bus_allocation_2.p4 b/backends/tofino/bf-asm/test/internal/test_config_151_action_bus_allocation_2.p4 deleted file mode 100644 index 3d7c664fb84..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_151_action_bus_allocation_2.p4 +++ /dev/null @@ -1,84 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_signed : 32 (signed); - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_sat : 16 (saturating); - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_signed_sat : 8 (signed, saturating); - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -action action_0(param0){ - modify_field(pkt.field_b_32, param0, 0x0ff00000); -} - -action action_1(param0){ - modify_field(pkt.field_c_32, param0, 0x000ff000); -} - -action action_2(param0){ - modify_field(pkt.field_d_32, param0, 0x0ff0); -} - -table table_0 { - reads { - pkt.field_h_16 : ternary; - } - actions { - action_0; - } - size : 512; -} - -table table_1 { - reads { - pkt.field_h_16 : ternary; - } - actions { - action_1; - } - size : 512; -} - -table table_2 { - reads { - pkt.field_h_16 : ternary; - } - actions { - action_2; - } - size : 512; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_1); - apply(table_2); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_152_stateful_simple_cntr.p4 b/backends/tofino/bf-asm/test/internal/test_config_152_stateful_simple_cntr.p4 deleted file mode 100644 index b15b1ce5ea3..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_152_stateful_simple_cntr.p4 +++ /dev/null @@ -1,72 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -register stateful_cntr{ - width : 16; - /* direct : match_cntr; */ - instance_count : 8192; -} - - -blackbox stateful_alu cntr { - reg: stateful_cntr; - update_lo_1_value: register_lo + 1; -} - - -action cnt() { - cntr.execute_stateful_alu(); -} - -action do_nothing(){} - -table match_cntr { - reads { - pkt.field_a_32 : exact; - } - actions { - cnt; - do_nothing; - } - size : 16384; -} - - - -/* Main control flow */ - -control ingress { - apply(match_cntr); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_153_stateful_simple_cntr_with_output.p4 b/backends/tofino/bf-asm/test/internal/test_config_153_stateful_simple_cntr_with_output.p4 deleted file mode 100644 index 93032cd2278..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_153_stateful_simple_cntr_with_output.p4 +++ /dev/null @@ -1,91 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - } -} - -header_type meta_t { - fields { - count_value : 16; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; -metadata meta_t meta; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -register stateful_cntr{ - width : 16; - direct : match_cntr; - /* instance_count : 8192; */ -} - - -blackbox stateful_alu cntr { - reg: stateful_cntr; - update_lo_1_value: register_lo + 1; - output_value : alu_lo; - output_dst : meta.count_value; -} - - -action cnt(/* param0 */) { - cntr.execute_stateful_alu(); - /* modify_field(pkt.field_e_16, param0); */ -} - -action do_nothing(){} - -/* @pragma immediate 0 */ -table match_cntr { - reads { - pkt.field_a_32 : exact; - } - actions { - cnt; - } - size : 16384; -} - -table dummy { - reads { - meta.count_value : exact; - } - actions { - do_nothing; - } -} - - -/* Main control flow */ - -control ingress { - apply(match_cntr); - apply(dummy); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_154_stateful_sampling.p4 b/backends/tofino/bf-asm/test/internal/test_config_154_stateful_sampling.p4 deleted file mode 100644 index 6fdea7f3435..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_154_stateful_sampling.p4 +++ /dev/null @@ -1,85 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - } -} - -header_type meta_t { - fields { - needs_sampling : 8 (signed, saturating); - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; -metadata meta_t meta; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -register flow_cnt { - width : 8; - direct : match_tbl; - /* instance_count : 65536; */ -} - -blackbox stateful_alu sampler_alu { - reg: flow_cnt; - condition_lo: register_lo == 10; /* sample limit */ - update_lo_1_predicate: condition_lo; - update_lo_1_value: 1; - update_lo_2_predicate: not condition_lo; - update_lo_2_value: register_lo + 1; - output_predicate: condition_lo; - output_value : alu_lo; - output_dst : meta.needs_sampling; -} - -action sample(){ - sampler_alu.execute_stateful_alu(); -} - -action do_nothing(){} - -table match_tbl { - reads { - pkt.field_a_32 : ternary; - meta.needs_sampling : exact; /* hack to ensure phv puts it in mau space */ - } - actions { - sample; - } - size : 8192; -} - - - - -/* Main control flow */ - -control ingress { - apply(match_tbl); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_155_stateful_3_alus.p4 b/backends/tofino/bf-asm/test/internal/test_config_155_stateful_3_alus.p4 deleted file mode 100644 index 7e91def8360..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_155_stateful_3_alus.p4 +++ /dev/null @@ -1,139 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - } -} - -header_type meta_t { - fields { - count_value : 16; - needs_sampling : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; -metadata meta_t meta; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -register stateful_cntr_1{ - width : 16; - direct : match_cntr_1; - /* instance_count : 8192; */ -} - -register stateful_cntr_2{ - width : 16; - direct : match_cntr_2; - /* instance_count : 8192; */ -} - -register flow_cnt { - width : 8; - direct : match_flow; - /* instance_count : 65536; */ -} - -blackbox stateful_alu cntr_1 { - reg: stateful_cntr_1; - update_lo_1_value: register_lo + 1; -} - -blackbox stateful_alu cntr_2 { - reg: stateful_cntr_2; - update_lo_1_value: register_lo + 1; - output_value : alu_lo; - output_dst : meta.count_value; -} - -blackbox stateful_alu sampler_alu { - reg: flow_cnt; - condition_lo: register_lo == 10; /* sample limit */ - update_lo_1_predicate: condition_lo; - update_lo_1_value: 1; - update_lo_2_predicate: not condition_lo; - update_lo_2_value: register_lo + 1; - output_predicate: condition_lo; - output_value : alu_lo; - output_dst : meta.needs_sampling; -} - - -action cnt_1() { - cntr_1.execute_stateful_alu(); -} - -action cnt_2() { - cntr_2.execute_stateful_alu(); -} - -action sample(){ - sampler_alu.execute_stateful_alu(); -} - -@pragma table_counter disabled -table match_cntr_1 { - reads { - pkt.field_a_32 : exact; - } - actions { - cnt_1; - } - size : 16384; -} - -table match_cntr_2 { - reads { - pkt.field_a_32 : exact; - pkt.field_j_8 : exact; - meta.count_value : exact; - } - actions { - cnt_2; - } - size : 16384; -} - -table match_flow { - reads { - pkt.field_a_32 : ternary; - meta.needs_sampling : exact; /* hack to ensure phv puts it in mau space */ - } - actions { - sample; - } - size : 8192; -} - -/* Main control flow */ - -control ingress { - apply(match_cntr_1); - apply(match_cntr_2); - apply(match_flow); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_156_indirect_stateful_cntr.p4 b/backends/tofino/bf-asm/test/internal/test_config_156_indirect_stateful_cntr.p4 deleted file mode 100644 index e351f842d4f..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_156_indirect_stateful_cntr.p4 +++ /dev/null @@ -1,107 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - } -} - -header_type meta_t { - fields { - count_value : 16; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; -metadata meta_t meta; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -register stateful_cntr{ - width : 16; - /* direct : match_cntr; */ - instance_count : 8192; -} - - -blackbox stateful_alu cntr { - reg: stateful_cntr; - update_lo_1_value: register_lo + 1; - output_value : alu_lo; - output_dst : meta.count_value; - initial_register_lo_value : 1; -} - -/* -blackbox stateful_alu cntr2 { - reg: stateful_cntr; - update_lo_1_value: register_lo + 2; - output_value : alu_lo; - output_dst : meta.count_value; - initial_register_lo_value : 1; -} -*/ - -action cnt(/* param0 */) { - cntr.execute_stateful_alu(); - /* modify_field(pkt.field_e_16, param0); */ -} - -/* -action cnt2(){ - cntr2.execute_stateful_alu(); -} -*/ - -action do_nothing(){} - -/* @pragma immediate 0 */ -table match_cntr { - reads { - pkt.field_a_32 : exact; - } - actions { - cnt; - } - size : 16384; -} - -table dummy { - reads { - meta.count_value : exact; - } - actions { - do_nothing; - } -} - - -/* Main control flow */ - -control ingress { - apply(match_cntr); - apply(dummy); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_157_random_number_generator.p4 b/backends/tofino/bf-asm/test/internal/test_config_157_random_number_generator.p4 deleted file mode 100644 index 22db9116f55..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_157_random_number_generator.p4 +++ /dev/null @@ -1,75 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -action action_0(param0){ - modify_field_rng_uniform(pkt.field_a_32, 0, 65535); - modify_field(pkt.field_e_16, param0); -} - -action action_1(){ - modify_field_rng_uniform(pkt.field_d_32, 0, 0xffffff); -} - -action do_nothing(){} - -table table_0 { - reads { - pkt.field_b_32 : ternary; - } - actions { - action_0; - do_nothing; - } - size : 512; -} - -table table_1 { - reads { - pkt.field_c_32 : ternary; - } - actions { - action_1; - do_nothing; - } - size : 512; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_1); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_158_share_vliw.p4 b/backends/tofino/bf-asm/test/internal/test_config_158_share_vliw.p4 deleted file mode 100644 index deae036f0bf..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_158_share_vliw.p4 +++ /dev/null @@ -1,81 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -action action_0(){ - add(pkt.field_a_32, pkt.field_b_32, pkt.field_c_32); - modify_field(pkt.field_j_8, 3); -} - -action action_1(){ - subtract(pkt.field_a_32, pkt.field_b_32, pkt.field_c_32); - shift_left(pkt.field_e_16, pkt.field_e_16, 5); -} - -action do_nothing(){ no_op();} - -table table_0 { - reads { - pkt.field_b_32 : ternary; - } - actions { - action_0; - action_1; - do_nothing; - } - size : 512; -} - -table table_1 { - reads { - pkt.field_c_32 : ternary; - } - actions { - action_0; - action_1; - do_nothing; - } - size : 512; -} - - -/* Main control flow */ - -control ingress { - if (pkt.field_i_8 == 1){ - apply(table_0); - } else { - apply(table_1); - } -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_159_stateful_using_phv_field.p4 b/backends/tofino/bf-asm/test/internal/test_config_159_stateful_using_phv_field.p4 deleted file mode 100644 index 149e68edcaa..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_159_stateful_using_phv_field.p4 +++ /dev/null @@ -1,90 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_16 : 16; - field_j_16 : 16; - field_k_8 : 8; - field_l_8 : 8; - - } -} - -header_type meta_t { - fields { - needs_sampling : 16 (signed, saturating); - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; -metadata meta_t meta; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -@pragma stateful_table_counter table_hit -register flow_cnt { - width : 16; - direct : match_tbl; - /* instance_count : 65536; */ -} - -blackbox stateful_alu sampler_alu { - reg: flow_cnt; - condition_hi: pkt.field_i_16 == 3; /* testing */ - condition_lo: register_lo == 10; /* sample limit */ - update_lo_1_predicate: condition_lo; - update_lo_1_value: 1; - update_lo_2_predicate: not condition_lo; - update_lo_2_value: register_lo + 1; - update_hi_1_value: pkt.field_j_16 + 2; - output_predicate: condition_lo; - output_value : alu_lo; - output_dst : meta.needs_sampling; -} - -action sample(){ - sampler_alu.execute_stateful_alu(); -} - -action do_nothing(){} - -table match_tbl { - reads { - pkt.field_a_32 : ternary; - pkt.field_i_16 : exact; /* hack */ - pkt.field_j_16 : exact; /* hack */ - meta.needs_sampling : exact; /* hack to ensure phv puts it in mau space */ - } - actions { - sample; - } - size : 4096; -} - - - - -/* Main control flow */ - -control ingress { - apply(match_tbl); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_15_wide_key.p4 b/backends/tofino/bf-asm/test/internal/test_config_15_wide_key.p4 deleted file mode 100644 index 34c0fe1a645..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_15_wide_key.p4 +++ /dev/null @@ -1,93 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - - -field_list first_field_list { - ipv4.protocol; - ipv4.srcAddr; -} - - -field_list_calculation first_hash { - input { - first_field_list; - } - algorithm : crc16; - output_width : 16; -} - -action action_0(param0){ - modify_field(ipv4.hdrChecksum, param0); -} - -action do_nothing(){ - no_op(); -} - -//@pragma stage 2 -table table_0 { - reads { - ipv4.dstAddr : exact ; - ipv4.srcAddr : exact ; - ethernet.dstAddr : exact ; - ethernet.srcAddr : exact ; - ipv4.protocol : exact ; - } - actions { - action_0; - do_nothing; - } -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_160_stateful_single_bit_mode.p4 b/backends/tofino/bf-asm/test/internal/test_config_160_stateful_single_bit_mode.p4 deleted file mode 100644 index d197d18151f..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_160_stateful_single_bit_mode.p4 +++ /dev/null @@ -1,127 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 1; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_16 : 16; - field_j_16 : 16; - field_k_8 : 8; - field_l_8 : 8; - - from_pkt_gen : 1; - pad_0 : 7; - } -} - -header_type meta_t { - fields { - live_port : 1 (signed, saturating); - pad_0 : 7; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; -metadata meta_t meta; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -@pragma stateful_table_counter table_hit -register port_liveness_update { - width : 1; - /* direct : port_liveness_update_match_tbl; */ - instance_count : 65536; -} - -blackbox stateful_alu make_port_live { - reg: port_liveness_update; - selector_binding: selector_match_tbl; - update_lo_1_value: clr_bit; - output_value : alu_lo; - output_dst : meta.live_port; -} - -action port_alive(){ - make_port_live.execute_stateful_alu(); -} - -action action_0(param_0){ - modify_field(pkt.field_b_32, param_0); -} - -action do_nothing(){} - - -field_list selector_fields { - pkt.field_c_32; - pkt.field_d_32; -} - -field_list_calculation selector_hash { - input { - selector_fields; - } - algorithm : crc16; - output_width : 16; -} - - -action_selector some_selector { - selection_key : selector_hash; - selection_mode : fair; -} - -action_profile selector_match_tbl_action_profile { - actions { - action_0; - } - size : 1024; - dynamic_action_selection : some_selector; -} - - -table selector_match_tbl { - reads { - pkt.field_a_32 : ternary; - } - action_profile: selector_match_tbl_action_profile; - size : 4096; -} - -table port_liveness_update_match_tbl { - reads { - pkt.field_k_8 : ternary; - meta.live_port : exact; /* HACK */ - } - actions { - port_alive; - } - size : 1024; -} - -/* Main control flow */ - -control ingress { - if (pkt.from_pkt_gen == 0){ - apply(selector_match_tbl); - } else { - apply(port_liveness_update_match_tbl); - } -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_161_new_primitives.p4 b/backends/tofino/bf-asm/test/internal/test_config_161_new_primitives.p4 deleted file mode 100644 index ce3ffc15811..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_161_new_primitives.p4 +++ /dev/null @@ -1,123 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32 (signed); - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_x_32 : 32 (signed); - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -action action_0(){ - bit_nor(pkt.field_a_32, pkt.field_b_32, pkt.field_c_32); -} -action action_1(param0){ - bit_nand(pkt.field_a_32, param0, pkt.field_c_32); -} -action action_2(param0){ - bit_xnor(pkt.field_a_32, pkt.field_b_32, param0); -} -action action_3(){ - bit_not(pkt.field_a_32, pkt.field_d_32); -} -action action_4(param0){ - min(pkt.field_a_32, pkt.field_d_32, param0); -} -action action_5(param0){ - max(pkt.field_a_32, param0, pkt.field_d_32); -} -action action_6(){ - min(pkt.field_b_32, pkt.field_d_32, 7); -} -action action_7(param0){ - max(pkt.field_b_32, param0, pkt.field_d_32); -} -action action_8(param0){ - max(pkt.field_x_32, pkt.field_x_32, param0); -} -action action_9(){ - shift_right(pkt.field_x_32, pkt.field_x_32, 7); -} - -action action_10(param0){ - //bit_andca(pkt.field_a_32, pkt.field_a_32, param0); - bit_andca(pkt.field_a_32, param0, pkt.field_a_32); -} - -action action_11(param0){ - //bit_andcb(pkt.field_a_32, pkt.field_a_32, param0); - bit_andcb(pkt.field_a_32, param0, pkt.field_a_32); -} - -action action_12(param0){ - //bit_orca(pkt.field_a_32, pkt.field_a_32, param0); - bit_orca(pkt.field_a_32, param0, pkt.field_a_32); -} - -action action_13(param0){ - //bit_orcb(pkt.field_a_32, pkt.field_a_32, param0); - bit_orcb(pkt.field_a_32, param0, pkt.field_a_32); -} - -action do_nothing(){} - -table table_0 { - reads { - pkt.field_a_32 : ternary; - pkt.field_b_32 : ternary; - pkt.field_c_32 : ternary; - pkt.field_d_32 : ternary; - pkt.field_g_16 : ternary; - pkt.field_h_16 : ternary; - } - actions { - action_0; - action_1; - action_2; - action_3; - action_4; - action_5; - action_6; - action_7; - action_8; - action_9; - action_10; - action_11; - action_12; - action_13; - do_nothing; - } - size : 512; -} - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_162_add_header_init.p4 b/backends/tofino/bf-asm/test/internal/test_config_162_add_header_init.p4 deleted file mode 100644 index e14a64a86dd..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_162_add_header_init.p4 +++ /dev/null @@ -1,80 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32 (signed); - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_x_32 : 32 (signed); - } -} - -header_type to_add_t { - fields { - field_one : 16; - field_two : 8; - field_three : 32; - field_four : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; -header to_add_t to_add; - -parser parse_ethernet { - extract(pkt); - return select(pkt.field_i_8){ - 1 : parse_to_add; - default: ingress; - } -} - -parser parse_to_add { - extract(to_add); - return ingress; -} - -action action_0(){ - add_header(to_add); - modify_field(to_add.field_two, 15); -} - -action do_nothing(){} - -table table_0 { - reads { - pkt.field_a_32 : ternary; - to_add.field_one : exact; - to_add.field_three : exact; - to_add.field_four : exact; - } - actions { - action_0; - do_nothing; - } - size : 512; -} - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_163_stateful_table_math_unit.p4 b/backends/tofino/bf-asm/test/internal/test_config_163_stateful_table_math_unit.p4 deleted file mode 100644 index 6b84ade4ec5..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_163_stateful_table_math_unit.p4 +++ /dev/null @@ -1,92 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - } -} - -header_type meta_t { - fields { - count_value : 16; - needs_sampling : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; -metadata meta_t meta; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -register stateful_cntr_1{ - width : 32; - direct : match_cntr_1; - //attributes: signed, saturating; - /* instance_count : 8192; */ -} - -blackbox stateful_alu cntr_1 { - reg: stateful_cntr_1; - condition_lo: pkt.field_e_16 == 7; - update_lo_1_predicate: condition_lo; - update_lo_1_value: register_lo + 1; - update_lo_2_predicate: not condition_lo; - update_lo_2_value: register_hi ^ math_unit; - - math_unit_input: pkt.field_f_16; - math_unit_output_scale: 4; - math_unit_exponent_shift: -1; - math_unit_exponent_invert: True; - math_unit_lookup_table: 0xf 14 13 0xc 0x0b 10 9 8 7 6 5 4 3 2 1 0; - - output_predicate: condition_lo; - output_value : alu_lo; - output_dst : meta.needs_sampling; -} - -action cnt_1() { - /* cntr_1.execute_stateful_alu(pkt.field_i_8); */ - cntr_1.execute_stateful_alu(); -} - -table match_cntr_1 { - reads { - pkt.field_a_32 : exact; - pkt.field_e_16 : exact; - pkt.field_f_16 : exact; - meta.needs_sampling: exact; - } - actions { - cnt_1; - } - size : 16384; -} - -/* Main control flow */ - -control ingress { - apply(match_cntr_1); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_164_stateful_deterministic_sampling.p4 b/backends/tofino/bf-asm/test/internal/test_config_164_stateful_deterministic_sampling.p4 deleted file mode 100644 index 9575811c3fd..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_164_stateful_deterministic_sampling.p4 +++ /dev/null @@ -1,115 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type meta_t { - fields { - needs_sampling : 8; - } -} - -header ethernet_t ethernet; -header ipv4_t ipv4; -metadata meta_t meta; - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x0800 : parse_ipv4; - default : ingress; - } -} - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -register flow_cnt { - width : 8; - direct : ipv4_fib; -} - -blackbox stateful_alu sampler_alu { - reg: flow_cnt; - condition_lo: register_lo == 100; - update_lo_1_predicate: condition_lo; - update_lo_1_value: 0; - - update_lo_2_predicate: not condition_lo; - update_lo_2_value: register_lo + 1; - update_hi_1_value: 1; - - output_predicate: condition_lo; - output_value : alu_hi; - output_dst : meta.needs_sampling; -} - -action on_miss() { } - -action drop_me(){ - drop(); -} - -action ipv4_fib_hit() { - sampler_alu.execute_stateful_alu(); -} - -table ipv4_fib { - reads { - /* l3_metadata.vrf : exact; */ - ipv4.dstAddr : exact; - } - actions { - ipv4_fib_hit; - } - default_action: on_miss; - size : 1024; -} - -table check_needs { - reads { - meta.needs_sampling : exact; - } - actions { - drop_me; - on_miss; - } -} - -/* Main control flow */ - -control ingress { - apply(ipv4_fib); - apply(check_needs); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_165_stateful_bfd_failure_detection.p4 b/backends/tofino/bf-asm/test/internal/test_config_165_stateful_bfd_failure_detection.p4 deleted file mode 100644 index 871a7db48da..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_165_stateful_bfd_failure_detection.p4 +++ /dev/null @@ -1,125 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type meta_t { - fields { - bfd_timeout_detected : 8; - bfd_tx_or_rx : 8; - bfd_discriminator : 16; - } -} - -header ethernet_t ethernet; -header ipv4_t ipv4; -metadata meta_t meta; - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x0800 : parse_ipv4; - default : ingress; - } -} - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -register bfd_cnt { - width : 8; - /* direct : bfd; */ - instance_count : 1024; -} - -blackbox stateful_alu bfd_cnt_rx_alu { - reg: bfd_cnt; - update_lo_1_value : 0; -} - -blackbox stateful_alu bfd_cnt_tx_alu { - reg: bfd_cnt; - condition_lo: register_lo > 3; - - update_hi_1_value : 1; - update_lo_1_value : register_lo + 1; - - output_predicate: condition_lo; - output_value : alu_hi; - output_dst : meta.bfd_timeout_detected; -} - -action on_miss() { } - -action drop_me(){ - drop(); -} - -action bfd_rx() { - bfd_cnt_rx_alu.execute_stateful_alu(); -} - -action bfd_tx() { - bfd_cnt_tx_alu.execute_stateful_alu(); -} - - -table bfd { - reads { - meta.bfd_tx_or_rx : exact; - meta.bfd_discriminator : exact; - } - actions { - bfd_rx; - bfd_tx; - } - size : 1024; -} - -table check_needs { - reads { - meta.bfd_timeout_detected : exact; - } - actions { - drop_me; - on_miss; - } -} - -/* Main control flow */ - -control ingress { - apply(bfd); - apply(check_needs); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_166_stateful_generic_counter.p4 b/backends/tofino/bf-asm/test/internal/test_config_166_stateful_generic_counter.p4 deleted file mode 100644 index 2bb1d3f08f2..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_166_stateful_generic_counter.p4 +++ /dev/null @@ -1,96 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type meta_t { - fields { - encap_decap_size : 16; - } -} - -header ethernet_t ethernet; -header ipv4_t ipv4; -metadata meta_t meta; - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x0800 : parse_ipv4; - default : ingress; - } -} - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -register cntr { - width : 64; - instance_count : 8192; -} - -blackbox stateful_alu counter_alu { - reg: cntr; - condition_hi: register_lo < 0; - condition_lo: register_lo + meta.encap_decap_size < 0; - - update_hi_1_predicate: condition_hi and not condition_lo; - update_hi_1_value: register_hi + 1; - - update_hi_2_predicate: not condition_hi and condition_lo; - update_hi_2_value: register_hi - 1; - - update_lo_1_value : register_lo + meta.encap_decap_size; -} - -action increment_counter() { - counter_alu.execute_stateful_alu(); -} - -table packet_offset_counting { - reads { - meta.encap_decap_size : exact; /* hack to get allocated */ - ig_intr_md.ingress_port : exact; - } - actions { - increment_counter; - } - size : 1024; -} - -/* Main control flow */ - -control ingress { - apply(packet_offset_counting); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_167_stateful_flowlet_switching.p4 b/backends/tofino/bf-asm/test/internal/test_config_167_stateful_flowlet_switching.p4 deleted file mode 100644 index ecd86a811b5..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_167_stateful_flowlet_switching.p4 +++ /dev/null @@ -1,144 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 4; - flags : 8; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type flowlet_state_layout { - fields { - padding : 16; - flowlet_next_hop : 16; - flowlet_last_time_seen : 32; - } -} - -header_type meta_t { - fields { - next_hop : 16; - tstamp : 32; - } -} - -header ethernet_t ethernet; -header ipv4_t ipv4; -header tcp_t tcp; -metadata meta_t meta; - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x0800 : parse_ipv4; - default : ingress; - } -} - -parser parse_ipv4 { - extract(ipv4); - return select(ipv4.protocol){ - 0x06 : parse_tcp; - default : ingress; - } -} - -parser parse_tcp { - extract(tcp); - return ingress; -} - -field_list hash_fields_5_tuple { - ipv4.srcAddr; - ipv4.dstAddr; - ipv4.protocol; - tcp.srcPort; - tcp.dstPort; -} - -field_list_calculation hash_id { - input { hash_fields_5_tuple; } - algorithm : crc32; - output_width : 16; -} - - -register flowlet_state { - layout : flowlet_state_layout; - instance_count : 65536; -} - -blackbox stateful_alu flowlet_state_alu { - reg: flowlet_state; - - condition_lo: meta.tstamp - register_lo > 20000; - - update_hi_1_predicate: condition_lo; - update_hi_1_value: register_hi; - - update_lo_1_value: meta.tstamp; - - output_value: alu_hi; - output_dst: meta.next_hop; -} - -action get_flowlet_next_hop() { - flowlet_state_alu.execute_stateful_alu(); -} - -table flowlet_next_hop { - reads { /* HACK, because actually want to use hash result to index */ - meta.next_hop : ternary; - meta.tstamp: exact; - } - actions { - get_flowlet_next_hop; - } - size : 1024; -} - -/* Main control flow */ - -control ingress { - apply(flowlet_next_hop); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_168_meter_bug.p4 b/backends/tofino/bf-asm/test/internal/test_config_168_meter_bug.p4 deleted file mode 100644 index ccf39b541cb..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_168_meter_bug.p4 +++ /dev/null @@ -1,89 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -//#include "tofino/stateful_alu_blackbox.p4" - - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - - -header ethernet_t ethernet; -header ipv4_t ipv4; - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x0800 : parse_ipv4; - default : ingress; - } -} - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - - -meter exm_meter2 { - type : bytes; - direct : table_0; - result : ipv4.diffserv; -} - - -action nop() { -} - -action action_0(){ - modify_field(ipv4.ttl, 4); -} - -action action_1(){ - modify_field(ipv4.ttl, 5); -} - - -table table_0 { - reads { - ipv4.srcAddr : exact; - ipv4.dstAddr : exact; - ipv4.diffserv : exact; /* hack */ - } - actions { - action_0; - action_1; - nop; - } -} - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_169_stateful_sflow_sequence.p4 b/backends/tofino/bf-asm/test/internal/test_config_169_stateful_sflow_sequence.p4 deleted file mode 100644 index e030a838ece..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_169_stateful_sflow_sequence.p4 +++ /dev/null @@ -1,195 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 4; - flags : 8; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type meta_t { - fields { - sflow_sample_seq_no : 32; - sflow_src : 16; - } -} - -header_type sflowHdr_t { - fields { - seq_num : 16; - num_samples : 16; - temp : 16 (saturating); - drops : 16; - } -} - - -header ethernet_t ethernet; -header ipv4_t ipv4; -header tcp_t tcp; -metadata meta_t meta; -metadata sflowHdr_t sflowHdr; - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x0800 : parse_ipv4; - default : ingress; - } -} - -parser parse_ipv4 { - extract(ipv4); - return select(ipv4.protocol){ - 0x06 : parse_tcp; - default : ingress; - } -} - -parser parse_tcp { - extract(tcp); - return ingress; -} - - -register sflow_state_seq_num { - width : 32; - direct : sflow_seq_num; -} - -blackbox stateful_alu seq_num_gen { - reg: sflow_state_seq_num; - - update_lo_1_value: register_lo + 1; - update_hi_1_value: register_lo; - - output_value: alu_hi; - output_dst: meta.sflow_sample_seq_no; -} - - -register sflow_state_exp_seq_num { - width : 32; - direct : sflow_verify_seq_no_step_2; -} - -blackbox stateful_alu sflow_exp_seq_num { - reg: sflow_state_exp_seq_num; - - update_hi_1_value: sflowHdr.seq_num - register_lo; - update_lo_1_value: sflowHdr.temp; - - output_value: alu_hi; - output_dst: sflowHdr.drops; -} - - -action get_sflow_seq_num(){ - seq_num_gen.execute_stateful_alu(); -} - -action calc_next_seq_num() { - add(sflowHdr.temp, sflowHdr.seq_num, sflowHdr.num_samples); -} - -action chk_sflow_seq_num() { - sflow_exp_seq_num.execute_stateful_alu(); -} - -action drop_me(){ - drop(); -} - -action do_nothing(){} - - -table sflow_seq_num { - reads { - meta.sflow_src: exact; - meta.sflow_sample_seq_no : exact; /* HACK */ - } - actions { - get_sflow_seq_num; - } - size : 1024; -} - -table sflow_verify_seq_no_step_1 { - actions { - calc_next_seq_num; - } - size : 512; -} - -@pragma stage 1 /* Provided dependency graph is incorrect */ -table sflow_verify_seq_no_step_2 { - reads { - meta.sflow_src : exact; - } - actions { - chk_sflow_seq_num; - } - size : 16384; -} - -table sflow_verify_seq_no_step_3 { - reads { - sflowHdr.drops : ternary; - } - actions { - drop_me; - do_nothing; - } - size : 512; -} - - - -/* Main control flow */ - -control ingress { - apply(sflow_seq_num); - apply(sflow_verify_seq_no_step_1); - apply(sflow_verify_seq_no_step_2); - apply(sflow_verify_seq_no_step_3); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_16_action_packing_multi_entry_with_pad.p4 b/backends/tofino/bf-asm/test/internal/test_config_16_action_packing_multi_entry_with_pad.p4 deleted file mode 100644 index 393a97e76ed..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_16_action_packing_multi_entry_with_pad.p4 +++ /dev/null @@ -1,79 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - - -action action_0(param0){ - modify_field(ipv4.hdrChecksum, param0); -} - -action action_1(param0, param1){ - modify_field(ipv4.diffserv, param0); - modify_field(ipv4.ttl, param1); -} - -action do_nothing(){ - no_op(); -} - -table table_0 { - reads { - ipv4.dstAddr : exact ; - } - actions { - action_0; - action_1; - } -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_170_stateful_selection_table_update.p4 b/backends/tofino/bf-asm/test/internal/test_config_170_stateful_selection_table_update.p4 deleted file mode 100644 index bd5fbb9b834..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_170_stateful_selection_table_update.p4 +++ /dev/null @@ -1,167 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 4; - flags : 8; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type meta_t { - fields { - egress_ifindex : 16; - instance_id : 16; - down_port : 1; - from_packet_generator : 1; - padding : 6; - } -} - - -header ethernet_t ethernet; -header ipv4_t ipv4; -header tcp_t tcp; -metadata meta_t meta; - - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x0800 : parse_ipv4; - default : ingress; - } -} - -parser parse_ipv4 { - extract(ipv4); - return select(ipv4.protocol){ - 0x06 : parse_tcp; - default : ingress; - } -} - -parser parse_tcp { - extract(tcp); - return ingress; -} - -field_list lag_hash_fields { - ethernet.srcAddr; - ethernet.dstAddr; - ipv4.srcAddr; - ipv4.dstAddr; - ipv4.protocol; - tcp.srcPort; - tcp.dstPort; -} - -field_list_calculation lag_hash { - input { lag_hash_fields; } - algorithm : crc16; - output_width : 14; -} - -action_selector lag_selector { - selection_key : lag_hash; - /* selection_map : lag_mbrs; */ -} -action set_lag_port(port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action_profile lag_action_profile { - actions { - set_lag_port; - } - size : 1024; - dynamic_action_selection : lag_selector; -} - - -register lag_mbrs { - width : 1; - instance_count : 1; -} - -blackbox stateful_alu port_status_alu { - reg: lag_mbrs; - selector_binding: lag_group; - update_lo_1_value: clr_bit; -} - -action set_mbr_down(){ - port_status_alu.execute_stateful_alu(); -} - -action drop_packet(){ - drop(); -} - - -table lag_group { - reads { - meta.egress_ifindex : exact; - } - action_profile: lag_action_profile; -} - -table lag_group_fast_update { - reads { - meta.down_port : exact; - meta.instance_id : exact; - } - actions { - set_mbr_down; - drop_packet; - } -} - -/* Main control flow */ - -control ingress { - if (meta.from_packet_generator == 0){ - apply(lag_group); - } else { - apply(lag_group_fast_update); - } -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_171_stateful_conga.p4 b/backends/tofino/bf-asm/test/internal/test_config_171_stateful_conga.p4 deleted file mode 100644 index dd752649729..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_171_stateful_conga.p4 +++ /dev/null @@ -1,175 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 4; - flags : 8; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type meta_t { - fields { - next_hop : 8; - dst_tor_id : 8; - is_conga_packet : 1 ; - padding : 7; - } -} - -header_type conga_meta_t { - fields { - next_hop : 8; - util : 8; - } -} - -header_type conga_state_layout { - fields { - next_hop : 8; - utilization : 8; - } -} - - -header ethernet_t ethernet; -header ipv4_t ipv4; -header tcp_t tcp; -metadata meta_t meta; -metadata conga_meta_t conga_meta; - - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x0800 : parse_ipv4; - default : ingress; - } -} - -parser parse_ipv4 { - extract(ipv4); - return select(ipv4.protocol){ - 0x06 : parse_tcp; - default : ingress; - } -} - -parser parse_tcp { - extract(tcp); - return ingress; -} - - - -register conga_state { - layout : conga_state_layout; - instance_count : 256; -} - -blackbox stateful_alu conga_alu { - reg: conga_state; - update_lo_1_value: register_hi; - output_value: alu_lo; - output_dst: meta.next_hop; -} - -blackbox stateful_alu conga_update_alu { - reg: conga_state; - - condition_hi: register_lo > conga_meta.util; - condition_lo: register_hi == conga_meta.next_hop; - - update_hi_1_predicate: condition_hi; - update_hi_1_value: conga_meta.next_hop; - - update_lo_1_predicate: condition_hi or condition_lo; - update_lo_1_value: conga_meta.util; - - output_value: alu_hi; - output_dst: meta.next_hop; -} - -action get_preferred_next_hop(){ - conga_alu.execute_stateful_alu(); -} - -action update_preferred_next_hop(){ - conga_update_alu.execute_stateful_alu(); -} - - -table conga_rd_next_hop_table { - reads { - meta.dst_tor_id : exact; - } - actions { - get_preferred_next_hop; - } - size : 256; -} - -table conga_wr_next_hop_table { - reads { - meta.dst_tor_id : exact; - meta.next_hop : exact; /* HACK */ - conga_meta.next_hop : exact; /* HACK */ - conga_meta.util : exact; /* HACK */ - } - actions { - update_preferred_next_hop; - } - size : 256; -} - - - -/* Main control flow */ - -control ingress { - if (meta.is_conga_packet == 1){ - apply(conga_wr_next_hop_table); - } else { - apply(conga_rd_next_hop_table); - } - -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_172_stateful_heavy_hitter.p4 b/backends/tofino/bf-asm/test/internal/test_config_172_stateful_heavy_hitter.p4 deleted file mode 100644 index aba3f4acdcf..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_172_stateful_heavy_hitter.p4 +++ /dev/null @@ -1,262 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 4; - flags : 8; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type meta_t { - fields { - is_not_heavy_hitter : 1; - padding : 7; - - pad_1 : 4; - hash_1 : 12; - pad_2 : 4; - hash_2 : 12; - //pad_3 : 4; - hash_3 : 32; - } -} - - - -header ethernet_t ethernet; -header ipv4_t ipv4; -header tcp_t tcp; -metadata meta_t meta; - - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x0800 : parse_ipv4; - default : ingress; - } -} - -parser parse_ipv4 { - extract(ipv4); - return select(ipv4.protocol){ - 0x06 : parse_tcp; - default : ingress; - } -} - -parser parse_tcp { - extract(tcp); - return ingress; -} - -field_list fields_for_hash { ipv4.srcAddr; } - -field_list_calculation hash_1 { - input { fields_for_hash; } - algorithm : crc16; - output_width : 12; -} - -field_list_calculation hash_2 { - input { fields_for_hash; } - algorithm : crc16_msb; - output_width : 12; -} - -field_list_calculation hash_3 { - input { fields_for_hash; } - algorithm : identity; - output_width : 32; -} - -register sketch_cnt_1 { - width: 32; - direct: heavy_hitter_tbl_1; -} - -register sketch_cnt_2 { - width: 32; - direct: heavy_hitter_tbl_2; -} - -register sketch_cnt_3 { - width: 32; - direct: heavy_hitter_tbl_3; -} - -blackbox stateful_alu sketch_cnt_alu_1 { - reg: sketch_cnt_1; - - condition_hi: register_lo > 10000000; - condition_lo: register_lo < 50000000; - - update_lo_1_value: register_lo + 1; - update_hi_1_value: 1; - - output_predicate: not condition_hi or not condition_lo; - output_value: alu_hi; - output_dst: meta.is_not_heavy_hitter; /* TODO: make reduction or */ -} - -blackbox stateful_alu sketch_cnt_alu_2 { - reg: sketch_cnt_2; - - condition_hi: register_lo > 10000000; - condition_lo: register_lo < 50000000; - - update_lo_1_value: register_lo + 1; - update_hi_1_value: 1; - - output_predicate: not condition_hi or not condition_lo; - output_value: alu_hi; - output_dst: meta.is_not_heavy_hitter; /* TODO: make reduction or */ -} - -blackbox stateful_alu sketch_cnt_alu_3 { - reg: sketch_cnt_3; - - condition_hi: register_lo > 10000000; - condition_lo: register_lo < 50000000; - - update_lo_1_value: register_lo + 1; - update_hi_1_value: 1; - - output_predicate: not condition_hi or not condition_lo; - output_value: alu_hi; - output_dst: meta.is_not_heavy_hitter; /* TODO: make reduction or */ -} - -action run_alu_1(){ - sketch_cnt_alu_1.execute_stateful_alu(); -} - -action run_alu_2(){ - sketch_cnt_alu_2.execute_stateful_alu(); -} - -action run_alu_3(){ - sketch_cnt_alu_3.execute_stateful_alu(); -} - -action set_hash_1_and_2(){ - modify_field_with_hash_based_offset(meta.hash_1, 0, hash_1, 4096); - modify_field_with_hash_based_offset(meta.hash_2, 0, hash_2, 4096); -} - -action set_hash_3(){ - modify_field_with_hash_based_offset(meta.hash_3, 0, hash_3, 4294967296);//4096); -} - -action drop_me(){ - drop(); -} - -action do_nothing(){} - - -table set_hashes_1_and_2_tbl { - actions { - set_hash_1_and_2; - } - size : 256; -} - -table set_hash_3_tbl { - actions { - set_hash_3; - } - size : 256; -} - -table heavy_hitter_tbl_1 { - reads { - meta.hash_1 : exact; - } - actions { - run_alu_1; - } -} - -table heavy_hitter_tbl_2 { - reads { - meta.hash_2 : exact; - } - actions { - run_alu_2; - } -} - -table heavy_hitter_tbl_3 { - reads { - meta.hash_3 : exact; - } - actions { - run_alu_3; - } -} - - -table react { - reads { - meta.is_not_heavy_hitter : exact; - } - actions { - drop_me; - do_nothing; - } -} - - -/* Main control flow */ - -control ingress { - apply(set_hashes_1_and_2_tbl); - apply(set_hash_3_tbl); - - apply(heavy_hitter_tbl_1); - apply(heavy_hitter_tbl_2); - apply(heavy_hitter_tbl_3); - - apply(react); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_173_stateful_bloom_filter.p4 b/backends/tofino/bf-asm/test/internal/test_config_173_stateful_bloom_filter.p4 deleted file mode 100644 index aa617f64b68..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_173_stateful_bloom_filter.p4 +++ /dev/null @@ -1,259 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 4; - flags : 8; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type meta_t { - fields { - pad_1 : 6; - hash_1 : 18; - pad_2 : 6; - hash_2 : 18; - pad_3 : 6; - hash_3 : 18; - - pad_4 : 7; - is_not_member : 1; - } -} - -header ethernet_t ethernet; -header ipv4_t ipv4; -header tcp_t tcp; -metadata meta_t meta; - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x0800 : parse_ipv4; - default : ingress; - } -} - -parser parse_ipv4 { - extract(ipv4); - return select(ipv4.protocol){ - 0x06 : parse_tcp; - default : ingress; - } -} - -parser parse_tcp { - extract(tcp); - return ingress; -} - -field_list fields_for_hash { - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation hash_1 { - input { fields_for_hash; } - algorithm: random; - output_width: 18; -} - -field_list_calculation hash_2 { - input { fields_for_hash; } - algorithm: crc32; - output_width: 18; -} - -field_list_calculation hash_3 { - input { fields_for_hash; } - algorithm: identity; - output_width: 18; -} - - -register bloom_filter_1 { - width : 1; - direct : bloom_filter_membership_1; -} - -register bloom_filter_2 { - width : 1; - direct : bloom_filter_membership_2; -} - -register bloom_filter_3 { - width : 1; - direct : bloom_filter_membership_3; -} - -blackbox stateful_alu bloom_filter_alu_1 { - reg: bloom_filter_1; - - update_lo_1_value: set_bitc; - - output_value: alu_lo; - output_dst: meta.is_not_member; /* Want reduction OR */ -} - -blackbox stateful_alu bloom_filter_alu_2 { - reg: bloom_filter_2; - - update_lo_1_value: set_bitc; - - output_value: alu_lo; - output_dst: meta.is_not_member; /* Want reduction OR */ -} - -blackbox stateful_alu bloom_filter_alu_3 { - reg: bloom_filter_3; - - update_lo_1_value: set_bitc; - - output_value: alu_lo; - output_dst: meta.is_not_member; /* Want reduction OR */ -} - -action run_bloom_filter_1(){ - bloom_filter_alu_1.execute_stateful_alu(); -} -action run_bloom_filter_2(){ - bloom_filter_alu_2.execute_stateful_alu(); -} -action run_bloom_filter_3(){ - bloom_filter_alu_3.execute_stateful_alu(); -} - -action set_hash_1(){ - modify_field_with_hash_based_offset(meta.hash_1, 0, hash_1, 262144); -} -action set_hash_2(){ - modify_field_with_hash_based_offset(meta.hash_2, 0, hash_2, 262144); -} -action set_hash_3(){ - modify_field_with_hash_based_offset(meta.hash_3, 0, hash_3, 262144); -} - - - - -action drop_me(){ - drop(); -} - -action do_nothing(){} - - -table set_hash_1_tbl { - actions { - set_hash_1; - } - size : 256; -} - -table set_hash_2_tbl { - actions { - set_hash_2; - } - size : 1; -} - -table set_hash_3_tbl { - actions { - set_hash_3; - } - size : 1; -} - -table bloom_filter_membership_1 { - reads { - meta.hash_1 : exact; - } - actions { - run_bloom_filter_1; - } - size : 262144; -} - -table bloom_filter_membership_2 { - reads { - meta.hash_2 : exact; - } - actions { - run_bloom_filter_2; - } - size : 262144; -} - -table bloom_filter_membership_3 { - reads { - meta.hash_3 : exact; - } - actions { - run_bloom_filter_3; - } - size : 262144; -} - -table react { - reads { - meta.is_not_member : exact; - } - actions { - drop_me; - do_nothing; - } -} - -/* Main control flow */ - -control ingress { - apply(set_hash_1_tbl); - apply(set_hash_2_tbl); - apply(set_hash_3_tbl); - - apply(bloom_filter_membership_1); - apply(bloom_filter_membership_2); - apply(bloom_filter_membership_3); - - apply(react); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_175_match_table_with_no_key.p4 b/backends/tofino/bf-asm/test/internal/test_config_175_match_table_with_no_key.p4 deleted file mode 100644 index 9c4cc3856f1..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_175_match_table_with_no_key.p4 +++ /dev/null @@ -1,70 +0,0 @@ - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32 (signed); - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_x_32 : 32 (signed); - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -action action_0(){ - bit_nor(pkt.field_a_32, pkt.field_b_32, pkt.field_c_32); -} -action action_1(param0){ - bit_orca(pkt.field_b_32, param0, pkt.field_c_32); -} - -action do_nothing(){} - -table table_0 { - actions { - action_0; - } -} - -table table_1 { - actions { - action_1; - } -} - -table table_2 { - actions { - do_nothing; - } -} - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_1); - if (pkt.field_i_8 == 0){ - apply(table_2); - } -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_176_extend_crc16.p4 b/backends/tofino/bf-asm/test/internal/test_config_176_extend_crc16.p4 deleted file mode 100644 index a21db0274ec..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_176_extend_crc16.p4 +++ /dev/null @@ -1,77 +0,0 @@ - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32 (signed); - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_x_32 : 32 (signed); - } -} - -header_type meta_t { - fields { - hash_1 : 16; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; -metadata meta_t meta; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -field_list fields_for_hash { - pkt.field_c_32; - pkt.field_d_32; -} - -field_list_calculation hash_1 { - input { fields_for_hash; } - algorithm: crc16; - output_width: 16; -} - - -action action_0(){ - //modify_field_with_hash_based_offset(meta.hash_1, 0, hash_1, 65536); //16 - modify_field_with_hash_based_offset(meta.hash_1, 0, hash_1, 16777216); //24 - //modify_field_with_hash_based_offset(meta.hash_1, 0, hash_1, 4294967296); //32 -} - -action do_nothing(){} - -table table_0 { - reads { - pkt.field_g_16 : ternary; - } - actions { - action_0; - do_nothing; - } -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_177_meter_test.p4 b/backends/tofino/bf-asm/test/internal/test_config_177_meter_test.p4 deleted file mode 100644 index 9e792a4efe0..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_177_meter_test.p4 +++ /dev/null @@ -1,90 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - color_0 : 8; - pad_0 : 24; - pad_1 : 160; - pad_2 : 24; - color_1 : 8; - pad_3 : 24; - - lpf : 16; - } -} - -header_type meta_t { - fields { - color_0 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; -metadata meta_t meta; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -meter meter_0 { - type : bytes; - direct : table_0; - result : pkt.color_0; - //static : table_0; - //instance_count : 500; -} - -action action_0(param0){ - //execute_meter(meter_0, 7, pkt.color_0); -} - -action action_1(param0){ - //execute_meter(meter_0, 0, pkt.color_1); -} - -action do_nothing(){ - no_op(); -} - - -table table_0 { - reads { - pkt.field_e_16 : ternary; - pkt.color_0 : exact; /* HACK */ - pkt.color_1 : exact; /* HACK */ - //meta.color_0 : exact; - } - actions { - action_0; - action_1; - do_nothing; - } - size : 6000; -} - - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_178_hash_action.p4 b/backends/tofino/bf-asm/test/internal/test_config_178_hash_action.p4 deleted file mode 100644 index 28121778867..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_178_hash_action.p4 +++ /dev/null @@ -1,69 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - color_0 : 8; - pad_0 : 24; - pad_1 : 160; - pad_2 : 24; - color_1 : 8; - pad_3 : 24; - - lpf : 16; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -meter meter_0 { - type : bytes; - static : table_0; - instance_count : 500; -} - -action action_0(param0){ - modify_field(pkt.field_a_32, param0); -} - - - -table table_0 { - reads { - pkt.field_i_8 : exact; - } - actions { - action_0; - } - size : 256; -} - - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_179_check_if_sequential_action_used.p4 b/backends/tofino/bf-asm/test/internal/test_config_179_check_if_sequential_action_used.p4 deleted file mode 100644 index 57bbaab3046..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_179_check_if_sequential_action_used.p4 +++ /dev/null @@ -1,79 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - color_0 : 8; - pad_0 : 24; - pad_1 : 160; - pad_2 : 24; - color_1 : 8; - pad_3 : 24; - - lpf : 16; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -action action_0(param0){ - modify_field(pkt.field_a_32, param0); - drop(); - add(pkt.field_b_32, pkt.field_a_32, 2); -} - -action action_1(param0){ - drop(); - add(pkt.field_b_32, pkt.field_a_32, 2); - modify_field(pkt.field_a_32, param0); -} - -action action_2(param0){ - drop(); - modify_field(pkt.field_a_32, param0); - add(pkt.field_b_32, pkt.field_c_32, pkt.field_a_32); -} - - - -table table_0 { - reads { - pkt.field_i_8 : exact; - } - actions { - //action_0; - action_1; - //action_2; - } - size : 256; -} - - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_17_action_packing_wide_with_pad.p4 b/backends/tofino/bf-asm/test/internal/test_config_17_action_packing_wide_with_pad.p4 deleted file mode 100644 index c770b5f80de..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_17_action_packing_wide_with_pad.p4 +++ /dev/null @@ -1,82 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - - -action action_0(param0, param1, param2, param3){ - modify_field(ethernet.dstAddr, param0); - modify_field(ethernet.srcAddr, param1); - modify_field(ipv4.dstAddr, param2); - modify_field(ipv4.srcAddr, param3); -} - -action action_1(param0, param1){ - modify_field(ipv4.diffserv, param0); - modify_field(ipv4.ttl, param1); -} - -action do_nothing(){ - no_op(); -} - -table table_0 { - reads { - ipv4.dstAddr : exact ; - } - actions { - action_0; - action_1; - } -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_180_first_proxy_hash.p4 b/backends/tofino/bf-asm/test/internal/test_config_180_first_proxy_hash.p4 deleted file mode 100644 index 536a672021e..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_180_first_proxy_hash.p4 +++ /dev/null @@ -1,74 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - color_0 : 8; - pad_0 : 24; - pad_1 : 160; - pad_2 : 24; - color_1 : 8; - pad_3 : 24; - - lpf : 16; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -action action_0(param0, param1){ - modify_field(pkt.field_c_32, param0); - modify_field(pkt.field_g_16, param1); -} - -action action_1(){ - drop(); -} - - -//@pragma immediate 0 -@pragma proxy_hash_width 24 -@pragma proxy_hash_algorithm crc16_extend -table table_0 { - reads { - pkt.field_a_32 : exact; - pkt.field_b_32 : exact; - pkt.field_e_16 : exact; - pkt.field_f_16 : exact; - } - actions { - action_0; - action_1; - } - size : 16384; -} - - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_181_first_alg_tcam.p4 b/backends/tofino/bf-asm/test/internal/test_config_181_first_alg_tcam.p4 deleted file mode 100644 index 51069ad36a9..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_181_first_alg_tcam.p4 +++ /dev/null @@ -1,161 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 4; - flags : 8; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - - -header_type meta_t { - fields { - partition_index : 11; - pad_0 : 9; - vrf : 12; - } -} - - -header ethernet_t ethernet; -header ipv4_t ipv4; -header tcp_t tcp; -metadata meta_t meta; - - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x0800 : parse_ipv4; - default : ingress; - } -} - -parser parse_ipv4 { - extract(ipv4); - return select(ipv4.protocol){ - 0x06 : parse_tcp; - default : ingress; - } -} - -parser parse_tcp { - extract(tcp); - return ingress; -} - - -action set_partition_index(idx){ - modify_field(meta.partition_index, idx); -} - -action ipv4_lpm_hit(){ - subtract(ipv4.ttl, ipv4.ttl, 1); -} - -action lpm_miss(){ - drop(); -} - -action do_nothing(){ } -action do_nothing_2(){} - -table ipv4_lpm_partition { - reads { - meta.vrf: exact; - ipv4.dstAddr: lpm; - } - actions { - set_partition_index; - } - size : 1024; -} - -/* @pragma atcam_number_partitions 1024 */ -@pragma atcam_partition_index meta.partition_index -table ipv4_alg_tcam { - reads { - meta.partition_index: exact; - meta.vrf: exact; - ipv4.dstAddr: lpm; - } - actions { - ipv4_lpm_hit; - lpm_miss; - } - /* size : 8192; */ - size: 65536; - /* size : 262144; */ -} - -table table_n { - reads { - ipv4.dstAddr : exact; - } - actions { - do_nothing; - do_nothing_2; - } -} - -table table_x { - reads { - ipv4.dstAddr : ternary; - } - actions { - do_nothing; - } -} - -/* Main control flow */ - -control ingress { - apply(ipv4_lpm_partition); - apply(ipv4_alg_tcam) { - lpm_miss { - apply(table_n) { - do_nothing_2 { - apply(table_x); - } - } - } - } -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_182_warp_primitive.p4 b/backends/tofino/bf-asm/test/internal/test_config_182_warp_primitive.p4 deleted file mode 100644 index a9fb3740e91..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_182_warp_primitive.p4 +++ /dev/null @@ -1,81 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type meta_t { - fields { - a : 16; - b : 16; - c : 16; - d : 16; - } -} - - -header ethernet_t ethernet; -metadata meta_t meta; - - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return ingress; -} - -action action_0(){ - bypass_egress(); - //mark_for_drop(); -} - -action action_1(){ - drop(); -} - -action action_2(){ - //exit(); -} - -table table_0 { - reads { - ethernet.dstAddr: exact; - } - actions { - action_0; - action_1; - } - size : 1024; -} - -table table_1 { - reads { - ethernet.dstAddr: exact; - } - actions { - action_2; - } -} - -table table_2 { - reads { - ethernet.dstAddr: exact; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); - apply(table_1); - apply(table_2); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_183_sample_e2e.p4 b/backends/tofino/bf-asm/test/internal/test_config_183_sample_e2e.p4 deleted file mode 100644 index d28e7ac56f5..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_183_sample_e2e.p4 +++ /dev/null @@ -1,58 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type meta_t { - fields { - a : 16; - b : 16; - c : 16; - d : 16; - } -} - - -header ethernet_t ethernet; -metadata meta_t meta; - - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return ingress; -} - -action action_0(){ - sample_e2e(1, 7); -} - -action action_1(){ -} - - -table table_0 { - reads { - ethernet.dstAddr: exact; - } - actions { - action_0; - action_1; - } - size : 1024; -} - -control ingress { } - -control egress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_184_stateful_bug1.p4 b/backends/tofino/bf-asm/test/internal/test_config_184_stateful_bug1.p4 deleted file mode 100644 index 3a020990a5f..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_184_stateful_bug1.p4 +++ /dev/null @@ -1,103 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - blah : 16; - } -} - -header_type meta_t { - fields { - a : 16; - b : 16; - c : 16; - d : 16; - } -} - - -header ethernet_t ethernet; -metadata meta_t meta; - - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return ingress; -} - -action action_0(){ - sampling_alu.execute_stateful_alu(); -} - -action action_1(){ -} - - -register sampling_cntr { - width : 32; - static: table_0; - instance_count : 139264; /* Fills 34 + 1 spare RAMs (max size - 1) */ -} - -/* Note the extra complexity of this ALU program is required so that if C2C was - * already set (by the bloom filter) it will stay set even if this ALU says not - * to sample. */ -blackbox stateful_alu sampling_alu { - reg: sampling_cntr; - initial_register_lo_value: 1; - condition_lo: register_lo >= 10; - condition_hi: ig_intr_md_for_tm.copy_to_cpu != 0; - update_lo_1_predicate: condition_lo; - update_lo_1_value: 1; - update_lo_2_predicate: not condition_lo; - update_lo_2_value: register_lo + 1; - update_hi_1_value: 1; - output_predicate: condition_lo or condition_hi; - output_value : alu_hi; - output_dst : ig_intr_md_for_tm.copy_to_cpu; -} - -field_list bf_hash_fields { - ethernet.dstAddr; - ethernet.etherType; -} - -field_list_calculation bf_hash_1 { - input { bf_hash_fields; } - algorithm: random; - output_width: 16; -} - -action action_7(){ - modify_field_with_hash_based_offset(ethernet.blah, 0, bf_hash_1, 262144); -} - - -table table_0 { - reads { - ethernet.dstAddr: exact; - } - actions { - action_0; - action_1; - } - size : 1024; -} - -table table_1 { - actions { action_7; } -} - -control ingress { - apply(table_0); - apply(table_1); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_185_first_lpf.p4 b/backends/tofino/bf-asm/test/internal/test_config_185_first_lpf.p4 deleted file mode 100644 index 2d259ae4c9d..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_185_first_lpf.p4 +++ /dev/null @@ -1,105 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/lpf_blackbox.p4" -#include "tofino/wred_blackbox.p4" -#include "tofino/meter_blackbox.p4" - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - blah0 : 16; - blah1 : 8; - blah2 : 8; - } -} - -header_type meta_t { - fields { - a : 16; - b : 16; - c : 16; - d : 16; - } -} - - -header ethernet_t ethernet; -metadata meta_t meta; - - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return ingress; -} - -action action_0(){ - my_lpf.execute(ethernet.blah0); -} - -action do_nothing(){} - -action action_1(){ - my_wred.execute(ethernet.blah1); -} - -action action_2(){ - my_meter.execute(ethernet.blah2); -} - -blackbox lpf my_lpf { - filter_input : ethernet.etherType; - direct : table_0; -} - -blackbox wred my_wred { - wred_input : ethernet.etherType; - direct : table_1; -} - -blackbox meter my_meter { - type : bytes; - direct : table_2; -} - -table table_0 { - reads { - ethernet.dstAddr: exact; - } - actions { - action_0; - //do_nothing; - } - size : 1024; -} - -table table_1 { - reads { - ethernet.dstAddr: exact; - } - actions { - action_1; - } - size : 1024; -} - -table table_2 { - reads { - ethernet.dstAddr: exact; - } - actions { - action_2; - } - size : 1024; -} - -control ingress { - apply(table_0); - apply(table_1); - apply(table_2); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_186_hlir_modify.p4 b/backends/tofino/bf-asm/test/internal/test_config_186_hlir_modify.p4 deleted file mode 100644 index 8c6803b1383..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_186_hlir_modify.p4 +++ /dev/null @@ -1,89 +0,0 @@ - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - blah0 : 16; - blah1 : 8; - blah2 : 8; - } -} - -header_type meta_t { - fields { - a : 16; - b : 16; - c : 16; - d : 16; - - e : 32; - f : 32; - g : 32; - h : 32; - - i : 8; - j : 8; - k : 8; - l : 8; - } -} - - -header ethernet_t ethernet; -metadata meta_t meta; - - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return ingress; -} - -action action_0(blah1, blah2, blah3){ - modify_field(meta.a, blah1); - modify_field(meta.b, blah2); - modify_field(meta.c, blah3); -} - -action action_1(){ - modify_field(meta.e, 7); - modify_field(meta.f, 8); - modify_field(meta.g, 2097151); /* 2**21 - 1 */ - modify_field(meta.h, -1); -} - -action do_nothing(){} - - -table table_0 { - reads { - ethernet.dstAddr: exact; - } - actions { - action_0; - do_nothing; - } - size : 1024; -} - -@pragma immediate 0 -table table_1 { - reads { - ethernet.dstAddr: exact; - } - actions { - action_1; - do_nothing; - } - size : 1024; -} - -control ingress { - apply(table_0); - apply(table_1); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_187_proxy_hash_2.p4 b/backends/tofino/bf-asm/test/internal/test_config_187_proxy_hash_2.p4 deleted file mode 100644 index 821e2e9ceb6..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_187_proxy_hash_2.p4 +++ /dev/null @@ -1,61 +0,0 @@ - -/* Sample P4 program */ -header_type pkt_t { - fields { - srcAddr : 32; - dstAddr : 32; - protocol : 8; - srcPort : 16; - dstPort : 16; - - blah : 16; - - a : 32; - b : 32; - c : 32; - d : 32; - - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -action set_dip(){ - modify_field(pkt.blah, 8); -} - -action nop(){ -} - -@pragma proxy_hash_width 24 -table exm_proxy_hash { - reads { - pkt.srcAddr : exact; - pkt.dstAddr : exact; - pkt.protocol : exact; - pkt.srcPort : exact; - pkt.dstPort : exact; - } - actions { - nop; - set_dip; - } - size : 400000; -} - - -/* Main control flow */ - -control ingress { - apply(exm_proxy_hash); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_188_action_data_overflow.p4 b/backends/tofino/bf-asm/test/internal/test_config_188_action_data_overflow.p4 deleted file mode 100644 index 125a4e9a0f0..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_188_action_data_overflow.p4 +++ /dev/null @@ -1,59 +0,0 @@ - -/* Sample P4 program */ -header_type pkt_t { - fields { - srcAddr : 32; - dstAddr : 32; - protocol : 8; - srcPort : 16; - dstPort : 16; - - a : 32; - b : 32; - c : 32; - d : 32; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -action action_0(param0, param1, param2, param3, param4){ - modify_field(pkt.a, param0); - modify_field(pkt.b, param1); - modify_field(pkt.c, param2); - //modify_field(pkt.d, param3); - //modify_field(pkt.dstPort, param4); -} - -action nop(){ -} - -@pragma immediate 0 -table table_0 { - reads { - pkt.srcPort : exact; - pkt.dstPort : ternary; - } - actions { - nop; - action_0; - } - size : 4098; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_189_stat_with_lrt.p4 b/backends/tofino/bf-asm/test/internal/test_config_189_stat_with_lrt.p4 deleted file mode 100644 index 5d64e167fb1..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_189_stat_with_lrt.p4 +++ /dev/null @@ -1,62 +0,0 @@ - -/* Sample P4 program */ -header_type pkt_t { - fields { - srcAddr : 32; - dstAddr : 32; - protocol : 8; - srcPort : 16; - dstPort : 16; - - a : 32; - b : 32; - c : 32; - d : 32; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -action action_0(param0, param1, param2, param3, param4){ - modify_field(pkt.a, param0); -} - -action nop(){ -} - -@pragma lrt_enable 1 -counter counter_0 { - type: packets; - direct: table_0; - min_width: 32; -} - -@pragma immediate 0 -table table_0 { - reads { - pkt.srcPort : exact; - pkt.dstPort : ternary; - } - actions { - nop; - action_0; - } - size : 4096; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_18_first_bit_xor.p4 b/backends/tofino/bf-asm/test/internal/test_config_18_first_bit_xor.p4 deleted file mode 100644 index 77b95538782..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_18_first_bit_xor.p4 +++ /dev/null @@ -1,100 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type blah_t { - fields { - a : 32; - b : 32; - c : 32; - d : 32; - e : 16; - f : 16; - g : 16; - h : 16; - i : 8; - j : 8; - k : 8; - l : 8; - } -} - - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return parse_blah; -} - -header blah_t blah; - -parser parse_blah { - extract(blah); - return ingress; -} - - - -action action_0(param0){ - bit_xor(blah.a, blah.b, param0); -} - -action do_nothing(){ - no_op(); -} - -table table_0 { - reads { - ipv4.dstAddr : exact ; - } - actions { - action_0; - do_nothing; - } -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_190_modify_with_expr.p4 b/backends/tofino/bf-asm/test/internal/test_config_190_modify_with_expr.p4 deleted file mode 100644 index 3ceed9971b3..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_190_modify_with_expr.p4 +++ /dev/null @@ -1,69 +0,0 @@ - -/* Sample P4 program */ -header_type pkt_t { - fields { - srcAddr : 32; - dstAddr : 32; - protocol : 8; - srcPort : 16; - dstPort : 16; - - a : 32; - b : 32; - c : 32; - d : 32; - - e : 16; - f : 16; - g : 16; - h : 16; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -action action_0(param0, param1, param2){ - modify_field(pkt.a, pkt.b + 2); - modify_field(pkt.b, 3 - pkt.b); - modify_field(pkt.c, pkt.c >> 3); - modify_field(pkt.d, pkt.d << 7); - - modify_field(pkt.e, param0 | pkt.e); - modify_field(pkt.f, pkt.f & param1); - modify_field(pkt.g, pkt.g ^ 0xfff); - modify_field(pkt.h, ~param2); - - -} - -action nop(){ -} - -table table_0 { - reads { - pkt.srcPort : exact; - pkt.dstPort : ternary; - } - actions { - nop; - action_0; - } - size : 4096; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_191_invalidate.p4 b/backends/tofino/bf-asm/test/internal/test_config_191_invalidate.p4 deleted file mode 100644 index 73d88f57580..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_191_invalidate.p4 +++ /dev/null @@ -1,64 +0,0 @@ - -/* Sample P4 program */ -header_type pkt_t { - fields { - srcAddr : 32; - dstAddr : 32; - protocol : 8; - srcPort : 16; - dstPort : 16; - - a : 32; - b : 32; - c : 32; - d : 32; - - e : 16; - f : 16; - g : 16; - h : 16; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -action action_0(){ - invalidate(144); -} - -action action_1(){ - invalidate(pkt.a); -} - -action nop(){ -} - -table table_0 { - reads { - pkt.srcPort : exact; - pkt.dstPort : ternary; - } - actions { - nop; - action_0; - action_1; - } - size : 4096; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_192_stateful_driven_by_hash.p4 b/backends/tofino/bf-asm/test/internal/test_config_192_stateful_driven_by_hash.p4 deleted file mode 100644 index 3343228020b..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_192_stateful_driven_by_hash.p4 +++ /dev/null @@ -1,300 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - - -/* ----------------------------------------- */ -field_list f_em_direct { - pkt.field_a_32; - pkt.field_b_32; -} - -field_list_calculation h_em_direct { - input { - f_em_direct; - } - algorithm : random; - output_width : 12; -} - -register r_em_direct { - width : 16; - static : t_em_direct; - instance_count : 2048; -} - -blackbox stateful_alu b_em_direct { - reg: r_em_direct; - update_lo_1_value: register_lo + 1; - output_value : alu_lo; - output_dst : pkt.field_e_16; -} - -action a_em_direct(){ - b_em_direct.execute_stateful_alu_from_hash(h_em_direct); -} - -table t_em_direct { - reads { - pkt.field_a_32 : exact; - } - - actions { - a_em_direct; - } - size : 4096; -} - -/* ----------------------------------------- */ -field_list f_em_indirect { - pkt.field_a_32; - pkt.field_b_32; -} - -field_list_calculation h_em_indirect { - input { - f_em_indirect; - } - algorithm : random; - output_width : 13; -} - -register r_em_indirect { - width : 16; - instance_count: 8192; -} - -blackbox stateful_alu b_em_indirect { - reg: r_em_indirect; - update_lo_1_value: register_lo + 5; - output_value : alu_lo; - output_dst : pkt.field_f_16; -} - -action a_em_indirect(){ - b_em_indirect.execute_stateful_alu_from_hash(h_em_indirect); -} - -table t_em_indirect { - reads { - pkt.field_a_32 : exact; - } - - actions { - a_em_indirect; - do_nothing; - } - size : 2048; -} - - -/* ----------------------------------------- */ -field_list f_t_direct { - pkt.field_a_32; - pkt.field_b_32; -} - -field_list_calculation h_t_direct { - input { - f_t_direct; - } - algorithm : random; - output_width : 12; -} - -register r_t_direct { - width : 16; - static : t_t_direct; - instance_count : 3072; -} - -blackbox stateful_alu b_t_direct { - reg: r_t_direct; - update_lo_1_value: register_lo + 1; - output_value : alu_lo; - output_dst : pkt.field_g_16; -} - -action a_t_direct(){ - b_t_direct.execute_stateful_alu_from_hash(h_t_direct); -} - -table t_t_direct { - reads { - pkt.field_a_32 : ternary; - } - - actions { - a_t_direct; - } - size : 4096; -} - - -/* ----------------------------------------- */ -field_list f_t_indirect { - pkt.field_a_32; - pkt.field_b_32; -} - -field_list_calculation h_t_indirect { - input { - f_t_indirect; - } - algorithm : random; - output_width : 13; -} - -register r_t_indirect { - width : 16; - instance_count: 8192; -} - -blackbox stateful_alu b_t_indirect { - reg: r_t_indirect; - update_lo_1_value: register_lo + 5; - output_value : alu_lo; - output_dst : pkt.field_h_16; -} - -action a_t_indirect(){ - b_t_indirect.execute_stateful_alu_from_hash(h_t_indirect); -} - -table t_t_indirect { - reads { - pkt.field_a_32 : ternary; - } - - actions { - a_t_indirect; - do_nothing; - } - size : 2048; -} - - -/* ----------------------------------------- */ -field_list f_no_key { - pkt.field_a_32; - pkt.field_b_32; -} - -field_list_calculation h_no_key { - input { - f_no_key; - } - algorithm : random; - output_width : 16; -} - -register r_no_key { - width : 16; - static: t_no_key; - instance_count : 1024; -} - -blackbox stateful_alu b_no_key { - reg: r_no_key; - update_lo_1_value: register_lo + 5; - output_value : alu_lo; - output_dst : pkt.field_i_8; -} - -action a_no_key(){ - b_no_key.execute_stateful_alu_from_hash(h_no_key); -} - -table t_no_key { - actions { - a_no_key; - } - size : 1024; -} - - -/* ----------------------------------------- */ -field_list f_hash_act { - pkt.field_a_32; - pkt.field_b_32; -} - -field_list_calculation h_hash_act { - input { - f_hash_act; - } - algorithm : random; - output_width : 10; -} - -register r_hash_act { - width : 8; - static: t_hash_act; - instance_count : 256; -} - -blackbox stateful_alu b_hash_act { - reg: r_hash_act; - update_lo_1_value: register_lo + 5; - output_value : alu_lo; - output_dst : pkt.field_j_8; -} - -action a_hash_act(){ - b_hash_act.execute_stateful_alu_from_hash(h_hash_act); -} - -table t_hash_act { - reads { - pkt.field_d_32 mask 0x3ff : exact; - } - actions { - a_hash_act; - } - size : 1024; -} - -action do_nothing(){} - -/* Main control flow */ - -control ingress { - apply(t_em_direct); - apply(t_em_indirect); - apply(t_t_direct); - apply(t_t_indirect); - apply(t_no_key); - apply(t_hash_act); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_193_indirect_stats_no_reads.p4 b/backends/tofino/bf-asm/test/internal/test_config_193_indirect_stats_no_reads.p4 deleted file mode 100644 index 7256ce7ae0d..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_193_indirect_stats_no_reads.p4 +++ /dev/null @@ -1,64 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -counter cntr_0 { - type: packets; - instance_count: 500; - //min_width: 32; -} - -action do_nothing(){} - -action action_0() { - count(cntr_0, pkt.field_i_8); -} - - -table table_0 { - actions { - action_0; - } - //size : 256; -} - - - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_194_same_action_param.p4 b/backends/tofino/bf-asm/test/internal/test_config_194_same_action_param.p4 deleted file mode 100644 index 38661288548..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_194_same_action_param.p4 +++ /dev/null @@ -1,103 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; -/* - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_m_16 : 16; -*/ - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -action do_nothing(){} - -/* -action action_0(param_0) { - bit_xor(pkt.field_f_16, pkt.field_g_16, param_0); - modify_field(pkt.field_e_16, param_0); -} - -@pragma immediate 0 -table table_0 { - reads { - pkt.field_l_8 : ternary; - - pkt.field_a_32 : ternary; - pkt.field_b_32 : exact; - pkt.field_c_32 : exact; - pkt.field_e_16 : exact; - - } - actions { - action_0; - } - size : 256; -} -*/ -action action_1(param_1){ - bit_xor(pkt.field_a_32, pkt.field_a_32, param_1); - modify_field(pkt.field_b_32, param_1); -} - - -@pragma immediate 0 -table table_1 { - reads { - pkt.field_a_32 mask 0xff: ternary; - } - actions { - action_1; - } - size : 256; -} - -action drop_me(){ - drop(); -} - -table table_e { - reads { - pkt.field_a_32: ternary; - } - actions { - do_nothing; - drop_me; - } - size : 512; -} - -control ingress { - //apply(table_0); - apply(table_1); -} - -control egress { - apply(table_e); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_195_stateful_predicate_output.p4 b/backends/tofino/bf-asm/test/internal/test_config_195_stateful_predicate_output.p4 deleted file mode 100644 index 9b127554a3c..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_195_stateful_predicate_output.p4 +++ /dev/null @@ -1,96 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - } -} - -header_type meta_t { - fields { - pred_4 : 4; - pad_4 : 4; - pad_6 : 6; - comb_pred_1 : 1; - pad_1 : 1; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; -metadata meta_t meta; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -register r_pred { - width : 8; - static : t_pred; - instance_count : 1024; -} - -blackbox stateful_alu b_pred { - reg: r_pred; - condition_lo : 1; - update_lo_1_value: register_lo + 1; - - //output_predicate : condition_lo; - output_value : predicate; - output_dst : meta.pred_4; -} - -blackbox stateful_alu b_comb_pred { - reg: r_pred; - condition_lo : register_lo > 0; - update_lo_1_value: register_lo + 2; - - output_predicate : condition_lo; - output_value : combined_predicate; - output_dst : meta.comb_pred_1; -} - -action a_pred(idx){ - b_pred.execute_stateful_alu(idx); -} - -action a_comb_pred(idx){ - b_comb_pred.execute_stateful_alu(idx); -} - -table t_pred { - reads { - pkt.field_a_32 : lpm; - } - - actions { - a_pred; - a_comb_pred; - } - size : 512; -} - -control ingress { - apply(t_pred); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_196_hit_miss.p4 b/backends/tofino/bf-asm/test/internal/test_config_196_hit_miss.p4 deleted file mode 100644 index 813b851b571..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_196_hit_miss.p4 +++ /dev/null @@ -1,119 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_m_16 : 16; - - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -action do_nothing(){} - -action action_0(param_0) { - bit_xor(pkt.field_f_16, pkt.field_g_16, param_0); - modify_field(pkt.field_e_16, param_0); -} - -@pragma immediate 0 -table table_0 { - reads { - pkt.field_l_8 : ternary; - - pkt.field_a_32 : ternary; - pkt.field_b_32 : exact; - pkt.field_c_32 : exact; - pkt.field_e_16 : exact; - - } - actions { - action_0; - drop_me; - do_nothing; - } - size : 256; -} - -action action_1(param_1){ - bit_xor(pkt.field_a_32, pkt.field_a_32, param_1); - modify_field(pkt.field_b_32, param_1); -} - - -@pragma immediate 0 -table table_1 { - reads { - pkt.field_a_32 mask 0xff: ternary; - } - actions { - action_1; - } - size : 256; -} - -table table_2 { - reads { - pkt.field_b_32 : exact; - } - actions { - action_1; - drop_me; - } -} - -action drop_me(){ - drop(); -} - -table table_e { - reads { - pkt.field_a_32: ternary; - } - actions { - do_nothing; - drop_me; - } - size : 512; -} - -control ingress { - - apply(table_0) { - hit { - apply(table_1); - apply(table_2); - } - } - apply(table_e); -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_197_default_next_table.p4 b/backends/tofino/bf-asm/test/internal/test_config_197_default_next_table.p4 deleted file mode 100644 index 1e8a25e0a09..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_197_default_next_table.p4 +++ /dev/null @@ -1,109 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_m_16 : 16; - - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -action do_nothing(){} - -action action_0(param_0) { - modify_field(pkt.field_e_16, param_0); -} - -table table_0 { - reads { - pkt.field_l_8 : ternary; - - pkt.field_a_32 : ternary; - pkt.field_b_32 : exact; - pkt.field_c_32 : exact; - pkt.field_e_16 : exact; - - } - actions { - action_0; - action_1; - drop_me; - do_nothing; - } - size : 256; -} - -action action_1(param_1){ - modify_field(pkt.field_b_32, param_1); -} - - -table table_1 { - reads { - pkt.field_a_32 mask 0xff: ternary; - } - actions { - do_nothing; - } - size : 256; -} - -table table_2 { - actions { - do_nothing; - } -} - -action drop_me(){ - drop(); -} - -table table_3 { - reads { - pkt.field_a_32: ternary; - } - actions { - do_nothing; - } - size : 512; -} - -control ingress { - apply(table_0) { - action_0 { - apply(table_1); - } - action_1 { - apply(table_2); - } - } - apply(table_3); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_198_shared_action_profile.p4 b/backends/tofino/bf-asm/test/internal/test_config_198_shared_action_profile.p4 deleted file mode 100644 index 096f17954b9..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_198_shared_action_profile.p4 +++ /dev/null @@ -1,92 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -action do_nothing(){ - no_op(); -} - -action action_0(param0) { - modify_field(pkt.field_a_32, param0); -} - -action action_1(param1) { - modify_field(pkt.field_b_32, param1); -} - -table table_0 { - reads { - pkt.field_a_32 : ternary; - } - action_profile: shared_action_profile; - size : 2048; -} - -table table_1 { - reads { - pkt.field_b_32 : ternary; - } - action_profile: shared_action_profile; - size : 2048; -} - -action_profile shared_action_profile { - actions { - do_nothing; - action_0; - action_1; - } - size : 1024; -} - -//@pragma stage 0 -table table_2 { - reads { - pkt.field_a_32 : exact; - } - actions { - do_nothing; - } -} - -/* Main control flow */ - -control ingress { - - if (pkt.field_i_8 == 0){ - apply(table_0); - } else { - apply(table_1); - } - - apply(table_2); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_199_stateful_constant_index.p4 b/backends/tofino/bf-asm/test/internal/test_config_199_stateful_constant_index.p4 deleted file mode 100644 index b6e4d42a5e2..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_199_stateful_constant_index.p4 +++ /dev/null @@ -1,67 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - blah : 16; - - x : 32; - y : 32; - z : 32; - } -} - -header ethernet_t ethernet; - - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return ingress; -} - -action action_0(){ - sampling_alu.execute_stateful_alu(8191); -} - -action action_1(){ -} - -register sampling_cntr { - width : 32; - static: table_0; - instance_count : 8192; -} - -blackbox stateful_alu sampling_alu { - reg: sampling_cntr; - condition_lo: 1; - update_lo_1_predicate: condition_lo; - update_lo_1_value: register_lo + 1; - output_predicate: condition_lo; - output_value : alu_lo; - output_dst : ethernet.x; -} - -@pragma ways 1 -table table_0 { - reads { - ethernet.blah: exact; - } - actions { - action_0; - //action_1; - } - size : 1024; -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_19_immediate_but_no_action_data_table.p4 b/backends/tofino/bf-asm/test/internal/test_config_19_immediate_but_no_action_data_table.p4 deleted file mode 100644 index 0b8cb5553d4..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_19_immediate_but_no_action_data_table.p4 +++ /dev/null @@ -1,76 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - - - -action action_0(param0){ - modify_field(ipv4.hdrChecksum, param0); -} - -action do_nothing(){ - no_op(); -} - -@pragma immediate 1 -table table_0 { - reads { - ipv4.dstAddr : exact ; - } - actions { - action_0; - do_nothing; - } -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_1_ternary_match_crossbar.p4 b/backends/tofino/bf-asm/test/internal/test_config_1_ternary_match_crossbar.p4 deleted file mode 100644 index 1421b5f661c..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_1_ternary_match_crossbar.p4 +++ /dev/null @@ -1,51 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type my_test_config_1_t { - fields { - a_32 : 32; - b_8 : 8; - c_8 : 8; - d_16 : 16; - e_32 : 32; - } -} - - -header my_test_config_1_t my_test_config_1; - -parser start{ - return parse_my_test_config_1; -} - -parser parse_my_test_config_1{ - extract(my_test_config_1); - return ingress; -} - -action modify_b(my_param){ - modify_field(my_test_config_1.b_8, my_param); -} - -action just_no_op(){ - no_op(); -} - - -table my_test_config_1_table { - reads { - my_test_config_1.a_32 : lpm; - my_test_config_1.e_32 : ternary; - //my_test_config_1.d_16 : ternary; - my_test_config_1.b_8 mask 0xf0: ternary; - my_test_config_1.c_8 : ternary; - } - actions { - modify_b; - just_no_op; - } - max_size : 2048; -} - -control ingress { - apply(my_test_config_1_table); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_200_counter_constant_index.p4 b/backends/tofino/bf-asm/test/internal/test_config_200_counter_constant_index.p4 deleted file mode 100644 index d8bf6b3f4ad..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_200_counter_constant_index.p4 +++ /dev/null @@ -1,63 +0,0 @@ - -/* Sample P4 program */ -header_type pkt_t { - fields { - srcAddr : 32; - dstAddr : 32; - protocol : 8; - srcPort : 16; - dstPort : 16; - - a : 32; - b : 32; - c : 32; - d : 32; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -action action_0(param0, param1, param2, param3, param4){ - count(counter_0, 2047); - modify_field(pkt.a, param0); -} - -action nop(){ -} - - -counter counter_0 { - type: packets_and_bytes; - static: table_0; - instance_count: 2048; - min_width: 32; -} - -table table_0 { - reads { - pkt.srcPort : exact; - pkt.dstPort : ternary; - } - actions { - //nop; - action_0; - } - size : 4096; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_201_meter_constant_index.p4 b/backends/tofino/bf-asm/test/internal/test_config_201_meter_constant_index.p4 deleted file mode 100644 index afcc162adba..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_201_meter_constant_index.p4 +++ /dev/null @@ -1,109 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/lpf_blackbox.p4" -#include "tofino/wred_blackbox.p4" -#include "tofino/meter_blackbox.p4" - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - blah0 : 16; - blah1 : 8; - blah2 : 8; - } -} - -header_type meta_t { - fields { - a : 16; - b : 16; - c : 16; - d : 16; - } -} - - -header ethernet_t ethernet; -metadata meta_t meta; - - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return ingress; -} - -action action_0(){ - my_lpf.execute(ethernet.blah0, 1023); -} - -action do_nothing(){} - -action action_1(){ - my_wred.execute(ethernet.blah1, 1022); -} - -action action_2(){ - my_meter.execute(ethernet.blah2, 3071); -} - -blackbox lpf my_lpf { - filter_input : ethernet.etherType; - static : table_0; - instance_count: 1024; -} - -blackbox wred my_wred { - wred_input : ethernet.etherType; - instance_count: 1024; - drop_value : 127; - no_drop_value : 63; -} - -blackbox meter my_meter { - type : bytes; - instance_count: 3072; -} - -table table_0 { - //reads { - // ethernet.dstAddr: exact; - //} - actions { - action_0; - } - size : 1024; -} - -table table_1 { - reads { - ethernet.dstAddr: exact; - } - actions { - action_1; - } - size : 1024; -} - -table table_2 { - reads { - ethernet.dstAddr: exact; - } - actions { - action_2; - } - size : 1024; -} - -control ingress { - if (ethernet.blah1 == 2){ - apply(table_0); - } - apply(table_1); - apply(table_2); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_202_write_same_byte.p4 b/backends/tofino/bf-asm/test/internal/test_config_202_write_same_byte.p4 deleted file mode 100644 index 4f6702ba896..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_202_write_same_byte.p4 +++ /dev/null @@ -1,67 +0,0 @@ -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - field_m_4 : 4; - field_n_4 : 4; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -action action_0(param0) { - modify_field(pkt.field_m_4, param0); -} - -action action_1(param1) { - modify_field(pkt.field_n_4, param1); -} - -table table_0 { - reads { - pkt.field_a_32 : ternary; - } - actions { - action_0; - } - size : 1024; -} - -table table_1 { - reads { - pkt.field_b_32 : ternary; - } - actions { - action_1; - } - size : 1024; -} - - -control ingress { - apply(table_0); - apply(table_1); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_203_first_reduction_or.p4 b/backends/tofino/bf-asm/test/internal/test_config_203_first_reduction_or.p4 deleted file mode 100644 index 7f256fe2e47..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_203_first_reduction_or.p4 +++ /dev/null @@ -1,144 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - } -} - -header_type meta_t { - fields { - result_8 : 8; - result_8_2 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; -metadata meta_t meta; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -register reg_0 { - width : 8; - static : table_0; - instance_count : 1024; -} - -register reg_1 { - width : 8; - static : table_1; - instance_count : 1024; -} - - -register reg_2 { - width : 8; - static : table_2; - instance_count : 1024; -} - -blackbox stateful_alu alu_0 { - reg: reg_0; - condition_lo : 1; - update_lo_1_value: 15; - - output_value : alu_lo; - output_dst : meta.result_8; - reduction_or_group: or_group_1; -} - -blackbox stateful_alu alu_1 { - reg: reg_1; - condition_lo : 1; - update_lo_1_value: 0x30; - - output_value : alu_lo; - output_dst : meta.result_8; - reduction_or_group: or_group_1; -} - -blackbox stateful_alu alu_2 { - reg: reg_2; - condition_lo : 1; - update_lo_1_value: 0xc0; - - output_value : alu_lo; - output_dst : meta.result_8; - reduction_or_group: or_group_1; -} - -action action_0(idx){ - /* modify_field(pkt.field_c_32, 0); */ - alu_0.execute_stateful_alu(idx); -} - -action action_1(idx){ - alu_1.execute_stateful_alu(idx); -} - -action action_2(idx){ - alu_2.execute_stateful_alu(idx); -} - -table table_0 { - reads { - pkt.field_a_32 : lpm; - } - - actions { - action_0; - } - size : 512; -} - -table table_1 { - reads { - pkt.field_b_32 : lpm; - } - - actions { - action_1; - } - size : 512; -} - -table table_2 { - reads { - pkt.field_c_32 : lpm; - } - - actions { - action_2; - } - size : 512; -} - -control ingress { - apply(table_0); - apply(table_1); - apply(table_2); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_204_no_tables_in_stage0.p4 b/backends/tofino/bf-asm/test/internal/test_config_204_no_tables_in_stage0.p4 deleted file mode 100644 index 1643b18b238..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_204_no_tables_in_stage0.p4 +++ /dev/null @@ -1,75 +0,0 @@ - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -action action_0(){ - modify_field(pkt.field_l_8, 2); -} - -action action_1(){ - modify_field(pkt.field_k_8, 5); -} - -@pragma stage 2 -table table_0 { - reads { - pkt.field_a_32 : lpm; - } - - actions { - action_0; - } - size : 512; -} - -@pragma stage 1 -table table_1 { - reads { - pkt.field_b_32 : lpm; - } - - actions { - action_1; - } - size : 512; -} - -control ingress { - apply(table_0); -} - -control egress { - if (pkt.field_i_8 == 3) { - apply(table_1); - } -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_205_modify_field_from_hash.p4 b/backends/tofino/bf-asm/test/internal/test_config_205_modify_field_from_hash.p4 deleted file mode 100644 index 1ed4b3ee5f0..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_205_modify_field_from_hash.p4 +++ /dev/null @@ -1,90 +0,0 @@ - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - -field_list simple_fields { - pkt.field_e_16; - pkt.field_f_16; -} - - -field_list_calculation simple_hash { - input { simple_fields; } - algorithm : identity_lsb; - output_width : 31; -} - -field_list_calculation simple_hash_2 { - input { simple_fields; } - algorithm : identity_msb; - output_width : 31; -} - - -action common_action(){ - modify_field_with_hash_based_offset(pkt.field_b_32, 0, simple_hash, 2147483648); -} - -action action_0(){ - common_action(); - modify_field(pkt.field_k_8, 0); -} - -action action_1(){ - common_action(); - modify_field(pkt.field_k_8, 1); -} - -action action_2(){ - common_action(); - modify_field(pkt.field_k_8, 2); - //modify_field_with_hash_based_offset(pkt.field_c_32, 0, simple_hash_2, 2147483648); -} - -table table_0 { - reads { - pkt.field_a_32 : lpm; - } - - actions { - action_0; - action_1; - action_2; - } - size : 512; -} - - -control ingress { - apply(table_0); -} - diff --git a/backends/tofino/bf-asm/test/internal/test_config_206_stateful_logging.p4 b/backends/tofino/bf-asm/test/internal/test_config_206_stateful_logging.p4 deleted file mode 100644 index b512618a57d..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_206_stateful_logging.p4 +++ /dev/null @@ -1,70 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - blah : 16; - } -} - -header_type meta_t { - fields { - a : 16; - b : 16; - c : 16; - d : 16; - } -} - - -header ethernet_t ethernet; -metadata meta_t meta; - - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return ingress; -} - -register logging_reg { - width : 16; - static: table_0; - instance_count : 16384; -} - -blackbox stateful_alu logging_alu { - reg: logging_reg; - update_lo_1_value: ethernet.blah; - stateful_logging_mode : table_hit; -} - -action action_0(){ - drop(); - logging_alu.execute_stateful_log(); -} - -action action_1(){ } /* Note that stateful logging is still performed here. */ - -table table_0 { - reads { - ethernet.dstAddr: exact; - } - actions { - action_0; - action_1; - } - size : 1024; -} - - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_207_not_gateway.p4 b/backends/tofino/bf-asm/test/internal/test_config_207_not_gateway.p4 deleted file mode 100644 index e8af9c2ce25..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_207_not_gateway.p4 +++ /dev/null @@ -1,61 +0,0 @@ - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -action action_0(){ - modify_field(pkt.field_k_8, 0); -} - -action action_1(){ - modify_field(pkt.field_k_8, 1); -} - -table table_0 { - reads { - pkt.field_a_32 : lpm; - } - - actions { - action_0; - action_1; - } - size : 512; -} - - -control ingress { - if (not valid(pkt)){ - apply(table_0); - } -} - diff --git a/backends/tofino/bf-asm/test/internal/test_config_208_table_no_key.p4 b/backends/tofino/bf-asm/test/internal/test_config_208_table_no_key.p4 deleted file mode 100644 index 2710e8036cb..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_208_table_no_key.p4 +++ /dev/null @@ -1,51 +0,0 @@ - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -action action_0(param0){ - modify_field(pkt.field_k_8, param0); -} - -table table_0 { - actions { - action_0; - } -} - - -control ingress { - //if (pkt.field_i_8 == 1){ - apply(table_0); - //} -} - diff --git a/backends/tofino/bf-asm/test/internal/test_config_209_pack_hash_dist.p4 b/backends/tofino/bf-asm/test/internal/test_config_209_pack_hash_dist.p4 deleted file mode 100644 index 7bcd47f21b5..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_209_pack_hash_dist.p4 +++ /dev/null @@ -1,137 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - - } -} - -header_type meta_t { - fields { - result_8 : 8; - result_8_2 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; -metadata meta_t meta; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -register reg_0 { - width : 8; - static : table_0; - instance_count : 131072; -} - -register reg_1 { - width : 8; - static : table_1; - instance_count : 131072; -} - -blackbox stateful_alu alu_0 { - reg: reg_0; - condition_lo : 1; - update_lo_1_value: 15; - - output_value : alu_lo; - output_dst : meta.result_8; - reduction_or_group: or_group_1; -} - -blackbox stateful_alu alu_1 { - reg: reg_1; - condition_lo : 1; - update_lo_1_value: 0x30; - - output_value : alu_lo; - output_dst : meta.result_8; - reduction_or_group: or_group_1; -} - -field_list fl_0 { - pkt.field_a_32; - pkt.field_b_32; -} - -field_list_calculation hash0 { - input { - fl_0; - } - algorithm : random; - output_width : 17; -} - -field_list fl_1 { - pkt.field_c_32; - pkt.field_d_32; - pkt.field_e_16; -} - -field_list_calculation hash1 { - input { - fl_1; - } - algorithm : random; - output_width : 17; -} - -action action_0(){ - alu_0.execute_stateful_alu_from_hash(hash0); -} - -action action_1(){ - alu_1.execute_stateful_alu_from_hash(hash1); -} - -table table_0 { - reads { - pkt.field_a_32 : lpm; - } - - actions { - action_0; - } - size : 512; -} - -table table_1 { - reads { - pkt.field_b_32 : lpm; - } - - actions { - action_1; - } - size : 512; -} - -control ingress { - apply(table_0); - apply(table_1); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_20_table_dependencies.p4 b/backends/tofino/bf-asm/test/internal/test_config_20_table_dependencies.p4 deleted file mode 100644 index ada3a758cdb..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_20_table_dependencies.p4 +++ /dev/null @@ -1,131 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -action action_0(){ - modify_field(ipv4.diffserv, 1); -} - -action action_1() { - modify_field(ipv4.totalLen, 2); -} - -action action_2() { - modify_field(ipv4.identification, 3); -} - -action action_3(){ - modify_field(ipv4.identification, 4); -} - - -action do_nothing(){ - no_op(); -} - - -table table_0 { - reads { - ethernet.etherType : lpm; - ipv4.diffserv : exact; - } - actions { - action_0; - do_nothing; - } - max_size : 1024; -} - -table table_1 { - reads { - ipv4.srcAddr : exact; - ipv4.dstAddr : exact; - } - actions { - action_1; - do_nothing; - } - max_size : 16384; -} - -table table_2 { - reads { - ipv4.srcAddr : exact; - ipv4.totalLen : exact; - } - actions { - action_2; - do_nothing; - } - max_size : 4096; -} - -table table_3 { - reads { - ipv4.srcAddr : exact; - } - actions { - action_3; - } - max_size : 2048; -} - - -/* Main control flow */ - -control ingress { - - apply(table_0); - apply(table_1); - - if (valid(ipv4)){ - apply(table_2); - } - - apply(table_3); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_21_tcam_vpns.p4 b/backends/tofino/bf-asm/test/internal/test_config_21_tcam_vpns.p4 deleted file mode 100644 index 0eb86e69974..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_21_tcam_vpns.p4 +++ /dev/null @@ -1,76 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -action action_0(param0){ - modify_field(ipv4.diffserv, param0); -} - -action action_1(param1) { - modify_field(ipv4.totalLen, param1); -} - - -@pragma immediate 1 -table table_0 { - reads { - ipv4.srcAddr : lpm; - } - actions { - action_0; - action_1; - } - max_size : 8192; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_22_direct_mapped_exact.p4 b/backends/tofino/bf-asm/test/internal/test_config_22_direct_mapped_exact.p4 deleted file mode 100644 index 246b8506332..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_22_direct_mapped_exact.p4 +++ /dev/null @@ -1,92 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type vlan_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - 0x8100: parse_vlan; - default: ingress; - } -} - -header ipv4_t ipv4; -header vlan_t vlan; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -parser parse_vlan { - extract(vlan); - return ingress; -} - - -action action_0(param0){ - modify_field(ipv4.diffserv, param0); -} - -action action_1(param1) { - modify_field(ipv4.totalLen, param1); -} - - -table table_0 { - reads { - vlan.vid : exact; - } - actions { - action_0; - action_1; - } - max_size : 8192; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_23_same_container_modified.p4 b/backends/tofino/bf-asm/test/internal/test_config_23_same_container_modified.p4 deleted file mode 100644 index 768ae76192d..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_23_same_container_modified.p4 +++ /dev/null @@ -1,95 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type vlan_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - 0x8100: parse_vlan; - default: ingress; - } -} - -header ipv4_t ipv4; -header vlan_t vlan; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -parser parse_vlan { - extract(vlan); - return ingress; -} - - -action action_0(my_param0, my_param1){ - modify_field(ipv4.protocol, my_param0, 0xF8); - modify_field(ipv4.ttl, my_param1); - //modify_field(ipv4.totalLen, ipv4.hdrChecksum); - //modify_field(ipv4.protocol, ipv4.ttl); -} - -action action_1(my_param2) { - modify_field(ipv4.totalLen, ipv4.totalLen); -} - - -table table_0 { - reads { - ipv4.srcAddr : exact; - } - actions { - action_0; - action_1; - } - max_size : 4096; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_24_action_entries_pragma.p4 b/backends/tofino/bf-asm/test/internal/test_config_24_action_entries_pragma.p4 deleted file mode 100644 index 2826c6e17c9..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_24_action_entries_pragma.p4 +++ /dev/null @@ -1,87 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type vlan_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - 0x8100: parse_vlan; - default: ingress; - } -} - -header ipv4_t ipv4; -header vlan_t vlan; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -parser parse_vlan { - extract(vlan); - return ingress; -} - - -action action_0(my_param0, my_param1){ - modify_field(ipv4.ttl, my_param1); -} - -@pragma action_entries 1024 -table table_0 { - reads { - ipv4.srcAddr : exact; - } - actions { - action_0; - } - max_size : 4096; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_25_no_reads_for_table.p4 b/backends/tofino/bf-asm/test/internal/test_config_25_no_reads_for_table.p4 deleted file mode 100644 index 5179d856d13..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_25_no_reads_for_table.p4 +++ /dev/null @@ -1,83 +0,0 @@ - -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type vlan_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - 0x8100: parse_vlan; - default: ingress; - } -} - -header ipv4_t ipv4; -header vlan_t vlan; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -parser parse_vlan { - extract(vlan); - return ingress; -} - - -action action_0(my_param0, my_param1){ - modify_field(ethernet.dstAddr, 0xcba987654321); -} - -table table_0 { - actions { - action_0; - } -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_26_direct_add_primitive.p4 b/backends/tofino/bf-asm/test/internal/test_config_26_direct_add_primitive.p4 deleted file mode 100644 index 04c56621683..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_26_direct_add_primitive.p4 +++ /dev/null @@ -1,88 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type vlan_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - 0x8100: parse_vlan; - default: ingress; - } -} - -header ipv4_t ipv4; -header vlan_t vlan; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -parser parse_vlan { - extract(vlan); - return ingress; -} - - -action action_0(my_param_0){ - add(vlan.etherType, vlan.etherType, my_param_0); - //add(ethernet.etherType, ethernet.etherType, my_param_0); - //add(ipv4.diffserv, ipv4.diffserv, -1); -} - -table table_0 { - reads { - ipv4.srcAddr : lpm; - } - actions { - action_0; - } - max_size : 1024; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_2_action_data_table_sizing.p4 b/backends/tofino/bf-asm/test/internal/test_config_2_action_data_table_sizing.p4 deleted file mode 100644 index 5b19bfde64e..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_2_action_data_table_sizing.p4 +++ /dev/null @@ -1,66 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - - -header_type my_test_config_1_t { - fields { - a_32 : 32; - b_8 : 8; - c_8 : 8; - d_16 : 16; - e_32 : 32; - f_32 : 32; - g_32 : 32; - h_32 : 32; - i_32 : 32; - j_16 : 16; - k_16 : 16; - l_16 : 16; - m_16 : 16; - } -} - - -header my_test_config_1_t my_test_config_1; - -parser start{ - return parse_my_test_config_1; -} - -parser parse_my_test_config_1 { - extract(my_test_config_1); - return ingress; -} - -action action_160(param_1_32, param_2_32, param_3_32, param_4_32, param_5_16, param_6_8){ - modify_field(my_test_config_1.a_32, param_1_32); - modify_field(my_test_config_1.e_32, param_2_32); - modify_field(my_test_config_1.f_32, param_3_32); - //modify_field(my_test_config_1.g_32, param_4_32); - modify_field(my_test_config_1.m_16, param_5_16); - modify_field(my_test_config_1.c_8, param_6_8); -} - -action action_8(param_1_8){ - modify_field(my_test_config_1.b_8, param_1_8); -} - - -table my_test_config_1_table { - reads { - my_test_config_1.a_32 : lpm; - my_test_config_1.e_32 : ternary; - //my_test_config_1.d_16 : ternary; - my_test_config_1.b_8 mask 0xf0: ternary; - my_test_config_1.c_8 : ternary; - } - - actions { - action_160; - action_8; - } - max_size : 1024; -} - -control ingress { - apply(my_test_config_1_table); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_30_action_data_imm_param.p4 b/backends/tofino/bf-asm/test/internal/test_config_30_action_data_imm_param.p4 deleted file mode 100644 index f663a3938ff..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_30_action_data_imm_param.p4 +++ /dev/null @@ -1,87 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type vlan_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - 0x8100: parse_vlan; - default: ingress; - } -} - -header ipv4_t ipv4; -header vlan_t vlan; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -parser parse_vlan { - extract(vlan); - return ingress; -} - - -action action_0(my_param0){ - modify_field(ipv4.protocol, 0xA5); - modify_field(ipv4.ttl, my_param0); -} - -table table_0 { - reads { - ipv4.srcAddr : exact; - } - actions { - action_0; - } - max_size : 4096; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_31_action_data_imm_imm.p4 b/backends/tofino/bf-asm/test/internal/test_config_31_action_data_imm_imm.p4 deleted file mode 100644 index a7ed086f43c..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_31_action_data_imm_imm.p4 +++ /dev/null @@ -1,87 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type vlan_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - 0x8100: parse_vlan; - default: ingress; - } -} - -header ipv4_t ipv4; -header vlan_t vlan; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -parser parse_vlan { - extract(vlan); - return ingress; -} - - -action action_0(){ - modify_field(ipv4.protocol, 0xA5); - modify_field(ipv4.ttl, 0x81); -} - -table table_0 { - reads { - ipv4.srcAddr : exact; - } - actions { - action_0; - } - max_size : 4096; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_32_action_data_imm_param_imm.p4 b/backends/tofino/bf-asm/test/internal/test_config_32_action_data_imm_param_imm.p4 deleted file mode 100644 index 2cf49cf723b..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_32_action_data_imm_param_imm.p4 +++ /dev/null @@ -1,44 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_a : 4; - field_b : 8; - field_c : 4; - field_d : 32; - field_e : 32; - } -} - - -header test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(test.field_a, 2); - modify_field(test.field_b, my_param_0); - modify_field(test.field_c, 15); -} - - -table table_0 { - reads { - test.field_e : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_33_action_data_paramx3.p4 b/backends/tofino/bf-asm/test/internal/test_config_33_action_data_paramx3.p4 deleted file mode 100644 index f8ed7850a14..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_33_action_data_paramx3.p4 +++ /dev/null @@ -1,44 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_a : 4; - field_b : 8; - field_c : 4; - field_d : 32; - field_e : 32; - } -} - - -header test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test); - return ingress; -} - - -action action_0(my_param_0, my_param_1, my_param_2){ - modify_field(test.field_a, my_param_0); - modify_field(test.field_b, my_param_1); - modify_field(test.field_c, my_param_2); -} - - -table table_0 { - reads { - test.field_e : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_34_action_data_1_bit_params.p4 b/backends/tofino/bf-asm/test/internal/test_config_34_action_data_1_bit_params.p4 deleted file mode 100644 index 0f1e2ee5897..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_34_action_data_1_bit_params.p4 +++ /dev/null @@ -1,114 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_0 : 1; - field_1 : 1; - field_2 : 1; - field_3 : 1; - field_4 : 1; - field_5 : 1; - field_6 : 1; - field_7 : 1; - field_8 : 1; - field_9 : 1; - field_10 : 1; - field_11 : 1; - field_12 : 1; - field_13 : 1; - field_14 : 1; - field_15 : 1; - field_16 : 1; - field_17 : 1; - field_18 : 1; - field_19 : 1; - field_20 : 1; - field_21 : 1; - field_22 : 1; - field_23 : 1; - field_24 : 1; - field_25 : 1; - field_26 : 1; - field_27 : 1; - field_28 : 1; - field_29 : 1; - field_30 : 1; - field_31 : 1; - - field_a : 32; - field_b : 32; - } -} - - -header test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test); - return ingress; -} - - -action action_0(my_param_0, my_param_1, my_param_2, - my_param_3, my_param_4, my_param_5, - my_param_6, my_param_7, my_param_8, - my_param_9, my_param_10, my_param_11, - my_param_12, my_param_13, my_param_14, - my_param_15, my_param_16, my_param_17, - my_param_18, my_param_19, my_param_20, - my_param_21, my_param_22, my_param_23, - my_param_24, my_param_25, my_param_26, - my_param_27, my_param_28, my_param_29, - my_param_30, my_param_31){ - - modify_field(test.field_0, my_param_0); - modify_field(test.field_1, my_param_1); - modify_field(test.field_2, my_param_2); - modify_field(test.field_3, my_param_3); - modify_field(test.field_4, my_param_4); - modify_field(test.field_5, my_param_5); - modify_field(test.field_6, my_param_6); - modify_field(test.field_7, my_param_7); - modify_field(test.field_8, my_param_8); - modify_field(test.field_9, my_param_9); - modify_field(test.field_10, my_param_10); - modify_field(test.field_11, my_param_11); - modify_field(test.field_12, my_param_12); - modify_field(test.field_13, my_param_13); - modify_field(test.field_14, my_param_14); - modify_field(test.field_15, my_param_15); - modify_field(test.field_16, my_param_16); - modify_field(test.field_17, my_param_17); - modify_field(test.field_18, my_param_18); - modify_field(test.field_19, my_param_19); - modify_field(test.field_20, my_param_20); - modify_field(test.field_21, my_param_21); - modify_field(test.field_22, my_param_22); - modify_field(test.field_23, my_param_23); - modify_field(test.field_24, my_param_24); - modify_field(test.field_25, my_param_25); - modify_field(test.field_26, my_param_26); - modify_field(test.field_27, my_param_27); - modify_field(test.field_28, my_param_28); - modify_field(test.field_29, my_param_29); - modify_field(test.field_30, my_param_30); - modify_field(test.field_31, my_param_31); -} - - -table table_0 { - reads { - test.field_a : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_35_action_data_1_bit_params_and_imms.p4 b/backends/tofino/bf-asm/test/internal/test_config_35_action_data_1_bit_params_and_imms.p4 deleted file mode 100644 index b26ffb0af0e..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_35_action_data_1_bit_params_and_imms.p4 +++ /dev/null @@ -1,113 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_0 : 1; - field_1 : 1; - field_2 : 1; - field_3 : 1; - field_4 : 1; - field_5 : 1; - field_6 : 1; - field_7 : 1; - field_8 : 1; - field_9 : 1; - field_10 : 1; - field_11 : 1; - field_12 : 1; - field_13 : 1; - field_14 : 1; - field_15 : 1; - field_16 : 1; - field_17 : 1; - field_18 : 1; - field_19 : 1; - field_20 : 1; - field_21 : 1; - field_22 : 1; - field_23 : 1; - field_24 : 1; - field_25 : 1; - field_26 : 1; - field_27 : 1; - field_28 : 1; - field_29 : 1; - field_30 : 1; - field_31 : 1; - - field_a : 32; - field_b : 32; - } -} - - -header test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test); - return ingress; -} - - -action action_0(my_param_0, my_param_1, my_param_2, - my_param_4, my_param_5, - my_param_6, my_param_7, my_param_8, - my_param_10, my_param_11, - my_param_12, my_param_13, my_param_14, - my_param_16, my_param_17, - my_param_18, my_param_19, my_param_20, - my_param_21, my_param_22, my_param_23, - my_param_25, my_param_26, - my_param_27, my_param_28, - my_param_31){ - - modify_field(test.field_0, my_param_0); - modify_field(test.field_1, my_param_1); - modify_field(test.field_2, my_param_2); - modify_field(test.field_3, 0); - modify_field(test.field_4, my_param_4); - modify_field(test.field_5, my_param_5); - modify_field(test.field_6, my_param_6); - modify_field(test.field_7, my_param_7); - modify_field(test.field_8, my_param_8); - modify_field(test.field_9, 1); - modify_field(test.field_10, my_param_10); - modify_field(test.field_11, my_param_11); - modify_field(test.field_12, my_param_12); - modify_field(test.field_13, my_param_13); - modify_field(test.field_14, my_param_14); - modify_field(test.field_15, 1); - modify_field(test.field_16, my_param_16); - modify_field(test.field_17, my_param_17); - modify_field(test.field_18, my_param_18); - modify_field(test.field_19, my_param_19); - modify_field(test.field_20, my_param_20); - modify_field(test.field_21, my_param_21); - modify_field(test.field_22, my_param_22); - modify_field(test.field_23, my_param_23); - modify_field(test.field_24, 0); - modify_field(test.field_25, my_param_25); - modify_field(test.field_26, my_param_26); - modify_field(test.field_27, my_param_27); - modify_field(test.field_28, my_param_28); - modify_field(test.field_29, 1); - modify_field(test.field_30, 1); - modify_field(test.field_31, my_param_31); -} - -table table_0 { - reads { - test.field_a : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_36_action_data_field_param.p4 b/backends/tofino/bf-asm/test/internal/test_config_36_action_data_field_param.p4 deleted file mode 100644 index c0a91ae1107..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_36_action_data_field_param.p4 +++ /dev/null @@ -1,43 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_a : 4; - field_b : 8; - field_c : 4; - field_d : 32; - field_e : 32; - } -} - - -header test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(test.field_a, test.field_c); - modify_field(test.field_e, my_param_0); -} - - -table table_0 { - reads { - test.field_e : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_37_action_data_field_field.p4 b/backends/tofino/bf-asm/test/internal/test_config_37_action_data_field_field.p4 deleted file mode 100644 index cb12ae45526..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_37_action_data_field_field.p4 +++ /dev/null @@ -1,46 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_a : 4; - field_b : 8; - field_c : 4; - field_d : 4; - field_e : 8; - field_f : 4; - - field_g : 32; - field_h : 32; - } -} - - -header test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(test.field_a, test.field_f); -} - - -table table_0 { - reads { - test.field_e : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_38_action_data_field_same_container.p4 b/backends/tofino/bf-asm/test/internal/test_config_38_action_data_field_same_container.p4 deleted file mode 100644 index 091dd479fef..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_38_action_data_field_same_container.p4 +++ /dev/null @@ -1,46 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_a : 4; - field_b : 4; - field_c : 4; - field_d : 4; - field_e : 8; - field_f : 4; - - field_g : 32; - field_h : 32; - } -} - - -header test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(test.field_a, test.field_b); -} - - -table table_0 { - reads { - test.field_e : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_39_action_data_add_to_field.p4 b/backends/tofino/bf-asm/test/internal/test_config_39_action_data_add_to_field.p4 deleted file mode 100644 index 608c81cb541..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_39_action_data_add_to_field.p4 +++ /dev/null @@ -1,46 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_a : 8; - field_b : 4; - field_c : 4; - field_d : 4; - field_e : 8; - field_f : 4; - - field_g : 32; - field_h : 32; - } -} - - -header test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test); - return ingress; -} - - -action action_0(){ - add_to_field(test.field_a, -1); -} - - -table table_0 { - reads { - test.field_e : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_3_add_to_field.PHV_BUG b/backends/tofino/bf-asm/test/internal/test_config_3_add_to_field.PHV_BUG deleted file mode 100644 index 5f6e8a7ee39..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_3_add_to_field.PHV_BUG +++ /dev/null @@ -1,74 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type my_test_config_1_t { - fields { - a_32 : 32; - b_8 : 8; - c_8 : 8; - d_16 : 16; - e_32 : 32; - f_32 : 32; - g_32 : 32; - h_32 : 32; - i_32 : 32; - j_16 : 16; - k_16 : 16; - l_16 : 16; - m_16 : 16; - n_4 : 4; - o_1 : 1; - p_3 : 3; - } -} - - -header my_test_config_1_t my_test_config_1; - -parser start{ - return parse_my_test_config_1; -} - -parser parse_my_test_config_1 { - extract(my_test_config_1); - return ingress; -} - -action action_add_constant(){ - add_to_field(my_test_config_1.b_8, -1); -} - -action action_add_param(param_1_16){ - add_to_field(my_test_config_1.j_16, param_1_16); -} - -action action_add_field(){ - add_to_field(my_test_config_1.b_8, my_test_config_1.b_8); -} - -action drop_me(){ - drop(); -} - -action set_flag(){ - modify_field(my_test_config_1.o_1, 1); -} - - -table my_test_config_1_table { - reads { - my_test_config_1.a_32 : lpm; - } - - actions { - action_add_constant; - action_add_param; - action_add_field; - drop_me; - set_flag; - } - max_size : 1024; -} - -control ingress { - apply(my_test_config_1_table); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_40_action_data_bit_xor.p4 b/backends/tofino/bf-asm/test/internal/test_config_40_action_data_bit_xor.p4 deleted file mode 100644 index 6c6102b688a..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_40_action_data_bit_xor.p4 +++ /dev/null @@ -1,46 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_a : 32; - field_b : 4; - field_c : 4; - field_d : 4; - field_e : 8; - field_f : 4; - - field_g : 32; - field_h : 32; - } -} - - -header test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test); - return ingress; -} - - -action action_0(){ - bit_xor(test.field_a, test.field_a, 0x74); -} - - -table table_0 { - reads { - test.field_e : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_41_action_data_remove_header.p4 b/backends/tofino/bf-asm/test/internal/test_config_41_action_data_remove_header.p4 deleted file mode 100644 index 47cb94c1c9a..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_41_action_data_remove_header.p4 +++ /dev/null @@ -1,46 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_a : 8; - field_b : 4; - field_c : 4; - field_d : 4; - field_e : 8; - field_f : 4; - - field_g : 32; - field_h : 32; - } -} - - -header test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test); - return ingress; -} - - -action action_0(){ - remove_header(test); -} - - -table table_0 { - reads { - test.field_e : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_42_action_data_add_header.p4 b/backends/tofino/bf-asm/test/internal/test_config_42_action_data_add_header.p4 deleted file mode 100644 index 25c48d47b58..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_42_action_data_add_header.p4 +++ /dev/null @@ -1,45 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_a : 8; - field_b : 4; - field_c : 4; - field_d : 4; - field_e : 8; - field_f : 4; - - field_g : 32; - field_h : 32; - } -} - -header test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test); - return ingress; -} - - -action action_0(){ - add_header(test); -} - - -table table_0 { - reads { - test.field_e : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_43_action_data_drop.PHV_BUG b/backends/tofino/bf-asm/test/internal/test_config_43_action_data_drop.PHV_BUG deleted file mode 100644 index 2d7008cc27e..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_43_action_data_drop.PHV_BUG +++ /dev/null @@ -1,46 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_a : 32; - field_b : 4; - field_c : 4; - field_d : 4; - field_e : 8; - field_f : 4; - - field_g : 32; - field_h : 32; - } -} - - -header test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test); - return ingress; -} - - -action action_0(){ - drop(); -} - - -table table_0 { - reads { - test.field_e : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_44_action_data_immediate.p4 b/backends/tofino/bf-asm/test/internal/test_config_44_action_data_immediate.p4 deleted file mode 100644 index 471b3971a88..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_44_action_data_immediate.p4 +++ /dev/null @@ -1,47 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_a : 32; - field_b : 4; - field_c : 4; - field_d : 4; - field_e : 8; - field_f : 4; - - field_g : 32; - field_h : 32; - } -} - - -header test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test); - return ingress; -} - - -action action_0(my_param_0, my_param_1){ - modify_field(test.field_b, my_param_0); - modify_field(test.field_c, my_param_1); -} - -@pragma immediate 1 -table table_0 { - reads { - test.field_e : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_45_action_data_immediate_param_and_constant.p4 b/backends/tofino/bf-asm/test/internal/test_config_45_action_data_immediate_param_and_constant.p4 deleted file mode 100644 index 9b280cd1d51..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_45_action_data_immediate_param_and_constant.p4 +++ /dev/null @@ -1,49 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_a : 32; - field_b : 4; - field_c : 4; - field_d : 4; - field_e : 8; - field_f : 4; - - field_g : 32; - field_h : 32; - } -} - - -header test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test); - return ingress; -} - - -action action_0(my_param_0, my_param_1, my_param_2){ - modify_field(test.field_b, my_param_0); - modify_field(test.field_c, 0xc); - modify_field(test.field_d, my_param_1); - modify_field(test.field_f, my_param_2); -} - -@pragma immediate 1 -table table_0 { - reads { - test.field_e : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_46_action_data_big_constant.p4 b/backends/tofino/bf-asm/test/internal/test_config_46_action_data_big_constant.p4 deleted file mode 100644 index fa607db1cb1..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_46_action_data_big_constant.p4 +++ /dev/null @@ -1,87 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type vlan_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - 0x8100: parse_vlan; - default: ingress; - } -} - -header ipv4_t ipv4; -header vlan_t vlan; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -parser parse_vlan { - extract(vlan); - return ingress; -} - - -action action_0(my_param0, my_param1){ - modify_field(ethernet.dstAddr, 0xcba987654321); -} - -@pragma immediate 1 -table table_0 { - reads { - ipv4.srcAddr : lpm; - } - actions { - action_0; - } - max_size : 1024; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_47_action_data_big_constant_immediate.p4 b/backends/tofino/bf-asm/test/internal/test_config_47_action_data_big_constant_immediate.p4 deleted file mode 100644 index fa607db1cb1..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_47_action_data_big_constant_immediate.p4 +++ /dev/null @@ -1,87 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type vlan_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - 0x8100: parse_vlan; - default: ingress; - } -} - -header ipv4_t ipv4; -header vlan_t vlan; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -parser parse_vlan { - extract(vlan); - return ingress; -} - - -action action_0(my_param0, my_param1){ - modify_field(ethernet.dstAddr, 0xcba987654321); -} - -@pragma immediate 1 -table table_0 { - reads { - ipv4.srcAddr : lpm; - } - actions { - action_0; - } - max_size : 1024; -} - - -/* Main control flow */ - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_48_action_data_bit_masked_set.p4 b/backends/tofino/bf-asm/test/internal/test_config_48_action_data_bit_masked_set.p4 deleted file mode 100644 index 781bdc0bd6c..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_48_action_data_bit_masked_set.p4 +++ /dev/null @@ -1,44 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_a : 2; - field_b : 2; - field_c : 2; - field_d : 2; - field_e : 32; - field_f : 32; - } -} - - -header test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test); - return ingress; -} - - -action action_0(my_param_0, my_param_1){ - modify_field(test.field_a, my_param_0); - modify_field(test.field_c, my_param_1); -} - - -table table_0 { - reads { - test.field_e : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_49_action_data_bit_masked_set_immediate.p4 b/backends/tofino/bf-asm/test/internal/test_config_49_action_data_bit_masked_set_immediate.p4 deleted file mode 100644 index 602a6e16a7f..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_49_action_data_bit_masked_set_immediate.p4 +++ /dev/null @@ -1,50 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - field_e : 16; - field_f : 16; - field_g : 16; - field_h : 16; - field_i : 2; - field_j : 2; - field_k : 2; - field_l : 2; - } -} - - -header test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test); - return ingress; -} - - -action action_0(my_param_0, my_param_1){ - modify_field(test.field_i, my_param_0); - modify_field(test.field_k, my_param_1); -} - -@pragma immediate 1 -table table_0 { - reads { - test.field_e : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_4_modify_field.p4 b/backends/tofino/bf-asm/test/internal/test_config_4_modify_field.p4 deleted file mode 100644 index e78d5b43469..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_4_modify_field.p4 +++ /dev/null @@ -1,65 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type my_test_config_1_t { - fields { - a_32 : 32; - b_8 : 8; - c_8 : 8; - d_16 : 16; - e_32 : 32; - f_32 : 32; - g_32 : 32; - h_32 : 32; - i_32 : 32; - j_16 : 16; - k_16 : 16; - l_16 : 16; - m_16 : 16; - n_4 : 4; - o_1 : 1; - p_3 : 3; - } -} - - -header my_test_config_1_t my_test_config_1; - -parser start{ - return parse_my_test_config_1; -} - -parser parse_my_test_config_1 { - extract(my_test_config_1); - return ingress; -} - -action modify_from_constant(){ - modify_field(my_test_config_1.e_32, 3); -} - -action modify_from_field(){ - modify_field(my_test_config_1.h_32, my_test_config_1.g_32); -} - - -action modify_from_param(param1_32){ - modify_field(my_test_config_1.f_32, param1_32); -} - - -table my_test_config_1_table { - reads { - my_test_config_1.a_32 : lpm; - } - - actions { - modify_from_constant; - modify_from_field; - modify_from_param; - } - max_size : 1024; -} - -control ingress { - apply(my_test_config_1_table); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_50_action_data_different_size_fields.p4 b/backends/tofino/bf-asm/test/internal/test_config_50_action_data_different_size_fields.p4 deleted file mode 100644 index 13da225d720..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_50_action_data_different_size_fields.p4 +++ /dev/null @@ -1,44 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - field_e : 16; - field_f : 16; - field_g : 16; - field_h : 16; - } -} - - -header test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test); - return ingress; -} - - -action action_0(){ - modify_field(test.field_a, test.field_e); -} - -table table_0 { - reads { - test.field_b : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_51_action_data_same_parameter_used_multiple.p4 b/backends/tofino/bf-asm/test/internal/test_config_51_action_data_same_parameter_used_multiple.p4 deleted file mode 100644 index 0c597fa4d22..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_51_action_data_same_parameter_used_multiple.p4 +++ /dev/null @@ -1,51 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - field_e : 16; - field_f : 16; - field_g : 16; - field_h : 16; - } -} - - -header test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(test.field_a, my_param_0); - modify_field(test.field_c, my_param_0); -} - -action action_1(){ - no_op(); -} - -@pragma action_entries 200 -table table_0 { - reads { - test.field_b : ternary; - } - actions { - action_0; - action_1; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_52_copy_header.p4 b/backends/tofino/bf-asm/test/internal/test_config_52_copy_header.p4 deleted file mode 100644 index 7c7c7012849..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_52_copy_header.p4 +++ /dev/null @@ -1,45 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_a : 8; - field_b : 16; - field_c : 8; - field_d : 32; - field_e : 16; - field_f : 16; - } -} - - -header test_t test_dest; -header test_t test_src; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test_dest); - extract(test_src); - return ingress; -} - - -action action_0(){ - copy_header(test_dest, test_src); -} - - -table table_0 { - reads { - test_src.field_e : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_53_ternary_swizzle.p4 b/backends/tofino/bf-asm/test/internal/test_config_53_ternary_swizzle.p4 deleted file mode 100644 index cb522a6f84f..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_53_ternary_swizzle.p4 +++ /dev/null @@ -1,43 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type test_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - field_e : 32; - } -} - - -header test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(test); - return ingress; -} - - -action action_0(){ - modify_field(test.field_a, 2); -} - - -table table_0 { - reads { - test.field_a : ternary; - test.field_b mask 0xff00 : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_54_modify_field_different_size.PHV_BUG b/backends/tofino/bf-asm/test/internal/test_config_54_modify_field_different_size.PHV_BUG deleted file mode 100644 index e5eb489d96d..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_54_modify_field_different_size.PHV_BUG +++ /dev/null @@ -1,51 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - } -} - -header_type test_t { - fields { - - field_a_8 : 8; - field_a_16 : 16; - - field_d_8 : 8; - field_d_16 : 16; - - } -} - -header pkt_t pkt; -metadata test_t test; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(){ - modify_field(test.field_a_8, test.field_a_16); - modify_field(test.field_d_16, test.field_d_8); -} - - -table table_0 { - reads { - pkt.field_a : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_55_generate_digest.p4 b/backends/tofino/bf-asm/test/internal/test_config_55_generate_digest.p4 deleted file mode 100644 index 5cfd98e2b13..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_55_generate_digest.p4 +++ /dev/null @@ -1,42 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -field_list tcp_digest { - pkt.field_a; -} - - -action action_0(){ - generate_digest(0, tcp_digest); -} - - -table table_0 { - reads { - pkt.field_a : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_56_iterate_through_packing.p4 b/backends/tofino/bf-asm/test/internal/test_config_56_iterate_through_packing.p4 deleted file mode 100644 index 85088974408..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_56_iterate_through_packing.p4 +++ /dev/null @@ -1,39 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - field_b : 32; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0, my_param_1){ - modify_field(pkt.field_a, my_param_0); - modify_field(pkt.field_b, my_param_1); -} - - -table table_0 { - reads { - pkt.field_a : exact; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_57_tcam_with_44_bits_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_57_tcam_with_44_bits_no_version.p4 deleted file mode 100644 index e04305a484f..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_57_tcam_with_44_bits_no_version.p4 +++ /dev/null @@ -1,41 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 4; - field_b : 12; - field_c : 16; - field_d : 32; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 0 -table table_0 { - reads { - pkt.field_b : ternary; - pkt.field_d : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_58_tcam_with_40_bits.p4 b/backends/tofino/bf-asm/test/internal/test_config_58_tcam_with_40_bits.p4 deleted file mode 100644 index bb7c1f4c2e1..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_58_tcam_with_40_bits.p4 +++ /dev/null @@ -1,41 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 8; - field_b : 8; - field_c : 16; - field_d : 32; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 0 -table table_0 { - reads { - pkt.field_b : ternary; - pkt.field_d : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_59_tcam_with_44_bits_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_59_tcam_with_44_bits_and_version.p4 deleted file mode 100644 index e04305a484f..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_59_tcam_with_44_bits_and_version.p4 +++ /dev/null @@ -1,41 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 4; - field_b : 12; - field_c : 16; - field_d : 32; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 0 -table table_0 { - reads { - pkt.field_b : ternary; - pkt.field_d : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_5_sram_allocation.p4 b/backends/tofino/bf-asm/test/internal/test_config_5_sram_allocation.p4 deleted file mode 100644 index 4cd64b34c8b..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_5_sram_allocation.p4 +++ /dev/null @@ -1,69 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type my_test_config_1_t { - fields { - a_32 : 32; - b_8 : 8; - c_8 : 8; - d_16 : 16; - e_32 : 32; - f_32 : 32; - g_32 : 32; - h_32 : 32; - i_32 : 32; - j_16 : 16; - k_16 : 16; - l_16 : 16; - m_16 : 16; - n_4 : 4; - o_1 : 1; - p_3 : 3; - } -} - - -header my_test_config_1_t my_test_config_1; - -parser start{ - return parse_my_test_config_1; -} - -parser parse_my_test_config_1 { - extract(my_test_config_1); - return ingress; -} - -action set_flag(){ - modify_field(my_test_config_1.o_1, 1); -} - -action do_nothing(){ - no_op(); -} - -table test_exact_table { - reads { - //my_test_config_1.a_32 : exact; - //my_test_config_1.a_32 mask 0xff0fff0f: exact; - //my_test_config_1.p_3 : valid; - - my_test_config_1.a_32 : exact; - my_test_config_1.e_32 : exact; - my_test_config_1.f_32 : exact; - my_test_config_1.g_32 : exact; - my_test_config_1.h_32 : exact; - my_test_config_1.i_32 : exact; - - - } - - actions { - set_flag; - do_nothing; - } - max_size : 16384; -} - -control ingress { - apply(test_exact_table); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_60_tcam_with_44_and_no_version_high_nibble.p4 b/backends/tofino/bf-asm/test/internal/test_config_60_tcam_with_44_and_no_version_high_nibble.p4 deleted file mode 100644 index 1163dfbac57..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_60_tcam_with_44_and_no_version_high_nibble.p4 +++ /dev/null @@ -1,41 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 12; - field_b : 4; - field_c : 16; - field_d : 32; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 1 -table table_0 { - reads { - pkt.field_a : ternary; - pkt.field_d : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_61_tcam_with_44_bits_and_no_version_low_nibble.p4 b/backends/tofino/bf-asm/test/internal/test_config_61_tcam_with_44_bits_and_no_version_low_nibble.p4 deleted file mode 100644 index 761aff8036c..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_61_tcam_with_44_bits_and_no_version_low_nibble.p4 +++ /dev/null @@ -1,41 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 4; - field_b : 12; - field_c : 16; - field_d : 32; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 1 -table table_0 { - reads { - pkt.field_b : ternary; - pkt.field_d : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_62_tcam_with_48_bits_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_62_tcam_with_48_bits_and_version.p4 deleted file mode 100644 index 38979e77e58..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_62_tcam_with_48_bits_and_version.p4 +++ /dev/null @@ -1,41 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 8; - field_b : 16; - field_c : 16; - field_d : 32; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 0 -table table_0 { - reads { - pkt.field_b : ternary; - pkt.field_d : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_63_tcam_with_48_bits_and_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_63_tcam_with_48_bits_and_no_version.p4 deleted file mode 100644 index 55d4cc9497f..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_63_tcam_with_48_bits_and_no_version.p4 +++ /dev/null @@ -1,41 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 8; - field_b : 16; - field_c : 16; - field_d : 32; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 1 -table table_0 { - reads { - pkt.field_b : ternary; - pkt.field_d : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_64_tcam_with_84_bits_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_64_tcam_with_84_bits_and_version.p4 deleted file mode 100644 index e04305a484f..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_64_tcam_with_84_bits_and_version.p4 +++ /dev/null @@ -1,41 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 4; - field_b : 12; - field_c : 16; - field_d : 32; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 0 -table table_0 { - reads { - pkt.field_b : ternary; - pkt.field_d : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_64_tcam_with_84_bits_high_nibble_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_64_tcam_with_84_bits_high_nibble_and_version.p4 deleted file mode 100644 index e23b199f462..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_64_tcam_with_84_bits_high_nibble_and_version.p4 +++ /dev/null @@ -1,45 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 12; - field_b : 4; - field_c : 16; - field_d : 32; - field_e : 32; - field_f : 8; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 0 -table table_0 { - reads { - pkt.field_a : ternary; - pkt.field_d : ternary; - pkt.field_e : ternary; - pkt.field_f : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_65_tcam_with_84_bits_low_nibble_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_65_tcam_with_84_bits_low_nibble_and_version.p4 deleted file mode 100644 index 9ebba80b73d..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_65_tcam_with_84_bits_low_nibble_and_version.p4 +++ /dev/null @@ -1,45 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 4; - field_b : 12; - field_c : 16; - field_d : 32; - field_e : 32; - field_f : 8; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 0 -table table_0 { - reads { - pkt.field_b : ternary; - pkt.field_d : ternary; - pkt.field_e : ternary; - pkt.field_f : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_66_tcam_with_84_bits_high_nibble_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_66_tcam_with_84_bits_high_nibble_no_version.p4 deleted file mode 100644 index d2bc060c8bc..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_66_tcam_with_84_bits_high_nibble_no_version.p4 +++ /dev/null @@ -1,45 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 12; - field_b : 4; - field_c : 16; - field_d : 32; - field_e : 32; - field_f : 8; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 1 -table table_0 { - reads { - pkt.field_a : ternary; - pkt.field_d : ternary; - pkt.field_e : ternary; - pkt.field_f : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_67_tcam_with_84_bits_low_nibble_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_67_tcam_with_84_bits_low_nibble_no_version.p4 deleted file mode 100644 index 8de0a0fcf37..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_67_tcam_with_84_bits_low_nibble_no_version.p4 +++ /dev/null @@ -1,45 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 4; - field_b : 12; - field_c : 16; - field_d : 32; - field_e : 32; - field_f : 8; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 1 -table table_0 { - reads { - pkt.field_b : ternary; - pkt.field_d : ternary; - pkt.field_e : ternary; - pkt.field_f : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_68_tcam_with_88_bits_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_68_tcam_with_88_bits_and_version.p4 deleted file mode 100644 index bff51acb4d8..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_68_tcam_with_88_bits_and_version.p4 +++ /dev/null @@ -1,45 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 8; - field_b : 16; - field_c : 16; - field_d : 32; - field_e : 32; - field_f : 8; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 0 -table table_0 { - reads { - pkt.field_b : ternary; - pkt.field_d : ternary; - pkt.field_e : ternary; - pkt.field_f : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_69_tcam_with_88_bits_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_69_tcam_with_88_bits_no_version.p4 deleted file mode 100644 index 0e8c6b60d7c..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_69_tcam_with_88_bits_no_version.p4 +++ /dev/null @@ -1,45 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 8; - field_b : 16; - field_c : 16; - field_d : 32; - field_e : 32; - field_f : 8; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 1 -table table_0 { - reads { - pkt.field_b : ternary; - pkt.field_d : ternary; - pkt.field_e : ternary; - pkt.field_f : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_6_sram_and_tcam_allocation.p4 b/backends/tofino/bf-asm/test/internal/test_config_6_sram_and_tcam_allocation.p4 deleted file mode 100644 index fa0f38693e3..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_6_sram_and_tcam_allocation.p4 +++ /dev/null @@ -1,131 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -action ig_drop() { - modify_field(routing_metadata.drop, 1); -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(standard_metadata.egress_port, egress_port); -} - -action do_nothing(){ - no_op(); -} - -action l3_set_index(index) { - modify_field( ipv4.diffserv, index); -} - -action hop_ipv4(srcmac, srcip, dstmac, egress_port){ - hop(ipv4.ttl, egress_port); - modify_field(ipv4.srcAddr, srcip); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -table ipv4_routing { - reads { - ipv4.dstAddr : lpm; - ipv4.srcAddr : exact; - } - actions { - ig_drop; - hop_ipv4; - } - max_size : 2048; -} - -table host_ip { - reads { - ipv4.dstAddr : exact; - } - actions { - do_nothing; - l3_set_index; - } - max_size : 16384; -} - - -/* Main control flow */ -control ingress { - apply(ipv4_routing); - apply(host_ip); -} - -action eg_drop() { - modify_field(standard_metadata.egress_spec, 0); -} - -action permit() { -} - -table egress_acl { - reads { - routing_metadata.drop: ternary; - } - actions { - eg_drop; - permit; - } -} - -control egress { - apply(egress_acl); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_70_tcam_with_128_bits_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_70_tcam_with_128_bits_and_version.p4 deleted file mode 100644 index 3798f18b9a4..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_70_tcam_with_128_bits_and_version.p4 +++ /dev/null @@ -1,43 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 0 -table table_0 { - reads { - pkt.field_a : ternary; - pkt.field_b : ternary; - pkt.field_c : ternary; - pkt.field_d : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_71_tcam_with_128_bits_and_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_71_tcam_with_128_bits_and_no_version.p4 deleted file mode 100644 index 4e060d03f93..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_71_tcam_with_128_bits_and_no_version.p4 +++ /dev/null @@ -1,43 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 1 -table table_0 { - reads { - pkt.field_a : ternary; - pkt.field_b : ternary; - pkt.field_c : ternary; - pkt.field_d : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_72_tcam_with_172_bits_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_72_tcam_with_172_bits_and_version.p4 deleted file mode 100644 index 9ce7c42ad21..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_72_tcam_with_172_bits_and_version.p4 +++ /dev/null @@ -1,45 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - field_e : 32; - - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 0 -table table_0 { - reads { - pkt.field_a : ternary; - pkt.field_b : ternary; - pkt.field_c : ternary; - pkt.field_d : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_72_tcam_with_172_bits_high_nibble_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_72_tcam_with_172_bits_high_nibble_and_version.p4 deleted file mode 100644 index 667cf30b457..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_72_tcam_with_172_bits_high_nibble_and_version.p4 +++ /dev/null @@ -1,48 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - field_e : 32; - field_f : 12; - field_g : 4; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 0 -table table_0 { - reads { - pkt.field_a : ternary; - pkt.field_b : ternary; - pkt.field_c : ternary; - pkt.field_d : ternary; - pkt.field_e : ternary; - pkt.field_f : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_73_tcam_with_172_bits_low_nibble_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_73_tcam_with_172_bits_low_nibble_and_version.p4 deleted file mode 100644 index f6511c668c0..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_73_tcam_with_172_bits_low_nibble_and_version.p4 +++ /dev/null @@ -1,48 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - field_e : 32; - field_f : 4; - field_g : 12; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 0 -table table_0 { - reads { - pkt.field_a : ternary; - pkt.field_b : ternary; - pkt.field_c : ternary; - pkt.field_d : ternary; - pkt.field_e : ternary; - pkt.field_g : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_74_tcam_with_172_bits_low_nibble_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_74_tcam_with_172_bits_low_nibble_no_version.p4 deleted file mode 100644 index b9c776c48f5..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_74_tcam_with_172_bits_low_nibble_no_version.p4 +++ /dev/null @@ -1,48 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - field_e : 32; - field_f : 4; - field_g : 12; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 1 -table table_0 { - reads { - pkt.field_a : ternary; - pkt.field_b : ternary; - pkt.field_c : ternary; - pkt.field_d : ternary; - pkt.field_e : ternary; - pkt.field_g : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_75_tcam_with_176_bits_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_75_tcam_with_176_bits_no_version.p4 deleted file mode 100644 index 1f51a058ece..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_75_tcam_with_176_bits_no_version.p4 +++ /dev/null @@ -1,47 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - field_e : 32; - field_f : 16; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 1 -table table_0 { - reads { - pkt.field_a : ternary; - pkt.field_b : ternary; - pkt.field_c : ternary; - pkt.field_d : ternary; - pkt.field_e : ternary; - pkt.field_f : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_76_tcam_with_176_bits_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_76_tcam_with_176_bits_and_version.p4 deleted file mode 100644 index 993c5db41de..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_76_tcam_with_176_bits_and_version.p4 +++ /dev/null @@ -1,47 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - field_e : 32; - field_f : 16; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 0 -table table_0 { - reads { - pkt.field_a : ternary; - pkt.field_b : ternary; - pkt.field_c : ternary; - pkt.field_d : ternary; - pkt.field_e : ternary; - pkt.field_f : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_77_tcam_with_216_bits_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_77_tcam_with_216_bits_and_version.p4 deleted file mode 100644 index 0bcd316d9b5..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_77_tcam_with_216_bits_and_version.p4 +++ /dev/null @@ -1,51 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - field_e : 32; - field_f : 32; - field_g : 16; - field_h : 8; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 0 -table table_0 { - reads { - pkt.field_a : ternary; - pkt.field_b : ternary; - pkt.field_c : ternary; - pkt.field_d : ternary; - pkt.field_e : ternary; - pkt.field_f : ternary; - pkt.field_g : ternary; - pkt.field_h : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_78_tcam_with_220_bits_high_nibble_and_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_78_tcam_with_220_bits_high_nibble_and_version.p4 deleted file mode 100644 index 65239c86c03..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_78_tcam_with_220_bits_high_nibble_and_version.p4 +++ /dev/null @@ -1,56 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - field_e : 32; - field_f : 32; - field_g : 16; - field_h : 12; - field_i : 4; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0, my_param_1, my_param_2, my_param_3, my_param_4){ - modify_field(pkt.field_c, my_param_0); - //modify_field(pkt.field_d, my_param_1); - modify_field(pkt.field_g, my_param_2); - modify_field(pkt.field_i, my_param_3); - //modify_field(pkt.field_a, my_param_4); -} - -@pragma no_versioning 0 -table table_0 { - reads { - pkt.field_a : ternary; - pkt.field_b : ternary; - pkt.field_c : ternary; - pkt.field_d : ternary; - pkt.field_e : ternary; - pkt.field_f : ternary; - pkt.field_g : ternary; - pkt.field_h : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_79_tcam_with_220_bits_high_nibble_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_79_tcam_with_220_bits_high_nibble_no_version.p4 deleted file mode 100644 index ce5de789db0..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_79_tcam_with_220_bits_high_nibble_no_version.p4 +++ /dev/null @@ -1,52 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - field_e : 32; - field_f : 32; - field_g : 16; - field_h : 12; - field_i : 4; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 1 -table table_0 { - reads { - pkt.field_a : ternary; - pkt.field_b : ternary; - pkt.field_c : ternary; - pkt.field_d : ternary; - pkt.field_e : ternary; - pkt.field_f : ternary; - pkt.field_g : ternary; - pkt.field_h : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_80_tcam_with_220_bits_low_nibble_no_version.p4 b/backends/tofino/bf-asm/test/internal/test_config_80_tcam_with_220_bits_low_nibble_no_version.p4 deleted file mode 100644 index c687d0041ba..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_80_tcam_with_220_bits_low_nibble_no_version.p4 +++ /dev/null @@ -1,52 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - field_e : 32; - field_f : 32; - field_g : 16; - field_i : 4; - field_h : 12; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -@pragma no_versioning 1 -table table_0 { - reads { - pkt.field_a : ternary; - pkt.field_b : ternary; - pkt.field_c : ternary; - pkt.field_d : ternary; - pkt.field_e : ternary; - pkt.field_f : ternary; - pkt.field_g : ternary; - pkt.field_h : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_81_indirect_action_data_default.p4 b/backends/tofino/bf-asm/test/internal/test_config_81_indirect_action_data_default.p4 deleted file mode 100644 index 588560e5c3e..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_81_indirect_action_data_default.p4 +++ /dev/null @@ -1,60 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - field_e : 32; - field_f : 32; - field_g : 16; - field_h : 12; - field_i : 4; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(){ - no_op(); -} - -action action_1(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -action action_2(my_param_0, my_param_1, my_param_2, my_param_3){ - modify_field(pkt.field_a, my_param_0); - modify_field(pkt.field_b, my_param_1); - modify_field(pkt.field_c, my_param_2); - modify_field(pkt.field_d, my_param_3); -} - - -@pragma action_entries 100 -table table_0 { - reads { - pkt.field_a : ternary; - } - actions { - action_0; - action_1; - action_2; - } - min_size : 2049; -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_82_param_sharing.p4 b/backends/tofino/bf-asm/test/internal/test_config_82_param_sharing.p4 deleted file mode 100644 index 9f81dd87db9..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_82_param_sharing.p4 +++ /dev/null @@ -1,78 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 4; - field_b : 4; - field_c : 4; - field_d : 4; - field_e : 4; - field_f : 4; - field_g : 4; - field_h : 4; - - field_i : 4; - field_j : 4; - field_k : 4; - field_l : 4; - field_m : 4; - field_n : 4; - field_o : 4; - field_p : 4; - - field_q : 32; - field_r : 32; - - field_s : 16; - field_t : 16; - field_u : 16; - field_v : 16; - - field_w : 8; - field_x : 8; - field_y : 8; - field_z : 8; - - - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(){ - no_op(); -} - -action action_1(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -action action_2(my_param_0, my_param_1){ - modify_field(pkt.field_a, my_param_0); - modify_field(pkt.field_i, my_param_1); -} - -table table_0 { - reads { - pkt.field_b : ternary; - } - actions { - action_0; - action_1; - action_2; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_83_no_immediate_when_indirect_action_table.p4 b/backends/tofino/bf-asm/test/internal/test_config_83_no_immediate_when_indirect_action_table.p4 deleted file mode 100644 index 1eb9b09dcb6..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_83_no_immediate_when_indirect_action_table.p4 +++ /dev/null @@ -1,53 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 16; - field_b : 16; - field_c : 16; - field_d : 16; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(){ - no_op(); -} - -action action_1(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -action action_2(my_param_0, my_param_1){ - modify_field(pkt.field_a, my_param_0); - modify_field(pkt.field_d, my_param_1); -} - -//@pragma immediate 0 -@pragma action_entries 1024 -table table_0 { - reads { - pkt.field_b : ternary; - } - actions { - action_0; - action_1; - action_2; - } - size : 2048; -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_84_simple_wide_exact_match.p4 b/backends/tofino/bf-asm/test/internal/test_config_84_simple_wide_exact_match.p4 deleted file mode 100644 index 6d60cefbd1c..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_84_simple_wide_exact_match.p4 +++ /dev/null @@ -1,53 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - - field_e : 32; - field_f : 32; - field_g : 32; - field_h : 32; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action action_0(){ - no_op(); -} - -action action_1(my_param_0){ - modify_field(pkt.field_c, my_param_0); -} - -table table_0 { - reads { - pkt.field_a : exact; - pkt.field_b : exact; - pkt.field_c : exact; - pkt.field_d : exact; - pkt.field_e : exact; - } - actions { - action_0; - action_1; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_85_table_ordering.p4 b/backends/tofino/bf-asm/test/internal/test_config_85_table_ordering.p4 deleted file mode 100644 index fb412ff6f79..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_85_table_ordering.p4 +++ /dev/null @@ -1,126 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - - field_e : 32; - field_f : 32; - field_g : 32; - field_h : 32; - field_i : 32; - field_j : 32; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action nop(){ - no_op(); -} - -action action_0(my_param_0, my_param_4){ - modify_field(pkt.field_a, my_param_0); - modify_field(pkt.field_g, my_param_4); -} - -action action_1(my_param_1){ - modify_field(pkt.field_c, my_param_1); -} - -action action_2(my_param_2){ - modify_field(pkt.field_e, my_param_2); -} - -action action_3(my_param_3){ - modify_field(pkt.field_i, my_param_3); -} - -action action_4(my_param_4){ - modify_field(pkt.field_j, my_param_4); -} - -@pragma immediate 0 -table table_0 { - reads { - pkt.field_b : exact; - } - actions { - action_0; - nop; - } - size : 256000; -} - -table table_1 { - reads { - pkt.field_d : exact; - } - actions { - action_1; - nop; - } -} - -table table_2 { - reads { - pkt.field_f : exact; - } - actions { - action_2; - nop; - } -} - -table table_3 { - reads { - pkt.field_h : exact; - } - actions { - action_3; - nop; - } -} - - -table table_4 { - reads { - pkt.field_e : exact; - } - actions { - action_4; - nop; - } -} - - - -control ingress { - apply(table_0){ - nop { - apply(table_1); - } - } - - if (valid(pkt)){ - apply(table_2); - } else { - apply(table_3); - } - - apply(table_4); - -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_86_multiple_action_widths_for_indirect_action.p4 b/backends/tofino/bf-asm/test/internal/test_config_86_multiple_action_widths_for_indirect_action.p4 deleted file mode 100644 index 7009c772d57..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_86_multiple_action_widths_for_indirect_action.p4 +++ /dev/null @@ -1,95 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 8; - field_b : 8; - field_c : 16; - field_d : 16; - - field_e : 32; - field_f : 32; - field_g : 32; - field_h : 32; - field_i : 32; - field_j : 32; - field_k : 32; - field_l : 32; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action nop(){ - no_op(); -} - -//8 -action action_0(my_param_a){ - modify_field(pkt.field_a, my_param_a); -} - -//16 -action action_1(my_param_c){ - modify_field(pkt.field_c, my_param_c); -} - -//32 -action action_2(my_param_e){ - modify_field(pkt.field_e, my_param_e); -} - -//64 -action action_3(my_param_f, my_param_g){ - modify_field(pkt.field_f, my_param_f); - modify_field(pkt.field_g, my_param_g); -} - -//128 -action action_4(my_param_h, my_param_i, my_param_j, my_param_k){ - modify_field(pkt.field_h, my_param_h); - modify_field(pkt.field_i, my_param_i); - modify_field(pkt.field_j, my_param_j); - modify_field(pkt.field_k, my_param_k); -} - -//160 -action action_5(my_param_h, my_param_i, my_param_j, my_param_k, my_param_l){ - modify_field(pkt.field_h, my_param_h); - modify_field(pkt.field_i, my_param_i); - modify_field(pkt.field_j, my_param_j); - modify_field(pkt.field_k, my_param_k); - modify_field(pkt.field_l, my_param_l); -} - - -@pragma immediate 0 -@pragma action_entries 1024 -table table_0 { - reads { - pkt.field_b : exact; - } - actions { - action_0; - action_1; - action_2; - action_3; - action_4; - action_5; - } - size : 4096; -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_87_share_parameter_for_different_containers.p4 b/backends/tofino/bf-asm/test/internal/test_config_87_share_parameter_for_different_containers.p4 deleted file mode 100644 index b7f4830cea1..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_87_share_parameter_for_different_containers.p4 +++ /dev/null @@ -1,59 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a : 32; - field_b : 32; - field_c : 32; - field_d : 32; - - field_e : 16; - field_f : 16; - field_g : 16; - field_h : 16; - - field_i : 8; - field_j : 8; - field_k : 8; - field_l : 8; - } -} - -header pkt_t pkt; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action nop(){ - no_op(); -} - -action action_0(my_only_param){ - modify_field(pkt.field_a, my_only_param); - modify_field(pkt.field_e, my_only_param); - modify_field(pkt.field_i, my_only_param); - -} - - -@pragma immediate 0 -table table_0 { - reads { - pkt.field_b : exact; - } - actions { - action_0; - } - size : 1024; -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_88_testing_action_data_allocation_3.p4 b/backends/tofino/bf-asm/test/internal/test_config_88_testing_action_data_allocation_3.p4 deleted file mode 100644 index 0893bc91ee5..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_88_testing_action_data_allocation_3.p4 +++ /dev/null @@ -1,192 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -header_type meta_t { - fields { - meta_a_32 : 32; - meta_b_32 : 32; - meta_c_32 : 32; - meta_d_32 : 32; - } -} - - -header pkt_t pkt; -metadata meta_t meta; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action nop(){ - no_op(); -} - -//Simple Actions - -action action_0(param_a_32){ - modify_field(pkt.field_a_32, param_a_32); -} - -action action_1(param_e_16){ - modify_field(pkt.field_e_16, param_e_16); -} - -action action_2(param_i_8){ - modify_field(pkt.field_i_8, param_i_8); -} - -//Adjacent Actions - -action action_3(param_b_32){ - modify_field(pkt.field_b_32, param_b_32, 0xffffafff); -} - -action action_4(param_f_16){ - modify_field(pkt.field_f_16, param_f_16, 0xfaff); -} - -action action_5(param_j_8){ - modify_field(pkt.field_j_8, param_j_8, 0xaa); -} - - -//Long Actions - - -action action_6(param_c_32, param_g_16, param_k_8){ - modify_field(pkt.field_c_32, param_c_32); - modify_field(pkt.field_g_16, param_g_16); - modify_field(pkt.field_k_8, param_k_8); -} - -action action_7(param_c_32, param_d_32, param_h_16, param_l_8, param_a_32, param_e_16){ - modify_field(pkt.field_c_32, param_c_32); - modify_field(pkt.field_d_32, param_d_32); - modify_field(pkt.field_h_16, param_h_16); - modify_field(pkt.field_l_8, param_l_8); - modify_field(pkt.field_a_32, param_a_32, 0xffcf); - modify_field(pkt.field_e_16, param_e_16, 0xfcff); -} - -action action_8(param_i_8, param_j_8, param_k_8){ - modify_field(pkt.field_i_8, param_i_8); - modify_field(pkt.field_j_8, param_j_8); - modify_field(pkt.field_k_8, param_k_8); -} - -action action_9(param_e_16, param_f_16, param_g_16){ - modify_field(pkt.field_e_16, param_e_16); - modify_field(pkt.field_f_16, param_f_16); - modify_field(pkt.field_g_16, param_g_16); -} - -action action_10(param_a_32, param_b_32, param_c_32, param_d_32){ - modify_field(pkt.field_a_32, param_a_32); - modify_field(pkt.field_b_32, param_b_32); - modify_field(pkt.field_c_32, param_c_32); - modify_field(pkt.field_d_32, param_d_32); -} - -action action_11(param_a_32, param_b_32, param_c_32, param_e_16, param_f_16, - param_g_16, param_i_8, param_j_8, param_k_8, param_l_8){ - modify_field(pkt.field_a_32, param_a_32); - modify_field(pkt.field_b_32, param_b_32); - modify_field(pkt.field_c_32, param_c_32); - modify_field(pkt.field_e_16, param_e_16); - modify_field(pkt.field_f_16, param_f_16); - modify_field(pkt.field_g_16, param_g_16); - modify_field(pkt.field_i_8, param_i_8); - modify_field(pkt.field_j_8, param_j_8); - modify_field(pkt.field_k_8, param_k_8); - modify_field(pkt.field_l_8, param_l_8); -} - -action action_12(param_a_32, param_b_32, param_c_32, param_i_8, param_j_8, param_k_8, param_l_8){ - modify_field(pkt.field_a_32, param_a_32, 0xffcf); - modify_field(pkt.field_b_32, param_b_32, 0xfcff); - modify_field(pkt.field_c_32, param_c_32); - modify_field(pkt.field_i_8, param_i_8); - modify_field(pkt.field_j_8, param_j_8); - modify_field(pkt.field_k_8, param_k_8); - modify_field(pkt.field_l_8, param_l_8); -} - -action action_13(param_a_32, param_b_32, param_c_32, param_e_16, param_f_16, param_g_16, param_h_16){ - modify_field(pkt.field_a_32, param_a_32, 0xffcf); - modify_field(pkt.field_b_32, param_b_32, 0xfcff); - - modify_field(pkt.field_c_32, param_c_32); - - modify_field(pkt.field_e_16, param_e_16); - modify_field(pkt.field_f_16, param_f_16); - modify_field(pkt.field_g_16, param_g_16); - modify_field(pkt.field_h_16, param_h_16); -} - -action action_14(param_a_32, param_b_32, param_c_32, param_d_32, - param_meta_a_32){ //, param_meta_b_32, param_meta_c_32){ - modify_field(pkt.field_a_32, param_a_32, 0xffcf); - modify_field(pkt.field_b_32, param_b_32, 0xfcff); - modify_field(pkt.field_c_32, param_c_32); - modify_field(pkt.field_d_32, param_d_32); - modify_field(meta.meta_a_32, param_meta_a_32); -} - -action action_15(){ -} - -//@pragma immediate 0 -@pragma action_entries 512 -table table_0 { - reads { - pkt.field_b_32 : exact; - } - actions { - action_0; - action_1; - action_2; - action_3; - action_4; - action_5; - action_6; - action_7; - action_8; - action_9; - action_10; - action_11; - action_12; - action_13; - action_14; - action_15; - } - size : 1024; -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_89_testing_action_data_allocation_3_with_partial_ram.p4 b/backends/tofino/bf-asm/test/internal/test_config_89_testing_action_data_allocation_3_with_partial_ram.p4 deleted file mode 100644 index 7735fde20a7..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_89_testing_action_data_allocation_3_with_partial_ram.p4 +++ /dev/null @@ -1,121 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -header_type meta_t { - fields { - meta_a_32 : 32; - meta_b_32 : 32; - meta_c_32 : 32; - meta_d_32 : 32; - } -} - - -header pkt_t pkt; -metadata meta_t meta; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action nop(){ - no_op(); -} - -//Simple Actions - -action action_0(param_a_32){ - modify_field(pkt.field_a_32, param_a_32); -} - -action action_1(param_e_16){ - modify_field(pkt.field_e_16, param_e_16); -} - -action action_2(param_i_8){ - modify_field(pkt.field_i_8, param_i_8); -} - - -// Partial field modifications - -action action_3(param_a_32){ - modify_field(pkt.field_a_32, param_a_32, 0xffff); -} - -action action_4(param_e_16){ - modify_field(pkt.field_e_16, param_e_16, 0xff); -} - -action action_5(param_a_32, param_e_16){ - modify_field(pkt.field_a_32, param_a_32, 0xffff0000); - modify_field(pkt.field_e_16, param_e_16, 0xff); -} - -action action_6(param_b_32, param_f_16){ - modify_field(pkt.field_b_32, param_b_32, 0xfff00000); - modify_field(pkt.field_f_16, param_f_16, 0xff00); -} - - -action action_15(){ -} - -@pragma immediate 0 -table table_0 { - reads { - pkt.field_b_32 : exact; - } - actions { -/* - action_0; - action_1; - action_2; - action_3; - action_4; - action_5; - action_6; -*/ -/* - - action_7; - action_8; - action_9; - action_10; - action_11; - action_12; - action_13; - action_14; -*/ - action_15; - } - size : 1024; -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_8_next_table.BUG b/backends/tofino/bf-asm/test/internal/test_config_8_next_table.BUG deleted file mode 100644 index 1c6d976c57e..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_8_next_table.BUG +++ /dev/null @@ -1,175 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -action action_0(){ - modify_field(ipv4.diffserv, 1); -} - -action action_1() { - modify_field(ipv4.totalLen, 2); -} - -action action_2() { - modify_field(ipv4.identification, 3); -} - -action action_3(param_3) { - modify_field(ipv4.ttl, param_3); -} - -action action_4(param_4) { - modify_field(ipv4.protocol, param_4); -} - -action do_nothing(){ - no_op(); -} - - -table table_0_ways_6_pack_3 { - reads { - ethernet.etherType : exact; - } - actions { - action_0; - do_nothing; - } - max_size : 4096; -} - -table table_1 { - reads { - ipv4.srcAddr : exact; - } - actions { - action_1; - do_nothing; - } - max_size : 4096; -} - -table table_2 { - reads { - ipv4.dstAddr : exact; - } - actions { - action_2; - do_nothing; - } - max_size : 4096; -} - -table table_3 { - reads { - ipv4.srcAddr : exact; - ipv4.dstAddr : exact; - } - actions { - action_3; - do_nothing; - } - max_size : 4096; -} - -table table_4 { - reads { - ethernet.dstAddr : exact; - } - actions { - action_4; - do_nothing; - } - max_size : 4096; -} - - - -/* Main control flow */ - -control ingress { - apply(table_0_ways_6_pack_3){ - hit { - apply(table_1); - } - miss { - if (valid(ipv4)){ - apply(table_2); - if (valid(ethernet)){ - apply(table_3); - } - } - } - } - apply(table_4); -} - - -/* -control ingress { - apply(table_0){ - action_0 { - apply(table_1); - } - do_nothing { - if (valid(ipv4)){ - apply(table_2); - } - } - } - apply(table_4); -} -*/ diff --git a/backends/tofino/bf-asm/test/internal/test_config_90_testing_action_data_allocation_3_with_fields_in_overhead.p4 b/backends/tofino/bf-asm/test/internal/test_config_90_testing_action_data_allocation_3_with_fields_in_overhead.p4 deleted file mode 100644 index fe5734e052c..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_90_testing_action_data_allocation_3_with_fields_in_overhead.p4 +++ /dev/null @@ -1,121 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -header_type meta_t { - fields { - meta_a_32 : 32; - meta_b_32 : 32; - meta_c_32 : 32; - meta_d_32 : 32; - } -} - - -header pkt_t pkt; -metadata meta_t meta; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action nop(){ - no_op(); -} - -//Simple Actions - -action action_0(param_a_32){ - modify_field(pkt.field_a_32, param_a_32, 0xfff00000); -} - -action action_1(param_e_16){ - modify_field(pkt.field_e_16, param_e_16); -} - -action action_2(param_i_8){ - modify_field(pkt.field_i_8, param_i_8); -} - - -// Partial field modifications - -action action_3(param_a_32){ - modify_field(pkt.field_a_32, param_a_32, 0xffff); -} - -action action_4(param_e_16){ - modify_field(pkt.field_e_16, param_e_16, 0xff); -} - -action action_5(param_a_32, param_e_16){ - modify_field(pkt.field_a_32, param_a_32, 0xffff0000); - modify_field(pkt.field_e_16, param_e_16, 0xff); -} - -action action_6(param_b_32, param_f_16){ - modify_field(pkt.field_b_32, param_b_32, 0xfff00000); - modify_field(pkt.field_f_16, param_f_16, 0xff00); -} - - -action action_15(){ -} - -table table_0 { - reads { - pkt.field_b_32 : exact; - } - actions { - action_0; - action_1; - action_2; -/* - action_3; - - action_4; - action_5; - action_6; - -/* - - action_7; - action_8; - action_9; - action_10; - action_11; - action_12; - action_13; - action_14; -*/ - action_15; - } - size : 1024; -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_91_gateway_with_split_table.p4 b/backends/tofino/bf-asm/test/internal/test_config_91_gateway_with_split_table.p4 deleted file mode 100644 index a54bfaab5dc..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_91_gateway_with_split_table.p4 +++ /dev/null @@ -1,77 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -header_type meta_t { - fields { - meta_a_32 : 32; - meta_b_32 : 32; - meta_c_32 : 32; - meta_d_32 : 32; - } -} - - -header pkt_t pkt; -metadata meta_t meta; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action nop(){ - no_op(); -} - -//Simple Actions - -action action_0(param_a_32){ - modify_field(pkt.field_a_32, param_a_32); -} - - -action action_15(){ -} - -table table_0 { - reads { - pkt.field_a_32 : exact; - pkt.field_b_32 : exact; - pkt.field_c_32 : exact; - pkt.field_e_16 : exact; - } - actions { - action_0; - action_15; - } - size : 200000; -} - -control ingress { - if (valid(pkt)){ - apply(table_0); - } -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_92_bit_xor_10_bits.p4 b/backends/tofino/bf-asm/test/internal/test_config_92_bit_xor_10_bits.p4 deleted file mode 100644 index 8d8f8295127..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_92_bit_xor_10_bits.p4 +++ /dev/null @@ -1,56 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_16 : 16; - } -} - -header_type meta_t { - fields { - field_a_10 : 10; - field_b_10 : 10; - } -} - -header pkt_t pkt; -metadata meta_t meta; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - return ingress; -} - - -action nop(){ - no_op(); -} - -action action_0(){ - bit_xor(meta.field_a_10, meta.field_a_10, meta.field_b_10); -} - - -action action_15(){ -} - -//@pragma pa_atomic ingress meta.field_a_10 meta.field_b_10 -table table_0 { - reads { - pkt.field_a_32 : ternary; - } - actions { - action_0; - action_15; - } - size : 1024; -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_93_push_and_pop.p4 b/backends/tofino/bf-asm/test/internal/test_config_93_push_and_pop.p4 deleted file mode 100644 index 48e29ed3fd6..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_93_push_and_pop.p4 +++ /dev/null @@ -1,71 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -header_type tags_t { - fields { - field_a_8 : 8; - field_b_12 : 12; - field_c_4 : 4; - field_d_8 : 8; - } -} - - - -header pkt_t pkt; -header tags_t tags[5]; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - extract(tags[0]); - return ingress; -} - - -action nop(){ - no_op(); -} - -action push_action(){ - push(tags, 3); -} - -action pop_action(){ - pop(tags, 4); -} -table table_0 { - reads { - pkt.field_a_32 : exact; - } - actions { - push_action; - pop_action; - } - size : 1024; -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_94_action_constant_alignment.p4 b/backends/tofino/bf-asm/test/internal/test_config_94_action_constant_alignment.p4 deleted file mode 100644 index 009888d79a6..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_94_action_constant_alignment.p4 +++ /dev/null @@ -1,75 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type pkt_t { - fields { - - field_x_12 : 12; - field_x_4 : 4; - field_x_16 : 16; - - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -header_type tags_t { - fields { - field_a_8 : 8; - field_b_12 : 12; - field_c_4 : 4; - field_d_8 : 8; - } -} - - - -header pkt_t pkt; -header tags_t tags[5]; - -parser start { - return parse_test; -} - -parser parse_test { - extract(pkt); - extract(tags[0]); - return ingress; -} - - -action nop(){ - no_op(); -} - -action action_0(){ - modify_field(pkt.field_x_12, 0xfff); - modify_field(pkt.field_x_4, 0); -} - - -@pragma immediate 0 -table table_0 { - reads { - pkt.field_a_32 : ternary; - } - actions { - action_0; - } - size : 1024; -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_95_first_meter_table.NOT_READY b/backends/tofino/bf-asm/test/internal/test_config_95_first_meter_table.NOT_READY deleted file mode 100644 index ebd7b10780b..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_95_first_meter_table.NOT_READY +++ /dev/null @@ -1,105 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - color_0 : 8; - color_1 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -meter meter_0 { - type : bytes; - static : table_0; - result : pkt.color_0; - instance_count : 7000; -} - - -meter meter_1 { - type : bytes; - static : table_1; - result : pkt.color_1; - instance_count : 500; -} - - -action action_0(param0){ - //modify_field(pkt.field_f_16, param0); - execute_meter(meter_0, 7, pkt.color_0); -} - - -action action_1(param0){ - //modify_field(pkt.field_g_16, param0); - execute_meter(meter_1, 7, pkt.color_1); -} - - -action do_nothing(){ - no_op(); -// drop(); -} - - - -@pragma include_idletime 1 -@pragma pa_solitare meter_result.color_0, meter_result.color_1 -@pragma include_stash 1 -table table_0 { - reads { - pkt.field_e_16 : ternary; - pkt.color_0 : exact; //HACK - pkt.color_1 : exact; //HACK - } - actions { - action_0; -// do_nothing; - } - size : 7000; -} - - -@pragma include_idletime 1 -@pragma idletime_two_way_notification 1 -table table_1 { - reads { - pkt.field_e_16: exact; - } - actions { -// do_nothing; - action_1; - } -} - - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_1); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_96_hash_data.p4 b/backends/tofino/bf-asm/test/internal/test_config_96_hash_data.p4 deleted file mode 100644 index 1352506b7fb..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_96_hash_data.p4 +++ /dev/null @@ -1,171 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_28 : 28; - field_a2_4 : 4; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -parser start { - return parse_pkt; -} - -header pkt_t pkt; - -parser parse_pkt { - extract(pkt); - return ingress; -} - - - - -field_list field_list_0 { - pkt.field_a_28; - pkt.field_b_32; - pkt.field_i_8; -} - -field_list field_list_1 { - pkt.field_c_32; - pkt.field_g_16; - pkt.field_h_16; - pkt.field_k_8; -} - -field_list field_list_2 { - pkt.field_d_32; - pkt.field_l_8; - pkt.field_c_32; - pkt.field_e_16; - pkt.field_f_16; -} - -field_list_calculation hash_0 { - input { - field_list_0; - } - algorithm : crc32; - output_width : 32; -} - -field_list_calculation hash_1 { - input { - field_list_1; - } - algorithm : crc16; - output_width : 16; -} - -field_list_calculation hash_2 { - input { - field_list_2; - } - algorithm : random; - output_width : 72; -} - -action action_0(param0){ - modify_field(pkt.field_e_16, param0); - modify_field_with_hash_based_offset(pkt.field_a_28, 0, hash_0, 16384); -} - -action action_1(){ - modify_field_with_hash_based_offset(pkt.field_l_8, 0, hash_1, 256); -} - -action action_2(param0){ - modify_field(pkt.field_h_16, param0); -} - - -action do_nothing(){ - no_op(); -} - - -@pragma include_idletime 1 -@pragma idletime_precision 1 -table table_0 { - reads { - pkt.field_a_28 : exact; - } - actions { - action_0; - } -} - - -@pragma ways 8 -@pragma include_idletime 1 -table table_1 { - reads { - pkt.field_c_32 : exact; - pkt.field_d_32 : exact; - - pkt.field_f_16 : exact; - pkt.field_g_16 : exact; - pkt.field_h_16 : exact; - } - actions { - action_1; - do_nothing; - } - size : 2048; -} - -@pragma selector_max_group_size 121 -@pragma include_idletime 1 -@pragma idletime_sweep_interval 12 -table table_2 { - reads { - pkt.field_b_32 : ternary;//exact; - } - action_profile : table_2_action_profile; - size : 2048; -} - -action_profile table_2_action_profile { - actions { - action_2; - do_nothing; - } - size : 512; - dynamic_action_selection : table_2_selector; -} - -action_selector table_2_selector { - selection_key : hash_2; -} - - - -/* Main control flow */ - -control ingress { - if (valid(pkt)){ - apply(table_0); - } - - if (valid(pkt)){ - apply(table_1); - } - - - apply(table_2); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_97_unrelated_tables.p4 b/backends/tofino/bf-asm/test/internal/test_config_97_unrelated_tables.p4 deleted file mode 100644 index 0709ae4eefe..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_97_unrelated_tables.p4 +++ /dev/null @@ -1,94 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_28 : 28; - field_a2_4 : 4; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -parser start { - return parse_pkt; -} - -header pkt_t pkt; - -parser parse_pkt { - extract(pkt); - return ingress; -} - - -action action_0(param0){ - modify_field(pkt.field_b_32, param0); -} - -action action_1(param0){ - modify_field(pkt.field_c_32, param0); -} - -action action_2(param0){ - modify_field(pkt.field_d_32, param0); -} - -action do_nothing(){ - no_op(); -} - -table table_0 { - reads { - pkt.field_e_16 : exact; - } - actions { - action_0; - } - size : 200000; -} - -table table_1 { - reads { - pkt.field_f_16 : exact; - } - actions { - action_1; - } -} - -table table_2 { - reads { - pkt.field_g_16 : exact; - } - actions { - action_2; - } -} - - -/* Main control flow */ - -control ingress { - if (valid(pkt)){ - apply(table_0); - apply(table_1); - } -/* - if (valid(pkt)){ - apply(table_1); - } -*/ - apply(table_2); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_98_multiple_control_flow.p4 b/backends/tofino/bf-asm/test/internal/test_config_98_multiple_control_flow.p4 deleted file mode 100644 index b4b2f8779b9..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_98_multiple_control_flow.p4 +++ /dev/null @@ -1,103 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_28 : 28; - field_a2_4 : 4; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -parser start { - return parse_pkt; -} - -header pkt_t pkt; - -parser parse_pkt { - extract(pkt); - return ingress; -} - - -action action_0(param0){ - modify_field(pkt.field_b_32, param0); -} - -action action_1(param0){ - modify_field(pkt.field_c_32, param0); -} - -action action_2(param0){ - modify_field(pkt.field_d_32, param0); -} - -action do_nothing(){ - no_op(); -} - -table table_0 { - reads { - pkt.field_e_16 : exact; - } - actions { - action_0; - } -} - -table table_1 { - reads { - pkt.field_f_16 : exact; - } - actions { - action_1; - } -} - -table table_2 { - reads { - pkt.field_g_16 : exact; - } - actions { - action_2; - } -} - -table table_3 { - reads { - pkt.field_g_16 : exact; - } - actions { - do_nothing; - } -} - -/* Main control flow */ - -control ingress { - apply(table_0); - pipe_0(); -} - -control pipe_0 { - apply(table_1); -// pipe_1(); -} - -control egress { - apply(table_2); - apply(table_3); -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_99_share_exact_match_key.p4 b/backends/tofino/bf-asm/test/internal/test_config_99_share_exact_match_key.p4 deleted file mode 100644 index 6f9e0141cc2..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_99_share_exact_match_key.p4 +++ /dev/null @@ -1,91 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - field_k_8 : 8; - field_l_8 : 8; - } -} - -parser start { - return parse_pkt; -} - -header pkt_t pkt; - -parser parse_pkt { - extract(pkt); - return ingress; -} - - -action action_0(param0){ - modify_field(pkt.field_d_32, param0); -} - -action action_1(param0){ - modify_field(pkt.field_h_16, param0); -} - -action do_nothing(){ - no_op(); -} - -table table_0 { - reads { - pkt.field_a_32 : ternary; - pkt.field_b_32 : exact; - pkt.field_e_16 : exact; - pkt.field_f_16 : exact; - pkt.field_i_8 : exact; - } - actions { - action_0; - } - size : 512; - //size : 4096; -} - -@pragma include_idletime 1 -table table_1 { - reads { - pkt.field_a_32 : exact; - pkt.field_e_16 : exact; - pkt.field_b_32 : exact; - pkt.field_f_16 : exact; - //pkt.field_i_8 : exact; - - pkt.field_c_32 : exact; - pkt.field_g_16 : exact; - pkt.field_j_8 : exact; - pkt.field_k_8 : exact; - - } - actions { - action_1; - } - size : 1024; - //size : 8192; -} - -/* Main control flow */ - -control ingress { - if (valid(pkt)){ - apply(table_0); - apply(table_1); - } -} diff --git a/backends/tofino/bf-asm/test/internal/test_config_9_no_ternary_indirection.p4 b/backends/tofino/bf-asm/test/internal/test_config_9_no_ternary_indirection.p4 deleted file mode 100644 index 057a337355a..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_config_9_no_ternary_indirection.p4 +++ /dev/null @@ -1,92 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -action action_0(param_0){ - modify_field(ipv4.diffserv, param_0); -} - -action action_1(){ - modify_field(ipv4.totalLen, 1); -} - -table table_0 { - reads { - ethernet.etherType : ternary; - } - actions { - action_0; - } - max_size : 4096; -} - -table table_1 { - reads { - ethernet.etherType : ternary; - } - actions { - action_1; - } - max_size : 4096; -} - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_1); -} - diff --git a/backends/tofino/bf-asm/test/internal/test_tp_1_one_table_spill.p4 b/backends/tofino/bf-asm/test/internal/test_tp_1_one_table_spill.p4 deleted file mode 100644 index 9e746eb9546..00000000000 --- a/backends/tofino/bf-asm/test/internal/test_tp_1_one_table_spill.p4 +++ /dev/null @@ -1,104 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -action action_0(param0){ - modify_field(ipv4.diffserv, param0); -} - -action action_1(param1){ - modify_field(ipv4.hdrChecksum, param1); -} - -action action_e(param2, param_3){ - modify_field(ipv4.diffserv, param2); - modify_field(ipv4.hdrChecksum, param_3); -} - -table table_0 { - reads { - ipv4.dstAddr: lpm; - } - actions { - action_0; - action_1; - } - //max_size : 32768; -} - -table table_1 { - reads { - ipv4.dstAddr: exact; - ipv4.protocol: exact; - } - actions { - action_1; - } -} - -table table_e { - reads { - ipv4.srcAddr: exact; - ipv4.diffserv: exact; - } - actions { - action_e; - } -} - -/* Main control flow */ - -control ingress { - apply(table_0); - apply(table_1); -} - - -control egress { - apply(table_e); -} diff --git a/backends/tofino/bf-asm/test/internal/vk_basic_ipv4.PHV_BUG b/backends/tofino/bf-asm/test/internal/vk_basic_ipv4.PHV_BUG deleted file mode 100644 index b0ca5faf362..00000000000 --- a/backends/tofino/bf-asm/test/internal/vk_basic_ipv4.PHV_BUG +++ /dev/null @@ -1,629 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm: csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop_ipv4(egress_port /*,srcmac, dstmac*/) { - hop(ipv4.ttl, egress_port); -// modify_field(ethernet.srcAddr, srcmac); -// modify_field(ethernet.dstAddr, dstmac); -} - -action drop_ipv4 () { - drop(); -} - -action next_hop_ipv4(egress_port, srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action mod_mac_adr(egress_port, srcmac, dstmac) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action udp_hdr_add (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - add_header(udp); - modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); - add_to_field(ipv4.totalLen, 8); -} - -action udp_set_dest(port) { - modify_field(udp.dstPort, port); -} -action udp_set_src(port) { - modify_field(udp.srcPort, port); -} - -action tcp_hdr_rm (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - remove_header(tcp); - modify_field(ipv4.protocol, 0); -// add_to_field(ipv4.totalLen, -20); -// modify_field(ipv4.totalLen, 66); -} - -action modify_tcp_dst_port_1(dstPort, egress_port) { - modify_field(tcp.dstPort, dstPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ipv4.srcAddr, ipAddr); - modify_field(ethernet.dstAddr, dstAddr); - modify_field(tcp.dstPort, tcpPort); -} - -action custom_action_2(egress_port, ipAddr, tcpPort) -{ - modify_field(ipv4.srcAddr, ipAddr); - modify_field(tcp.dstPort, tcpPort); - hop(ipv4.ttl, egress_port); -} - -action custom_action_3(egress_port, dstAddr, dstIp) -{ - modify_field(ipv4.dstAddr, dstIp); - modify_field(ethernet.dstAddr, dstAddr); - hop(ipv4.ttl, egress_port); -} - -action modify_l2 (egress_port, srcAddr, dstAddr) { - // Trying for 128 bit action data - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcAddr); - modify_field(ethernet.dstAddr, dstAddr); -} - - - -@pragma immediate 1 -@pragma stage 0 -table ig_udp { - reads { - ethernet : valid; - ipv4 : valid; - udp : valid; - udp.dstPort : ternary; - } - actions { - nop; - udp_set_dest; - } -} -@pragma immediate 1 -@pragma stage 0 -table eg_udp { - reads { - ethernet : valid; - ipv4 : valid; - udp : valid; - udp.srcPort : exact; - } - actions { - nop; - udp_set_src; - } -} - -@pragma immediate 1 -@pragma stage 0 -table ipv4_routing { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - hop_ipv4; - drop_ipv4; - } -} - -@pragma immediate 1 -@pragma stage 0 -@pragma ways 3 -@pragma pack 5 -table ipv4_routing_exm_ways_3_pack_5 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - modify_tcp_dst_port_1; - } -} - - -@pragma immediate 1 -@pragma stage 1 -@pragma ways 3 -@pragma pack 3 -table ipv4_routing_exm_ways_3_pack_3 { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - custom_action_1; - } -} - -@pragma immediate 1 -@pragma stage 1 -@pragma ways 4 -@pragma pack 3 -table ipv4_routing_exm_ways_4_pack_3_stage_1 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma immediate 1 -@pragma stage 1 -table ipv4_routing_stage_1 { - reads { - ipv4.dstAddr : lpm; - ipv4.srcAddr : exact; - } - actions { - nop; - hop_ipv4; - } - size : 1024; -} - -@pragma stage 2 -table tcam_tbl_stage_2 { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - mod_mac_adr; - } -} - -@pragma stage 2 -@pragma ways 4 -@pragma pack 7 -table ipv4_routing_exm_ways_4_pack_7_stage_2 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - tcp.dstPort : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -@pragma immediate 1 -@pragma stage 3 -@pragma ways 5 -@pragma pack 3 -table ipv4_routing_exm_ways_5_pack_3_stage_3 { - reads { - ipv4.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma immediate 1 -@pragma stage 3 -table udp_add_tbl_stage_3 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - udp_hdr_add; - } -} - -@pragma immediate 1 -@pragma stage 4 -@pragma ways 6 -@pragma pack 3 -table ipv4_routing_exm_ways_6_pack_3_stage_4 { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - - -@pragma immediate 1 -@pragma stage 4 -table tcp_rm_tbl_stage_4 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - tcp_hdr_rm; - } -} - -@pragma immediate 1 -@pragma stage 5 -@pragma ways 3 -@pragma pack 4 -table ipv4_routing_exm_ways_3_pack_4_stage_5 { - reads { - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - modify_tcp_dst_port_1; - } -} - -@pragma stage 6 -@pragma ways 4 -@pragma pack 4 -table ipv4_routing_exm_ways_4_pack_4_stage_6 { - reads { - ethernet.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma immediate 1 -@pragma stage 7 -@pragma ways 5 -@pragma pack 4 -table ipv4_routing_exm_ways_5_pack_4_stage_7 { - reads { - ipv4.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - -@pragma immediate 1 -@pragma stage 8 -table tcam_adt_deep_stage_8 { - reads { - ethernet.srcAddr : ternary; - ethernet.dstAddr : ternary; - ipv4.srcAddr : ternary; - ipv4.dstAddr : ternary; - } - actions { - nop; - modify_l2; - } - size : 2048; -} - -@pragma stage 8 -@pragma ways 4 -@pragma pack 5 -table ipv4_routing_exm_ways_4_pack_5_stage_8 { - reads { - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.srcPort : exact; - tcp.dstPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -@pragma stage 9 -table ipv4_routing_select { - reads { - ipv4.dstAddr: lpm; - } - action_profile : ecmp_action_profile; - size : 512; -} - -field_list ecmp_hash_fields { - ipv4.srcAddr; - ipv4.dstAddr; - ipv4.identification; - ipv4.protocol; -} - -field_list_calculation ecmp_hash { - input { - ecmp_hash_fields; - } - algorithm : crc16; - output_width : 10; -} - -action_profile ecmp_action_profile { - actions { - nhop_set; - nop; - } - size : 1024; - // optional - dynamic_action_selection : ecmp_selector; -} - -action_selector ecmp_selector { - selection_key : ecmp_hash; // take a field_list_calculation only - // optional - selection_mode : resilient; // “resilient” or “non-resilient” -} - -action nhop_set(port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -@pragma stage 10 -table tcam_indirect_action { - reads { - ethernet.srcAddr : ternary; - ethernet.dstAddr : ternary; - ethernet.etherType: exact; - ipv4.srcAddr : ternary; - ipv4.dstAddr : ternary; - ipv4.protocol : exact; - ipv4.version : exact; - } - action_profile : indirect_action_profile; - size : 3072; -} - -action modify_ip_id(port, id, srcAddr, dstAddr) { - modify_field(ipv4.identification, id); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); - modify_field(ethernet.srcAddr, srcAddr); - modify_field(ethernet.dstAddr, dstAddr); -} - -action_profile indirect_action_profile { - actions { - nop; - modify_ip_id; - } - size : 2048; -} - -@pragma stage 11 -@pragma ways 6 -@pragma pack 4 -table ipv4_routing_exm_ways_6_pack_4_stage_11 { - reads { - ipv4.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - - -/* Main control flow */ -control ingress { - /* A general principle : Always keep the exact match tables ahead of the - * ternary tables in the same stage, except first stage. Logic relating to next-table - * will cause the Tofino model not to launch a lookup on th exact match - * tables if the order is reversed. - */ - apply(ig_udp); - apply(ipv4_routing); - apply(ipv4_routing_exm_ways_3_pack_5); - apply(ipv4_routing_exm_ways_3_pack_3); - apply(ipv4_routing_exm_ways_4_pack_3_stage_1); - apply(ipv4_routing_stage_1); - apply(tcam_tbl_stage_2); - apply(ipv4_routing_exm_ways_4_pack_7_stage_2); - apply(ipv4_routing_exm_ways_5_pack_3_stage_3); - /* Gateway not yet supported */ -// if (ipv4.protocol == 0) { - apply(udp_add_tbl_stage_3); -// } - apply(ipv4_routing_exm_ways_6_pack_3_stage_4); -// if (valid(tcp)) { - apply(tcp_rm_tbl_stage_4); -// } - apply(ipv4_routing_exm_ways_3_pack_4_stage_5); - apply(ipv4_routing_exm_ways_4_pack_4_stage_6); - apply(ipv4_routing_exm_ways_5_pack_4_stage_7); - apply(tcam_adt_deep_stage_8); - apply(ipv4_routing_exm_ways_4_pack_5_stage_8); - // Stage 9 - Please use caution before adding any more tables in stage 9 - // Poor man's selector may not work - apply(ipv4_routing_select); - // Stage 10 - apply(tcam_indirect_action); - // Stage 11 -} - -control egress { - apply(eg_udp); - apply(ipv4_routing_exm_ways_6_pack_4_stage_11); -} diff --git a/backends/tofino/bf-asm/test/internal/vk_basic_ipv4_20150706.p4 b/backends/tofino/bf-asm/test/internal/vk_basic_ipv4_20150706.p4 deleted file mode 100644 index 991f3d2fd0f..00000000000 --- a/backends/tofino/bf-asm/test/internal/vk_basic_ipv4_20150706.p4 +++ /dev/null @@ -1,707 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - learn_meta_1:20; - learn_meta_2:24; - learn_meta_3:25; - learn_meta_4:10; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm : csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -field_list learn_1 { - ipv4.ihl; - ipv4.protocol; - ipv4.srcAddr; - ethernet.srcAddr; - ethernet.dstAddr; - ipv4.fragOffset; - ipv4.identification; - routing_metadata.learn_meta_1; - routing_metadata.learn_meta_4; -} - -action learn_1 (learn_meta_1, learn_meta_4) { - generate_digest(FLOW_LRN_DIGEST_RCVR, learn_1); - modify_field(routing_metadata.learn_meta_1, learn_meta_1); - modify_field(routing_metadata.learn_meta_4, learn_meta_4); -} - -field_list learn_2 { - ipv4.ihl; - ipv4.identification; - ipv4.protocol; - ipv4.srcAddr; - ethernet.srcAddr; - ethernet.dstAddr; - ipv4.fragOffset; - routing_metadata.learn_meta_2; - routing_metadata.learn_meta_3; -} - -action learn_2 (learn_meta_2, learn_meta_3) { - generate_digest(FLOW_LRN_DIGEST_RCVR, learn_2); - modify_field(routing_metadata.learn_meta_2, learn_meta_2); - modify_field(routing_metadata.learn_meta_3, learn_meta_3); -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop_ipv4(egress_port /*,srcmac, dstmac*/) { - hop(ipv4.ttl, egress_port); -// modify_field(ethernet.srcAddr, srcmac); -// modify_field(ethernet.dstAddr, dstmac); -} - -action drop_ipv4 () { - drop(); -} - -action next_hop_ipv4(egress_port, srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action mod_mac_adr(egress_port, srcmac, dstmac) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action udp_hdr_add (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - add_header(udp); - modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); - add_to_field(ipv4.totalLen, 8); -} - -action udp_set_dest(port) { - modify_field(udp.dstPort, port); -} -action udp_set_src(port) { - modify_field(udp.srcPort, port); -} - -action tcp_hdr_rm (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - remove_header(tcp); - modify_field(ipv4.protocol, 0); -// add_to_field(ipv4.totalLen, -20); -// modify_field(ipv4.totalLen, 66); -} - -action modify_tcp_dst_port_1(dstPort, egress_port) { - modify_field(tcp.dstPort, dstPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ipv4.srcAddr, ipAddr); - modify_field(ethernet.dstAddr, dstAddr); - modify_field(tcp.dstPort, tcpPort); -} - -action custom_action_2(egress_port, ipAddr, tcpPort) -{ - modify_field(ipv4.srcAddr, ipAddr); - modify_field(tcp.dstPort, tcpPort); - hop(ipv4.ttl, egress_port); -} - -action custom_action_3(egress_port, dstAddr, dstIp) -{ - modify_field(ipv4.dstAddr, dstIp); - modify_field(ethernet.dstAddr, dstAddr); - hop(ipv4.ttl, egress_port); -} - -action modify_l2 (egress_port, srcAddr, dstAddr, tcp_sport, tcp_dport) { - // Trying for >128 bit action data - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcAddr); - modify_field(ethernet.dstAddr, dstAddr); - modify_field(tcp.dstPort, tcp_dport); - modify_field(tcp.srcPort, tcp_sport); -} - -@pragma immediate 1 -@pragma stage 0 -table ig_udp { - reads { - ethernet : valid; - ipv4 : valid; - udp : valid; - udp.dstPort : ternary; - } - actions { - nop; - udp_set_dest; - } -} -@pragma immediate 1 -@pragma stage 0 -table eg_udp { - reads { - ethernet : valid; - ipv4 : valid; - udp : valid; - udp.srcPort : exact; - } - actions { - nop; - udp_set_src; - } -} - -@pragma immediate 1 -@pragma stage 0 -table ipv4_routing { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - hop_ipv4; - drop_ipv4; - learn_1; - learn_2; - } - size : 512; -} - -@pragma immediate 1 -@pragma stage 0 -@pragma ways 3 -@pragma pack 5 -table ipv4_routing_exm_ways_3_pack_5 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - modify_tcp_dst_port_1; - } -} - - -@pragma immediate 1 -@pragma stage 1 -@pragma ways 3 -@pragma pack 3 -table ipv4_routing_exm_ways_3_pack_3 { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - custom_action_1; - } -} - -@pragma immediate 1 -@pragma stage 1 -@pragma ways 4 -@pragma pack 3 -table ipv4_routing_exm_ways_4_pack_3_stage_1 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma immediate 1 -@pragma stage 1 -table ipv4_routing_stage_1 { - reads { - ipv4.dstAddr : lpm; - ipv4.srcAddr : exact; - } - actions { - nop; - hop_ipv4; - } - size : 1024; -} - -@pragma stage 2 -table tcam_tbl_stage_2 { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - mod_mac_adr; - } -} - -@pragma stage 2 -@pragma ways 4 -@pragma pack 7 -table ipv4_routing_exm_ways_4_pack_7_stage_2 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - tcp.dstPort : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -@pragma immediate 1 -@pragma stage 3 -@pragma ways 5 -@pragma pack 3 -table ipv4_routing_exm_ways_5_pack_3_stage_3 { - reads { - ipv4.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma immediate 1 -@pragma stage 3 -table udp_add_tbl_stage_3 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - udp_hdr_add; - } -} - -@pragma immediate 1 -@pragma stage 4 -@pragma ways 6 -@pragma pack 3 -table ipv4_routing_exm_ways_6_pack_3_stage_4 { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - - -@pragma immediate 1 -@pragma stage 4 -table tcp_rm_tbl_stage_4 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - tcp_hdr_rm; - } -} - -@pragma immediate 1 -@pragma stage 5 -@pragma ways 3 -@pragma pack 4 -table ipv4_routing_exm_ways_3_pack_4_stage_5 { - reads { - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - modify_tcp_dst_port_1; - } -} - -@pragma stage 6 -@pragma ways 4 -@pragma pack 4 -table ipv4_routing_exm_ways_4_pack_4_stage_6 { - reads { - ethernet.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma immediate 1 -@pragma stage 7 -@pragma ways 5 -@pragma pack 4 -table ipv4_routing_exm_ways_5_pack_4_stage_7 { - reads { - ipv4.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - -@pragma immediate 1 -@pragma stage 8 -table tcam_adt_deep_stage_8 { - reads { - ethernet.srcAddr : ternary; - ethernet.dstAddr : ternary; - ipv4.srcAddr : ternary; - ipv4.dstAddr : ternary; - } - actions { - nop; - modify_l2; - } - size : 3072; -} - -@pragma stage 8 -@pragma ways 4 -@pragma pack 5 -table ipv4_routing_exm_ways_4_pack_5_stage_8 { - reads { - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.srcPort : exact; - tcp.dstPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -@pragma stage 9 -table ipv4_routing_select { - reads { - ipv4.dstAddr: lpm; - } - action_profile : ecmp_action_profile; - size : 512; -} - -field_list ecmp_hash_fields { - ipv4.srcAddr; - ipv4.dstAddr; - ipv4.identification; - ipv4.protocol; -} - -field_list_calculation ecmp_hash { - input { - ecmp_hash_fields; - } - algorithm : crc16; - output_width : 10; -} - -action_profile ecmp_action_profile { - actions { - nhop_set; - nop; - } - size : 1024; - // optional - dynamic_action_selection : ecmp_selector; -} - -action_selector ecmp_selector { - selection_key : ecmp_hash; // take a field_list_calculation only - // optional - selection_mode : resilient; // “resilient” or “non-resilient” -} - -action nhop_set(port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -@pragma stage 10 -table tcam_indirect_action { - reads { - ethernet.srcAddr : ternary; - ethernet.dstAddr : ternary; - ethernet.etherType: exact; - ipv4.srcAddr : ternary; - ipv4.dstAddr : ternary; - ipv4.protocol : exact; - ipv4.version : exact; - } - action_profile : indirect_action_profile; - size : 2048; -} - -action modify_ip_id(port, id, srcAddr, dstAddr) { - modify_field(ipv4.identification, id); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); - modify_field(ethernet.srcAddr, srcAddr); - modify_field(ethernet.dstAddr, dstAddr); -} - -action_profile indirect_action_profile { - actions { - nop; - modify_ip_id; - } - size : 1500; -} - -@pragma stage 11 -@pragma ways 6 -@pragma pack 4 -table ipv4_routing_exm_ways_6_pack_4_stage_11 { - reads { - ipv4.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma stage 5 -table tcam_range { - reads { - ipv4.dstAddr : ternary; - tcp.dstPort : range; - } - actions { - nop; - hop_ipv4; - } - size : 1024; -} - - -/* Main control flow */ -control ingress { -#if 0 - /* A general principle : Always keep the exact match tables ahead of the - * ternary tables in the same stage, except first stage. Logic relating to next-table - * will cause the Tofino model not to launch a lookup on th exact match - * tables if the order is reversed. - */ - apply(ig_udp); - apply(ipv4_routing); - apply(ipv4_routing_exm_ways_3_pack_5); - apply(ipv4_routing_exm_ways_3_pack_3); - apply(ipv4_routing_exm_ways_4_pack_3_stage_1); - apply(ipv4_routing_stage_1); - apply(tcam_tbl_stage_2); - apply(ipv4_routing_exm_ways_4_pack_7_stage_2); - apply(ipv4_routing_exm_ways_5_pack_3_stage_3); - /* Gateway not yet supported */ -// if (ipv4.protocol == 0) { - apply(udp_add_tbl_stage_3); -// } - apply(ipv4_routing_exm_ways_6_pack_3_stage_4); -// if (valid(tcp)) { - apply(tcp_rm_tbl_stage_4); -// } - apply(ipv4_routing_exm_ways_3_pack_4_stage_5); - apply(ipv4_routing_exm_ways_4_pack_4_stage_6); - apply(ipv4_routing_exm_ways_5_pack_4_stage_7); - apply(tcam_adt_deep_stage_8); - apply(ipv4_routing_exm_ways_4_pack_5_stage_8); - // Stage 9 - Please use caution before adding any more tables in stage 9 - // Poor man's selector may not work - apply(ipv4_routing_select); - // Stage 10 - apply(tcam_indirect_action); - // Stage 11 -#endif - apply(tcam_range); -} - -control egress { - apply(eg_udp); - // Commenting out since modify of egress port is not possible in egress -// apply(ipv4_routing_exm_ways_6_pack_4_stage_11); -} - diff --git a/backends/tofino/bf-asm/test/internal/vk_basic_ipv4_subset.p4 b/backends/tofino/bf-asm/test/internal/vk_basic_ipv4_subset.p4 deleted file mode 100644 index 8f193301d8d..00000000000 --- a/backends/tofino/bf-asm/test/internal/vk_basic_ipv4_subset.p4 +++ /dev/null @@ -1,189 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm: csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -@pragma stage 10 -table tcam_indirect_action { - reads { - ethernet.srcAddr : ternary; - ethernet.dstAddr : ternary; - ethernet.etherType: exact; - ipv4.srcAddr : ternary; - ipv4.dstAddr : ternary; - ipv4.protocol : exact; - ipv4.version : exact; - } - action_profile : indirect_action_profile; - size : 2048; -} - -action modify_ip_id(port, id, srcAddr, dstAddr) { - modify_field(ipv4.identification, id); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); - modify_field(ethernet.srcAddr, srcAddr); - modify_field(ethernet.dstAddr, dstAddr); -} - -action_profile indirect_action_profile { - actions { - nop; - modify_ip_id; - } - size : 2048; -} - -/* Main control flow */ -control ingress { - if (valid(ipv4)){ - apply(tcam_indirect_action); - } -} - diff --git a/backends/tofino/bf-asm/test/jdiff.sh b/backends/tofino/bf-asm/test/jdiff.sh deleted file mode 100755 index 26274e046d0..00000000000 --- a/backends/tofino/bf-asm/test/jdiff.sh +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/bash - -curdir=`pwd` -json_diff_file="json_diff.txt" - -TRY_BINDIRS=" - $PWD - $PWD/.. - $PWD/../* - $TESTDIR/.. - $TESTDIR/../* -" - -function findbin () { - found="" - if [ -x "$BUILDDIR/$1" ]; then - echo $BUILDDIR/$1 - return - fi - for d in $TRY_BINDIRS; do - if [ -x "$d/$1" ]; then - if [ -z "$found" -o "$d/$1" -nt "$found" ]; then - found="$(cd $d; pwd -P)/$1" - fi - fi - done - if [ -z "$found" ]; then - echo >&2 "Can't find $1 executable" - echo false - exit - else - echo $found - fi -} - -if [ ! -x "$JSON_DIFF" ]; then - JSON_DIFF=$(findbin json_diff) -fi - -if [ -z "$1" ] || [ -z "$2" ]; then - echo "Please specify 2 dirs to diff" - exit 1 -fi - -dir1=$(readlink -f "$1") -dir2=$(readlink -f "$2") -echo "Comparing dir1 vs dir2" -echo "dir1="$dir1 -echo "dir2="$dir2 - -> $json_diff_file -for f1 in $dir1/*.cfg.json*; do - f=$(basename $f1) - f2="$dir2/${f1##*/}" - if [ ! -r $f2 ]; then - ext="${f2##*.}" - if [ "$ext" = "gz" ]; then - f2=${f2%.*} - else - f2="$f2.gz" - fi - fi - if [ ! -r $f2 ]; then - echo "Cannot read file $f2" - continue - fi - echo "Comparing file $(basename $f1) vs $(basename $f2)" - if zcmp -s $f1 $f2; then - continue - elif [ "$f1" = "$dir1/regs.pipe.cfg.json" ]; then - $JSON_DIFF -i mau $f1 $f2 - if [ $? -gt 128 ]; then - echo "***json_diff crashed" - fi - continue - fi - $JSON_DIFF $f1 $f2 >> $json_diff_file -done - -if [ -r $dir1/context.json ]; then - { $JSON_DIFF $CTXT_DIFFARGS $dir1/context.json $dir2/context.json; - if [ $? -gt 128 ]; then echo "***json_diff crashed"; fi; } >> \ - $json_diff_file -fi diff --git a/backends/tofino/bf-asm/test/mac_rewrite.p4 b/backends/tofino/bf-asm/test/mac_rewrite.p4 deleted file mode 100644 index 4d700ede2ab..00000000000 --- a/backends/tofino/bf-asm/test/mac_rewrite.p4 +++ /dev/null @@ -1,149 +0,0 @@ -parser start { - return parse_ethernet; -} - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header ethernet_t ethernet; -#define ETHERTYPE_IPV4 0x0800 -#define ETHERTYPE_IPV6 0x86dd - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - ETHERTYPE_IPV4 : parse_ipv4; - ETHERTYPE_IPV6 : parse_ipv6; - default: ingress; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} -header ipv4_t ipv4; -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -header_type ipv6_t { - fields { - version : 4; - trafficClass : 8; - flowLabel : 20; - payloadLen : 16; - nextHdr : 8; - hopLimit : 8; - srcAddr : 128; - dstAddr : 128; - } -} -header ipv6_t ipv6; - -parser parse_ipv6 { - extract(ipv6); - return ingress; -} - -header_type egress_metadata_t { - fields { - payload_length : 16; /* payload length for tunnels */ - smac_idx : 9; /* index into source mac table */ - bd : 16; /* egress inner bd */ - inner_replica : 1; /* is copy is due to inner replication */ - replica : 1; /* is this a replica */ - mac_da : 48; /* final mac da */ - routed : 1; /* is this replica routed */ - same_bd_check : 16; /* ingress bd xor egress bd */ - - header_count: 4; /* Number of headers */ - - drop_reason : 8; /* drop reason for negative mirroring */ - egress_bypass : 1; /* skip the entire egress pipeline */ - drop_exception : 8; /* MTU check fail, .. */ - } -} -metadata egress_metadata_t egress_metadata; - -action do_setup(idx, routed) { - modify_field(egress_metadata.mac_da, ethernet.dstAddr); - modify_field(egress_metadata.smac_idx, idx); - modify_field(egress_metadata.routed, routed); -} - -table setup { - reads { ethernet: valid; } - actions { do_setup; } -} - -control ingress { - apply(setup); - process_mac_rewrite(); -} - -action nop() { } - -action rewrite_ipv4_unicast_mac(smac) { - modify_field(ethernet.srcAddr, smac); - modify_field(ethernet.dstAddr, egress_metadata.mac_da); - add_to_field(ipv4.ttl, -1); -} - -action rewrite_ipv4_multicast_mac(smac) { - modify_field(ethernet.srcAddr, smac); - modify_field(ethernet.dstAddr, 0x01005E000000, 0xFFFFFF800000); - add_to_field(ipv4.ttl, -1); -} - -action rewrite_ipv6_unicast_mac(smac) { - modify_field(ethernet.srcAddr, smac); - modify_field(ethernet.dstAddr, egress_metadata.mac_da); - add_to_field(ipv6.hopLimit, -1); -} - -action rewrite_ipv6_multicast_mac(smac) { - modify_field(ethernet.srcAddr, smac); - modify_field(ethernet.dstAddr, 0x333300000000, 0xFFFF00000000); - add_to_field(ipv6.hopLimit, -1); -} - -table mac_rewrite { - reads { - egress_metadata.smac_idx : exact; - ipv4 : valid; - ipv6 : valid; - } - actions { - nop; - rewrite_ipv4_unicast_mac; - rewrite_ipv4_multicast_mac; - rewrite_ipv6_unicast_mac; - rewrite_ipv6_multicast_mac; - } - size : 512; -} - -control process_mac_rewrite { - if (egress_metadata.routed == 1) { - apply(mac_rewrite); - } -} diff --git a/backends/tofino/bf-asm/test/mau/01-FlexCounter.p4 b/backends/tofino/bf-asm/test/mau/01-FlexCounter.p4 deleted file mode 100644 index f67bf1b1358..00000000000 --- a/backends/tofino/bf-asm/test/mau/01-FlexCounter.p4 +++ /dev/null @@ -1,89 +0,0 @@ -#ifdef __TARGET_TOFINO__ -#include -#include -#include -#else -#include "includes/tofino.p4" -#endif - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - ethertype : 16; - } -} - -header_type vlan_tag_t { - fields { - prio : 3; - cfi : 1; - vlan_id : 12; - } -} - -header ethernet_t ethernet; -header vlan_tag_t vlan_tag; - -parser start { - extract(ethernet); - return select(latest.ethertype) { - 0x8100 : parse_vlan_tag; - default: ingress; - } -} - -parser parse_vlan_tag { - extract(vlan_tag); - return ingress; -} - -@pragma pa_solitary md.flex_counter_offset - -header_type metadata_t { - fields { - flex_counter_index : 13; - } -} - -metadata metadata_t md; - -counter flex_counter { - type : packets; - instance_count : 8192; -} - -action set_flex_counter_index(flex_counter_base) { - add(md.flex_counter_index, flex_counter_base, vlan_tag.prio); -} - -action update_flex_counter() { - count(flex_counter, md.flex_counter_index); -} - -table vlan { - reads { - vlan_tag.vlan_id : exact; - } - actions { - set_flex_counter_index; - } - size : 4096; -} - -table update_counters { - actions { - update_flex_counter; - } -} - -control ingress { - apply(vlan) { - hit { - apply(update_counters); - } - } -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/mau/02-FlexCounterActionProfile.p4 b/backends/tofino/bf-asm/test/mau/02-FlexCounterActionProfile.p4 deleted file mode 100644 index 6e3f02fc254..00000000000 --- a/backends/tofino/bf-asm/test/mau/02-FlexCounterActionProfile.p4 +++ /dev/null @@ -1,101 +0,0 @@ -#ifdef __TARGET_TOFINO__ -#include -#include -#include -#else -#include "includes/tofino.p4" -#endif - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - ethertype : 16; - } -} - -header_type vlan_tag_t { - fields { - prio : 3; - cfi : 1; - vlan_id : 12; - } -} - -header ethernet_t ethernet; -header vlan_tag_t vlan_tag; - -parser start { - extract(ethernet); - return select(latest.ethertype) { - 0x8100 : parse_vlan_tag; - default: ingress; - } -} - -parser parse_vlan_tag { - extract(vlan_tag); - return ingress; -} - -@pragma pa_solitary md.flex_counter_offset - -header_type metadata_t { - fields { - flex_counter_index : 13; - } -} - -metadata metadata_t md; - -counter flex_counter { - type : packets; - instance_count : 8192; -} - -action set_flex_counter_index(flex_counter_base) { - add(md.flex_counter_index, flex_counter_base, vlan_tag.prio); -} - -action update_flex_counter(flex_counter_index) { - count(flex_counter, flex_counter_index); -} - -field_list vlan_prio_fields { - vlan_tag.prio; -} - -field_list_calculation vlan_prio_calc { - input { - vlan_prio_fields; - } - algorithm : identity_lsb; - output_width : 3; -} - -action_selector vlan_prio_sel { - selection_key : vlan_prio_calc; -} - -action_profile vlan_flex_counter_profile { - actions { - update_flex_counter; - } - size : 8; - dynamic_action_selection : vlan_prio_sel; -} - -table vlan { - reads { - vlan_tag.vlan_id : exact; - } - action_profile: vlan_flex_counter_profile; - size : 4096; -} - -control ingress { - apply(vlan); -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/mau/02-FullPHV1.p4 b/backends/tofino/bf-asm/test/mau/02-FullPHV1.p4 deleted file mode 100644 index 44ce6a957e4..00000000000 --- a/backends/tofino/bf-asm/test/mau/02-FullPHV1.p4 +++ /dev/null @@ -1,766 +0,0 @@ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - ethertype : 16; - } -} - -header ethernet_t ethernet; - -header_type m_t { - fields { - field_8_01 : 8; - field_8_02 : 8; - field_8_03 : 8; - field_8_04 : 8; - field_8_05 : 8; - field_8_06 : 8; - field_8_07 : 8; - field_8_08 : 8; - field_8_09 : 8; - field_8_10 : 8; - field_8_11 : 8; - field_8_12 : 8; - field_8_13 : 8; - field_8_14 : 8; - field_8_15 : 8; - field_8_16 : 8; - field_8_17 : 8; - field_8_18 : 8; - field_8_19 : 8; - field_8_20 : 8; - field_8_21 : 8; - field_8_22 : 8; - field_8_23 : 8; - field_8_24 : 8; - field_8_25 : 8; - field_8_26 : 8; - field_8_27 : 8; - field_8_28 : 8; - field_8_29 : 8; - field_8_30 : 8; - field_8_31 : 8; - field_8_32 : 8; - field_8_33 : 8; - field_8_34 : 8; - field_8_35 : 8; - field_8_36 : 8; - field_8_37 : 8; - field_8_38 : 8; - field_8_39 : 8; - field_8_40 : 8; - field_8_41 : 8; - field_8_42 : 8; - field_8_43 : 8; - field_8_44 : 8; - field_8_45 : 8; - field_8_46 : 8; - field_8_47 : 8; - field_8_48 : 8; - field_8_49 : 8; - field_8_50 : 8; - field_8_51 : 8; - field_8_52 : 8; - field_8_53 : 8; - field_8_54 : 8; - field_8_55 : 8; - field_8_56 : 8; - field_8_57 : 8; - field_8_58 : 8; - field_8_59 : 8; - field_8_60 : 8; - field_8_61 : 8; - field_8_62 : 8; - field_8_63 : 8; - field_8_64 : 8; - - field_16_01 : 16; - field_16_02 : 16; - field_16_03 : 16; - field_16_04 : 16; - field_16_05 : 16; - field_16_06 : 16; - field_16_07 : 16; - field_16_08 : 16; - field_16_09 : 16; - field_16_10 : 16; - field_16_11 : 16; - field_16_12 : 16; - field_16_13 : 16; - field_16_14 : 16; - field_16_15 : 16; - field_16_16 : 16; - field_16_17 : 16; - field_16_18 : 16; - field_16_19 : 16; - field_16_20 : 16; - field_16_21 : 16; - field_16_22 : 16; - field_16_23 : 16; - field_16_24 : 16; - field_16_25 : 16; - field_16_26 : 16; - field_16_27 : 16; - field_16_28 : 16; - field_16_29 : 16; - field_16_30 : 16; - field_16_31 : 16; - field_16_32 : 16; - field_16_33 : 16; - field_16_34 : 16; - field_16_35 : 16; - field_16_36 : 16; - field_16_37 : 16; - field_16_38 : 16; - field_16_39 : 16; - field_16_40 : 16; - field_16_41 : 16; - field_16_42 : 16; - field_16_43 : 16; - field_16_44 : 16; - field_16_45 : 16; - field_16_46 : 16; - field_16_47 : 16; - field_16_48 : 16; - field_16_49 : 16; - field_16_50 : 16; - field_16_51 : 16; - field_16_52 : 16; - field_16_53 : 16; - field_16_54 : 16; - field_16_55 : 16; - field_16_56 : 16; - field_16_57 : 16; - field_16_58 : 16; - field_16_59 : 16; - field_16_60 : 16; - field_16_61 : 16; - field_16_62 : 16; - field_16_63 : 16; - field_16_64 : 16; - field_16_65 : 16; - field_16_66 : 16; - field_16_67 : 16; - field_16_68 : 16; - field_16_69 : 16; - field_16_70 : 16; - field_16_71 : 16; - field_16_72 : 16; - field_16_73 : 16; - field_16_74 : 16; - field_16_75 : 16; - field_16_76 : 16; - field_16_77 : 16; - field_16_78 : 16; - field_16_79 : 16; - field_16_80 : 16; - field_16_81 : 16; - field_16_82 : 16; - field_16_83 : 16; - field_16_84 : 16; - field_16_85 : 16; - field_16_86 : 16; - field_16_87 : 16; - field_16_88 : 16; - field_16_89 : 16; - field_16_90 : 16; - field_16_91 : 16; - field_16_92 : 16; - field_16_93 : 16; - field_16_94 : 16; - field_16_95 : 16; - field_16_96 : 16; - - field_32_01 : 32; - field_32_02 : 32; - field_32_03 : 32; - field_32_04 : 32; - field_32_05 : 32; - field_32_06 : 32; - field_32_07 : 32; - field_32_08 : 32; - field_32_09 : 32; - field_32_10 : 32; - field_32_11 : 32; - field_32_12 : 32; - field_32_13 : 32; - field_32_14 : 32; - field_32_15 : 32; - field_32_16 : 32; - field_32_17 : 32; - field_32_18 : 32; - field_32_19 : 32; - field_32_20 : 32; - field_32_21 : 32; - field_32_22 : 32; - field_32_23 : 32; - field_32_24 : 32; - field_32_25 : 32; - field_32_26 : 32; - field_32_27 : 32; - field_32_28 : 32; - field_32_29 : 32; - field_32_30 : 32; - field_32_31 : 32; - field_32_32 : 32; - field_32_33 : 32; - field_32_34 : 32; - field_32_35 : 32; - field_32_36 : 32; - field_32_37 : 32; - field_32_38 : 32; - field_32_39 : 32; - field_32_40 : 32; - field_32_41 : 32; - field_32_42 : 32; - field_32_43 : 32; - field_32_44 : 32; - field_32_45 : 32; - field_32_46 : 32; - field_32_47 : 32; - field_32_48 : 32; - field_32_49 : 32; - field_32_50 : 32; - field_32_51 : 32; - field_32_52 : 32; - field_32_53 : 32; - field_32_54 : 32; - field_32_55 : 32; - field_32_56 : 32; - field_32_57 : 32; - field_32_58 : 32; - field_32_59 : 32; - field_32_60 : 32; - field_32_61 : 32; - field_32_62 : 32; - field_32_63 : 32; - field_32_64 : 32; - } -} - -metadata m_t m; - -parser start { - extract(ethernet); - return ingress; -} - -action a1() { - modify_field(m.field_8_01, 1); - modify_field(m.field_8_02, 2); - modify_field(m.field_8_03, 3); - modify_field(m.field_8_04, 4); - modify_field(m.field_8_05, 5); - modify_field(m.field_8_06, 6); - modify_field(m.field_8_07, 7); - modify_field(m.field_8_08, 8); - modify_field(m.field_8_09, 9); - modify_field(m.field_8_10, 10); - modify_field(m.field_8_11, 11); - modify_field(m.field_8_12, 12); - modify_field(m.field_8_13, 13); - modify_field(m.field_8_14, 14); - modify_field(m.field_8_15, 15); - modify_field(m.field_8_16, 16); - modify_field(m.field_8_17, 17); - modify_field(m.field_8_18, 18); - modify_field(m.field_8_19, 19); - modify_field(m.field_8_20, 20); - modify_field(m.field_8_21, 21); - modify_field(m.field_8_22, 22); - modify_field(m.field_8_23, 23); - modify_field(m.field_8_24, 24); - modify_field(m.field_8_25, 25); - modify_field(m.field_8_26, 26); - modify_field(m.field_8_27, 27); - modify_field(m.field_8_28, 28); - modify_field(m.field_8_29, 29); - modify_field(m.field_8_30, 30); - modify_field(m.field_8_31, 31); - modify_field(m.field_8_32, 32); - modify_field(m.field_8_33, 33); - modify_field(m.field_8_34, 34); - modify_field(m.field_8_35, 35); - modify_field(m.field_8_36, 36); - modify_field(m.field_8_37, 37); - modify_field(m.field_8_38, 38); - modify_field(m.field_8_39, 39); - modify_field(m.field_8_40, 40); - modify_field(m.field_8_41, 41); - modify_field(m.field_8_42, 42); - modify_field(m.field_8_43, 43); - modify_field(m.field_8_44, 44); - modify_field(m.field_8_45, 45); - modify_field(m.field_8_46, 46); - modify_field(m.field_8_47, 47); - modify_field(m.field_8_48, 48); - modify_field(m.field_8_49, 49); - modify_field(m.field_8_50, 50); - modify_field(m.field_8_51, 51); - modify_field(m.field_8_52, 52); - modify_field(m.field_8_53, 53); - modify_field(m.field_8_54, 54); - modify_field(m.field_8_55, 55); - modify_field(m.field_8_56, 56); - modify_field(m.field_8_57, 57); - modify_field(m.field_8_58, 58); - modify_field(m.field_8_59, 59); - modify_field(m.field_8_60, 60); - modify_field(m.field_8_61, 61); - modify_field(m.field_8_62, 62); - modify_field(m.field_8_63, 63); - modify_field(m.field_8_64, 64); - - modify_field(m.field_16_01, 1); - modify_field(m.field_16_02, 2); - modify_field(m.field_16_03, 3); - modify_field(m.field_16_04, 4); - modify_field(m.field_16_05, 5); - modify_field(m.field_16_06, 6); - modify_field(m.field_16_07, 7); - modify_field(m.field_16_08, 8); - modify_field(m.field_16_09, 9); - modify_field(m.field_16_10, 10); - modify_field(m.field_16_11, 11); - modify_field(m.field_16_12, 12); - modify_field(m.field_16_13, 13); - modify_field(m.field_16_14, 14); - modify_field(m.field_16_15, 15); - modify_field(m.field_16_16, 16); - modify_field(m.field_16_17, 17); - modify_field(m.field_16_18, 18); - modify_field(m.field_16_19, 19); - modify_field(m.field_16_20, 20); - modify_field(m.field_16_21, 21); - modify_field(m.field_16_22, 22); - modify_field(m.field_16_23, 23); - modify_field(m.field_16_24, 24); - modify_field(m.field_16_25, 25); - modify_field(m.field_16_26, 26); - modify_field(m.field_16_27, 27); - modify_field(m.field_16_28, 28); - modify_field(m.field_16_29, 29); - modify_field(m.field_16_30, 30); - modify_field(m.field_16_31, 31); - modify_field(m.field_16_32, 32); - modify_field(m.field_16_33, 33); - modify_field(m.field_16_34, 34); - modify_field(m.field_16_35, 35); - modify_field(m.field_16_36, 36); - modify_field(m.field_16_37, 37); - modify_field(m.field_16_38, 38); - modify_field(m.field_16_39, 39); - modify_field(m.field_16_40, 40); - modify_field(m.field_16_41, 41); - modify_field(m.field_16_42, 42); - modify_field(m.field_16_43, 43); - modify_field(m.field_16_44, 44); - modify_field(m.field_16_45, 45); - modify_field(m.field_16_46, 46); - modify_field(m.field_16_47, 47); - modify_field(m.field_16_48, 48); - modify_field(m.field_16_49, 49); - modify_field(m.field_16_50, 50); - modify_field(m.field_16_51, 51); - modify_field(m.field_16_52, 52); - modify_field(m.field_16_53, 53); - modify_field(m.field_16_54, 54); - modify_field(m.field_16_55, 55); - modify_field(m.field_16_56, 56); - modify_field(m.field_16_57, 57); - modify_field(m.field_16_58, 58); - modify_field(m.field_16_59, 59); - modify_field(m.field_16_60, 60); - modify_field(m.field_16_61, 61); - modify_field(m.field_16_62, 62); - modify_field(m.field_16_63, 63); - modify_field(m.field_16_64, 64); - modify_field(m.field_16_65, 65); - modify_field(m.field_16_66, 66); - modify_field(m.field_16_67, 67); - modify_field(m.field_16_68, 68); - modify_field(m.field_16_69, 69); - modify_field(m.field_16_70, 70); - modify_field(m.field_16_71, 71); - modify_field(m.field_16_72, 72); - modify_field(m.field_16_73, 73); - modify_field(m.field_16_74, 74); - modify_field(m.field_16_75, 75); - modify_field(m.field_16_76, 76); - modify_field(m.field_16_77, 77); - modify_field(m.field_16_78, 78); - modify_field(m.field_16_79, 79); - modify_field(m.field_16_80, 80); - modify_field(m.field_16_81, 81); - modify_field(m.field_16_82, 82); - modify_field(m.field_16_83, 83); - modify_field(m.field_16_84, 84); - modify_field(m.field_16_85, 85); - modify_field(m.field_16_86, 86); - modify_field(m.field_16_87, 87); - modify_field(m.field_16_88, 88); - modify_field(m.field_16_89, 89); - modify_field(m.field_16_90, 90); - modify_field(m.field_16_91, 91); - modify_field(m.field_16_92, 92); - modify_field(m.field_16_93, 93); - modify_field(m.field_16_94, 94); - modify_field(m.field_16_95, 95); - modify_field(m.field_16_96, 96); - - modify_field(m.field_32_01, 1); - modify_field(m.field_32_02, 2); - modify_field(m.field_32_03, 3); - modify_field(m.field_32_04, 4); - modify_field(m.field_32_05, 5); - modify_field(m.field_32_06, 6); - modify_field(m.field_32_07, 7); - modify_field(m.field_32_08, 8); - modify_field(m.field_32_09, 9); - modify_field(m.field_32_10, 10); - modify_field(m.field_32_11, 11); - modify_field(m.field_32_12, 12); - modify_field(m.field_32_13, 13); - modify_field(m.field_32_14, 14); - modify_field(m.field_32_15, 15); - modify_field(m.field_32_16, 16); - modify_field(m.field_32_17, 17); - modify_field(m.field_32_18, 18); - modify_field(m.field_32_19, 19); - modify_field(m.field_32_20, 20); - modify_field(m.field_32_21, 21); - modify_field(m.field_32_22, 22); - modify_field(m.field_32_23, 23); - modify_field(m.field_32_24, 24); - modify_field(m.field_32_25, 25); - modify_field(m.field_32_26, 26); - modify_field(m.field_32_27, 27); - modify_field(m.field_32_28, 28); - modify_field(m.field_32_29, 29); - modify_field(m.field_32_30, 30); - modify_field(m.field_32_31, 31); - modify_field(m.field_32_32, 32); - modify_field(m.field_32_33, 33); - modify_field(m.field_32_34, 34); - modify_field(m.field_32_35, 35); - modify_field(m.field_32_36, 36); - modify_field(m.field_32_37, 37); - modify_field(m.field_32_38, 38); - modify_field(m.field_32_39, 39); -#if 0 - modify_field(m.field_32_40, 40); - modify_field(m.field_32_41, 41); - modify_field(m.field_32_42, 42); - modify_field(m.field_32_43, 43); - modify_field(m.field_32_44, 44); - modify_field(m.field_32_45, 45); - modify_field(m.field_32_46, 46); - modify_field(m.field_32_47, 47); - modify_field(m.field_32_48, 48); - modify_field(m.field_32_49, 49); - modify_field(m.field_32_50, 50); - modify_field(m.field_32_51, 51); - modify_field(m.field_32_52, 52); - modify_field(m.field_32_53, 53); - modify_field(m.field_32_54, 54); - modify_field(m.field_32_55, 55); - modify_field(m.field_32_56, 56); - modify_field(m.field_32_57, 57); - modify_field(m.field_32_58, 58); - modify_field(m.field_32_59, 59); - modify_field(m.field_32_60, 60); - modify_field(m.field_32_61, 61); - modify_field(m.field_32_62, 62); - modify_field(m.field_32_63, 63); - modify_field(m.field_32_64, 64); -#endif -} - -table t1 { - actions { - a1; - } -} - -action a2_1() { - modify_field(m.field_16_01, 1); - modify_field(m.field_16_02, 2); - modify_field(m.field_16_03, 3); - modify_field(m.field_16_04, 4); - modify_field(m.field_16_05, 5); - modify_field(m.field_16_06, 6); - modify_field(m.field_16_07, 7); - modify_field(m.field_16_08, 8); - modify_field(m.field_16_09, 9); - modify_field(m.field_16_10, 10); - modify_field(m.field_16_11, 11); - modify_field(m.field_16_12, 12); - modify_field(m.field_16_13, 13); - modify_field(m.field_16_14, 14); - modify_field(m.field_16_15, 15); - modify_field(m.field_16_16, 16); - modify_field(m.field_16_17, 17); - modify_field(m.field_16_18, 18); - modify_field(m.field_16_19, 19); - modify_field(m.field_16_20, 20); - modify_field(m.field_16_21, 21); - modify_field(m.field_16_22, 22); - modify_field(m.field_16_23, 23); - modify_field(m.field_16_24, 24); - modify_field(m.field_16_25, 25); - modify_field(m.field_16_26, 26); - modify_field(m.field_16_27, 27); - modify_field(m.field_16_28, 28); - modify_field(m.field_16_29, 29); - modify_field(m.field_16_30, 30); - modify_field(m.field_16_31, 31); - modify_field(m.field_16_32, 32); - modify_field(m.field_16_33, 33); - modify_field(m.field_16_34, 34); - modify_field(m.field_16_35, 35); - modify_field(m.field_16_36, 36); - modify_field(m.field_16_37, 37); - modify_field(m.field_16_38, 38); - modify_field(m.field_16_39, 39); - modify_field(m.field_16_40, 40); - modify_field(m.field_16_41, 41); - modify_field(m.field_16_42, 42); - modify_field(m.field_16_43, 43); - modify_field(m.field_16_44, 44); - modify_field(m.field_16_45, 45); - modify_field(m.field_16_46, 46); - modify_field(m.field_16_47, 47); - modify_field(m.field_16_48, 48); -} - -table t2_1 { - reads { - m.field_8_01 : exact; - m.field_8_02 : exact; - m.field_8_03 : exact; - m.field_8_04 : exact; - m.field_8_05 : exact; - m.field_8_06 : exact; - m.field_8_07 : exact; - m.field_8_08 : exact; - m.field_8_09 : exact; - m.field_8_10 : exact; - m.field_8_11 : exact; - m.field_8_12 : exact; - m.field_8_13 : exact; - m.field_8_14 : exact; - m.field_8_15 : exact; - m.field_8_16 : exact; - m.field_8_17 : exact; - m.field_8_18 : exact; - m.field_8_19 : exact; - m.field_8_20 : exact; - m.field_8_21 : exact; - m.field_8_22 : exact; - m.field_8_23 : exact; - m.field_8_24 : exact; - m.field_8_25 : exact; - m.field_8_26 : exact; - m.field_8_27 : exact; - m.field_8_28 : exact; - m.field_8_29 : exact; - m.field_8_30 : exact; - m.field_8_31 : exact; - m.field_8_32 : exact; - m.field_8_33 : exact; - m.field_8_34 : exact; - m.field_8_35 : exact; - m.field_8_36 : exact; - m.field_8_37 : exact; - m.field_8_38 : exact; - m.field_8_39 : exact; - m.field_8_40 : exact; - m.field_8_41 : exact; - m.field_8_42 : exact; - m.field_8_43 : exact; - m.field_8_44 : exact; - m.field_8_45 : exact; - m.field_8_46 : exact; - m.field_8_47 : exact; - m.field_8_48 : exact; - m.field_8_49 : exact; - m.field_8_50 : exact; - m.field_8_51 : exact; - m.field_8_52 : exact; - m.field_8_53 : exact; - m.field_8_54 : exact; - m.field_8_55 : exact; - m.field_8_56 : exact; - m.field_8_57 : exact; - m.field_8_58 : exact; - m.field_8_59 : exact; - m.field_8_60 : exact; - m.field_8_61 : exact; - m.field_8_62 : exact; - m.field_8_63 : exact; - m.field_8_64 : exact; - } - actions { - a2_1; - } -} - -action a2_2() { - modify_field(m.field_16_49, 49); - modify_field(m.field_16_50, 50); - modify_field(m.field_16_51, 51); - modify_field(m.field_16_52, 52); - modify_field(m.field_16_53, 53); - modify_field(m.field_16_54, 54); - modify_field(m.field_16_55, 55); - modify_field(m.field_16_56, 56); - modify_field(m.field_16_57, 57); - modify_field(m.field_16_58, 58); - modify_field(m.field_16_59, 59); - modify_field(m.field_16_60, 60); - modify_field(m.field_16_61, 61); - modify_field(m.field_16_62, 62); - modify_field(m.field_16_63, 63); -} - -table t2_2 { - reads { - m.field_32_01 : exact; - m.field_32_02 : exact; - m.field_32_03 : exact; - m.field_32_04 : exact; - m.field_32_05 : exact; - m.field_32_06 : exact; - m.field_32_07 : exact; - m.field_32_08 : exact; - m.field_32_09 : exact; - m.field_32_10 : exact; - m.field_32_11 : exact; - m.field_32_12 : exact; - m.field_32_13 : exact; - m.field_32_14 : exact; - m.field_32_15 : exact; - m.field_32_16 : exact; - } - actions { - a2_2; - } -} - -action a2_3() { - modify_field(m.field_16_65, 65); - modify_field(m.field_16_66, 66); - modify_field(m.field_16_67, 67); - modify_field(m.field_16_68, 68); - modify_field(m.field_16_69, 69); - modify_field(m.field_16_70, 70); - modify_field(m.field_16_71, 71); - modify_field(m.field_16_72, 72); - modify_field(m.field_16_73, 73); - modify_field(m.field_16_74, 74); - modify_field(m.field_16_75, 75); - modify_field(m.field_16_76, 76); - modify_field(m.field_16_77, 77); - modify_field(m.field_16_78, 78); - modify_field(m.field_16_79, 79); -} - -table t2_3 { - reads { - m.field_32_17 : ternary; - m.field_32_18 : ternary; - m.field_32_19 : ternary; - m.field_32_20 : ternary; - m.field_32_21 : ternary; - m.field_32_22 : ternary; - m.field_32_23 : ternary; - m.field_32_24 : ternary; - m.field_32_25 : ternary; - m.field_32_26 : ternary; - m.field_32_27 : ternary; - m.field_32_28 : ternary; - m.field_32_29 : ternary; - m.field_32_30 : ternary; - m.field_32_31 : ternary; - m.field_32_32 : ternary; - } - actions { - a2_3; - } -} - -action a3_1() { - modify_field(m.field_16_80, 80); - modify_field(m.field_16_81, 81); - modify_field(m.field_16_82, 82); - modify_field(m.field_16_83, 83); - modify_field(m.field_16_84, 84); - modify_field(m.field_16_85, 85); - modify_field(m.field_16_86, 86); - modify_field(m.field_16_87, 87); - modify_field(m.field_16_88, 88); - modify_field(m.field_16_89, 89); - modify_field(m.field_16_90, 90); - modify_field(m.field_16_91, 91); - modify_field(m.field_16_92, 92); - modify_field(m.field_16_93, 93); - modify_field(m.field_16_94, 94); - modify_field(m.field_16_95, 95); - modify_field(m.field_16_96, 96); -} - -table t3_1 { - reads { - m.field_32_33 : exact; - m.field_32_34 : exact; - m.field_32_35 : exact; - m.field_32_36 : exact; - m.field_32_37 : exact; - m.field_32_38 : exact; - m.field_32_39 : exact; - m.field_32_40 : exact; - m.field_32_41 : exact; - m.field_32_42 : exact; - m.field_32_43 : exact; - m.field_32_44 : exact; - m.field_32_45 : exact; - m.field_32_46 : exact; - m.field_32_47 : exact; - m.field_32_48 : exact; - m.field_32_49 : exact; -#if 0 - m.field_32_50 : exact; - m.field_32_51 : exact; - m.field_32_52 : exact; - m.field_32_53 : exact; - m.field_32_54 : exact; - m.field_32_55 : exact; - m.field_32_56 : exact; - m.field_32_57 : exact; - m.field_32_58 : exact; - m.field_32_59 : exact; - m.field_32_60 : exact; - m.field_32_61 : exact; - m.field_32_62 : exact; - m.field_32_63 : exact; - m.field_32_64 : exact; -#endif - } - actions { - a3_1; - } -} - -control ingress { - apply(t1); - - apply(t2_1); - apply(t2_2); - apply(t2_3); - - apply(t3_1); -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/mau/04-FieldProblem.p4 b/backends/tofino/bf-asm/test/mau/04-FieldProblem.p4 deleted file mode 100644 index 138615c8950..00000000000 --- a/backends/tofino/bf-asm/test/mau/04-FieldProblem.p4 +++ /dev/null @@ -1,91 +0,0 @@ -header_type vag_t { - fields { - f1 : 8; - f2 : 16; - f3 : 32; - } -} - -header vag_t vag; - -parser start { - extract(vag); - return ingress; -} - -header_type ingress_metadata_t { - fields { - f1 : 8; - f2 : 16; - f3 : 32; - } -} - -metadata ingress_metadata_t ing_metadata; - -action nop() { -} - -action set_f1(f1) { - modify_field(ing_metadata.f1, f1); -} - -action set_f2(f2) { - modify_field(ing_metadata.f2, f2); -} - -action set_f3(f3) { - modify_field(ing_metadata.f3, f3); -} - -table i_t1 { - reads { - vag.f1 : exact; - } - actions { - nop; - set_f1; - } - size : 1024; -} - -table i_t2 { - reads { - vag.f2 : exact; - } - actions { - nop; - set_f2; - } - size : 1024; -} - -table i_t3 { - reads { - vag.f3 : exact; - } - actions { - nop; - set_f3; - } - size : 1024; -} - -control ingress { - apply(i_t1); -// apply(i_t2); -// apply(i_t3); -} - -table e_t1 { - reads { - vag.f1 : exact; - } - actions { - nop; - } -} - -control egress { - apply(e_t1); -} diff --git a/backends/tofino/bf-asm/test/mau/07-MacAddrCheck.p4 b/backends/tofino/bf-asm/test/mau/07-MacAddrCheck.p4 deleted file mode 100644 index 076136de13c..00000000000 --- a/backends/tofino/bf-asm/test/mau/07-MacAddrCheck.p4 +++ /dev/null @@ -1,52 +0,0 @@ -#ifdef __TARGET_TOFINO__ -#include -#include -#include -#else -#include "includes/tofino.p4" -#endif - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - ethertype : 16; - } -} - -header ethernet_t ethernet; - -parser start { - extract(ethernet); - return ingress; -} - -header_type ingress_metadata_t { - fields { - drop : 1; - } -} - -metadata ingress_metadata_t ing_metadata; - -action nop() { -} - -action ing_drop() { - drop(); -} - -table bad_mac_drop { - actions { - ing_drop; - } -} - -control ingress { - if (ethernet.srcAddr == ethernet.dstAddr) { - apply(bad_mac_drop); - } -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/mau/08-MacAddrCheck1.p4 b/backends/tofino/bf-asm/test/mau/08-MacAddrCheck1.p4 deleted file mode 100644 index 49b8e6d5375..00000000000 --- a/backends/tofino/bf-asm/test/mau/08-MacAddrCheck1.p4 +++ /dev/null @@ -1,55 +0,0 @@ -#ifdef __TARGET_TOFINO__ -#include -#include -#include -#else -#include "includes/tofino.p4" -#endif - -header_type ethernet_t { - fields { - dstAddr16 : 16; - dstAddr32 : 32; - srcAddr16 : 16; - srcAddr32 : 32; - ethertype : 16; - } -} - -header ethernet_t ethernet; - -parser start { - extract(ethernet); - return ingress; -} - -header_type ingress_metadata_t { - fields { - drop : 1; - } -} - -metadata ingress_metadata_t ing_metadata; - -action nop() { -} - -action ing_drop() { - drop(); -} - -table bad_mac_drop { - actions { - ing_drop; - } -} - -control ingress { - if ((ethernet.srcAddr16 == ethernet.dstAddr16) and - (ethernet.srcAddr32 == ethernet.dstAddr32)) { - apply(bad_mac_drop); - } -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/mau/08-MultiProtocolIfElse.p4 b/backends/tofino/bf-asm/test/mau/08-MultiProtocolIfElse.p4 deleted file mode 100644 index 53ea59195d7..00000000000 --- a/backends/tofino/bf-asm/test/mau/08-MultiProtocolIfElse.p4 +++ /dev/null @@ -1,199 +0,0 @@ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type ipv6_t { - fields { - version : 4; - trafficClass : 8; - flowLabel : 20; - payloadLen : 16; - nextHdr : 8; - hopLimit : 8; - srcAddr : 128; - dstAddr : 128; - } -} - -header_type icmp_t { - fields { - typeCode : 16; - hdrChecksum : 16; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 4; - flags : 8; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - length_ : 16; - checksum : 16; - } -} - -header ethernet_t ethernet; -header vlan_tag_t vlan_tag; -header ipv4_t ipv4; -header ipv6_t ipv6; -header tcp_t tcp; -header udp_t udp; -header icmp_t icmp; - -parser start { - extract(ethernet); - return select(latest.etherType) { - 0x8100, 0x9100 : parse_vlan_tag; - 0x0800 : parse_ipv4; - 0x86DD : parse_ipv6; - default : ingress; - } -} - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x0800 : parse_ipv4; - 0x86DD : parse_ipv6; - default : ingress; - } -} - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.ihl, latest.protocol) { - 0x0000501 mask 0x0000fff : parse_icmp; - 0x0000506 mask 0x0000fff : parse_tcp; - 0x0000511 mask 0x0000fff : parse_udp; - default : ingress; - } -} - -parser parse_ipv6 { - extract(ipv6); - return select(latest.nextHdr) { - 0x01 : parse_icmp; - 0x06 : parse_tcp; - 0x11 : parse_udp; - default : ingress; - } -} - -parser parse_icmp { - extract(icmp); - return ingress; -} - -parser parse_tcp { - extract(tcp); - return ingress; -} - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type ingress_metadata_t { - fields { - drop : 1; - egress_port : 8; - packet_type : 4; - } -} - -metadata ingress_metadata_t ing_metadata; - -action nop() { -} - -action set_egress_port(egress_port) { - modify_field(ing_metadata.egress_port, egress_port); -} - -table ipv4_match { - reads { - ipv4.srcAddr : exact; - } - actions { - nop; - set_egress_port; - } -} - -table ipv6_match { - reads { - ipv6.srcAddr : exact; - } - actions { - nop; - set_egress_port; - } -} - -table l2_match { - reads { - ethernet.srcAddr : exact; - } - actions { - nop; - set_egress_port; - } -} - -control ingress { - if (ethernet.etherType == 0x0800) { - apply(ipv4_match); - } else if (ethernet.etherType == 0x86DD) { - apply(ipv6_match); - } else { - apply(l2_match); - } -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/mau/09-MacAddrCheck2.p4 b/backends/tofino/bf-asm/test/mau/09-MacAddrCheck2.p4 deleted file mode 100644 index 07f0b7ca8d8..00000000000 --- a/backends/tofino/bf-asm/test/mau/09-MacAddrCheck2.p4 +++ /dev/null @@ -1,56 +0,0 @@ -#ifdef __TARGET_TOFINO__ -#include -#include -#include -#else -#include "includes/tofino.p4" -#endif - -header_type ethernet_t { - fields { - dstAddr16 : 16; - dstAddr32 : 32; - srcAddr16 : 16; - srcAddr32 : 32; - ethertype : 16; - } -} - -header ethernet_t ethernet; - -parser start { - extract(ethernet); - return ingress; -} - -header_type ingress_metadata_t { - fields { - drop : 1; - } -} - -metadata ingress_metadata_t ing_metadata; - -action nop() { -} - -action ing_drop() { - drop(); -} - -table bad_mac_drop { - actions { - ing_drop; - } -} - -control ingress { - if (ethernet.srcAddr16 == ethernet.dstAddr16) { - if (ethernet.srcAddr32 == ethernet.dstAddr32) { - apply(bad_mac_drop); - } - } -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/mau/10-AssignChooseSource.p4 b/backends/tofino/bf-asm/test/mau/10-AssignChooseSource.p4 deleted file mode 100644 index af678b9e46e..00000000000 --- a/backends/tofino/bf-asm/test/mau/10-AssignChooseSource.p4 +++ /dev/null @@ -1,100 +0,0 @@ -#ifdef __TARGET_TOFINO__ -#include -#include -#include -#else -#include "includes/tofino.p4" -#endif - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - ethertype : 16; - } -} - -header ethernet_t ethernet; - -parser start { - extract(ethernet); - return ingress; -} - -header_type ingress_metadata_t { - fields { - flag : 1; - tmp1 : 9; - tmp2 : 9; - egress_port : 9; - } -} - -metadata ingress_metadata_t ing_metadata; - -action set_ingress_port_props(port_type) { - modify_field(ing_metadata.flag, port_type); -} - -table ingress_port_map { - reads { - ig_intr_md.ingress_port : exact; - } - actions { - set_ingress_port_props; - } - size : 288; -} - -action assign_egress_interfaces(value1, value2) { - modify_field(ing_metadata.tmp1, value1); - modify_field(ing_metadata.tmp2, value2); -} - -table dmac { - reads { - ethernet.dstAddr : exact; - } - actions { - assign_egress_interfaces; - } -} - -action assign_egress1_action() { - modify_field(ing_metadata.egress_port, ing_metadata.tmp1); -} - -table assign_egress1 { - actions { - assign_egress1_action; - } -} - -action assign_egress2_action() { - modify_field(ing_metadata.egress_port, ing_metadata.tmp2); -} - -table assign_egress2 { - actions { - assign_egress2_action; - } -} - -control ingress { - if (ig_intr_md.resubmit_flag == 0) { - apply(ingress_port_map); - - apply(dmac) { - assign_egress_interfaces { - if (ing_metadata.flag == 1) { - apply(assign_egress1); - } else { - apply(assign_egress2); - } - } - } - } -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/mau/12-Counters.p4 b/backends/tofino/bf-asm/test/mau/12-Counters.p4 deleted file mode 100644 index 8aaa3513ae9..00000000000 --- a/backends/tofino/bf-asm/test/mau/12-Counters.p4 +++ /dev/null @@ -1,49 +0,0 @@ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - ethertype : 16; - } -} - -header ethernet_t ethernet; - -parser start { - extract(ethernet); - return ingress; -} - -counter c1 { - type : packets; - instance_count : 1024; -} - -action count_c1_1() { - count(c1, 1); -} - -table t1 { - reads { - ethernet.dstAddr : exact; - } - actions { - count_c1_1; - } -} - -table t2 { - reads { - ethernet.srcAddr : exact; - } - actions { - count_c1_1; - } -} - -control ingress { - apply(t1); - apply(t2); -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/mau/12-SmallToBigFieldWithMask8.p4 b/backends/tofino/bf-asm/test/mau/12-SmallToBigFieldWithMask8.p4 deleted file mode 100644 index dc3ed584a2f..00000000000 --- a/backends/tofino/bf-asm/test/mau/12-SmallToBigFieldWithMask8.p4 +++ /dev/null @@ -1,59 +0,0 @@ -#ifdef __TARGET_TOFINO__ -#include -#include -#include -#else -#include "includes/tofino.p4" -#endif - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - ethertype : 16; - } -} - -header ethernet_t ethernet; - -parser start { - extract(ethernet); - return ingress; -} - -header_type m1_t { - fields { - f1 : 16; - } -} - -metadata m1_t m1; - -action a1(p1) { - modify_field(m1.f1, p1); -} - -action a2() { - modify_field(ethernet.dstAddr, m1.f1, 0xfffF); - //modify_field(ethernet.dstAddr, m1.f1); -} - -table t1 { - actions { - a1; - } -} - -table t2 { - actions { - a2; - } -} - -control ingress { - apply(t1); - apply(t2); -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/mau/14-Counter.p4 b/backends/tofino/bf-asm/test/mau/14-Counter.p4 deleted file mode 100644 index eb6d310df68..00000000000 --- a/backends/tofino/bf-asm/test/mau/14-Counter.p4 +++ /dev/null @@ -1,36 +0,0 @@ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - ethertype : 16; - } -} - -header ethernet_t ethernet; - -parser start { - extract(ethernet); - return ingress; -} - -counter c1 { - type : packets; - instance_count : 1024; -} - -action count_c1_1() { - count(c1, 1); -} - -table t1 { - actions { - count_c1_1; - } -} - -control ingress { - apply(t1); -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/mau/15-MultiProtocolIfElseMinimal.p4 b/backends/tofino/bf-asm/test/mau/15-MultiProtocolIfElseMinimal.p4 deleted file mode 100644 index 3581d584761..00000000000 --- a/backends/tofino/bf-asm/test/mau/15-MultiProtocolIfElseMinimal.p4 +++ /dev/null @@ -1,107 +0,0 @@ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header ethernet_t ethernet; -header vlan_tag_t vlan_tag; -header ipv4_t ipv4; - -parser start { - extract(ethernet); - return select(latest.etherType) { - 0x8100, 0x9100 : parse_vlan_tag; - 0x0800 : parse_ipv4; - default : ingress; - } -} - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x0800 : parse_ipv4; - default : ingress; - } -} - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -header_type ingress_metadata_t { - fields { - drop : 1; - egress_port : 8; - packet_type : 4; - } -} - -metadata ingress_metadata_t ing_metadata; - -action nop() { -} - -action set_egress_port(egress_port) { - modify_field(ing_metadata.egress_port, egress_port); -} - -table ipv4_match { - reads { - ipv4.srcAddr : exact; - } - actions { - nop; - set_egress_port; - } -} - -table l2_match { - reads { - ethernet.srcAddr : exact; - } - actions { - nop; - set_egress_port; - } -} - -control ingress { - if (ethernet.etherType == 0x0800) { - apply(ipv4_match); - } else { - apply(l2_match); - } -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/mau/16-NoHeaders.p4 b/backends/tofino/bf-asm/test/mau/16-NoHeaders.p4 deleted file mode 100644 index c409c7cc2ca..00000000000 --- a/backends/tofino/bf-asm/test/mau/16-NoHeaders.p4 +++ /dev/null @@ -1,19 +0,0 @@ -parser start { - return ingress; -} - -action a1() { -} - -table t1 { - actions { - a1; - } -} - -control ingress { - apply(t1); -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/mau/19-SimpleTrill.p4 b/backends/tofino/bf-asm/test/mau/19-SimpleTrill.p4 deleted file mode 100644 index db1c61cff2c..00000000000 --- a/backends/tofino/bf-asm/test/mau/19-SimpleTrill.p4 +++ /dev/null @@ -1,94 +0,0 @@ -#ifdef __TARGET_TOFINO__ -#include -#include -#include -#else -#include "includes/tofino.p4" -#endif - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - ethertype : 16; - } -} - -header ethernet_t outer_ethernet; -header ethernet_t inner_ethernet; - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vid : 12; - ethertype : 16; - } -} - -header vlan_tag_t vlan_tag; - -header_type trill_t { - fields { - version : 2; - reserved : 2; - multiDestination : 1; - optLength : 5; - hopCount : 6; - egressRbridge : 16; - ingressRbridge : 16; - } -} - -header trill_t trill; - -parser start { - extract(outer_ethernet); - return select(latest.ethertype) { - 0x8100 : parse_vlan_tag; - 0x2222 : parse_trill; - default : ingress; - } -} - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.ethertype) { - 0x2222 : parse_trill; - default : ingress; - } -} - -parser parse_trill { - extract(trill); - extract(inner_ethernet); - return ingress; -} - -/* - * TRILL Forwarding Table - */ -action forward_trill(new_mac_da, new_mac_sa, new_vlan_id, new_port) { - modify_field(outer_ethernet.dstAddr, new_mac_da); - modify_field(outer_ethernet.srcAddr, new_mac_sa); - modify_field(vlan_tag.vid, new_vlan_id); - modify_field(ig_intr_md_for_tm.ucast_egress_port, new_port); - add_to_field(trill.hopCount, -1); -} - -table trill_forward { - reads { - trill.egressRbridge : exact; - } - actions { - forward_trill; - } -} - -control ingress { - apply(trill_forward); -} - - -control egress { -} diff --git a/backends/tofino/bf-asm/test/mau/20-SimpleTrillTwoStep.p4 b/backends/tofino/bf-asm/test/mau/20-SimpleTrillTwoStep.p4 deleted file mode 100644 index 77399460f4f..00000000000 --- a/backends/tofino/bf-asm/test/mau/20-SimpleTrillTwoStep.p4 +++ /dev/null @@ -1,115 +0,0 @@ -#ifdef __TARGET_TOFINO__ -#include -#include -#include -#else -#include "includes/tofino.p4" -#endif - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - ethertype : 16; - } -} - -header ethernet_t outer_ethernet; -header ethernet_t inner_ethernet; - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vid : 12; - ethertype : 16; - } -} - -header vlan_tag_t vlan_tag; - -header_type trill_t { - fields { - version : 2; - reserved : 2; - multiDestination : 1; - optLength : 5; - hopCount : 6; - egressRbridge : 16; - ingressRbridge : 16; - } -} - -header trill_t trill; - -header_type my_metadata_t { - fields { - hopCount : 6 (saturating); - } -} - -metadata my_metadata_t m; - -parser start { - extract(outer_ethernet); - return select(latest.ethertype) { - 0x8100 : parse_vlan_tag; - 0x2222 : parse_trill; - default : ingress; - } -} - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.ethertype) { - 0x2222 : parse_trill; - default : ingress; - } -} - -parser parse_trill { - extract(trill); - //set_metadata(m.hopCount, trill.hopCount); - extract(inner_ethernet); - return ingress; -} - -/* - * TRILL Forwarding Table - */ -action forward_trill(new_mac_da, new_mac_sa, new_vlan_id, new_port) { - modify_field(outer_ethernet.dstAddr, new_mac_da); - modify_field(outer_ethernet.srcAddr, new_mac_sa); - modify_field(vlan_tag.vid, new_vlan_id); - modify_field(ig_intr_md_for_tm.ucast_egress_port, new_port); - add(m.hopCount, trill.hopCount, -1); - //add_to_field(m.hopCount, -1); -} - -table trill_forward { - reads { - trill.egressRbridge : exact; - } - actions { - forward_trill; - } -} - -action copy_hopCount() { - modify_field(trill.hopCount, m.hopCount); -} - -table fix_trill_header { - actions { - copy_hopCount; - } -} - -control ingress { - apply(trill_forward); - apply(fix_trill_header); -} - - -control egress { -} diff --git a/backends/tofino/bf-asm/test/mau/22-BigToSmallFieldWithMask8.p4 b/backends/tofino/bf-asm/test/mau/22-BigToSmallFieldWithMask8.p4 deleted file mode 100644 index 34eca7f4a9b..00000000000 --- a/backends/tofino/bf-asm/test/mau/22-BigToSmallFieldWithMask8.p4 +++ /dev/null @@ -1,58 +0,0 @@ -#ifdef __TARGET_TOFINO__ -#include -#include -#include -#else -#include "includes/tofino.p4" -#endif - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - ethertype : 16; - } -} - -header ethernet_t ethernet; - -parser start { - extract(ethernet); - return ingress; -} - -header_type m1_t { - fields { - f1 : 60; - } -} - -metadata m1_t m1; - -action a1(p1) { - modify_field(m1.f1, p1); -} - -action a2() { - modify_field(ethernet.dstAddr, m1.f1, 0xFF); -} - -table t1 { - actions { - a1; - } -} - -table t2 { - actions { - a2; - } -} - -control ingress { - apply(t1); - apply(t2); -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/mau/22-SimpleTrillThreeStep.p4 b/backends/tofino/bf-asm/test/mau/22-SimpleTrillThreeStep.p4 deleted file mode 100644 index 0cc862aa562..00000000000 --- a/backends/tofino/bf-asm/test/mau/22-SimpleTrillThreeStep.p4 +++ /dev/null @@ -1,124 +0,0 @@ -#ifdef __TARGET_TOFINO__ -#include -#include -#include -#else -#include "includes/tofino.p4" -#endif - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - ethertype : 16; - } -} - -header ethernet_t outer_ethernet; -header ethernet_t inner_ethernet; - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vid : 12; - ethertype : 16; - } -} - -header vlan_tag_t vlan_tag; - -header_type trill_t { - fields { - version : 2; - reserved : 2; - multiDestination : 1; - optLength : 5; - hopCount : 6; - egressRbridge : 16; - ingressRbridge : 16; - } -} - -header trill_t trill; - -header_type my_metadata_t { - fields { - hopCount : 6; - } -} - -metadata my_metadata_t m; - -parser start { - extract(outer_ethernet); - return select(latest.ethertype) { - 0x8100 : parse_vlan_tag; - 0x2222 : parse_trill; - default : ingress; - } -} - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.ethertype) { - 0x2222 : parse_trill; - default : ingress; - } -} - -parser parse_trill { - extract(trill); - extract(inner_ethernet); - return ingress; -} - -/* - * TRILL Forwarding Table - */ -action forward_trill(new_mac_da, new_mac_sa, new_vlan_id, new_port) { - modify_field(outer_ethernet.dstAddr, new_mac_da); - modify_field(outer_ethernet.srcAddr, new_mac_sa); - modify_field(vlan_tag.vid, new_vlan_id); - modify_field(ig_intr_md_for_tm.ucast_egress_port, new_port); - add_to_field(m.hopCount, -1); -} - -table trill_forward { - reads { - trill.egressRbridge : exact; - } - actions { - forward_trill; - } -} - -action do_copy_hopCount_to_m() { - bit_and(m.hopCount, trill.hopCount, 0x3f); -} - -table copy_hopCount_to_m { - actions { - do_copy_hopCount_to_m; - } -} - -action do_copy_hopCount_from_m() { - modify_field(trill.hopCount, m.hopCount); -} - -table copy_hopCount_from_m { - actions { - do_copy_hopCount_from_m; - } -} - -control ingress { - apply(copy_hopCount_to_m); - apply(trill_forward); - apply(copy_hopCount_from_m); -} - - -control egress { -} diff --git a/backends/tofino/bf-asm/test/mau/action_params.p4 b/backends/tofino/bf-asm/test/mau/action_params.p4 deleted file mode 100644 index 3f185f0814f..00000000000 --- a/backends/tofino/bf-asm/test/mau/action_params.p4 +++ /dev/null @@ -1,136 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type pkt_t { - fields { - field_a_32 : 32; - field_b_32 : 32; - field_c_32 : 32; - field_d_32 : 32; - - field_e_16 : 16; - field_f_16 : 16; - field_g_16 : 16; - field_h_16 : 16; - field_i_16 : 16; - field_j_16 : 16; - field_k_16 : 16; - - field_i_8 : 8; - field_j_8 : 8; - color_0 : 4; - pad_0 : 4; - color_1 : 8; - color_2 : 8; - color_3 : 8; - } -} - -parser start { - return parse_ethernet; -} - -header pkt_t pkt; - -parser parse_ethernet { - extract(pkt); - return ingress; -} - - -action action_0(param0){ - modify_field(pkt.field_f_16, param0); -} - -//action action_1(param0){ -// modify_field(pkt.field_g_16, param0); -//} - -action action_1(param0, param1, param2){ - modify_field(pkt.field_g_16, param0); - modify_field(pkt.field_i_16, param1); - modify_field(pkt.field_j_16, param2); -} - -//action action_2(param0){ -// modify_field(pkt.field_h_16, param0); -//} - -action action_2(param0, param1, param2){ - modify_field(pkt.field_h_16, param0); - modify_field(pkt.field_i_16, param1); - modify_field(pkt.field_j_16, param2); -} - -action action_3(param0){ - modify_field(pkt.field_k_16, param0); -} - - -action do_nothing(){ - no_op(); -} - -@pragma table_counter gateway_hit -table table_0 { - reads { - pkt.field_e_16 : ternary; - } - actions { - do_nothing; - } - size : 4096; -} - -@pragma table_counter table_miss -table table_1 { - reads { - pkt.field_e_16: exact; - pkt.field_f_16 mask 0xffff : exact; - } - actions { - do_nothing; - - } - default_action : action_1(0xffff,0xdead,0xbeef); - //default_action : action_1(0xf); - size : 16384; -} - -@pragma table_counter table_hit -table table_2 { - reads { - pkt.field_f_16: ternary; - } - actions { - do_nothing; - - } - //default_action: do_nothing; - default_action : action_2(0x1111, 0x2222, 0x3333); - size : 2048; -} - -table table_3 { - reads { - pkt.field_k_16: ternary; - } - actions { - do_nothing; - - } - default_action : action_3(0xf); - size : 2048; -} - -/* Main control flow */ - -control ingress { - if (valid(pkt)){ - apply(table_0); - } else { - apply(table_1); - } - apply(table_2); - apply(table_3); -} diff --git a/backends/tofino/bf-asm/test/mau/basic_ipv4_selection.p4 b/backends/tofino/bf-asm/test/mau/basic_ipv4_selection.p4 deleted file mode 100644 index 6e72baf4428..00000000000 --- a/backends/tofino/bf-asm/test/mau/basic_ipv4_selection.p4 +++ /dev/null @@ -1,215 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -header_type ingress_metadata_t { - fields { - port: 16; - } -} - -metadata ingress_metadata_t /*metadata*/ ingress_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm: csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - - -/* Main control flow */ -control ingress { - apply(ipv4_routing_select_2); -} - - -control egress { -// apply(egress_acl); -} - -field_list ecmp_hash_fields { - ipv4.srcAddr; - ipv4.dstAddr; - ipv4.identification; - ipv4.protocol; -} - - -field_list_calculation ecmp_hash { - input { - ecmp_hash_fields; - } - algorithm : crc16; - output_width : 14; -} - - -table ipv4_routing_select_2 { - reads { - ipv4.dstAddr: lpm; - } - action_profile : ecmp_action_profile; - size : 512; -} - -action_profile ecmp_action_profile { - actions { - nhop_set; - nop; - } - size : 4096; - // optional - dynamic_action_selection : ecmp_selector; -} - -action_selector ecmp_selector { - selection_key : ecmp_hash; // take a field_list_calculation only - // optional - selection_mode : fair; // “resilient” or “non-resilient” -} - -action nhop_set(port) { - modify_field(ipv4.identification, port); -} diff --git a/backends/tofino/bf-asm/test/mau/do_nothing.p4 b/backends/tofino/bf-asm/test/mau/do_nothing.p4 deleted file mode 100644 index 66208821fe0..00000000000 --- a/backends/tofino/bf-asm/test/mau/do_nothing.p4 +++ /dev/null @@ -1,36 +0,0 @@ -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return ingress; -} - -action action_0(){ - no_op(); -} - -table table_0 { - reads { - ethernet.etherType : ternary; - } - actions { - action_0; - } -} - -control ingress { - apply(table_0); -} diff --git a/backends/tofino/bf-asm/test/mau/expected_failures.txt b/backends/tofino/bf-asm/test/mau/expected_failures.txt deleted file mode 100644 index bde2b0e514e..00000000000 --- a/backends/tofino/bf-asm/test/mau/expected_failures.txt +++ /dev/null @@ -1,111 +0,0 @@ -test_config_96_hash_data.p4 bfas - - incorrect asm code for hash_action+counter -test_config_101_switch_msdc.p4 compile - - compiler uses tcam byte swizzler to duplicate 8-bit phv, rather than just loading it directly -test_config_120_tcam_range_4.p4 mismatch - - compiler uses tcam byte swizzler to duplicate 8-bit phv, rather than just loading it directly -test_config_132_meter_pre_color_4.p4 bfas - - compiler uses tcam byte swizzler to duplicate 8-bit phv, rather than just loading it directly -test_config_136_tcam_error_detection.p4 mismatch -test_config_137_tcam_error_detection_2.p4 mismatch -test_config_138_tcam_error_detection_3.p4 mismatch -test_config_139_tcam_error_detection_4.p4 mismatch - -14-Counter.p4 bfas -- invalid asm refers to stat_ptr but doesn't define it. - -test_config_91_gateway_with_split_table.p4 mismatch -- action table split at 8 rows instead of 10? - -debug_issue_3_7_way_table.p4 mismatch -dileep.p4 mismatch -dileep2.p4 mismatch -dileep4.p4 mismatch -test_config_85_table_ordering.p4 mismatch -test_config_97_unrelated_tables.p4 mismatch -test_config_103_first_phase_0.p4 mismatch -- data duplicated on ixbar; assembler always uses first copy in byteswizzle - -12-SmallToBigFieldWithMask8.p4 mismatch -22-BigToSmallFieldWithMask8.p4 mismatch -action_params.p4 mismatch -test_config_114_simple_drop.p4 mismatch -test_config_130_test_default_action.p4 mismatch -test_config_140_table_counter.p4 mismatch -test_config_182_warp_primitive.p4 mismatch -test_config_208_table_no_key.p4 mismatch -test_config_25_no_reads_for_table.p4 mismatch -- missing default_action.allowed_to_be_default_action in context.json - -- uncharacterized failures (FIXME) -01-FlexCounter.p4 compile -02-FlexCounterActionProfile.p4 compile -07-MacAddrCheck.p4 compile -08-MacAddrCheck1.p4 compile -12-Counters.p4 compile -19-SimpleTrill.p4 compile -22-SimpleTrillThreeStep.p4 compile - -dileep10.p4 mismatch -dileep11.p4 mismatch -dileep12.p4 mismatch -dileep8.p4 mismatch -test_config_10_new_crossbar_allocation.p4 compile -test_config_13_first_selection.p4 compile -test_config_78_tcam_with_220_bits_high_nibble_and_version.p4 mismatch -test_config_93_push_and_pop.p4 compile -test_config_100_hash_action.p4 bfas -test_config_123_meter_2.p4 bfas -test_config_124_meter_3.p4 bfas -test_config_125_meter_pre_color.p4 bfas -test_config_126_meter_pre_color_2.p4 bfas -test_config_127_meter_pre_color_3.p4 bfas -test_config_142_stateful_bfd.p4 compile -test_config_148_action_profile.p4 mismatch -test_config_152_stateful_simple_cntr.p4 mismatch -test_config_153_stateful_simple_cntr_with_output.p4 mismatch -test_config_154_stateful_sampling.p4 mismatch -test_config_155_stateful_3_alus.p4 mismatch -test_config_156_indirect_stateful_cntr.p4 mismatch -test_config_157_random_number_generator.p4 bfas -test_config_159_stateful_using_phv_field.p4 mismatch -test_config_160_stateful_single_bit_mode.p4 mismatch -test_config_161_new_primitives.p4 mismatch -test_config_163_stateful_table_math_unit.p4 mismatch -test_config_164_stateful_deterministic_sampling.p4 mismatch -test_config_165_stateful_bfd_failure_detection.p4 mismatch -test_config_166_stateful_generic_counter.p4 mismatch -test_config_167_stateful_flowlet_switching.p4 compile -test_config_168_meter_bug.p4 mismatch -test_config_169_stateful_sflow_sequence.p4 bfas -test_config_170_stateful_selection_table_update.p4 mismatch -test_config_171_stateful_conga.p4 compile -test_config_172_stateful_heavy_hitter.p4 bfas -test_config_173_stateful_bloom_filter.p4 compile -test_config_175_match_table_with_no_key.p4 mismatch -test_config_177_meter_test.p4 bfas -test_config_180_first_proxy_hash.p4 mismatch -test_config_181_first_alg_tcam.p4 bfas -test_config_183_sample_e2e.p4 compile -test_config_184_stateful_bug1.p4 bfas -test_config_185_first_lpf.p4 mismatch -test_config_187_proxy_hash_2.p4 mismatch -test_config_189_stat_with_lrt.p4 mismatch -test_config_190_modify_with_expr.p4 compile -test_config_191_invalidate.p4 mismatch -test_config_192_stateful_driven_by_hash.p4 bfas -test_config_193_indirect_stats_no_reads.p4 bfas -test_config_195_stateful_predicate_output.p4 mismatch -test_config_196_hit_miss.p4 mismatch -test_config_197_default_next_table.p4 mismatch -test_config_198_shared_action_profile.p4 mismatch -test_config_199_stateful_constant_index.p4 bfas -test_config_200_counter_constant_index.p4 mismatch -test_config_201_meter_constant_index.p4 bfas -test_config_203_first_reduction_or.p4 mismatch -test_config_204_no_tables_in_stage0.p4 mismatch -test_config_205_modify_field_from_hash.p4 compile -test_config_206_stateful_logging.p4 bfas -test_config_209_pack_hash_dist.p4 mismatch -vk_basic_ipv4_20150706.p4 mismatch -vk_basic_ipv4_subset.p4 mismatch diff --git a/backends/tofino/bf-asm/test/mau/instruct1.p4 b/backends/tofino/bf-asm/test/mau/instruct1.p4 deleted file mode 100644 index e0f12c83018..00000000000 --- a/backends/tofino/bf-asm/test/mau/instruct1.p4 +++ /dev/null @@ -1,61 +0,0 @@ - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; -header_type data2_t { - fields { - x1 : 16; - x2 : 16; - } -} -header data2_t hdr1; -header data2_t hdr2; - -parser start { - extract(data); - return select(data.b1) { - 0x00: parse_data2; - default: ingress; - } -} -parser parse_data2 { - extract(hdr1); - return select(hdr1.x1) { - 1 mask 1: parse_hdr2; - default: ingress; - } -} -parser parse_hdr2 { - extract(hdr2); - return ingress; -} - -action noop() { } -action decap() { - copy_header(hdr1, hdr2); - remove_header(hdr2); -} - -table test1 { - reads { - data.f1 : exact; - } - actions { - decap; - noop; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/mau/selector1.p4 b/backends/tofino/bf-asm/test/mau/selector1.p4 deleted file mode 100644 index 6482f718ab2..00000000000 --- a/backends/tofino/bf-asm/test/mau/selector1.p4 +++ /dev/null @@ -1,60 +0,0 @@ -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -field_list sel_fields { - data.f1; - data.f2; - data.f3; - data.f4; -} - -field_list_calculation sel_hash { - input { - sel_fields; - } - algorithm : crc16; - output_width : 16; -} - -action_selector sel { - selection_key : sel_hash; - selection_mode : fair; -} - -action noop(param0) { modify_field(data.b1, param0); } - -action_profile sel_profile { - actions { - noop; - } - size : 16384; - dynamic_action_selection : sel; -} - -table test1 { - reads { - data.b1 : exact; - } - action_profile : sel_profile; - size : 1024; -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/mau/ternary_match0.p4 b/backends/tofino/bf-asm/test/mau/ternary_match0.p4 deleted file mode 100644 index df0c0f900c0..00000000000 --- a/backends/tofino/bf-asm/test/mau/ternary_match0.p4 +++ /dev/null @@ -1,34 +0,0 @@ - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } - -table test1 { - reads { - data.f1 : ternary; - } - actions { - noop; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/meter_test1.p4 b/backends/tofino/bf-asm/test/meter_test1.p4 deleted file mode 100644 index 26af0800d1b..00000000000 --- a/backends/tofino/bf-asm/test/meter_test1.p4 +++ /dev/null @@ -1,69 +0,0 @@ -header_type data_t { - fields { - f1 : 32; - f2 : 32; - h1 : 16; - h2 : 16; - h3 : 16; - h4 : 16; - h5 : 16; - h6 : 16; - color_1 : 8; - color_2 : 8; - } -} - -header data_t data; -parser start { - extract (data); - return ingress; -} - -action h1_3(val1, val2, val3) { - modify_field(data.h1, val1); - modify_field(data.h2, val2); - modify_field(data.h3, val3); -} - -action h4_6(val4, val5, val6, port) { - modify_field(data.h4, val4); - modify_field(data.h5, val5); - modify_field(data.h6, val6); - modify_field(standard_metadata.egress_spec, port); -} - - -meter meter_1 { - type : bytes; - direct : test1; - result : data.color_1; -} - -meter meter_2 { - type : bytes; - direct : test2; - result : data.color_2; -} - -table test1 { - reads { - data.f1 : exact; - } actions { - h1_3; - } - size : 6000; -} - -table test2 { - reads { - data.f2 : exact; - } actions { - h4_6; - } - size : 10000; -} - -control ingress { - apply(test1); - apply(test2); -} diff --git a/backends/tofino/bf-asm/test/parser1.p4 b/backends/tofino/bf-asm/test/parser1.p4 deleted file mode 100644 index 8cc97cb8313..00000000000 --- a/backends/tofino/bf-asm/test/parser1.p4 +++ /dev/null @@ -1,154 +0,0 @@ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - -header_type mpls_t { - fields { - label : 20; - tc : 3; - bos : 1; - ttl : 8; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -parser start { - return parse_ethernet; -} - -#define ETHERTYPE_CPU 0x9000, 0x010c -#define ETHERTYPE_VLAN 0x8100, 0x9100, 0x9200, 0x9300 -#define ETHERTYPE_MPLS 0x8847 -#define ETHERTYPE_IPV4 0x0800 -#define ETHERTYPE_IPV6 0x86dd -#define ETHERTYPE_ARP 0x0806 -#define ETHERTYPE_RARP 0x8035 -#define ETHERTYPE_NSH 0x894f -#define ETHERTYPE_ETHERNET 0x6558 -#define ETHERTYPE_ROCE 0x8915 -#define ETHERTYPE_FCOE 0x8906 -/* missing: vlan_3b, vlan_5b, ieee802_1q, ieee802_1ad */ - -#define IPV4_MULTICAST_MAC 0x01005E -#define IPV6_MULTICAST_MAC 0x3333 - -/* Tunnel types */ -#define TUNNEL_TYPE_NONE 0 -#define TUNNEL_TYPE_VXLAN 1 -#define TUNNEL_TYPE_GRE 2 -#define TUNNEL_TYPE_GENEVE 3 -#define TUNNEL_TYPE_NVGRE 4 -#define TUNNEL_TYPE_MPLS 5 - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - ETHERTYPE_VLAN : parse_vlan; - ETHERTYPE_MPLS : parse_mpls; - ETHERTYPE_IPV4 : parse_ipv4; - default: ingress; - } -} - -#define VLAN_DEPTH 2 -header vlan_tag_t vlan_tag_[VLAN_DEPTH]; - -parser parse_vlan { - extract(vlan_tag_[next]); - return select(latest.etherType) { - ETHERTYPE_VLAN : parse_vlan; - ETHERTYPE_MPLS : parse_mpls; - ETHERTYPE_IPV4 : parse_ipv4; - default: ingress; - } -} - -#define MPLS_DEPTH 3 -/* all the tags but the last one */ -header mpls_t mpls[MPLS_DEPTH]; - -/* last mpls tag in the stack */ -header mpls_t mpls_bos; - -/* TODO: this will be optimized when pushed to the chip ? */ - -parser parse_mpls { - return select(current(23, 1)) { - 0 : parse_mpls_not_bos; - 1 : parse_mpls_bos; - default: ingress; - } -} - -parser parse_mpls_not_bos { - extract(mpls[next]); - return parse_mpls; -} - -parser parse_mpls_bos { - extract(mpls_bos); - return select(current(0, 4)) { - 0x4 : parse_ipv4; - default : ingress; - } -} - -#define IP_PROTOCOLS_ICMP 1 -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 -#define IP_PROTOCOLS_GRE 47 -#define IP_PROTOCOLS_IPSEC_ESP 50 -#define IP_PROTOCOLS_IPSEC_AH 51 -#define IP_PROTOCOLS_ICMPV6 58 -#define IP_PROTOCOLS_SCTP 132 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -action do_noop() { } - -table do_nothing { - reads { - ethernet.dstAddr : exact; - } - actions { - do_noop; - } -} - -control ingress { apply(do_nothing); } diff --git a/backends/tofino/bf-asm/test/parser2.p4 b/backends/tofino/bf-asm/test/parser2.p4 deleted file mode 100644 index 575c533cc66..00000000000 --- a/backends/tofino/bf-asm/test/parser2.p4 +++ /dev/null @@ -1,255 +0,0 @@ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - -header_type mpls_t { - fields { - label : 20; - tc : 3; - bos : 1; - ttl : 8; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type ipv6_t { - fields { - version : 4; - trafficClass : 8; - flowLabel : 20; - payloadLen : 16; - nextHdr : 8; - hopLimit : 8; - srcAddr : 128; - dstAddr : 128; - } -} - -header_type icmp_t { - fields { - type_ : 8; - code : 8; - hdrChecksum : 16; - } -} - -header_type icmpv6_t { - fields { - type_ : 8; - code : 8; - hdrChecksum : 16; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 4; - flags : 8; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - length_ : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -#define ETHERTYPE_CPU 0x9000, 0x010c -#define ETHERTYPE_VLAN 0x8100, 0x9100, 0x9200, 0x9300 -#define ETHERTYPE_MPLS 0x8847 -#define ETHERTYPE_IPV4 0x0800 -#define ETHERTYPE_IPV6 0x86dd -#define ETHERTYPE_ARP 0x0806 -#define ETHERTYPE_RARP 0x8035 -#define ETHERTYPE_NSH 0x894f -#define ETHERTYPE_ETHERNET 0x6558 -#define ETHERTYPE_ROCE 0x8915 -#define ETHERTYPE_FCOE 0x8906 -/* missing: vlan_3b, vlan_5b, ieee802_1q, ieee802_1ad */ - -#define IPV4_MULTICAST_MAC 0x01005E -#define IPV6_MULTICAST_MAC 0x3333 - -/* Tunnel types */ -#define TUNNEL_TYPE_NONE 0 -#define TUNNEL_TYPE_VXLAN 1 -#define TUNNEL_TYPE_GRE 2 -#define TUNNEL_TYPE_GENEVE 3 -#define TUNNEL_TYPE_NVGRE 4 -#define TUNNEL_TYPE_MPLS 5 - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - ETHERTYPE_VLAN : parse_vlan; - ETHERTYPE_MPLS : parse_mpls; - ETHERTYPE_IPV4 : parse_ipv4; - ETHERTYPE_IPV6 : parse_ipv6; - default: ingress; - } -} - -#define VLAN_DEPTH 2 -header vlan_tag_t vlan_tag_[VLAN_DEPTH]; - -parser parse_vlan { - extract(vlan_tag_[next]); - return select(latest.etherType) { - ETHERTYPE_VLAN : parse_vlan; - ETHERTYPE_MPLS : parse_mpls; - ETHERTYPE_IPV4 : parse_ipv4; - ETHERTYPE_IPV6 : parse_ipv6; - default: ingress; - } -} - -#define MPLS_DEPTH 3 -/* all the tags but the last one */ -header mpls_t mpls[MPLS_DEPTH]; - -/* last mpls tag in the stack */ -header mpls_t mpls_bos; - -/* TODO: this will be optimized when pushed to the chip ? */ - -parser parse_mpls { - return select(current(23, 1)) { - 0 : parse_mpls_not_bos; - 1 : parse_mpls_bos; - default: ingress; - } -} - -parser parse_mpls_not_bos { - extract(mpls[next]); - return parse_mpls; -} - -parser parse_mpls_bos { - extract(mpls_bos); - return select(current(0, 4)) { - 0x4 : parse_ipv4; - 0x6 : parse_ipv6; - default : ingress; - } -} - -#define IP_PROTOCOLS_ICMP 1 -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 -#define IP_PROTOCOLS_GRE 47 -#define IP_PROTOCOLS_IPSEC_ESP 50 -#define IP_PROTOCOLS_IPSEC_AH 51 -#define IP_PROTOCOLS_ICMPV6 58 -#define IP_PROTOCOLS_SCTP 132 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_ICMP : parse_icmp; - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header ipv6_t ipv6; - -parser parse_ipv6 { - extract(ipv6); - return select(latest.nextHdr) { - IP_PROTOCOLS_ICMPV6 : parse_icmpv6; - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header icmp_t icmp; - -parser parse_icmp { - extract(icmp); - return ingress; -} - -header icmpv6_t icmpv6; - -parser parse_icmpv6 { - extract(icmpv6); - return ingress; -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -action do_noop() { } - -table do_nothing { - reads { - ethernet.dstAddr : exact; - } - actions { - do_noop; - } -} - -control ingress { apply(do_nothing); } diff --git a/backends/tofino/bf-asm/test/parser3.p4 b/backends/tofino/bf-asm/test/parser3.p4 deleted file mode 100644 index fd743ba43ae..00000000000 --- a/backends/tofino/bf-asm/test/parser3.p4 +++ /dev/null @@ -1,63 +0,0 @@ - -header_type data1_t { - fields { - f1 : 32; - x1 : 2; - x2 : 4; - x3 : 4; - x4 : 4; - x5 : 2; - x6 : 5; - x7 : 2; - x8 : 1; - } -} -header data1_t data1; -header_type data2_t { - fields { - a1 : 8; - a2 : 4; - a3 : 4; - a4 : 8; - a5 : 4; - a6 : 4; - } -} -header data2_t data2; -#if 0 -header_type data3_t { - fields { - b1 : 13; - b2 : 3; - } -} -header data3_t data3; -#endif - -parser start { - extract(data1); - return select(data1.x3, data1.x1, data1.x7) { - 0xe4: parse_data2; - default: ingress; - } -} - -parser parse_data2 { - extract(data2); - return ingress; -} - -action noop() { } - -table test1 { - reads { - data1.f1 : exact; - } - actions { - noop; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/parser_dc_full.p4 b/backends/tofino/bf-asm/test/parser_dc_full.p4 deleted file mode 100644 index 6c33dcf0139..00000000000 --- a/backends/tofino/bf-asm/test/parser_dc_full.p4 +++ /dev/null @@ -1,959 +0,0 @@ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type snap_header_t { - fields { - dsap : 8; - ssap : 8; - control_ : 8; - oui : 24; - type_ : 16; - } -} - -header_type roce_header_t { - fields { - ib_grh : 320; - ib_bth : 96; - } -} - -header_type roce_v2_header_t { - fields { - ib_bth : 96; - } -} - -header_type fcoe_header_t { - fields { - version : 4; - type_ : 4; - sof : 8; - rsvd1 : 32; - ts_upper : 32; - ts_lower : 32; - size_ : 32; - eof : 8; - rsvd2 : 24; - } -} - -header_type cpu_header_t { - fields { - qid : 3; - pad : 1; - reason_code : 12; - rxhash : 16; - bridge_domain : 16; - ingress_lif : 16; - egress_lif : 16; - lu_bypass_ingress : 1; - lu_bypass_egress : 1; - pad1 : 14; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - -header_type vlan_tag_3b_t { - fields { - pcp : 3; - cfi : 1; - vid : 4; - etherType : 16; - } -} -header_type vlan_tag_5b_t { - fields { - pcp : 3; - cfi : 1; - vid : 20; - etherType : 16; - } -} - -header_type ieee802_1ah_t { - fields { - pcp : 3; - dei : 1; - uca : 1; - reserved : 3; - i_sid : 24; - } -} - -header_type mpls_t { - fields { - label : 20; - tc : 3; - bos : 1; - ttl : 8; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type ipv6_t { - fields { - version : 4; - trafficClass : 8; - flowLabel : 20; - payloadLen : 16; - nextHdr : 8; - hopLimit : 8; - srcAddr : 128; - dstAddr : 128; - } -} - -header_type icmp_t { - fields { - type_ : 8; - code : 8; - hdrChecksum : 16; - } -} - -header_type icmpv6_t { - fields { - type_ : 8; - code : 8; - hdrChecksum : 16; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 4; - flags : 8; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - length_ : 16; - checksum : 16; - } -} - -header_type sctp_t { - fields { - srcPort : 16; - dstPort : 16; - verifTag : 32; - checksum : 32; - } -} - -header_type gre_t { - fields { - C : 1; - R : 1; - K : 1; - S : 1; - s : 1; - recurse : 3; - flags : 5; - ver : 3; - proto : 16; - } -} - -header_type nvgre_t { - fields { - tni : 24; - reserved : 8; - } -} - -/* 8 bytes */ -header_type erspan_header_v1_t { - fields { - version : 4; - vlan : 12; - priority : 6; - span_id : 10; - direction : 8; - truncated: 8; - } -} - -/* 8 bytes */ -header_type erspan_header_v2_t { - fields { - version : 4; - vlan : 12; - priority : 6; - span_id : 10; - unknown7 : 32; - } -} - -header_type ipsec_esp_t { - fields { - spi : 32; - seqNo : 32; - } -} - -header_type ipsec_ah_t { - fields { - nextHdr : 8; - length_ : 8; - zero : 16; - spi : 32; - seqNo : 32; - } -} - -header_type arp_rarp_t { - fields { - hwType : 16; - protoType : 16; - hwAddrLen : 8; - protoAddrLen : 8; - opcode : 16; - } -} - -header_type arp_rarp_ipv4_t { - fields { - srcHwAddr : 48; - srcProtoAddr : 32; - dstHwAddr : 48; - dstProtoAddr : 32; - } -} - -header_type eompls_t { - fields { - zero : 4; - reserved : 12; - seqNo : 16; - } -} - -header_type vxlan_t { - fields { - flags : 8; - reserved : 24; - vni : 24; - reserved2 : 8; - } -} - -header_type nsh_t { - fields { - oam : 1; - context : 1; - flags : 6; - reserved : 8; - protoType: 16; - spath : 24; - sindex : 8; - } -} - -header_type nsh_context_t { - fields { - network_platform : 32; - network_shared : 32; - service_platform : 32; - service_shared : 32; - } -} - -/* GENEVE HEADERS - 3 possible options with known type, known length */ - -header_type genv_t { - fields { - ver : 2; - optLen : 6; - oam : 1; - critical : 1; - reserved : 6; - protoType : 16; - vni : 24; - reserved2 : 8; - } -} - -#define GENV_OPTION_A_TYPE 0x000001 -/* TODO: Would it be convenient to have some kind of sizeof macro ? */ -#define GENV_OPTION_A_LENGTH 2 /* in bytes */ - -header_type genv_opt_A_t { - fields { - optClass : 16; - optType : 8; - reserved : 3; - optLen : 5; - data : 32; - } -} - -#define GENV_OPTION_B_TYPE 0x000002 -#define GENV_OPTION_B_LENGTH 3 /* in bytes */ - -header_type genv_opt_B_t { - fields { - optClass : 16; - optType : 8; - reserved : 3; - optLen : 5; - data : 64; - } -} - -#define GENV_OPTION_C_TYPE 0x000003 -#define GENV_OPTION_C_LENGTH 2 /* in bytes */ - -header_type genv_opt_C_t { - fields { - optClass : 16; - optType : 8; - reserved : 3; - optLen : 5; - data : 32; - } -} -parser start { - return parse_input_port; -} - -header_type input_port_hdr_t { - fields { - port : 16; - } -} - -header input_port_hdr_t input_port_hdr; - -parser parse_input_port { - extract (input_port_hdr); - return parse_ethernet; -} - -#define ETHERTYPE_CPU 0x9000, 0x010c -#define ETHERTYPE_VLAN 0x8100, 0x9100, 0x9200, 0x9300 -#define ETHERTYPE_MPLS 0x8847 -#define ETHERTYPE_IPV4 0x0800 -#define ETHERTYPE_IPV6 0x86dd -#define ETHERTYPE_ARP 0x0806 -#define ETHERTYPE_RARP 0x8035 -#define ETHERTYPE_NSH 0x894f -#define ETHERTYPE_ETHERNET 0x6558 -#define ETHERTYPE_ROCE 0x8915 -#define ETHERTYPE_FCOE 0x8906 -/* missing: vlan_3b, vlan_5b, ieee802_1q, ieee802_1ad */ - -#define IPV4_MULTICAST_MAC 0x01005E -#define IPV6_MULTICAST_MAC 0x3333 - -/* Tunnel types */ -#define TUNNEL_TYPE_NONE 0 -#define TUNNEL_TYPE_VXLAN 1 -#define TUNNEL_TYPE_GRE 2 -#define TUNNEL_TYPE_GENEVE 3 -#define TUNNEL_TYPE_NVGRE 4 -#define TUNNEL_TYPE_MPLS 5 - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0 mask 0xf800: parse_snap_header; /* < 1536 */ - ETHERTYPE_CPU : parse_cpu_header; - ETHERTYPE_VLAN : parse_vlan; - ETHERTYPE_MPLS : parse_mpls; - ETHERTYPE_IPV4 : parse_ipv4; - ETHERTYPE_IPV6 : parse_ipv6; - ETHERTYPE_ARP : parse_arp_rarp; - ETHERTYPE_RARP : parse_arp_rarp; - ETHERTYPE_NSH : parse_nsh; - ETHERTYPE_ROCE: parse_roce; - ETHERTYPE_FCOE: parse_fcoe; - default: ingress; - } -} - -header snap_header_t snap_header; - -parser parse_snap_header { - extract(snap_header); - return ingress; -} - -header roce_header_t roce; - -parser parse_roce { - extract(roce); - return ingress; -} - -header fcoe_header_t fcoe; - -parser parse_fcoe { - extract(fcoe); - return ingress; -} - -header cpu_header_t cpu_header; - -parser parse_cpu_header { - extract(cpu_header); - return select(latest.etherType) { - 0 mask 0xf800: parse_snap_header; /* < 1536 */ - ETHERTYPE_VLAN : parse_vlan; - ETHERTYPE_MPLS : parse_mpls; - ETHERTYPE_IPV4 : parse_ipv4; - ETHERTYPE_IPV6 : parse_ipv6; - ETHERTYPE_ARP : parse_arp_rarp; - ETHERTYPE_RARP : parse_arp_rarp; - ETHERTYPE_NSH : parse_nsh; - ETHERTYPE_ROCE: parse_roce; - ETHERTYPE_FCOE: parse_fcoe; - default: ingress; - } -} - -#define VLAN_DEPTH 2 -header vlan_tag_t vlan_tag_[VLAN_DEPTH]; -header vlan_tag_3b_t vlan_tag_3b[VLAN_DEPTH]; -header vlan_tag_5b_t vlan_tag_5b[VLAN_DEPTH]; - -parser parse_vlan { - extract(vlan_tag_[next]); - return select(latest.etherType) { - ETHERTYPE_VLAN : parse_vlan; - ETHERTYPE_MPLS : parse_mpls; - ETHERTYPE_IPV4 : parse_ipv4; - ETHERTYPE_IPV6 : parse_ipv6; - ETHERTYPE_ARP : parse_arp_rarp; - ETHERTYPE_RARP : parse_arp_rarp; - default: ingress; - } -} - -#define MPLS_DEPTH 3 -/* all the tags but the last one */ -header mpls_t mpls[MPLS_DEPTH]; - -/* last mpls tag in the stack */ -header mpls_t mpls_bos; - -/* TODO: this will be optimized when pushed to the chip ? */ - -parser parse_mpls { - return select(current(23, 1)) { - 0 : parse_mpls_not_bos; - 1 : parse_mpls_bos; - default: ingress; - } -} - -parser parse_mpls_not_bos { - extract(mpls[next]); - return parse_mpls; -} - -parser parse_mpls_bos { - extract(mpls_bos); - return select(current(0, 4)) { - 0x4 : parse_inner_ipv4; - 0x6 : parse_inner_ipv6; - default : parse_eompls; - } -} - -#define IP_PROTOCOLS_ICMP 1 -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 -#define IP_PROTOCOLS_GRE 47 -#define IP_PROTOCOLS_IPSEC_ESP 50 -#define IP_PROTOCOLS_IPSEC_AH 51 -#define IP_PROTOCOLS_ICMPV6 58 -#define IP_PROTOCOLS_SCTP 132 - -header ipv4_t ipv4; - -field_list ipv4_checksum_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_checksum { - input { - ipv4_checksum_list; - } - algorithm : csum16; - output_width : 16; -} - -calculated_field ipv4.hdrChecksum { -#ifdef __TARGET_TOFINO__ - verify ipv4_checksum; - update ipv4_checksum; -#else - verify ipv4_checksum if(ipv4.ihl == 5); - update ipv4_checksum if(ipv4.ihl == 5); -#endif -} - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_ICMP : parse_icmp; - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - IP_PROTOCOLS_GRE : parse_gre; -// IP_PROTOCOLS_SCTP : parse_sctp; - default: ingress; - } -} - -header ipv6_t ipv6; - -parser parse_ipv6 { - extract(ipv6); - return select(latest.nextHdr) { - IP_PROTOCOLS_ICMPV6 : parse_icmpv6; - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - IP_PROTOCOLS_GRE : parse_gre; -// IP_PROTOCOLS_SCTP : parse_sctp; - default: ingress; - } -} - -header icmp_t icmp; - -parser parse_icmp { - extract(icmp); - return ingress; -} - -header icmpv6_t icmpv6; - -parser parse_icmpv6 { - extract(icmpv6); - return ingress; -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -#define UDP_PORT_VXLAN 4789 -#define UDP_PORT_GENV 6081 -// Check IANA UDP port number - #define UDP_PORT_ROCE_V2 1021 - -header udp_t udp; - -header roce_v2_header_t roce_v2; - -parser parse_roce_v2 { - extract(roce_v2); - return ingress; -} - -parser parse_udp { - extract(udp); - return select(latest.dstPort) { - UDP_PORT_VXLAN : parse_vxlan; - UDP_PORT_GENV: parse_geneve; - UDP_PORT_ROCE_V2: parse_roce_v2; - default: ingress; - } -} - -header sctp_t sctp; - -parser parse_sctp { - extract(sctp); - return ingress; -} - - -#define GRE_PROTOCOLS_NVGRE 0x6558 -#define GRE_PROTOCOLS_GRE 0x6559 -#define GRE_PROTOCOLS_ERSPAN_V1 0x88BE -#define GRE_PROTOCOLS_ERSPAN_V2 0x22EB - -#define GRE_DEPTH 2 - -//header gre_t gre[GRE_DEPTH]; -header gre_t gre; - -#if 0 -header_type gre_opt_t { - fields { - key : 32; - } -} - -header gre_opt_t gre_opt; - -parser parse_gre_key { - extract(gre_opt); - return ingress; -} -parser parse_gre_key2 { - extract(gre_opt); - extract(gre_opt); - return ingress; -} -parser parse_gre_key22 { - extract(gre_opt); - extract(gre_opt); - return ingress; -} -parser parse_gre_opt1 { - extract(gre_opt); - return ingress; -} -parser parse_gre_opt2 { - extract(gre_opt); - extract(gre_opt); - return ingress; -} -parser parse_gre_opt3 { - extract(gre_opt); - extract(gre_opt); - extract(gre_opt); - return ingress; -} - -parser parse_gre_opts { - return select(latest.C, latest.S, latest.K) { - 1 mask 0x0000 : parse_gre_key; - 2 mask 0x0000 : parse_gre_opt1; - 3 mask 0x0000 : parse_gre_key2; - 4 mask 0x0000 : parse_gre_opt1; - 5 mask 0x0000 : parse_gre_key22; - 6 mask 0x0000 : parse_gre_opt2; - 7 mask 0x0000 : parse_gre_opt3; - default: ingress; - } -} -#endif - -parser parse_gre { - extract(gre); -// parse_gre_opts; - return select(latest.K, latest.proto) { - GRE_PROTOCOLS_NVGRE : parse_nvgre; -// GRE_PROTOCOLS_GRE : parse_gre; - GRE_PROTOCOLS_ERSPAN_V1 : parse_erspan_v1; - GRE_PROTOCOLS_ERSPAN_V2 : parse_erspan_v2; - ETHERTYPE_NSH : parse_nsh; - default: ingress; - } -} - -header nvgre_t nvgre; -header ethernet_t inner_ethernet; - -header ipv4_t inner_ipv4; -header ipv6_t inner_ipv6; -header ipv4_t outer_ipv4; -header ipv6_t outer_ipv6; - -field_list inner_ipv4_checksum_list { - inner_ipv4.version; - inner_ipv4.ihl; - inner_ipv4.diffserv; - inner_ipv4.totalLen; - inner_ipv4.identification; - inner_ipv4.flags; - inner_ipv4.fragOffset; - inner_ipv4.ttl; - inner_ipv4.protocol; - inner_ipv4.srcAddr; - inner_ipv4.dstAddr; -} - -field_list_calculation inner_ipv4_checksum { - input { - inner_ipv4_checksum_list; - } - algorithm : csum16; - output_width : 16; -} - -calculated_field inner_ipv4.hdrChecksum { -#ifdef __TARGET_TOFINO__ - verify inner_ipv4_checksum; - update inner_ipv4_checksum; -#else - verify inner_ipv4_checksum if(valid(ipv4)); - update inner_ipv4_checksum if(valid(ipv4)); -#endif -} - -header udp_t outer_udp; - -parser parse_nvgre { - extract(nvgre); - return parse_inner_ethernet; -} - -header erspan_header_v1_t erspan_v1_header; - -parser parse_erspan_v1 { - extract(erspan_v1_header); - return ingress; -} - -header erspan_header_v2_t erspan_v2_header; - -parser parse_erspan_v2 { - extract(erspan_v2_header); - return ingress; -} - -#define ARP_PROTOTYPES_ARP_RARP_IPV4 0x0800 - -header arp_rarp_t arp_rarp; - -parser parse_arp_rarp { - extract(arp_rarp); - return select(latest.protoType) { - ARP_PROTOTYPES_ARP_RARP_IPV4 : parse_arp_rarp_ipv4; - default: ingress; - } -} - -header arp_rarp_ipv4_t arp_rarp_ipv4; - -parser parse_arp_rarp_ipv4 { - extract(arp_rarp_ipv4); - return ingress; -} - -header eompls_t eompls; - -parser parse_eompls { - extract(eompls); - extract(inner_ethernet); - return ingress; -} - -header vxlan_t vxlan; - -parser parse_vxlan { - extract(vxlan); - return parse_inner_ethernet; -} - -header genv_t genv; - -header genv_opt_A_t genv_opt_A; -header genv_opt_B_t genv_opt_B; -header genv_opt_C_t genv_opt_C; - -parser parse_geneve { - extract(genv); - /* - counter_init(counter_1, latest.optLen); - return select(latest.optLen) { - 0 : parse_genv_inner; - default : parse_genv_opts; - } - */ - return parse_genv_inner; -} - -#if 0 - -parser parse_genv_opts { - /* switching on combined class and type */ - return select(current(0, 24)) { - GENV_OPTION_A_TYPE: parse_genv_opt_A; - GENV_OPTION_B_TYPE: parse_genv_opt_B; - GENV_OPTION_C_TYPE: parse_genv_opt_C; - } -} - -parser parse_genv_opt_A { - extract(genv_opt_A); - counter_decrement(counter_1, GENV_OPTION_A_LENGTH); - return select(counter_1) { - 0 : parse_genv_inner; - default : parse_genv_opts; - } -} - -parser parse_genv_opt_B { - extract(genv_opt_B); - counter_decrement(counter_1, GENV_OPTION_B_LENGTH); - return select(counter_1) { - 0 : parse_genv_inner; - default : parse_genv_opts; - } -} - -parser parse_genv_opt_C { - extract(genv_opt_C); - counter_decrement(counter_1, GENV_OPTION_C_LENGTH); - return select(counter_1) { - 0 : parse_genv_inner; - default : parse_genv_opts; - } -} -#endif - -parser parse_genv_inner { - return select(genv.protoType) { - ETHERTYPE_ETHERNET : parse_inner_ethernet; - ETHERTYPE_IPV4 : parse_inner_ipv4; - ETHERTYPE_IPV6 : parse_inner_ipv6; - default : ingress; - } -} - -header nsh_t nsh; -header nsh_context_t nsh_context; - -parser parse_nsh { - extract(nsh); - extract(nsh_context); - return select(nsh.protoType) { - ETHERTYPE_IPV4 : parse_inner_ipv4; - ETHERTYPE_IPV6 : parse_inner_ipv6; - ETHERTYPE_ETHERNET : parse_inner_ethernet; - default: ingress; - } -} - -parser parse_inner_ipv4 { - extract(inner_ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_ICMP : parse_inner_icmp; - IP_PROTOCOLS_TCP : parse_inner_tcp; - IP_PROTOCOLS_UDP : parse_inner_udp; -// IP_PROTOCOLS_SCTP : parse_inner_sctp; - default: ingress; - } -} - -header icmp_t inner_icmp; - -parser parse_inner_icmp { - extract(inner_icmp); - return ingress; -} - -header tcp_t inner_tcp; - -parser parse_inner_tcp { - extract(inner_tcp); - return ingress; -} - -header udp_t inner_udp; - -parser parse_inner_udp { - extract(inner_udp); - return ingress; -} - -header sctp_t inner_sctp; - -parser parse_inner_sctp { - extract(inner_sctp); - return ingress; -} - -parser parse_inner_ipv6 { - extract(inner_ipv6); - return select(latest.nextHdr) { - IP_PROTOCOLS_ICMPV6 : parse_inner_icmpv6; - IP_PROTOCOLS_TCP : parse_inner_tcp; - IP_PROTOCOLS_UDP : parse_inner_udp; -// IP_PROTOCOLS_SCTP : parse_inner_sctp; - default: ingress; - } -} - -header icmpv6_t inner_icmpv6; - -parser parse_inner_icmpv6 { - extract(inner_icmpv6); - return ingress; -} - -parser parse_inner_ethernet { - extract(inner_ethernet); - return select(latest.etherType) { - ETHERTYPE_IPV4 : parse_inner_ipv4; - ETHERTYPE_IPV6 : parse_inner_ipv6; - default: ingress; - } -} - -action do_noop() { } - -table do_nothing { - reads { - ethernet.dstAddr : exact; - } - actions { - do_noop; - } -} - -control ingress { apply(do_nothing); } diff --git a/backends/tofino/bf-asm/test/port_vlan_mapping.p4 b/backends/tofino/bf-asm/test/port_vlan_mapping.p4 deleted file mode 100644 index 5c01dfc1d20..00000000000 --- a/backends/tofino/bf-asm/test/port_vlan_mapping.p4 +++ /dev/null @@ -1,1415 +0,0 @@ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type snap_header_t { - fields { - dsap : 8; - ssap : 8; - control_ : 8; - oui : 24; - type_ : 16; - } -} - -header_type roce_header_t { - fields { - ib_grh : 320; - ib_bth : 96; - } -} - -header_type roce_v2_header_t { - fields { - ib_bth : 96; - } -} - -header_type fcoe_header_t { - fields { - version : 4; - type_ : 4; - sof : 8; - rsvd1 : 32; - ts_upper : 32; - ts_lower : 32; - size_ : 32; - eof : 8; - rsvd2 : 24; - } -} - -header_type cpu_header_t { - fields { - qid : 3; - pad : 1; - reason_code : 12; - rxhash : 16; - bridge_domain : 16; - ingress_lif : 16; - egress_lif : 16; - lu_bypass_ingress : 1; - lu_bypass_egress : 1; - pad1 : 14; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - -header_type vlan_tag_3b_t { - fields { - pcp : 3; - cfi : 1; - vid : 4; - etherType : 16; - } -} -header_type vlan_tag_5b_t { - fields { - pcp : 3; - cfi : 1; - vid : 20; - etherType : 16; - } -} - -header_type ieee802_1ah_t { - fields { - pcp : 3; - dei : 1; - uca : 1; - reserved : 3; - i_sid : 24; - } -} - -header_type mpls_t { - fields { - label : 20; - tc : 3; - bos : 1; - ttl : 8; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type ipv6_t { - fields { - version : 4; - trafficClass : 8; - flowLabel : 20; - payloadLen : 16; - nextHdr : 8; - hopLimit : 8; - srcAddr : 128; - dstAddr : 128; - } -} - -header_type icmp_t { - fields { - type_ : 8; - code : 8; - hdrChecksum : 16; - } -} - -header_type icmpv6_t { - fields { - type_ : 8; - code : 8; - hdrChecksum : 16; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 4; - flags : 8; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - length_ : 16; - checksum : 16; - } -} - -header_type sctp_t { - fields { - srcPort : 16; - dstPort : 16; - verifTag : 32; - checksum : 32; - } -} - -header_type gre_t { - fields { - C : 1; - R : 1; - K : 1; - S : 1; - s : 1; - recurse : 3; - flags : 5; - ver : 3; - proto : 16; - } -} - -header_type nvgre_t { - fields { - tni : 24; - reserved : 8; - } -} - -/* 8 bytes */ -header_type erspan_header_v1_t { - fields { - version : 4; - vlan : 12; - priority : 6; - span_id : 10; - direction : 8; - truncated: 8; - } -} - -/* 8 bytes */ -header_type erspan_header_v2_t { - fields { - version : 4; - vlan : 12; - priority : 6; - span_id : 10; - unknown7 : 32; - } -} - -header_type ipsec_esp_t { - fields { - spi : 32; - seqNo : 32; - } -} - -header_type ipsec_ah_t { - fields { - nextHdr : 8; - length_ : 8; - zero : 16; - spi : 32; - seqNo : 32; - } -} - -header_type arp_rarp_t { - fields { - hwType : 16; - protoType : 16; - hwAddrLen : 8; - protoAddrLen : 8; - opcode : 16; - } -} - -header_type arp_rarp_ipv4_t { - fields { - srcHwAddr : 48; - srcProtoAddr : 32; - dstHwAddr : 48; - dstProtoAddr : 32; - } -} - -header_type eompls_t { - fields { - zero : 4; - reserved : 12; - seqNo : 16; - } -} - -header_type vxlan_t { - fields { - flags : 8; - reserved : 24; - vni : 24; - reserved2 : 8; - } -} - -header_type nsh_t { - fields { - oam : 1; - context : 1; - flags : 6; - reserved : 8; - protoType: 16; - spath : 24; - sindex : 8; - } -} - -header_type nsh_context_t { - fields { - network_platform : 32; - network_shared : 32; - service_platform : 32; - service_shared : 32; - } -} - -/* GENEVE HEADERS - 3 possible options with known type, known length */ - -header_type genv_t { - fields { - ver : 2; - optLen : 6; - oam : 1; - critical : 1; - reserved : 6; - protoType : 16; - vni : 24; - reserved2 : 8; - } -} - -#define GENV_OPTION_A_TYPE 0x000001 -/* TODO: Would it be convenient to have some kind of sizeof macro ? */ -#define GENV_OPTION_A_LENGTH 2 /* in bytes */ - -header_type genv_opt_A_t { - fields { - optClass : 16; - optType : 8; - reserved : 3; - optLen : 5; - data : 32; - } -} - -#define GENV_OPTION_B_TYPE 0x000002 -#define GENV_OPTION_B_LENGTH 3 /* in bytes */ - -header_type genv_opt_B_t { - fields { - optClass : 16; - optType : 8; - reserved : 3; - optLen : 5; - data : 64; - } -} - -#define GENV_OPTION_C_TYPE 0x000003 -#define GENV_OPTION_C_LENGTH 2 /* in bytes */ - -header_type genv_opt_C_t { - fields { - optClass : 16; - optType : 8; - reserved : 3; - optLen : 5; - data : 32; - } -} -parser start { - return parse_input_port; -} - -header_type input_port_hdr_t { - fields { - port : 16; - } -} - -header input_port_hdr_t input_port_hdr; - -parser parse_input_port { - extract (input_port_hdr); - return parse_ethernet; -} - -#define ETHERTYPE_CPU 0x9000, 0x010c -#define ETHERTYPE_VLAN 0x8100, 0x9100, 0x9200, 0x9300 -#define ETHERTYPE_MPLS 0x8847 -#define ETHERTYPE_IPV4 0x0800 -#define ETHERTYPE_IPV6 0x86dd -#define ETHERTYPE_ARP 0x0806 -#define ETHERTYPE_RARP 0x8035 -#define ETHERTYPE_NSH 0x894f -#define ETHERTYPE_ETHERNET 0x6558 -#define ETHERTYPE_ROCE 0x8915 -#define ETHERTYPE_FCOE 0x8906 -/* missing: vlan_3b, vlan_5b, ieee802_1q, ieee802_1ad */ - -#define IPV4_MULTICAST_MAC 0x01005E -#define IPV6_MULTICAST_MAC 0x3333 - -/* Tunnel types */ -#define TUNNEL_TYPE_NONE 0 -#define TUNNEL_TYPE_VXLAN 1 -#define TUNNEL_TYPE_GRE 2 -#define TUNNEL_TYPE_GENEVE 3 -#define TUNNEL_TYPE_NVGRE 4 -#define TUNNEL_TYPE_MPLS 5 - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0 mask 0xf800: parse_snap_header; /* < 1536 */ - ETHERTYPE_CPU : parse_cpu_header; - ETHERTYPE_VLAN : parse_vlan; - ETHERTYPE_MPLS : parse_mpls; - ETHERTYPE_IPV4 : parse_ipv4; - ETHERTYPE_IPV6 : parse_ipv6; - ETHERTYPE_ARP : parse_arp_rarp; - ETHERTYPE_RARP : parse_arp_rarp; - ETHERTYPE_NSH : parse_nsh; - ETHERTYPE_ROCE: parse_roce; - ETHERTYPE_FCOE: parse_fcoe; - default: ingress; - } -} - -header snap_header_t snap_header; - -parser parse_snap_header { - extract(snap_header); - return ingress; -} - -header roce_header_t roce; - -parser parse_roce { - extract(roce); - return ingress; -} - -header fcoe_header_t fcoe; - -parser parse_fcoe { - extract(fcoe); - return ingress; -} - -header cpu_header_t cpu_header; - -parser parse_cpu_header { - extract(cpu_header); - return select(latest.etherType) { - 0 mask 0xf800: parse_snap_header; /* < 1536 */ - ETHERTYPE_VLAN : parse_vlan; - ETHERTYPE_MPLS : parse_mpls; - ETHERTYPE_IPV4 : parse_ipv4; - ETHERTYPE_IPV6 : parse_ipv6; - ETHERTYPE_ARP : parse_arp_rarp; - ETHERTYPE_RARP : parse_arp_rarp; - ETHERTYPE_NSH : parse_nsh; - ETHERTYPE_ROCE: parse_roce; - ETHERTYPE_FCOE: parse_fcoe; - default: ingress; - } -} - -#define VLAN_DEPTH 2 -header vlan_tag_t vlan_tag_[VLAN_DEPTH]; -header vlan_tag_3b_t vlan_tag_3b[VLAN_DEPTH]; -header vlan_tag_5b_t vlan_tag_5b[VLAN_DEPTH]; - -parser parse_vlan { - extract(vlan_tag_[next]); - return select(latest.etherType) { - ETHERTYPE_VLAN : parse_vlan; - ETHERTYPE_MPLS : parse_mpls; - ETHERTYPE_IPV4 : parse_ipv4; - ETHERTYPE_IPV6 : parse_ipv6; - ETHERTYPE_ARP : parse_arp_rarp; - ETHERTYPE_RARP : parse_arp_rarp; - default: ingress; - } -} - -#define MPLS_DEPTH 3 -/* all the tags but the last one */ -header mpls_t mpls[MPLS_DEPTH]; - -/* last mpls tag in the stack */ -header mpls_t mpls_bos; - -/* TODO: this will be optimized when pushed to the chip ? */ - -parser parse_mpls { - return select(current(23, 1)) { - 0 : parse_mpls_not_bos; - 1 : parse_mpls_bos; - default: ingress; - } -} - -parser parse_mpls_not_bos { - extract(mpls[next]); - return parse_mpls; -} - -parser parse_mpls_bos { - extract(mpls_bos); - return select(current(0, 4)) { - 0x4 : parse_inner_ipv4; - 0x6 : parse_inner_ipv6; - default : parse_eompls; - } -} - -#define IP_PROTOCOLS_ICMP 1 -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 -#define IP_PROTOCOLS_GRE 47 -#define IP_PROTOCOLS_IPSEC_ESP 50 -#define IP_PROTOCOLS_IPSEC_AH 51 -#define IP_PROTOCOLS_ICMPV6 58 -#define IP_PROTOCOLS_SCTP 132 - -header ipv4_t ipv4; - -field_list ipv4_checksum_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_checksum { - input { - ipv4_checksum_list; - } - algorithm : csum16; - output_width : 16; -} - -calculated_field ipv4.hdrChecksum { -#ifdef __TARGET_TOFINO__ - verify ipv4_checksum; - update ipv4_checksum; -#else - verify ipv4_checksum if(ipv4.ihl == 5); - update ipv4_checksum if(ipv4.ihl == 5); -#endif -} - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_ICMP : parse_icmp; - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - IP_PROTOCOLS_GRE : parse_gre; -// IP_PROTOCOLS_SCTP : parse_sctp; - default: ingress; - } -} - -header ipv6_t ipv6; - -parser parse_ipv6 { - extract(ipv6); - return select(latest.nextHdr) { - IP_PROTOCOLS_ICMPV6 : parse_icmpv6; - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - IP_PROTOCOLS_GRE : parse_gre; -// IP_PROTOCOLS_SCTP : parse_sctp; - default: ingress; - } -} - -header icmp_t icmp; - -parser parse_icmp { - extract(icmp); - return ingress; -} - -header icmpv6_t icmpv6; - -parser parse_icmpv6 { - extract(icmpv6); - return ingress; -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -#define UDP_PORT_VXLAN 4789 -#define UDP_PORT_GENV 6081 -// Check IANA UDP port number - #define UDP_PORT_ROCE_V2 1021 - -header udp_t udp; - -header roce_v2_header_t roce_v2; - -parser parse_roce_v2 { - extract(roce_v2); - return ingress; -} - -parser parse_udp { - extract(udp); - return select(latest.dstPort) { - UDP_PORT_VXLAN : parse_vxlan; - UDP_PORT_GENV: parse_geneve; - UDP_PORT_ROCE_V2: parse_roce_v2; - default: ingress; - } -} - -header sctp_t sctp; - -parser parse_sctp { - extract(sctp); - return ingress; -} - - -#define GRE_PROTOCOLS_NVGRE 0x6558 -#define GRE_PROTOCOLS_GRE 0x6559 -#define GRE_PROTOCOLS_ERSPAN_V1 0x88BE -#define GRE_PROTOCOLS_ERSPAN_V2 0x22EB - -#define GRE_DEPTH 2 - -//header gre_t gre[GRE_DEPTH]; -header gre_t gre; - -#if 0 -header_type gre_opt_t { - fields { - key : 32; - } -} - -header gre_opt_t gre_opt; - -parser parse_gre_key { - extract(gre_opt); - return ingress; -} -parser parse_gre_key2 { - extract(gre_opt); - extract(gre_opt); - return ingress; -} -parser parse_gre_key22 { - extract(gre_opt); - extract(gre_opt); - return ingress; -} -parser parse_gre_opt1 { - extract(gre_opt); - return ingress; -} -parser parse_gre_opt2 { - extract(gre_opt); - extract(gre_opt); - return ingress; -} -parser parse_gre_opt3 { - extract(gre_opt); - extract(gre_opt); - extract(gre_opt); - return ingress; -} - -parser parse_gre_opts { - return select(latest.C, latest.S, latest.K) { - 1 mask 0x0000 : parse_gre_key; - 2 mask 0x0000 : parse_gre_opt1; - 3 mask 0x0000 : parse_gre_key2; - 4 mask 0x0000 : parse_gre_opt1; - 5 mask 0x0000 : parse_gre_key22; - 6 mask 0x0000 : parse_gre_opt2; - 7 mask 0x0000 : parse_gre_opt3; - default: ingress; - } -} -#endif - -parser parse_gre { - extract(gre); -// parse_gre_opts; - return select(latest.K, latest.proto) { - GRE_PROTOCOLS_NVGRE : parse_nvgre; -// GRE_PROTOCOLS_GRE : parse_gre; - GRE_PROTOCOLS_ERSPAN_V1 : parse_erspan_v1; - GRE_PROTOCOLS_ERSPAN_V2 : parse_erspan_v2; - ETHERTYPE_NSH : parse_nsh; - default: ingress; - } -} - -header nvgre_t nvgre; -header ethernet_t inner_ethernet; - -header ipv4_t inner_ipv4; -header ipv6_t inner_ipv6; -header ipv4_t outer_ipv4; -header ipv6_t outer_ipv6; - -field_list inner_ipv4_checksum_list { - inner_ipv4.version; - inner_ipv4.ihl; - inner_ipv4.diffserv; - inner_ipv4.totalLen; - inner_ipv4.identification; - inner_ipv4.flags; - inner_ipv4.fragOffset; - inner_ipv4.ttl; - inner_ipv4.protocol; - inner_ipv4.srcAddr; - inner_ipv4.dstAddr; -} - -field_list_calculation inner_ipv4_checksum { - input { - inner_ipv4_checksum_list; - } - algorithm : csum16; - output_width : 16; -} - -calculated_field inner_ipv4.hdrChecksum { -#ifdef __TARGET_TOFINO__ - verify inner_ipv4_checksum; - update inner_ipv4_checksum; -#else - verify inner_ipv4_checksum if(valid(ipv4)); - update inner_ipv4_checksum if(valid(ipv4)); -#endif -} - -header udp_t outer_udp; - -parser parse_nvgre { - extract(nvgre); - return parse_inner_ethernet; -} - -header erspan_header_v1_t erspan_v1_header; - -parser parse_erspan_v1 { - extract(erspan_v1_header); - return ingress; -} - -header erspan_header_v2_t erspan_v2_header; - -parser parse_erspan_v2 { - extract(erspan_v2_header); - return ingress; -} - -#define ARP_PROTOTYPES_ARP_RARP_IPV4 0x0800 - -header arp_rarp_t arp_rarp; - -parser parse_arp_rarp { - extract(arp_rarp); - return select(latest.protoType) { - ARP_PROTOTYPES_ARP_RARP_IPV4 : parse_arp_rarp_ipv4; - default: ingress; - } -} - -header arp_rarp_ipv4_t arp_rarp_ipv4; - -parser parse_arp_rarp_ipv4 { - extract(arp_rarp_ipv4); - return ingress; -} - -header eompls_t eompls; - -parser parse_eompls { - extract(eompls); - extract(inner_ethernet); - return ingress; -} - -header vxlan_t vxlan; - -parser parse_vxlan { - extract(vxlan); - return parse_inner_ethernet; -} - -header genv_t genv; - -header genv_opt_A_t genv_opt_A; -header genv_opt_B_t genv_opt_B; -header genv_opt_C_t genv_opt_C; - -parser parse_geneve { - extract(genv); - /* - counter_init(counter_1, latest.optLen); - return select(latest.optLen) { - 0 : parse_genv_inner; - default : parse_genv_opts; - } - */ - return parse_genv_inner; -} - -#if 0 - -parser parse_genv_opts { - /* switching on combined class and type */ - return select(current(0, 24)) { - GENV_OPTION_A_TYPE: parse_genv_opt_A; - GENV_OPTION_B_TYPE: parse_genv_opt_B; - GENV_OPTION_C_TYPE: parse_genv_opt_C; - } -} - -parser parse_genv_opt_A { - extract(genv_opt_A); - counter_decrement(counter_1, GENV_OPTION_A_LENGTH); - return select(counter_1) { - 0 : parse_genv_inner; - default : parse_genv_opts; - } -} - -parser parse_genv_opt_B { - extract(genv_opt_B); - counter_decrement(counter_1, GENV_OPTION_B_LENGTH); - return select(counter_1) { - 0 : parse_genv_inner; - default : parse_genv_opts; - } -} - -parser parse_genv_opt_C { - extract(genv_opt_C); - counter_decrement(counter_1, GENV_OPTION_C_LENGTH); - return select(counter_1) { - 0 : parse_genv_inner; - default : parse_genv_opts; - } -} -#endif - -parser parse_genv_inner { - return select(genv.protoType) { - ETHERTYPE_ETHERNET : parse_inner_ethernet; - ETHERTYPE_IPV4 : parse_inner_ipv4; - ETHERTYPE_IPV6 : parse_inner_ipv6; - default : ingress; - } -} - -header nsh_t nsh; -header nsh_context_t nsh_context; - -parser parse_nsh { - extract(nsh); - extract(nsh_context); - return select(nsh.protoType) { - ETHERTYPE_IPV4 : parse_inner_ipv4; - ETHERTYPE_IPV6 : parse_inner_ipv6; - ETHERTYPE_ETHERNET : parse_inner_ethernet; - default: ingress; - } -} - -parser parse_inner_ipv4 { - extract(inner_ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_ICMP : parse_inner_icmp; - IP_PROTOCOLS_TCP : parse_inner_tcp; - IP_PROTOCOLS_UDP : parse_inner_udp; -// IP_PROTOCOLS_SCTP : parse_inner_sctp; - default: ingress; - } -} - -header icmp_t inner_icmp; - -parser parse_inner_icmp { - extract(inner_icmp); - return ingress; -} - -header tcp_t inner_tcp; - -parser parse_inner_tcp { - extract(inner_tcp); - return ingress; -} - -header udp_t inner_udp; - -parser parse_inner_udp { - extract(inner_udp); - return ingress; -} - -header sctp_t inner_sctp; - -parser parse_inner_sctp { - extract(inner_sctp); - return ingress; -} - -parser parse_inner_ipv6 { - extract(inner_ipv6); - return select(latest.nextHdr) { - IP_PROTOCOLS_ICMPV6 : parse_inner_icmpv6; - IP_PROTOCOLS_TCP : parse_inner_tcp; - IP_PROTOCOLS_UDP : parse_inner_udp; -// IP_PROTOCOLS_SCTP : parse_inner_sctp; - default: ingress; - } -} - -header icmpv6_t inner_icmpv6; - -parser parse_inner_icmpv6 { - extract(inner_icmpv6); - return ingress; -} - -parser parse_inner_ethernet { - extract(inner_ethernet); - return select(latest.etherType) { - ETHERTYPE_IPV4 : parse_inner_ipv4; - ETHERTYPE_IPV6 : parse_inner_ipv6; - default: ingress; - } -} - -#define VALIDATE_PACKET_TABLE_SIZE 64 -#define PORTMAP_TABLE_SIZE 288 -#define STORM_CONTROL_TABLE_SIZE 256 -#define STORM_CONTROL_METER_TABLE_SIZE 256 -#define PORT_VLAN_TABLE_SIZE 32768 -#define OUTER_BD_TABLE_SIZE 256 -#define OUTER_ROUTER_MAC_TABLE_SIZE 256 -#define DEST_TUNNEL_TABLE_SIZE 512 -#define SRC_TUNNEL_TABLE_SIZE 16384 -#define OUTER_MULTICAST_STAR_G_TABLE_SIZE 512 -#define OUTER_MULTICAST_S_G_TABLE_SIZE 1024 -#define VNID_MAPPING_TABLE_SIZE 16384 -#define BD_TABLE_SIZE 16384 -#define OUTER_MCAST_RPF_TABLE_SIZE 512 -#define MPLS_TABLE_SIZE 4096 -#define VALIDATE_MPLS_TABLE_SIZE 512 - -#define ROUTER_MAC_TABLE_SIZE 512 -#define DMAC_TABLE_SIZE 65536 -#define SMAC_TABLE_SIZE 65536 -#define IPSG_TABLE_SIZE 8192 -#define IPSG_PERMIT_SPECIAL_TABLE_SIZE 512 -#define INGRESS_MIRROR_ACL_TABLE_SIZE 512 -#define INGRESS_MAC_ACL_TABLE_SIZE 512 -#define INGRESS_IP_ACL_TABLE_SIZE 1024 -#define INGRESS_IPV6_ACL_TABLE_SIZE 512 -#define INGRESS_QOS_ACL_TABLE_SIZE 512 -#define INGRESS_IP_RACL_TABLE_SIZE 1024 -#define INGRESS_IPV6_RACL_TABLE_SIZE 256 -#define IP_NAT_TABLE_SIZE 4096 - -#define IPV4_LPM_TABLE_SIZE 8192 -#define IPV6_LPM_TABLE_SIZE 2048 -#define IPV4_HOST_TABLE_SIZE 65536 -#define IPV6_HOST_TABLE_SIZE 16384 - -#define IPV4_MULTICAST_STAR_G_TABLE_SIZE 2048 -#define IPV4_MULTICAST_S_G_TABLE_SIZE 4096 -#define IPV6_MULTICAST_STAR_G_TABLE_SIZE 512 -#define IPV6_MULTICAST_S_G_TABLE_SIZE 512 -#define MCAST_RPF_TABLE_SIZE 32768 - -#define FWD_RESULT_TABLE_SIZE 512 -#define URPF_GROUP_TABLE_SIZE 32768 -#define ECMP_GROUP_TABLE_SIZE 1024 -#define ECMP_SELECT_TABLE_SIZE 16384 -#define NEXTHOP_TABLE_SIZE 49152 -#ifdef HARLYN -#define LAG_GROUP_TABLE_SIZE 4096 -#else -#define LAG_GROUP_TABLE_SIZE 1024 -#endif -#define LAG_SELECT_TABLE_SIZE 1024 -#define SYSTEM_ACL_SIZE 1024 -#define LEARN_NOTIFY_TABLE_SIZE 512 - -#define MAC_REWRITE_TABLE_SIZE 512 -#define EGRESS_VNID_MAPPING_TABLE_SIZE 16384 -#define EGRESS_BD_MAPPING_TABLE_SIZE 16384 -#define REPLICA_TYPE_TABLE_SIZE 16 -#define RID_TABLE_SIZE 65536 -#define TUNNEL_DECAP_TABLE_SIZE 512 -#define IP_MTU_TABLE_SIZE 512 -#define EGRESS_SYSTEM_ACL_TABLE_SIZE 512 -#define EGRESS_VLAN_XLATE_TABLE_SIZE 32768 -#define SPANNING_TREE_TABLE_SIZE 4096 -#define CPU_REWRITE_TABLE_SIZE 512 -#define EGRESS_ACL_TABLE_SIZE 2048 -#define VLAN_DECAP_TABLE_SIZE 256 -#define TUNNEL_HEADER_TABLE_SIZE 256 -#define TUNNEL_REWRITE_TABLE_SIZE 16384 -#define TUNNEL_SMAC_REWRITE_TABLE_SIZE 512 -#define TUNNEL_DMAC_REWRITE_TABLE_SIZE 16384 - -/* Boolean */ -#define FALSE 0 -#define TRUE 1 - -/* Packet types */ -#define L2_UNICAST 1 -#define L2_MULTICAST 2 -#define L2_BROADCAST 4 - -#define STORM_CONTROL_COLOR_GREEN 0 -#define STORM_CONTROL_COLOR_RED 1 - -/* IP types */ -#define IPTYPE_NONE 0 -#define IPTYPE_IPV4 1 -#define IPTYPE_IPV6 2 - -/* Multicast modes */ -#define MCAST_MODE_NONE 0 -#define MCAST_MODE_SM 1 -#define MCAST_MODE_BIDIR 2 - -#define OUTER_MCAST_KEY_TYPE_BD 0 -#define OUTER_MCAST_KEY_TYPE_VRF 1 - -/* URPF modes */ -#define URPF_MODE_NONE 0 -#define URPF_MODE_LOOSE 1 -#define URPF_MODE_STRICT 2 - -/* NAT modes */ -#define NAT_MODE_NONE 0 -#define NAT_MODE_INSIDE 1 -#define NAT_MODE_OUTSIDE 2 - -/* Egress tunnel types */ -#define EGRESS_TUNNEL_TYPE_NONE 0 -#define EGRESS_TUNNEL_TYPE_IPV4_VXLAN 1 -#define EGRESS_TUNNEL_TYPE_IPV6_VXLAN 2 -#define EGRESS_TUNNEL_TYPE_IPV4_GENEVE 3 -#define EGRESS_TUNNEL_TYPE_IPV6_GENEVE 4 -#define EGRESS_TUNNEL_TYPE_IPV4_NVGRE 5 -#define EGRESS_TUNNEL_TYPE_IPV6_NVGRE 6 -#define EGRESS_TUNNEL_TYPE_IPV4_ERSPANV2 7 -#define EGRESS_TUNNEL_TYPE_IPV6_ERSPANV2 8 -#define EGRESS_TUNNEL_TYPE_IPV4_GRE 9 -#define EGRESS_TUNNEL_TYPE_IPV6_GRE 10 -#define EGRESS_TUNNEL_TYPE_IPV4_IP 11 -#define EGRESS_TUNNEL_TYPE_IPV6_IP 12 -#define EGRESS_TUNNEL_TYPE_MPLS_L2VPN 13 -#define EGRESS_TUNNEL_TYPE_MPLS_L3VPN 14 - -#define VRF_BIT_WIDTH 12 -#define BD_BIT_WIDTH 16 -#define ECMP_BIT_WIDTH 10 -#define LAG_BIT_WIDTH 8 -#define IFINDEX_BIT_WIDTH 16 - -#define STP_GROUP_NONE 0 - -#define CPU_PORT_ID 64 -#define CPU_MIRROR_SESSION_ID 250 - -/* Learning Receivers */ -#ifndef HARLYN -#define MAC_LEARN_RECEIVER 1024 -#else -#define MAC_LEARN_RECEIVER 0 -#endif - -/* Nexthop Type */ -#define NEXTHOP_TYPE_SIMPLE 0 -#define NEXTHOP_TYPE_ECMP 1 - -/* METADATA */ -header_type ingress_metadata_t { - fields { - lkp_pkt_type : 3; - lkp_mac_sa : 48; - lkp_mac_da : 48; - lkp_mac_type : 16; - lkp_ip_type : 2; - lkp_ipv4_sa : 32; - lkp_ipv4_da : 32; - lkp_ipv6_sa : 128; - lkp_ipv6_da : 128; - lkp_ip_proto : 8; - lkp_ip_tc : 8; - lkp_ip_ttl : 8; - - lkp_l4_sport : 16; - lkp_l4_dport : 16; - lkp_inner_l4_sport : 16; - lkp_inner_l4_dport : 16; - - lkp_icmp_type : 8; - lkp_icmp_code : 8; - lkp_inner_icmp_type : 8; - lkp_inner_icmp_code : 8; - - l3_length : 16; /* l3 length */ - - ifindex : IFINDEX_BIT_WIDTH; /* input interface index - MSB bit lag*/ - vrf : VRF_BIT_WIDTH; /* VRF */ - -#ifdef HARLYN - tunnel_type : 8; /* tunnel type from parser */ -#else - tunnel_type : 4; /* tunnel type from parser */ -#endif - tunnel_terminate : 1; /* should tunnel be terminated */ - tunnel_vni : 24; /* tunnel id */ - src_vtep_miss : 1; /* src vtep lookup failed */ - - outer_bd : 8; /* outer BD */ - outer_ipv4_mcast_key_type : 1; /* 0 bd, 1 vrf */ - outer_ipv4_mcast_key : 8; /* bd or vrf value */ - outer_ipv6_mcast_key_type : 1; /* 0 bd, 1 vrf */ - outer_ipv6_mcast_key : 8; /* bd or vrf value */ - outer_mcast_route_hit : 1; /* hit in the outer multicast table */ - outer_mcast_mode : 2; /* multicast mode from route */ - outer_dscp : 8; /* outer dscp */ - outer_ttl : 8; /* outer ttl */ - outer_routed : 1; /* is outer packet routed */ - - l2_multicast : 1; /* packet is l2 multicast */ - ip_multicast : 1; /* packet is ip multicast */ - src_is_link_local : 1; /* source is link local address */ - bd : BD_BIT_WIDTH; /* inner BD */ - ipsg_enabled : 1; /* is ip source guard feature enabled */ - ipv4_unicast_enabled : 1; /* is ipv4 unicast routing enabled on BD */ - ipv6_unicast_enabled : 1; /* is ipv6 unicast routing enabled on BD */ - ipv4_multicast_mode : 2; /* ipv4 multicast mode BD */ - ipv6_multicast_mode : 2; /* ipv6 multicast mode BD */ - igmp_snooping_enabled : 1; /* is IGMP snooping enabled on BD */ - mld_snooping_enabled : 1; /* is MLD snooping enabled on BD */ - mpls_enabled : 1; /* is mpls enabled on BD */ - mpls_label: 20; /* Mpls label */ - mpls_exp: 3; /* Mpls Traffic Class */ - mpls_ttl: 8; /* Mpls Ttl */ - ipv4_urpf_mode : 2; /* 0: none, 1: strict, 3: loose */ - ipv6_urpf_mode : 2; /* 0: none, 1: strict, 3: loose */ - urpf_mode : 2; /* urpf mode for current lookup */ - nat_mode : 2; /* 0: none, 1: inside, 2: outside */ - rmac_group : 10; /* Rmac group, for rmac indirection */ - rmac_hit : 1; /* dst mac is the router's mac */ - mcast_route_hit : 1; /* hit in the multicast route table */ - mcast_bridge_hit : 1; /* hit in the multicast bridge table */ - bd_mrpf_group : BD_BIT_WIDTH; /* rpf group from bd lookup */ - mcast_rpf_group : BD_BIT_WIDTH; /* rpf group from mcast lookup */ - mcast_mode : 2; /* multicast mode from route */ - uuc_mc_index : 16; /* unknown unicast multicast index */ - umc_mc_index : 16; /* unknown multicast multicast index */ - bcast_mc_index : 16; /* broadcast multicast index */ - multicast_route_mc_index : 16; /* multicast index from mfib */ - multicast_bridge_mc_index : 16; /* multicast index from igmp/mld snoop */ - storm_control_color : 1; /* 0 : pass, 1 : fail */ - urpf_hit : 1; /* hit in urpf table */ - urpf_check_fail :1; /* urpf check failed */ - urpf_bd_group : BD_BIT_WIDTH; /* urpf bd group */ - routed : 1; /* is packet routed */ - - if_label : 16; /* if label for acls */ - bd_label : 16; /* bd label for acls */ - - l2_src_miss : 1; /* l2 source miss */ - l2_src_move : IFINDEX_BIT_WIDTH; /* l2 source interface mis-match */ - ipsg_check_fail : 1; /* ipsg check failed */ - acl_deny : 1; /* ifacl/vacl deny action */ - racl_deny : 1; /* racl deny action */ - l2_redirect : 1; /* l2 redirect action */ - acl_redirect : 1; /* ifacl/vacl redirect action */ - racl_redirect : 1; /* racl redirect action */ - fib_hit : 1; /* fib hit */ - nat_hit : 1; /* fwd and rewrite info from nat */ - - mirror_session_id : 10; /* mirror session id */ - - l2_nexthop : 16; /* next hop from l2 */ - acl_nexthop : 16; /* next hop from ifacl/vacl */ - racl_nexthop : 16; /* next hop from racl */ - fib_nexthop : 16; /* next hop from fib */ - nat_nexthop : 16; /* next hop from nat */ - l2_nexthop_type : 1; /* ecmp or nexthop */ - acl_nexthop_type : 1; /* ecmp or nexthop */ - racl_nexthop_type : 1; /* ecmp or nexthop */ - fib_nexthop_type : 1; /* ecmp or nexthop */ - nexthop_index : 16; /* final next hop index */ - nexthop_type : 1; /* final next hop index type */ - nat_rewrite_index : 16; /* NAT rewrite index */ - - marked_cos : 3; /* marked vlan cos value */ - marked_dscp : 8; /* marked dscp value */ - marked_exp : 3; /* marked exp value */ - ttl : 8; /* update ttl */ - -#ifndef HARLYN - egress_ifindex : IFINDEX_BIT_WIDTH; /* egress interface index */ -#else - egress_ifindex : 32; /* egress interface index */ -#endif - egress_bd : BD_BIT_WIDTH; /* egress BD */ - same_bd_check : BD_BIT_WIDTH; /* ingress bd xor egress bd */ - - ingress_bypass : 1; /* skip the entire ingress pipeline */ - ipv4_dstaddr_24b : 24; /* first 24b of ipv4 dst addr */ - drop_0 : 1; /* dummy */ - drop_reason : 8; /* drop reason for negative mirroring */ - stp_group: 10; /* spanning tree group id */ - stp_state : 3; /* spanning tree port state */ - control_frame: 1; /* control frame */ - header_count: 4; /* Number of headers */ - } -} - -metadata ingress_metadata_t ingress_metadata; - -table port_vlan_mapping { - reads { - ingress_metadata.ifindex : exact; - vlan_tag_[0] : valid; - vlan_tag_[0].vid : exact; - vlan_tag_[1] : valid; - vlan_tag_[1].vid : exact; - } - - action_profile: outer_bd_action_profile; - size : PORT_VLAN_TABLE_SIZE; -} - -action set_outer_bd_ipv4_mcast_switch_ipv6_mcast_switch_flags(bd, vrf, - rmac_group, mrpf_group, - bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, - ipv4_unicast_enabled, ipv6_unicast_enabled, - ipv4_multicast_mode, ipv6_multicast_mode, - igmp_snooping_enabled, mld_snooping_enabled, - ipv4_urpf_mode, ipv6_urpf_mode, stp_group) { - modify_field(ingress_metadata.vrf, vrf); - modify_field(ingress_metadata.bd, bd); - modify_field(ingress_metadata.outer_bd, bd); - modify_field(ingress_metadata.outer_ipv4_mcast_key_type, OUTER_MCAST_KEY_TYPE_BD); - modify_field(ingress_metadata.outer_ipv4_mcast_key, bd); - modify_field(ingress_metadata.outer_ipv6_mcast_key_type, OUTER_MCAST_KEY_TYPE_BD); - modify_field(ingress_metadata.outer_ipv6_mcast_key, bd); - - modify_field(ingress_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); - modify_field(ingress_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled); - modify_field(ingress_metadata.ipv4_multicast_mode, ipv4_multicast_mode); - modify_field(ingress_metadata.ipv6_multicast_mode, ipv6_multicast_mode); - modify_field(ingress_metadata.igmp_snooping_enabled, igmp_snooping_enabled); - modify_field(ingress_metadata.mld_snooping_enabled, mld_snooping_enabled); - modify_field(ingress_metadata.ipv4_urpf_mode, ipv4_urpf_mode); - modify_field(ingress_metadata.ipv6_urpf_mode, ipv6_urpf_mode); - modify_field(ingress_metadata.rmac_group, rmac_group); - modify_field(ingress_metadata.bd_mrpf_group, mrpf_group); - modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); - modify_field(ingress_metadata.umc_mc_index, umc_mc_index); - modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); - modify_field(ingress_metadata.bd_label, bd_label); - modify_field(ingress_metadata.stp_group, stp_group); -} - -action set_outer_bd_ipv4_mcast_switch_ipv6_mcast_route_flags(bd, vrf, - rmac_group, mrpf_group, - bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, - ipv4_unicast_enabled, ipv6_unicast_enabled, - ipv4_multicast_mode, ipv6_multicast_mode, - igmp_snooping_enabled, mld_snooping_enabled, - ipv4_urpf_mode, ipv6_urpf_mode, stp_group) { - modify_field(ingress_metadata.vrf, vrf); - modify_field(ingress_metadata.bd, bd); - modify_field(ingress_metadata.outer_bd, bd); - modify_field(ingress_metadata.outer_ipv4_mcast_key_type, OUTER_MCAST_KEY_TYPE_BD); - modify_field(ingress_metadata.outer_ipv4_mcast_key, bd); - modify_field(ingress_metadata.outer_ipv6_mcast_key_type, OUTER_MCAST_KEY_TYPE_VRF); - modify_field(ingress_metadata.outer_ipv6_mcast_key, vrf); - - modify_field(ingress_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); - modify_field(ingress_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled); - modify_field(ingress_metadata.ipv4_multicast_mode, ipv4_multicast_mode); - modify_field(ingress_metadata.ipv6_multicast_mode, ipv6_multicast_mode); - modify_field(ingress_metadata.igmp_snooping_enabled, igmp_snooping_enabled); - modify_field(ingress_metadata.mld_snooping_enabled, mld_snooping_enabled); - modify_field(ingress_metadata.ipv4_urpf_mode, ipv4_urpf_mode); - modify_field(ingress_metadata.ipv6_urpf_mode, ipv6_urpf_mode); - modify_field(ingress_metadata.rmac_group, rmac_group); - modify_field(ingress_metadata.bd_mrpf_group, mrpf_group); - modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); - modify_field(ingress_metadata.umc_mc_index, umc_mc_index); - modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); - modify_field(ingress_metadata.bd_label, bd_label); - modify_field(ingress_metadata.stp_group, stp_group); -} - -action set_outer_bd_ipv4_mcast_route_ipv6_mcast_switch_flags(bd, vrf, - rmac_group, mrpf_group, - bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, - ipv4_unicast_enabled, ipv6_unicast_enabled, - ipv4_multicast_mode, ipv6_multicast_mode, - igmp_snooping_enabled, mld_snooping_enabled, - ipv4_urpf_mode, ipv6_urpf_mode, stp_group) { - modify_field(ingress_metadata.vrf, vrf); - modify_field(ingress_metadata.bd, bd); - modify_field(ingress_metadata.outer_bd, bd); - modify_field(ingress_metadata.outer_ipv4_mcast_key_type, OUTER_MCAST_KEY_TYPE_VRF); - modify_field(ingress_metadata.outer_ipv4_mcast_key, vrf); - modify_field(ingress_metadata.outer_ipv6_mcast_key_type, OUTER_MCAST_KEY_TYPE_BD); - modify_field(ingress_metadata.outer_ipv6_mcast_key, bd); - - modify_field(ingress_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); - modify_field(ingress_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled); - modify_field(ingress_metadata.ipv4_multicast_mode, ipv4_multicast_mode); - modify_field(ingress_metadata.ipv6_multicast_mode, ipv6_multicast_mode); - modify_field(ingress_metadata.igmp_snooping_enabled, igmp_snooping_enabled); - modify_field(ingress_metadata.mld_snooping_enabled, mld_snooping_enabled); - modify_field(ingress_metadata.ipv4_urpf_mode, ipv4_urpf_mode); - modify_field(ingress_metadata.ipv6_urpf_mode, ipv6_urpf_mode); - modify_field(ingress_metadata.rmac_group, rmac_group); - modify_field(ingress_metadata.bd_mrpf_group, mrpf_group); - modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); - modify_field(ingress_metadata.umc_mc_index, umc_mc_index); - modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); - modify_field(ingress_metadata.bd_label, bd_label); - modify_field(ingress_metadata.stp_group, stp_group); -} - -action set_outer_bd_ipv4_mcast_route_ipv6_mcast_route_flags(bd, vrf, - rmac_group, mrpf_group, - bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, - ipv4_unicast_enabled, ipv6_unicast_enabled, - ipv4_multicast_mode, ipv6_multicast_mode, - igmp_snooping_enabled, mld_snooping_enabled, - ipv4_urpf_mode, ipv6_urpf_mode, stp_group) { - modify_field(ingress_metadata.vrf, vrf); - modify_field(ingress_metadata.bd, bd); - modify_field(ingress_metadata.outer_bd, bd); - modify_field(ingress_metadata.outer_ipv4_mcast_key_type, OUTER_MCAST_KEY_TYPE_VRF); - modify_field(ingress_metadata.outer_ipv4_mcast_key, vrf); - modify_field(ingress_metadata.outer_ipv6_mcast_key_type, OUTER_MCAST_KEY_TYPE_VRF); - modify_field(ingress_metadata.outer_ipv6_mcast_key, vrf); - - modify_field(ingress_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); - modify_field(ingress_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled); - modify_field(ingress_metadata.ipv4_multicast_mode, ipv4_multicast_mode); - modify_field(ingress_metadata.ipv6_multicast_mode, ipv6_multicast_mode); - modify_field(ingress_metadata.igmp_snooping_enabled, igmp_snooping_enabled); - modify_field(ingress_metadata.mld_snooping_enabled, mld_snooping_enabled); - modify_field(ingress_metadata.ipv4_urpf_mode, ipv4_urpf_mode); - modify_field(ingress_metadata.ipv6_urpf_mode, ipv6_urpf_mode); - modify_field(ingress_metadata.rmac_group, rmac_group); - modify_field(ingress_metadata.bd_mrpf_group, mrpf_group); - modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); - modify_field(ingress_metadata.umc_mc_index, umc_mc_index); - modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); - modify_field(ingress_metadata.bd_label, bd_label); - modify_field(ingress_metadata.stp_group, stp_group); -} - -action set_bd(outer_vlan_bd, vrf, rmac_group, - bd_label, uuc_mc_index, bcast_mc_index, umc_mc_index, - ipv4_unicast_enabled, - igmp_snooping_enabled, stp_group) { - modify_field(ingress_metadata.vrf, vrf); - modify_field(ingress_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); - modify_field(ingress_metadata.igmp_snooping_enabled, igmp_snooping_enabled); - modify_field(ingress_metadata.rmac_group, rmac_group); - modify_field(ingress_metadata.uuc_mc_index, uuc_mc_index); - modify_field(ingress_metadata.umc_mc_index, umc_mc_index); - modify_field(ingress_metadata.bcast_mc_index, bcast_mc_index); - modify_field(ingress_metadata.bd_label, bd_label); - modify_field(ingress_metadata.bd, outer_vlan_bd); - modify_field(ingress_metadata.stp_group, stp_group); -} - -action_profile outer_bd_action_profile { - actions { - /* - * This is the default miss action if the outer bd is not found in this - * table. - */ - set_bd; - set_outer_bd_ipv4_mcast_switch_ipv6_mcast_switch_flags; - set_outer_bd_ipv4_mcast_switch_ipv6_mcast_route_flags; - set_outer_bd_ipv4_mcast_route_ipv6_mcast_switch_flags; - set_outer_bd_ipv4_mcast_route_ipv6_mcast_route_flags; - } - size : OUTER_BD_TABLE_SIZE; -} - -control ingress { - - apply(port_vlan_mapping); - -} diff --git a/backends/tofino/bf-asm/test/proxy_hash1.p4 b/backends/tofino/bf-asm/test/proxy_hash1.p4 deleted file mode 100644 index 685fb7ab4c2..00000000000 --- a/backends/tofino/bf-asm/test/proxy_hash1.p4 +++ /dev/null @@ -1,109 +0,0 @@ -header_type ethernet_t { - fields { - dst_addr : 48; // width in bits - src_addr : 48; - ethertype : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr : 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 4; - flags : 8; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - length_ : 16; - checksum : 16; - } -} - -header ethernet_t ethernet; -header ipv4_t ipv4; -header tcp_t tcp; -header udp_t udp; - -// Start with ethernet always. -parser start { - return ethernet; -} - -parser ethernet { - extract(ethernet); // Start with the ethernet header - return select(ethernet.ethertype) { - 0x800: ipv4; -// default: ingress; - } -} - -parser ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - //1 : icmp; - 6 : tcp; - 17 : udp; - default: ingress; - } -} - -parser tcp { - extract(tcp); - return ingress; -} - -parser udp { - extract(udp); - return ingress; -} - -action nop() {} -action set_dip() {} - -@pragma proxy_hash_width 24 -table exm_proxy_hash { - reads { - ipv4.srcAddr : exact; - ipv4.dstAddr : exact; - ipv4.protocol : exact; - tcp.srcPort : exact; - tcp.dstPort : exact; - } - actions { - nop; - set_dip; - } - size : 131072; -} - -control ingress { - apply(exm_proxy_hash); -} diff --git a/backends/tofino/bf-asm/test/ptf/action_spec_format.p4 b/backends/tofino/bf-asm/test/ptf/action_spec_format.p4 deleted file mode 100644 index aa093aa4e5e..00000000000 --- a/backends/tofino/bf-asm/test/ptf/action_spec_format.p4 +++ /dev/null @@ -1,464 +0,0 @@ -#include -#include - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm : csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -meter exm_meter1 { - type : bytes; - static : exm_tbl_act_spec_format_1; - result : ipv4.diffserv; - instance_count : 500; -} - -counter exm_cntr1 { - type : packets; - direct : exm_tbl_act_spec_format_1; -} - -meter exm_meter2 { - type : bytes; - direct : exm_tbl_act_spec_format_2; - result : ipv4.diffserv; -} - -counter exm_cntr2 { - type : packets; - static : exm_tbl_act_spec_format_2; - instance_count : 500; -} - -meter exm_meter3 { - type : bytes; - static : exm_tbl_act_spec_format_3; - result : ipv4.diffserv; - instance_count : 500; -} - -counter exm_cntr3 { - type : packets; - static : exm_tbl_act_spec_format_3; - instance_count : 500; -} - -//meter exm_meter4 { -// type : bytes; -// direct : exm_tbl_act_spec_format_4; -// result : ipv4.diffserv; -//} -// -//counter exm_cntr4 { -// type : packets; -// direct : exm_tbl_act_spec_format_4; -//} - -meter tcam_meter1 { - type : bytes; - static : tcam_tbl_act_spec_format_1; - result : ipv4.diffserv; - instance_count : 500; -} - -counter tcam_cntr1 { - type : packets; - direct : tcam_tbl_act_spec_format_1; -} - -meter tcam_meter2 { - type : bytes; - direct : tcam_tbl_act_spec_format_2; - result : ipv4.diffserv; -} - -counter tcam_cntr2 { - type : packets; - static : tcam_tbl_act_spec_format_2; - instance_count : 500; -} - -meter tcam_meter3 { - type : bytes; - static : tcam_tbl_act_spec_format_3; - result : ipv4.diffserv; - instance_count : 500; -} - -counter tcam_cntr3 { - type : packets; - static : tcam_tbl_act_spec_format_3; - instance_count : 500; -} - -//meter tcam_meter4 { -// type : bytes; -// direct : tcam_tbl_act_spec_format_4; -// result : ipv4.diffserv; -//} -// -//counter tcam_cntr4 { -// type : packets; -// direct : tcam_tbl_act_spec_format_4; -//} - -action nop() { -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action next_hop_ipv4(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action next_hop_ipv4_meters_1(egress_port ,srcmac, dstmac, meter_idx) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); - execute_meter(exm_meter1, meter_idx, ipv4.diffserv); -} - -action next_hop_ipv4_stats_2(egress_port ,srcmac, dstmac, stat_idx) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); - count(exm_cntr2, stat_idx); -} - -action next_hop_ipv4_stats_meters_3(egress_port ,srcmac, dstmac, meter_idx, stat_idx) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); - count(exm_cntr3, stat_idx); - execute_meter(exm_meter3, meter_idx, ipv4.diffserv); -} - -action next_hop_ipv4_stats_3(egress_port ,srcmac, dstmac, stat_idx) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); - count(exm_cntr3, stat_idx); -} - -action next_hop_ipv4_meters_3(egress_port ,srcmac, dstmac, meter_idx) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); - execute_meter(exm_meter3, meter_idx, ipv4.diffserv); -} - -action tcam_next_hop_ipv4_meters_1(egress_port ,srcmac, dstmac, meter_idx) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); - execute_meter(tcam_meter1, meter_idx, ipv4.diffserv); -} - -action tcam_next_hop_ipv4_stats_2(egress_port ,srcmac, dstmac, stat_idx) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); - count(tcam_cntr2, stat_idx); -} - -action tcam_next_hop_ipv4_stats_meters_3(egress_port ,srcmac, dstmac, meter_idx, stat_idx) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); - count(tcam_cntr3, stat_idx); - execute_meter(tcam_meter3, meter_idx, ipv4.diffserv); -} - -action tcam_next_hop_ipv4_stats_3(egress_port ,srcmac, dstmac, stat_idx) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); - count(tcam_cntr3, stat_idx); -} - -action tcam_next_hop_ipv4_meters_3(egress_port ,srcmac, dstmac, meter_idx) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); - execute_meter(tcam_meter3, meter_idx, ipv4.diffserv); -} - -/* Exact match table referring to meter table indirectly for one action - * And directly referring to a stats table. - */ - -table exm_tbl_act_spec_format_1 { - reads { - ipv4.srcAddr : exact; - ipv4.dstAddr : exact; - } - actions { - next_hop_ipv4_meters_1; - next_hop_ipv4; - } - default_action: nop(); -} - -/* Exact match table referring to stat table indirectly for one action - * And directly referring to a meter table - */ - -table exm_tbl_act_spec_format_2 { - reads { - ipv4.srcAddr : exact; - ipv4.dstAddr : exact; - } - actions { - next_hop_ipv4_stats_2; - next_hop_ipv4; - } - default_action: nop(); -} - -/* Exact match table referring to stat table and meter table indirectly with - * all combinations across four actions. - */ - -table exm_tbl_act_spec_format_3 { - reads { - ipv4.srcAddr : exact; - ipv4.dstAddr : exact; - } - actions { - next_hop_ipv4_stats_meters_3; - next_hop_ipv4_stats_3; - next_hop_ipv4_meters_3; - next_hop_ipv4; - } - default_action: nop(); -} - -/* Exact match table referring to a stat table and meter table directly */ - -table exm_tbl_act_spec_format_4 { - reads { - ipv4.srcAddr : exact; - ipv4.dstAddr : exact; - } - actions { - next_hop_ipv4; - } - default_action: nop(); -} - -/* TCAM table referring to meter table indirectly for one action - * And directly referring to a stats table. - */ - -table tcam_tbl_act_spec_format_1 { - reads { - ipv4.srcAddr : lpm; - ipv4.dstAddr : exact; - } - actions { - tcam_next_hop_ipv4_meters_1; - next_hop_ipv4; - } - default_action: nop(); -} - -/* TCAM table referring to stat table indirectly for one action - * And directly referring to a meter table - */ - -table tcam_tbl_act_spec_format_2 { - reads { - ipv4.srcAddr : lpm; - ipv4.dstAddr : exact; - } - actions { - tcam_next_hop_ipv4_stats_2; - next_hop_ipv4; - } - default_action: nop(); -} - -/* TCAM table referring to stat table and meter table indirectly with - * all combinations across four actions. - */ - -table tcam_tbl_act_spec_format_3 { - reads { - ipv4.srcAddr : lpm; - ipv4.dstAddr : exact; - } - actions { - tcam_next_hop_ipv4_stats_meters_3; - tcam_next_hop_ipv4_stats_3; - tcam_next_hop_ipv4_meters_3; - next_hop_ipv4; - } - default_action: nop(); -} - -/* TCAM table referring to a stat table and meter table directly */ - -table tcam_tbl_act_spec_format_4 { - reads { - ipv4.srcAddr : lpm; - ipv4.dstAddr : exact; - } - actions { - next_hop_ipv4; - nop; - } - default_action: nop(); -} - - -control ingress { - apply(exm_tbl_act_spec_format_2); - apply(tcam_tbl_act_spec_format_2); - apply(exm_tbl_act_spec_format_1); - apply(exm_tbl_act_spec_format_3); - apply(tcam_tbl_act_spec_format_1); - apply(tcam_tbl_act_spec_format_3); - //apply(exm_tbl_act_spec_format_4); -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/ptf/alpm_test.p4 b/backends/tofino/bf-asm/test/ptf/alpm_test.p4 deleted file mode 100644 index fb2bb8b6d2a..00000000000 --- a/backends/tofino/bf-asm/test/ptf/alpm_test.p4 +++ /dev/null @@ -1,173 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 4; - flags : 8; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - - -header_type meta_t { - fields { - pad_0 : 4; - vrf : 12; - } -} - - -header ethernet_t ethernet; -header ipv4_t ipv4; -header tcp_t tcp; -metadata meta_t meta; - - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x0800 : parse_ipv4; - default : ingress; - } -} - -parser parse_ipv4 { - extract(ipv4); - return select(ipv4.protocol){ - 0x06 : parse_tcp; - default : ingress; - } -} - -parser parse_tcp { - extract(tcp); - return ingress; -} - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm : csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action ipv4_lpm_hit(egress_port) { - hop(ipv4.ttl, egress_port); -} - -action lpm_miss(){ - drop(); -} - -action nop() {} - -@pragma alpm 1 -table ipv4_alpm { - reads { - meta.vrf: exact; - ipv4.dstAddr: lpm; - } - actions { - ipv4_lpm_hit; - lpm_miss; - nop; - } - size: 8192; -} - -@pragma alpm 1 -@pragma alpm_partitions 1024 -@pragma alpm_subtrees_per_partition 4 -table ipv4_alpm_large { - reads { - meta.vrf: exact; - ipv4.dstAddr: lpm; - } - actions { - ipv4_lpm_hit; - lpm_miss; - nop; - } - size: 200000; -} - -@pragma alpm 1 -table ipv4_alpm_idle { - reads { - ipv4.dstAddr: lpm; - } - actions { - ipv4_lpm_hit; - nop; - } - size: 8192; - support_timeout: true; -} - -/* Main control flow */ -control ingress { - apply(ipv4_alpm); - apply(ipv4_alpm_large); - apply(ipv4_alpm_idle); -} diff --git a/backends/tofino/bf-asm/test/ptf/basic_ipv4.p4 b/backends/tofino/bf-asm/test/ptf/basic_ipv4.p4 deleted file mode 100644 index 2d80e912300..00000000000 --- a/backends/tofino/bf-asm/test/ptf/basic_ipv4.p4 +++ /dev/null @@ -1,866 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header_type md_t { - fields { - sport:16; - dport:16; - } -} - -metadata md_t md; - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - set_metadata(md.sport, latest.srcPort); - set_metadata(md.dport, latest.dstPort); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - set_metadata(md.sport, latest.srcPort); - set_metadata(md.dport, latest.dstPort); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - learn_meta_1:20; - learn_meta_2:24; - learn_meta_3:25; - learn_meta_4:10; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -header_type range_metadata_t { - fields { - src_range_index : 16; - dest_range_index : 16; - } -} - -metadata range_metadata_t range_mdata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm : csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -field_list learn_1 { - ipv4.ihl; - ipv4.protocol; - ipv4.srcAddr; - ethernet.srcAddr; - ethernet.dstAddr; - ipv4.fragOffset; - ipv4.identification; - routing_metadata.learn_meta_1; - routing_metadata.learn_meta_4; -} - -action learn_1 (learn_meta_1, learn_meta_4) { - generate_digest(FLOW_LRN_DIGEST_RCVR, learn_1); - modify_field(routing_metadata.learn_meta_1, learn_meta_1); - modify_field(routing_metadata.learn_meta_4, learn_meta_4); -} - -field_list learn_2 { - ipv4.ihl; - ipv4.identification; - ipv4.protocol; - ipv4.srcAddr; - ethernet.srcAddr; - ethernet.dstAddr; - ipv4.fragOffset; - routing_metadata.learn_meta_2; - routing_metadata.learn_meta_3; -} - -action learn_2 (learn_meta_2, learn_meta_3) { - generate_digest(FLOW_LRN_DIGEST_RCVR, learn_2); - modify_field(routing_metadata.learn_meta_2, learn_meta_2); - modify_field(routing_metadata.learn_meta_3, learn_meta_3); -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop_ipv4(egress_port /*,srcmac, dstmac*/) { - hop(ipv4.ttl, egress_port); -// modify_field(ethernet.srcAddr, srcmac); -// modify_field(ethernet.dstAddr, dstmac); -} - -action set_srange_mdata(index) { - modify_field(range_mdata.src_range_index, index); -} - -action set_drange_mdata(index) { - modify_field(range_mdata.dest_range_index, index); -} - -action drop_ipv4 () { - drop(); -} - -action next_hop_ipv4(egress_port, srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action mod_mac_adr(egress_port, srcmac, dstmac) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action udp_hdr_add (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - add_header(udp); - modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); - add_to_field(ipv4.totalLen, 8); -} - -action udp_set_dest(port) { - modify_field(udp.dstPort, port); -} -action udp_set_src(port) { - modify_field(udp.srcPort, port); -} -action tcp_set_src_dest(sport, dport) { - modify_field(tcp.srcPort, sport); - modify_field(tcp.dstPort, dport); -} - -action tcp_hdr_rm (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - remove_header(tcp); - modify_field(ipv4.protocol, 0); -// add_to_field(ipv4.totalLen, -20); -// modify_field(ipv4.totalLen, 66); -} - -action modify_tcp_dst_port_1(dstPort, egress_port) { - modify_field(tcp.dstPort, dstPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ipv4.srcAddr, ipAddr); - modify_field(ethernet.dstAddr, dstAddr); - modify_field(tcp.dstPort, tcpPort); -} - -action custom_action_2(egress_port, ipAddr, tcpPort) -{ - modify_field(ipv4.srcAddr, ipAddr); - modify_field(tcp.dstPort, tcpPort); - hop(ipv4.ttl, egress_port); -} - -action custom_action_3(egress_port, dstAddr, dstIp) -{ - modify_field(ipv4.dstAddr, dstIp); - modify_field(ethernet.dstAddr, dstAddr); - hop(ipv4.ttl, egress_port); -} - -action modify_l2 (egress_port, srcAddr, dstAddr, tcp_sport, tcp_dport) { - // Trying for >128 bit action data - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcAddr); - modify_field(ethernet.dstAddr, dstAddr); - modify_field(tcp.dstPort, tcp_dport); - modify_field(tcp.srcPort, tcp_sport); -} - -@pragma command_line --no-dead-code-elimination -@pragma immediate 1 -@pragma stage 0 -table ig_udp { - reads { - ethernet : valid; - ipv4 : valid; - udp : valid; - udp.dstPort : ternary; - } - actions { - nop; - udp_set_dest; - } -} -@pragma immediate 1 -@pragma stage 0 -table eg_udp { - reads { - ethernet : valid; - ipv4 : valid; - udp : valid; - udp.srcPort : exact; - } - actions { - nop; - udp_set_src; - } -} -table ig_udp_ternary_valid { - reads { - ethernet : valid; - ipv4.valid : exact; - udp.valid : ternary; - md.dport : ternary; - } - actions { - nop; - udp_set_dest; - tcp_set_src_dest; - } -} - -@pragma immediate 1 -@pragma stage 0 -table ipv4_routing { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - hop_ipv4; - drop_ipv4; - learn_1; - learn_2; - } - size : 512; -} - -@pragma immediate 1 -@pragma stage 0 -@pragma ways 3 -@pragma pack 5 -table ipv4_routing_exm_ways_3_pack_5 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - modify_tcp_dst_port_1; - } -} - - -@pragma immediate 1 -@pragma stage 1 -@pragma ways 3 -@pragma pack 3 -table ipv4_routing_exm_ways_3_pack_3 { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - custom_action_1; - } -} - -@pragma immediate 1 -@pragma stage 1 -@pragma ways 4 -@pragma pack 3 -table ipv4_routing_exm_ways_4_pack_3_stage_1 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma immediate 1 -@pragma stage 1 -table ipv4_routing_stage_1 { - reads { - ipv4.dstAddr : lpm; - ipv4.srcAddr : exact; - } - actions { - nop; - hop_ipv4; - } - size : 1024; -} - -@pragma stage 2 -table tcam_tbl_stage_2 { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - mod_mac_adr; - } -} - -@pragma stage 2 -@pragma ways 4 -@pragma pack 7 -table ipv4_routing_exm_ways_4_pack_7_stage_2 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - tcp.dstPort : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -@pragma immediate 1 -@pragma stage 3 -@pragma ways 5 -@pragma pack 3 -table ipv4_routing_exm_ways_5_pack_3_stage_3 { - reads { - ipv4.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma immediate 1 -@pragma stage 3 -table udp_add_tbl_stage_3 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - udp_hdr_add; - } -} - -@pragma immediate 1 -@pragma stage 4 -@pragma ways 6 -@pragma pack 3 -table ipv4_routing_exm_ways_6_pack_3_stage_4 { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - - -@pragma immediate 1 -@pragma stage 4 -table tcp_rm_tbl_stage_4 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - tcp_hdr_rm; - } -} - -@pragma immediate 1 -@pragma stage 5 -@pragma ways 3 -@pragma pack 4 -table ipv4_routing_exm_ways_3_pack_4_stage_5 { - reads { - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - modify_tcp_dst_port_1; - } -} - -@pragma stage 6 -@pragma ways 4 -@pragma pack 4 -table ipv4_routing_exm_ways_4_pack_4_stage_6 { - reads { - ethernet.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma immediate 1 -@pragma stage 7 -@pragma ways 5 -@pragma pack 4 -table ipv4_routing_exm_ways_5_pack_4_stage_7 { - reads { - ipv4.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - -@pragma immediate 1 -@pragma stage 8 -table tcam_adt_deep_stage_8 { - reads { - ethernet.srcAddr : ternary; - ethernet.dstAddr : ternary; - ipv4.srcAddr : ternary; - ipv4.dstAddr : ternary; - } - actions { - nop; - modify_l2; - } - size : 3072; -} - -@pragma stage 8 -@pragma ways 4 -@pragma pack 5 -table ipv4_routing_exm_ways_4_pack_5_stage_8 { - reads { - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.srcPort : exact; - tcp.dstPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -@pragma stage 9 -table ipv4_routing_select { - reads { - ipv4.dstAddr: lpm; - } - action_profile : ecmp_action_profile; - size : 512; -} - -field_list ecmp_hash_fields { - ipv4.srcAddr; - ipv4.dstAddr; - ipv4.identification; - ipv4.protocol; -} - -field_list_calculation ecmp_hash { - input { - ecmp_hash_fields; - } -#if defined(BMV2TOFINO) - algorithm : xxh64; -#else - algorithm : random; -#endif - output_width : 64; -} - -action_profile ecmp_action_profile { - actions { - nhop_set; - nop; - } - size : 1024; - // optional - dynamic_action_selection : ecmp_selector; -} - -action_selector ecmp_selector { - selection_key : ecmp_hash; // take a field_list_calculation only - // optional - selection_mode : resilient; // “resilient” or “non-resilient” -} - -action nhop_set(port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -@pragma stage 10 -table tcam_indirect_action { - reads { - ethernet.srcAddr : ternary; - ethernet.dstAddr : ternary; - ethernet.etherType: exact; - ipv4.srcAddr : ternary; - ipv4.dstAddr : ternary; - ipv4.protocol : exact; - ipv4.version : exact; - } - action_profile : indirect_action_profile; - size : 2048; -} - -action modify_ip_id(port, id, srcAddr, dstAddr) { - modify_field(ipv4.identification, id); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); - modify_field(ethernet.srcAddr, srcAddr); - modify_field(ethernet.dstAddr, dstAddr); -} - -action_profile indirect_action_profile { - actions { - nop; - modify_ip_id; - } - size : 1500; -} - -@pragma stage 11 -@pragma ways 6 -@pragma pack 4 -table ipv4_routing_exm_ways_6_pack_4_stage_11 { - reads { - ipv4.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma stage 5 -table tcam_range { - reads { - ipv4.dstAddr : ternary; - tcp.dstPort : range; - } - actions { - nop; - hop_ipv4; - } - size : 1024; -} - -@pragma stage 5 -table tcam_range_ternary_valid { - reads { - tcp.valid : ternary; - ipv4.dstAddr : ternary; - md.dport : range; - } - actions { - nop; - hop_ipv4; - } - size : 1024; -} - -@pragma stage 6 -@pragma entries_with_ranges 1 -table tcam_range_2_fields { - reads { - ipv4.dstAddr : ternary; - tcp.dstPort : range; - tcp.srcPort : range; - } - actions { - nop; - hop_ipv4; - } - size : 1024; -} - -@pragma stage 7 -table src_non_overlap_range_table{ - reads { - tcp.srcPort : range; - } - actions { - nop; - set_srange_mdata; - } - size : 1024; -} - -@pragma stage 7 -table dest_non_overlap_range_table{ - reads { - tcp.dstPort : range; - } - actions { - nop; - set_drange_mdata; - } - size : 1024; -} - -@pragma stage 11 -@pragma entries_with_ranges 1 -table match_range_table{ - reads { - range_mdata.src_range_index : ternary; - range_mdata.dest_range_index : ternary; - tcp.srcPort : range; - tcp.dstPort : range; - ipv4.dstAddr : ternary; - ipv4.srcAddr : ternary; - } - actions { - nop; - hop_ipv4; - } - size : 1024; -} - -action set_mgid() { - modify_field(ig_intr_md_for_tm.mcast_grp_a, 0xAAAA); - modify_field(ig_intr_md_for_tm.mcast_grp_b, 0x5555); -} -action clr_mgid() { - bit_andca(ig_intr_md_for_tm.mcast_grp_a, ig_intr_md_for_tm.mcast_grp_a, ig_intr_md_for_tm.mcast_grp_a); - bit_andca(ig_intr_md_for_tm.mcast_grp_b, ig_intr_md_for_tm.mcast_grp_b, ig_intr_md_for_tm.mcast_grp_b); -} -@pragma stage 10 -table no_key_1 { - actions { - set_mgid; - } -} -@pragma stage 11 -table no_key_2 { - actions { - clr_mgid; - } -} - -/* Main control flow */ -control ingress { - /* A general principle : Always keep the exact match tables ahead of the - * ternary tables in the same stage, except first stage. Logic relating to next-table - * will cause the Tofino model not to launch a lookup on th exact match - * tables if the order is reversed. - */ - // stage 0 - apply(ig_udp); - apply(ig_udp_ternary_valid); - apply(ipv4_routing); - apply(ipv4_routing_exm_ways_3_pack_5); - // stage 1 - apply(ipv4_routing_exm_ways_3_pack_3); - apply(ipv4_routing_exm_ways_4_pack_3_stage_1); - apply(ipv4_routing_stage_1); - // stage 2 - apply(tcam_tbl_stage_2); - apply(ipv4_routing_exm_ways_4_pack_7_stage_2); - // stage 3 - apply(ipv4_routing_exm_ways_5_pack_3_stage_3); - /* Gateway not yet supported */ -// if (ipv4.protocol == 0) { - apply(udp_add_tbl_stage_3); -// } - - // stage 4 - apply(ipv4_routing_exm_ways_6_pack_3_stage_4); -// if (valid(tcp)) { - apply(tcp_rm_tbl_stage_4); -// } - - // stage 5 - apply(ipv4_routing_exm_ways_3_pack_4_stage_5); - apply(tcam_range); - apply(tcam_range_ternary_valid); - // stage 6 - apply(ipv4_routing_exm_ways_4_pack_4_stage_6); - apply(tcam_range_2_fields); - // stage 7 - apply(ipv4_routing_exm_ways_5_pack_4_stage_7); - apply(src_non_overlap_range_table); - apply(dest_non_overlap_range_table); - // stage 8 - apply(tcam_adt_deep_stage_8); - apply(ipv4_routing_exm_ways_4_pack_5_stage_8); - // Stage 9 - apply(ipv4_routing_select); - // Stage 10 - apply(tcam_indirect_action); - apply(no_key_1); - // Stage 11 - apply(match_range_table); - apply(no_key_2); -} - -control egress { - apply(eg_udp); - // Commenting out since modify of egress port is not possible in egress -// apply(ipv4_routing_exm_ways_6_pack_4_stage_11); -} - diff --git a/backends/tofino/bf-asm/test/ptf/basic_ipv4_selector.p4 b/backends/tofino/bf-asm/test/ptf/basic_ipv4_selector.p4 deleted file mode 100644 index 841d5641bba..00000000000 --- a/backends/tofino/bf-asm/test/ptf/basic_ipv4_selector.p4 +++ /dev/null @@ -1,269 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header_type md_t { - fields { - sport:16; - dport:16; - } -} - -metadata md_t md; - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - set_metadata(md.sport, latest.srcPort); - set_metadata(md.dport, latest.dstPort); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - set_metadata(md.sport, latest.srcPort); - set_metadata(md.dport, latest.dstPort); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - learn_meta_1:20; - learn_meta_2:24; - learn_meta_3:25; - learn_meta_4:10; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -header_type range_metadata_t { - fields { - src_range_index : 16; - dest_range_index : 16; - } -} - -metadata range_metadata_t range_mdata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm : csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action udp_set_src(port) { - modify_field(udp.srcPort, port); -} - -action nop() { -} - -@pragma command_line --no-dead-code-elimination -table ipv4_routing_select { - reads { - ipv4.dstAddr: lpm; - } - action_profile : ecmp_action_profile; - size : 512; -} - -field_list ecmp_hash_fields { - ipv4.srcAddr; - ipv4.dstAddr; - ipv4.identification; - ipv4.protocol; -} - -field_list_calculation ecmp_hash { - input { - ecmp_hash_fields; - } -#if defined(BMV2TOFINO) - algorithm : xxh64; -#else - algorithm : random; -#endif - output_width : 64; -} - -action_profile ecmp_action_profile { - actions { - nhop_set; - nop; - } - size : 1024; - // optional - dynamic_action_selection : ecmp_selector; -} - -action_selector ecmp_selector { - selection_key : ecmp_hash; // take a field_list_calculation only - // optional - selection_mode : resilient; // “resilient” or “non-resilient” -} - -action nhop_set(port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -table eg_udp { - reads { - ethernet : valid; - ipv4 : valid; - udp : valid; - udp.srcPort : exact; - } - actions { - nop; - udp_set_src; - } -} - - -control ingress { - apply(ipv4_routing_select); -} - -control egress { - apply(eg_udp); -} - diff --git a/backends/tofino/bf-asm/test/ptf/basic_switching.p4 b/backends/tofino/bf-asm/test/ptf/basic_switching.p4 deleted file mode 100644 index 0fd3e4a375e..00000000000 --- a/backends/tofino/bf-asm/test/ptf/basic_switching.p4 +++ /dev/null @@ -1,79 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// This is P4 sample source for basic_switching - -#include "includes/headers.p4" -#include "includes/parser.p4" -#include -#include - -action set_egr(egress_spec) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_spec); -} - -action nop() { -} - -action _drop() { - drop(); -} - -table forward { - reads { - ethernet.dstAddr : exact; - } - actions { - set_egr; nop; - } -} - -#if 0 -// VLAN based forwarding -table vlan_map { - reads { - ig_intr_md.ingress_port: exact; - vlan.vid : exact; - } - actions { - set_egr; - } -} - -#endif - -table acl { - reads { - ethernet.dstAddr : ternary; - ethernet.srcAddr : ternary; - } - actions { - nop; - _drop; - } -} - -control ingress { - apply(forward); -#if 0 - apply(vlan_map); -#endif -} - -control egress { - apply(acl); -} - diff --git a/backends/tofino/bf-asm/test/ptf/dkm.p4 b/backends/tofino/bf-asm/test/ptf/dkm.p4 deleted file mode 100644 index 413ead4cb47..00000000000 --- a/backends/tofino/bf-asm/test/ptf/dkm.p4 +++ /dev/null @@ -1,214 +0,0 @@ -#include -#include -#include - -#define VLAN_DEPTH 2 -#define ETHERTYPE_VLAN 0x8100 -#define ETHERTYPE_IPV4 0x0800 - - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr : 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl :3; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type metadata_t { - fields { - table_hit : 1; - table_id : 8; - } -} - -header ethernet_t ethernet; -header vlan_tag_t vlan_tag; -header ipv4_t ipv4; -header tcp_t tcp; -metadata metadata_t md; - -parser start { - return parse_ethernet; -} - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan; - default : ingress; - } -} - -parser parse_vlan { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default: ingress; - } -} - -parser parse_ipv4 { - extract(ipv4); - return select (latest.protocol) { - 6 : parse_tcp; - default: ingress; - } -} - -parser parse_tcp { - extract(tcp); - return ingress; -} - -action switch_to_dest_port (dport) { - modify_field(md.table_hit, 1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, dport); -} - -action switch_to_miss_port(miss_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, miss_port); -} - -action nop() { -} - - -/* - * Exm tables covering following scenarios are implemented/Tested using this p4. - * - Multiple match spec packed in one sram RAM word. - * - Multiple match spec packed in more than one sram RAM word. - * - More than 1 way. - * - Table spaning more than 1 stage. - */ - - - -@pragma stage 0 -@pragma ways 3 -@pragma pack 2 -@pragma dynamic_table_key_masks 1 -table l2_stage0_ways_3_pack_2 { - reads { - ethernet.srcAddr : exact; - ethernet.dstAddr : exact; - } - actions { - switch_to_dest_port; - } - size : 1024; -} - - -@pragma stage 1 -@pragma ways 6 -@pragma pack 2 -@pragma dynamic_table_key_masks 1 -table l2_stage1_ways_6_pack_2 { - reads { - ethernet.srcAddr : exact; - ethernet.dstAddr : exact; - } - actions { - switch_to_dest_port; - } - size : 1024; -} - - -@pragma stage 2 -@pragma ways 6 -@pragma pack 3 -@pragma dynamic_table_key_masks 1 -table l2_stage2_ways_6_pack_3 { - reads { - ethernet.srcAddr : exact; - ethernet.dstAddr : exact; - } - actions { - switch_to_dest_port; - } - size : 1024; -} - -@pragma ways 6 -@pragma pack 3 -@pragma dynamic_table_key_masks 1 -table l2_multistage_ways_6_pack_3 { - reads { - ethernet.srcAddr : exact; - ethernet.dstAddr : exact; - } - actions { - switch_to_dest_port; - } - size: 64000; -} - - - -table miss_check { - reads { - md.table_hit : exact; - } - actions { - switch_to_miss_port; - } - size : 1; -} - - - -control ingress { - apply(l2_stage0_ways_3_pack_2); - apply(l2_stage1_ways_6_pack_2); - apply(l2_stage2_ways_6_pack_3); - apply(l2_multistage_ways_6_pack_3); - apply(miss_check); -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/ptf/drivers_test.p4 b/backends/tofino/bf-asm/test/ptf/drivers_test.p4 deleted file mode 100644 index 3be6e1a4423..00000000000 --- a/backends/tofino/bf-asm/test/ptf/drivers_test.p4 +++ /dev/null @@ -1,477 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include "tofino/intrinsic_metadata.p4" -#include "tofino/constants.p4" -#include "p4features.h" - -#if defined(STATEFUL_DIRECT) || defined(STATEFUL_INDIRECT) -#include "tofino/stateful_alu_blackbox.p4" -#endif - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type ipv6_t { - fields { - version : 4; - trafficClass : 8; - flowLabel : 20; - payloadLen : 16; - nextHdr : 8; - hopLimit : 8; - srcAddr : 128; - dstAddr : 128; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - 0x86dd : parse_ipv6; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; -header ipv6_t ipv6; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -parser parse_ipv6 { - extract(ipv6); - return select(latest.nextHdr) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default : ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm : csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -#if defined(STATS_DIRECT) || defined(STATS_INDIRECT) -counter cntr { - type : packets; -#ifdef STATS_DIRECT - direct : match_tbl; -#elif defined(STATS_INDIRECT) -// static : match_tbl; - instance_count : STATS_COUNT; -#endif -} -#endif - -#if defined(METER_DIRECT) || defined(METER_INDIRECT) -meter mtr { - type : bytes; -#ifdef METER_DIRECT - direct : match_tbl; -// result : ig_intr_md_for_tm.packet_color; - result : ipv4.diffserv; -#elif defined(METER_INDIRECT) -// static : match_tbl; -// result : ig_intr_md_for_tm.packet_color; -// result : ipv4.diffserv; - instance_count : METER_COUNT; -#endif -} -#endif - -#if defined(STATEFUL_DIRECT) -register r { - width : 32; - direct : match_tbl; -} -blackbox stateful_alu r_alu { - reg: r; - initial_register_lo_value: 1; - update_lo_1_value: register_lo + 1; -} -#endif - -#if defined(STATEFUL_INDIRECT) -register r { - width : 32; - instance_count: STATEFUL_COUNT; -} -blackbox stateful_alu r_alu1 { - reg: r; - initial_register_lo_value: 1; - update_lo_1_value: register_lo + 1; -} -blackbox stateful_alu r_alu2 { - reg: r; - initial_register_lo_value: 1; - update_lo_1_value: register_lo + 100; -} -blackbox stateful_alu r_alu3 { - reg: r; - initial_register_lo_value: 1; - update_lo_1_value: register_lo + 1234; -} -blackbox stateful_alu r_alu4 { - reg: r; - initial_register_lo_value: 1; - update_lo_1_value: register_lo + 333; -} -#endif - - -action tcp_sport_modify (sPort, port) { - modify_field(tcp.srcPort, sPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -#ifdef STATEFUL_DIRECT - r_alu.execute_stateful_alu(); -#endif -} - -action tcp_dport_modify (dPort, port -#ifdef STATEFUL_INDIRECT - , stful_idx -#endif - ) { - modify_field(tcp.dstPort, dPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -#ifdef STATEFUL_INDIRECT - r_alu1.execute_stateful_alu(stful_idx); -#endif -#ifdef STATEFUL_DIRECT - r_alu.execute_stateful_alu(); -#endif -} - -action ipsa_modify (ipsa, port -#ifdef STATS_INDIRECT - ,stat_idx -#endif -#ifdef METER_INDIRECT - , meter_idx -#endif -#ifdef STATEFUL_INDIRECT - , stful_idx -#endif - ) { - modify_field(ipv4.srcAddr, ipsa); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -#ifdef STATS_INDIRECT - count(cntr, stat_idx); -#endif -#ifdef METER_INDIRECT -// execute_meter(mtr, meter_idx, ig_intr_md_for_tm.packet_color); - execute_meter(mtr, meter_idx, ipv4.diffserv); -#endif -#ifdef STATEFUL_INDIRECT - r_alu1.execute_stateful_alu(stful_idx); -#endif -#ifdef STATEFUL_DIRECT - r_alu.execute_stateful_alu(); -#endif -} - -action ipda_modify (ipda, port -#ifdef STATEFUL_INDIRECT - , stful_idx -#endif - ) { - modify_field(ipv4.dstAddr, ipda); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -#ifdef STATEFUL_INDIRECT - r_alu2.execute_stateful_alu(stful_idx); -#endif -#ifdef STATEFUL_DIRECT - r_alu.execute_stateful_alu(); -#endif -} - -action ipds_modify(ds, port -#ifdef STATEFUL_INDIRECT - , stful_idx -#endif - ) { - modify_field(ipv4.diffserv, ds); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -#ifdef STATEFUL_INDIRECT - r_alu3.execute_stateful_alu(stful_idx); -#endif -#ifdef STATEFUL_DIRECT - r_alu.execute_stateful_alu(); -#endif -} - -action ipttl_modify(ttl, port -#ifdef STATEFUL_INDIRECT - , stful_idx -#endif - ) { - modify_field(ipv4.ttl, ttl); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -#ifdef STATEFUL_INDIRECT - r_alu4.execute_stateful_alu(stful_idx); -#endif -#ifdef STATEFUL_DIRECT - r_alu.execute_stateful_alu(); -#endif -} - -#ifdef SELECTOR_INDIRECT -field_list ecmp_hash_fields { - ipv4.srcAddr; - ipv4.dstAddr; - ipv4.identification; - ipv4.protocol; -} - -field_list_calculation ecmp_hash { - input { - ecmp_hash_fields; - } - algorithm : random; - output_width : 72; -} - -action_selector ecmp_selector { - selection_key : ecmp_hash; // take a field_list_calculation only - // optional - selection_mode : resilient; // “resilient” or “non-resilient” -} -#endif - -#ifdef ACTION_INDIRECT -#ifdef STATS_INDIRECT -@pragma bind_indirect_res_to_match cntr -#endif -#ifdef METER_INDIRECT -@pragma bind_indirect_res_to_match mtr -#endif -#ifdef STATEFUL_INDIRECT -@pragma bind_indirect_res_to_match r -#endif -action_profile selector_profile { - actions { - tcp_sport_modify; - tcp_dport_modify; - ipsa_modify; - ipda_modify; - ipds_modify; - ipttl_modify; - } - size : ACTION_COUNT; -#ifdef SELECTOR_INDIRECT - dynamic_action_selection : ecmp_selector; -#endif -} -#endif - -#ifdef MATCH_EXM -#if MATCH_COUNT > 40000 -@pragma stage 0 8192 -@pragma stage 1 6144 -@pragma stage 2 8192 -@pragma stage 3 6144 -@pragma stage 4 8192 -@pragma stage 5 6144 -@pragma stage 6 8192 -@pragma stage 7 6144 -@pragma stage 8 8192 -@pragma stage 9 6144 -@pragma stage 10 8192 -@pragma stage 11 -#endif -#endif -#ifdef MATCH_ATCAM -@pragma atcam_partition_index vlan_tag.vlan_id -#endif -#ifdef MATCH_ALPM -@pragma alpm 1 -#endif -#ifdef SELECTOR_INDIRECT -@pragma selector_max_group_size 20 -@pragma selector_num_max_groups SELECTOR_COUNT -#endif -table match_tbl { - reads { -#ifdef MATCH_EXM - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - ipv4.protocol : exact; - ethernet.dstAddr : exact; -#elif defined(MATCH_TCAM) - ipv4.dstAddr:ternary; -#elif defined(MATCH_ATCAM) - ipv4.dstAddr : ternary; - vlan_tag.vlan_id : exact; -#elif defined(MATCH_ALPM) - ipv4.dstAddr : lpm; - vlan_tag.vlan_id : exact; -#endif - } -#ifdef ACTION_INDIRECT - action_profile : selector_profile; -#elif defined(ACTION_DIRECT) - actions { - tcp_sport_modify; - tcp_dport_modify; - ipsa_modify; - ipda_modify; - ipds_modify; - ipttl_modify; - } -#endif - size : MATCH_COUNT; -#ifdef SUPPORT_IDLE - support_timeout: true; -#endif -} - -/* Main control flow */ -control ingress { - apply(match_tbl); -} - -control egress { -} - diff --git a/backends/tofino/bf-asm/test/ptf/easy.p4 b/backends/tofino/bf-asm/test/ptf/easy.p4 deleted file mode 100644 index 6b5cd0dda55..00000000000 --- a/backends/tofino/bf-asm/test/ptf/easy.p4 +++ /dev/null @@ -1,32 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header ethernet_t ethernet; - -parser start { - return parse_ethernet; -} - -parser parse_ethernet { - extract(ethernet); - return ingress; -} - -action nop() { } - -action do() { modify_field(ig_intr_md_for_tm.ucast_egress_port, 2); } - -table t { - reads { ig_intr_md.ingress_port : exact; } - actions { nop; do; } - default_action : do(); -} - -control ingress { apply(t); } diff --git a/backends/tofino/bf-asm/test/ptf/easy_ternary.p4 b/backends/tofino/bf-asm/test/ptf/easy_ternary.p4 deleted file mode 100644 index 56fa427edd0..00000000000 --- a/backends/tofino/bf-asm/test/ptf/easy_ternary.p4 +++ /dev/null @@ -1,32 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header ethernet_t ethernet; - -parser start { - return parse_ethernet; -} - -parser parse_ethernet { - extract(ethernet); - return ingress; -} - -action nop() { } - -action do(val) { modify_field(ig_intr_md_for_tm.ucast_egress_port, val); } - -table t { - reads { ethernet.etherType : lpm; } - actions { nop; do; } - default_action : nop(); -} - -control ingress { apply(t); } diff --git a/backends/tofino/bf-asm/test/ptf/ecmp_pi.p4 b/backends/tofino/bf-asm/test/ptf/ecmp_pi.p4 deleted file mode 100644 index 40b969d1381..00000000000 --- a/backends/tofino/bf-asm/test/ptf/ecmp_pi.p4 +++ /dev/null @@ -1,221 +0,0 @@ -/* Copyright 2013-present Barefoot Networks, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -parser start { - return parse_ethernet; -} - -#define ETHERTYPE_IPV4 0x0800 - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - ETHERTYPE_IPV4 : parse_ipv4; - default: ingress; - } -} - -header ipv4_t ipv4; - -field_list ipv4_checksum_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_checksum { - input { - ipv4_checksum_list; - } - algorithm : csum16; - output_width : 16; -} - -calculated_field ipv4.hdrChecksum { - verify ipv4_checksum; - update ipv4_checksum; -} - -#define IP_PROTOCOLS_TCP 6 - -parser parse_ipv4 { - extract(ipv4); - return select(latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - default: ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - - -action _drop() { - drop(); -} - -header_type routing_metadata_t { - fields { - nhop_ipv4 : 32; - } -} - -metadata routing_metadata_t routing_metadata; - -action set_nhop(nhop_ipv4, port) { - modify_field(routing_metadata.nhop_ipv4, nhop_ipv4); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); - add_to_field(ipv4.ttl, -1); -} - -#define ECMP_BIT_WIDTH 16 -#define ECMP_GROUP_TABLE_SIZE 1024 -#define ECMP_SELECT_TABLE_SIZE 16384 - -field_list l3_hash_fields { - ipv4.srcAddr; - ipv4.dstAddr; - ipv4.protocol; - tcp.srcPort; - tcp.dstPort; -} - -field_list_calculation ecmp_hash { - input { - l3_hash_fields; - } - algorithm : crc16; - output_width : ECMP_BIT_WIDTH; -} - -table ecmp_group { - reads { - ipv4.dstAddr : lpm; - } - action_profile: ecmp_action_profile; - size : ECMP_GROUP_TABLE_SIZE; -} - -action_selector ecmp_selector { - selection_key : ecmp_hash; -} - -action_profile ecmp_action_profile { - actions { - _drop; - set_nhop; - } - size : ECMP_SELECT_TABLE_SIZE; - dynamic_action_selection : ecmp_selector; -} - -action set_dmac(dmac) { - modify_field(ethernet.dstAddr, dmac); -} - -table forward { - reads { - routing_metadata.nhop_ipv4 : exact; - } - actions { - set_dmac; - _drop; - } - size: 512; -} - -action rewrite_mac(smac) { - modify_field(ethernet.srcAddr, smac); -} - -table send_frame { - reads { - eg_intr_md.egress_port: exact; - } - actions { - rewrite_mac; - _drop; - } - size: 256; -} - -control ingress { - if(valid(ipv4) and ipv4.ttl != 0) { - apply(ecmp_group); - apply(forward); - } -} - -control egress { - apply(send_frame); -} diff --git a/backends/tofino/bf-asm/test/ptf/emulation.p4 b/backends/tofino/bf-asm/test/ptf/emulation.p4 deleted file mode 100644 index 765936d6a66..00000000000 --- a/backends/tofino/bf-asm/test/ptf/emulation.p4 +++ /dev/null @@ -1,202 +0,0 @@ -#include -#include -#include - -#define VLAN_DEPTH 2 -#define ETHERTYPE_VLAN 0x8100 -#define ETHERTYPE_IPV4 0x0800 - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - - -header ethernet_t ethernet; -header vlan_tag_t vlan_tag_; - -parser start { - return parse_ethernet; -} - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - ETHERTYPE_VLAN : parse_vlan; - default : ingress; - } -} - -parser parse_vlan { - extract(vlan_tag_); - return ingress; -} - - -action dmac_miss(flood_mc_index) { - modify_field(ig_intr_md_for_tm.mcast_grp_a, flood_mc_index); -} - -action dmac_unicast_hit(egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action dmac_multicast_hit(mc_index) { - modify_field(ig_intr_md_for_tm.mcast_grp_a, mc_index); - modify_field(ig_intr_md_for_tm.enable_mcast_cutthru, 1); -} - -action dmac_uc_mc_hit(egress_port, mc_index) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ig_intr_md_for_tm.mcast_grp_a, mc_index); - modify_field(ig_intr_md_for_tm.enable_mcast_cutthru, 1); -} - -table dmac { - reads { - ethernet.dstAddr : exact; - } - actions { - dmac_miss; - dmac_unicast_hit; - dmac_multicast_hit; - dmac_uc_mc_hit; - } - size : 4096; -} - -action qos_miss() { - modify_field(ig_intr_md_for_tm.ingress_cos, 0); - modify_field(ig_intr_md_for_tm.qid, 0); -} - -action qos_hit_eg_bypass_no_mirror(qid, color) { - modify_field(ig_intr_md_for_tm.ingress_cos, 1); - modify_field(ig_intr_md_for_tm.qid, qid); - bypass_egress(); -#ifndef SINGLE_STAGE - modify_field(ig_intr_md_for_tm.packet_color, color); -#else - modify_field(ig_intr_md_for_tm._pad5, color); -#endif /* !SINGLE_STAGE */ -} - -action qos_hit_no_eg_bypass_no_mirror(qid, color) { - modify_field(ig_intr_md_for_tm.ingress_cos, 1); - modify_field(ig_intr_md_for_tm.qid, qid); -#ifndef SINGLE_STAGE - modify_field(ig_intr_md_for_tm.packet_color, color); -#else - modify_field(ig_intr_md_for_tm._pad5, color); -#endif /* !SINGLE_STAGE */ -} - -action qos_hit_eg_bypass_i2e_mirror(qid, mirror_id) { - modify_field(ig_intr_md_for_tm.ingress_cos, 1); - modify_field(ig_intr_md_for_tm.qid, qid); - bypass_egress(); - clone_ingress_pkt_to_egress(mirror_id); -} - -action qos_hit_e2e_mirror(qid, mirror_id) { - clone_egress_pkt_to_egress(mirror_id); -} - - -table ingress_qos { - reads { - vlan_tag_: valid; - vlan_tag_.vid : exact; - } - actions { - qos_miss; - qos_hit_eg_bypass_i2e_mirror; - qos_hit_eg_bypass_no_mirror; - qos_hit_no_eg_bypass_no_mirror; - } - size : 8192; -} - -action do_resubmit() { - resubmit(); -} - -table resubmit_tbl { - actions { do_resubmit; } -} - -action do_deflect_on_drop() { - modify_field(ig_intr_md_for_tm.deflect_on_drop, 1); -} - -table deflect_on_drop_tbl { - actions { do_deflect_on_drop; } -} - -action do_recirc() { - recirculate(68); - invalidate(ig_intr_md_for_tm.mcast_grp_a); -} - -action noop() { - no_op(); -} - -table recirc_tbl { - reads { - ig_intr_md.ingress_port : exact; - } - actions { - do_recirc; - noop; - } -} - - -table egress_qos { - reads { - vlan_tag_: valid; - vlan_tag_.vid : exact; - } - actions { - qos_hit_e2e_mirror; - } - size : 8192; -} - - - -control ingress { - apply(dmac); - apply(ingress_qos); -#ifndef SINGLE_STAGE - if (0 == ig_intr_md.resubmit_flag and - 1 == vlan_tag_.pcp) { - apply(resubmit_tbl); - } else - if (2 == vlan_tag_.pcp) { - apply(deflect_on_drop_tbl); - } else - if (3 == vlan_tag_.pcp) { - apply(recirc_tbl); - } -#endif /* !SINGLE_STAGE */ -} - -control egress { - if (pkt_is_not_mirrored) { - apply(egress_qos); - } -} diff --git a/backends/tofino/bf-asm/test/ptf/exm_direct.p4 b/backends/tofino/bf-asm/test/ptf/exm_direct.p4 deleted file mode 100644 index 32962153718..00000000000 --- a/backends/tofino/bf-asm/test/ptf/exm_direct.p4 +++ /dev/null @@ -1,723 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include "tofino_exm.p4" -#include "tofino/intrinsic_metadata.p4" -#include "tofino/constants.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type ipv6_t { - fields { - version : 4; - trafficClass : 8; - flowLabel : 20; - payloadLen : 16; - nextHdr : 8; - hopLimit : 8; - srcAddr : 128; - dstAddr : 128; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - 0x86dd : parse_ipv6; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; -header ipv6_t ipv6; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -parser parse_ipv6 { - extract(ipv6); - return select(latest.nextHdr) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default : ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm : csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action egress_port(egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop_ipv4(egress_port /*,srcmac, dstmac*/) { - hop(ipv4.ttl, egress_port); -// modify_field(ethernet.srcAddr, srcmac); -// modify_field(ethernet.dstAddr, dstmac); -} - -action drop_ipv4 () { - drop(); -} - -action next_hop_ipv4(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action next_hop_ipv6(egress_port ,srcmac, dstmac) { - hop(ipv6.hopLimit, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action ig_drop() { -// modify_field(routing_metadata.drop, 1); - add_to_field(ipv4.ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); -} - -action mod_mac_addr(egress_port, srcmac, dstmac) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action udp_hdr_add (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - add_header(udp); - modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); - add_to_field(ipv4.totalLen, 8); -} - -action tcp_hdr_rm (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - remove_header(tcp); - modify_field(ipv4.protocol, 0); -// add_to_field(ipv4.totalLen, -20); -// modify_field(ipv4.totalLen, 66); -} - -action modify_tcp_dst_port(dstPort) { - modify_field(tcp.dstPort, dstPort); -} - -action modify_tcp_dst_port_1(dstPort, egress_port) { - modify_field(tcp.dstPort, dstPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ipv4.srcAddr, ipAddr); - modify_field(ethernet.dstAddr, dstAddr); - modify_field(tcp.dstPort, tcpPort); -} - -action custom_action_2(egress_port, ipAddr, tcpPort) -{ - modify_field(ipv4.srcAddr, ipAddr); - modify_field(tcp.dstPort, tcpPort); - hop(ipv4.ttl, egress_port); -} - -action custom_action_3(egress_port, dstAddr, dstIp) -{ - modify_field(ipv4.dstAddr, dstIp); - modify_field(ethernet.dstAddr, dstAddr); - hop(ipv4.ttl, egress_port); -} - -action custom_action_4(egress_port, dstPort, srcPort) -{ - modify_field(tcp.dstPort, dstPort); - modify_field(tcp.srcPort, srcPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_5(dstPort, srcPort) -{ - modify_field(tcp.dstPort, dstPort); - modify_field(tcp.srcPort, srcPort); -} - -action switching_action_1(egress_port/*, vlan_id */) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - //modify_field(vlan_tag.vlan_id, vlan_id); -} - -action nhop_set(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action nhop_set_1(port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -@pragma command_line --no-dead-code-elimination -@pragma stage 0 -@pragma pack 5 -@pragma ways 5 -table exm_5ways_5Entries { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_3; - } - - size : 25600; -} - -@pragma stage 1 -@pragma pack 5 -@pragma ways 6 - -table exm_6ways_5Entries { - reads { - ethernet.dstAddr : exact; - ipv4.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - next_hop_ipv4; - } - size : 30720; -} - -@pragma stage 2 -@pragma pack 6 -@pragma ways 4 - -table exm_4ways_6Entries { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - custom_action_1; - } - size : 24576; -} - -@pragma stage 3 -@pragma pack 6 -@pragma ways 5 - -table exm_5ways_6Entries { - reads { - ethernet.dstAddr : exact; - } - actions { - nop; - custom_action_2; - } - size : 30720; -} - -@pragma stage 4 -@pragma pack 6 -@pragma ways 6 - -table exm_6ways_6Entries { - reads { - ethernet.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - mod_mac_addr; - } - size : 36864; -} - -@pragma stage 5 -@pragma pack 7 -@pragma ways 3 - -table exm_3ways_7Entries { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } - size : 21504; -} - -@pragma stage 6 -@pragma pack 8 -@pragma ways 4 - -table exm_4ways_8Entries { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - modify_tcp_dst_port_1; - } - size : 32768; -} - -field_list ecmp_hash_fields { - ipv4.srcAddr; - ipv4.dstAddr; - ipv4.identification; - ipv4.protocol; -} - -field_list_calculation ecmp_hash { - input { - ecmp_hash_fields; - } -#if defined(BMV2TOFINO) - algorithm : xxh64; -#else - algorithm : random; -#endif - output_width : 72; -} - -@pragma stage 7 -@pragma selector_max_group_size 119040 -//@pragma selector_max_group_size 200 -table tcp_port_select { - reads { - ipv4.dstAddr: lpm; - } - action_profile : tcp_port_action_profile; - size : 512; -} - -action_profile tcp_port_action_profile { - actions { - tcp_port_modify; - nop; - } - size : 131072; -// size : 1024; - dynamic_action_selection : ecmp_selector; -} - -action_selector ecmp_selector { - selection_key : ecmp_hash; // take a field_list_calculation only - // optional - selection_mode : resilient; // “resilient” or “non-resilient” -} - -@pragma stage 8 -//@pragma selector_max_group_size 119040 -@pragma selector_max_group_size 100 -table tcp_port_select_exm { - reads { - ipv4.dstAddr: exact; - } - action_profile : tcp_port_action_profile_exm; - size : 512; -} - -action_profile tcp_port_action_profile_exm { - actions { - tcp_port_modify; - nop; - } -// size : 131072; - size : 2048; - dynamic_action_selection : fair_selector; -} - -action_selector fair_selector { - selection_key : ecmp_hash; // take a field_list_calculation only - // optional - selection_mode : non_resilient; // “resilient” or “non-resilient” -} - -action tcp_port_modify(sPort, port) { - modify_field(tcp.srcPort, sPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -@pragma immediate 1 -@pragma stage 9 -@pragma include_idletime 1 -@pragma idletime_precision 2 -table idle_tcam_2 { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - hop_ipv4; - } - size : 512; - support_timeout: true; -} - -@pragma immediate 1 -@pragma stage 9 -@pragma include_idletime 1 -@pragma idletime_precision 6 -table idle_tcam_6 { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - hop_ipv4; - } - size : 512; - support_timeout: true; -} - -@pragma immediate 1 -@pragma stage 9 -@pragma include_idletime 1 -@pragma idletime_precision 3 -@pragma idletime_per_flow_idletime 0 -table idle_tcam_3d { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - hop_ipv4; - } - size : 512; - support_timeout: true; -} - -@pragma immediate 1 -@pragma stage 9 -@pragma include_idletime 1 -@pragma idletime_precision 6 -@pragma idletime_per_flow_idletime 0 -table idle_tcam_6d { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - hop_ipv4; - } - size : 512; - support_timeout: true; -} - -@pragma stage 9 -@pragma pack 1 -@pragma ways 4 -table exm_movereg { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } - size : 4096; -} - -counter exm_cnt { - type : packets; - direct : exm_movereg; -} - -@pragma immediate 1 -@pragma stage 10 -@pragma include_idletime 1 -@pragma idletime_precision 1 -table idle_tcam_1 { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - hop_ipv4; - } - size : 512; - support_timeout: true; -} - -@pragma immediate 1 -@pragma stage 10 -@pragma include_idletime 1 -@pragma idletime_precision 2 -table idle_2 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - hop_ipv4; - } - size : 1024; - support_timeout: true; -} - -@pragma immediate 1 -@pragma stage 10 -@pragma include_idletime 1 -@pragma idletime_precision 3 -table idle_3 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - hop_ipv4; - } - size : 1024; - support_timeout: true; -} - -@pragma immediate 1 -@pragma stage 10 -@pragma include_idletime 1 -@pragma idletime_precision 6 -table idle_6 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - hop_ipv4; - } - size : 1024; - support_timeout: true; -} - -@pragma immediate 1 -@pragma stage 11 -@pragma include_idletime 1 -@pragma idletime_precision 3 -table idle_tcam_3 { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - hop_ipv4; - } - size : 12288; - support_timeout: true; -} - - -/* Main control flow */ -control ingress { - /* A general principle : Always keep the exact match tables ahead of the - * ternary tables in the same stage, except first stage. Logic relating to next-table - * will cause the Tofino model not to launch a lookup on th exact match - * tables if the order is reversed. - */ - apply(exm_5ways_5Entries); - apply(exm_6ways_5Entries); - apply(exm_4ways_6Entries); - apply(exm_5ways_6Entries); - apply(exm_6ways_6Entries); - apply(exm_3ways_7Entries); - apply(exm_4ways_8Entries); - //Stage 7 - apply(tcp_port_select); - // Stage 8 - apply(tcp_port_select_exm); - // Stage 9 - apply(idle_tcam_2); - apply(idle_tcam_6); - apply(idle_tcam_3d); - apply(idle_tcam_6d); - apply(exm_movereg); - //Stage 10 - apply(idle_tcam_1); - apply(idle_2); - apply(idle_3); - apply(idle_6); - //Stage 11 - apply(idle_tcam_3); -} - -action eg_drop() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); - modify_field(intrinsic_metadata.egress_port, 0); -} - -action permit() { -} - -table egress_acl { - reads { - routing_metadata.drop: ternary; - } - actions { - permit; - eg_drop; - } -} - -control egress { -// apply(egress_acl); -} diff --git a/backends/tofino/bf-asm/test/ptf/exm_direct_1.p4 b/backends/tofino/bf-asm/test/ptf/exm_direct_1.p4 deleted file mode 100644 index 236d0ebfd2b..00000000000 --- a/backends/tofino/bf-asm/test/ptf/exm_direct_1.p4 +++ /dev/null @@ -1,780 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include "tofino.p4" -#include "tofino/intrinsic_metadata.p4" -#include "tofino/constants.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type ipv6_t { - fields { - version : 4; - trafficClass : 8; - flowLabel : 20; - payloadLen : 16; - nextHdr : 8; - hopLimit : 8; - srcAddr : 128; - dstAddr : 128; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - 0x86dd : parse_ipv6; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; -header ipv6_t ipv6; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -parser parse_ipv6 { - extract(ipv6); - return select(latest.nextHdr) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default : ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm : csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action egress_port(egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop_ipv4(egress_port /*,srcmac, dstmac*/) { - hop(ipv4.ttl, egress_port); -// modify_field(ethernet.srcAddr, srcmac); -// modify_field(ethernet.dstAddr, dstmac); -} - -action drop_ipv4 () { - drop(); -} - -action next_hop_ipv4(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action next_hop_ipv6(egress_port ,srcmac, dstmac) { - hop(ipv6.hopLimit, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action ig_drop() { -// modify_field(routing_metadata.drop, 1); - add_to_field(ipv4.ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); -} - -action mod_mac_addr(egress_port, dstmac) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ethernet.dstAddr, dstmac); -} - -action udp_hdr_add (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - add_header(udp); - modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); - add_to_field(ipv4.totalLen, 8); -} - -action tcp_hdr_rm (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - remove_header(tcp); - modify_field(ipv4.protocol, 0); -// add_to_field(ipv4.totalLen, -20); -// modify_field(ipv4.totalLen, 66); -} - -action modify_tcp_dst_port(dstPort) { - modify_field(tcp.dstPort, dstPort); -} - -action modify_tcp_dst_port_1(dstPort, egress_port) { - modify_field(tcp.dstPort, dstPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ipv4.srcAddr, ipAddr); - modify_field(ethernet.dstAddr, dstAddr); - modify_field(tcp.dstPort, tcpPort); -} - -action custom_action_2(egress_port, ipAddr, tcpPort) -{ - modify_field(ipv4.srcAddr, ipAddr); - modify_field(tcp.dstPort, tcpPort); - hop(ipv4.ttl, egress_port); -} - -action custom_action_3(egress_port, dstAddr, dstIp) -{ - modify_field(ipv4.dstAddr, dstIp); - modify_field(ethernet.dstAddr, dstAddr); - hop(ipv4.ttl, egress_port); -} - -action custom_action_4(egress_port, dstPort, srcPort) -{ - modify_field(tcp.dstPort, dstPort); - modify_field(tcp.srcPort, srcPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_5(dstPort, srcPort) -{ - modify_field(tcp.dstPort, dstPort); - modify_field(tcp.srcPort, srcPort); -} - -action switching_action_1(egress_port/*, vlan_id */) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - //modify_field(vlan_tag.vlan_id, vlan_id); -} - - -@pragma command_line --no-dead-code-elimination -@pragma pack 7 -@pragma ways 5 -table exm_5ways_7Entries { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - custom_action_3; - } - size : 35840; -} - - - -@pragma stage 0 -@pragma pack 2 - -table exm_6ways_2Entries { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - modify_tcp_dst_port; - } - size : 12288; -} - -@pragma stage 0 -@pragma ways 3 -@pragma pack 1 - -table exm_3ways_1Entries { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } - size : 3072; -} - - -@pragma stage 1 -@pragma ways 4 -@pragma pack 1 - -table exm_4ways_1Entries { - reads { - ipv4.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - custom_action_2; - } - size : 4096; -} - -@pragma stage 2 -@pragma pack 1 -@pragma ways 5 - -table exm_5ways_1Entries { - reads { - ethernet.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_3; - } - - size : 5120; -} - - -@pragma stage 3 -@pragma ways 6 -@pragma pack 7 - -table exm_6ways_7Entries { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } - size : 43008; -} - -@pragma stage 4 -@pragma pack 8 - -table exm_deep_32k { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - custom_action_3; - } - - size : 32768; -} - -@pragma stage 5 -@pragma pack 8 - -table exm_deep_64k { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - modify_tcp_dst_port_1; - } - - size : 65536; -} - -@pragma stage 6 -@pragma pack 1 -@pragma ways 6 - -table exm_6ways_1Entries { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - tcp.dstPort : exact; - tcp.srcPort : exact; - } - actions { - nop; - next_hop_ipv4; - } - size : 6144; -} - -@pragma stage 7 -@pragma pack 2 -@pragma ways 5 - -table exm_5ways_2Entries { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - custom_action_4; - } - - size : 10240; -} - -@pragma stage 8 -@pragma pack 2 -@pragma ways 4 - -table exm_4ways_2Entries { - reads { - ipv4.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - next_hop_ipv4; - } - - size : 8192; -} - -@pragma stage 8 -@pragma pack 2 -@pragma ways 3 - -table exm_3ways_2Entries { - reads { - ipv4.srcAddr : exact; - ipv4.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - custom_action_5; - } - - size : 6144; -} - -@pragma stage 9 - -table exm_wide_key { - reads { - ipv4.srcAddr : exact; - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - tcp.dstPort : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_1; - } - - size : 2048; -} - -@pragma stage 10 -@pragma ways 6 -@pragma pack 8 - -table exm_6ways_8Entries { - reads { - ethernet.dstAddr : exact; - } - actions { - nop; - mod_mac_addr; - } - - size : 49152; -} - -@pragma stage 11 -@pragma ways 5 -@pragma pack 8 - -table exm_5ways_8Entries { - reads { - tcp.dstPort : exact; - } - actions { - nop; - tcp_hdr_rm; - } - - size: 40960; -} - -@pragma ways 3 -@pragma pack 8 - -table exm_3ways_8Entries_stage_1 { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - custom_action_2; - } -} - -@pragma pack 7 -@pragma ways 2 - -table exm_2ways_7Entries_stage_3 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - ipv4.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 8 -@pragma ways 2 - -table exm_2ways_8Entries_stage_3 { - reads { - tcp.dstPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - - - - - -@pragma pack 4 -@pragma ways 2 - -table exm_2ways_4Entries_stage_5 { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma pack 5 -@pragma ways 2 - -table exm_2ways_5Entries_stage_5 { - reads { - tcp.srcPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -@pragma ways 4 -table exm_4ways_16k_stage_5 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } - - size : 16384; -} - -@pragma pack 6 -@pragma ways 2 - -table exm_2ways_6Entries_stage_6 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - - -@pragma ways 5 -table exm_5ways_16k_stage_7 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - tcp.srcPort : exact; - tcp.dstPort : exact; - } - actions { - nop; - next_hop_ipv4; - } - - size : 16384; -} - -@pragma ways 6 -table exm_6ways_32k_stage_8 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - tcp.srcPort : exact; - tcp.dstPort : exact; - } - actions { - nop; - next_hop_ipv4; - } - - size : 32768; -} - -@pragma ways 2 -@pragma pack 2 - -table exm_2ways_32k_stage_9 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - tcp.srcPort : exact; - tcp.dstPort : exact; - } - actions { - nop; - custom_action_3; - } - - size : 32768; -} - -@pragma pack 8 -@pragma ways 4 - -table exm_4ways_8Entries { - reads { - ipv4.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_3; - } -} - - -/* Main control flow */ -control ingress { - /* A general principle : Always keep the exact match tables ahead of the - * ternary tables in the same stage, except first stage. Logic relating to next-table - * will cause the Tofino model not to launch a lookup on th exact match - * tables if the order is reversed. - */ - apply(exm_5ways_7Entries); - apply(exm_6ways_2Entries); - //apply(exm_4ways_8Entries); - apply(exm_3ways_1Entries); - apply(exm_4ways_1Entries); - apply(exm_5ways_1Entries); - apply(exm_6ways_7Entries); - apply(exm_deep_32k); - apply(exm_deep_64k); - apply(exm_6ways_1Entries); - apply(exm_5ways_2Entries); - apply(exm_4ways_2Entries); - apply(exm_3ways_2Entries); - apply(exm_wide_key); - apply(exm_6ways_8Entries); - apply(exm_5ways_8Entries); - ////apply(exm_3ways_8Entries_stage_1); - //apply(exm_2ways_7Entries_stage_3); - ////apply(exm_2ways_8Entries_stage_3); - //apply(exm_2ways_4Entries_stage_5); - //apply(exm_2ways_5Entries_stage_5); - //apply(exm_2ways_6Entries_stage_6); -} - -action eg_drop() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); - modify_field(intrinsic_metadata.egress_port, 0); -} - -action permit() { -} - -table egress_acl { - reads { - routing_metadata.drop: ternary; - } - actions { - permit; - eg_drop; - } -} - -control egress { -// apply(egress_acl); -} - diff --git a/backends/tofino/bf-asm/test/ptf/exm_indirect_1.p4 b/backends/tofino/bf-asm/test/ptf/exm_indirect_1.p4 deleted file mode 100644 index 90e2113ee0d..00000000000 --- a/backends/tofino/bf-asm/test/ptf/exm_indirect_1.p4 +++ /dev/null @@ -1,893 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include "tofino.p4" -#include "tofino/intrinsic_metadata.p4" -#include "tofino/constants.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type ipv6_t { - fields { - version : 4; - trafficClass : 8; - flowLabel : 20; - payloadLen : 16; - nextHdr : 8; - hopLimit : 8; - srcAddr : 128; - dstAddr : 128; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - 0x86dd : parse_ipv6; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; -header ipv6_t ipv6; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -parser parse_ipv6 { - extract(ipv6); - return select(latest.nextHdr) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default : ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm : csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action egress_port(egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop_ipv4(egress_port /*,srcmac, dstmac*/) { - hop(ipv4.ttl, egress_port); -// modify_field(ethernet.srcAddr, srcmac); -// modify_field(ethernet.dstAddr, dstmac); -} - -action drop_ipv4 () { - drop(); -} - -action next_hop_ipv4(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action next_hop_ipv6(egress_port ,srcmac, dstmac) { - hop(ipv6.hopLimit, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action ig_drop() { -// modify_field(routing_metadata.drop, 1); - add_to_field(ipv4.ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); -} - -action mod_mac_addr(egress_port, srcmac, dstmac) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action udp_hdr_add (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - add_header(udp); - modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); - add_to_field(ipv4.totalLen, 8); -} - -action tcp_hdr_rm (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - remove_header(tcp); - modify_field(ipv4.protocol, 0); -// add_to_field(ipv4.totalLen, -20); -// modify_field(ipv4.totalLen, 66); -} - -action modify_tcp_dst_port(dstPort) { - modify_field(tcp.dstPort, dstPort); -} - -action modify_tcp_dst_port_1(dstPort, egress_port) { - modify_field(tcp.dstPort, dstPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ipv4.srcAddr, ipAddr); - modify_field(ethernet.dstAddr, dstAddr); - modify_field(tcp.dstPort, tcpPort); -} - -action custom_action_2(egress_port, ipAddr, tcpPort) -{ - modify_field(ipv4.srcAddr, ipAddr); - modify_field(tcp.dstPort, tcpPort); - hop(ipv4.ttl, egress_port); -} - -action custom_action_3(egress_port, dstAddr, dstIp) -{ - modify_field(ipv4.dstAddr, dstIp); - modify_field(ethernet.dstAddr, dstAddr); - hop(ipv4.ttl, egress_port); -} - -action custom_action_4(egress_port, dstPort, srcPort) -{ - modify_field(tcp.dstPort, dstPort); - modify_field(tcp.srcPort, srcPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_5(dstPort, srcPort) -{ - modify_field(tcp.dstPort, dstPort); - modify_field(tcp.srcPort, srcPort); -} - -action switching_action_1(egress_port/*, vlan_id */) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - //modify_field(vlan_tag.vlan_id, vlan_id); -} - -action nhop_set(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action nhop_set_1(port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action hash_action(value) { - modify_field(ipv4.ttl, value); -} - -action hash_action2(value) { - modify_field(vlan_tag.pri, value); -} - -action_profile custom_action_3_profile { - actions { - nop; - custom_action_3; - egress_port; - } - size : 1024; -} - -action_profile next_hop_ipv4_profile { - actions { - nop; - next_hop_ipv4; - } - - size : 2048; -} - -action_profile next_hop_ipv4_1_profile { - actions { - nop; - next_hop_ipv4; - } - - size : 2048; -} - -action_profile custom_action_1_profile { - actions { - nop; - custom_action_1; - } - size : 2048; -} - -action_profile custom_action_2_profile { - actions { - nop; - custom_action_2; - } - size : 2048; -} - -action_profile mod_mac_addr_profile { - actions { - nop; - mod_mac_addr; - } - size : 1024; -} - -action_profile modify_tcp_dst_port_1_profile { - actions { - nop; - modify_tcp_dst_port_1; - } - size : 1024; -} - -@pragma command_line --no-dead-code-elimination -@pragma stage 0 -@pragma pack 5 -@pragma ways 5 -table exm_5ways_5Entries { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - tcp.srcPort : exact; - } - - action_profile : custom_action_3_profile; - - size : 25600; -} - -@pragma stage 1 -@pragma pack 5 -@pragma ways 6 - -table exm_6ways_5Entries { - reads { - ethernet.dstAddr : exact; - ipv4.dstAddr : exact; - tcp.dstPort : exact; - } - - action_profile : next_hop_ipv4_profile; - - size : 30720; -} - -@pragma stage 2 -@pragma pack 6 -@pragma ways 4 - -table exm_4ways_6Entries { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - - action_profile : custom_action_1_profile; - - size : 24576; -} - -@pragma stage 3 -@pragma pack 6 -@pragma ways 5 - -table exm_5ways_6Entries { - reads { - ethernet.dstAddr : exact; - } - - action_profile : custom_action_2_profile; - - size : 30720; -} - -@pragma stage 4 -@pragma pack 6 -@pragma ways 6 - -table exm_6ways_6Entries { - reads { - ethernet.dstAddr : exact; - tcp.srcPort : exact; - } - - action_profile : mod_mac_addr_profile; - - size : 36864; -} - -@pragma stage 5 -@pragma pack 7 -@pragma ways 3 - -table exm_3ways_7Entries { - reads { - ipv4.dstAddr : exact; - } - - action_profile : next_hop_ipv4_1_profile; - - size : 21504; -} - -@pragma stage 6 -@pragma pack 8 -@pragma ways 4 - -table exm_4ways_8Entries { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - - action_profile : modify_tcp_dst_port_1_profile; - - size : 32768; -} - -@pragma stage 7 - -table exm_ipv4_routing { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - - action_profile : next_hop_profile; - - size : 32768; -} - -action_profile next_hop_profile { - actions { - nhop_set; - nop; - } -size : 4096; -} - -field_list ecmp_hash_fields { - ipv4.srcAddr; - ipv4.dstAddr; - ipv4.identification; - ipv4.protocol; -} - -field_list_calculation ecmp_hash { - input { - ecmp_hash_fields; - } -#if defined(BMV2TOFINO) - algorithm : xxh64; -#else - algorithm : random; -#endif - output_width : 64; -} - -@pragma stage 8 -table ipv4_routing_select { - reads { - ipv4.dstAddr: exact; - } - action_profile : ecmp_action_profile; -} - -@pragma stage 8 -table ipv4_routing_select_iter { - reads { - ipv4.dstAddr: exact; - } - action_profile : ecmp_action_profile_iter; -} - -@pragma stage 9 -table stat_tbl_indirect_pkt_64bit { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - act; - } - - size : 2048; -} - -@pragma stage 9 -table stat_tbl_indirect_pkt_32bit { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - act2; - } - - size : 2048; -} - -@pragma stage 9 -table stat_tbl_indirect_pkt_byte_64bit { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - act5; - } - - size : 2048; -} - -@pragma stage 10 -table stat_tbl_direct_pkt_64bit { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - act1; - } - - size : 2048; -} - -@pragma stage 10 -table stat_tbl_direct_pkt_32bit { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - act4; - } - - size : 2048; -} - -@pragma stage 11 -table stat_tbl_direct_pkt_byte_64bit { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - act1; - } - - size : 2048; -} - -@pragma stage 11 -table stat_tbl_direct_pkt_byte_32bit { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - act1; - } - - size : 2048; -} - -table stat_tcam_direct_pkt_64bit { - reads { - ipv4.dstAddr : lpm; - } - actions { - egr_act1; - } - - size : 2048; -} - -@pragma stage 11 -table hash_action_exm { - reads { - ipv4.ttl : exact; - ipv4 : valid; - } - actions { - hash_action; - } - default_action : hash_action(33); - size : 512; -} - -@pragma stage 11 -table hash_action2_exm { - reads { - vlan_tag.vlan_id : exact; - vlan_tag.pri : exact; - } - actions { - hash_action2; - } - default_action : hash_action2(1); - size : 32768; -} - -header_type l3_metadata_t { - fields { - vrf : 24; - fib_hit : 1; - fib_nexthop : 16; - fib_nexthop_type : 1; - } -} - -metadata l3_metadata_t l3_metadata; - -action fib_hit_nexthop(nexthop_index) { - modify_field(l3_metadata.fib_hit, 1); - modify_field(l3_metadata.fib_nexthop, nexthop_index); - modify_field(l3_metadata.fib_nexthop_type, 0); -} - -action fib_hit_ecmp(ecmp_index) { - modify_field(l3_metadata.fib_hit, 1); - modify_field(l3_metadata.fib_nexthop, ecmp_index); - modify_field(l3_metadata.fib_nexthop_type, 1); -} - -table duplicate_check_exm_immediate_action { - reads { - l3_metadata.vrf : exact; - ipv4.dstAddr : exact; - } - actions { - nop; - fib_hit_nexthop; - fib_hit_ecmp; - } - - size : 2048; -} - -action act(idx, egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - count(cntDum, idx); -} - -action act1(egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action egr_act1(tcp_sport) { - modify_field(tcp.srcPort, tcp_sport); -} - -action act4(egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action act2(idx, egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - count(cntDum3, idx); -} - -action act5(idx, egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - count(cntDum6, idx); -} - -counter cntDum { - type : packets; - static : stat_tbl_indirect_pkt_64bit; - instance_count : 256; -} - -counter cntDum3 { - type : packets; - static : stat_tbl_indirect_pkt_32bit; - instance_count : 256; -} - -counter cntDum1 { - type : packets; - direct : stat_tbl_direct_pkt_64bit; -} - -counter cntDum2 { - type : packets; - direct : stat_tbl_direct_pkt_32bit; - min_width : 20; -} - -counter cntDum4 { - type : packets_and_bytes; - direct : stat_tbl_direct_pkt_byte_64bit; -} - -counter cntDum5 { - type : packets_and_bytes; - direct : stat_tbl_direct_pkt_byte_32bit; - min_width : 20; -} - -counter cntDum6 { - type : packets_and_bytes; - static : stat_tbl_indirect_pkt_byte_64bit; - instance_count : 256; -} - -counter egr_cntDum1 { - type : packets; - direct : stat_tcam_direct_pkt_64bit; -} - -action_profile ecmp_action_profile { - actions { - nop; - nhop_set_1; - } - size : 1024; - // optional - dynamic_action_selection : ecmp_selector; -} - -action_profile ecmp_action_profile_iter { - actions { - nop; - nhop_set_1; - } - size : 1024; - // optional - dynamic_action_selection : ecmp_selector; -} - -action_selector ecmp_selector { - selection_key : ecmp_hash; // take a field_list_calculation only - // optional - selection_mode : resilient; // “resilient” or “non-resilient” -} - -action set_ucast_dest(dest) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, dest); -} - -@pragma stage 11 -table exm_txn_test { - reads { - ig_intr_md.ingress_port : exact; - } - actions { - set_ucast_dest; - } - size : 256; -} - -/* Main control flow */ -control ingress { - /* A general principle : Always keep the exact match tables ahead of the - * ternary tables in the same stage, except first stage. Logic relating to next-table - * will cause the Tofino model not to launch a lookup on th exact match - * tables if the order is reversed. - */ - apply(exm_5ways_5Entries); - apply(exm_6ways_5Entries); - apply(exm_4ways_6Entries); - apply(exm_5ways_6Entries); - apply(exm_6ways_6Entries); - apply(exm_3ways_7Entries); - apply(exm_4ways_8Entries); - apply(exm_ipv4_routing); /* Explicitly managed action data entries */ - apply(ipv4_routing_select); - apply(ipv4_routing_select_iter); - apply(stat_tbl_indirect_pkt_64bit); - apply(stat_tbl_indirect_pkt_32bit); - apply(stat_tbl_indirect_pkt_byte_64bit); - apply(stat_tbl_direct_pkt_64bit); - apply(stat_tbl_direct_pkt_32bit); - apply(stat_tbl_direct_pkt_byte_64bit); - apply(stat_tbl_direct_pkt_byte_32bit); - /* Hash-action tables are always executed. Using gateway condition - of tcp-srcport to prevent all tests from hitting this condition - */ - if (tcp.srcPort == 9000) { - apply(hash_action_exm); - apply(hash_action2_exm); - } - apply(exm_txn_test); -} - -action eg_drop() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); - modify_field(intrinsic_metadata.egress_port, 0); -} - -action permit() { -} - -table egress_acl { - reads { - routing_metadata.drop: ternary; - } - actions { - permit; - eg_drop; - } -} - -action action1() { - add_to_field(ipv4.ttl, -1); -} - -table exm_txn_test1 { - reads { - ipv4.dstAddr : exact; - } - actions { - action1; - } - size : 4096; -} - -control egress { - apply(stat_tcam_direct_pkt_64bit); - apply(duplicate_check_exm_immediate_action); - apply(exm_txn_test1); -// apply(egress_acl); -} - diff --git a/backends/tofino/bf-asm/test/ptf/exm_smoke_test.p4 b/backends/tofino/bf-asm/test/ptf/exm_smoke_test.p4 deleted file mode 100644 index 45bfec06352..00000000000 --- a/backends/tofino/bf-asm/test/ptf/exm_smoke_test.p4 +++ /dev/null @@ -1,766 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include "tofino.p4" -#include "tofino/intrinsic_metadata.p4" -#include "tofino/constants.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type ipv6_t { - fields { - version : 4; - trafficClass : 8; - flowLabel : 20; - payloadLen : 16; - nextHdr : 8; - hopLimit : 8; - srcAddr : 128; - dstAddr : 128; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - 0x86dd : parse_ipv6; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; -header ipv6_t ipv6; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -parser parse_ipv6 { - extract(ipv6); - return select(latest.nextHdr) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default : ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm : csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action egress_port(egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop_ipv4(egress_port /*,srcmac, dstmac*/) { - hop(ipv4.ttl, egress_port); -// modify_field(ethernet.srcAddr, srcmac); -// modify_field(ethernet.dstAddr, dstmac); -} - -action drop_ipv4 () { - drop(); -} - -action next_hop_ipv4(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action next_hop_ipv6(egress_port ,srcmac, dstmac) { - hop(ipv6.hopLimit, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action ig_drop() { -// modify_field(routing_metadata.drop, 1); - add_to_field(ipv4.ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); -} - -action mod_mac_addr(egress_port, srcmac, dstmac) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action udp_hdr_add (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - add_header(udp); - modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); - add_to_field(ipv4.totalLen, 8); -} - -action tcp_hdr_rm (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - remove_header(tcp); - modify_field(ipv4.protocol, 0); -// add_to_field(ipv4.totalLen, -20); -// modify_field(ipv4.totalLen, 66); -} - -action modify_tcp_dst_port(dstPort) { - modify_field(tcp.dstPort, dstPort); -} - -action modify_tcp_dst_port_1(dstPort, egress_port) { - modify_field(tcp.dstPort, dstPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ipv4.srcAddr, ipAddr); - modify_field(ethernet.dstAddr, dstAddr); - modify_field(tcp.dstPort, tcpPort); -} - -action custom_action_2(egress_port, ipAddr, tcpPort) -{ - modify_field(ipv4.srcAddr, ipAddr); - modify_field(tcp.dstPort, tcpPort); - hop(ipv4.ttl, egress_port); -} - -action custom_action_3(egress_port, dstAddr, dstIp) -{ - modify_field(ipv4.dstAddr, dstIp); - modify_field(ethernet.dstAddr, dstAddr); - hop(ipv4.ttl, egress_port); -} - -action custom_action_4(egress_port, dstPort, srcPort) -{ - modify_field(tcp.dstPort, dstPort); - modify_field(tcp.srcPort, srcPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_5(dstPort, srcPort) -{ - modify_field(tcp.dstPort, dstPort); - modify_field(tcp.srcPort, srcPort); -} - -action switching_action_1(egress_port/*, vlan_id */) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - //modify_field(vlan_tag.vlan_id, vlan_id); -} - -action_profile custom_action_3_profile { - actions { - nop; - egress_port; - custom_action_3; - } - size : 2048; -} - -action_profile custom_action_4_profile { - actions { - nop; - custom_action_4; - } - size : 1024; -} - -action_profile custom_action_5_profile { - actions { - nop; - custom_action_5; - } - size : 1024; -} - -action_profile custom_action_3_1_profile { - actions { - nop; - custom_action_3; - } - size : 1024; -} - -action_profile custom_action_3_2_profile { - actions { - nop; - custom_action_3; - } - size : 1024; -} - -action_profile modify_tcp_dst_port_profile { - actions { - nop; - modify_tcp_dst_port; - } - size : 1024; -} - -action_profile modify_tcp_dst_port_1_profile { - actions { - nop; - modify_tcp_dst_port_1; - } - size : 2048; -} - -action_profile next_hop_ipv4_profile { - actions { - nop; - next_hop_ipv4; - } - - size : 1024; -} - -action_profile next_hop_ipv4_1_profile { - actions { - nop; - next_hop_ipv4; - } - - size : 1024; -} - -action_profile next_hop_ipv4_2_profile { - actions { - nop; - next_hop_ipv4; - } - - size : 1024; -} - -action_profile next_hop_ipv4_3_profile { - actions { - nop; - next_hop_ipv4; - } - - size : 1024; -} - -action_profile custom_action_1_profile { - actions { - nop; - custom_action_1; - } - size : 1024; -} - -action_profile custom_action_2_profile { - actions { - nop; - custom_action_2; - } - size : 2048; -} - -action_profile mod_mac_addr_profile { - actions { - nop; - mod_mac_addr; - } - size : 2048; -} - -action_profile tcp_hdr_rm_profile { - actions { - nop; - tcp_hdr_rm; - } - size : 2048; -} - -@pragma command_line --no-dead-code-elimination -@pragma pack 7 -@pragma ways 5 -table exm_5ways_7Entries { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - - action_profile : custom_action_3_profile; - - size : 35840; -} - - - -@pragma stage 0 -@pragma pack 2 -@pragma ways 6 - -table exm_6ways_2Entries { - reads { - ipv4.dstAddr : exact; - } - - action_profile : modify_tcp_dst_port_profile; - - size : 12288; -} - -@pragma stage 0 -@pragma ways 3 -@pragma pack 1 - -table exm_3ways_1Entries { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - - action_profile : next_hop_ipv4_profile; - - size : 3072; -} - - -@pragma stage 1 -@pragma ways 4 -@pragma pack 1 - -table exm_4ways_1Entries { - reads { - ipv4.dstAddr : exact; - tcp.dstPort : exact; - } - - action_profile : custom_action_2_profile; - - size : 4096; -} - -@pragma stage 2 -@pragma pack 1 -@pragma ways 5 - -table exm_5ways_1Entries { - reads { - ethernet.dstAddr : exact; - tcp.srcPort : exact; - } - - action_profile : custom_action_3_1_profile; - - size : 5120; -} - - -@pragma stage 3 -@pragma ways 6 -@pragma pack 7 - -table exm_6ways_7Entries { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - - action_profile : next_hop_ipv4_1_profile; - - size : 43008; -} - -@pragma stage 4 -@pragma pack 8 - -table exm_deep_32k { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - - action_profile : custom_action_3_2_profile; - - size : 32768; -} - -@pragma stage 5 -@pragma pack 8 - -table exm_deep_64k { - reads { - ipv4.dstAddr : exact; - } - - action_profile : modify_tcp_dst_port_1_profile; - - size : 65536; -} - -@pragma stage 6 -@pragma pack 1 -@pragma ways 6 - -table exm_6ways_1Entries { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - tcp.dstPort : exact; - tcp.srcPort : exact; - } - - action_profile : next_hop_ipv4_2_profile; - - size : 6144; -} - -@pragma stage 7 -@pragma pack 2 -@pragma ways 5 - -table exm_5ways_2Entries { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - tcp.dstPort : exact; - } - - action_profile : custom_action_4_profile; - - size : 10240; -} - -@pragma stage 8 -@pragma pack 2 -@pragma ways 4 - -table exm_4ways_2Entries { - reads { - ipv4.dstAddr : exact; - tcp.srcPort : exact; - } - - action_profile : next_hop_ipv4_3_profile; - - size : 8192; -} - -@pragma stage 8 -@pragma pack 2 -@pragma ways 3 - -table exm_3ways_2Entries { - reads { - ipv4.srcAddr : exact; - ipv4.dstAddr : exact; - tcp.dstPort : exact; - } - - action_profile : custom_action_5_profile; - - size : 6144; -} - -@pragma stage 9 - -table exm_wide_key { - reads { - ipv4.srcAddr : exact; - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - tcp.dstPort : exact; - tcp.srcPort : exact; - } - - action_profile : custom_action_1_profile; - - size : 2048; -} - -@pragma stage 10 -@pragma ways 6 -@pragma pack 8 - -table exm_6ways_8Entries { - reads { - ethernet.dstAddr : exact; - } - - action_profile : mod_mac_addr_profile; - - size : 49152; -} - -@pragma stage 11 -@pragma ways 5 -@pragma pack 8 - -table exm_5ways_8Entries { - reads { - tcp.dstPort : exact; - } - - action_profile : tcp_hdr_rm_profile; - - size: 40960; -} - -@pragma pack 5 -@pragma ways 2 - -table exm_2ways_5Entries_stage_5 { - reads { - tcp.srcPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -@pragma ways 4 -table exm_4ways_16k_stage_5 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } - - size : 16384; -} - -@pragma pack 6 -@pragma ways 2 - -table exm_2ways_6Entries_stage_6 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - -@pragma pack 8 -@pragma ways 4 - -table exm_4ways_8Entries { - reads { - ipv4.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_3; - } -} - - -/* Main control flow */ -control ingress { - /* A general principle : Always keep the exact match tables ahead of the - * ternary tables in the same stage, except first stage. Logic relating to next-table - * will cause the Tofino model not to launch a lookup on th exact match - * tables if the order is reversed. - */ - apply(exm_5ways_7Entries); - apply(exm_6ways_2Entries); - //apply(exm_4ways_8Entries); - apply(exm_3ways_1Entries); - apply(exm_4ways_1Entries); - apply(exm_5ways_1Entries); - apply(exm_6ways_7Entries); - apply(exm_deep_32k); - apply(exm_deep_64k); - apply(exm_6ways_1Entries); - apply(exm_5ways_2Entries); - apply(exm_4ways_2Entries); - apply(exm_3ways_2Entries); - apply(exm_wide_key); - apply(exm_6ways_8Entries); - apply(exm_5ways_8Entries); - ////apply(exm_3ways_8Entries_stage_1); - //apply(exm_2ways_7Entries_stage_3); - ////apply(exm_2ways_8Entries_stage_3); - //apply(exm_2ways_4Entries_stage_5); - //apply(exm_2ways_5Entries_stage_5); - //apply(exm_2ways_6Entries_stage_6); -} - -action eg_drop() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 0); - modify_field(intrinsic_metadata.egress_port, 0); -} - -action permit() { -} - -table egress_acl { - reads { - routing_metadata.drop: ternary; - } - actions { - permit; - eg_drop; - } -} - -control egress { -// apply(egress_acl); -} - diff --git a/backends/tofino/bf-asm/test/ptf/fast_reconfig.p4 b/backends/tofino/bf-asm/test/ptf/fast_reconfig.p4 deleted file mode 100644 index ac93b004d1f..00000000000 --- a/backends/tofino/bf-asm/test/ptf/fast_reconfig.p4 +++ /dev/null @@ -1,279 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags_resv : 1; - flags_df : 1; - flags_mf : 1; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type ingress_metadata_t { - fields { - ifid : 32; /* Logical Interface ID */ - brid : 16; /* Bridging Domain ID */ - vrf : 16; - l3 : 1; /* Set if routed */ - } -} - -metadata ingress_metadata_t ing_md; -header ethernet_t ethernet; -header ipv4_t ipv4; -header vlan_tag_t vlan_tag; - - -parser start { - return parse_ethernet; -} - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags_resv; - ipv4.flags_df; - ipv4.flags_mf; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm : csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - - - - - - - -/****************************************************************************** - * - * Table: ing_port - * Key: Incoming physical port number - * Top VLAN tag - * - * Maps the physical port to a logical port and also invalidates the egress - * unicast port and MGID intrinsic metadatas. - * - *****************************************************************************/ -action set_ifid(ifid) { - modify_field(ing_md.ifid, ifid); - /* Set the destination port to an invalid value. */ - modify_field(ig_intr_md_for_tm.ucast_egress_port, 0x1FF); -} - -table ing_port { - reads { - ig_intr_md.ingress_port : exact; - vlan_tag : valid; - vlan_tag.vlan_id : exact; - } - actions { - set_ifid; - } -} - - -/****************************************************************************** - * - * Table: ing_src_ifid - * Key: Logical interface id - * - * Assigns ingress interface specific metadata: iRID, XID, YID, and brid. - * Also sets the hash values used for multicast replication. - * - *****************************************************************************/ -action set_src_ifid_md(rid, yid, brid, h1, h2) { - modify_field(ig_intr_md_for_tm.rid, rid); - modify_field(ig_intr_md_for_tm.level2_exclusion_id, yid); - modify_field(ing_md.brid, brid); - modify_field(ig_intr_md_for_tm.level1_mcast_hash, h1); - modify_field(ig_intr_md_for_tm.level2_mcast_hash, h2); -} - -table ing_src_ifid { - reads { - ing_md.ifid : exact; - } - actions { - set_src_ifid_md; - } -} - - -/****************************************************************************** - * - * Table: ing_dmac - * Key: Bridging domain and DMAC - * - * Will either setup the packet to L2 flood, L2 switch or route. - * - *****************************************************************************/ -action flood() { - modify_field(ig_intr_md_for_tm.mcast_grp_a, ing_md.brid); -} -action switch(egr_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egr_port); -} -action route(vrf) { - modify_field(ing_md.l3, 1); - modify_field(ing_md.vrf, vrf); -} -table ing_dmac { - reads { - ing_md.brid : exact; - ethernet.dstAddr : exact; - } - actions { - flood; - switch; - route; - } -} - - -/****************************************************************************** - * - * Table: ing_ipv4_mcast - * Key: IPv4 addresses and VRF - * - * Will assign MGID and XID - * - *****************************************************************************/ -action mcast_route(xid, mgid1, mgid2) { - modify_field(ig_intr_md_for_tm.level1_exclusion_id, xid); - modify_field(ig_intr_md_for_tm.mcast_grp_a, mgid1); - modify_field(ig_intr_md_for_tm.mcast_grp_b, mgid2); - add_to_field(ipv4.ttl, -1); -} -table ing_ipv4_mcast { - reads { - ing_md.vrf : exact; - ipv4.srcAddr : ternary; - ipv4.dstAddr : ternary; - } - actions { - mcast_route; - } -} - - -control ingress { - apply(ing_port); - apply(ing_src_ifid); - apply(ing_dmac); - if (ing_md.l3 == 1) { - apply(ing_ipv4_mcast); - } -} - - -/****************************************************************************** - * - * Table: egr_encode - * Key: None - * - * Encodes metadata generated by the multicast replication into the packet. - * - *****************************************************************************/ -action do_egr_encode() { - modify_field(ipv4.identification, eg_intr_md.egress_rid); - modify_field(ipv4.diffserv, eg_intr_md.egress_rid_first); -} -table egr_encode { - actions { - do_egr_encode; - } -} - - -control egress { - if (valid(ipv4)) { - apply(egr_encode); - } -} - - diff --git a/backends/tofino/bf-asm/test/ptf/fr_test.p4 b/backends/tofino/bf-asm/test/ptf/fr_test.p4 deleted file mode 100644 index 173e664f671..00000000000 --- a/backends/tofino/bf-asm/test/ptf/fr_test.p4 +++ /dev/null @@ -1,635 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include "tofino/intrinsic_metadata.p4" -#include "tofino/constants.p4" -#include "tofino/stateful_alu_blackbox.p4" - - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} -header ethernet_t ethernet; - -parser start { - return parse_ethernet; -} -parser parse_ethernet { - extract(ethernet); - return ingress; -} - -header_type md_t { - fields { - run_eg : 1; - run_t1 : 1; - run_t2 : 1; - key0 : 32; - t1_hit : 1; - t2_hit : 1; - } -} -metadata md_t md; - -/* Resources for the egress table. */ -counter cntr { - type : packets_and_bytes; - instance_count : 29696; -} -meter mtr { - type : packets; - instance_count : 4096; -} - -/* Resources for the ingress tables. */ -register reg_0 { - width : 32; - instance_count : 36864; -} -blackbox stateful_alu reg_alu_0 { - reg: reg_0; - update_lo_1_value: register_lo + 1; - initial_register_lo_value: 100; -} -register reg_1 { - width : 32; - instance_count : 36864; -} -blackbox stateful_alu reg_alu_1 { - reg: reg_1; - update_lo_1_value: register_lo + 1; - initial_register_lo_value: 100; -} -register reg_2 { - width : 32; - instance_count : 36864; -} -blackbox stateful_alu reg_alu_2 { - reg: reg_2; - update_lo_1_value: register_lo + 1; - initial_register_lo_value: 100; -} -register reg_3 { - width : 32; - instance_count : 36864; -} -blackbox stateful_alu reg_alu_3 { - reg: reg_3; - update_lo_1_value: register_lo + 1; - initial_register_lo_value: 100; -} -register reg_4 { - width : 32; - instance_count : 36864; -} -blackbox stateful_alu reg_alu_4 { - reg: reg_4; - update_lo_1_value: register_lo + 1; - initial_register_lo_value: 100; -} -register reg_5 { - width : 32; - instance_count : 36864; -} -blackbox stateful_alu reg_alu_5 { - reg: reg_5; - update_lo_1_value: register_lo + 1; - initial_register_lo_value: 100; -} -register reg_6 { - width : 32; - instance_count : 36864; -} -blackbox stateful_alu reg_alu_6 { - reg: reg_6; - update_lo_1_value: register_lo + 1; - initial_register_lo_value: 100; -} -register reg_7 { - width : 32; - instance_count : 36864; -} -blackbox stateful_alu reg_alu_7 { - reg: reg_7; - update_lo_1_value: register_lo + 1; - initial_register_lo_value: 100; -} -register reg_8 { - width : 32; - instance_count : 36864; -} -blackbox stateful_alu reg_alu_8 { - reg: reg_8; - update_lo_1_value: register_lo + 1; - initial_register_lo_value: 100; -} -register reg_9 { - width : 32; - instance_count : 36864; -} -blackbox stateful_alu reg_alu_9 { - reg: reg_9; - update_lo_1_value: register_lo + 1; - initial_register_lo_value: 100; -} -register reg_10 { - width : 32; - instance_count : 36864; -} -blackbox stateful_alu reg_alu_10 { - reg: reg_10; - update_lo_1_value: register_lo + 1; - initial_register_lo_value: 100; -} - -meter ing_mtr { - type : packets; - instance_count : 10240; -} - -table t0 { - reads { ig_intr_md.ingress_port : exact; } - actions { set_md; } - size : 288; -} -action set_md(run_eg, run_t1, run_t2, key0) { - modify_field(md.run_eg, run_eg); - modify_field(md.run_t1, run_t1); - modify_field(md.run_t2, run_t2); - modify_field(md.key0, key0); -} - -@pragma ways 4 -@pragma pack 1 -@pragma immediate 0 -@pragma idletime_precision 2 -table t1_0 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - ethernet.etherType : exact; - md.key0 : exact; - } - actions { t1a_0; } - size: 8000; - support_timeout: true; -} -action t1a_0(etype) { - modify_field(md.t1_hit, 1); - modify_field(ethernet.etherType, etype); -} -@pragma ways 4 -@pragma pack 1 -table t2_0 { - reads { - md.key0 : exact; - } - actions { t2a_0; } - size: 7168; -} -action t2a_0(reg_index) { - modify_field(md.t2_hit, 1); - add(md.key0, md.key0, 1); - reg_alu_0.execute_stateful_alu(reg_index); -} - -@pragma ways 4 -@pragma pack 1 -@pragma immediate 0 -@pragma idletime_precision 2 -table t1_1 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - ethernet.etherType : exact; - md.key0 : exact; - } - actions { t1a_1; } - size: 8000; - support_timeout: true; -} -action t1a_1(etype) { - modify_field(md.t1_hit, 1); - modify_field(ethernet.etherType, etype); -} -@pragma ways 4 -@pragma pack 1 -table t2_1 { - reads { - md.key0 : exact; - } - actions { t2a_1; } - size: 7168; -} -action t2a_1(reg_index) { - modify_field(md.t2_hit, 1); - add(md.key0, md.key0, 1); - reg_alu_1.execute_stateful_alu(reg_index); -} - -@pragma ways 4 -@pragma pack 1 -@pragma immediate 0 -@pragma idletime_precision 2 -table t1_2 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - ethernet.etherType : exact; - md.key0 : exact; - } - actions { t1a_2; } - size: 8000; - support_timeout: true; -} -action t1a_2(etype) { - modify_field(md.t1_hit, 1); - modify_field(ethernet.etherType, etype); -} -@pragma ways 4 -@pragma pack 1 -table t2_2 { - reads { - md.key0 : exact; - } - actions { t2a_2; } - size: 7168; -} -action t2a_2(reg_index) { - modify_field(md.t2_hit, 1); - add(md.key0, md.key0, 1); - reg_alu_2.execute_stateful_alu(reg_index); -} - -@pragma ways 4 -@pragma pack 1 -@pragma immediate 0 -@pragma idletime_precision 2 -table t1_3 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - ethernet.etherType : exact; - md.key0 : exact; - } - actions { t1a_3; } - size: 8000; - support_timeout: true; -} -action t1a_3(etype) { - modify_field(md.t1_hit, 1); - modify_field(ethernet.etherType, etype); -} -@pragma ways 4 -@pragma pack 1 -table t2_3 { - reads { - md.key0 : exact; - } - actions { t2a_3; } - size: 7168; -} -action t2a_3(reg_index) { - modify_field(md.t2_hit, 1); - add(md.key0, md.key0, 1); - reg_alu_3.execute_stateful_alu(reg_index); -} - -@pragma ways 4 -@pragma pack 1 -@pragma immediate 0 -@pragma idletime_precision 2 -table t1_4 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - ethernet.etherType : exact; - md.key0 : exact; - } - actions { t1a_4; } - size: 8000; - support_timeout: true; -} -action t1a_4(etype) { - modify_field(md.t1_hit, 1); - modify_field(ethernet.etherType, etype); -} -@pragma ways 4 -@pragma pack 1 -table t2_4 { - reads { - md.key0 : exact; - } - actions { t2a_4; } - size: 7168; -} -action t2a_4(reg_index) { - modify_field(md.t2_hit, 1); - add(md.key0, md.key0, 1); - reg_alu_4.execute_stateful_alu(reg_index); -} - -@pragma ways 4 -@pragma pack 1 -@pragma immediate 0 -@pragma idletime_precision 2 -table t1_5 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - ethernet.etherType : exact; - md.key0 : exact; - } - actions { t1a_5; } - size: 8000; - support_timeout: true; -} -action t1a_5(etype) { - modify_field(md.t1_hit, 1); - modify_field(ethernet.etherType, etype); -} -@pragma ways 4 -@pragma pack 1 -table t2_5 { - reads { - md.key0 : exact; - } - actions { t2a_5; } - size: 7168; -} -action t2a_5(reg_index) { - modify_field(md.t2_hit, 1); - add(md.key0, md.key0, 1); - reg_alu_5.execute_stateful_alu(reg_index); -} - -@pragma ways 4 -@pragma pack 1 -@pragma immediate 0 -@pragma idletime_precision 2 -table t1_6 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - ethernet.etherType : exact; - md.key0 : exact; - } - actions { t1a_6; } - size: 8000; - support_timeout: true; -} -action t1a_6(etype) { - modify_field(md.t1_hit, 1); - modify_field(ethernet.etherType, etype); -} -@pragma ways 4 -@pragma pack 1 -table t2_6 { - reads { - md.key0 : exact; - } - actions { t2a_6; } - size: 7168; -} -action t2a_6(reg_index) { - modify_field(md.t2_hit, 1); - add(md.key0, md.key0, 1); - reg_alu_6.execute_stateful_alu(reg_index); -} - -@pragma ways 4 -@pragma pack 1 -@pragma immediate 0 -@pragma idletime_precision 2 -table t1_7 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - ethernet.etherType : exact; - md.key0 : exact; - } - actions { t1a_7; } - size: 8000; - support_timeout: true; -} -action t1a_7(etype) { - modify_field(md.t1_hit, 1); - modify_field(ethernet.etherType, etype); -} -@pragma ways 4 -@pragma pack 1 -table t2_7 { - reads { - md.key0 : exact; - } - actions { t2a_7; } - size: 7168; -} -action t2a_7(reg_index) { - modify_field(md.t2_hit, 1); - add(md.key0, md.key0, 1); - reg_alu_7.execute_stateful_alu(reg_index); -} - -@pragma ways 4 -@pragma pack 1 -@pragma immediate 0 -@pragma idletime_precision 2 -table t1_8 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - ethernet.etherType : exact; - md.key0 : exact; - } - actions { t1a_8; } - size: 8000; - support_timeout: true; -} -action t1a_8(etype) { - modify_field(md.t1_hit, 1); - modify_field(ethernet.etherType, etype); -} -@pragma ways 4 -@pragma pack 1 -table t2_8 { - reads { - md.key0 : exact; - } - actions { t2a_8; } - size: 7168; -} -action t2a_8(reg_index) { - modify_field(md.t2_hit, 1); - add(md.key0, md.key0, 1); - reg_alu_8.execute_stateful_alu(reg_index); -} - -@pragma ways 4 -@pragma pack 1 -@pragma immediate 0 -@pragma idletime_precision 2 -table t1_9 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - ethernet.etherType : exact; - md.key0 : exact; - } - actions { t1a_9; } - size: 8000; - support_timeout: true; -} -action t1a_9(etype) { - modify_field(md.t1_hit, 1); - modify_field(ethernet.etherType, etype); -} -@pragma ways 4 -@pragma pack 1 -table t2_9 { - reads { - md.key0 : exact; - } - actions { t2a_9; } - size: 7168; -} -action t2a_9(reg_index) { - modify_field(md.t2_hit, 1); - add(md.key0, md.key0, 1); - reg_alu_9.execute_stateful_alu(reg_index); -} - -@pragma ways 4 -@pragma pack 1 -@pragma immediate 0 -@pragma idletime_precision 2 -table t1_10 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - ethernet.etherType : exact; - md.key0 : exact; - } - actions { t1a_10; } - size: 8000; - support_timeout: true; -} -action t1a_10(etype) { - modify_field(md.t1_hit, 1); - modify_field(ethernet.etherType, etype); -} -@pragma ways 4 -@pragma pack 1 -table t2_10 { - reads { - md.key0 : exact; - } - actions { t2a_10; } - size: 7168; -} -action t2a_10(reg_index) { - modify_field(md.t2_hit, 1); - add(md.key0, md.key0, 1); - reg_alu_10.execute_stateful_alu(reg_index); -} - -table t3 { - reads { - ethernet.dstAddr : exact; - ethernet.srcAddr : exact; - ethernet.etherType : exact; - } - actions { t3a; } - size : 24000; -} -action t3a(meter_index) { - execute_meter(ing_mtr, meter_index, ig_intr_md_for_tm.packet_color); -} - -table set_dest { - actions { set_egr_port; } - default_action: set_egr_port; - size : 1; -} -action set_egr_port() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, ig_intr_md.ingress_port); -} -table set_drop { - actions { drop_pkt; } - default_action: drop_pkt; - size : 1; -} -action drop_pkt() { - drop(); -} - -table egr_tbl { - reads { md.key0 : ternary; } - actions { egr_tbl_action; } - size: 147456; -} -action egr_tbl_action(cntr_index, meter_index) { - count(cntr, cntr_index); - execute_meter(mtr, meter_index, ig_intr_md_for_tm.packet_color); -} - - - - -control ingress { - if (0 == ig_intr_md.resubmit_flag) { - apply(t0); - } - if (1 == md.run_t1) { apply(t1_0); } - if (1 == md.run_t2) { apply(t2_0); } - if (1 == md.run_t1) { apply(t1_1); } - if (1 == md.run_t2) { apply(t2_1); } - if (1 == md.run_t1) { apply(t1_2); } - if (1 == md.run_t2) { apply(t2_2); } - if (1 == md.run_t1) { apply(t1_3); } - if (1 == md.run_t2) { apply(t2_3); } - if (1 == md.run_t1) { apply(t1_4); } - if (1 == md.run_t2) { apply(t2_4); } - if (1 == md.run_t1) { apply(t1_5); } - if (1 == md.run_t2) { apply(t2_5); } - if (1 == md.run_t1) { apply(t1_6); } - if (1 == md.run_t2) { apply(t2_6); } - if (1 == md.run_t1) { apply(t1_7); } - if (1 == md.run_t2) { apply(t2_7); } - if (1 == md.run_t1) { apply(t1_8); } - if (1 == md.run_t2) { apply(t2_8); } - if (1 == md.run_t1) { apply(t1_9); } - if (1 == md.run_t2) { apply(t2_9); } - if (1 == md.run_t1) { apply(t1_10); } - if (1 == md.run_t2) { apply(t2_10); } - - if (md.t1_hit == 1 or md.t2_hit == 1 or (md.run_t1 == 0 and md.run_t2 == 0)) { - apply(set_dest); - } else { - apply(set_drop); - } - - apply(t3); -} - -control egress { - if (1 == md.run_eg) { apply(egr_tbl); } -} - diff --git a/backends/tofino/bf-asm/test/ptf/includes/headers.p4 b/backends/tofino/bf-asm/test/ptf/includes/headers.p4 deleted file mode 100644 index 5842e002dc2..00000000000 --- a/backends/tofino/bf-asm/test/ptf/includes/headers.p4 +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Template headers.p4 file for basic_switching -// Edit this file as needed for your P4 program - -// Here's an ethernet header to get started. - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header ethernet_t ethernet; - -header_type vlan_tag_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - -header vlan_tag_t vlan; diff --git a/backends/tofino/bf-asm/test/ptf/includes/parser.p4 b/backends/tofino/bf-asm/test/ptf/includes/parser.p4 deleted file mode 100644 index dc5ac2de9e6..00000000000 --- a/backends/tofino/bf-asm/test/ptf/includes/parser.p4 +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Template parser.p4 file for basic_switching -// Edit this file as needed for your P4 program - -// This parses an ethernet header - -parser start { - return parse_ethernet; -} - -#define ETHERTYPE_VLAN 0x8100 -#define ETHERTYPE_IPV4 0x0800 - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - ETHERTYPE_VLAN : parse_vlan; -// ETHERTYPE_IPV4 : parse_ipv4; - default: ingress; - } -} - -parser parse_vlan { - extract(vlan); - return select(latest.etherType) { -// ETHERTYPE_VLAN : parse_vlan; -// ETHERTYPE_IPV4 : parse_ipv4; - default: ingress; - } -} - diff --git a/backends/tofino/bf-asm/test/ptf/iterator.p4 b/backends/tofino/bf-asm/test/ptf/iterator.p4 deleted file mode 100644 index 8d1248b3d8c..00000000000 --- a/backends/tofino/bf-asm/test/ptf/iterator.p4 +++ /dev/null @@ -1,195 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include "tofino/intrinsic_metadata.p4" - -action n() {} -action N(x) {modify_field(ig_intr_md_for_tm.rid, x);} - -table p0 { - reads { - ig_intr_md.ingress_port : exact; - } - actions {N;} - size: 288; -} -table exm { - reads { - ig_intr_md.ingress_port : exact; - } - actions {n;} -} -table tcam { - reads { - ig_intr_md.ingress_port : ternary; - } - actions {n;} -} -@pragma use_hash_action 1 -table ha { - reads { - ig_intr_md.ingress_port : exact; - } - actions {n;} - default_action : n(); - size: 512; -} -counter ha_cntr { - type: packets; - direct: ha; -} - -@pragma alpm 1 -table alpm { - reads { - ig_intr_md.ingress_port : lpm; - } - actions {n;} -} - -/* - * Shared Counter - */ -counter cntr { - type: packets_and_bytes; - instance_count: 1000; - min_width : 32; -} - -/* - * Shared Selection Table w/ Counter - */ -action a(x) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, x); -} -action b(x,i) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, x); - count(cntr, i); -} -action c(x) { - a(x); - count(cntr, 1); -} -action d(x,y,i) { - modify_field(ipv6.srcAddr, x); - modify_field(ipv6.flowLabel, y); - count(cntr, i); -} -action e() { - count(cntr, 0); -} -action_profile sel_ap { - actions { a;b;c;d;e; } - dynamic_action_selection : sel_as; -} -action_selector sel_as { - selection_key : sel_as_hash; -} -field_list_calculation sel_as_hash { - input { sel_as_hash_fields; } - algorithm : crc32; - output_width : 29; -} -field_list sel_as_hash_fields { - ethernet.dstAddr; - ethernet.srcAddr; -} - -table exm_sel { - reads { - ipv6.valid : exact; - ipv6.srcAddr : exact; - ipv6.dstAddr : exact; - } - action_profile : sel_ap; -} -table tcam_sel { - reads { - ipv6.valid : exact; - ipv6.srcAddr : exact; - ipv6.dstAddr : lpm; - } - action_profile : sel_ap; -} - -/* - * Shared Indirect Action w/ Counter - */ -action_profile ap { - actions { a;b;c;d;e; } -} -table exm_ap { - reads { - ipv6.valid : exact; - ipv6.srcAddr : exact; - ipv6.dstAddr : exact; - } - action_profile : ap; -} -table tcam_ap { - reads { - ipv6.valid : exact; - ipv6.srcAddr : exact; - ipv6.dstAddr : lpm; - } - action_profile : ap; -} - - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} -header_type ipv6_t { - fields { - version : 4; - trafficClass : 8; - flowLabel : 20; - payloadLen : 16; - nextHdr : 8; - hopLimit : 8; - srcAddr : 128; - dstAddr : 128; - } -} -header ethernet_t ethernet; -header ipv6_t ipv6; -parser start { - extract(ethernet); - extract(ipv6); - return ingress; -} -control ingress { - if (0 == ig_intr_md.resubmit_flag) { - apply(p0); - } - apply(exm); - apply(tcam); - apply(ha); - apply(alpm); - if (ig_intr_md.ingress_port == 0) { - apply(exm_sel); - } else if (ig_intr_md.ingress_port == 1) { - apply(tcam_sel); - } else if (ig_intr_md.ingress_port == 2) { - apply(exm_ap); - } else if (ig_intr_md.ingress_port == 3) { - apply(tcam_ap); - } -} diff --git a/backends/tofino/bf-asm/test/ptf/mau_mem_test.p4 b/backends/tofino/bf-asm/test/ptf/mau_mem_test.p4 deleted file mode 100644 index dc41ffa437e..00000000000 --- a/backends/tofino/bf-asm/test/ptf/mau_mem_test.p4 +++ /dev/null @@ -1,294 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - default: ingress; - } -} - -header ethernet_t ethernet; - -action action_0(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_1(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_2(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_3(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_4(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_5(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_6(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_7(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_8(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_9(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_10(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_11(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -counter counter_ingress { - type : packets; - instance_count : 512; -} - -action ingress_action(){ - count(counter_ingress, ig_intr_md.ingress_port); -} - -counter counter_egress { - type : packets; - instance_count : 512; -} -action egress_action(){ - count(counter_egress, eg_intr_md.egress_port); -} - -action do_nothing(){} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_0 -table simple_table_0 { - reads { - ethernet.srcAddr mask 0xFFFF : exact; - } - actions { - action_0; - do_nothing; - } - size : 65536; -} - -@pragma stage_0 -table simple_table_ingress { - actions { - ingress_action; - } -} - -//@pragma use_hash_action 1 -table simple_table_egress { - actions { - egress_action; - } -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_1 -table simple_table_1 { - reads { - ethernet.srcAddr mask 0xFFFF : exact; - } - actions { - action_1; - do_nothing; - } - size : 65536; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_2 -table simple_table_2 { - reads { - ethernet.srcAddr mask 0xFFFF : exact; - } - actions { - action_2; - do_nothing; - } - size : 65536; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_3 -table simple_table_3 { - reads { - ethernet.srcAddr mask 0xFFFF : exact; - } - actions { - action_3; - do_nothing; - } - size : 65536; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_4 -table simple_table_4 { - reads { - ethernet.srcAddr mask 0xFFFF : exact; - } - actions { - action_4; - do_nothing; - } - size : 65536; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_5 -table simple_table_5 { - reads { - ethernet.srcAddr mask 0xFFFF : exact; - } - actions { - action_5; - do_nothing; - } - size : 65536; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_6 -table simple_table_6 { - reads { - ethernet.srcAddr mask 0xFFFF : exact; - } - actions { - action_6; - do_nothing; - } - size : 65536; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_7 -table simple_table_7 { - reads { - ethernet.srcAddr mask 0xFFFF : exact; - } - actions { - action_7; - do_nothing; - } - size : 65536; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_8 -table simple_table_8 { - reads { - ethernet.srcAddr mask 0xFFFF : exact; - } - actions { - action_8; - do_nothing; - } - size : 65536; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_9 -table simple_table_9 { - reads { - ethernet.srcAddr mask 0xFFFF : exact; - } - actions { - action_9; - do_nothing; - } - size : 65536; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_10 -table simple_table_10 { - reads { - ethernet.srcAddr mask 0xFFFF : exact; - } - actions { - action_10; - do_nothing; - } - size : 65536; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_11 -table simple_table_11 { - reads { - ethernet.srcAddr mask 0xFFFF : exact; - } - actions { - action_11; - do_nothing; - } - size : 65536; -} - -control ingress { - if (ethernet.etherType == 0) apply(simple_table_0); - if (ethernet.etherType == 1) apply(simple_table_1); - if (ethernet.etherType == 2) apply(simple_table_2); - if (ethernet.etherType == 3) apply(simple_table_3); - if (ethernet.etherType == 4) apply(simple_table_4); - if (ethernet.etherType == 5) apply(simple_table_5); - if (ethernet.etherType == 6) apply(simple_table_6); - if (ethernet.etherType == 7) apply(simple_table_7); - if (ethernet.etherType == 8) apply(simple_table_8); - if (ethernet.etherType == 9) apply(simple_table_9); - if (ethernet.etherType == 10) apply(simple_table_10); - if (ethernet.etherType == 11) apply(simple_table_11); - apply(simple_table_ingress); -} - -control egress { - apply(simple_table_egress); -} - diff --git a/backends/tofino/bf-asm/test/ptf/mau_tcam_test.p4 b/backends/tofino/bf-asm/test/ptf/mau_tcam_test.p4 deleted file mode 100644 index e0f370e915d..00000000000 --- a/backends/tofino/bf-asm/test/ptf/mau_tcam_test.p4 +++ /dev/null @@ -1,282 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -parser start { - return parse_ethernet; -} - - -parser parse_ethernet { - extract(ethernet); - return select(ethernet.etherType) { - default: ingress; - } -} - -header ethernet_t ethernet; - -action action_0(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_1(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_2(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_3(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_4(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_5(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_6(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_7(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_8(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_9(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_10(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action action_11(port){ - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -counter counter_ingress { - type : packets; - instance_count : 512; -} - -action ingress_action(){ - count(counter_ingress, ig_intr_md.ingress_port); -} - -counter counter_egress { - type : packets; - instance_count : 512; -} -action egress_action(){ - count(counter_egress, eg_intr_md.egress_port); -} - -action do_nothing(){} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_0 -table simple_table_0 { - reads { - ethernet.srcAddr mask 0x1FFF : ternary; - } - actions { - action_0; - } - size : 8192; -} - -@pragma stage_0 -table simple_table_ingress { - actions { - ingress_action; - } -} - -//@pragma use_hash_action 1 -table simple_table_egress { - actions { - egress_action; - } -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_1 -table simple_table_1 { - reads { - ethernet.srcAddr mask 0x1FFF : ternary; - } - actions { - action_1; - } - size : 8192; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_2 -table simple_table_2 { - reads { - ethernet.srcAddr mask 0x1FFF : ternary; - } - actions { - action_2; - } - size : 8192; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_3 -table simple_table_3 { - reads { - ethernet.srcAddr mask 0x1FFF : ternary; - } - actions { - action_3; - } - size : 8192; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_4 -table simple_table_4 { - reads { - ethernet.srcAddr mask 0x1FFF : ternary; - } - actions { - action_4; - } - size : 8192; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_5 -table simple_table_5 { - reads { - ethernet.srcAddr mask 0x1FFF : ternary; - } - actions { - action_5; - } - size : 8192; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_6 -table simple_table_6 { - reads { - ethernet.srcAddr mask 0x1FFF : ternary; - } - actions { - action_6; - } - size : 8192; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_7 -table simple_table_7 { - reads { - ethernet.srcAddr mask 0x1FFF : ternary; - } - actions { - action_7; - } - size : 8192; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_8 -table simple_table_8 { - reads { - ethernet.srcAddr mask 0x1FFF : ternary; - } - actions { - action_8; - } - size : 8192; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_9 -table simple_table_9 { - reads { - ethernet.srcAddr mask 0x1FFF : ternary; - } - actions { - action_9; - } - size : 8192; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_10 -table simple_table_10 { - reads { - ethernet.srcAddr mask 0x1FFF : ternary; - } - actions { - action_10; - } - size : 8192; -} - -@pragma use_identity_hash 1 -@pragma immediate 0 -@pragma stage_11 -table simple_table_11 { - reads { - ethernet.srcAddr mask 0x1FFF : ternary; - } - actions { - action_11; - } - size : 8192; -} - -control ingress { - if (ethernet.etherType == 0) apply(simple_table_0); - if (ethernet.etherType == 1) apply(simple_table_1); - if (ethernet.etherType == 2) apply(simple_table_2); - if (ethernet.etherType == 3) apply(simple_table_3); - if (ethernet.etherType == 4) apply(simple_table_4); - if (ethernet.etherType == 5) apply(simple_table_5); - if (ethernet.etherType == 6) apply(simple_table_6); - if (ethernet.etherType == 7) apply(simple_table_7); - if (ethernet.etherType == 8) apply(simple_table_8); - if (ethernet.etherType == 9) apply(simple_table_9); - if (ethernet.etherType == 10) apply(simple_table_10); - if (ethernet.etherType == 11) apply(simple_table_11); - apply(simple_table_ingress); -} - -control egress { - apply(simple_table_egress); -} - diff --git a/backends/tofino/bf-asm/test/ptf/mau_test.p4 b/backends/tofino/bf-asm/test/ptf/mau_test.p4 deleted file mode 100644 index cfae09e6c77..00000000000 --- a/backends/tofino/bf-asm/test/ptf/mau_test.p4 +++ /dev/null @@ -1,1285 +0,0 @@ -#include -#include "tofino/stateful_alu_blackbox.p4" -#include "tofino/lpf_blackbox.p4" - -#define VLAN_DEPTH 2 -#define ETHERTYPE_VLAN 0x8100 -#define ETHERTYPE_IPV4 0x0800 - -header_type metadata_t { - fields { - stats_key : 32; - m1_clr : 8; - m1_idx : 32; - m1_drop : 1; - drop_it : 1; - count_it : 2; - resubmit_for_meter_test : 1; - dummy : 1; - mr_clr : 8; - e3_meter : 8; - t3_meter : 8; - e4_meter : 8; - t4_meter : 8; - e5_lpf : 32; - t5_lpf : 32; - e6_lpf : 32; - t6_lpf : 32; - e5_lpf_tmp1 : 32; - t5_lpf_tmp1 : 32; - e6_lpf_tmp1 : 32; - t6_lpf_tmp1 : 32; - e5_lpf_tmp2 : 32; - t5_lpf_tmp2 : 32; - e6_lpf_tmp2 : 32; - t6_lpf_tmp2 : 32; - - e1_stful : 32; - t1_stful : 32; - mr1_fail : 32; - - etherType_hi : 16; - } -} -header_type ethernet_t { - /* Source address is split into two fields as a hack to work around a - * compiler limitation with gateway tables. SrcAddr is used in a gateway - * table but with a mask so really only the masked bits need to be in the - * gateway but the compiler thinks all 48 bits should go in and complains. - * Split the field so that it will "fit" in a gateway. */ - fields { - dstAddr : 48; - srcAddrHi : 16; - srcAddr : 32; - etherType : 16; - } -} - -header_type move_reg_key_t { - fields { - hi : 8; - lo : 8; - } -} -@pragma pa_fragment egress mrk.hi -@pragma pa_fragment egress mrk.lo -header move_reg_key_t mrk; - -metadata metadata_t md; - -@pragma pa_fragment egress ethernet.etherType -header ethernet_t ethernet; - -parser start { - return parse_ethernet; -} - -parser parse_ethernet { - extract(ethernet); - - return select(latest.etherType) { - 0xCCC1 : stat_tag_one; - 0xCCC2 : stat_tag_two; - 0xCCC3 : stat_tag_three; - 0xDEAD : drop_tag; - default : get_move_reg_key; - } -} - -parser stat_tag_one { - set_metadata(md.count_it, 1); - return ingress; -} -parser stat_tag_two { - set_metadata(md.count_it, 2); - return ingress; -} -parser stat_tag_three { - set_metadata(md.count_it, 3); - return ingress; -} -parser drop_tag { - set_metadata(md.drop_it, 1); - return ingress; -} -parser get_move_reg_key { - extract(mrk); - return ingress; -} - - -/* - * Simple table to set packet destination. - */ -action set_dest() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, ig_intr_md.ingress_port); - shift_right(md.etherType_hi, ethernet.etherType, 8); -} -table dest { - actions { set_dest; } -} - - -register mrk_hi_reg { - width : 16; - instance_count : 1024; -} -register mrk_lo_reg { - width : 16; - instance_count : 1024; -} -blackbox stateful_alu set_mrk_hi_alu { - reg: mrk_hi_reg; - update_lo_1_value: md.etherType_hi; - output_value: alu_lo; - output_dst: mrk.hi; -} -blackbox stateful_alu set_mrk_lo_alu { - reg: mrk_lo_reg; - update_lo_1_value: ethernet.etherType & 0xFF; - output_value: alu_lo; - output_dst: mrk.lo; -} -action do_set_mrk_hi() { - set_mrk_hi_alu.execute_stateful_alu(0); -} -action do_set_mrk_lo() { - set_mrk_lo_alu.execute_stateful_alu(0); -} -@pragma stage 1 -table set_mrk_hi { - actions {do_set_mrk_hi;} -} -@pragma stage 0 -table set_mrk_lo { - actions {do_set_mrk_lo;} -} - -/* - * Counter test, 2 ingress and 2 egress counter tables. - */ - -table stats_resubmit { - reads { ethernet.etherType : ternary; } - actions { nothing; do_resubmit; } - default_action: nothing; -} -register stats_key_reg { - width : 64; - instance_count : 2048; -} -blackbox stateful_alu stats_key_alu3 { - /* Register hi: Counts 0..X then resets back to 0. X represents the number - * of back to back packets which should go to the same stats entry. - * Register lo: The stats key, range is 0-11 so there are 12 keys total, it - * will only increment every X packets (i.e. when register_lo resets). - */ - reg: stats_key_reg; - condition_hi: register_hi >= 2; - condition_lo: register_lo >= 11; - update_hi_1_predicate: not condition_hi; - update_hi_1_value: register_hi + 1; - update_hi_2_predicate: condition_hi; - update_hi_2_value: 0; - - update_lo_1_predicate: condition_hi and not condition_lo; - update_lo_1_value: register_lo + 1; - update_lo_2_predicate: condition_lo; - update_lo_2_value: 0; - - output_value: register_lo; - output_dst: md.stats_key; -} -blackbox stateful_alu stats_key_alu1 { - /* Same as stats_key_alu3 but uses a larger space for the output key. */ - reg: stats_key_reg; - condition_hi: register_hi >= 2; - condition_lo: register_lo >= 2099; - update_hi_1_predicate: not condition_hi; - update_hi_1_value: register_hi + 1; - update_hi_2_predicate: condition_hi; - update_hi_2_value: 0; - - update_lo_1_predicate: condition_hi and not condition_lo; - update_lo_1_value: register_lo + 1; - update_lo_2_predicate: condition_lo; - update_lo_2_value: 100; - - output_value: register_lo; - output_dst: md.stats_key; - - initial_register_lo_value: 100; -} -action do_set_stats_key1() { - stats_key_alu1.execute_stateful_alu(0); -} -action do_set_stats_key2() { - modify_field(md.stats_key, 0xFFFFFFFF); -} -action do_set_stats_key3() { - stats_key_alu3.execute_stateful_alu(1); -} -table set_stats_key1 { - actions { do_set_stats_key1; } -} -table set_stats_key2 { - actions { do_set_stats_key2; } -} -table set_stats_key3 { - actions { do_set_stats_key3; } -} - - -@pragma lrt_enable 1 -//@pragma lrt_scale 64 -counter ig_cntr_1 { - type : packets_and_bytes; - instance_count : 32768; - min_width : 32; -} -@pragma lrt_enable 1 -//@pragma lrt_scale 65 -counter ig_cntr_2 { - type : packets_and_bytes; - instance_count : 4096; - min_width : 32; -} -@pragma lrt_enable 1 -//@pragma lrt_scale 64 -counter eg_cntr_1 { - type : packets_and_bytes; - instance_count : 32768; - min_width : 32; -} -@pragma lrt_enable 1 -//@pragma lrt_scale 65 -counter eg_cntr_2 { - type : packets_and_bytes; - instance_count : 4096; - min_width : 32; -} -counter ig_cntr_3 { - type : packets_and_bytes; - instance_count : 16384; -} -counter ig_cntr_4 { - type : packets; - instance_count : 2048; -} -counter eg_cntr_3 { - type : packets_and_bytes; - instance_count : 16384; -} -counter eg_cntr_4 { - type : packets; - instance_count : 2048; -} - - -@pragma stage 1 -table ig_stat_1 { - reads { md.stats_key : exact; } - actions { inc_ig_cntr_1; } - size : 4096; -} - -@pragma stage 1 -table ig_stat_2 { - reads { md.stats_key : exact; } - actions { inc_ig_cntr_2; } - size : 4096; -} - -@pragma stage 1 -table eg_stat_1 { - reads { md.stats_key : exact; } - actions { inc_eg_cntr_1; } - size : 4096; -} - -@pragma stage 1 -table eg_stat_2 { - reads { md.stats_key : exact; } - actions { inc_eg_cntr_2; } - size : 4096; -} - -@pragma stage 6 -table ig_stat_3 { - reads { md.stats_key mask 0xFFF : exact; } - actions { inc_ig_cntr_3; } - size : 4096; -} - -@pragma stage 6 -table ig_stat_4 { - reads { md.stats_key mask 0xFFF : exact; } - actions { inc_ig_cntr_4; } - size : 4096; -} - -@pragma stage 6 -table eg_stat_3 { - reads { md.stats_key mask 0xFFF : exact; } - actions { inc_eg_cntr_3; } - size : 4096; -} - -@pragma stage 6 -table eg_stat_4 { - reads { md.stats_key mask 0xFFF : exact; } - actions { inc_eg_cntr_4; } - size : 4096; -} - -action inc_ig_cntr_1(cntr_index) { - count(ig_cntr_1, cntr_index); -} -action inc_ig_cntr_2(cntr_index) { - count(ig_cntr_2, cntr_index); -} -action inc_ig_cntr_3(cntr_index) { - count(ig_cntr_3, cntr_index); -} -action inc_ig_cntr_4(cntr_index) { - count(ig_cntr_4, cntr_index); -} -action inc_eg_cntr_1(cntr_index) { - count(eg_cntr_1, cntr_index); -} -action inc_eg_cntr_2(cntr_index) { - count(eg_cntr_2, cntr_index); -} -action inc_eg_cntr_3(cntr_index) { - count(eg_cntr_3, cntr_index); -} -action inc_eg_cntr_4(cntr_index) { - count(eg_cntr_4, cntr_index); -} - - -/* - * Idletime test, 16 idletime tables in a mix of 1 and 3 bit mode - */ - -action nothing() {} -@pragma stage 2 -@pragma include_idletime 1 -@pragma idletime_precision 3 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 1 -table ig_idle_1 { reads { ethernet.srcAddr mask 0x3FFF : exact; } actions { nothing; } size : 18432; support_timeout: true;} -@pragma stage 2 -@pragma include_idletime 1 -@pragma idletime_precision 3 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 1 -table ig_idle_2 { reads { ethernet.srcAddr mask 0x3FFF : exact; } actions { nothing; } size : 8192; support_timeout: true;} -@pragma stage 2 -@pragma include_idletime 1 -@pragma idletime_precision 3 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 1 -table ig_idle_3 { reads { ethernet.srcAddr mask 0x3FFF : exact; } actions { nothing; } size : 8192; support_timeout: true;} -@pragma stage 2 -@pragma include_idletime 1 -@pragma idletime_precision 3 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 1 -table ig_idle_4 { reads { ethernet.srcAddr mask 0x3FFF : exact; } actions { nothing; } size : 8192; support_timeout: true;} -@pragma stage 2 -@pragma include_idletime 1 -@pragma idletime_precision 3 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 1 -table ig_idle_5 { reads { ethernet.srcAddr mask 0x3FFF : exact; } actions { nothing; } size : 8192; support_timeout: true;} -@pragma stage 2 -@pragma include_idletime 1 -@pragma idletime_precision 3 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 1 -table ig_idle_6 { reads { ethernet.srcAddr mask 0x3FFF : exact; } actions { nothing; } size : 8192; support_timeout: true;} -@pragma stage 2 -@pragma include_idletime 1 -@pragma idletime_precision 3 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 1 -table ig_idle_7 { reads { ethernet.srcAddr mask 0x3FFF : exact; } actions { nothing; } size : 8192; support_timeout: true;} -@pragma stage 2 -@pragma include_idletime 1 -@pragma idletime_precision 3 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 1 -table ig_idle_8 { reads { ethernet.srcAddr mask 0x3FFF : exact; } actions { nothing; } size : 8192; support_timeout: true;} -@pragma stage 2 -@pragma include_idletime 1 -@pragma idletime_precision 3 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 0 -table ig_idle_9 { reads { ethernet.srcAddr mask 0x3FFF : ternary; } actions { nothing; } size : 1536; support_timeout: true;} -@pragma stage 2 -@pragma include_idletime 1 -@pragma idletime_precision 3 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 0 -table ig_idle_10 { reads { ethernet.srcAddr mask 0x3FFF : ternary; } actions { nothing; } size : 1536; support_timeout: true;} -@pragma stage 2 -@pragma include_idletime 1 -@pragma idletime_precision 3 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 0 -table ig_idle_11 { reads { ethernet.srcAddr mask 0x3FFF : ternary; } actions { nothing; } size : 1536; support_timeout: true;} -@pragma stage 2 -@pragma include_idletime 1 -@pragma idletime_precision 3 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 0 -table ig_idle_12 { reads { ethernet.srcAddr mask 0x3FFF : ternary; } actions { nothing; } size : 1536; support_timeout: true;} -@pragma stage 2 -@pragma include_idletime 1 -@pragma idletime_precision 3 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 0 -table ig_idle_13 { reads { ethernet.srcAddr mask 0x3FFF : ternary; } actions { nothing; } size : 1536; support_timeout: true;} -@pragma stage 2 -@pragma include_idletime 1 -@pragma idletime_precision 3 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 0 -table ig_idle_14 { reads { ethernet.srcAddr mask 0x3FFF : ternary; } actions { nothing; } size : 1536; support_timeout: true;} -@pragma stage 2 -@pragma include_idletime 1 -@pragma idletime_precision 3 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 0 -table ig_idle_15 { reads { ethernet.srcAddr mask 0x3FFF : ternary; } actions { nothing; } size : 1536; support_timeout: true;} -@pragma stage 2 -@pragma include_idletime 1 -@pragma idletime_precision 3 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 0 -table ig_idle_16 { reads { ethernet.srcAddr mask 0xFFFF : ternary; } actions { nothing; } size : 1536; support_timeout: true;} - - -@pragma stage 3 -@pragma include_idletime 1 -@pragma idletime_precision 1 -table eg_idle_1 { reads { ethernet.srcAddr mask 0xFFFF : exact; } actions { nothing; } size : 131072; support_timeout: true;} -@pragma stage 3 -@pragma include_idletime 1 -@pragma idletime_precision 1 -table eg_idle_2 { reads { ethernet.srcAddr mask 0xFFFF : exact; } actions { nothing; } size : 65536; support_timeout: true;} -@pragma stage 3 -@pragma include_idletime 1 -@pragma idletime_precision 1 -table eg_idle_3 { reads { ethernet.srcAddr mask 0xFFFF : exact; } actions { nothing; } size : 65536; support_timeout: true;} -@pragma stage 3 -@pragma include_idletime 1 -@pragma idletime_precision 1 -table eg_idle_4 { reads { ethernet.srcAddr mask 0xFFFF : exact; } actions { nothing; } size : 65536; support_timeout: true;} - - -action mark_meter_resubmit() { - modify_field(md.resubmit_for_meter_test, 1); -} -table ig_meter_resubmit { - actions {mark_meter_resubmit;} -} -action set_m1_clr() { - modify_field(md.m1_clr, ethernet.etherType, 0x03); -} -table ig_m1_color { - actions { set_m1_clr; } -} -@pragma meter_per_flow_enable 1 -@pragma meter_pre_color_aware_per_flow_enable 1 -@pragma meter_sweep_interval 0 -meter m1 { - type : bytes; - static : ig_m1; - pre_color : md.m1_clr; - instance_count : 20480; -} - -action m1(index) { - execute_meter(m1, index, md.m1_clr, md.m1_clr); - modify_field(md.m1_idx, index); -} - -@pragma stage 4 -table ig_m1 { reads {ethernet.dstAddr mask 0xFFFF00000000 : exact;} actions {m1; nothing;} size: 1024;} - -counter ig_m1_cntr { - type : bytes; - direct : ig_m1_cnt; -} -table ig_m1_cnt { reads { md.m1_idx: exact; md.m1_clr: exact; } actions { nothing; } size:1024; } - -action m1_tag_for_drop() { - modify_field(md.m1_drop, 1); -} -table ig_meter_test_discard { - actions { m1_tag_for_drop; } -} - - - -/****************************************************************************** -* * -* Selection Test * -* * -******************************************************************************/ - -register sel_tbl_reg { - width : 1; - instance_count : 131072; -} -blackbox stateful_alu stateful_selection_alu { - reg: sel_tbl_reg; - selector_binding: sel_tbl; - update_lo_1_value: clr_bit; -} -@pragma action_default_only nothing -@pragma stage 5 -table sel_tbl { - reads { ethernet.dstAddr : ternary; } - action_profile: sel_tbl_ap; - //default_action: nothing; - size : 1; -} -action set_egr_port(p) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, p); -} -action_profile sel_tbl_ap { - actions { set_egr_port; nothing; } - size : 1024; - dynamic_action_selection : sel_tbl_as; -} -action_selector sel_tbl_as { - selection_key: sel_tbl_hash; - selection_mode: resilient; -} -field_list_calculation sel_tbl_hash { - input { sel_tbl_fields; } -#if defined(BMV2TOFINO) - algorithm : xxh64; -#else - algorithm: random; -#endif - output_width: 51; -} -field_list sel_tbl_fields { - ethernet.dstAddr; - ethernet.etherType; -} - -action update_stful_sel_tbl(index) { - stateful_selection_alu.execute_stateful_alu(index); -} -@pragma stage 5 -table dummy_tbl { - reads { ethernet.dstAddr : exact; } - actions { update_stful_sel_tbl; } - size : 1; -} - -register sel_res_reg { - width : 16; - instance_count : 64; -} -blackbox stateful_alu sel_res_alu { - reg: sel_res_reg; - update_lo_1_value: ig_intr_md_for_tm.ucast_egress_port; -} -field_list sel_res_hash_fields { - ethernet.dstAddr; -} -field_list_calculation sel_res_hash { - input { sel_res_hash_fields; } - algorithm: identity; - output_width: 6; -} -action log_egr_port() { - sel_res_alu.execute_stateful_alu_from_hash(sel_res_hash); -} -table sel_res { - reads { - ethernet.dstAddr : ternary; - } - actions { log_egr_port; nothing; } - default_action: nothing; - size : 64; -} - -action do_resubmit() { - resubmit(); -} -table resubmit_2_tbl { - actions { do_resubmit; } -} -action drop_it() { mark_for_drop(); } -@pragma stage 1 -table eg_discard { - actions { drop_it; } -} - -/****************************************************************************** -* * -* move reg * -* * -******************************************************************************/ -#define MR1 0 -#define MR1_NEXT 10 -#define MR2 9 -#define MR3 10 -#define MR4 10 -#define MR5 8 -#define MR6 8 -#define MR_VERIFY_SETUP 10 -#define MR_VERIFY 11 - -@pragma idletime_precision 1 -@pragma stage MR1 -table t1 { - reads { ethernet.etherType : ternary; } - actions { t1_action; } - support_timeout: true; -} -@pragma lrt_enable 0 -@pragma lrt_scale 154 -counter t1_cntr { - type : packets; - direct: t1; - min_width : 64; -} -register t1_reg { - width: 64; - direct: t1; - attributes: signed; -} -blackbox stateful_alu t1_alu { - reg: t1_reg; - condition_lo: register_lo != ethernet.etherType; - update_hi_1_value: register_hi + 1; - update_lo_1_predicate: condition_lo; - update_lo_1_value: 0; - output_value: register_hi; - output_dst: md.t1_stful; -} -action t1_action() { - t1_alu.execute_stateful_alu(); -} - - -@pragma idletime_precision 1 -@pragma stage MR1 -@pragma pack 1 -@pragma ways 4 -@pragma random_seed 1027 -table e1 { - reads { mrk.lo : exact; mrk.hi : exact; } - actions { e1_action; } - size: 4096; - support_timeout: true; -} -@pragma lrt_enable 0 -@pragma lrt_scale 154 -counter e1_cntr { - type : packets; - direct: e1; - min_width : 64; -} -register e1_reg { - width: 64; - direct: e1; - attributes: signed; -} -blackbox stateful_alu e1_alu { - reg: e1_reg; - condition_lo: register_lo != ethernet.etherType; - update_hi_1_value: register_hi + 1; - update_lo_1_predicate: condition_lo; - update_lo_1_value: 0; - output_value: register_hi; - output_dst: md.e1_stful; -} -action e1_action() { - e1_alu.execute_stateful_alu(); -} - - -@pragma stage MR1_NEXT -table mr1_verify { - actions {mr1_verify_fail;} -} -action mr1_verify_fail() { - modify_field(md.mr1_fail, 1); -} - - -@pragma idletime_precision 3 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 1 -@pragma stage MR2 -table t2 { - reads { ethernet.etherType : ternary; } - actions { t2_action; } - support_timeout: true; -} -@pragma lrt_enable 0 -@pragma lrt_scale 15811 -counter t2_cntr { - type : packets; - direct : t2; - min_width : 32; -} -register t2_reg { - width: 32; - direct: t2; -} -blackbox stateful_alu t2_alu { - reg: t2_reg; - condition_lo: register_lo != ethernet.etherType; - update_hi_1_value: register_hi + 1; - update_lo_1_predicate: condition_lo; - update_lo_1_value: 0; -} -action t2_action() { - t2_alu.execute_stateful_alu(); -} - -@pragma idletime_precision 3 -@pragma idletime_two_way_notification 1 -@pragma idletime_per_flow_idletime 1 -@pragma stage MR2 -@pragma pack 1 -@pragma ways 4 -@pragma random_seed 1027 -table e2 { - reads { mrk.lo : exact; mrk.hi : exact; } - actions { e2_action; } - size: 4096; - support_timeout: true; -} -@pragma lrt_enable 0 -@pragma lrt_scale 15811 -counter e2_cntr { - type : packets; - direct : e2; - min_width : 32; -} -register e2_reg { - width: 32; - direct: e2; -} -blackbox stateful_alu e2_alu { - reg: e2_reg; - condition_lo: register_lo != ethernet.etherType; - update_hi_1_value: register_hi + 1; - update_lo_1_predicate: condition_lo; - update_lo_1_value: 0; -} -action e2_action() { - e2_alu.execute_stateful_alu(); -} - - -@pragma stage 0 -table eg_mr_meter_clr_setup { - actions { setup_mr_meter_clr; } -} -action setup_mr_meter_clr() { - modify_field(md.mr_clr, ethernet.dstAddr, 3); -} - -@pragma stage MR3 -table t3 { - reads { ethernet.etherType : ternary; } - actions { t3_action; } -} -@pragma lrt_enable 0 -@pragma lrt_scale 154 -counter t3_cntr { - type : bytes; - direct : t3; - min_width : 64; -} -@pragma meter_sweep_interval 0 -meter t3_meter { - type: bytes; - direct: t3; - result: md.t3_meter; - pre_color : md.mr_clr; -} -action t3_action() {} - -@pragma stage MR3 -@pragma pack 1 -@pragma ways 4 -@pragma random_seed 1027 -table e3 { - reads { mrk.lo : exact; mrk.hi : exact; } - actions { e3_action; } - size: 4096; -} -@pragma lrt_enable 0 -@pragma lrt_scale 154 -counter e3_cntr { - type : bytes; - direct : e3; - min_width : 64; -} -@pragma meter_sweep_interval 0 -meter e3_meter { - type: bytes; - direct: e3; - result: md.e3_meter; - pre_color : md.mr_clr; -} -action e3_action() {} - - - - -@pragma stage MR4 -table t4 { - reads { ethernet.etherType : ternary; } - actions { t4_action; } -} -@pragma lrt_enable 0 -@pragma lrt_scale 15811 -counter t4_cntr { - type : packets; - direct : t4; - //min_width : 32; -} -@pragma meter_sweep_interval 0 -meter t4_meter { - type: packets; - direct: t4; - result: md.t4_meter; - pre_color : md.mr_clr; -} -action t4_action() {} - -@pragma stage MR4 -@pragma pack 1 -@pragma ways 4 -@pragma random_seed 1027 -table e4 { - reads { mrk.lo : exact; mrk.hi : exact; } - actions { e4_action; } - size: 4096; -} -@pragma lrt_enable 0 -@pragma lrt_scale 15811 -counter e4_cntr { - type : packets; - direct : e4; - //min_width : 32; -} -@pragma meter_sweep_interval 0 -meter e4_meter { - type: packets; - direct: e4; - result: md.e4_meter; - pre_color : md.mr_clr; -} -action e4_action() {} - - - - - -@pragma stage MR5 -table t5 { - reads { ethernet.etherType : ternary; } - actions { t5_action; } -} -@pragma lrt_enable 0 -@pragma lrt_scale 154 -counter t5_cntr { - type : bytes; - direct : t5; - min_width : 32; -} -blackbox lpf t5_lpf { - filter_input: ethernet.srcAddr; - direct: t5; -} -//action t5_action() { } -action t5_action() { t5_lpf.execute(md.t5_lpf); } - -@pragma stage MR5 -@pragma pack 1 -@pragma ways 4 -@pragma random_seed 1027 -table e5 { - reads { mrk.lo : exact; mrk.hi : exact; } - actions { e5_action; } - size: 4096; -} -@pragma lrt_enable 0 -@pragma lrt_scale 154 -counter e5_cntr { - type : bytes; - direct : e5; - min_width : 32; -} -blackbox lpf e5_lpf { - filter_input: ethernet.srcAddr; - direct: e5; -} -//action e5_action() { } -action e5_action() { e5_lpf.execute(md.e5_lpf); } - - - - -@pragma stage MR6 -table t6 { - reads { ethernet.etherType : ternary; } - actions { t6_action; } -} -@pragma lrt_enable 0 -@pragma lrt_scale 15811 -counter t6_cntr { - type : packets; - direct : t6; - //min_width : 32; -} -blackbox lpf t6_lpf { - filter_input: ethernet.srcAddr; - direct: t6; -} -//action t6_action() { } -action t6_action() { t6_lpf.execute(md.t6_lpf); } - -@pragma stage MR6 -@pragma pack 1 -@pragma ways 4 -@pragma random_seed 1027 -table e6 { - reads { mrk.lo : exact; mrk.hi : exact; } - actions { e6_action; } - size: 4096; -} -@pragma lrt_enable 0 -@pragma lrt_scale 15811 -counter e6_cntr { - type : packets; - direct : e6; - //min_width : 32; -} -blackbox lpf e6_lpf { - filter_input: ethernet.srcAddr; - direct: e6; -} -//action e6_action() { } -action e6_action() { e6_lpf.execute(md.e6_lpf); } - - -@pragma stage MR_VERIFY_SETUP -table mr_verify_setup { - actions { mr_verify_setup_action; } -} -action mr_verify_setup_action() { - shift_right(md.t5_lpf_tmp1, md.t5_lpf, 4); - shift_right(md.t5_lpf_tmp2, md.t5_lpf, 8); - shift_right(md.e5_lpf_tmp1, md.e5_lpf, 4); - shift_right(md.e5_lpf_tmp2, md.e5_lpf, 8); - shift_right(md.t6_lpf_tmp1, md.t6_lpf, 4); - shift_right(md.t6_lpf_tmp2, md.t6_lpf, 8); - shift_right(md.e6_lpf_tmp1, md.e6_lpf, 4); - shift_right(md.e6_lpf_tmp2, md.e6_lpf, 8); -} - -counter v3_cntr { - type : bytes; - direct : v3; -} -@pragma stage MR_VERIFY -table v3 { - reads { ethernet.etherType : exact; } - actions { nothing; } -} -counter v4_cntr { - type : packets; - direct : v4; -} -@pragma stage MR_VERIFY -table v4 { - reads { ethernet.etherType : exact; } - actions { nothing; } -} -counter v5_cntr { - type : bytes; - direct : v5; -} -@pragma stage MR_VERIFY -table v5 { - reads { ethernet.etherType : exact; } - actions { nothing; } -} -counter v6_cntr { - type : packets; - direct : v6; -} -@pragma stage MR_VERIFY -table v6 { - reads { ethernet.etherType : exact; } - actions { nothing; } -} - - -register vp5_reg { - width: 64; - direct: vp5; -} -blackbox stateful_alu vp5_alu { - reg: vp5_reg; - condition_lo: register_lo == 0xFFFFFFFF; - update_hi_1_predicate: condition_lo; - update_hi_1_value: register_hi + 1; - update_lo_1_value: register_lo + 1; -} -action vp5_action() { - vp5_alu.execute_stateful_alu(); -} -@pragma stage MR_VERIFY -table vp5 { - reads { ethernet.etherType : exact; } - actions { vp5_action; } -} -register vp6_reg { - width: 64; - direct: vp6; -} -blackbox stateful_alu vp6_alu { - reg: vp6_reg; - condition_lo: register_lo == 0xFFFFFFFF; - update_hi_1_predicate: condition_lo; - update_hi_1_value: register_hi + 1; - update_lo_1_value: register_lo + 1; -} -action vp6_action() { - vp6_alu.execute_stateful_alu(); -} -@pragma stage MR_VERIFY -table vp6 { - reads { ethernet.etherType : exact; } - actions { vp6_action; } -} -register vpp5_reg { - width: 64; - direct: vpp5; -} -blackbox stateful_alu vpp5_alu { - reg: vpp5_reg; - condition_lo: register_lo == 0xFFFFFFFF; - update_hi_1_predicate: condition_lo; - update_hi_1_value: register_hi + 1; - update_lo_1_value: register_lo + 1; -} -action vpp5_action() { - vpp5_alu.execute_stateful_alu(); -} -@pragma stage MR_VERIFY -table vpp5 { - reads { ethernet.etherType : exact; } - actions { vpp5_action; } -} -register vpp6_reg { - width: 64; - direct: vpp6; -} -blackbox stateful_alu vpp6_alu { - reg: vpp6_reg; - condition_lo: register_lo == 0xFFFFFFFF; - update_hi_1_predicate: condition_lo; - update_hi_1_value: register_hi + 1; - update_lo_1_value: register_lo + 1; -} -action vpp6_action() { - vpp6_alu.execute_stateful_alu(); -} -@pragma stage MR_VERIFY -table vpp6 { - reads { ethernet.etherType : exact; } - actions { vpp6_action; } -} - - -/* -t1 : TCAM with idle-1 and stats-bytes and stateful-64bit -t2 : TCAM with idle-3 and stats-packets and stateful-32bit -t3 : TCAM with meter and stats-bytes -t4 : TCAM with meter and stats-packets -t5 : TCAM with LPF and stats-bytes -t6 : TCAM with LPF and stats-packets - -e1 : EXM with idle-1 and stats-bytes and stateful-64bit -e2 : EXM with idle-3 and stats-packets and stateful-32bit -e3 : EXM with meter and stats-bytes -e4 : EXM with meter and stats-packets -e5 : EXM with LPF and stats-bytes -e6 : EXM with LPF and stats-packets -*/ - - -action eg_dummy_action() { - modify_field(md.t3_meter, md.t3_meter); - modify_field(md.e3_meter, md.e3_meter); - modify_field(md.t4_meter, md.t4_meter); - modify_field(md.e4_meter, md.e4_meter); - modify_field(md.t5_lpf, md.t5_lpf); - modify_field(md.e5_lpf, md.e5_lpf); - modify_field(md.t6_lpf, md.t6_lpf); - modify_field(md.e6_lpf, md.e6_lpf); - modify_field(md.mr_clr, md.mr_clr); - modify_field(mrk.hi, 0x30); - modify_field(mrk.lo, 0x30); -} -@pragma stage 11 -table eg_dummy { - actions { eg_dummy_action; } -} - - -control ingress { - apply(dest); - apply(set_mrk_lo); - - if (0 == ig_intr_md.resubmit_flag and 0 == md.drop_it) { - apply(stats_resubmit); - } - if (1 == md.count_it) { - apply(set_stats_key1); - } else if (2 == md.count_it) { - apply(set_stats_key2); - } else if (3 == md.count_it) { - apply(set_stats_key3); - } - - if (1 == (ethernet.srcAddr & 1) and 0 == ig_intr_md.resubmit_flag and 0 == md.drop_it) { - apply(ig_meter_resubmit); - } - - apply(set_mrk_hi); - - if (1 == md.count_it or 2 == md.count_it or 3 == md.count_it) { - apply(ig_stat_1); - apply(ig_stat_2); - } - - apply(ig_idle_1); - apply(ig_idle_2); - apply(ig_idle_3); - apply(ig_idle_4); - apply(ig_idle_5); - apply(ig_idle_6); - apply(ig_idle_7); - apply(ig_idle_8); - apply(ig_idle_9); - apply(ig_idle_10); - apply(ig_idle_11); - apply(ig_idle_12); - apply(ig_idle_13); - apply(ig_idle_14); - apply(ig_idle_15); - apply(ig_idle_16); - - if (1 == md.resubmit_for_meter_test and 0 == ig_intr_md.resubmit_flag) { - apply(resubmit_2_tbl); - } else { - apply(ig_m1_color); - apply(ig_m1) { - hit { - apply(ig_m1_cnt); - if (md.m1_clr == 3) { - apply(ig_meter_test_discard); - } - } - } - } - - if (0 == md.dummy) { - apply(sel_tbl) { - hit { apply(sel_res); } - miss { - apply(ig_stat_3); - apply(ig_stat_4); - } - } - } else { - apply(dummy_tbl); - } -} - -control egress { - apply(t1); - apply(e1); - - apply(eg_mr_meter_clr_setup); - - if (1 == md.count_it or 2 == md.count_it or 3 == md.count_it or md.m1_drop == 1) { - apply(eg_stat_1); - apply(eg_stat_2); - //apply(eg_discard); - } - - apply(eg_idle_1); - apply(eg_idle_2); - apply(eg_idle_3); - apply(eg_idle_4); - - apply(eg_stat_3); - apply(eg_stat_4); - - apply(t5); - apply(e5); - apply(t6); - apply(e6); - - apply(t2); - apply(e2); - - if (md.t1_stful != md.e1_stful) { - apply(mr1_verify); - } - - apply(t3); - apply(e3); - apply(t4); - apply(e4); - - apply(mr_verify_setup); - - if (md.t3_meter == md.e3_meter) { - apply(v3); - } - if (md.t4_meter == md.e4_meter) { - apply(v4); - } - if (md.t5_lpf == md.e5_lpf) { - apply(v5); - } - if (md.t6_lpf == md.e6_lpf) { - apply(v6); - } - if (md.t5_lpf_tmp1 == md.e5_lpf_tmp1) { - apply(vp5); - } - if (md.t5_lpf_tmp2 == md.e5_lpf_tmp2) { - apply(vpp5); - } - if (md.t6_lpf_tmp1 == md.e6_lpf_tmp1) { - apply(vp6); - } - if (md.t6_lpf_tmp2 == md.e6_lpf_tmp2) { - apply(vpp6); - } - apply(eg_dummy); -} - - diff --git a/backends/tofino/bf-asm/test/ptf/meters.p4 b/backends/tofino/bf-asm/test/ptf/meters.p4 deleted file mode 100644 index 1f37d1ccd2d..00000000000 --- a/backends/tofino/bf-asm/test/ptf/meters.p4 +++ /dev/null @@ -1,447 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include "tofino.p4" -#include "tofino/intrinsic_metadata.p4" -#include "tofino/constants.p4" -#include "tofino/lpf_blackbox.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type ipv6_t { - fields { - version : 4; - trafficClass : 8; - flowLabel : 20; - payloadLen : 16; - nextHdr : 8; - hopLimit : 8; - srcAddr : 128; - dstAddr : 128; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - 0x86dd : parse_ipv6; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; -header ipv6_t ipv6; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -parser parse_ipv6 { - extract(ipv6); - return select(latest.nextHdr) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default : ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm : csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action next_hop_ipv4(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - - -action next_hop_ipv6(egress_port ,srcmac, dstmac) { - hop(ipv6.hopLimit, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -meter meter_0 { - type : bytes; - static : meter_tbl; - result : ipv4.diffserv; - instance_count : 500; -} - -meter meter_1 { - type : bytes; - direct : meter_tbl_direct; - result : ipv4.diffserv; -} - - -@pragma meter_pre_color_aware_per_flow_enable 1 -meter meter_2 { - type : bytes; - static : meter_tbl_color_aware_indirect; - result : ipv4.diffserv; - pre_color : ipv4.diffserv; - instance_count : 500; -} - -meter meter_3 { - type : bytes; - direct : meter_tbl_color_aware_direct; - result : ipv4.diffserv; - pre_color : ipv4.diffserv; -} - -blackbox lpf meter_lpf { - filter_input : ipv4.srcAddr; - instance_count : 500; -} - - -blackbox lpf meter_lpf_tcam { - filter_input : ipv4.srcAddr; - static : match_tbl_tcam_lpf; - instance_count : 500; -} - -blackbox lpf meter_lpf_direct { - filter_input : ipv4.srcAddr; - direct : match_tbl_lpf_direct; -} - -blackbox lpf meter_lpf_tcam_direct { - filter_input : ipv4.srcAddr; - direct : match_tbl_tcam_lpf_direct; -} - -action meter_action (egress_port, srcmac, dstmac, idx) { - next_hop_ipv4(egress_port, srcmac, dstmac); - execute_meter(meter_0, idx, ipv4.diffserv); -} - -action meter_action_color_aware (egress_port, srcmac, dstmac, idx) { - next_hop_ipv4(egress_port, srcmac, dstmac); - execute_meter(meter_2, idx, ipv4.diffserv, ipv4.diffserv); -} - -action count_color(color_idx) { - count(colorCntr, color_idx); -} - -action next_hop_ipv4_lpf(egress_port ,srcmac, dstmac, lpf_idx) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); - meter_lpf.execute(ipv4.srcAddr, lpf_idx); -} - -action next_hop_ipv4_direct_lpf(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); - meter_lpf_direct.execute(ipv4.srcAddr); -} - -action next_hop_ipv4_lpf_tcam(egress_port ,srcmac, dstmac, lpf_idx) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); - meter_lpf_tcam.execute(ipv4.srcAddr, lpf_idx); -} - -action next_hop_ipv4_lpf_direct_tcam(egress_port ,srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); - meter_lpf_tcam_direct.execute(ipv4.srcAddr); -} - -counter colorCntr { - type : packets; - static : color_match; - instance_count : 100; -} - -@pragma command_line --no-dead-code-elimination -@pragma stage 1 -table meter_tbl { - reads { - ipv4.dstAddr : exact; - } - actions { - nop; - meter_action; - } -} - -@pragma stage 0 -table meter_tbl_direct { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma stage 2 -table meter_tbl_color_aware_indirect { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - meter_action_color_aware; - } -} - - -@pragma stage 3 -table meter_tbl_color_aware_direct { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - next_hop_ipv4; - } - default_action : nop(); -} - -@pragma stage 4 -table match_tbl_lpf { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - next_hop_ipv4_lpf; - } - default_action : nop(); -} - -@pragma stage 4 -table match_tbl_tcam_lpf { - reads { - ipv4.dstAddr : ternary; - ipv4.srcAddr : ternary; - } - actions { - next_hop_ipv4_lpf_tcam; - } - default_action : nop(); -} - - -@pragma stage 5 -table match_tbl_lpf_direct { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - next_hop_ipv4_direct_lpf; - } - default_action : nop(); -} - -@pragma stage 5 -table match_tbl_tcam_lpf_direct { - reads { - ipv4.dstAddr : ternary; - ipv4.srcAddr : ternary; - } - actions { - next_hop_ipv4_lpf_direct_tcam; - } - default_action : nop(); -} - - -@pragma stage 11 -table color_match { - reads { - ethernet.dstAddr: exact; - ipv4.diffserv: exact; - } - actions { - count_color; - } - size : 256; -} - - -/* Main control flow */ -control ingress { - /* A general principle : Always keep the exact match tables ahead of the - * ternary tables in the same stage, except first stage. Logic relating to next-table - * will cause the Tofino model not to launch a lookup on th exact match - * tables if the order is reversed. - */ - apply(meter_tbl_direct); - apply(meter_tbl); - apply(meter_tbl_color_aware_indirect); - apply(meter_tbl_color_aware_direct); - apply(match_tbl_lpf); - apply(match_tbl_tcam_lpf); - apply(match_tbl_lpf_direct); - apply(match_tbl_tcam_lpf_direct); - apply(color_match); -} - -control egress { - -} - diff --git a/backends/tofino/bf-asm/test/ptf/multi_device.p4 b/backends/tofino/bf-asm/test/ptf/multi_device.p4 deleted file mode 100644 index 1b5b3491b91..00000000000 --- a/backends/tofino/bf-asm/test/ptf/multi_device.p4 +++ /dev/null @@ -1,692 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - learn_meta_1:20; - learn_meta_2:24; - learn_meta_3:25; - learn_meta_4:10; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm : csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -field_list learn_1 { - ipv4.ihl; - ipv4.protocol; - ipv4.srcAddr; - ethernet.srcAddr; - ethernet.dstAddr; - ipv4.fragOffset; - ipv4.identification; - routing_metadata.learn_meta_1; - routing_metadata.learn_meta_4; -} - -action learn_1 (learn_meta_1, learn_meta_4) { - generate_digest(FLOW_LRN_DIGEST_RCVR, learn_1); - modify_field(routing_metadata.learn_meta_1, learn_meta_1); - modify_field(routing_metadata.learn_meta_4, learn_meta_4); -} - -field_list learn_2 { - ipv4.ihl; - ipv4.identification; - ipv4.protocol; - ipv4.srcAddr; - ethernet.srcAddr; - ethernet.dstAddr; - ipv4.fragOffset; - routing_metadata.learn_meta_2; - routing_metadata.learn_meta_3; -} - -action learn_2 (learn_meta_2, learn_meta_3) { - generate_digest(FLOW_LRN_DIGEST_RCVR, learn_2); - modify_field(routing_metadata.learn_meta_2, learn_meta_2); - modify_field(routing_metadata.learn_meta_3, learn_meta_3); -} - -action hop(ttl, egress_port) { - add_to_field(ttl, -1); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action hop_ipv4(egress_port /*,srcmac, dstmac*/) { - hop(ipv4.ttl, egress_port); -// modify_field(ethernet.srcAddr, srcmac); -// modify_field(ethernet.dstAddr, dstmac); -} - -action drop_ipv4 () { - drop(); -} - -action next_hop_ipv4(egress_port, srcmac, dstmac) { - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action mod_mac_adr(egress_port, srcmac, dstmac) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ethernet.srcAddr, srcmac); - modify_field(ethernet.dstAddr, dstmac); -} - -action udp_hdr_add (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - add_header(udp); - modify_field(ipv4.protocol, IP_PROTOCOLS_UDP); - add_to_field(ipv4.totalLen, 8); -} - -action udp_set_dest(port) { - modify_field(udp.dstPort, port); -} -action udp_set_src(port) { - modify_field(udp.srcPort, port); -} - -action tcp_hdr_rm (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - remove_header(tcp); - modify_field(ipv4.protocol, 0); -// add_to_field(ipv4.totalLen, -20); -// modify_field(ipv4.totalLen, 66); -} - -action modify_tcp_dst_port_1(dstPort, egress_port) { - modify_field(tcp.dstPort, dstPort); - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action custom_action_1(egress_port, ipAddr, dstAddr, tcpPort) -{ - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ipv4.srcAddr, ipAddr); - modify_field(ethernet.dstAddr, dstAddr); - modify_field(tcp.dstPort, tcpPort); -} - -action custom_action_2(egress_port, ipAddr, tcpPort) -{ - modify_field(ipv4.srcAddr, ipAddr); - modify_field(tcp.dstPort, tcpPort); - hop(ipv4.ttl, egress_port); -} - -action custom_action_3(egress_port, dstAddr, dstIp) -{ - modify_field(ipv4.dstAddr, dstIp); - modify_field(ethernet.dstAddr, dstAddr); - hop(ipv4.ttl, egress_port); -} - -action modify_l2 (egress_port, srcAddr, dstAddr, tcp_sport, tcp_dport) { - // Trying for >128 bit action data - hop(ipv4.ttl, egress_port); - modify_field(ethernet.srcAddr, srcAddr); - modify_field(ethernet.dstAddr, dstAddr); - modify_field(tcp.dstPort, tcp_dport); - modify_field(tcp.srcPort, tcp_sport); -} - -@pragma command_line --no-dead-code-elimination -@pragma immediate 1 -@pragma stage 0 -table ig_udp { - reads { - ethernet : valid; - ipv4 : valid; - udp : valid; - udp.dstPort : ternary; - } - actions { - nop; - udp_set_dest; - } -} -@pragma immediate 1 -@pragma stage 0 -table eg_udp { - reads { - ethernet : valid; - ipv4 : valid; - udp : valid; - udp.srcPort : exact; - } - actions { - nop; - udp_set_src; - } -} - -@pragma immediate 1 -@pragma stage 0 -table ipv4_routing { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - hop_ipv4; - drop_ipv4; - learn_1; - learn_2; - } - size : 512; -} - -@pragma immediate 1 -@pragma stage 0 -@pragma ways 3 -@pragma pack 5 -table ipv4_routing_exm_ways_3_pack_5 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - modify_tcp_dst_port_1; - } -} - - -@pragma immediate 1 -@pragma stage 1 -@pragma ways 3 -@pragma pack 3 -table ipv4_routing_exm_ways_3_pack_3 { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - custom_action_1; - } -} - -@pragma immediate 1 -@pragma stage 1 -@pragma ways 4 -@pragma pack 3 -table ipv4_routing_exm_ways_4_pack_3_stage_1 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma immediate 1 -@pragma stage 1 -table ipv4_routing_stage_1 { - reads { - ipv4.dstAddr : lpm; - ipv4.srcAddr : exact; - } - actions { - nop; - hop_ipv4; - } - size : 1024; -} - -@pragma stage 2 -table tcam_tbl_stage_2 { - reads { - ipv4.dstAddr : lpm; - } - actions { - nop; - mod_mac_adr; - } -} - -@pragma stage 2 -@pragma ways 4 -@pragma pack 7 -table ipv4_routing_exm_ways_4_pack_7_stage_2 { - reads { - ipv4.dstAddr : exact; - ipv4.srcAddr : exact; - tcp.dstPort : exact; - tcp.srcPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -@pragma immediate 1 -@pragma stage 3 -@pragma ways 5 -@pragma pack 3 -table ipv4_routing_exm_ways_5_pack_3_stage_3 { - reads { - ipv4.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma immediate 1 -@pragma stage 3 -table udp_add_tbl_stage_3 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - udp_hdr_add; - } -} - -@pragma immediate 1 -@pragma stage 4 -@pragma ways 6 -@pragma pack 3 -table ipv4_routing_exm_ways_6_pack_3_stage_4 { - reads { - ipv4.dstAddr : exact; - ethernet.dstAddr : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - - -@pragma immediate 1 -@pragma stage 4 -table tcp_rm_tbl_stage_4 { - reads { - ethernet.srcAddr : ternary; - } - actions { - nop; - tcp_hdr_rm; - } -} - -@pragma immediate 1 -@pragma stage 5 -@pragma ways 3 -@pragma pack 4 -table ipv4_routing_exm_ways_3_pack_4_stage_5 { - reads { - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - modify_tcp_dst_port_1; - } -} - -@pragma stage 6 -@pragma ways 4 -@pragma pack 4 -table ipv4_routing_exm_ways_4_pack_4_stage_6 { - reads { - ethernet.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.srcPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - -@pragma immediate 1 -@pragma stage 7 -@pragma ways 5 -@pragma pack 4 -table ipv4_routing_exm_ways_5_pack_4_stage_7 { - reads { - ipv4.dstAddr : exact; - ethernet.srcAddr : exact; - } - actions { - nop; - custom_action_3; - } -} - -@pragma immediate 1 -@pragma stage 8 -table tcam_adt_deep_stage_8 { - reads { - ethernet.srcAddr : ternary; - ethernet.dstAddr : ternary; - ipv4.srcAddr : ternary; - ipv4.dstAddr : ternary; - } - actions { - nop; - modify_l2; - } - size : 3072; -} - -@pragma stage 8 -@pragma ways 4 -@pragma pack 5 -table ipv4_routing_exm_ways_4_pack_5_stage_8 { - reads { - ipv4.srcAddr : exact; - ethernet.dstAddr : exact; - tcp.srcPort : exact; - tcp.dstPort : exact; - } - actions { - nop; - custom_action_2; - } -} - -@pragma stage 9 -table ipv4_routing_select { - reads { - ipv4.dstAddr: lpm; - } - action_profile : ecmp_action_profile; - size : 512; -} - -field_list ecmp_hash_fields { - ipv4.srcAddr; - ipv4.dstAddr; - ipv4.identification; - ipv4.protocol; -} - -field_list_calculation ecmp_hash { - input { - ecmp_hash_fields; - } - algorithm : crc16; - output_width : 14; -} - -action_profile ecmp_action_profile { - actions { - nhop_set; - nop; - } - size : 1024; - // optional - dynamic_action_selection : ecmp_selector; -} - -action_selector ecmp_selector { - selection_key : ecmp_hash; // take a field_list_calculation only - // optional - selection_mode : fair; // “resilient” or “non-resilient” -} - -action nhop_set(port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -@pragma stage 10 -table tcam_indirect_action { - reads { - ethernet.srcAddr : ternary; - ethernet.dstAddr : ternary; - ethernet.etherType: exact; - ipv4.srcAddr : ternary; - ipv4.dstAddr : ternary; - ipv4.protocol : exact; - ipv4.version : exact; - } - action_profile : indirect_action_profile; - size : 2048; -} - -action modify_ip_id(port, id, srcAddr, dstAddr) { - modify_field(ipv4.identification, id); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); - modify_field(ethernet.srcAddr, srcAddr); - modify_field(ethernet.dstAddr, dstAddr); -} - -action_profile indirect_action_profile { - actions { - nop; - modify_ip_id; - } - size : 1500; -} - -@pragma stage 11 -@pragma ways 6 -@pragma pack 4 -table ipv4_routing_exm_ways_6_pack_4_stage_11 { - reads { - ipv4.dstAddr : exact; - tcp.dstPort : exact; - } - actions { - nop; - next_hop_ipv4; - } -} - - -/* Main control flow */ -control ingress { - /* A general principle : Always keep the exact match tables ahead of the - * ternary tables in the same stage, except first stage. Logic relating to next-table - * will cause the Tofino model not to launch a lookup on th exact match - * tables if the order is reversed. - */ - apply(ig_udp); - apply(ipv4_routing); - apply(ipv4_routing_exm_ways_3_pack_5); - apply(ipv4_routing_exm_ways_3_pack_3); - apply(ipv4_routing_exm_ways_4_pack_3_stage_1); - apply(ipv4_routing_stage_1); - apply(tcam_tbl_stage_2); - apply(ipv4_routing_exm_ways_4_pack_7_stage_2); - apply(ipv4_routing_exm_ways_5_pack_3_stage_3); - /* Gateway not yet supported */ -// if (ipv4.protocol == 0) { - apply(udp_add_tbl_stage_3); -// } - apply(ipv4_routing_exm_ways_6_pack_3_stage_4); -// if (valid(tcp)) { - apply(tcp_rm_tbl_stage_4); -// } - apply(ipv4_routing_exm_ways_3_pack_4_stage_5); - apply(ipv4_routing_exm_ways_4_pack_4_stage_6); - apply(ipv4_routing_exm_ways_5_pack_4_stage_7); - apply(tcam_adt_deep_stage_8); - apply(ipv4_routing_exm_ways_4_pack_5_stage_8); - // Stage 9 - Please use caution before adding any more tables in stage 9 - // Poor man's selector may not work - apply(ipv4_routing_select); - // Stage 10 - apply(tcam_indirect_action); - // Stage 11 -} - -control egress { - apply(eg_udp); - // Commenting out since modify of egress port is not possible in egress -// apply(ipv4_routing_exm_ways_6_pack_4_stage_11); -} - diff --git a/backends/tofino/bf-asm/test/ptf/multicast_scale.p4 b/backends/tofino/bf-asm/test/ptf/multicast_scale.p4 deleted file mode 100644 index f28e6dc0cf2..00000000000 --- a/backends/tofino/bf-asm/test/ptf/multicast_scale.p4 +++ /dev/null @@ -1,120 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include "tofino/stateful_alu_blackbox.p4" -#include - -header_type ethernet_t { - fields { - dmac : 48; - smac : 48; - etype : 16; - } -} -header ethernet_t ethernet; - -parser start { - extract(ethernet); - return ingress; -} - - - - - -action set_general_md(rid, xid, yid, h1, h2) { - modify_field(ig_intr_md_for_tm.rid, rid); - modify_field(ig_intr_md_for_tm.level1_exclusion_id, xid); - modify_field(ig_intr_md_for_tm.level2_exclusion_id, yid); - modify_field(ig_intr_md_for_tm.level1_mcast_hash, h1); - modify_field(ig_intr_md_for_tm.level2_mcast_hash, h2); -} -action mcast_1(mgid, rid, xid, yid, h1, h2) { - modify_field(ig_intr_md_for_tm.mcast_grp_a, mgid); - set_general_md(rid, xid, yid, h1, h2); -} -action mcast_2(mgid, rid, xid, yid, h1, h2) { - modify_field(ig_intr_md_for_tm.mcast_grp_b, mgid); - set_general_md(rid, xid, yid, h1, h2); -} -action mcast_both(mgid1, mgid2, rid, xid, yid, h1, h2) { - modify_field(ig_intr_md_for_tm.mcast_grp_a, mgid1); - modify_field(ig_intr_md_for_tm.mcast_grp_b, mgid2); - set_general_md(rid, xid, yid, h1, h2); -} - -table ing { - reads { - ig_intr_md.ingress_port mask 0x7f : exact; - ethernet.dmac : exact; - } - actions { - mcast_1; - mcast_2; - mcast_both; - } - size: 65536; // Enough to assign 64k MGIDs -} - - -action on_miss() { count(cntr, 1); drop();} - -action log_only() { - salu.execute_stateful_alu(); - count(cntr, 0); - drop(); -} - -counter cntr { - type: packets; - instance_count: 2; - min_width: 64; -} -register log { - width : 16; - direct: egr; -} -blackbox stateful_alu salu { - reg: log; - condition_lo: eg_intr_md.egress_rid_first == 1; - update_lo_1_predicate: condition_lo; - update_lo_1_value: register_lo + 0x100; - update_lo_2_predicate: not condition_lo; - update_lo_2_value: register_lo + 1; -} - -table egr { - reads { - eg_intr_md.egress_port mask 0x7f : exact; - eg_intr_md.egress_rid : exact; - } - actions { - log_only; - } - default_action: on_miss; - size: 1048576; // Enough for 16384 RIDs on 64 ports -} - -control ingress { - apply(ing); -} - -control egress { - apply(egr); -} - - diff --git a/backends/tofino/bf-asm/test/ptf/multicast_test.p4 b/backends/tofino/bf-asm/test/ptf/multicast_test.p4 deleted file mode 100644 index ac93b004d1f..00000000000 --- a/backends/tofino/bf-asm/test/ptf/multicast_test.p4 +++ /dev/null @@ -1,279 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags_resv : 1; - flags_df : 1; - flags_mf : 1; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type ingress_metadata_t { - fields { - ifid : 32; /* Logical Interface ID */ - brid : 16; /* Bridging Domain ID */ - vrf : 16; - l3 : 1; /* Set if routed */ - } -} - -metadata ingress_metadata_t ing_md; -header ethernet_t ethernet; -header ipv4_t ipv4; -header vlan_tag_t vlan_tag; - - -parser start { - return parse_ethernet; -} - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags_resv; - ipv4.flags_df; - ipv4.flags_mf; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm : csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - - - - - - - -/****************************************************************************** - * - * Table: ing_port - * Key: Incoming physical port number - * Top VLAN tag - * - * Maps the physical port to a logical port and also invalidates the egress - * unicast port and MGID intrinsic metadatas. - * - *****************************************************************************/ -action set_ifid(ifid) { - modify_field(ing_md.ifid, ifid); - /* Set the destination port to an invalid value. */ - modify_field(ig_intr_md_for_tm.ucast_egress_port, 0x1FF); -} - -table ing_port { - reads { - ig_intr_md.ingress_port : exact; - vlan_tag : valid; - vlan_tag.vlan_id : exact; - } - actions { - set_ifid; - } -} - - -/****************************************************************************** - * - * Table: ing_src_ifid - * Key: Logical interface id - * - * Assigns ingress interface specific metadata: iRID, XID, YID, and brid. - * Also sets the hash values used for multicast replication. - * - *****************************************************************************/ -action set_src_ifid_md(rid, yid, brid, h1, h2) { - modify_field(ig_intr_md_for_tm.rid, rid); - modify_field(ig_intr_md_for_tm.level2_exclusion_id, yid); - modify_field(ing_md.brid, brid); - modify_field(ig_intr_md_for_tm.level1_mcast_hash, h1); - modify_field(ig_intr_md_for_tm.level2_mcast_hash, h2); -} - -table ing_src_ifid { - reads { - ing_md.ifid : exact; - } - actions { - set_src_ifid_md; - } -} - - -/****************************************************************************** - * - * Table: ing_dmac - * Key: Bridging domain and DMAC - * - * Will either setup the packet to L2 flood, L2 switch or route. - * - *****************************************************************************/ -action flood() { - modify_field(ig_intr_md_for_tm.mcast_grp_a, ing_md.brid); -} -action switch(egr_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egr_port); -} -action route(vrf) { - modify_field(ing_md.l3, 1); - modify_field(ing_md.vrf, vrf); -} -table ing_dmac { - reads { - ing_md.brid : exact; - ethernet.dstAddr : exact; - } - actions { - flood; - switch; - route; - } -} - - -/****************************************************************************** - * - * Table: ing_ipv4_mcast - * Key: IPv4 addresses and VRF - * - * Will assign MGID and XID - * - *****************************************************************************/ -action mcast_route(xid, mgid1, mgid2) { - modify_field(ig_intr_md_for_tm.level1_exclusion_id, xid); - modify_field(ig_intr_md_for_tm.mcast_grp_a, mgid1); - modify_field(ig_intr_md_for_tm.mcast_grp_b, mgid2); - add_to_field(ipv4.ttl, -1); -} -table ing_ipv4_mcast { - reads { - ing_md.vrf : exact; - ipv4.srcAddr : ternary; - ipv4.dstAddr : ternary; - } - actions { - mcast_route; - } -} - - -control ingress { - apply(ing_port); - apply(ing_src_ifid); - apply(ing_dmac); - if (ing_md.l3 == 1) { - apply(ing_ipv4_mcast); - } -} - - -/****************************************************************************** - * - * Table: egr_encode - * Key: None - * - * Encodes metadata generated by the multicast replication into the packet. - * - *****************************************************************************/ -action do_egr_encode() { - modify_field(ipv4.identification, eg_intr_md.egress_rid); - modify_field(ipv4.diffserv, eg_intr_md.egress_rid_first); -} -table egr_encode { - actions { - do_egr_encode; - } -} - - -control egress { - if (valid(ipv4)) { - apply(egr_encode); - } -} - - diff --git a/backends/tofino/bf-asm/test/ptf/p4features.h b/backends/tofino/bf-asm/test/ptf/p4features.h deleted file mode 100644 index 5bdfeeaff80..00000000000 --- a/backends/tofino/bf-asm/test/ptf/p4features.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef BACKENDS_TOFINO_BF_ASM_TEST_PTF_P4FEATURES_H_ -#define BACKENDS_TOFINO_BF_ASM_TEST_PTF_P4FEATURES_H_ - -#define MATCH_ATCAM -#define MATCH_COUNT 50000 -#define STATS_INDIRECT -#define STATS_COUNT 18000 -#define STATEFUL_INDIRECT -#define STATEFUL_COUNT 40000 -#define ACTION_DIRECT -#define ACTION_COUNT 50000 - -#endif /* BACKENDS_TOFINO_BF_ASM_TEST_PTF_P4FEATURES_H_ */ diff --git a/backends/tofino/bf-asm/test/ptf/parser_intr_md.p4 b/backends/tofino/bf-asm/test/ptf/parser_intr_md.p4 deleted file mode 100644 index 5d45dbc11ae..00000000000 --- a/backends/tofino/bf-asm/test/ptf/parser_intr_md.p4 +++ /dev/null @@ -1,129 +0,0 @@ -// Test program for enhancement to use ig_intr_md in the parser for branching -// Compiler-216 - -#ifdef __TARGET_TOFINO__ -#include -#include -#include -#include -#endif - -#define ETHERTYPE_IPV4 0x0800 - -@pragma parser_value_set_size 2 -parser_value_set pvs_server_port; -@pragma parser_value_set_size 2 -parser_value_set pvs_fabric_port; - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} -header ethernet_t ethernet; - -header_type fabric_header_t { - fields { - packetType : 3; - headerVersion : 2; - packetVersion : 2; - pad1 : 1; - - fabricColor : 3; - fabricQos : 5; - - dstDevice : 8; - dstPortOrGroup : 16; - } -} -header fabric_header_t fabric_header; -#define ETHERTYPE_BF_PKTGEN 0x9001 -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} -header ipv4_t ipv4; - -parser start { - //return select(ig_intr_md._pad2, ig_intr_md.ingress_port) { - return select(ig_intr_md.ingress_port) { -#ifdef PVS - //pvs_server_port : parse_ethernet; - pvs_fabric_port : parse_fabric_header; -#else - 0x0000 mask 0x0001 : parse_ethernet; - 0x0001 mask 0x0001 : parse_fabric_header; -#endif - default : parse_ethernet; - } -} - -parser parse_fabric_header { - extract(ethernet); - extract(fabric_header); - return ingress; -} - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x0800: parse_ipv4; - default: ingress; - } -} - -parser parse_pktgen_header { - extract(pktgen_generic); - return ingress; -} - -parser parse_ipv4 { - extract(ipv4); - return ingress; -} - -// Tables -action fwd_to_fabric() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 3); -} - -action fwd_to_server() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 4); -} - -action fwd_drop() { - drop(); -} - -table fwd_packet { - // all ip packets received from server ports are sent to port 3 - // all fabric packets received from fabric ports are sent to server port 4 - reads { - ipv4 : valid; - fabric_header : valid; - } - actions { - fwd_to_fabric; - fwd_to_server; - fwd_drop; - } - size : 4; -} - -control ingress { - apply(fwd_packet); -} diff --git a/backends/tofino/bf-asm/test/ptf/pcie_pkt_test.p4 b/backends/tofino/bf-asm/test/ptf/pcie_pkt_test.p4 deleted file mode 100644 index f5a90ed1dce..00000000000 --- a/backends/tofino/bf-asm/test/ptf/pcie_pkt_test.p4 +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include - -parser start { - return ingress; -} - -action set_md(eg_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, eg_port); -} - -table port_tbl { - reads { - ig_intr_md.ingress_port : exact; - } - actions { - set_md; - } - size : 288; -} - - -control ingress { - if (0 == ig_intr_md.resubmit_flag) { - apply(port_tbl); - } -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/ptf/pctr.p4 b/backends/tofino/bf-asm/test/ptf/pctr.p4 deleted file mode 100644 index 5602d112cc4..00000000000 --- a/backends/tofino/bf-asm/test/ptf/pctr.p4 +++ /dev/null @@ -1,226 +0,0 @@ -#include - -#define _parser_counter_ ig_prsr_ctrl.parser_counter - -#define ETHERTYPE_IPV4 0x0800 -#define ETHERTYPE_IPV6 0x86dd - -#define IP_PROTOCOLS_SR 43 -#define SRH_MAX_SEGMENTS 9 - -#define IPV4_OPTION_EOL_VALUE 0x00 -#define IPV4_OPTION_NOP_VALUE 0x01 -#define IPV4_OPTION_ADDRESS_EXTENSION 0x93 - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -// End of Option List -header_type ipv4_option_EOL_t { - fields { - value : 8; - } -} - -// No operation -header_type ipv4_option_NOP_t { - fields { - value : 8; - } -} - -header_type ipv4_option_addr_ext_t { - fields { - value : 8; - len : 8; - src_ext : 32; - dst_ext : 32; - } -} - -header_type ipv6_t { - fields { - version : 4; - trafficClass : 8; - flowLabel : 20; - payloadLen : 16; - nextHdr : 8; - hopLimit : 8; - srcAddr : 128; - dstAddr : 128; - } -} - -header_type ipv6_srh_t { - fields { - nextHdr : 8; - hdrExtLen : 8; - routingType : 8; - segLeft : 8; - firstSeg : 8; - flags : 16; - reserved : 8; - } -} - -header_type ipv6_srh_segment_t { - fields { - sid : 128; - } -} - -header ethernet_t ethernet; -header ipv4_t ipv4; -@pragma header_ordering ipv4_option_addr_ext ipv4_option_NOP ipv4_option_EOL -header ipv4_option_EOL_t ipv4_option_EOL; -header ipv4_option_NOP_t ipv4_option_NOP; -header ipv4_option_addr_ext_t ipv4_option_addr_ext; -header ipv6_t ipv6; -header ipv6_srh_t ipv6_srh; -header ipv6_srh_segment_t ipv6_srh_seg_list[SRH_MAX_SEGMENTS]; -header ipv6_srh_segment_t active_segment; - - -parser start { - return parse_ethernet; -} - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - ETHERTYPE_IPV4 : parse_ipv4; - ETHERTYPE_IPV6 : parse_ipv6; - } -} - -parser parse_ipv4 { - extract(ipv4); - // Little bit hacky. This shouldve been ipv4.ihl * 4 - 20. Extra -1 is to - // get rid of the effect of version (0x0100) - set_metadata(_parser_counter_, ipv4.ihl * 4 - 21); - return select(ipv4.ihl) { - 0x05 : ingress; - default : parse_ipv4_options; - } -} - -parser parse_ipv4_options { - // match on byte counter and option value - return select(_parser_counter_, current(0, 8)) { - 0x0000 mask 0xff00 : ingress; - 0x0000 mask 0x00ff : parse_ipv4_option_eol; - 0x0001 mask 0x00ff : parse_ipv4_option_nop; - 0x0093 mask 0x00ff : parse_ipv4_option_addr_ext; - } -} - -parser parse_ipv4_option_eol { - extract(ipv4_option_EOL); - set_metadata(_parser_counter_, _parser_counter_ - 1); - return parse_ipv4_options; -} - -parser parse_ipv4_option_nop { - extract(ipv4_option_NOP); - set_metadata(_parser_counter_, _parser_counter_ - 1); - return parse_ipv4_options; -} - -parser parse_ipv4_option_addr_ext { - extract(ipv4_option_addr_ext); - // security option must have length 11 bytes - set_metadata(_parser_counter_, _parser_counter_ - 10); - return parse_ipv4_options; -} - -parser parse_ipv6 { - extract(ipv6); - return select(latest.nextHdr) { - IP_PROTOCOLS_SR : parse_ipv6_srh; - } -} - -parser parse_ipv6_srh { - extract(ipv6_srh); - set_metadata(_parser_counter_, ipv6_srh.segLeft); - return parse_ipv6_srh_seg_list; -} - -parser parse_ipv6_srh_seg_list { - return select(_parser_counter_) { - 0x00 : parse_ipv6_srh_active_segment; - default : parse_ipv6_srh_segment; - } -} - -parser parse_ipv6_srh_segment { - extract(ipv6_srh_seg_list[next]); - set_metadata(_parser_counter_, _parser_counter_ - 1); - return parse_ipv6_srh_seg_list; -} - -parser parse_ipv6_srh_active_segment { - extract(active_segment); - return ingress; -} - -action rewrite_ipv6_and_set_egress_port() { - modify_field(ipv6.dstAddr, active_segment.sid); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); -} - -action set_egress_port() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 1); -} - -table sr_lookup { - actions { - rewrite_ipv6_and_set_egress_port; - } -} - -table ipv4_option_lookup { - reads { - ipv4_option_NOP : valid; - ipv4_option_EOL : valid; - ipv4_option_addr_ext : valid; - } - actions { - set_egress_port; - } -} - -control ingress { - if (valid(ipv6_srh)) { - apply(sr_lookup); - } - if (valid(ipv4)) { - apply(ipv4_option_lookup); - } -} - -control egress { - -} diff --git a/backends/tofino/bf-asm/test/ptf/perf_test.p4 b/backends/tofino/bf-asm/test/ptf/perf_test.p4 deleted file mode 100644 index efc3fcd376a..00000000000 --- a/backends/tofino/bf-asm/test/ptf/perf_test.p4 +++ /dev/null @@ -1,245 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include "tofino.p4" -#include "tofino/intrinsic_metadata.p4" -#include "tofino/constants.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type ipv6_t { - fields { - version : 4; - trafficClass : 8; - flowLabel : 20; - payloadLen : 16; - nextHdr : 8; - hopLimit : 8; - srcAddr : 128; - dstAddr : 128; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -header_type l3_metadata_t { - fields { - vrf : 24; - fib_hit : 1; - fib_nexthop : 16; - fib_nexthop_type : 1; - } -} - -metadata l3_metadata_t l3_metadata; - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - 0x86dd : parse_ipv6; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; -header ipv6_t ipv6; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -parser parse_ipv6 { - extract(ipv6); - return select(latest.nextHdr) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default : ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm : csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action fib_hit_nexthop(nexthop_index) { - modify_field(l3_metadata.fib_hit, 1); - modify_field(l3_metadata.fib_nexthop, nexthop_index); - modify_field(l3_metadata.fib_nexthop_type, 0); -} - -action fib_hit_ecmp(ecmp_index) { - modify_field(l3_metadata.fib_hit, 1); - modify_field(l3_metadata.fib_nexthop, ecmp_index); - modify_field(l3_metadata.fib_nexthop_type, 1); -} - -@pragma command_line --no-dead-code-elimination -table perf_exm_immediate_action { - reads { - l3_metadata.vrf : exact; - ipv4.dstAddr : exact; - } - actions { - nop; - fib_hit_nexthop; - fib_hit_ecmp; - } - - size : 1000000; -} - -/* Main control flow */ -control ingress { - /* A general principle : Always keep the exact match tables ahead of the - * ternary tables in the same stage, except first stage. Logic relating to next-table - * will cause the Tofino model not to launch a lookup on th exact match - * tables if the order is reversed. - */ - apply(perf_exm_immediate_action); -} - -control egress { - -} diff --git a/backends/tofino/bf-asm/test/ptf/perf_test_alpm.p4 b/backends/tofino/bf-asm/test/ptf/perf_test_alpm.p4 deleted file mode 100644 index 9f2b3fcc7b6..00000000000 --- a/backends/tofino/bf-asm/test/ptf/perf_test_alpm.p4 +++ /dev/null @@ -1,217 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include "tofino.p4" -#include "tofino/intrinsic_metadata.p4" -#include "tofino/constants.p4" - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -header_type l3_metadata_t { - fields { - vrf : 24; - fib_hit : 1; - fib_nexthop : 16; - fib_nexthop_type : 1; - } -} - -metadata l3_metadata_t l3_metadata; - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type routing_metadata_t { - fields { - drop: 1; - } -} - -metadata routing_metadata_t /*metadata*/ routing_metadata; - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm : csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -action nop() { -} - -action fib_hit_nexthop(nexthop_index) { - modify_field(l3_metadata.fib_hit, 1); - modify_field(l3_metadata.fib_nexthop, nexthop_index); - modify_field(l3_metadata.fib_nexthop_type, 0); -} - -action fib_hit_ecmp(ecmp_index) { - modify_field(l3_metadata.fib_hit, 1); - modify_field(l3_metadata.fib_nexthop, ecmp_index); - modify_field(l3_metadata.fib_nexthop_type, 1); -} - -@pragma command_line --no-dead-code-elimination -@pragma alpm 1 -table perf_alpm_immediate_action { - reads { - l3_metadata.vrf : exact; - ipv4.dstAddr : lpm; - } - actions { - nop; - fib_hit_nexthop; - fib_hit_ecmp; - } - - size : 130000; -} - -/* Main control flow */ -control ingress { - apply(perf_alpm_immediate_action); -} - -control egress { - -} diff --git a/backends/tofino/bf-asm/test/ptf/pgrs.p4 b/backends/tofino/bf-asm/test/ptf/pgrs.p4 deleted file mode 100644 index 65fe93f8c65..00000000000 --- a/backends/tofino/bf-asm/test/ptf/pgrs.p4 +++ /dev/null @@ -1,309 +0,0 @@ - -#ifdef __TARGET_TOFINO__ -#include -#include -#include -#include "tofino/stateful_alu_blackbox.p4" -#else -#include "includes/tofino.p4" -#include "includes/pktgen_headers.p4" -#endif -@pragma pa_alias ingress ig_intr_md.ingress_port ingress_metadata.ingress_port - -header_type pktgen_header_t { - fields { - id : 8; - } - -} - -header pktgen_header_t pgen_header; - -parser start { - extract(pgen_header); - return select(latest.id) { - 0x00 mask 0x1F: pktgen_port_down; // Pipe 0, App 0 - 0x01 mask 0x1F: pktgen_timer; // App 1 - 0x02 mask 0x1F: pktgen_recirc; // App 2 - 0x03 mask 0x1F: pktgen_timer; // App 3 - 0x04 mask 0x1F: pktgen_timer; // App 4 - 0x05 mask 0x1F: pktgen_timer; // App 5 - 0x06 mask 0x1F: pktgen_timer; // App 6 - 0x07 mask 0x1F: pktgen_timer; // App 7 - 0x08 mask 0x1F: pktgen_timer; // Pipe 1, App 0 - 0x09 mask 0x1F: pktgen_port_down; // App 1 - 0x0A mask 0x1F: pktgen_timer; // App 2 - 0x0B mask 0x1F: pktgen_recirc; // App 3 - 0x0C mask 0x1F: pktgen_timer; // App 4 - 0x0D mask 0x1F: pktgen_timer; // App 5 - 0x0E mask 0x1F: pktgen_timer; // App 6 - 0x0F mask 0x1F: pktgen_timer; // App 7 - 0x10 mask 0x1F: pktgen_timer; // Pipe 2, App 0 - 0x11 mask 0x1F: pktgen_timer; // App 1 - 0x12 mask 0x1F: pktgen_port_down; // App 2 - 0x13 mask 0x1F: pktgen_timer; // App 3 - 0x14 mask 0x1F: pktgen_recirc; // App 4 - 0x15 mask 0x1F: pktgen_timer; // App 5 - 0x16 mask 0x1F: pktgen_timer; // App 6 - 0x17 mask 0x1F: pktgen_timer; // App 7 - 0x18 mask 0x1F: pktgen_timer; // Pipe 3, App 0 - 0x19 mask 0x1F: pktgen_timer; // App 1 - 0x1A mask 0x1F: pktgen_timer; // App 2 - 0x1B mask 0x1F: pktgen_port_down; // App 3 - 0x1C mask 0x1F: pktgen_timer; // App 4 - 0x1D mask 0x1F: pktgen_recirc; // App 5 - 0x1E mask 0x1F: pktgen_timer; // App 6 - 0x1F mask 0x1F: pktgen_timer; // App 7 - default: ingress; - } -} - -parser pktgen_timer { - set_metadata(ig_md.pktgen_type, 0); - return pktgen_done; -} -parser pktgen_port_down { - set_metadata(ig_md.pktgen_type, 2); - return pktgen_done; -} -parser pktgen_recirc { - set_metadata(ig_md.pktgen_type, 3); - return pktgen_done; -} -parser pktgen_done { - return ingress; -} - - -header_type ig_md_t { - fields { - skip_lkups : 1; - pktgen_port : 1; - pktgen_type : 2; - test_recirc : 1; - pfe_override_test : 1; - } -} -metadata ig_md_t ig_md; - -action set_md(eg_port, skip, pktgen_port, test_recirc, mgid1, mgid2, pfe) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, eg_port); - modify_field(ig_md.skip_lkups, skip); - modify_field(ig_md.pktgen_port, pktgen_port); - modify_field(ig_md.test_recirc, test_recirc); - modify_field(ig_intr_md_for_tm.mcast_grp_a, mgid1); - modify_field(ig_intr_md_for_tm.mcast_grp_b, mgid2); - modify_field(ig_md.pfe_override_test, pfe); -} - -table port_tbl { - reads { - ig_intr_md.ingress_port : exact; - } - actions { - set_md; - } - size : 288; -} - - -action timer_ok() { -#ifndef __TARGET_TOFINO__ - modify_field(eg_intr_md.enq_congest_stat, 1024); - -#endif -} -action timer_nok() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 6); -} -table pg_verify_timer { - reads { - ig_intr_md.ingress_port : exact; - } - actions { - timer_ok; - timer_nok; - } -} - -action port_down_ok() { -} -action port_down_nok() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 6); -} -table pg_verify_port_down { - reads { - ig_intr_md.ingress_port : exact; - } - actions { - port_down_ok; - port_down_nok; - } -} - -action recirc_ok() { -} -action recirc_nok() { - modify_field(ig_intr_md_for_tm.ucast_egress_port, 6); -} -table pg_verify_recirc { - reads { - ig_intr_md.ingress_port : exact; - } - actions { - recirc_ok; - recirc_nok; - } -} - -action local_recirc(local_port) { -#ifdef __TARGET_TOFINO__ - recirculate( local_port ); -#endif -} -table do_local_recirc { - actions { local_recirc; } -} - -table eg_tcam_or_exm { - reads { ig_intr_md.ingress_port : exact; } - actions { - do_tcam; - do_exm; - } - size : 2; -} -action do_tcam() {} -action do_exm() {} -header_type pfe_md_t { - fields { - a:16; - } -} -metadata pfe_md_t pfe_md; -counter c1 { - type : packets; - instance_count : 500; -} -counter c2 { - type : packets; - instance_count : 500; -} -register r1 { - width : 32; - instance_count : 500; -} -register r2 { - width : 32; - instance_count : 500; -} -blackbox stateful_alu alu1 { - reg: r1; - update_lo_1_value: register_lo + 1; -} -blackbox stateful_alu alu2 { - reg: r2; - update_lo_1_value: register_lo + 1; -} -action a1() { -} -action a2(cntr_index) { - count(c1, cntr_index); -} -action a3() { - count(c2, ig_intr_md.ingress_port); -} -action a4() { - count(c1, 12); -} -action a5(stful_index) { - alu1.execute_stateful_alu(stful_index); -} -action a6() { - alu2.execute_stateful_alu(ig_intr_md.ingress_port); -} -action a7() { - alu1.execute_stateful_alu(12); -} - -table t1 { - reads { ig_intr_md.ingress_port : ternary; } - actions { a1; a2; a4; } - size : 5; -} -table t2 { - reads { ig_intr_md.ingress_port : ternary; } - actions { a1; a3; } - size : 5; -} -table t4 { - reads { ig_intr_md.ingress_port : ternary; } - actions { a1; a5; a7; } - size : 5; -} -table t5 { - reads { ig_intr_md.ingress_port : ternary; } - actions { a1; a6; } - size : 5; -} -table e1 { - reads { ig_intr_md.ingress_port : exact; } - actions { a1; a2; a4; } - size : 5; -} -table e2 { - reads { ig_intr_md.ingress_port : exact; } - actions { a1; a3; } - size : 5; -} -table e4 { - reads { ig_intr_md.ingress_port : exact; } - actions { a1; a5; a7; } - size : 5; -} -table e5 { - reads { ig_intr_md.ingress_port : exact; } - actions { a1; a6; } - size : 5; -} -control ingress { - //if (0 == ig_intr_md.resubmit_flag) { - apply(port_tbl); - //} - if (ig_md.skip_lkups == 0) { - if (ig_md.pktgen_port == 1) { - if (ig_md.pktgen_type == 0) { - apply( pg_verify_timer ); - } - if (ig_md.pktgen_type == 2) { - apply( pg_verify_port_down ); - } - if (ig_md.pktgen_type == 3) { - apply( pg_verify_recirc ); - } - } - if (ig_md.pfe_override_test == 1) { - apply(eg_tcam_or_exm) { - do_tcam { - apply(t1); - apply(t2); - apply(t4); - apply(t5); - } - do_exm { - apply(e1); - apply(e2); - apply(e4); - apply(e5); - } - } - } - } else { - if (ig_md.test_recirc == 1) { - apply( do_local_recirc ); - } - } -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/ptf/pktgen_headers.p4 b/backends/tofino/bf-asm/test/ptf/pktgen_headers.p4 deleted file mode 100644 index f03a97fc66d..00000000000 --- a/backends/tofino/bf-asm/test/ptf/pktgen_headers.p4 +++ /dev/null @@ -1,57 +0,0 @@ - -/******************************************************************************** - * Packet Generator Header Definition for Tofino * - *******************************************************************************/ - -#ifndef _TOFINO_LIB_PKTGEN_HEADERS -#define _TOFINO_LIB_PKTGEN_HEADERS 1 - -header_type pktgen_generic_header_t { - fields { - _pad0 : 3; - app_id : 3; - pipe_id : 2; - key_msb : 8; // Only valid for recirc triggers. - batch_id : 16; // Overloaded to port# or lsbs of key for port down and - // recirc triggers. - packet_id : 16; - } -} -header pktgen_generic_header_t pktgen_generic; - -header_type pktgen_timer_header_t { - fields { - _pad0 : 3; - app_id : 3; - pipe_id : 2; - _pad1 : 8; - batch_id : 16; - packet_id : 16; - } -} -header pktgen_timer_header_t pktgen_timer; - -header_type pktgen_port_down_header_t { - fields { - _pad0 : 3; - app_id : 3; - pipe_id : 2; - _pad1 : 15; - port_num : 9; - packet_id : 16; - } -} -header pktgen_port_down_header_t pktgen_port_down; - -header_type pktgen_recirc_header_t { - fields { - _pad0 : 3; - app_id : 3; - pipe_id : 2; - key : 24; - packet_id : 16; - } -} -header pktgen_recirc_header_t pktgen_recirc; - -#endif diff --git a/backends/tofino/bf-asm/test/ptf/pvs.p4 b/backends/tofino/bf-asm/test/ptf/pvs.p4 deleted file mode 100644 index 31d88b55888..00000000000 --- a/backends/tofino/bf-asm/test/ptf/pvs.p4 +++ /dev/null @@ -1,160 +0,0 @@ -#include -#include -#include - -#define VLAN_DEPTH 2 -#define ETHERTYPE_VLAN 0x8100 -#define ETHERTYPE_IPV4 0x0800 - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pcp : 3; - cfi : 1; - vid : 12; - etherType : 16; - } -} - -header_type new_tag_24t { - fields { - t24_f1_6b : 6; - t24_f2_12b : 12; - t24_f3_14b : 14; - } -} - -header_type new_tag_32t { - fields { - t32_f1_16b : 16; - t32_f2_16b : 16; - } -} - -header_type new_tag_48t { - fields { - t48_f1_16b : 16; - t48_f2_32b : 32; - } -} - -header_type new_tag_64t { - fields { - t64_f1_48b : 48; - t64_f2_16b : 16; - } -} - -header ethernet_t ethernet; -header vlan_tag_t vlan_tag_; -header new_tag_24t new_tag24_; -header new_tag_32t new_tag32_; -header new_tag_48t new_tag48_; -header new_tag_64t new_tag64_; -header new_tag_64t new_tag64_2_; - -parser start { - return parse_ethernet; -} - -@pragma parser_value_set_size 5 -parser_value_set pvs1; -@pragma parser_value_set_size 7 -parser_value_set pvs2; -@pragma parser_value_set_size 9 -parser_value_set pvs3; -@pragma parser_value_set_size 2 -parser_value_set pvs4; -@pragma parser_value_set_size 5 -parser_value_set pvs5; - - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - pvs2 : parse_vlan; - default : ingress; - } -} - -parser parse_vlan { - extract(vlan_tag_); - return ingress; -} - - -// Example of using PVS along with constant select value -parser parse_hdr_pvs1 { - extract(new_tag24_); - return select(latest.t24_f1_6b, latest.t24_f3_14b) { - pvs3 : parse_hdr_pvs3; - 199: parse_hdr_pvs4; - default: ingress; - } -} - -parser parse_hdr_pvs2 { - extract(new_tag32_); - return ingress; -} - -parser parse_hdr_pvs3 { - extract(new_tag48_); - return select(latest.t48_f2_32b) { - pvs4: parse_hdr_pvs4; - default: ingress; - } -} - -parser parse_hdr_pvs4 { - extract(new_tag64_); - // Expected to get compile error when branch condition value is > 32bits - //return select(latest.t64_f1_48b) { - // 6700: parse_hdr_pvs5; - // default: ingress; - //} - return ingress; -} - -parser parse_hdr_pvs5 { - extract(new_tag64_2_); - return ingress; -} - - -action vlan_miss(egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -action vlan_hit(egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -table vlan { - reads { - vlan_tag_.vid: exact; - } - actions { - vlan_miss; - vlan_hit; - } - size : 512; -} - - -action noop() { - no_op(); -} - - -control ingress { - apply(vlan); -} - diff --git a/backends/tofino/bf-asm/test/ptf/range.p4 b/backends/tofino/bf-asm/test/ptf/range.p4 deleted file mode 100644 index 84d66721b2c..00000000000 --- a/backends/tofino/bf-asm/test/ptf/range.p4 +++ /dev/null @@ -1,185 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/constants.p4" - -/* Headers */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type ipv6_t { - fields { - version : 4; - trafficClass : 8; - flowLabel : 20; - payloadLen : 16; - nextHdr : 8; - hopLimit : 8; - srcAddr : 128; - dstAddr : 128; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - 0x86dd : parse_ipv6; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; -header ipv6_t ipv6; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -parser parse_ipv6 { - extract(ipv6); - return select(latest.nextHdr) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default : ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -header_type bit9_t { - fields { - gauche : 1; - tartly : 9; - } -} -metadata bit9_t bit9; - -/* Actions */ -action nop() { -} - -action set_val(val) { - modify_field(bit9.tartly, val); -} - -table range_set { - reads { - ipv4.srcAddr : exact; - } - actions { - set_val; - } -} - -action set_egress(port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} -/* Tables */ -table bit9_match { - reads { - bit9.gauche : ternary; - bit9.tartly : range; - } - actions { - set_egress; - } - size : 1024; -} - -/* Controls */ -control ingress { - apply(range_set); - apply(bit9_match); -} diff --git a/backends/tofino/bf-asm/test/ptf/resubmit.p4 b/backends/tofino/bf-asm/test/ptf/resubmit.p4 deleted file mode 100644 index c78ad7e8a23..00000000000 --- a/backends/tofino/bf-asm/test/ptf/resubmit.p4 +++ /dev/null @@ -1,129 +0,0 @@ - -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* - * This sample program hightlights the use of resubmit on Tofino - * Not tested on BM (v1 or v2). - */ - -#ifdef __TARGET_TOFINO__ -#include -#endif - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header ethernet_t ethernet; - -parser start { - extract(ethernet); - return ingress; -} - - -header_type test_metadata_t { - fields { - field_A: 8; - field_B: 8; - field_C: 16; - } -} - -metadata test_metadata_t test_metadata; - -field_list resubmit_fields { - test_metadata.field_A; - test_metadata.field_C; -} - -action nop() { - -} - -/* - * Processing regular packet - */ - -action do_resubmit_with_fields() { - modify_field(test_metadata.field_C, 0x1234); - resubmit(resubmit_fields); -} - -action do_resubmit() { -#if defined(BMV2TOFINO) - resubmit_no_fields(); -#else - resubmit(); -#endif -} - - -table l2_resubmit { - reads { - ethernet.dstAddr: exact; - } - actions { - nop; - do_resubmit; - do_resubmit_with_fields; - } - size : 512; -} - -/* - * Processing resubmitted packet - */ - -action nhop_set(port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action nhop_set_with_type(port) { - modify_field(ethernet.etherType, test_metadata.field_C); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -table l2_nhop { - reads { - ethernet.dstAddr: exact; - } - actions { - nop; - nhop_set; - nhop_set_with_type; - } - size : 512; -} - -/* Main control flow */ -control ingress { - if (0 == ig_intr_md.resubmit_flag) { - apply(l2_resubmit); - } else { - apply(l2_nhop); - } -} - -control egress { - -} - diff --git a/backends/tofino/bf-asm/test/ptf/smoke_large_tbls.p4 b/backends/tofino/bf-asm/test/ptf/smoke_large_tbls.p4 deleted file mode 100644 index 84c26ea6eb3..00000000000 --- a/backends/tofino/bf-asm/test/ptf/smoke_large_tbls.p4 +++ /dev/null @@ -1,253 +0,0 @@ -#include -#include -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -field_list ipv4_field_list { - ipv4.version; - ipv4.ihl; - ipv4.diffserv; - ipv4.totalLen; - ipv4.identification; - ipv4.flags; - ipv4.fragOffset; - ipv4.ttl; - ipv4.protocol; - ipv4.srcAddr; - ipv4.dstAddr; -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -field_list_calculation ipv4_chksum_calc { - input { - ipv4_field_list; - } - algorithm : csum16; - output_width: 16; -} - -calculated_field ipv4.hdrChecksum { - update ipv4_chksum_calc; -} - -counter dummy_cntr { - type : packets; - direct : idle_stats_tbl; -} - -action drop_count (count_idx) { - //count(dummy_cntr, count_idx); - drop(); -} - -action nop() { -} - -action set_egress (egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); -} - -@pragma command_line --no-dead-code-elimination -table idle_stats_tbl { - reads { - ethernet.dstAddr : ternary; - ethernet.srcAddr : ternary; - ethernet.etherType : ternary; - vlan_tag.pri : ternary; - vlan_tag.cfi : ternary; - vlan_tag.vlan_id : ternary; - vlan_tag.etherType : ternary; - ipv4.version : ternary; - ipv4.ihl : ternary; - ipv4.diffserv : ternary; - ipv4.totalLen : ternary; - ipv4.identification : ternary; - ipv4.flags : ternary; - ipv4.fragOffset : ternary; - ipv4.ttl : ternary; - ipv4.protocol : ternary; - ipv4.hdrChecksum : ternary; - ipv4.dstAddr : lpm; - ipv4.srcAddr : ternary; - tcp.srcPort : ternary; - tcp.dstPort : ternary; - tcp.seqNo : ternary; - tcp.ackNo : ternary; - tcp.dataOffset : ternary; - tcp.res : ternary; - tcp.ecn : ternary; - tcp.ctrl : ternary; - tcp.window : ternary; - tcp.checksum : ternary; - tcp.urgentPtr : ternary; - udp.srcPort : ternary; - udp.dstPort : ternary; - udp.hdr_length : ternary; - } - actions { - set_egress; - nop; - } - size : 2048; - support_timeout: true; -} - -@pragma pack 2 -@pragma ways 4 -@pragma atcam_partition_index vlan_tag.vlan_id -//@pragma atcam_number_partitions 1024 -table atcam_tbl { - reads { - tcp.valid : ternary; - vlan_tag.vlan_id : exact; - ipv4.dstAddr : ternary; - } - actions { - set_egress; - nop; - } - size: 500000; -} - -action set_ip_id (ip_id, egress_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_port); - modify_field(ipv4.identification, ip_id); -} - -action_profile atcam_action_profile { - actions { - set_ip_id; - nop; - } - size : 65536; -} - -@pragma atcam_partition_index vlan_tag.vlan_id -//@pragma atcam_number_partitions 1024 -table atcam_indirect_tbl { - reads { - vlan_tag.vlan_id : exact; - ipv4.srcAddr : ternary; - } - action_profile : atcam_action_profile; - size: 100000; -} - -control ingress { - apply(idle_stats_tbl); - apply(atcam_tbl); - apply(atcam_indirect_tbl); -} - -control egress { -} - diff --git a/backends/tofino/bf-asm/test/ptf/stats_pi.p4 b/backends/tofino/bf-asm/test/ptf/stats_pi.p4 deleted file mode 100644 index 51e60a2f816..00000000000 --- a/backends/tofino/bf-asm/test/ptf/stats_pi.p4 +++ /dev/null @@ -1,171 +0,0 @@ -/* Copyright 2013-present Barefoot Networks, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type meta_t { - fields { - f8 : 8; - f16 : 16; - f20 : 20; - f24 : 24; - f32 : 32; - f48 : 48; - f64 : 64; - } -} - -metadata meta_t meta; -header ethernet_t ethernet; - -parser start { - return parse_ethernet; -} - -parser parse_ethernet { - extract(ethernet); - return ingress; -} - -action no_op() { } - -action actionA(param, port) { - modify_field(meta.f32, param); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action actionB(port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -table ExactOne { - reads { - ethernet.dstAddr : exact; - } - actions { - actionA; actionB; no_op; - } - size: 512; -} - -counter ExactOne_counter { - type : packets; - direct : ExactOne; -} - -meter ExactOne_meter { - type : bytes; - direct : ExactOne; - result : meta.f8; -} - -meter MeterA { - type : packets; - instance_count : 1024; -} - -action _MeterAAction() { - execute_meter(MeterA, 16, meta.f8); -} - -table _MeterATable { - reads { - ethernet.dstAddr : exact; - } - actions { - _MeterAAction; - } - size: 512; -} - -counter CounterA { - type : packets; - instance_count : 1024; -} - -action _CounterAAction1(idx) { - count(CounterA, idx); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 3); -} - -action _CounterAAction2() { - count(CounterA, 37); - modify_field(ig_intr_md_for_tm.ucast_egress_port, 3); -} - -table _CounterATable { - reads { - ethernet.dstAddr : exact; - } - actions { - _CounterAAction1; _CounterAAction2; - } - size: 512; -} - -// an indirect table to test indirect resource management - -field_list hash_fields { ethernet.srcAddr; } -field_list_calculation hash { - input { hash_fields; } - algorithm : crc16; - output_width : 16; -} - -table IndirectTable { - reads { ethernet.dstAddr : exact; } - action_profile : ActionProf; - size : 1024; -} - -counter CounterB { - type : packets; - instance_count : 64; -} - -action indirectAction(idx, port) { - count(CounterB, idx); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -action_profile ActionProf { - actions { indirectAction; } - size : 128; - dynamic_action_selection : Selector; -} - -action_selector Selector { - selection_key : hash; -} - -control ingress { - apply(ExactOne); - apply(_MeterATable); - apply(_CounterATable); - apply(IndirectTable); -} - -control egress { - -} diff --git a/backends/tofino/bf-asm/test/ptf/stful.p4 b/backends/tofino/bf-asm/test/ptf/stful.p4 deleted file mode 100644 index b29954ac924..00000000000 --- a/backends/tofino/bf-asm/test/ptf/stful.p4 +++ /dev/null @@ -1,932 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" -#include "tofino/stateful_alu_blackbox.p4" -#include "tofino/pktgen_headers.p4" - - -/* - * TCAM EXM No Tbl - * Direct Addressed egr_port ifid XXX - * Indirect Addressed next_hop sip_sampler - * Hash Addressed flowlet bloom filter - * Logging Addressed - */ -header_type ethernet_t { - fields { - dmac : 48; - smac : 48; - ethertype : 16; - } -} -header ethernet_t ethernet; - -header_type ipv4_t { - fields { - ver : 4; - len : 4; - diffserv : 8; - totalLen : 16; - id : 16; - flags : 3; - offset : 13; - ttl : 8; - proto : 8; - csum : 16; - sip : 32; - dip : 32; - } -} -header ipv4_t ipv4; - -header_type tcp_t { - fields { - sPort : 16; - dPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} -header tcp_t tcp; - -header_type udp_t { - fields { - sPort : 16; - dPort : 16; - hdr_length : 16; - checksum : 16; - } -} -header udp_t udp; - -header_type user_metadata_t { - fields { - ifid : 16; - egr_ifid : 16; - timestamp : 48; - offset : 32 (signed); - bf_tmp_1 : 1; - bf_tmp_2 : 1; - bf_tmp_3 : 1; - flowlet_hash_input : 8; - nh_id : 16; - flowlet_temp : 15; - flowlet_ts : 32; - lag_tbl_bit_index : 17; - ecmp_tbl_bit_index: 17; - pkt_gen_pkt : 1; - recirc_pkt : 1; - one_bit_val_1 : 1; - one_bit_val_2 : 1; - } -} -@pragma pa_solitary ingress md.flowlet_temp -metadata user_metadata_t md; - -header_type recirc_header_t { - fields { - tag : 4; // Must be 0xF - rtype : 4; // 0: TDB, 1: pktgen port down, 2:pktgen recirc, 3:TDB, ... - pad : 8; - key : 16; - } -} -header recirc_header_t recirc_hdr; - -parser start { - return select( current(0,8) ) { - 0x01 mask 0xE7: parse_pkt_gen_port_down; // Pipe x, App 1 - 0x02 mask 0xE7: parse_pkt_gen_recirc; // Pipe x, App 2 - 0x03 mask 0xE7: parse_pkt_gen_hw_clr; // Pipex, App 3 - 0xF0 mask 0xF0: parse_recirc_pkt; - default: parse_ethernet; - } -} - -#define RECIRC_TYPE_PG_PORT_DOWN 1 -#define RECIRC_TYPE_PG_RECIRC 2 - -parser parse_recirc_pkt { - extract(recirc_hdr); - set_metadata(md.recirc_pkt, 1); - return select(latest.rtype) { - RECIRC_TYPE_PG_PORT_DOWN : parse_pkt_gen_port_down; - RECIRC_TYPE_PG_RECIRC : parse_recirc_trigger_pkt; - default: ingress; - } -} -parser parse_ethernet { - extract(ethernet); - return select(latest.ethertype) { - 0x0800 : parse_ipv4; - } -} -parser parse_ipv4 { - extract(ipv4); - return select(latest.proto) { - 6 : parse_tcp; - 17: parse_udp; - } -} -parser parse_tcp { - extract(tcp); - return ingress; -} -parser parse_udp { - extract(udp); - return ingress; -} - -parser parse_pkt_gen_port_down { - extract(pktgen_port_down); - set_metadata(md.pkt_gen_pkt, 1); - return ingress; -} - -parser parse_pkt_gen_recirc { - extract(pktgen_recirc); - set_metadata(md.pkt_gen_pkt, 1); - return ingress; -} - -parser parse_pkt_gen_hw_clr { - extract(pktgen_generic); - set_metadata(md.pkt_gen_pkt, 1); - return ingress; -} - -parser parse_recirc_trigger_pkt { - return parse_ethernet; -} - - - - -/****************************************************************************** - * - * Ingress Port Table - * - *****************************************************************************/ -action set_ifid(ifid) { - modify_field(md.ifid, ifid); -} - -@pragma --metadata-overlay False -table ing_port { - reads { ig_intr_md.ingress_port : exact; } - actions { set_ifid; } - size : 288; -} - -/****************************************************************************** - * - * Test one bit reads - * - *****************************************************************************/ -register ob1 { - width : 1; - instance_count: 1000; -} -register ob2 { - width : 1; - instance_count: 1000; -} -blackbox stateful_alu one_bit_alu_1 { - reg: ob1; - output_value: register_lo; - output_dst: md.one_bit_val_1; -} -blackbox stateful_alu one_bit_alu_2 { - reg: ob2; - update_lo_1_value: read_bit; - output_value: alu_lo; - output_dst: md.one_bit_val_2; -} -table one_bit_read_1 { - actions { run_one_bit_read_1; } - default_action: run_one_bit_read_1; - size : 1; -} -table one_bit_read_2 { - actions { run_one_bit_read_2; } - default_action: run_one_bit_read_2; - size : 1; -} -action run_one_bit_read_1() { one_bit_alu_1.execute_stateful_alu(1); } -action run_one_bit_read_2() { one_bit_alu_2.execute_stateful_alu(2); } -table undrop { - actions {do_undrop;} - default_action: do_undrop; - size: 1; -} -action do_undrop() { - modify_field(ig_intr_md_for_tm.drop_ctl, 0); - modify_field(ig_intr_md_for_tm.ucast_egress_port, ig_intr_md.ingress_port); -} - -/****************************************************************************** - * - * IFID Table - * - Runs a stateful table to increment a signed saturating counter - * - *****************************************************************************/ -register ifid_cntr { - width: 16; - direct: ifid; - attributes: signed, saturating; -} -blackbox stateful_alu ifid_cntr_alu { - reg: ifid_cntr; - update_lo_1_value: register_lo + ipv4.ttl; -} -action set_ifid_based_params(ts, offset) { - run_ifid_cntr(); - modify_field(md.timestamp, ts); - modify_field(md.offset, offset); -} -action drop_it() { - run_ifid_cntr(); - mark_for_drop(); -} -action run_ifid_cntr() { - ifid_cntr_alu.execute_stateful_alu(); -} -table ifid { - reads { md.ifid : exact; } - actions { - set_ifid_based_params; - drop_it; - } - size : 25000; -} - -/****************************************************************************** - * - * Bloom Filter Table - * - Will set the C2C flag for packets not part of the filter - * - Will add the packet to the filter - * - *****************************************************************************/ - -/* Field list describing which fields contribute to the bloom filter hash. */ -field_list bf_hash_fields { - ipv4.proto; - ipv4.sip; - ipv4.dip; - tcp.sPort; - tcp.dPort; -} - -/* Three hash functions for the filter, just using random hash functions right - * now. */ -field_list_calculation bf_hash_1 { - input { bf_hash_fields; } -#ifdef BMV2TOFINO - algorithm: crc32; -#else - algorithm: random; -#endif - output_width: 18; -} -field_list_calculation bf_hash_2 { - input { bf_hash_fields; } -#ifdef BMV2TOFINO - algorithm: crc16; -#else - algorithm: random; -#endif - output_width: 18; -} -field_list_calculation bf_hash_3 { - input { bf_hash_fields; } -#ifdef BMV2TOFINO - algorithm: csum16; -#else - algorithm: random; -#endif - output_width: 18; -} - -field_list bf_clr_hash_fields { - pktgen_generic.batch_id; - pktgen_generic.packet_id; -} -field_list_calculation bf_clr_hash { - input { bf_clr_hash_fields; } - algorithm: identity; - output_width: 18; -} - -/* Three registers implementing the bloom filter. Each register takes 3 RAMs; - * each RAM has 128k entries so two RAMs to make 256k plus a third RAM as the - * spare, so 9 RAMs total. */ -register bloom_filter_1 { - width : 1; - instance_count : 262144; -} -register bloom_filter_2 { - width : 1; - instance_count : 262144; -} -register bloom_filter_3 { - width : 1; - instance_count : 262144; -} - -/* Three stateful ALU blackboxes running the bloom filter. - * Note there is no reduction-OR support yet so each ALU outputs to a separate - * metadata temp variable. - * Output is 1 if the packet is not in the filter and 0 if it is in. */ -blackbox stateful_alu bloom_filter_alu_1 { - reg: bloom_filter_1; - update_lo_1_value: set_bitc; - output_value: alu_lo; - output_dst: md.bf_tmp_1; -} -blackbox stateful_alu bloom_filter_alu_2 { - reg: bloom_filter_2; - update_lo_1_value: set_bitc; - output_value: alu_lo; - output_dst: md.bf_tmp_2; -} -blackbox stateful_alu bloom_filter_alu_3 { - reg: bloom_filter_3; - update_lo_1_value: set_bitc; - output_value: alu_lo; - output_dst: md.bf_tmp_3; -} -blackbox stateful_alu clr_bloom_filter_alu_1 { - reg: bloom_filter_1; - update_lo_1_value: clr_bit; -} -blackbox stateful_alu clr_bloom_filter_alu_2 { - reg: bloom_filter_2; - update_lo_1_value: clr_bit; -} -blackbox stateful_alu clr_bloom_filter_alu_3 { - reg: bloom_filter_3; - update_lo_1_value: clr_bit; -} - -/* Note that we need additional actions here to OR the bloom filter results - * into a single result. */ -action check_bloom_filter_1() { - bloom_filter_alu_1.execute_stateful_alu_from_hash(bf_hash_1); -} -action check_bloom_filter_2() { - bloom_filter_alu_2.execute_stateful_alu_from_hash(bf_hash_2); -} -action check_bloom_filter_3() { - bloom_filter_alu_3.execute_stateful_alu_from_hash(bf_hash_3); -} -action bloom_filter_mark_sample() { - modify_field(ig_intr_md_for_tm.copy_to_cpu, 1); -} -action clear_bloom_filter_1() { - clr_bloom_filter_alu_1.execute_stateful_alu_from_hash(bf_clr_hash); -} -action clear_bloom_filter_2() { - clr_bloom_filter_alu_2.execute_stateful_alu_from_hash(bf_clr_hash); -} -action clear_bloom_filter_3() { - clr_bloom_filter_alu_3.execute_stateful_alu_from_hash(bf_clr_hash); -} - -@pragma stage 0 -table bloom_filter_1 { - actions { check_bloom_filter_1; } - size : 1; -} -@pragma stage 1 -table bloom_filter_2 { - actions { check_bloom_filter_2; } - size : 1; -} -@pragma stage 1 -table bloom_filter_3 { - actions { check_bloom_filter_3; } - size : 1; -} -@pragma stage 0 -table clr_bloom_filter_1 { - actions { clear_bloom_filter_1; } - size : 1; -} -@pragma stage 1 -table clr_bloom_filter_2 { - actions { clear_bloom_filter_2; } - size : 1; -} -@pragma stage 1 -table clr_bloom_filter_3 { - actions { clear_bloom_filter_3; } - size : 1; -} -action drop_clearing_packet() { drop(); } -table drop_bloom_filter_clear { - actions { drop_clearing_packet; } - size : 1; -} - -/* Extra tables to run an action to mark a packet for sampling. - * This will be removed once the compiler supports the reduction-OR - * operation. */ -table bloom_filter_sample { - actions { bloom_filter_mark_sample; } - size : 1; -} - - -/****************************************************************************** - * - * Sampling Table - * - Sample, with C2C, every Nth packet from a particular IPv4 source. - * - Note that multiple IPv4 sources can share the same stateful entry to - * - sample the Nth packet from a group of sources. - * - *****************************************************************************/ -register sampling_cntr { - width : 32; - static: sip_sampler; - instance_count : 143360; // Fills 35 + 1 spare RAMs (max size) -} - -/* Note the extra complexity of this ALU program is required so that if C2C was - * already set (by the bloom filter) it will stay set even if this ALU says not - * to sample. */ -blackbox stateful_alu sampling_alu { - reg: sampling_cntr; - initial_register_lo_value: 1; - condition_lo: register_lo >= 10; - condition_hi: ig_intr_md_for_tm.copy_to_cpu != 0; - update_lo_1_predicate: condition_lo; - update_lo_1_value: 1; - update_lo_2_predicate: not condition_lo; - update_lo_2_value: register_lo + 1; - update_hi_1_value: 1; - output_predicate: condition_lo or condition_hi; - output_value : alu_hi; - output_dst : ig_intr_md_for_tm.copy_to_cpu; -} -action sample(index) { - sampling_alu.execute_stateful_alu(index); -} -action no_sample() {} -table sip_sampler { - reads { ipv4.sip : exact; } - actions { - sample; - no_sample; - } - size : 85000; -} - - -/****************************************************************************** - * - * Flowlet Table - * - Generate an extra 8 bit field to influence action profile selection. - * - Ideally the timestamp should come from the "global timestamp" intrinsic - * metadata however that is difficult to control from a test script, instead - * a dummy timestamp will be used. - * - *****************************************************************************/ -/* Field list describing which fields contribute to the flowlet hash. */ -field_list flowlet_hash_fields { - ipv4.proto; - ipv4.sip; - ipv4.dip; - tcp.sPort; - tcp.dPort; -} -field_list_calculation flowlet_hash { - input { flowlet_hash_fields; } - algorithm: crc16; - output_width: 15; -} - -register flowlet_state { - width : 64; - instance_count : 32768; -} - -/* Flowlet lifetime is 50 microseconds. Use 0xFFFF as un-initialized value - * to signal no next hop has been stored yet. */ -blackbox stateful_alu flowlet_alu { - reg: flowlet_state; - condition_hi: register_hi != 65535; - condition_lo: md.flowlet_ts - register_lo > 50000; - update_hi_1_predicate: condition_hi or condition_lo; - update_hi_1_value: md.nh_id; - update_lo_2_value: md.flowlet_ts; - output_value: alu_hi; - output_dst: md.nh_id; - initial_register_hi_value: 65535; - initial_register_lo_value: 60000; -} - -action set_flowlet_hash_and_ts() { - modify_field_with_hash_based_offset(md.flowlet_temp, 0, flowlet_hash, 32768); - modify_field(md.flowlet_ts, md.timestamp); -} -table flowlet_prepare { - actions { set_flowlet_hash_and_ts; } - size : 1; -} -action run_flowlet_alu() { - flowlet_alu.execute_stateful_alu(md.flowlet_temp); -} -table flowlet_next_hop { - actions { run_flowlet_alu; } - size : 1; -} - - -/****************************************************************************** - * - * IPv4 Route Table - * - *****************************************************************************/ -action set_next_hop(nh) { - modify_field(md.nh_id, nh); -} -action set_ecmp(ecmp_id) { - modify_field(md.nh_id, ecmp_id); -} -table ipv4_route { - reads { ipv4.dip : lpm; } - actions { - set_next_hop; - set_ecmp; - } - size : 512; -} - -/****************************************************************************** - * - * Next Hop ECMP Table - * - *****************************************************************************/ -field_list next_hop_ecmp_hash_fields { - ipv4.proto; - ipv4.sip; - ipv4.dip; - tcp.sPort; - tcp.dPort; - md.flowlet_hash_input; -} -field_list_calculation next_hop_ecmp_hash { - input { next_hop_ecmp_hash_fields; } - algorithm : crc32; - output_width : 29; -} -register next_hop_ecmp_reg { - width : 1; - instance_count : 131072; -} -blackbox stateful_alu next_hop_ecmp_alu { - reg: next_hop_ecmp_reg; - selector_binding: next_hop_ecmp; - update_lo_1_value: clr_bit; -} -action_selector next_hop_ecmp_selector { - selection_key: next_hop_ecmp_hash; - selection_mode: fair; -} -action_profile next_hop_ecmp_ap { - actions { set_next_hop; } - size : 4096; - dynamic_action_selection : next_hop_ecmp_selector; -} -@pragma stage 6 -@pragma selector_max_group_size 200 -table next_hop_ecmp { - reads { md.nh_id : exact; } - action_profile : next_hop_ecmp_ap; - size : 4096; -} -field_list ecmp_index_identity_hash_fields { - md.ecmp_tbl_bit_index; -} -field_list_calculation ecmp_index_identity_hash { - input { ecmp_index_identity_hash_fields; } - algorithm: identity; - output_width: 17; -} -action set_mbr_down() { - next_hop_ecmp_alu.execute_stateful_alu_from_hash(ecmp_index_identity_hash); - drop(); -} -@pragma stage 6 -table next_hop_ecmp_fast_update { - actions { - set_mbr_down; - } - size : 1; -} - -@pragma stage 5 -table make_key_ecmp_fast_update { - reads { - pktgen_recirc.key mask 0xFFFF : exact; - pktgen_recirc.packet_id : exact; - } - actions { - set_ecmp_fast_update_key; - drop_ecmp_update_pkt; - } - default_action: drop_ecmp_update_pkt; - size : 16384; -} -action set_ecmp_fast_update_key(key) { - modify_field(md.ecmp_tbl_bit_index, key); -} -action drop_ecmp_update_pkt() { - drop(); -} - -/****************************************************************************** - * - * Next Hop Table - * - Uses a register to do useless operations to test multiple instructions - * on a stateful ALU. - * - *****************************************************************************/ -register scratch { - width: 16; - static: next_hop; - instance_count: 4096; -} -blackbox stateful_alu scratch_alu_add { - reg: scratch; - update_lo_1_value: register_lo + md.nh_id; -} -blackbox stateful_alu scratch_alu_sub { - reg: scratch; - update_lo_1_value: md.nh_id - register_lo; -} -blackbox stateful_alu scratch_alu_zero { - reg: scratch; - update_lo_1_value: 0; -} -blackbox stateful_alu scratch_alu_invert { - reg: scratch; - update_lo_1_value: ~register_lo; -} - -action set_egr_ifid(ifid) { - modify_field(md.egr_ifid, ifid); -} -action scratch_add(index, ifid) { - set_egr_ifid(ifid); - scratch_alu_add.execute_stateful_alu(index); -} -action scratch_sub(index, ifid) { - set_egr_ifid(ifid); - scratch_alu_sub.execute_stateful_alu(index); -} -action scratch_zero(index, ifid) { - set_egr_ifid(ifid); - scratch_alu_zero.execute_stateful_alu(index); -} -action scratch_invert(index, ifid) { - set_egr_ifid(ifid); - scratch_alu_invert.execute_stateful_alu(index); -} -action next_hop_down(mgid) { - add_header(recirc_hdr); - modify_field(recirc_hdr.tag, 0xF); - modify_field(recirc_hdr.rtype, RECIRC_TYPE_PG_RECIRC); - modify_field(recirc_hdr.pad, 0); - modify_field(recirc_hdr.key, md.nh_id); - modify_field(ig_intr_md_for_tm.mcast_grp_b, mgid); -} -table next_hop { - reads { md.nh_id : ternary; } - actions { - set_egr_ifid; - scratch_add; - scratch_sub; - scratch_zero; - scratch_invert; - next_hop_down; - } - size: 4096; -} - - -/****************************************************************************** - * - * Egress Ifid Table - * - *****************************************************************************/ -register lag_reg { - width : 1; - instance_count : 131072; -} -blackbox stateful_alu lag_alu { - reg: lag_reg; - selector_binding: egr_ifid; - update_lo_1_value: clr_bit; -} -@pragma seletor_num_max_groups 128 -@pragma selector_max_group_size 1200 -table egr_ifid { - reads {md.egr_ifid : exact;} - action_profile : lag_ap; - size : 16384; -} -action_profile lag_ap { - actions { set_egr_port; } - size : 4096; - dynamic_action_selection : lag_as; -} -action_selector lag_as { - selection_key: lag_hash; - selection_mode: resilient; -} -field_list_calculation lag_hash { - input { lag_fields; } -#ifdef BMV2TOFINO - algorithm: xxh64; -#else - algorithm: random; -#endif - output_width: 66; -} -field_list lag_fields { - ipv4.proto; - ipv4.sip; - ipv4.dip; - tcp.sPort; - tcp.dPort; - ig_intr_md.ingress_port; -} -action set_egr_port(port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -@pragma stage 7 -table egr_ifid_fast_update_make_key { - reads { - pktgen_port_down.port_num : exact; - pktgen_port_down.packet_id : exact; - } - actions { - set_lag_fast_update_key; - drop_ifid_update_pkt; - } - default_action: drop_ifid_update_pkt; - size : 16384; -} -action set_lag_fast_update_key(key) { - modify_field(md.lag_tbl_bit_index, key); -} -@pragma stage 8 -table egr_ifid_fast_update { - actions { - set_lag_mbr_down; - } - size : 1; -} -field_list lag_index_identity_hash_fields { - md.lag_tbl_bit_index; -} -field_list_calculation lag_index_identity_hash { - input { lag_index_identity_hash_fields; } - algorithm: identity; - output_width: 17; -} -action set_lag_mbr_down() { - lag_alu.execute_stateful_alu_from_hash(lag_index_identity_hash); - drop(); -} -action drop_ifid_update_pkt() { - drop(); -} - -/****************************************************************************** - * - * Egress Port Table - * - *****************************************************************************/ -register port_cntr { - width: 64; - direct: egr_port; - attributes: signed; -} -blackbox stateful_alu counter_alu { - reg: port_cntr; - condition_hi: register_lo < 0; - condition_lo: register_lo + md.offset < 0; - - update_hi_1_predicate: condition_hi and not condition_lo; - update_hi_1_value: register_hi + 1; - update_hi_2_predicate: not condition_hi and condition_lo; - update_hi_2_value: register_hi - 1; - - update_lo_1_value: register_lo + md.offset; -} - -action set_dest(port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); - counter_alu.execute_stateful_alu(); -} -table egr_port { - reads { md.egr_ifid : ternary; } - actions { set_dest; } - size : 16384; -} - - -control ingress { - if (0 == ig_intr_md.resubmit_flag) { - apply(ing_port); - } - if (0 == md.recirc_pkt and 0 == md.pkt_gen_pkt) { - apply( ifid ) { - drop_it { - apply(one_bit_read_1); - apply(one_bit_read_2); - if (md.one_bit_val_1 == 1 and md.one_bit_val_2 == 1) { - apply(undrop); - } - } - default { - apply(bloom_filter_1); - apply(bloom_filter_2); - apply(bloom_filter_3); - if ((md.bf_tmp_1 != 0) or (md.bf_tmp_2 != 0) or (md.bf_tmp_3 != 0)) { - apply(bloom_filter_sample); - } - - apply(sip_sampler); - - apply(flowlet_prepare); - apply(ipv4_route) { - set_ecmp { - apply(next_hop_ecmp); - //apply(flowlet_next_hop); - } - } - - apply(next_hop); - - apply(egr_ifid) { - miss { - apply(egr_port); - } - } - } - } - } else if (0 == md.recirc_pkt and 1 == md.pkt_gen_pkt) { - pgen_pass_1_ctrl_flow(); - } else if (1 == md.recirc_pkt and 0 == md.pkt_gen_pkt) { - recirc_trigger_pkt_ctrl_flow(); - } else if (1 == md.recirc_pkt and 1 == md.pkt_gen_pkt) { - pgen_pass_2_ctrl_flow(); - } -} - -control recirc_trigger_pkt_ctrl_flow { - /* Nothing to do let it go to the deparser and be dropped. */ -} - -@pragma stage 8 -table prepare_for_recirc { - reads { pktgen_port_down.app_id : exact; } - actions {prepare_for_recirc;} - size : 7; -} -action prepare_for_recirc(rtype, mgid) { - add_header(recirc_hdr); - modify_field(recirc_hdr.tag, 0xF); - modify_field(recirc_hdr.rtype, rtype); - modify_field(ig_intr_md_for_tm.mcast_grp_b, mgid); -} -control pgen_pass_1_ctrl_flow { - if ( valid(pktgen_generic) ) { - apply( clr_bloom_filter_1 ); - apply( clr_bloom_filter_2 ); - apply( clr_bloom_filter_3 ); - } else if ( valid(pktgen_recirc) ) { - apply(make_key_ecmp_fast_update); - apply(next_hop_ecmp_fast_update); - } else { - apply(prepare_for_recirc); - } -} - -control pgen_pass_2_ctrl_flow { - if (recirc_hdr.rtype == RECIRC_TYPE_PG_RECIRC) { - - } else if (recirc_hdr.rtype == RECIRC_TYPE_PG_PORT_DOWN) { - apply(egr_ifid_fast_update_make_key); - apply(egr_ifid_fast_update); - } -} diff --git a/backends/tofino/bf-asm/test/ptf/tofino.p4 b/backends/tofino/bf-asm/test/ptf/tofino.p4 deleted file mode 100644 index 31890f6df19..00000000000 --- a/backends/tofino/bf-asm/test/ptf/tofino.p4 +++ /dev/null @@ -1,145 +0,0 @@ -/******************************************************************************* - * Intrinsic Metadata Definition for Tofino * - ******************************************************************************/ - -header_type ingress_parser_control_signals { - fields { - priority : 3; // set packet priority - } -} -metadata ingress_parser_control_signals ig_prsr_ctrl; - -header_type ingress_intrinsic_metadata_t { - fields { - resubmit_flag : 1; // flag distinguishing original packets - // from resubmitted packets. - - ingress_port : 9; // ingress physical port id. - - ingress_global_tstamp : 48; // global timestamp (ns) taken upon - // arrival at ingress. - - lf_field_list : 32; // hack for learn filter. - } -} -metadata ingress_intrinsic_metadata_t ig_intr_md; - -header_type ingress_intrinsic_metadata_for_tm_t { - fields { - ucast_egress_port : 9; // egress port for unicast packets. - - mcast_grp_a : 16; // 1st multicast group (i.e., tree) id; - // a tree can have two levels. must be - // presented to TM for multicast. - - mcast_grp_b : 16; // 2nd multicast group (i.e., tree) id; - // a tree can have two levels. - - level1_mcast_hash : 13; // source of entropy for multicast - // replication-tree level1 (i.e., L3 - // replication). must be presented to TM - // for L3 dynamic member selection - // (e.g., ECMP) for multicast. - - level2_mcast_hash : 13; // source of entropy for multicast - // replication-tree level2 (i.e., L2 - // replication). must be presented to TM - // for L2 dynamic member selection - // (e.g., LAG) for nested multicast. - - level1_exclusion_id : 16; // exclusion id for multicast - // replication-tree level1. used for - // pruning. - - level2_exclusion_id : 9; // exclusion id for multicast - // replication-tree level2. used for - // pruning. - - rid : 16; // L3 replication id for multicast. - // used for pruning. - deflect_on_drop : 1; // flag indicating whether a packet can - // be deflected by TM on congestion drop - } -} - -metadata ingress_intrinsic_metadata_for_tm_t ig_intr_md_for_tm; - -header_type egress_intrinsic_metadata_t { - fields { - egress_port : 16; // egress port id. - - enq_qdepth : 19; // queue depth at the packet enqueue - // time. - - enq_congest_stat : 2; // queue congestion status at the packet - // enqueue time. - - enq_tstamp : 32; // time snapshot taken when the packet - // is enqueued (in nsec). - - deq_qdepth : 19; // queue depth at the packet dequeue - // time. - - deq_congest_stat : 2; // queue congestion status at the packet - // dequeue time. - - app_pool_congest_stat : 8; // dequeue-time application-pool - // congestion status. 2bits per - // pool. - - deq_timedelta : 32; // time delta between the packet's - // enqueue and dequeue time. - - egress_rid : 16; // L3 replication id for multicast - // packets. - - egress_rid_first : 1; // flag indicating the first replica for - // the given multicast group. - - egress_qid : 5; // egress (physical) queue id via which - // this packet was served. - - egress_cos : 3; // egress cos (eCoS) value. - - deflection_flag : 1; // flag indicating whether a packet is - // deflected due to deflect_on_drop. - } -} - -metadata egress_intrinsic_metadata_t eg_intr_md; - -/* primitive/library function extensions */ - -action deflect_on_drop() { - modify_field(ig_intr_md_for_tm.deflect_on_drop, 1); -} - -#define _ingress_global_tstamp_ ig_intr_md.ingress_global_tstamp - -header_type egress_intrinsic_metadata_from_parser_aux_t { - fields { - clone_src : 8; - egress_global_tstamp: 48; - } -} -metadata egress_intrinsic_metadata_from_parser_aux_t eg_intr_md_from_parser_aux; - -#define PKT_INSTANCE_TYPE_NORMAL 0 -#define PKT_INSTANCE_TYPE_INGRESS_CLONE 1 -#define PKT_INSTANCE_TYPE_EGRESS_CLONE 2 -#define PKT_INSTANCE_TYPE_COALESCED 3 -#define PKT_INSTANCE_TYPE_INGRESS_RECIRC 4 -#define PKT_INSTANCE_TYPE_REPLICATION 5 -#define PKT_INSTANCE_TYPE_RESUBMIT 6 - -// XXX check other types RECIRC etc and exclude those -#define pkt_is_mirrored \ - ((standard_metadata.instance_type != PKT_INSTANCE_TYPE_NORMAL) and \ - (standard_metadata.instance_type != PKT_INSTANCE_TYPE_REPLICATION)) -#define pkt_is_not_mirrored \ - ((standard_metadata.instance_type == PKT_INSTANCE_TYPE_NORMAL) or \ - (standard_metadata.instance_type == PKT_INSTANCE_TYPE_REPLICATION)) -#define pkt_is_i2e_mirrored \ - (standard_metadata.instance_type == PKT_INSTANCE_TYPE_INGRESS_CLONE) -#define pkt_is_e2e_mirrored \ - (standard_metadata.instance_type == PKT_INSTANCE_TYPE_EGRESS_CLONE) diff --git a/backends/tofino/bf-asm/test/ptf/tofino/constants.p4 b/backends/tofino/bf-asm/test/ptf/tofino/constants.p4 deleted file mode 100644 index c4540219da4..00000000000 --- a/backends/tofino/bf-asm/test/ptf/tofino/constants.p4 +++ /dev/null @@ -1,52 +0,0 @@ -// This file is to be kept in precise sync with constants.py - -#ifndef _TOFINO_LIB_CONSTANTS -#define _TOFINO_LIB_CONSTANTS 1 - -///////////////////////////////////////////////////////////// -// Parser hardware error codes -#define PARSER_ERROR_OK 0x0000 -#define PARSER_ERROR_NO_TCAM 0x0001 -#define PARSER_ERROR_PARTIAL_HDR 0x0002 -#define PARSER_ERROR_CTR_RANGE 0x0004 -#define PARSER_ERROR_TIMEOUT_USER 0x0008 -#define PARSER_ERROR_TIMEOUT_HW 0x0010 -#define PARSER_ERROR_SRC_EXT 0x0020 -#define PARSER_ERROR_DST_CONT 0x0040 -#define PARSER_ERROR_PHV_OWNER 0x0080 -#define PARSER_ERROR_MULTIWRITE 0x0100 -#define PARSER_ERROR_ARAM_SBE 0x0200 -#define PARSER_ERROR_ARAM_MBE 0x0400 -#define PARSER_ERROR_FCS 0x0800 -#define PARSER_ERROR_CSUM 0x1000 - -#define PARSER_ERROR_ARRAY_OOB 0xC000 -///////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////// -// Digest receivers -#define FLOW_LRN_DIGEST_RCVR 0 - -#define RECIRCULATE_DIGEST_RCVR 90 -#define RESUBMIT_DIGEST_RCVR 91 -#define CLONE_I2I_DIGEST_RCVR 92 -#define CLONE_E2I_DIGEST_RCVR 93 -#define CLONE_I2E_DIGEST_RCVR 94 -#define CLONE_E2E_DIGEST_RCVR 95 -///////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////// -// Clone soruces -// (to be used with eg_intr_md_from_parser_aux.clone_src) -#define NOT_CLONED 0 -#define CLONED_FROM_INGRESS 1 -#define CLONED_FROM_EGRESS 3 -#define COALESCED 5 -///////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////// -// Default priorities -#define PARSER_DEF_PRI 0 -#define PARSER_THRESH_PRI 3 - -#endif diff --git a/backends/tofino/bf-asm/test/ptf/tofino/intrinsic_metadata.p4 b/backends/tofino/bf-asm/test/ptf/tofino/intrinsic_metadata.p4 deleted file mode 100644 index 0cf5f384985..00000000000 --- a/backends/tofino/bf-asm/test/ptf/tofino/intrinsic_metadata.p4 +++ /dev/null @@ -1,445 +0,0 @@ -/******************************************************************************** - * Intrinsic Metadata Definition for Tofino * - *******************************************************************************/ - -#ifndef _TOFINO_LIB_INTRINSIC_METADATA -#define _TOFINO_LIB_INTRINSIC_METADATA 1 - -/* Control signals for the Ingress Parser during parsing (not used in or - passed to the MAU) */ -header_type ingress_parser_control_signals { - fields { - priority : 3; // set packet priority - _pad1 : 5; - parser_counter : 8; // parser counter - } -} - -@pragma not_deparsed ingress -@pragma not_deparsed egress -@pragma pa_intrinsic_header ingress ig_prsr_ctrl -header ingress_parser_control_signals ig_prsr_ctrl; - - -/* Produced by Ingress Parser */ -header_type ingress_intrinsic_metadata_t { - fields { - - resubmit_flag : 1; // flag distinguising original packets - // from resubmitted packets. - - _pad1 : 1; - - _pad2 : 2; // packet version; irrelevant for s/w. - - _pad3 : 3; - - ingress_port : 9; // ingress physical port id. - // this field is passed to the deparser - - ingress_mac_tstamp : 48; // ingress IEEE 1588 timestamp (in nsec) - // taken at the ingress MAC. - } -} - -@pragma dont_trim -@pragma not_deparsed ingress -@pragma not_deparsed egress -@pragma pa_intrinsic_header ingress ig_intr_md -@pragma pa_mandatory_intrinsic_field ingress ig_intr_md.ingress_port -header ingress_intrinsic_metadata_t ig_intr_md; - - -/* Produced by Packet Generator */ -header_type generator_metadata_t { - fields { - - app_id : 16; // packet-generation session (app) id - - batch_id: 16; // batch id - - instance_id: 16; // instance (packet) id - } -} - -@pragma not_deparsed ingress -@pragma not_deparsed egress -header generator_metadata_t ig_pg_md; - - -/* Produced by Ingress Parser-Auxiliary */ -header_type ingress_intrinsic_metadata_from_parser_aux_t { - fields { - ingress_global_tstamp : 48; // global timestamp (ns) taken upon - // arrival at ingress. - - ingress_global_ver : 32; // global version number taken upon - // arrival at ingress. - - ingress_parser_err : 16; // error flags indicating error(s) - // encountered at ingress parser. - } -} - -@pragma pa_fragment ingress ig_intr_md_from_parser_aux.ingress_parser_err -@pragma pa_atomic ingress ig_intr_md_from_parser_aux.ingress_parser_err -@pragma not_deparsed ingress -@pragma not_deparsed egress -@pragma pa_intrinsic_header ingress ig_intr_md_from_parser_aux -header ingress_intrinsic_metadata_from_parser_aux_t ig_intr_md_from_parser_aux; - - -/* Consumed by Ingress Deparser for Traffic Manager (TM) */ -header_type ingress_intrinsic_metadata_for_tm_t { - fields { - - // The ingress physical port id is passed to the TM directly from - // ig_intr_md.ingress_port - - _pad1 : 7; - ucast_egress_port : 9; // egress port for unicast packets. must - // be presented to TM for unicast. - - // --------------------- - - drop_ctl : 3; // disable packet replication: - // - bit 0 disables unicast, - // multicast, and resubmit - // - bit 1 disables copy-to-cpu - // - bit 2 disables mirroring - bypass_egress : 1; // request flag for the warp mode - // (egress bypass). - deflect_on_drop : 1; // request for deflect on drop. must be - // presented to TM to enable deflection - // upon drop. - - ingress_cos : 3; // ingress cos (iCoS) for PG mapping, - // ingress admission control, PFC, - // etc. - - // --------------------- - - qid : 5; // egress (logical) queue id into which - // this packet will be deposited. - icos_for_copy_to_cpu : 3; // ingress cos for the copy to CPU. must - // be presented to TM if copy_to_cpu == - // 1. - - // --------------------- - - _pad2: 3; - - copy_to_cpu : 1; // request for copy to cpu. - - packet_color : 2; // packet color (G,Y,R) that is - // typically derived from meters and - // used for color-based tail dropping. - - disable_ucast_cutthru : 1; // disable cut-through forwarding for - // unicast. - enable_mcast_cutthru : 1; // enable cut-through forwarding for - // multicast. - - // --------------------- - - mcast_grp_a : 16; // 1st multicast group (i.e., tree) id; - // a tree can have two levels. must be - // presented to TM for multicast. - - // --------------------- - - mcast_grp_b : 16; // 2nd multicast group (i.e., tree) id; - // a tree can have two levels. - - // --------------------- - - _pad3 : 3; - level1_mcast_hash : 13; // source of entropy for multicast - // replication-tree level1 (i.e., L3 - // replication). must be presented to TM - // for L3 dynamic member selection - // (e.g., ECMP) for multicast. - - // --------------------- - - _pad4 : 3; - level2_mcast_hash : 13; // source of entropy for multicast - // replication-tree level2 (i.e., L2 - // replication). must be presented to TM - // for L2 dynamic member selection - // (e.g., LAG) for nested multicast. - - // --------------------- - - level1_exclusion_id : 16; // exclusion id for multicast - // replication-tree level1. used for - // pruning. - - // --------------------- - - _pad5 : 7; - level2_exclusion_id : 9; // exclusion id for multicast - // replication-tree level2. used for - // pruning. - - // --------------------- - - rid : 16; // L3 replication id for multicast. - // used for pruning. - - - } -} - -@pragma pa_atomic ingress ig_intr_md_for_tm.ucast_egress_port - -@pragma pa_fragment ingress ig_intr_md_for_tm.drop_ctl -@pragma pa_fragment ingress ig_intr_md_for_tm.qid -@pragma pa_fragment ingress ig_intr_md_for_tm._pad2 - -@pragma pa_atomic ingress ig_intr_md_for_tm.mcast_grp_a -@pragma pa_fragment ingress ig_intr_md_for_tm.mcast_grp_a -@pragma pa_mandatory_intrinsic_field ingress ig_intr_md_for_tm.mcast_grp_a - -@pragma pa_atomic ingress ig_intr_md_for_tm.mcast_grp_b -@pragma pa_fragment ingress ig_intr_md_for_tm.mcast_grp_b -@pragma pa_mandatory_intrinsic_field ingress ig_intr_md_for_tm.mcast_grp_b - -@pragma pa_atomic ingress ig_intr_md_for_tm.level1_mcast_hash -@pragma pa_fragment ingress ig_intr_md_for_tm._pad3 - -@pragma pa_atomic ingress ig_intr_md_for_tm.level2_mcast_hash -@pragma pa_fragment ingress ig_intr_md_for_tm._pad4 - -@pragma pa_atomic ingress ig_intr_md_for_tm.level1_exclusion_id -@pragma pa_fragment ingress ig_intr_md_for_tm.level1_exclusion_id - -@pragma pa_atomic ingress ig_intr_md_for_tm.level2_exclusion_id -@pragma pa_fragment ingress ig_intr_md_for_tm._pad5 - -@pragma pa_atomic ingress ig_intr_md_for_tm.rid -@pragma pa_fragment ingress ig_intr_md_for_tm.rid - -@pragma not_deparsed ingress -@pragma not_deparsed egress -@pragma pa_intrinsic_header ingress ig_intr_md_for_tm -@pragma dont_trim -@pragma pa_mandatory_intrinsic_field ingress ig_intr_md_for_tm.drop_ctl -header ingress_intrinsic_metadata_for_tm_t ig_intr_md_for_tm; - -/* Consumed by Mirror Buffer */ -header_type ingress_intrinsic_metadata_for_mirror_buffer_t { - fields { - _pad1 : 6; - ingress_mirror_id : 10; // ingress mirror id. must be presented - // to mirror buffer for mirrored - // packets. - } -} - -@pragma dont_trim -@pragma pa_intrinsic_header ingress ig_intr_md_for_mb -@pragma pa_atomic ingress ig_intr_md_for_mb.ingress_mirror_id -@pragma pa_mandatory_intrinsic_field ingress ig_intr_md_for_mb.ingress_mirror_id -@pragma not_deparsed ingress -@pragma not_deparsed egress -header ingress_intrinsic_metadata_for_mirror_buffer_t ig_intr_md_for_mb; - -/* Produced by TM */ -header_type egress_intrinsic_metadata_t { - fields { - - _pad0 : 7; - egress_port : 9; // egress port id. - // this field is passed to the deparser - - _pad1: 5; - enq_qdepth : 19; // queue depth at the packet enqueue - // time. - - _pad2: 6; - enq_congest_stat : 2; // queue congestion status at the packet - // enqueue time. - - enq_tstamp : 32; // time snapshot taken when the packet - // is enqueued (in nsec). - - _pad3: 5; - deq_qdepth : 19; // queue depth at the packet dequeue - // time. - - _pad4: 6; - deq_congest_stat : 2; // queue congestion status at the packet - // dequeue time. - - app_pool_congest_stat : 8; // dequeue-time application-pool - // congestion status. 2bits per - // pool. - - deq_timedelta : 32; // time delta between the packet's - // enqueue and dequeue time. - - egress_rid : 16; // L3 replication id for multicast - // packets. - - _pad5: 7; - egress_rid_first : 1; // flag indicating the first replica for - // the given multicast group. - - _pad6: 3; - egress_qid : 5; // egress (physical) queue id via which - // this packet was served. - - _pad7: 5; - egress_cos : 3; // egress cos (eCoS) value. - // this field is passed to the deparser - - _pad8: 7; - deflection_flag : 1; // flag indicating whether a packet is - // deflected due to deflect_on_drop. - - pkt_length : 16; // Packet length, in bytes - } -} - -@pragma dont_trim -@pragma not_deparsed ingress -@pragma not_deparsed egress -@pragma pa_intrinsic_header egress eg_intr_md - -@pragma pa_atomic egress eg_intr_md.egress_port -@pragma pa_fragment egress eg_intr_md._pad1 -@pragma pa_fragment egress eg_intr_md._pad7 -@pragma pa_fragment egress eg_intr_md._pad8 -@pragma pa_mandatory_intrinsic_field egress eg_intr_md.egress_port -@pragma pa_mandatory_intrinsic_field egress eg_intr_md.egress_cos - -header egress_intrinsic_metadata_t eg_intr_md; - -/* Produced by Egress Parser-Auxiliary */ -header_type egress_intrinsic_metadata_from_parser_aux_t { - fields { - egress_global_tstamp : 48; // global time stamp (ns) taken at the - // egress pipe. - - egress_global_ver : 32; // global version number taken at the - // egress pipe. - - egress_parser_err : 16; // error flags indicating error(s) - // encountered at egress - // parser. - - clone_digest_id : 4; // value indicating the digest ID, - // based on the field list ID. - - clone_src : 4; // value indicating whether or not a - // packet is a cloned copy - // (see #defines in constants.p4) - - coalesce_sample_count : 8; // if clone_src indicates this packet - // is coalesced, the number of samples - // taken from other packets - } -} - -@pragma pa_fragment egress eg_intr_md_from_parser_aux.coalesce_sample_count -@pragma pa_fragment egress eg_intr_md_from_parser_aux.clone_src -@pragma pa_fragment egress eg_intr_md_from_parser_aux.egress_parser_err -@pragma pa_atomic egress eg_intr_md_from_parser_aux.egress_parser_err -@pragma not_deparsed ingress -@pragma not_deparsed egress -@pragma pa_intrinsic_header egress eg_intr_md_from_parser_aux -header egress_intrinsic_metadata_from_parser_aux_t eg_intr_md_from_parser_aux; - - -/* Consumed by Egress Deparser */ -// egress_port and egress_cos are passed to the deparser directly from the -// eg_intr_md header instance. The following commented out header is a -// stand-alone definition of this data: -/* -header_type egress_intrinsic_metadata_for_deparser_t { - fields { - - egress_port : 16; // egress port id. must be presented to - // egress deparser for every packet, or - // the packet will be dropped by egress - // deparser. - - egress_cos : 8; // egress cos (eCoS) value. must be - // presented to egress buffer for every - // lossless-class packet. - } -} - -@pragma pa_atomic egress eg_intr_md_for_deparser.egress_port -@pragma pa_fragment egress eg_intr_md_for_deparser.egress_cos -@pragma not_deparsed ingress -@pragma not_deparsed egress -header egress_intrinsic_metadata_for_deparser_t eg_intr_md_for_deparser; -*/ - -/* Consumed by Mirror Buffer */ -header_type egress_intrinsic_metadata_for_mirror_buffer_t { - fields { - _pad1 : 6; - egress_mirror_id : 10; // egress mirror id. must be presented to - // mirror buffer for mirrored packets. - - coalesce_flush: 1; // flush the coalesced mirror buffer - coalesce_length: 7; // the number of bytes in the current - // packet to collect in the mirror - // buffer - } -} - -@pragma dont_trim -@pragma pa_intrinsic_header egress eg_intr_md_for_mb -@pragma pa_atomic egress eg_intr_md_for_mb.egress_mirror_id -@pragma pa_fragment egress eg_intr_md_for_mb.coalesce_flush -@pragma pa_mandatory_intrinsic_field egress eg_intr_md_for_mb.egress_mirror_id -@pragma pa_mandatory_intrinsic_field egress eg_intr_md_for_mb.coalesce_flush -@pragma pa_mandatory_intrinsic_field egress eg_intr_md_for_mb.coalesce_length -@pragma not_deparsed ingress -@pragma not_deparsed egress -header egress_intrinsic_metadata_for_mirror_buffer_t eg_intr_md_for_mb; - - -/* Consumed by Egress MAC (port) */ -header_type egress_intrinsic_metadata_for_output_port_t { - fields { - - _pad1 : 2; - capture_tstamp_on_tx : 1; // request for packet departure - // timestamping at egress MAC for IEEE - // 1588. consumed by h/w (egress MAC). - update_delay_on_tx : 1; // request for PTP delay (elapsed time) - // update at egress MAC for IEEE 1588 - // Transparent Clock. consumed by h/w - // (egress MAC). when this is enabled, - // the egress pipeline must prepend a - // custom header composed of in front of the - // Ethernet header. - force_tx_error : 1; // force a hardware transmission error - - drop_ctl : 3; // disable packet replication: - // - bit 0 disables unicast, - // multicast, and resubmit - // - bit 1 disables copy-to-cpu - // - bit 2 disables mirroring - // TODO: which of these actually apply - // for egress? - - } -} - -@pragma dont_trim -@pragma pa_mandatory_intrinsic_field egress eg_intr_md_for_oport.drop_ctl -@pragma not_deparsed ingress -@pragma not_deparsed egress -@pragma pa_intrinsic_header egress eg_intr_md_for_oport -header egress_intrinsic_metadata_for_output_port_t eg_intr_md_for_oport; - -#endif diff --git a/backends/tofino/bf-asm/test/ptf/tofino/lpf_blackbox.p4 b/backends/tofino/bf-asm/test/ptf/tofino/lpf_blackbox.p4 deleted file mode 100644 index 79977705fe7..00000000000 --- a/backends/tofino/bf-asm/test/ptf/tofino/lpf_blackbox.p4 +++ /dev/null @@ -1,53 +0,0 @@ -/***************************************************************************/ - -blackbox_type lpf { - - attribute filter_input { - /* Reference to the input field to compute the filter on. - The maximum input bit width supported is 32 bits. */ - type: bit<0>; - } - - attribute direct { - /* Mutually exclusive with 'static' attribute. - Must be a match table reference */ - type: table; - optional; - } - - attribute static { - /* Mutually exclusive with 'direct' attribute. - Must be a table reference */ - type: table; - optional; - } - - attribute instance_count { - /* Mutually exclusive with 'direct' attribute. */ - type: int; - optional; - } - - - /* - Execute the low pass filter for a given cell in the array and writes - the result to the output parameter. - If the low pass filter is direct, then 'index' is ignored as the table - entry determines which cell to reference. - - Callable from: - - Actions - - Parameters: - - destination: A field reference to store the low pass filter state. - The maximum output bit width is 32 bits. - - index: Optional. The offset in the low pass filter array to update. Necessary - unless the low pass filter is declared as direct, in which case it should - not be present. - */ - method execute (out bit<0> destination, optional in int index){ - reads {filter_input} - } -} - -/***************************************************************************/ diff --git a/backends/tofino/bf-asm/test/ptf/tofino/meter_blackbox.p4 b/backends/tofino/bf-asm/test/ptf/tofino/meter_blackbox.p4 deleted file mode 100644 index 58f3a671921..00000000000 --- a/backends/tofino/bf-asm/test/ptf/tofino/meter_blackbox.p4 +++ /dev/null @@ -1,83 +0,0 @@ -/***************************************************************************/ - -blackbox_type meter { - - attribute type { - /* Must be either: - bytes - packets */ - type: string; - } - - attribute direct { - /* Mutually exclusive with 'static' attribute. - Must be a match table reference */ - type: table; - optional; - } - - attribute static { - /* Mutually exclusive with 'direct' attribute. - Must be a table reference */ - type: table; - optional; - } - - attribute instance_count { - /* Mutually exclusive with 'direct' attribute. */ - type: int; - optional; - } - - attribute green_value { - /* An 8-bit value that can be output if the packet is to be marked as green. - The default value is 0. */ - type: int; - optional; - } - attribute yellow_value { - /* An 8-bit value that can be output if the packet is to be marked as yellow. - The default value is 1. */ - type: int; - optional; - } - attribute red_value { - /* An 8-bit value that can be output if the packet is to be marked as red. - The default value is 3. */ - type: int; - optional; - } - - /* - Execute the metering operation for a given cell in the array. If - the meter is direct, then 'index' is ignored as the table - entry determines which cell to reference. The length of the packet - is implicitly passed to the meter. The state of meter is updated - and the meter returns information (a 'color') which is stored in - 'destination'. If the parent header of 'destination' is not valid, - the meter state is updated, but resulting output is discarded. - - Callable from: - - Actions - - Parameters: - - destination: A field reference to store the low pass filter state. - The maximum output bit width is 32 bits. - - index: Optional. The offset in the low pass filter array to update. Necessary - unless the low pass filter is declared as direct, in which case it should - not be present. - */ - method execute (out bit<0> destination, optional in int index){} - - /* Same as execute, but the precolor attribute specifies the minimum color the packet - may be tagged with. - Pre-color encoding (which is not programmable): - 0 = green - 1 = yellow - 2 = yellow - 3 = red - */ - method execute_with_pre_color (out bit<0> destination, in bit<0> precolor, optional in int index){} -} - -/***************************************************************************/ diff --git a/backends/tofino/bf-asm/test/ptf/tofino/pktgen_headers.p4 b/backends/tofino/bf-asm/test/ptf/tofino/pktgen_headers.p4 deleted file mode 100644 index 3f739dfc403..00000000000 --- a/backends/tofino/bf-asm/test/ptf/tofino/pktgen_headers.p4 +++ /dev/null @@ -1,57 +0,0 @@ - -/******************************************************************************** - * Packet Generator Header Definition for Tofino * - *******************************************************************************/ - -#ifndef _TOFINO_LIB_PKTGEN_HEADERS -#define _TOFINO_LIB_PKTGEN_HEADERS 1 - -header_type pktgen_generic_header_t { - fields { - _pad0 : 3; - pipe_id : 2; - app_id : 3; - key_msb : 8; // Only valid for recirc triggers. - batch_id : 16; // Overloaded to port# or lsbs of key for port down and - // recirc triggers. - packet_id : 16; - } -} -header pktgen_generic_header_t pktgen_generic; - -header_type pktgen_timer_header_t { - fields { - _pad0 : 3; - pipe_id : 2; - app_id : 3; - _pad1 : 8; - batch_id : 16; - packet_id : 16; - } -} -header pktgen_timer_header_t pktgen_timer; - -header_type pktgen_port_down_header_t { - fields { - _pad0 : 3; - pipe_id : 2; - app_id : 3; - _pad1 : 15; - port_num : 9; - packet_id : 16; - } -} -header pktgen_port_down_header_t pktgen_port_down; - -header_type pktgen_recirc_header_t { - fields { - _pad0 : 3; - pipe_id : 2; - app_id : 3; - key : 24; - packet_id : 16; - } -} -header pktgen_recirc_header_t pktgen_recirc; - -#endif diff --git a/backends/tofino/bf-asm/test/ptf/tofino/primitives.p4 b/backends/tofino/bf-asm/test/ptf/tofino/primitives.p4 deleted file mode 100644 index 9f7c4ed0266..00000000000 --- a/backends/tofino/bf-asm/test/ptf/tofino/primitives.p4 +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _TOFINO_LIB_PRIMITIVES -#define _TOFINO_LIB_PRIMITIVES 1 - -///////////////////////////////////////////////////////////// -// Primitive aliases - -#define clone_i2e clone_ingress_pkt_to_egress -#define clone_e2e clone_egress_pkt_to_egress - -action deflect_on_drop(enable_dod) { - modify_field(ig_intr_md_for_tm.deflect_on_drop, enable_dod); -} - -#define _ingress_global_tstamp_ ig_intr_md_from_parser_aux.ingress_global_tstamp - -#define _parser_counter_ ig_prsr_ctrl.parser_counter - -#define pkt_is_mirrored (eg_intr_md_from_parser_aux.clone_src != NOT_CLONED) -#define pkt_is_not_mirrored (eg_intr_md_from_parser_aux.clone_src == NOT_CLONED) - -#define pkt_is_i2e_mirrored (eg_intr_md_from_parser_aux.clone_src == CLONED_FROM_INGRESS) -#define pkt_is_e2e_mirrored (eg_intr_md_from_parser_aux.clone_src == CLONED_FROM_EGRESS) -#define pkt_is_coalesced (eg_intr_md_from_parser_aux.clone_src == COALESCED) -#define pkt_is_not_coalesced (eg_intr_md_from_parser_aux.clone_src != COALESCED) - -#endif diff --git a/backends/tofino/bf-asm/test/ptf/tofino/stateful_alu_blackbox.p4 b/backends/tofino/bf-asm/test/ptf/tofino/stateful_alu_blackbox.p4 deleted file mode 100644 index 8ac0e09ecee..00000000000 --- a/backends/tofino/bf-asm/test/ptf/tofino/stateful_alu_blackbox.p4 +++ /dev/null @@ -1,276 +0,0 @@ -/***************************************************************************/ - -blackbox_type stateful_alu { - - attribute reg { - /* Reference to the register table description. */ - type: register; - } - - attribute selector_binding { - /* Bind this stateful ALU to the selector used by the specified match table. */ - type: table; - optional; - } - - attribute initial_register_lo_value { - /* The initial value to use for the stateful memory cell. Used in dual-width mode as the - low half initial value. In single-width mode, this is the initial value of the entire memory cell. - */ - type: int; - optional; - } - - attribute initial_register_hi_value { - /* The initial value to use for the stateful memory cell. Only relevant in dual-width mode to - specify the high half initial value. - */ - type: int; - optional; - } - - attribute condition_hi { - /* Condition associated with cmp hi unit. - An expression that can be transformed into the form: - memory +/- phv - constant operation 0 - */ - type: expression; - expression_local_variables {register_lo, register_hi} - optional; - } - - attribute condition_lo { - /* Condition associated with cmp lo unit. - An expression that can be transformed into the form: - memory +/- phv - constant operation 0 - */ - type: expression; - expression_local_variables {register_lo, register_hi} - optional; - } - - - attribute update_lo_1_predicate { - /* Condition expression associated with running ALU 1 lo. */ - type: expression; - expression_local_variables {condition_lo, condition_hi} - optional; - } - - attribute update_lo_1_value { - /* Expression computed in ALU 1 lo. - In single-bit mode, this ALU can only perform single_bit instructions, which perform the following: - - +-------------------+---------------------------------------------------------------------------------+ - | Operation Name | Description | - +-------------------+---------------------------------------------------------------------------------+ - | set_bit | Sets the specified bit to 1, outputs the previous bit value. | - +-------------------+---------------------------------------------------------------------------------+ - | set_bitc | Sets the specified bit to 1, outputs the complement of the previous bit value. | - +-------------------+---------------------------------------------------------------------------------+ - | clr_bit | Sets the specified bit to 0, outputs the previous bit value. | - +-------------------+---------------------------------------------------------------------------------+ - | clr_bitc | Sets the specified bit to 0, outputs the complement of the previous bit value. | - +-------------------+---------------------------------------------------------------------------------+ - | read_bit | Does not modify specified bit, outputs current bit value. | - +-------------------+---------------------------------------------------------------------------------+ - | read_bitc | Does not modify specified bit, outputs complement of the current bit value. | - +-------------------+---------------------------------------------------------------------------------+ - - */ - type: expression; - expression_local_variables {register_lo, register_hi, - set_bit, set_bitc, clr_bit, clr_bitc, read_bit, read_bitc} - optional; - } - - attribute update_lo_2_predicate { - /* Condition expression associated with running ALU 2 lo. */ - type: expression; - expression_local_variables {condition_lo, condition_hi} - optional; - } - - attribute update_lo_2_value { - /* Expression computed in ALU 2 lo. */ - type: expression; - expression_local_variables {register_lo, register_hi, math_unit} - optional; - } - - attribute update_hi_1_predicate { - /* Condition expression associated with running ALU 1 hi. */ - type: expression; - expression_local_variables {condition_lo, condition_hi} - optional; - } - - attribute update_hi_1_value { - /* Expression computed in ALU 1 hi. */ - type: expression; - expression_local_variables {register_lo, register_hi} - optional; - } - - attribute update_hi_2_predicate { - /* Condition expression associated with running ALU 2 hi. */ - type: expression; - expression_local_variables {condition_lo, condition_hi} - optional; - } - - attribute update_hi_2_value { - /* Expression computed in ALU 2 hi. */ - type: expression; - expression_local_variables {register_lo, register_hi} - optional; - } - - attribute output_predicate { - /* Condition expression associated with outputting result to action data bus. - Allowed references are 'condition_lo' and 'condition_hi'. - Allowed operations are 'and', 'or', and 'not'. - */ - type: expression; - expression_local_variables {condition_lo, condition_hi} - optional; - } - - attribute output_value { - /* Output result expression. - Allowed references are 'alu_lo', 'alu_hi', 'register_lo', 'register_hi', - 'predicate', and 'combined_predicate'. - In the case of 'register_lo' and 'register_hi', these are the values - fetched from memory on this access, not the value to be written back - computed by the ALU(s). - */ - type: expression; - expression_local_variables {alu_lo, alu_hi, register_lo, register_hi, predicate, combined_predicate} - optional; - } - - attribute output_dst { - /* Optional field to write the stateful result to. */ - type: bit<0>; - optional; - } - - attribute math_unit_input { - /* Specification of the math unit's input. - This attribute must be defined if a math_unit is referenced in 'update_lo_2_value'. - */ - type: expression; - expression_local_variables {register_lo, register_hi} - optional; - } - attribute math_unit_output_scale { - /* Specification of the math unit's output scale. - This is a 6-bit signed number added to the exponent, which shifts the output result. - The default value is 0. - */ - type: int; - optional; - } - attribute math_unit_exponent_shift { - /* Specification of the math unit's exponent shift. - Supported shift values are -1, 0, and 1. The default value is 0. - This value controls the shifting of the input data exponent. - With an exponent shift of -1, the math unit normalization is 2-bit resolution. - Otherwise, the math unit normalization is 1-bit resolution. - */ - type: int; - optional; - } - attribute math_unit_exponent_invert { - /* Specifies whether the math unit should invert the computed exponent. - By default, the exponent is not inverted. Allowed values are True and False. - Inverting allows reciprocal exponents, e.g. 1/x, 1/x**2, or 1/sqrt(x) - */ - type: string; - optional; - } - - attribute math_unit_lookup_table { - /* Specifies the math unit's lookup table values. - There are 16 8-bit values that can be looked up. - This attribute must be defined if a math_unit is referenced in 'update_lo_2_value'. - Input is specified with the most significant byte appearing first in the string. - For example: - 0x0f 0x0e 0x0d 0x0c 0x0b 0x0a 9 8 7 6 5 4 3 2 1 0; - */ - type: string; - optional; - } - - attribute reduction_or_group { - /* Specifies that the output value to be written belongs to a group of stateful ALU - outputs that are all OR'd together. Using a reduction OR group breaks what - would normally be considered a dependency. - A typical use case is to perform a membership check in, e.g., a Bloom filter. - For example, n unique hash functions may be used to check for membership in - n unique registers. If any of the hashed locations are active, - the member is active. - */ - type: string; - optional; - } - - attribute stateful_logging_mode { - /* Specify that stateful logging should be performed. - Stateful logging writes a result to consecutive addresses in a register based on the mode - of logging being performed. - Allowed values are: - table_hit - performing logging if the match table hits and is predicated on. - table_miss - performing logging if the match table misses and is predicated on. - gateway_inhibit - performing logging if the gateway table inhibits a match table and is predicated on. - address - any time the table is predicated on. - */ - type: string; - optional; - } - - /* - Executes this stateful alu instance. - - If output_dst is defined, this writes the output_value to a destination field. - - output_dst = output_value - - Callable from: - - Actions - - Parameters: - - index: The offset into the stateful register to access. - May be a constant or an address provided by the run time. - */ - method execute_stateful_alu(optional in bit<0> index){ - reads {condition_hi, condition_lo, - update_lo_1_predicate, update_lo_1_value, - update_lo_2_predicate, update_lo_2_value, - update_hi_1_predicate, update_hi_1_value, - update_hi_2_predicate, update_hi_2_value, - math_unit_input} - writes {output_dst} - } - - method execute_stateful_alu_from_hash(in field_list_calculation hash_field_list){ - reads {condition_hi, condition_lo, - update_lo_1_predicate, update_lo_1_value, - update_lo_2_predicate, update_lo_2_value, - update_hi_1_predicate, update_hi_1_value, - update_hi_2_predicate, update_hi_2_value, - math_unit_input} - writes {output_dst} - } - - method execute_stateful_log(){ - reads {condition_hi, condition_lo, - update_lo_1_predicate, update_lo_1_value, - update_lo_2_predicate, update_lo_2_value, - update_hi_1_predicate, update_hi_1_value, - update_hi_2_predicate, update_hi_2_value, - math_unit_input} - } -} - -/***************************************************************************/ diff --git a/backends/tofino/bf-asm/test/ptf/tofino/wred_blackbox.p4 b/backends/tofino/bf-asm/test/ptf/tofino/wred_blackbox.p4 deleted file mode 100644 index 9ca9a475bcb..00000000000 --- a/backends/tofino/bf-asm/test/ptf/tofino/wred_blackbox.p4 +++ /dev/null @@ -1,64 +0,0 @@ -/***************************************************************************/ - -blackbox_type wred { - - attribute wred_input { - /* Reference to the input field to compute the moving average on. - The maximum input bit width supported is 32 bits. */ - type: bit<0>; - } - - attribute direct { - /* Mutually exclusive with 'static' attribute. - Must be a match table reference */ - type: table; - optional; - } - - attribute static { - /* Mutually exclusive with 'direct' attribute. - Must be a table reference */ - type: table; - optional; - } - - attribute instance_count { - /* Mutually exclusive with 'direct' attribute. */ - type: int; - optional; - } - - attribute drop_value { - /* Specifies the lower bound for which the computed moving average should result in a drop. */ - type: int; - optional; - } - - attribute no_drop_value { - /* Specifies the upper bound for which the computed moving average should not result in a drop. */ - type: int; - optional; - } - - /* - Execute the moving average for a given cell in the array and writes - the result to the output parameter. - If the wred is direct, then 'index' is ignored as the table - entry determines which cell to reference. - - Callable from: - - Actions - - Parameters: - - destination: A field reference to store the moving average state. - The maximum output bit width is 8 bits. - - index: Optional. The offset in the wred array to update. Necessary - unless the wred is declared as direct, in which case it should - not be present. - */ - method execute (out bit<0> destination, optional in int index){ - reads {wred_input} - } -} - -/***************************************************************************/ diff --git a/backends/tofino/bf-asm/test/ptf/tofino_diag.p4 b/backends/tofino/bf-asm/test/ptf/tofino_diag.p4 deleted file mode 100644 index de7577496e1..00000000000 --- a/backends/tofino/bf-asm/test/ptf/tofino_diag.p4 +++ /dev/null @@ -1,158 +0,0 @@ -#include -#include - -/* Sample P4 program */ -header_type ethernet_t { - fields { - dstAddr : 48; - srcAddr : 48; - etherType : 16; - } -} - -header_type vlan_tag_t { - fields { - pri : 3; - cfi : 1; - vlan_id : 12; - etherType : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr: 32; - } -} - -header_type tcp_t { - fields { - srcPort : 16; - dstPort : 16; - seqNo : 32; - ackNo : 32; - dataOffset : 4; - res : 3; - ecn : 3; - ctrl : 6; - window : 16; - checksum : 16; - urgentPtr : 16; - } -} - -header_type udp_t { - fields { - srcPort : 16; - dstPort : 16; - hdr_length : 16; - checksum : 16; - } -} - -parser start { - return parse_ethernet; -} - -header ethernet_t ethernet; - -parser parse_ethernet { - extract(ethernet); - return select(latest.etherType) { - 0x8100 : parse_vlan_tag; - 0x800 : parse_ipv4; - default: ingress; - } -} - -#define IP_PROTOCOLS_TCP 6 -#define IP_PROTOCOLS_UDP 17 - -header ipv4_t ipv4; - -parser parse_ipv4 { - extract(ipv4); - return select(latest.fragOffset, latest.protocol) { - IP_PROTOCOLS_TCP : parse_tcp; - IP_PROTOCOLS_UDP : parse_udp; - default: ingress; - } -} - -header vlan_tag_t vlan_tag; - -parser parse_vlan_tag { - extract(vlan_tag); - return select(latest.etherType) { - 0x800 : parse_ipv4; - default : ingress; - } -} - -header tcp_t tcp; - -parser parse_tcp { - extract(tcp); - return ingress; -} - -header udp_t udp; - -parser parse_udp { - extract(udp); - return ingress; -} - -counter dummy_cntr { - type : packets; - static : idle_stats_tbl; - instance_count : 256; -} - -action drop_count (count_idx) { - count(dummy_cntr, count_idx); - drop(); -} - -table idle_stats_tbl { - reads { - ipv4.dstAddr : exact; - } - actions { - drop_count; - } - support_timeout: true; -} - -action set_egress_port (eg_port) { - modify_field(ig_intr_md_for_tm.ucast_egress_port, eg_port); -} - -table snake_test { - reads { - ig_intr_md.ingress_port : exact; - } - actions { - set_egress_port; - } - size : 512; -} - -control ingress { -// apply(idle_stats_tbl); - apply(snake_test); -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/runtests b/backends/tofino/bf-asm/test/runtests deleted file mode 100755 index ec5b1004b76..00000000000 --- a/backends/tofino/bf-asm/test/runtests +++ /dev/null @@ -1,703 +0,0 @@ -#!/bin/bash - -fast=false -brig=false -glass=false -outdir=false -verbose=false -diff=false -link=false -clean=false -skip_ctxtjson=false -TIME=false -# parallel make arguments -PARALLEL=1 -TOKEN_READ=0 -TOKEN_WRITE=0 - -shopt -s nullglob -set -o pipefail - -TESTDIR=$(cd $(dirname $0); pwd -P) - -prev_mflag="" -for mflag in $MAKEFLAGS; do - case $mflag in - n) exit 0 - ;; - -j[1-9]|-j[1-9][0-9]) - PARALLEL=${mflag#-j} - ;; - [1-9]|[1-9][0-9]) - if [ "$prev_mflag" = "-j" ]; then - PARALLEL=${mflag} - fi - ;; - --jobserver-*=*) - fds=${mflag/*=/} - vec=(${fds/,/ }) - if eval "command >&${vec[1]}" 2>/dev/null; then - TOKEN_READ=${vec[0]} - TOKEN_WRITE=${vec[1]} - else - echo >&2 "invalid --jobserver, assuming -j1 -- must use '+' in Makefile rule" - fi - ;; - esac - prev_mflag=$mflag -done - -while expr "$1" : - >/dev/null; do - case $1 in - -f) fast=true - ;; - -c) clean=true - ;; - -b) brig=true - ;; - -g) glass=true - ;; - -l) link=true - ;; - -t) - TIME=true - ;; - -d) - diff=true - ;; - -j) - shift - if [[ $1 =~ ^[0-9]+$ ]]; then - PARALLEL=$1 - else - echo >&2 "invalid number -j $1" - fi - ;; - -j[1-9]|-j[1-9][0-9]) - PARALLEL=${1#-j} - ;; - -o) - shift - outdir=true - odir=$1 - ;; - -v) - verbose=true - ;; - --skip_ctxtjson) - skip_ctxtjson=true - ;; - -*) - echo >&2 "unknown argument $1" - ;; - esac - shift -done - -# If neither '-b' or '-g' specified run for both brig and glass as default case -# unless just -d specified -- then just run glass to do json_diff comparisons -if ! $brig && ! $glass; then - glass=true; - if ! $diff; then - brig=true; - fi -fi - -#glsc_args="--placement-order ingress_before_egress --libpd --placement secret" -#glsc_args="--verbose 2 -vl 2 -S -G --placement-order ingress_before_egress --no-bin --new_ctx_json" -glsc_args="--verbose 2 -vl 2 --gen_asm --gen_json --placement-order ingress_before_egress" - -trap 'release_all_tokens; exit' 2 - -if [ $# -eq 0 ]; then - set *.p4 -fi - -count=$# - -rm -rf faillog.txt -FAILLOG=$(pwd -P)/faillog.txt - -echo -n "Test run started at " >$FAILLOG -date >> $FAILLOG - -TRY_BINDIRS=" -" - -function searchdir () { - found="" - if [ -x "$BUILDDIR/$1" ]; then - echo $BUILDDIR/$1 - return - fi - for d in $TRY_BINDIRS; do - if [[ $2 ]]; then - if [ -d "$d/$2" ]; then - for f in $(find -L $d/$2 -executable -type f -name $1); do - if [ "$f" -nt "$found" ]; then - found="$f" - fi - done - if [ -n "$found" ]; then - break; - fi - fi - else - for f in $(find -L $d -executable -type f -name $1); do - if [ "$f" -nt "$found" ]; then - found="$f" - fi - done - if [ -n "$found" ]; then - break; - fi - fi - done - if [ -z "$found" ]; then - found=$(which $1) - fi - if [ -z "$found" ]; then - echo >&2 "Can't find $1 executable" - echo false - else - echo $found - fi -} - -function findexec () { - evarref=\$"$1" - evalue=`eval "expr \"$evarref\" "` - if [ ! -x "$evalue" ]; then - e=$(searchdir $2 $4) - eval "${1}=${e}" - evalue=`eval "expr \"$evarref\" "` - if [ -x "$evalue" ]; then - echo "Using $evalue" - else - #echo >&2 "Can't find $3 executable" - eval "${1}=false" - fi - fi -} - -#FINDFUNC PARAM EXECUTABLE NAME OPTIONAL SEARCH DIR PREFIX -findexec GLSC "shell.py" "glass" "" -findexec BRIG "p4c-barefoot" "brig" "" -findexec STF1 "tofino_test_harness" "tofino_test_harness" "model" -findexec STF2 "jbay_test_harness" "jbay_test_harness" "model" -findexec BFAS "bfas" "bfas" "" -findexec BFLINK "bflink" "bflink" "" -findexec REFLOW "reflow" "reflow" "" -findexec JSON_DIFF "json_diff" "json_diff" "" -findexec SCHEMA "gen_schema.py" "gen_schema.py" "ctx_json" -findexec SCHEMA_VAL "validate.py" "validate.py" "" -findexec WALLE "walle" "walle" "" - -function not() { if "$@"; then return 1; else return 0; fi } - -ctxt_json_ignore=$TESTDIR/ctxt_json_ignore_new -echo "Using context json ignore file - $ctxt_json_ignore" - -# -l specifies the key 'field' the vector will be sorted before comparison -if [ -r $ctxt_json_ignore ]; then - CTXT_DIFFARGS="-l start_offset -l entry_number -l name -l field_name -i @$ctxt_json_ignore" -else - CTXT_DIFFARGS="-al handle -i table_type" -fi - -TIMEOUT_COMMAND=$(which gtimeout || which timeout) -run() { - if $verbose; then - echo "$@" >/dev/tty - fi - if [ -z "$TIMEOUT" ]; then - $TIME_COMMAND "$@" - else - $TIME_COMMAND $TIMEOUT_COMMAND --foreground $TIMEOUT "$@" - fi - status=$? - if [ $status -eq 124 ]; then - echo >&2 $1 TIMEOUT - elif [ $status -gt 128 ]; then - echo >&2 $1 CRASH with signal $(expr $status - 128) - elif [ $status -gt 0 ]; then - echo >&2 $1 FAILED - fi - return $status -} - -function link_json() { - p4file=$1 - pushd $(dirname $p4file) >/dev/null - name=$(basename $p4file .p4) - ok=true - if [ -d $name.out ];then - cd $name.out - bindir=$PWD/glass - jsondir=$PWD/glass/cfg - if $brig;then - if [ -d brig ];then - bindir=$PWD/brig - jsondir=$PWD/brig - else - msg="$msg no $jsondir/brig found" - ok=false - rv=1 - fi - fi - if $ok && run $BFLINK --walle $WALLE --target tofino -o $bindir/tofino.bin $jsondir/*.cfg.json* >/dev/null 2>&1; then - msg="$msg link pass" - else - msg="$msg link failed" - flock $FAILLOG -c "echo '$1:' >>$FAILLOG; sed -e 's/^/ /'$name.out/link.txt >>$FAILLOG" - rv=1 - fi - fi - return $rv -} - -function test_p4() { - p4file="$1" - pushd $(dirname $p4file) >/dev/null - name=$(basename $p4file .p4) - if $clean; then - if [ -d $name.out ]; then - rm -rf $name.out - fi - fi - mkdir -p $name.out - expect_fail=$(sed -n "/^$name.p4/s/[^ ]* *//p" expected_failures.txt 2>/dev/null | head -1) - cd $name.out - ok=true - rv=0 - fail_type="" - #echo "about to run $name.p4, expecting ${expect_fail:-no} failure" - msg="$p4file" - start=`date +%s` - tfafile=brig/$name.tfa - if $diff; then - tfafile=glass/$name.tfa - fi - if $fast && [ -r $tfafile ]; then - true - else - mkdir -p brig - mkdir -p glass - # Remove old assembly files - if [ -d glass ]; then - rm -f glass/$name.tfa - rm -f glass/out.tfa - fi - if [ -d brig ]; then - rm -f brig/$name.tfa - rm -f brig/out.tfa - fi - # Run both glass and brig if '-b' and '-g' not specified - if $brig; then - clog='brig.log' - if $ok && not run $BRIG -D__TARGET_TOFINO__ ../$name.p4 -o brig/out.tfa brig.log 2>&1; then - ok=false - fi - if not $ok; then - msg="$msg p4 brig compile failed" - fi - fi - if $glass; then - clog='glsc.log' - if not run $GLSC -o glass $glsc_args ../$name.p4 glsc.log 2>&1; then - ok=false - fi - if not $ok; then - msg="$msg p4 glass compile failed" - fi - fi - if not $ok; then - fail_type="compile" - rv=1 - fi - if [ -d glass ]; then - cd glass - if [ out.tfa -nt $name.tfa ]; then - rm -f $name.tfa - ln -s out.tfa $name.tfa - fi - cd .. - fi - if [ -d brig ]; then - cd brig - if [ out.tfa -nt $name.tfa ]; then - rm -f $name.tfa - ln -s out.tfa $name.tfa - fi - cd .. - fi - if $glass && [ ! -r glass/$name.tfa ] && $ok; then - msg="$msg p4 glass compile failed to produce asm" - fail_type="compile" - rv=1 - ok=false - fi - if $brig && [ ! -r brig/$name.tfa ] && $ok; then - msg="$msg p4 brig compile failed to produce asm" - fail_type="compile" - rv=1 - ok=false - fi - if not $ok && ( [ $count -eq 1 ] || [ "$expect_fail" != "compile" ] ); then - flock $FAILLOG -c "echo '$p4file:' >>$FAILLOG; sed 's/^/ /' $clog >>$FAILLOG" - fi - fi - glsc_cfg=. - if $ok; then - rm -f $brig/*.json - if [ -d glass/cfg ]; then - glsc_cfg=glass/cfg - fi - fi - for f in $glsc_cfg/*.json; do - if $REFLOW $f | gzip -9 > $f.gz; then - rm $f - fi - done - if $diff; then - BFAS_OPTS="--gen_json -M" - else - BFAS_OPTS="" - fi - if $ok && run $BFAS -g -o brig $BFAS_OPTS -vvvvl brig/bfas.config.log $tfafile >brig/bfas.log 2>&1; then - # Validate context json output from assembler - $SCHEMA > schema.json - python $SCHEMA_VAL brig/context.json schema.json > context_json_schema_validate.log - for f in brig/*.cfg.json; do - if $REFLOW $f | gzip -9 > $f.gz; then - rm $f - fi - done - if $diff; then - for f in brig/*.cfg.json.gz; do - if zcmp -s $f $glsc_cfg/$(basename $f); then - continue - elif [ "$f" = "$name.out/regs.pipe.cfg.json.gz" ]; then - $JSON_DIFF -i mau $f $glsc_cfg/$(basename $f) - if [ $? -gt 128 ]; then - echo "***json_diff crashed" - fi - continue - fi - $JSON_DIFF $f $glsc_cfg/$(basename $f) - done > json_diff.txt - glsc_ctxt=glass/${name}_context_llir.json - if [ -d glass/context ]; then - glsc_ctxt=glass/context/context.json - fi - brig_ctxt=brig/context.json - if ! $skip_ctxtjson && [ -r $brig_ctxt ]; then - { $JSON_DIFF $CTXT_DIFFARGS $brig_ctxt $glsc_ctxt; - if [ $? -gt 128 ]; then echo "***json_diff crashed"; fi; } >> json_diff.txt - #echo $JSON_DIFF $CTXT_DIFFARGS $brig_ctxt $glsc_ctxt; - fi - cnt=$(grep -Ev '^\+\+\+|^---|"int_inj"' json_diff.txt | grep -Ec '^\+|^-') - if [ $cnt -gt 0 ]; then - msg="$msg mismatch" - fail_type="mismatch" - rv=1 - if [ $count -eq 1 ] || [ "$expect_fail" != "mismatch" ]; then - flock $FAILLOG -c "echo '$p4file:' >>$FAILLOG; cat json_diff.txt >>$FAILLOG" - fi - ok=false - else - msg="$msg pass" - let pass++ - fi - fi - elif $ok; then - msg="$msg bfas failed" - fail_type="bfas" - rv=1 - if [ $count -eq 1 ] || [ "$expect_fail" != "bfas" ]; then - flock $FAILLOG -c "echo '$p4file:' >>$FAILLOG; sed -e 's/^/ /' -e'/\n/!a\' brig/bfas.log >>$FAILLOG" - fi - ok=false - fi - if [ "$expect_fail" != "" ] && $diff; then - if $ok; then - msg="$msg (UNEXPECTED PASS -- expected $expect_fail failure)" - rv=3 - elif [ "$expect_fail" != "$fail_type" ]; then - msg="$msg (expected $expect_fail failure)" - if [ "$fail_type" = "mismatch" -o "$expect_fail" = "compile" ]; then - rv=2 - fi - else - msg="$msg (expected)" - rv=2 - fi - fi - if $TIME; then - let elapsed=`date +%s`-start - let min=elapsed/60 - let sec=elapsed%60 - if [ $sec -lt 10 ]; then - sec=0$sec - fi - msg="$msg ($min:$sec)" - fi - echo "$msg" - popd >/dev/null - return $rv -} - -function test_bfa() { - if [ -z "$2" ]; then - target="" - else - target="-t $2" - fi - msg="$1" - pushd $(dirname $1) >/dev/null - srcfile=$(basename $1) - name=${srcfile%.*} - mkdir -p $name.out - rm -f $name.out/*.json $name.out/*.json.gz $name.out/*.bin - expect_fail=$(sed -n "/^$srcfile/s/[^ ]* *//p" expected_failures.txt 2>/dev/null | head -1) - ok=true - rv=0 - start=`date +%s` - # added -Tcrash:0 to disable stack trace on crash as it seems unreasonably slow - if not run $BFAS --partial -g $target -Tcrash:0 -Mvvvvl $name.out/bfas.config.log $srcfile -o $name.out >$name.out/bfas.log 2>&1; then - msg="$msg bfas failed" - fail_type="bfas" - if [ $count -eq 1 ] || [ "$expect_fail" != "bfas" ]; then - flock $FAILLOG -c "echo '$1:' >>$FAILLOG; sed -e 's/^/ /' -e '/\n/!a\' $name.out/bfas.log >>$FAILLOG" - fi - rv=1 - ok=false - else - msg="$msg pass" - for f in $name.out/*.cfg.json; do - if $REFLOW $f | gzip -9 > $f.gz; then - rm $f - fi - done - for f in $name.out/*.bin; do - rm -f $f.gz - gzip -9 $f - done - fi - if [ "$expect_fail" != "" ]; then - if $ok; then - msg="$msg (UNEXPECTED PASS -- expected $expect_fail failure)" - rv=3 - elif [ "$expect_fail" != "$fail_type" ]; then - msg="$msg (expected $expect_fail failure)" - if [ "$fail_type" = "mismatch" -o "$expect_fail" = "compile" ]; then - rv=2 - fi - else - msg="$msg (expected)" - rv=2 - fi - fi - if $TIME; then - let elapsed=`date +%s`-start - let min=elapsed/60 - let sec=elapsed%60 - if [ $sec -lt 10 ]; then - sec=0$sec - fi - msg="$msg ($min:$sec)" - fi - echo "$msg" - popd >/dev/null - return $rv -} - -function test_stf() { - msg="$1" - pushd $(dirname $1) >/dev/null - name=$(basename $1 .stf) - rv=0 - if [[ $rv == 0 && -d $name.out ]]; then - bindir=$name.out - rm -f $name.out/stf.txt - if [ -d "$bindir/$name.out" ]; then - bindir="$bindir/$name.out" - fi - if [ -d $outdir ]; then - bindir=$outdir - fi - if [ -r $bindir/tofino.bin -o -r $bindir/tofino.bin.gz ]; then - STF=$STF1 - elif [ -r $bindir/tofino2.bin -o -r $bindir/tofino2.bin.gz ]; then - STF=$STF2 - else - STF= - echo "$msg not built" - popd >/dev/null - return 4 - fi - if [ ! -x $STF ]; then - echo "$msg simple_test_framework not available" - popd >/dev/null - return 4 - fi - start=`date +%s` - if run "$STF" -l $bindir $name.stf >$name.out/stf.txt 2>&1; then - msg="$msg pass" - else - msg="$msg fail" - rv=1 - flock $FAILLOG -c "echo '$1:' >>$FAILLOG; sed -e 's/^/ /' $name.out/stf.txt >>$FAILLOG" - fi - if $TIME; then - let elapsed=`date +%s`-start - let min=elapsed/60 - let sec=elapsed%60 - if [ $sec -lt 10 ]; then - sec=0$sec - fi - msg="$msg ($min:$sec)" - fi - echo "$msg" - else - echo "$msg not built" - rv=4 - fi - popd >/dev/null - return $rv -} - -pass=0 -fail=0 -skip=0 -expected_fail=0 -unexpected_pass=0 -running=0 -tokens=0 -token_request=0 - -function get_token() { - eval "dd bs=1 count=1 of=/dev/null <&$TOKEN_READ" 2>/dev/null - exit 99 -} - -function release_one_token() { - eval "dd if=/dev/zero bs=1 count=1 >&$TOKEN_WRITE" 2>/dev/null - let tokens-- - let token_request-- -} - -function release_all_tokens() { - if (( token_request > 0 )); then - eval "dd if=/dev/zero bs=1 count=$token_request >&$TOKEN_WRITE" 2>/dev/null - token_request=0 - fi -} - -function wait_1() { - if [[ ${BASH_VERSINFO[0]} -lt 4 ]]; then - wait %1 - rv=$? - else - wait -n - rv=$? - fi - case $rv in - 0) let pass++ - ;; - 1) let fail++ - ;; - 2) let fail++ - let expected_fail++ - ;; - 3) let pass++ - let unexpected_pass++ - ;; - 4) let skip++ - ;; - 99) let tokens++ - return - ;; - esac - let running-- -} - -if $verbose; then echo "running $PARALLEL threads"; fi - -for file in "$@"; do - if (( running >= PARALLEL + tokens )); then - if (( TOKEN_READ && tokens == token_request )); then - let token_request++ - get_token & - fi - wait_1 - fi - if $outdir; then - if [ "${file##*.}" == "stf" ]; then - let running++ - test_stf $file & - else - echo "-o option can only be passed for stf file" - echo "Input file : $file" - exit 1 - fi - elif [ "${file##*.}" == "p4" ]; then - let running++ - test_p4 $file & - elif [ "${file##*.}" == "bfa" ]; then - let running++ - test_bfa $file & - elif [ "${file##*.}" == "tfa" ]; then - let running++ - test_bfa $file tofino & - elif [ "${file##*.}" == "jba" ]; then - let running++ - test_bfa $file tofino2 & - elif [ "${file##*.}" == "stf" ]; then - let running++ - test_stf $file & - else - echo "unrecognized file type $file" - fi - if [[ ${BASH_VERSINFO[0]} -lt 4 ]]; then - wait_1 - fi - if $link; then - link_json $file - fi -done - -while (( running > 0 )); do - while (( running < PARALLEL + tokens && tokens > 0)); do - release_one_token - done - wait_1 -done - -release_all_tokens - -if [ $pass -ne 1 ]; then - pmsg="$pass tests passed" -else - pmsg="1 test passed" -fi -if [ $fail -ne 1 ]; then - fmsg="$fail tests failed" -else - fmsg="1 test failed" -fi - -if [ $unexpected_pass -gt 1 ]; then - uxp=" ($unexpected_pass tests unexpectedly pass)" -elif [ $unexpected_pass -gt 0 ]; then - uxp=" ($unexpected_pass test unexpectedly passes)" -else - uxp="" -fi - -echo "$pmsg, $fmsg ($expected_fail expected)$uxp" -echo "$pmsg, $fmsg ($expected_fail expected)$uxp" >>$FAILLOG - -if [ $fail -ne $expected_fail ]; then - exit 1 -fi diff --git a/backends/tofino/bf-asm/test/selector0.p4 b/backends/tofino/bf-asm/test/selector0.p4 deleted file mode 100644 index 19aa5251f4b..00000000000 --- a/backends/tofino/bf-asm/test/selector0.p4 +++ /dev/null @@ -1,60 +0,0 @@ -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -field_list sel_fields { - data.f1; - data.f2; - data.f3; - data.f4; -} - -field_list_calculation sel_hash { - input { - sel_fields; - } - algorithm : crc16; - output_width : 14; -} - -action_selector sel { - selection_key : sel_hash; - selection_mode : fair; -} - -action noop() { } - -action_profile sel_profile { - actions { - noop; - } - size : 16384; - dynamic_action_selection : sel; -} - -table test1 { - reads { - data.b1 : exact; - } - action_profile : sel_profile; - size : 1024; -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/selector1.p4 b/backends/tofino/bf-asm/test/selector1.p4 deleted file mode 100644 index dc40bccc6c7..00000000000 --- a/backends/tofino/bf-asm/test/selector1.p4 +++ /dev/null @@ -1,62 +0,0 @@ -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -field_list sel_fields { - data.f1; - data.f2; - data.f3; - data.f4; -} - -field_list_calculation sel_hash { - input { - sel_fields; - } - algorithm : crc16; - output_width : 14; -} - -action_selector sel { - selection_key : sel_hash; - selection_mode : fair; -} - -action noop() { } -action setf1(val) { modify_field(data.f1, val); } - -action_profile sel_profile { - actions { - noop; - setf1; - } - size : 16384; - dynamic_action_selection : sel; -} - -table test1 { - reads { - data.b1 : exact; - } - action_profile : sel_profile; - size : 1024; -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/selector2.p4 b/backends/tofino/bf-asm/test/selector2.p4 deleted file mode 100644 index 39433fa7893..00000000000 --- a/backends/tofino/bf-asm/test/selector2.p4 +++ /dev/null @@ -1,62 +0,0 @@ -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -field_list sel_fields { - data.f1; - data.f2; - data.f3; - data.f4; -} - -field_list_calculation sel_hash { - input { - sel_fields; - } - algorithm : crc16; - output_width : 14; -} - -action_selector sel { - selection_key : sel_hash; - selection_mode : fair; -} - -action noop() { } -action setf1(val) { modify_field(data.f1, val); } - -action_profile sel_profile { - actions { - noop; - setf1; - } - size : 16384; - dynamic_action_selection : sel; -} - -table test1 { - reads { - data.b1 : ternary; - } - action_profile : sel_profile; - size : 1024; -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/selector3.p4 b/backends/tofino/bf-asm/test/selector3.p4 deleted file mode 100644 index 800d0ddb10b..00000000000 --- a/backends/tofino/bf-asm/test/selector3.p4 +++ /dev/null @@ -1,69 +0,0 @@ -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -field_list sel_fields { - data.f1; - data.f2; - data.f3; - data.f4; -} - -field_list_calculation sel_hash { - input { - sel_fields; - } - algorithm : crc16; - output_width : 14; -} - -action_selector sel { - selection_key : sel_hash; - selection_mode : fair; -} - -action noop() { } -action setf1(val) { modify_field(data.f1, val); } -action setall(v1, v2, v3, v4) { - modify_field(data.f1, v1); - modify_field(data.f2, v2); - modify_field(data.f3, v3); - modify_field(data.f4, v4); -} - -action_profile sel_profile { - actions { - noop; - setf1; - setall; - } - size : 16384; - dynamic_action_selection : sel; -} - -table test1 { - reads { - data.b1 : exact; - } - action_profile : sel_profile; - size : 1024; -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/stf/exact_match1.p4 b/backends/tofino/bf-asm/test/stf/exact_match1.p4 deleted file mode 100644 index 681b35eb75c..00000000000 --- a/backends/tofino/bf-asm/test/stf/exact_match1.p4 +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - h1 : 16; - b1 : 8; - b2 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setb1(val, port) { - modify_field(data.b1, val); - modify_field(standard_metadata.egress_spec, port); -} - -table test1 { - reads { - data.f1 : exact; - } - actions { - setb1; - noop; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/stf/exact_match1.stf b/backends/tofino/bf-asm/test/stf/exact_match1.stf deleted file mode 100644 index 34520d4e443..00000000000 --- a/backends/tofino/bf-asm/test/stf/exact_match1.stf +++ /dev/null @@ -1,8 +0,0 @@ - -add test1 data.f1:0x01010101 setb1(val:0x7f, port:2) -add test1 data.f1:0x02020202 setb1(val:7, port:3) - -expect 2 01010101 ******** **** 7f 66 -packet 0 01010101 00000202 0303 55 66 77 88 -expect 3 02020202 ******** **** 07 66 -packet 2 02020202 00000303 0404 55 66 77 88 diff --git a/backends/tofino/bf-asm/test/stf/hash_action_basic.p4 b/backends/tofino/bf-asm/test/stf/hash_action_basic.p4 deleted file mode 100644 index ce99dacb23c..00000000000 --- a/backends/tofino/bf-asm/test/stf/hash_action_basic.p4 +++ /dev/null @@ -1,64 +0,0 @@ -header_type data_t { - fields { - f1 : 32; - f2 : 32; - h1 : 16; - h2 : 16; - h3 : 16; - h4 : 16; - } -} - -header data_t data; - -header_type counter_metadata_t { - fields { - counter_index : 16; - } -} - -metadata counter_metadata_t counter_metadata; - -parser start { - extract(data); - return ingress; -} - -action set_index(index, port) { - modify_field(counter_metadata.counter_index, index); - modify_field(standard_metadata.egress_spec, port); -} - -table index_setter { - reads { - data.f1 : exact; - data.f2 : exact; - } - actions { - set_index; - } - size : 2048; -} - -counter count1 { - type : packets; - static : stats; - instance_count : 16384; - min_width : 32; -} - -action count_entries() { - count(count1, counter_metadata.counter_index); -} - -table stats { - actions { - count_entries; - } - default_action: count_entries; -} - -control ingress { - apply(index_setter); - apply(stats); -} diff --git a/backends/tofino/bf-asm/test/stf/hash_action_basic.stf b/backends/tofino/bf-asm/test/stf/hash_action_basic.stf deleted file mode 100644 index 4b0c4263abf..00000000000 --- a/backends/tofino/bf-asm/test/stf/hash_action_basic.stf +++ /dev/null @@ -1,20 +0,0 @@ -add index_setter data.f1:0x11111111 data.f2:0x22222222 set_index(index:9, port:1) -add index_setter data.f1:0x22222222 data.f2:0x33333333 set_index(index:9, port:2) -add index_setter data.f1:0x33333333 data.f2:0x44444444 set_index(index:9, port:2) -add index_setter data.f1:0x44444444 data.f2:0x55555555 set_index(index:8, port:3) - -expect 1 11111111 22222222 0101 0202 0303 0404 -packet 0 11111111 22222222 0101 0202 0303 0404 - -# expect 2 22222222 33333333 0202 0303 0404 0505 -# packet 0 22222222 33333333 0202 0303 0404 0505 - -# expect 2 33333333 44444444 0303 0404 0505 0606 -# packet 0 33333333 44444444 0303 0404 0505 0606 - -# expect 3 44444444 55555555 0404 0505 0606 0707 -# packet 0 44444444 55555555 0404 0505 0606 0707 - -wait -# check_counter count1(8) packets == 1 -check_counter count1(9) packets == 1 diff --git a/backends/tofino/bf-asm/test/stf/max_counters.p4 b/backends/tofino/bf-asm/test/stf/max_counters.p4 deleted file mode 100644 index dc0e090d1cb..00000000000 --- a/backends/tofino/bf-asm/test/stf/max_counters.p4 +++ /dev/null @@ -1,87 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - c1 : 8; - c2 : 8; - c3 : 8; - c4 : 8; - } -} - -header data_t data; - -parser start { - extract(data); - return ingress; -} -action c1_2(val1, val2) { - modify_field(data.c1, val1); - modify_field(data.c2, val2); -} - -action c3_4(val3, val4, port) { - modify_field(data.c3, val3); - modify_field(data.c4, val4); - modify_field(standard_metadata.egress_spec, port); -} - -table test1 { - reads { - data.f1 : exact; - } - actions { - c1_2; - } -} - -table test2 { - reads { - data.f2 : exact; - } - actions { - c3_4; - } - size: 1024; -} - -counter cnt { - type: packets; - direct: test1; -} - -counter cnt2 { - type: bytes; - direct: test1; -} - -counter cnt3 { - type: packets; - direct: test2; -} - -counter cnt4 { - type: bytes; - direct: test2; -} - -control ingress { - apply(test1); - apply(test2); -} diff --git a/backends/tofino/bf-asm/test/stf/max_counters.stf b/backends/tofino/bf-asm/test/stf/max_counters.stf deleted file mode 100644 index 804b1d81f96..00000000000 --- a/backends/tofino/bf-asm/test/stf/max_counters.stf +++ /dev/null @@ -1,14 +0,0 @@ -add test1 data.f1:0x01010101 c1_2(val1:0x01, val2:0x02) -add test1 data.f1:0x02020202 c1_2(val1:0x10, val2:0x20) - -add test2 data.f2:0x03030303 c3_4(val3:0x03, val4:0x04, port:1) -add test2 data.f2:0x04040404 c3_4(val3:0x30, val4:0x40, port:2) - -expect 1 01010101 03030303 01 02 03 04 -packet 0 01010101 03030303 55 66 77 88 -expect 2 01010101 04040404 01 02 30 40 -packet 0 01010101 04040404 55 66 77 88 -expect 1 02020202 03030303 10 20 03 04 -packet 0 02020202 03030303 99 88 77 66 -expect 2 02020202 04040404 10 20 30 40 -packet 0 02020202 04040404 14 25 36 47 diff --git a/backends/tofino/bf-asm/test/stf/p4c-5198.bfa b/backends/tofino/bf-asm/test/stf/p4c-5198.bfa deleted file mode 100644 index fb658cf4d54..00000000000 --- a/backends/tofino/bf-asm/test/stf/p4c-5198.bfa +++ /dev/null @@ -1,6776 +0,0 @@ -version: - version: 1.0.1 - run_id: "ecba7fb5cb3842db" - target: Tofino2 -phv ingress: - ig_intr_md_for_dprsr.mirror_type.$valid: H7(0) - ig_intr_md.ingress_port: { stage 0..8: H65(0..8), stage 9..13: DH20(0..8), stage 14..15: H65(0..8) } - hdr.fabric_trace.trace_counter: { stage 16..20: H43 } - hdr.fabric_trace.timestamp.0-31: MW11 - hdr.fabric_trace.timestamp.32-47: { stage 0..8: H52, stage 9: DH16, stage 10..19: H52 } - ig_md.ig_ft.srv6.sid.0-31: { stage 2..8: DW0 } - ig_md.ig_ft.srv6.sid.32-63: { stage 2..8: DW4 } - ig_md.ig_ft.srv6.sid.64-95: { stage 2..8: DW5 } - ig_md.ig_ft.srv6.sid.96-127: { stage 2..8: DW8 } - ig_md.ig_ft.srv6.g_sid.0-15: { stage 2..7: DH3 } - ig_md.ig_ft.srv6.g_sid.16-31: { stage 2..7: DH12 } - ig_md.ig_ft.srv6.g_sid.32-63: { stage 2..7: DW3 } - ig_md.ig_ft.srv6.g_sid.64-95: { stage 2..7: DW2 } - ig_md.ig_ft.srv6.g_sid.96-127: { stage 2..7: DW1 } - ig_md.ig_ft.srv6.args.0-31: { stage 11..12: W5 } - ig_md.ig_ft.srv6.args.32-63: { stage 11..12: W14 } - ig_md.ig_ft.srv6.c_sid: { stage 8: W0 } - ig_md.ig_ft.srv6.prefixlen: { stage 7..8: H8(6..13) } - ig_md.ig_ft.srv6.si: { stage 7..9: W6(0..1) } - ig_md.ig_ft.srv6.srh_terminate: { stage 9..14: B13(6) } - ig_md.ig_ft.srv6.next_hdr: { stage 2..14: MB1 } - ig_md.ig_ft.srv6.end_type: { stage 5..14: W30(0..4) } - ig_md.ig_ft.srv6.tmp_info: { stage 10..15: H16(0..14) } - ig_md.ig_ft.srv6.end_flag: { stage 10..14: H43(3) } - ig_md.ig_ft.srv6.sl_flag: { stage 9..14: B35(7) } - ig_md.ig_ft.srv6.tmp_no_frr: { stage 0..13: B34(1) } - ig_md.ig_ft.srv6.sl_minus_flag: { stage 1..8: H16(15) } - ig_md.ig_ft.srv6.global_pf_mode: { stage 6..8: W28(0..1) } - ig_md.ig_ft.srv6.pf_bypass: { stage 1..7: B10(6) } - ig_md.ig_ft.srv6.pf_downgrade: { stage 0..8: MB8(0) } - ig_md.ig_ft.srv6.ext_flag: { stage 7..16: H8(3) } - ig_md.ig_ft.srv6.lif_type: { stage 10..14: H57(0) } - ig_md.ig_ft.srv6.is_end_as: { stage 10..14: H30(7) } - hdr.fabric_base.pkt_type: B37(2..7) - hdr.fabric_base.is_mirror: B37(1) - hdr.fabric_base.is_mcast: B37(0) - hdr.fabric_qos.tc: { stage 0..6: H69(5..7) } - hdr.fabric_qos.color: { stage 0..6: H69(3..4) } - hdr.fabric_qos.track: { stage 0: H69(0) } - hdr.fabric_data_template_plus.flags: B15 - hdr.fabric_data_template_plus.vb: B36 - hdr.fabric_data_template_plus.vh0: H53 - hdr.fabric_data_template_plus.vh1: H19 - hdr.fabric_data_template_plus.vh2: H1 - hdr.fabric_data_template_plus.vh3: H17 - hdr.fabric_data_template_plus.one: H13(15) - hdr.fabric_data_template_plus.iif: H13(0..14) - hdr.ig_ft.ipv6.version: B41(4..7) - hdr.ig_ft.ipv6.traffic_class.0-3: B40(4..7) - hdr.ig_ft.ipv6.traffic_class.4-7: B41(0..3) - hdr.ig_ft.ipv6.flow_label.0-15: H3 - hdr.ig_ft.ipv6.flow_label.16-19: B40(0..3) - hdr.ig_ft.ipv6.payload_len: H0 - hdr.ig_ft.ipv6.next_hdr: MB6 - hdr.ig_ft.ipv6.src_addr.0-15: H2 - hdr.ig_ft.ipv6.src_addr.16-31: MH12 - hdr.ig_ft.ipv6.src_addr.32-63: MW2 - hdr.ig_ft.ipv6.src_addr.64-95: MW1 - hdr.ig_ft.ipv6.src_addr.96-127: MW0 - hdr.ig_ft.ipv6.dst_addr.0-31: MW3 - hdr.ig_ft.ipv6.dst_addr.32-63: MW6 - hdr.ig_ft.ipv6.dst_addr.64-95: MW7 - hdr.ig_ft.ipv6.dst_addr.96-127: MW8 - ig_md.ig_ft.lkp.vid: { stage 0..11: H67(0..11) } - ig_md.ig_ft.lkp.mac_dst_addr.0-31: { stage 0..15: W16 } - ig_md.ig_ft.lkp.mac_dst_addr.32-47: { stage 0..15: H64 } - ig_md.ig_ft.lkp.mac_src_addr.0-15: { stage 0..2: W30(0..15) } - ig_md.ig_ft.lkp.mac_src_addr.16-23: { stage 0..2: H22(0..7) } - ig_md.ig_ft.lkp.mac_src_addr.24-47: { stage 0..2: W17(0..23) } - ig_md.ig_ft.lkp.l4_port_label_32.0-15: { stage 1..8: H43 } - ig_md.ig_ft.lkp.l4_port_label_32.16-31: { stage 1..8: H57 } - ig_md.ig_ft.lkp.l4_src_port: { stage 0..11: H66 } - ig_md.ig_ft.lkp.l4_dst_port: { stage 0..11: W31(0..15) } - ig_md.ig_ft.lkp.ip_frag: { stage 3..8: H22(0..1) } - ig_md.ig_ft.lkp.ip_tos.0-1: { stage 1..8: B44(0..1) } - ig_md.ig_ft.lkp.ip_tos.2-3: { stage 1..8: B45(0..1) } - ig_md.ig_ft.lkp.ip_tos.4-7: { stage 1..8: B46(0..3) } - ig_md.ig_ft.lkp.ip_proto: { stage 0..11: B18 } - ig_md.ig_ft.lkp.srv6_ip_proto: { stage 0..1: MB0 } - ig_md.ig_ft.lkp.ip_src_addr.0-15: { stage 0..11: H10 } - ig_md.ig_ft.lkp.ip_src_addr.16-31: { stage 0..11: MH13 } - ig_md.ig_ft.lkp.ip_src_addr.32-63: { stage 0..11: W3 } - ig_md.ig_ft.lkp.ip_src_addr.64-95: { stage 0..11: W2 } - ig_md.ig_ft.lkp.ip_src_addr.96-127: { stage 0..11: W1 } - ig_md.ig_ft.lkp.ip_dst_addr.0-31: { stage 0..13: W4 } - ig_md.ig_ft.lkp.ip_dst_addr.32-63: { stage 0..13: W13 } - ig_md.ig_ft.lkp.ip_dst_addr.64-95: { stage 0..13: W15 } - ig_md.ig_ft.lkp.ip_dst_addr.96-127: { stage 0..13: W24 } - ig_md.ig_ft.lkp.tcp_flags: { stage 0..8: H29(0..7) } - ig_md.ig_ft.lkp.ip_ttl: { stage 0..11: MH0(0..7) } - ig_md.ig_ft.lkp.flow_label: { stage 0..3: W28(0..19) } - ig_md.ig_ft.lkp.tmp_ipv4_checksum: { stage 0: H20 } - hdr.ig_ft.vxlan.vni.0-15: H4 - hdr.ig_ft.vxlan.vni.16-23: B47 - ig_md.ig_ft.flags.ipv4_checksum_err: { stage 0..15: H8(1) } - ig_md.ig_ft.flags.inner_ipv4_checksum_err: { stage 0..10: H8(2) } - ig_md.ig_ft.flags.tunnel_info: { stage 13..20: H12(14) } - ig_md.ig_ft.flags.drop: { stage 16..18: H37(0) } - hdr.ig_ft.srv6_srh.next_hdr: MB4 - hdr.ig_ft.srv6_srh.seg_left: B14 - hdr.ig_ft.srv6_srh.last_entry: B47 - hdr.ig_ft.doh_e2e.next_hdr: { stage 0: B45, stage 1..8: DB13, stage 9..19: B45 } - hdr.ig_ft.doh_e2e.hdr_ext_len: { stage 0: B46, stage 1..8: DB12, stage 9..19: B46 } - hdr.ig_ft.doh_e2e.option_type: { stage 0: H28(8..15), stage 1..16: DH8(8..15), stage 17..19: H28(8..15) } - hdr.ig_ft.doh_e2e.option_len: { stage 0: H28(0..7), stage 1..16: DH8(0..7), stage 17..19: H28(0..7) } - ig_md.ig_ft.ifit.loss_label: { stage 0..15: MB12(3) } - ig_md.ig_ft.ifit.delay_label: { stage 0..15: MB14(2) } - ig_md.ig_ft.ifit.ifit_enable: { stage 10..15: W38(0) } - ig_md.ig_ft.ifit.dyna_learn_flag: { stage 10..15: H69(0) } - ig_md.ig_ft.ifit.ifit_decap_enable: { stage 10..15: H69(3) } - ig_md.ig_ft.ifit.endpoint_enable: { stage 6..17: B35(6) } - ig_md.ig_ft.ifit.hti: { stage 0..15: MB10(6..7) } - ig_md.ig_ft.ifit.index: { stage 9..17: H22(0..11) } - ig_md.ig_ft.ifit.var_h1: { stage 11..20: H54 } - ig_md.ig_ft.ifit.flow_id: { stage 0..11: MW5(4..23) } - ig_md.ig_ft.ifit.flow_node_id: { stage 0..11: MW10(4..23) } - hdr.ig_ft.doh.next_hdr: MB5 - hdr.ig_ft.srv6_h2h_ifit.reserved3.0-15: H4 - hdr.ig_ft.srv6_h2h_ifit.reserved3.16-23: { stage 0: B31, stage 1..15: DB8, stage 16..19: B31 } - hdr.ext_tunnel_decap.ext_type: B38(5..7) - hdr.ext_tunnel_decap.extend: B38(4) - hdr.ext_tunnel_decap.sub_type: B38(0..3) - hdr.ext_tunnel_decap.vb: B39 - hdr.ext_tunnel_decap.vh: H18 - hdr.ig_ft.ethernet.dst_addr.0-31: MW15 - hdr.ig_ft.ethernet.dst_addr.32-47: H23 - hdr.ig_ft.ethernet.src_addr.0-31: MW14 - hdr.ig_ft.ethernet.src_addr.32-47: H55 - hdr.ig_ft.ethernet.ether_type: MH14 - hdr.ig_ft.vlan_tag$0.pcp: W10(29..31) - hdr.ig_ft.vlan_tag$0.cfi: W10(28) - hdr.ig_ft.vlan_tag$0.vid: W10(16..27) - hdr.ig_ft.vlan_tag$0.ether_type: W10(0..15) - hdr.ig_ft.vlan_tag$1.pcp: W11(29..31) - hdr.ig_ft.vlan_tag$1.cfi: W11(28) - hdr.ig_ft.vlan_tag$1.vid: W11(16..27) - hdr.ig_ft.vlan_tag$1.ether_type: W11(0..15) - ig_md.ig_ft.common.mac_type: { stage 1..16: H71(10..11) } - ig_md.ig_ft.common.pkt_type: B37(2..7) - ig_md.ig_ft.common.pipeline_location: { stage 19..20: MB15 } - ig_md.ig_ft.common.eport.0-7: { stage 1..2: H16(0..7) } - ig_md.ig_ft.common.eport.8-15: { stage 1..2: MH6(8..15) } - ig_md.ig_ft.common.src_port: { stage 1..20: MB13 } - ig_md.ig_ft.common.from_cpu: { stage 1..18: B13(4) } - ig_md.ig_ft.common.hash_mode: { stage 1..4: W38(0..3) } - ig_md.ig_ft.common.mirror_dst_eport: { stage 6..20: H56 } - ig_md.ig_ft.common.ether_type: { stage 0..15: MH11 } - ig_md.ig_ft.common.iif: { stage 1..20: H15(0..14) } - ig_md.ig_ft.common.ul_iif: { stage 1..20: H14(0..14) } - ig_md.ig_ft.common.iif_type: { stage 1..18: W37(0) } - ig_md.ig_ft.common.bridge_type: { stage 1..18: B35(0..4) } - ig_md.ig_ft.common.usi: { stage 3..4: H20(4..13) } - ig_md.ig_ft.common.trace_vh3: { stage 16..20: H57 } - ig_md.ig_ft.common.redirect_recirc: { stage 14..17: B34(1) } - ig_md.ig_ft.common.vpntovpn_flag: { stage 14..16: H16(15) } - ig_md.ig_ft.common.drop_reason: { stage 6..20: B30 } - ig_md.ig_ft.common.tstamp_flag: { stage 6..18: W17(17) } - ig_md.ig_ft.common.extend: { stage 1..18: B13(7) } - ig_md.ig_ft.common.diag: { stage 1..18: B13(3) } - ig_md.ig_ft.common.track: { stage 1..18: H70(0) } - ig_md.ig_ft.common.decap_len: { stage 10..17: H29 } - hdr.ig_ft.ipv4.diffserv: B40 - hdr.ig_ft.ipv4.flags: B14(5..7) - hdr.ig_ft.ipv4.frag_offset.0-7: MB5 - hdr.ig_ft.ipv4.frag_offset.8-12: B14(0..4) - hdr.ig_ft.ipv4.protocol: MB4 - hdr.ig_ft.ipv4.src_addr.0-15: H0 - hdr.ig_ft.ipv4.src_addr.16-31: MH12 - hdr.ig_ft.ipv4.dst_addr: MW0 - hdr.ig_ft.ipv4_option.type: MB6 - hdr.ig_ft.ipv4_option.length: H2(8..15) - hdr.ig_ft.ipv4_option.value.8-15: H2(0..7) - hdr.ig_ft.mpls_ig$0.label.0-3: H5(12..15) - hdr.ig_ft.mpls_ig$0.label.4-19: H40 - hdr.ig_ft.mpls_ig$0.exp: H5(9..11) - hdr.ig_ft.mpls_ig$0.bos: H5(8) - hdr.ig_ft.mpls_ig$0.ttl: H5(0..7) - hdr.ig_ft.mpls_ig$1.label.0-3: H4(12..15) - hdr.ig_ft.mpls_ig$1.label.4-19: H39 - hdr.ig_ft.mpls_ig$1.exp: H4(9..11) - hdr.ig_ft.mpls_ig$1.bos: H4(8) - hdr.ig_ft.mpls_ig$1.ttl: H4(0..7) - hdr.ig_ft.mpls_ig$2.label.0-3: H3(12..15) - hdr.ig_ft.mpls_ig$2.label.4-19: H38 - hdr.ig_ft.mpls_ig$2.exp: H3(9..11) - hdr.ig_ft.mpls_ig$2.bos: H3(8) - hdr.ig_ft.mpls_ig$2.ttl: H3(0..7) - hdr.ig_ft.mpls_ig$3.label.0-3: H2(12..15) - hdr.ig_ft.mpls_ig$3.label.4-19: { stage 0..15: H37, stage 16..18: DH14, stage 19: H37 } - hdr.ig_ft.mpls_ig$3.exp: H2(9..11) - hdr.ig_ft.mpls_ig$3.bos: H2(8) - hdr.ig_ft.mpls_ig$3.ttl: H2(0..7) - hdr.ig_ft.mpls_ig$4.label.0-3: H0(12..15) - hdr.ig_ft.mpls_ig$4.label.4-19: { stage 0..11: H36, stage 12..18: DH13, stage 19: H36 } - hdr.ig_ft.mpls_ig$4.exp: H0(9..11) - hdr.ig_ft.mpls_ig$4.bos: H0(8) - hdr.ig_ft.mpls_ig$4.ttl: H0(0..7) - hdr.ig_ft.br_tag.ecid: { stage 0: H1(0..11) } - hdr.fabric_from_cpu_eth_ccm.dev_port: { stage 0..12: MW8(0..8) } - ig_md.ig_ft.route.vrf: { stage 4..20: H12(0..12) } - ig_md.ig_ft.route.rmac_hit: { stage 1..18: B12(7) } - ig_md.ig_ft.route.ipv4_unicast_enable: { stage 4..6: H22(8) } - ig_md.ig_ft.route.ipv6_unicast_enable: { stage 4..11: H8(5) } - ig_md.ig_ft.tunnel.mpls_enable: { stage 1..15: H8(4) } - ig_md.ig_ft.tunnel.type: { stage 1..15: B31(0..2) } - ig_md.ig_ft.tunnel.sub_type: { stage 3..15: W6(17..20) } - ig_md.ig_ft.tunnel.is_ttl_copy: { stage 1..18: H8(0) } - ig_md.ig_ft.tunnel.is_ttl_copy_1: { stage 6..8: W0(1) } - ig_md.ig_ft.tunnel.is_ttl_copy_2: { stage 7..8: W0(0) } - ig_md.ig_ft.tunnel.is_ttl_copy_3: { stage 8: W0(2) } - ig_md.ig_ft.tunnel.ttl_2: { stage 6..8: DH0(0..7) } - ig_md.ig_ft.tunnel.ttl_3: { stage 7..8: DH1(0..7) } - ig_md.ig_ft.tunnel.ttl_4: { stage 8: DH2(0..7) } - ig_md.ig_ft.tunnel.urpf_type: { stage 2..15: W38(4..7) } - ig_md.ig_ft.tunnel.decap_pre_len: { stage 1..16: H28 } - ig_md.ig_ft.tunnel.is_pre_len_add: { stage 14..16: H30(8) } - ig_md.ig_ft.tunnel.is_terminate: { stage 6..18: MH5(13) } - ig_md.ig_ft.tunnel.is_ilm_continue: { stage 6..7: MH4(0) } - ig_md.ig_ft.tunnel.is_vpn_terminate: { stage 5..15: W28(2) } - ig_md.ig_ft.tunnel.ipv4_true: { stage 11..20: H12(15) } - ig_md.ig_ft.tunnel.evpn_end_type: { stage 10..15: H57(1) } - ig_md.ig_ft.tunnel.inner_pkt_parsed: { stage 3..14: H6(12..14) } - ig_md.ig_ft.tunnel.src_netport_group: { stage 10..15: H43(0..2) } - ig_md.ig_ft.tunnel.source_id: { stage 10..15: H31(1..10) } - ig_md.ig_ft.tunnel.tmp_oif: { stage 7: MH4(0..14) } - ig_md.ig_ft.tunnel.srv6_flavors: { stage 5..8: W28(3..6) } - ig_md.ig_ft.tunnel.bypass_pw: { stage 6..15: W17(18) } - ig_md.ig_ft.tunnel.is_cw: { stage 8..14: H6(15) } - ig_md.ig_ft.tunnel.decap_num: { stage 9: MB2(0..1) } - ig_md.ig_ft.ipfix.flow_id: { stage 3..9: H70(8..15) } - ig_md.ig_ft.ipfix.sample_gap: { stage 3..6: MH9 } - ig_md.ig_ft.ipfix.random_num: { stage 1..9: H30 } - ig_md.ig_ft.ipfix.count: { stage 6..9: W17(1..16) } - ig_md.ig_ft.ipfix.delta: { stage 5: H31 } - ig_md.ig_ft.ipfix.random_flag: { stage 9: H52(0) } - ig_md.ig_ft.mirror.session_id: { stage 3..20: MB7 } - ig_md.ig_ft.mirror.meter_id: { stage 6: H16(0..9) } - ig_md.ig_ft.mirror.sample_flag: { stage 9..18: W17(0) } - ig_md.ig_ft.mirror.span_flag: { stage 6..18: B5(0) } - ig_md.ig_ft.mirror.flags: { stage 17..20: MB2 } - ig_md.ig_ft.mirror.ifit_flag: { stage 14..18: B6(0) } - ig_md.ig_ft.mirror.src: { stage 17..20: MB0(5..7) } - ig_md.ig_ft.mirror.type: { stage 17..20: MB0(0..4) } - ig_md.ig_ft.ebridge.evlan: { stage 5..18: H20(0..13) } - ig_md.ig_ft.ebridge.is_iif_block: { stage 4..18: B13(5) } - ul_lif_properties_check_usi_states_0: { stage 5: H22(9) } - ig_md.ig_ft.qos.meter_mode: { stage 5..9: H70(7) } - ig_md.ig_ft.qos.acl_meter_index.0-7: { stage 5..10: B6 } - ig_md.ig_ft.qos.acl_meter_index.8-13: { stage 5..10: H70(1..6) } - ig_md.ig_ft.qos.acl_meter_color: { stage 11..15: B5(3..4) } - ig_md.ig_ft.qos.lif_trust_mode: { stage 4..5: B5(5..7) } - ig_md.ig_ft.qos.lif_ds: { stage 4..5: H71(5..9) } - ig_md.ig_ft.qos.lif_meter_index: { stage 4..13: W37(1..14) } - ig_md.ig_ft.qos.is_auto_trust: { stage 4..15: B35(5) } - ig_md.ig_ft.qos.color: { stage 4..18: H71(0..1) } - ig_md.ig_ft.qos.tc: { stage 4..18: H71(2..4) } - ig_md.ig_ft.qos.BA: { stage 4..18: H6(11) } - ig_md.ig_ft.qos.set_dscp: { stage 12: B6(1) } - ig_md.ig_ft.qos.dscp: { stage 12: B44(2..7) } - ig_md.ig_ft.qos.chgDSCP_disable: { stage 12..18: H36(0) } - ig_md.ig_ft.qos.lif_meter_color: { stage 13..15: B5(1..2) } - ig_md.ig_ft.policer.slice1.vag_classid.0-7: { stage 3: H29(8..15) } - ig_md.ig_ft.policer.slice1.vag_classid.8-15: { stage 3: H69(8..15) } - ig_md.ig_ft.policer.slice2.vag_classid: { stage 3..8: W30(16..31) } - ig_md.ig_ft.policer.slice3.vag_classid: { stage 3..4: W31(16..31) } - ig_intr_md_for_dprsr.drop_ctl: { stage 4..20: W6(2..4) } - ig_intr_md_for_dprsr.mirror_type: { stage 17..20: B1(0..3) } - ig_intr_md_for_dprsr.mirror_io_select: { stage 16..20: H31(0) } - ig_intr_md_for_dprsr.drop_ctl.$valid: { stage 4..20: B10(3) } - ig_md.ig_ft.policer.mac_drop: { stage 5..15: B10(7) } - ig_md.ig_ft.policer.behavior_id: { stage 5..11: W6(5..16) } - hdr.ext_srv6.ext_type: { stage 17..20: B11(5..7) } - hdr.ext_srv6.extend: { stage 18..20: B11(4) } - hdr.ext_srv6.bypass_L3: { stage 7..20: B11(3) } - hdr.ext_srv6.level: { stage 7..20: B11(1..2) } - hdr.ext_srv6.is_ecmp: { stage 7..20: B11(0) } - hdr.ext_srv6.priority: { stage 7..20: W7(24..31) } - hdr.ext_srv6.nexthop: { stage 7..20: W7(8..23) } - hdr.ext_srv6.no_frr: { stage 14..20: W7(7) } - hdr.ext_srv6.nexthop_ext: { stage 7..20: W7(6) } - hdr.ext_srv6.is_pf: { stage 10..20: W7(5) } - hdr.ext_srv6.is_endx_pf: { stage 10..20: W7(4) } - hdr.ext_srv6.oam_flag: { stage 9..20: W7(0..3) } - hdr.fabric_qos_encap.data: { stage 19..20: B29 } - ig_intr_md_for_tm.ucast_egress_port: { stage 1..20: MW9(0..8) } - ig_intr_md_for_tm.bypass_egress: { stage 7..20: B12(6) } - ig_intr_md_for_tm.deflect_on_drop: { stage 16..20: H31(1) } - ig_intr_md_for_tm.qid: { stage 16..20: H30(0..6) } - ig_intr_md_for_tm.bypass_egress.$valid: { stage 7..20: H7(1) } - hdr.ext_ifit_encap.ext_type: { stage 16..20: H22(13..15) } - hdr.ext_ifit_encap.extend: { stage 16..20: H22(12) } - hdr.ext_ifit_encap.index: { stage 9..17: H22(0..11) } - hdr.ext_ifit_encap.var_h1: { stage 16..20: H21 } - cpu_egress_port_mapping_fabric_lag_flag: { stage 9..10: H65(0..6) } - ig_intr_md_for_tm.ucast_egress_port.$valid: { stage 1..20: B10(2) } - ig_intr_md_for_tm.qid.$valid: { stage 16..20: B9(5) } - ig_intr_md_for_tm.deflect_on_drop.$valid: { stage 19..20: H7(2) } - ig_intr_md_for_dprsr.mirror_io_select.$valid: { stage 19..20: H7(3) } - hdr.bridged_md_12_encap.decap_len: { stage 18..20: H24 } - hdr.switch_bridged_src.src: { stage 19..20: B28(5..7) } - hdr.switch_bridged_src.bridge_type: { stage 19..20: B28(0..4) } - $tmp11: { stage 20: B0 } - $pad14: { stage 20: H15(15) } - $pad15: { stage 20: H14(15) } - $pad18: { stage 20: H12(13) } - hdr.fabric_trace.$valid: { stage 7..20: H7(4) } - hdr.fabric_base.$valid: B10(4) - hdr.fabric_data_template_plus.$valid: B13(1) - hdr.ig_ft.ipv6.$valid: H7(5) - hdr.ig_ft.udp.$valid: H7(6) - hdr.ig_ft.vxlan.$valid: H7(7) - hdr.ig_ft.inner_ethernet.$valid: H7(8) - hdr.ig_ft.inner_ipv4.$valid: H7(9) - hdr.ig_ft.inner_ipv6.$valid: H7(10) - hdr.ig_ft.inner_vlan_tag.$valid: H7(11) - hdr.ig_ft.srv6_srh.$valid: H7(12) - hdr.ig_ft.doh_e2e.$valid: H7(13) - hdr.ig_ft.srv6_e2e_ifit.$valid: H7(14) - hdr.ig_ft.doh.$valid: H7(15) - hdr.ig_ft.srv6_h2h_ifit.$valid: B12(0) - hdr.ext_tunnel_decap.$valid: B13(0) - hdr.ig_ft.ethernet.$valid: B12(1) - hdr.ig_ft.ipv4.$valid: B12(2) - hdr.ig_ft.ipv4_option.$valid: B12(3) - hdr.ig_ft.br_tag.$valid: { stage 0..13: B12(4) } - hdr.ext_srv6.$valid: { stage 17..20: B13(2) } - hdr.fabric_qos_encap.$valid: { stage 7..20: B9(6) } - hdr.ext_ifit_encap.$valid: { stage 16..20: B12(5) } - hdr.bridged_md_12_encap.$valid: { stage 19..20: B9(7) } - hdr.switch_bridged_src.$valid: { stage 19..20: B10(5) } - hdr.ig_ft.srv6_list.$stkvalid: H6(0..10) - hdr.ig_ft.srv6_list$0.$valid: { stage 4..20: H6(10) } - hdr.ig_ft.srv6_list$1.$valid: { stage 4..20: H6(9) } - hdr.ig_ft.srv6_list$2.$valid: { stage 4..20: H6(8) } - hdr.ig_ft.srv6_list$3.$valid: { stage 4..20: H6(7) } - hdr.ig_ft.srv6_list$4.$valid: { stage 4..20: H6(6) } - hdr.ig_ft.srv6_list$5.$valid: { stage 4..20: H6(5) } - hdr.ig_ft.srv6_list$6.$valid: { stage 4..20: H6(4) } - hdr.ig_ft.srv6_list$7.$valid: { stage 4..20: H6(3) } - hdr.ig_ft.srv6_list$8.$valid: { stage 4..20: H6(2) } - hdr.ig_ft.srv6_list$9.$valid: { stage 4..20: H6(1) } - hdr.ig_ft.srv6_list$10.$valid: H6(0) - hdr.ig_ft.vlan_tag.$stkvalid: B10(0..1) - hdr.ig_ft.vlan_tag$0.$valid: B10(1) - hdr.ig_ft.vlan_tag$1.$valid: { stage 1..20: B10(0) } - hdr.ig_ft.mpls_ig.$stkvalid: B8 - hdr.ig_ft.mpls_ig$0.$valid: B8(7) - hdr.ig_ft.mpls_ig$1.$valid: { stage 5..20: B8(6) } - hdr.ig_ft.mpls_ig$2.$valid: { stage 5..20: B8(5) } - hdr.ig_ft.mpls_ig$3.$valid: { stage 5..20: B8(4) } - hdr.ig_ft.mpls_ig$4.$valid: B8(3) - hdr.ig_ft.mpls2_ig.$stkvalid: B9(0..4) - hdr.ig_ft.mpls2_ig$0.$valid: { stage 15..20: B9(4) } - hdr.ig_ft.mpls2_ig$1.$valid: { stage 20: B9(3) } - hdr.ig_ft.mpls2_ig$2.$valid: { stage 20: B9(2) } - hdr.ig_ft.mpls2_ig$3.$valid: { stage 20: B9(1) } - hdr.ig_ft.mpls2_ig$4.$valid: B9(0) - context_json: - DB8: - - { name : hdr.ig_ft.srv6_h2h_ifit.reserved3, live_start : 1, live_end : 15, mutually_exclusive_with: [ ] } - DB12: - - { name : hdr.ig_ft.doh_e2e.hdr_ext_len, live_start : 1, live_end : 8, mutually_exclusive_with: [ ] } - DB13: - - { name : hdr.ig_ft.doh_e2e.next_hdr, live_start : 1, live_end : 8, mutually_exclusive_with: [ ] } - DH0: - - { name : ig_md.ig_ft.tunnel.ttl_2, live_start : 6, live_end : 8, mutually_exclusive_with: [ ] } - DH1: - - { name : ig_md.ig_ft.tunnel.ttl_3, live_start : 7, live_end : 8, mutually_exclusive_with: [ ] } - DH2: - - { name : ig_md.ig_ft.tunnel.ttl_4, live_start : 8, live_end : 8, mutually_exclusive_with: [ ] } - DH3: - - { name : ig_md.ig_ft.srv6.g_sid, live_start : 2, live_end : 7, mutually_exclusive_with: [ ] } - DH8: - - { name : hdr.ig_ft.doh_e2e.option_type, live_start : 1, live_end : 16, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.doh_e2e.option_len, live_start : 1, live_end : 16, mutually_exclusive_with: [ ] } - DH12: - - { name : ig_md.ig_ft.srv6.g_sid, live_start : 2, live_end : 7, mutually_exclusive_with: [ ] } - DH13: - - { name : hdr.ig_ft.mpls_ig$4.label, live_start : 12, live_end : 18, mutually_exclusive_with: [ ] } - DH14: - - { name : hdr.ig_ft.mpls_ig$3.label, live_start : 16, live_end : 18, mutually_exclusive_with: [ ] } - DH16: - - { name : hdr.fabric_trace.timestamp, live_start : 9, live_end : 9, mutually_exclusive_with: [ ] } - DH20: - - { name : ig_intr_md.ingress_port, live_start : 9, live_end : 13, mutually_exclusive_with: [ ] } - DW0: - - { name : ig_md.ig_ft.srv6.sid, live_start : 2, live_end : 8, mutually_exclusive_with: [ ] } - DW1: - - { name : ig_md.ig_ft.srv6.g_sid, live_start : 2, live_end : 7, mutually_exclusive_with: [ ] } - DW2: - - { name : ig_md.ig_ft.srv6.g_sid, live_start : 2, live_end : 7, mutually_exclusive_with: [ ] } - DW3: - - { name : ig_md.ig_ft.srv6.g_sid, live_start : 2, live_end : 7, mutually_exclusive_with: [ ] } - DW4: - - { name : ig_md.ig_ft.srv6.sid, live_start : 2, live_end : 8, mutually_exclusive_with: [ ] } - DW5: - - { name : ig_md.ig_ft.srv6.sid, live_start : 2, live_end : 8, mutually_exclusive_with: [ ] } - DW8: - - { name : ig_md.ig_ft.srv6.sid, live_start : 2, live_end : 8, mutually_exclusive_with: [ ] } - MB0: - - { name : ig_md.ig_ft.lkp.srv6_ip_proto, live_start : 0, live_end : 1, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.mirror.src, live_start : 17, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.mirror.type, live_start : 17, live_end : deparser, mutually_exclusive_with: [ ] } - MB1: - - { name : ig_md.ig_ft.srv6.next_hdr, live_start : 2, live_end : 14, mutually_exclusive_with: [ ] } - MB2: - - { name : ig_md.ig_ft.tunnel.decap_num, live_start : 9, live_end : 9, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.mirror.flags, live_start : 17, live_end : deparser, mutually_exclusive_with: [ ] } - MB4: - - { name : hdr.ig_ft.srv6_srh.next_hdr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4.protocol ] } - - { name : hdr.ig_ft.ipv4.protocol, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.srv6_srh.next_hdr ] } - MB5: - - { name : hdr.ig_ft.doh.next_hdr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4.frag_offset ] } - - { name : hdr.ig_ft.ipv4.frag_offset, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.doh.next_hdr ] } - MB6: - - { name : hdr.ig_ft.ipv6.next_hdr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4_option.type ] } - - { name : hdr.ig_ft.ipv4_option.type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.next_hdr ] } - MB7: - - { name : ig_md.ig_ft.mirror.session_id, live_start : 3, live_end : deparser, mutually_exclusive_with: [ ] } - MB8: - - { name : ig_md.ig_ft.srv6.pf_downgrade, live_start : parser, live_end : 8, mutually_exclusive_with: [ ] } - MB10: - - { name : ig_md.ig_ft.ifit.hti, live_start : parser, live_end : 15, mutually_exclusive_with: [ ] } - MB12: - - { name : ig_md.ig_ft.ifit.loss_label, live_start : parser, live_end : 15, mutually_exclusive_with: [ ] } - MB13: - - { name : ig_md.ig_ft.common.src_port, live_start : 1, live_end : deparser, mutually_exclusive_with: [ ] } - MB14: - - { name : ig_md.ig_ft.ifit.delay_label, live_start : parser, live_end : 15, mutually_exclusive_with: [ ] } - MB15: - - { name : ig_md.ig_ft.common.pipeline_location, live_start : 19, live_end : deparser, mutually_exclusive_with: [ ] } - MH0: - - { name : ig_md.ig_ft.lkp.ip_ttl, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } - MH4: - - { name : ig_md.ig_ft.tunnel.is_ilm_continue, live_start : 6, live_end : 7, mutually_exclusive_with: [ ig_md.ig_ft.tunnel.tmp_oif ] } - - { name : ig_md.ig_ft.tunnel.tmp_oif, live_start : 7, live_end : 7, mutually_exclusive_with: [ ig_md.ig_ft.tunnel.is_ilm_continue ] } - MH5: - - { name : ig_md.ig_ft.tunnel.is_terminate, live_start : 6, live_end : 18, mutually_exclusive_with: [ ] } - MH6: - - { name : ig_md.ig_ft.common.eport, live_start : 1, live_end : 2, mutually_exclusive_with: [ ] } - MH9: - - { name : ig_md.ig_ft.ipfix.sample_gap, live_start : 3, live_end : 6, mutually_exclusive_with: [ ] } - MH11: - - { name : ig_md.ig_ft.common.ether_type, live_start : parser, live_end : 15, mutually_exclusive_with: [ ] } - MH12: - - { name : hdr.ig_ft.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4.src_addr ] } - - { name : hdr.ig_ft.ipv4.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.src_addr ] } - MH13: - - { name : ig_md.ig_ft.lkp.ip_src_addr, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } - MH14: - - { name : hdr.ig_ft.ethernet.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - MW0: - - { name : hdr.ig_ft.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4.dst_addr ] } - - { name : hdr.ig_ft.ipv4.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.src_addr ] } - MW1: - - { name : hdr.ig_ft.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - MW2: - - { name : hdr.ig_ft.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - MW3: - - { name : hdr.ig_ft.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - MW5: - - { name : ig_md.ig_ft.ifit.flow_id, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } - MW6: - - { name : hdr.ig_ft.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - MW7: - - { name : hdr.ig_ft.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - MW8: - - { name : hdr.ig_ft.ipv6.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.fabric_from_cpu_eth_ccm.dev_port ] } - - { name : hdr.fabric_from_cpu_eth_ccm.dev_port, live_start : parser, live_end : 12, mutually_exclusive_with: [ hdr.ig_ft.ipv6.dst_addr ] } - MW9: - - { name : ig_intr_md_for_tm.ucast_egress_port, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } - MW10: - - { name : ig_md.ig_ft.ifit.flow_node_id, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } - MW11: - - { name : hdr.fabric_trace.timestamp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - MW14: - - { name : hdr.ig_ft.ethernet.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - MW15: - - { name : hdr.ig_ft.ethernet.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B0: - - { name : $tmp11, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - B1: - - { name : ig_intr_md_for_dprsr.mirror_type, live_start : 17, live_end : deparser, mutually_exclusive_with: [ ] } - B5: - - { name : ig_md.ig_ft.mirror.span_flag, live_start : 6, live_end : 18, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.qos.acl_meter_color, live_start : 11, live_end : 15, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.qos.lif_trust_mode, live_start : 4, live_end : 5, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.qos.lif_meter_color, live_start : 13, live_end : 15, mutually_exclusive_with: [ ] } - B6: - - { name : ig_md.ig_ft.mirror.ifit_flag, live_start : 14, live_end : 18, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.qos.acl_meter_index, live_start : 5, live_end : 10, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.qos.set_dscp, live_start : 12, live_end : 12, mutually_exclusive_with: [ ] } - B8: - - { name : hdr.ig_ft.mpls_ig$4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.mpls_ig.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.mpls_ig$0.$valid, live_start : 0, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.mpls_ig$1.$valid, live_start : 5, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.mpls_ig$2.$valid, live_start : 5, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.mpls_ig$3.$valid, live_start : 5, live_end : deparser, mutually_exclusive_with: [ ] } - B9: - - { name : ig_intr_md_for_tm.qid.$valid, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_qos_encap.$valid, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.bridged_md_12_encap.$valid, live_start : 19, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.mpls2_ig$4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.mpls2_ig.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.mpls2_ig$0.$valid, live_start : 15, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.mpls2_ig$1.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.mpls2_ig$2.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.mpls2_ig$3.$valid, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - B10: - - { name : ig_md.ig_ft.srv6.pf_bypass, live_start : 1, live_end : 7, mutually_exclusive_with: [ ] } - - { name : ig_intr_md_for_dprsr.drop_ctl.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.policer.mac_drop, live_start : 5, live_end : 15, mutually_exclusive_with: [ ] } - - { name : ig_intr_md_for_tm.ucast_egress_port.$valid, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_base.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.switch_bridged_src.$valid, live_start : 19, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.vlan_tag$0.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.vlan_tag.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.vlan_tag$1.$valid, live_start : 1, live_end : deparser, mutually_exclusive_with: [ ] } - B11: - - { name : hdr.ext_srv6.ext_type, live_start : 17, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ext_srv6.extend, live_start : 18, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ext_srv6.bypass_L3, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ext_srv6.level, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ext_srv6.is_ecmp, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } - B12: - - { name : ig_md.ig_ft.route.rmac_hit, live_start : 1, live_end : 18, mutually_exclusive_with: [ ] } - - { name : ig_intr_md_for_tm.bypass_egress, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.srv6_h2h_ifit.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.ethernet.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.ipv4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.ipv4_option.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.br_tag.$valid, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - - { name : hdr.ext_ifit_encap.$valid, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } - B13: - - { name : ig_md.ig_ft.srv6.srh_terminate, live_start : 9, live_end : 14, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.common.from_cpu, live_start : 1, live_end : 18, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.common.extend, live_start : 1, live_end : 18, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.common.diag, live_start : 1, live_end : 18, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.ebridge.is_iif_block, live_start : 4, live_end : 18, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_data_template_plus.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ext_tunnel_decap.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ext_srv6.$valid, live_start : 17, live_end : deparser, mutually_exclusive_with: [ ] } - B14: - - { name : hdr.ig_ft.srv6_srh.seg_left, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4.flags, hdr.ig_ft.ipv4.frag_offset ] } - - { name : hdr.ig_ft.ipv4.flags, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.srv6_srh.seg_left ] } - - { name : hdr.ig_ft.ipv4.frag_offset, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.srv6_srh.seg_left ] } - B15: - - { name : hdr.fabric_data_template_plus.flags, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B18: - - { name : ig_md.ig_ft.lkp.ip_proto, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } - B28: - - { name : hdr.switch_bridged_src.src, live_start : 19, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.switch_bridged_src.bridge_type, live_start : 19, live_end : deparser, mutually_exclusive_with: [ ] } - B29: - - { name : hdr.fabric_qos_encap.data, live_start : 19, live_end : deparser, mutually_exclusive_with: [ ] } - B30: - - { name : ig_md.ig_ft.common.drop_reason, live_start : 6, live_end : deparser, mutually_exclusive_with: [ ] } - B31: - - { name : hdr.ig_ft.srv6_h2h_ifit.reserved3, live_start : 0, live_end : 0, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.srv6_h2h_ifit.reserved3, live_start : 16, live_end : 19, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.tunnel.type, live_start : 1, live_end : 15, mutually_exclusive_with: [ ] } - B34: - - { name : ig_md.ig_ft.srv6.tmp_no_frr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.common.redirect_recirc, live_start : 14, live_end : 17, mutually_exclusive_with: [ ] } - B35: - - { name : ig_md.ig_ft.srv6.sl_flag, live_start : 9, live_end : 14, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.ifit.endpoint_enable, live_start : 6, live_end : 17, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.common.bridge_type, live_start : 1, live_end : 18, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.qos.is_auto_trust, live_start : 4, live_end : 15, mutually_exclusive_with: [ ] } - B36: - - { name : hdr.fabric_data_template_plus.vb, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B37: - - { name : ig_md.ig_ft.common.pkt_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_base.pkt_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_base.is_mirror, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_base.is_mcast, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B38: - - { name : hdr.ext_tunnel_decap.ext_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ext_tunnel_decap.extend, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ext_tunnel_decap.sub_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B39: - - { name : hdr.ext_tunnel_decap.vb, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B40: - - { name : hdr.ig_ft.ipv6.traffic_class, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4.diffserv ] } - - { name : hdr.ig_ft.ipv6.flow_label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4.diffserv ] } - - { name : hdr.ig_ft.ipv4.diffserv, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.traffic_class, hdr.ig_ft.ipv6.flow_label ] } - B41: - - { name : hdr.ig_ft.ipv6.version, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.ipv6.traffic_class, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B44: - - { name : ig_md.ig_ft.lkp.ip_tos, live_start : 1, live_end : 8, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.qos.dscp, live_start : 12, live_end : 12, mutually_exclusive_with: [ ] } - B45: - - { name : ig_md.ig_ft.lkp.ip_tos, live_start : 1, live_end : 8, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.doh_e2e.next_hdr, live_start : 0, live_end : 0, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.doh_e2e.next_hdr, live_start : 9, live_end : 19, mutually_exclusive_with: [ ] } - B46: - - { name : ig_md.ig_ft.lkp.ip_tos, live_start : 1, live_end : 8, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.doh_e2e.hdr_ext_len, live_start : 0, live_end : 0, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.doh_e2e.hdr_ext_len, live_start : 9, live_end : 19, mutually_exclusive_with: [ ] } - B47: - - { name : hdr.ig_ft.vxlan.vni, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.srv6_srh.last_entry ] } - - { name : hdr.ig_ft.srv6_srh.last_entry, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.vxlan.vni ] } - H0: - - { name : hdr.ig_ft.ipv6.payload_len, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4.src_addr, hdr.ig_ft.mpls_ig$4.label, hdr.ig_ft.mpls_ig$4.exp, hdr.ig_ft.mpls_ig$4.bos, hdr.ig_ft.mpls_ig$4.ttl ] } - - { name : hdr.ig_ft.ipv4.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.payload_len, hdr.ig_ft.mpls_ig$4.label, hdr.ig_ft.mpls_ig$4.exp, hdr.ig_ft.mpls_ig$4.bos, hdr.ig_ft.mpls_ig$4.ttl ] } - - { name : hdr.ig_ft.mpls_ig$4.label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.payload_len, hdr.ig_ft.ipv4.src_addr ] } - - { name : hdr.ig_ft.mpls_ig$4.exp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.payload_len, hdr.ig_ft.ipv4.src_addr ] } - - { name : hdr.ig_ft.mpls_ig$4.bos, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.payload_len, hdr.ig_ft.ipv4.src_addr ] } - - { name : hdr.ig_ft.mpls_ig$4.ttl, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.payload_len, hdr.ig_ft.ipv4.src_addr ] } - H1: - - { name : hdr.fabric_data_template_plus.vh2, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.br_tag.ecid ] } - - { name : hdr.ig_ft.br_tag.ecid, live_start : parser, live_end : 0, mutually_exclusive_with: [ hdr.fabric_data_template_plus.vh2 ] } - H2: - - { name : hdr.ig_ft.ipv6.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv4_option.length, hdr.ig_ft.ipv4_option.value, hdr.ig_ft.mpls_ig$3.label, hdr.ig_ft.mpls_ig$3.exp, hdr.ig_ft.mpls_ig$3.bos, hdr.ig_ft.mpls_ig$3.ttl ] } - - { name : hdr.ig_ft.ipv4_option.length, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.src_addr, hdr.ig_ft.mpls_ig$3.label, hdr.ig_ft.mpls_ig$3.exp, hdr.ig_ft.mpls_ig$3.bos, hdr.ig_ft.mpls_ig$3.ttl ] } - - { name : hdr.ig_ft.ipv4_option.value, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.src_addr, hdr.ig_ft.mpls_ig$3.label, hdr.ig_ft.mpls_ig$3.exp, hdr.ig_ft.mpls_ig$3.bos, hdr.ig_ft.mpls_ig$3.ttl ] } - - { name : hdr.ig_ft.mpls_ig$3.label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.src_addr, hdr.ig_ft.ipv4_option.length, hdr.ig_ft.ipv4_option.value ] } - - { name : hdr.ig_ft.mpls_ig$3.exp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.src_addr, hdr.ig_ft.ipv4_option.length, hdr.ig_ft.ipv4_option.value ] } - - { name : hdr.ig_ft.mpls_ig$3.bos, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.src_addr, hdr.ig_ft.ipv4_option.length, hdr.ig_ft.ipv4_option.value ] } - - { name : hdr.ig_ft.mpls_ig$3.ttl, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.src_addr, hdr.ig_ft.ipv4_option.length, hdr.ig_ft.ipv4_option.value ] } - H3: - - { name : hdr.ig_ft.ipv6.flow_label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.mpls_ig$2.label, hdr.ig_ft.mpls_ig$2.exp, hdr.ig_ft.mpls_ig$2.bos, hdr.ig_ft.mpls_ig$2.ttl ] } - - { name : hdr.ig_ft.mpls_ig$2.label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.flow_label ] } - - { name : hdr.ig_ft.mpls_ig$2.exp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.flow_label ] } - - { name : hdr.ig_ft.mpls_ig$2.bos, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.flow_label ] } - - { name : hdr.ig_ft.mpls_ig$2.ttl, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.ipv6.flow_label ] } - H4: - - { name : hdr.ig_ft.vxlan.vni, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.srv6_h2h_ifit.reserved3, hdr.ig_ft.mpls_ig$1.label, hdr.ig_ft.mpls_ig$1.exp, hdr.ig_ft.mpls_ig$1.bos, hdr.ig_ft.mpls_ig$1.ttl ] } - - { name : hdr.ig_ft.srv6_h2h_ifit.reserved3, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.vxlan.vni, hdr.ig_ft.mpls_ig$1.label, hdr.ig_ft.mpls_ig$1.exp, hdr.ig_ft.mpls_ig$1.bos, hdr.ig_ft.mpls_ig$1.ttl ] } - - { name : hdr.ig_ft.mpls_ig$1.label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.vxlan.vni, hdr.ig_ft.srv6_h2h_ifit.reserved3 ] } - - { name : hdr.ig_ft.mpls_ig$1.exp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.vxlan.vni, hdr.ig_ft.srv6_h2h_ifit.reserved3 ] } - - { name : hdr.ig_ft.mpls_ig$1.bos, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.vxlan.vni, hdr.ig_ft.srv6_h2h_ifit.reserved3 ] } - - { name : hdr.ig_ft.mpls_ig$1.ttl, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.ig_ft.vxlan.vni, hdr.ig_ft.srv6_h2h_ifit.reserved3 ] } - H5: - - { name : hdr.ig_ft.mpls_ig$0.label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.mpls_ig$0.exp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.mpls_ig$0.bos, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.mpls_ig$0.ttl, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H6: - - { name : ig_md.ig_ft.tunnel.inner_pkt_parsed, live_start : 3, live_end : 14, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.tunnel.is_cw, live_start : 8, live_end : 14, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.qos.BA, live_start : 4, live_end : 18, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.srv6_list$10.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.srv6_list.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.srv6_list$0.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.srv6_list$1.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.srv6_list$2.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.srv6_list$3.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.srv6_list$4.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.srv6_list$5.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.srv6_list$6.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.srv6_list$7.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.srv6_list$8.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.srv6_list$9.$valid, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } - H7: - - { name : ig_intr_md_for_dprsr.mirror_type.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_intr_md_for_tm.bypass_egress.$valid, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_intr_md_for_tm.deflect_on_drop.$valid, live_start : 19, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_intr_md_for_dprsr.mirror_io_select.$valid, live_start : 19, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_trace.$valid, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.ipv6.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.udp.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.vxlan.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.inner_ethernet.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.inner_ipv4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.inner_ipv6.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.inner_vlan_tag.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.srv6_srh.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.doh_e2e.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.srv6_e2e_ifit.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.doh.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H8: - - { name : ig_md.ig_ft.srv6.prefixlen, live_start : 7, live_end : 8, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.srv6.ext_flag, live_start : 7, live_end : 16, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.flags.ipv4_checksum_err, live_start : parser, live_end : 15, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.flags.inner_ipv4_checksum_err, live_start : parser, live_end : 10, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.route.ipv6_unicast_enable, live_start : 4, live_end : 11, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.tunnel.mpls_enable, live_start : 1, live_end : 15, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.tunnel.is_ttl_copy, live_start : 1, live_end : 18, mutually_exclusive_with: [ ] } - H10: - - { name : ig_md.ig_ft.lkp.ip_src_addr, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } - H12: - - { name : ig_md.ig_ft.flags.tunnel_info, live_start : 13, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.route.vrf, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.tunnel.ipv4_true, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : $pad18, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - H13: - - { name : hdr.fabric_data_template_plus.one, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_data_template_plus.iif, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H14: - - { name : ig_md.ig_ft.common.ul_iif, live_start : 1, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : $pad15, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - H15: - - { name : ig_md.ig_ft.common.iif, live_start : 1, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : $pad14, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - H16: - - { name : ig_md.ig_ft.srv6.tmp_info, live_start : 10, live_end : 15, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.srv6.sl_minus_flag, live_start : 1, live_end : 8, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.common.eport, live_start : 1, live_end : 2, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.common.vpntovpn_flag, live_start : 14, live_end : 16, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.mirror.meter_id, live_start : 6, live_end : 6, mutually_exclusive_with: [ ] } - H17: - - { name : hdr.fabric_data_template_plus.vh3, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H18: - - { name : hdr.ext_tunnel_decap.vh, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H19: - - { name : hdr.fabric_data_template_plus.vh1, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H20: - - { name : ig_md.ig_ft.lkp.tmp_ipv4_checksum, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.common.usi, live_start : 3, live_end : 4, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.ebridge.evlan, live_start : 5, live_end : 18, mutually_exclusive_with: [ ] } - H21: - - { name : hdr.ext_ifit_encap.var_h1, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } - H22: - - { name : ig_md.ig_ft.lkp.mac_src_addr, live_start : 0, live_end : 2, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.lkp.ip_frag, live_start : 3, live_end : 8, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.ifit.index, live_start : 9, live_end : 17, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.route.ipv4_unicast_enable, live_start : 4, live_end : 6, mutually_exclusive_with: [ ] } - - { name : ul_lif_properties_check_usi_states_0, live_start : 5, live_end : 5, mutually_exclusive_with: [ ] } - - { name : hdr.ext_ifit_encap.ext_type, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ext_ifit_encap.extend, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ext_ifit_encap.index, live_start : 9, live_end : 17, mutually_exclusive_with: [ ] } - H23: - - { name : hdr.ig_ft.ethernet.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H24: - - { name : hdr.bridged_md_12_encap.decap_len, live_start : 18, live_end : deparser, mutually_exclusive_with: [ ] } - H28: - - { name : hdr.ig_ft.doh_e2e.option_type, live_start : 0, live_end : 0, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.doh_e2e.option_type, live_start : 17, live_end : 19, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.doh_e2e.option_len, live_start : 0, live_end : 0, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.doh_e2e.option_len, live_start : 17, live_end : 19, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.tunnel.decap_pre_len, live_start : 1, live_end : 16, mutually_exclusive_with: [ ] } - H29: - - { name : ig_md.ig_ft.lkp.tcp_flags, live_start : 0, live_end : 8, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.common.decap_len, live_start : 10, live_end : 17, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.policer.slice1.vag_classid, live_start : 3, live_end : 3, mutually_exclusive_with: [ ] } - H30: - - { name : ig_md.ig_ft.srv6.is_end_as, live_start : 10, live_end : 14, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.tunnel.is_pre_len_add, live_start : 14, live_end : 16, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.ipfix.random_num, live_start : 1, live_end : 9, mutually_exclusive_with: [ ] } - - { name : ig_intr_md_for_tm.qid, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } - H31: - - { name : ig_md.ig_ft.tunnel.source_id, live_start : 10, live_end : 15, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.ipfix.delta, live_start : 5, live_end : 5, mutually_exclusive_with: [ ] } - - { name : ig_intr_md_for_dprsr.mirror_io_select, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_intr_md_for_tm.deflect_on_drop, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } - H36: - - { name : hdr.ig_ft.mpls_ig$4.label, live_start : 0, live_end : 11, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.mpls_ig$4.label, live_start : 19, live_end : 19, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.qos.chgDSCP_disable, live_start : 12, live_end : 18, mutually_exclusive_with: [ ] } - H37: - - { name : ig_md.ig_ft.flags.drop, live_start : 16, live_end : 18, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.mpls_ig$3.label, live_start : 0, live_end : 15, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.mpls_ig$3.label, live_start : 19, live_end : 19, mutually_exclusive_with: [ ] } - H38: - - { name : hdr.ig_ft.mpls_ig$2.label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H39: - - { name : hdr.ig_ft.mpls_ig$1.label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H40: - - { name : hdr.ig_ft.mpls_ig$0.label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H43: - - { name : hdr.fabric_trace.trace_counter, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.srv6.end_flag, live_start : 10, live_end : 14, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.lkp.l4_port_label_32, live_start : 1, live_end : 8, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.tunnel.src_netport_group, live_start : 10, live_end : 15, mutually_exclusive_with: [ ] } - H52: - - { name : hdr.fabric_trace.timestamp, live_start : 0, live_end : 8, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_trace.timestamp, live_start : 10, live_end : 19, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.ipfix.random_flag, live_start : 9, live_end : 9, mutually_exclusive_with: [ ] } - H53: - - { name : hdr.fabric_data_template_plus.vh0, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H54: - - { name : ig_md.ig_ft.ifit.var_h1, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } - H55: - - { name : hdr.ig_ft.ethernet.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H56: - - { name : ig_md.ig_ft.common.mirror_dst_eport, live_start : 6, live_end : deparser, mutually_exclusive_with: [ ] } - H57: - - { name : ig_md.ig_ft.srv6.lif_type, live_start : 10, live_end : 14, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.lkp.l4_port_label_32, live_start : 1, live_end : 8, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.common.trace_vh3, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.tunnel.evpn_end_type, live_start : 10, live_end : 15, mutually_exclusive_with: [ ] } - H64: - - { name : ig_md.ig_ft.lkp.mac_dst_addr, live_start : parser, live_end : 15, mutually_exclusive_with: [ ] } - H65: - - { name : ig_intr_md.ingress_port, live_start : 0, live_end : 8, mutually_exclusive_with: [ ] } - - { name : ig_intr_md.ingress_port, live_start : 14, live_end : 15, mutually_exclusive_with: [ ] } - - { name : cpu_egress_port_mapping_fabric_lag_flag, live_start : 9, live_end : 10, mutually_exclusive_with: [ ] } - H66: - - { name : ig_md.ig_ft.lkp.l4_src_port, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } - H67: - - { name : ig_md.ig_ft.lkp.vid, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } - H69: - - { name : hdr.fabric_qos.tc, live_start : parser, live_end : 6, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_qos.color, live_start : parser, live_end : 6, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_qos.track, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.ifit.dyna_learn_flag, live_start : 10, live_end : 15, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.ifit.ifit_decap_enable, live_start : 10, live_end : 15, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.policer.slice1.vag_classid, live_start : 3, live_end : 3, mutually_exclusive_with: [ ] } - H70: - - { name : ig_md.ig_ft.common.track, live_start : 1, live_end : 18, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.ipfix.flow_id, live_start : 3, live_end : 9, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.qos.meter_mode, live_start : 5, live_end : 9, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.qos.acl_meter_index, live_start : 5, live_end : 10, mutually_exclusive_with: [ ] } - H71: - - { name : ig_md.ig_ft.common.mac_type, live_start : 1, live_end : 16, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.qos.lif_ds, live_start : 4, live_end : 5, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.qos.color, live_start : 4, live_end : 18, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.qos.tc, live_start : 4, live_end : 18, mutually_exclusive_with: [ ] } - W0: - - { name : ig_md.ig_ft.srv6.c_sid, live_start : 8, live_end : 8, mutually_exclusive_with: [ ig_md.ig_ft.tunnel.is_ttl_copy_1, ig_md.ig_ft.tunnel.is_ttl_copy_2, ig_md.ig_ft.tunnel.is_ttl_copy_3 ] } - - { name : ig_md.ig_ft.tunnel.is_ttl_copy_1, live_start : 6, live_end : 8, mutually_exclusive_with: [ ig_md.ig_ft.srv6.c_sid ] } - - { name : ig_md.ig_ft.tunnel.is_ttl_copy_2, live_start : 7, live_end : 8, mutually_exclusive_with: [ ig_md.ig_ft.srv6.c_sid ] } - - { name : ig_md.ig_ft.tunnel.is_ttl_copy_3, live_start : 8, live_end : 8, mutually_exclusive_with: [ ig_md.ig_ft.srv6.c_sid ] } - W1: - - { name : ig_md.ig_ft.lkp.ip_src_addr, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } - W2: - - { name : ig_md.ig_ft.lkp.ip_src_addr, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } - W3: - - { name : ig_md.ig_ft.lkp.ip_src_addr, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } - W4: - - { name : ig_md.ig_ft.lkp.ip_dst_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - W5: - - { name : ig_md.ig_ft.srv6.args, live_start : 11, live_end : 12, mutually_exclusive_with: [ ] } - W6: - - { name : ig_md.ig_ft.srv6.si, live_start : 7, live_end : 9, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.tunnel.sub_type, live_start : 3, live_end : 15, mutually_exclusive_with: [ ] } - - { name : ig_intr_md_for_dprsr.drop_ctl, live_start : 4, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.policer.behavior_id, live_start : 5, live_end : 11, mutually_exclusive_with: [ ] } - W7: - - { name : hdr.ext_srv6.priority, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ext_srv6.nexthop, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ext_srv6.no_frr, live_start : 14, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ext_srv6.nexthop_ext, live_start : 7, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ext_srv6.is_pf, live_start : 10, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ext_srv6.is_endx_pf, live_start : 10, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ext_srv6.oam_flag, live_start : 9, live_end : deparser, mutually_exclusive_with: [ ] } - W10: - - { name : hdr.ig_ft.vlan_tag$0.pcp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.vlan_tag$0.cfi, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.vlan_tag$0.vid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.vlan_tag$0.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W11: - - { name : hdr.ig_ft.vlan_tag$1.pcp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.vlan_tag$1.cfi, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.vlan_tag$1.vid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ig_ft.vlan_tag$1.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W13: - - { name : ig_md.ig_ft.lkp.ip_dst_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - W14: - - { name : ig_md.ig_ft.srv6.args, live_start : 11, live_end : 12, mutually_exclusive_with: [ ] } - W15: - - { name : ig_md.ig_ft.lkp.ip_dst_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - W16: - - { name : ig_md.ig_ft.lkp.mac_dst_addr, live_start : parser, live_end : 15, mutually_exclusive_with: [ ] } - W17: - - { name : ig_md.ig_ft.lkp.mac_src_addr, live_start : parser, live_end : 2, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.common.tstamp_flag, live_start : 6, live_end : 18, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.tunnel.bypass_pw, live_start : 6, live_end : 15, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.ipfix.count, live_start : 6, live_end : 9, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.mirror.sample_flag, live_start : 9, live_end : 18, mutually_exclusive_with: [ ] } - W24: - - { name : ig_md.ig_ft.lkp.ip_dst_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - W28: - - { name : ig_md.ig_ft.srv6.global_pf_mode, live_start : 6, live_end : 8, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.lkp.flow_label, live_start : 0, live_end : 3, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.tunnel.is_vpn_terminate, live_start : 5, live_end : 15, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.tunnel.srv6_flavors, live_start : 5, live_end : 8, mutually_exclusive_with: [ ] } - W30: - - { name : ig_md.ig_ft.srv6.end_type, live_start : 5, live_end : 14, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.lkp.mac_src_addr, live_start : parser, live_end : 2, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.policer.slice2.vag_classid, live_start : 3, live_end : 8, mutually_exclusive_with: [ ] } - W31: - - { name : ig_md.ig_ft.lkp.l4_dst_port, live_start : parser, live_end : 11, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.policer.slice3.vag_classid, live_start : 3, live_end : 4, mutually_exclusive_with: [ ] } - W37: - - { name : ig_md.ig_ft.common.iif_type, live_start : 1, live_end : 18, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.qos.lif_meter_index, live_start : 4, live_end : 13, mutually_exclusive_with: [ ] } - W38: - - { name : ig_md.ig_ft.ifit.ifit_enable, live_start : 10, live_end : 15, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.common.hash_mode, live_start : 1, live_end : 4, mutually_exclusive_with: [ ] } - - { name : ig_md.ig_ft.tunnel.urpf_type, live_start : 2, live_end : 15, mutually_exclusive_with: [ ] } -phv egress: - eg_intr_md_from_prsr.global_tstamp.0-31: { stage 0..17: MW12 } - eg_intr_md_from_prsr.global_tstamp.32-47: { stage 0..17: H42 } - eg_intr_md_for_dprsr.drop_ctl: { stage 15..20: B16(1..3) } - eg_intr_md_for_dprsr.mirror_type: { stage 16..20: B4(0..3) } - eg_intr_md_for_dprsr.mirror_io_select: MH18(0) - eg_intr_md_for_dprsr.mtu_trunc_len: { stage 17..20: MH17(0..13) } - eg_intr_md_for_dprsr.mirror_io_select.$valid: H9(0) - eg_intr_md.egress_port: MH16(0..8) - eg_intr_md.deflection_flag: { stage 0..17: W36(24) } - eg_intr_md.egress_port.$valid: H9(1) - eg_md.eg_ft.common.mac_type: { stage 16..17: B2(2..3) } - eg_md.eg_ft.common.pkt_length: { stage 0..16: H25 } - eg_md.eg_ft.common.pkt_type: B25(2..7) - eg_md.eg_ft.common.cpu_eth_encap_id: { stage 0..16: B42 } - eg_md.eg_ft.common.decap_len: { stage 0: MH8 } - eg_md.eg_ft.common.dst_port: B20 - eg_md.eg_ft.common.backpush_dst_port: B21 - eg_md.eg_ft.common.mirror_dst_eport: { stage 11..20: H51 } - eg_md.eg_ft.common.hash: { stage 0..13: H61, stage 14..17: DH21, stage 18: H61 } - eg_md.eg_ft.common.iif: H49(0..14) - eg_md.eg_ft.common.oif: H50(0..14) - eg_md.eg_ft.common.from_cpu: { stage 0..17: W34(6) } - eg_md.eg_ft.common.diag: { stage 0..16: W34(5) } - eg_md.eg_ft.common.is_mirror: B25(1) - eg_md.eg_ft.common.is_mcast: B25(0) - eg_md.eg_ft.common.track: B24(0) - eg_md.eg_ft.common.deq_timedelta: MW4 - eg_md.eg_ft.common.ether_type: { stage 0..14: MH15 } - eg_md.eg_ft.common.drop_reason: { stage 15..20: MB11 } - eg_md.eg_ft.common.pipeline_location: { stage 18..20: B26 } - eg_md.eg_ft.common.trace_counter: { stage 17..20: H62 } - eg_md.eg_ft.common.cpu_color: { stage 15..16: B3(2..3) } - eg_md.eg_ft.common.ve_map_miss: { stage 5..14: H41(13) } - eg_md.eg_ft.common.timestamp_delta: { stage 1: W12 } - eg_md.eg_ft.qos.acl_meter_color: { stage 3..14: B3(0..1) } - eg_md.eg_ft.qos.set_dscp: { stage 13: W19(0) } - eg_md.eg_ft.qos.dscp: { stage 1..13: H35(0..5) } - eg_md.eg_ft.qos.qdepth: { stage 0..5: W29(0..18) } - eg_md.eg_ft.qos.tc: B24(5..7) - eg_md.eg_ft.qos.color: B24(3..4) - eg_md.eg_ft.qos.q_hi_flag: { stage 1..13: W33(0) } - eg_md.eg_ft.qos.q_lo_flag: { stage 6..13: B3(6) } - eg_md.eg_ft.qos.etm_flag: { stage 4..13: B3(4) } - eg_md.eg_ft.flags.bypass_acl: { stage 1..13: B43(0) } - eg_md.eg_ft.flags.bypass_sec_acl: { stage 0..13: W34(0) } - eg_md.eg_ft.flags.drop: { stage 0..17: W34(4) } - eg_md.eg_ft.lkp.vid: { stage 4..15: H41(0..11) } - eg_md.eg_ft.lkp.ip_src_addr.0-15: { stage 0..13: H63 } - eg_md.eg_ft.lkp.ip_src_addr.16-31: { stage 0..13: H58 } - eg_md.eg_ft.lkp.ip_src_addr.32-63: { stage 0..12: W18 } - eg_md.eg_ft.lkp.ip_src_addr.64-95: { stage 0..12: W19 } - eg_md.eg_ft.lkp.ip_src_addr.96-127: { stage 0..13: W20 } - eg_md.eg_ft.lkp.ip_dst_addr.0-31: { stage 0..13: W21 } - eg_md.eg_ft.lkp.ip_dst_addr.32-63: { stage 0..13: W22 } - eg_md.eg_ft.lkp.ip_dst_addr.64-95: { stage 0..13: W23 } - eg_md.eg_ft.lkp.ip_dst_addr.96-127: { stage 0..13: W25 } - eg_md.eg_ft.lkp.ip_proto: { stage 0..13: MB3 } - eg_md.eg_ft.lkp.l4_src_port: { stage 0..13: H59 } - eg_md.eg_ft.lkp.l4_dst_port: { stage 0..13: W32(0..15) } - eg_md.eg_ft.lkp.l4_port_label_64.0-31: { stage 0..13: W26 } - eg_md.eg_ft.lkp.l4_port_label_64.32-63: { stage 0..13: W27 } - eg_md.eg_ft.lkp.tcp_flags: { stage 0..13: W35(0..7) } - eg_md.eg_ft.lkp.ip_frag: { stage 0..13: W34(2..3) } - eg_md.eg_ft.lkp.tmp_ipv4_checksum: MH7 - eg_md.eg_ft.ebridge.evlan: { stage 0: W33(0..13), stage 1..15: DW9(0..13), stage 16: W33(0..13) } - eg_md.eg_ft.ebridge.encap_vlan_action: { stage 4..15: W40(8..11) } - eg_md.eg_ft.ifit.dyna_learn_flag: { stage 1..14: B2(1) } - eg_md.eg_ft.ifit.ifit_decap_enable: { stage 0..14: B43(4) } - eg_md.eg_ft.ifit.loss_label: { stage 0..14: B43(3) } - eg_md.eg_ft.ifit.delay_stats_flag: { stage 0..14: B43(2) } - eg_md.eg_ft.ifit.index: { stage 0..14: H68(0..11) } - eg_md.eg_ft.ifit.var_h1: { stage 14..20: H63 } - eg_md.eg_ft.ifit.counter_index.0-7: { stage 1..15: W39(0..7) } - eg_md.eg_ft.ifit.counter_index.8-12: { stage 1..15: B17(2..6) } - hdr.eg_ft.ethernet.dst_addr.0-31: W9 - hdr.eg_ft.ethernet.dst_addr.32-47: H48 - hdr.eg_ft.ethernet.src_addr.0-15: H32 - hdr.eg_ft.ethernet.src_addr.16-31: H33 - hdr.eg_ft.ethernet.src_addr.32-47: H60 - hdr.eg_ft.ethernet.ether_type: MH1 - hdr.eg_ft.ipv4.version: H34(12..15) - hdr.eg_ft.ipv4.ihl: H34(8..11) - hdr.eg_ft.ipv4.diffserv: H34(0..7) - hdr.eg_ft.ipv4.hdr_checksum: MH2 - hdr.eg_ft.ipv6.version: H34(12..15) - hdr.eg_ft.ipv6.traffic_class: H34(4..11) - hdr.eg_ft.ipv6.flow_label.0-15: { stage 0: H35, stage 1..13: DH9, stage 14..18: H35 } - hdr.eg_ft.ipv6.flow_label.16-19: H34(0..3) - hdr.eg_ft.vlan_tag$0.pcp: H45(13..15) - hdr.eg_ft.vlan_tag$0.cfi: H45(12) - hdr.eg_ft.vlan_tag$0.vid: H45(0..11) - hdr.eg_ft.vlan_tag$0.ether_type: MH22 - hdr.eg_ft.vlan_tag$1.pcp: H44(13..15) - hdr.eg_ft.vlan_tag$1.cfi: H44(12) - hdr.eg_ft.vlan_tag$1.vid: H44(0..11) - hdr.eg_ft.vlan_tag$1.ether_type: MH21 - hdr.fabric_base.pkt_type: B23(2..7) - hdr.fabric_base.is_mirror: B23(1) - hdr.fabric_base.is_mcast: B23(0) - hdr.fabric_qos.tc: B22(5..7) - hdr.fabric_qos.color: B22(3..4) - hdr.fabric_qos.chgDSCP_disable: B22(2) - hdr.fabric_qos.BA: B22(1) - hdr.fabric_qos.track: B22(0) - hdr.fabric_data_template_plus.vh1: MH20 - hdr.fabric_data_template_plus.vh3.0-7: { stage 0: B33, stage 1..12: DB11, stage 13..18: B33 } - hdr.fabric_data_template_plus.one: H11(15) - hdr.fabric_data_template_plus.iif: H11(0..14) - hdr.ext_tunnel_decap.vb: { stage 0: B32, stage 1..12: DB10, stage 13..18: B32 } - hdr.ext_tunnel_decap.vh: MH19 - hdr.eg_ft.br_tag.epcp: H47(13..15) - hdr.eg_ft.br_tag.edei: H47(12) - hdr.eg_ft.br_tag.ingress_ecid: H47(0..11) - hdr.eg_ft.br_tag.reserved: W8(30..31) - hdr.eg_ft.br_tag.grp: W8(28..29) - hdr.eg_ft.br_tag.ecid: W8(16..27) - hdr.eg_ft.br_tag.ingress_ecid_ext: W8(8..15) - hdr.eg_ft.br_tag.ecid_ext: W8(0..7) - hdr.eg_ft.br_tag.ether_type: MH2 - hdr.eg_ft.ethernet_evpn.ether_type: MH23 - eg_md.eg_ft.policer.slice1.vag_classid: { stage 1..13: W34(7..22) } - eg_md.eg_ft.policer.slice2.vag_classid: { stage 1..9: W35(8..23) } - eg_md.eg_ft.policer.slice3.vag_classid: { stage 1..2: W32(16..31) } - eg_md.eg_ft.mirror.session_id: { stage 1..20: MB9 } - eg_md.eg_ft.mirror.meter_id: { stage 11: W39(8..17) } - eg_md.eg_ft.mirror.sample_flag: { stage 3..17: B17(1) } - eg_md.eg_ft.mirror.span_flag: { stage 11..17: B2(0) } - eg_md.eg_ft.mirror.backpush_flag: { stage 14..15: W18(0..2) } - eg_md.eg_ft.mirror.flags: { stage 16..20: B27 } - eg_md.eg_ft.mirror.src: { stage 16..20: B19(5..7) } - eg_md.eg_ft.mirror.type: { stage 16..20: B19(0..4) } - eg_md.eg_ft.mirror.ifit_flag: { stage 14..17: H61(0) } - eg_md.eg_ft.ipfix.flow_id: { stage 3..12: W39(18..25) } - eg_md.eg_ft.ipfix.sample_gap: { stage 3..10: MH10 } - eg_md.eg_ft.ipfix.random_num: { stage 1..12: H26 } - eg_md.eg_ft.ipfix.count.0-7: { stage 1..12: B32 } - eg_md.eg_ft.ipfix.count.8-15: { stage 1..12: B33 } - eg_md.eg_ft.ipfix.delta: { stage 11: H27 } - eg_md.eg_ft.ipfix.random_flag: { stage 12: B7(6) } - eg_intr_md_for_dprsr.mirror_type.$valid: { stage 16..20: H9(2) } - eg_md.eg_ft.policer.mac_drop: { stage 3..14: H41(12) } - eg_md.eg_ft.policer.behavior_id.0-7: { stage 3..12: W40(0..7) } - eg_md.eg_ft.policer.behavior_id.8-11: { stage 3..12: B16(4..7) } - trace_latency_latency_track: { stage 1: B3(5) } - hdr.fabric_eth_etype.ether_type: { stage 15..20: MH3 } - hdr.fabric_timestamp.timestamp.0-31: { stage 15..20: MW13 } - hdr.fabric_timestamp.timestamp.32-47: { stage 15..20: H46 } - eg_md.eg_ft.tunnel.ptag_igmod: { stage 1..15: B7(7) } - eg_intr_md_for_dprsr.drop_ctl.$valid: { stage 15..20: B16(0) } - eg_intr_md_for_dprsr.mtu_trunc_len.$valid: { stage 17..20: B7(4) } - $pad20: { stage 20: H50(15) } - $pad21: { stage 20: H49(15) } - $pad22: { stage 20: B24(1..2) } - hdr.ext_ifit.$valid: { stage 0: H9(3) } - hdr.eg_ft.ethernet.$valid: H9(4) - hdr.eg_ft.ipv4.$valid: H9(5) - hdr.pad.$valid: B7(5) - hdr.eg_ft.ipv6.$valid: H9(6) - hdr.eg_ft.ipv6_frag.$valid: H9(7) - hdr.eg_ft.mpls_vc_eg.$valid: H9(8) - hdr.fabric_base.$valid: H9(9) - hdr.fabric_qos.$valid: H9(10) - hdr.fabric_data_template_plus.$valid: H9(11) - hdr.ext_tunnel_decap.$valid: H9(12) - hdr.eg_ft.br_tag.$valid: B17(0) - hdr.eg_ft.ethernet_evpn.$valid: H9(13) - hdr.fabric_eth_etype.$valid: { stage 15..20: H9(14) } - hdr.fabric_timestamp.$valid: { stage 15..20: H9(15) } - hdr.eg_ft.vlan_tag.$stkvalid: B7(0..3) - hdr.eg_ft.vlan_tag$0.$valid: { stage 2..20: B7(2) } - hdr.eg_ft.vlan_tag$1.$valid: B7(1) - Eg_front.backpush_mirror.hi_check_reg$ena: { stage 20..0: H41(14) } - Eg_front.backpush_mirror.hi_check_reg$index: { stage 20..0: W40(12..21) } - context_json: - DB10: - - { name : hdr.ext_tunnel_decap.vb, live_start : 1, live_end : 12, mutually_exclusive_with: [ ] } - DB11: - - { name : hdr.fabric_data_template_plus.vh3, live_start : 1, live_end : 12, mutually_exclusive_with: [ ] } - DH9: - - { name : hdr.eg_ft.ipv6.flow_label, live_start : 1, live_end : 13, mutually_exclusive_with: [ ] } - DH21: - - { name : eg_md.eg_ft.common.hash, live_start : 14, live_end : 17, mutually_exclusive_with: [ ] } - DW9: - - { name : eg_md.eg_ft.ebridge.evlan, live_start : 1, live_end : 15, mutually_exclusive_with: [ ] } - MB3: - - { name : eg_md.eg_ft.lkp.ip_proto, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - MB9: - - { name : eg_md.eg_ft.mirror.session_id, live_start : 1, live_end : deparser, mutually_exclusive_with: [ ] } - MB11: - - { name : eg_md.eg_ft.common.drop_reason, live_start : 15, live_end : deparser, mutually_exclusive_with: [ ] } - MH1: - - { name : hdr.eg_ft.ethernet.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - MH2: - - { name : hdr.eg_ft.ipv4.hdr_checksum, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.eg_ft.br_tag.ether_type ] } - - { name : hdr.eg_ft.br_tag.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.eg_ft.ipv4.hdr_checksum ] } - MH3: - - { name : hdr.fabric_eth_etype.ether_type, live_start : 15, live_end : deparser, mutually_exclusive_with: [ ] } - MH7: - - { name : eg_md.eg_ft.lkp.tmp_ipv4_checksum, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - MH8: - - { name : eg_md.eg_ft.common.decap_len, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } - MH10: - - { name : eg_md.eg_ft.ipfix.sample_gap, live_start : 3, live_end : 10, mutually_exclusive_with: [ ] } - MH15: - - { name : eg_md.eg_ft.common.ether_type, live_start : parser, live_end : 14, mutually_exclusive_with: [ ] } - MH16: - - { name : eg_intr_md.egress_port, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - MH17: - - { name : eg_intr_md_for_dprsr.mtu_trunc_len, live_start : 17, live_end : deparser, mutually_exclusive_with: [ ] } - MH18: - - { name : eg_intr_md_for_dprsr.mirror_io_select, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - MH19: - - { name : hdr.ext_tunnel_decap.vh, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - MH20: - - { name : hdr.fabric_data_template_plus.vh1, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - MH21: - - { name : hdr.eg_ft.vlan_tag$1.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - MH22: - - { name : hdr.eg_ft.vlan_tag$0.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - MH23: - - { name : hdr.eg_ft.ethernet_evpn.ether_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - MW4: - - { name : eg_md.eg_ft.common.deq_timedelta, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - MW12: - - { name : eg_intr_md_from_prsr.global_tstamp, live_start : parser, live_end : 17, mutually_exclusive_with: [ ] } - MW13: - - { name : hdr.fabric_timestamp.timestamp, live_start : 15, live_end : deparser, mutually_exclusive_with: [ ] } - B2: - - { name : eg_md.eg_ft.common.mac_type, live_start : 16, live_end : 17, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.ifit.dyna_learn_flag, live_start : 1, live_end : 14, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.mirror.span_flag, live_start : 11, live_end : 17, mutually_exclusive_with: [ ] } - B3: - - { name : eg_md.eg_ft.common.cpu_color, live_start : 15, live_end : 16, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.qos.acl_meter_color, live_start : 3, live_end : 14, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.qos.q_lo_flag, live_start : 6, live_end : 13, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.qos.etm_flag, live_start : 4, live_end : 13, mutually_exclusive_with: [ ] } - - { name : trace_latency_latency_track, live_start : 1, live_end : 1, mutually_exclusive_with: [ ] } - B4: - - { name : eg_intr_md_for_dprsr.mirror_type, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } - B7: - - { name : eg_md.eg_ft.ipfix.random_flag, live_start : 12, live_end : 12, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.tunnel.ptag_igmod, live_start : 1, live_end : 15, mutually_exclusive_with: [ ] } - - { name : eg_intr_md_for_dprsr.mtu_trunc_len.$valid, live_start : 17, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.pad.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.vlan_tag$1.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.vlan_tag.$stkvalid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.vlan_tag$0.$valid, live_start : 2, live_end : deparser, mutually_exclusive_with: [ ] } - B16: - - { name : eg_intr_md_for_dprsr.drop_ctl, live_start : 15, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.policer.behavior_id, live_start : 3, live_end : 12, mutually_exclusive_with: [ ] } - - { name : eg_intr_md_for_dprsr.drop_ctl.$valid, live_start : 15, live_end : deparser, mutually_exclusive_with: [ ] } - B17: - - { name : eg_md.eg_ft.ifit.counter_index, live_start : 1, live_end : 15, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.mirror.sample_flag, live_start : 3, live_end : 17, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.br_tag.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B19: - - { name : eg_md.eg_ft.mirror.src, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.mirror.type, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } - B20: - - { name : eg_md.eg_ft.common.dst_port, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B21: - - { name : eg_md.eg_ft.common.backpush_dst_port, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B22: - - { name : hdr.fabric_qos.tc, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_qos.color, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_qos.chgDSCP_disable, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_qos.BA, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_qos.track, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B23: - - { name : hdr.fabric_base.pkt_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_base.is_mirror, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_base.is_mcast, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B24: - - { name : eg_md.eg_ft.common.track, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.qos.tc, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.qos.color, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : $pad22, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - B25: - - { name : eg_md.eg_ft.common.pkt_type, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.common.is_mirror, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.common.is_mcast, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - B26: - - { name : eg_md.eg_ft.common.pipeline_location, live_start : 18, live_end : deparser, mutually_exclusive_with: [ ] } - B27: - - { name : eg_md.eg_ft.mirror.flags, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } - B32: - - { name : hdr.ext_tunnel_decap.vb, live_start : 0, live_end : 0, mutually_exclusive_with: [ ] } - - { name : hdr.ext_tunnel_decap.vb, live_start : 13, live_end : 18, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.ipfix.count, live_start : 1, live_end : 12, mutually_exclusive_with: [ ] } - B33: - - { name : hdr.fabric_data_template_plus.vh3, live_start : 0, live_end : 0, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_data_template_plus.vh3, live_start : 13, live_end : 18, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.ipfix.count, live_start : 1, live_end : 12, mutually_exclusive_with: [ ] } - B42: - - { name : eg_md.eg_ft.common.cpu_eth_encap_id, live_start : parser, live_end : 16, mutually_exclusive_with: [ ] } - B43: - - { name : eg_md.eg_ft.flags.bypass_acl, live_start : 1, live_end : 13, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.ifit.ifit_decap_enable, live_start : parser, live_end : 14, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.ifit.loss_label, live_start : parser, live_end : 14, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.ifit.delay_stats_flag, live_start : parser, live_end : 14, mutually_exclusive_with: [ ] } - H9: - - { name : eg_intr_md_for_dprsr.mirror_io_select.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : eg_intr_md.egress_port.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : eg_intr_md_for_dprsr.mirror_type.$valid, live_start : 16, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ext_ifit.$valid, live_start : parser, live_end : 0, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.ethernet.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.ipv4.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.ipv6.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.ipv6_frag.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.mpls_vc_eg.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_base.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_qos.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_data_template_plus.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.ext_tunnel_decap.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.ethernet_evpn.$valid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_eth_etype.$valid, live_start : 15, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_timestamp.$valid, live_start : 15, live_end : deparser, mutually_exclusive_with: [ ] } - H11: - - { name : hdr.fabric_data_template_plus.one, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.fabric_data_template_plus.iif, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H25: - - { name : eg_md.eg_ft.common.pkt_length, live_start : parser, live_end : 16, mutually_exclusive_with: [ ] } - H26: - - { name : eg_md.eg_ft.ipfix.random_num, live_start : 1, live_end : 12, mutually_exclusive_with: [ ] } - H27: - - { name : eg_md.eg_ft.ipfix.delta, live_start : 11, live_end : 11, mutually_exclusive_with: [ ] } - H32: - - { name : hdr.eg_ft.ethernet.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H33: - - { name : hdr.eg_ft.ethernet.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H34: - - { name : hdr.eg_ft.ipv4.version, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.eg_ft.ipv6.version, hdr.eg_ft.ipv6.traffic_class, hdr.eg_ft.ipv6.flow_label ] } - - { name : hdr.eg_ft.ipv4.ihl, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.eg_ft.ipv6.version, hdr.eg_ft.ipv6.traffic_class, hdr.eg_ft.ipv6.flow_label ] } - - { name : hdr.eg_ft.ipv4.diffserv, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.eg_ft.ipv6.version, hdr.eg_ft.ipv6.traffic_class, hdr.eg_ft.ipv6.flow_label ] } - - { name : hdr.eg_ft.ipv6.version, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.eg_ft.ipv4.version, hdr.eg_ft.ipv4.ihl, hdr.eg_ft.ipv4.diffserv ] } - - { name : hdr.eg_ft.ipv6.traffic_class, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.eg_ft.ipv4.version, hdr.eg_ft.ipv4.ihl, hdr.eg_ft.ipv4.diffserv ] } - - { name : hdr.eg_ft.ipv6.flow_label, live_start : parser, live_end : deparser, mutually_exclusive_with: [ hdr.eg_ft.ipv4.version, hdr.eg_ft.ipv4.ihl, hdr.eg_ft.ipv4.diffserv ] } - H35: - - { name : eg_md.eg_ft.qos.dscp, live_start : 1, live_end : 13, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.ipv6.flow_label, live_start : 0, live_end : 0, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.ipv6.flow_label, live_start : 14, live_end : 18, mutually_exclusive_with: [ ] } - H41: - - { name : eg_md.eg_ft.common.ve_map_miss, live_start : 5, live_end : 14, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.lkp.vid, live_start : 4, live_end : 15, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.policer.mac_drop, live_start : 3, live_end : 14, mutually_exclusive_with: [ ] } - - { name : Eg_front.backpush_mirror.hi_check_reg$ena, live_start : deparser, live_end : parser, mutually_exclusive_with: [ ] } - H42: - - { name : eg_intr_md_from_prsr.global_tstamp, live_start : parser, live_end : 17, mutually_exclusive_with: [ ] } - H44: - - { name : hdr.eg_ft.vlan_tag$1.pcp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.vlan_tag$1.cfi, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.vlan_tag$1.vid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H45: - - { name : hdr.eg_ft.vlan_tag$0.pcp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.vlan_tag$0.cfi, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.vlan_tag$0.vid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H46: - - { name : hdr.fabric_timestamp.timestamp, live_start : 15, live_end : deparser, mutually_exclusive_with: [ ] } - H47: - - { name : hdr.eg_ft.br_tag.epcp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.br_tag.edei, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.br_tag.ingress_ecid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H48: - - { name : hdr.eg_ft.ethernet.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H49: - - { name : eg_md.eg_ft.common.iif, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : $pad21, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - H50: - - { name : eg_md.eg_ft.common.oif, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : $pad20, live_start : deparser, live_end : deparser, mutually_exclusive_with: [ ] } - H51: - - { name : eg_md.eg_ft.common.mirror_dst_eport, live_start : 11, live_end : deparser, mutually_exclusive_with: [ ] } - H58: - - { name : eg_md.eg_ft.lkp.ip_src_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - H59: - - { name : eg_md.eg_ft.lkp.l4_src_port, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - H60: - - { name : hdr.eg_ft.ethernet.src_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - H61: - - { name : eg_md.eg_ft.common.hash, live_start : 0, live_end : 13, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.common.hash, live_start : 18, live_end : 18, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.mirror.ifit_flag, live_start : 14, live_end : 17, mutually_exclusive_with: [ ] } - H62: - - { name : eg_md.eg_ft.common.trace_counter, live_start : 17, live_end : deparser, mutually_exclusive_with: [ ] } - H63: - - { name : eg_md.eg_ft.lkp.ip_src_addr, live_start : 0, live_end : 13, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.ifit.var_h1, live_start : 14, live_end : deparser, mutually_exclusive_with: [ ] } - H68: - - { name : eg_md.eg_ft.ifit.index, live_start : parser, live_end : 14, mutually_exclusive_with: [ ] } - W8: - - { name : hdr.eg_ft.br_tag.reserved, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.br_tag.grp, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.br_tag.ecid, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.br_tag.ingress_ecid_ext, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - - { name : hdr.eg_ft.br_tag.ecid_ext, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W9: - - { name : hdr.eg_ft.ethernet.dst_addr, live_start : parser, live_end : deparser, mutually_exclusive_with: [ ] } - W12: - - { name : eg_md.eg_ft.common.timestamp_delta, live_start : 1, live_end : 1, mutually_exclusive_with: [ ] } - W18: - - { name : eg_md.eg_ft.lkp.ip_src_addr, live_start : 0, live_end : 12, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.mirror.backpush_flag, live_start : 14, live_end : 15, mutually_exclusive_with: [ ] } - W19: - - { name : eg_md.eg_ft.qos.set_dscp, live_start : 13, live_end : 13, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.lkp.ip_src_addr, live_start : 0, live_end : 12, mutually_exclusive_with: [ ] } - W20: - - { name : eg_md.eg_ft.lkp.ip_src_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - W21: - - { name : eg_md.eg_ft.lkp.ip_dst_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - W22: - - { name : eg_md.eg_ft.lkp.ip_dst_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - W23: - - { name : eg_md.eg_ft.lkp.ip_dst_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - W25: - - { name : eg_md.eg_ft.lkp.ip_dst_addr, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - W26: - - { name : eg_md.eg_ft.lkp.l4_port_label_64, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - W27: - - { name : eg_md.eg_ft.lkp.l4_port_label_64, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - W29: - - { name : eg_md.eg_ft.qos.qdepth, live_start : parser, live_end : 5, mutually_exclusive_with: [ ] } - W32: - - { name : eg_md.eg_ft.lkp.l4_dst_port, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.policer.slice3.vag_classid, live_start : 1, live_end : 2, mutually_exclusive_with: [ ] } - W33: - - { name : eg_md.eg_ft.qos.q_hi_flag, live_start : 1, live_end : 13, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.ebridge.evlan, live_start : 0, live_end : 0, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.ebridge.evlan, live_start : 16, live_end : 16, mutually_exclusive_with: [ ] } - W34: - - { name : eg_md.eg_ft.common.from_cpu, live_start : parser, live_end : 17, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.common.diag, live_start : parser, live_end : 16, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.flags.bypass_sec_acl, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.flags.drop, live_start : parser, live_end : 17, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.lkp.ip_frag, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.policer.slice1.vag_classid, live_start : 1, live_end : 13, mutually_exclusive_with: [ ] } - W35: - - { name : eg_md.eg_ft.lkp.tcp_flags, live_start : parser, live_end : 13, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.policer.slice2.vag_classid, live_start : 1, live_end : 9, mutually_exclusive_with: [ ] } - W36: - - { name : eg_intr_md.deflection_flag, live_start : parser, live_end : 17, mutually_exclusive_with: [ ] } - W39: - - { name : eg_md.eg_ft.ifit.counter_index, live_start : 1, live_end : 15, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.mirror.meter_id, live_start : 11, live_end : 11, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.ipfix.flow_id, live_start : 3, live_end : 12, mutually_exclusive_with: [ ] } - W40: - - { name : eg_md.eg_ft.ebridge.encap_vlan_action, live_start : 4, live_end : 15, mutually_exclusive_with: [ ] } - - { name : eg_md.eg_ft.policer.behavior_id, live_start : 3, live_end : 12, mutually_exclusive_with: [ ] } - - { name : Eg_front.backpush_mirror.hi_check_reg$index, live_start : deparser, live_end : parser, mutually_exclusive_with: [ ] } -parser ingress: - start: $entry_point - bitwise_or: [ MB4, MB5, B8, B9, B10, B12, B13, B14, B15, B36, B37, B38, B39, B40, B41, B46, B47, H6, H7 ] - clear_on_write: [ MB0, MB8, MB10, MB12, MB14, MH11, MH13, MH14, MW5, MW10, B18, H10, W1, W2, W3, W4, W13, W15, W24 ] - hdr_len_adj: 32 - states: - $entry_point: - *: - H7: 1 # value 1 -> H7 bit[0]: ingress::ig_intr_md_for_dprsr.mirror_type.$valid - load: { byte0 : 8 } - buf_req: 9 - next: start - start: - match: [ byte0 ] - 0x*a: - 0..1: H65 # bit[7..15] -> H65 bit[8..0]: ingress::ig_intr_md.ingress_port - 2..3: H52 # ingress::hdr.fabric_trace.timestamp[47:32].32-47 - 4..7: MW11 # ingress::hdr.fabric_trace.timestamp[31:0].0-31 - 9: MB8 # bit[79] -> MB8 bit[0]: ingress::ig_md.ig_ft.srv6.pf_downgrade - shift: 32 - buf_req: 32 - next: parse_signal - 0x*7: - 0..1: H65 # bit[7..15] -> H65 bit[8..0]: ingress::ig_intr_md.ingress_port - 2..3: H52 # ingress::hdr.fabric_trace.timestamp[47:32].32-47 - 4..7: MW11 # ingress::hdr.fabric_trace.timestamp[31:0].0-31 - 9: MB8 # bit[79] -> MB8 bit[0]: ingress::ig_md.ig_ft.srv6.pf_downgrade - load: { byte1 : 9 } - shift: 32 - buf_req: 32 - next: start.$oob_stall_0 - 0x**: - 0..1: H65 # bit[7..15] -> H65 bit[8..0]: ingress::ig_intr_md.ingress_port - 2..3: H52 # ingress::hdr.fabric_trace.timestamp[47:32].32-47 - 4..7: MW11 # ingress::hdr.fabric_trace.timestamp[31:0].0-31 - 9: MB8 # bit[79] -> MB8 bit[0]: ingress::ig_md.ig_ft.srv6.pf_downgrade - load: { byte1 : 9 } - shift: 32 - buf_req: 32 - next: start.$oob_stall_1 - parse_signal: - *: - priority: 7 - 0: B37 - # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type - # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror - # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast - 0..1: H69 - # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc - # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color - # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track - 2: B15 # ingress::hdr.fabric_data_template_plus.flags - 3: B36 # ingress::hdr.fabric_data_template_plus.vb - 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 - 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 - 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 - 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 - 12..13: H13 - # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one - # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif - B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid - B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid - shift: 14 - buf_req: 14 - next: end - start.$oob_stall_0: - *: - load: { byte0 : 0 } - buf_req: 1 - next: parse_fabric_recirc - parse_fabric_recirc: - match: [ byte0 ] - 0b011100**: - 0: B37 - # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type - # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror - # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast - 0..1: H69 - # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc - # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color - # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track - 2: B15 # ingress::hdr.fabric_data_template_plus.flags - 2: MB8 # bit[23] -> MB8 bit[0]: ingress::ig_md.ig_ft.srv6.pf_downgrade - 3: B36 # ingress::hdr.fabric_data_template_plus.vb - 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 - 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 - 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 - 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 - 12..13: H13 - # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one - # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif - B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid - B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid - load: { byte1 : 2 } - shift: 14 - buf_req: 14 - next: parse_ipv6 - 0b011111**: - load: { byte0 : 2 } - buf_req: 3 - next: parse_fabric_evpn_110 - 0b010011**: - 0: B37 - # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type - # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror - # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast - 0..1: H69 - # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc - # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color - # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track - 2: B15 # ingress::hdr.fabric_data_template_plus.flags - 3: B36 # ingress::hdr.fabric_data_template_plus.vb - 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 - 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 - 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 - 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 - 12..13: H13 - # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one - # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif - 14..15: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 - 16..19: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 - 20..21: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 - 22..25: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 - 26..27: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid - B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid - load: { byte0 : 26, byte1 : 27 } - shift: 28 - buf_req: 28 - next: parse_fabric_2544_pktgen.$split_0 - 0x**: - buf_req: 0 - next: end - parse_ipv6: - *: - 0: B41 - # - bit[0..3] -> B41 bit[7..4]: ingress::hdr.ig_ft.ipv6.version - # - bit[4..7] -> B41 bit[3..0]: ingress::hdr.ig_ft.ipv6.traffic_class[7:4].4-7 - 1: B40 - # - bit[8..11] -> B40 bit[7..4]: ingress::hdr.ig_ft.ipv6.traffic_class[3:0].0-3 - # - bit[12..15] -> B40 bit[3..0]: ingress::hdr.ig_ft.ipv6.flow_label[19:16].16-19 - 2..3: H3 # ingress::hdr.ig_ft.ipv6.flow_label[15:0].0-15 - 4..5: H0 # ingress::hdr.ig_ft.ipv6.payload_len - 6: MB6 # ingress::hdr.ig_ft.ipv6.next_hdr - 6: B18 # ingress::ig_md.ig_ft.lkp.ip_proto - 6: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto - 6..7: MH0 # bit[56..63] -> MH0 bit[7..0]: ingress::ig_md.ig_ft.lkp.ip_ttl - 8..11: MW0 # ingress::hdr.ig_ft.ipv6.src_addr[127:96].96-127 - 12..15: MW1 # ingress::hdr.ig_ft.ipv6.src_addr[95:64].64-95 - 16..19: MW2 # ingress::hdr.ig_ft.ipv6.src_addr[63:32].32-63 - 20..21: MH12 # ingress::hdr.ig_ft.ipv6.src_addr[31:16].16-31 - 22..23: H2 # ingress::hdr.ig_ft.ipv6.src_addr[15:0].0-15 - 24..27: MW8 # ingress::hdr.ig_ft.ipv6.dst_addr[127:96].96-127 - 28..31: MW7 # ingress::hdr.ig_ft.ipv6.dst_addr[95:64].64-95 - clot 27 : - start: 7 - length: 17 - load: { byte0 : 6 } - shift: 32 - buf_req: 32 - next: parse_ipv6.$split_0 - parse_ipv6.$split_0: - match: [ byte0 ] - 0x3a: - 0..3: MW6 # ingress::hdr.ig_ft.ipv6.dst_addr[63:32].32-63 - 4..7: MW3 # ingress::hdr.ig_ft.ipv6.dst_addr[31:0].0-31 - H7: 32 # value 1 -> H7 bit[5]: ingress::hdr.ig_ft.ipv6.$valid - shift: 8 - buf_req: 8 - next: parse_icmp - 0x06: - 0..3: MW6 # ingress::hdr.ig_ft.ipv6.dst_addr[63:32].32-63 - 4..7: MW3 # ingress::hdr.ig_ft.ipv6.dst_addr[31:0].0-31 - H7: 32 # value 1 -> H7 bit[5]: ingress::hdr.ig_ft.ipv6.$valid - shift: 8 - buf_req: 8 - next: parse_tcp - 0x11: - 0..3: MW6 # ingress::hdr.ig_ft.ipv6.dst_addr[63:32].32-63 - 4..7: MW3 # ingress::hdr.ig_ft.ipv6.dst_addr[31:0].0-31 - H7: 32 # value 1 -> H7 bit[5]: ingress::hdr.ig_ft.ipv6.$valid - load: { byte0 : 10, byte1 : 11 } - shift: 8 - buf_req: 12 - next: parse_udp - 0x8f: - 0..3: MW6 # ingress::hdr.ig_ft.ipv6.dst_addr[63:32].32-63 - 4..7: MW3 # ingress::hdr.ig_ft.ipv6.dst_addr[31:0].0-31 - H7: 32 # value 1 -> H7 bit[5]: ingress::hdr.ig_ft.ipv6.$valid - load: { byte0 : 20, byte1 : 21 } - shift: 8 - buf_req: 22 - next: parse_inner_ethernet - 0x04: - 0..3: MW6 # ingress::hdr.ig_ft.ipv6.dst_addr[63:32].32-63 - 4..7: MW3 # ingress::hdr.ig_ft.ipv6.dst_addr[31:0].0-31 - H7: 32 # value 1 -> H7 bit[5]: ingress::hdr.ig_ft.ipv6.$valid - load: { byte0 : 8, byte1 : 14, byte2 : 15, byte3 : 17 } - shift: 8 - buf_req: 18 - next: parse_inner_ipv4 - 0x29: - 0..3: MW6 # ingress::hdr.ig_ft.ipv6.dst_addr[63:32].32-63 - 4..7: MW3 # ingress::hdr.ig_ft.ipv6.dst_addr[31:0].0-31 - H7: 32 # value 1 -> H7 bit[5]: ingress::hdr.ig_ft.ipv6.$valid - shift: 8 - buf_req: 8 - next: parse_inner_ipv6 - 0x2b: - 0..3: MW6 # ingress::hdr.ig_ft.ipv6.dst_addr[63:32].32-63 - 4..7: MW3 # ingress::hdr.ig_ft.ipv6.dst_addr[31:0].0-31 - H7: 32 # value 1 -> H7 bit[5]: ingress::hdr.ig_ft.ipv6.$valid - shift: 8 - buf_req: 8 - next: parse_srh_check - 0x3c: - 0..3: MW6 # ingress::hdr.ig_ft.ipv6.dst_addr[63:32].32-63 - 4..7: MW3 # ingress::hdr.ig_ft.ipv6.dst_addr[31:0].0-31 - H7: 32 # value 1 -> H7 bit[5]: ingress::hdr.ig_ft.ipv6.$valid - load: { byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_doh - 0x**: - 0..3: MW6 # ingress::hdr.ig_ft.ipv6.dst_addr[63:32].32-63 - 4..7: MW3 # ingress::hdr.ig_ft.ipv6.dst_addr[31:0].0-31 - H7: 32 # value 1 -> H7 bit[5]: ingress::hdr.ig_ft.ipv6.$valid - shift: 8 - buf_req: 8 - next: end - parse_icmp: - *: - 0..1: H66 # ingress::ig_md.ig_ft.lkp.l4_src_port - buf_req: 2 - next: end - parse_tcp: - *: - 0..1: H66 # ingress::ig_md.ig_ft.lkp.l4_src_port - 0..3: W31 # bit[16..31] -> W31 bit[15..0]: ingress::ig_md.ig_ft.lkp.l4_dst_port - 12..13: H29 # bit[104..111] -> H29 bit[7..0]: ingress::ig_md.ig_ft.lkp.tcp_flags - buf_req: 14 - next: end - parse_udp: - match: [ byte0, byte1 ] - value_set IgParser_front.udp_port_vxlan 1: - handle: 511 - field_mapping: - hdr.ig_ft.udp.dst_port(0..7) : byte1(0..7) - hdr.ig_ft.udp.dst_port(8..15) : byte0(0..7) - 0..1: H66 # ingress::ig_md.ig_ft.lkp.l4_src_port - 0..3: W31 # bit[16..31] -> W31 bit[15..0]: ingress::ig_md.ig_ft.lkp.l4_dst_port - H7: 64 # value 1 -> H7 bit[6]: ingress::hdr.ig_ft.udp.$valid - clot 17 : - start: 0 - length: 8 - shift: 8 - buf_req: 8 - next: parse_vxlan - 0x****: - 0..1: H66 # ingress::ig_md.ig_ft.lkp.l4_src_port - 0..3: W31 # bit[16..31] -> W31 bit[15..0]: ingress::ig_md.ig_ft.lkp.l4_dst_port - H7: 64 # value 1 -> H7 bit[6]: ingress::hdr.ig_ft.udp.$valid - clot 17 : - start: 0 - length: 8 - shift: 8 - buf_req: 8 - next: end - parse_vxlan: - *: - 4: B47 # ingress::hdr.ig_ft.vxlan.vni[23:16].16-23 - 5..6: H4 # ingress::hdr.ig_ft.vxlan.vni[15:0].0-15 - H7: 128 # value 1 -> H7 bit[7]: ingress::hdr.ig_ft.vxlan.$valid - clot 18 : - start: 0 - length: 8 - shift: 8 - buf_req: 8 - next: end - parse_inner_ethernet: - match: [ byte0, byte1 ] - 0x0800: - 0..1: H64 # ingress::ig_md.ig_ft.lkp.mac_dst_addr[47:32].32-47 - 2..5: W16 # ingress::ig_md.ig_ft.lkp.mac_dst_addr[31:0].0-31 - 5..8: W17 # bit[48..71] -> W17 bit[23..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[47:24].24-47 - 8..9: H22 # bit[72..79] -> H22 bit[7..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[23:16].16-23 - 8..11: W30 # bit[80..95] -> W30 bit[15..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[15:0].0-15 - H7: 256 # value 1 -> H7 bit[8]: ingress::hdr.ig_ft.inner_ethernet.$valid - clot 13 : - start: 0 - length: 14 - load: { byte0 : 14, byte1 : 20, byte2 : 21, byte3 : 23 } - shift: 14 - buf_req: 24 - next: parse_inner_ipv4 - 0x86dd: - 0..1: H64 # ingress::ig_md.ig_ft.lkp.mac_dst_addr[47:32].32-47 - 2..5: W16 # ingress::ig_md.ig_ft.lkp.mac_dst_addr[31:0].0-31 - 5..8: W17 # bit[48..71] -> W17 bit[23..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[47:24].24-47 - 8..9: H22 # bit[72..79] -> H22 bit[7..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[23:16].16-23 - 8..11: W30 # bit[80..95] -> W30 bit[15..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[15:0].0-15 - H7: 256 # value 1 -> H7 bit[8]: ingress::hdr.ig_ft.inner_ethernet.$valid - clot 13 : - start: 0 - length: 14 - shift: 14 - buf_req: 14 - next: parse_inner_ipv6 - 0x8100: - 0..1: H64 # ingress::ig_md.ig_ft.lkp.mac_dst_addr[47:32].32-47 - 2..5: W16 # ingress::ig_md.ig_ft.lkp.mac_dst_addr[31:0].0-31 - 5..8: W17 # bit[48..71] -> W17 bit[23..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[47:24].24-47 - 8..9: H22 # bit[72..79] -> H22 bit[7..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[23:16].16-23 - 8..11: W30 # bit[80..95] -> W30 bit[15..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[15:0].0-15 - H7: 256 # value 1 -> H7 bit[8]: ingress::hdr.ig_ft.inner_ethernet.$valid - clot 13 : - start: 0 - length: 14 - load: { byte0 : 16, byte1 : 17 } - shift: 14 - buf_req: 18 - next: parse_inner_vlan - 0x****: - 0..1: H64 # ingress::ig_md.ig_ft.lkp.mac_dst_addr[47:32].32-47 - 2..5: W16 # ingress::ig_md.ig_ft.lkp.mac_dst_addr[31:0].0-31 - 5..8: W17 # bit[48..71] -> W17 bit[23..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[47:24].24-47 - 8..9: H22 # bit[72..79] -> H22 bit[7..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[23:16].16-23 - 8..11: W30 # bit[80..95] -> W30 bit[15..0]: ingress::ig_md.ig_ft.lkp.mac_src_addr[15:0].0-15 - H7: 256 # value 1 -> H7 bit[8]: ingress::hdr.ig_ft.inner_ethernet.$valid - clot 13 : - start: 0 - length: 14 - shift: 14 - buf_req: 14 - next: end - parse_inner_ipv4: - match: [ byte3, byte0, byte1, byte2 ] - 0b00010001****0101**00000000000000: - checksum 0: - type: VERIFY - mask: [ 0, 1, 2..3, 4..5, 6, 6..7, 8, 9, 10..11, 12..15, 16..19 ] - swap: 0 - start: 1 - end: 1 - dest: H8(2) - 9: B18 # ingress::ig_md.ig_ft.lkp.ip_proto - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - 16..19: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H7: 512 # value 1 -> H7 bit[9]: ingress::hdr.ig_ft.inner_ipv4.$valid - clot 1 : - start: 0 - length: 20 - shift: 20 - buf_req: 20 - next: parse_inner_udp - 0b00000110****0101**00000000000000: - checksum 0: - type: VERIFY - mask: [ 0, 1, 2..3, 4..5, 6, 6..7, 8, 9, 10..11, 12..15, 16..19 ] - swap: 0 - start: 1 - end: 1 - dest: H8(2) - 9: B18 # ingress::ig_md.ig_ft.lkp.ip_proto - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - 16..19: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H7: 512 # value 1 -> H7 bit[9]: ingress::hdr.ig_ft.inner_ipv4.$valid - clot 1 : - start: 0 - length: 20 - shift: 20 - buf_req: 20 - next: parse_inner_tcp - 0x********: - checksum 0: - type: VERIFY - mask: [ 0, 1, 2..3, 4..5, 6, 6..7, 8, 9, 10..11, 12..15, 16..19 ] - swap: 0 - start: 1 - end: 1 - dest: H8(2) - 9: B18 # ingress::ig_md.ig_ft.lkp.ip_proto - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - 16..19: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H7: 512 # value 1 -> H7 bit[9]: ingress::hdr.ig_ft.inner_ipv4.$valid - clot 1 : - start: 0 - length: 20 - shift: 20 - buf_req: 20 - next: end - parse_inner_udp: - *: - 0..1: H66 # ingress::ig_md.ig_ft.lkp.l4_src_port - 0..3: W31 # bit[16..31] -> W31 bit[15..0]: ingress::ig_md.ig_ft.lkp.l4_dst_port - buf_req: 4 - next: end - parse_inner_tcp: - *: - 0..1: H66 # ingress::ig_md.ig_ft.lkp.l4_src_port - 0..3: W31 # bit[16..31] -> W31 bit[15..0]: ingress::ig_md.ig_ft.lkp.l4_dst_port - buf_req: 4 - next: end - parse_inner_ipv6: - *: - 0..3: W28 # bit[12..31] -> W28 bit[19..0]: ingress::ig_md.ig_ft.lkp.flow_label - 6: B18 # ingress::ig_md.ig_ft.lkp.ip_proto - 8..11: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 12..15: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 16..19: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 20..21: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 22..23: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - 24..27: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 28..31: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - H7: 1024 # value 1 -> H7 bit[10]: ingress::hdr.ig_ft.inner_ipv6.$valid - clot 0 : - start: 0 - length: 40 - load: { byte0 : 6 } - shift: 32 - buf_req: 32 - next: parse_inner_ipv6.$split_0 - parse_inner_ipv6.$split_0: - match: [ byte0 ] - 0x06: - 0..3: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 4..7: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - # clot 0 (spilled) - shift: 8 - buf_req: 8 - next: parse_inner_tcp - 0x11: - 0..3: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 4..7: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - # clot 0 (spilled) - shift: 8 - buf_req: 8 - next: parse_inner_udp - 0x**: - 0..3: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 4..7: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - # clot 0 (spilled) - shift: 8 - buf_req: 8 - next: end - parse_inner_vlan: - match: [ byte0, byte1 ] - 0x0800: - H7: 2048 # value 1 -> H7 bit[11]: ingress::hdr.ig_ft.inner_vlan_tag.$valid - clot 20 : - start: 0 - length: 4 - load: { byte0 : 4, byte1 : 10, byte2 : 11, byte3 : 13 } - shift: 4 - buf_req: 14 - next: parse_inner_ipv4 - 0x86dd: - H7: 2048 # value 1 -> H7 bit[11]: ingress::hdr.ig_ft.inner_vlan_tag.$valid - clot 20 : - start: 0 - length: 4 - shift: 4 - buf_req: 4 - next: parse_inner_ipv6 - 0x****: - H7: 2048 # value 1 -> H7 bit[11]: ingress::hdr.ig_ft.inner_vlan_tag.$valid - clot 20 : - start: 0 - length: 4 - shift: 4 - buf_req: 4 - next: end - parse_srh_check: - match: [ byte1 ] - 0b*******1: - load: { byte0 : 4 } - buf_req: 5 - next: parse_srh_downgrade - 0x**: - 0: MB4 # ingress::hdr.ig_ft.srv6_srh.next_hdr - 0: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto - 3: B14 # ingress::hdr.ig_ft.srv6_srh.seg_left - 4: B47 # ingress::hdr.ig_ft.srv6_srh.last_entry - 5: B34 # bit[46] -> B34 bit[1]: ingress::ig_md.ig_ft.srv6.tmp_no_frr - H7: 4096 # value 1 -> H7 bit[12]: ingress::hdr.ig_ft.srv6_srh.$valid - clot 19 : - start: 0 - length: 8 - load: { byte0 : 0, byte1 : 3, byte2 : 4 } - shift: 8 - buf_req: 8 - next: parse_srh_segment_0 - parse_srh_downgrade: - match: [ byte0 ] - 0x00: - 0: MB4 # ingress::hdr.ig_ft.srv6_srh.next_hdr - 0: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto - 3: B14 # ingress::hdr.ig_ft.srv6_srh.seg_left - 4: B47 # ingress::hdr.ig_ft.srv6_srh.last_entry - 5: B34 # bit[46] -> B34 bit[1]: ingress::ig_md.ig_ft.srv6.tmp_no_frr - H7: 4096 # value 1 -> H7 bit[12]: ingress::hdr.ig_ft.srv6_srh.$valid - clot 19 : - start: 0 - length: 8 - load: { byte0 : 0 } - shift: 8 - buf_req: 8 - next: set_active_gsid_dg_and_parse_srh_next_0 - 0x**: - 0: MB4 # ingress::hdr.ig_ft.srv6_srh.next_hdr - 0: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto - 3: B14 # ingress::hdr.ig_ft.srv6_srh.seg_left - 4: B47 # ingress::hdr.ig_ft.srv6_srh.last_entry - 5: B34 # bit[46] -> B34 bit[1]: ingress::ig_md.ig_ft.srv6.tmp_no_frr - H7: 4096 # value 1 -> H7 bit[12]: ingress::hdr.ig_ft.srv6_srh.$valid - clot 19 : - start: 0 - length: 8 - load: { byte0 : 0, byte1 : 4 } - shift: 8 - buf_req: 8 - next: set_active_gsid_dg_0 - set_active_gsid_dg_and_parse_srh_next_0: - *: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 1024 # value 1024 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 12 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - parse_srh_next_header: - match: [ byte0 ] - 0x3c: - load: { byte0 : 2 } - buf_req: 3 - next: parse_doh_e2e - 0x**: - buf_req: 0 - next: end - parse_doh_e2e: - match: [ byte0 ] - 0x12: - 0: B45 # ingress::hdr.ig_ft.doh_e2e.next_hdr - 1: B46 # ingress::hdr.ig_ft.doh_e2e.hdr_ext_len - 2..3: H28 - # - bit[16..23] -> H28 bit[15..8]: ingress::hdr.ig_ft.doh_e2e.option_type - # - bit[24..31] -> H28 bit[7..0]: ingress::hdr.ig_ft.doh_e2e.option_len - H7: 8192 # value 1 -> H7 bit[13]: ingress::hdr.ig_ft.doh_e2e.$valid - buf_req: 4 - next: parse_srv6_e2e_ifit - 0x**: - 0: B45 # ingress::hdr.ig_ft.doh_e2e.next_hdr - 1: B46 # ingress::hdr.ig_ft.doh_e2e.hdr_ext_len - 2..3: H28 - # - bit[16..23] -> H28 bit[15..8]: ingress::hdr.ig_ft.doh_e2e.option_type - # - bit[24..31] -> H28 bit[7..0]: ingress::hdr.ig_ft.doh_e2e.option_len - H7: 8192 # value 1 -> H7 bit[13]: ingress::hdr.ig_ft.doh_e2e.$valid - buf_req: 4 - next: end - parse_srv6_e2e_ifit: - *: - 0: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto - 3..6: MW5 # bit[32..51] -> MW5 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_id - 6: MB12 # bit[52] -> MB12 bit[3]: ingress::ig_md.ig_ft.ifit.loss_label - 6: MB14 # bit[53] -> MB14 bit[2]: ingress::ig_md.ig_ft.ifit.delay_label - 7..10: MW10 # bit[64..83] -> MW10 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_node_id - 11: MB10 # bit[88..89] -> MB10 bit[7..6]: ingress::ig_md.ig_ft.ifit.hti - H7: 16384 # value 1 -> H7 bit[14]: ingress::hdr.ig_ft.srv6_e2e_ifit.$valid - clot 14 : - start: 4 - length: 12 - shift: 16 - buf_req: 16 - next: end - set_active_gsid_dg_0: - match: [ byte1 ] - 0x01: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 1024 # value 1024 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 12 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header_dg_1 - 0x**: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 1024 # value 1024 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 12 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_dg_b1 - parse_srh_next_header_dg_1: - *: - H6: 512 # value 512 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 11 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - parse_srh_segment_dg_b1: - match: [ byte1 ] - 0x02: - H6: 512 # value 512 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 11 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header_dg_2 - 0x**: - H6: 512 # value 512 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 11 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_dg_b2 - parse_srh_next_header_dg_2: - *: - H6: 256 # value 256 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 10 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - parse_srh_segment_dg_b2: - match: [ byte1 ] - 0x03: - H6: 256 # value 256 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 10 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header_dg_3 - 0x**: - H6: 256 # value 256 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 10 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_dg_b3 - parse_srh_next_header_dg_3: - *: - H6: 128 # value 128 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 9 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - parse_srh_segment_dg_b3: - match: [ byte1 ] - 0x04: - H6: 128 # value 128 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 9 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header_dg_4 - 0x**: - H6: 128 # value 128 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 9 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_dg_b4 - parse_srh_next_header_dg_4: - *: - H6: 64 # value 64 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 8 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - parse_srh_segment_dg_b4: - match: [ byte1 ] - 0x05: - H6: 64 # value 64 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 8 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header_dg_5 - 0x**: - H6: 64 # value 64 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 8 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_dg_b5 - parse_srh_next_header_dg_5: - *: - H6: 32 # value 32 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 7 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - parse_srh_segment_dg_b5: - match: [ byte1 ] - 0x06: - H6: 32 # value 32 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 7 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header_dg_6 - 0x**: - H6: 32 # value 32 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 7 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_dg_b6 - parse_srh_next_header_dg_6: - *: - H6: 16 # value 16 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 6 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - parse_srh_segment_dg_b6: - match: [ byte1 ] - 0x07: - H6: 16 # value 16 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 6 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header_dg_7 - 0x**: - H6: 16 # value 16 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 6 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_dg_b7 - parse_srh_next_header_dg_7: - *: - H6: 8 # value 8 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 5 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - parse_srh_segment_dg_b7: - match: [ byte1 ] - 0x08: - H6: 8 # value 8 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 5 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header_dg_8 - 0x**: - H6: 8 # value 8 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 5 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_dg_b8 - parse_srh_next_header_dg_8: - *: - H6: 4 # value 4 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 4 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - parse_srh_segment_dg_b8: - match: [ byte1 ] - 0x09: - H6: 4 # value 4 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 4 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header_dg_9 - 0x**: - H6: 4 # value 4 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 4 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_dg_b9 - parse_srh_next_header_dg_9: - *: - H6: 2 # value 2 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 3 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - parse_srh_segment_dg_b9: - *: - H6: 2 # value 2 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 3 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header_10 - parse_srh_next_header_10: - *: - H6: 1 # value 1 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 2 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - parse_srh_segment_0: - match: [ byte2, byte1 ] - 0x0001: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 1024 # value 1024 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 12 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x0000: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 1024 # value 1024 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 12 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x00**: - H6: 1024 # value 1024 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 12 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x**01: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 1024 # value 1024 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 12 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_1 - 0x**00: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 1024 # value 1024 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 12 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_1 - 0x****: - H6: 1024 # value 1024 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 12 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_1 - parse_srh_segment_1: - match: [ byte2, byte1 ] - 0x0102: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 512 # value 512 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 11 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x0101: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 512 # value 512 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 11 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x01**: - H6: 512 # value 512 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 11 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x**02: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 512 # value 512 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 11 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_2 - 0x**01: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 512 # value 512 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 11 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_2 - 0x****: - H6: 512 # value 512 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 11 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_2 - parse_srh_segment_2: - match: [ byte2, byte1 ] - 0x0203: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 256 # value 256 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 10 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x0202: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 256 # value 256 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 10 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x02**: - H6: 256 # value 256 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 10 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x**03: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 256 # value 256 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 10 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_3 - 0x**02: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 256 # value 256 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 10 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_3 - 0x****: - H6: 256 # value 256 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 10 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_3 - parse_srh_segment_3: - match: [ byte2, byte1 ] - 0x0304: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 128 # value 128 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 9 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x0303: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 128 # value 128 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 9 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x03**: - H6: 128 # value 128 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 9 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x**04: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 128 # value 128 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 9 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_4 - 0x**03: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 128 # value 128 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 9 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_4 - 0x****: - H6: 128 # value 128 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 9 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_4 - parse_srh_segment_4: - match: [ byte2, byte1 ] - 0x0405: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 64 # value 64 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 8 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x0404: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 64 # value 64 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 8 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x04**: - H6: 64 # value 64 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 8 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x**05: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 64 # value 64 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 8 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_5 - 0x**04: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 64 # value 64 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 8 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_5 - 0x****: - H6: 64 # value 64 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 8 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_5 - parse_srh_segment_5: - match: [ byte2, byte1 ] - 0x0506: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 32 # value 32 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 7 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x0505: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 32 # value 32 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 7 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x05**: - H6: 32 # value 32 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 7 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x**06: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 32 # value 32 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 7 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_6 - 0x**05: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 32 # value 32 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 7 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_6 - 0x****: - H6: 32 # value 32 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 7 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_6 - parse_srh_segment_6: - match: [ byte2, byte1 ] - 0x0607: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 16 # value 16 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 6 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x0606: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 16 # value 16 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 6 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x06**: - H6: 16 # value 16 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 6 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x**07: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 16 # value 16 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 6 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_7 - 0x**06: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 16 # value 16 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 6 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_7 - 0x****: - H6: 16 # value 16 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 6 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_7 - parse_srh_segment_7: - match: [ byte2, byte1 ] - 0x0708: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 8 # value 8 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 5 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x0707: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 8 # value 8 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 5 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x07**: - H6: 8 # value 8 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 5 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x**08: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 8 # value 8 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 5 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_8 - 0x**07: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 8 # value 8 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 5 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_8 - 0x****: - H6: 8 # value 8 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 5 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_8 - parse_srh_segment_8: - match: [ byte2, byte1 ] - 0x0809: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 4 # value 4 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 4 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x0808: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 4 # value 4 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 4 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x08**: - H6: 4 # value 4 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 4 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x**09: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 4 # value 4 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 4 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_9 - 0x**08: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 4 # value 4 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 4 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_9 - 0x****: - H6: 4 # value 4 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 4 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_9 - parse_srh_segment_9: - match: [ byte2, byte1 ] - 0x090a: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 2 # value 2 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 3 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x0909: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 2 # value 2 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 3 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x09**: - H6: 2 # value 2 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 3 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x**0a: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 2 # value 2 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 3 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_10 - 0x**09: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 2 # value 2 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 3 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_10 - 0x****: - H6: 2 # value 2 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 3 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_segment_10 - parse_srh_segment_10: - match: [ byte2, byte1 ] - 0x0a0b: - 0..3: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 4..7: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - 8..11: W13 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[63:32].32-63 - 12..15: W4 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[31:0].0-31 - H6: 1 # value 1 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 2 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x**0a: - 0..3: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 4..7: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 8..11: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 12..13: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - H6: 1 # value 1 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 2 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - 0x****: - H6: 1 # value 1 -> H6 bit[10..0]: ingress::hdr.ig_ft.srv6_list.$stkvalid - clot 2 : - start: 0 - length: 16 - shift: 16 - buf_req: 16 - next: parse_srh_next_header - parse_doh: - match: [ byte0 ] - 0x12: - 0: MB5 # ingress::hdr.ig_ft.doh.next_hdr - H7: 32768 # value 1 -> H7 bit[15]: ingress::hdr.ig_ft.doh.$valid - clot 26 : - start: 1 - length: 3 - load: { byte0 : 0 } - buf_req: 1 - next: parse_h2h_ifit - 0x**: - 0: MB5 # ingress::hdr.ig_ft.doh.next_hdr - H7: 32768 # value 1 -> H7 bit[15]: ingress::hdr.ig_ft.doh.$valid - clot 26 : - start: 1 - length: 3 - buf_req: 1 - next: end - parse_h2h_ifit: - match: [ byte0 ] - 0x2b: - 0: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto - 3..6: MW5 # bit[32..51] -> MW5 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_id - 6: MB12 # bit[52] -> MB12 bit[3]: ingress::ig_md.ig_ft.ifit.loss_label - 6: MB14 # bit[53] -> MB14 bit[2]: ingress::ig_md.ig_ft.ifit.delay_label - 7..10: MW10 # bit[64..83] -> MW10 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_node_id - 11: MB10 # bit[88..89] -> MB10 bit[7..6]: ingress::ig_md.ig_ft.ifit.hti - 13: B31 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[23:16].16-23 - 14..15: H4 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[15:0].0-15 - B12: 1 # value 1 -> B12 bit[0]: ingress::hdr.ig_ft.srv6_h2h_ifit.$valid - clot 15 : - start: 4 - length: 9 - shift: 16 - buf_req: 16 - next: parse_srh_check - 0x8f: - 0: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto - 3..6: MW5 # bit[32..51] -> MW5 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_id - 6: MB12 # bit[52] -> MB12 bit[3]: ingress::ig_md.ig_ft.ifit.loss_label - 6: MB14 # bit[53] -> MB14 bit[2]: ingress::ig_md.ig_ft.ifit.delay_label - 7..10: MW10 # bit[64..83] -> MW10 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_node_id - 11: MB10 # bit[88..89] -> MB10 bit[7..6]: ingress::ig_md.ig_ft.ifit.hti - 13: B31 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[23:16].16-23 - 14..15: H4 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[15:0].0-15 - B12: 1 # value 1 -> B12 bit[0]: ingress::hdr.ig_ft.srv6_h2h_ifit.$valid - clot 15 : - start: 4 - length: 9 - load: { byte0 : 28, byte1 : 29 } - shift: 16 - buf_req: 30 - next: parse_inner_ethernet - 0x04: - 0: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto - 3..6: MW5 # bit[32..51] -> MW5 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_id - 6: MB12 # bit[52] -> MB12 bit[3]: ingress::ig_md.ig_ft.ifit.loss_label - 6: MB14 # bit[53] -> MB14 bit[2]: ingress::ig_md.ig_ft.ifit.delay_label - 7..10: MW10 # bit[64..83] -> MW10 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_node_id - 11: MB10 # bit[88..89] -> MB10 bit[7..6]: ingress::ig_md.ig_ft.ifit.hti - 13: B31 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[23:16].16-23 - 14..15: H4 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[15:0].0-15 - B12: 1 # value 1 -> B12 bit[0]: ingress::hdr.ig_ft.srv6_h2h_ifit.$valid - clot 15 : - start: 4 - length: 9 - load: { byte0 : 16, byte1 : 22, byte2 : 23, byte3 : 25 } - shift: 16 - buf_req: 26 - next: parse_inner_ipv4 - 0x29: - 0: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto - 3..6: MW5 # bit[32..51] -> MW5 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_id - 6: MB12 # bit[52] -> MB12 bit[3]: ingress::ig_md.ig_ft.ifit.loss_label - 6: MB14 # bit[53] -> MB14 bit[2]: ingress::ig_md.ig_ft.ifit.delay_label - 7..10: MW10 # bit[64..83] -> MW10 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_node_id - 11: MB10 # bit[88..89] -> MB10 bit[7..6]: ingress::ig_md.ig_ft.ifit.hti - 13: B31 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[23:16].16-23 - 14..15: H4 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[15:0].0-15 - B12: 1 # value 1 -> B12 bit[0]: ingress::hdr.ig_ft.srv6_h2h_ifit.$valid - clot 15 : - start: 4 - length: 9 - shift: 16 - buf_req: 16 - next: parse_inner_ipv6 - 0x**: - 0: MB0 # ingress::ig_md.ig_ft.lkp.srv6_ip_proto - 3..6: MW5 # bit[32..51] -> MW5 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_id - 6: MB12 # bit[52] -> MB12 bit[3]: ingress::ig_md.ig_ft.ifit.loss_label - 6: MB14 # bit[53] -> MB14 bit[2]: ingress::ig_md.ig_ft.ifit.delay_label - 7..10: MW10 # bit[64..83] -> MW10 bit[23..4]: ingress::ig_md.ig_ft.ifit.flow_node_id - 11: MB10 # bit[88..89] -> MB10 bit[7..6]: ingress::ig_md.ig_ft.ifit.hti - 13: B31 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[23:16].16-23 - 14..15: H4 # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[15:0].0-15 - B12: 1 # value 1 -> B12 bit[0]: ingress::hdr.ig_ft.srv6_h2h_ifit.$valid - clot 15 : - start: 4 - length: 9 - shift: 16 - buf_req: 16 - next: end - parse_fabric_evpn_110: - match: [ byte0 ] - 0b1*******: - 0: B37 - # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type - # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror - # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast - 0..1: H69 - # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc - # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color - # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track - 2: B15 # ingress::hdr.fabric_data_template_plus.flags - 3: B36 # ingress::hdr.fabric_data_template_plus.vb - 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 - 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 - 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 - 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 - 12..13: H13 - # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one - # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif - B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid - B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid - shift: 14 - buf_req: 14 - next: parse_extension_tunnel_decap - 0x**: - 0: B37 - # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type - # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror - # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast - 0..1: H69 - # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc - # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color - # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track - 2: B15 # ingress::hdr.fabric_data_template_plus.flags - 3: B36 # ingress::hdr.fabric_data_template_plus.vb - 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 - 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 - 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 - 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 - 12..13: H13 - # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one - # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif - B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid - B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid - load: { byte0 : 26, byte1 : 27 } - shift: 14 - buf_req: 28 - next: parse_ethernet_evpn110 - parse_extension_tunnel_decap: - *: - 0: B38 - # - bit[0..2] -> B38 bit[7..5]: ingress::hdr.ext_tunnel_decap.ext_type - # - bit[3] -> B38 bit[4]: ingress::hdr.ext_tunnel_decap.extend - # - bit[4..7] -> B38 bit[3..0]: ingress::hdr.ext_tunnel_decap.sub_type - 1: B39 # ingress::hdr.ext_tunnel_decap.vb - 2..3: H18 # ingress::hdr.ext_tunnel_decap.vh - B13: 1 # value 1 -> B13 bit[0]: ingress::hdr.ext_tunnel_decap.$valid - load: { byte0 : 16, byte1 : 17 } - shift: 4 - buf_req: 18 - next: parse_ethernet_evpn110 - parse_ethernet_evpn110: - match: [ byte0, byte1 ] - 0x8100: - 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 - 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 - 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 - 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid - load: { byte0 : 16, byte1 : 17 } - shift: 14 - buf_req: 18 - next: parse_vlan_evpn110 - 0x****: - 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 - 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 - 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 - 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid - shift: 14 - buf_req: 14 - next: end - parse_vlan_evpn110: - match: [ byte0, byte1 ] - 0x8100: - 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid - 0..3: W10 - # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp - # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi - # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid - # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type - B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_vlan1_evpn110 - 0x****: - 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid - 0..3: W10 - # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp - # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi - # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid - # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type - B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_vlan1_evpn110: - *: - 0..3: W11 - # - bit[0..2] -> W11 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[1].pcp - # - bit[3] -> W11 bit[28]: ingress::hdr.ig_ft.vlan_tag[1].cfi - # - bit[4..15] -> W11 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[1].vid - # - bit[16..31] -> W11 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[1].ether_type - B10: 1 # value 1 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_fabric_2544_pktgen.$split_0: - match: [ byte0, byte1 ] - 0x8100: - B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid - load: { byte0 : 2, byte1 : 3 } - buf_req: 4 - next: parse_vlan_2544 - 0x****: - B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid - buf_req: 0 - next: end - parse_vlan_2544: - match: [ byte0, byte1 ] - 0x8100: - 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid - 0..3: W10 - # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp - # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi - # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid - # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type - B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_vlan1_2544 - 0x****: - 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid - 0..3: W10 - # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp - # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi - # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid - # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type - B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_vlan1_2544: - *: - 0..3: W11 - # - bit[0..2] -> W11 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[1].pcp - # - bit[3] -> W11 bit[28]: ingress::hdr.ig_ft.vlan_tag[1].cfi - # - bit[4..15] -> W11 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[1].vid - # - bit[16..31] -> W11 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[1].ether_type - B10: 1 # value 1 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - start.$oob_stall_1: - *: - load: { byte0 : 12, byte2 : 13 } - buf_req: 14 - next: parse_ethernet - parse_ethernet: - match: [ byte0, byte2 ] - 0x0800: - 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 - 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 - 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 - 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type - B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid - load: { byte0 : 14 } - shift: 14 - buf_req: 15 - next: parse_ipv4 - 0x86dd: - 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 - 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 - 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 - 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type - B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid - shift: 14 - buf_req: 14 - next: parse_ipv6 - 0x8100: - 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 - 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 - 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 - 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type - B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid - load: { byte0 : 16, byte2 : 17 } - shift: 14 - buf_req: 18 - next: parse_vlan - 0x8847: - 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 - 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 - 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 - 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type - B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid - load: { byte0 : 16, byte1 : 20, byte2 : 24 } - shift: 14 - buf_req: 25 - next: parse_mpls - 0x893f: - 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 - 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 - 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 - 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type - B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid - load: { byte0 : 20, byte2 : 21 } - shift: 14 - buf_req: 22 - next: parse_1br - 0x9000: - 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 - 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 - 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 - 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type - B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid - load: { byte0 : 14 } - shift: 14 - buf_req: 15 - next: parse_fabric_eth_cpu - 0x88a8: - 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 - 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 - 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 - 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type - B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid - load: { byte0 : 16, byte2 : 17 } - shift: 14 - buf_req: 18 - next: parse_qinq - 0x9100: - 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 - 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 - 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 - 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type - B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid - load: { byte0 : 16, byte2 : 17 } - shift: 14 - buf_req: 18 - next: parse_qinq - value_set IgParser_front.qinq_tpid 1: - handle: 510 - field_mapping: - hdr.ig_ft.ethernet.ether_type(0..7) : byte2(0..7) - hdr.ig_ft.ethernet.ether_type(8..15) : byte0(0..7) - 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 - 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 - 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 - 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type - B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid - load: { byte0 : 16, byte2 : 17 } - shift: 14 - buf_req: 18 - next: parse_qinq - 0x****: - 0..1: H23 # ingress::hdr.ig_ft.ethernet.dst_addr[47:32].32-47 - 2..5: MW15 # ingress::hdr.ig_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H55 # ingress::hdr.ig_ft.ethernet.src_addr[47:32].32-47 - 8..11: MW14 # ingress::hdr.ig_ft.ethernet.src_addr[31:0].0-31 - 12..13: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - 12..13: MH11 # ingress::ig_md.ig_ft.common.ether_type - B12: 2 # value 1 -> B12 bit[1]: ingress::hdr.ig_ft.ethernet.$valid - shift: 14 - buf_req: 14 - next: end - parse_ipv4: - match: [ byte0 ] - 0x*5: - checksum 0: - type: RESIDUAL - mask: [ 0, 1, 10..11 ] - swap: 0 - start: 1 - end: 1 - dest: H20 - end_pos: 19 - checksum 1: - type: VERIFY - mask: [ 0, 1, 2..3, 4..5, 6, 6..7, 8, 9, 10..11, 12..15, 16..19 ] - swap: 0 - start: 1 - end: 0 - 1: B40 # ingress::hdr.ig_ft.ipv4.diffserv - 6: B14 - # - bit[48..50] -> B14 bit[7..5]: ingress::hdr.ig_ft.ipv4.flags - # - bit[51..55] -> B14 bit[4..0]: ingress::hdr.ig_ft.ipv4.frag_offset[12:8].8-12 - 7: MB5 # ingress::hdr.ig_ft.ipv4.frag_offset[7:0].0-7 - 7..8: MH0 # bit[64..71] -> MH0 bit[7..0]: ingress::ig_md.ig_ft.lkp.ip_ttl - 9: MB4 # ingress::hdr.ig_ft.ipv4.protocol - 9: B18 # ingress::ig_md.ig_ft.lkp.ip_proto - 12..13: MH12 # ingress::hdr.ig_ft.ipv4.src_addr[31:16].16-31 - 14..15: H0 # ingress::hdr.ig_ft.ipv4.src_addr[15:0].0-15 - 16..19: MW0 # ingress::hdr.ig_ft.ipv4.dst_addr - B12: 4 # value 1 -> B12 bit[2]: ingress::hdr.ig_ft.ipv4.$valid - clot 16 : - start: 0 - length: 20 - load: { byte0 : 6, byte1 : 7, byte2 : 9 } - shift: 20 - buf_req: 20 - next: parse_ipv4_no_options - 0x*6: - checksum 0: - type: RESIDUAL - mask: [ 0, 1, 10..11 ] - swap: 0 - start: 1 - end: 1 - dest: H20 - end_pos: 19 - checksum 1: - type: VERIFY - mask: [ 0, 1, 2..3, 4..5, 6, 6..7, 8, 9, 10..11, 12..15, 16..19 ] - swap: 0 - start: 1 - end: 0 - 1: B40 # ingress::hdr.ig_ft.ipv4.diffserv - 6: B14 - # - bit[48..50] -> B14 bit[7..5]: ingress::hdr.ig_ft.ipv4.flags - # - bit[51..55] -> B14 bit[4..0]: ingress::hdr.ig_ft.ipv4.frag_offset[12:8].8-12 - 7: MB5 # ingress::hdr.ig_ft.ipv4.frag_offset[7:0].0-7 - 7..8: MH0 # bit[64..71] -> MH0 bit[7..0]: ingress::ig_md.ig_ft.lkp.ip_ttl - 9: MB4 # ingress::hdr.ig_ft.ipv4.protocol - 9: B18 # ingress::ig_md.ig_ft.lkp.ip_proto - 12..13: MH12 # ingress::hdr.ig_ft.ipv4.src_addr[31:16].16-31 - 14..15: H0 # ingress::hdr.ig_ft.ipv4.src_addr[15:0].0-15 - 16..19: MW0 # ingress::hdr.ig_ft.ipv4.dst_addr - B12: 4 # value 1 -> B12 bit[2]: ingress::hdr.ig_ft.ipv4.$valid - clot 16 : - start: 0 - length: 20 - load: { byte0 : 6, byte1 : 7, byte2 : 9 } - shift: 20 - buf_req: 20 - next: parse_ipv4_options - 0x**: - checksum 0: - type: RESIDUAL - mask: [ 0, 1, 10..11 ] - swap: 0 - start: 1 - end: 1 - dest: H20 - end_pos: 19 - checksum 1: - type: VERIFY - mask: [ 0, 1, 2..3, 4..5, 6, 6..7, 8, 9, 10..11, 12..15, 16..19 ] - swap: 0 - start: 1 - end: 0 - 1: B40 # ingress::hdr.ig_ft.ipv4.diffserv - 6: B14 - # - bit[48..50] -> B14 bit[7..5]: ingress::hdr.ig_ft.ipv4.flags - # - bit[51..55] -> B14 bit[4..0]: ingress::hdr.ig_ft.ipv4.frag_offset[12:8].8-12 - 7: MB5 # ingress::hdr.ig_ft.ipv4.frag_offset[7:0].0-7 - 7..8: MH0 # bit[64..71] -> MH0 bit[7..0]: ingress::ig_md.ig_ft.lkp.ip_ttl - 9: MB4 # ingress::hdr.ig_ft.ipv4.protocol - 9: B18 # ingress::ig_md.ig_ft.lkp.ip_proto - 12..13: MH12 # ingress::hdr.ig_ft.ipv4.src_addr[31:16].16-31 - 14..15: H0 # ingress::hdr.ig_ft.ipv4.src_addr[15:0].0-15 - 16..19: MW0 # ingress::hdr.ig_ft.ipv4.dst_addr - B12: 4 # value 1 -> B12 bit[2]: ingress::hdr.ig_ft.ipv4.$valid - clot 16 : - start: 0 - length: 20 - shift: 20 - buf_req: 20 - next: end - parse_ipv4_no_options: - match: [ byte2, byte0, byte1 ] - 0b00000001***0000000000000: - checksum 1: - type: VERIFY - mask: [ ] - swap: 0 - start: 0 - end: 1 - dest: H8(1) - buf_req: 0 - next: parse_icmp - 0b00000110***0000000000000: - checksum 1: - type: VERIFY - mask: [ ] - swap: 0 - start: 0 - end: 1 - dest: H8(1) - buf_req: 0 - next: parse_tcp - 0b00010001***0000000000000: - checksum 1: - type: VERIFY - mask: [ ] - swap: 0 - start: 0 - end: 1 - dest: H8(1) - load: { byte0 : 2, byte1 : 3 } - buf_req: 4 - next: parse_udp - 0x******: - checksum 1: - type: VERIFY - mask: [ ] - swap: 0 - start: 0 - end: 1 - dest: H8(1) - buf_req: 0 - next: end - parse_ipv4_options: - *: - checksum 1: - type: VERIFY - mask: [ 0, 1, 2..3 ] - swap: 0 - start: 0 - end: 0 - 0: MB6 # ingress::hdr.ig_ft.ipv4_option.type - 1..2: H2 - # - bit[8..15] -> H2 bit[15..8]: ingress::hdr.ig_ft.ipv4_option.length - # - bit[16..23] -> H2 bit[7..0]: ingress::hdr.ig_ft.ipv4_option.value[15:8].8-15 - B12: 8 # value 1 -> B12 bit[3]: ingress::hdr.ig_ft.ipv4_option.$valid - clot 28 : - start: 3 - length: 1 - shift: 4 - buf_req: 4 - next: parse_ipv4_no_options - parse_vlan: - match: [ byte0, byte2 ] - 0x0800: - 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid - 0..3: W10 - # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp - # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi - # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid - # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type - 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type - B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid - load: { byte0 : 4 } - shift: 4 - buf_req: 5 - next: parse_ipv4 - 0x8100: - 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid - 0..3: W10 - # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp - # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi - # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid - # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type - 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type - B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid - load: { byte0 : 6, byte2 : 7 } - shift: 4 - buf_req: 8 - next: parse_vlan_1 - 0x86dd: - 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid - 0..3: W10 - # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp - # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi - # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid - # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type - 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type - B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv6 - 0x8847: - 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid - 0..3: W10 - # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp - # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi - # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid - # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type - 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type - B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid - load: { byte0 : 6, byte1 : 10, byte2 : 14 } - shift: 4 - buf_req: 15 - next: parse_mpls - 0x****: - 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid - 0..3: W10 - # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp - # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi - # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid - # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type - 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type - B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_vlan_1: - match: [ byte0, byte2 ] - 0x0800: - 0..3: W11 - # - bit[0..2] -> W11 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[1].pcp - # - bit[3] -> W11 bit[28]: ingress::hdr.ig_ft.vlan_tag[1].cfi - # - bit[4..15] -> W11 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[1].vid - # - bit[16..31] -> W11 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[1].ether_type - 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type - B10: 1 # value 1 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid - load: { byte0 : 4 } - shift: 4 - buf_req: 5 - next: parse_ipv4 - 0x86dd: - 0..3: W11 - # - bit[0..2] -> W11 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[1].pcp - # - bit[3] -> W11 bit[28]: ingress::hdr.ig_ft.vlan_tag[1].cfi - # - bit[4..15] -> W11 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[1].vid - # - bit[16..31] -> W11 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[1].ether_type - 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type - B10: 1 # value 1 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv6 - 0x8847: - 0..3: W11 - # - bit[0..2] -> W11 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[1].pcp - # - bit[3] -> W11 bit[28]: ingress::hdr.ig_ft.vlan_tag[1].cfi - # - bit[4..15] -> W11 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[1].vid - # - bit[16..31] -> W11 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[1].ether_type - 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type - B10: 1 # value 1 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid - load: { byte0 : 6, byte1 : 10, byte2 : 14 } - shift: 4 - buf_req: 15 - next: parse_mpls - 0x8100: - 0..3: W11 - # - bit[0..2] -> W11 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[1].pcp - # - bit[3] -> W11 bit[28]: ingress::hdr.ig_ft.vlan_tag[1].cfi - # - bit[4..15] -> W11 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[1].vid - # - bit[16..31] -> W11 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[1].ether_type - 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type - B10: 1 # value 1 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - 0x****: - 0..3: W11 - # - bit[0..2] -> W11 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[1].pcp - # - bit[3] -> W11 bit[28]: ingress::hdr.ig_ft.vlan_tag[1].cfi - # - bit[4..15] -> W11 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[1].vid - # - bit[16..31] -> W11 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[1].ether_type - 2..3: MH11 # ingress::ig_md.ig_ft.common.ether_type - B10: 1 # value 1 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_mpls: - match: [ byte0, byte1, byte2 ] - 0b*******0*******0*******0: - 0..1: H40 # ingress::hdr.ig_ft.mpls_ig[0].label[19:4].4-19 - 2..3: H5 - # - bit[16..19] -> H5 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[0].label[3:0].0-3 - # - bit[20..22] -> H5 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[0].exp - # - bit[23] -> H5 bit[8]: ingress::hdr.ig_ft.mpls_ig[0].bos - # - bit[24..31] -> H5 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[0].ttl - 2..3: MH0 # bit[24..31] -> MH0 bit[7..0]: ingress::ig_md.ig_ft.lkp.ip_ttl - B8: 128 # value 128 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - load: { byte0 : 14, byte1 : 18, byte2 : 22 } - shift: 4 - buf_req: 23 - next: parse_mpls3_or_more - 0b*******0*******0*******1: - 0..1: H40 # ingress::hdr.ig_ft.mpls_ig[0].label[19:4].4-19 - 2..3: H5 - # - bit[16..19] -> H5 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[0].label[3:0].0-3 - # - bit[20..22] -> H5 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[0].exp - # - bit[23] -> H5 bit[8]: ingress::hdr.ig_ft.mpls_ig[0].bos - # - bit[24..31] -> H5 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[0].ttl - 2..3: MH0 # bit[24..31] -> MH0 bit[7..0]: ingress::ig_md.ig_ft.lkp.ip_ttl - B8: 128 # value 128 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - shift: 4 - buf_req: 4 - next: parse_mpls2 - 0b*******0*******1********: - 0..1: H40 # ingress::hdr.ig_ft.mpls_ig[0].label[19:4].4-19 - 2..3: H5 - # - bit[16..19] -> H5 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[0].label[3:0].0-3 - # - bit[20..22] -> H5 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[0].exp - # - bit[23] -> H5 bit[8]: ingress::hdr.ig_ft.mpls_ig[0].bos - # - bit[24..31] -> H5 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[0].ttl - 2..3: MH0 # bit[24..31] -> MH0 bit[7..0]: ingress::ig_md.ig_ft.lkp.ip_ttl - B8: 128 # value 128 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - shift: 4 - buf_req: 4 - next: parse_mpls1 - 0x******: - 0..1: H40 # ingress::hdr.ig_ft.mpls_ig[0].label[19:4].4-19 - 2..3: H5 - # - bit[16..19] -> H5 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[0].label[3:0].0-3 - # - bit[20..22] -> H5 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[0].exp - # - bit[23] -> H5 bit[8]: ingress::hdr.ig_ft.mpls_ig[0].bos - # - bit[24..31] -> H5 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[0].ttl - 2..3: MH0 # bit[24..31] -> MH0 bit[7..0]: ingress::ig_md.ig_ft.lkp.ip_ttl - B8: 128 # value 128 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - load: { byte0 : 4 } - shift: 4 - buf_req: 5 - next: parse_mpls_bos - parse_mpls3_or_more: - match: [ byte0, byte1, byte2 ] - 0b*******0*******0*******0: - 0..1: H39 # ingress::hdr.ig_ft.mpls_ig[1].label[19:4].4-19 - 2..3: H4 - # - bit[16..19] -> H4 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[1].label[3:0].0-3 - # - bit[20..22] -> H4 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[1].exp - # - bit[23] -> H4 bit[8]: ingress::hdr.ig_ft.mpls_ig[1].bos - # - bit[24..31] -> H4 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[1].ttl - 4..5: H38 # ingress::hdr.ig_ft.mpls_ig[2].label[19:4].4-19 - 6..7: H3 - # - bit[48..51] -> H3 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[2].label[3:0].0-3 - # - bit[52..54] -> H3 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[2].exp - # - bit[55] -> H3 bit[8]: ingress::hdr.ig_ft.mpls_ig[2].bos - # - bit[56..63] -> H3 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[2].ttl - 8..9: H37 # ingress::hdr.ig_ft.mpls_ig[3].label[19:4].4-19 - 10..11: H2 - # - bit[80..83] -> H2 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[3].label[3:0].0-3 - # - bit[84..86] -> H2 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[3].exp - # - bit[87] -> H2 bit[8]: ingress::hdr.ig_ft.mpls_ig[3].bos - # - bit[88..95] -> H2 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[3].ttl - B8: 112 - # - value 64 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - # - value 32 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - # - value 16 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - load: { byte0 : 22, byte1 : 26, byte2 : 30 } - shift: 12 - buf_req: 31 - next: parse_mpls6_or_more - 0b*******0*******0*******1: - 0..1: H39 # ingress::hdr.ig_ft.mpls_ig[1].label[19:4].4-19 - 2..3: H4 - # - bit[16..19] -> H4 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[1].label[3:0].0-3 - # - bit[20..22] -> H4 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[1].exp - # - bit[23] -> H4 bit[8]: ingress::hdr.ig_ft.mpls_ig[1].bos - # - bit[24..31] -> H4 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[1].ttl - 4..5: H38 # ingress::hdr.ig_ft.mpls_ig[2].label[19:4].4-19 - 6..7: H3 - # - bit[48..51] -> H3 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[2].label[3:0].0-3 - # - bit[52..54] -> H3 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[2].exp - # - bit[55] -> H3 bit[8]: ingress::hdr.ig_ft.mpls_ig[2].bos - # - bit[56..63] -> H3 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[2].ttl - 8..9: H37 # ingress::hdr.ig_ft.mpls_ig[3].label[19:4].4-19 - 10..11: H2 - # - bit[80..83] -> H2 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[3].label[3:0].0-3 - # - bit[84..86] -> H2 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[3].exp - # - bit[87] -> H2 bit[8]: ingress::hdr.ig_ft.mpls_ig[3].bos - # - bit[88..95] -> H2 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[3].ttl - B8: 112 - # - value 64 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - # - value 32 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - # - value 16 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - shift: 12 - buf_req: 12 - next: parse_mpls5 - 0b*******0*******1********: - 0..1: H39 # ingress::hdr.ig_ft.mpls_ig[1].label[19:4].4-19 - 2..3: H4 - # - bit[16..19] -> H4 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[1].label[3:0].0-3 - # - bit[20..22] -> H4 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[1].exp - # - bit[23] -> H4 bit[8]: ingress::hdr.ig_ft.mpls_ig[1].bos - # - bit[24..31] -> H4 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[1].ttl - 4..5: H38 # ingress::hdr.ig_ft.mpls_ig[2].label[19:4].4-19 - 6..7: H3 - # - bit[48..51] -> H3 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[2].label[3:0].0-3 - # - bit[52..54] -> H3 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[2].exp - # - bit[55] -> H3 bit[8]: ingress::hdr.ig_ft.mpls_ig[2].bos - # - bit[56..63] -> H3 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[2].ttl - 8..9: H37 # ingress::hdr.ig_ft.mpls_ig[3].label[19:4].4-19 - 10..11: H2 - # - bit[80..83] -> H2 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[3].label[3:0].0-3 - # - bit[84..86] -> H2 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[3].exp - # - bit[87] -> H2 bit[8]: ingress::hdr.ig_ft.mpls_ig[3].bos - # - bit[88..95] -> H2 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[3].ttl - B8: 112 - # - value 64 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - # - value 32 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - # - value 16 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - shift: 12 - buf_req: 12 - next: parse_mpls4 - 0x******: - 0..1: H39 # ingress::hdr.ig_ft.mpls_ig[1].label[19:4].4-19 - 2..3: H4 - # - bit[16..19] -> H4 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[1].label[3:0].0-3 - # - bit[20..22] -> H4 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[1].exp - # - bit[23] -> H4 bit[8]: ingress::hdr.ig_ft.mpls_ig[1].bos - # - bit[24..31] -> H4 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[1].ttl - 4..5: H38 # ingress::hdr.ig_ft.mpls_ig[2].label[19:4].4-19 - 6..7: H3 - # - bit[48..51] -> H3 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[2].label[3:0].0-3 - # - bit[52..54] -> H3 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[2].exp - # - bit[55] -> H3 bit[8]: ingress::hdr.ig_ft.mpls_ig[2].bos - # - bit[56..63] -> H3 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[2].ttl - 8..9: H37 # ingress::hdr.ig_ft.mpls_ig[3].label[19:4].4-19 - 10..11: H2 - # - bit[80..83] -> H2 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[3].label[3:0].0-3 - # - bit[84..86] -> H2 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[3].exp - # - bit[87] -> H2 bit[8]: ingress::hdr.ig_ft.mpls_ig[3].bos - # - bit[88..95] -> H2 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[3].ttl - B8: 112 - # - value 64 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - # - value 32 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - # - value 16 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - load: { byte0 : 12 } - shift: 12 - buf_req: 13 - next: parse_mpls_bos - parse_mpls6_or_more: - match: [ byte0, byte1, byte2 ] - 0b*******0*******0*******0: - 0..1: H36 # ingress::hdr.ig_ft.mpls_ig[4].label[19:4].4-19 - 2..3: H0 - # - bit[16..19] -> H0 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[4].label[3:0].0-3 - # - bit[20..22] -> H0 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[4].exp - # - bit[23] -> H0 bit[8]: ingress::hdr.ig_ft.mpls_ig[4].bos - # - bit[24..31] -> H0 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[4].ttl - B8: 8 # value 8 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - B9: 24 - # - value 16 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid - # - value 8 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid - clot 25 : - start: 4 - length: 4 - clot 24 : - start: 8 - length: 4 - shift: 12 - buf_req: 12 - next: parse_mpls10_or_more - 0b*******0*******0*******1: - 0..1: H36 # ingress::hdr.ig_ft.mpls_ig[4].label[19:4].4-19 - 2..3: H0 - # - bit[16..19] -> H0 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[4].label[3:0].0-3 - # - bit[20..22] -> H0 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[4].exp - # - bit[23] -> H0 bit[8]: ingress::hdr.ig_ft.mpls_ig[4].bos - # - bit[24..31] -> H0 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[4].ttl - B8: 8 # value 8 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - B9: 24 - # - value 16 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid - # - value 8 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid - clot 25 : - start: 4 - length: 4 - clot 24 : - start: 8 - length: 4 - shift: 12 - buf_req: 12 - next: parse_mpls9 - 0b*******0*******1********: - 0..1: H36 # ingress::hdr.ig_ft.mpls_ig[4].label[19:4].4-19 - 2..3: H0 - # - bit[16..19] -> H0 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[4].label[3:0].0-3 - # - bit[20..22] -> H0 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[4].exp - # - bit[23] -> H0 bit[8]: ingress::hdr.ig_ft.mpls_ig[4].bos - # - bit[24..31] -> H0 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[4].ttl - B8: 8 # value 8 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - B9: 24 - # - value 16 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid - # - value 8 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid - clot 25 : - start: 4 - length: 4 - clot 24 : - start: 8 - length: 4 - shift: 12 - buf_req: 12 - next: parse_mpls8 - 0x******: - 0..1: H36 # ingress::hdr.ig_ft.mpls_ig[4].label[19:4].4-19 - 2..3: H0 - # - bit[16..19] -> H0 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[4].label[3:0].0-3 - # - bit[20..22] -> H0 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[4].exp - # - bit[23] -> H0 bit[8]: ingress::hdr.ig_ft.mpls_ig[4].bos - # - bit[24..31] -> H0 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[4].ttl - B8: 8 # value 8 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - B9: 24 - # - value 16 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid - # - value 8 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid - clot 25 : - start: 4 - length: 4 - clot 24 : - start: 8 - length: 4 - load: { byte0 : 12 } - shift: 12 - buf_req: 13 - next: parse_mpls_bos - parse_mpls10_or_more: - *: - B9: 7 - # - value 4 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid - # - value 2 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid - # - value 1 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid - clot 23 : - start: 0 - length: 4 - clot 22 : - start: 4 - length: 4 - load: { byte0 : 10 } - shift: 8 - buf_req: 11 - next: parse_mpls10_or_more.$split_0 - parse_mpls10_or_more.$split_0: - match: [ byte0 ] - 0b*******1: - clot 21 : - start: 0 - length: 4 - load: { byte0 : 4 } - shift: 4 - buf_req: 5 - next: parse_mpls_bos - 0x**: - clot 21 : - start: 0 - length: 4 - shift: 4 - buf_req: 4 - next: end - parse_mpls_bos: - match: [ byte0 ] - 0x4*: - load: { byte0 : 0, byte1 : 6, byte2 : 7, byte3 : 9 } - buf_req: 10 - next: parse_inner_ipv4 - 0x6*: - 0..3: W28 # bit[12..31] -> W28 bit[19..0]: ingress::ig_md.ig_ft.lkp.flow_label - 6: B18 # ingress::ig_md.ig_ft.lkp.ip_proto - 8..11: W1 # ingress::ig_md.ig_ft.lkp.ip_src_addr[127:96].96-127 - 12..15: W2 # ingress::ig_md.ig_ft.lkp.ip_src_addr[95:64].64-95 - 16..19: W3 # ingress::ig_md.ig_ft.lkp.ip_src_addr[63:32].32-63 - 20..21: MH13 # ingress::ig_md.ig_ft.lkp.ip_src_addr[31:16].16-31 - 22..23: H10 # ingress::ig_md.ig_ft.lkp.ip_src_addr[15:0].0-15 - 24..27: W24 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[127:96].96-127 - 28..31: W15 # ingress::ig_md.ig_ft.lkp.ip_dst_addr[95:64].64-95 - H7: 1024 # value 1 -> H7 bit[10]: ingress::hdr.ig_ft.inner_ipv6.$valid - clot 0 : - start: 0 - length: 40 - load: { byte0 : 6 } - shift: 32 - buf_req: 32 - next: parse_inner_ipv6.$split_0 - 0x**: - load: { byte0 : 12, byte1 : 13 } - buf_req: 14 - next: parse_inner_ethernet - parse_mpls9: - *: - B9: 6 - # - value 4 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid - # - value 2 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid - clot 23 : - start: 0 - length: 4 - clot 22 : - start: 4 - length: 4 - load: { byte0 : 8 } - shift: 8 - buf_req: 9 - next: parse_mpls_bos - parse_mpls8: - *: - B9: 4 # value 4 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid - clot 23 : - start: 0 - length: 4 - load: { byte0 : 4 } - shift: 4 - buf_req: 5 - next: parse_mpls_bos - parse_mpls5: - *: - 0..1: H36 # ingress::hdr.ig_ft.mpls_ig[4].label[19:4].4-19 - 2..3: H0 - # - bit[16..19] -> H0 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[4].label[3:0].0-3 - # - bit[20..22] -> H0 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[4].exp - # - bit[23] -> H0 bit[8]: ingress::hdr.ig_ft.mpls_ig[4].bos - # - bit[24..31] -> H0 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[4].ttl - B8: 8 # value 8 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - B9: 16 # value 16 -> B9 bit[4..0]: ingress::hdr.ig_ft.mpls2_ig.$stkvalid - clot 25 : - start: 4 - length: 4 - load: { byte0 : 8 } - shift: 8 - buf_req: 9 - next: parse_mpls_bos - parse_mpls4: - *: - 0..1: H36 # ingress::hdr.ig_ft.mpls_ig[4].label[19:4].4-19 - 2..3: H0 - # - bit[16..19] -> H0 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[4].label[3:0].0-3 - # - bit[20..22] -> H0 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[4].exp - # - bit[23] -> H0 bit[8]: ingress::hdr.ig_ft.mpls_ig[4].bos - # - bit[24..31] -> H0 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[4].ttl - B8: 8 # value 8 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - load: { byte0 : 4 } - shift: 4 - buf_req: 5 - next: parse_mpls_bos - parse_mpls2: - *: - 0..1: H39 # ingress::hdr.ig_ft.mpls_ig[1].label[19:4].4-19 - 2..3: H4 - # - bit[16..19] -> H4 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[1].label[3:0].0-3 - # - bit[20..22] -> H4 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[1].exp - # - bit[23] -> H4 bit[8]: ingress::hdr.ig_ft.mpls_ig[1].bos - # - bit[24..31] -> H4 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[1].ttl - 4..5: H38 # ingress::hdr.ig_ft.mpls_ig[2].label[19:4].4-19 - 6..7: H3 - # - bit[48..51] -> H3 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[2].label[3:0].0-3 - # - bit[52..54] -> H3 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[2].exp - # - bit[55] -> H3 bit[8]: ingress::hdr.ig_ft.mpls_ig[2].bos - # - bit[56..63] -> H3 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[2].ttl - B8: 96 - # - value 64 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - # - value 32 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - load: { byte0 : 8 } - shift: 8 - buf_req: 9 - next: parse_mpls_bos - parse_mpls1: - *: - 0..1: H39 # ingress::hdr.ig_ft.mpls_ig[1].label[19:4].4-19 - 2..3: H4 - # - bit[16..19] -> H4 bit[15..12]: ingress::hdr.ig_ft.mpls_ig[1].label[3:0].0-3 - # - bit[20..22] -> H4 bit[11..9]: ingress::hdr.ig_ft.mpls_ig[1].exp - # - bit[23] -> H4 bit[8]: ingress::hdr.ig_ft.mpls_ig[1].bos - # - bit[24..31] -> H4 bit[7..0]: ingress::hdr.ig_ft.mpls_ig[1].ttl - B8: 64 # value 64 -> B8 bit[7..0]: ingress::hdr.ig_ft.mpls_ig.$stkvalid - load: { byte0 : 4 } - shift: 4 - buf_req: 5 - next: parse_mpls_bos - parse_1br: - match: [ byte0, byte2 ] - 0x0800: - 2..3: H1 # bit[20..31] -> H1 bit[11..0]: ingress::hdr.ig_ft.br_tag.ecid - 6..7: MH11 # ingress::ig_md.ig_ft.common.ether_type - 6..7: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - B12: 16 # value 1 -> B12 bit[4]: ingress::hdr.ig_ft.br_tag.$valid - load: { byte0 : 8 } - shift: 8 - buf_req: 9 - next: parse_ipv4 - 0x86dd: - 2..3: H1 # bit[20..31] -> H1 bit[11..0]: ingress::hdr.ig_ft.br_tag.ecid - 6..7: MH11 # ingress::ig_md.ig_ft.common.ether_type - 6..7: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - B12: 16 # value 1 -> B12 bit[4]: ingress::hdr.ig_ft.br_tag.$valid - shift: 8 - buf_req: 8 - next: parse_ipv6 - 0x8100: - 2..3: H1 # bit[20..31] -> H1 bit[11..0]: ingress::hdr.ig_ft.br_tag.ecid - 6..7: MH11 # ingress::ig_md.ig_ft.common.ether_type - 6..7: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - B12: 16 # value 1 -> B12 bit[4]: ingress::hdr.ig_ft.br_tag.$valid - load: { byte0 : 10, byte2 : 11 } - shift: 8 - buf_req: 12 - next: parse_vlan - 0x8847: - 2..3: H1 # bit[20..31] -> H1 bit[11..0]: ingress::hdr.ig_ft.br_tag.ecid - 6..7: MH11 # ingress::ig_md.ig_ft.common.ether_type - 6..7: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - B12: 16 # value 1 -> B12 bit[4]: ingress::hdr.ig_ft.br_tag.$valid - load: { byte0 : 10, byte1 : 14, byte2 : 18 } - shift: 8 - buf_req: 19 - next: parse_mpls - 0x88a8: - 2..3: H1 # bit[20..31] -> H1 bit[11..0]: ingress::hdr.ig_ft.br_tag.ecid - 6..7: MH11 # ingress::ig_md.ig_ft.common.ether_type - 6..7: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - B12: 16 # value 1 -> B12 bit[4]: ingress::hdr.ig_ft.br_tag.$valid - load: { byte0 : 10, byte2 : 11 } - shift: 8 - buf_req: 12 - next: parse_qinq - 0x9100: - 2..3: H1 # bit[20..31] -> H1 bit[11..0]: ingress::hdr.ig_ft.br_tag.ecid - 6..7: MH11 # ingress::ig_md.ig_ft.common.ether_type - 6..7: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - B12: 16 # value 1 -> B12 bit[4]: ingress::hdr.ig_ft.br_tag.$valid - load: { byte0 : 10, byte2 : 11 } - shift: 8 - buf_req: 12 - next: parse_qinq - value_set IgParser_front.qinq_tpid 1: - handle: 510 - field_mapping: - hdr.ig_ft.br_tag.ether_type(0..7) : byte2(0..7) - hdr.ig_ft.br_tag.ether_type(8..15) : byte0(0..7) - 2..3: H1 # bit[20..31] -> H1 bit[11..0]: ingress::hdr.ig_ft.br_tag.ecid - 6..7: MH11 # ingress::ig_md.ig_ft.common.ether_type - 6..7: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - B12: 16 # value 1 -> B12 bit[4]: ingress::hdr.ig_ft.br_tag.$valid - load: { byte0 : 10, byte2 : 11 } - shift: 8 - buf_req: 12 - next: parse_qinq - 0x****: - 2..3: H1 # bit[20..31] -> H1 bit[11..0]: ingress::hdr.ig_ft.br_tag.ecid - 6..7: MH11 # ingress::ig_md.ig_ft.common.ether_type - 6..7: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - B12: 16 # value 1 -> B12 bit[4]: ingress::hdr.ig_ft.br_tag.$valid - shift: 8 - buf_req: 8 - next: end - parse_qinq: - match: [ byte0, byte2 ] - 0x8100: - 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid - 0..3: W10 - # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp - # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi - # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid - # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type - B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid - MH14: 33024 # value 33024 -> MH14 bit[15..0]: ingress::hdr.ig_ft.ethernet.ether_type - load: { byte0 : 6, byte2 : 7 } - shift: 4 - buf_req: 8 - next: parse_vlan_1 - 0x****: - 0..1: H67 # bit[4..15] -> H67 bit[11..0]: ingress::ig_md.ig_ft.lkp.vid - 0..3: W10 - # - bit[0..2] -> W10 bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp - # - bit[3] -> W10 bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi - # - bit[4..15] -> W10 bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid - # - bit[16..31] -> W10 bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type - B10: 2 # value 2 -> B10 bit[1..0]: ingress::hdr.ig_ft.vlan_tag.$stkvalid - MH14: 33024 # value 33024 -> MH14 bit[15..0]: ingress::hdr.ig_ft.ethernet.ether_type - shift: 4 - buf_req: 4 - next: end - parse_fabric_eth_cpu: - match: [ byte0 ] - 0b001011**: - 0: B37 - # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type - # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror - # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast - 0..1: H69 - # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc - # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color - # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track - 0..3: MW8 # bit[23..31] -> MW8 bit[8..0]: ingress::hdr.fabric_from_cpu_eth_ccm.dev_port - B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid - shift: 4 - buf_req: 4 - next: end - 0x**: - load: { byte0 : 14, byte2 : 15 } - buf_req: 16 - next: parse_fabric_eth_cpu_common - parse_fabric_eth_cpu_common: - match: [ byte0, byte2 ] - 0x0800: - 0: B37 - # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type - # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror - # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast - 0..1: H69 - # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc - # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color - # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track - 2: B15 # ingress::hdr.fabric_data_template_plus.flags - 3: B36 # ingress::hdr.fabric_data_template_plus.vb - 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 - 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 - 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 - 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 - 12..13: H13 - # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one - # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif - 14..15: MH11 # ingress::ig_md.ig_ft.common.ether_type - 14..15: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid - B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid - load: { byte0 : 16 } - shift: 16 - buf_req: 17 - next: parse_ipv4 - 0x86dd: - 0: B37 - # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type - # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror - # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast - 0..1: H69 - # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc - # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color - # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track - 2: B15 # ingress::hdr.fabric_data_template_plus.flags - 3: B36 # ingress::hdr.fabric_data_template_plus.vb - 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 - 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 - 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 - 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 - 12..13: H13 - # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one - # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif - 14..15: MH11 # ingress::ig_md.ig_ft.common.ether_type - 14..15: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid - B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid - shift: 16 - buf_req: 16 - next: parse_ipv6 - 0x8847: - 0: B37 - # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type - # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror - # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast - 0..1: H69 - # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc - # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color - # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track - 2: B15 # ingress::hdr.fabric_data_template_plus.flags - 3: B36 # ingress::hdr.fabric_data_template_plus.vb - 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 - 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 - 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 - 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 - 12..13: H13 - # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one - # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif - 14..15: MH11 # ingress::ig_md.ig_ft.common.ether_type - 14..15: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid - B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid - load: { byte0 : 18, byte1 : 22, byte2 : 26 } - shift: 16 - buf_req: 27 - next: parse_mpls - 0x8100: - 0: B37 - # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type - # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror - # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast - 0..1: H69 - # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc - # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color - # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track - 2: B15 # ingress::hdr.fabric_data_template_plus.flags - 3: B36 # ingress::hdr.fabric_data_template_plus.vb - 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 - 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 - 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 - 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 - 12..13: H13 - # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one - # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif - 14..15: MH11 # ingress::ig_md.ig_ft.common.ether_type - 14..15: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid - B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid - load: { byte0 : 18, byte2 : 19 } - shift: 16 - buf_req: 20 - next: parse_vlan - 0x****: - 0: B37 - # - bit[0..5] -> B37 bit[7..2]: ingress::hdr.fabric_base.pkt_type - # - bit[6] -> B37 bit[1]: ingress::hdr.fabric_base.is_mirror - # - bit[7] -> B37 bit[0]: ingress::hdr.fabric_base.is_mcast - 0..1: H69 - # - bit[8..10] -> H69 bit[7..5]: ingress::hdr.fabric_qos.tc - # - bit[11..12] -> H69 bit[4..3]: ingress::hdr.fabric_qos.color - # - bit[15] -> H69 bit[0]: ingress::hdr.fabric_qos.track - 2: B15 # ingress::hdr.fabric_data_template_plus.flags - 3: B36 # ingress::hdr.fabric_data_template_plus.vb - 4..5: H53 # ingress::hdr.fabric_data_template_plus.vh0 - 6..7: H19 # ingress::hdr.fabric_data_template_plus.vh1 - 8..9: H1 # ingress::hdr.fabric_data_template_plus.vh2 - 10..11: H17 # ingress::hdr.fabric_data_template_plus.vh3 - 12..13: H13 - # - bit[96] -> H13 bit[15]: ingress::hdr.fabric_data_template_plus.one - # - bit[97..111] -> H13 bit[14..0]: ingress::hdr.fabric_data_template_plus.iif - 14..15: MH11 # ingress::ig_md.ig_ft.common.ether_type - 14..15: MH14 # ingress::hdr.ig_ft.ethernet.ether_type - B10: 16 # value 1 -> B10 bit[4]: ingress::hdr.fabric_base.$valid - B13: 2 # value 1 -> B13 bit[1]: ingress::hdr.fabric_data_template_plus.$valid - shift: 16 - buf_req: 16 - next: end -deparser ingress: - dictionary: - B28: B10(5) - # - bit[7..5]: ingress::hdr.switch_bridged_src.src if ingress::hdr.switch_bridged_src.$valid - # - bit[4..0]: ingress::hdr.switch_bridged_src.bridge_type if ingress::hdr.switch_bridged_src.$valid - B37: B10(4) - # - bit[7..2]: ingress::hdr.fabric_base.pkt_type if ingress::hdr.fabric_base.$valid - # - bit[1]: ingress::hdr.fabric_base.is_mirror if ingress::hdr.fabric_base.$valid - # - bit[0]: ingress::hdr.fabric_base.is_mcast if ingress::hdr.fabric_base.$valid - B29: B9(6) # ingress::hdr.fabric_qos_encap.data if ingress::hdr.fabric_qos_encap.$valid - H24: B9(7) # ingress::hdr.bridged_md_12_encap.decap_len if ingress::hdr.bridged_md_12_encap.$valid - B15: B13(1) # ingress::hdr.fabric_data_template_plus.flags if ingress::hdr.fabric_data_template_plus.$valid - B36: B13(1) # ingress::hdr.fabric_data_template_plus.vb if ingress::hdr.fabric_data_template_plus.$valid - H53: B13(1) # ingress::hdr.fabric_data_template_plus.vh0 if ingress::hdr.fabric_data_template_plus.$valid - H19: B13(1) # ingress::hdr.fabric_data_template_plus.vh1 if ingress::hdr.fabric_data_template_plus.$valid - H1: B13(1) # ingress::hdr.fabric_data_template_plus.vh2 if ingress::hdr.fabric_data_template_plus.$valid - H17: B13(1) # ingress::hdr.fabric_data_template_plus.vh3 if ingress::hdr.fabric_data_template_plus.$valid - H13: B13(1) - # - bit[15]: ingress::hdr.fabric_data_template_plus.one if ingress::hdr.fabric_data_template_plus.$valid - # - bit[14..0]: ingress::hdr.fabric_data_template_plus.iif if ingress::hdr.fabric_data_template_plus.$valid - B11: B13(2) - # - bit[7..5]: ingress::hdr.ext_srv6.ext_type if ingress::hdr.ext_srv6.$valid - # - bit[4]: ingress::hdr.ext_srv6.extend if ingress::hdr.ext_srv6.$valid - # - bit[3]: ingress::hdr.ext_srv6.bypass_L3 if ingress::hdr.ext_srv6.$valid - # - bit[2..1]: ingress::hdr.ext_srv6.level if ingress::hdr.ext_srv6.$valid - # - bit[0]: ingress::hdr.ext_srv6.is_ecmp if ingress::hdr.ext_srv6.$valid - W7: B13(2) - # - bit[31..24]: ingress::hdr.ext_srv6.priority if ingress::hdr.ext_srv6.$valid - # - bit[23..8]: ingress::hdr.ext_srv6.nexthop if ingress::hdr.ext_srv6.$valid - # - bit[7]: ingress::hdr.ext_srv6.no_frr if ingress::hdr.ext_srv6.$valid - # - bit[6]: ingress::hdr.ext_srv6.nexthop_ext if ingress::hdr.ext_srv6.$valid - # - bit[5]: ingress::hdr.ext_srv6.is_pf if ingress::hdr.ext_srv6.$valid - # - bit[4]: ingress::hdr.ext_srv6.is_endx_pf if ingress::hdr.ext_srv6.$valid - # - bit[3..0]: ingress::hdr.ext_srv6.oam_flag if ingress::hdr.ext_srv6.$valid - B38: B13(0) - # - bit[7..5]: ingress::hdr.ext_tunnel_decap.ext_type if ingress::hdr.ext_tunnel_decap.$valid - # - bit[4]: ingress::hdr.ext_tunnel_decap.extend if ingress::hdr.ext_tunnel_decap.$valid - # - bit[3..0]: ingress::hdr.ext_tunnel_decap.sub_type if ingress::hdr.ext_tunnel_decap.$valid - B39: B13(0) # ingress::hdr.ext_tunnel_decap.vb if ingress::hdr.ext_tunnel_decap.$valid - H18: B13(0) # ingress::hdr.ext_tunnel_decap.vh if ingress::hdr.ext_tunnel_decap.$valid - H22: B12(5) - # - bit[15..13]: ingress::hdr.ext_ifit_encap.ext_type if ingress::hdr.ext_ifit_encap.$valid - # - bit[12]: ingress::hdr.ext_ifit_encap.extend if ingress::hdr.ext_ifit_encap.$valid - # - bit[11..0]: ingress::hdr.ext_ifit_encap.index if ingress::hdr.ext_ifit_encap.$valid - H21: B12(5) # ingress::hdr.ext_ifit_encap.var_h1 if ingress::hdr.ext_ifit_encap.$valid - H23: B12(1) # ingress::hdr.ig_ft.ethernet.dst_addr.32-47 if ingress::hdr.ig_ft.ethernet.$valid - MW15: B12(1) # ingress::hdr.ig_ft.ethernet.dst_addr.0-31 if ingress::hdr.ig_ft.ethernet.$valid - H55: B12(1) # ingress::hdr.ig_ft.ethernet.src_addr.32-47 if ingress::hdr.ig_ft.ethernet.$valid - MW14: B12(1) # ingress::hdr.ig_ft.ethernet.src_addr.0-31 if ingress::hdr.ig_ft.ethernet.$valid - MH14: B12(1) # ingress::hdr.ig_ft.ethernet.ether_type if ingress::hdr.ig_ft.ethernet.$valid - W10: B10(1) - # - bit[31..29]: ingress::hdr.ig_ft.vlan_tag[0].pcp if ingress::hdr.ig_ft.vlan_tag[0].$valid - # - bit[28]: ingress::hdr.ig_ft.vlan_tag[0].cfi if ingress::hdr.ig_ft.vlan_tag[0].$valid - # - bit[27..16]: ingress::hdr.ig_ft.vlan_tag[0].vid if ingress::hdr.ig_ft.vlan_tag[0].$valid - # - bit[15..0]: ingress::hdr.ig_ft.vlan_tag[0].ether_type if ingress::hdr.ig_ft.vlan_tag[0].$valid - W11: B10(0) - # - bit[31..29]: ingress::hdr.ig_ft.vlan_tag[1].pcp if ingress::hdr.ig_ft.vlan_tag[1].$valid - # - bit[28]: ingress::hdr.ig_ft.vlan_tag[1].cfi if ingress::hdr.ig_ft.vlan_tag[1].$valid - # - bit[27..16]: ingress::hdr.ig_ft.vlan_tag[1].vid if ingress::hdr.ig_ft.vlan_tag[1].$valid - # - bit[15..0]: ingress::hdr.ig_ft.vlan_tag[1].ether_type if ingress::hdr.ig_ft.vlan_tag[1].$valid - H40: B8(7) # ingress::hdr.ig_ft.mpls_ig[0].label.4-19 if ingress::hdr.ig_ft.mpls_ig[0].$valid - H5: B8(7) - # - bit[15..12]: ingress::hdr.ig_ft.mpls_ig[0].label.0-3 if ingress::hdr.ig_ft.mpls_ig[0].$valid - # - bit[11..9]: ingress::hdr.ig_ft.mpls_ig[0].exp if ingress::hdr.ig_ft.mpls_ig[0].$valid - # - bit[8]: ingress::hdr.ig_ft.mpls_ig[0].bos if ingress::hdr.ig_ft.mpls_ig[0].$valid - # - bit[7..0]: ingress::hdr.ig_ft.mpls_ig[0].ttl if ingress::hdr.ig_ft.mpls_ig[0].$valid - H39: B8(6) # ingress::hdr.ig_ft.mpls_ig[1].label.4-19 if ingress::hdr.ig_ft.mpls_ig[1].$valid - H4: B8(6) - # - bit[15..12]: ingress::hdr.ig_ft.mpls_ig[1].label.0-3 if ingress::hdr.ig_ft.mpls_ig[1].$valid - # - bit[11..9]: ingress::hdr.ig_ft.mpls_ig[1].exp if ingress::hdr.ig_ft.mpls_ig[1].$valid - # - bit[8]: ingress::hdr.ig_ft.mpls_ig[1].bos if ingress::hdr.ig_ft.mpls_ig[1].$valid - # - bit[7..0]: ingress::hdr.ig_ft.mpls_ig[1].ttl if ingress::hdr.ig_ft.mpls_ig[1].$valid - H38: B8(5) # ingress::hdr.ig_ft.mpls_ig[2].label.4-19 if ingress::hdr.ig_ft.mpls_ig[2].$valid - H3: B8(5) - # - bit[15..12]: ingress::hdr.ig_ft.mpls_ig[2].label.0-3 if ingress::hdr.ig_ft.mpls_ig[2].$valid - # - bit[11..9]: ingress::hdr.ig_ft.mpls_ig[2].exp if ingress::hdr.ig_ft.mpls_ig[2].$valid - # - bit[8]: ingress::hdr.ig_ft.mpls_ig[2].bos if ingress::hdr.ig_ft.mpls_ig[2].$valid - # - bit[7..0]: ingress::hdr.ig_ft.mpls_ig[2].ttl if ingress::hdr.ig_ft.mpls_ig[2].$valid - H37: B8(4) # ingress::hdr.ig_ft.mpls_ig[3].label.4-19 if ingress::hdr.ig_ft.mpls_ig[3].$valid - H2: B8(4) - # - bit[15..12]: ingress::hdr.ig_ft.mpls_ig[3].label.0-3 if ingress::hdr.ig_ft.mpls_ig[3].$valid - # - bit[11..9]: ingress::hdr.ig_ft.mpls_ig[3].exp if ingress::hdr.ig_ft.mpls_ig[3].$valid - # - bit[8]: ingress::hdr.ig_ft.mpls_ig[3].bos if ingress::hdr.ig_ft.mpls_ig[3].$valid - # - bit[7..0]: ingress::hdr.ig_ft.mpls_ig[3].ttl if ingress::hdr.ig_ft.mpls_ig[3].$valid - H36: B8(3) # ingress::hdr.ig_ft.mpls_ig[4].label.4-19 if ingress::hdr.ig_ft.mpls_ig[4].$valid - H0: B8(3) - # - bit[15..12]: ingress::hdr.ig_ft.mpls_ig[4].label.0-3 if ingress::hdr.ig_ft.mpls_ig[4].$valid - # - bit[11..9]: ingress::hdr.ig_ft.mpls_ig[4].exp if ingress::hdr.ig_ft.mpls_ig[4].$valid - # - bit[8]: ingress::hdr.ig_ft.mpls_ig[4].bos if ingress::hdr.ig_ft.mpls_ig[4].$valid - # - bit[7..0]: ingress::hdr.ig_ft.mpls_ig[4].ttl if ingress::hdr.ig_ft.mpls_ig[4].$valid - clot 25: - pov: hdr.ig_ft.mpls2_ig$0.$valid - clot 24: - pov: hdr.ig_ft.mpls2_ig$1.$valid - clot 23: - pov: hdr.ig_ft.mpls2_ig$2.$valid - clot 22: - pov: hdr.ig_ft.mpls2_ig$3.$valid - clot 21: - pov: hdr.ig_ft.mpls2_ig$4.$valid - clot 16: - pov: hdr.ig_ft.ipv4.$valid - 1 : B40 - MB6: B12(3) # ingress::hdr.ig_ft.ipv4_option.type if ingress::hdr.ig_ft.ipv4_option.$valid - H2: B12(3) - # - bit[15..8]: ingress::hdr.ig_ft.ipv4_option.length if ingress::hdr.ig_ft.ipv4_option.$valid - # - bit[7..0]: ingress::hdr.ig_ft.ipv4_option.value[15:8].8-15 if ingress::hdr.ig_ft.ipv4_option.$valid - clot 28: - pov: hdr.ig_ft.ipv4_option.$valid - B41: H7(5) - # - bit[7..4]: ingress::hdr.ig_ft.ipv6.version if ingress::hdr.ig_ft.ipv6.$valid - # - bit[3..0]: ingress::hdr.ig_ft.ipv6.traffic_class.4-7 if ingress::hdr.ig_ft.ipv6.$valid - B40: H7(5) - # - bit[7..4]: ingress::hdr.ig_ft.ipv6.traffic_class.0-3 if ingress::hdr.ig_ft.ipv6.$valid - # - bit[3..0]: ingress::hdr.ig_ft.ipv6.flow_label.16-19 if ingress::hdr.ig_ft.ipv6.$valid - H3: H7(5) # ingress::hdr.ig_ft.ipv6.flow_label.0-15 if ingress::hdr.ig_ft.ipv6.$valid - H0: H7(5) # ingress::hdr.ig_ft.ipv6.payload_len if ingress::hdr.ig_ft.ipv6.$valid - MB6: H7(5) # ingress::hdr.ig_ft.ipv6.next_hdr if ingress::hdr.ig_ft.ipv6.$valid - clot 27: - pov: hdr.ig_ft.ipv6.$valid - MW8: H7(5) # ingress::hdr.ig_ft.ipv6.dst_addr.96-127 if ingress::hdr.ig_ft.ipv6.$valid - MW7: H7(5) # ingress::hdr.ig_ft.ipv6.dst_addr.64-95 if ingress::hdr.ig_ft.ipv6.$valid - MW6: H7(5) # ingress::hdr.ig_ft.ipv6.dst_addr.32-63 if ingress::hdr.ig_ft.ipv6.$valid - MW3: H7(5) # ingress::hdr.ig_ft.ipv6.dst_addr.0-31 if ingress::hdr.ig_ft.ipv6.$valid - MB5: H7(15) # ingress::hdr.ig_ft.doh.next_hdr if ingress::hdr.ig_ft.doh.$valid - clot 26: - pov: hdr.ig_ft.doh.$valid - clot 15: - pov: hdr.ig_ft.srv6_h2h_ifit.$valid - B31: B12(0) # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[23:0].16-23 if ingress::hdr.ig_ft.srv6_h2h_ifit.$valid - H4: B12(0) # ingress::hdr.ig_ft.srv6_h2h_ifit.reserved3[23:0].0-15 if ingress::hdr.ig_ft.srv6_h2h_ifit.$valid - clot 19: - pov: hdr.ig_ft.srv6_srh.$valid - 3 : B14 - clot 12: - pov: hdr.ig_ft.srv6_list$0.$valid - clot 11: - pov: hdr.ig_ft.srv6_list$1.$valid - clot 10: - pov: hdr.ig_ft.srv6_list$2.$valid - clot 9: - pov: hdr.ig_ft.srv6_list$3.$valid - clot 8: - pov: hdr.ig_ft.srv6_list$4.$valid - clot 7: - pov: hdr.ig_ft.srv6_list$5.$valid - clot 6: - pov: hdr.ig_ft.srv6_list$6.$valid - clot 5: - pov: hdr.ig_ft.srv6_list$7.$valid - clot 4: - pov: hdr.ig_ft.srv6_list$8.$valid - clot 3: - pov: hdr.ig_ft.srv6_list$9.$valid - clot 2: - pov: hdr.ig_ft.srv6_list$10.$valid - B45: H7(13) # ingress::hdr.ig_ft.doh_e2e.next_hdr if ingress::hdr.ig_ft.doh_e2e.$valid - B46: H7(13) # ingress::hdr.ig_ft.doh_e2e.hdr_ext_len if ingress::hdr.ig_ft.doh_e2e.$valid - H28: H7(13) - # - bit[15..8]: ingress::hdr.ig_ft.doh_e2e.option_type if ingress::hdr.ig_ft.doh_e2e.$valid - # - bit[7..0]: ingress::hdr.ig_ft.doh_e2e.option_len if ingress::hdr.ig_ft.doh_e2e.$valid - clot 14: - pov: hdr.ig_ft.srv6_e2e_ifit.$valid - clot 17: - pov: hdr.ig_ft.udp.$valid - clot 18: - pov: hdr.ig_ft.vxlan.$valid - clot 13: - pov: hdr.ig_ft.inner_ethernet.$valid - clot 20: - pov: hdr.ig_ft.inner_vlan_tag.$valid - clot 1: - pov: hdr.ig_ft.inner_ipv4.$valid - clot 0: - pov: hdr.ig_ft.inner_ipv6.$valid - H43: H7(4) # ingress::hdr.fabric_trace.trace_counter if ingress::hdr.fabric_trace.$valid - H52: H7(4) # ingress::hdr.fabric_trace.timestamp.32-47 if ingress::hdr.fabric_trace.$valid - MW11: H7(4) # ingress::hdr.fabric_trace.timestamp.0-31 if ingress::hdr.fabric_trace.$valid - egress_unicast_port: { MW9(0..8): B10(2) } # bit[8..0]: ingress::ig_intr_md_for_tm.ucast_egress_port if ingress::ig_intr_md_for_tm.ucast_egress_port.$valid - deflect_on_drop: { H31(1..1): H7(2) } # bit[1]: ingress::ig_intr_md_for_tm.deflect_on_drop if ingress::ig_intr_md_for_tm.deflect_on_drop.$valid - qid: { H30(0..6): B9(5) } # bit[6..0]: ingress::ig_intr_md_for_tm.qid if ingress::ig_intr_md_for_tm.qid.$valid - bypss_egr: { B12(6..6): H7(1) } # bit[6]: ingress::ig_intr_md_for_tm.bypass_egress if ingress::ig_intr_md_for_tm.bypass_egress.$valid - drop_ctl: { W6(2..4): B10(3) } # bit[4..2]: ingress::ig_intr_md_for_dprsr.drop_ctl if ingress::ig_intr_md_for_dprsr.drop_ctl.$valid - mirr_io_sel: { H31(0..0): H7(3) } # bit[0]: ingress::ig_intr_md_for_dprsr.mirror_io_select if ingress::ig_intr_md_for_dprsr.mirror_io_select.$valid - mirror: - select: { B1(0..3): H7(0) } # bit[3..0]: ingress::ig_intr_md_for_dprsr.mirror_type - 0: - - B0 # ingress::$tmp11 - 1: - - MB7 # ingress::ig_md.ig_ft.mirror.session_id - - MB0 - # - bit[7..5]: ingress::ig_md.ig_ft.mirror.src - # - bit[4..0]: ingress::ig_md.ig_ft.mirror.type - - MB7 # ingress::ig_md.ig_ft.mirror.session_id - - B37 - # - bit[7..2]: ingress::hdr.fabric_base.pkt_type - # - bit[1]: ingress::hdr.fabric_base.is_mirror - # - bit[0]: ingress::hdr.fabric_base.is_mcast - - B29 # ingress::hdr.fabric_qos_encap.data - - MB2 # ingress::ig_md.ig_ft.mirror.flags - - MB13 # ingress::ig_md.ig_ft.common.src_port - - H53 # ingress::hdr.fabric_data_template_plus.vh0 - - H56 # ingress::ig_md.ig_ft.common.mirror_dst_eport - - H15(0..14) # bit[14..0]: ingress::ig_md.ig_ft.common.iif - - H54 # ingress::ig_md.ig_ft.ifit.var_h1 - - H14(0..14) # bit[14..0]: ingress::ig_md.ig_ft.common.ul_iif - 7: - - MB7 # ingress::ig_md.ig_ft.mirror.session_id - - MB0 - # - bit[7..5]: ingress::ig_md.ig_ft.mirror.src - # - bit[4..0]: ingress::ig_md.ig_ft.mirror.type - - MB7 # ingress::ig_md.ig_ft.mirror.session_id - - H56 # ingress::ig_md.ig_ft.common.mirror_dst_eport - - B37 - # - bit[7..2]: ingress::hdr.fabric_base.pkt_type - # - bit[1]: ingress::hdr.fabric_base.is_mirror - # - bit[0]: ingress::hdr.fabric_base.is_mcast - - B29 # ingress::hdr.fabric_qos_encap.data - - MB15 # ingress::ig_md.ig_ft.common.pipeline_location - - MB15 # ingress::ig_md.ig_ft.common.pipeline_location - - H43 # ingress::hdr.fabric_trace.trace_counter - - B30 # ingress::ig_md.ig_ft.common.drop_reason - - B30 # ingress::ig_md.ig_ft.common.drop_reason - - H53 # ingress::hdr.fabric_data_template_plus.vh0 - - H57 # ingress::ig_md.ig_ft.common.trace_vh3 - - H14(0..14) # bit[14..0]: ingress::ig_md.ig_ft.common.ul_iif - - H52 # ingress::hdr.fabric_trace.timestamp.32-47 - - MW11 # ingress::hdr.fabric_trace.timestamp.0-31 - 6: - - MB7 # ingress::ig_md.ig_ft.mirror.session_id - - MB0 - # - bit[7..5]: ingress::ig_md.ig_ft.mirror.src - # - bit[4..0]: ingress::ig_md.ig_ft.mirror.type - - MB7 # ingress::ig_md.ig_ft.mirror.session_id - - B37 - # - bit[7..2]: ingress::hdr.fabric_base.pkt_type - # - bit[1]: ingress::hdr.fabric_base.is_mirror - # - bit[0]: ingress::hdr.fabric_base.is_mcast - - B29 # ingress::hdr.fabric_qos_encap.data - - MB2 # ingress::ig_md.ig_ft.mirror.flags - - MB13 # ingress::ig_md.ig_ft.common.src_port - - H53 # ingress::hdr.fabric_data_template_plus.vh0 - - H56 # ingress::ig_md.ig_ft.common.mirror_dst_eport - - H15(0..14) # bit[14..0]: ingress::ig_md.ig_ft.common.iif - - H12 - # - bit[15]: ingress::ig_md.ig_ft.tunnel.ipv4_true - # - bit[14]: ingress::ig_md.ig_ft.flags.tunnel_info - # - bit[12..0]: ingress::ig_md.ig_ft.route.vrf - - H14(0..14) # bit[14..0]: ingress::ig_md.ig_ft.common.ul_iif -parser egress: - start: hdr.eg_ft.vlan_tag$shim.$entry_point - bitwise_or: [ B7, B22, B23, B24, B25, B32, B33, H9 ] - clear_on_write: [ MB3, MH15 ] - hdr_len_adj: 28 - meta_opt: 8191 - states: - hdr.eg_ft.vlan_tag$shim.$entry_point: - *: - 52..55: MW12 # buffer mapped I/O: bit[416..447] -> MW12 bit[31..0]: egress::eg_intr_md_from_prsr.global_tstamp[31:0].0-31 - 50..51: H42 # buffer mapped I/O: bit[400..415] -> H42 bit[15..0]: egress::eg_intr_md_from_prsr.global_tstamp[47:32].32-47 - B7: 8 # value 8 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - intr_md: 48 - load: { byte0 : 28 } - buf_req: 29 - next: start - start: - match: [ byte0 ] - 0x00: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - load: { byte0 : 29, byte1 : 31 } - shift: 28 - buf_req: 32 - next: parse_bridged_pkt_910 - 0x03: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - shift: 28 - buf_req: 28 - next: parse_bridged_pkt_110 - 0x05: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - load: { byte0 : 31 } - shift: 28 - buf_req: 32 - next: parse_bridged_pkt_310 - 0x06: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - load: { byte0 : 29 } - shift: 28 - buf_req: 30 - next: parse_bridged_pkt_recirc - 0x08: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - shift: 28 - buf_req: 28 - next: start.$oob_stall_0 - 0x09: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - load: { byte0 : 29 } - shift: 28 - buf_req: 30 - next: parse_bridged_pkt_710_front - 0x0b: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - shift: 28 - buf_req: 28 - next: parse_bridged_pkt_910_ccm - 0x0c: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - load: { byte0 : 29 } - shift: 28 - buf_req: 30 - next: parse_bridged_pkt_recirc - 0x0f: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - shift: 28 - buf_req: 28 - next: parse_bridged_pkt_signal - 0x10: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - shift: 28 - buf_req: 28 - next: parse_bridged_pkt_110_recirc - 0x11: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - shift: 28 - buf_req: 28 - next: start.$oob_stall_1 - 0x48: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - shift: 28 - buf_req: 28 - next: parse_xon_xoff_mirrored_metadata - 0x49: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - shift: 28 - buf_req: 28 - next: parse_xon_xoff_mirrored_metadata - 0x27: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - shift: 28 - buf_req: 28 - next: parse_common_mirrored_metadata - 0x47: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - shift: 28 - buf_req: 28 - next: parse_common_mirrored_metadata - 0x30: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - shift: 28 - buf_req: 28 - next: parse_common_mirrored_metadata - 0x50: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - shift: 28 - buf_req: 28 - next: parse_common_mirrored_metadata - 0x31: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - shift: 28 - buf_req: 28 - next: parse_common_mirrored_metadata - 0x51: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - shift: 28 - buf_req: 28 - next: parse_common_mirrored_metadata - 0x32: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - shift: 28 - buf_req: 28 - next: parse_ig_uplink_ifit_mirrored_metadata - 0x**: - 0..1: MH16 # bit[7..15] -> MH16 bit[8..0]: egress::eg_intr_md.egress_port - 9..12: W29 # bit[85..103] -> W29 bit[18..0]: egress::eg_md.eg_ft.qos.qdepth - 15..18: MW4 # egress::eg_md.eg_ft.common.deq_timedelta - 24..27: W36 # bit[199] -> W36 bit[24]: egress::eg_intr_md.deflection_flag - 25..26: H25 # egress::eg_md.eg_ft.common.pkt_length - MH18: 1 # value 1 -> MH18 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select - H9: 3 - # - value 1 -> H9 bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - # - value 1 -> H9 bit[1]: egress::eg_intr_md.egress_port.$valid - intr_md: 10 - shift: 28 - buf_req: 28 - next: parse_ghost - parse_bridged_pkt_910: - match: [ byte1, byte0 ] - 0o1*****: - 0..3: W34 - # - bit[25] -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu - # - bit[26] -> W34 bit[5]: egress::eg_md.eg_ft.common.diag - # - bit[27] -> W34 bit[4]: egress::eg_md.eg_ft.flags.drop - # - bit[28..29] -> W34 bit[3..2]: egress::eg_md.eg_ft.lkp.ip_frag - # - bit[31] -> W34 bit[0]: egress::eg_md.eg_ft.flags.bypass_sec_acl - 1: B25 - # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast - 2: B24 - # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc - # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color - # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track - 4: B20 # egress::eg_md.eg_ft.common.dst_port - 5..6: H61 # egress::eg_md.eg_ft.common.hash - 9..10: H50 # bit[73..87] -> H50 bit[14..0]: egress::eg_md.eg_ft.common.oif - 9..12: W33 # bit[90..103] -> W33 bit[13..0]: egress::eg_md.eg_ft.ebridge.evlan - 13..14: H49 # bit[105..119] -> H49 bit[14..0]: egress::eg_md.eg_ft.common.iif - 21..24: W27 # egress::eg_md.eg_ft.lkp.l4_port_label_64[63:32].32-63 - 25..28: W26 # egress::eg_md.eg_ft.lkp.l4_port_label_64[31:0].0-31 - 29..30: MH8 # egress::eg_md.eg_ft.common.decap_len - shift: 31 - buf_req: 31 - next: parse_ext_ifit - 0x****: - 0..3: W34 - # - bit[25] -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu - # - bit[26] -> W34 bit[5]: egress::eg_md.eg_ft.common.diag - # - bit[27] -> W34 bit[4]: egress::eg_md.eg_ft.flags.drop - # - bit[28..29] -> W34 bit[3..2]: egress::eg_md.eg_ft.lkp.ip_frag - # - bit[31] -> W34 bit[0]: egress::eg_md.eg_ft.flags.bypass_sec_acl - 1: B25 - # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast - 2: B24 - # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc - # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color - # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track - 4: B20 # egress::eg_md.eg_ft.common.dst_port - 5..6: H61 # egress::eg_md.eg_ft.common.hash - 9..10: H50 # bit[73..87] -> H50 bit[14..0]: egress::eg_md.eg_ft.common.oif - 9..12: W33 # bit[90..103] -> W33 bit[13..0]: egress::eg_md.eg_ft.ebridge.evlan - 13..14: H49 # bit[105..119] -> H49 bit[14..0]: egress::eg_md.eg_ft.common.iif - 21..24: W27 # egress::eg_md.eg_ft.lkp.l4_port_label_64[63:32].32-63 - 25..28: W26 # egress::eg_md.eg_ft.lkp.l4_port_label_64[31:0].0-31 - 29..30: MH8 # egress::eg_md.eg_ft.common.decap_len - shift: 31 - buf_req: 31 - next: parse_bridged_pkt_910.$oob_stall_0 - parse_ext_ifit: - *: - 0..1: H68 # bit[4..15] -> H68 bit[11..0]: egress::eg_md.eg_ft.ifit.index - 2: B43 - # - bit[19] -> B43 bit[4]: egress::eg_md.eg_ft.ifit.ifit_decap_enable - # - bit[20] -> B43 bit[3]: egress::eg_md.eg_ft.ifit.loss_label - # - bit[21] -> B43 bit[2]: egress::eg_md.eg_ft.ifit.delay_stats_flag - H9: 8 # value 1 -> H9 bit[3]: egress::hdr.ext_ifit.$valid - load: { byte0 : 16, byte1 : 17 } - shift: 4 - buf_req: 18 - next: parse_ethernet - parse_ethernet: - match: [ byte0, byte1 ] - 0x0800: - 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 - 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 - 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 - 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 - 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type - 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type - H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid - load: { byte0 : 14, byte1 : 20, byte2 : 21, byte3 : 23 } - shift: 14 - buf_req: 24 - next: parse_ipv4 - 0x86dd: - 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 - 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 - 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 - 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 - 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type - 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type - H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid - shift: 14 - buf_req: 14 - next: parse_ipv6 - 0x8847: - 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 - 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 - 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 - 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 - 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type - 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type - H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid - shift: 14 - buf_req: 14 - next: parse_mpls - 0x8100: - 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 - 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 - 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 - 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 - 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type - 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type - H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid - load: { byte0 : 16, byte1 : 17 } - shift: 14 - buf_req: 18 - next: parse_vlan - 0x****: - 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 - 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 - 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 - 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 - 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type - 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type - H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid - shift: 14 - buf_req: 14 - next: parse_pad - parse_ipv4: - match: [ byte3, byte0, byte1, byte2 ] - 0b00010001****0101***0000000000000: - checksum 0: - type: RESIDUAL - mask: [ 0, 1, 10..11 ] - swap: 0 - start: 1 - end: 1 - dest: MH7 - end_pos: 19 - checksum 2: - type: CLOT - mask: [ 0 ] - swap: 0 - start: 1 - end: 1 - dest: clot 2 - 0..1: H34 - # - bit[0..3] -> H34 bit[15..12]: egress::hdr.eg_ft.ipv4.version - # - bit[4..7] -> H34 bit[11..8]: egress::hdr.eg_ft.ipv4.ihl - # - bit[8..15] -> H34 bit[7..0]: egress::hdr.eg_ft.ipv4.diffserv - 9: MB3 # egress::eg_md.eg_ft.lkp.ip_proto - 10..11: MH2 # egress::hdr.eg_ft.ipv4.hdr_checksum - 12..13: H58 # egress::eg_md.eg_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H63 # egress::eg_md.eg_ft.lkp.ip_src_addr[15:0].0-15 - 16..19: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 - H9: 32 # value 1 -> H9 bit[5]: egress::hdr.eg_ft.ipv4.$valid - clot 2 : - start: 0 - length: 20 - checksum: 2 - shift: 20 - buf_req: 20 - next: parse_udp - 0b00000110****0101***0000000000000: - checksum 0: - type: RESIDUAL - mask: [ 0, 1, 10..11 ] - swap: 0 - start: 1 - end: 1 - dest: MH7 - end_pos: 19 - checksum 2: - type: CLOT - mask: [ 0 ] - swap: 0 - start: 1 - end: 1 - dest: clot 2 - 0..1: H34 - # - bit[0..3] -> H34 bit[15..12]: egress::hdr.eg_ft.ipv4.version - # - bit[4..7] -> H34 bit[11..8]: egress::hdr.eg_ft.ipv4.ihl - # - bit[8..15] -> H34 bit[7..0]: egress::hdr.eg_ft.ipv4.diffserv - 9: MB3 # egress::eg_md.eg_ft.lkp.ip_proto - 10..11: MH2 # egress::hdr.eg_ft.ipv4.hdr_checksum - 12..13: H58 # egress::eg_md.eg_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H63 # egress::eg_md.eg_ft.lkp.ip_src_addr[15:0].0-15 - 16..19: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 - H9: 32 # value 1 -> H9 bit[5]: egress::hdr.eg_ft.ipv4.$valid - clot 2 : - start: 0 - length: 20 - checksum: 2 - shift: 20 - buf_req: 20 - next: parse_tcp - 0b00000001****0101***0000000000000: - checksum 0: - type: RESIDUAL - mask: [ 0, 1, 10..11 ] - swap: 0 - start: 1 - end: 1 - dest: MH7 - end_pos: 19 - checksum 2: - type: CLOT - mask: [ 0 ] - swap: 0 - start: 1 - end: 1 - dest: clot 2 - 0..1: H34 - # - bit[0..3] -> H34 bit[15..12]: egress::hdr.eg_ft.ipv4.version - # - bit[4..7] -> H34 bit[11..8]: egress::hdr.eg_ft.ipv4.ihl - # - bit[8..15] -> H34 bit[7..0]: egress::hdr.eg_ft.ipv4.diffserv - 9: MB3 # egress::eg_md.eg_ft.lkp.ip_proto - 10..11: MH2 # egress::hdr.eg_ft.ipv4.hdr_checksum - 12..13: H58 # egress::eg_md.eg_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H63 # egress::eg_md.eg_ft.lkp.ip_src_addr[15:0].0-15 - 16..19: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 - H9: 32 # value 1 -> H9 bit[5]: egress::hdr.eg_ft.ipv4.$valid - clot 2 : - start: 0 - length: 20 - checksum: 2 - shift: 20 - buf_req: 20 - next: parse_icmp - 0x***6****: - checksum 0: - type: RESIDUAL - mask: [ 0, 1, 10..11 ] - swap: 0 - start: 1 - end: 1 - dest: MH7 - end_pos: 19 - checksum 2: - type: CLOT - mask: [ 0 ] - swap: 0 - start: 1 - end: 1 - dest: clot 2 - 0..1: H34 - # - bit[0..3] -> H34 bit[15..12]: egress::hdr.eg_ft.ipv4.version - # - bit[4..7] -> H34 bit[11..8]: egress::hdr.eg_ft.ipv4.ihl - # - bit[8..15] -> H34 bit[7..0]: egress::hdr.eg_ft.ipv4.diffserv - 9: MB3 # egress::eg_md.eg_ft.lkp.ip_proto - 10..11: MH2 # egress::hdr.eg_ft.ipv4.hdr_checksum - 12..13: H58 # egress::eg_md.eg_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H63 # egress::eg_md.eg_ft.lkp.ip_src_addr[15:0].0-15 - 16..19: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 - H9: 32 # value 1 -> H9 bit[5]: egress::hdr.eg_ft.ipv4.$valid - clot 2 : - start: 0 - length: 20 - checksum: 2 - load: { byte0 : 6, byte1 : 7, byte2 : 9 } - shift: 20 - buf_req: 20 - next: parse_ipv4_options - 0x***5****: - checksum 0: - type: RESIDUAL - mask: [ 0, 1, 10..11 ] - swap: 0 - start: 1 - end: 1 - dest: MH7 - end_pos: 19 - checksum 2: - type: CLOT - mask: [ 0 ] - swap: 0 - start: 1 - end: 1 - dest: clot 2 - 0..1: H34 - # - bit[0..3] -> H34 bit[15..12]: egress::hdr.eg_ft.ipv4.version - # - bit[4..7] -> H34 bit[11..8]: egress::hdr.eg_ft.ipv4.ihl - # - bit[8..15] -> H34 bit[7..0]: egress::hdr.eg_ft.ipv4.diffserv - 9: MB3 # egress::eg_md.eg_ft.lkp.ip_proto - 10..11: MH2 # egress::hdr.eg_ft.ipv4.hdr_checksum - 12..13: H58 # egress::eg_md.eg_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H63 # egress::eg_md.eg_ft.lkp.ip_src_addr[15:0].0-15 - 16..19: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 - H9: 32 # value 1 -> H9 bit[5]: egress::hdr.eg_ft.ipv4.$valid - clot 2 : - start: 0 - length: 20 - checksum: 2 - shift: 20 - buf_req: 20 - next: parse_pad - 0x********: - checksum 0: - type: RESIDUAL - mask: [ 0, 1, 10..11 ] - swap: 0 - start: 1 - end: 1 - dest: MH7 - end_pos: 19 - checksum 2: - type: CLOT - mask: [ 0 ] - swap: 0 - start: 1 - end: 1 - dest: clot 2 - 0..1: H34 - # - bit[0..3] -> H34 bit[15..12]: egress::hdr.eg_ft.ipv4.version - # - bit[4..7] -> H34 bit[11..8]: egress::hdr.eg_ft.ipv4.ihl - # - bit[8..15] -> H34 bit[7..0]: egress::hdr.eg_ft.ipv4.diffserv - 9: MB3 # egress::eg_md.eg_ft.lkp.ip_proto - 10..11: MH2 # egress::hdr.eg_ft.ipv4.hdr_checksum - 12..13: H58 # egress::eg_md.eg_ft.lkp.ip_src_addr[31:16].16-31 - 14..15: H63 # egress::eg_md.eg_ft.lkp.ip_src_addr[15:0].0-15 - 16..19: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 - H9: 32 # value 1 -> H9 bit[5]: egress::hdr.eg_ft.ipv4.$valid - clot 2 : - start: 0 - length: 20 - checksum: 2 - shift: 20 - buf_req: 20 - next: parse_pad - parse_udp: - *: - 0..1: H59 # egress::eg_md.eg_ft.lkp.l4_src_port - 0..3: W32 # bit[16..31] -> W32 bit[15..0]: egress::eg_md.eg_ft.lkp.l4_dst_port - buf_req: 4 - next: parse_pad - parse_pad: - *: - B7: 32 - # - value 1 -> B7 bit[5]: egress::hdr.pad.$valid - # - value 1 -> B7 bit[5]: egress::hdr.pad.$valid - clot 0 : - start: 0 - length: 64 - buf_req: 0 - next: end - parse_tcp: - *: - 0..1: H59 # egress::eg_md.eg_ft.lkp.l4_src_port - 0..3: W32 # bit[16..31] -> W32 bit[15..0]: egress::eg_md.eg_ft.lkp.l4_dst_port - 10..13: W35 # bit[104..111] -> W35 bit[7..0]: egress::eg_md.eg_ft.lkp.tcp_flags - buf_req: 14 - next: parse_pad - parse_icmp: - *: - 0..1: H59 # egress::eg_md.eg_ft.lkp.l4_src_port - buf_req: 2 - next: parse_pad - parse_ipv4_options: - match: [ byte2, byte0, byte1 ] - 0b00010001***0000000000000: - 4..5: H59 # egress::eg_md.eg_ft.lkp.l4_src_port - 4..7: W32 # bit[48..63] -> W32 bit[15..0]: egress::eg_md.eg_ft.lkp.l4_dst_port - buf_req: 8 - next: parse_pad - 0b00000110***0000000000000: - 4..5: H59 # egress::eg_md.eg_ft.lkp.l4_src_port - 4..7: W32 # bit[48..63] -> W32 bit[15..0]: egress::eg_md.eg_ft.lkp.l4_dst_port - 14..17: W35 # bit[136..143] -> W35 bit[7..0]: egress::eg_md.eg_ft.lkp.tcp_flags - buf_req: 18 - next: parse_pad - 0b00000001***0000000000000: - 4..5: H59 # egress::eg_md.eg_ft.lkp.l4_src_port - buf_req: 6 - next: parse_pad - 0x******: - buf_req: 0 - next: parse_pad - parse_ipv6: - *: - 0..1: H34 - # - bit[0..3] -> H34 bit[15..12]: egress::hdr.eg_ft.ipv6.version - # - bit[4..11] -> H34 bit[11..4]: egress::hdr.eg_ft.ipv6.traffic_class - # - bit[12..15] -> H34 bit[3..0]: egress::hdr.eg_ft.ipv6.flow_label[19:16].16-19 - 2..3: H35 # egress::hdr.eg_ft.ipv6.flow_label[15:0].0-15 - 6: MB3 # egress::eg_md.eg_ft.lkp.ip_proto - 8..11: W20 # egress::eg_md.eg_ft.lkp.ip_src_addr[127:96].96-127 - 12..15: W19 # egress::eg_md.eg_ft.lkp.ip_src_addr[95:64].64-95 - 16..19: W18 # egress::eg_md.eg_ft.lkp.ip_src_addr[63:32].32-63 - 20..21: H58 # egress::eg_md.eg_ft.lkp.ip_src_addr[31:16].16-31 - 22..23: H63 # egress::eg_md.eg_ft.lkp.ip_src_addr[15:0].0-15 - 24..27: W25 # egress::eg_md.eg_ft.lkp.ip_dst_addr[127:96].96-127 - 28..31: W23 # egress::eg_md.eg_ft.lkp.ip_dst_addr[95:64].64-95 - H9: 64 # value 1 -> H9 bit[6]: egress::hdr.eg_ft.ipv6.$valid - clot 1 : - start: 4 - length: 36 - load: { byte0 : 6 } - shift: 32 - buf_req: 32 - next: parse_ipv6.$split_0 - parse_ipv6.$split_0: - match: [ byte0 ] - 0x06: - 0..3: W22 # egress::eg_md.eg_ft.lkp.ip_dst_addr[63:32].32-63 - 4..7: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 - # clot 1 (spilled) - shift: 8 - buf_req: 8 - next: parse_tcp - 0x11: - 0..3: W22 # egress::eg_md.eg_ft.lkp.ip_dst_addr[63:32].32-63 - 4..7: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 - # clot 1 (spilled) - shift: 8 - buf_req: 8 - next: parse_udp - 0x3a: - 0..3: W22 # egress::eg_md.eg_ft.lkp.ip_dst_addr[63:32].32-63 - 4..7: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 - # clot 1 (spilled) - shift: 8 - buf_req: 8 - next: parse_icmp - 0x2c: - 0..3: W22 # egress::eg_md.eg_ft.lkp.ip_dst_addr[63:32].32-63 - 4..7: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 - # clot 1 (spilled) - load: { byte0 : 8, byte1 : 10, byte2 : 11 } - shift: 8 - buf_req: 12 - next: parse_ipv6_frag - 0x**: - 0..3: W22 # egress::eg_md.eg_ft.lkp.ip_dst_addr[63:32].32-63 - 4..7: W21 # egress::eg_md.eg_ft.lkp.ip_dst_addr[31:0].0-31 - # clot 1 (spilled) - shift: 8 - buf_req: 8 - next: parse_pad - parse_ipv6_frag: - match: [ byte0, byte1, byte2 ] - 0o0140000*: - 0: MB3 # egress::eg_md.eg_ft.lkp.ip_proto - H9: 128 # value 1 -> H9 bit[7]: egress::hdr.eg_ft.ipv6_frag.$valid - clot 4 : - start: 0 - length: 8 - shift: 8 - buf_req: 8 - next: parse_tcp - 0o0420000*: - 0: MB3 # egress::eg_md.eg_ft.lkp.ip_proto - H9: 128 # value 1 -> H9 bit[7]: egress::hdr.eg_ft.ipv6_frag.$valid - clot 4 : - start: 0 - length: 8 - shift: 8 - buf_req: 8 - next: parse_udp - 0o1640000*: - 0: MB3 # egress::eg_md.eg_ft.lkp.ip_proto - H9: 128 # value 1 -> H9 bit[7]: egress::hdr.eg_ft.ipv6_frag.$valid - clot 4 : - start: 0 - length: 8 - shift: 8 - buf_req: 8 - next: parse_icmp - 0x******: - 0: MB3 # egress::eg_md.eg_ft.lkp.ip_proto - H9: 128 # value 1 -> H9 bit[7]: egress::hdr.eg_ft.ipv6_frag.$valid - clot 4 : - start: 0 - length: 8 - shift: 8 - buf_req: 8 - next: parse_pad - parse_mpls: - *: - H9: 256 # value 1 -> H9 bit[8]: egress::hdr.eg_ft.mpls_vc_eg.$valid - clot 6 : - start: 0 - length: 4 - shift: 4 - buf_req: 4 - next: parse_pad - parse_vlan: - match: [ byte0, byte1 ] - 0x0800: - 0..1: H45 - # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp - # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi - # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid - 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type - 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type - B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - load: { byte0 : 4, byte1 : 10, byte2 : 11, byte3 : 13 } - shift: 4 - buf_req: 14 - next: parse_ipv4 - 0x86dd: - 0..1: H45 - # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp - # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi - # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid - 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type - 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type - B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv6 - 0x8847: - 0..1: H45 - # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp - # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi - # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid - 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type - 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type - B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_mpls - 0x8100: - 0..1: H45 - # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp - # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi - # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid - 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type - 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type - B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - load: { byte0 : 6, byte1 : 7 } - shift: 4 - buf_req: 8 - next: parse_vlan.$it1 - 0x****: - 0..1: H45 - # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp - # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi - # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid - 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type - 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type - B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_pad - parse_vlan.$it1: - match: [ byte0, byte1 ] - 0x0800: - 0..1: H44 - # - bit[0..2] -> H44 bit[15..13]: egress::hdr.eg_ft.vlan_tag[1].pcp - # - bit[3] -> H44 bit[12]: egress::hdr.eg_ft.vlan_tag[1].cfi - # - bit[4..15] -> H44 bit[11..0]: egress::hdr.eg_ft.vlan_tag[1].vid - 2..3: MH21 # egress::hdr.eg_ft.vlan_tag[1].ether_type - 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type - B7: 2 # value 2 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - load: { byte0 : 4, byte1 : 10, byte2 : 11, byte3 : 13 } - shift: 4 - buf_req: 14 - next: parse_ipv4 - 0x86dd: - 0..1: H44 - # - bit[0..2] -> H44 bit[15..13]: egress::hdr.eg_ft.vlan_tag[1].pcp - # - bit[3] -> H44 bit[12]: egress::hdr.eg_ft.vlan_tag[1].cfi - # - bit[4..15] -> H44 bit[11..0]: egress::hdr.eg_ft.vlan_tag[1].vid - 2..3: MH21 # egress::hdr.eg_ft.vlan_tag[1].ether_type - 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type - B7: 2 # value 2 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv6 - 0x8847: - 0..1: H44 - # - bit[0..2] -> H44 bit[15..13]: egress::hdr.eg_ft.vlan_tag[1].pcp - # - bit[3] -> H44 bit[12]: egress::hdr.eg_ft.vlan_tag[1].cfi - # - bit[4..15] -> H44 bit[11..0]: egress::hdr.eg_ft.vlan_tag[1].vid - 2..3: MH21 # egress::hdr.eg_ft.vlan_tag[1].ether_type - 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type - B7: 2 # value 2 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_mpls - 0x8100: - 0..1: H44 - # - bit[0..2] -> H44 bit[15..13]: egress::hdr.eg_ft.vlan_tag[1].pcp - # - bit[3] -> H44 bit[12]: egress::hdr.eg_ft.vlan_tag[1].cfi - # - bit[4..15] -> H44 bit[11..0]: egress::hdr.eg_ft.vlan_tag[1].vid - 2..3: MH21 # egress::hdr.eg_ft.vlan_tag[1].ether_type - 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type - B7: 2 # value 2 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - 0x****: - 0..1: H44 - # - bit[0..2] -> H44 bit[15..13]: egress::hdr.eg_ft.vlan_tag[1].pcp - # - bit[3] -> H44 bit[12]: egress::hdr.eg_ft.vlan_tag[1].cfi - # - bit[4..15] -> H44 bit[11..0]: egress::hdr.eg_ft.vlan_tag[1].vid - 2..3: MH21 # egress::hdr.eg_ft.vlan_tag[1].ether_type - 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type - B7: 2 # value 2 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_pad - parse_bridged_pkt_910.$oob_stall_0: - *: - load: { byte0 : 12, byte1 : 13 } - buf_req: 14 - next: parse_ethernet - parse_bridged_pkt_110: - *: - 1: B25 - # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast - 2: B24 - # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc - # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color - # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track - 3..4: MH8 # egress::eg_md.eg_ft.common.decap_len - 10: B20 # egress::eg_md.eg_ft.common.dst_port - load: { byte0 : 29, byte1 : 30 } - shift: 17 - buf_req: 31 - next: parse_ethernet - parse_bridged_pkt_310: - match: [ byte0 ] - 0x**: - 1: B25 - # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast - 2: B24 - # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc - # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color - # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track - 8: B20 # egress::eg_md.eg_ft.common.dst_port - 9..10: H50 # bit[73..87] -> H50 bit[14..0]: egress::eg_md.eg_ft.common.oif - W34: 64 # value 1 -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu - load: { byte0 : 27, byte1 : 28 } - shift: 15 - buf_req: 29 - next: parse_ethernet_310 - parse_ethernet_310: - match: [ byte0, byte1 ] - 0x8100: - 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 - 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 - 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 - 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 - 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type - 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type - H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid - load: { byte0 : 16, byte1 : 17 } - shift: 14 - buf_req: 18 - next: parse_vlan_310 - 0x0800: - 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 - 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 - 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 - 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 - 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type - 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type - H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid - shift: 14 - buf_req: 14 - next: parse_ipv4_310 - 0x86dd: - 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 - 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 - 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 - 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 - 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type - 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type - H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid - shift: 14 - buf_req: 14 - next: parse_ipv6_310 - 0x****: - 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 - 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 - 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 - 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 - 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type - 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type - H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid - shift: 14 - buf_req: 14 - next: end - parse_vlan_310: - match: [ byte0, byte1 ] - 0x8100: - 0..1: H45 - # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp - # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi - # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid - 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type - 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type - B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_vlan1_310 - 0x0800: - 0..1: H45 - # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp - # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi - # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid - 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type - 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type - B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv4_310 - 0x86dd: - 0..1: H45 - # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp - # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi - # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid - 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type - 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type - B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_ipv6_310 - 0x****: - 0..1: H45 - # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp - # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi - # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid - 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type - 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type - B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_vlan1_310: - *: - 0..1: H44 - # - bit[0..2] -> H44 bit[15..13]: egress::hdr.eg_ft.vlan_tag[1].pcp - # - bit[3] -> H44 bit[12]: egress::hdr.eg_ft.vlan_tag[1].cfi - # - bit[4..15] -> H44 bit[11..0]: egress::hdr.eg_ft.vlan_tag[1].vid - 2..3: MH21 # egress::hdr.eg_ft.vlan_tag[1].ether_type - 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type - B7: 2 # value 2 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_ipv4_310: - *: - checksum 0: - type: RESIDUAL - mask: [ 0, 1, 10..11 ] - swap: 0 - start: 1 - end: 1 - dest: MH7 - end_pos: 19 - checksum 2: - type: CLOT - mask: [ 0 ] - swap: 0 - start: 1 - end: 1 - dest: clot 2 - 0..1: H34 - # - bit[0..3] -> H34 bit[15..12]: egress::hdr.eg_ft.ipv4.version - # - bit[4..7] -> H34 bit[11..8]: egress::hdr.eg_ft.ipv4.ihl - # - bit[8..15] -> H34 bit[7..0]: egress::hdr.eg_ft.ipv4.diffserv - 10..11: MH2 # egress::hdr.eg_ft.ipv4.hdr_checksum - H9: 32 # value 1 -> H9 bit[5]: egress::hdr.eg_ft.ipv4.$valid - clot 2 : - start: 0 - length: 20 - checksum: 2 - shift: 20 - buf_req: 20 - next: end - parse_ipv6_310: - *: - 0..1: H34 - # - bit[0..3] -> H34 bit[15..12]: egress::hdr.eg_ft.ipv6.version - # - bit[4..11] -> H34 bit[11..4]: egress::hdr.eg_ft.ipv6.traffic_class - # - bit[12..15] -> H34 bit[3..0]: egress::hdr.eg_ft.ipv6.flow_label[19:16].16-19 - 2..3: H35 # egress::hdr.eg_ft.ipv6.flow_label[15:0].0-15 - H9: 64 # value 1 -> H9 bit[6]: egress::hdr.eg_ft.ipv6.$valid - clot 1 : - start: 4 - length: 36 - shift: 32 - buf_req: 32 - next: parse_ipv6_310.$split_0 - parse_ipv6_310.$split_0: - *: - # clot 1 (spilled) - shift: 8 - buf_req: 8 - next: end - parse_bridged_pkt_recirc: - match: [ byte0 ] - 0b011100**: - 1: B23 - # - bit[0..5] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[6] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[7] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 1: B25 - # - bit[0..5] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - bit[6] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - # - bit[7] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast - 2: B22 - # - bit[8..10] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[11..12] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[13] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[14] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[15] -> B22 bit[0]: egress::hdr.fabric_qos.track - 2: B24 - # - bit[8..10] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc - # - bit[11..12] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color - # - bit[15] -> B24 bit[0]: egress::eg_md.eg_ft.common.track - 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 13..14: H11 - # - bit[96] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[97..111] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - H9: 3584 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - B42: 22 # value 22 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id - clot 5 : - start: 3 - length: 9 - shift: 15 - buf_req: 15 - next: parse_pad - 0x**: - shift: 1 - buf_req: 1 - next: end - start.$oob_stall_0: - *: - load: { byte0 : 3, byte1 : 15 } - buf_req: 16 - next: parse_bridged_pkt_710_cpu - parse_bridged_pkt_710_cpu: - match: [ byte1, byte0 ] - 0b******000*******: - 0..3: W34 # bit[25] -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu - 1: B23 - # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 1: B25 - # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast - 2: B22 - # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track - 2: B24 - # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc - # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color - # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track - 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 13..14: H11 - # - bit[104] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[105..119] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - 16: B42 # egress::eg_md.eg_ft.common.cpu_eth_encap_id - H9: 3584 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - clot 5 : - start: 3 - length: 9 - load: { byte0 : 29, byte1 : 30 } - shift: 17 - buf_req: 31 - next: parse_ethernet_310 - 0b******100*******: - 0..3: W34 # bit[25] -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu - 1: B23 - # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 1: B25 - # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast - 2: B22 - # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track - 2: B24 - # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc - # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color - # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track - 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 13..14: H11 - # - bit[104] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[105..119] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - 16: B42 # egress::eg_md.eg_ft.common.cpu_eth_encap_id - H9: 3584 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - clot 5 : - start: 3 - length: 9 - shift: 17 - buf_req: 17 - next: parse_ipv4_310 - 0b******110*******: - 0..3: W34 # bit[25] -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu - 1: B23 - # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 1: B25 - # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast - 2: B22 - # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track - 2: B24 - # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc - # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color - # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track - 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 13..14: H11 - # - bit[104] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[105..119] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - 16: B42 # egress::eg_md.eg_ft.common.cpu_eth_encap_id - H9: 3584 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - clot 5 : - start: 3 - length: 9 - shift: 17 - buf_req: 17 - next: parse_ipv6_310 - 0b********1*******: - 0..3: W34 # bit[25] -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu - 1: B23 - # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 1: B25 - # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast - 2: B22 - # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track - 2: B24 - # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc - # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color - # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track - 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 13..14: H11 - # - bit[104] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[105..119] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - 16: B42 # egress::eg_md.eg_ft.common.cpu_eth_encap_id - H9: 3584 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - clot 5 : - start: 3 - length: 9 - load: { byte0 : 15 } - shift: 17 - buf_req: 17 - next: parse_extension_tunnel_decap - 0x****: - 0..3: W34 # bit[25] -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu - 1: B23 - # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 1: B25 - # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast - 2: B22 - # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track - 2: B24 - # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc - # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color - # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track - 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 13..14: H11 - # - bit[104] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[105..119] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - 16: B42 # egress::eg_md.eg_ft.common.cpu_eth_encap_id - H9: 3584 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - clot 5 : - start: 3 - length: 9 - load: { byte0 : 17 } - shift: 17 - buf_req: 18 - next: parse_depth_pad - parse_extension_tunnel_decap: - match: [ byte0 ] - 0b******00: - 1: B32 # egress::hdr.ext_tunnel_decap.vb - 2..3: MH19 # egress::hdr.ext_tunnel_decap.vh - H9: 4096 # value 1 -> H9 bit[12]: egress::hdr.ext_tunnel_decap.$valid - clot 7 : - start: 0 - length: 1 - load: { byte0 : 16, byte1 : 17 } - shift: 4 - buf_req: 18 - next: parse_ethernet_310 - 0b******10: - 1: B32 # egress::hdr.ext_tunnel_decap.vb - 2..3: MH19 # egress::hdr.ext_tunnel_decap.vh - H9: 4096 # value 1 -> H9 bit[12]: egress::hdr.ext_tunnel_decap.$valid - clot 7 : - start: 0 - length: 1 - shift: 4 - buf_req: 4 - next: parse_ipv4_310 - 0b******11: - 1: B32 # egress::hdr.ext_tunnel_decap.vb - 2..3: MH19 # egress::hdr.ext_tunnel_decap.vh - H9: 4096 # value 1 -> H9 bit[12]: egress::hdr.ext_tunnel_decap.$valid - clot 7 : - start: 0 - length: 1 - shift: 4 - buf_req: 4 - next: parse_ipv6_310 - 0x**: - 1: B32 # egress::hdr.ext_tunnel_decap.vb - 2..3: MH19 # egress::hdr.ext_tunnel_decap.vh - H9: 4096 # value 1 -> H9 bit[12]: egress::hdr.ext_tunnel_decap.$valid - clot 7 : - start: 0 - length: 1 - load: { byte0 : 4 } - shift: 4 - buf_req: 5 - next: parse_depth_pad - parse_depth_pad: - match: [ byte0 ] - 0b1*******: - load: { byte0 : 0 } - buf_req: 1 - next: parse_depth_pad_1 - 0x**: - load: { byte0 : 0 } - buf_req: 1 - next: parse_depth_pad_2 - parse_depth_pad_1: - match: [ byte0 ] - 0b1*******: - load: { byte0 : 0 } - buf_req: 1 - next: parse_depth_pad_2 - 0x**: - load: { byte0 : 0 } - buf_req: 1 - next: end - parse_depth_pad_2: - match: [ byte0 ] - 0b1*******: - load: { byte0 : 0 } - buf_req: 1 - next: end - 0x**: - buf_req: 0 - next: end - parse_bridged_pkt_710_front: - match: [ byte0 ] - 0b001101**: - 1: B23 - # - bit[0..5] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[6] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[7] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 1: B25 - # - bit[0..5] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - bit[6] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - # - bit[7] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast - 2: B22 - # - bit[8..10] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[11..12] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[13] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[14] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[15] -> B22 bit[0]: egress::hdr.fabric_qos.track - 2: B24 - # - bit[8..10] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc - # - bit[11..12] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color - # - bit[15] -> B24 bit[0]: egress::eg_md.eg_ft.common.track - 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 13..14: H11 - # - bit[96] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[97..111] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - 15..16: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 - 17..20: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 - 21..22: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 - 23..24: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 - 25..26: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 - 27..28: MH1 # egress::hdr.eg_ft.ethernet.ether_type - 27..28: MH15 # egress::eg_md.eg_ft.common.ether_type - H9: 3600 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - # - value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid - W34: 64 # value 1 -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu - clot 5 : - start: 3 - length: 9 - shift: 29 - buf_req: 29 - next: parse_bridged_pkt_spec_cpu_eth.$split_0 - 0b001111**: - 1: B23 - # - bit[0..5] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[6] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[7] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 1: B25 - # - bit[0..5] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - bit[6] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - # - bit[7] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast - 2: B22 - # - bit[8..10] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[11..12] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[13] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[14] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[15] -> B22 bit[0]: egress::hdr.fabric_qos.track - 2: B24 - # - bit[8..10] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc - # - bit[11..12] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color - # - bit[15] -> B24 bit[0]: egress::eg_md.eg_ft.common.track - 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 13..14: H11 - # - bit[96] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[97..111] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - H9: 3584 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - W34: 64 # value 1 -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu - clot 5 : - start: 3 - length: 9 - shift: 15 - buf_req: 15 - next: parse_bridged_pkt_c2c.$split_0 - 0b011101**: - 1: B23 - # - bit[0..5] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[6] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[7] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 1: B25 - # - bit[0..5] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - bit[7] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast - 2: B22 - # - bit[8..10] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[11..12] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[13] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[14] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[15] -> B22 bit[0]: egress::hdr.fabric_qos.track - 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 13..14: H11 - # - bit[96] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[97..111] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - B25: 2 # value 1 -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - H9: 3584 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - clot 5 : - start: 3 - length: 9 - shift: 15 - buf_req: 15 - next: parse_bridged_pkt_ipfix_ig.$split_0 - 0b011110**: - 1: B23 - # - bit[0..5] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[6] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[7] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 1: B25 - # - bit[0..5] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - bit[7] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast - 2: B22 - # - bit[8..10] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[11..12] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[13] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[14] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[15] -> B22 bit[0]: egress::hdr.fabric_qos.track - 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 13..14: H11 - # - bit[96] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[97..111] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - B25: 2 # value 1 -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - H9: 3584 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - clot 5 : - start: 3 - length: 9 - shift: 15 - buf_req: 15 - next: parse_bridged_pkt_ipfix_eg.$split_0 - 0b000111**: - 4: B20 # egress::eg_md.eg_ft.common.dst_port - 15: B23 - # - bit[112..117] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[118] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[119] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 16: B22 - # - bit[120..122] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[123..124] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[125] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[126] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[127] -> B22 bit[0]: egress::hdr.fabric_qos.track - 21..22: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 26: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 27..28: H11 - # - bit[208] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[209..223] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - H9: 3584 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - B42: 8 # value 8 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id - clot 5 : - start: 17 - length: 9 - shift: 29 - buf_req: 29 - next: parse_bridged_pkt_trace.$split_0 - 0b010110**: - 15: B23 - # - bit[112..117] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[118] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[119] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 16: B22 - # - bit[120..122] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[123..124] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[125] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[126] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[127] -> B22 bit[0]: egress::hdr.fabric_qos.track - 21..22: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 26: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 27..28: H11 - # - bit[208] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[209..223] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - H9: 3584 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - B42: 21 # value 21 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id - clot 5 : - start: 17 - length: 9 - shift: 29 - buf_req: 29 - next: parse_bridged_pkt_ccm_trace.$split_0 - 0b010101**: - 2: B24 - # - bit[8..10] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc - # - bit[11..12] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color - # - bit[15] -> B24 bit[0]: egress::eg_md.eg_ft.common.track - 4: B20 # egress::eg_md.eg_ft.common.dst_port - B25: 86 - # - value 21 -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - value 1 -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - load: { byte0 : 27, byte1 : 28 } - shift: 15 - buf_req: 29 - next: parse_mirror_ethernet - 0x**: - shift: 1 - buf_req: 1 - next: end - parse_bridged_pkt_spec_cpu_eth.$split_0: - *: - B42: 18 # value 18 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id - load: { byte0 : 0 } - buf_req: 1 - next: parse_depth_pad - parse_bridged_pkt_c2c.$split_0: - *: - B42: 17 # value 17 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id - load: { byte0 : 0 } - buf_req: 1 - next: parse_depth_pad - parse_bridged_pkt_ipfix_ig.$split_0: - *: - B42: 4 # value 4 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id - load: { byte0 : 12, byte1 : 13 } - buf_req: 14 - next: parse_mirror_ethernet - parse_mirror_ethernet: - match: [ byte0, byte1 ] - 0x893f: - 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 - 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 - 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 - 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 - 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type - 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type - H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid - load: { byte0 : 20, byte1 : 21 } - shift: 14 - buf_req: 22 - next: parse_mirror_1br - 0x****: - 0..1: H48 # egress::hdr.eg_ft.ethernet.dst_addr[47:32].32-47 - 2..5: W9 # egress::hdr.eg_ft.ethernet.dst_addr[31:0].0-31 - 6..7: H60 # egress::hdr.eg_ft.ethernet.src_addr[47:32].32-47 - 8..9: H33 # egress::hdr.eg_ft.ethernet.src_addr[31:16].16-31 - 10..11: H32 # egress::hdr.eg_ft.ethernet.src_addr[15:0].0-15 - 12..13: MH1 # egress::hdr.eg_ft.ethernet.ether_type - 12..13: MH15 # egress::eg_md.eg_ft.common.ether_type - H9: 16 # value 1 -> H9 bit[4]: egress::hdr.eg_ft.ethernet.$valid - load: { byte0 : 14 } - shift: 14 - buf_req: 15 - next: parse_depth_pad - parse_mirror_1br: - match: [ byte0, byte1 ] - 0x8100: - 0..1: H47 - # - bit[0..2] -> H47 bit[15..13]: egress::hdr.eg_ft.br_tag.epcp - # - bit[3] -> H47 bit[12]: egress::hdr.eg_ft.br_tag.edei - # - bit[4..15] -> H47 bit[11..0]: egress::hdr.eg_ft.br_tag.ingress_ecid - 2..5: W8 - # - bit[16..17] -> W8 bit[31..30]: egress::hdr.eg_ft.br_tag.reserved - # - bit[18..19] -> W8 bit[29..28]: egress::hdr.eg_ft.br_tag.grp - # - bit[20..31] -> W8 bit[27..16]: egress::hdr.eg_ft.br_tag.ecid - # - bit[32..39] -> W8 bit[15..8]: egress::hdr.eg_ft.br_tag.ingress_ecid_ext - # - bit[40..47] -> W8 bit[7..0]: egress::hdr.eg_ft.br_tag.ecid_ext - 6..7: MH2 # egress::hdr.eg_ft.br_tag.ether_type - 6..7: MH15 # egress::eg_md.eg_ft.common.ether_type - B17: 1 # value 1 -> B17 bit[0]: egress::hdr.eg_ft.br_tag.$valid - shift: 8 - buf_req: 8 - next: parse_mirror_1br_vlan - 0x****: - 0..1: H47 - # - bit[0..2] -> H47 bit[15..13]: egress::hdr.eg_ft.br_tag.epcp - # - bit[3] -> H47 bit[12]: egress::hdr.eg_ft.br_tag.edei - # - bit[4..15] -> H47 bit[11..0]: egress::hdr.eg_ft.br_tag.ingress_ecid - 2..5: W8 - # - bit[16..17] -> W8 bit[31..30]: egress::hdr.eg_ft.br_tag.reserved - # - bit[18..19] -> W8 bit[29..28]: egress::hdr.eg_ft.br_tag.grp - # - bit[20..31] -> W8 bit[27..16]: egress::hdr.eg_ft.br_tag.ecid - # - bit[32..39] -> W8 bit[15..8]: egress::hdr.eg_ft.br_tag.ingress_ecid_ext - # - bit[40..47] -> W8 bit[7..0]: egress::hdr.eg_ft.br_tag.ecid_ext - 6..7: MH2 # egress::hdr.eg_ft.br_tag.ether_type - 6..7: MH15 # egress::eg_md.eg_ft.common.ether_type - B17: 1 # value 1 -> B17 bit[0]: egress::hdr.eg_ft.br_tag.$valid - shift: 8 - buf_req: 8 - next: end - parse_mirror_1br_vlan: - *: - 0..1: H45 - # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp - # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi - # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid - 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type - 2..3: MH15 # egress::eg_md.eg_ft.common.ether_type - B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_bridged_pkt_ipfix_eg.$split_0: - *: - B42: 5 # value 5 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id - load: { byte0 : 12, byte1 : 13 } - buf_req: 14 - next: parse_mirror_ethernet - parse_bridged_pkt_trace.$split_0: - *: - B25: 2 # value 1 -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - load: { byte0 : 0 } - buf_req: 1 - next: parse_depth_pad - parse_bridged_pkt_ccm_trace.$split_0: - *: - B25: 2 # value 1 -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - load: { byte0 : 0 } - buf_req: 1 - next: parse_depth_pad - parse_bridged_pkt_910_ccm: - *: - 1: B23 - # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 1: B25 - # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast - 2: B22 - # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track - 2: B24 # bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track - 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 13..14: H11 - # - bit[104] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[105..119] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - H9: 3584 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - W34: 64 # value 1 -> W34 bit[6]: egress::eg_md.eg_ft.common.from_cpu - clot 5 : - start: 3 - length: 9 - shift: 15 - buf_req: 15 - next: parse_bridged_pkt_910_ccm.$split_0 - parse_bridged_pkt_910_ccm.$split_0: - *: - B42: 11 # value 11 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id - load: { byte0 : 0 } - buf_req: 1 - next: parse_depth_pad - parse_bridged_pkt_signal: - *: - 1: B23 - # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 1: B25 - # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast - 2: B22 - # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track - 2: B24 - # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc - # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color - # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track - 7..8: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 12: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 13..14: H11 - # - bit[104] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[105..119] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - H9: 3584 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - B42: 19 # value 19 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id - clot 5 : - start: 3 - length: 9 - load: { byte0 : 23 } - shift: 23 - buf_req: 24 - next: parse_depth_pad - parse_bridged_pkt_110_recirc: - *: - 1: B23 - # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 1: B25 - # - bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - bit[14] -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - # - bit[15] -> B25 bit[0]: egress::eg_md.eg_ft.common.is_mcast - 2: B22 - # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track - 2: B24 - # - bit[16..18] -> B24 bit[7..5]: egress::eg_md.eg_ft.qos.tc - # - bit[19..20] -> B24 bit[4..3]: egress::eg_md.eg_ft.qos.color - # - bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track - 3..4: MH8 # egress::eg_md.eg_ft.common.decap_len - 9..10: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 14: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 15..16: H11 - # - bit[120] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[121..135] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - H9: 3584 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - B42: 24 # value 24 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id - clot 5 : - start: 5 - length: 9 - shift: 17 - buf_req: 17 - next: parse_pad - start.$oob_stall_1: - *: - load: { byte0 : 5 } - buf_req: 6 - next: parse_bridged_pkt_110_recirc_evpn - parse_bridged_pkt_110_recirc_evpn: - match: [ byte0 ] - 0b1*******: - 1: B23 - # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 1: B25 # bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - 2: B22 - # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track - 2: B24 # bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track - 3..4: MH8 # egress::eg_md.eg_ft.common.decap_len - 9..10: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 14: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 15..16: H11 - # - bit[120] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[121..135] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - 15..16: H49 # bit[121..135] -> H49 bit[14..0]: egress::eg_md.eg_ft.common.iif - H9: 3584 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - B42: 25 # value 25 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id - clot 5 : - start: 5 - length: 9 - load: { byte0 : 18 } - shift: 17 - buf_req: 19 - next: parse_bridged_pkt_110_evpn_ext - 0x**: - 1: B23 - # - bit[8..13] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[14] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[15] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 1: B25 # bit[8..13] -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - 2: B22 - # - bit[16..18] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[19..20] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[21] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[22] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[23] -> B22 bit[0]: egress::hdr.fabric_qos.track - 2: B24 # bit[23] -> B24 bit[0]: egress::eg_md.eg_ft.common.track - 3..4: MH8 # egress::eg_md.eg_ft.common.decap_len - 9..10: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 14: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 15..16: H11 - # - bit[120] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[121..135] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - 15..16: H49 # bit[121..135] -> H49 bit[14..0]: egress::eg_md.eg_ft.common.iif - H9: 3584 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - B42: 25 # value 25 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id - clot 5 : - start: 5 - length: 9 - load: { byte0 : 29, byte1 : 30 } - shift: 17 - buf_req: 31 - next: parse_ethernet_evpn110 - parse_bridged_pkt_110_evpn_ext: - match: [ byte0 ] - 0b****0***: - 1: B32 # egress::hdr.ext_tunnel_decap.vb - 2..3: MH19 # egress::hdr.ext_tunnel_decap.vh - H9: 4096 # value 1 -> H9 bit[12]: egress::hdr.ext_tunnel_decap.$valid - clot 7 : - start: 0 - length: 1 - load: { byte0 : 16, byte1 : 17 } - shift: 4 - buf_req: 18 - next: parse_ethernet_evpn110 - 0b****1***: - 1: B32 # egress::hdr.ext_tunnel_decap.vb - 2..3: MH19 # egress::hdr.ext_tunnel_decap.vh - H9: 4096 # value 1 -> H9 bit[12]: egress::hdr.ext_tunnel_decap.$valid - clot 7 : - start: 0 - length: 1 - shift: 4 - buf_req: 4 - next: parse_pw_cw - parse_ethernet_evpn110: - match: [ byte0, byte1 ] - 0x8100: - 12..13: MH23 # egress::hdr.eg_ft.ethernet_evpn.ether_type - H9: 8192 # value 1 -> H9 bit[13]: egress::hdr.eg_ft.ethernet_evpn.$valid - clot 3 : - start: 0 - length: 12 - load: { byte0 : 16, byte1 : 17 } - shift: 14 - buf_req: 18 - next: parse_vlan_evpn110 - 0x****: - 12..13: MH23 # egress::hdr.eg_ft.ethernet_evpn.ether_type - H9: 8192 # value 1 -> H9 bit[13]: egress::hdr.eg_ft.ethernet_evpn.$valid - clot 3 : - start: 0 - length: 12 - shift: 14 - buf_req: 14 - next: end - parse_vlan_evpn110: - match: [ byte0, byte1 ] - 0x8100: - 0..1: H45 - # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp - # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi - # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid - 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type - B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: parse_vlan1_evpn110 - 0x****: - 0..1: H45 - # - bit[0..2] -> H45 bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp - # - bit[3] -> H45 bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi - # - bit[4..15] -> H45 bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid - 2..3: MH22 # egress::hdr.eg_ft.vlan_tag[0].ether_type - B7: 4 # value 4 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_vlan1_evpn110: - *: - 0..1: H44 - # - bit[0..2] -> H44 bit[15..13]: egress::hdr.eg_ft.vlan_tag[1].pcp - # - bit[3] -> H44 bit[12]: egress::hdr.eg_ft.vlan_tag[1].cfi - # - bit[4..15] -> H44 bit[11..0]: egress::hdr.eg_ft.vlan_tag[1].vid - 2..3: MH21 # egress::hdr.eg_ft.vlan_tag[1].ether_type - B7: 2 # value 2 -> B7 bit[3..0]: egress::hdr.eg_ft.vlan_tag.$stkvalid - shift: 4 - buf_req: 4 - next: end - parse_pw_cw: - *: - load: { byte0 : 16, byte1 : 17 } - shift: 4 - buf_req: 18 - next: parse_ethernet_evpn110 - parse_xon_xoff_mirrored_metadata: - *: - 0: B42 # egress::eg_md.eg_ft.common.cpu_eth_encap_id - 3: B21 # egress::eg_md.eg_ft.common.backpush_dst_port - B25: 2 # value 1 -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - load: { byte0 : 16, byte1 : 17 } - shift: 4 - buf_req: 18 - next: parse_mirror_ethernet - parse_common_mirrored_metadata: - *: - 0: B42 # egress::eg_md.eg_ft.common.cpu_eth_encap_id - 3: B20 # egress::eg_md.eg_ft.common.dst_port - 4: B23 - # - bit[32..37] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[38] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[39] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 5: B22 - # - bit[40..42] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[43..44] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[45] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[46] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[47] -> B22 bit[0]: egress::hdr.fabric_qos.track - 10..11: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 15: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 16..17: H11 - # - bit[128] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[129..143] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - H9: 3584 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - B25: 2 # value 1 -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - clot 5 : - start: 6 - length: 9 - load: { byte0 : 18 } - shift: 18 - buf_req: 19 - next: parse_depth_pad - parse_ig_uplink_ifit_mirrored_metadata: - *: - 2: B23 - # - bit[16..21] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[22] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[23] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 3: B22 - # - bit[24..26] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[27..28] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[29] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[30] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[31] -> B22 bit[0]: egress::hdr.fabric_qos.track - 8..9: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 13: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 14..15: H11 - # - bit[112] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[113..127] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - H9: 3584 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - B42: 26 # value 26 -> B42 bit[7..0]: egress::eg_md.eg_ft.common.cpu_eth_encap_id - clot 5 : - start: 4 - length: 9 - shift: 16 - buf_req: 16 - next: parse_ig_uplink_ifit_mirrored_metadata.$split_0 - parse_ig_uplink_ifit_mirrored_metadata.$split_0: - *: - B25: 2 # value 1 -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - load: { byte0 : 0 } - buf_req: 1 - next: parse_depth_pad - parse_ghost: - *: - 0: B23 - # - bit[0..5] -> B23 bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[6] -> B23 bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[7] -> B23 bit[0]: egress::hdr.fabric_base.is_mcast - 1: B22 - # - bit[8..10] -> B22 bit[7..5]: egress::hdr.fabric_qos.tc - # - bit[11..12] -> B22 bit[4..3]: egress::hdr.fabric_qos.color - # - bit[13] -> B22 bit[2]: egress::hdr.fabric_qos.chgDSCP_disable - # - bit[14] -> B22 bit[1]: egress::hdr.fabric_qos.BA - # - bit[15] -> B22 bit[0]: egress::hdr.fabric_qos.track - 6..7: MH20 # egress::hdr.fabric_data_template_plus.vh1 - 11: B33 # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 - 12..13: H11 - # - bit[96] -> H11 bit[15]: egress::hdr.fabric_data_template_plus.one - # - bit[97..111] -> H11 bit[14..0]: egress::hdr.fabric_data_template_plus.iif - H9: 3584 - # - value 1 -> H9 bit[9]: egress::hdr.fabric_base.$valid - # - value 1 -> H9 bit[10]: egress::hdr.fabric_qos.$valid - # - value 1 -> H9 bit[11]: egress::hdr.fabric_data_template_plus.$valid - B25: 110 - # - value 27 -> B25 bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - value 1 -> B25 bit[1]: egress::eg_md.eg_ft.common.is_mirror - clot 5 : - start: 2 - length: 9 - load: { byte0 : 14 } - shift: 14 - buf_req: 15 - next: parse_depth_pad -deparser egress: - dictionary: - H48: H9(4) # egress::hdr.eg_ft.ethernet.dst_addr.32-47 if egress::hdr.eg_ft.ethernet.$valid - W9: H9(4) # egress::hdr.eg_ft.ethernet.dst_addr.0-31 if egress::hdr.eg_ft.ethernet.$valid - H60: H9(4) # egress::hdr.eg_ft.ethernet.src_addr.32-47 if egress::hdr.eg_ft.ethernet.$valid - H33: H9(4) # egress::hdr.eg_ft.ethernet.src_addr.16-31 if egress::hdr.eg_ft.ethernet.$valid - H32: H9(4) # egress::hdr.eg_ft.ethernet.src_addr.0-15 if egress::hdr.eg_ft.ethernet.$valid - MH1: H9(4) # egress::hdr.eg_ft.ethernet.ether_type if egress::hdr.eg_ft.ethernet.$valid - H47: B17(0) - # - bit[15..13]: egress::hdr.eg_ft.br_tag.epcp if egress::hdr.eg_ft.br_tag.$valid - # - bit[12]: egress::hdr.eg_ft.br_tag.edei if egress::hdr.eg_ft.br_tag.$valid - # - bit[11..0]: egress::hdr.eg_ft.br_tag.ingress_ecid if egress::hdr.eg_ft.br_tag.$valid - W8: B17(0) - # - bit[31..30]: egress::hdr.eg_ft.br_tag.reserved if egress::hdr.eg_ft.br_tag.$valid - # - bit[29..28]: egress::hdr.eg_ft.br_tag.grp if egress::hdr.eg_ft.br_tag.$valid - # - bit[27..16]: egress::hdr.eg_ft.br_tag.ecid if egress::hdr.eg_ft.br_tag.$valid - # - bit[15..8]: egress::hdr.eg_ft.br_tag.ingress_ecid_ext if egress::hdr.eg_ft.br_tag.$valid - # - bit[7..0]: egress::hdr.eg_ft.br_tag.ecid_ext if egress::hdr.eg_ft.br_tag.$valid - MH2: B17(0) # egress::hdr.eg_ft.br_tag.ether_type if egress::hdr.eg_ft.br_tag.$valid - B23: H9(9) - # - bit[7..2]: egress::hdr.fabric_base.pkt_type if egress::hdr.fabric_base.$valid - # - bit[1]: egress::hdr.fabric_base.is_mirror if egress::hdr.fabric_base.$valid - # - bit[0]: egress::hdr.fabric_base.is_mcast if egress::hdr.fabric_base.$valid - B22: H9(10) - # - bit[7..5]: egress::hdr.fabric_qos.tc if egress::hdr.fabric_qos.$valid - # - bit[4..3]: egress::hdr.fabric_qos.color if egress::hdr.fabric_qos.$valid - # - bit[2]: egress::hdr.fabric_qos.chgDSCP_disable if egress::hdr.fabric_qos.$valid - # - bit[1]: egress::hdr.fabric_qos.BA if egress::hdr.fabric_qos.$valid - # - bit[0]: egress::hdr.fabric_qos.track if egress::hdr.fabric_qos.$valid - clot 5: - pov: hdr.fabric_data_template_plus.$valid - 4 : MH20 - B33: H9(11) # egress::hdr.fabric_data_template_plus.vh3[7:0].0-7 if egress::hdr.fabric_data_template_plus.$valid - H11: H9(11) - # - bit[15]: egress::hdr.fabric_data_template_plus.one if egress::hdr.fabric_data_template_plus.$valid - # - bit[14..0]: egress::hdr.fabric_data_template_plus.iif if egress::hdr.fabric_data_template_plus.$valid - MH3: H9(14) # egress::hdr.fabric_eth_etype.ether_type if egress::hdr.fabric_eth_etype.$valid - H46: H9(15) # egress::hdr.fabric_timestamp.timestamp.32-47 if egress::hdr.fabric_timestamp.$valid - MW13: H9(15) # egress::hdr.fabric_timestamp.timestamp.0-31 if egress::hdr.fabric_timestamp.$valid - clot 7: - pov: hdr.ext_tunnel_decap.$valid - B32: H9(12) # egress::hdr.ext_tunnel_decap.vb if egress::hdr.ext_tunnel_decap.$valid - MH19: H9(12) # egress::hdr.ext_tunnel_decap.vh if egress::hdr.ext_tunnel_decap.$valid - clot 3: - pov: hdr.eg_ft.ethernet_evpn.$valid - MH23: H9(13) # egress::hdr.eg_ft.ethernet_evpn.ether_type if egress::hdr.eg_ft.ethernet_evpn.$valid - H45: B7(2) - # - bit[15..13]: egress::hdr.eg_ft.vlan_tag[0].pcp if egress::hdr.eg_ft.vlan_tag[0].$valid - # - bit[12]: egress::hdr.eg_ft.vlan_tag[0].cfi if egress::hdr.eg_ft.vlan_tag[0].$valid - # - bit[11..0]: egress::hdr.eg_ft.vlan_tag[0].vid if egress::hdr.eg_ft.vlan_tag[0].$valid - MH22: B7(2) # egress::hdr.eg_ft.vlan_tag[0].ether_type if egress::hdr.eg_ft.vlan_tag[0].$valid - H44: B7(1) - # - bit[15..13]: egress::hdr.eg_ft.vlan_tag[1].pcp if egress::hdr.eg_ft.vlan_tag[1].$valid - # - bit[12]: egress::hdr.eg_ft.vlan_tag[1].cfi if egress::hdr.eg_ft.vlan_tag[1].$valid - # - bit[11..0]: egress::hdr.eg_ft.vlan_tag[1].vid if egress::hdr.eg_ft.vlan_tag[1].$valid - MH21: B7(1) # egress::hdr.eg_ft.vlan_tag[1].ether_type if egress::hdr.eg_ft.vlan_tag[1].$valid - clot 2: - pov: hdr.eg_ft.ipv4.$valid - 0 : H34 - 10 : full_checksum 4 - H34: H9(6) - # - bit[15..12]: egress::hdr.eg_ft.ipv6.version if egress::hdr.eg_ft.ipv6.$valid - # - bit[11..4]: egress::hdr.eg_ft.ipv6.traffic_class if egress::hdr.eg_ft.ipv6.$valid - # - bit[3..0]: egress::hdr.eg_ft.ipv6.flow_label.16-19 if egress::hdr.eg_ft.ipv6.$valid - H35: H9(6) # egress::hdr.eg_ft.ipv6.flow_label.0-15 if egress::hdr.eg_ft.ipv6.$valid - clot 1: - pov: hdr.eg_ft.ipv6.$valid - clot 4: - pov: hdr.eg_ft.ipv6_frag.$valid - clot 6: - pov: hdr.eg_ft.mpls_vc_eg.$valid - clot 0: - pov: hdr.pad.$valid - partial_checksum 4: - - H34(0..7): { pov: H9(5) } # bit[7..0]: egress::hdr.eg_ft.ipv4.diffserv if egress::hdr.eg_ft.ipv4.$valid - - MH7: { pov: H9(5) } # egress::eg_md.eg_ft.lkp.tmp_ipv4_checksum if egress::hdr.eg_ft.ipv4.$valid - full_checksum 4: - - partial_checksum 4: { pov: H9(5) } - - clot 2: { pov: H9(5) } - drop_ctl: { B16(1..3): B16(0) } # bit[3..1]: egress::eg_intr_md_for_dprsr.drop_ctl if egress::eg_intr_md_for_dprsr.drop_ctl.$valid - mirr_io_sel: { MH18(0..0): H9(0) } # bit[0]: egress::eg_intr_md_for_dprsr.mirror_io_select if egress::eg_intr_md_for_dprsr.mirror_io_select.$valid - mtu_trunc_len: { MH17(0..13): B7(4) } # bit[13..0]: egress::eg_intr_md_for_dprsr.mtu_trunc_len if egress::eg_intr_md_for_dprsr.mtu_trunc_len.$valid - egress_unicast_port: { MH16(0..8): H9(1) } # bit[8..0]: egress::eg_intr_md.egress_port if egress::eg_intr_md.egress_port.$valid - mirror: - select: { B4(0..3): H9(2) } # bit[3..0]: egress::eg_intr_md_for_dprsr.mirror_type - 1: - - MB9 # egress::eg_md.eg_ft.mirror.session_id - - B19 - # - bit[7..5]: egress::eg_md.eg_ft.mirror.src - # - bit[4..0]: egress::eg_md.eg_ft.mirror.type - - MB9 # egress::eg_md.eg_ft.mirror.session_id - - B23 - # - bit[7..2]: egress::hdr.fabric_base.pkt_type - # - bit[1]: egress::hdr.fabric_base.is_mirror - # - bit[0]: egress::hdr.fabric_base.is_mcast - - B21 # egress::eg_md.eg_ft.common.backpush_dst_port - - B27 # egress::eg_md.eg_ft.mirror.flags - - B20 # egress::eg_md.eg_ft.common.dst_port - - H61 # egress::eg_md.eg_ft.common.hash - - H51 # egress::eg_md.eg_ft.common.mirror_dst_eport - - H50(0..14) # bit[14..0]: egress::eg_md.eg_ft.common.oif - - H63 # egress::eg_md.eg_ft.ifit.var_h1 - - H49(0..14) # bit[14..0]: egress::eg_md.eg_ft.common.iif - 7: - - MB9 # egress::eg_md.eg_ft.mirror.session_id - - B19 - # - bit[7..5]: egress::eg_md.eg_ft.mirror.src - # - bit[4..0]: egress::eg_md.eg_ft.mirror.type - - MB9 # egress::eg_md.eg_ft.mirror.session_id - - H51 # egress::eg_md.eg_ft.common.mirror_dst_eport - - B25 - # - bit[7..2]: egress::eg_md.eg_ft.common.pkt_type - # - bit[1]: egress::eg_md.eg_ft.common.is_mirror - # - bit[0]: egress::eg_md.eg_ft.common.is_mcast - - B24 - # - bit[7..5]: egress::eg_md.eg_ft.qos.tc - # - bit[4..3]: egress::eg_md.eg_ft.qos.color - # - bit[0]: egress::eg_md.eg_ft.common.track - - B26 # egress::eg_md.eg_ft.common.pipeline_location - - B26 # egress::eg_md.eg_ft.common.pipeline_location - - H62 # egress::eg_md.eg_ft.common.trace_counter - - MB11 # egress::eg_md.eg_ft.common.drop_reason - - MB11 # egress::eg_md.eg_ft.common.drop_reason - - MW4 # egress::eg_md.eg_ft.common.deq_timedelta - - H49(0..14) # bit[14..0]: egress::eg_md.eg_ft.common.iif - - H46 # egress::hdr.fabric_timestamp.timestamp.32-47 - - MW13 # egress::hdr.fabric_timestamp.timestamp.0-31 -stage 0 ingress: - mpr_stage_id: 0 - mpr_bus_dep_glob_exec: 0x0 - mpr_bus_dep_long_brch: 0x0 - mpr_always_run: 0x201f - phase0_match IgParser_front.$PORT_METADATA: - p4: - name: IgParser_front.$PORT_METADATA - size: 288 - preferred_match_type: exact - match_type: exact - size: 288 - p4_param_order: - ig_intr_md.ingress_port: { type: exact, size: 9 } - format: {port_type: 120..123, is_zero: 112..112} - constant_value: 0 - actions: - set_port_metadata: - - handle: 0x20000000 - - p4_param_order: { port_type: 4, is_zero: 1 } - ternary_match tbl_set_egress_port 0: - always_run: true - p4: { name: tbl_set_egress_port, hidden: true } - hit: [ END ] - miss: END - indirect: tbl_set_egress_port$tind - ternary_indirect tbl_set_egress_port$tind: - row: 0 - bus: 0 - format: { action: 0..0 } - instruction: tbl_set_egress_port$tind(action, $DEFAULT) - actions: - set_egress_port(0, 11): - - hit_allowed: { allowed: true } - - default_action: { allowed: true, is_constant: true } - - handle: 0x20000001 - - next_table: 0 - - set ig_intr_md_for_tm.ucast_egress_port.$valid, 1 - - set MW9, 4 - default_action: set_egress_port - - -primitives: "switch_tofino_x1.prim.json" -dynhash: "switch_tofino_x1.dynhash.json" diff --git a/backends/tofino/bf-asm/test/stf/p4c-5198.stf b/backends/tofino/bf-asm/test/stf/p4c-5198.stf deleted file mode 100644 index 6aa0911799a..00000000000 --- a/backends/tofino/bf-asm/test/stf/p4c-5198.stf +++ /dev/null @@ -1,11 +0,0 @@ -packet 20 \ - 00 14 00 4b 2e a3 48 40 01 00 00 00 00 00 00 00 \ - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ - 00 11 11 11 11 11 00 22 22 22 22 22 81 00 03 ea \ - 81 00 00 14 08 00 45 00 00 4e 00 01 00 00 40 06 - -expect 4 \ - 00 00 11 11 11 11 11 00 22 22 22 22 22 81 00 03 \ - ea 81 00 00 14 08 00 45 00 00 4e 00 01 00 00 40 \ - 06 - diff --git a/backends/tofino/bf-asm/test/stf/simple_counter.p4 b/backends/tofino/bf-asm/test/stf/simple_counter.p4 deleted file mode 100644 index 1421c8b4736..00000000000 --- a/backends/tofino/bf-asm/test/stf/simple_counter.p4 +++ /dev/null @@ -1,73 +0,0 @@ - -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - c1 : 8; - c2 : 8; - c3 : 8; - c4 : 8; - } -} - -header data_t data; - -parser start { - extract(data); - return ingress; -} -action c1_2(val1, val2) { - modify_field(data.c1, val1); - modify_field(data.c2, val2); -} - -action c3_4(val3, val4, port) { - modify_field(data.c3, val3); - modify_field(data.c4, val4); - modify_field(standard_metadata.egress_spec, port); -} - -table test1 { - reads { - data.f1 : exact; - } - actions { - c1_2; - } -} - -table test2 { - reads { - data.f2 : exact; - } - actions { - c3_4; - } - size: 1024; -} - -counter cnt { - type: packets; - direct: test1; -} - -control ingress { - apply(test1); - apply(test2); -} diff --git a/backends/tofino/bf-asm/test/stf/simple_counter.stf b/backends/tofino/bf-asm/test/stf/simple_counter.stf deleted file mode 100644 index ac66866e825..00000000000 --- a/backends/tofino/bf-asm/test/stf/simple_counter.stf +++ /dev/null @@ -1,15 +0,0 @@ - -add test1 data.f1:0x01010101 c1_2(val1:0x01, val2:0x02) -add test1 data.f1:0x02020202 c1_2(val1:0x10, val2:0x20) - -add test2 data.f2:0x03030303 c3_4(val3:0x03, val4:0x04, port:1) -add test2 data.f2:0x04040404 c3_4(val3:0x30, val4:0x40, port:2) - -expect 1 01010101 03030303 01 02 03 04 -packet 0 01010101 03030303 55 66 77 88 -expect 2 01010101 04040404 01 02 30 40 -packet 0 01010101 04040404 55 66 77 88 -expect 1 02020202 03030303 10 20 03 04 -packet 0 02020202 03030303 99 88 77 66 -expect 2 02020202 04040404 10 20 30 40 -packet 0 02020202 04040404 14 25 36 47 diff --git a/backends/tofino/bf-asm/test/ternary_match0.p4 b/backends/tofino/bf-asm/test/ternary_match0.p4 deleted file mode 100644 index df0c0f900c0..00000000000 --- a/backends/tofino/bf-asm/test/ternary_match0.p4 +++ /dev/null @@ -1,34 +0,0 @@ - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } - -table test1 { - reads { - data.f1 : ternary; - } - actions { - noop; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/ternary_match1.p4 b/backends/tofino/bf-asm/test/ternary_match1.p4 deleted file mode 100644 index 05684341c80..00000000000 --- a/backends/tofino/bf-asm/test/ternary_match1.p4 +++ /dev/null @@ -1,40 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setb1(val, port) { - modify_field(data.b1, val); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -table test1 { - reads { - data.f1 : ternary; - } - actions { - setb1; - noop; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/ternary_match1.stf b/backends/tofino/bf-asm/test/ternary_match1.stf deleted file mode 100644 index 50bdd050eed..00000000000 --- a/backends/tofino/bf-asm/test/ternary_match1.stf +++ /dev/null @@ -1,18 +0,0 @@ - -tcam_2bit_mode TRUE - -add test1 0 data.f1:0x****0101 setb1(val:0x7f, port:2) - -#write_raw_tcam 0:23:0 00000101 & 0000ffff -# for some reason, address 0 in the tcam is match address 7 for tind lookup? -#write_raw_sram 0:2:3 00fe0004 & 1ffffffff << 64 - -add test1 503 data.f1:0x****0202 setb1(val:7, port:3) - -#write_raw_tcam 0:23:503 00000202 & 0000ffff -#write_raw_sram 0:2:255 000e0006 & 1ffffffff << 0 - -expect 2 00000101 ******** ******** ******** 7f 66 -packet 0 00000101 00000202 00000303 00000404 55 66 77 88 -expect 3 00000202 ******** ******** ******** 07 66 -packet 1 00000202 00000303 00000404 00000404 55 66 77 88 diff --git a/backends/tofino/bf-asm/test/ternary_match2.p4 b/backends/tofino/bf-asm/test/ternary_match2.p4 deleted file mode 100644 index 7bc043c3857..00000000000 --- a/backends/tofino/bf-asm/test/ternary_match2.p4 +++ /dev/null @@ -1,41 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setb1(val, port) { - modify_field(data.b1, val); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -table test1 { - reads { - data.f1 : ternary; - } - actions { - setb1; - noop; - } - size: 10000; -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/ternary_match2.stf b/backends/tofino/bf-asm/test/ternary_match2.stf deleted file mode 100644 index c1152cf9a2e..00000000000 --- a/backends/tofino/bf-asm/test/ternary_match2.stf +++ /dev/null @@ -1,84 +0,0 @@ - -tcam_2bit_mode TRUE - -add test1 0 data.f1:0b*******************************1 setb1(port:4, val:0) -add test1 600 data.f1:0b******************************1* setb1(port:4, val:1) -add test1 1200 data.f1:0b*****************************1** setb1(port:4, val:2) -add test1 1800 data.f1:0b****************************1*** setb1(port:4, val:3) -add test1 2400 data.f1:0b***************************1**** setb1(port:4, val:4) -add test1 3000 data.f1:0b**************************1***** setb1(port:4, val:5) -add test1 3500 data.f1:0b*************************1****** setb1(port:4, val:6) -add test1 4000 data.f1:0b************************1******* setb1(port:4, val:7) -add test1 4500 data.f1:0b***********************1******** setb1(port:4, val:8) -add test1 5000 data.f1:0b**********************1********* setb1(port:4, val:9) -add test1 5500 data.f1:0b*********************1********** setb1(port:4, val:10) -add test1 6000 data.f1:0b********************1*********** setb1(port:4, val:11) -add test1 6500 data.f1:0b*******************1************ setb1(port:4, val:12) -add test1 7000 data.f1:0b******************1************* setb1(port:4, val:13) -add test1 7500 data.f1:0b*****************1************** setb1(port:4, val:14) -add test1 8000 data.f1:0b****************1*************** setb1(port:4, val:15) -add test1 8500 data.f1:0b***************1**************** setb1(port:4, val:16) -add test1 9000 data.f1:0b**************1***************** setb1(port:4, val:17) -add test1 9500 data.f1:0b*************1****************** setb1(port:4, val:18) -add test1 9999 data.f1:0b************1******************* setb1(port:4, val:19) - -expect 4 00000001 ******** ******** ******** 00 66 -packet 0 00000001 02020202 03030303 04040404 55 66 77 88 -wait -expect 4 00000003 ******** ******** ******** 01 66 -packet 0 00000003 02020202 03030303 04040404 55 66 77 88 -wait -expect 4 00000007 ******** ******** ******** 02 66 -packet 0 00000007 02020202 03030303 04040404 55 66 77 88 -wait -expect 4 0000000f ******** ******** ******** 03 66 -packet 0 0000000f 02020202 03030303 04040404 55 66 77 88 -wait -expect 4 0000001f ******** ******** ******** 04 66 -packet 0 0000001f 02020202 03030303 04040404 55 66 77 88 -wait -expect 4 0000003f ******** ******** ******** 05 66 -packet 0 0000003f 02020202 03030303 04040404 55 66 77 88 -wait -expect 4 0000007f ******** ******** ******** 06 66 -packet 0 0000007f 02020202 03030303 04040404 55 66 77 88 -wait -expect 4 000000ff ******** ******** ******** 07 66 -packet 0 000000ff 02020202 03030303 04040404 55 66 77 88 -wait -expect 4 000001ff ******** ******** ******** 08 66 -packet 0 000001ff 02020202 03030303 04040404 55 66 77 88 -wait -expect 4 000003ff ******** ******** ******** 09 66 -packet 0 000003ff 02020202 03030303 04040404 55 66 77 88 -wait -expect 4 000007ff ******** ******** ******** 0a 66 -packet 0 000007ff 02020202 03030303 04040404 55 66 77 88 -wait -expect 4 00000fff ******** ******** ******** 0b 66 -packet 0 00000fff 02020202 03030303 04040404 55 66 77 88 -wait -expect 4 00001fff ******** ******** ******** 0c 66 -packet 0 00001fff 02020202 03030303 04040404 55 66 77 88 -wait -expect 4 00003fff ******** ******** ******** 0d 66 -packet 0 00003fff 02020202 03030303 04040404 55 66 77 88 -wait -expect 4 00007fff ******** ******** ******** 0e 66 -packet 0 00007fff 02020202 03030303 04040404 55 66 77 88 -wait -expect 4 0000ffff ******** ******** ******** 0f 66 -packet 0 0000ffff 02020202 03030303 04040404 55 66 77 88 -wait -expect 4 0001ffff ******** ******** ******** 10 66 -packet 0 0001ffff 02020202 03030303 04040404 55 66 77 88 -wait -expect 4 0003ffff ******** ******** ******** 11 66 -packet 0 0003ffff 02020202 03030303 04040404 55 66 77 88 -wait -expect 4 0007ffff ******** ******** ******** 12 66 -packet 0 0007ffff 02020202 03030303 04040404 55 66 77 88 -wait -expect 4 000fffff ******** ******** ******** 13 66 -packet 0 000fffff 02020202 03030303 04040404 55 66 77 88 -wait diff --git a/backends/tofino/bf-asm/test/ternary_match3.p4 b/backends/tofino/bf-asm/test/ternary_match3.p4 deleted file mode 100644 index 15dbef5f6b7..00000000000 --- a/backends/tofino/bf-asm/test/ternary_match3.p4 +++ /dev/null @@ -1,43 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setb1(val, port) { - modify_field(data.b1, val); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -table test1 { - reads { - data.f1 : ternary; - data.f2 : ternary; - data.f3 : ternary; - data.f4 : ternary; - } - actions { - setb1; - noop; - } -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/ternary_match3.stf b/backends/tofino/bf-asm/test/ternary_match3.stf deleted file mode 100644 index a3f3a4c5ca9..00000000000 --- a/backends/tofino/bf-asm/test/ternary_match3.stf +++ /dev/null @@ -1,7 +0,0 @@ - -tcam_2bit_mode TRUE - -add test1 0 data.f1:0x10111213 data.f2:0x20212223 data.f3:0x30313233 data.f4:0x40414243 setb1(val:0x7f, port:2) - -expect 2 10111213 ******** ******** ******** 7f 66 -packet 0 10111213 20212223 30313233 40414243 55 66 77 88 diff --git a/backends/tofino/bf-asm/test/ternary_match4.p4 b/backends/tofino/bf-asm/test/ternary_match4.p4 deleted file mode 100644 index 592e69ee0d1..00000000000 --- a/backends/tofino/bf-asm/test/ternary_match4.p4 +++ /dev/null @@ -1,44 +0,0 @@ -#include "tofino/intrinsic_metadata.p4" - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 32; - f4 : 32; - b1 : 8; - b2 : 8; - b3 : 8; - b4 : 8; - } -} -header data_t data; - -parser start { - extract(data); - return ingress; -} - -action noop() { } -action setb1(val, port) { - modify_field(data.b1, val); - modify_field(ig_intr_md_for_tm.ucast_egress_port, port); -} - -table test1 { - reads { - data.f1 : ternary; - data.f2 : ternary; - data.f3 : ternary; - data.f4 : ternary; - } - actions { - setb1; - noop; - } - size : 10000; -} - -control ingress { - apply(test1); -} diff --git a/backends/tofino/bf-asm/test/ternary_match4.stf b/backends/tofino/bf-asm/test/ternary_match4.stf deleted file mode 100644 index b3dc00da2fc..00000000000 --- a/backends/tofino/bf-asm/test/ternary_match4.stf +++ /dev/null @@ -1,84 +0,0 @@ - -tcam_2bit_mode TRUE - -add test1 0 data.f1:0x*******1 setb1(port:4, val:0) -add test1 600 data.f1:0x******1* setb1(port:4, val:1) -add test1 1200 data.f1:0x*****1** setb1(port:4, val:2) -add test1 1800 data.f1:0x****1*** setb1(port:4, val:3) -add test1 2400 data.f1:0x***1**** setb1(port:4, val:4) -add test1 3000 data.f1:0x**1***** setb1(port:4, val:5) -add test1 3500 data.f1:0x*1****** setb1(port:4, val:6) -add test1 4000 data.f1:0x1******* setb1(port:4, val:7) -add test1 4500 data.f2:0x*******1 setb1(port:4, val:8) -add test1 5000 data.f2:0x******1* setb1(port:4, val:9) -add test1 5500 data.f2:0x*****1** setb1(port:4, val:10) -add test1 6000 data.f2:0x****1*** setb1(port:4, val:11) -add test1 6500 data.f2:0x***1**** setb1(port:4, val:12) -add test1 7000 data.f2:0x**1***** setb1(port:4, val:13) -add test1 7500 data.f2:0x*1****** setb1(port:4, val:14) -add test1 8000 data.f2:0x1******* setb1(port:4, val:15) -add test1 8500 data.f3:0x*******1 setb1(port:4, val:16) -add test1 9000 data.f3:0x******1* setb1(port:4, val:17) -add test1 9500 data.f3:0x*****1** setb1(port:4, val:18) -add test1 9999 data.f3:0x****1*** setb1(port:4, val:19) - -expect 4 00000001 ******** ******** ******** 00 66 -packet 0 00000001 00000000 00000000 00000000 55 66 77 88 -wait -expect 4 00000011 ******** ******** ******** 01 66 -packet 0 00000011 00000000 00000000 00000000 55 66 77 88 -wait -expect 4 00000111 ******** ******** ******** 02 66 -packet 0 00000111 00000000 00000000 00000000 55 66 77 88 -wait -expect 4 00001111 ******** ******** ******** 03 66 -packet 0 00001111 00000000 00000000 00000000 55 66 77 88 -wait -expect 4 00011111 ******** ******** ******** 04 66 -packet 0 00011111 00000000 00000000 00000000 55 66 77 88 -wait -expect 4 00111111 ******** ******** ******** 05 66 -packet 0 00111111 00000000 00000000 00000000 55 66 77 88 -wait -expect 4 01111111 ******** ******** ******** 06 66 -packet 0 01111111 00000000 00000000 00000000 55 66 77 88 -wait -expect 4 11111111 ******** ******** ******** 07 66 -packet 0 11111111 00000000 00000000 00000000 55 66 77 88 -wait -expect 4 11111111 ******** ******** ******** 08 66 -packet 0 11111111 00000001 00000000 00000000 55 66 77 88 -wait -expect 4 11111111 ******** ******** ******** 09 66 -packet 0 11111111 00000011 00000000 00000000 55 66 77 88 -wait -expect 4 11111111 ******** ******** ******** 0a 66 -packet 0 11111111 00000111 00000000 00000000 55 66 77 88 -wait -expect 4 11111111 ******** ******** ******** 0b 66 -packet 0 11111111 00001111 00000000 00000000 55 66 77 88 -wait -expect 4 11111111 ******** ******** ******** 0c 66 -packet 0 11111111 00011111 00000000 00000000 55 66 77 88 -wait -expect 4 11111111 ******** ******** ******** 0d 66 -packet 0 11111111 00111111 00000000 00000000 55 66 77 88 -wait -expect 4 11111111 ******** ******** ******** 0e 66 -packet 0 11111111 01111111 00000000 00000000 55 66 77 88 -wait -expect 4 11111111 ******** ******** ******** 0f 66 -packet 0 11111111 11111111 00000000 00000000 55 66 77 88 -wait -expect 4 11111111 ******** ******** ******** 10 66 -packet 0 11111111 11111111 00000001 00000000 55 66 77 88 -wait -expect 4 11111111 ******** ******** ******** 11 66 -packet 0 11111111 11111111 00000011 00000000 55 66 77 88 -wait -expect 4 11111111 ******** ******** ******** 12 66 -packet 0 11111111 11111111 00000111 00000000 55 66 77 88 -wait -expect 4 11111111 ******** ******** ******** 13 66 -packet 0 11111111 11111111 00001111 00000000 55 66 77 88 -wait diff --git a/backends/tofino/bf-asm/test/test-bfas-bin b/backends/tofino/bf-asm/test/test-bfas-bin deleted file mode 100755 index 636992e3962..00000000000 --- a/backends/tofino/bf-asm/test/test-bfas-bin +++ /dev/null @@ -1,144 +0,0 @@ -#!/bin/bash - -shopt -s nullglob -set -o pipefail - -TESTDIR=$(cd $(dirname $0); pwd -P) -LOG=faillog.txt - -function findbin() { - for d in \ - $PWD \ - $PWD/.. \ - $PWD/../.. \ - $PWD/../../.. \ - $PWD/../../../.. \ - $TESTDIR/.. \ - $TESTDIR/../.. \ - ; do - for f in $(find $d -name '*test*' -prune -o -executable -type f -name $1); do - if [ "$f" -nt "$found" ]; then - found="$f" - fi - done - if [ -n "$found" ]; then - break; - fi - done - if [ -z "$found" ]; then - found=$(which $1) - fi - if [ -z "$found" ]; then - echo >&2 "Can't find $1 executable" - echo false - else - echo $found - fi -} - -BFAS=bfas #$(findbin bfas) -echo "BFAS=$BFAS" -BFLINK=bflink #$(findbin bflink) -echo "BFLINK=$BFLINK" -BFDUMPBIN=bfdumpbin #$(findbin bfdumpbin) -echo "BFDUMPBIN=$BFDUMPBIN" - -filter_zero="cat" -do_sort="cat" -target="tofino" -remove_temps=true - -while expr "$1" : - >/dev/null; do - case $1 in - --tofino) - target=tofino - ;; - --jbay) - target=tofino2 - ;; - --sort) - do_sort="sort" - ;; - --filter_zero) - filter_zero="grep -v '^R.*: 00000000$'" - ;; - --preserve) - remove_temps=false - ;; - -*) - echo >&2 "unknown argument $1" - ;; - esac - shift -done - -function test_bfa() { - local targ - targ=$target - dir=$(dirname $1) - name=$(basename $1) - if expr $name : '.*\.tfa' >/dev/null; then - targ=tofino - fi - if expr $name : '.*\.jba' >/dev/null; then - targ=tofino2 - fi - echo -n $1 - echo $1: >&2 - pushd $dir >/dev/null - rm -rf tmp-$name.out - rv=0 - mkdir tmp-$name.out - if $BFAS -t $targ --gen_json --singlepipe -vvvvl tmp-$name.out/bfas.config.log $name -o tmp-$name.out; then - pushd tmp-$name.out >/dev/null - if [ -r tofino.bin ]; then - $BFDUMPBIN -H -L tofino.bin | $filter_zero | $do_sort >bfas.dump - elif [ -r tofino2.bin ]; then - $BFDUMPBIN -H -L tofino2.bin | $filter_zero | $do_sort >bfas.dump - else - echo " no binary?" - rv=1 - fi - if (( rv == 0 )); then - $BFLINK -s -o walle.bin *.cfg.json >&2 - $BFDUMPBIN -H -L walle.bin | $filter_zero | $do_sort >walle.dump - if diff -u bfas.dump walle.dump >&2; then - echo " PASS" - else - echo " mismatch" - rv=1; - fi - fi - popd >/dev/null - else - echo " bfas failed" - rv=2 - fi - if $remove_temps; then - rm -rf tmp-$name.out - fi - popd >/dev/null - return $rv -} - -echo -n "started at " > $LOG -date >> $LOG - -if [ $# -eq 0 ]; then - set $(find . -name '*.bfa') -fi -pass=0 -fail=0 -for file in "$@"; do - if test_bfa $file 2>stdout.txt; then - let pass++ - else - if [[ $? -eq 1 ]]; then - let fail++ - fi - cat stdout.txt >>$LOG - fi - rm stdout.txt -done - -echo "$pass pass, $fail fail" diff --git a/backends/tofino/bf-asm/test/testgw.p4 b/backends/tofino/bf-asm/test/testgw.p4 deleted file mode 100644 index 088dee1e776..00000000000 --- a/backends/tofino/bf-asm/test/testgw.p4 +++ /dev/null @@ -1,91 +0,0 @@ -// Standard L2 Ethernet header -header_type ethernet_t { - fields { - dst_addr : 48; // width in bits - src_addr : 48; - ethertype : 16; - } -} - -header ethernet_t ethernet; - -header_type data_t { - fields { - f1 : 32; - f2 : 32; - f3 : 16; - f4 : 16; - f5 : 8; - f6 : 8; - f7 : 4; - f8 : 4; - } -} -header data_t data; - -parser start { - extract(ethernet); - return data; -} -parser data { - extract(data); - return ingress; -} - -action route_eth(egress_spec, src_addr) { - modify_field(standard_metadata.egress_spec, egress_spec); - modify_field(ethernet.src_addr, src_addr); -} -action noop() { } - -table routing { - reads { - ethernet.dst_addr : lpm; - } - actions { - route_eth; - noop; - } -} - -action setf2(val) { - modify_field(data.f2, val); - //add_to_field(data.f3, data.f4); -} - -table test1 { - reads { - data.f1 : exact; - } - actions { - setf2; - noop; - } -} - -action setf1(val) { - modify_field(data.f1, val); - //add_to_field(data.f4, 1); -} - -table test2 { - reads { - data.f2 : exact; - } - actions { - setf1; - noop; - } -} - -control ingress { - apply(routing); - if (data.f5 != data.f6) { - apply(test1); - } else { - apply(test2); - } -} - -control egress { -} diff --git a/backends/tofino/bf-asm/test/triv_eth.p4 b/backends/tofino/bf-asm/test/triv_eth.p4 deleted file mode 100644 index 1b1962ccd89..00000000000 --- a/backends/tofino/bf-asm/test/triv_eth.p4 +++ /dev/null @@ -1,36 +0,0 @@ -// Standard L2 Ethernet header -header_type ethernet_t { - fields { - dst_addr : 48; // width in bits - src_addr : 48; - ethertype : 16; - } -} - -header ethernet_t ethernet; - -// just ethernet -parser start { - extract(ethernet); - return ingress; -} - -action route_eth(egress_spec, src_addr) { - modify_field(standard_metadata.egress_spec, egress_spec); - modify_field(ethernet.src_addr, src_addr); -} -action noop() { } - -table routing { - reads { - ethernet.dst_addr : lpm; - } - actions { - route_eth; - noop; - } -} - -control ingress { - apply(routing); -} diff --git a/backends/tofino/bf-asm/test/triv_ipv4.p4 b/backends/tofino/bf-asm/test/triv_ipv4.p4 deleted file mode 100644 index c64a29278a2..00000000000 --- a/backends/tofino/bf-asm/test/triv_ipv4.p4 +++ /dev/null @@ -1,72 +0,0 @@ -header_type ethernet_t { - fields { - dst_addr : 48; // width in bits - src_addr : 48; - ethertype : 16; - } -} - -header_type ipv4_t { - fields { - version : 4; - ihl : 4; - diffserv : 8; - totalLen : 16; - identification : 16; - flags : 3; - fragOffset : 13; - ttl : 8; - protocol : 8; - hdrChecksum : 16; - srcAddr : 32; - dstAddr : 32; -// options : *; // Variable length options - } -// length : ihl * 4; -// max_length : 60; -} - -header ethernet_t ethernet; -header ipv4_t ipv4; - -// Start with ethernet always. -parser start { - return ethernet; -} - -parser ethernet { - extract(ethernet); // Start with the ethernet header - return select(ethernet.ethertype) { - 0x800: ipv4; -// default: ingress; - } -} - -parser ipv4 { - extract(ipv4); - return ingress; -} - -action route_ipv4(egress_spec) { - add_to_field(ipv4.ttl, -1); - modify_field(standard_metadata.egress_spec, egress_spec); -} -action do_drop() { /*drop();*/ } -action do_noop() { } - -table routing { - reads { - ipv4.dstAddr : lpm; - } - actions { - do_drop; - route_ipv4; - } - size: 2048; -} - -control ingress { - apply(routing); -} -control egress { -} diff --git a/backends/tofino/bf-asm/test/update_config.py b/backends/tofino/bf-asm/test/update_config.py deleted file mode 100644 index 01e8ff20e2e..00000000000 --- a/backends/tofino/bf-asm/test/update_config.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright 2013-present Barefoot Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import argparse -import struct -from time import sleep - -import google.protobuf.text_format -import grpc -from p4 import p4runtime_pb2 -from p4.config import p4info_pb2 -from p4.tmp import p4config_pb2 - -parser = argparse.ArgumentParser(description='Mininet demo') -parser.add_argument('--dev-id', help='Device id of switch', type=int, action="store", default=0) -parser.add_argument('--p4info', help='text p4info proto', type=str, action="store", required=True) -parser.add_argument('--tofino-bin', help='tofino bin', type=str, action="store", required=True) -parser.add_argument('--cxt-json', help='context json', type=str, action="store", required=True) - -args = parser.parse_args() - - -def main(): - channel = grpc.insecure_channel('localhost:50051') - stub = p4runtime_pb2.P4RuntimeStub(channel) - - print("Sending P4 config") - request = p4runtime_pb2.SetForwardingPipelineConfigRequest() - request.device_id = 0 - config = request.config - with open(args.p4info) as p4info_f: - google.protobuf.text_format.Merge(p4info_f.read(), config.p4info) - device_config = p4config_pb2.P4DeviceConfig() - with open(args.tofino_bin) as tofino_bin_f: - with open(args.cxt_json) as cxt_json_f: - device_config.device_data = "" - prog_name = "easy" - device_config.device_data += struct.pack(" Date: Thu, 20 Feb 2025 11:40:26 -0500 Subject: [PATCH 14/19] Try to get warnings under control. Signed-off-by: fruffy --- backends/tofino/bf-asm/input_xbar.h | 2 +- backends/tofino/bf-asm/jbay/CMakeLists.txt | 2 +- backends/tofino/bf-asm/jbay/parser.cpp | 3 +- backends/tofino/bf-asm/json.h | 34 +++++++------ backends/tofino/bf-asm/tables.h | 51 +++++++++++--------- backends/tofino/bf-asm/target.h | 2 +- backends/tofino/bf-asm/tofino/CMakeLists.txt | 2 +- backends/tofino/bf-asm/tofino/gateway.h | 2 +- 8 files changed, 54 insertions(+), 44 deletions(-) diff --git a/backends/tofino/bf-asm/input_xbar.h b/backends/tofino/bf-asm/input_xbar.h index 772ba492eab..f5d64a18d8c 100644 --- a/backends/tofino/bf-asm/input_xbar.h +++ b/backends/tofino/bf-asm/input_xbar.h @@ -225,7 +225,7 @@ class InputXbar { } return ""; } - bool is_p4_param_bit_in_hash(std::string p4_param_name, int bit) { + bool is_p4_param_bit_in_hash(std::string p4_param_name, unsigned bit) { for (auto &g : groups) { for (auto &p : g.second) { std::string phv_field_name = p.what.name(); diff --git a/backends/tofino/bf-asm/jbay/CMakeLists.txt b/backends/tofino/bf-asm/jbay/CMakeLists.txt index 52fa8f73680..c285f9ade6f 100644 --- a/backends/tofino/bf-asm/jbay/CMakeLists.txt +++ b/backends/tofino/bf-asm/jbay/CMakeLists.txt @@ -53,4 +53,4 @@ set (BFAS_JBAY_SRCS add_library (regs_jbay ${GEN_JBAY_SRCS}) target_link_libraries (regs_jbay p4ctoolkit) # Disable errors for warnings. FIXME: Get rid of this. -target_compile_options(regs_jbay PUBLIC "-Wno-error") +target_compile_options(regs_jbay PUBLIC -Wno-error -Wno-unused-parameter -Wno-unused-variable -Wno-type-limits -Wno-sign-compare) diff --git a/backends/tofino/bf-asm/jbay/parser.cpp b/backends/tofino/bf-asm/jbay/parser.cpp index 34948f0180d..f226b36a1c7 100644 --- a/backends/tofino/bf-asm/jbay/parser.cpp +++ b/backends/tofino/bf-asm/jbay/parser.cpp @@ -303,7 +303,8 @@ void *Parser::setup_phv_output_map(Target::JBay::parser_regs ®s, gress_t gres return ®s.memory[gress].po_action_row[row]; } template <> -void Parser::mark_unused_output_map(Target::JBay::parser_regs &, void *, unsigned) { +void Parser::mark_unused_output_map(Target::JBay::parser_regs & /*regs*/, void * /*map*/, + unsigned /*used*/) { // unneeded on jbay } diff --git a/backends/tofino/bf-asm/json.h b/backends/tofino/bf-asm/json.h index 4bd76105f47..27f707e9fa3 100644 --- a/backends/tofino/bf-asm/json.h +++ b/backends/tofino/bf-asm/json.h @@ -63,11 +63,11 @@ class obj { bool operator<=(const obj &a) const { return !(a < *this); } virtual bool operator==(const obj &a) const = 0; bool operator!=(const obj &a) const { return !(*this == a); } - virtual bool operator==(const char *str) const { return false; } - virtual bool operator==(const std::string &str) const { return false; } - virtual bool operator==(const string &str) const { return false; } + virtual bool operator==(const char * /*str*/) const { return false; } + virtual bool operator==(const std::string & /*str*/) const { return false; } + virtual bool operator==(const string & /*str*/) const { return false; } bool operator!=(const char *str) const { return !(*this == str); } - virtual bool operator==(int64_t val) const { return false; } + virtual bool operator==(int64_t /*val*/) const { return false; } bool operator!=(int64_t val) const { return !(*this == val); } struct ptrless { bool operator()(const obj *a, const obj *b) const { return b ? a ? *a < *b : true : false; } @@ -75,8 +75,8 @@ class obj { return b ? a ? *a < *b : true : false; } }; - virtual void print_on(std::ostream &out, int indent = 0, int width = 80, - const char *pfx = "") const = 0; + virtual void print_on(std::ostream &out, int /*indent*/ = 0, int /*width*/ = 80, + const char * /*pfx*/ = "") const = 0; virtual bool test_width(int &limit) const = 0; virtual number *as_number() { return nullptr; } virtual const number *as_number() const { return nullptr; } @@ -112,7 +112,8 @@ class True : public obj { return std::type_index(typeid(*this)) < std::type_index(typeid(a)); } bool operator==(const obj &a) const { return dynamic_cast(&a) != 0; } - void print_on(std::ostream &out, int indent = 0, int width = 80, const char *pfx = "") const { + void print_on(std::ostream &out, int /*indent*/ = 0, int /*width*/ = 80, + const char * /*pfx*/ = "") const { out << "true"; } bool test_width(int &limit) const { @@ -128,7 +129,8 @@ class False : public obj { return std::type_index(typeid(*this)) < std::type_index(typeid(a)); } bool operator==(const obj &a) const { return dynamic_cast(&a) != 0; } - void print_on(std::ostream &out, int indent = 0, int width = 80, const char *pfx = "") const { + void print_on(std::ostream &out, int /*indent*/ = 0, int /*width*/ = 80, + const char * /*pfx*/ = "") const { out << "false"; } bool test_width(int &limit) const { @@ -153,8 +155,8 @@ class number : public obj { return false; } bool operator==(int64_t v) const override { return val == v; } - void print_on(std::ostream &out, int indent = 0, int width = 80, - const char *pfx = "") const override { + void print_on(std::ostream &out, int /*indent*/ = 0, int /*width*/ = 80, + const char * /*pfx*/ = "") const override { out << val; } bool test_width(int &limit) const override { @@ -199,8 +201,8 @@ class string : public obj, public std::string { bool operator==(const std::string &str) const override { return static_cast(*this) == str; } - void print_on(std::ostream &out, int indent = 0, int width = 80, - const char *pfx = "") const override { + void print_on(std::ostream &out, int /*indent*/ = 0, int /*width*/ = 80, + const char * /*pfx*/ = "") const override { out << '"' << *this << '"'; } bool test_width(int &limit) const override { @@ -257,8 +259,8 @@ class vector : public obj, public vector_base { return false; } using obj::operator!=; - void print_on(std::ostream &out, int indent = 0, int width = 80, - const char *pfx = "") const override; + void print_on(std::ostream &out, int /*indent*/ = 0, int /*width*/ = 80, + const char * /*pfx*/ = "") const override; bool test_width(int &limit) const override { limit -= 2; for (auto &e : *this) { @@ -350,8 +352,8 @@ class map : public obj, public map_base { } return std::unique_ptr(); } - void print_on(std::ostream &out, int indent = 0, int width = 80, - const char *pfx = "") const override; + void print_on(std::ostream &out, int /*indent*/ = 0, int /*width*/ = 80, + const char * /*pfx*/ = "") const override; bool test_width(int &limit) const override { limit -= 2; for (auto &e : *this) { diff --git a/backends/tofino/bf-asm/tables.h b/backends/tofino/bf-asm/tables.h index 1ba0d5b0b32..46ae5fcba2f 100644 --- a/backends/tofino/bf-asm/tables.h +++ b/backends/tofino/bf-asm/tables.h @@ -974,8 +974,8 @@ class Table { // Generate the context json for a field into field list. // Use the bits specified in field, offset by the base bit. // If the field is a constant, output a const_tuple map, including the specified value. - void output_field_to_pack_format(json::vector &field_list, int basebit, std::string name, - std::string source, int start_bit, + void output_field_to_pack_format(json::vector &field_list, unsigned basebit, std::string name, + std::string source, unsigned start_bit, const Table::Format::Field &field, unsigned value = 0) const; void add_zero_padding_fields(Table::Format *format, Table::Actions::Action *act = nullptr, unsigned format_width = 64) const; @@ -1001,7 +1001,8 @@ class Table { virtual int get_tcam_id() const { BUG("%s not a TCAM table", name()); } const std::vector find_p4_params(std::string s, std::string t = "", - int start_bit = -1, int width = -1) const { + unsigned start_bit = -1, + int width = -1) const { remove_name_tail_range(s); std::vector params; if (start_bit <= -1) return params; @@ -1019,7 +1020,7 @@ class Table { return params; } - const p4_param *find_p4_param(std::string s, std::string t = "", int start_bit = -1, + const p4_param *find_p4_param(std::string s, std::string t = "", unsigned start_bit = -1, int width = -1) const { remove_name_tail_range(s); std::vector params; @@ -1088,7 +1089,7 @@ class AlwaysRunTable : public Table { void pass1() override { actions->pass1(this); } void pass2() override { actions->pass2(this); } void pass3() override {} - FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_regs, (mau_regs & regs), override;) + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_regs, (mau_regs & regs), override) void gen_tbl_cfg(json::vector &out) const override {} }; @@ -1198,7 +1199,7 @@ DECLARE_ABSTRACT_TABLE_TYPE( * the name with a _vt extension to help it out. */ \ template \ void write_regs_vt(REGS ®s); \ - FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_regs, (mau_regs & regs), override;) \ + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_regs, (mau_regs & regs), override) \ void gen_tbl_cfg(json::vector &out) const override; \ \ private: \ @@ -1307,7 +1308,7 @@ DECLARE_ABSTRACT_TABLE_TYPE(SRamMatchTable, MatchTable, // exact, atcam, void pass1() override; template void write_regs_vt(REGS ®s); FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, - void write_regs, (mau_regs ®s), override; ) + void write_regs, (mau_regs ®s), override ) virtual std::string get_match_mode(const Phv::Ref &pref, int offset) const; json::map* add_common_sram_tbl_cfgs(json::map &tbl, std::string match_type, std::string stage_table_type) const; @@ -1611,7 +1612,7 @@ DECLARE_TABLE_TYPE( table_type_t table_type() const override { return HASH_ACTION; } template void write_merge_regs_vt(REGS ®s, int type, int bus); FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_merge_regs, - (mau_regs & regs, int type, int bus), override;) Format::Field * + (mau_regs & regs, int type, int bus), override) Format::Field * lookup_field(const std::string &n, const std::string &act = "") const override; void add_hash_functions(json::map &stage_tbl) const override; void determine_word_and_result_bus() override; @@ -1949,7 +1950,7 @@ DECLARE_TABLE_TYPE( FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_merge_regs, (mau_regs & regs, MatchTable *match, int type, int bus, const std::vector &args), - override;) int address_shift() + override) int address_shift() const override { return 7; } std::vector determine_spare_bank_memory_units() const override; unsigned meter_group() const { return layout.at(0).row / 4U; } int home_row() const override { @@ -2001,9 +2002,9 @@ class IdletimeTable : public Table { void write_merge_regs_vt(REGS ®s, int type, int bus); template void write_regs_vt(REGS ®s); - FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_regs, (mau_regs & regs), override;) + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_regs, (mau_regs & regs), override) FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_merge_regs, - (mau_regs & regs, int type, int bus), override;) + (mau_regs & regs, int type, int bus), override) void gen_tbl_cfg(json::vector &out) const override { /* nothing at top level */ } void gen_stage_tbl_cfg(json::map &out) const; static IdletimeTable *create(int lineno, const std::string &name, gress_t gress, Stage *stage, @@ -2034,11 +2035,15 @@ DECLARE_ABSTRACT_TABLE_TYPE( OVERLOAD_FUNC_FOREACH(TARGET_CLASS, void, alloc_vpns, (), ()) template void write_regs_vt(REGS ®s); FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_regs, (mau_regs & regs), override) - FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_merge_regs, - (mau_regs & regs, MatchTable *match, int type, int bus, - const std::vector &args), - override = 0) void common_init_setup(const VECTOR(pair_t) &, bool, - P4Table::type) override; + // FIXME: This comment is necessary to stop cpplint from complaining. The format is off because + // this code is within a macro. + FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_merge_regs, + (mau_regs & regs, MatchTable *match, int type, int bus, + const std::vector &args), + override = 0) + // FIXME: This comment is necessary to stop cpplint from complaining. The format is off because + // this code is within a macro. + void common_init_setup(const VECTOR(pair_t) &, bool, P4Table::type) override; bool common_setup(pair_t &, const VECTOR(pair_t) &, P4Table::type) override; void pass1() override; void pass2() override; void pass3() override;) @@ -2046,18 +2051,20 @@ DECLARE_TABLE_TYPE( CounterTable, Synth2Port, "counter", enum {NONE = 0, PACKETS = 1, BYTES = 2, BOTH = 3} type = NONE; int teop = -1; bool teop_initialized = false; int bytecount_adjust = 0; - table_type_t table_type() const override { return COUNTER; } template + table_type_t table_type() const override { return COUNTER; } + // FIXME: This comment is necessary to stop cpplint from complaining. The format is off because + // this code is within a macro. + template void write_merge_regs_vt(REGS ®s, MatchTable *match, int type, int bus, const std::vector &args); FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_merge_regs, (mau_regs & regs, MatchTable *match, int type, int bus, const std::vector &args), - override;) + override) template void setup_teop_regs(REGS ®s, int stats_group_index); template void write_alu_vpn_range(REGS ®s); - template void setup_teop_regs_2(REGS ®s, int stats_group_index); template void write_alu_vpn_range_2(REGS ®s); @@ -2091,7 +2098,7 @@ DECLARE_TABLE_TYPE( FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_merge_regs, (mau_regs & regs, MatchTable *match, int type, int bus, const std::vector &args), - override;) + override) template void setup_teop_regs(REGS ®s, int meter_group_index); @@ -2145,13 +2152,13 @@ DECLARE_TABLE_TYPE(StatefulTable, Synth2Port, "stateful", bool setup_jbay(const pair_t &kv); template void write_action_regs_vt(REGS ®s, const Actions::Action *); FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, - void write_action_regs, (mau_regs ®s, const Actions::Action *act), override; ) + void write_action_regs, (mau_regs ®s, const Actions::Action *act), override) template void write_merge_regs_vt(REGS ®s, MatchTable *match, int type, int bus, const std::vector &args); template void write_logging_regs(REGS ®s); FOR_ALL_REGISTER_SETS(TARGET_OVERLOAD, void write_merge_regs, (mau_regs ®s, MatchTable *match, int type, - int bus, const std::vector &args), override; ) + int bus, const std::vector &args), override) template void write_tofino2_common_regs(REGS ®s); struct const_info_t { int lineno; diff --git a/backends/tofino/bf-asm/target.h b/backends/tofino/bf-asm/target.h index 9bf99443829..6c6b6103ffa 100644 --- a/backends/tofino/bf-asm/target.h +++ b/backends/tofino/bf-asm/target.h @@ -463,7 +463,7 @@ class Target::JBay : public Target { typedef ::JBay::regs_match_action_stage_ mau_regs; typedef ::JBay::regs_deparser deparser_regs; - enum { + enum : int { ARAM_UNITS_PER_STAGE = 0, PARSER_CHECKSUM_UNITS = 5, PARSER_EXTRACT_BYTES = true, diff --git a/backends/tofino/bf-asm/tofino/CMakeLists.txt b/backends/tofino/bf-asm/tofino/CMakeLists.txt index f36c390ae40..e1d922b3e7e 100644 --- a/backends/tofino/bf-asm/tofino/CMakeLists.txt +++ b/backends/tofino/bf-asm/tofino/CMakeLists.txt @@ -57,4 +57,4 @@ set (BFAS_TOFINO_SRCS add_library (regs_tofino ${GEN_TOFINO_SRCS}) target_link_libraries (regs_tofino p4ctoolkit) # Disable errors for warnings. FIXME: Get rid of this. -target_compile_options(regs_tofino PUBLIC "-Wno-error") +target_compile_options(regs_tofino PUBLIC -Wno-error -Wno-unused-parameter -Wno-unused-variable -Wno-type-limits -Wno-sign-compare) diff --git a/backends/tofino/bf-asm/tofino/gateway.h b/backends/tofino/bf-asm/tofino/gateway.h index b8836f32afd..6035a80dab7 100644 --- a/backends/tofino/bf-asm/tofino/gateway.h +++ b/backends/tofino/bf-asm/tofino/gateway.h @@ -31,7 +31,7 @@ class Target::Tofino::GatewayTable : public ::GatewayTable { bool check_match_key(MatchKey &, const std::vector &, bool) override; int gw_memory_unit() const override { return layout[0].row * 2 + gw_unit; } - REGSETS_IN_CLASS(Tofino, TARGET_OVERLOAD, void write_next_table_regs, (mau_regs &), override;) + REGSETS_IN_CLASS(Tofino, TARGET_OVERLOAD, void write_next_table_regs, (mau_regs &), override) }; template From 564a034946e92b8753b198ecddeb741c6ddf8b00 Mon Sep 17 00:00:00 2001 From: fruffy Date: Thu, 20 Feb 2025 16:17:56 -0500 Subject: [PATCH 15/19] Sensitive warning fixes. Signed-off-by: fruffy --- backends/tofino/bf-asm/sram_match.cpp | 2 +- backends/tofino/bf-asm/tables.cpp | 8 ++++---- backends/tofino/bf-asm/tables.h | 6 +++--- backends/tofino/bf-asm/ternary_match.cpp | 2 ++ 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/backends/tofino/bf-asm/sram_match.cpp b/backends/tofino/bf-asm/sram_match.cpp index cfec66b31fe..697a796d028 100644 --- a/backends/tofino/bf-asm/sram_match.cpp +++ b/backends/tofino/bf-asm/sram_match.cpp @@ -1323,7 +1323,7 @@ std::string SRamMatchTable::get_match_mode(const Phv::Ref &pref, int offset) con return "unused"; } -void SRamMatchTable::add_field_to_pack_format(json::vector &field_list, int basebit, +void SRamMatchTable::add_field_to_pack_format(json::vector &field_list, unsigned basebit, std::string name, const Table::Format::Field &field, const Table::Actions::Action *act) const { if (name != "match") { diff --git a/backends/tofino/bf-asm/tables.cpp b/backends/tofino/bf-asm/tables.cpp index c2980c73a41..4fb3e581438 100644 --- a/backends/tofino/bf-asm/tables.cpp +++ b/backends/tofino/bf-asm/tables.cpp @@ -917,7 +917,7 @@ void Table::alloc_rams(bool logical, BFN::Alloc2Dbase

&use, } else { use[r][c] = this; } - } catch (std::out_of_range) { + } catch (std::out_of_range & /*e*/) { error(lineno, "Table %s using out-of-bounds (%d,%d)", name(), r, c); } } @@ -3022,7 +3022,7 @@ void Table::get_cjson_source(const std::string &field_name, std::string &source, * separate functions, as the corner casing for these different cases can be quite different * and lead to some significant confusion */ -void Table::add_field_to_pack_format(json::vector &field_list, int basebit, std::string name, +void Table::add_field_to_pack_format(json::vector &field_list, unsigned basebit, std::string name, const Table::Format::Field &field, const Table::Actions::Action *act) const { decltype(act->reverse_alias()) aliases; @@ -3071,8 +3071,8 @@ void Table::add_field_to_pack_format(json::vector &field_list, int basebit, std: canon_field_list(field_list); } -void Table::output_field_to_pack_format(json::vector &field_list, int basebit, std::string name, - std::string source, int start_bit, +void Table::output_field_to_pack_format(json::vector &field_list, unsigned basebit, + std::string name, std::string source, unsigned start_bit, const Table::Format::Field &field, unsigned value) const { unsigned add_width = 0; bool pfe_enable = false; diff --git a/backends/tofino/bf-asm/tables.h b/backends/tofino/bf-asm/tables.h index 46ae5fcba2f..ad66ae2fcea 100644 --- a/backends/tofino/bf-asm/tables.h +++ b/backends/tofino/bf-asm/tables.h @@ -961,8 +961,8 @@ class Table { json::map &add_pack_format(json::map &stage_tbl, Table::Format *format, bool pad_zeros = true, bool print_fields = true, Table::Actions::Action *act = nullptr) const; - virtual void add_field_to_pack_format(json::vector &field_list, int basebit, std::string name, - const Table::Format::Field &field, + virtual void add_field_to_pack_format(json::vector &field_list, unsigned basebit, + std::string name, const Table::Format::Field &field, const Table::Actions::Action *act) const; virtual bool validate_call(Table::Call &call, MatchTable *self, size_t required_args, int hash_dist_type, Table::Call &first_call) { @@ -1317,7 +1317,7 @@ DECLARE_ABSTRACT_TABLE_TYPE(SRamMatchTable, MatchTable, // exact, atcam, unsigned get_number_entries() const; unsigned get_format_width() const; virtual int determine_pre_byteswizzle_loc(MatchSource *ms, int lo, int hi, int word); - void add_field_to_pack_format(json::vector &field_list, int basebit, std::string name, + void add_field_to_pack_format(json::vector &field_list, unsigned basebit, std::string name, const Table::Format::Field &field, const Table::Actions::Action *act) const override; std::unique_ptr gen_memory_resource_allocation_tbl_cfg(const Way &) const; diff --git a/backends/tofino/bf-asm/ternary_match.cpp b/backends/tofino/bf-asm/ternary_match.cpp index a5d195db7fc..ff4d85f6092 100644 --- a/backends/tofino/bf-asm/ternary_match.cpp +++ b/backends/tofino/bf-asm/ternary_match.cpp @@ -848,6 +848,8 @@ void TernaryMatchTable::gen_match_fields(json::vector &match_field_list, width, match[word].byte_group, tcam_bits[match_index - word]); } break; + default: + BUG("Unknown group type"); } } } From be4d5989786425e12ceec8926788e5fc1190deb0 Mon Sep 17 00:00:00 2001 From: fruffy Date: Fri, 21 Feb 2025 11:27:26 -0500 Subject: [PATCH 16/19] More warning fixes. Signed-off-by: fruffy --- backends/tofino/bf-asm/action_bus.cpp | 23 +++++++++++++---------- backends/tofino/bf-asm/action_bus.h | 25 ++++++++++++++----------- backends/tofino/bf-asm/asm-types.cpp | 3 +++ backends/tofino/bf-asm/deparser.cpp | 2 +- backends/tofino/bf-asm/deparser.h | 5 ++++- backends/tofino/bf-asm/hashexpr.cpp | 13 ++----------- backends/tofino/bf-asm/jbay/parser.cpp | 2 -- backends/tofino/bf-asm/tables.cpp | 1 - backends/tofino/bf-asm/target.cpp | 8 ++++---- 9 files changed, 41 insertions(+), 41 deletions(-) diff --git a/backends/tofino/bf-asm/action_bus.cpp b/backends/tofino/bf-asm/action_bus.cpp index 8006c73d7c8..6019286c81a 100644 --- a/backends/tofino/bf-asm/action_bus.cpp +++ b/backends/tofino/bf-asm/action_bus.cpp @@ -44,8 +44,9 @@ std::ostream &operator<<(std::ostream &out, const ActionBusSource &src) { out << "HashDist(" << src.hd->hash_group << ", " << src.hd->id << ")"; break; case ActionBusSource::HashDistPair: - out << "HashDistPair([" << src.hd1->hash_group << ", " << src.hd1->id << "]," << "[" - << src.hd2->hash_group << ", " << src.hd2->id << "])"; + out << "HashDistPair([" << src.hd_tuple.hd1->hash_group << ", " << src.hd_tuple.hd1->id + << "]," << "[" << src.hd_tuple.hd2->hash_group << ", " << src.hd_tuple.hd2->id + << "])"; break; case ActionBusSource::RandomGen: out << "rng " << src.rng.unit; @@ -63,7 +64,7 @@ std::ostream &operator<<(std::ostream &out, const ActionBusSource &src) { out << "EALU"; break; case ActionBusSource::XcmpData: - out << "XCMP(" << src.xcmp_group << ":" << src.xcmp_byte << ")"; + out << "XCMP(" << src.xcmp_data.xcmp_group << ":" << src.xcmp_data.xcmp_byte << ")"; break; case ActionBusSource::NameRef: out << "NameRef(" << (src.name_ref ? src.name_ref->name : "0") << ")"; @@ -294,11 +295,11 @@ unsigned ActionBus::Slot::lo(Table *tbl) const { bool ActionBus::compatible(const ActionBusSource &a, unsigned a_off, const ActionBusSource &b, unsigned b_off) { if ((a.type == ActionBusSource::HashDist) && (b.type == ActionBusSource::HashDistPair)) { - return ((compatible(a, a_off, ActionBusSource(b.hd1), b_off)) || - (compatible(a, a_off, ActionBusSource(b.hd2), b_off + 16))); + return ((compatible(a, a_off, ActionBusSource(b.hd_tuple.hd1), b_off)) || + (compatible(a, a_off, ActionBusSource(b.hd_tuple.hd2), b_off + 16))); } else if ((a.type == ActionBusSource::HashDistPair) && (b.type == ActionBusSource::HashDist)) { - return ((compatible(ActionBusSource(a.hd1), a_off, b, b_off)) || - (compatible(ActionBusSource(a.hd2), a_off + 16, b, b_off))); + return ((compatible(ActionBusSource(a.hd_tuple.hd1), a_off, b, b_off)) || + (compatible(ActionBusSource(a.hd_tuple.hd2), a_off + 16, b, b_off))); } if (a.type != b.type) return false; switch (a.type) { @@ -310,9 +311,11 @@ bool ActionBus::compatible(const ActionBusSource &a, unsigned a_off, const Actio case ActionBusSource::HashDist: return a.hd->hash_group == b.hd->hash_group && a.hd->id == b.hd->id && a_off == b_off; case ActionBusSource::HashDistPair: - return ((a.hd1->hash_group == b.hd1->hash_group && a.hd1->id == b.hd1->id) && + return ((a.hd_tuple.hd1->hash_group == b.hd_tuple.hd1->hash_group && + a.hd_tuple.hd1->id == b.hd_tuple.hd1->id) && (a_off == b_off) && - (a.hd2->hash_group == b.hd2->hash_group && a.hd2->id == b.hd2->id)); + (a.hd_tuple.hd2->hash_group == b.hd_tuple.hd2->hash_group && + a.hd_tuple.hd2->id == b.hd_tuple.hd2->id)); case ActionBusSource::TableOutput: return a.table == b.table; default: @@ -1140,7 +1143,7 @@ std::string ActionBusSource::toString(Table *tbl) const { case Ealu: return "ealu"; case XcmpData: - tmp << "xcmp(" << xcmp_group << ":" << xcmp_byte << ")"; + tmp << "xcmp(" << xcmp_data.xcmp_group << ":" << xcmp_data.xcmp_byte << ")"; return tmp.str(); case NameRef: case ColorRef: diff --git a/backends/tofino/bf-asm/action_bus.h b/backends/tofino/bf-asm/action_bus.h index f19352532e7..16b86e43fe6 100644 --- a/backends/tofino/bf-asm/action_bus.h +++ b/backends/tofino/bf-asm/action_bus.h @@ -46,13 +46,13 @@ struct ActionBusSource { HashDistribution *hd; struct { HashDistribution *hd1, *hd2; - }; + } hd_tuple; Table *table; Table::Ref *name_ref; RandomNumberGen rng; struct { short xcmp_group, xcmp_byte; - }; + } xcmp_data; }; ActionBusSource() : type(None) { field = nullptr; } ActionBusSource(Table::Format::Field *f) : type(Field) { // NOLINT(runtime/explicit) @@ -60,8 +60,8 @@ struct ActionBusSource { } ActionBusSource(HashDistribution *h) : type(HashDist) { hd = h; } // NOLINT(runtime/explicit) ActionBusSource(HashDistribution *h1, HashDistribution *h2) : type(HashDistPair) { - hd1 = h1; - hd2 = h2; + hd_tuple.hd1 = h1; + hd_tuple.hd2 = h2; } ActionBusSource(Table *t, TableOutputModifier m = TableOutputModifier::NONE) // NOLINT(runtime/explicit) @@ -115,23 +115,26 @@ struct ActionBusSource { ActionBusSource(InputXbar::Group grp, int byte) : type(XcmpData) { BUG_CHECK(grp.type == InputXbar::Group::XCMP, "Not xcmp ixbar"); field = nullptr; - xcmp_group = grp.index; - xcmp_byte = byte; + xcmp_data.xcmp_group = grp.index; + xcmp_data.xcmp_byte = byte; } bool operator==(const ActionBusSource &a) const { if (type == XcmpData) - return a.type == XcmpData && xcmp_group == a.xcmp_group && xcmp_byte == a.xcmp_byte; - if (type == HashDistPair && hd2 != a.hd2) return false; + return a.type == XcmpData && xcmp_data.xcmp_group == a.xcmp_data.xcmp_group && + xcmp_data.xcmp_byte == a.xcmp_data.xcmp_byte; + if (type == HashDistPair && hd_tuple.hd2 != a.hd_tuple.hd2) return false; return type == a.type && field == a.field; } bool operator<(const ActionBusSource &a) const { if (type != a.type) return type < a.type; switch (type) { case HashDistPair: - return hd1 == a.hd1 ? hd2 < a.hd2 : hd1 < a.hd1; + return hd_tuple.hd1 == a.hd_tuple.hd1 ? hd_tuple.hd2 < a.hd_tuple.hd2 + : hd_tuple.hd1 < a.hd_tuple.hd1; case XcmpData: - return xcmp_group == a.xcmp_group ? xcmp_byte < a.xcmp_byte - : xcmp_group < a.xcmp_group; + return xcmp_data.xcmp_group == a.xcmp_data.xcmp_group + ? xcmp_data.xcmp_byte < a.xcmp_data.xcmp_byte + : xcmp_data.xcmp_group < a.xcmp_data.xcmp_group; default: return field < a.field; } diff --git a/backends/tofino/bf-asm/asm-types.cpp b/backends/tofino/bf-asm/asm-types.cpp index 8fc2ea055f5..bfcc5e524d8 100644 --- a/backends/tofino/bf-asm/asm-types.cpp +++ b/backends/tofino/bf-asm/asm-types.cpp @@ -310,6 +310,9 @@ bool operator==(const struct value_t &a, const struct value_t &b) { if (a.map.data[i].value != b.map.data[i].value) return false; } return true; + case tBIGMATCH: + default: + break; } assert(false && "unknown value type"); return ""; diff --git a/backends/tofino/bf-asm/deparser.cpp b/backends/tofino/bf-asm/deparser.cpp index 7a1ed225426..922b07baf11 100644 --- a/backends/tofino/bf-asm/deparser.cpp +++ b/backends/tofino/bf-asm/deparser.cpp @@ -673,7 +673,7 @@ void Deparser::process() { } for (int i = 0; i < MAX_DEPARSER_CHECKSUM_UNITS; i++) for (auto &ent : full_checksum_unit[gress][i].entries) { - for (auto entry : ent.second) { + for (const auto &entry : ent.second) { if (!entry.check()) error(entry.lineno, "Invalid checksum entry"); } ent.second = merge_csum_entries(ent.second, i); diff --git a/backends/tofino/bf-asm/deparser.h b/backends/tofino/bf-asm/deparser.h index d561907e3e7..c956e1723e5 100644 --- a/backends/tofino/bf-asm/deparser.h +++ b/backends/tofino/bf-asm/deparser.h @@ -115,8 +115,11 @@ class Deparser : public Section { swap = a.swap; return *this; } + ChecksumVal(const ChecksumVal &a) : Val(a) { + mask = a.mask; + swap = a.swap; + }; ChecksumVal() : Val() {} - bool check() const override { if (is_phv()) { if (mask == 0) error(lineno, "mask is 0 for phv checkum value?"); diff --git a/backends/tofino/bf-asm/hashexpr.cpp b/backends/tofino/bf-asm/hashexpr.cpp index af384b077e2..00bd2b0bc52 100644 --- a/backends/tofino/bf-asm/hashexpr.cpp +++ b/backends/tofino/bf-asm/hashexpr.cpp @@ -21,17 +21,6 @@ #include "lib/bitops.h" #include "lib/bitvec.h" -static bitvec crc(bitvec poly, bitvec val) { - int poly_size = poly.max().index() + 1; - if (!poly_size) return bitvec(0); - val <<= poly_size - 1; - for (auto i = val.max(); i.index() >= (poly_size - 1); --i) { - BUG_CHECK(*i); - val ^= poly << (i.index() - (poly_size - 1)); - } - return val; -} - static bool check_ixbar(Phv::Ref &ref, InputXbar *ix, InputXbar::HashTable hash_table) { if (!ref.check()) return false; if (ref->reg.mau_id() < 0) { @@ -682,6 +671,7 @@ void HashExpr::generate_ixbar_inputs_with_gaps(const std::multimap void Parser::gen_configuration_cache(Target::JBay::parser_regs ®s, json::vector &cfg_cache) { std::string reg_fqname; std::string reg_name; - unsigned reg_value; std::string reg_value_str; unsigned reg_width = 13; @@ -578,7 +577,6 @@ void Parser::gen_configuration_cache(Target::JBay::parser_regs ®s, json::vect reg_fqname = "pardereg.pgstnreg.epbprsr4reg[" + std::to_string(i) + "].epbreg.chan0_group.chnl_ctrl.meta_opt"; reg_name = "epb" + std::to_string(i) + "parser0_chnl_ctrl_0"; - reg_value = meta_opt; reg_value_str = int_to_hex_string(meta_opt, reg_width); add_cfg_reg(cfg_cache, reg_fqname, reg_name, reg_value_str); } diff --git a/backends/tofino/bf-asm/tables.cpp b/backends/tofino/bf-asm/tables.cpp index 4fb3e581438..5d915918f05 100644 --- a/backends/tofino/bf-asm/tables.cpp +++ b/backends/tofino/bf-asm/tables.cpp @@ -150,7 +150,6 @@ void Table::NextTables::resolve_long_branch(const Table *tbl, break; } next_table_ = n; - continue2:; } } diff --git a/backends/tofino/bf-asm/target.cpp b/backends/tofino/bf-asm/target.cpp index daea10fd1ad..41b3b1f7c50 100644 --- a/backends/tofino/bf-asm/target.cpp +++ b/backends/tofino/bf-asm/target.cpp @@ -313,9 +313,9 @@ int Target::NUM_BUS_OF_TYPE(int bus_type) { } // should these be inline in the header file? -#define DEFINE_PER_TARGET_CONSTANT(TYPE, NAME) \ - TYPE Target::NAME() { \ - SWITCH_FOREACH_TARGET(options.target, return TARGET::NAME;) \ - return (TYPE){}; /* NOLINT(readability/braces) */ \ +#define DEFINE_PER_TARGET_CONSTANT(TYPE, NAME) \ + TYPE Target::NAME() { \ + SWITCH_FOREACH_TARGET(options.target, return TARGET::NAME;) \ + return std::conditional_t, std::nullptr_t, TYPE>(); \ } PER_TARGET_CONSTANTS(DEFINE_PER_TARGET_CONSTANT) From aa841f036b7ef52bcc68398367f3c201ed9e41cb Mon Sep 17 00:00:00 2001 From: fruffy Date: Fri, 14 Mar 2025 17:15:30 -0400 Subject: [PATCH 17/19] Fix some more warnings. Signed-off-by: fruffy --- backends/tofino/bf-asm/error_mode.cpp | 2 +- backends/tofino/bf-asm/match_table.cpp | 2 +- backends/tofino/bf-asm/parser-tofino-jbay.cpp | 2 +- backends/tofino/bf-asm/phv.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backends/tofino/bf-asm/error_mode.cpp b/backends/tofino/bf-asm/error_mode.cpp index 4d888d1a775..7ae161eca48 100644 --- a/backends/tofino/bf-asm/error_mode.cpp +++ b/backends/tofino/bf-asm/error_mode.cpp @@ -162,7 +162,7 @@ void ErrorMode::write_regs(REGS ®s, const Stage *stage, gress_t gress) { break; } default: - BUG(); + BUG("unexpected stage_dep: %d", stage->stage_dep[gress]); } } diff --git a/backends/tofino/bf-asm/match_table.cpp b/backends/tofino/bf-asm/match_table.cpp index caf0d78ca53..7a602c4728d 100644 --- a/backends/tofino/bf-asm/match_table.cpp +++ b/backends/tofino/bf-asm/match_table.cpp @@ -661,7 +661,7 @@ void MatchTable::add_hash_functions(json::map &stage_tbl) const { if (ht.size() > 0) { // Merge all bits to xor across multiple hash ways in single // json::vector for each hash bit - for (const auto hash_table : ht) { + for (const auto &hash_table : ht) { json::map hash_function; json::vector &hash_bits = hash_function["hash_bits"] = json::vector(); hash_function["hash_function_number"] = hash_table.first.uid(); diff --git a/backends/tofino/bf-asm/parser-tofino-jbay.cpp b/backends/tofino/bf-asm/parser-tofino-jbay.cpp index 70e20667916..fbe83db78a4 100644 --- a/backends/tofino/bf-asm/parser-tofino-jbay.cpp +++ b/backends/tofino/bf-asm/parser-tofino-jbay.cpp @@ -807,7 +807,7 @@ void Parser::Checksum::pass2(Parser *parser) { } Parser::CounterInit::CounterInit(gress_t gress, pair_t data) - : lineno(data.key.lineno), gress(gress) { + : gress(gress), lineno(data.key.lineno) { if (!CHECKTYPE2(data.key, tSTR, tCMD)) return; if (!CHECKTYPE(data.value, tMAP)) return; diff --git a/backends/tofino/bf-asm/phv.cpp b/backends/tofino/bf-asm/phv.cpp index 61ade268af1..b7fcf49d0a9 100644 --- a/backends/tofino/bf-asm/phv.cpp +++ b/backends/tofino/bf-asm/phv.cpp @@ -199,7 +199,7 @@ Phv::Ref::Ref(gress_t g, int stage, const value_t &n) } Phv::Ref::Ref(const Phv::Register &r, gress_t gr, int l, int h) - : gress_(gr), stage(0), name_(r.name), lo(l), hi(h < 0 ? l : h), lineno(-1) {} + : gress_(gr), name_(r.name), stage(0), lo(l), hi(h < 0 ? l : h), lineno(-1) {} bool Phv::Ref::merge(const Phv::Ref &r) { if (r.name_ != name_ || r.gress_ != gress_) return false; From b6dd3e97533ac24cd150cb113b58ec533bdad48b Mon Sep 17 00:00:00 2001 From: fruffy Date: Fri, 14 Mar 2025 20:23:14 -0400 Subject: [PATCH 18/19] Fix more warnings. Signed-off-by: fruffy --- backends/tofino/bf-asm/deparser.h | 9 +++++++-- backends/tofino/bf-asm/disasm.h | 1 + backends/tofino/bf-asm/error_mode.cpp | 1 + backends/tofino/bf-asm/instruction.cpp | 8 +++++--- backends/tofino/bf-asm/ternary_match.cpp | 7 ++++--- backends/tofino/bf-p4c/phv/phv_fields.cpp | 6 +++--- ir/json_loader.h | 10 ++++++++-- 7 files changed, 29 insertions(+), 13 deletions(-) diff --git a/backends/tofino/bf-asm/deparser.h b/backends/tofino/bf-asm/deparser.h index c956e1723e5..c958f3dd428 100644 --- a/backends/tofino/bf-asm/deparser.h +++ b/backends/tofino/bf-asm/deparser.h @@ -46,8 +46,11 @@ class Deparser : public Section { Phv::Ref val; int tag = -1; ordered_set pov; - const int &lineno = val.lineno; - Val() {} + std::reference_wrapper lineno = val.lineno; + Val() = default; + Val(const Val &) = default; + Val(Val &&) = default; + Val &operator=(Val &&) = default; virtual ~Val() {} Val(gress_t gr, const value_t &v) : val(gr, DEPARSER_STAGE, v) {} Val(gress_t gr, const value_t &v, const value_t &p) : val(gr, DEPARSER_STAGE, v) { @@ -120,6 +123,8 @@ class Deparser : public Section { swap = a.swap; }; ChecksumVal() : Val() {} + ChecksumVal(ChecksumVal &&) = default; + ChecksumVal &operator=(ChecksumVal &&) = default; bool check() const override { if (is_phv()) { if (mask == 0) error(lineno, "mask is 0 for phv checkum value?"); diff --git a/backends/tofino/bf-asm/disasm.h b/backends/tofino/bf-asm/disasm.h index 285d6661fe8..812ed4af0b5 100644 --- a/backends/tofino/bf-asm/disasm.h +++ b/backends/tofino/bf-asm/disasm.h @@ -23,6 +23,7 @@ class Disasm { public: FOR_ALL_TARGETS(DECLARE_TARGET_CLASS) + virtual ~Disasm() {} virtual void input_binary(uint64_t addr, char tag, uint32_t *data, size_t len) = 0; static Disasm *create(std::string target); }; diff --git a/backends/tofino/bf-asm/error_mode.cpp b/backends/tofino/bf-asm/error_mode.cpp index 7ae161eca48..ca710fd98a2 100644 --- a/backends/tofino/bf-asm/error_mode.cpp +++ b/backends/tofino/bf-asm/error_mode.cpp @@ -161,6 +161,7 @@ void ErrorMode::write_regs(REGS ®s, const Stage *stage, gress_t gress) { merge.prev_error_ctl[gress].prev_error_ctl_match = 1; break; } + [[fallthrough]]; default: BUG("unexpected stage_dep: %d", stage->stage_dep[gress]); } diff --git a/backends/tofino/bf-asm/instruction.cpp b/backends/tofino/bf-asm/instruction.cpp index 7f5827ee498..415930d8d24 100644 --- a/backends/tofino/bf-asm/instruction.cpp +++ b/backends/tofino/bf-asm/instruction.cpp @@ -140,7 +140,8 @@ struct Operand : public IHasDbPrint { if (dest_size != -1) { // DepositField::encode() calling. auto rotConst = DepositField::discoverRotation(val, group_size[group], 8, minconst - 1); - if (rotConst.rotate) return rotConst.value + 24 | (rotConst.rotate << RotationBits); + if (rotConst.rotate) + return (rotConst.value + 24) | (rotConst.rotate << RotationBits); } if (val >= minconst && val < 8) return val + 24; @@ -1002,7 +1003,8 @@ Instruction *LoadConst::pass1(Table *tbl, Table::Actions::Action *) { } slot = dest->reg.mau_id(); int size = Phv::reg(slot)->size; - int minval = -1 << (size - 1); + BUG_CHECK(size > 0, "bad register size"); + int minval = ~0u << (size - 1); if (size > 21) { size = 21; minval = 0; @@ -1168,8 +1170,8 @@ struct ByteRotateMerge : VLIWInstruction { }; Phv::Ref dest; Operand src1, src2; - bitvec byte_mask; int src1_shift, src2_shift; + bitvec byte_mask; ByteRotateMerge(Table *tbl, const Table::Actions::Action *act, const value_t &d, const value_t &s1, const value_t &s2, int s1s, int s2s, int bm) : VLIWInstruction(d.lineno), diff --git a/backends/tofino/bf-asm/ternary_match.cpp b/backends/tofino/bf-asm/ternary_match.cpp index ff4d85f6092..688c0e3a869 100644 --- a/backends/tofino/bf-asm/ternary_match.cpp +++ b/backends/tofino/bf-asm/ternary_match.cpp @@ -408,9 +408,10 @@ void TernaryMatchTable::tcam_table_map(REGS ®s, int row, int col) { static void set_tcam_mode_logical_table(ubits<4> ®, int tcam_id, int logical_id) { reg = logical_id; } -static void set_tcam_mode_logical_table(ubits<8> ®, int tcam_id, int logical_id) { - reg |= 1U << tcam_id; -} +// TODO: Unused? +// static void set_tcam_mode_logical_table(ubits<8> ®, int tcam_id, int logical_id) { +// reg |= 1U << tcam_id; +// } template void TernaryMatchTable::write_regs_vt(REGS ®s) { diff --git a/backends/tofino/bf-p4c/phv/phv_fields.cpp b/backends/tofino/bf-p4c/phv/phv_fields.cpp index 9d2f42115e3..45a616126fe 100644 --- a/backends/tofino/bf-p4c/phv/phv_fields.cpp +++ b/backends/tofino/bf-p4c/phv/phv_fields.cpp @@ -1568,9 +1568,9 @@ struct ComputeFieldAlignments : public Inspector { // For non-set instructions accessing an AttachedOutput if ((instr->operands.size() == 3) && (instr->name != "set")) { - int op_id = 0; + bool first = true; for (auto op_f : instr->operands) { - if (!op_id) { + if (first) { // Keep destination field that may need alignment setting dst_f = phv.field(op_f); } else { @@ -1592,7 +1592,7 @@ struct ComputeFieldAlignments : public Inspector { } } } - op_id++; + first = false; } } return false; diff --git a/ir/json_loader.h b/ir/json_loader.h index 335a256630a..34fa571185c 100644 --- a/ir/json_loader.h +++ b/ir/json_loader.h @@ -92,11 +92,17 @@ class JSONLoader { const IR::Node *get_node() { if (!json || !json->is()) return nullptr; // invalid json exception? int id; - load("Node_ID", id); + auto success = load("Node_ID", id); + if (!success) { + return nullptr; + } if (id >= 0) { if (node_refs.find(id) == node_refs.end()) { cstring type; - load("Node_Type", type); + auto success = load("Node_Type", type); + if (!success) { + return nullptr; + } if (auto fn = get(IR::unpacker_table, type)) { node_refs[id] = fn(*this); // Creating JsonObject from source_info read from jsonFile From fa1091b56f30852056863b8187874fee8f2d48c3 Mon Sep 17 00:00:00 2001 From: fruffy Date: Fri, 14 Mar 2025 20:23:20 -0400 Subject: [PATCH 19/19] Shift fixes? Signed-off-by: fruffy --- backends/tofino/bf-asm/salu_inst.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backends/tofino/bf-asm/salu_inst.cpp b/backends/tofino/bf-asm/salu_inst.cpp index aaa0c8c207d..a4e370fb2f8 100644 --- a/backends/tofino/bf-asm/salu_inst.cpp +++ b/backends/tofino/bf-asm/salu_inst.cpp @@ -551,7 +551,7 @@ Instruction *AluOP::pass1(Table *tbl_, Table::Actions::Action *act) { if (k1 && (k1->value < Target::STATEFUL_ALU_CONST_MIN() || k1->value > Target::STATEFUL_ALU_CONST_MAX())) { if (k1->value >= (INT64_C(1) << tbl->alu_size()) || - k1->value < (INT64_C(-1) << (tbl->alu_size() - 1))) { + k1->value < (INT64_C(~0u) << (tbl->alu_size() - 1))) { error(lineno, "value %" PRIi64 " of the constant operand" @@ -571,7 +571,7 @@ Instruction *AluOP::pass1(Table *tbl_, Table::Actions::Action *act) { if (!r1) r1 = r2; if (r1) { int64_t v1 = tbl->get_const_val(r1->index); - if (v1 >= (INT64_C(1) << tbl->alu_size()) || v1 < (INT64_C(-1) << (tbl->alu_size() - 1))) { + if (v1 >= (INT64_C(1) << tbl->alu_size()) || v1 < (INT64_C(~0u) << (tbl->alu_size() - 1))) { error(lineno, "initial value %" PRIi64 " of the register file operand"